Beschreibung |
---|
Gui-Frontend für pip zum Installieren/Entfernen von PyPI-Paketen in der FreeCAD-Python-Umgebung. Versionsmakro : 0.4 Datum der letzten Änderung : 2025.01.18 FreeCAD version : 1.0 Herunterladen : Werkzeugleisten-Symbol Autor: TheMarkster |
Autor |
TheMarkster |
Herunterladen |
Werkzeugleisten-Symbol |
Links |
Makros Rezepte Wie man Makros installiert Symbolleisten anpassen |
Macro-Version |
0.4 |
Datum der letzten Änderung |
2025.01.18 |
FreeCAD-Version(s) |
1.0 |
Standardverknüpfung |
None |
Siehe auch |
None |
Dies ist eine grafische Benutzeroberfläche für pip zur Installation von pypi-Paketen in der FreeCAD-Python-Umgebung.
Pakete Bildschirmaufnahme
Dieses Makro installiert PyPI-Pakete in einem speziellen Ordner namens AdditionalPythonPackages. Dies ist genau derselbe Ordner, der auch vom AddonManager zum Installieren von Abhängigkeiten für verschiedene Addons verwendet wird. Die Dateien in diesem Ordner können vom Addon-Manager oder von diesem Makro installiert worden sein. Klicke auf die Schaltfläche in der unteren rechten Ecke, um den Speicherort des Ordners in Ihrem Standard-Dateibrowser zu öffnen. Der Ordner wird erstellt wird, falls er noch nicht existiert. Wenn der Ordner erstellt werden muss, erkennt FreeCAD die darin installierten Pakete erst nach einem Neustart von FreeCAD. Danach sollte kein Neustart von FreeCAD mehr erforderlich sein. Pakete werden mit pip installiert. Diese werden von pypi installiert. Es werden nur die 8000 am häufigsten heruntergeladenen Pakete aufgelistet, aber Sie können die Suchschaltfläche verwenden, um auch Pakete zu installieren, die nicht zu den 8000 beliebtesten Paketen gehören. Die Schaltfläche „Filter anwenden” verwendet den Inhalt der Filterzeile, um die Pakete in der Liste der 8000 beliebtesten Pakete zu filtern. Das Kontrollkästchen „Sortieren” schaltet zwischen alphabetischer Sortierung und Sortierung nach Beliebtheit um (standardmäßig deaktiviert). Die Schaltfläche „URL öffnen“ öffnet die pypi-Seite für das ausgewählte Paket im Standardbrowser.
Es gilt zu beachten, dass ein Paket zusätzliche Abhängigkeiten haben kann, die ebenfalls installiert werden. Wenn das Paket entfernt wird, werden auch die damit installierten Abhängigkeiten entfernt, es sei denn, sie wurden ebenfalls als Abhängigkeiten für ein anderes Paket installiert. Es ist möglich, den gesamten Ordner zu löschen, um alle mit diesem Makro und dem Addon-Manager installierten Abhängigkeitspakete zu entfernen. Dies kann jedoch dazu führen, dass Addons, die diese Pakete benötigen, nicht mehr funktionieren.
Die installierten Pakete werden in einem Unterordner gespeichert, der auf der verwendeten Python-Version basiert. Wenn FreeCAD auf eine neuere Python-Version aktualisiert wird, müssen diese Pakete höchstwahrscheinlich neu installiert werden. Man kopiert sie einfach in den Ordner der neuen Python-Version, aber es ist besser, pip zu verwenden, falls die neuere Python-Version eine neuere Version des Pakets erfordert.
packages.py
# packages.py # 2024, <TheMarkster> LGPL 2.1 or later # thanks to forum member hasecilu for help with setting pyside6 icons # a utility to install Python packages in FreeCAD __version__ = "0.4" from PySide import QtWidgets, QtGui, QtCore QDialog = QtWidgets.QDialog QVBoxLayout = QtWidgets.QVBoxLayout QHBoxLayout = QtWidgets.QHBoxLayout QLabel = QtWidgets.QLabel QLineEdit = QtWidgets.QLineEdit QSpinBox = QtWidgets.QSpinBox QPushButton = QtWidgets.QPushButton QListWidget = QtWidgets.QListWidget QMessageBox = QtWidgets.QMessageBox QCheckBox = QtWidgets.QCheckBox QApplication = QtGui.QApplication QFileDialog = QtGui.QFileDialog Qt = QtCore.Qt import requests import re import webbrowser import subprocess, sys, platform import freecad.utils as utils import addonmanager_utilities as amutils import shutil import json import importlib class Packages: def __init__(self): self.python_version = f"{sys.version_info.major}.{sys.version_info.minor}" self.pg = FreeCAD.ParamGet(f"User parameter:Plugins/Packages_Macro/{self.python_version}") layout = QVBoxLayout() self.mw = FreeCADGui.getMainWindow() self.pathEdit = QLineEdit() self.pathEdit.setToolTip("Path to python executable.") self.pathEdit.setText(self.findExecutable()) self.form = QtWidgets.QWidget() self.form.setLayout(layout) self.mode = "install" # can also be "uninstall" filterLayout = QHBoxLayout() self.filterEdit = QLineEdit() self.filterEdit.setPlaceholderText("Filter packages") self.filterEdit.returnPressed.connect(self.applyFilter) self.filterEdit.textChanged.connect(self.enableButtons) filterLayout.addWidget(QLabel("Filter:")) filterLayout.addWidget(self.filterEdit) self.sortedCheckBox = QCheckBox("Sort") self.sortedCheckBox.setToolTip(""" Default is sorting by popularity in terms of most downloads in the last 30 days. Checked = sort A to Z. Note toggling applies the filter.""") self.sortedCheckBox.setChecked(False) self.sortedCheckBox.stateChanged.connect(self.applyFilter) # this is to initialize stateChanged, otherwise first toggle does not update checked = self.sortedCheckBox.isChecked() filterLayout.addWidget(self.sortedCheckBox) self.filterButton = QPushButton("Apply Filter") self.filterButton.clicked.connect(self.applyFilter) filterLayout.addWidget(self.filterButton) self.searchButton = QPushButton("Search") self.searchButton.setIcon(FreeCADGui.getIcon("internet-web-browser")) self.searchButton.setToolTip("Search for filter on pypi.org in default browser") self.searchButton.setEnabled(False) filterLayout.addWidget(self.searchButton) self.searchButton.clicked.connect(self.search) self.packageList = QListWidget() self.packageList.itemSelectionChanged.connect(self.enableButtons) self.fetchButton = QPushButton("Fetch summary") self.fetchButton.setIcon(FreeCADGui.getIcon("internet-web-browser")) self.fetchButton.setEnabled(False) self.fetchButton.clicked.connect(self.fetchSummary) layout.addLayout(filterLayout) layout.addWidget(self.packageList) buttonLayout = QHBoxLayout() buttonLayout.addWidget(self.fetchButton) self.installButton = QPushButton("Install / Update") self.installButton.clicked.connect(self.install) self.installButton.setEnabled(False) self.installButton.setToolTip(""" If this is disabled with an active selection it means the package is a base package. You are allowed to install again an added package because there might be an update available for it.""") buttonLayout.addWidget(self.installButton) self.uninstallButton = QPushButton("Uninstall") style = self.form.style() try: trashIcon = style.standardIcon(style.SP_TrashIcon) except: trashIcon = style.standardIcon(style.StandardPixmap.SP_TrashIcon) self.uninstallButton.setIcon(trashIcon) self.uninstallButton.clicked.connect(self.uninstall) self.uninstallButton.setEnabled(False) self.uninstallButton.setToolTip(""" If this is disabled with an active selection it means the selected package is either not already installed or it is a base package included with the packaging or distribution.""") buttonLayout.addWidget(self.uninstallButton) self.openUrlButton = QPushButton("Open Url") self.openUrlButton.setIcon(FreeCADGui.getIcon("internet-web-browser")) self.openUrlButton.clicked.connect(self.openUrl) self.openUrlButton.setEnabled(False) buttonLayout.addWidget(self.openUrlButton) layout.addLayout(buttonLayout) pathLayout = QHBoxLayout() layout.addLayout(pathLayout) self.pathEdit.setPlaceholderText("Path to python executable") pathLayout.addWidget(QLabel("Python:")) pathLayout.addWidget(self.pathEdit) self.pathButton = QPushButton("...") try: self.pathButton.setIcon(style.standardIcon(style.SP_FileDialogStart)) except: self.pathButton.setIcon(style.standardIcon(style.StandardPixmap.SP_FileDialogStart)) self.pathButton.setFixedWidth(self.pathButton.sizeHint().width()) self.pathButton.setToolTip("Click to browse for python executable.") self.pathButton.clicked.connect(self.setupPath) pathLayout.addWidget(self.pathButton) additionalLayout = QHBoxLayout() layout.addLayout(additionalLayout) additionalLayout.addWidget(QLabel("AdditionalPythonPackages folder:")) self.additionalEdit = QLineEdit() self.additionalEdit.setPlaceholderText("AdditionalPythonPackages folder goes here") pathToPackages = self.pg.GetString("PathToPackages","") if not pathToPackages: pathToPackages = amutils.get_pip_target_directory() if not os.path.exists(pathToPackages): os.makedirs(pathToPackages) self.pg.SetString("PathToPackages", pathToPackages) FreeCAD.Console.PrintMessage("AdditionalPythonPackages folder has been created. You will likely need to restart FreeCAD to use any newly installed packages.\n") self.additionalEdit.setText(pathToPackages) self.additionalEdit.setReadOnly(True) additionalLayout.addWidget(self.additionalEdit) self.additionalButton = QPushButton("Open") try: self.additionalButton.setIcon(style.standardIcon(style.SP_DirOpenIcon)) except: self.additionalButton.setIcon(style.standardIcon(style.StandardPixmap.SP_DirOpenIcon)) self.additionalButton.clicked.connect(self.openAdditional) self.additionalButton.setToolTip(""" Opens the AdditionalPythonPackages folder. Note that the only things that should be in this folder are things installed using this macro or additional dependencies installed via the addon manager. It should be relatively safe to remove things from here. You should take note of what extra folders were added when you install something. These dependencies are not being tracked as pip doesn't support tracking packages added to custom folders. When we uninstall something we only install what we added, not the additional dependencies pip might have added.""") additionalLayout.addWidget(self.additionalButton) self.packages = self.loadPackageData() title = f"Packages {__version__} ({len(self.packages)} packages)" self.form.setWindowTitle(title) self.applyFilter() self.form.setWindowIcon(self.QIconFromXPMString(__icon__)) def loadPackageData(self): # would be faster to cache this locally, but this way it's always up to date url = "https://hugovk.github.io/top-pypi-packages/top-pypi-packages-30-days.json" try: response = requests.get(url) response.raise_for_status() data = response.json() return data["rows"] except requests.RequestException as e: QMessageBox.critical(self.mw, "Error", f"Could not load data: {e}") return [] def openAdditional(self): """ open the addtional python packages folder. note that this is a different folder for each version of python used by various freecad installations, for example if the user has multiple versions in simultaneous use. this folder is really for the addon manager to install dependencies when installing various addons, so we do not have exclusive use of it. but the advantage is the addon manager can also update these for use when updates are available. this folder is made available to python via initGui,py in src/App, which is how addons are able to import the packages installed here. """ sys = platform.system() userFolder = self.additionalEdit.text() if 'Windows' in sys: subprocess.Popen('start explorer.exe '+userFolder, shell=True) elif 'Linux' in sys: os.system("xdg-open '%s'" % userFolder) elif 'Darwin' in sys: subprocess.Popen(["open", userFolder]) else: msgBox = QtGui.QMessageBox() msg = "We were unable to determine your platform, and thus cannot open your '+userFolder+' for you, but you can still do it manually.\n" msgBox.exec_() def getStandardButtons(self): return (QtWidgets.QDialogButtonBox.Close) def setupPath(self): """ This is for the user to bre able to set a python that he wants to use rather than the default found with the freecad.utils function """ path, ok = QFileDialog.getOpenFileName(self.mw, "Select Python Executable", "", "Python Executable (python*);;All Files (*)") if path: self.pathEdit.setText(path) self.pg.SetString("PathToPython", path) def applyFilter(self): """ This is called when the user clicks the Apply filters button, and also when the user toggles the sort checkbox, and when the enter key is pressed in the filter line edit widget. If sorting is active, then the filtered packages are sorted alphabetically, otherwise they are sorted based on the popularity as measured by the number of downloads in the last 30 days. """ filter = self.filterEdit.text() try: filtered = [pkg for pkg in self.packages if re.search(filter, pkg["project"], re.IGNORECASE)] exactMatch = False self.packageList.clear() for pkg in filtered: self.packageList.addItem(pkg["project"]) if pkg == filter: exactMatch = True self.packageList.setSortingEnabled(self.sortedCheckBox.isChecked()) if filter and not exactMatch: description, version = self.getInfo(filter) if description: self.packageList.insertItem(0, filter + " (not in top 8000)") except re.error as e: QMessageBox.warning(self.mw, "Invalid Regex", f"Error in regular expression: {e}") self.form.setWindowTitle(f"Packages {__version__}") def enableButtons(self): """enables or disables buttons based on whether a package is selected in the list widget and whether that package is already installed.""" hasSelection = bool(self.packageList.selectedItems()) self.openUrlButton.setEnabled(hasSelection) self.fetchButton.setEnabled(hasSelection) hasFilter = bool(self.filterEdit.text()) self.searchButton.setEnabled(hasFilter) added, base = (False, False) if hasSelection: added, base = self.isInstalled() self.installButton.setEnabled(not base) self.uninstallButton.setEnabled(added) def install(self): self.mode = "install" self.managePackages() def uninstall(self): self.mode = "uninstall" self.managePackages() def findExecutable(self): """ find the python executable in use, luckily there is a function for this already in FreeCAD, but we still want to allow the user the flexibility of setting a different python executable if the function gets it wrong """ path = self.pg.GetString("PathToPython","") if path: return path pyEx = utils.get_python_exe() if os.path.exists(pyEx): self.pg.SetString("PathToPython", pyEx) return pyEx else: FreeCAD.Console.PrintError(f"Python executable not found. You may try to find it manually by clicking the '...' button at the bottom of the dialog.\n") return "Path to python executable" def managePackages(self): """ Here is where the installing and uninstalling happens. We track which packages we have installed and which dependencies were installed along with them. The caveat here is the AddonManager might also install stuff in our folder, but I don't think the AM tracks extra dependencies. """ package = self.packageList.currentItem().text().replace(" (not in top 8000)", "") python_exe = self.pathEdit.text() vendor_path = self.additionalEdit.text() if "APPIMAGE" in os.environ: os.environ['PYTHONHOME'] = '/usr' os.environ['PYTHONPATH'] = f"/usr/lib/python{self.python_version}/site-packages" if self.mode == "uninstall": added = self.loadAddedSubfolders(package) self.pg.RemString(f"{package}_Subfolders") for subfolder in added: item_path = os.path.join(vendor_path, subfolder) if os.path.exists(item_path): shutil.rmtree(item_path) print(f"{subfolder} removed\n") self.enableButtons() return existing = set(os.listdir(vendor_path)) command = [python_exe, "-m", "pip", self.mode, "--target", vendor_path, package] try: result = subprocess.run( command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, check=True ) FreeCAD.Console.PrintMessage(f"{result.stdout}\n") new_folders = set(os.listdir(vendor_path)) - existing added = list(new_folders) self.saveAddedSubfolders(package, added) except subprocess.CalledProcessError as e: FreeCAD.Console.PrintError(f"Error: {e.stderr}\n") except Exception as e: FreeCAD.Console.PrintError(f"An unexpected error occurred: {e}\n") finally: self.enableButtons() def saveAddedSubfolders(self, package, added): """ Here we track the folders that we added to this AdditionalPythonPackages folder and removed them during uninstallation. The complication is that sometimes additional dependencies are also added, and when they are, we should also track them and remove them. Further complicating this is other packages might have also added the same dependencies. These we reconcile in the loadAddedSubfolders() method below. """ json_string = json.dumps(added) self.pg.SetString(f"{package}_Subfolders", json_string) def loadAddedSubfolders(self, package): """ We get all of the packages that were added by all installations, this is in allPackages list. The added list only includes the new subfolders that were added when this package was installed. Anything in added that is not also in allPackages can be safely removed during uninstallation. """ json_string = self.pg.GetString(f"{package}_Subfolders", "") added = json.loads(json_string) if json_string else [] allPackages = [] for key in self.pg.GetStrings(): if key.endswith("_Subfolders") and key != f"{package}_Subfolders": other_json = self.pg.GetString(key, "") try: otherPackages = json.loads(other_json) allPackages.extend(otherPackages) except json.JSONDecodeError: print(f"Error decoding subfolder list for {key}.") unique = [folder for folder in added if folder not in allPackages] return unique def isInstalled(self): """ Called only by the enable buttons function. We return a tuple (added, base) added = True means this was something we added to the additional packages folder. base = True means this is installed, but as a base package either through the packaging or user installed into the system environment, either way we don't try to install or uninstall anything we didn't add or that the addon manager didn't add as an additional dependency in our user addon folder """ added = False base = False package = self.packageList.currentItem().text().replace(" (not in top 8000)", "") python_exe = self.pathEdit.text() vendor_path = amutils.get_pip_target_directory() if not os.path.exists(vendor_path): os.makedirs(vendor_path) fullpath = os.path.join(vendor_path,package) if os.path.exists(fullpath): added = True try: importlib.import_module(package) if not added: # we didn't add this base = True except ImportError: # added might or might not be false because this might not yet be # available to import if the additionalpythonpackages folder was # only just created this FreeCAD session, so we don't set it False # here, but instead rely on the above test base = False return (added, base) def fetchSummary(self): selectedItem = self.packageList.currentItem() if not selectedItem: return package = selectedItem.text().replace(" (not in top 8000)","") description, version = self.getInfo(package) QMessageBox.information(self.mw, "Package Summary", f"{package} (v{version}): {description}") def getInfo(self, package): """ called by fetchSummary(), pops up a very brief description of the package in a message box. User can use the OpenUrl button to get more details. We also use this to check if a custom entered package is available outside the top 8000 list. """ url = f"https://pypi.org/pypi/{package}/json" try: response = requests.get(url) response.raise_for_status() data = response.json() description = data["info"].get("summary", "No description available.") version = data["info"].get("version", "Unknown version") return description, version except requests.RequestException: return "", "Unknown version" def search(self): filter = self.filterEdit.text() if not filter: return url = f"https://pypi.org/search/?q={filter}" try: webbrowser.open(url) except Exception as e: QMessageBox.critical(self.mw, "Error", f"Unable to open the browser. Error: {e}") def openUrl(self): package = self.packageList.currentItem().text().replace(" (not in top 8000)", "") url = f"https://pypi.org/pypi/{package}" try: webbrowser.open(url) except Exception as e: QMessageBox.critical(self.mw, "Error", f"Unable to open the browser. Error: {e}") def QIconFromXPMString(self, xpm_string): if "/*pixels*/" in xpm_string: xpm = xpm_string.replace("\"","").replace(',','').splitlines()[4:] else: xpm = xpm_string.replace("\"","").replace(',','').splitlines()[3:] for line in reversed(xpm): if line.startswith("/*") and line.endswith("*/"): xpm.pop(xpm.index(line)) pixmap = QtGui.QPixmap(xpm) icon = QtGui.QIcon(pixmap) return icon __icon__ = """ /* XPM */ static char *dummy[]={ "64 64 1050 2", "Qt c None", ".g c #010101", "br c #020202", "a3 c #030202", "h3 c #030303", "ej c #030304", ".I c #040404", "ao c #050504", ".# c #050505", "m9 c #060605", "dI c #060606", ".J c #070707", "a2 c #090907", "nl c #090909", "mW c #0a0a0a", "mV c #0b0a09", "aL c #0b0b09", "bh c #0b0b0b", ".s c #0b0c0c", "nz c #0c0b0b", "oj c #0c0c0c", "d3 c #0c0c0d", "n9 c #0d0c0c", "dJ c #0d0d0d", "#b c #0d0d0e", ".W c #0d0e0f", "mL c #0e0e0f", "eI c #0f0f10", "#T c #0f1317", "#x c #0f1417", "mK c #100f0d", "nN c #11100e", "nk c #11100f", "mA c #111111", "bM c #111112", "#a c #111417", "c# c #121212", "#U c #121415", "mo c #131313", ".t c #131315", "mU c #15130e", "nA c #151516", "aK c #16140d", "#y c #16181b", "mM c #171717", "fj c #181819", ".X c #181a1c", "gY c #191919", ".f c #191b1d", "h# c #1a1a1b", "#7 c #1a1e21", "m8 c #1c1a15", "an c #1d1b15", "oi c #1d1d1e", "ot c #1e1e1e", "mX c #202020", "ap c #212328", "aM c #212428", "nY c #22211c", "bs c #222223", "h4 c #232325", "#8 c #23252a", "#c c #23272e", "cx c #242425", ".H c #242629", "#z c #242b34", "o. c #252526", ".h c #25272a", "ek c #262627", ".K c #262a2f", "cP c #282729", "d# c #282829", "iM c #29292a", "du c #29292b", "#d c #2c3845", "#A c #2e3d4b", "am c #2f2919", "aJ c #2f2a1c", "m7 c #2f2a1d", "nO c #2f2f30", ".A c #2f6491", "mY c #303030", ".B c #306491", ".Q c #306591", "ib c #306592", "nj c #312d23", "ny c #312f2a", ".Y c #313942", "#E c #316591", "eS c #316592", "ja c #323233", "a5 c #326592", ".z c #326692", "mT c #332e21", "av c #336692", "#p c #336792", "dC c #336793", "a6 c #346792", ".R c #346793", "aw c #346893", "n. c #353536", ".Z c #354658", ".l c #35658f", ".m c #356792", ".6 c #356893", "ev c #356894", "os c #363637", ".u c #363d46", ".P c #366792", "#i c #366894", "dW c #366994", "bg c #373630", "mz c #373737", "#e c #374d61", "#h c #376893", "f. c #376994", "ax c #376a95", "#R c #3775a9", ".y c #386891", ".n c #386993", "ac c #386994", "ew c #386a95", "ba c #3875a9", "bA c #3876a9", "dl c #3876aa", ".o c #39678f", "lj c #3976a9", "c2 c #3977aa", "nm c #3a3a3c", ".x c #3a648a", "ab c #3a6a94", ".C c #3a6b95", "dB c #3a6b96", "aR c #3a6c96", "#Q c #3a77aa", "#Z c #3b6c96", "ad c #3b6c97", "ea c #3b6d96", "b# c #3b77aa", "dK c #3c3b3d", ".a c #3c4149", ".0 c #3c5974", "#Y c #3c6c94", "iw c #3c6c96", "aC c #3c78aa", "ht c #3c78ab", ".k c #3d6589", ".O c #3d688f", "#D c #3d6b94", "fw c #3d6d95", "b. c #3d78aa", "k2 c #3d79ab", "bi c #3e3e40", ".D c #3e6c93", "fr c #3e6c95", "eT c #3e6e98", "ae c #3e6f9a", "dX c #3e79ab", "iq c #3f3f42", ".w c #3f607d", "g# c #3f6c95", "gm c #3f6e96", ".7 c #3f6e98", "#F c #3f6f98", "lE c #3f79ab", "#5 c #3f7aab", "cH c #3f7aac", "nM c #403c30", "gQ c #406e96", "au c #406e97", "g4 c #406f96", "#o c #406f98", "cI c #407aab", "fY c #407aac", "#V c #414b56", "aq c #415c76", ".E c #416789", "ds c #417bab", "#v c #417bac", ".r c #42474d", "#B c #425a73", "a4 c #425c75", "aN c #425c76", ".S c #426f97", "ay c #42729b", "dD c #427bac", "b0 c #427dae", "jb c #434343", "mN c #434344", "#g c #436b91", "kk c #437199", "ic c #43719a", "hr c #43729a", "hV c #437cac", "iN c #444446", "#f c #446482", "fs c #446f96", "hd c #447299", "ia c #44729a", "aV c #447dad", "ok c #454547", "bN c #454548", ".v c #45576a", "fP c #456f97", "fx c #45739b", "iB c #457dad", ".i c #465161", ".T c #466e91", "hf c #467dad", "n8 c #474541", "a7 c #477198", "ft c #477298", "e9 c #477299", "k1 c #47739b", "eh c #477ead", "eZ c #477eae", "cn c #4780b0", "ar c #487197", "fR c #487298", "aa c #487398", "e6 c #487399", "dV c #48759c", "dE c #487fae", "nx c #49422f", "#C c #496c8e", "fQ c #497398", "iU c #49749a", "eu c #49759b", "gn c #4979a2", "c3 c #497fae", "bV c #4980ad", "nB c #4a4a4c", "fS c #4a7399", "j8 c #4a79a2", "g5 c #4a7aa3", "bz c #4a80ad", "go c #4a80ae", "eY c #4a80af", ".j c #4b647d", ".N c #4b6b87", "eR c #4b769b", "cp c #4b80ae", "bm c #4b81ae", "fu c #4c7398", "fv c #4c7499", "#M c #4c7ba2", "gS c #4c80aa", "#P c #4c82af", "nn c #4d4d4f", "d4 c #4d4d50", "e7 c #4d7499", "#j c #4d789e", "#q c #4d799f", "gC c #4d81ad", "bD c #4d84b2", "ca c #4e4e4f", "ex c #4e789e", "kl c #4e7ea6", "hs c #4e7ea8", "i2 c #4e83af", "he c #4f7ea7", "n# c #504f51", ".1 c #507495", "aQ c #50789c", ".5 c #507a9f", "#L c #507ca2", "by c #507fa6", "id c #5083b0", "lF c #5083b1", "ci c #5084b0", "dk c #5086b4", "#9 c #51667b", "hU c #517a9f", "ee c #517ea6", "ch c #517fa6", "dY c #5184b0", "fX c #5184b1", "aE c #5185b1", "aO c #527699", "e8 c #52779a", "eA c #527ba0", "af c #527ea3", "#s c #5280a8", "c8 c #5284b0", "fB c #5285b0", "aj c #5285b1", "bF c #5285b2", "nZ c #535355", ".L c #535c67", ".F c #536b81", ".p c #537390", "#X c #537697", "a. c #53789a", "e# c #53799b", "h9 c #537b9f", "eU c #537ca0", "#J c #537ca1", "fA c #5383ad", "fc c #5383ae", "k3 c #5385b1", "do c #5386b1", "l2 c #5386b2", "ni c #544e3b", "ga c #54799c", "iX c #547ca0", "fT c #547ca1", "f# c #547ea2", "#r c #5480a6", "fV c #5482aa", "cJ c #5485b1", "aB c #5487b1", "#I c #557da1", "fU c #5581a7", "eF c #5586b2", "cY c #5588b3", "iz c #567da1", "#K c #567ea1", "bl c #5681a7", "a9 c #5686af", "c4 c #5687b2", ".G c #57626e", "at c #577b9d", "eB c #5783a8", "#u c #5788b2", "al c #58543e", ".b c #586a80", "a# c #587b9c", "ix c #587da1", "#m c #5880a3", ".8 c #5881a6", "fb c #5886ad", "fW c #5887b0", "bB c #588cb7", "iA c #597fa2", "iy c #597fa3", "#l c #5980a3", ".9 c #5984a9", "fz c #5985ab", "cD c #598ab4", "c1 c #598cb7", "jf c #5a7fa2", "#t c #5a88b0", "iC c #5a89b3", "i# c #5b80a4", ".2 c #5b81a2", "gp c #5b89ae", "#4 c #5b8ab3", "eJ c #5c5c60", "iW c #5c80a4", "#G c #5c82a5", "#N c #5c88ad", "#. c #5c88ae", "ig c #5c8bb3", "ox c #5d5d61", ".U c #5d7386", "#W c #5d738c", ".c c #5d7c99", "as c #5d7c9c", ".3 c #5d82a4", "#n c #5d83a4", "fy c #5d85a8", "jj c #5d8bb3", "c5 c #5d8bb4", "nX c #5e5742", "l1 c #5e88ad", "cL c #5e8bb3", "fC c #5e8cb4", "gc c #5e8db4", "ir c #5f5f61", ".V c #5f6a75", "ed c #5f83a5", "aS c #5f86a8", "lk c #5f8cb5", "iD c #5f8db4", "m6 c #60563a", "i. c #6082a4", "iY c #6084a5", "l0 c #6085a5", "#k c #6185a6", "cK c #618db5", "#O c #618eb5", "oh c #626266", ".e c #626d78", ".M c #627181", ".q c #627384", "#0 c #6288a9", "h5 c #636366", "iV c #6385a5", "gb c #6388aa", "fe c #638fb5", "dp c #638fb6", "dn c #638fb7", "nP c #646467", "aP c #64819f", "gD c #648ea8", "bt c #656569", "fa c #658cae", "c6 c #658fb6", "i0 c #6590b6", "bW c #6594bd", "nL c #665b3c", "mJ c #666152", ".4 c #6688a8", "lG c #6692b9", "iO c #676768", "az c #678caf", "iZ c #678cb0", "ie c #6790b7", "if c #6791b7", "aU c #6792b7", "dS c #6888a7", "eb c #688aa9", "ef c #6891b8", "li c #698aa9", "a8 c #698cab", "ah c #6992b7", "i1 c #6992b8", "a1 c #6a6452", "nC c #6a6a6c", "dR c #6a87a4", "#H c #6a8baa", "dU c #6a8bab", "#S c #6a8fb1", "eC c #6a92b6", "dr c #6a93b7", "g. c #6b87a3", "#w c #6b90b1", "bk c #6c87a1", "fq c #6c87a3", "et c #6c89a6", "ag c #6c91b3", "#6 c #6c92b2", "gB c #6c94b8", "iT c #6d88a5", "je c #6d89a5", "jI c #6d89a6", "kj c #6d8aa6", "gR c #6d94b8", "eX c #6d95b8", ".d c #6e879f", "iv c #6e88a5", "gl c #6e89a5", "jv c #6e89a6", "hg c #6f94b7", "nw c #70623b", "bC c #709dc1", "c7 c #7197b9", "hc c #728da9", "gA c #728daa", "ey c #7290ae", "hI c #7296b6", "dj c #729ec2", "ou c #737376", "ez c #7391af", "dZ c #7397bb", "ak c #7398b6", "aA c #7398b9", "ji c #7398bb", "l3 c #739bbe", "no c #747474", "bO c #747477", "mn c #747478", "hH c #7499ba", "lU c #757578", "jg c #7591ad", "#3 c #7599b9", "eg c #7599ba", "mZ c #767676", "dq c #7699bb", "eV c #7795b1", "gT c #7797aa", "jh c #7896b5", "dt c #789cbc", "d2 c #789dbd", "e5 c #798fa8", "## c #7995af", "ff c #799dbd", "dA c #7a95ae", "lD c #7a97b1", "aF c #7a9cb3", "eG c #7a9fbf", "c9 c #7b9ebd", "aD c #7b9fbe", "ei c #7b9fbf", "fD c #7ba0bf", "aT c #7c9db9", "eD c #7c9dbe", "dH c #7c9ebd", "bn c #7c9fbf", "co c #7ca0c0", "dT c #7d96b2", "fd c #7d9ebc", "bE c #7d9fc0", "b1 c #7da0c0", "h8 c #7e94ac", "bx c #7e98b1", "eE c #7e9ebe", "ll c #7ea2c2", "cb c #7f7f80", "el c #7f7f83", "eQ c #7f97af", "dm c #7fa1c0", "e. c #8095ac", "di c #809ab3", "gq c #809b9f", "bU c #819cb4", "bj c #82858c", "ec c #829ab4", "k0 c #8398af", "#1 c #839eb9", "cG c #83aaca", "gd c #84a3bf", "mB c #858589", "g6 c #85a2bd", "bZ c #85aaca", "nW c #877748", "n0 c #88888a", "or c #88888d", "hT c #889bb1", "nQ c #89898a", "hu c #89a3b8", "cq c #89a5bb", "dG c #89a5c2", "dF c #89a6c0", "ai c #89a7c2", "n7 c #8a8884", "e1 c #8a898c", "d0 c #8aa5c1", "cM c #8aa6c0", "mc c #8b8b90", "j9 c #8ba2a8", "lZ c #8ba2b9", "jJ c #8ba3a8", "kL c #8ba3a9", "iE c #8ca4a8", "lH c #8dacc9", "is c #919192", "eK c #919195", "gE c #91a4a1", "jc c #929293", "#2 c #92a7bd", "hW c #92aabf", "nK c #938146", "bu c #949496", "ol c #949498", "eW c #94a9bf", "lh c #95abbe", "mS c #968964", "ih c #96aab3", "my c #999797", "g7 c #99acbb", "d1 c #9aafc6", "aI c #9b8c5f", "nD c #9b9a9b", "cy c #9b9a9e", "og c #9b9ba0", "es c #9ba9ba", "mg c #9bafc4", "cm c #9cbad4", "dQ c #9dabbb", "k4 c #9daeb4", "cj c #9dbbd5", "d5 c #9e9ea3", "hJ c #9eacaa", "nh c #9f9473", "l4 c #9fb6cf", "bf c #a09268", "o# c #a1a0a3", "bP c #a1a1a3", "hh c #a1b0b6", "eP c #a3acbb", "gU c #a3aeaa", "lC c #a3b3c4", "mf c #a4b2c3", "mO c #a5a5a8", "na c #a7a7aa", "lm c #a7bed3", "n1 c #a9a9a8", "cQ c #acabae", "n6 c #acacae", "da c #adacaf", "mm c #adadb2", "c0 c #adc6dc", "lg c #afb7c3", "dv c #b0afb3", "iP c #b0b0b2", "gr c #b1b9ad", "lY c #b1bcc9", "mh c #b1c1d4", "em c #b2b2b5", "js c #b3b3b6", "dz c #b3b9c4", "bX c #b3cade", "nv c #b49d59", "m5 c #b6a36a", "nV c #b6a573", "cc c #b6b6b6", "nR c #b6b6b7", "e2 c #b7b7b9", "ow c #b7b7bd", "lI c #b7c7d9", "cE c #b9cfe1", "gF c #baba9d", "np c #bbbabb", "mI c #bcaa78", "hv c #bcba99", "ov c #bcbcbf", "m0 c #bdbdc0", "gZ c #bdbdc2", "g8 c #bebea8", "fk c #bebec1", "d9 c #bec4cc", "hX c #bfbc98", "om c #bfbec0", "dL c #bfbec2", "eL c #bfbfbf", "gJ c #c0c0c2", "fK c #c0c0c3", "bv c #c1c1c0", "gk c #c1c5cc", "a0 c #c3ae6f", "it c #c3c3c5", "jd c #c3c3c6", "mC c #c4c3c8", "lB c #c4cad2", "bq c #c5b582", "oa c #c5c4c3", "mp c #c6c6c6", "me c #c6cbd1", "of c #c7c7c9", "l5 c #c7d1de", "d6 c #c8c7cb", "lT c #c8c8c9", "ln c #cacdc7", "dy c #cbccd1", "f9 c #cbd0d5", "ha c #cccccf", "bw c #cccfd3", "hK c #cdbf7a", "hl c #cdcccf", "jV c #cdccd0", "nE c #cdcdcd", "g0 c #cdcdd2", "ng c #ceb568", "hi c #cec9b0", "hC c #cecdcf", "h6 c #cecdd1", "nb c #ceced0", "j5 c #ceced2", "kf c #ceced3", "nJ c #cfb35b", "kE c #cfcdd1", "le c #cfced1", "lx c #cfced2", "bQ c #cfcfcf", "mx c #d0be88", "lz c #d0ced2", "iu c #d0cfd2", "jE c #d0cfd3", "md c #d0d0d3", "hS c #d0d2d7", "h7 c #d0d3d7", "gz c #d0d4da", "ms c #d1d0d4", "mE c #d1d0d5", "jt c #d1d1d3", "iS c #d1d1d4", "nc c #d1d1d5", "kK c #d1d5d8", "be c #d2b65c", "n2 c #d2d1d0", "jW c #d2d1d6", "dP c #d2d6d9", "j7 c #d2d6da", "ki c #d2d7da", "mR c #d3ba71", "m1 c #d3d2d4", "n5 c #d3d3d5", "gN c #d3d3d7", "jH c #d3d6da", "ju c #d3d7da", "bY c #d3e1ec", "jD c #d4d3d5", "eq c #d4d3d6", "cZ c #d4e1ed", "hY c #d5c270", "gV c #d5c78e", "d7 c #d5d4d6", "iQ c #d5d5d6", "lf c #d5d5d8", "hp c #d5d5d9", "er c #d5d8da", "ho c #d6d5d7", "de c #d6d6d8", "hG c #d6dbdf", "j6 c #d7d7d9", "lX c #d7dadb", "dh c #d7dadd", "cd c #d8d8d9", "fp c #d8dce0", "aH c #d9bc62", "cz c #d9d9d9", "g1 c #d9d9db", "cS c #dad9db", "kg c #dad9dd", "jC c #dadad9", "e4 c #dadee1", "g3 c #dadee2", "gP c #dadfe2", "jT c #dbdad9", "gx c #dbdadb", "lw c #dbdbd9", "gM c #dbdbdb", "f8 c #dbdbdc", "gy c #dbdbdd", "lJ c #dbe1e8", "on c #dcdbd8", "lV c #dcdbda", "en c #dcdcdb", "kI c #dcdcde", "m4 c #ddc67d", "j4 c #dddcdc", "fn c #dddcde", "ko c #ded0a6", "fL c #dedddd", "cT c #dedede", "hb c #dededf", "ob c #dfdedc", "dd c #dfdede", "kq c #dfdee1", "f7 c #dfdfde", "nu c #e0c162", "fi c #e0cd94", "kH c #e0dfdf", "mb c #e0e0e2", "bT c #e0e2e4", "cg c #e0e2e5", "mi c #e0e5ea", "bp c #e1c87e", "k5 c #e1cc87", "nU c #e1dbcd", "df c #e1e1e1", "gs c #e2cd86", "jZ c #e2cd8c", "ka c #e2ce94", "j0 c #e2ce95", "fM c #e2e1e1", "kZ c #e2e1e2", "eM c #e2e2e0", "fl c #e2e2e1", "fO c #e2e2e2", "oq c #e2e2e3", "eO c #e2e3e5", "hw c #e3c865", "ge c #e3cb75", "jP c #e3cd8f", "k# c #e3ce90", "jz c #e3cf93", "ip c #e3cf94", "jA c #e3dac3", "ly c #e3e2e1", "mD c #e3e2e2", "fm c #e3e3e2", "cA c #e3e3e3", "gO c #e3e3e4", "lA c #e3e4e2", "kM c #e4cc7b", "hQ c #e4e3e1", "hR c #e4e3e2", "kG c #e4e3e3", "dx c #e4e4e2", "fN c #e4e4e3", "kJ c #e4e4e4", "ii c #e5cd77", "kn c #e5ce88", "iL c #e5dfd1", "gj c #e5e4e2", "kh c #e5e4e4", "bR c #e5e5e4", "aG c #e6c550", "hL c #e6c960", "mq c #e6e5e1", "cR c #e6e5e3", "hF c #e6e5e4", "fo c #e6e5e5", "d8 c #e6e7e4", "dO c #e6e7e5", "gG c #e7cc70", "gw c #e7e6e4", "jF c #e7e6e6", "hn c #e7e7e4", "kp c #e7e7e5", "cU c #e7e7e6", "lS c #e7e7e9", "cN c #e8cd6d", "fJ c #e8cf82", "ky c #e8d28f", "jq c #e8e3d8", "hE c #e8e7e4", "nd c #e8e7e5", "ep c #e8e7e7", "gL c #e8e8e5", "cV c #e8e8e8", "oe c #e8e8e9", "cr c #e9ca5f", "hZ c #e9cb64", "mH c #e9cb6a", "jK c #e9cc6c", "ks c #e9cd6c", "hy c #e9d28a", "ke c #e9e8e5", "gv c #e9e8e6", "nF c #e9e8e7", "cB c #e9e8e8", "mt c #e9e8e9", "kr c #e9e9e7", "mF c #e9e9e9", "m2 c #e9e9ea", "iF c #eacd6c", "jQ c #eace7d", "kO c #eacf7a", "lo c #ead17f", "jR c #ead38a", "jp c #eadcb4", "nS c #eae8e7", "hm c #eae9e6", "gK c #eae9e7", "hq c #eaeae9", "oo c #eaeaec", "fG c #ebcf79", "ku c #ebcf7a", "kv c #ebd07f", "jm c #ebd286", "k. c #ebd287", "i8 c #ebe2c8", "j3 c #ebeae7", "dN c #ebebe7", "lW c #ebebe8", "dg c #ebebea", "jO c #ecce71", "fh c #ecce74", "gH c #ecd385", "mk c #ecd386", "mr c #eceae7", "nq c #eceae8", "dc c #ecebe7", "gi c #ecebe8", "nI c #edc95a", "gg c #edce72", "bL c #edd076", "hO c #edd384", "lp c #edd484", "kY c #edece8", "hD c #edece9", "ne c #edeced", "eo c #ededeb", "ce c #ededec", "n4 c #ededef", "l6 c #edf0f2", "aZ c #eec954", "d. c #eecc53", "fZ c #eecc54", "f2 c #eecf70", "gh c #eecf72", "i3 c #eed385", "j2 c #eed483", "ik c #eed484", "iG c #eed485", "ml c #eeebe3", "i9 c #eeede8", "dM c #eeede9", "jU c #eeedea", "cW c #eeeeed", "nr c #eeeeee", "nG c #eeeeef", "aW c #efc431", "b2 c #efc432", "mw c #efc84d", "nf c #efcb5d", "eH c #efcc53", "g9 c #efce60", "kN c #efcf6a", "km c #efcf6b", "f1 c #efcf6c", "f4 c #efd06e", "fH c #efd171", "iI c #efd172", "gX c #efd47f", "hA c #efd480", "lc c #efd483", "kX c #efd484", "iJ c #efd992", "mG c #efe7d3", "mP c #efe8d3", "lL c #efe9d3", "kF c #efedea", "dw c #efeee9", "db c #efeeea", "iR c #efefef", "cF c #eff4f8", "bd c #f0c12b", "bH c #f0cd5d", "io c #f0cf69", "kP c #f0d068", "k7 c #f0d069", "e0 c #f0d06a", "h2 c #f0d06b", "nH c #f0d379", "h1 c #f0d380", "im c #f0d480", "i7 c #f0dea8", "iK c #f0e4bf", "ns c #f0e7d3", "lv c #f0f0f3", "ck c #f0f5f9", "fF c #f1cf65", "k6 c #f1cf67", "bI c #f1cf68", "hj c #f1d064", "jY c #f1d066", "gf c #f1d067", "c. c #f1d16b", "cw c #f1d16c", "jo c #f1d98d", "e3 c #f1f1ef", "ld c #f1f1f2", "j# c #f1f1f3", "bo c #f2c848", "hx c #f2cd52", "b4 c #f2ce5e", "f3 c #f2cf63", "kb c #f2d16a", "i6 c #f2d478", "jG c #f2f2f0", "hM c #f3cf56", "i5 c #f3d062", "jn c #f3d26c", "jB c #f3f2f0", "bS c #f3f3f0", "cC c #f3f3f1", "ma c #f3f3f4", "mQ c #f4cf5a", "jy c #f4d05d", "fI c #f4d05f", "kQ c #f4d060", "kw c #f4d061", "m3 c #f4d370", "lM c #f4d470", "g2 c #f4f4f1", "b3 c #f5cb49", "b5 c #f5cf57", "bJ c #f5cf58", "iH c #f5d05b", "kt c #f5d05d", "kR c #f5d15e", "f5 c #f5d161", "eN c #f5f5f2", "op c #f5f5f6", "cs c #f6cf58", "f0 c #f6d057", "ct c #f6d260", "cX c #f6f6f3", "od c #f6f6f7", "nt c #f7d053", "b6 c #f7d157", "kx c #f7d158", "kz c #f7d25d", "cf c #f7f7f4", "lK c #f7f7f8", "gW c #f8d150", "jx c #f8d153", "k8 c #f8d154", "j1 c #f8d157", "b7 c #f8d259", "hP c #f8d25b", "hz c #f8d25c", "jX c #f8d25d", "jk c #f8d35b", "il c #f8d35c", "lR c #f8f8f9", "h0 c #f9d14e", "fg c #f9d151", "bK c #f9d153", "gt c #f9d256", "cu c #f9d257", "bc c #fac723", "mv c #facf46", "i4 c #fad14f", "jN c #fad151", "jr c #fafaf9", "n3 c #fafafb", "jw c #fbd14c", "kc c #fbd24d", "bG c #fcc925", "hk c #fcd147", "jM c #fcd14a", "in c #fcd24a", "gI c #fcd24b", "h. c #fcd24c", "b8 c #fcd24d", "jS c #fcf9f0", "mj c #fcfcfc", "m# c #fcfcfd", "mu c #fdd145", "fE c #fdd146", "jl c #fdd147", "jL c #fdd246", "hN c #fdd247", "kd c #fdd248", "cO c #fdd249", "hB c #fdd24c", "oc c #fdfdfd", "nT c #fdfdfe", "aY c #fec91f", "bb c #fec921", "gu c #fed243", "cv c #fed244", "ij c #fed246", "j. c #fefefe", "aX c #ffc91d", "b9 c #ffd242", "f6 c #ffd243", "m. c #ffd347", "kD c #ffd348", "l7 c #ffd449", "kS c #ffd44b", "kA c #ffd54f", "lu c #ffd654", "kW c #ffd757", "lb c #ffd85d", "l9 c #ffda65", "kC c #ffdc6c", "k9 c #ffdd71", "l8 c #ffde74", "lQ c #ffdf77", "lN c #ffdf78", "kB c #ffe07e", "lq c #ffe48e", "kT c #ffe9a2", "lt c #ffefbf", "kV c #fff2c6", "lO c #fff2c8", "lP c #fff3cc", "kU c #fff5d7", "l. c #fff7de", "la c #fffae9", "lr c #fffaec", "l# c #fffefd", "ls c #fffffe", "cl c #ffffff", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt.#.a.b.c.d.e.f.gQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt.g.h.i.j.k.l.m.n.o.p.q.r.sQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt.t.u.v.w.x.y.z.A.A.A.B.C.D.E.F.G.H.IQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt.J.K.L.M.N.O.P.Q.A.A.A.A.A.A.A.A.R.S.T.U.V.WQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt.g.X.Y.Z.0.1.2.3.4.5.6.A.A.A.A.A.A.A.A.7.8.9#.###aQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt#b#c#d#e#f#g#h.A#i#j#k#l#m#n#o.Q.A.A#p#q#r#s#t#u#v#w#xQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt.##y#z#A#B#C#D#E.A.A.A.A.A.A#F#G#H#I#J#K#L#M#N#O#P#Q#R#R#S#TQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt#U#V#W#X#Y.A.A.A.A.A.A.A.A.A.A.A#Z#0#1#2#3#4#5#R#R#R#R#R#6#7.gQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt#8#9a.a#aaabac.z.A.A.A.A.A.zadaeafagahaiaj#R#R#R#R#R#R#RakalamanaoQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtapaq.A#parasatau.mav.QawaxayazaAaBaC#RaDaE#R#R#R#R#R#R#RaFaGaHaIaJaKaL.gQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtaMaN.A.A.A.AabaOaPaQaRaSaTaUaV#R#R#R#RaDaE#R#R#R#R#R#R#RaFaWaXaYaZa0a1a2a3.g", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtaMa4.A.A.A.A.Ba5a6a7a8a9b.b#ba#R#R#R#RaDaE#R#R#R#R#R#R#RaFaWaXaXbbbcbdbebfbg", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtbhbibjbk.A.A.A.A.A.A.A#hblbm#R#R#R#R#R#R#RbnaE#R#R#R#R#R#R#RaFaWaXaXaXaXaYbobpbq", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtbrbsbtbubvbwbx.A.A.A.A.A.A.A#pbybzbAbBbCbD#R#R#RbEbF#R#R#R#R#R#R#RaFaWaXaXbGbHbIbJbKbL", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtbMbNbObPbQbRbSbTbU.A.A.A.A.A.A.A#pbybVbWbXbYbZb0#R#Rb1bF#R#R#R#R#R#R#RaFb2b3b4b5b6b7b8b9c.", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtc#cacbcccdcecfcfcfcgbU.A.A.A.A.A.A.A#pchcicjckclcmcn#R#RcobF#R#R#R#R#Rbacpcqcrcsctcucvb9b9b9cw", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtcxcyczcAcBcCcfcfcfcgbU.A.A.A.A.A.A.A#pchcDcEclcFcGcH#R#RcobF#R#R#RcIcJcKcLcMcNcOb9b9b9b9b9b9cw", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtcPcQcRcScTcUcVcWcXbTbU.A.A.A.A.A.A.A#pbycYcjcZc0c1#R#R#Rb1bFc2c3c4c5c6c7c8c9d.b9b9b9b9b9b9b9c.", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtd#dadbdbdcdddedfdgdhdi.B.A.A.A.A.A.A#pbybzc1djdkdl#R#R#Rdmdndodpdqdrds#R#Rdtd.b9b9b9b9b9b9b9cw", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtdudvdbdbdbdbdwdxdydzdA#odBdC.A.A.A.A#pchbV#R#R#R#Rb#dDdEdFdGdHbmbA#R#R#R#Rdtd.b9b9b9b9b9b9b9cw", "QtQtQtQtQtQtQtQtQtQtQtQtQtQt.gdIdJdKdLdbdbdMdNdOdPdQdRdSdTdUdVdWav.B.A#pchbz#Rbab#dXdYdZd0d1do#R#R#R#R#R#R#Rd2d.b9b9b9b9b9b9b9cw", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtd3d4d5d6d7dbdbd8d9e.e#.6.B.B.QeaebeceddB.AdCeebV#RdDefd0egehbAeiaE#R#R#R#R#R#R#Rd2d.b9b9b9b9b9b9b9c.", "QtQtQtQtQtQtQtQtQtQtQtejekelemeneoepeqereseteuacav.A.A.A.A.QevewexeyezeAeBeCeDeEeF#vdXbA#ReGaE#R#R#R#R#R#R#Rd2eHb9b9b9b9b9b9b9cw", "QtQtQtQtQtQtQtQtQteIeJeKeLeMeoeNcfeOePeQeRaceS.A.A.A.A.A.A.A.A.A.6eTeUeVeWeXeYeZb.#R#R#R#ReGaE#R#R#R#R#R#R#Rd2d.b9b9b9b9b9b9b9e0", "QtQtQtQtQtQtQtQtbMe1e2cTe3cfcfcfcfe4e5e6e7e8e9eS.A.A.A.A.A.A.Af.f#fafbfcfdfebA#R#R#R#R#R#ReiaE#R#R#R#R#R#R#RffeHb9b9b9b9b9fgfhfi", "QtQtQtQtQtQtQtQtfjfkflfmfnfocXcfcffpfqavfrfsftfufvfw.A.A#EfxfyfzfAfBeh#QeXfC#R#R#R#R#R#R#RfDaE#R#R#R#R#R#R#Rd2d.b9b9fEfFfGfHfIfJ", "QtQtQtQtQtQtQtQtfjfKdMcRfLfMfNfOeofpfq.A.A.B#hfPfQfRfSfTfUfVfWfXfY#R#R#ReXfC#R#R#R#R#R#R#RfDaE#R#R#R#R#R#R#Rd2fZf0f1f2f3f4f5f6cw", "QtQtQtQtQtQtQtQtfjfKdbdbdbdcf7f8cAf9g..A.A.A.A.A.zg#gagb#4dEba#R#R#R#R#ReXgc#R#R#R#R#R#R#RfDaE#R#R#R#R#R#RdDgdgegfggghcOb9b9b9c.", "QtQtQtQtQtQtQtQtfjfKdbdbdbdbgigjddgkgl.A.A.A.A.A.A.Agmgn#R#R#R#R#R#R#R#ReXfC#R#R#R#R#R#R#RfDaE#R#R#Rb#gogpgqgrgsgtgub9b9b9b9b9cw", "QtQtQtQtQtQtQtQtfjfKdbdMgvgwcRgxgygzgA.A.A.A.A.A.A.Agmgn#R#R#R#R#R#R#R#RgBfC#R#R#R#R#R#R#ReiaEba#vgCgDgEgFgGgHgIb9b9b9b9b9b9b9c.", "QtQtQtQtQtQtQtQtfjgJgKgLgMgNgOcXcfgPgA.A.A.A.A.A.A.AgQgn#R#R#R#R#R#R#R#RgRfC#R#R#R#R#R#R#Rbn#4gSgTgUgVgWb9b9gXgIb9b9b9b9b9b9b9cw", "QtQtQtQtQtQtQtQtgYgZg0g1g2cfcfcfcfg3gA.A.A.A.A.A.A.Ag4g5#R#R#R#R#R#R#R#RgRfC#R#R#R#Rba#Qb.g6g7g8g9cvb9b9b9b9gXh.b9b9b9b9b9b9b9cw", "QtQtQtQtQtQtQtQth#d6hahbcfcfcfcfcfg3hc.A.A.A.A.A.A.Ahdhe#R#R#R#R#R#R#R#RgRfC#R#R#R#Rhfhghhhihjhkgub9b9b9b9b9gXh.b9b9b9b9b9b9b9cw", "QtQtQtQtQtQtQtQth#hlhmhnhohphqcfcfgPhc.A.A.A.A.A.A.Ahrhs#R#R#R#R#R#R#R#RgRfC#Rhtc5huhvhwhxhyhzb9b9b9b9b9b9b9hAhBb9b9b9b9b9b9b9cw", "QtQtQtQtQtQtQtQth#hCdbhDhEhFfOdehbhGhc.A.A.A.A.A.A.Ahrhs#R#R#R#R#R#R#R#ReXhHhIhJhKhLhMhNb9hOhPb9b9b9b9b9b9b9hAgIb9b9b9b9b9b9b9c.", "QtQtQtQtQtQtQtQth#hCdbdbdbdMgKhQhRhShThUaw.A.A.A.A.Ahrhs#R#R#R#R#R#RhVfChWhXhYhZh0f6b9b9b9hOhPb9b9b9b9b9b9b9h1h.b9b9b9b9b9b9b9h2", "QtQtQtQtQtQth3h4h5h6dbdbdbdbdbdbhDh7h8h9i.i#iaib.A.Aichs#R#R#RaCidieifigihiiijb9b9b9b9b9b9ikilb9b9b9b9b9b9b9imhBb9b9b9b9b9inioip", "QtQtQt.gdJiqirisitiudbdbdbdbdbdbdbdPiviwixiyiziAex.ChrhsbAiBiCdpiDcK#4dDiEiFb9b9b9b9b9b9b9iGhzb9b9b9b9b9b9b9imhBb9b9cviHiIiJiKiL", "QtbriMiNiOiPiQiRe3iSdbdbdbdbdbdbdbdPiT.A.AaviUiViWiXiYiZiCc5i0i1i2#R#R#RiEiFb9b9b9b9b9b9b9i3hzb9b9b9b9b9b9b9imh.i4i5i6i7i8i9j.j#", "jajbjcjdcUcfcfcfe3iSdbdbdbdbdbdbdbdPje.A.A.A.A.A.Cjfjgjhjijjb##R#R#R#R#RiEiFb9b9b9b9b9b9b9i3jkb9b9b9b9b9b9jljmjnjojpjqjrclclclj#", "jsjteog2cfcfcfcfe3iSdbdbdbdbdbdbdbjujv.A.A.A.A.A.A.Agmgn#R#R#R#R#R#R#R#RiEiFb9b9b9b9b9b9b9i3ilb9b9b9gujwjxjyjzjAjBj.clclclclclj#", "jCjDjEjFjGcCcXcfe3iSdbdbdbdbdbdbdbjHjI.A.A.A.A.A.A.Agmgn#R#R#R#R#R#R#R#RjJjKb9b9b9b9b9b9b9i3ilb9jLjMjNjOjPjQjRjSclclclclclclclj#", "jTdbjUgjjVjWe3cXe3iSdbdbdbdbdbdbdbjHjI.A.A.A.A.A.A.Agmgn#R#R#R#R#R#R#R#RjJjKb9b9b9b9b9b9b9i3jXcvjYjZj0j1f6b9j2jSclclclclclclclj#", "jTdbdbdMgij3j4j5j6iQdbdbdbdbdbdbdbj7jv.A.A.A.A.A.A.AgQj8#R#R#R#R#R#R#R#Rj9jKb9b9b9b9b9b9b9k.k#kakbkckdcvb9b9j2jSclclclclclclclj#", "jTdbdbdbdbdbj3kecRkfkgkhdMdbdbdbdbkikj.A.A.A.A.A.A.Akkkl#R#R#R#R#R#R#R#Rj9jKb9b9b9b9inkmknkokbfgcOf6b9b9b9b9j2jSclclclclclclclj#", "jTdbdbdbdbdbdbdbhmh6kpfNg1kqkrdbdbkikj.A.A.A.A.A.A.Ahrhs#R#R#R#R#R#R#R#Rj9ksb9cvktkukvkwkxkykzb9b9b9kAkBkCkDj2jSclclclclclclclj#", "jTdbdbdbdbdbdbdbhmkEkFj3kGkhkHkIkJkKjI.A.A.A.A.A.A.Ahrhs#R#R#R#R#R#R#R#RkLkMkNkOkPkQkRgIb9hOhPb9b9kSkTkUkVkWkXjSclclclclclclclj#", "jTdbdbdbdbdbdbdbhmkEdbdbdbkYcRkZkGbwk0k1eS.A.A.A.A.Ahrhs#R#R#R#R#R#Rk2k3k4k5k6k7k8gub9b9b9hOhPb9b9k9l.l#lalblcjSclclclclclclclld", "jTdbdbdbdbdbdbdbhmledbdbdbdbdbdbj3lflglhlihUiw.A.A.Ahrhs#R#R#RljeZlklllmlnloinb9b9b9b9b9b9lpilb9b9lqlrlsltlulcjSclclclclclj.lvj6", "lwdbdbdbdbdbdbdbhmlxdbdbdbdbdbdbdblylzlAlBlClD#Kia.6hrhs#RlElFlGlHlIlJlKlLlMb9b9b9b9b9b9b9iGjkb9b9lNlOlPlQkDkXjSclclcllRlSlTeKlU", "lVdbdbdbdbdbdbdbhmlxdbdbdbdbdbdbdblyiudbdblWlXlYlZl0#ll1l2l3l4l5l6j.clcllLlMb9b9b9b9b9b9b9i3hzb9b9l7l8l9m.b9lcjSm#mambjsmcd4.#Qt", "jTdbdbdbdbdbdbdbhmlxdbdbdbdbdbdbdblymddbdbdbdbdbcRmemfmgmhmimjclclclclcllLlMb9b9b9b9b9b9b9i3hzb9b9b9b9b9b9cvmkmliQmmmnmo.gQtQtQt", "mpmqmrdMdbdbdbdbhmlxdbdbdbdbdbdbdblymsdbdbdbdbdbdbdbgjmtclclclclclclclcllLlMb9b9b9b9b9b9b9i3hzb9b9b9b9mumvmwmxmymz.IQtQtQtQtQtQt", "mAmBmCkhdbdbdbdbhmlxdbdbdbdbdbdbdbmDmEdbdbdbdbdbdbdbcRmFclclclclclclclclmGlMb9b9b9b9b9b9b9i3ilb9b9b9cvmHmImJmKh3.gQtQtQtQtQtQtQt", "brmLmMmNmOd7gidbhmlxdbdbdbdbdbdbdbmDmEdbdbdbdbdbdbdbcRmFclclclclclclclclmPlMb9b9b9b9b9b9b9i3ilb9mQmRmSmTmUmV.gQtQtQtQtQtQtQtQtQt", "QtQtQtmWmXmYmZm0f8m1dbdbdbdbdbdbdbfmmsdbdbdbdbdbdbdbcRm2clclclclclclclclmPm3b9b9b9b9b9b9b9gHm4m5m6m7m8m9QtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtbrh#n.n#nanbkpdbdbdbdbdbmDncdbdbdbdbdbdbdbndneclclclclclclclclmPlMb9b9b9b9ijnfngnhninjnkbrQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtnlnmnnnonpgxnqdbdbfmncdbdbdbdbdbdbdbgKnrclclclclclclclclnsm3b9b9ntnunvnwnxnynzQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtbrnAnBnCnDnEhRlyncdbdbdbdbdbdbdbnFnGclclclclclclclclnsnHnInJnKnLnMnNQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQt.JnOnPnQnRh6gKdbdbdbdbdbdbnSnGclclclclclclnTlKnUnVnWnXnYh3QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtc#nZn0n1n2hQhDdbdbdbkrnGclclclcln3n4n5n6n7n8n9QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQth3o.bOo#oaobhmdMgKnGclocodoeofogohoiQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtojokolomonlyooopoqgZorosbrQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtotouovgNowoxmLQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt"}; """ if __name__ == "__main__": dlg = Packages() if not FreeCADGui.Control.activeDialog(): FreeCADGui.Control.showDialog(dlg) else: FreeCAD.Console.PrintError("Already there is an active task dialog.\n")
Diskussion im FreeCAD-Forum: Macro Packages