From 01f606fe31b4096c410d473c4ac61bbb3bfcfabc Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Wed, 8 Sep 2021 18:55:25 +0200 Subject: [PATCH 001/111] initial wip --- openpype/modules/base.py | 1 - .../default_modules/royal_render/__init__.py | 0 .../plugins/collect_default_rr_path.py | 23 +++++++++ .../plugins/collect_rr_path_from_instance.py | 49 +++++++++++++++++++ .../royal_render/royal_render_module.py | 27 ++++++++++ 5 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 openpype/modules/default_modules/royal_render/__init__.py create mode 100644 openpype/modules/default_modules/royal_render/plugins/collect_default_rr_path.py create mode 100644 openpype/modules/default_modules/royal_render/plugins/collect_rr_path_from_instance.py create mode 100644 openpype/modules/default_modules/royal_render/royal_render_module.py diff --git a/openpype/modules/base.py b/openpype/modules/base.py index 01c3cebe60..2e4b042a4c 100644 --- a/openpype/modules/base.py +++ b/openpype/modules/base.py @@ -417,7 +417,6 @@ class OpenPypeModule: """ pass - @abstractmethod def connect_with_modules(self, enabled_modules): """Connect with other enabled modules.""" pass diff --git a/openpype/modules/default_modules/royal_render/__init__.py b/openpype/modules/default_modules/royal_render/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/openpype/modules/default_modules/royal_render/plugins/collect_default_rr_path.py b/openpype/modules/default_modules/royal_render/plugins/collect_default_rr_path.py new file mode 100644 index 0000000000..cdca03bef0 --- /dev/null +++ b/openpype/modules/default_modules/royal_render/plugins/collect_default_rr_path.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +"""Collect default Deadline server.""" +import pyblish.api + + +class CollectDefaultRRPath(pyblish.api.ContextPlugin): + """Collect default Royal Render path.""" + + order = pyblish.api.CollectorOrder + 0.01 + label = "Default Royal Render Path" + + def process(self, context): + try: + rr_module = context.data.get( + "openPypeModules")["royalrender"] + except AttributeError: + msg = "Cannot get OpenPype Royal Render module." + self.log.error(msg) + raise AssertionError(msg) + + # get default deadline webservice url from deadline module + self.log.debug(rr_module.rr_paths) + context.data["defaultRRPath"] = rr_module.rr_paths["default"] # noqa: E501 diff --git a/openpype/modules/default_modules/royal_render/plugins/collect_rr_path_from_instance.py b/openpype/modules/default_modules/royal_render/plugins/collect_rr_path_from_instance.py new file mode 100644 index 0000000000..939b7c6e00 --- /dev/null +++ b/openpype/modules/default_modules/royal_render/plugins/collect_rr_path_from_instance.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +import pyblish.api + + +class CollectRRPathFromInstance(pyblish.api.InstancePlugin): + """Collect RR Path from instance.""" + + order = pyblish.api.CollectorOrder + label = "Deadline Webservice from the Instance" + families = ["rendering"] + + def process(self, instance): + instance.data["rrPath"] = self._collect_rr_path(instance) + self.log.info( + "Using {} for submission.".format(instance.data["rrPath"])) + + @staticmethod + def _collect_rr_path(render_instance): + # type: (pyblish.api.Instance) -> str + """Get Royal Render path from render instance.""" + rr_settings = ( + render_instance.context.data + ["system_settings"] + ["modules"] + ["royalrender"] + ) + try: + default_servers = rr_settings["rr_paths"] + project_servers = ( + render_instance.context.data + ["project_settings"] + ["royalrender"] + ["rr_paths"] + ) + rr_servers = { + k: default_servers[k] + for k in project_servers + if k in default_servers + } + + except AttributeError: + # Handle situation were we had only one url for deadline. + return render_instance.context.data["defaultRRPath"] + + return rr_servers[ + list(rr_servers.keys())[ + int(render_instance.data.get("rrPaths")) + ] + ] diff --git a/openpype/modules/default_modules/royal_render/royal_render_module.py b/openpype/modules/default_modules/royal_render/royal_render_module.py new file mode 100644 index 0000000000..1c34c4aef2 --- /dev/null +++ b/openpype/modules/default_modules/royal_render/royal_render_module.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +"""Module providing support for Royal Render.""" +import os +from openpype.modules import OpenPypeModule +from openpype_interfaces import IPluginPaths + + +class RoyalRenderModule(OpenPypeModule, IPluginPaths): + """Class providing basic Royal Render implementation logic.""" + name = "royalrender" + + def __init__(self, manager, settings): + self.rr_paths = {} + super(RoyalRenderModule, self).__init__(manager, settings) + + def initialize(self, module_settings): + rr_settings = module_settings[self.name] + self.enabled = rr_settings["enabled"] + self.rr_paths = rr_settings.get("rr_paths") + + @staticmethod + def get_plugin_paths(self): + """Deadline plugin paths.""" + current_dir = os.path.dirname(os.path.abspath(__file__)) + return { + "publish": [os.path.join(current_dir, "plugins", "publish")] + } From a89afdbc0706f8b42f8b7ac34b908598a94020f5 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Fri, 10 Sep 2021 23:36:12 +0200 Subject: [PATCH 002/111] define rr job attributes --- .../default_modules/royal_render/rr_job.py | 246 ++++++++++++++++++ 1 file changed, 246 insertions(+) create mode 100644 openpype/modules/default_modules/royal_render/rr_job.py diff --git a/openpype/modules/default_modules/royal_render/rr_job.py b/openpype/modules/default_modules/royal_render/rr_job.py new file mode 100644 index 0000000000..f72af5cc6c --- /dev/null +++ b/openpype/modules/default_modules/royal_render/rr_job.py @@ -0,0 +1,246 @@ +# -*- coding: utf-8 -*- +"""Python wrapper for RoyalRender XML job file.""" +import xml +from xml.dom import minidom as md +import attr +from collections import namedtuple, OrderedDict + + +CustomAttribute = namedtuple("CustomAttribute", ["name", "value"]) + + +@attr.s +class RRJob: + """Mapping of Royal Render job file to a data class.""" + + # Required + # -------- + + # Name of your render application. Same as in the render config file. + # (Maya, Softimage) + Software = attr.ib() # type: str + + # The OS the scene was created on, all texture paths are set on + # that OS. Possible values are windows, linux, osx + SceneOS = attr.ib() # type: str + + # Renderer you use. Same as in the render config file + # (VRay, Mental Ray, Arnold) + Renderer = attr.ib() # type: str + + # Version you want to render with. (5.11, 2010, 12) + Version = attr.ib() # type: str + + # Name of the scene file with full path. + SceneName = attr.ib() # type: str + + # Is the job enabled for submission? + # enabled by default + IsActive = attr.ib() # type: str + + # Sequence settings of this job + SeqStart = attr.ib() # type: int + SeqEnd = attr.ib() # type: int + SeqStep = attr.ib() # type: int + SeqFileOffset = attr.ib() # type: int + + # If you specify ImageDir, then ImageFilename has no path. If you do + # NOT specify ImageDir, then ImageFilename has to include the path. + # Same for ImageExtension. + # Important: Do not forget any _ or . in front or after the frame + # numbering. Usually ImageExtension always starts with a . (.tga, .exr) + ImageDir = attr.ib() # type: str + ImageFilename = attr.ib() # type: str + ImageExtension = attr.ib() # type: str + + # Some applications always add a . or _ in front of the frame number. + # Set this variable to that character. The user can then change + # the filename at the rrSubmitter and the submitter keeps + # track of this character. + ImagePreNumberLetter = attr.ib() # type: str + + # If you render a single file, e.g. Quicktime or Avi, then you have to + # set this value. Videos have to be rendered at once on one client. + ImageSingleOutputFile = attr.ib(default="false") # type: str + + # Semi-Required (required for some render applications) + # ----------------------------------------------------- + + # The database of your scene file. In Maya and XSI called "project", + # in Lightwave "content dir" + SceneDatabaseDir = attr.ib(default=None) # type: str + + # Required if you want to split frames on multiple clients + ImageWidth = attr.ib(default=None) # type: int + ImageHeight = attr.ib(default=None) # type: int + Camera = attr.ib(default=None) # type: str + Layer = attr.ib(default=None) # type: str + Channel = attr.ib(default=None) # type: str + + # Optional + # -------- + + # Used for the RR render license function. + # E.g. If you render with mentalRay, then add mentalRay. If you render + # with Nuke and you use Furnace plugins in your comp, add Furnace. + # TODO: determine how this work for multiple plugins + RequiredPlugins = attr.ib(default=None) # type: str + + # Frame Padding of the frame number in the rendered filename. + # Some render config files are setting the padding at render time. + ImageFramePadding = attr.ib(default=None) # type: str + + # Some render applications support overriding the image format at + # the render commandline. + OverrideImageFormat = attr.ib(default=None) # type: str + + # rrControl can display the name of additonal channels that are + # rendered. Each channel requires these two values. ChannelFilename + # contains the full path. + ChannelFilename = attr.ib(default=None) # type: str + ChannelExtension = attr.ib(default=None) # type: str + + # A value between 0 and 255. Each job gets the Pre ID attached as small + # letter to the main ID. A new main ID is generated for every machine + # for every 5/1000s. + PreID = attr.ib(default=None) # type: int + + # When the job is received by the server, the server checks for other + # jobs send from this machine. If a job with the PreID was found, then + # this jobs waits for the other job. Note: This flag can be used multiple + # times to wait for multiple jobs. + WaitForPreID = attr.ib(default=None) # type: int + + # List of submitter options per job + # list item must be of `SubmitterParameter` type + SubmitterParameters = attr.ib(factory=list) # type: list + + # List of Custom job attributes + # Royal Render support custom attributes in format or + # + # list item must be of `CustomAttribute` named tuple + CustomAttributes = attr.ib(factory=list) # type: list + + # Additional information for subsequent publish script and + # for better display in rrControl + UserName = attr.ib(default=None) # type: str + CustomSeQName = attr.ib(default=None) # type: str + CustomSHotName = attr.ib(default=None) # type: str + CustomVersionName = attr.ib(default=None) # type: str + CustomUserInfo = attr.ib(default=None) # type: str + SubmitMachine = attr.ib(default=None) # type: str + Color_ID = attr.ib(default=2) # type: int + + RequiredLicenses = attr.ib(default=None) # type: str + + # Additional frame info + Priority = attr.ib(default=50) # type: int + TotalFrames = attr.ib(default=None) # type: int + Tiled = attr.ib(default=None) # type: str + + +class SubmitterParameter: + + def __init__(self, parameter, *args): + # type: (str, list) -> None + self._parameter = parameter + self._values = args + + def serialize(self): + # type: () -> str + return '"{param}={val}"'.format( + param=self._parameter, val="~".join(self._values)) + + +@attr.s +class SubmitFile: + """Class wrapping Royal Render submission XML file.""" + + # Syntax version of the submission file. + syntax_version = attr.ib(default="6.0") # type: str + + # Delete submission file after processing + DeleteXML = attr.ib(default=1) # type: int + + # List of submitter options per job + # list item must be of `SubmitterParameter` type + SubmitterParameters = attr.ib(factory=list) # type: list + + # List of job is submission batch. + # list item must be of type `RRJob` + Jobs = attr.ib(factory=list) # type: list + + @staticmethod + def _process_submitter_parameters(parameters, dom, append_to): + # type: (list, md.Document, md.Element) -> None + """Take list of :class:`SubmitterParameter` and process it as XML. + + This will take :class:`SubmitterParameter`, create XML element + for them and convert value to Royal Render compatible string + (options and values separated by ~) + + Args: + parameters (list of SubmitterParameter): List of parameters. + dom (xml.dom.minidom.Document): XML Document + append_to (xml.dom.minidom.Element): Element to append to. + + """ + for param in parameters: + if not isinstance(param, SubmitterParameter): + raise AttributeError( + "{} is not of type `SubmitterParameter`".format(param)) + xml_parameter = dom.createElement("SubmitterParameter") + xml_parameter.appendChild(dom.createTextNode(param.serialize())) + append_to.appendChild(xml_parameter) + + def serialize(self): + # type: () -> str + """Return all data serialized as XML. + + Returns: + str: XML data as string. + + """ + def filter_data(a, v): + if a.name.startswith("_"): + return False + if v is None: + return False + return True + + root = md.Document() + job_file = root.createElement('RR_Job_File') + job_file.setAttribute("syntax_version", self.syntax_version) + + # handle Submitter Parameters for batch + self._process_submitter_parameters( + self.SubmitterParameters, root, job_file) + + for job in self.Jobs: # type: RRJob + if not isinstance(job, RRJob): + raise AttributeError( + "{} is not of type `SubmitterParameter`".format(job)) + xml_job = root.createElement("Job") + # handle Submitter Parameters for job + self._process_submitter_parameters( + job.SubmitterParameters, root, xml_job + ) + job_custom_attributes = job.CustomAttributes + + serialized_job = attr.asdict( + job, dict_factory=OrderedDict, filter=filter_data) + serialized_job.pop("CustomAttributes") + serialized_job.pop("SubmitterParameters") + + for custom_attr in job_custom_attributes: # type: CustomAttribute + serialized_job["Custom{}".format( + custom_attr.name)] = custom_attr.value + + for item, value in serialized_job.items(): + xml_attr = root.create(item) + xml_attr.appendChild( + root.createTextNode(value) + ) + xml_job.appendChild(xml_attr) + + return root.toprettyxml(indent="\t") From 594daa27d546d5ba1a0f2765d6e1421a9ecb13b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Samohel?= Date: Tue, 14 Sep 2021 10:18:35 +0200 Subject: [PATCH 003/111] add rr api --- openpype/modules/default_modules/royal_render/api.py | 12 ++++++++++++ .../royal_render/royal_render_module.py | 11 +++++++++++ .../default_modules/royal_render/test_rr_job.py | 10 ++++++++++ 3 files changed, 33 insertions(+) create mode 100644 openpype/modules/default_modules/royal_render/api.py create mode 100644 tests/openpype/modules/default_modules/royal_render/test_rr_job.py diff --git a/openpype/modules/default_modules/royal_render/api.py b/openpype/modules/default_modules/royal_render/api.py new file mode 100644 index 0000000000..7eda976caf --- /dev/null +++ b/openpype/modules/default_modules/royal_render/api.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- +from .rr_job import RRJob, SubmitFile + + +class Api: + + def create_submission(self, jobs, submitter_attributes): + """""" + raise NotImplementedError + + def add_job(self, job): + ... \ No newline at end of file diff --git a/openpype/modules/default_modules/royal_render/royal_render_module.py b/openpype/modules/default_modules/royal_render/royal_render_module.py index 1c34c4aef2..48862b6a45 100644 --- a/openpype/modules/default_modules/royal_render/royal_render_module.py +++ b/openpype/modules/default_modules/royal_render/royal_render_module.py @@ -8,6 +8,16 @@ from openpype_interfaces import IPluginPaths class RoyalRenderModule(OpenPypeModule, IPluginPaths): """Class providing basic Royal Render implementation logic.""" name = "royalrender" + _api = None + + @property + def api(self): + if not self._api: + # import royal render modules + from . import api as rr_api + self._api = rr_api.Api() + + return self._api def __init__(self, manager, settings): self.rr_paths = {} @@ -25,3 +35,4 @@ class RoyalRenderModule(OpenPypeModule, IPluginPaths): return { "publish": [os.path.join(current_dir, "plugins", "publish")] } + diff --git a/tests/openpype/modules/default_modules/royal_render/test_rr_job.py b/tests/openpype/modules/default_modules/royal_render/test_rr_job.py new file mode 100644 index 0000000000..deab32c29b --- /dev/null +++ b/tests/openpype/modules/default_modules/royal_render/test_rr_job.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +"""Test suite for User Settings.""" +import pytest +from openpype.modules import ModulesManager + + +def test_rr_job(): + manager = ModulesManager() + rr_module = manager.modules_by_name["royalrender"] + From 9aaceef4110253d1032726702df048739b99781b Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Wed, 15 Sep 2021 00:03:21 +0200 Subject: [PATCH 004/111] wip on api --- .../default_modules/royal_render/api.py | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/openpype/modules/default_modules/royal_render/api.py b/openpype/modules/default_modules/royal_render/api.py index 7eda976caf..02a4dd3e48 100644 --- a/openpype/modules/default_modules/royal_render/api.py +++ b/openpype/modules/default_modules/royal_render/api.py @@ -1,12 +1,26 @@ # -*- coding: utf-8 -*- +"""Wrapper around Royal Render API.""" from .rr_job import RRJob, SubmitFile class Api: - def create_submission(self, jobs, submitter_attributes): - """""" + def create_submission(self, jobs, submitter_attributes, file_name=None): + # type: (list, list, str) -> SubmitFile + """Create jobs submission file. + + Args: + jobs (list): List of :class:`RRJob` + submitter_attributes (list): List of submitter attributes + :class:`SubmitterParameter` for whole submission batch. + file_name (str), optional): File path to write data to. + + Returns: + str: XML data of job submission files. + + """ raise NotImplementedError - def add_job(self, job): - ... \ No newline at end of file + def send_job_file(self, submit_file): + # type: (str) -> None + ... From bc08d06d5ce3b584ff9304d416635c2992a6c237 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Wed, 15 Sep 2021 19:05:19 +0200 Subject: [PATCH 005/111] add api support --- .../default_modules/royal_render/api.py | 138 +++++++++++++++++- .../royal_render/royal_render_module.py | 14 +- .../default_modules/royal_render/rr_job.py | 15 +- 3 files changed, 159 insertions(+), 8 deletions(-) diff --git a/openpype/modules/default_modules/royal_render/api.py b/openpype/modules/default_modules/royal_render/api.py index 02a4dd3e48..59f6eeb1ff 100644 --- a/openpype/modules/default_modules/royal_render/api.py +++ b/openpype/modules/default_modules/royal_render/api.py @@ -1,12 +1,69 @@ # -*- coding: utf-8 -*- """Wrapper around Royal Render API.""" -from .rr_job import RRJob, SubmitFile +import sys +import os +from xml.dom import minidom + +from openpype.settings import get_project_settings +from openpype.lib.local_settings import OpenPypeSettingsRegistry +from openpype.lib import PypeLogger +from .rr_job import RRJob, SubmitFile, SubmitterParameter + + +log = PypeLogger.get_logger("RoyalRender") class Api: + _settings = None + RR_SUBMIT_CONSOLE = 1 + RR_SUBMIT_API = 2 + + def __init__(self, settings): + self._settings = settings + + def initialize_rr_modules(self, project=None): + # type: (str) -> None + + is_64bit_python = sys.maxsize > 2 ** 32 + if project: + project_settings = get_project_settings(project) + rr_path = ( + project_settings + ["royalrender"] + ["rr_paths"] + ) + else: + rr_path = ( + self._settings + ["modules"] + ["royalrender"] + ["rr_path"] + ["default"] + ) + + # default for linux + rr_module_path = "/bin/lx64/lib" + + if sys.platform.lower() == "win32": + rr_module_path = "/bin/win64" + if not is_64bit_python: + # we are using 64bit python + rr_module_path = "/bin/win" + rr_module_path = rr_module_path.replace( + "/", os.path.sep + ) + + if sys.platform.lower() == "darwin": + rr_module_path = "/bin/mac64/lib/python/27" + if not is_64bit_python: + rr_module_path = "/bin/mac/lib/python/27" + + sys.path.append(os.path.join(rr_path, rr_module_path)) + os.environ["RR_ROOT"] = rr_path + def create_submission(self, jobs, submitter_attributes, file_name=None): - # type: (list, list, str) -> SubmitFile + # type: (list[RRJob], list[SubmitterParameter], str) -> SubmitFile """Create jobs submission file. Args: @@ -21,6 +78,79 @@ class Api: """ raise NotImplementedError - def send_job_file(self, submit_file): - # type: (str) -> None + def submit_file(self, file, mode=RR_SUBMIT_CONSOLE): + # type: (SubmitFile, int) -> None + if mode == self.RR_SUBMIT_CONSOLE: + self._submit_using_console(file) + + # RR v7 supports only Python 2.7 so we bail out in fear + # until there is support for Python 3 😰 + raise NotImplementedError( + "Submission via RoyalRender API is not supported yet") + # self._submit_using_api(file) + + def _submit_using_console(self, file): + # type: (SubmitFile) -> bool ... + + def _submit_using_api(self, file): + # type: (SubmitFile) -> None + """Use RR API to submit jobs. + + Args: + file (SubmitFile): Submit jobs definition. + + Throws: + RoyalRenderException: When something fails. + + """ + self.initialize_rr_modules() + + import libpyRR2 as rrLib + from rrJob import getClass_JobBasics + import libpyRR2 as _RenderAppBasic + + tcp = rrLib._rrTCP("") + rr_server = tcp.getRRServer() + + if len(rr_server) == 0: + log.info("Got RR IP address {}".format(rr_server)) + + # TODO: Port is hardcoded in RR? If not, move it to Settings + if not tcp.setServer(rr_server, 7773): + log.error( + "Can not set RR server: {}".format(tcp.errorMessage())) + raise RoyalRenderException(tcp.errorMessage()) + + # TODO: This need UI and better handling of username/password. + # We can't store password in keychain as it is pulled multiple + # times and users on linux must enter keychain password every time. + # Probably best way until we setup our own user management would be + # to encrypt password and save it to json locally. Not bulletproof + # but at least it is not stored in plaintext. + reg = OpenPypeSettingsRegistry() + try: + rr_user = reg.get_item("rr_username") + rr_password = reg.get_item("rr_password") + except ValueError: + # user has no rr credentials set + pass + else: + # login to RR + tcp.setLogin(rr_user, rr_password) + + job = getClass_JobBasics() + renderer = _RenderAppBasic() + + # iterate over SubmitFile, set _JobBasic (job) and renderer + # and feed it to jobSubmitNew() + # not implemented yet + + job.renderer = renderer + + tcp.jobSubmitNew(job) + + +class RoyalRenderException(Exception): + """Exception used in various error states coming from RR.""" + pass diff --git a/openpype/modules/default_modules/royal_render/royal_render_module.py b/openpype/modules/default_modules/royal_render/royal_render_module.py index 48862b6a45..e49ff9a487 100644 --- a/openpype/modules/default_modules/royal_render/royal_render_module.py +++ b/openpype/modules/default_modules/royal_render/royal_render_module.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- """Module providing support for Royal Render.""" import os +import openpype.modules from openpype.modules import OpenPypeModule from openpype_interfaces import IPluginPaths @@ -9,28 +10,37 @@ class RoyalRenderModule(OpenPypeModule, IPluginPaths): """Class providing basic Royal Render implementation logic.""" name = "royalrender" _api = None + settings = None @property def api(self): if not self._api: # import royal render modules from . import api as rr_api - self._api = rr_api.Api() + self._api = rr_api.Api(self.settings) return self._api def __init__(self, manager, settings): + # type: (openpype.modules.base.ModulesManager, dict) -> None self.rr_paths = {} + self.settings = settings super(RoyalRenderModule, self).__init__(manager, settings) def initialize(self, module_settings): + # type: (dict) -> None rr_settings = module_settings[self.name] self.enabled = rr_settings["enabled"] self.rr_paths = rr_settings.get("rr_paths") @staticmethod def get_plugin_paths(self): - """Deadline plugin paths.""" + # type: (None) -> dict + """Royal Render plugin paths. + + Returns: + dict: Dictionary of plugin paths for RR. + """ current_dir = os.path.dirname(os.path.abspath(__file__)) return { "publish": [os.path.join(current_dir, "plugins", "publish")] diff --git a/openpype/modules/default_modules/royal_render/rr_job.py b/openpype/modules/default_modules/royal_render/rr_job.py index f72af5cc6c..8cf7dac007 100644 --- a/openpype/modules/default_modules/royal_render/rr_job.py +++ b/openpype/modules/default_modules/royal_render/rr_job.py @@ -140,7 +140,7 @@ class RRJob: class SubmitterParameter: - + """Wrapper for Submitter Parameters.""" def __init__(self, parameter, *args): # type: (str, list) -> None self._parameter = parameter @@ -148,6 +148,14 @@ class SubmitterParameter: def serialize(self): # type: () -> str + """Serialize submitter parameter as a string value. + + This can be later on used as text node in job xml file. + + Returns: + str: concatenated string of parameter values. + + """ return '"{param}={val}"'.format( param=self._parameter, val="~".join(self._values)) @@ -172,7 +180,7 @@ class SubmitFile: @staticmethod def _process_submitter_parameters(parameters, dom, append_to): - # type: (list, md.Document, md.Element) -> None + # type: (list[SubmitterParameter], md.Document, md.Element) -> None """Take list of :class:`SubmitterParameter` and process it as XML. This will take :class:`SubmitterParameter`, create XML element @@ -202,6 +210,7 @@ class SubmitFile: """ def filter_data(a, v): + """Skip private attributes.""" if a.name.startswith("_"): return False if v is None: @@ -209,10 +218,12 @@ class SubmitFile: return True root = md.Document() + # root element: job_file = root.createElement('RR_Job_File') job_file.setAttribute("syntax_version", self.syntax_version) # handle Submitter Parameters for batch + # foo=bar~baz~goo self._process_submitter_parameters( self.SubmitterParameters, root, job_file) From 9e479c30b03ed5693df8aa51da9fbc53f47edc2a Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Thu, 23 Sep 2021 13:37:32 +0200 Subject: [PATCH 006/111] fix hound --- openpype/modules/default_modules/royal_render/api.py | 1 - .../default_modules/royal_render/royal_render_module.py | 1 - openpype/modules/default_modules/royal_render/rr_job.py | 1 - .../modules/default_modules/royal_render/test_rr_job.py | 9 +++++---- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/openpype/modules/default_modules/royal_render/api.py b/openpype/modules/default_modules/royal_render/api.py index 59f6eeb1ff..7e651fe051 100644 --- a/openpype/modules/default_modules/royal_render/api.py +++ b/openpype/modules/default_modules/royal_render/api.py @@ -2,7 +2,6 @@ """Wrapper around Royal Render API.""" import sys import os -from xml.dom import minidom from openpype.settings import get_project_settings from openpype.lib.local_settings import OpenPypeSettingsRegistry diff --git a/openpype/modules/default_modules/royal_render/royal_render_module.py b/openpype/modules/default_modules/royal_render/royal_render_module.py index e49ff9a487..3c67cab514 100644 --- a/openpype/modules/default_modules/royal_render/royal_render_module.py +++ b/openpype/modules/default_modules/royal_render/royal_render_module.py @@ -45,4 +45,3 @@ class RoyalRenderModule(OpenPypeModule, IPluginPaths): return { "publish": [os.path.join(current_dir, "plugins", "publish")] } - diff --git a/openpype/modules/default_modules/royal_render/rr_job.py b/openpype/modules/default_modules/royal_render/rr_job.py index 8cf7dac007..c660eceac7 100644 --- a/openpype/modules/default_modules/royal_render/rr_job.py +++ b/openpype/modules/default_modules/royal_render/rr_job.py @@ -1,6 +1,5 @@ # -*- coding: utf-8 -*- """Python wrapper for RoyalRender XML job file.""" -import xml from xml.dom import minidom as md import attr from collections import namedtuple, OrderedDict diff --git a/tests/openpype/modules/default_modules/royal_render/test_rr_job.py b/tests/openpype/modules/default_modules/royal_render/test_rr_job.py index deab32c29b..a0e2c24671 100644 --- a/tests/openpype/modules/default_modules/royal_render/test_rr_job.py +++ b/tests/openpype/modules/default_modules/royal_render/test_rr_job.py @@ -1,10 +1,11 @@ # -*- coding: utf-8 -*- """Test suite for User Settings.""" -import pytest -from openpype.modules import ModulesManager +# import pytest +# from openpype.modules import ModulesManager def test_rr_job(): - manager = ModulesManager() - rr_module = manager.modules_by_name["royalrender"] + # manager = ModulesManager() + # rr_module = manager.modules_by_name["royalrender"] + ... From 85546bcbe3ee5f75c8aab08be6397b0326f6f4e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Samohel?= Date: Wed, 13 Oct 2021 11:26:41 +0200 Subject: [PATCH 007/111] run rrSubmitterconsole with job file --- .../default_modules/royal_render/api.py | 88 ++++++++++++++----- 1 file changed, 66 insertions(+), 22 deletions(-) diff --git a/openpype/modules/default_modules/royal_render/api.py b/openpype/modules/default_modules/royal_render/api.py index 7e651fe051..ed9e71f240 100644 --- a/openpype/modules/default_modules/royal_render/api.py +++ b/openpype/modules/default_modules/royal_render/api.py @@ -5,7 +5,7 @@ import os from openpype.settings import get_project_settings from openpype.lib.local_settings import OpenPypeSettingsRegistry -from openpype.lib import PypeLogger +from openpype.lib import PypeLogger, run_subprocess from .rr_job import RRJob, SubmitFile, SubmitterParameter @@ -18,13 +18,19 @@ class Api: RR_SUBMIT_CONSOLE = 1 RR_SUBMIT_API = 2 - def __init__(self, settings): + def __init__(self, settings, project=None): self._settings = settings + self._initialize_rr(project) - def initialize_rr_modules(self, project=None): + def _initialize_rr(self, project=None): # type: (str) -> None + """Initialize RR Path. - is_64bit_python = sys.maxsize > 2 ** 32 + Args: + project (str, Optional): Project name to set RR api in + context. + + """ if project: project_settings = get_project_settings(project) rr_path = ( @@ -40,26 +46,52 @@ class Api: ["rr_path"] ["default"] ) + os.environ["RR_ROOT"] = rr_path + self._rr_path = rr_path - # default for linux - rr_module_path = "/bin/lx64/lib" + def _get_rr_bin_path(self, rr_root=None): + # type: (str) -> str + """Get path to RR bin folder.""" + rr_root = rr_root or self._rr_path + is_64bit_python = sys.maxsize > 2 ** 32 + rr_bin_path = "" if sys.platform.lower() == "win32": - rr_module_path = "/bin/win64" + rr_bin_path = "/bin/win64" if not is_64bit_python: # we are using 64bit python - rr_module_path = "/bin/win" + rr_bin_path = "/bin/win" + rr_bin_path = rr_bin_path.replace( + "/", os.path.sep + ) + + if sys.platform.lower() == "darwin": + rr_bin_path = "/bin/mac64" + if not is_64bit_python: + rr_bin_path = "/bin/mac" + + if sys.platform.lower() == "linux": + rr_bin_path = "/bin/lx64" + + return os.path.join(rr_root, rr_bin_path) + + def _initialize_module_path(self): + # type: () -> None + """Set RR modules for Python.""" + # default for linux + rr_bin = self._get_rr_bin_path() + rr_module_path = os.path.join(rr_bin, "lx64/lib") + + if sys.platform.lower() == "win32": + rr_module_path = rr_bin rr_module_path = rr_module_path.replace( "/", os.path.sep ) if sys.platform.lower() == "darwin": - rr_module_path = "/bin/mac64/lib/python/27" - if not is_64bit_python: - rr_module_path = "/bin/mac/lib/python/27" + rr_module_path = os.path.join(rr_bin, "lib/python/27") - sys.path.append(os.path.join(rr_path, rr_module_path)) - os.environ["RR_ROOT"] = rr_path + sys.path.append(os.path.join(self._rr_path, rr_module_path)) def create_submission(self, jobs, submitter_attributes, file_name=None): # type: (list[RRJob], list[SubmitterParameter], str) -> SubmitFile @@ -90,7 +122,22 @@ class Api: def _submit_using_console(self, file): # type: (SubmitFile) -> bool - ... + rr_console = os.path.join( + self._get_rr_bin_path(), + "rrSubmitterconsole" + ) + + if sys.platform.lower() == "darwin": + if "/bin/mac64" in rr_console: + rr_console = rr_console.replace("/bin/mac64", "/bin/mac") + + if sys.platform.lower() == "win32": + if "/bin/win64" in rr_console: + rr_console = rr_console.replace("/bin/win64", "/bin/win") + rr_console += ".exe" + + args = [rr_console, file] + run_subprocess(" ".join(args), logger=log) def _submit_using_api(self, file): # type: (SubmitFile) -> None @@ -103,13 +150,12 @@ class Api: RoyalRenderException: When something fails. """ - self.initialize_rr_modules() + self._initialize_module_path() + import libpyRR2 as rrLib # noqa + from rrJob import getClass_JobBasics # noqa + import libpyRR2 as _RenderAppBasic # noqa - import libpyRR2 as rrLib - from rrJob import getClass_JobBasics - import libpyRR2 as _RenderAppBasic - - tcp = rrLib._rrTCP("") + tcp = rrLib._rrTCP("") # noqa rr_server = tcp.getRRServer() if len(rr_server) == 0: @@ -144,9 +190,7 @@ class Api: # iterate over SubmitFile, set _JobBasic (job) and renderer # and feed it to jobSubmitNew() # not implemented yet - job.renderer = renderer - tcp.jobSubmitNew(job) From 0ae584a2a9429aad9a503124f604c41f3726b6e7 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Fri, 22 Oct 2021 17:03:20 +0200 Subject: [PATCH 008/111] add stub for hierarchy browser --- openpype/cli.py | 6 ++ .../perjob/m55__openpype_publish_render.py | 99 +++++++++++++++++++ openpype/pype_commands.py | 3 + openpype/tools/hierarchy_browser/__init__.py | 0 openpype/tools/hierarchy_browser/__main__.py | 10 ++ openpype/tools/hierarchy_browser/app.py | 0 6 files changed, 118 insertions(+) create mode 100644 openpype/modules/default_modules/royal_render/rr_root/plugins/plugins/control_job/perjob/m55__openpype_publish_render.py create mode 100644 openpype/tools/hierarchy_browser/__init__.py create mode 100644 openpype/tools/hierarchy_browser/__main__.py create mode 100644 openpype/tools/hierarchy_browser/app.py diff --git a/openpype/cli.py b/openpype/cli.py index c69407e295..d6d9cbacd4 100644 --- a/openpype/cli.py +++ b/openpype/cli.py @@ -298,3 +298,9 @@ def run(script): def runtests(folder, mark, pyargs): """Run all automatic tests after proper initialization via start.py""" PypeCommands().run_tests(folder, mark, pyargs) + + +@main.command() +def context_selector(): + """Show widget to show context selector.""" + PypeCommands().show_context_selector() diff --git a/openpype/modules/default_modules/royal_render/rr_root/plugins/plugins/control_job/perjob/m55__openpype_publish_render.py b/openpype/modules/default_modules/royal_render/rr_root/plugins/plugins/control_job/perjob/m55__openpype_publish_render.py new file mode 100644 index 0000000000..eb8f137a05 --- /dev/null +++ b/openpype/modules/default_modules/royal_render/rr_root/plugins/plugins/control_job/perjob/m55__openpype_publish_render.py @@ -0,0 +1,99 @@ +# -*- coding: utf-8 -*- +"""This is RR control plugin that runs on the job by user interaction. + +It asks user for context to publish, getting it from OpenPype. In order to +run it needs `OPENPYPE_ROOT` to be set to know where to execute OpenPype. + +""" +import rr # noqa +import rrGlobal # noqa +import subprocess +import os +import glob +import platform + + +class OpenPypeContextSelector: + """Class to handle publishing context determination in RR.""" + + def __init__(self): + self.job = rr.getJob() + self.context = None + + op_path = os.environ.get("OPENPYPE_ROOT") + if not op_path: + print("Warning: OpenPype root is not found.") + + if platform.system().lower() == "windows": + print(" * trying to find OpenPype on local computer.") + op_path = os.path.join( + os.environ.get("PROGRAMFILES"), + "OpenPype", "openpype_console.exe" + ) + if os.path.exists(op_path): + print(" - found OpenPype installation {}".format(op_path)) + else: + # try to find in user local context + op_path = os.path.join( + os.environ.get("LOCALAPPDATA"), + "Programs" + "OpenPype", "openpype_console.exe" + ) + if os.path.exists(op_path): + print( + " - found OpenPype installation {}".format( + op_path)) + else: + print("Error: OpenPype was not found.") + op_path = None + + self.openpype_root = op_path + + # TODO: this should try to find metadata file. Either using + # jobs custom attributes or using environment variable + # or just using plain existence of file. + # self.context = self._process_metadata_file() + + def _process_metadata_file(self): + """Find and process metadata file. + + Try to find metadata json file in job folder to get context from. + + Returns: + dict: Context from metadata json file. + + """ + image_dir = self.job.imageDir + metadata_files = glob.glob( + "{}{}*_metadata.json".format(image_dir, os.path.sep)) + if not metadata_files: + return {} + + raise NotImplementedError( + "Processing existing metadata not implemented yet.") + + def process_job(self): + """Process selected job. + + This should process selected job. If context can be determined + automatically, no UI will be show and publishing will directly + proceed. + """ + if not self.context: + self.show() + + def show(self): + """Show UI for context selection. + + Because of RR UI limitations, this must be done using OpenPype + itself. + + """ + op_exec = "openpype_gui" + if platform.system().lower() == "windows": + op_exec = "openpype_gui.exe" + subprocess.check_output([self.openpype_root]) + + +selector = OpenPypeContextSelector() +selector.process_job() diff --git a/openpype/pype_commands.py b/openpype/pype_commands.py index 5288749e8b..69e17a0180 100644 --- a/openpype/pype_commands.py +++ b/openpype/pype_commands.py @@ -284,3 +284,6 @@ class PypeCommands: cmd = "pytest {} {} {}".format(folder, mark_str, pyargs_str) print("Running {}".format(cmd)) subprocess.run(cmd) + + def show_context_selector(self): + ... \ No newline at end of file diff --git a/openpype/tools/hierarchy_browser/__init__.py b/openpype/tools/hierarchy_browser/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/openpype/tools/hierarchy_browser/__main__.py b/openpype/tools/hierarchy_browser/__main__.py new file mode 100644 index 0000000000..ee23e9e1b6 --- /dev/null +++ b/openpype/tools/hierarchy_browser/__main__.py @@ -0,0 +1,10 @@ +if __name__ == "__main__": + import sys + from Qt import QtWidgets + + app = QtWidgets.QApplication([]) + + window = ProjectManagerWindow() + window.show() + + sys.exit(app.exec_()) \ No newline at end of file diff --git a/openpype/tools/hierarchy_browser/app.py b/openpype/tools/hierarchy_browser/app.py new file mode 100644 index 0000000000..e69de29bb2 From 96c2cc0f9099474fc1664d85710b95e36193ac52 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Mon, 25 Oct 2021 14:00:16 +0200 Subject: [PATCH 009/111] OP-1920 - create command for background running of Site Sync server WIP --- openpype/cli.py | 22 +++++++++++++++++++ .../sync_server/sync_server_module.py | 20 ++++++++++++----- openpype/pype_commands.py | 13 +++++++++++ 3 files changed, 50 insertions(+), 5 deletions(-) diff --git a/openpype/cli.py b/openpype/cli.py index c69407e295..a98ba8d177 100644 --- a/openpype/cli.py +++ b/openpype/cli.py @@ -298,3 +298,25 @@ def run(script): def runtests(folder, mark, pyargs): """Run all automatic tests after proper initialization via start.py""" PypeCommands().run_tests(folder, mark, pyargs) + + +@main.command() +@click.option("-d", "--debug", + is_flag=True, help=("Run process in debug mode")) +@click.option("-a", "--active_site", required=True, + help="Name of active stie") +@click.option("-r", "--remote_site", required=True, + help="Name of remote site") +def syncsiteserver(debug, active_site, remote_site): + """Run sync site server in background. + + Some Site Sync use cases need to expose site to another one. + For example if majority of artists work in studio, they are not using + SS at all, but if you want to expose published assets to 'studio' site + to SFTP for only a couple of artists, some background process must + mark published assets to live on multiple sites (they might be + physically in same location - mounted shared disk). + """ + if debug: + os.environ['OPENPYPE_DEBUG'] = '3' + PypeCommands().syncsiteserver(active_site, remote_site) \ No newline at end of file diff --git a/openpype/modules/default_modules/sync_server/sync_server_module.py b/openpype/modules/default_modules/sync_server/sync_server_module.py index f2e9237542..4bec626744 100644 --- a/openpype/modules/default_modules/sync_server/sync_server_module.py +++ b/openpype/modules/default_modules/sync_server/sync_server_module.py @@ -699,7 +699,11 @@ class SyncServerModule(OpenPypeModule, ITrayModule): Called when tray is initialized, it checks if module should be enabled. If not, no initialization necessary. """ - # import only in tray, because of Python2 hosts + self.server_init() + + def server_init(self): + """Actual initialization of Sync Server.""" + # import only in tray or Python3, because of Python2 hosts from .sync_server import SyncServerThread if not self.enabled: @@ -722,10 +726,10 @@ class SyncServerModule(OpenPypeModule, ITrayModule): self.enabled = False except KeyError: log.info(( - "There are not set presets for SyncServer OR " - "Credentials provided are invalid, " - "no syncing possible"). - format(str(self.sync_project_settings)), exc_info=True) + "There are not set presets for SyncServer OR " + "Credentials provided are invalid, " + "no syncing possible"). + format(str(self.sync_project_settings)), exc_info=True) self.enabled = False def tray_start(self): @@ -739,6 +743,9 @@ class SyncServerModule(OpenPypeModule, ITrayModule): Returns: None """ + self.server_start() + + def server_start(self): if self.sync_project_settings and self.enabled: self.sync_server_thread.start() else: @@ -751,6 +758,9 @@ class SyncServerModule(OpenPypeModule, ITrayModule): Called from Module Manager """ + self.server_exit() + + def server_exit(self): if not self.sync_server_thread: return diff --git a/openpype/pype_commands.py b/openpype/pype_commands.py index 5288749e8b..0a897e43e4 100644 --- a/openpype/pype_commands.py +++ b/openpype/pype_commands.py @@ -284,3 +284,16 @@ class PypeCommands: cmd = "pytest {} {} {}".format(folder, mark_str, pyargs_str) print("Running {}".format(cmd)) subprocess.run(cmd) + + def syncsiteserver(self, active_site, remote_site): + from openpype.modules import ModulesManager + + manager = ModulesManager() + sync_server_module = manager.modules_by_name["sync_server"] + + sync_server_module.init_server() + sync_server_module.start_server() + + import time + while True: + time.sleep(1.0) From 19b5d47b2494498d19701e1441ed1b0a05aa34a8 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Mon, 25 Oct 2021 16:46:45 +0200 Subject: [PATCH 010/111] OP-1920 - skip upload/download for same files --- .../default_modules/sync_server/providers/local_drive.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/openpype/modules/default_modules/sync_server/providers/local_drive.py b/openpype/modules/default_modules/sync_server/providers/local_drive.py index 8e5f170bc9..2961a07cdd 100644 --- a/openpype/modules/default_modules/sync_server/providers/local_drive.py +++ b/openpype/modules/default_modules/sync_server/providers/local_drive.py @@ -84,6 +84,7 @@ class LocalDriveHandler(AbstractProvider): if not os.path.isfile(source_path): raise FileNotFoundError("Source file {} doesn't exist." .format(source_path)) + if overwrite: thread = threading.Thread(target=self._copy, args=(source_path, target_path)) @@ -176,7 +177,10 @@ class LocalDriveHandler(AbstractProvider): def _copy(self, source_path, target_path): print("copying {}->{}".format(source_path, target_path)) - shutil.copy(source_path, target_path) + try: + shutil.copy(source_path, target_path) + except shutil.SameFileError: + print("same files, skipping") def _mark_progress(self, collection, file, representation, server, site, source_path, target_path, direction): From 421ac7716ea004c3738aa1c5ceb00518d05aa94d Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Mon, 25 Oct 2021 16:48:04 +0200 Subject: [PATCH 011/111] OP-1920 - override get_local_site_id from env var --- openpype/lib/local_settings.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/openpype/lib/local_settings.py b/openpype/lib/local_settings.py index 66dad279de..af8c3cdbc8 100644 --- a/openpype/lib/local_settings.py +++ b/openpype/lib/local_settings.py @@ -522,6 +522,11 @@ def get_local_site_id(): Identifier is created if does not exists yet. """ + # override local id from environment + # used for background syncing + if os.environ.get("SITE_SYNC_LOCAL_ID"): + return os.environ["SITE_SYNC_LOCAL_ID"] + registry = OpenPypeSettingsRegistry() try: return registry.get_item("localId") From 02b78dc7f8ec7a5c55e270156fef31f0f33ec8ff Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Mon, 25 Oct 2021 16:55:11 +0200 Subject: [PATCH 012/111] OP-1920 - added syncserver command --- openpype/cli.py | 11 +++++++---- openpype/pype_commands.py | 7 +++++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/openpype/cli.py b/openpype/cli.py index a98ba8d177..583fd6daac 100644 --- a/openpype/cli.py +++ b/openpype/cli.py @@ -305,9 +305,7 @@ def runtests(folder, mark, pyargs): is_flag=True, help=("Run process in debug mode")) @click.option("-a", "--active_site", required=True, help="Name of active stie") -@click.option("-r", "--remote_site", required=True, - help="Name of remote site") -def syncsiteserver(debug, active_site, remote_site): +def syncserver(debug, active_site): """Run sync site server in background. Some Site Sync use cases need to expose site to another one. @@ -316,7 +314,12 @@ def syncsiteserver(debug, active_site, remote_site): to SFTP for only a couple of artists, some background process must mark published assets to live on multiple sites (they might be physically in same location - mounted shared disk). + + Process mimics OP Tray with specific 'active_site' name, all + configuration for this "dummy" user comes from Setting or Local + Settings (configured by starting OP Tray with env + var SITE_SYNC_LOCAL_ID set to 'active_site'. """ if debug: os.environ['OPENPYPE_DEBUG'] = '3' - PypeCommands().syncsiteserver(active_site, remote_site) \ No newline at end of file + PypeCommands().syncserver(active_site) diff --git a/openpype/pype_commands.py b/openpype/pype_commands.py index 0a897e43e4..ed3fc5996b 100644 --- a/openpype/pype_commands.py +++ b/openpype/pype_commands.py @@ -285,13 +285,16 @@ class PypeCommands: print("Running {}".format(cmd)) subprocess.run(cmd) - def syncsiteserver(self, active_site, remote_site): + def syncserver(self, active_site): + """Start running sync_server in background.""" + os.environ["SITE_SYNC_LOCAL_ID"] = active_site + from openpype.modules import ModulesManager manager = ModulesManager() sync_server_module = manager.modules_by_name["sync_server"] - sync_server_module.init_server() + sync_server_module.server_init() sync_server_module.start_server() import time From a96b0b8d989d52a9a138859f1960c4f485c9c0af Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Mon, 25 Oct 2021 17:44:39 +0200 Subject: [PATCH 013/111] OP-1920 - fixes of names, tray not triggering --- .../default_modules/sync_server/sync_server_module.py | 7 ++++--- openpype/pype_commands.py | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/openpype/modules/default_modules/sync_server/sync_server_module.py b/openpype/modules/default_modules/sync_server/sync_server_module.py index 4bec626744..d8a69b3b07 100644 --- a/openpype/modules/default_modules/sync_server/sync_server_module.py +++ b/openpype/modules/default_modules/sync_server/sync_server_module.py @@ -694,13 +694,16 @@ class SyncServerModule(OpenPypeModule, ITrayModule): def tray_init(self): """ - Actual initialization of Sync Server. + Actual initialization of Sync Server for Tray. Called when tray is initialized, it checks if module should be enabled. If not, no initialization necessary. """ self.server_init() + from .tray.app import SyncServerWindow + self.widget = SyncServerWindow(self) + def server_init(self): """Actual initialization of Sync Server.""" # import only in tray or Python3, because of Python2 hosts @@ -719,8 +722,6 @@ class SyncServerModule(OpenPypeModule, ITrayModule): try: self.sync_server_thread = SyncServerThread(self) - from .tray.app import SyncServerWindow - self.widget = SyncServerWindow(self) except ValueError: log.info("No system setting for sync. Not syncing.", exc_info=True) self.enabled = False diff --git a/openpype/pype_commands.py b/openpype/pype_commands.py index ed3fc5996b..bb7ad152dc 100644 --- a/openpype/pype_commands.py +++ b/openpype/pype_commands.py @@ -295,7 +295,7 @@ class PypeCommands: sync_server_module = manager.modules_by_name["sync_server"] sync_server_module.server_init() - sync_server_module.start_server() + sync_server_module.server_start() import time while True: From 42119cfca19c09085d2e68615e468263df205b08 Mon Sep 17 00:00:00 2001 From: karimmozlia Date: Tue, 26 Oct 2021 14:58:38 +0200 Subject: [PATCH 014/111] disable maintain_aspect_ratio when width , height --- openpype/vendor/python/common/capture.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openpype/vendor/python/common/capture.py b/openpype/vendor/python/common/capture.py index 02d86952df..6b4c40a6e8 100644 --- a/openpype/vendor/python/common/capture.py +++ b/openpype/vendor/python/common/capture.py @@ -116,6 +116,8 @@ def capture(camera=None, if not cmds.objExists(camera): raise RuntimeError("Camera does not exist: {0}".format(camera)) + if width and height : + maintain_aspect_ratio = False width = width or cmds.getAttr("defaultResolution.width") height = height or cmds.getAttr("defaultResolution.height") if maintain_aspect_ratio: From be36900ffa037b4c98df70b87f68f4864e34a9aa Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Fri, 29 Oct 2021 13:55:47 +0200 Subject: [PATCH 015/111] OP-1920 - added always_accessible_on to Settings --- .../settings/defaults/project_settings/global.json | 1 + .../projects_schema/schema_project_syncserver.json | 13 +++++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/openpype/settings/defaults/project_settings/global.json b/openpype/settings/defaults/project_settings/global.json index 45c1a59d17..46e5574eb3 100644 --- a/openpype/settings/defaults/project_settings/global.json +++ b/openpype/settings/defaults/project_settings/global.json @@ -319,6 +319,7 @@ "config": { "retry_cnt": "3", "loop_delay": "60", + "always_accessible_on": [], "active_site": "studio", "remote_site": "studio" }, diff --git a/openpype/settings/entities/schemas/projects_schema/schema_project_syncserver.json b/openpype/settings/entities/schemas/projects_schema/schema_project_syncserver.json index 3211babd43..88ef2ed0c3 100644 --- a/openpype/settings/entities/schemas/projects_schema/schema_project_syncserver.json +++ b/openpype/settings/entities/schemas/projects_schema/schema_project_syncserver.json @@ -26,15 +26,24 @@ "key": "loop_delay", "label": "Loop Delay" }, + { + "type": "list", + "key": "always_accessible_on", + "label": "Always accessible on sites", + "object_type": "text" + }, + { + "type": "splitter" + }, { "type": "text", "key": "active_site", - "label": "Active Site" + "label": "User Default Active Site" }, { "type": "text", "key": "remote_site", - "label": "Remote Site" + "label": "User Default Remote Site" } ] }, From c69c15310fe1a55ffa9daf1410ad189ff125adb7 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Fri, 29 Oct 2021 14:02:24 +0200 Subject: [PATCH 016/111] OP-1920 - implemented always_accessible_on Needed when new representation is created to map wherever it needs to be synched in the end --- openpype/plugins/publish/integrate_new.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/openpype/plugins/publish/integrate_new.py b/openpype/plugins/publish/integrate_new.py index 451ea1d80d..fe780480c2 100644 --- a/openpype/plugins/publish/integrate_new.py +++ b/openpype/plugins/publish/integrate_new.py @@ -1028,6 +1028,7 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): """ local_site = 'studio' # default remote_site = None + always_accesible = [] sync_server_presets = None if (instance.context.data["system_settings"] @@ -1042,6 +1043,8 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): if sync_server_presets["enabled"]: local_site = sync_server_presets["config"].\ get("active_site", "studio").strip() + always_accesible = sync_server_presets["config"].\ + get("always_accessible_on", []) if local_site == 'local': local_site = local_site_id @@ -1072,6 +1075,12 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): meta = {"name": remote_site.strip()} rec["sites"].append(meta) + # add skeleton for site where it should be always synced to + for always_on_site in always_accesible: + if always_on_site not in [local_site, remote_site]: + meta = {"name": always_on_site.strip()} + rec["sites"].append(meta) + return rec def handle_destination_files(self, integrated_file_sizes, mode): From ba87f9bc09a14c30a0d9082c295d0803ba7f6219 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Fri, 29 Oct 2021 14:47:08 +0200 Subject: [PATCH 017/111] OP-1920 - added documentation --- website/docs/assets/site_sync_always_on.png | Bin 0 -> 27817 bytes website/docs/module_site_sync.md | 39 ++++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 website/docs/assets/site_sync_always_on.png diff --git a/website/docs/assets/site_sync_always_on.png b/website/docs/assets/site_sync_always_on.png new file mode 100644 index 0000000000000000000000000000000000000000..712adf173bc6049a2f55b7ff24d4d6cf09928ad3 GIT binary patch literal 27817 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 literal 0 HcmV?d00001 diff --git a/website/docs/module_site_sync.md b/website/docs/module_site_sync.md index b0604ed3cf..31854e2729 100644 --- a/website/docs/module_site_sync.md +++ b/website/docs/module_site_sync.md @@ -140,3 +140,42 @@ Beware that ssh key expects OpenSSH format (`.pem`) not a Putty format (`.ppk`)! If a studio needs to use other services for cloud storage, or want to implement totally different storage providers, they can do so by writing their own provider plugin. We're working on a developer documentation, however, for now we recommend looking at `abstract_provider.py`and `gdrive.py` inside `openpype/modules/sync_server/providers` and using it as a template. +### Running Site Sync in background + +Site Sync server synchronizes new published files from artist machine into configured remote location by default. + +There might be a use case where you need to synchronize between "non-artist" sites, for example between studio site and cloud. In this case +you need to run Site Sync as a background process from a command line (via service etc) 24/7. + +To configure all sites where all published files should be synced eventually you need to configure `project_settings/global/sync_server/config/always_accessible_on` property in Settins (per project) first. + +![Set another non artist remote site](assets/site_sync_always_on.png) + +This is an example of: +- Site Sync is enabled for a project +- default active and remote sites are set to `studio` - eg. standard process: everyone is working in a studio, publishing to shared location etc. +- (but this also allows any of the artists to work remotely, they would change their active site in their own Local Settings to `local` and configure local root. + This would result in everything artist publishes is saved first onto his local folder AND synchronized to `studio` site eventually.) +- everything exported must also be eventually uploaded to `sftp` site + +This eventual synchronization between `studio` and `sftp` sites must be physically handled by background process. + +As current implementation relies heavily on Settings and Local Settings, background process for a specific site ('studio' for example) must be configured via Tray first to `syncserver` command to work. + +To do this: + +- run OP `Tray` with environment variable SITE_SYNC_LOCAL_ID set to name of active (source) site. In most use cases it would be studio (for cases of backups of everything published to studio site to different cloud site etc.) +- start `Tray` +- check `Local ID` in information dialog after clicking on version number in the Tray +- open `Local Settings` in the `Tray` +- configure for each project necessary active site and remote site +- close `Tray` +- run OP from a command line with `syncserver` and `--active_site` arguments + + +This is an example how to trigger background synching process where active (source) site is `studio`. +(It is expected that OP is installed on a machine, `openpype_console` is on PATH. If not, add full path to executable. +) +```shell +openpype_console syncserver --active_site studio +``` \ No newline at end of file From 6f3944d01aa54d3f15c0d88ce7f0c8d617f96f50 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Fri, 29 Oct 2021 14:48:25 +0200 Subject: [PATCH 018/111] Hound --- .../default_modules/sync_server/sync_server_module.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openpype/modules/default_modules/sync_server/sync_server_module.py b/openpype/modules/default_modules/sync_server/sync_server_module.py index d8a69b3b07..82c1dc178a 100644 --- a/openpype/modules/default_modules/sync_server/sync_server_module.py +++ b/openpype/modules/default_modules/sync_server/sync_server_module.py @@ -727,9 +727,9 @@ class SyncServerModule(OpenPypeModule, ITrayModule): self.enabled = False except KeyError: log.info(( - "There are not set presets for SyncServer OR " - "Credentials provided are invalid, " - "no syncing possible"). + "There are not set presets for SyncServer OR " + "Credentials provided are invalid, " + "no syncing possible"). format(str(self.sync_project_settings)), exc_info=True) self.enabled = False From de8cfeff7f996ee2d33ca0b235ea3c60ccc66ebb Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Fri, 29 Oct 2021 14:52:12 +0200 Subject: [PATCH 019/111] OP-1920 - renamed reset site method --- .../sync_server/sync_server_module.py | 28 +++++++++---------- .../sync_server/tray/widgets.py | 4 +-- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/openpype/modules/default_modules/sync_server/sync_server_module.py b/openpype/modules/default_modules/sync_server/sync_server_module.py index 82c1dc178a..1fee0b4676 100644 --- a/openpype/modules/default_modules/sync_server/sync_server_module.py +++ b/openpype/modules/default_modules/sync_server/sync_server_module.py @@ -146,9 +146,9 @@ class SyncServerModule(OpenPypeModule, ITrayModule): if not site_name: site_name = self.DEFAULT_SITE - self.reset_provider_for_file(collection, - representation_id, - site_name=site_name, force=force) + self.reset_site_on_representation(collection, + representation_id, + site_name=site_name, force=force) # public facing API def remove_site(self, collection, representation_id, site_name, @@ -170,10 +170,10 @@ class SyncServerModule(OpenPypeModule, ITrayModule): if not self.get_sync_project_setting(collection): raise ValueError("Project not configured") - self.reset_provider_for_file(collection, - representation_id, - site_name=site_name, - remove=True) + self.reset_site_on_representation(collection, + representation_id, + site_name=site_name, + remove=True) if remove_local_files: self._remove_local_file(collection, representation_id, site_name) @@ -209,8 +209,8 @@ class SyncServerModule(OpenPypeModule, ITrayModule): """ log.info("Pausing SyncServer for {}".format(representation_id)) self._paused_representations.add(representation_id) - self.reset_provider_for_file(collection, representation_id, - site_name=site_name, pause=True) + self.reset_site_on_representation(collection, representation_id, + site_name=site_name, pause=True) def unpause_representation(self, collection, representation_id, site_name): """ @@ -229,8 +229,8 @@ class SyncServerModule(OpenPypeModule, ITrayModule): except KeyError: pass # self.paused_representations is not persistent - self.reset_provider_for_file(collection, representation_id, - site_name=site_name, pause=False) + self.reset_site_on_representation(collection, representation_id, + site_name=site_name, pause=False) def is_representation_paused(self, representation_id, check_parents=False, project_name=None): @@ -1240,9 +1240,9 @@ class SyncServerModule(OpenPypeModule, ITrayModule): return -1, None - def reset_provider_for_file(self, collection, representation_id, - side=None, file_id=None, site_name=None, - remove=False, pause=None, force=False): + def reset_site_on_representation(self, collection, representation_id, + side=None, file_id=None, site_name=None, + remove=False, pause=None, force=False): """ Reset information about synchronization for particular 'file_id' and provider. diff --git a/openpype/modules/default_modules/sync_server/tray/widgets.py b/openpype/modules/default_modules/sync_server/tray/widgets.py index 45537c1c2e..b401411db5 100644 --- a/openpype/modules/default_modules/sync_server/tray/widgets.py +++ b/openpype/modules/default_modules/sync_server/tray/widgets.py @@ -411,7 +411,7 @@ class _SyncRepresentationWidget(QtWidgets.QWidget): format(check_progress)) continue - self.sync_server.reset_provider_for_file( + self.sync_server.reset_site_on_representation( self.model.project, representation_id, site_name=site_name, @@ -786,7 +786,7 @@ class SyncRepresentationDetailWidget(_SyncRepresentationWidget): format(check_progress)) continue - self.sync_server.reset_provider_for_file( + self.sync_server.reset_site_on_representation( self.model.project, self.representation_id, site_name=site_name, From 1772e7bf8d887c059d28ca923448e5fd925285b8 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Fri, 29 Oct 2021 17:15:47 +0200 Subject: [PATCH 020/111] OP-1905 - implemented exit on key interrupt --- .../modules/default_modules/sync_server/sync_server.py | 1 + .../default_modules/sync_server/sync_server_module.py | 1 + openpype/pype_commands.py | 10 +++++++++- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/openpype/modules/default_modules/sync_server/sync_server.py b/openpype/modules/default_modules/sync_server/sync_server.py index 2227ec9366..48df5aad1b 100644 --- a/openpype/modules/default_modules/sync_server/sync_server.py +++ b/openpype/modules/default_modules/sync_server/sync_server.py @@ -246,6 +246,7 @@ class SyncServerThread(threading.Thread): asyncio.ensure_future(self.check_shutdown(), loop=self.loop) asyncio.ensure_future(self.sync_loop(), loop=self.loop) + log.info("Sync Server Started") self.loop.run_forever() except Exception: log.warning( diff --git a/openpype/modules/default_modules/sync_server/sync_server_module.py b/openpype/modules/default_modules/sync_server/sync_server_module.py index 1fee0b4676..281491eedf 100644 --- a/openpype/modules/default_modules/sync_server/sync_server_module.py +++ b/openpype/modules/default_modules/sync_server/sync_server_module.py @@ -771,6 +771,7 @@ class SyncServerModule(OpenPypeModule, ITrayModule): log.info("Stopping sync server server") self.sync_server_thread.is_running = False self.sync_server_thread.stop() + log.info("Sync server stopped") except Exception: log.warning( "Error has happened during Killing sync server", diff --git a/openpype/pype_commands.py b/openpype/pype_commands.py index cfa16012d0..e160db0f15 100644 --- a/openpype/pype_commands.py +++ b/openpype/pype_commands.py @@ -3,7 +3,6 @@ import os import sys import json -from datetime import datetime import time from openpype.lib import PypeLogger @@ -332,8 +331,17 @@ class PypeCommands: def syncserver(self, active_site): """Start running sync_server in background.""" + import signal os.environ["SITE_SYNC_LOCAL_ID"] = active_site + def signal_handler(sig, frame): + print("You pressed Ctrl+C. Process ended.") + sync_server_module.server_exit() + sys.exit(0) + + signal.signal(signal.SIGINT, signal_handler) + signal.signal(signal.SIGTERM, signal_handler) + from openpype.modules import ModulesManager manager = ModulesManager() From 3c11fdedc9599c52baf959ac10218292fdd3ba56 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Fri, 29 Oct 2021 18:37:32 +0200 Subject: [PATCH 021/111] add rr warning dialog --- .../royal_render/rr_root/plugins/README.md | 5 + ...der.py => m50__openpype_publish_render.py} | 31 +- poetry.lock | 1172 ++++++++++------- 3 files changed, 711 insertions(+), 497 deletions(-) create mode 100644 openpype/modules/default_modules/royal_render/rr_root/plugins/README.md rename openpype/modules/default_modules/royal_render/rr_root/plugins/plugins/control_job/perjob/{m55__openpype_publish_render.py => m50__openpype_publish_render.py} (75%) diff --git a/openpype/modules/default_modules/royal_render/rr_root/plugins/README.md b/openpype/modules/default_modules/royal_render/rr_root/plugins/README.md new file mode 100644 index 0000000000..0a9777833e --- /dev/null +++ b/openpype/modules/default_modules/royal_render/rr_root/plugins/README.md @@ -0,0 +1,5 @@ +## OpenPype RoyalRender integration plugins + +### Installation + +Copy content of this folder to your `RR_ROOT` (place where RoyalRender studio wide installation is). \ No newline at end of file diff --git a/openpype/modules/default_modules/royal_render/rr_root/plugins/plugins/control_job/perjob/m55__openpype_publish_render.py b/openpype/modules/default_modules/royal_render/rr_root/plugins/plugins/control_job/perjob/m50__openpype_publish_render.py similarity index 75% rename from openpype/modules/default_modules/royal_render/rr_root/plugins/plugins/control_job/perjob/m55__openpype_publish_render.py rename to openpype/modules/default_modules/royal_render/rr_root/plugins/plugins/control_job/perjob/m50__openpype_publish_render.py index eb8f137a05..11f57c7c93 100644 --- a/openpype/modules/default_modules/royal_render/rr_root/plugins/plugins/control_job/perjob/m55__openpype_publish_render.py +++ b/openpype/modules/default_modules/royal_render/rr_root/plugins/plugins/control_job/perjob/m50__openpype_publish_render.py @@ -11,6 +11,8 @@ import subprocess import os import glob import platform +import tempfile +import json class OpenPypeContextSelector: @@ -91,8 +93,33 @@ class OpenPypeContextSelector: """ op_exec = "openpype_gui" if platform.system().lower() == "windows": - op_exec = "openpype_gui.exe" - subprocess.check_output([self.openpype_root]) + op_exec = "{}.exe".format(op_exec) + + with tempfile.TemporaryFile() as tf: + args = list(self.openpype_root) + args.append("context_selector") + args.append(tf) + subprocess.check_output(args) + self.context = json.load(tf) + + if not self.context or \ + not self.context.project or \ + not self.context.asset or \ + not self.context.task: + self._show_rr_warning("Context selection failed.") + return + + @staticmethod + def _show_rr_warning(text): + warning_dialog = rrGlobal.getGenericUI() + warning_dialog.addItem(rrGlobal.genUIType.label, "infoLabel", "") + warning_dialog.setText("infoLabel", text) + warning_dialog.addItem( + rrGlobal.genUIType.layoutH, "btnLayout", "") + warning_dialog.addItem( + rrGlobal.genUIType.closeButton, "Ok", "btnLayout") + warning_dialog.execute() + del warning_dialog selector = OpenPypeContextSelector() diff --git a/poetry.lock b/poetry.lock index 36105f4213..c07a20253c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -80,7 +80,7 @@ python-dateutil = ">=2.7.0" [[package]] name = "astroid" -version = "2.5.6" +version = "2.8.4" description = "An abstract syntax tree for Python with inference support." category = "dev" optional = false @@ -89,7 +89,8 @@ python-versions = "~=3.6" [package.dependencies] lazy-object-proxy = ">=1.4.0" typed-ast = {version = ">=1.4.0,<1.5", markers = "implementation_name == \"cpython\" and python_version < \"3.8\""} -wrapt = ">=1.11,<1.13" +typing-extensions = {version = ">=3.10", markers = "python_version < \"3.10\""} +wrapt = ">=1.11,<1.14" [[package]] name = "async-timeout" @@ -162,20 +163,20 @@ typecheck = ["mypy"] [[package]] name = "blessed" -version = "1.18.0" +version = "1.19.0" description = "Easy, practical library for making terminal apps, by providing an elegant, well-documented interface to Colors, Keyboard input, and screen Positioning capabilities." category = "main" optional = false -python-versions = "*" +python-versions = ">=2.7" [package.dependencies] -jinxed = {version = ">=0.5.4", markers = "platform_system == \"Windows\""} +jinxed = {version = ">=1.1.0", markers = "platform_system == \"Windows\""} six = ">=1.9.0" wcwidth = ">=0.1.4" [[package]] name = "cachetools" -version = "4.2.2" +version = "4.2.4" description = "Extensible memoizing collections and decorators" category = "main" optional = false @@ -183,7 +184,7 @@ python-versions = "~=3.5" [[package]] name = "certifi" -version = "2021.5.30" +version = "2021.10.8" description = "Python package for providing Mozilla's CA Bundle." category = "main" optional = false @@ -191,7 +192,7 @@ python-versions = "*" [[package]] name = "cffi" -version = "1.14.5" +version = "1.15.0" description = "Foreign Function Interface for Python calling C code." category = "main" optional = false @@ -258,18 +259,21 @@ python-versions = "*" [[package]] name = "coverage" -version = "5.5" +version = "6.0.2" description = "Code coverage measurement for Python" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" +python-versions = ">=3.6" + +[package.dependencies] +tomli = {version = "*", optional = true, markers = "extra == \"toml\""} [package.extras] -toml = ["toml"] +toml = ["tomli"] [[package]] name = "cryptography" -version = "3.4.7" +version = "35.0.0" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." category = "main" optional = false @@ -282,9 +286,9 @@ cffi = ">=1.12" docs = ["sphinx (>=1.6.5,!=1.8.0,!=3.1.0,!=3.1.1)", "sphinx-rtd-theme"] docstest = ["doc8", "pyenchant (>=1.6.11)", "twine (>=1.12.0)", "sphinxcontrib-spelling (>=4.0.1)"] pep8test = ["black", "flake8", "flake8-import-order", "pep8-naming"] -sdist = ["setuptools-rust (>=0.11.4)"] +sdist = ["setuptools_rust (>=0.11.4)"] ssh = ["bcrypt (>=3.1.5)"] -test = ["pytest (>=6.0)", "pytest-cov", "pytest-subtests", "pytest-xdist", "pretend", "iso8601", "pytz", "hypothesis (>=1.11.4,!=3.79.2)"] +test = ["pytest (>=6.2.0)", "pytest-cov", "pytest-subtests", "pytest-xdist", "pretend", "iso8601", "pytz", "hypothesis (>=1.11.4,!=3.79.2)"] [[package]] name = "cx-freeze" @@ -328,7 +332,7 @@ trio = ["trio (>=0.14.0)", "sniffio (>=1.1)"] [[package]] name = "docutils" -version = "0.16" +version = "0.18" description = "Docutils -- Python Documentation Utilities" category = "dev" optional = false @@ -336,7 +340,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "dropbox" -version = "11.20.0" +version = "11.22.0" description = "Official Dropbox API Client" category = "main" optional = false @@ -409,30 +413,30 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" [[package]] name = "gitdb" -version = "4.0.7" +version = "4.0.9" description = "Git Object Database" category = "dev" optional = false -python-versions = ">=3.4" +python-versions = ">=3.6" [package.dependencies] -smmap = ">=3.0.1,<5" +smmap = ">=3.0.1,<6" [[package]] name = "gitpython" -version = "3.1.17" -description = "Python Git Library" +version = "3.1.24" +description = "GitPython is a python library used to interact with Git repositories" category = "dev" optional = false -python-versions = ">=3.5" +python-versions = ">=3.7" [package.dependencies] gitdb = ">=4.0.1,<5" -typing-extensions = {version = ">=3.7.4.0", markers = "python_version < \"3.8\""} +typing-extensions = {version = ">=3.7.4.3", markers = "python_version < \"3.10\""} [[package]] name = "google-api-core" -version = "1.30.0" +version = "1.31.3" description = "Google API client core library" category = "main" optional = false @@ -442,7 +446,7 @@ python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*" google-auth = ">=1.25.0,<2.0dev" googleapis-common-protos = ">=1.6.0,<2.0dev" packaging = ">=14.3" -protobuf = ">=3.12.0" +protobuf = ">=3.12.0,<3.18.0" pytz = "*" requests = ">=2.18.0,<3.0.0dev" six = ">=1.13.0" @@ -470,7 +474,7 @@ uritemplate = ">=3.0.0,<4dev" [[package]] name = "google-auth" -version = "1.31.0" +version = "1.35.0" description = "Google Authentication Library" category = "main" optional = false @@ -516,11 +520,11 @@ grpc = ["grpcio (>=1.0.0)"] [[package]] name = "httplib2" -version = "0.19.1" +version = "0.20.1" description = "A comprehensive HTTP client library." category = "main" optional = false -python-versions = "*" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [package.dependencies] pyparsing = ">=2.4.2,<3" @@ -543,7 +547,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "importlib-metadata" -version = "4.5.0" +version = "4.8.1" description = "Read metadata from Python packages" category = "main" optional = false @@ -555,7 +559,8 @@ zipp = ">=0.5" [package.extras] docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"] +perf = ["ipython"] +testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"] [[package]] name = "iniconfig" @@ -567,16 +572,17 @@ python-versions = "*" [[package]] name = "isort" -version = "5.8.0" +version = "5.9.3" description = "A Python utility / library to sort Python imports." category = "dev" optional = false -python-versions = ">=3.6,<4.0" +python-versions = ">=3.6.1,<4.0" [package.extras] pipfile_deprecated_finder = ["pipreqs", "requirementslib"] requirements_deprecated_finder = ["pipreqs", "pip-api"] colors = ["colorama (>=0.4.3,<0.5.0)"] +plugins = ["setuptools"] [[package]] name = "jedi" @@ -594,14 +600,15 @@ testing = ["colorama", "docopt", "pytest (>=3.1.0)"] [[package]] name = "jeepney" -version = "0.6.0" +version = "0.7.1" description = "Low-level, pure Python DBus protocol wrapper." category = "main" optional = false python-versions = ">=3.6" [package.extras] -test = ["pytest", "pytest-trio", "pytest-asyncio", "testpath", "trio"] +test = ["pytest", "pytest-trio", "pytest-asyncio", "testpath", "trio", "async-timeout"] +trio = ["trio", "async-generator"] [[package]] name = "jinja2" @@ -701,7 +708,7 @@ python-versions = "*" [[package]] name = "multidict" -version = "5.1.0" +version = "5.2.0" description = "multidict implementation" category = "main" optional = false @@ -729,18 +736,18 @@ reference = "openpype" [[package]] name = "packaging" -version = "20.9" +version = "21.2" description = "Core utilities for Python packages" category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=3.6" [package.dependencies] -pyparsing = ">=2.0.2" +pyparsing = ">=2.0.2,<3" [[package]] name = "paramiko" -version = "2.7.2" +version = "2.8.0" description = "SSH2 protocol library" category = "main" optional = false @@ -771,7 +778,7 @@ testing = ["docopt", "pytest (<6.0.0)"] [[package]] name = "pathlib2" -version = "2.3.5" +version = "2.3.6" description = "Object-oriented filesystem paths" category = "main" optional = false @@ -782,25 +789,38 @@ six = "*" [[package]] name = "pillow" -version = "8.3.2" +version = "8.4.0" description = "Python Imaging Library (Fork)" category = "main" optional = false python-versions = ">=3.6" +[[package]] +name = "platformdirs" +version = "2.4.0" +description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.extras] +docs = ["Sphinx (>=4)", "furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx-autodoc-typehints (>=1.12)"] +test = ["appdirs (==1.4.4)", "pytest (>=6)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)"] + [[package]] name = "pluggy" -version = "0.13.1" +version = "1.0.0" description = "plugin and hook calling mechanisms for python" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=3.6" [package.dependencies] importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} [package.extras] dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] [[package]] name = "ply" @@ -910,7 +930,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "pygments" -version = "2.9.0" +version = "2.10.0" description = "Pygments is a syntax highlighting package written in Python." category = "dev" optional = false @@ -918,22 +938,24 @@ python-versions = ">=3.5" [[package]] name = "pylint" -version = "2.8.3" +version = "2.11.1" description = "python code static checker" category = "dev" optional = false python-versions = "~=3.6" [package.dependencies] -astroid = "2.5.6" +astroid = ">=2.8.0,<2.9" colorama = {version = "*", markers = "sys_platform == \"win32\""} isort = ">=4.2.5,<6" mccabe = ">=0.6,<0.7" +platformdirs = ">=2.2.0" toml = ">=0.7.1" +typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\""} [[package]] name = "pymongo" -version = "3.11.4" +version = "3.12.1" description = "Python driver for MongoDB " category = "main" optional = false @@ -941,9 +963,9 @@ python-versions = "*" [package.extras] aws = ["pymongo-auth-aws (<2.0.0)"] -encryption = ["pymongocrypt (<2.0.0)"] +encryption = ["pymongocrypt (>=1.1.0,<2.0.0)"] gssapi = ["pykerberos"] -ocsp = ["pyopenssl (>=17.2.0)", "requests (<3.0.0)", "service-identity (>=18.1.0)"] +ocsp = ["pyopenssl (>=17.2.0)", "requests (<3.0.0)", "service-identity (>=18.1.0)", "certifi"] snappy = ["python-snappy"] srv = ["dnspython (>=1.16.0,<1.17.0)"] tls = ["ipaddress"] @@ -967,7 +989,7 @@ tests = ["pytest (>=3.2.1,!=3.3.0)", "hypothesis (>=3.27.0)"] [[package]] name = "pynput" -version = "1.7.3" +version = "1.7.4" description = "Monitor and control user input devices" category = "main" optional = false @@ -975,7 +997,8 @@ python-versions = "*" [package.dependencies] evdev = {version = ">=1.3", markers = "sys_platform in \"linux\""} -pyobjc-framework-Quartz = {version = ">=7.0", markers = "sys_platform == \"darwin\""} +pyobjc-framework-ApplicationServices = {version = ">=7.3", markers = "sys_platform == \"darwin\""} +pyobjc-framework-Quartz = {version = ">=7.3", markers = "sys_platform == \"darwin\""} python-xlib = {version = ">=0.17", markers = "sys_platform in \"linux\""} six = "*" @@ -987,6 +1010,19 @@ category = "main" optional = false python-versions = ">=3.6" +[[package]] +name = "pyobjc-framework-applicationservices" +version = "7.3" +description = "Wrappers for the framework ApplicationServices on macOS" +category = "main" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +pyobjc-core = ">=7.3" +pyobjc-framework-Cocoa = ">=7.3" +pyobjc-framework-Quartz = ">=7.3" + [[package]] name = "pyobjc-framework-cocoa" version = "7.3" @@ -1020,11 +1056,11 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" [[package]] name = "pyrsistent" -version = "0.17.3" +version = "0.18.0" description = "Persistent/Functional/Immutable data structures" category = "main" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" [[package]] name = "pysftp" @@ -1039,7 +1075,7 @@ paramiko = ">=1.17" [[package]] name = "pytest" -version = "6.2.4" +version = "6.2.5" description = "pytest: simple powerful testing with Python" category = "dev" optional = false @@ -1052,7 +1088,7 @@ colorama = {version = "*", markers = "sys_platform == \"win32\""} importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} iniconfig = "*" packaging = "*" -pluggy = ">=0.12,<1.0.0a1" +pluggy = ">=0.12,<2.0" py = ">=1.8.2" toml = "*" @@ -1061,37 +1097,36 @@ testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xm [[package]] name = "pytest-cov" -version = "2.12.1" +version = "3.0.0" description = "Pytest plugin for measuring coverage." category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.6" [package.dependencies] -coverage = ">=5.2.1" +coverage = {version = ">=5.2.1", extras = ["toml"]} pytest = ">=4.6" -toml = "*" [package.extras] testing = ["fields", "hunter", "process-tests", "six", "pytest-xdist", "virtualenv"] [[package]] name = "pytest-print" -version = "0.2.1" +version = "0.3.0" description = "pytest-print adds the printer fixture you can use to print messages to the user (directly to the pytest runner, not stdout)" category = "dev" optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" +python-versions = ">=3.6" [package.dependencies] -pytest = ">=3.0.0" +pytest = ">=6" [package.extras] -test = ["coverage (>=5)", "pytest (>=4)"] +test = ["coverage (>=5)"] [[package]] name = "python-dateutil" -version = "2.8.1" +version = "2.8.2" description = "Extensions to the standard Python datetime module" category = "main" optional = false @@ -1102,7 +1137,7 @@ six = ">=1.5" [[package]] name = "python-xlib" -version = "0.30" +version = "0.31" description = "Python X Library" category = "main" optional = false @@ -1121,7 +1156,7 @@ python-versions = "*" [[package]] name = "pytz" -version = "2021.1" +version = "2021.3" description = "World timezone definitions, modern and historical" category = "main" optional = false @@ -1145,7 +1180,7 @@ python-versions = "*" [[package]] name = "qt.py" -version = "1.3.3" +version = "1.3.6" description = "Python 2 & 3 compatibility wrapper around all Qt bindings - PySide, PySide2, PyQt4 and PyQt5." category = "main" optional = false @@ -1223,23 +1258,23 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" [[package]] name = "slack-sdk" -version = "3.6.0" +version = "3.11.2" description = "The Slack API Platform SDK for Python" category = "main" optional = false python-versions = ">=3.6.0" [package.extras] -optional = ["aiodns (>1.0)", "aiohttp (>=3.7.3,<4)", "boto3 (<=2)", "SQLAlchemy (>=1,<2)", "websockets (>=9.1,<10)", "websocket-client (>=0.57,<1)"] -testing = ["pytest (>=5.4,<6)", "pytest-asyncio (<1)", "Flask-Sockets (>=0.2,<1)", "pytest-cov (>=2,<3)", "codecov (>=2,<3)", "flake8 (>=3,<4)", "black (==21.5b1)", "psutil (>=5,<6)", "databases (>=0.3)"] +optional = ["aiodns (>1.0)", "aiohttp (>=3.7.3,<4)", "boto3 (<=2)", "SQLAlchemy (>=1,<2)", "websockets (>=9.1,<10)", "websocket-client (>=1,<2)"] +testing = ["pytest (>=5.4,<6)", "pytest-asyncio (<1)", "Flask-Sockets (>=0.2,<1)", "Flask (>=1,<2)", "Werkzeug (<2)", "pytest-cov (>=2,<3)", "codecov (>=2,<3)", "flake8 (>=3,<4)", "black (==21.9b0)", "psutil (>=5,<6)", "databases (>=0.3)", "boto3 (<=2)", "moto (<2)"] [[package]] name = "smmap" -version = "4.0.0" +version = "5.0.0" description = "A pure Python implementation of a sliding window memory map manager" category = "dev" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" [[package]] name = "snowballstemmer" @@ -1259,17 +1294,17 @@ python-versions = "*" [[package]] name = "sphinx" -version = "4.0.2" +version = "3.5.3" description = "Python documentation generator" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.5" [package.dependencies] alabaster = ">=0.7,<0.8" babel = ">=1.3" colorama = {version = ">=0.3.5", markers = "sys_platform == \"win32\""} -docutils = ">=0.14,<0.18" +docutils = ">=0.12" imagesize = "*" Jinja2 = ">=2.3" packaging = "*" @@ -1302,14 +1337,13 @@ sphinx = "*" [[package]] name = "sphinx-rtd-theme" -version = "0.5.2" +version = "0.5.1" description = "Read the Docs theme for Sphinx" category = "dev" optional = false python-versions = "*" [package.dependencies] -docutils = "<0.17" sphinx = "*" [package.extras] @@ -1429,6 +1463,14 @@ category = "dev" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +[[package]] +name = "tomli" +version = "1.2.2" +description = "A lil' TOML parser" +category = "dev" +optional = false +python-versions = ">=3.6" + [[package]] name = "typed-ast" version = "1.4.3" @@ -1439,7 +1481,7 @@ python-versions = "*" [[package]] name = "typing-extensions" -version = "3.10.0.0" +version = "3.10.0.2" description = "Backported and Experimental Type Hints for Python 3.5+" category = "main" optional = false @@ -1455,7 +1497,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "urllib3" -version = "1.26.5" +version = "1.26.7" description = "HTTP library with thread-safe connection pooling, file post, and more." category = "main" optional = false @@ -1487,11 +1529,11 @@ six = "*" [[package]] name = "wrapt" -version = "1.12.1" +version = "1.13.2" description = "Module for decorators, wrappers and monkey patching." category = "dev" optional = false -python-versions = "*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" [[package]] name = "wsrpc-aiohttp" @@ -1512,7 +1554,7 @@ ujson = ["ujson"] [[package]] name = "yarl" -version = "1.6.3" +version = "1.7.0" description = "Yet another URL library" category = "main" optional = false @@ -1525,7 +1567,7 @@ typing-extensions = {version = ">=3.7.4", markers = "python_version < \"3.8\""} [[package]] name = "zipp" -version = "3.4.1" +version = "3.6.0" description = "Backport of pathlib-compatible object wrapper for zip files" category = "main" optional = false @@ -1533,7 +1575,7 @@ python-versions = ">=3.6" [package.extras] docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=4.6)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "pytest-enabler", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"] +testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"] [metadata] lock-version = "1.1" @@ -1602,8 +1644,8 @@ arrow = [ {file = "arrow-0.17.0.tar.gz", hash = "sha256:ff08d10cda1d36c68657d6ad20d74fbea493d980f8b2d45344e00d6ed2bf6ed4"}, ] astroid = [ - {file = "astroid-2.5.6-py3-none-any.whl", hash = "sha256:4db03ab5fc3340cf619dbc25e42c2cc3755154ce6009469766d7143d1fc2ee4e"}, - {file = "astroid-2.5.6.tar.gz", hash = "sha256:8a398dfce302c13f14bab13e2b14fe385d32b73f4e4853b9bdfb64598baa1975"}, + {file = "astroid-2.8.4-py3-none-any.whl", hash = "sha256:0755c998e7117078dcb7d0bda621391dd2a85da48052d948c7411ab187325346"}, + {file = "astroid-2.8.4.tar.gz", hash = "sha256:1e83a69fd51b013ebf5912d26b9338d6643a55fec2f20c787792680610eed4a2"}, ] async-timeout = [ {file = "async-timeout-3.0.1.tar.gz", hash = "sha256:0c3c816a028d47f659d6ff5c745cb2acf1f966da1fe5c19c77a70282b25f4c5f"}, @@ -1635,67 +1677,68 @@ bcrypt = [ {file = "bcrypt-3.2.0.tar.gz", hash = "sha256:5b93c1726e50a93a033c36e5ca7fdcd29a5c7395af50a6892f5d9e7c6cfbfb29"}, ] blessed = [ - {file = "blessed-1.18.0-py2.py3-none-any.whl", hash = "sha256:5b5e2f0563d5a668c282f3f5946f7b1abb70c85829461900e607e74d7725106e"}, - {file = "blessed-1.18.0.tar.gz", hash = "sha256:1312879f971330a1b7f2c6341f2ae7e2cbac244bfc9d0ecfbbecd4b0293bc755"}, + {file = "blessed-1.19.0-py2.py3-none-any.whl", hash = "sha256:1f2d462631b2b6d2d4c3c65b54ef79ad87a6ca2dd55255df2f8d739fcc8a1ddb"}, + {file = "blessed-1.19.0.tar.gz", hash = "sha256:4db0f94e5761aea330b528e84a250027ffe996b5a94bf03e502600c9a5ad7a61"}, ] cachetools = [ - {file = "cachetools-4.2.2-py3-none-any.whl", hash = "sha256:2cc0b89715337ab6dbba85b5b50effe2b0c74e035d83ee8ed637cf52f12ae001"}, - {file = "cachetools-4.2.2.tar.gz", hash = "sha256:61b5ed1e22a0924aed1d23b478f37e8d52549ff8a961de2909c69bf950020cff"}, + {file = "cachetools-4.2.4-py3-none-any.whl", hash = "sha256:92971d3cb7d2a97efff7c7bb1657f21a8f5fb309a37530537c71b1774189f2d1"}, + {file = "cachetools-4.2.4.tar.gz", hash = "sha256:89ea6f1b638d5a73a4f9226be57ac5e4f399d22770b92355f92dcb0f7f001693"}, ] certifi = [ - {file = "certifi-2021.5.30-py2.py3-none-any.whl", hash = "sha256:50b1e4f8446b06f41be7dd6338db18e0990601dce795c2b1686458aa7e8fa7d8"}, - {file = "certifi-2021.5.30.tar.gz", hash = "sha256:2bbf76fd432960138b3ef6dda3dde0544f27cbf8546c458e60baf371917ba9ee"}, + {file = "certifi-2021.10.8-py2.py3-none-any.whl", hash = "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569"}, + {file = "certifi-2021.10.8.tar.gz", hash = "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872"}, ] cffi = [ - {file = "cffi-1.14.5-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:bb89f306e5da99f4d922728ddcd6f7fcebb3241fc40edebcb7284d7514741991"}, - {file = "cffi-1.14.5-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:34eff4b97f3d982fb93e2831e6750127d1355a923ebaeeb565407b3d2f8d41a1"}, - {file = "cffi-1.14.5-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:99cd03ae7988a93dd00bcd9d0b75e1f6c426063d6f03d2f90b89e29b25b82dfa"}, - {file = "cffi-1.14.5-cp27-cp27m-win32.whl", hash = "sha256:65fa59693c62cf06e45ddbb822165394a288edce9e276647f0046e1ec26920f3"}, - {file = "cffi-1.14.5-cp27-cp27m-win_amd64.whl", hash = "sha256:51182f8927c5af975fece87b1b369f722c570fe169f9880764b1ee3bca8347b5"}, - {file = "cffi-1.14.5-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:43e0b9d9e2c9e5d152946b9c5fe062c151614b262fda2e7b201204de0b99e482"}, - {file = "cffi-1.14.5-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:cbde590d4faaa07c72bf979734738f328d239913ba3e043b1e98fe9a39f8b2b6"}, - {file = "cffi-1.14.5-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:5de7970188bb46b7bf9858eb6890aad302577a5f6f75091fd7cdd3ef13ef3045"}, - {file = "cffi-1.14.5-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:a465da611f6fa124963b91bf432d960a555563efe4ed1cc403ba5077b15370aa"}, - {file = "cffi-1.14.5-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:d42b11d692e11b6634f7613ad8df5d6d5f8875f5d48939520d351007b3c13406"}, - {file = "cffi-1.14.5-cp35-cp35m-win32.whl", hash = "sha256:72d8d3ef52c208ee1c7b2e341f7d71c6fd3157138abf1a95166e6165dd5d4369"}, - {file = "cffi-1.14.5-cp35-cp35m-win_amd64.whl", hash = "sha256:29314480e958fd8aab22e4a58b355b629c59bf5f2ac2492b61e3dc06d8c7a315"}, - {file = "cffi-1.14.5-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:3d3dd4c9e559eb172ecf00a2a7517e97d1e96de2a5e610bd9b68cea3925b4892"}, - {file = "cffi-1.14.5-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:48e1c69bbacfc3d932221851b39d49e81567a4d4aac3b21258d9c24578280058"}, - {file = "cffi-1.14.5-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:69e395c24fc60aad6bb4fa7e583698ea6cc684648e1ffb7fe85e3c1ca131a7d5"}, - {file = "cffi-1.14.5-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:9e93e79c2551ff263400e1e4be085a1210e12073a31c2011dbbda14bda0c6132"}, - {file = "cffi-1.14.5-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:24ec4ff2c5c0c8f9c6b87d5bb53555bf267e1e6f70e52e5a9740d32861d36b6f"}, - {file = "cffi-1.14.5-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3c3f39fa737542161d8b0d680df2ec249334cd70a8f420f71c9304bd83c3cbed"}, - {file = "cffi-1.14.5-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:681d07b0d1e3c462dd15585ef5e33cb021321588bebd910124ef4f4fb71aef55"}, - {file = "cffi-1.14.5-cp36-cp36m-win32.whl", hash = "sha256:58e3f59d583d413809d60779492342801d6e82fefb89c86a38e040c16883be53"}, - {file = "cffi-1.14.5-cp36-cp36m-win_amd64.whl", hash = "sha256:005a36f41773e148deac64b08f233873a4d0c18b053d37da83f6af4d9087b813"}, - {file = "cffi-1.14.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2894f2df484ff56d717bead0a5c2abb6b9d2bf26d6960c4604d5c48bbc30ee73"}, - {file = "cffi-1.14.5-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:0857f0ae312d855239a55c81ef453ee8fd24136eaba8e87a2eceba644c0d4c06"}, - {file = "cffi-1.14.5-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:cd2868886d547469123fadc46eac7ea5253ea7fcb139f12e1dfc2bbd406427d1"}, - {file = "cffi-1.14.5-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:35f27e6eb43380fa080dccf676dece30bef72e4a67617ffda586641cd4508d49"}, - {file = "cffi-1.14.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:06d7cd1abac2ffd92e65c0609661866709b4b2d82dd15f611e602b9b188b0b69"}, - {file = "cffi-1.14.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0f861a89e0043afec2a51fd177a567005847973be86f709bbb044d7f42fc4e05"}, - {file = "cffi-1.14.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cc5a8e069b9ebfa22e26d0e6b97d6f9781302fe7f4f2b8776c3e1daea35f1adc"}, - {file = "cffi-1.14.5-cp37-cp37m-win32.whl", hash = "sha256:9ff227395193126d82e60319a673a037d5de84633f11279e336f9c0f189ecc62"}, - {file = "cffi-1.14.5-cp37-cp37m-win_amd64.whl", hash = "sha256:9cf8022fb8d07a97c178b02327b284521c7708d7c71a9c9c355c178ac4bbd3d4"}, - {file = "cffi-1.14.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8b198cec6c72df5289c05b05b8b0969819783f9418e0409865dac47288d2a053"}, - {file = "cffi-1.14.5-cp38-cp38-manylinux1_i686.whl", hash = "sha256:ad17025d226ee5beec591b52800c11680fca3df50b8b29fe51d882576e039ee0"}, - {file = "cffi-1.14.5-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:6c97d7350133666fbb5cf4abdc1178c812cb205dc6f41d174a7b0f18fb93337e"}, - {file = "cffi-1.14.5-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:8ae6299f6c68de06f136f1f9e69458eae58f1dacf10af5c17353eae03aa0d827"}, - {file = "cffi-1.14.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:04c468b622ed31d408fea2346bec5bbffba2cc44226302a0de1ade9f5ea3d373"}, - {file = "cffi-1.14.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:06db6321b7a68b2bd6df96d08a5adadc1fa0e8f419226e25b2a5fbf6ccc7350f"}, - {file = "cffi-1.14.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:293e7ea41280cb28c6fcaaa0b1aa1f533b8ce060b9e701d78511e1e6c4a1de76"}, - {file = "cffi-1.14.5-cp38-cp38-win32.whl", hash = "sha256:b85eb46a81787c50650f2392b9b4ef23e1f126313b9e0e9013b35c15e4288e2e"}, - {file = "cffi-1.14.5-cp38-cp38-win_amd64.whl", hash = "sha256:1f436816fc868b098b0d63b8920de7d208c90a67212546d02f84fe78a9c26396"}, - {file = "cffi-1.14.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1071534bbbf8cbb31b498d5d9db0f274f2f7a865adca4ae429e147ba40f73dea"}, - {file = "cffi-1.14.5-cp39-cp39-manylinux1_i686.whl", hash = "sha256:9de2e279153a443c656f2defd67769e6d1e4163952b3c622dcea5b08a6405322"}, - {file = "cffi-1.14.5-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:6e4714cc64f474e4d6e37cfff31a814b509a35cb17de4fb1999907575684479c"}, - {file = "cffi-1.14.5-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:158d0d15119b4b7ff6b926536763dc0714313aa59e320ddf787502c70c4d4bee"}, - {file = "cffi-1.14.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bf1ac1984eaa7675ca8d5745a8cb87ef7abecb5592178406e55858d411eadc0"}, - {file = "cffi-1.14.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:df5052c5d867c1ea0b311fb7c3cd28b19df469c056f7fdcfe88c7473aa63e333"}, - {file = "cffi-1.14.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:24a570cd11895b60829e941f2613a4f79df1a27344cbbb82164ef2e0116f09c7"}, - {file = "cffi-1.14.5-cp39-cp39-win32.whl", hash = "sha256:afb29c1ba2e5a3736f1c301d9d0abe3ec8b86957d04ddfa9d7a6a42b9367e396"}, - {file = "cffi-1.14.5-cp39-cp39-win_amd64.whl", hash = "sha256:f2d45f97ab6bb54753eab54fffe75aaf3de4ff2341c9daee1987ee1837636f1d"}, - {file = "cffi-1.14.5.tar.gz", hash = "sha256:fd78e5fee591709f32ef6edb9a015b4aa1a5022598e36227500c8f4e02328d9c"}, + {file = "cffi-1.15.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:c2502a1a03b6312837279c8c1bd3ebedf6c12c4228ddbad40912d671ccc8a962"}, + {file = "cffi-1.15.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:23cfe892bd5dd8941608f93348c0737e369e51c100d03718f108bf1add7bd6d0"}, + {file = "cffi-1.15.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:41d45de54cd277a7878919867c0f08b0cf817605e4eb94093e7516505d3c8d14"}, + {file = "cffi-1.15.0-cp27-cp27m-win32.whl", hash = "sha256:4a306fa632e8f0928956a41fa8e1d6243c71e7eb59ffbd165fc0b41e316b2474"}, + {file = "cffi-1.15.0-cp27-cp27m-win_amd64.whl", hash = "sha256:e7022a66d9b55e93e1a845d8c9eba2a1bebd4966cd8bfc25d9cd07d515b33fa6"}, + {file = "cffi-1.15.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:14cd121ea63ecdae71efa69c15c5543a4b5fbcd0bbe2aad864baca0063cecf27"}, + {file = "cffi-1.15.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:d4d692a89c5cf08a8557fdeb329b82e7bf609aadfaed6c0d79f5a449a3c7c023"}, + {file = "cffi-1.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0104fb5ae2391d46a4cb082abdd5c69ea4eab79d8d44eaaf79f1b1fd806ee4c2"}, + {file = "cffi-1.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:91ec59c33514b7c7559a6acda53bbfe1b283949c34fe7440bcf917f96ac0723e"}, + {file = "cffi-1.15.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f5c7150ad32ba43a07c4479f40241756145a1f03b43480e058cfd862bf5041c7"}, + {file = "cffi-1.15.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:00c878c90cb53ccfaae6b8bc18ad05d2036553e6d9d1d9dbcf323bbe83854ca3"}, + {file = "cffi-1.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:abb9a20a72ac4e0fdb50dae135ba5e77880518e742077ced47eb1499e29a443c"}, + {file = "cffi-1.15.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a5263e363c27b653a90078143adb3d076c1a748ec9ecc78ea2fb916f9b861962"}, + {file = "cffi-1.15.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f54a64f8b0c8ff0b64d18aa76675262e1700f3995182267998c31ae974fbc382"}, + {file = "cffi-1.15.0-cp310-cp310-win32.whl", hash = "sha256:c21c9e3896c23007803a875460fb786118f0cdd4434359577ea25eb556e34c55"}, + {file = "cffi-1.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:5e069f72d497312b24fcc02073d70cb989045d1c91cbd53979366077959933e0"}, + {file = "cffi-1.15.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:64d4ec9f448dfe041705426000cc13e34e6e5bb13736e9fd62e34a0b0c41566e"}, + {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2756c88cbb94231c7a147402476be2c4df2f6078099a6f4a480d239a8817ae39"}, + {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b96a311ac60a3f6be21d2572e46ce67f09abcf4d09344c49274eb9e0bf345fc"}, + {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75e4024375654472cc27e91cbe9eaa08567f7fbdf822638be2814ce059f58032"}, + {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:59888172256cac5629e60e72e86598027aca6bf01fa2465bdb676d37636573e8"}, + {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:27c219baf94952ae9d50ec19651a687b826792055353d07648a5695413e0c605"}, + {file = "cffi-1.15.0-cp36-cp36m-win32.whl", hash = "sha256:4958391dbd6249d7ad855b9ca88fae690783a6be9e86df65865058ed81fc860e"}, + {file = "cffi-1.15.0-cp36-cp36m-win_amd64.whl", hash = "sha256:f6f824dc3bce0edab5f427efcfb1d63ee75b6fcb7282900ccaf925be84efb0fc"}, + {file = "cffi-1.15.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:06c48159c1abed75c2e721b1715c379fa3200c7784271b3c46df01383b593636"}, + {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:c2051981a968d7de9dd2d7b87bcb9c939c74a34626a6e2f8181455dd49ed69e4"}, + {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:fd8a250edc26254fe5b33be00402e6d287f562b6a5b2152dec302fa15bb3e997"}, + {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:91d77d2a782be4274da750752bb1650a97bfd8f291022b379bb8e01c66b4e96b"}, + {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:45db3a33139e9c8f7c09234b5784a5e33d31fd6907800b316decad50af323ff2"}, + {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:263cc3d821c4ab2213cbe8cd8b355a7f72a8324577dc865ef98487c1aeee2bc7"}, + {file = "cffi-1.15.0-cp37-cp37m-win32.whl", hash = "sha256:17771976e82e9f94976180f76468546834d22a7cc404b17c22df2a2c81db0c66"}, + {file = "cffi-1.15.0-cp37-cp37m-win_amd64.whl", hash = "sha256:3415c89f9204ee60cd09b235810be700e993e343a408693e80ce7f6a40108029"}, + {file = "cffi-1.15.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4238e6dab5d6a8ba812de994bbb0a79bddbdf80994e4ce802b6f6f3142fcc880"}, + {file = "cffi-1.15.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0808014eb713677ec1292301ea4c81ad277b6cdf2fdd90fd540af98c0b101d20"}, + {file = "cffi-1.15.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:57e9ac9ccc3101fac9d6014fba037473e4358ef4e89f8e181f8951a2c0162024"}, + {file = "cffi-1.15.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b6c2ea03845c9f501ed1313e78de148cd3f6cad741a75d43a29b43da27f2e1e"}, + {file = "cffi-1.15.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:10dffb601ccfb65262a27233ac273d552ddc4d8ae1bf93b21c94b8511bffe728"}, + {file = "cffi-1.15.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:786902fb9ba7433aae840e0ed609f45c7bcd4e225ebb9c753aa39725bb3e6ad6"}, + {file = "cffi-1.15.0-cp38-cp38-win32.whl", hash = "sha256:da5db4e883f1ce37f55c667e5c0de439df76ac4cb55964655906306918e7363c"}, + {file = "cffi-1.15.0-cp38-cp38-win_amd64.whl", hash = "sha256:181dee03b1170ff1969489acf1c26533710231c58f95534e3edac87fff06c443"}, + {file = "cffi-1.15.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:45e8636704eacc432a206ac7345a5d3d2c62d95a507ec70d62f23cd91770482a"}, + {file = "cffi-1.15.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:31fb708d9d7c3f49a60f04cf5b119aeefe5644daba1cd2a0fe389b674fd1de37"}, + {file = "cffi-1.15.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6dc2737a3674b3e344847c8686cf29e500584ccad76204efea14f451d4cc669a"}, + {file = "cffi-1.15.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:74fdfdbfdc48d3f47148976f49fab3251e550a8720bebc99bf1483f5bfb5db3e"}, + {file = "cffi-1.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffaa5c925128e29efbde7301d8ecaf35c8c60ffbcd6a1ffd3a552177c8e5e796"}, + {file = "cffi-1.15.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f7d084648d77af029acb79a0ff49a0ad7e9d09057a9bf46596dac9514dc07df"}, + {file = "cffi-1.15.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ef1f279350da2c586a69d32fc8733092fd32cc8ac95139a00377841f59a3f8d8"}, + {file = "cffi-1.15.0-cp39-cp39-win32.whl", hash = "sha256:2a23af14f408d53d5e6cd4e3d9a24ff9e05906ad574822a10563efcef137979a"}, + {file = "cffi-1.15.0-cp39-cp39-win_amd64.whl", hash = "sha256:3773c4d81e6e818df2efbc7dd77325ca0dcb688116050fb2b3011218eda36139"}, + {file = "cffi-1.15.0.tar.gz", hash = "sha256:920f0d66a896c2d99f0adbb391f990a84091179542c205fa53ce5787aff87954"}, ] chardet = [ {file = "chardet-4.0.0-py2.py3-none-any.whl", hash = "sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5"}, @@ -1722,74 +1765,61 @@ coolname = [ {file = "coolname-1.1.0.tar.gz", hash = "sha256:410fe6ea9999bf96f2856ef0c726d5f38782bbefb7bb1aca0e91e0dc98ed09e3"}, ] coverage = [ - {file = "coverage-5.5-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:b6d534e4b2ab35c9f93f46229363e17f63c53ad01330df9f2d6bd1187e5eaacf"}, - {file = "coverage-5.5-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:b7895207b4c843c76a25ab8c1e866261bcfe27bfaa20c192de5190121770672b"}, - {file = "coverage-5.5-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:c2723d347ab06e7ddad1a58b2a821218239249a9e4365eaff6649d31180c1669"}, - {file = "coverage-5.5-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:900fbf7759501bc7807fd6638c947d7a831fc9fdf742dc10f02956ff7220fa90"}, - {file = "coverage-5.5-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:004d1880bed2d97151facef49f08e255a20ceb6f9432df75f4eef018fdd5a78c"}, - {file = "coverage-5.5-cp27-cp27m-win32.whl", hash = "sha256:06191eb60f8d8a5bc046f3799f8a07a2d7aefb9504b0209aff0b47298333302a"}, - {file = "coverage-5.5-cp27-cp27m-win_amd64.whl", hash = "sha256:7501140f755b725495941b43347ba8a2777407fc7f250d4f5a7d2a1050ba8e82"}, - {file = "coverage-5.5-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:372da284cfd642d8e08ef606917846fa2ee350f64994bebfbd3afb0040436905"}, - {file = "coverage-5.5-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:8963a499849a1fc54b35b1c9f162f4108017b2e6db2c46c1bed93a72262ed083"}, - {file = "coverage-5.5-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:869a64f53488f40fa5b5b9dcb9e9b2962a66a87dab37790f3fcfb5144b996ef5"}, - {file = "coverage-5.5-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:4a7697d8cb0f27399b0e393c0b90f0f1e40c82023ea4d45d22bce7032a5d7b81"}, - {file = "coverage-5.5-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:8d0a0725ad7c1a0bcd8d1b437e191107d457e2ec1084b9f190630a4fb1af78e6"}, - {file = "coverage-5.5-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:51cb9476a3987c8967ebab3f0fe144819781fca264f57f89760037a2ea191cb0"}, - {file = "coverage-5.5-cp310-cp310-win_amd64.whl", hash = "sha256:c0891a6a97b09c1f3e073a890514d5012eb256845c451bd48f7968ef939bf4ae"}, - {file = "coverage-5.5-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:3487286bc29a5aa4b93a072e9592f22254291ce96a9fbc5251f566b6b7343cdb"}, - {file = "coverage-5.5-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:deee1077aae10d8fa88cb02c845cfba9b62c55e1183f52f6ae6a2df6a2187160"}, - {file = "coverage-5.5-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:f11642dddbb0253cc8853254301b51390ba0081750a8ac03f20ea8103f0c56b6"}, - {file = "coverage-5.5-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:6c90e11318f0d3c436a42409f2749ee1a115cd8b067d7f14c148f1ce5574d701"}, - {file = "coverage-5.5-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:30c77c1dc9f253283e34c27935fded5015f7d1abe83bc7821680ac444eaf7793"}, - {file = "coverage-5.5-cp35-cp35m-win32.whl", hash = "sha256:9a1ef3b66e38ef8618ce5fdc7bea3d9f45f3624e2a66295eea5e57966c85909e"}, - {file = "coverage-5.5-cp35-cp35m-win_amd64.whl", hash = "sha256:972c85d205b51e30e59525694670de6a8a89691186012535f9d7dbaa230e42c3"}, - {file = "coverage-5.5-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:af0e781009aaf59e25c5a678122391cb0f345ac0ec272c7961dc5455e1c40066"}, - {file = "coverage-5.5-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:74d881fc777ebb11c63736622b60cb9e4aee5cace591ce274fb69e582a12a61a"}, - {file = "coverage-5.5-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:92b017ce34b68a7d67bd6d117e6d443a9bf63a2ecf8567bb3d8c6c7bc5014465"}, - {file = "coverage-5.5-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:d636598c8305e1f90b439dbf4f66437de4a5e3c31fdf47ad29542478c8508bbb"}, - {file = "coverage-5.5-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:41179b8a845742d1eb60449bdb2992196e211341818565abded11cfa90efb821"}, - {file = "coverage-5.5-cp36-cp36m-win32.whl", hash = "sha256:040af6c32813fa3eae5305d53f18875bedd079960822ef8ec067a66dd8afcd45"}, - {file = "coverage-5.5-cp36-cp36m-win_amd64.whl", hash = "sha256:5fec2d43a2cc6965edc0bb9e83e1e4b557f76f843a77a2496cbe719583ce8184"}, - {file = "coverage-5.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:18ba8bbede96a2c3dde7b868de9dcbd55670690af0988713f0603f037848418a"}, - {file = "coverage-5.5-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:2910f4d36a6a9b4214bb7038d537f015346f413a975d57ca6b43bf23d6563b53"}, - {file = "coverage-5.5-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:f0b278ce10936db1a37e6954e15a3730bea96a0997c26d7fee88e6c396c2086d"}, - {file = "coverage-5.5-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:796c9c3c79747146ebd278dbe1e5c5c05dd6b10cc3bcb8389dfdf844f3ead638"}, - {file = "coverage-5.5-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:53194af30d5bad77fcba80e23a1441c71abfb3e01192034f8246e0d8f99528f3"}, - {file = "coverage-5.5-cp37-cp37m-win32.whl", hash = "sha256:184a47bbe0aa6400ed2d41d8e9ed868b8205046518c52464fde713ea06e3a74a"}, - {file = "coverage-5.5-cp37-cp37m-win_amd64.whl", hash = "sha256:2949cad1c5208b8298d5686d5a85b66aae46d73eec2c3e08c817dd3513e5848a"}, - {file = "coverage-5.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:217658ec7187497e3f3ebd901afdca1af062b42cfe3e0dafea4cced3983739f6"}, - {file = "coverage-5.5-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1aa846f56c3d49205c952d8318e76ccc2ae23303351d9270ab220004c580cfe2"}, - {file = "coverage-5.5-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:24d4a7de75446be83244eabbff746d66b9240ae020ced65d060815fac3423759"}, - {file = "coverage-5.5-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:d1f8bf7b90ba55699b3a5e44930e93ff0189aa27186e96071fac7dd0d06a1873"}, - {file = "coverage-5.5-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:970284a88b99673ccb2e4e334cfb38a10aab7cd44f7457564d11898a74b62d0a"}, - {file = "coverage-5.5-cp38-cp38-win32.whl", hash = "sha256:01d84219b5cdbfc8122223b39a954820929497a1cb1422824bb86b07b74594b6"}, - {file = "coverage-5.5-cp38-cp38-win_amd64.whl", hash = "sha256:2e0d881ad471768bf6e6c2bf905d183543f10098e3b3640fc029509530091502"}, - {file = "coverage-5.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d1f9ce122f83b2305592c11d64f181b87153fc2c2bbd3bb4a3dde8303cfb1a6b"}, - {file = "coverage-5.5-cp39-cp39-manylinux1_i686.whl", hash = "sha256:13c4ee887eca0f4c5a247b75398d4114c37882658300e153113dafb1d76de529"}, - {file = "coverage-5.5-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:52596d3d0e8bdf3af43db3e9ba8dcdaac724ba7b5ca3f6358529d56f7a166f8b"}, - {file = "coverage-5.5-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:2cafbbb3af0733db200c9b5f798d18953b1a304d3f86a938367de1567f4b5bff"}, - {file = "coverage-5.5-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:44d654437b8ddd9eee7d1eaee28b7219bec228520ff809af170488fd2fed3e2b"}, - {file = "coverage-5.5-cp39-cp39-win32.whl", hash = "sha256:d314ed732c25d29775e84a960c3c60808b682c08d86602ec2c3008e1202e3bb6"}, - {file = "coverage-5.5-cp39-cp39-win_amd64.whl", hash = "sha256:13034c4409db851670bc9acd836243aeee299949bd5673e11844befcb0149f03"}, - {file = "coverage-5.5-pp36-none-any.whl", hash = "sha256:f030f8873312a16414c0d8e1a1ddff2d3235655a2174e3648b4fa66b3f2f1079"}, - {file = "coverage-5.5-pp37-none-any.whl", hash = "sha256:2a3859cb82dcbda1cfd3e6f71c27081d18aa251d20a17d87d26d4cd216fb0af4"}, - {file = "coverage-5.5.tar.gz", hash = "sha256:ebe78fe9a0e874362175b02371bdfbee64d8edc42a044253ddf4ee7d3c15212c"}, + {file = "coverage-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1549e1d08ce38259de2bc3e9a0d5f3642ff4a8f500ffc1b2df73fd621a6cdfc0"}, + {file = "coverage-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bcae10fccb27ca2a5f456bf64d84110a5a74144be3136a5e598f9d9fb48c0caa"}, + {file = "coverage-6.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:53a294dc53cfb39c74758edaa6305193fb4258a30b1f6af24b360a6c8bd0ffa7"}, + {file = "coverage-6.0.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8251b37be1f2cd9c0e5ccd9ae0380909c24d2a5ed2162a41fcdbafaf59a85ebd"}, + {file = "coverage-6.0.2-cp310-cp310-win32.whl", hash = "sha256:db42baa892cba723326284490283a68d4de516bfb5aaba369b4e3b2787a778b7"}, + {file = "coverage-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:bbffde2a68398682623d9dd8c0ca3f46fda074709b26fcf08ae7a4c431a6ab2d"}, + {file = "coverage-6.0.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:60e51a3dd55540bec686d7fff61b05048ca31e804c1f32cbb44533e6372d9cc3"}, + {file = "coverage-6.0.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a6a9409223a27d5ef3cca57dd7cd4dfcb64aadf2fad5c3b787830ac9223e01a"}, + {file = "coverage-6.0.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:4b34ae4f51bbfa5f96b758b55a163d502be3dcb24f505d0227858c2b3f94f5b9"}, + {file = "coverage-6.0.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3bbda1b550e70fa6ac40533d3f23acd4f4e9cb4e6e77251ce77fdf41b3309fb2"}, + {file = "coverage-6.0.2-cp36-cp36m-win32.whl", hash = "sha256:4e28d2a195c533b58fc94a12826f4431726d8eb029ac21d874345f943530c122"}, + {file = "coverage-6.0.2-cp36-cp36m-win_amd64.whl", hash = "sha256:a82d79586a0a4f5fd1cf153e647464ced402938fbccb3ffc358c7babd4da1dd9"}, + {file = "coverage-6.0.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3be1206dc09fb6298de3fce70593e27436862331a85daee36270b6d0e1c251c4"}, + {file = "coverage-6.0.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9cd3828bbe1a40070c11fe16a51df733fd2f0cb0d745fb83b7b5c1f05967df7"}, + {file = "coverage-6.0.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:d036dc1ed8e1388e995833c62325df3f996675779541f682677efc6af71e96cc"}, + {file = "coverage-6.0.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:04560539c19ec26995ecfb3d9307ff154fbb9a172cb57e3b3cfc4ced673103d1"}, + {file = "coverage-6.0.2-cp37-cp37m-win32.whl", hash = "sha256:e4fb7ced4d9dec77d6cf533acfbf8e1415fe799430366affb18d69ee8a3c6330"}, + {file = "coverage-6.0.2-cp37-cp37m-win_amd64.whl", hash = "sha256:77b1da5767ed2f44611bc9bc019bc93c03fa495728ec389759b6e9e5039ac6b1"}, + {file = "coverage-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:61b598cbdbaae22d9e34e3f675997194342f866bb1d781da5d0be54783dce1ff"}, + {file = "coverage-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:36e9040a43d2017f2787b28d365a4bb33fcd792c7ff46a047a04094dc0e2a30d"}, + {file = "coverage-6.0.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9f1627e162e3864a596486774876415a7410021f4b67fd2d9efdf93ade681afc"}, + {file = "coverage-6.0.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e7a0b42db2a47ecb488cde14e0f6c7679a2c5a9f44814393b162ff6397fcdfbb"}, + {file = "coverage-6.0.2-cp38-cp38-win32.whl", hash = "sha256:a1b73c7c4d2a42b9d37dd43199c5711d91424ff3c6c22681bc132db4a4afec6f"}, + {file = "coverage-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:1db67c497688fd4ba85b373b37cc52c50d437fd7267520ecd77bddbd89ea22c9"}, + {file = "coverage-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f2f184bf38e74f152eed7f87e345b51f3ab0b703842f447c22efe35e59942c24"}, + {file = "coverage-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cd1cf1deb3d5544bd942356364a2fdc8959bad2b6cf6eb17f47d301ea34ae822"}, + {file = "coverage-6.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:ad9b8c1206ae41d46ec7380b78ba735ebb77758a650643e841dd3894966c31d0"}, + {file = "coverage-6.0.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:381d773d896cc7f8ba4ff3b92dee4ed740fb88dfe33b6e42efc5e8ab6dfa1cfe"}, + {file = "coverage-6.0.2-cp39-cp39-win32.whl", hash = "sha256:424c44f65e8be58b54e2b0bd1515e434b940679624b1b72726147cfc6a9fc7ce"}, + {file = "coverage-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:abbff240f77347d17306d3201e14431519bf64495648ca5a49571f988f88dee9"}, + {file = "coverage-6.0.2-pp36-none-any.whl", hash = "sha256:7092eab374346121805fb637572483270324407bf150c30a3b161fc0c4ca5164"}, + {file = "coverage-6.0.2-pp37-none-any.whl", hash = "sha256:30922626ce6f7a5a30bdba984ad21021529d3d05a68b4f71ea3b16bda35b8895"}, + {file = "coverage-6.0.2.tar.gz", hash = "sha256:6807947a09510dc31fa86f43595bf3a14017cd60bf633cc746d52141bfa6b149"}, ] cryptography = [ - {file = "cryptography-3.4.7-cp36-abi3-macosx_10_10_x86_64.whl", hash = "sha256:3d8427734c781ea5f1b41d6589c293089704d4759e34597dce91014ac125aad1"}, - {file = "cryptography-3.4.7-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:8e56e16617872b0957d1c9742a3f94b43533447fd78321514abbe7db216aa250"}, - {file = "cryptography-3.4.7-cp36-abi3-manylinux2010_x86_64.whl", hash = "sha256:37340614f8a5d2fb9aeea67fd159bfe4f5f4ed535b1090ce8ec428b2f15a11f2"}, - {file = "cryptography-3.4.7-cp36-abi3-manylinux2014_aarch64.whl", hash = "sha256:240f5c21aef0b73f40bb9f78d2caff73186700bf1bc6b94285699aff98cc16c6"}, - {file = "cryptography-3.4.7-cp36-abi3-manylinux2014_x86_64.whl", hash = "sha256:1e056c28420c072c5e3cb36e2b23ee55e260cb04eee08f702e0edfec3fb51959"}, - {file = "cryptography-3.4.7-cp36-abi3-win32.whl", hash = "sha256:0f1212a66329c80d68aeeb39b8a16d54ef57071bf22ff4e521657b27372e327d"}, - {file = "cryptography-3.4.7-cp36-abi3-win_amd64.whl", hash = "sha256:de4e5f7f68220d92b7637fc99847475b59154b7a1b3868fb7385337af54ac9ca"}, - {file = "cryptography-3.4.7-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:26965837447f9c82f1855e0bc8bc4fb910240b6e0d16a664bb722df3b5b06873"}, - {file = "cryptography-3.4.7-pp36-pypy36_pp73-manylinux2014_x86_64.whl", hash = "sha256:eb8cc2afe8b05acbd84a43905832ec78e7b3873fb124ca190f574dca7389a87d"}, - {file = "cryptography-3.4.7-pp37-pypy37_pp73-macosx_10_10_x86_64.whl", hash = "sha256:b01fd6f2737816cb1e08ed4807ae194404790eac7ad030b34f2ce72b332f5586"}, - {file = "cryptography-3.4.7-pp37-pypy37_pp73-manylinux2010_x86_64.whl", hash = "sha256:7ec5d3b029f5fa2b179325908b9cd93db28ab7b85bb6c1db56b10e0b54235177"}, - {file = "cryptography-3.4.7-pp37-pypy37_pp73-manylinux2014_x86_64.whl", hash = "sha256:ee77aa129f481be46f8d92a1a7db57269a2f23052d5f2433b4621bb457081cc9"}, - {file = "cryptography-3.4.7-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:bf40af59ca2465b24e54f671b2de2c59257ddc4f7e5706dbd6930e26823668d3"}, - {file = "cryptography-3.4.7.tar.gz", hash = "sha256:3d10de8116d25649631977cb37da6cbdd2d6fa0e0281d014a5b7d337255ca713"}, + {file = "cryptography-35.0.0-cp36-abi3-macosx_10_10_x86_64.whl", hash = "sha256:d57e0cdc1b44b6cdf8af1d01807db06886f10177469312fbde8f44ccbb284bc9"}, + {file = "cryptography-35.0.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:ced40344e811d6abba00295ced98c01aecf0c2de39481792d87af4fa58b7b4d6"}, + {file = "cryptography-35.0.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:54b2605e5475944e2213258e0ab8696f4f357a31371e538ef21e8d61c843c28d"}, + {file = "cryptography-35.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:7b7ceeff114c31f285528ba8b390d3e9cfa2da17b56f11d366769a807f17cbaa"}, + {file = "cryptography-35.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d69645f535f4b2c722cfb07a8eab916265545b3475fdb34e0be2f4ee8b0b15e"}, + {file = "cryptography-35.0.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a2d0e0acc20ede0f06ef7aa58546eee96d2592c00f450c9acb89c5879b61992"}, + {file = "cryptography-35.0.0-cp36-abi3-manylinux_2_24_x86_64.whl", hash = "sha256:07bb7fbfb5de0980590ddfc7f13081520def06dc9ed214000ad4372fb4e3c7f6"}, + {file = "cryptography-35.0.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:7eba2cebca600a7806b893cb1d541a6e910afa87e97acf2021a22b32da1df52d"}, + {file = "cryptography-35.0.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:18d90f4711bf63e2fb21e8c8e51ed8189438e6b35a6d996201ebd98a26abbbe6"}, + {file = "cryptography-35.0.0-cp36-abi3-win32.whl", hash = "sha256:c10c797ac89c746e488d2ee92bd4abd593615694ee17b2500578b63cad6b93a8"}, + {file = "cryptography-35.0.0-cp36-abi3-win_amd64.whl", hash = "sha256:7075b304cd567694dc692ffc9747f3e9cb393cc4aa4fb7b9f3abd6f5c4e43588"}, + {file = "cryptography-35.0.0-pp36-pypy36_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a688ebcd08250eab5bb5bca318cc05a8c66de5e4171a65ca51db6bd753ff8953"}, + {file = "cryptography-35.0.0-pp36-pypy36_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d99915d6ab265c22873f1b4d6ea5ef462ef797b4140be4c9d8b179915e0985c6"}, + {file = "cryptography-35.0.0-pp36-pypy36_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:928185a6d1ccdb816e883f56ebe92e975a262d31cc536429041921f8cb5a62fd"}, + {file = "cryptography-35.0.0-pp37-pypy37_pp73-macosx_10_10_x86_64.whl", hash = "sha256:ebeddd119f526bcf323a89f853afb12e225902a24d29b55fe18dd6fcb2838a76"}, + {file = "cryptography-35.0.0-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:22a38e96118a4ce3b97509443feace1d1011d0571fae81fc3ad35f25ba3ea999"}, + {file = "cryptography-35.0.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb80e8a1f91e4b7ef8b33041591e6d89b2b8e122d787e87eeb2b08da71bb16ad"}, + {file = "cryptography-35.0.0-pp37-pypy37_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:abb5a361d2585bb95012a19ed9b2c8f412c5d723a9836418fab7aaa0243e67d2"}, + {file = "cryptography-35.0.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:1ed82abf16df40a60942a8c211251ae72858b25b7421ce2497c2eb7a1cee817c"}, + {file = "cryptography-35.0.0.tar.gz", hash = "sha256:9933f28f70d0517686bd7de36166dda42094eac49415459d9bdf5e7df3e0086d"}, ] cx-freeze = [] cx-logging = [ @@ -1812,13 +1842,13 @@ dnspython = [ {file = "dnspython-2.1.0.zip", hash = "sha256:e4a87f0b573201a0f3727fa18a516b055fd1107e0e5477cded4a2de497df1dd4"}, ] docutils = [ - {file = "docutils-0.16-py2.py3-none-any.whl", hash = "sha256:0c5b78adfbf7762415433f5515cd5c9e762339e23369dbe8000d84a4bf4ab3af"}, - {file = "docutils-0.16.tar.gz", hash = "sha256:c2de3a60e9e7d07be26b7f2b00ca0309c207e06c100f9cc2a94931fc75a478fc"}, + {file = "docutils-0.18-py2.py3-none-any.whl", hash = "sha256:a31688b2ea858517fa54293e5d5df06fbb875fb1f7e4c64529271b77781ca8fc"}, + {file = "docutils-0.18.tar.gz", hash = "sha256:c1d5dab2b11d16397406a282e53953fe495a46d69ae329f55aa98a5c4e3c5fbb"}, ] dropbox = [ - {file = "dropbox-11.20.0-py2-none-any.whl", hash = "sha256:0926aab25445fe78b0284e0b86f4126ec4e5e2bf6cd2ac8562002008a21073b8"}, - {file = "dropbox-11.20.0-py3-none-any.whl", hash = "sha256:f2106aa566f9e3c175879c226c60b7089a39099b228061acbb7258670f6b859c"}, - {file = "dropbox-11.20.0.tar.gz", hash = "sha256:1aa351ec8bbb11cf3560e731b81d25f39c7edcb5fa92c06c5d68866cb9f90d54"}, + {file = "dropbox-11.22.0-py2-none-any.whl", hash = "sha256:f2efc924529be2e2e2a1d6f49246b25966c201b23dda231dfb148a6f5ae1a149"}, + {file = "dropbox-11.22.0-py3-none-any.whl", hash = "sha256:0a9cc253391cae7fccf1954da75edf8459d6567ba764e21b471019f0fa001ab4"}, + {file = "dropbox-11.22.0.tar.gz", hash = "sha256:ab84c9c78606faa0dc94cdb95c6b2bdb579beb5f34fff42091c98a1e0fbeb16c"}, ] enlighten = [ {file = "enlighten-1.10.1-py2.py3-none-any.whl", hash = "sha256:3d6c3eec8cf3eb626ee7b65eddc1b3e904d01f4547a2b9fe7f1da8892a0297e8"}, @@ -1839,24 +1869,24 @@ future = [ {file = "future-0.18.2.tar.gz", hash = "sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d"}, ] gitdb = [ - {file = "gitdb-4.0.7-py3-none-any.whl", hash = "sha256:6c4cc71933456991da20917998acbe6cf4fb41eeaab7d6d67fbc05ecd4c865b0"}, - {file = "gitdb-4.0.7.tar.gz", hash = "sha256:96bf5c08b157a666fec41129e6d327235284cca4c81e92109260f353ba138005"}, + {file = "gitdb-4.0.9-py3-none-any.whl", hash = "sha256:8033ad4e853066ba6ca92050b9df2f89301b8fc8bf7e9324d412a63f8bf1a8fd"}, + {file = "gitdb-4.0.9.tar.gz", hash = "sha256:bac2fd45c0a1c9cf619e63a90d62bdc63892ef92387424b855792a6cabe789aa"}, ] gitpython = [ - {file = "GitPython-3.1.17-py3-none-any.whl", hash = "sha256:29fe82050709760081f588dd50ce83504feddbebdc4da6956d02351552b1c135"}, - {file = "GitPython-3.1.17.tar.gz", hash = "sha256:ee24bdc93dce357630764db659edaf6b8d664d4ff5447ccfeedd2dc5c253f41e"}, + {file = "GitPython-3.1.24-py3-none-any.whl", hash = "sha256:dc0a7f2f697657acc8d7f89033e8b1ea94dd90356b2983bca89dc8d2ab3cc647"}, + {file = "GitPython-3.1.24.tar.gz", hash = "sha256:df83fdf5e684fef7c6ee2c02fc68a5ceb7e7e759d08b694088d0cacb4eba59e5"}, ] google-api-core = [ - {file = "google-api-core-1.30.0.tar.gz", hash = "sha256:0724d354d394b3d763bc10dfee05807813c5210f0bd9b8e2ddf6b6925603411c"}, - {file = "google_api_core-1.30.0-py2.py3-none-any.whl", hash = "sha256:92cd9e9f366e84bfcf2524e34d2dc244906c645e731962617ba620da1620a1e0"}, + {file = "google-api-core-1.31.3.tar.gz", hash = "sha256:4b7ad965865aef22afa4aded3318b8fa09b20bcc7e8dbb639a3753cf60af08ea"}, + {file = "google_api_core-1.31.3-py2.py3-none-any.whl", hash = "sha256:f52c708ab9fd958862dea9ac94d9db1a065608073fe583c3b9c18537b177f59a"}, ] google-api-python-client = [ {file = "google-api-python-client-1.12.8.tar.gz", hash = "sha256:f3b9684442eec2cfe9f9bb48e796ef919456b82142c7528c5fd527e5224f08bb"}, {file = "google_api_python_client-1.12.8-py2.py3-none-any.whl", hash = "sha256:3c4c4ca46b5c21196bec7ee93453443e477d82cbfa79234d1ce0645f81170eaf"}, ] google-auth = [ - {file = "google-auth-1.31.0.tar.gz", hash = "sha256:154f7889c5d679a6f626f36adb12afbd4dbb0a9a04ec575d989d6ba79c4fd65e"}, - {file = "google_auth-1.31.0-py2.py3-none-any.whl", hash = "sha256:6d47c79b5d09fbc7e8355fd9594cc4cf65fdde5d401c63951eaac4baa1ba2ae1"}, + {file = "google-auth-1.35.0.tar.gz", hash = "sha256:b7033be9028c188ee30200b204ea00ed82ea1162e8ac1df4aa6ded19a191d88e"}, + {file = "google_auth-1.35.0-py2.py3-none-any.whl", hash = "sha256:997516b42ecb5b63e8d80f5632c1a61dddf41d2a4c2748057837e06e00014258"}, ] google-auth-httplib2 = [ {file = "google-auth-httplib2-0.1.0.tar.gz", hash = "sha256:a07c39fd632becacd3f07718dfd6021bf396978f03ad3ce4321d060015cc30ac"}, @@ -1867,8 +1897,8 @@ googleapis-common-protos = [ {file = "googleapis_common_protos-1.53.0-py2.py3-none-any.whl", hash = "sha256:f6d561ab8fb16b30020b940e2dd01cd80082f4762fa9f3ee670f4419b4b8dbd0"}, ] httplib2 = [ - {file = "httplib2-0.19.1-py3-none-any.whl", hash = "sha256:2ad195faf9faf079723f6714926e9a9061f694d07724b846658ce08d40f522b4"}, - {file = "httplib2-0.19.1.tar.gz", hash = "sha256:0b12617eeca7433d4c396a100eaecfa4b08ee99aa881e6df6e257a7aad5d533d"}, + {file = "httplib2-0.20.1-py3-none-any.whl", hash = "sha256:8fa4dbf2fbf839b71f8c7837a831e00fcdc860feca99b8bda58ceae4bc53d185"}, + {file = "httplib2-0.20.1.tar.gz", hash = "sha256:0efbcb8bfbfbc11578130d87d8afcc65c2274c6eb446e59fc674e4d7c972d327"}, ] idna = [ {file = "idna-2.10-py2.py3-none-any.whl", hash = "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"}, @@ -1879,24 +1909,24 @@ imagesize = [ {file = "imagesize-1.2.0.tar.gz", hash = "sha256:b1f6b5a4eab1f73479a50fb79fcf729514a900c341d8503d62a62dbc4127a2b1"}, ] importlib-metadata = [ - {file = "importlib_metadata-4.5.0-py3-none-any.whl", hash = "sha256:833b26fb89d5de469b24a390e9df088d4e52e4ba33b01dc5e0e4f41b81a16c00"}, - {file = "importlib_metadata-4.5.0.tar.gz", hash = "sha256:b142cc1dd1342f31ff04bb7d022492b09920cb64fed867cd3ea6f80fe3ebd139"}, + {file = "importlib_metadata-4.8.1-py3-none-any.whl", hash = "sha256:b618b6d2d5ffa2f16add5697cf57a46c76a56229b0ed1c438322e4e95645bd15"}, + {file = "importlib_metadata-4.8.1.tar.gz", hash = "sha256:f284b3e11256ad1e5d03ab86bb2ccd6f5339688ff17a4d797a0fe7df326f23b1"}, ] iniconfig = [ {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, ] isort = [ - {file = "isort-5.8.0-py3-none-any.whl", hash = "sha256:2bb1680aad211e3c9944dbce1d4ba09a989f04e238296c87fe2139faa26d655d"}, - {file = "isort-5.8.0.tar.gz", hash = "sha256:0a943902919f65c5684ac4e0154b1ad4fac6dcaa5d9f3426b732f1c8b5419be6"}, + {file = "isort-5.9.3-py3-none-any.whl", hash = "sha256:e17d6e2b81095c9db0a03a8025a957f334d6ea30b26f9ec70805411e5c7c81f2"}, + {file = "isort-5.9.3.tar.gz", hash = "sha256:9c2ea1e62d871267b78307fe511c0838ba0da28698c5732d54e2790bf3ba9899"}, ] jedi = [ {file = "jedi-0.13.3-py2.py3-none-any.whl", hash = "sha256:2c6bcd9545c7d6440951b12b44d373479bf18123a401a52025cf98563fbd826c"}, {file = "jedi-0.13.3.tar.gz", hash = "sha256:2bb0603e3506f708e792c7f4ad8fc2a7a9d9c2d292a358fbbd58da531695595b"}, ] jeepney = [ - {file = "jeepney-0.6.0-py3-none-any.whl", hash = "sha256:aec56c0eb1691a841795111e184e13cad504f7703b9a64f63020816afa79a8ae"}, - {file = "jeepney-0.6.0.tar.gz", hash = "sha256:7d59b6622675ca9e993a6bd38de845051d315f8b0c72cca3aef733a20b648657"}, + {file = "jeepney-0.7.1-py3-none-any.whl", hash = "sha256:1b5a0ea5c0e7b166b2f5895b91a08c14de8915afda4407fb5022a195224958ac"}, + {file = "jeepney-0.7.1.tar.gz", hash = "sha256:fa9e232dfa0c498bd0b8a3a73b8d8a31978304dcef0515adc859d4e096f96f4f"}, ] jinja2 = [ {file = "Jinja2-2.11.3-py2.py3-none-any.whl", hash = "sha256:03e47ad063331dd6a3f04a43eddca8a966a26ba0c5b7207a9a9e4e08f1b29419"}, @@ -1942,22 +1972,12 @@ log4mongo = [ {file = "log4mongo-1.7.0.tar.gz", hash = "sha256:dc374617206162a0b14167fbb5feac01dbef587539a235dadba6200362984a68"}, ] markupsafe = [ - {file = "MarkupSafe-2.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d8446c54dc28c01e5a2dbac5a25f071f6653e6e40f3a8818e8b45d790fe6ef53"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:36bc903cbb393720fad60fc28c10de6acf10dc6cc883f3e24ee4012371399a38"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-win32.whl", hash = "sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:baa1a4e8f868845af802979fcdbf0bb11f94f1cb7ced4c4b8a351bb60d108145"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-win32.whl", hash = "sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567"}, @@ -1966,21 +1986,14 @@ markupsafe = [ {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:60bf42e36abfaf9aff1f50f52644b336d4f0a3fd6d8a60ca0d054ac9f713a864"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-win32.whl", hash = "sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9"}, {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3dd007d54ee88b46be476e293f48c85048603f5f516008bee124ddd891398ed6"}, {file = "MarkupSafe-2.0.1-cp38-cp38-win32.whl", hash = "sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64"}, {file = "MarkupSafe-2.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833"}, {file = "MarkupSafe-2.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26"}, @@ -1990,9 +2003,6 @@ markupsafe = [ {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135"}, {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902"}, {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1f2ade76b9903f39aa442b4aadd2177decb66525062db244b35d71d0ee8599b6"}, {file = "MarkupSafe-2.0.1-cp39-cp39-win32.whl", hash = "sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74"}, {file = "MarkupSafe-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8"}, {file = "MarkupSafe-2.0.1.tar.gz", hash = "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a"}, @@ -2002,119 +2012,146 @@ mccabe = [ {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, ] multidict = [ - {file = "multidict-5.1.0-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:b7993704f1a4b204e71debe6095150d43b2ee6150fa4f44d6d966ec356a8d61f"}, - {file = "multidict-5.1.0-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:9dd6e9b1a913d096ac95d0399bd737e00f2af1e1594a787e00f7975778c8b2bf"}, - {file = "multidict-5.1.0-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:f21756997ad8ef815d8ef3d34edd98804ab5ea337feedcd62fb52d22bf531281"}, - {file = "multidict-5.1.0-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:1ab820665e67373de5802acae069a6a05567ae234ddb129f31d290fc3d1aa56d"}, - {file = "multidict-5.1.0-cp36-cp36m-manylinux2014_ppc64le.whl", hash = "sha256:9436dc58c123f07b230383083855593550c4d301d2532045a17ccf6eca505f6d"}, - {file = "multidict-5.1.0-cp36-cp36m-manylinux2014_s390x.whl", hash = "sha256:830f57206cc96ed0ccf68304141fec9481a096c4d2e2831f311bde1c404401da"}, - {file = "multidict-5.1.0-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:2e68965192c4ea61fff1b81c14ff712fc7dc15d2bd120602e4a3494ea6584224"}, - {file = "multidict-5.1.0-cp36-cp36m-win32.whl", hash = "sha256:2f1a132f1c88724674271d636e6b7351477c27722f2ed789f719f9e3545a3d26"}, - {file = "multidict-5.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:3a4f32116f8f72ecf2a29dabfb27b23ab7cdc0ba807e8459e59a93a9be9506f6"}, - {file = "multidict-5.1.0-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:46c73e09ad374a6d876c599f2328161bcd95e280f84d2060cf57991dec5cfe76"}, - {file = "multidict-5.1.0-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:018132dbd8688c7a69ad89c4a3f39ea2f9f33302ebe567a879da8f4ca73f0d0a"}, - {file = "multidict-5.1.0-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:4b186eb7d6ae7c06eb4392411189469e6a820da81447f46c0072a41c748ab73f"}, - {file = "multidict-5.1.0-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:3a041b76d13706b7fff23b9fc83117c7b8fe8d5fe9e6be45eee72b9baa75f348"}, - {file = "multidict-5.1.0-cp37-cp37m-manylinux2014_ppc64le.whl", hash = "sha256:051012ccee979b2b06be928a6150d237aec75dd6bf2d1eeeb190baf2b05abc93"}, - {file = "multidict-5.1.0-cp37-cp37m-manylinux2014_s390x.whl", hash = "sha256:6a4d5ce640e37b0efcc8441caeea8f43a06addace2335bd11151bc02d2ee31f9"}, - {file = "multidict-5.1.0-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:5cf3443199b83ed9e955f511b5b241fd3ae004e3cb81c58ec10f4fe47c7dce37"}, - {file = "multidict-5.1.0-cp37-cp37m-win32.whl", hash = "sha256:f200755768dc19c6f4e2b672421e0ebb3dd54c38d5a4f262b872d8cfcc9e93b5"}, - {file = "multidict-5.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:05c20b68e512166fddba59a918773ba002fdd77800cad9f55b59790030bab632"}, - {file = "multidict-5.1.0-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:54fd1e83a184e19c598d5e70ba508196fd0bbdd676ce159feb412a4a6664f952"}, - {file = "multidict-5.1.0-cp38-cp38-manylinux1_i686.whl", hash = "sha256:0e3c84e6c67eba89c2dbcee08504ba8644ab4284863452450520dad8f1e89b79"}, - {file = "multidict-5.1.0-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:dc862056f76443a0db4509116c5cd480fe1b6a2d45512a653f9a855cc0517456"}, - {file = "multidict-5.1.0-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:0e929169f9c090dae0646a011c8b058e5e5fb391466016b39d21745b48817fd7"}, - {file = "multidict-5.1.0-cp38-cp38-manylinux2014_ppc64le.whl", hash = "sha256:d81eddcb12d608cc08081fa88d046c78afb1bf8107e6feab5d43503fea74a635"}, - {file = "multidict-5.1.0-cp38-cp38-manylinux2014_s390x.whl", hash = "sha256:585fd452dd7782130d112f7ddf3473ffdd521414674c33876187e101b588738a"}, - {file = "multidict-5.1.0-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:37e5438e1c78931df5d3c0c78ae049092877e5e9c02dd1ff5abb9cf27a5914ea"}, - {file = "multidict-5.1.0-cp38-cp38-win32.whl", hash = "sha256:07b42215124aedecc6083f1ce6b7e5ec5b50047afa701f3442054373a6deb656"}, - {file = "multidict-5.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:929006d3c2d923788ba153ad0de8ed2e5ed39fdbe8e7be21e2f22ed06c6783d3"}, - {file = "multidict-5.1.0-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:b797515be8743b771aa868f83563f789bbd4b236659ba52243b735d80b29ed93"}, - {file = "multidict-5.1.0-cp39-cp39-manylinux1_i686.whl", hash = "sha256:d5c65bdf4484872c4af3150aeebe101ba560dcfb34488d9a8ff8dbcd21079647"}, - {file = "multidict-5.1.0-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:b47a43177a5e65b771b80db71e7be76c0ba23cc8aa73eeeb089ed5219cdbe27d"}, - {file = "multidict-5.1.0-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:806068d4f86cb06af37cd65821554f98240a19ce646d3cd24e1c33587f313eb8"}, - {file = "multidict-5.1.0-cp39-cp39-manylinux2014_ppc64le.whl", hash = "sha256:46dd362c2f045095c920162e9307de5ffd0a1bfbba0a6e990b344366f55a30c1"}, - {file = "multidict-5.1.0-cp39-cp39-manylinux2014_s390x.whl", hash = "sha256:ace010325c787c378afd7f7c1ac66b26313b3344628652eacd149bdd23c68841"}, - {file = "multidict-5.1.0-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:ecc771ab628ea281517e24fd2c52e8f31c41e66652d07599ad8818abaad38cda"}, - {file = "multidict-5.1.0-cp39-cp39-win32.whl", hash = "sha256:fc13a9524bc18b6fb6e0dbec3533ba0496bbed167c56d0aabefd965584557d80"}, - {file = "multidict-5.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:7df80d07818b385f3129180369079bd6934cf70469f99daaebfac89dca288359"}, - {file = "multidict-5.1.0.tar.gz", hash = "sha256:25b4e5f22d3a37ddf3effc0710ba692cfc792c2b9edfb9c05aefe823256e84d5"}, + {file = "multidict-5.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3822c5894c72e3b35aae9909bef66ec83e44522faf767c0ad39e0e2de11d3b55"}, + {file = "multidict-5.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:28e6d883acd8674887d7edc896b91751dc2d8e87fbdca8359591a13872799e4e"}, + {file = "multidict-5.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b61f85101ef08cbbc37846ac0e43f027f7844f3fade9b7f6dd087178caedeee7"}, + {file = "multidict-5.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d9b668c065968c5979fe6b6fa6760bb6ab9aeb94b75b73c0a9c1acf6393ac3bf"}, + {file = "multidict-5.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:517d75522b7b18a3385726b54a081afd425d4f41144a5399e5abd97ccafdf36b"}, + {file = "multidict-5.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1b4ac3ba7a97b35a5ccf34f41b5a8642a01d1e55454b699e5e8e7a99b5a3acf5"}, + {file = "multidict-5.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:df23c83398715b26ab09574217ca21e14694917a0c857e356fd39e1c64f8283f"}, + {file = "multidict-5.2.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e58a9b5cc96e014ddf93c2227cbdeca94b56a7eb77300205d6e4001805391747"}, + {file = "multidict-5.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:f76440e480c3b2ca7f843ff8a48dc82446b86ed4930552d736c0bac507498a52"}, + {file = "multidict-5.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:cfde464ca4af42a629648c0b0d79b8f295cf5b695412451716531d6916461628"}, + {file = "multidict-5.2.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:0fed465af2e0eb6357ba95795d003ac0bdb546305cc2366b1fc8f0ad67cc3fda"}, + {file = "multidict-5.2.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:b70913cbf2e14275013be98a06ef4b412329fe7b4f83d64eb70dce8269ed1e1a"}, + {file = "multidict-5.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a5635bcf1b75f0f6ef3c8a1ad07b500104a971e38d3683167b9454cb6465ac86"}, + {file = "multidict-5.2.0-cp310-cp310-win32.whl", hash = "sha256:77f0fb7200cc7dedda7a60912f2059086e29ff67cefbc58d2506638c1a9132d7"}, + {file = "multidict-5.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:9416cf11bcd73c861267e88aea71e9fcc35302b3943e45e1dbb4317f91a4b34f"}, + {file = "multidict-5.2.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:fd77c8f3cba815aa69cb97ee2b2ef385c7c12ada9c734b0f3b32e26bb88bbf1d"}, + {file = "multidict-5.2.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:98ec9aea6223adf46999f22e2c0ab6cf33f5914be604a404f658386a8f1fba37"}, + {file = "multidict-5.2.0-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e5283c0a00f48e8cafcecadebfa0ed1dac8b39e295c7248c44c665c16dc1138b"}, + {file = "multidict-5.2.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5f79c19c6420962eb17c7e48878a03053b7ccd7b69f389d5831c0a4a7f1ac0a1"}, + {file = "multidict-5.2.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:e4a67f1080123de76e4e97a18d10350df6a7182e243312426d508712e99988d4"}, + {file = "multidict-5.2.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:94b117e27efd8e08b4046c57461d5a114d26b40824995a2eb58372b94f9fca02"}, + {file = "multidict-5.2.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:2e77282fd1d677c313ffcaddfec236bf23f273c4fba7cdf198108f5940ae10f5"}, + {file = "multidict-5.2.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:116347c63ba049c1ea56e157fa8aa6edaf5e92925c9b64f3da7769bdfa012858"}, + {file = "multidict-5.2.0-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:dc3a866cf6c13d59a01878cd806f219340f3e82eed514485e094321f24900677"}, + {file = "multidict-5.2.0-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:ac42181292099d91217a82e3fa3ce0e0ddf3a74fd891b7c2b347a7f5aa0edded"}, + {file = "multidict-5.2.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:f0bb0973f42ffcb5e3537548e0767079420aefd94ba990b61cf7bb8d47f4916d"}, + {file = "multidict-5.2.0-cp36-cp36m-win32.whl", hash = "sha256:ea21d4d5104b4f840b91d9dc8cbc832aba9612121eaba503e54eaab1ad140eb9"}, + {file = "multidict-5.2.0-cp36-cp36m-win_amd64.whl", hash = "sha256:e6453f3cbeb78440747096f239d282cc57a2997a16b5197c9bc839099e1633d0"}, + {file = "multidict-5.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d3def943bfd5f1c47d51fd324df1e806d8da1f8e105cc7f1c76a1daf0f7e17b0"}, + {file = "multidict-5.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35591729668a303a02b06e8dba0eb8140c4a1bfd4c4b3209a436a02a5ac1de11"}, + {file = "multidict-5.2.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8cacda0b679ebc25624d5de66c705bc53dcc7c6f02a7fb0f3ca5e227d80422"}, + {file = "multidict-5.2.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:baf1856fab8212bf35230c019cde7c641887e3fc08cadd39d32a421a30151ea3"}, + {file = "multidict-5.2.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a43616aec0f0d53c411582c451f5d3e1123a68cc7b3475d6f7d97a626f8ff90d"}, + {file = "multidict-5.2.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:25cbd39a9029b409167aa0a20d8a17f502d43f2efebfe9e3ac019fe6796c59ac"}, + {file = "multidict-5.2.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:0a2cbcfbea6dc776782a444db819c8b78afe4db597211298dd8b2222f73e9cd0"}, + {file = "multidict-5.2.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:3d2d7d1fff8e09d99354c04c3fd5b560fb04639fd45926b34e27cfdec678a704"}, + {file = "multidict-5.2.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:a37e9a68349f6abe24130846e2f1d2e38f7ddab30b81b754e5a1fde32f782b23"}, + {file = "multidict-5.2.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:637c1896497ff19e1ee27c1c2c2ddaa9f2d134bbb5e0c52254361ea20486418d"}, + {file = "multidict-5.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:9815765f9dcda04921ba467957be543423e5ec6a1136135d84f2ae092c50d87b"}, + {file = "multidict-5.2.0-cp37-cp37m-win32.whl", hash = "sha256:8b911d74acdc1fe2941e59b4f1a278a330e9c34c6c8ca1ee21264c51ec9b67ef"}, + {file = "multidict-5.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:380b868f55f63d048a25931a1632818f90e4be71d2081c2338fcf656d299949a"}, + {file = "multidict-5.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e7d81ce5744757d2f05fc41896e3b2ae0458464b14b5a2c1e87a6a9d69aefaa8"}, + {file = "multidict-5.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2d1d55cdf706ddc62822d394d1df53573d32a7a07d4f099470d3cb9323b721b6"}, + {file = "multidict-5.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a4771d0d0ac9d9fe9e24e33bed482a13dfc1256d008d101485fe460359476065"}, + {file = "multidict-5.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da7d57ea65744d249427793c042094c4016789eb2562576fb831870f9c878d9e"}, + {file = "multidict-5.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cdd68778f96216596218b4e8882944d24a634d984ee1a5a049b300377878fa7c"}, + {file = "multidict-5.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ecc99bce8ee42dcad15848c7885197d26841cb24fa2ee6e89d23b8993c871c64"}, + {file = "multidict-5.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:067150fad08e6f2dd91a650c7a49ba65085303fcc3decbd64a57dc13a2733031"}, + {file = "multidict-5.2.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:78c106b2b506b4d895ddc801ff509f941119394b89c9115580014127414e6c2d"}, + {file = "multidict-5.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e6c4fa1ec16e01e292315ba76eb1d012c025b99d22896bd14a66628b245e3e01"}, + {file = "multidict-5.2.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:b227345e4186809d31f22087d0265655114af7cda442ecaf72246275865bebe4"}, + {file = "multidict-5.2.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:06560fbdcf22c9387100979e65b26fba0816c162b888cb65b845d3def7a54c9b"}, + {file = "multidict-5.2.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:7878b61c867fb2df7a95e44b316f88d5a3742390c99dfba6c557a21b30180cac"}, + {file = "multidict-5.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:246145bff76cc4b19310f0ad28bd0769b940c2a49fc601b86bfd150cbd72bb22"}, + {file = "multidict-5.2.0-cp38-cp38-win32.whl", hash = "sha256:c30ac9f562106cd9e8071c23949a067b10211917fdcb75b4718cf5775356a940"}, + {file = "multidict-5.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:f19001e790013ed580abfde2a4465388950728861b52f0da73e8e8a9418533c0"}, + {file = "multidict-5.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c1ff762e2ee126e6f1258650ac641e2b8e1f3d927a925aafcfde943b77a36d24"}, + {file = "multidict-5.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bd6c9c50bf2ad3f0448edaa1a3b55b2e6866ef8feca5d8dbec10ec7c94371d21"}, + {file = "multidict-5.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fc66d4016f6e50ed36fb39cd287a3878ffcebfa90008535c62e0e90a7ab713ae"}, + {file = "multidict-5.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a9acb76d5f3dd9421874923da2ed1e76041cb51b9337fd7f507edde1d86535d6"}, + {file = "multidict-5.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dfc924a7e946dd3c6360e50e8f750d51e3ef5395c95dc054bc9eab0f70df4f9c"}, + {file = "multidict-5.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:32fdba7333eb2351fee2596b756d730d62b5827d5e1ab2f84e6cbb287cc67fe0"}, + {file = "multidict-5.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:b9aad49466b8d828b96b9e3630006234879c8d3e2b0a9d99219b3121bc5cdb17"}, + {file = "multidict-5.2.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:93de39267c4c676c9ebb2057e98a8138bade0d806aad4d864322eee0803140a0"}, + {file = "multidict-5.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f9bef5cff994ca3026fcc90680e326d1a19df9841c5e3d224076407cc21471a1"}, + {file = "multidict-5.2.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:5f841c4f14331fd1e36cbf3336ed7be2cb2a8f110ce40ea253e5573387db7621"}, + {file = "multidict-5.2.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:38ba256ee9b310da6a1a0f013ef4e422fca30a685bcbec86a969bd520504e341"}, + {file = "multidict-5.2.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:3bc3b1621b979621cee9f7b09f024ec76ec03cc365e638126a056317470bde1b"}, + {file = "multidict-5.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6ee908c070020d682e9b42c8f621e8bb10c767d04416e2ebe44e37d0f44d9ad5"}, + {file = "multidict-5.2.0-cp39-cp39-win32.whl", hash = "sha256:1c7976cd1c157fa7ba5456ae5d31ccdf1479680dc9b8d8aa28afabc370df42b8"}, + {file = "multidict-5.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:c9631c642e08b9fff1c6255487e62971d8b8e821808ddd013d8ac058087591ac"}, + {file = "multidict-5.2.0.tar.gz", hash = "sha256:0dd1c93edb444b33ba2274b66f63def8a327d607c6c790772f448a53b6ea59ce"}, ] opentimelineio = [] packaging = [ - {file = "packaging-20.9-py2.py3-none-any.whl", hash = "sha256:67714da7f7bc052e064859c05c595155bd1ee9f69f76557e21f051443c20947a"}, - {file = "packaging-20.9.tar.gz", hash = "sha256:5b327ac1320dc863dca72f4514ecc086f31186744b84a230374cc1fd776feae5"}, + {file = "packaging-21.2-py3-none-any.whl", hash = "sha256:14317396d1e8cdb122989b916fa2c7e9ca8e2be9e8060a6eff75b6b7b4d8a7e0"}, + {file = "packaging-21.2.tar.gz", hash = "sha256:096d689d78ca690e4cd8a89568ba06d07ca097e3306a4381635073ca91479966"}, ] paramiko = [ - {file = "paramiko-2.7.2-py2.py3-none-any.whl", hash = "sha256:4f3e316fef2ac628b05097a637af35685183111d4bc1b5979bd397c2ab7b5898"}, - {file = "paramiko-2.7.2.tar.gz", hash = "sha256:7f36f4ba2c0d81d219f4595e35f70d56cc94f9ac40a6acdf51d6ca210ce65035"}, + {file = "paramiko-2.8.0-py2.py3-none-any.whl", hash = "sha256:def3ec612399bab4e9f5eb66b0ae5983980db9dd9120d9e9c6ea3ff673865d1c"}, + {file = "paramiko-2.8.0.tar.gz", hash = "sha256:e673b10ee0f1c80d46182d3af7751d033d9b573dd7054d2d0aa46be186c3c1d2"}, ] parso = [ {file = "parso-0.8.2-py2.py3-none-any.whl", hash = "sha256:a8c4922db71e4fdb90e0d0bc6e50f9b273d3397925e5e60a717e719201778d22"}, {file = "parso-0.8.2.tar.gz", hash = "sha256:12b83492c6239ce32ff5eed6d3639d6a536170723c6f3f1506869f1ace413398"}, ] pathlib2 = [ - {file = "pathlib2-2.3.5-py2.py3-none-any.whl", hash = "sha256:0ec8205a157c80d7acc301c0b18fbd5d44fe655968f5d947b6ecef5290fc35db"}, - {file = "pathlib2-2.3.5.tar.gz", hash = "sha256:6cd9a47b597b37cc57de1c05e56fb1a1c9cc9fab04fe78c29acd090418529868"}, + {file = "pathlib2-2.3.6-py2.py3-none-any.whl", hash = "sha256:3a130b266b3a36134dcc79c17b3c7ac9634f083825ca6ea9d8f557ee6195c9c8"}, + {file = "pathlib2-2.3.6.tar.gz", hash = "sha256:7d8bcb5555003cdf4a8d2872c538faa3a0f5d20630cb360e518ca3b981795e5f"}, ] pillow = [ - {file = "Pillow-8.3.2-cp310-cp310-macosx_10_10_universal2.whl", hash = "sha256:c691b26283c3a31594683217d746f1dad59a7ae1d4cfc24626d7a064a11197d4"}, - {file = "Pillow-8.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f514c2717012859ccb349c97862568fdc0479aad85b0270d6b5a6509dbc142e2"}, - {file = "Pillow-8.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be25cb93442c6d2f8702c599b51184bd3ccd83adebd08886b682173e09ef0c3f"}, - {file = "Pillow-8.3.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d675a876b295afa114ca8bf42d7f86b5fb1298e1b6bb9a24405a3f6c8338811c"}, - {file = "Pillow-8.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59697568a0455764a094585b2551fd76bfd6b959c9f92d4bdec9d0e14616303a"}, - {file = "Pillow-8.3.2-cp310-cp310-win32.whl", hash = "sha256:2d5e9dc0bf1b5d9048a94c48d0813b6c96fccfa4ccf276d9c36308840f40c228"}, - {file = "Pillow-8.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:11c27e74bab423eb3c9232d97553111cc0be81b74b47165f07ebfdd29d825875"}, - {file = "Pillow-8.3.2-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:11eb7f98165d56042545c9e6db3ce394ed8b45089a67124298f0473b29cb60b2"}, - {file = "Pillow-8.3.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f23b2d3079522fdf3c09de6517f625f7a964f916c956527bed805ac043799b8"}, - {file = "Pillow-8.3.2-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:19ec4cfe4b961edc249b0e04b5618666c23a83bc35842dea2bfd5dfa0157f81b"}, - {file = "Pillow-8.3.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5a31c07cea5edbaeb4bdba6f2b87db7d3dc0f446f379d907e51cc70ea375629"}, - {file = "Pillow-8.3.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:15ccb81a6ffc57ea0137f9f3ac2737ffa1d11f786244d719639df17476d399a7"}, - {file = "Pillow-8.3.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:8f284dc1695caf71a74f24993b7c7473d77bc760be45f776a2c2f4e04c170550"}, - {file = "Pillow-8.3.2-cp36-cp36m-win32.whl", hash = "sha256:4abc247b31a98f29e5224f2d31ef15f86a71f79c7f4d2ac345a5d551d6393073"}, - {file = "Pillow-8.3.2-cp36-cp36m-win_amd64.whl", hash = "sha256:a048dad5ed6ad1fad338c02c609b862dfaa921fcd065d747194a6805f91f2196"}, - {file = "Pillow-8.3.2-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:06d1adaa284696785375fa80a6a8eb309be722cf4ef8949518beb34487a3df71"}, - {file = "Pillow-8.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd24054aaf21e70a51e2a2a5ed1183560d3a69e6f9594a4bfe360a46f94eba83"}, - {file = "Pillow-8.3.2-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27a330bf7014ee034046db43ccbb05c766aa9e70b8d6c5260bfc38d73103b0ba"}, - {file = "Pillow-8.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13654b521fb98abdecec105ea3fb5ba863d1548c9b58831dd5105bb3873569f1"}, - {file = "Pillow-8.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a1bd983c565f92779be456ece2479840ec39d386007cd4ae83382646293d681b"}, - {file = "Pillow-8.3.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:4326ea1e2722f3dc00ed77c36d3b5354b8fb7399fb59230249ea6d59cbed90da"}, - {file = "Pillow-8.3.2-cp37-cp37m-win32.whl", hash = "sha256:085a90a99404b859a4b6c3daa42afde17cb3ad3115e44a75f0d7b4a32f06a6c9"}, - {file = "Pillow-8.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:18a07a683805d32826c09acfce44a90bf474e6a66ce482b1c7fcd3757d588df3"}, - {file = "Pillow-8.3.2-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:4e59e99fd680e2b8b11bbd463f3c9450ab799305d5f2bafb74fefba6ac058616"}, - {file = "Pillow-8.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4d89a2e9219a526401015153c0e9dd48319ea6ab9fe3b066a20aa9aee23d9fd3"}, - {file = "Pillow-8.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56fd98c8294f57636084f4b076b75f86c57b2a63a8410c0cd172bc93695ee979"}, - {file = "Pillow-8.3.2-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2b11c9d310a3522b0fd3c35667914271f570576a0e387701f370eb39d45f08a4"}, - {file = "Pillow-8.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0412516dcc9de9b0a1e0ae25a280015809de8270f134cc2c1e32c4eeb397cf30"}, - {file = "Pillow-8.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bcb04ff12e79b28be6c9988f275e7ab69f01cc2ba319fb3114f87817bb7c74b6"}, - {file = "Pillow-8.3.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:0b9911ec70731711c3b6ebcde26caea620cbdd9dcb73c67b0730c8817f24711b"}, - {file = "Pillow-8.3.2-cp38-cp38-win32.whl", hash = "sha256:ce2e5e04bb86da6187f96d7bab3f93a7877830981b37f0287dd6479e27a10341"}, - {file = "Pillow-8.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:35d27687f027ad25a8d0ef45dd5208ef044c588003cdcedf05afb00dbc5c2deb"}, - {file = "Pillow-8.3.2-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:04835e68ef12904bc3e1fd002b33eea0779320d4346082bd5b24bec12ad9c3e9"}, - {file = "Pillow-8.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:10e00f7336780ca7d3653cf3ac26f068fa11b5a96894ea29a64d3dc4b810d630"}, - {file = "Pillow-8.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cde7a4d3687f21cffdf5bb171172070bb95e02af448c4c8b2f223d783214056"}, - {file = "Pillow-8.3.2-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c3ff00110835bdda2b1e2b07f4a2548a39744bb7de5946dc8e95517c4fb2ca6"}, - {file = "Pillow-8.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:35d409030bf3bd05fa66fb5fdedc39c521b397f61ad04309c90444e893d05f7d"}, - {file = "Pillow-8.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6bff50ba9891be0a004ef48828e012babaaf7da204d81ab9be37480b9020a82b"}, - {file = "Pillow-8.3.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7dbfbc0020aa1d9bc1b0b8bcf255a7d73f4ad0336f8fd2533fcc54a4ccfb9441"}, - {file = "Pillow-8.3.2-cp39-cp39-win32.whl", hash = "sha256:963ebdc5365d748185fdb06daf2ac758116deecb2277ec5ae98139f93844bc09"}, - {file = "Pillow-8.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:cc9d0dec711c914ed500f1d0d3822868760954dce98dfb0b7382a854aee55d19"}, - {file = "Pillow-8.3.2-pp36-pypy36_pp73-macosx_10_10_x86_64.whl", hash = "sha256:2c661542c6f71dfd9dc82d9d29a8386287e82813b0375b3a02983feac69ef864"}, - {file = "Pillow-8.3.2-pp36-pypy36_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:548794f99ff52a73a156771a0402f5e1c35285bd981046a502d7e4793e8facaa"}, - {file = "Pillow-8.3.2-pp36-pypy36_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8b68f565a4175e12e68ca900af8910e8fe48aaa48fd3ca853494f384e11c8bcd"}, - {file = "Pillow-8.3.2-pp36-pypy36_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:838eb85de6d9307c19c655c726f8d13b8b646f144ca6b3771fa62b711ebf7624"}, - {file = "Pillow-8.3.2-pp36-pypy36_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:feb5db446e96bfecfec078b943cc07744cc759893cef045aa8b8b6d6aaa8274e"}, - {file = "Pillow-8.3.2-pp37-pypy37_pp73-macosx_10_10_x86_64.whl", hash = "sha256:fc0db32f7223b094964e71729c0361f93db43664dd1ec86d3df217853cedda87"}, - {file = "Pillow-8.3.2-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:fd4fd83aa912d7b89b4b4a1580d30e2a4242f3936882a3f433586e5ab97ed0d5"}, - {file = "Pillow-8.3.2-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d0c8ebbfd439c37624db98f3877d9ed12c137cadd99dde2d2eae0dab0bbfc355"}, - {file = "Pillow-8.3.2-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6cb3dd7f23b044b0737317f892d399f9e2f0b3a02b22b2c692851fb8120d82c6"}, - {file = "Pillow-8.3.2-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a66566f8a22561fc1a88dc87606c69b84fa9ce724f99522cf922c801ec68f5c1"}, - {file = "Pillow-8.3.2-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:ce651ca46d0202c302a535d3047c55a0131a720cf554a578fc1b8a2aff0e7d96"}, - {file = "Pillow-8.3.2.tar.gz", hash = "sha256:dde3f3ed8d00c72631bc19cbfff8ad3b6215062a5eed402381ad365f82f0c18c"}, + {file = "Pillow-8.4.0-cp310-cp310-macosx_10_10_universal2.whl", hash = "sha256:81f8d5c81e483a9442d72d182e1fb6dcb9723f289a57e8030811bac9ea3fef8d"}, + {file = "Pillow-8.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3f97cfb1e5a392d75dd8b9fd274d205404729923840ca94ca45a0af57e13dbe6"}, + {file = "Pillow-8.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb9fc393f3c61f9054e1ed26e6fe912c7321af2f41ff49d3f83d05bacf22cc78"}, + {file = "Pillow-8.4.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d82cdb63100ef5eedb8391732375e6d05993b765f72cb34311fab92103314649"}, + {file = "Pillow-8.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:62cc1afda735a8d109007164714e73771b499768b9bb5afcbbee9d0ff374b43f"}, + {file = "Pillow-8.4.0-cp310-cp310-win32.whl", hash = "sha256:e3dacecfbeec9a33e932f00c6cd7996e62f53ad46fbe677577394aaa90ee419a"}, + {file = "Pillow-8.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:620582db2a85b2df5f8a82ddeb52116560d7e5e6b055095f04ad828d1b0baa39"}, + {file = "Pillow-8.4.0-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:1bc723b434fbc4ab50bb68e11e93ce5fb69866ad621e3c2c9bdb0cd70e345f55"}, + {file = "Pillow-8.4.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:72cbcfd54df6caf85cc35264c77ede902452d6df41166010262374155947460c"}, + {file = "Pillow-8.4.0-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:70ad9e5c6cb9b8487280a02c0ad8a51581dcbbe8484ce058477692a27c151c0a"}, + {file = "Pillow-8.4.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:25a49dc2e2f74e65efaa32b153527fc5ac98508d502fa46e74fa4fd678ed6645"}, + {file = "Pillow-8.4.0-cp36-cp36m-win32.whl", hash = "sha256:93ce9e955cc95959df98505e4608ad98281fff037350d8c2671c9aa86bcf10a9"}, + {file = "Pillow-8.4.0-cp36-cp36m-win_amd64.whl", hash = "sha256:2e4440b8f00f504ee4b53fe30f4e381aae30b0568193be305256b1462216feff"}, + {file = "Pillow-8.4.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:8c803ac3c28bbc53763e6825746f05cc407b20e4a69d0122e526a582e3b5e153"}, + {file = "Pillow-8.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c8a17b5d948f4ceeceb66384727dde11b240736fddeda54ca740b9b8b1556b29"}, + {file = "Pillow-8.4.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1394a6ad5abc838c5cd8a92c5a07535648cdf6d09e8e2d6df916dfa9ea86ead8"}, + {file = "Pillow-8.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:792e5c12376594bfcb986ebf3855aa4b7c225754e9a9521298e460e92fb4a488"}, + {file = "Pillow-8.4.0-cp37-cp37m-win32.whl", hash = "sha256:d99ec152570e4196772e7a8e4ba5320d2d27bf22fdf11743dd882936ed64305b"}, + {file = "Pillow-8.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:7b7017b61bbcdd7f6363aeceb881e23c46583739cb69a3ab39cb384f6ec82e5b"}, + {file = "Pillow-8.4.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:d89363f02658e253dbd171f7c3716a5d340a24ee82d38aab9183f7fdf0cdca49"}, + {file = "Pillow-8.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0a0956fdc5defc34462bb1c765ee88d933239f9a94bc37d132004775241a7585"}, + {file = "Pillow-8.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b7bb9de00197fb4261825c15551adf7605cf14a80badf1761d61e59da347779"}, + {file = "Pillow-8.4.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:72b9e656e340447f827885b8d7a15fc8c4e68d410dc2297ef6787eec0f0ea409"}, + {file = "Pillow-8.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a5a4532a12314149d8b4e4ad8ff09dde7427731fcfa5917ff16d0291f13609df"}, + {file = "Pillow-8.4.0-cp38-cp38-win32.whl", hash = "sha256:82aafa8d5eb68c8463b6e9baeb4f19043bb31fefc03eb7b216b51e6a9981ae09"}, + {file = "Pillow-8.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:066f3999cb3b070a95c3652712cffa1a748cd02d60ad7b4e485c3748a04d9d76"}, + {file = "Pillow-8.4.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:5503c86916d27c2e101b7f71c2ae2cddba01a2cf55b8395b0255fd33fa4d1f1a"}, + {file = "Pillow-8.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4acc0985ddf39d1bc969a9220b51d94ed51695d455c228d8ac29fcdb25810e6e"}, + {file = "Pillow-8.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b052a619a8bfcf26bd8b3f48f45283f9e977890263e4571f2393ed8898d331b"}, + {file = "Pillow-8.4.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:493cb4e415f44cd601fcec11c99836f707bb714ab03f5ed46ac25713baf0ff20"}, + {file = "Pillow-8.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8831cb7332eda5dc89b21a7bce7ef6ad305548820595033a4b03cf3091235ed"}, + {file = "Pillow-8.4.0-cp39-cp39-win32.whl", hash = "sha256:5e9ac5f66616b87d4da618a20ab0a38324dbe88d8a39b55be8964eb520021e02"}, + {file = "Pillow-8.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:3eb1ce5f65908556c2d8685a8f0a6e989d887ec4057326f6c22b24e8a172c66b"}, + {file = "Pillow-8.4.0-pp36-pypy36_pp73-macosx_10_10_x86_64.whl", hash = "sha256:ddc4d832a0f0b4c52fff973a0d44b6c99839a9d016fe4e6a1cb8f3eea96479c2"}, + {file = "Pillow-8.4.0-pp36-pypy36_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a3e5ddc44c14042f0844b8cf7d2cd455f6cc80fd7f5eefbe657292cf601d9ad"}, + {file = "Pillow-8.4.0-pp36-pypy36_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c70e94281588ef053ae8998039610dbd71bc509e4acbc77ab59d7d2937b10698"}, + {file = "Pillow-8.4.0-pp37-pypy37_pp73-macosx_10_10_x86_64.whl", hash = "sha256:3862b7256046fcd950618ed22d1d60b842e3a40a48236a5498746f21189afbbc"}, + {file = "Pillow-8.4.0-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a4901622493f88b1a29bd30ec1a2f683782e57c3c16a2dbc7f2595ba01f639df"}, + {file = "Pillow-8.4.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84c471a734240653a0ec91dec0996696eea227eafe72a33bd06c92697728046b"}, + {file = "Pillow-8.4.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:244cf3b97802c34c41905d22810846802a3329ddcb93ccc432870243211c79fc"}, + {file = "Pillow-8.4.0.tar.gz", hash = "sha256:b8e2f83c56e141920c39464b852de3719dfbfb6e3c99a2d8da0edf4fb33176ed"}, +] +platformdirs = [ + {file = "platformdirs-2.4.0-py3-none-any.whl", hash = "sha256:8868bbe3c3c80d42f20156f22e7131d2fb321f5bc86a2a345375c6481a67021d"}, + {file = "platformdirs-2.4.0.tar.gz", hash = "sha256:367a5e80b3d04d2428ffa76d33f124cf11e8fff2acdaa9b43d545f5c7d661ef2"}, ] pluggy = [ - {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"}, - {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"}, + {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, + {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, ] ply = [ {file = "ply-3.11-py2.py3-none-any.whl", hash = "sha256:096f9b8350b65ebd2fd1346b12452efe5b9607f7482813ffca50c22722a807ce"}, @@ -2143,13 +2180,9 @@ protobuf = [ {file = "protobuf-3.17.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2ae692bb6d1992afb6b74348e7bb648a75bb0d3565a3f5eea5bec8f62bd06d87"}, {file = "protobuf-3.17.3-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:99938f2a2d7ca6563c0ade0c5ca8982264c484fdecf418bd68e880a7ab5730b1"}, {file = "protobuf-3.17.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6902a1e4b7a319ec611a7345ff81b6b004b36b0d2196ce7a748b3493da3d226d"}, - {file = "protobuf-3.17.3-cp38-cp38-win32.whl", hash = "sha256:59e5cf6b737c3a376932fbfb869043415f7c16a0cf176ab30a5bbc419cd709c1"}, - {file = "protobuf-3.17.3-cp38-cp38-win_amd64.whl", hash = "sha256:ebcb546f10069b56dc2e3da35e003a02076aaa377caf8530fe9789570984a8d2"}, {file = "protobuf-3.17.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4ffbd23640bb7403574f7aff8368e2aeb2ec9a5c6306580be48ac59a6bac8bde"}, {file = "protobuf-3.17.3-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:26010f693b675ff5a1d0e1bdb17689b8b716a18709113288fead438703d45539"}, {file = "protobuf-3.17.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:e76d9686e088fece2450dbc7ee905f9be904e427341d289acbe9ad00b78ebd47"}, - {file = "protobuf-3.17.3-cp39-cp39-win32.whl", hash = "sha256:a38bac25f51c93e4be4092c88b2568b9f407c27217d3dd23c7a57fa522a17554"}, - {file = "protobuf-3.17.3-cp39-cp39-win_amd64.whl", hash = "sha256:85d6303e4adade2827e43c2b54114d9a6ea547b671cb63fafd5011dc47d0e13d"}, {file = "protobuf-3.17.3-py2.py3-none-any.whl", hash = "sha256:2bfb815216a9cd9faec52b16fd2bfa68437a44b67c56bee59bc3926522ecb04e"}, {file = "protobuf-3.17.3.tar.gz", hash = "sha256:72804ea5eaa9c22a090d2803813e280fb273b62d5ae497aaf3553d141c4fdd7b"}, ] @@ -2212,78 +2245,121 @@ pyflakes = [ {file = "pyflakes-2.3.1.tar.gz", hash = "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db"}, ] pygments = [ - {file = "Pygments-2.9.0-py3-none-any.whl", hash = "sha256:d66e804411278594d764fc69ec36ec13d9ae9147193a1740cd34d272ca383b8e"}, - {file = "Pygments-2.9.0.tar.gz", hash = "sha256:a18f47b506a429f6f4b9df81bb02beab9ca21d0a5fee38ed15aef65f0545519f"}, + {file = "Pygments-2.10.0-py3-none-any.whl", hash = "sha256:b8e67fe6af78f492b3c4b3e2970c0624cbf08beb1e493b2c99b9fa1b67a20380"}, + {file = "Pygments-2.10.0.tar.gz", hash = "sha256:f398865f7eb6874156579fdf36bc840a03cab64d1cde9e93d68f46a425ec52c6"}, ] pylint = [ - {file = "pylint-2.8.3-py3-none-any.whl", hash = "sha256:792b38ff30903884e4a9eab814ee3523731abd3c463f3ba48d7b627e87013484"}, - {file = "pylint-2.8.3.tar.gz", hash = "sha256:0a049c5d47b629d9070c3932d13bff482b12119b6a241a93bc460b0be16953c8"}, + {file = "pylint-2.11.1-py3-none-any.whl", hash = "sha256:0f358e221c45cbd4dad2a1e4b883e75d28acdcccd29d40c76eb72b307269b126"}, + {file = "pylint-2.11.1.tar.gz", hash = "sha256:2c9843fff1a88ca0ad98a256806c82c5a8f86086e7ccbdb93297d86c3f90c436"}, ] pymongo = [ - {file = "pymongo-3.11.4-cp27-cp27m-macosx_10_14_intel.whl", hash = "sha256:b7efc7e7049ef366777cfd35437c18a4166bb50a5606a1c840ee3b9624b54fc9"}, - {file = "pymongo-3.11.4-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:517ba47ca04a55b1f50ee8df9fd97f6c37df5537d118fb2718952b8623860466"}, - {file = "pymongo-3.11.4-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:225c61e08fe517aede7912937939e09adf086c8e6f7e40d4c85ad678c2c2aea3"}, - {file = "pymongo-3.11.4-cp27-cp27m-win32.whl", hash = "sha256:e4e9db78b71db2b1684ee4ecc3e32c4600f18cdf76e6b9ae03e338e52ee4b168"}, - {file = "pymongo-3.11.4-cp27-cp27m-win_amd64.whl", hash = "sha256:8e0004b0393d72d76de94b4792a006cb960c1c65c7659930fbf9a81ce4341982"}, - {file = "pymongo-3.11.4-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:fedf0dee7a412ca6d1d6d92c158fe9cbaa8ea0cae90d268f9ccc0744de7a97d0"}, - {file = "pymongo-3.11.4-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:f947b359cc4769af8b49be7e37af01f05fcf15b401da2528021148e4a54426d1"}, - {file = "pymongo-3.11.4-cp34-cp34m-macosx_10_6_intel.whl", hash = "sha256:3a3498a8326111221560e930f198b495ea6926937e249f475052ffc6893a6680"}, - {file = "pymongo-3.11.4-cp34-cp34m-manylinux1_i686.whl", hash = "sha256:9a4f6e0b01df820ba9ed0b4e618ca83a1c089e48d4f268d0e00dcd49893d4549"}, - {file = "pymongo-3.11.4-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:d65bac5f6724d9ea6f0b5a0f0e4952fbbf209adcf6b5583b54c54bd2fcd74dc0"}, - {file = "pymongo-3.11.4-cp34-cp34m-win32.whl", hash = "sha256:15b083d1b789b230e5ac284442d9ecb113c93f3785a6824f748befaab803b812"}, - {file = "pymongo-3.11.4-cp34-cp34m-win_amd64.whl", hash = "sha256:f08665d3cc5abc2f770f472a9b5f720a9b3ab0b8b3bb97c7c1487515e5653d39"}, - {file = "pymongo-3.11.4-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:977b1d4f868986b4ba5d03c317fde4d3b66e687d74473130cd598e3103db34fa"}, - {file = "pymongo-3.11.4-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:510cd3bfabb63a07405b7b79fae63127e34c118b7531a2cbbafc7a24fd878594"}, - {file = "pymongo-3.11.4-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:071552b065e809d24c5653fcc14968cfd6fde4e279408640d5ac58e3353a3c5f"}, - {file = "pymongo-3.11.4-cp35-cp35m-manylinux2014_aarch64.whl", hash = "sha256:f4ba58157e8ae33ee86fadf9062c506e535afd904f07f9be32731f4410a23b7f"}, - {file = "pymongo-3.11.4-cp35-cp35m-manylinux2014_i686.whl", hash = "sha256:b413117210fa6d92664c3d860571e8e8727c3e8f2ff197276c5d0cb365abd3ad"}, - {file = "pymongo-3.11.4-cp35-cp35m-manylinux2014_ppc64le.whl", hash = "sha256:08b8723248730599c9803ae4c97b8f3f76c55219104303c88cb962a31e3bb5ee"}, - {file = "pymongo-3.11.4-cp35-cp35m-manylinux2014_s390x.whl", hash = "sha256:8a41fdc751dc4707a4fafb111c442411816a7c225ebb5cadb57599534b5d5372"}, - {file = "pymongo-3.11.4-cp35-cp35m-manylinux2014_x86_64.whl", hash = "sha256:f664ed7613b8b18f0ce5696b146776266a038c19c5cd6efffa08ecc189b01b73"}, - {file = "pymongo-3.11.4-cp35-cp35m-win32.whl", hash = "sha256:5c36428cc4f7fae56354db7f46677fd21222fc3cb1e8829549b851172033e043"}, - {file = "pymongo-3.11.4-cp35-cp35m-win_amd64.whl", hash = "sha256:d0a70151d7de8a3194cdc906bcc1a42e14594787c64b0c1c9c975e5a2af3e251"}, - {file = "pymongo-3.11.4-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:9b9298964389c180a063a9e8bac8a80ed42de11d04166b20249bfa0a489e0e0f"}, - {file = "pymongo-3.11.4-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:b2f41261b648cf5dee425f37ff14f4ad151c2f24b827052b402637158fd056ef"}, - {file = "pymongo-3.11.4-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:e02beaab433fd1104b2804f909e694cfbdb6578020740a9051597adc1cd4e19f"}, - {file = "pymongo-3.11.4-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:8898f6699f740ca93a0879ed07d8e6db02d68af889d0ebb3d13ab017e6b1af1e"}, - {file = "pymongo-3.11.4-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:62c29bc36a6d9be68fe7b5aaf1e120b4aa66a958d1e146601fcd583eb12cae7b"}, - {file = "pymongo-3.11.4-cp36-cp36m-manylinux2014_ppc64le.whl", hash = "sha256:424799c71ff435094e5fb823c40eebb4500f0e048133311e9c026467e8ccebac"}, - {file = "pymongo-3.11.4-cp36-cp36m-manylinux2014_s390x.whl", hash = "sha256:3551912f5c34d8dd7c32c6bb00ae04192af47f7b9f653608f107d19c1a21a194"}, - {file = "pymongo-3.11.4-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:5db59223ed1e634d842a053325f85f908359c6dac9c8ddce8ef145061fae7df8"}, - {file = "pymongo-3.11.4-cp36-cp36m-win32.whl", hash = "sha256:fea5cb1c63efe1399f0812532c7cf65458d38fd011be350bc5021dfcac39fba8"}, - {file = "pymongo-3.11.4-cp36-cp36m-win_amd64.whl", hash = "sha256:d4e62417e89b717a7bcd8576ac3108cd063225942cc91c5b37ff5465fdccd386"}, - {file = "pymongo-3.11.4-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:4c7e8c8e1e1918dcf6a652ac4b9d87164587c26fd2ce5dd81e73a5ab3b3d492f"}, - {file = "pymongo-3.11.4-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:38a7b5140a48fc91681cdb5cb95b7cd64640b43d19259fdd707fa9d5a715f2b2"}, - {file = "pymongo-3.11.4-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:aff3656af2add93f290731a6b8930b23b35c0c09569150130a58192b3ec6fc61"}, - {file = "pymongo-3.11.4-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:03be7ad107d252bb7325d4af6309fdd2c025d08854d35f0e7abc8bf048f4245e"}, - {file = "pymongo-3.11.4-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:6060794aac9f7b0644b299f46a9c6cbc0bc470bd01572f4134df140afd41ded6"}, - {file = "pymongo-3.11.4-cp37-cp37m-manylinux2014_ppc64le.whl", hash = "sha256:73326b211e7410c8bd6a74500b1e3f392f39cf10862e243d00937e924f112c01"}, - {file = "pymongo-3.11.4-cp37-cp37m-manylinux2014_s390x.whl", hash = "sha256:20d75ea11527331a2980ab04762a9d960bcfea9475c54bbeab777af880de61cd"}, - {file = "pymongo-3.11.4-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:3135dd574ef1286189f3f04a36c8b7a256376914f8cbbce66b94f13125ded858"}, - {file = "pymongo-3.11.4-cp37-cp37m-win32.whl", hash = "sha256:7c97554ea521f898753d9773891d0347ebfaddcc1dee2ad94850b163171bf1f1"}, - {file = "pymongo-3.11.4-cp37-cp37m-win_amd64.whl", hash = "sha256:a08c8b322b671857c81f4c30cd3c8df2895fd3c0e9358714f39e0ef8fb327702"}, - {file = "pymongo-3.11.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f3d851af3852f16ad4adc7ee054fd9c90a7a5063de94d815b7f6a88477b9f4c6"}, - {file = "pymongo-3.11.4-cp38-cp38-manylinux1_i686.whl", hash = "sha256:3bfc7689a1bacb9bcd2f2d5185d99507aa29f667a58dd8adaa43b5a348139e46"}, - {file = "pymongo-3.11.4-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:b8f94acd52e530a38f25e4d5bf7ddfdd4bea9193e718f58419def0d4406b58d3"}, - {file = "pymongo-3.11.4-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:e4b631688dfbdd61b5610e20b64b99d25771c6d52d9da73349342d2a0f11c46a"}, - {file = "pymongo-3.11.4-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:474e21d0e07cd09679e357d1dac76e570dab86665e79a9d3354b10a279ac6fb3"}, - {file = "pymongo-3.11.4-cp38-cp38-manylinux2014_ppc64le.whl", hash = "sha256:421d13523d11c57f57f257152bc4a6bb463aadf7a3918e9c96fefdd6be8dbfb8"}, - {file = "pymongo-3.11.4-cp38-cp38-manylinux2014_s390x.whl", hash = "sha256:0cabfc297f4cf921f15bc789a8fbfd7115eb9f813d3f47a74b609894bc66ab0d"}, - {file = "pymongo-3.11.4-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:fe4189846448df013cd9df11bba38ddf78043f8c290a9f06430732a7a8601cce"}, - {file = "pymongo-3.11.4-cp38-cp38-win32.whl", hash = "sha256:eb4d176394c37a76e8b0afe54b12d58614a67a60a7f8c0dd3a5afbb013c01092"}, - {file = "pymongo-3.11.4-cp38-cp38-win_amd64.whl", hash = "sha256:fffff7bfb6799a763d3742c59c6ee7ffadda21abed557637bc44ed1080876484"}, - {file = "pymongo-3.11.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:13acf6164ead81c9fc2afa0e1ea6d6134352973ce2bb35496834fee057063c04"}, - {file = "pymongo-3.11.4-cp39-cp39-manylinux1_i686.whl", hash = "sha256:d360e5d5dd3d55bf5d1776964625018d85b937d1032bae1926dd52253decd0db"}, - {file = "pymongo-3.11.4-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:0aaf4d44f1f819360f9432df538d54bbf850f18152f34e20337c01b828479171"}, - {file = "pymongo-3.11.4-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:08bda7b2c522ff9f1e554570da16298271ebb0c56ab9699446aacba249008988"}, - {file = "pymongo-3.11.4-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:1a994a42f49dab5b6287e499be7d3d2751776486229980d8857ad53b8333d469"}, - {file = "pymongo-3.11.4-cp39-cp39-manylinux2014_ppc64le.whl", hash = "sha256:161fcd3281c42f644aa8dec7753cca2af03ce654e17d76da4f0dab34a12480ca"}, - {file = "pymongo-3.11.4-cp39-cp39-manylinux2014_s390x.whl", hash = "sha256:78f07961f4f214ea8e80be63cffd5cc158eb06cd922ffbf6c7155b11728f28f9"}, - {file = "pymongo-3.11.4-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:ad31f184dcd3271de26ab1f9c51574afb99e1b0e484ab1da3641256b723e4994"}, - {file = "pymongo-3.11.4-cp39-cp39-win32.whl", hash = "sha256:5e606846c049ed40940524057bfdf1105af6066688c0e6a1a3ce2038589bae70"}, - {file = "pymongo-3.11.4-cp39-cp39-win_amd64.whl", hash = "sha256:3491c7de09e44eded16824cb58cf9b5cc1dc6f066a0bb7aa69929d02aa53b828"}, - {file = "pymongo-3.11.4-py2.7-macosx-10.14-intel.egg", hash = "sha256:506a6dab4c7ffdcacdf0b8e70bd20eb2e77fa994519547c9d88d676400fcad58"}, - {file = "pymongo-3.11.4.tar.gz", hash = "sha256:539d4cb1b16b57026999c53e5aab857fe706e70ae5310cc8c232479923f932e6"}, + {file = "pymongo-3.12.1-cp27-cp27m-macosx_10_14_intel.whl", hash = "sha256:c4653830375ab019b86d218c749ad38908b74182b2863d09936aa8d7f990d30e"}, + {file = "pymongo-3.12.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:2462a68f6675da548e333fa299d8e9807e00f95a4d198cfe9194d7be69f40c9b"}, + {file = "pymongo-3.12.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:4168b6c425d783e81723fc3dc382d374a228ff29530436a472a36d9f27593e73"}, + {file = "pymongo-3.12.1-cp27-cp27m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:36806ee53a85c3ba73939652f2ced2961e6a77cfbae385cd83f2e24cd97964b7"}, + {file = "pymongo-3.12.1-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:bf2d9d62178bb5c05e77d40becf89c309b1966fbcfb5c306238f81bf1ec2d6a2"}, + {file = "pymongo-3.12.1-cp27-cp27m-win32.whl", hash = "sha256:75c7ef67b4b8ec070e7a4740764f6c03ec9246b59d95e2ae45c029d41cb9efa1"}, + {file = "pymongo-3.12.1-cp27-cp27m-win_amd64.whl", hash = "sha256:49b0d92724d3fce1174fd30b0b428595072d5c6b14d6203e46a9ea347ae7b439"}, + {file = "pymongo-3.12.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:cef2675004d85d85a4ccc24730b73a99931547368d18ceeed1259a2d9fcddbc1"}, + {file = "pymongo-3.12.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:5e3833c001a04aa06a28c6fd9628256862a654c09b0f81c07734b5629bc014ab"}, + {file = "pymongo-3.12.1-cp27-cp27mu-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6a96c04ce39d66df60d9ce89f4c254c4967bc7d9e2e2c52adc58f47be826ee96"}, + {file = "pymongo-3.12.1-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:c2a17752f97a942bdb4ff4a0516a67c5ade1658ebe1ab2edacdec0b42e39fa75"}, + {file = "pymongo-3.12.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:02e0c088f189ca69fac094cb5f851b43bbbd7cec42114495777d4d8f297f7f8a"}, + {file = "pymongo-3.12.1-cp310-cp310-manylinux1_i686.whl", hash = "sha256:45d6b47d70ed44e3c40bef618ed61866c48176e7e5dff80d06d8b1a6192e8584"}, + {file = "pymongo-3.12.1-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:891f541c7ed29b95799da0cd249ae1db1842777b564e8205a197b038c5df6135"}, + {file = "pymongo-3.12.1-cp310-cp310-manylinux2014_i686.whl", hash = "sha256:dc4749c230a71b34db50ac2481d9008bb17b67c92671c443c3b40e192fbea78e"}, + {file = "pymongo-3.12.1-cp310-cp310-manylinux2014_ppc64le.whl", hash = "sha256:aa434534cc91f51a85e3099dc257ee8034b3d2be77f2ca58fb335a686e3a681f"}, + {file = "pymongo-3.12.1-cp310-cp310-manylinux2014_s390x.whl", hash = "sha256:180b405e17b90a877ea5dbc5efe7f4c171af4c89323148e100c0f12cedb86f12"}, + {file = "pymongo-3.12.1-cp310-cp310-manylinux2014_x86_64.whl", hash = "sha256:a472ca3d43d33e596ff5836c6cc71c3e61be33f44fe1cfdab4a1100f4af60333"}, + {file = "pymongo-3.12.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fe16517b275031d61261a4e3941c411fb7c46a9cd012f02381b56e7907cc9e06"}, + {file = "pymongo-3.12.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c0947d7be30335cb4c3d5d0983d8ebc8294ae52503cf1d596c926f7e7183900b"}, + {file = "pymongo-3.12.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:adb37bf22d25a51b84d989a2a5c770d4514ac590201eea1cb50ce8c9c5257f1d"}, + {file = "pymongo-3.12.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f5fe59328838fa28958cc06ecf94be585726b97d637012f168bc3c7abe4fd81"}, + {file = "pymongo-3.12.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:87114b995506e7584cf3daf891e419b5f6e7e383e7df6267494da3a76312aa22"}, + {file = "pymongo-3.12.1-cp310-cp310-win32.whl", hash = "sha256:4f4bc64fe9cbd70d46f519f1e88c9e4677f7af18ab9cd4942abce2bcfa7549c3"}, + {file = "pymongo-3.12.1-cp310-cp310-win_amd64.whl", hash = "sha256:8f87f53c9cd89010ae45490ec2c963ff18b31f5f290dc08b04151709589fe8d9"}, + {file = "pymongo-3.12.1-cp34-cp34m-macosx_10_6_intel.whl", hash = "sha256:37a63da5ee623acdf98e6d511171c8a5827a6106b0712c18af4441ef4f11e6be"}, + {file = "pymongo-3.12.1-cp34-cp34m-manylinux1_i686.whl", hash = "sha256:b1b06038c9940a49c73db0aeb0f6809b308e198da1326171768cf68d843af521"}, + {file = "pymongo-3.12.1-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:ab27d6d7d41a66d9e54269a290d27cd5c74f08e9add0054a754b4821026c4f42"}, + {file = "pymongo-3.12.1-cp34-cp34m-win32.whl", hash = "sha256:63be03f7ae1e15e72a234637ec7941ef229c7ab252c9ff6af48bba1e5418961c"}, + {file = "pymongo-3.12.1-cp34-cp34m-win_amd64.whl", hash = "sha256:56feb80ea1f5334ccab9bd16a5161571ab70392e51fcc752fb8a1dc67125f663"}, + {file = "pymongo-3.12.1-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:a81e52dbf95f236a0c89a5abcd2b6e1331da0c0312f471c73fae76c79d2acf6b"}, + {file = "pymongo-3.12.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:712de1876608fd5d76abc3fc8ec55077278dd5044073fbe9492631c9a2c58351"}, + {file = "pymongo-3.12.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:47ed77f62c8417a86f9ad158b803f3459a636386cb9d3d4e9e7d6a82d051f907"}, + {file = "pymongo-3.12.1-cp35-cp35m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1fa6f08ddb6975371777f97592d35c771e713ee2250e55618148a5e57e260aff"}, + {file = "pymongo-3.12.1-cp35-cp35m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:3a2fcbd04273a509fa85285d9eccf17ab65ce440bd4f5e5a58c978e563cd9e9a"}, + {file = "pymongo-3.12.1-cp35-cp35m-win32.whl", hash = "sha256:d1b98539b0de822b6f717498e59ae3e5ae2e7f564370ab513e6d0c060753e447"}, + {file = "pymongo-3.12.1-cp35-cp35m-win_amd64.whl", hash = "sha256:c660fd1e4a4b52f79f7d134a3d31d452948477b7f46ff5061074a534c5805ba6"}, + {file = "pymongo-3.12.1-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:460bdaa3f65ddb5b7474ae08589a1763b5da1a78b8348351b9ba1c63b459d67d"}, + {file = "pymongo-3.12.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:1d55982e5335925c55e2b87467043866ce72bd30ea7e7e3eeed6ec3d95a806d4"}, + {file = "pymongo-3.12.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:67e0b2ad3692f6d0335ae231a40de55ec395b6c2e971ad6f55b162244d1ec542"}, + {file = "pymongo-3.12.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:515e4708d6567901ffc06476a38abe2c9093733f52638235d9f149579c1d3de0"}, + {file = "pymongo-3.12.1-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:ed20ec5a01c43254f6047c5d8124b70d28e39f128c8ad960b437644fe94e1827"}, + {file = "pymongo-3.12.1-cp36-cp36m-manylinux2014_ppc64le.whl", hash = "sha256:e2bccadbe313b11704160aaba5eec95d2da1aa663f02f41d2d1520d02bbbdcd5"}, + {file = "pymongo-3.12.1-cp36-cp36m-manylinux2014_s390x.whl", hash = "sha256:ef8b927813c27c3bdfc82c55682d7767403bcdadfd9f9c0fc49f4be4553a877b"}, + {file = "pymongo-3.12.1-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:2d3abe548a280b49269c7907d5b71199882510c484d680a5ea7860f30c4a695f"}, + {file = "pymongo-3.12.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e30cce3cc86d6082c8596b3fbee0d4f54bc4d337a4fa1bf536920e2e319e24f0"}, + {file = "pymongo-3.12.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fe3ae4294d593da54862f0140fdcc89d1aeeb94258ca97f094119ed7f0e5882d"}, + {file = "pymongo-3.12.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9641be893ccce7d192a0094efd0a0d9f1783a1ebf314b4128f8a27bfadb8a77c"}, + {file = "pymongo-3.12.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13a7c6d055af58a1e9c505e736da8b6a2e95ccc8cec10b008143f7a536e5de8a"}, + {file = "pymongo-3.12.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:25fd76deabe9ea37c8360c362b32f702cc095a208dd1c5328189938ca7685847"}, + {file = "pymongo-3.12.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e841695b5dbea38909ab2dbf17e91e9a823412d8d88d1ef77f1b94a7bc551c0f"}, + {file = "pymongo-3.12.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6ead0126fb4424c6c6a4fdc603d699a9db7c03cdb8eac374c352a75fec8a820a"}, + {file = "pymongo-3.12.1-cp36-cp36m-win32.whl", hash = "sha256:a5dbeeea6a375fbd79448b48a54c46fc9351611a03ef8398d2a40b684ce46194"}, + {file = "pymongo-3.12.1-cp36-cp36m-win_amd64.whl", hash = "sha256:87db421c9eb915b8d9a9a13c5b2ee338350e36ee83e26ff0adfc48abc5db3ac3"}, + {file = "pymongo-3.12.1-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:8851544168703fb519e95556e3b463fca4beeef7ed3f731d81a68c8268515d9d"}, + {file = "pymongo-3.12.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:7d8cdd2f070c71366e64990653522cce84b08dc26ab0d1fa19aa8d14ee0cf9ba"}, + {file = "pymongo-3.12.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:51437c77030bed72d57d8a61e22758e3c389b13fea7787c808030002bb05ca39"}, + {file = "pymongo-3.12.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:f43cacda46fc188f998e6d308afe1c61ff41dcb300949f4cbf731e9a0a5eb2d3"}, + {file = "pymongo-3.12.1-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:1a7b138a04fdd17849930dc8bf664002e17db38448850bfb96d200c9c5a8b3a1"}, + {file = "pymongo-3.12.1-cp37-cp37m-manylinux2014_ppc64le.whl", hash = "sha256:444c00ebc20f2f9dc62e34f7dc9453dc2f5f5a72419c8dccad6e26d546c35712"}, + {file = "pymongo-3.12.1-cp37-cp37m-manylinux2014_s390x.whl", hash = "sha256:81ce5f871f5d8e82615c8bd0b34b68a9650204c8b1a04ce7890d58c98eb66e39"}, + {file = "pymongo-3.12.1-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:837cdef094f39c6f4a2967abc646a412999c2540fbf5d3cce1dd3b671f4b876c"}, + {file = "pymongo-3.12.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2174d3279b8e2b6d7613b338f684cd78ff7adf1e7ec5b7b7bde5609a129c9898"}, + {file = "pymongo-3.12.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:303531649fa45f96b694054c1aa02f79bda32ef57affe42c5c339336717eed74"}, + {file = "pymongo-3.12.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1821ce4e5a293313947fd017bbd2d2535aa6309680fa29b33d0442d15da296ec"}, + {file = "pymongo-3.12.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15dae01341571d0af51526b7a21648ca575e9375e16ba045c9860848dfa8952f"}, + {file = "pymongo-3.12.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcc021530b7c71069132fe4846d95a3cdd74d143adc2f7e398d5fabf610f111c"}, + {file = "pymongo-3.12.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f44bea60fd2178d7153deef9621c4b526a93939da30010bba24d3408a98b0f79"}, + {file = "pymongo-3.12.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6f0f0a10f128ea0898e607d351ebfabf70941494fc94e87f12c76e2894d8e6c4"}, + {file = "pymongo-3.12.1-cp37-cp37m-win32.whl", hash = "sha256:afb16330ab6efbbf995375ad94e970fa2f89bb46bd10d854b7047620fdb0d67d"}, + {file = "pymongo-3.12.1-cp37-cp37m-win_amd64.whl", hash = "sha256:dcf906c1f7a33e4222e4bff18da1554d69323bc4dd95fe867a6fa80709ee5f93"}, + {file = "pymongo-3.12.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9b62d84478f471fdb0dcea3876acff38f146bd23cbdbed15074fb4622064ec2e"}, + {file = "pymongo-3.12.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:48722e91981bb22a16b0431ea01da3e1cc5b96805634d3b8d3c2a5315c1ce7f1"}, + {file = "pymongo-3.12.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:d6c6989c10008ac70c2bb2ad2b940fcfe883712746c89f7e3308c14c213a70d7"}, + {file = "pymongo-3.12.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:573e2387d0686976642142c50740dfc4d3494cc627e2a7d22782b99f70879055"}, + {file = "pymongo-3.12.1-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:7117bfd8827cfe550f65a3c399dcd6e02226197a91c6d11a3540c3e8efc686d6"}, + {file = "pymongo-3.12.1-cp38-cp38-manylinux2014_ppc64le.whl", hash = "sha256:6eb6789f26c398c383225e1313c8e75a7d290d323b8eaf65f3f3ddd0eb8a5a3c"}, + {file = "pymongo-3.12.1-cp38-cp38-manylinux2014_s390x.whl", hash = "sha256:138248c542051eb462f88b50b0267bd5286d6661064bab06faa0ef6ac30cdb4b"}, + {file = "pymongo-3.12.1-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:7abc87e45b572eb6d17a50422e69a9e5d6f13e691e821fe2312df512500faa50"}, + {file = "pymongo-3.12.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a7430f3987d232e782304c109be1d0e6fff46ca6405cb2479e4d8d08cd29541e"}, + {file = "pymongo-3.12.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cb48ff6cc6109190e1ccf8ea1fc71cc244c9185813ce7d1c415dce991cfb8709"}, + {file = "pymongo-3.12.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:68409171ab2aa7ccd6e8e839233e4b8ddeec246383c9a3698614e814739356f9"}, + {file = "pymongo-3.12.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13d74bf3435c1e58d8fafccc0d5e87f246ae2c6e9cbef4b35e32a1c3759e354f"}, + {file = "pymongo-3.12.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:849e641cfed05c75d772f9e9018f42c5fbd00655d43d52da1b9c56346fd3e4cc"}, + {file = "pymongo-3.12.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5183b698d6542219e4135de583b57bc6286bd37df7f645b688278eb919bfa785"}, + {file = "pymongo-3.12.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:65f159c445761cab04b665fc448b3fc008aebc98e54fdcbfd1aff195ef1b1408"}, + {file = "pymongo-3.12.1-cp38-cp38-win32.whl", hash = "sha256:3b40e36d3036bfe69ba63ec8e746a390721f75467085a0384b528e1dda532c69"}, + {file = "pymongo-3.12.1-cp38-cp38-win_amd64.whl", hash = "sha256:58a67b3800476232f9989e533d0244060309451b436d46670a53e6d189f1a7e7"}, + {file = "pymongo-3.12.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db3efec9dcecd96555d752215797816da40315d61878f90ca39c8e269791bf17"}, + {file = "pymongo-3.12.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:bfd073fea04061019a103a288847846b5ef40dfa2f73b940ed61e399ca95314f"}, + {file = "pymongo-3.12.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:5067c04d3b19c820faac6342854d887ade58e8d38c3db79b68c2a102bbb100e7"}, + {file = "pymongo-3.12.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:1c4e51a3b69789b6f468a8e881a13f2d1e8f5e99e41f80fd44845e6ec0f701e1"}, + {file = "pymongo-3.12.1-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:2fa101bb23619120673899694a65b094364269e597f551a87c4bdae3a474d726"}, + {file = "pymongo-3.12.1-cp39-cp39-manylinux2014_ppc64le.whl", hash = "sha256:eb65ec0255a0fccc47c87d44e505ef5180bfd71690bd5f84161b1f23949fb209"}, + {file = "pymongo-3.12.1-cp39-cp39-manylinux2014_s390x.whl", hash = "sha256:ed751a20840a31242e7bea566fcf93ba75bc11b33afe2777bbf46069c1af5094"}, + {file = "pymongo-3.12.1-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:17238115e6d37f5423b046cb829f1ca02c4ea7edb163f5b8b88e0c975dc3fec9"}, + {file = "pymongo-3.12.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2fda3b3fb5c0d159195ab834b322a23808f1b059bcc7e475765abeddee6a2529"}, + {file = "pymongo-3.12.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6235bf2157aa46e53568ed79b70603aa8874baa202d5d1de82fa0eb917696e73"}, + {file = "pymongo-3.12.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5d6428b8b422ba5205140e8be11722fa7292a0bedaa8bc80fb34c92eb19ba45"}, + {file = "pymongo-3.12.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1e6d1cf4bd6552b5f519432cce1530c09e6b0aab98d44803b991f7e880bd332"}, + {file = "pymongo-3.12.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:287c2a0063267c1458c4ddf528b44063ce7f376a6436eea5bccd7f625bbc3b5e"}, + {file = "pymongo-3.12.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4a2d73a9281faefb273a5448f6d25f44ebd311ada9eb79b6801ae890508fe231"}, + {file = "pymongo-3.12.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6f07888e3b73c0dfa46f12d098760494f5f23fd66923a6615edfe486e6a7649c"}, + {file = "pymongo-3.12.1-cp39-cp39-win32.whl", hash = "sha256:77dddf596fb065de29fb39992fbc81301f7fd0003be649b7fa7448c77ca53bed"}, + {file = "pymongo-3.12.1-cp39-cp39-win_amd64.whl", hash = "sha256:979e34db4f3dc5710c18db437aaf282f691092b352e708cb2afd4df287698c76"}, + {file = "pymongo-3.12.1-py2.7-macosx-10.14-intel.egg", hash = "sha256:c04e84ccf590933a266180286d8b6a5fc844078a5d934432628301bd8b5f9ca7"}, + {file = "pymongo-3.12.1.tar.gz", hash = "sha256:704879b6a54c45ad76cea7c6789c1ae7185050acea7afd15b58318fa1932ed45"}, ] pynacl = [ {file = "PyNaCl-1.4.0-cp27-cp27m-macosx_10_10_x86_64.whl", hash = "sha256:ea6841bc3a76fa4942ce00f3bda7d436fda21e2d91602b9e21b7ca9ecab8f3ff"}, @@ -2306,24 +2382,30 @@ pynacl = [ {file = "PyNaCl-1.4.0.tar.gz", hash = "sha256:54e9a2c849c742006516ad56a88f5c74bf2ce92c9f67435187c3c5953b346505"}, ] pynput = [ - {file = "pynput-1.7.3-py2.py3-none-any.whl", hash = "sha256:fea5777454f896bd79d35393088cd29a089f3b2da166f0848a922b1d5a807d4f"}, - {file = "pynput-1.7.3-py3.8.egg", hash = "sha256:6626e8ea9ca482bb5628a7169e1193824e382c4ad3053e40f4f24f41ee7b41c9"}, - {file = "pynput-1.7.3.tar.gz", hash = "sha256:4e50b1a0ab86847e87e58f6d1993688b9a44f9f4c88d4712315ea8eb552ef828"}, + {file = "pynput-1.7.4-py2.py3-none-any.whl", hash = "sha256:f78502cb2abd101721d867451bf315a4e1334666372f8682651393f16e1d2d9b"}, + {file = "pynput-1.7.4-py3.9.egg", hash = "sha256:225926bf5e98d36738911112c72e19e0cba830aafee3882ef8661c8d9cfb3b63"}, + {file = "pynput-1.7.4.tar.gz", hash = "sha256:16fecc4d1e53a28fb7c669c79e189c3f2cde14a08d6b457c3da07075c82f3b4c"}, ] pyobjc-core = [ {file = "pyobjc-core-7.3.tar.gz", hash = "sha256:5081aedf8bb40aac1a8ad95adac9e44e148a882686ded614adf46bb67fd67574"}, - {file = "pyobjc_core-7.3-1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a1f1e6b457127cbf2b5bd2b94520a7c89fb590b739911eadb2b0499a3a5b0e6f"}, - {file = "pyobjc_core-7.3-1-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:ed708cc47bae8b711f81f252af09898a5f986c7a38cec5ad5623d571d328bff8"}, {file = "pyobjc_core-7.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4e93ad769a20b908778fe950f62a843a6d8f0fa71996e5f3cc9fab5ae7d17771"}, {file = "pyobjc_core-7.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:9f63fd37bbf3785af4ddb2f86cad5ca81c62cfc7d1c0099637ca18343c3656c1"}, {file = "pyobjc_core-7.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e9b1311f72f2e170742a7ee3a8149f52c35158dc024a21e88d6f1e52ba5d718b"}, {file = "pyobjc_core-7.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8d5e12a0729dfd1d998a861998b422d0a3e41923d75ea229bacf31372c831d7b"}, {file = "pyobjc_core-7.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:efdee8c4884405e0c0186c57f87d7bfaa0abc1f50b18e865db3caea3a1f329b9"}, ] +pyobjc-framework-applicationservices = [ + {file = "pyobjc-framework-ApplicationServices-7.3.tar.gz", hash = "sha256:1925ac30a817e557d1c08450005103bbf76ebd3ff473631fe9875070377b0b4d"}, + {file = "pyobjc_framework_ApplicationServices-7.3-1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:484e5b5e9f1757ad7e28799bb5d5d59ce861a3e5449f06fc3a0d05b998e9e6bb"}, + {file = "pyobjc_framework_ApplicationServices-7.3-1-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:ec0c07775ff7034751306fa382117d12ae8e383b696cda1b2815dfd334c36ff7"}, + {file = "pyobjc_framework_ApplicationServices-7.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:daa4a9c51a927630fdd3d3f627e03ebc370aee3c397305db85a0a8ba4c28ae93"}, + {file = "pyobjc_framework_ApplicationServices-7.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:167aa21ee47b0ee6e4e399915371d183ae84880dc3813c27519e759acb9d20c9"}, + {file = "pyobjc_framework_ApplicationServices-7.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7a98f0f1e21465868f9dd32588ae71e5e6a4cb5c434d4158c9e12273fd7b8f27"}, + {file = "pyobjc_framework_ApplicationServices-7.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2d55796610e6293e83cc40183347e7f75a7c0682775cc19e5986945efa9cac1b"}, + {file = "pyobjc_framework_ApplicationServices-7.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:afd1ef147447fe7b06a271458eabb37ece6436705abf86265d7fb57310eca45f"}, +] pyobjc-framework-cocoa = [ {file = "pyobjc-framework-Cocoa-7.3.tar.gz", hash = "sha256:b18d05e7a795a3455ad191c3e43d6bfa673c2a4fd480bb1ccf57191051b80b7e"}, - {file = "pyobjc_framework_Cocoa-7.3-1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1e31376806e5de883a1d7c7c87d9ff2a8b09fc05d267e0dfce6e42409fb70c67"}, - {file = "pyobjc_framework_Cocoa-7.3-1-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:d999387927284346035cb63ebb51f86331abc41f9376f9a6970e7f18207db392"}, {file = "pyobjc_framework_Cocoa-7.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:9edffdfa6dd1f71f21b531c3e61fdd3e4d5d3bf6c5a528c98e88828cd60bac11"}, {file = "pyobjc_framework_Cocoa-7.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:35a6340437a4e0109a302150b7d1f6baf57004ccf74834f9e6062fcafe2fd8d7"}, {file = "pyobjc_framework_Cocoa-7.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7c3886f2608ab3ed02482f8b2ebf9f782b324c559e84b52cfd92dba8a1109872"}, @@ -2332,8 +2414,6 @@ pyobjc-framework-cocoa = [ ] pyobjc-framework-quartz = [ {file = "pyobjc-framework-Quartz-7.3.tar.gz", hash = "sha256:98812844c34262def980bdf60923a875cd43428a8375b6fd53bd2cd800eccf0b"}, - {file = "pyobjc_framework_Quartz-7.3-1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1139bc6874c0f8b58f0b8602015e0994198bc506a6bcec1071208de32b55ed26"}, - {file = "pyobjc_framework_Quartz-7.3-1-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:d94a3ed7051266c52392ec07d3b5adbf28d4be83341a24df0d88639344dcd84f"}, {file = "pyobjc_framework_Quartz-7.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1ef18f5a16511ded65980bf4f5983ea5d35c88224dbad1b3112abd29c60413ea"}, {file = "pyobjc_framework_Quartz-7.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3b41eec8d4b10c7c7e011e2f9051367f5499ef315ba52dfbae573c3a2e05469c"}, {file = "pyobjc_framework_Quartz-7.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2c65456ed045dfe1711d0298734e5a3ad670f8c770f7eb3b19979256c388bdd2"}, @@ -2345,37 +2425,57 @@ pyparsing = [ {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, ] pyrsistent = [ - {file = "pyrsistent-0.17.3.tar.gz", hash = "sha256:2e636185d9eb976a18a8a8e96efce62f2905fea90041958d8cc2a189756ebf3e"}, + {file = "pyrsistent-0.18.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f4c8cabb46ff8e5d61f56a037974228e978f26bfefce4f61a4b1ac0ba7a2ab72"}, + {file = "pyrsistent-0.18.0-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:da6e5e818d18459fa46fac0a4a4e543507fe1110e808101277c5a2b5bab0cd2d"}, + {file = "pyrsistent-0.18.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:5e4395bbf841693eaebaa5bb5c8f5cdbb1d139e07c975c682ec4e4f8126e03d2"}, + {file = "pyrsistent-0.18.0-cp36-cp36m-win32.whl", hash = "sha256:527be2bfa8dc80f6f8ddd65242ba476a6c4fb4e3aedbf281dfbac1b1ed4165b1"}, + {file = "pyrsistent-0.18.0-cp36-cp36m-win_amd64.whl", hash = "sha256:2aaf19dc8ce517a8653746d98e962ef480ff34b6bc563fc067be6401ffb457c7"}, + {file = "pyrsistent-0.18.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:58a70d93fb79dc585b21f9d72487b929a6fe58da0754fa4cb9f279bb92369396"}, + {file = "pyrsistent-0.18.0-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:4916c10896721e472ee12c95cdc2891ce5890898d2f9907b1b4ae0f53588b710"}, + {file = "pyrsistent-0.18.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:73ff61b1411e3fb0ba144b8f08d6749749775fe89688093e1efef9839d2dcc35"}, + {file = "pyrsistent-0.18.0-cp37-cp37m-win32.whl", hash = "sha256:b29b869cf58412ca5738d23691e96d8aff535e17390128a1a52717c9a109da4f"}, + {file = "pyrsistent-0.18.0-cp37-cp37m-win_amd64.whl", hash = "sha256:097b96f129dd36a8c9e33594e7ebb151b1515eb52cceb08474c10a5479e799f2"}, + {file = "pyrsistent-0.18.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:772e94c2c6864f2cd2ffbe58bb3bdefbe2a32afa0acb1a77e472aac831f83427"}, + {file = "pyrsistent-0.18.0-cp38-cp38-manylinux1_i686.whl", hash = "sha256:c1a9ff320fa699337e05edcaae79ef8c2880b52720bc031b219e5b5008ebbdef"}, + {file = "pyrsistent-0.18.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:cd3caef37a415fd0dae6148a1b6957a8c5f275a62cca02e18474608cb263640c"}, + {file = "pyrsistent-0.18.0-cp38-cp38-win32.whl", hash = "sha256:e79d94ca58fcafef6395f6352383fa1a76922268fa02caa2272fff501c2fdc78"}, + {file = "pyrsistent-0.18.0-cp38-cp38-win_amd64.whl", hash = "sha256:a0c772d791c38bbc77be659af29bb14c38ced151433592e326361610250c605b"}, + {file = "pyrsistent-0.18.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d5ec194c9c573aafaceebf05fc400656722793dac57f254cd4741f3c27ae57b4"}, + {file = "pyrsistent-0.18.0-cp39-cp39-manylinux1_i686.whl", hash = "sha256:6b5eed00e597b5b5773b4ca30bd48a5774ef1e96f2a45d105db5b4ebb4bca680"}, + {file = "pyrsistent-0.18.0-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:48578680353f41dca1ca3dc48629fb77dfc745128b56fc01096b2530c13fd426"}, + {file = "pyrsistent-0.18.0-cp39-cp39-win32.whl", hash = "sha256:f3ef98d7b76da5eb19c37fda834d50262ff9167c65658d1d8f974d2e4d90676b"}, + {file = "pyrsistent-0.18.0-cp39-cp39-win_amd64.whl", hash = "sha256:404e1f1d254d314d55adb8d87f4f465c8693d6f902f67eb6ef5b4526dc58e6ea"}, + {file = "pyrsistent-0.18.0.tar.gz", hash = "sha256:773c781216f8c2900b42a7b638d5b517bb134ae1acbebe4d1e8f1f41ea60eb4b"}, ] pysftp = [ {file = "pysftp-0.2.9.tar.gz", hash = "sha256:fbf55a802e74d663673400acd92d5373c1c7ee94d765b428d9f977567ac4854a"}, ] pytest = [ - {file = "pytest-6.2.4-py3-none-any.whl", hash = "sha256:91ef2131a9bd6be8f76f1f08eac5c5317221d6ad1e143ae03894b862e8976890"}, - {file = "pytest-6.2.4.tar.gz", hash = "sha256:50bcad0a0b9c5a72c8e4e7c9855a3ad496ca6a881a3641b4260605450772c54b"}, + {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, + {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"}, ] pytest-cov = [ - {file = "pytest-cov-2.12.1.tar.gz", hash = "sha256:261ceeb8c227b726249b376b8526b600f38667ee314f910353fa318caa01f4d7"}, - {file = "pytest_cov-2.12.1-py2.py3-none-any.whl", hash = "sha256:261bb9e47e65bd099c89c3edf92972865210c36813f80ede5277dceb77a4a62a"}, + {file = "pytest-cov-3.0.0.tar.gz", hash = "sha256:e7f0f5b1617d2210a2cabc266dfe2f4c75a8d32fb89eafb7ad9d06f6d076d470"}, + {file = "pytest_cov-3.0.0-py3-none-any.whl", hash = "sha256:578d5d15ac4a25e5f961c938b85a05b09fdaae9deef3bb6de9a6e766622ca7a6"}, ] pytest-print = [ - {file = "pytest_print-0.2.1-py2.py3-none-any.whl", hash = "sha256:2cfcdeee8b398457d3e3488f1fde5f8303b404c30187be5fcb4c7818df5f4529"}, - {file = "pytest_print-0.2.1.tar.gz", hash = "sha256:8f61e5bb2d031ee88d19a5a7695a0c863caee7b1478f1a82d080c2128b76ad83"}, + {file = "pytest_print-0.3.0-py2.py3-none-any.whl", hash = "sha256:53fb0f71d371f137ac2e7171d92f204eb45055580e8c7920df619d9b2ee45359"}, + {file = "pytest_print-0.3.0.tar.gz", hash = "sha256:769f1b1b0943b2941dbeeaac6985766e76b341130ed538f88c23ebcd7087b90d"}, ] python-dateutil = [ - {file = "python-dateutil-2.8.1.tar.gz", hash = "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c"}, - {file = "python_dateutil-2.8.1-py2.py3-none-any.whl", hash = "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"}, + {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, + {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, ] python-xlib = [ - {file = "python-xlib-0.30.tar.gz", hash = "sha256:74131418faf9e7b83178c71d9d80297fbbd678abe99ae9258f5a20cd027acb5f"}, - {file = "python_xlib-0.30-py2.py3-none-any.whl", hash = "sha256:c4c92cd47e07588b2cbc7d52de18407b2902c3812d7cdec39cd2177b060828e2"}, + {file = "python-xlib-0.31.tar.gz", hash = "sha256:74d83a081f532bc07f6d7afcd6416ec38403d68f68b9b9dc9e1f28fbf2d799e9"}, + {file = "python_xlib-0.31-py2.py3-none-any.whl", hash = "sha256:1ec6ce0de73d9e6592ead666779a5732b384e5b8fb1f1886bd0a81cafa477759"}, ] python3-xlib = [ {file = "python3-xlib-0.15.tar.gz", hash = "sha256:dc4245f3ae4aa5949c1d112ee4723901ade37a96721ba9645f2bfa56e5b383f8"}, ] pytz = [ - {file = "pytz-2021.1-py2.py3-none-any.whl", hash = "sha256:eb10ce3e7736052ed3623d49975ce333bcd712c7bb19a58b9e2089d4057d0798"}, - {file = "pytz-2021.1.tar.gz", hash = "sha256:83a4a90894bf38e243cf052c8b58f381bfe9a7a483f6a9cab140bc7f702ac4da"}, + {file = "pytz-2021.3-py2.py3-none-any.whl", hash = "sha256:3672058bc3453457b622aab7a1c3bfd5ab0bdae451512f6cf25f64ed37f5b87c"}, + {file = "pytz-2021.3.tar.gz", hash = "sha256:acad2d8b20a1af07d4e4c9d2e9285c5ed9104354062f275f3fcd88dcef4f1326"}, ] pywin32 = [ {file = "pywin32-301-cp35-cp35m-win32.whl", hash = "sha256:93367c96e3a76dfe5003d8291ae16454ca7d84bb24d721e0b74a07610b7be4a7"}, @@ -2394,8 +2494,8 @@ pywin32-ctypes = [ {file = "pywin32_ctypes-0.2.0-py2.py3-none-any.whl", hash = "sha256:9dc2d991b3479cc2df15930958b674a48a227d5361d413827a4cfd0b5876fc98"}, ] "qt.py" = [ - {file = "Qt.py-1.3.3-py2.py3-none-any.whl", hash = "sha256:9e3f5417187c98d246918a9b27a9e1f8055e089bdb2b063a2739986bc19a3d2e"}, - {file = "Qt.py-1.3.3.tar.gz", hash = "sha256:601606127f70be9adc82c248d209d696cccbd1df242c24d3fb1a9e399f3ecaf1"}, + {file = "Qt.py-1.3.6-py2.py3-none-any.whl", hash = "sha256:7edf6048d07a6924707506b5ba34a6e05d66dde9a3f4e3a62f9996ccab0b91c7"}, + {file = "Qt.py-1.3.6.tar.gz", hash = "sha256:0d78656a2f814602eee304521c7bf5da0cec414818b3833712c77524294c404a"}, ] recommonmark = [ {file = "recommonmark-0.7.1-py2.py3-none-any.whl", hash = "sha256:1b1db69af0231efce3fa21b94ff627ea33dee7079a01dd0a7f8482c3da148b3f"}, @@ -2422,12 +2522,12 @@ six = [ {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, ] slack-sdk = [ - {file = "slack_sdk-3.6.0-py2.py3-none-any.whl", hash = "sha256:e1b257923a1ef88b8620dd3abff94dc5b3eee16ef37975d101ba9e60123ac3af"}, - {file = "slack_sdk-3.6.0.tar.gz", hash = "sha256:195f044e02a2844579a7a26818ce323e85dde8de224730c859644918d793399e"}, + {file = "slack_sdk-3.11.2-py2.py3-none-any.whl", hash = "sha256:35245ec34c8549fbb5c43ccc17101afd725b3508bb784da46530b214f496bf93"}, + {file = "slack_sdk-3.11.2.tar.gz", hash = "sha256:131bf605894525c2d66da064677eabc19f53f02ce0f82a3f2fa130d4ec3bc1b0"}, ] smmap = [ - {file = "smmap-4.0.0-py2.py3-none-any.whl", hash = "sha256:a9a7479e4c572e2e775c404dcd3080c8dc49f39918c2cf74913d30c4c478e3c2"}, - {file = "smmap-4.0.0.tar.gz", hash = "sha256:7e65386bd122d45405ddf795637b7f7d2b532e7e401d46bbe3fb49b9986d5182"}, + {file = "smmap-5.0.0-py3-none-any.whl", hash = "sha256:2aba19d6a040e78d8b09de5c57e96207b09ed71d8e55ce0959eeee6c8e190d94"}, + {file = "smmap-5.0.0.tar.gz", hash = "sha256:c840e62059cd3be204b0c9c9f74be2c09d5648eddd4580d9314c3ecde0b30936"}, ] snowballstemmer = [ {file = "snowballstemmer-2.1.0-py2.py3-none-any.whl", hash = "sha256:b51b447bea85f9968c13b650126a888aabd4cb4463fca868ec596826325dedc2"}, @@ -2438,16 +2538,16 @@ speedcopy = [ {file = "speedcopy-2.1.0.tar.gz", hash = "sha256:8bb1a6c735900b83901a7be84ba2175ed3887c13c6786f97dea48f2ea7d504c2"}, ] sphinx = [ - {file = "Sphinx-4.0.2-py3-none-any.whl", hash = "sha256:d1cb10bee9c4231f1700ec2e24a91be3f3a3aba066ea4ca9f3bbe47e59d5a1d4"}, - {file = "Sphinx-4.0.2.tar.gz", hash = "sha256:b5c2ae4120bf00c799ba9b3699bc895816d272d120080fbc967292f29b52b48c"}, + {file = "Sphinx-3.5.3-py3-none-any.whl", hash = "sha256:3f01732296465648da43dec8fb40dc451ba79eb3e2cc5c6d79005fd98197107d"}, + {file = "Sphinx-3.5.3.tar.gz", hash = "sha256:ce9c228456131bab09a3d7d10ae58474de562a6f79abb3dc811ae401cf8c1abc"}, ] sphinx-qt-documentation = [ {file = "sphinx_qt_documentation-0.3-py3-none-any.whl", hash = "sha256:bee247cb9e4fc03fc496d07adfdb943100e1103320c3e5e820e0cfa7c790d9b6"}, {file = "sphinx_qt_documentation-0.3.tar.gz", hash = "sha256:f09a0c9d9e989172ba3e282b92bf55613bb23ad47315ec5b0d38536b343ac6c8"}, ] sphinx-rtd-theme = [ - {file = "sphinx_rtd_theme-0.5.2-py2.py3-none-any.whl", hash = "sha256:4a05bdbe8b1446d77a01e20a23ebc6777c74f43237035e76be89699308987d6f"}, - {file = "sphinx_rtd_theme-0.5.2.tar.gz", hash = "sha256:32bd3b5d13dc8186d7a42fc816a23d32e83a4827d7d9882948e7b837c232da5a"}, + {file = "sphinx_rtd_theme-0.5.1-py2.py3-none-any.whl", hash = "sha256:fa6bebd5ab9a73da8e102509a86f3fcc36dec04a0b52ea80e5a033b2aba00113"}, + {file = "sphinx_rtd_theme-0.5.1.tar.gz", hash = "sha256:eda689eda0c7301a80cf122dad28b1861e5605cbf455558f3775e1e8200e83a5"}, ] sphinxcontrib-applehelp = [ {file = "sphinxcontrib-applehelp-1.0.2.tar.gz", hash = "sha256:a072735ec80e7675e3f432fcae8610ecf509c5f1869d17e2eecff44389cdbc58"}, @@ -2489,6 +2589,10 @@ toml = [ {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, ] +tomli = [ + {file = "tomli-1.2.2-py3-none-any.whl", hash = "sha256:f04066f68f5554911363063a30b108d2b5a5b1a010aa8b6132af78489fe3aade"}, + {file = "tomli-1.2.2.tar.gz", hash = "sha256:c6ce0015eb38820eaf32b5db832dbc26deb3dd427bd5f6556cf0acac2c214fee"}, +] typed-ast = [ {file = "typed_ast-1.4.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:2068531575a125b87a41802130fa7e29f26c09a2833fea68d9a40cf33902eba6"}, {file = "typed_ast-1.4.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:c907f561b1e83e93fad565bac5ba9c22d96a54e7ea0267c708bffe863cbe4075"}, @@ -2522,17 +2626,17 @@ typed-ast = [ {file = "typed_ast-1.4.3.tar.gz", hash = "sha256:fb1bbeac803adea29cedd70781399c99138358c26d05fcbd23c13016b7f5ec65"}, ] typing-extensions = [ - {file = "typing_extensions-3.10.0.0-py2-none-any.whl", hash = "sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497"}, - {file = "typing_extensions-3.10.0.0-py3-none-any.whl", hash = "sha256:779383f6086d90c99ae41cf0ff39aac8a7937a9283ce0a414e5dd782f4c94a84"}, - {file = "typing_extensions-3.10.0.0.tar.gz", hash = "sha256:50b6f157849174217d0656f99dc82fe932884fb250826c18350e159ec6cdf342"}, + {file = "typing_extensions-3.10.0.2-py2-none-any.whl", hash = "sha256:d8226d10bc02a29bcc81df19a26e56a9647f8b0a6d4a83924139f4a8b01f17b7"}, + {file = "typing_extensions-3.10.0.2-py3-none-any.whl", hash = "sha256:f1d25edafde516b146ecd0613dabcc61409817af4766fbbcfb8d1ad4ec441a34"}, + {file = "typing_extensions-3.10.0.2.tar.gz", hash = "sha256:49f75d16ff11f1cd258e1b988ccff82a3ca5570217d7ad8c5f48205dd99a677e"}, ] uritemplate = [ {file = "uritemplate-3.0.1-py2.py3-none-any.whl", hash = "sha256:07620c3f3f8eed1f12600845892b0e036a2420acf513c53f7de0abd911a5894f"}, {file = "uritemplate-3.0.1.tar.gz", hash = "sha256:5af8ad10cec94f215e3f48112de2022e1d5a37ed427fbd88652fa908f2ab7cae"}, ] urllib3 = [ - {file = "urllib3-1.26.5-py2.py3-none-any.whl", hash = "sha256:753a0374df26658f99d826cfe40394a686d05985786d946fbe4165b5148f5a7c"}, - {file = "urllib3-1.26.5.tar.gz", hash = "sha256:a7acd0977125325f516bda9735fa7142b909a8d01e8b2e4c8108d0984e6e0098"}, + {file = "urllib3-1.26.7-py2.py3-none-any.whl", hash = "sha256:c4fdf4019605b6e5423637e01bc9fe4daef873709a7973e195ceba0a62bbc844"}, + {file = "urllib3-1.26.7.tar.gz", hash = "sha256:4987c65554f7a2dbf30c18fd48778ef124af6fab771a377103da0585e2336ece"}, ] wcwidth = [ {file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"}, @@ -2543,52 +2647,130 @@ websocket-client = [ {file = "websocket_client-0.59.0-py2.py3-none-any.whl", hash = "sha256:2e50d26ca593f70aba7b13a489435ef88b8fc3b5c5643c1ce8808ff9b40f0b32"}, ] wrapt = [ - {file = "wrapt-1.12.1.tar.gz", hash = "sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7"}, + {file = "wrapt-1.13.2-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:3de7b4d3066cc610054e7aa2c005645e308df2f92be730aae3a47d42e910566a"}, + {file = "wrapt-1.13.2-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:8164069f775c698d15582bf6320a4f308c50d048c1c10cf7d7a341feaccf5df7"}, + {file = "wrapt-1.13.2-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9adee1891253670575028279de8365c3a02d3489a74a66d774c321472939a0b1"}, + {file = "wrapt-1.13.2-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:a70d876c9aba12d3bd7f8f1b05b419322c6789beb717044eea2c8690d35cb91b"}, + {file = "wrapt-1.13.2-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:3f87042623530bcffea038f824b63084180513c21e2e977291a9a7e65a66f13b"}, + {file = "wrapt-1.13.2-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:e634136f700a21e1fcead0c137f433dde928979538c14907640607d43537d468"}, + {file = "wrapt-1.13.2-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:3e33c138d1e3620b1e0cc6fd21e46c266393ed5dae0d595b7ed5a6b73ed57aa0"}, + {file = "wrapt-1.13.2-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:283e402e5357e104ac1e3fba5791220648e9af6fb14ad7d9cc059091af2b31d2"}, + {file = "wrapt-1.13.2-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:ccb34ce599cab7f36a4c90318697ead18312c67a9a76327b3f4f902af8f68ea1"}, + {file = "wrapt-1.13.2-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:fbad5ba74c46517e6488149514b2e2348d40df88cd6b52a83855b7a8bf04723f"}, + {file = "wrapt-1.13.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:724ed2bc9c91a2b9026e5adce310fa60c6e7c8760b03391445730b9789b9d108"}, + {file = "wrapt-1.13.2-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:83f2793ec6f3ef513ad8d5b9586f5ee6081cad132e6eae2ecb7eac1cc3decae0"}, + {file = "wrapt-1.13.2-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:0473d1558b93e314e84313cc611f6c86be779369f9d3734302bf185a4d2625b1"}, + {file = "wrapt-1.13.2-cp35-cp35m-win32.whl", hash = "sha256:15eee0e6fd07f48af2f66d0e6f2ff1916ffe9732d464d5e2390695296872cad9"}, + {file = "wrapt-1.13.2-cp35-cp35m-win_amd64.whl", hash = "sha256:bc85d17d90201afd88e3d25421da805e4e135012b5d1f149e4de2981394b2a52"}, + {file = "wrapt-1.13.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:c6ee5f8734820c21b9b8bf705e99faba87f21566d20626568eeb0d62cbeaf23c"}, + {file = "wrapt-1.13.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:53c6706a1bcfb6436f1625511b95b812798a6d2ccc51359cd791e33722b5ea32"}, + {file = "wrapt-1.13.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:fbe6aebc9559fed7ea27de51c2bf5c25ba2a4156cf0017556f72883f2496ee9a"}, + {file = "wrapt-1.13.2-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:0582180566e7a13030f896c2f1ac6a56134ab5f3c3f4c5538086f758b1caf3f2"}, + {file = "wrapt-1.13.2-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:bff0a59387a0a2951cb869251257b6553663329a1b5525b5226cab8c88dcbe7e"}, + {file = "wrapt-1.13.2-cp36-cp36m-win32.whl", hash = "sha256:df3eae297a5f1594d1feb790338120f717dac1fa7d6feed7b411f87e0f2401c7"}, + {file = "wrapt-1.13.2-cp36-cp36m-win_amd64.whl", hash = "sha256:1eb657ed84f4d3e6ad648483c8a80a0cf0a78922ef94caa87d327e2e1ad49b48"}, + {file = "wrapt-1.13.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0cdedf681db878416c05e1831ec69691b0e6577ac7dca9d4f815632e3549580"}, + {file = "wrapt-1.13.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:87ee3c73bdfb4367b26c57259995935501829f00c7b3eed373e2ad19ec21e4e4"}, + {file = "wrapt-1.13.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:3e0d16eedc242d01a6f8cf0623e9cdc3b869329da3f97a15961d8864111d8cf0"}, + {file = "wrapt-1.13.2-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:8318088860968c07e741537030b1abdd8908ee2c71fbe4facdaade624a09e006"}, + {file = "wrapt-1.13.2-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:d90520616fce71c05dedeac3a0fe9991605f0acacd276e5f821842e454485a70"}, + {file = "wrapt-1.13.2-cp37-cp37m-win32.whl", hash = "sha256:22142afab65daffc95863d78effcbd31c19a8003eca73de59f321ee77f73cadb"}, + {file = "wrapt-1.13.2-cp37-cp37m-win_amd64.whl", hash = "sha256:d0d717e10f952df7ea41200c507cc7e24458f4c45b56c36ad418d2e79dacd1d4"}, + {file = "wrapt-1.13.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:593cb049ce1c391e0288523b30426c4430b26e74c7e6f6e2844bd99ac7ecc831"}, + {file = "wrapt-1.13.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:8860c8011a6961a651b1b9f46fdbc589ab63b0a50d645f7d92659618a3655867"}, + {file = "wrapt-1.13.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:ada5e29e59e2feb710589ca1c79fd989b1dd94d27079dc1d199ec954a6ecc724"}, + {file = "wrapt-1.13.2-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:fdede980273aeca591ad354608778365a3a310e0ecdd7a3587b38bc5be9b1808"}, + {file = "wrapt-1.13.2-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:af9480de8e63c5f959a092047aaf3d7077422ded84695b3398f5d49254af3e90"}, + {file = "wrapt-1.13.2-cp38-cp38-win32.whl", hash = "sha256:c65e623ea7556e39c4f0818200a046cbba7575a6b570ff36122c276fdd30ab0a"}, + {file = "wrapt-1.13.2-cp38-cp38-win_amd64.whl", hash = "sha256:b20703356cae1799080d0ad15085dc3213c1ac3f45e95afb9f12769b98231528"}, + {file = "wrapt-1.13.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1c5c4cf188b5643a97e87e2110bbd4f5bc491d54a5b90633837b34d5df6a03fe"}, + {file = "wrapt-1.13.2-cp39-cp39-manylinux1_i686.whl", hash = "sha256:82223f72eba6f63eafca87a0f614495ae5aa0126fe54947e2b8c023969e9f2d7"}, + {file = "wrapt-1.13.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:81a4cf257263b299263472d669692785f9c647e7dca01c18286b8f116dbf6b38"}, + {file = "wrapt-1.13.2-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:728e2d9b7a99dd955d3426f237b940fc74017c4a39b125fec913f575619ddfe9"}, + {file = "wrapt-1.13.2-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:7574de567dcd4858a2ffdf403088d6df8738b0e1eabea220553abf7c9048f59e"}, + {file = "wrapt-1.13.2-cp39-cp39-win32.whl", hash = "sha256:c7ac2c7a8e34bd06710605b21dd1f3576764443d68e069d2afba9b116014d072"}, + {file = "wrapt-1.13.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e6d1a8eeef415d7fb29fe017de0e48f45e45efd2d1bfda28fc50b7b330859ef"}, + {file = "wrapt-1.13.2.tar.gz", hash = "sha256:dca56cc5963a5fd7c2aa8607017753f534ee514e09103a6c55d2db70b50e7447"}, ] wsrpc-aiohttp = [ {file = "wsrpc-aiohttp-3.2.0.tar.gz", hash = "sha256:f467abc51bcdc760fc5aeb7041abdeef46eeca3928dc43dd6e7fa7a533563818"}, {file = "wsrpc_aiohttp-3.2.0-py3-none-any.whl", hash = "sha256:fa9b0bf5cb056898cb5c9f64cbc5eacb8a5dd18ab1b7f0cd4a2208b4a7fde282"}, ] yarl = [ - {file = "yarl-1.6.3-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:0355a701b3998dcd832d0dc47cc5dedf3874f966ac7f870e0f3a6788d802d434"}, - {file = "yarl-1.6.3-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:bafb450deef6861815ed579c7a6113a879a6ef58aed4c3a4be54400ae8871478"}, - {file = "yarl-1.6.3-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:547f7665ad50fa8563150ed079f8e805e63dd85def6674c97efd78eed6c224a6"}, - {file = "yarl-1.6.3-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:63f90b20ca654b3ecc7a8d62c03ffa46999595f0167d6450fa8383bab252987e"}, - {file = "yarl-1.6.3-cp36-cp36m-manylinux2014_ppc64le.whl", hash = "sha256:97b5bdc450d63c3ba30a127d018b866ea94e65655efaf889ebeabc20f7d12406"}, - {file = "yarl-1.6.3-cp36-cp36m-manylinux2014_s390x.whl", hash = "sha256:d8d07d102f17b68966e2de0e07bfd6e139c7c02ef06d3a0f8d2f0f055e13bb76"}, - {file = "yarl-1.6.3-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:15263c3b0b47968c1d90daa89f21fcc889bb4b1aac5555580d74565de6836366"}, - {file = "yarl-1.6.3-cp36-cp36m-win32.whl", hash = "sha256:b5dfc9a40c198334f4f3f55880ecf910adebdcb2a0b9a9c23c9345faa9185721"}, - {file = "yarl-1.6.3-cp36-cp36m-win_amd64.whl", hash = "sha256:b2e9a456c121e26d13c29251f8267541bd75e6a1ccf9e859179701c36a078643"}, - {file = "yarl-1.6.3-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:ce3beb46a72d9f2190f9e1027886bfc513702d748047b548b05dab7dfb584d2e"}, - {file = "yarl-1.6.3-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:2ce4c621d21326a4a5500c25031e102af589edb50c09b321049e388b3934eec3"}, - {file = "yarl-1.6.3-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:d26608cf178efb8faa5ff0f2d2e77c208f471c5a3709e577a7b3fd0445703ac8"}, - {file = "yarl-1.6.3-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:4c5bcfc3ed226bf6419f7a33982fb4b8ec2e45785a0561eb99274ebbf09fdd6a"}, - {file = "yarl-1.6.3-cp37-cp37m-manylinux2014_ppc64le.whl", hash = "sha256:4736eaee5626db8d9cda9eb5282028cc834e2aeb194e0d8b50217d707e98bb5c"}, - {file = "yarl-1.6.3-cp37-cp37m-manylinux2014_s390x.whl", hash = "sha256:68dc568889b1c13f1e4745c96b931cc94fdd0defe92a72c2b8ce01091b22e35f"}, - {file = "yarl-1.6.3-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:7356644cbed76119d0b6bd32ffba704d30d747e0c217109d7979a7bc36c4d970"}, - {file = "yarl-1.6.3-cp37-cp37m-win32.whl", hash = "sha256:00d7ad91b6583602eb9c1d085a2cf281ada267e9a197e8b7cae487dadbfa293e"}, - {file = "yarl-1.6.3-cp37-cp37m-win_amd64.whl", hash = "sha256:69ee97c71fee1f63d04c945f56d5d726483c4762845400a6795a3b75d56b6c50"}, - {file = "yarl-1.6.3-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:e46fba844f4895b36f4c398c5af062a9808d1f26b2999c58909517384d5deda2"}, - {file = "yarl-1.6.3-cp38-cp38-manylinux1_i686.whl", hash = "sha256:31ede6e8c4329fb81c86706ba8f6bf661a924b53ba191b27aa5fcee5714d18ec"}, - {file = "yarl-1.6.3-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:fcbb48a93e8699eae920f8d92f7160c03567b421bc17362a9ffbbd706a816f71"}, - {file = "yarl-1.6.3-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:72a660bdd24497e3e84f5519e57a9ee9220b6f3ac4d45056961bf22838ce20cc"}, - {file = "yarl-1.6.3-cp38-cp38-manylinux2014_ppc64le.whl", hash = "sha256:324ba3d3c6fee56e2e0b0d09bf5c73824b9f08234339d2b788af65e60040c959"}, - {file = "yarl-1.6.3-cp38-cp38-manylinux2014_s390x.whl", hash = "sha256:e6b5460dc5ad42ad2b36cca524491dfcaffbfd9c8df50508bddc354e787b8dc2"}, - {file = "yarl-1.6.3-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:6d6283d8e0631b617edf0fd726353cb76630b83a089a40933043894e7f6721e2"}, - {file = "yarl-1.6.3-cp38-cp38-win32.whl", hash = "sha256:9ede61b0854e267fd565e7527e2f2eb3ef8858b301319be0604177690e1a3896"}, - {file = "yarl-1.6.3-cp38-cp38-win_amd64.whl", hash = "sha256:f0b059678fd549c66b89bed03efcabb009075bd131c248ecdf087bdb6faba24a"}, - {file = "yarl-1.6.3-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:329412812ecfc94a57cd37c9d547579510a9e83c516bc069470db5f75684629e"}, - {file = "yarl-1.6.3-cp39-cp39-manylinux1_i686.whl", hash = "sha256:c49ff66d479d38ab863c50f7bb27dee97c6627c5fe60697de15529da9c3de724"}, - {file = "yarl-1.6.3-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:f040bcc6725c821a4c0665f3aa96a4d0805a7aaf2caf266d256b8ed71b9f041c"}, - {file = "yarl-1.6.3-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:d5c32c82990e4ac4d8150fd7652b972216b204de4e83a122546dce571c1bdf25"}, - {file = "yarl-1.6.3-cp39-cp39-manylinux2014_ppc64le.whl", hash = "sha256:d597767fcd2c3dc49d6eea360c458b65643d1e4dbed91361cf5e36e53c1f8c96"}, - {file = "yarl-1.6.3-cp39-cp39-manylinux2014_s390x.whl", hash = "sha256:8aa3decd5e0e852dc68335abf5478a518b41bf2ab2f330fe44916399efedfae0"}, - {file = "yarl-1.6.3-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:73494d5b71099ae8cb8754f1df131c11d433b387efab7b51849e7e1e851f07a4"}, - {file = "yarl-1.6.3-cp39-cp39-win32.whl", hash = "sha256:5b883e458058f8d6099e4420f0cc2567989032b5f34b271c0827de9f1079a424"}, - {file = "yarl-1.6.3-cp39-cp39-win_amd64.whl", hash = "sha256:4953fb0b4fdb7e08b2f3b3be80a00d28c5c8a2056bb066169de00e6501b986b6"}, - {file = "yarl-1.6.3.tar.gz", hash = "sha256:8a9066529240171b68893d60dca86a763eae2139dd42f42106b03cf4b426bf10"}, + {file = "yarl-1.7.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e35d8230e4b08d86ea65c32450533b906a8267a87b873f2954adeaecede85169"}, + {file = "yarl-1.7.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:eb4b3f277880c314e47720b4b6bb2c85114ab3c04c5442c9bc7006b3787904d8"}, + {file = "yarl-1.7.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c7015dcedb91d90a138eebdc7e432aec8966e0147ab2a55f2df27b1904fa7291"}, + {file = "yarl-1.7.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb3e478175e15e00d659fb0354a6a8db71a7811a2a5052aed98048bc972e5d2b"}, + {file = "yarl-1.7.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8b8c409aa3a7966647e7c1c524846b362a6bcbbe120bf8a176431f940d2b9a2e"}, + {file = "yarl-1.7.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b22ea41c7e98170474a01e3eded1377d46b2dfaef45888a0005c683eaaa49285"}, + {file = "yarl-1.7.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a7dfc46add4cfe5578013dbc4127893edc69fe19132d2836ff2f6e49edc5ecd6"}, + {file = "yarl-1.7.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:82ff6f85f67500a4f74885d81659cd270eb24dfe692fe44e622b8a2fd57e7279"}, + {file = "yarl-1.7.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:f3cd2158b2ed0fb25c6811adfdcc47224efe075f2d68a750071dacc03a7a66e4"}, + {file = "yarl-1.7.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:59c0f13f9592820c51280d1cf811294d753e4a18baf90f0139d1dc93d4b6fc5f"}, + {file = "yarl-1.7.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:7f7655ad83d1a8afa48435a449bf2f3009293da1604f5dd95b5ddcf5f673bd69"}, + {file = "yarl-1.7.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:aa9f0d9b62d15182341b3e9816582f46182cab91c1a57b2d308b9a3c4e2c4f78"}, + {file = "yarl-1.7.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fdd1b90c225a653b1bd1c0cae8edf1957892b9a09c8bf7ee6321eeb8208eac0f"}, + {file = "yarl-1.7.0-cp310-cp310-win32.whl", hash = "sha256:7c8d0bb76eabc5299db203e952ec55f8f4c53f08e0df4285aac8c92bd9e12675"}, + {file = "yarl-1.7.0-cp310-cp310-win_amd64.whl", hash = "sha256:622a36fa779efb4ff9eff5fe52730ff17521431379851a31e040958fc251670c"}, + {file = "yarl-1.7.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:3d461b7a8e139b9e4b41f62eb417ffa0b98d1c46d4caf14c845e6a3b349c0bb1"}, + {file = "yarl-1.7.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81cfacdd1e40bc931b5519499342efa388d24d262c30a3d31187bfa04f4a7001"}, + {file = "yarl-1.7.0-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:821b978f2152be7695d4331ef0621d207aedf9bbd591ba23a63412a3efc29a01"}, + {file = "yarl-1.7.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b64bd24c8c9a487f4a12260dc26732bf41028816dbf0c458f17864fbebdb3131"}, + {file = "yarl-1.7.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:98c9ddb92b60a83c21be42c776d3d9d5ec632a762a094c41bda37b7dfbd2cd83"}, + {file = "yarl-1.7.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a532d75ca74431c053a88a802e161fb3d651b8bf5821a3440bc3616e38754583"}, + {file = "yarl-1.7.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:053e09817eafb892e94e172d05406c1b3a22a93bc68f6eff5198363a3d764459"}, + {file = "yarl-1.7.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:98c51f02d542945d306c8e934aa2c1e66ba5e9c1c86b5bf37f3a51c8a747067e"}, + {file = "yarl-1.7.0-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:15ec41a5a5fdb7bace6d7b16701f9440007a82734f69127c0fbf6d87e10f4a1e"}, + {file = "yarl-1.7.0-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:a7f08819dba1e1255d6991ed37448a1bf4b1352c004bcd899b9da0c47958513d"}, + {file = "yarl-1.7.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:8e3ffab21db0542ffd1887f3b9575ddd58961f2cf61429cb6458afc00c4581e0"}, + {file = "yarl-1.7.0-cp36-cp36m-win32.whl", hash = "sha256:50127634f519b2956005891507e3aa4ac345f66a7ea7bbc2d7dcba7401f41898"}, + {file = "yarl-1.7.0-cp36-cp36m-win_amd64.whl", hash = "sha256:36ec44f15193f6d5288d42ebb8e751b967ebdfb72d6830983838d45ab18edb4f"}, + {file = "yarl-1.7.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:ec1b5a25a25c880c976d0bb3d107def085bb08dbb3db7f4442e0a2b980359d24"}, + {file = "yarl-1.7.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b36f5a63c891f813c6f04ef19675b382efc190fd5ce7e10ab19386d2548bca06"}, + {file = "yarl-1.7.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:38173b8c3a29945e7ecade9a3f6ff39581eee8201338ee6a2c8882db5df3e806"}, + {file = "yarl-1.7.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ba402f32184f0b405fb281b93bd0d8ab7e3257735b57b62a6ed2e94cdf4fe50"}, + {file = "yarl-1.7.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:be52bc5208d767cdd8308a9e93059b3b36d1e048fecbea0e0346d0d24a76adc0"}, + {file = "yarl-1.7.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:08c2044a956f4ef30405f2f433ce77f1f57c2c773bf81ae43201917831044d5a"}, + {file = "yarl-1.7.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:484d61c047c45670ef5967653a1d0783e232c54bf9dd786a7737036828fa8d54"}, + {file = "yarl-1.7.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b7de92a4af85cfcaf4081f8aa6165b1d63ee5de150af3ee85f954145f93105a7"}, + {file = "yarl-1.7.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:376e41775aab79c5575534924a386c8e0f1a5d91db69fc6133fd27a489bcaf10"}, + {file = "yarl-1.7.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:8a8b10d0e7bac154f959b709fcea593cda527b234119311eb950096653816a86"}, + {file = "yarl-1.7.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:f46cd4c43e6175030e2a56def8f1d83b64e6706eeb2bb9ab0ef4756f65eab23f"}, + {file = "yarl-1.7.0-cp37-cp37m-win32.whl", hash = "sha256:b28cfb46140efe1a6092b8c5c4994a1fe70dc83c38fbcea4992401e0c6fb9cce"}, + {file = "yarl-1.7.0-cp37-cp37m-win_amd64.whl", hash = "sha256:9624154ec9c02a776802da1086eed7f5034bd1971977f5146233869c2ac80297"}, + {file = "yarl-1.7.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:69945d13e1bbf81784a9bc48824feb9cd66491e6a503d4e83f6cd7c7cc861361"}, + {file = "yarl-1.7.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:46a742ed9e363bd01be64160ce7520e92e11989bd4cb224403cfd31c101cc83d"}, + {file = "yarl-1.7.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cb4ff1ac7cb4500f43581b3f4cbd627d702143aa6be1fdc1fa3ebffaf4dc1be5"}, + {file = "yarl-1.7.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ad51e17cd65ea3debb0e10f0120cf8dd987c741fe423ed2285087368090b33d"}, + {file = "yarl-1.7.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7e37786ea89a5d3ffbbf318ea9790926f8dfda83858544f128553c347ad143c6"}, + {file = "yarl-1.7.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c63c1e208f800daad71715786bfeb1cecdc595d87e2e9b1cd234fd6e597fd71d"}, + {file = "yarl-1.7.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:91cbe24300c11835ef186436363352b3257db7af165e0a767f4f17aa25761388"}, + {file = "yarl-1.7.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e510dbec7c59d32eaa61ffa48173d5e3d7170a67f4a03e8f5e2e9e3971aca622"}, + {file = "yarl-1.7.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3def6e681cc02397e5d8141ee97b41d02932b2bcf0fb34532ad62855eab7c60e"}, + {file = "yarl-1.7.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:263c81b94e6431942b27f6f671fa62f430a0a5c14bb255f2ab69eeb9b2b66ff7"}, + {file = "yarl-1.7.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:e78c91faefe88d601ddd16e3882918dbde20577a2438e2320f8239c8b7507b8f"}, + {file = "yarl-1.7.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:22b2430c49713bfb2f0a0dd4a8d7aab218b28476ba86fd1c78ad8899462cbcf2"}, + {file = "yarl-1.7.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2e7ad9db939082f5d0b9269cfd92c025cb8f2fbbb1f1b9dc5a393c639db5bd92"}, + {file = "yarl-1.7.0-cp38-cp38-win32.whl", hash = "sha256:3a31e4a8dcb1beaf167b7e7af61b88cb961b220db8d3ba1c839723630e57eef7"}, + {file = "yarl-1.7.0-cp38-cp38-win_amd64.whl", hash = "sha256:d579957439933d752358c6a300c93110f84aae67b63dd0c19dde6ecbf4056f6b"}, + {file = "yarl-1.7.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:87721b549505a546eb003252185103b5ec8147de6d3ad3714d148a5a67b6fe53"}, + {file = "yarl-1.7.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a1fa866fa24d9f4108f9e58ea8a2135655419885cdb443e36b39a346e1181532"}, + {file = "yarl-1.7.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1d3b8449dfedfe94eaff2b77954258b09b24949f6818dfa444b05dbb05ae1b7e"}, + {file = "yarl-1.7.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:db2372e350794ce8b9f810feb094c606b7e0e4aa6807141ac4fadfe5ddd75bb0"}, + {file = "yarl-1.7.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a06d9d0b9a97fa99b84fee71d9dd11e69e21ac8a27229089f07b5e5e50e8d63c"}, + {file = "yarl-1.7.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a3455c2456d6307bcfa80bc1157b8603f7d93573291f5bdc7144489ca0df4628"}, + {file = "yarl-1.7.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:d30d67e3486aea61bb2cbf7cf81385364c2e4f7ce7469a76ed72af76a5cdfe6b"}, + {file = "yarl-1.7.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c18a4b286e8d780c3a40c31d7b79836aa93b720f71d5743f20c08b7e049ca073"}, + {file = "yarl-1.7.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d54c925396e7891666cabc0199366ca55b27d003393465acef63fd29b8b7aa92"}, + {file = "yarl-1.7.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:64773840952de17851a1c7346ad7f71688c77e74248d1f0bc230e96680f84028"}, + {file = "yarl-1.7.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:acbf1756d9dc7cd0ae943d883be72e84e04396f6c2ff93a6ddeca929d562039f"}, + {file = "yarl-1.7.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:2e48f27936aa838939c798f466c851ba4ae79e347e8dfce43b009c64b930df12"}, + {file = "yarl-1.7.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1beef4734ca1ad40a9d8c6b20a76ab46e3a2ed09f38561f01e4aa2ea82cafcef"}, + {file = "yarl-1.7.0-cp39-cp39-win32.whl", hash = "sha256:8ee78c9a5f3c642219d4607680a4693b59239c27a3aa608b64ef79ddc9698039"}, + {file = "yarl-1.7.0-cp39-cp39-win_amd64.whl", hash = "sha256:d750503682605088a14d29a4701548c15c510da4f13c8b17409c4097d5b04c52"}, + {file = "yarl-1.7.0.tar.gz", hash = "sha256:8e7ebaf62e19c2feb097ffb7c94deb0f0c9fab52590784c8cd679d30ab009162"}, ] zipp = [ - {file = "zipp-3.4.1-py3-none-any.whl", hash = "sha256:51cb66cc54621609dd593d1787f286ee42a5c0adbb4b29abea5a63edc3e03098"}, - {file = "zipp-3.4.1.tar.gz", hash = "sha256:3607921face881ba3e026887d8150cca609d517579abe052ac81fc5aeffdbd76"}, + {file = "zipp-3.6.0-py3-none-any.whl", hash = "sha256:9fe5ea21568a0a70e50f273397638d39b03353731e6cbbb3fd8502a33fec40bc"}, + {file = "zipp-3.6.0.tar.gz", hash = "sha256:71c644c5369f4a6e07636f0aa966270449561fcea2e3d6747b8d23efaa9d7832"}, ] From c6e424bc87d0a6606fbae7b48d4e80ae032ccec3 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Tue, 2 Nov 2021 12:05:37 +0100 Subject: [PATCH 022/111] OP-1923 - abstracted dirmap for reuse in hosts Implemented for Maya (refactored current implementation) --- openpype/hosts/maya/api/__init__.py | 117 +++-------------------- openpype/lib/path_tools.py | 140 ++++++++++++++++++++++++++++ 2 files changed, 152 insertions(+), 105 deletions(-) diff --git a/openpype/hosts/maya/api/__init__.py b/openpype/hosts/maya/api/__init__.py index 0a8370eafc..e330904abf 100644 --- a/openpype/hosts/maya/api/__init__.py +++ b/openpype/hosts/maya/api/__init__.py @@ -13,6 +13,7 @@ from pyblish import api as pyblish from openpype.lib import any_outdated import openpype.hosts.maya from openpype.hosts.maya.lib import copy_workspace_mel +from openpype.lib.path_tools import HostDirmap from . import menu, lib log = logging.getLogger("openpype.hosts.maya") @@ -30,7 +31,8 @@ def install(): project_settings = get_project_settings(os.getenv("AVALON_PROJECT")) # process path mapping - process_dirmap(project_settings) + dirmap_processor = MayaDirmap("maya", project_settings) + dirmap_processor.process_dirmap() pyblish.register_plugin_path(PUBLISH_PATH) avalon.register_plugin_path(avalon.Loader, LOAD_PATH) @@ -60,110 +62,6 @@ def install(): avalon.data["familiesStateToggled"] = ["imagesequence"] -def process_dirmap(project_settings): - # type: (dict) -> None - """Go through all paths in Settings and set them using `dirmap`. - - If artists has Site Sync enabled, take dirmap mapping directly from - Local Settings when artist is syncing workfile locally. - - Args: - project_settings (dict): Settings for current project. - - """ - local_mapping = _get_local_sync_dirmap(project_settings) - if not project_settings["maya"].get("maya-dirmap") and not local_mapping: - return - - mapping = local_mapping or \ - project_settings["maya"]["maya-dirmap"]["paths"] \ - or {} - mapping_enabled = project_settings["maya"]["maya-dirmap"]["enabled"] \ - or bool(local_mapping) - - if not mapping or not mapping_enabled: - return - if mapping.get("source-path") and mapping_enabled is True: - log.info("Processing directory mapping ...") - cmds.dirmap(en=True) - for k, sp in enumerate(mapping["source-path"]): - try: - print("{} -> {}".format(sp, mapping["destination-path"][k])) - cmds.dirmap(m=(sp, mapping["destination-path"][k])) - cmds.dirmap(m=(mapping["destination-path"][k], sp)) - except IndexError: - # missing corresponding destination path - log.error(("invalid dirmap mapping, missing corresponding" - " destination directory.")) - break - except RuntimeError: - log.error("invalid path {} -> {}, mapping not registered".format( - sp, mapping["destination-path"][k] - )) - continue - - -def _get_local_sync_dirmap(project_settings): - """ - Returns dirmap if synch to local project is enabled. - - Only valid mapping is from roots of remote site to local site set in - Local Settings. - - Args: - project_settings (dict) - Returns: - dict : { "source-path": [XXX], "destination-path": [YYYY]} - """ - import json - mapping = {} - - if not project_settings["global"]["sync_server"]["enabled"]: - log.debug("Site Sync not enabled") - return mapping - - from openpype.settings.lib import get_site_local_overrides - from openpype.modules import ModulesManager - - manager = ModulesManager() - sync_module = manager.modules_by_name["sync_server"] - - project_name = os.getenv("AVALON_PROJECT") - sync_settings = sync_module.get_sync_project_setting( - os.getenv("AVALON_PROJECT"), exclude_locals=False, cached=False) - log.debug(json.dumps(sync_settings, indent=4)) - - active_site = sync_module.get_local_normalized_site( - sync_module.get_active_site(project_name)) - remote_site = sync_module.get_local_normalized_site( - sync_module.get_remote_site(project_name)) - log.debug("active {} - remote {}".format(active_site, remote_site)) - - if active_site == "local" \ - and project_name in sync_module.get_enabled_projects()\ - and active_site != remote_site: - overrides = get_site_local_overrides(os.getenv("AVALON_PROJECT"), - active_site) - for root_name, value in overrides.items(): - if os.path.isdir(value): - try: - mapping["destination-path"] = [value] - mapping["source-path"] = [sync_settings["sites"]\ - [remote_site]\ - ["root"]\ - [root_name]] - except IndexError: - # missing corresponding destination path - log.debug("overrides".format(overrides)) - log.error( - ("invalid dirmap mapping, missing corresponding" - " destination directory.")) - break - - log.debug("local sync mapping:: {}".format(mapping)) - return mapping - - def uninstall(): pyblish.deregister_plugin_path(PUBLISH_PATH) avalon.deregister_plugin_path(avalon.Loader, LOAD_PATH) @@ -326,3 +224,12 @@ def before_workfile_save(workfile_path): workdir = os.path.dirname(workfile_path) copy_workspace_mel(workdir) + + +class MayaDirmap(HostDirmap): + def on_enable_dirmap(self): + cmds.dirmap(en=True) + + def dirmap_routine(self, source_path, destination_path): + cmds.dirmap(m=(source_path, destination_path)) + cmds.dirmap(m=(destination_path, source_path)) diff --git a/openpype/lib/path_tools.py b/openpype/lib/path_tools.py index 048bf0eda0..f4385ec66e 100644 --- a/openpype/lib/path_tools.py +++ b/openpype/lib/path_tools.py @@ -2,6 +2,8 @@ import json import logging import os import re +import abc +import six from .anatomy import Anatomy @@ -196,3 +198,141 @@ def get_project_basic_paths(project_name): if isinstance(folder_structure, str): folder_structure = json.loads(folder_structure) return _list_path_items(folder_structure) + + +@six.add_metaclass(abc.ABCMeta) +class HostDirmap: + """ + Abstract class for running dirmap on a workfile in a host. + + Dirmap is used to translate paths inside of host workfile from one + OS to another. (Eg. arstist created workfile on Win, different artists + opens same file on Linux.) + + Expects methods to be implemented inside of host: + on_dirmap_enabled: run host code for enabling dirmap + do_dirmap: run host code to do actual remapping + """ + def __init__(self, host_name, project_settings): + self.host_name = host_name + self.project_settings = project_settings + + @abc.abstractmethod + def on_enable_dirmap(self): + """ + Run host dependent operation for enabling dirmap if necessary. + """ + + @abc.abstractmethod + def dirmap_routine(self, source_path, destination_path): + """ + Run host dependent remapping from source_path to destination_path + """ + + def process_dirmap(self): + # type: (dict) -> None + """Go through all paths in Settings and set them using `dirmap`. + + If artists has Site Sync enabled, take dirmap mapping directly from + Local Settings when artist is syncing workfile locally. + + Args: + project_settings (dict): Settings for current project. + + """ + local_mapping = self._get_local_sync_dirmap(self.project_settings) + dirmap_label = "{}-dirmap".format(self.host_name) + if not self.project_settings[self.host_name].get(dirmap_label) and \ + not local_mapping: + return + + mapping = local_mapping or \ + self.project_settings[self.host_name][dirmap_label]["paths"] or {} + mapping_enabled = self.project_settings[self.host_name]\ + [dirmap_label]\ + ["enabled"] \ + or bool(local_mapping) + + if not mapping or not mapping_enabled: + return + if mapping.get("source-path") and mapping_enabled is True: + log.info("Processing directory mapping ...") + self.on_enable_dirmap() + + for k, sp in enumerate(mapping["source-path"]): + try: + print("{} -> {}".format(sp, mapping["destination-path"][k])) + self.dirmap_routine(sp, mapping["destination-path"][k]) + except IndexError: + # missing corresponding destination path + log.error(("invalid dirmap mapping, missing corresponding" + " destination directory.")) + break + except RuntimeError: + log.error("invalid path {} -> {}, mapping not registered".format( #noqa + sp, mapping["destination-path"][k] + )) + continue + + def _get_local_sync_dirmap(self, project_settings): + """ + Returns dirmap if synch to local project is enabled. + + Only valid mapping is from roots of remote site to local site set + in Local Settings. + + Args: + project_settings (dict) + Returns: + dict : { "source-path": [XXX], "destination-path": [YYYY]} + """ + import json + mapping = {} + + if not project_settings["global"]["sync_server"]["enabled"]: + log.debug("Site Sync not enabled") + return mapping + + from openpype.settings.lib import get_site_local_overrides + from openpype.modules import ModulesManager + + manager = ModulesManager() + sync_module = manager.modules_by_name["sync_server"] + + project_name = os.getenv("AVALON_PROJECT") + + active_site = sync_module.get_local_normalized_site( + sync_module.get_active_site(project_name)) + remote_site = sync_module.get_local_normalized_site( + sync_module.get_remote_site(project_name)) + log.debug("active {} - remote {}".format(active_site, remote_site)) + + if active_site == "local" \ + and project_name in sync_module.get_enabled_projects()\ + and active_site != remote_site: + + sync_settings = sync_module.get_sync_project_setting( + os.getenv("AVALON_PROJECT"), exclude_locals=False, + cached=False) + log.debug(json.dumps(sync_settings, indent=4)) + + overrides = get_site_local_overrides(os.getenv("AVALON_PROJECT"), + active_site) + for root_name, value in overrides.items(): + if os.path.isdir(value): + try: + mapping["destination-path"] = [value] + mapping["source-path"] = [sync_settings["sites"]\ + [remote_site]\ + ["root"]\ + [root_name]] + except IndexError: + # missing corresponding destination path + log.debug("overrides".format(overrides)) + log.error( + ("invalid dirmap mapping, missing corresponding" + " destination directory.")) + break + + log.debug("local sync mapping:: {}".format(mapping)) + return mapping From 1bfa8c7daed2021d4e3072080c6ef9ab6e625e8e Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Tue, 2 Nov 2021 15:33:35 +0100 Subject: [PATCH 023/111] OP-1923 - implemented dirmap for Nuke --- openpype/hosts/nuke/startup/menu.py | 42 +++++++++++++ openpype/lib/path_tools.py | 60 +++++++++++-------- .../defaults/project_settings/nuke.json | 10 +++- .../projects_schema/schema_project_nuke.json | 33 ++++++++++ 4 files changed, 117 insertions(+), 28 deletions(-) diff --git a/openpype/hosts/nuke/startup/menu.py b/openpype/hosts/nuke/startup/menu.py index c452acb709..bdbc818ae6 100644 --- a/openpype/hosts/nuke/startup/menu.py +++ b/openpype/hosts/nuke/startup/menu.py @@ -1,8 +1,12 @@ +import os from openpype.hosts.nuke.api.lib import ( on_script_load, check_inventory_versions, WorkfileSettings ) +from openpype.lib.path_tools import HostDirmap +from openpype.settings import get_project_settings +from openpype.modules import ModulesManager import nuke from openpype.api import Logger @@ -10,6 +14,29 @@ from openpype.api import Logger log = Logger().get_logger(__name__) +class NukeDirmap(HostDirmap): + def __init__(self, host_name, project_settings, sync_module, file_name): + """ + Args: + host_name (str): Nuke + project_settings (dict): settings of current project + sync_module (SyncServerModule): to limit reinitialization + file_name (str): full path of referenced file from workfiles + """ + self.host_name = host_name + self.project_settings = project_settings + self.file_name = file_name + self.sync_module = sync_module + + def on_enable_dirmap(self): + pass + + def dirmap_routine(self, source_path, destination_path): + log.debug("{}: {}->{}".format(self.file_name, + source_path, destination_path)) + self.file_name = self.file_name.replace(source_path, destination_path) + + # fix ffmpeg settings on script nuke.addOnScriptLoad(on_script_load) @@ -20,4 +47,19 @@ nuke.addOnScriptSave(check_inventory_versions) # # set apply all workfile settings on script load and save nuke.addOnScriptLoad(WorkfileSettings().set_context_settings) + +project_settings = get_project_settings(os.getenv("AVALON_PROJECT")) +manager = ModulesManager() +sync_module = manager.modules_by_name["sync_server"] + + +def myFilenameFilter(file_name): + dirmap_processor = NukeDirmap("nuke", project_settings, sync_module, + file_name) + dirmap_processor.process_dirmap() + return dirmap_processor.file_name + + +nuke.addFilenameFilter(myFilenameFilter) + log.info('Automatic syncing of write file knob to script version') diff --git a/openpype/lib/path_tools.py b/openpype/lib/path_tools.py index f4385ec66e..a03f9e862e 100644 --- a/openpype/lib/path_tools.py +++ b/openpype/lib/path_tools.py @@ -213,9 +213,10 @@ class HostDirmap: on_dirmap_enabled: run host code for enabling dirmap do_dirmap: run host code to do actual remapping """ - def __init__(self, host_name, project_settings): + def __init__(self, host_name, project_settings, sync_module=None): self.host_name = host_name self.project_settings = project_settings + self.sync_module = sync_module # to limit reinit of Modules @abc.abstractmethod def on_enable_dirmap(self): @@ -240,24 +241,12 @@ class HostDirmap: project_settings (dict): Settings for current project. """ - local_mapping = self._get_local_sync_dirmap(self.project_settings) - dirmap_label = "{}-dirmap".format(self.host_name) - if not self.project_settings[self.host_name].get(dirmap_label) and \ - not local_mapping: + mapping = self.get_mappings(self.project_settings) + if not mapping: return - mapping = local_mapping or \ - self.project_settings[self.host_name][dirmap_label]["paths"] or {} - mapping_enabled = self.project_settings[self.host_name]\ - [dirmap_label]\ - ["enabled"] \ - or bool(local_mapping) - - if not mapping or not mapping_enabled: - return - if mapping.get("source-path") and mapping_enabled is True: - log.info("Processing directory mapping ...") - self.on_enable_dirmap() + log.info("Processing directory mapping ...") + self.on_enable_dirmap() for k, sp in enumerate(mapping["source-path"]): try: @@ -274,6 +263,24 @@ class HostDirmap: )) continue + def get_mappings(self, project_settings): + local_mapping = self._get_local_sync_dirmap(project_settings) + dirmap_label = "{}-dirmap".format(self.host_name) + if not self.project_settings[self.host_name].get(dirmap_label) and \ + not local_mapping: + return [] + + mapping = local_mapping or \ + self.project_settings[self.host_name][dirmap_label]["paths"] or {} + mapping_enabled = self.project_settings[self.host_name]\ + [dirmap_label]\ + ["enabled"] \ + or bool(local_mapping) + + if not mapping or not mapping_enabled: + return [] + return mapping + def _get_local_sync_dirmap(self, project_settings): """ Returns dirmap if synch to local project is enabled. @@ -294,24 +301,25 @@ class HostDirmap: return mapping from openpype.settings.lib import get_site_local_overrides - from openpype.modules import ModulesManager - manager = ModulesManager() - sync_module = manager.modules_by_name["sync_server"] + if not self.sync_module: + from openpype.modules import ModulesManager + manager = ModulesManager() + self.sync_module = manager.modules_by_name["sync_server"] project_name = os.getenv("AVALON_PROJECT") - active_site = sync_module.get_local_normalized_site( - sync_module.get_active_site(project_name)) - remote_site = sync_module.get_local_normalized_site( - sync_module.get_remote_site(project_name)) + active_site = self.sync_module.get_local_normalized_site( + self.sync_module.get_active_site(project_name)) + remote_site = self.sync_module.get_local_normalized_site( + self.sync_module.get_remote_site(project_name)) log.debug("active {} - remote {}".format(active_site, remote_site)) if active_site == "local" \ - and project_name in sync_module.get_enabled_projects()\ + and project_name in self.sync_module.get_enabled_projects()\ and active_site != remote_site: - sync_settings = sync_module.get_sync_project_setting( + sync_settings = self.sync_module.get_sync_project_setting( os.getenv("AVALON_PROJECT"), exclude_locals=False, cached=False) log.debug(json.dumps(sync_settings, indent=4)) diff --git a/openpype/settings/defaults/project_settings/nuke.json b/openpype/settings/defaults/project_settings/nuke.json index e3c7834e4a..9741e5277b 100644 --- a/openpype/settings/defaults/project_settings/nuke.json +++ b/openpype/settings/defaults/project_settings/nuke.json @@ -8,6 +8,13 @@ "build_workfile": "ctrl+alt+b" } }, + "nuke-dirmap": { + "enabled": true, + "paths": { + "source-path": [], + "destination-path": [] + } + }, "create": { "CreateWriteRender": { "fpath_template": "{work}/renders/nuke/{subset}/{subset}.{frame}.{ext}", @@ -130,8 +137,7 @@ }, "LoadClip": { "enabled": true, - "_representations": [ - ], + "_representations": [], "node_name_template": "{class_name}_{ext}" } }, diff --git a/openpype/settings/entities/schemas/projects_schema/schema_project_nuke.json b/openpype/settings/entities/schemas/projects_schema/schema_project_nuke.json index e0b21f4037..22cb8a4ea3 100644 --- a/openpype/settings/entities/schemas/projects_schema/schema_project_nuke.json +++ b/openpype/settings/entities/schemas/projects_schema/schema_project_nuke.json @@ -46,6 +46,39 @@ } ] }, + { + "type": "dict", + "collapsible": true, + "checkbox_key": "enabled", + "key": "nuke-dirmap", + "label": "Nuke Directory Mapping", + "is_group": true, + "children": [ + { + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "dict", + "key": "paths", + "children": [ + { + "type": "list", + "object_type": "text", + "key": "source-path", + "label": "Source Path" + }, + { + "type": "list", + "object_type": "text", + "key": "destination-path", + "label": "Destination Path" + } + ] + } + ] + }, { "type": "dict", "collapsible": true, From 852cea7714f56143ede2a2e78c98f2198133f7db Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Tue, 2 Nov 2021 17:35:09 +0100 Subject: [PATCH 024/111] Hound --- openpype/lib/path_tools.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/openpype/lib/path_tools.py b/openpype/lib/path_tools.py index a03f9e862e..755be7cbe5 100644 --- a/openpype/lib/path_tools.py +++ b/openpype/lib/path_tools.py @@ -258,7 +258,7 @@ class HostDirmap: " destination directory.")) break except RuntimeError: - log.error("invalid path {} -> {}, mapping not registered".format( #noqa + log.error("invalid path {} -> {}, mapping not registered".format( # noqa: E501 sp, mapping["destination-path"][k] )) continue @@ -272,10 +272,8 @@ class HostDirmap: mapping = local_mapping or \ self.project_settings[self.host_name][dirmap_label]["paths"] or {} - mapping_enabled = self.project_settings[self.host_name]\ - [dirmap_label]\ - ["enabled"] \ - or bool(local_mapping) + enbled = self.project_settings[self.host_name][dirmap_label]["enabled"] + mapping_enabled = enbled or bool(local_mapping) if not mapping or not mapping_enabled: return [] @@ -330,9 +328,9 @@ class HostDirmap: if os.path.isdir(value): try: mapping["destination-path"] = [value] - mapping["source-path"] = [sync_settings["sites"]\ - [remote_site]\ - ["root"]\ + mapping["source-path"] = [sync_settings["sites"] + [remote_site] + ["root"] [root_name]] except IndexError: # missing corresponding destination path From 17443c4a91944e6558be153d7d987c286613fe73 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Wed, 3 Nov 2021 09:54:19 +0100 Subject: [PATCH 025/111] add context selector wip --- .../perjob/m50__openpype_publish_render.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/openpype/modules/default_modules/royal_render/rr_root/plugins/plugins/control_job/perjob/m50__openpype_publish_render.py b/openpype/modules/default_modules/royal_render/rr_root/plugins/plugins/control_job/perjob/m50__openpype_publish_render.py index 11f57c7c93..62aa1a59b6 100644 --- a/openpype/modules/default_modules/royal_render/rr_root/plugins/plugins/control_job/perjob/m50__openpype_publish_render.py +++ b/openpype/modules/default_modules/royal_render/rr_root/plugins/plugins/control_job/perjob/m50__openpype_publish_render.py @@ -23,6 +23,7 @@ class OpenPypeContextSelector: self.context = None op_path = os.environ.get("OPENPYPE_ROOT") + print("initializing ... {}".format(op_path)) if not op_path: print("Warning: OpenPype root is not found.") @@ -46,8 +47,7 @@ class OpenPypeContextSelector: " - found OpenPype installation {}".format( op_path)) else: - print("Error: OpenPype was not found.") - op_path = None + raise Exception("Error: OpenPype was not found.") self.openpype_root = op_path @@ -96,10 +96,11 @@ class OpenPypeContextSelector: op_exec = "{}.exe".format(op_exec) with tempfile.TemporaryFile() as tf: - args = list(self.openpype_root) - args.append("context_selector") - args.append(tf) - subprocess.check_output(args) + op_args = [os.path.join(self.openpype_root, op_exec), + "contextselection", tf.name] + + print(">>> running {}".format(op_args)) + subprocess.call(op_args) self.context = json.load(tf) if not self.context or \ @@ -122,5 +123,6 @@ class OpenPypeContextSelector: del warning_dialog +print("running selector") selector = OpenPypeContextSelector() selector.process_job() From 863b353eef7b83b7a85b662fe94215039e3928a1 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Wed, 3 Nov 2021 12:52:44 +0100 Subject: [PATCH 026/111] OP-1932 - remove wrong defaults for dirmaps --- .../settings/defaults/project_settings/maya.json | 12 +++--------- .../settings/defaults/project_settings/nuke.json | 2 +- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/openpype/settings/defaults/project_settings/maya.json b/openpype/settings/defaults/project_settings/maya.json index f8f3432d0f..ae1ce9ef13 100644 --- a/openpype/settings/defaults/project_settings/maya.json +++ b/openpype/settings/defaults/project_settings/maya.json @@ -8,16 +8,10 @@ "yetiRig": "ma" }, "maya-dirmap": { - "enabled": true, + "enabled": false, "paths": { - "source-path": [ - "foo1", - "foo2" - ], - "destination-path": [ - "bar1", - "bar2" - ] + "source-path": [], + "destination-path": [] } }, "scriptsmenu": { diff --git a/openpype/settings/defaults/project_settings/nuke.json b/openpype/settings/defaults/project_settings/nuke.json index 9741e5277b..069994d0e8 100644 --- a/openpype/settings/defaults/project_settings/nuke.json +++ b/openpype/settings/defaults/project_settings/nuke.json @@ -9,7 +9,7 @@ } }, "nuke-dirmap": { - "enabled": true, + "enabled": false, "paths": { "source-path": [], "destination-path": [] From 93953e65c8b24f424106677e81d6ac7953414b82 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Wed, 3 Nov 2021 13:07:17 +0100 Subject: [PATCH 027/111] OP-1932 - refactoring - moved everything to lib Added caching class for expensive operations --- openpype/hosts/nuke/api/lib.py | 61 +++++++++++++++++++++++++++++ openpype/hosts/nuke/startup/menu.py | 44 +-------------------- openpype/lib/path_tools.py | 28 +++++++++---- 3 files changed, 84 insertions(+), 49 deletions(-) diff --git a/openpype/hosts/nuke/api/lib.py b/openpype/hosts/nuke/api/lib.py index 9ee3a4464b..bfbb19ddcb 100644 --- a/openpype/hosts/nuke/api/lib.py +++ b/openpype/hosts/nuke/api/lib.py @@ -24,6 +24,10 @@ from openpype.api import ( ApplicationManager ) from openpype.tools.utils import host_tools +from openpype.lib.path_tools import HostDirmap +from openpype.settings import get_project_settings +from openpype.modules import ModulesManager + import nuke from .utils import set_context_favorites @@ -1795,3 +1799,60 @@ def recreate_instance(origin_node, avalon_data=None): dn.setInput(0, new_node) return new_node + + +class NukeDirmap(HostDirmap): + def __init__(self, host_name, project_settings, sync_module, file_name): + """ + Args: + host_name (str): Nuke + project_settings (dict): settings of current project + sync_module (SyncServerModule): to limit reinitialization + file_name (str): full path of referenced file from workfiles + """ + self.host_name = host_name + self.project_settings = project_settings + self.file_name = file_name + self.sync_module = sync_module + + self._mapping = None # cache mapping + + def on_enable_dirmap(self): + pass + + def dirmap_routine(self, source_path, destination_path): + log.debug("{}: {}->{}".format(self.file_name, + source_path, destination_path)) + self.file_name = self.file_name.replace(source_path, destination_path) + + +class DirmapCache: + """Caching class to get settings and sync_module easily and only once.""" + _project_settings = None + _sync_module = None + + @classmethod + def project_settings(cls): + if cls._project_settings is None: + cls._project_settings = get_project_settings( + os.getenv("AVALON_PROJECT")) + return cls._project_settings + + @classmethod + def sync_module(cls): + if cls._sync_module is None: + cls._sync_module = ModulesManager().modules_by_name["sync_server"] + return cls._sync_module + + +def dirmap_file_name_filter(file_name): + """Nuke callback function with single full path argument. + + Checks project settings for potential mapping from source to dest. + """ + dirmap_processor = NukeDirmap("nuke", + DirmapCache.project_settings(), + DirmapCache.sync_module(), + file_name) + dirmap_processor.process_dirmap() + return dirmap_processor.file_name diff --git a/openpype/hosts/nuke/startup/menu.py b/openpype/hosts/nuke/startup/menu.py index bdbc818ae6..b7ed35b3b4 100644 --- a/openpype/hosts/nuke/startup/menu.py +++ b/openpype/hosts/nuke/startup/menu.py @@ -1,42 +1,15 @@ -import os from openpype.hosts.nuke.api.lib import ( on_script_load, check_inventory_versions, WorkfileSettings ) -from openpype.lib.path_tools import HostDirmap -from openpype.settings import get_project_settings -from openpype.modules import ModulesManager import nuke from openpype.api import Logger +from openpype.hosts.nuke.api.lib import dirmap_file_name_filter log = Logger().get_logger(__name__) - -class NukeDirmap(HostDirmap): - def __init__(self, host_name, project_settings, sync_module, file_name): - """ - Args: - host_name (str): Nuke - project_settings (dict): settings of current project - sync_module (SyncServerModule): to limit reinitialization - file_name (str): full path of referenced file from workfiles - """ - self.host_name = host_name - self.project_settings = project_settings - self.file_name = file_name - self.sync_module = sync_module - - def on_enable_dirmap(self): - pass - - def dirmap_routine(self, source_path, destination_path): - log.debug("{}: {}->{}".format(self.file_name, - source_path, destination_path)) - self.file_name = self.file_name.replace(source_path, destination_path) - - # fix ffmpeg settings on script nuke.addOnScriptLoad(on_script_load) @@ -47,19 +20,6 @@ nuke.addOnScriptSave(check_inventory_versions) # # set apply all workfile settings on script load and save nuke.addOnScriptLoad(WorkfileSettings().set_context_settings) - -project_settings = get_project_settings(os.getenv("AVALON_PROJECT")) -manager = ModulesManager() -sync_module = manager.modules_by_name["sync_server"] - - -def myFilenameFilter(file_name): - dirmap_processor = NukeDirmap("nuke", project_settings, sync_module, - file_name) - dirmap_processor.process_dirmap() - return dirmap_processor.file_name - - -nuke.addFilenameFilter(myFilenameFilter) +nuke.addFilenameFilter(dirmap_file_name_filter) log.info('Automatic syncing of write file knob to script version') diff --git a/openpype/lib/path_tools.py b/openpype/lib/path_tools.py index 755be7cbe5..193878c9aa 100644 --- a/openpype/lib/path_tools.py +++ b/openpype/lib/path_tools.py @@ -218,6 +218,8 @@ class HostDirmap: self.project_settings = project_settings self.sync_module = sync_module # to limit reinit of Modules + self._mapping = None # cache mapping + @abc.abstractmethod def on_enable_dirmap(self): """ @@ -241,17 +243,21 @@ class HostDirmap: project_settings (dict): Settings for current project. """ - mapping = self.get_mappings(self.project_settings) - if not mapping: + if not self._mapping: + self._mapping = self.get_mappings(self.project_settings) + if not self._mapping: return log.info("Processing directory mapping ...") self.on_enable_dirmap() + log.info("mapping:: {}".format(self._mapping)) - for k, sp in enumerate(mapping["source-path"]): + for k, sp in enumerate(self._mapping["source-path"]): try: - print("{} -> {}".format(sp, mapping["destination-path"][k])) - self.dirmap_routine(sp, mapping["destination-path"][k]) + print("{} -> {}".format(sp, + self._mapping["destination-path"][k])) + self.dirmap_routine(sp, + self._mapping["destination-path"][k]) except IndexError: # missing corresponding destination path log.error(("invalid dirmap mapping, missing corresponding" @@ -259,11 +265,16 @@ class HostDirmap: break except RuntimeError: log.error("invalid path {} -> {}, mapping not registered".format( # noqa: E501 - sp, mapping["destination-path"][k] + sp, self._mapping["destination-path"][k] )) continue def get_mappings(self, project_settings): + """Get translation from source-path to destination-path. + + It checks if Site Sync is enabled and user chose to use local + site, in that case configuration in Local Settings takes precedence + """ local_mapping = self._get_local_sync_dirmap(project_settings) dirmap_label = "{}-dirmap".format(self.host_name) if not self.project_settings[self.host_name].get(dirmap_label) and \ @@ -275,8 +286,11 @@ class HostDirmap: enbled = self.project_settings[self.host_name][dirmap_label]["enabled"] mapping_enabled = enbled or bool(local_mapping) - if not mapping or not mapping_enabled: + if not mapping or not mapping_enabled or \ + not mapping.get("destination-path") or \ + not mapping.get("source-path"): return [] + return mapping def _get_local_sync_dirmap(self, project_settings): From 052366c608258bbcff1707eb95e69557e93d5ec7 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Wed, 3 Nov 2021 15:05:44 +0100 Subject: [PATCH 028/111] OP-1932 - fix - source-path and destination path were switched for local sync --- openpype/lib/path_tools.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/openpype/lib/path_tools.py b/openpype/lib/path_tools.py index 193878c9aa..3dc142c11b 100644 --- a/openpype/lib/path_tools.py +++ b/openpype/lib/path_tools.py @@ -339,13 +339,12 @@ class HostDirmap: overrides = get_site_local_overrides(os.getenv("AVALON_PROJECT"), active_site) for root_name, value in overrides.items(): + remote_site_dir = \ + sync_settings["sites"][remote_site]["root"][root_name] if os.path.isdir(value): try: mapping["destination-path"] = [value] - mapping["source-path"] = [sync_settings["sites"] - [remote_site] - ["root"] - [root_name]] + mapping["source-path"] = [remote_site_dir] except IndexError: # missing corresponding destination path log.debug("overrides".format(overrides)) From 8a37b9065e340be28a1a7c85a4be68ac8308e9a1 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Wed, 3 Nov 2021 16:22:20 +0100 Subject: [PATCH 029/111] OP-1937 - added alternative_sites to System Setting for a site --- openpype/settings/entities/dict_conditional.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/openpype/settings/entities/dict_conditional.py b/openpype/settings/entities/dict_conditional.py index 6f27760570..3621c1319a 100644 --- a/openpype/settings/entities/dict_conditional.py +++ b/openpype/settings/entities/dict_conditional.py @@ -762,6 +762,17 @@ class SyncServerProviders(DictConditionalEntity): enum_children = [] for provider_code, configurables in system_settings_schema.items(): + # any site could be exposed or vendorized by different site + # eg studio site content could be mapped on sftp site, single file + # accessible via 2 different protocols (sites) + configurables.append( + { + "type": "list", + "key": "alternative_sites", + "label": "Alternative sites", + "object_type": "text" + } + ) label = provider_code_to_label.get(provider_code) or provider_code enum_children.append({ From 26b9bbaedae7e21b6f4346b403160a495eb53d83 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 4 Nov 2021 13:03:57 +0100 Subject: [PATCH 030/111] OP-1937 - added alternative_sites integrate_new --- openpype/plugins/publish/integrate_new.py | 68 +++++++++++++++-------- 1 file changed, 45 insertions(+), 23 deletions(-) diff --git a/openpype/plugins/publish/integrate_new.py b/openpype/plugins/publish/integrate_new.py index fe780480c2..2f90cd7d66 100644 --- a/openpype/plugins/publish/integrate_new.py +++ b/openpype/plugins/publish/integrate_new.py @@ -1029,31 +1029,25 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): local_site = 'studio' # default remote_site = None always_accesible = [] - sync_server_presets = None + alternate_sites = set() + system_sync_server_presets = instance.context.data["system_settings"]\ + ["modules"]\ + ["sync_server"] + log.debug("system_sett:: {}".format(system_sync_server_presets)) + if system_sync_server_presets["enabled"]: + sync_project_presets = (instance.context.data["project_settings"] + ["global"] + ["sync_server"]) - if (instance.context.data["system_settings"] - ["modules"] - ["sync_server"] - ["enabled"]): - sync_server_presets = (instance.context.data["project_settings"] - ["global"] - ["sync_server"]) + if sync_project_presets["enabled"]: + local_site, remote_site = self._get_sites(sync_project_presets) - local_site_id = openpype.api.get_local_site_id() - if sync_server_presets["enabled"]: - local_site = sync_server_presets["config"].\ - get("active_site", "studio").strip() - always_accesible = sync_server_presets["config"].\ - get("always_accessible_on", []) - if local_site == 'local': - local_site = local_site_id - - remote_site = sync_server_presets["config"].get("remote_site") - if remote_site == local_site: - remote_site = None - - if remote_site == 'local': - remote_site = local_site_id + sites = system_sync_server_presets.get("sites", {}) + log.debug("sites:: {}".format(sites)) + for site_name, site_info in sites.items(): + for added_site in [local_site, remote_site]: + if added_site in site_info.get("alternative_sites",[]): + alternate_sites.add(site_name) rec = { "_id": io.ObjectId(), @@ -1068,21 +1062,49 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): if sites: rec["sites"] = sites else: + already_attached_sites = set() meta = {"name": local_site, "created_dt": datetime.now()} rec["sites"] = [meta] + already_attached_sites.add(meta["name"]) if remote_site: meta = {"name": remote_site.strip()} rec["sites"].append(meta) + already_attached_sites.add(meta["name"]) # add skeleton for site where it should be always synced to for always_on_site in always_accesible: if always_on_site not in [local_site, remote_site]: meta = {"name": always_on_site.strip()} rec["sites"].append(meta) + already_attached_sites.add(meta["name"]) + + log.debug("alternate_sites:: {}".format(alternate_sites)) + for alt_site in alternate_sites: + if alt_site not in already_attached_sites: + meta = {"name": local_site, "created_dt": datetime.now()} + rec["sites"].append(meta) return rec + def _get_sites(self, sync_project_presets): + local_site_id = openpype.api.get_local_site_id() + local_site = sync_project_presets["config"]. \ + get("active_site", "studio").strip() + always_accesible = sync_project_presets["config"]. \ + get("always_accessible_on", []) + if local_site == 'local': + local_site = local_site_id + + remote_site = sync_project_presets["config"].get("remote_site") + if remote_site == local_site: + remote_site = None + + if remote_site == 'local': + remote_site = local_site_id + + return local_site, remote_site + def handle_destination_files(self, integrated_file_sizes, mode): """ Clean destination files Called when error happened during integrating to DB or to disk From 691faaf70d7abbd191d5ce7c22d188256c577066 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 4 Nov 2021 13:04:20 +0100 Subject: [PATCH 031/111] OP-1937 - added alternative_sites to upload/download --- .../sync_server/sync_server.py | 8 +++ .../sync_server/sync_server_module.py | 53 ++++++++++++++++--- 2 files changed, 55 insertions(+), 6 deletions(-) diff --git a/openpype/modules/default_modules/sync_server/sync_server.py b/openpype/modules/default_modules/sync_server/sync_server.py index 66d4e46db7..6eaede048c 100644 --- a/openpype/modules/default_modules/sync_server/sync_server.py +++ b/openpype/modules/default_modules/sync_server/sync_server.py @@ -80,6 +80,10 @@ async def upload(module, collection, file, representation, provider_name, remote_site_name, True ) + + module.handle_alternate_site(collection, representation, remote_site_name, + file["_id"]) + return file_id @@ -131,6 +135,10 @@ async def download(module, collection, file, representation, provider_name, local_site, True ) + + module.handle_alternate_site(collection, representation, remote_site_name, + file["_id"]) + return file_id diff --git a/openpype/modules/default_modules/sync_server/sync_server_module.py b/openpype/modules/default_modules/sync_server/sync_server_module.py index a2cfd6f6b9..af672e7a6f 100644 --- a/openpype/modules/default_modules/sync_server/sync_server_module.py +++ b/openpype/modules/default_modules/sync_server/sync_server_module.py @@ -109,6 +109,7 @@ class SyncServerModule(OpenPypeModule, ITrayModule): # some parts of code need to run sequentially, not in async self.lock = None + self._sync_system_settings = None # settings for all enabled projects for sync self._sync_project_settings = None self.sync_server_thread = None # asyncio requires new thread @@ -769,6 +770,38 @@ class SyncServerModule(OpenPypeModule, ITrayModule): enabled_projects.append(project_name) return enabled_projects + + def handle_alternate_site(self, collection, representation, processed_site, + file_id): + """ + For special use cases where one site vendors another. + + Current use case is sftp site vendoring (exposing) same data as + regular site (studio). Each site is accessible for different + audience. 'studio' for artists in a studio, 'sftp' for externals. + + Change of file status on one site actually means same change on + 'alternate' site. (eg. artists publish to 'studio', 'sftp' is using + same location >> file is accesible on 'sftp' site right away. + + Args: + collection (str): name of project + representation (dict) + processed_site (str): real site_name of published/uploaded file + file_id (ObjectId): DB id of file handled + """ + sites = self.sync_system_settings.get("sites", {}) + for site_name, site_info in sites.items(): + if processed_site in site_info.get("alternative_sites", []): + query = { + "_id": representation["_id"] + } + elem = {"name": "sftp", "created_dt": datetime.now()} + self.log.debug("Adding alternate {} to {}".format( + site_name, representation["_id"])) + self._add_site(collection, query, + [representation], elem, + site_name, file_id=file_id, force=True) """ End of Public API """ def get_local_file_path(self, collection, site_name, file_path): @@ -919,6 +952,14 @@ class SyncServerModule(OpenPypeModule, ITrayModule): return self._connection + @property + def sync_system_settings(self): + if self._sync_system_settings is None: + self._sync_system_settings = get_system_settings()["modules"].\ + get("sync_server") + + return self._sync_system_settings + @property def sync_project_settings(self): if self._sync_project_settings is None: @@ -1004,9 +1045,7 @@ class SyncServerModule(OpenPypeModule, ITrayModule): (dict): {'studio': {'provider':'local_drive'...}, 'MY_LOCAL': {'provider':....}} """ - sys_sett = get_system_settings() - sync_sett = sys_sett["modules"].get("sync_server") - + sync_sett = self.sync_system_settings project_enabled = True if project_name: project_enabled = project_name in self.get_enabled_projects() @@ -1064,8 +1103,7 @@ class SyncServerModule(OpenPypeModule, ITrayModule): if provider: return provider - sys_sett = get_system_settings() - sync_sett = sys_sett["modules"].get("sync_server") + sync_sett = self.sync_system_settings for site, detail in sync_sett.get("sites", {}).items(): sites[site] = detail.get("provider") @@ -1434,9 +1472,12 @@ class SyncServerModule(OpenPypeModule, ITrayModule): update = { "$set": {"files.$[f].sites.$[s]": elem} } + if not isinstance(file_id, ObjectId): + file_id = ObjectId(file_id) + arr_filter = [ {'s.name': site_name}, - {'f._id': ObjectId(file_id)} + {'f._id': file_id} ] self._update_site(collection, query, update, arr_filter) From f19b39185d47b4666a8065bb155823dbcaefd4dd Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 4 Nov 2021 13:04:54 +0100 Subject: [PATCH 032/111] OP-1937 - fixes to stabilize sftp provider if wrong settings --- .../sync_server/providers/sftp.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/openpype/modules/default_modules/sync_server/providers/sftp.py b/openpype/modules/default_modules/sync_server/providers/sftp.py index 07450265e2..8549c1c981 100644 --- a/openpype/modules/default_modules/sync_server/providers/sftp.py +++ b/openpype/modules/default_modules/sync_server/providers/sftp.py @@ -1,8 +1,7 @@ import os import os.path import time -import sys -import six +import paramiko import threading import platform @@ -37,7 +36,6 @@ class SFTPHandler(AbstractProvider): def __init__(self, project_name, site_name, tree=None, presets=None): self.presets = None - self.active = False self.project_name = project_name self.site_name = site_name self.root = None @@ -64,7 +62,6 @@ class SFTPHandler(AbstractProvider): self.sftp_key_pass = provider_presets["sftp_key_pass"] self._tree = None - self.active = True @property def conn(self): @@ -80,7 +77,9 @@ class SFTPHandler(AbstractProvider): Returns: (boolean) """ - return self.conn is not None + return self.presets.get(self.CODE) and \ + self.presets[self.CODE].get("sftp_host") and \ + self.conn is not None @classmethod def get_system_settings_schema(cls): @@ -108,7 +107,7 @@ class SFTPHandler(AbstractProvider): editable = [ # credentials could be overriden on Project or User level { - 'key': "sftp_server", + 'key': "sftp_host", 'label': "SFTP host name", 'type': 'text' }, @@ -421,7 +420,10 @@ class SFTPHandler(AbstractProvider): if self.sftp_key_pass: conn_params['private_key_pass'] = self.sftp_key_pass - return pysftp.Connection(**conn_params) + try: + return pysftp.Connection(**conn_params) + except paramiko.ssh_exception.SSHException: + log.warning("Couldn't connect", exc_info=True) def _mark_progress(self, collection, file, representation, server, site, source_path, target_path, direction): From ab36fdfe711400059e103e6475c43f60a6de754c Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 4 Nov 2021 14:00:03 +0100 Subject: [PATCH 033/111] OP-1937 - added documentation --- .../docs/assets/site_sync_system_sites.png | Bin 0 -> 13118 bytes website/docs/module_site_sync.md | 47 ++++++++++++------ 2 files changed, 32 insertions(+), 15 deletions(-) create mode 100644 website/docs/assets/site_sync_system_sites.png diff --git a/website/docs/assets/site_sync_system_sites.png b/website/docs/assets/site_sync_system_sites.png new file mode 100644 index 0000000000000000000000000000000000000000..e9f895c74347ac8f311e81ad3f1dd6a388723695 GIT binary patch literal 13118 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 Y)~G@38KWNnZe$uybRWYW*}eY10Psf-VgLXD literal 0 HcmV?d00001 diff --git a/website/docs/module_site_sync.md b/website/docs/module_site_sync.md index 31854e2729..4e3c8e4ed9 100644 --- a/website/docs/module_site_sync.md +++ b/website/docs/module_site_sync.md @@ -27,6 +27,38 @@ To use synchronization, *Site Sync* needs to be enabled globally in **OpenPype S ![Configure module](assets/site_sync_system.png) +### Sites + +By default there are two sites created for each OpenPype installation: +- **studio** - default site - usually a centralized mounted disk accessible to all artists. Studio site is used if Site Sync is disabled. +- **local** - each workstation or server running OpenPype Tray receives its own with unique site name. Workstation refers to itself as "local"however all other sites will see it under it's unique ID. + +Artists can explore their site ID by opening OpenPype Info tool by clicking on a version number in the tray app. + +Many different sites can be created and configured on the system level, and some or all can be assigned to each project. + +Each OpenPype Tray app works with two sites at one time. (Sites can be the same, and no synching is done in this setup). + +Sites could be configured differently per project basis. + +Each new site needs to be created first in `System Settings`. Most important feature of site is its Provider, select one from already prepared Providers. + +#### Alternative sites + +This attribute is meant for special use cases only. + +One of the use cases is sftp site vendoring (exposing) same data as regular site (studio). Each site is accessible for different audience. 'studio' for artists in a studio via shared disk, 'sftp' for externals via sftp server with mounted 'studio' drive. + +Change of file status on one site actually means same change on 'alternate' site occured too. (eg. artists publish to 'studio', 'sftp' is using +same location >> file is accessible on 'sftp' site right away, no need to sync it anyhow.) + +##### Example +![Configure module](assets/site_sync_system_sites.png) +Admin created new `sftp` site which is handled by `SFTP` provider. Somewhere in the studio SFTP server is deployed on a machine that has access to `studio` drive. + +Alternative sites work both way: +- everything published to `studio` is accessible on a `sftp` site too +- everything published to `sftp` (most probably via artist's local disk - artists publishes locally, representation is marked to be synced to `sftp`. Immediately after it is synced, it is marked to be available on `studio` too for artists in the studio to use.) ## Project Settings @@ -45,21 +77,6 @@ Artists can also override which site they use as active and remote if need be. ![Local overrides](assets/site_sync_local_setting.png) -## Sites - -By default there are two sites created for each OpenPype installation: -- **studio** - default site - usually a centralized mounted disk accessible to all artists. Studio site is used if Site Sync is disabled. -- **local** - each workstation or server running OpenPype Tray receives its own with unique site name. Workstation refers to itself as "local"however all other sites will see it under it's unique ID. - -Artists can explore their site ID by opening OpenPype Info tool by clicking on a version number in the tray app. - -Many different sites can be created and configured on the system level, and some or all can be assigned to each project. - -Each OpenPype Tray app works with two sites at one time. (Sites can be the same, and no synching is done in this setup). - -Sites could be configured differently per project basis. - - ## Providers Each site implements a so called `provider` which handles most common operations (list files, copy files etc.) and provides interface with a particular type of storage. (disk, gdrive, aws, etc.) From db02c03394f1d5d159152e0873059c6c7146b387 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 4 Nov 2021 14:01:51 +0100 Subject: [PATCH 034/111] OP-1937 - fix broken import in Python2 Not imported exception in that case shouldnt happen, as sync process is not running in Python2. --- openpype/modules/default_modules/sync_server/providers/sftp.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/modules/default_modules/sync_server/providers/sftp.py b/openpype/modules/default_modules/sync_server/providers/sftp.py index 8549c1c981..267e23f8fb 100644 --- a/openpype/modules/default_modules/sync_server/providers/sftp.py +++ b/openpype/modules/default_modules/sync_server/providers/sftp.py @@ -1,7 +1,6 @@ import os import os.path import time -import paramiko import threading import platform @@ -13,6 +12,7 @@ log = Logger().get_logger("SyncServer") pysftp = None try: import pysftp + import paramiko except (ImportError, SyntaxError): pass From 1e1b9b0416b804e815785fdfa83e7acf38e8128b Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 4 Nov 2021 16:19:04 +0100 Subject: [PATCH 035/111] OP-1937 - added file id to DB --- .../modules/default_modules/sync_server/sync_server.py | 4 ++-- .../default_modules/sync_server/sync_server_module.py | 9 +++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/openpype/modules/default_modules/sync_server/sync_server.py b/openpype/modules/default_modules/sync_server/sync_server.py index 6eaede048c..8518c4a301 100644 --- a/openpype/modules/default_modules/sync_server/sync_server.py +++ b/openpype/modules/default_modules/sync_server/sync_server.py @@ -82,7 +82,7 @@ async def upload(module, collection, file, representation, provider_name, ) module.handle_alternate_site(collection, representation, remote_site_name, - file["_id"]) + file["_id"], file_id) return file_id @@ -137,7 +137,7 @@ async def download(module, collection, file, representation, provider_name, ) module.handle_alternate_site(collection, representation, remote_site_name, - file["_id"]) + file["_id"], file_id) return file_id diff --git a/openpype/modules/default_modules/sync_server/sync_server_module.py b/openpype/modules/default_modules/sync_server/sync_server_module.py index af672e7a6f..9ff706d6dd 100644 --- a/openpype/modules/default_modules/sync_server/sync_server_module.py +++ b/openpype/modules/default_modules/sync_server/sync_server_module.py @@ -772,7 +772,7 @@ class SyncServerModule(OpenPypeModule, ITrayModule): return enabled_projects def handle_alternate_site(self, collection, representation, processed_site, - file_id): + file_id, synced_file_id): """ For special use cases where one site vendors another. @@ -789,6 +789,8 @@ class SyncServerModule(OpenPypeModule, ITrayModule): representation (dict) processed_site (str): real site_name of published/uploaded file file_id (ObjectId): DB id of file handled + synced_file_id (str): id of the created file returned + by provider """ sites = self.sync_system_settings.get("sites", {}) for site_name, site_info in sites.items(): @@ -796,7 +798,10 @@ class SyncServerModule(OpenPypeModule, ITrayModule): query = { "_id": representation["_id"] } - elem = {"name": "sftp", "created_dt": datetime.now()} + elem = {"name": "sftp", + "created_dt": datetime.now(), + "id": synced_file_id} + self.log.debug("Adding alternate {} to {}".format( site_name, representation["_id"])) self._add_site(collection, query, From 8ba0e606711c0bc440dbaf43750bbfeb3b685e9f Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 4 Nov 2021 16:19:23 +0100 Subject: [PATCH 036/111] OP-1937 - fix - integrate_new --- openpype/plugins/publish/integrate_new.py | 98 ++++++++++++++--------- 1 file changed, 62 insertions(+), 36 deletions(-) diff --git a/openpype/plugins/publish/integrate_new.py b/openpype/plugins/publish/integrate_new.py index ab79d95fb7..c0a90ee78e 100644 --- a/openpype/plugins/publish/integrate_new.py +++ b/openpype/plugins/publish/integrate_new.py @@ -1030,25 +1030,6 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): local_site = 'studio' # default remote_site = None always_accesible = [] - alternate_sites = set() - system_sync_server_presets = instance.context.data["system_settings"]\ - ["modules"]\ - ["sync_server"] - log.debug("system_sett:: {}".format(system_sync_server_presets)) - if system_sync_server_presets["enabled"]: - sync_project_presets = (instance.context.data["project_settings"] - ["global"] - ["sync_server"]) - - if sync_project_presets["enabled"]: - local_site, remote_site = self._get_sites(sync_project_presets) - - sites = system_sync_server_presets.get("sites", {}) - log.debug("sites:: {}".format(sites)) - for site_name, site_info in sites.items(): - for added_site in [local_site, remote_site]: - if added_site in site_info.get("alternative_sites",[]): - alternate_sites.add(site_name) rec = { "_id": io.ObjectId(), @@ -1063,28 +1044,48 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): if sites: rec["sites"] = sites else: - already_attached_sites = set() + system_sync_server_presets = ( + instance.context.data["system_settings"] + ["modules"] + ["sync_server"]) + log.debug("system_sett:: {}".format(system_sync_server_presets)) + + if system_sync_server_presets["enabled"]: + sync_project_presets = ( + instance.context.data["project_settings"] + ["global"] + ["sync_server"]) + + if sync_project_presets and sync_project_presets["enabled"]: + local_site, remote_site = self._get_sites(sync_project_presets) + + always_accesible = sync_project_presets["config"]. \ + get("always_accessible_on", []) + + already_attached_sites = {} meta = {"name": local_site, "created_dt": datetime.now()} rec["sites"] = [meta] - already_attached_sites.add(meta["name"]) + already_attached_sites[meta["name"]] = meta["created_dt"] - if remote_site: + if sync_project_presets and sync_project_presets["enabled"]: + # add remote meta = {"name": remote_site.strip()} rec["sites"].append(meta) - already_attached_sites.add(meta["name"]) + already_attached_sites[meta["name"]] = None - # add skeleton for site where it should be always synced to - for always_on_site in always_accesible: - if always_on_site not in [local_site, remote_site]: - meta = {"name": always_on_site.strip()} - rec["sites"].append(meta) - already_attached_sites.add(meta["name"]) + # add skeleton for site where it should be always synced to + for always_on_site in always_accesible: + if always_on_site not in already_attached_sites.keys(): + meta = {"name": always_on_site.strip()} + rec["sites"].append(meta) + already_attached_sites[meta["name"]] = None - log.debug("alternate_sites:: {}".format(alternate_sites)) - for alt_site in alternate_sites: - if alt_site not in already_attached_sites: - meta = {"name": local_site, "created_dt": datetime.now()} - rec["sites"].append(meta) + # add alternative sites + rec = self._add_alternative_sites(system_sync_server_presets, + already_attached_sites, + rec) + + log.debug("final sites:: {}".format(rec["sites"])) return rec @@ -1092,8 +1093,7 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): local_site_id = openpype.api.get_local_site_id() local_site = sync_project_presets["config"]. \ get("active_site", "studio").strip() - always_accesible = sync_project_presets["config"]. \ - get("always_accessible_on", []) + if local_site == 'local': local_site = local_site_id @@ -1106,6 +1106,32 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): return local_site, remote_site + def _add_alternative_sites(self, + system_sync_server_presets, + already_attached_sites, + rec): + """Loop through all configured sites and add alternatives. + + See SyncServerModule.handle_alternate_site + """ + conf_sites = system_sync_server_presets.get("sites", {}) + + for site_name, site_info in conf_sites.items(): + alt_sites = set(site_info.get("alternative_sites", [])) + for added_site in already_attached_sites.keys(): + if added_site in alt_sites: + if site_name in already_attached_sites.keys(): + continue + meta = {"name": site_name} + real_created = already_attached_sites[added_site] + # alt site inherits state of 'created_dt' + if real_created: + meta["created_dt"] = real_created + rec["sites"].append(meta) + already_attached_sites[meta["name"]] = real_created + + return rec + def handle_destination_files(self, integrated_file_sizes, mode): """ Clean destination files Called when error happened during integrating to DB or to disk From 828c601d144dc0d24cfacdbe1a4ba29157349e99 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 4 Nov 2021 16:38:29 +0100 Subject: [PATCH 037/111] OP-1937 - fix - failure when Site Sync is not enabled --- openpype/plugins/publish/integrate_new.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openpype/plugins/publish/integrate_new.py b/openpype/plugins/publish/integrate_new.py index c0a90ee78e..6c51f640fb 100644 --- a/openpype/plugins/publish/integrate_new.py +++ b/openpype/plugins/publish/integrate_new.py @@ -1030,6 +1030,7 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): local_site = 'studio' # default remote_site = None always_accesible = [] + sync_project_presets = None rec = { "_id": io.ObjectId(), @@ -1090,6 +1091,7 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): return rec def _get_sites(self, sync_project_presets): + """Returns tuple (local_site, remote_site)""" local_site_id = openpype.api.get_local_site_id() local_site = sync_project_presets["config"]. \ get("active_site", "studio").strip() From 199717a0df976d21e23c5f2566a843ed3562771e Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 4 Nov 2021 17:10:19 +0100 Subject: [PATCH 038/111] OP-1937 - fix - wrong icon used Icon of provider from last configured site was used --- .../modules/default_modules/sync_server/sync_server_module.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/modules/default_modules/sync_server/sync_server_module.py b/openpype/modules/default_modules/sync_server/sync_server_module.py index 9ff706d6dd..bfc7c75c83 100644 --- a/openpype/modules/default_modules/sync_server/sync_server_module.py +++ b/openpype/modules/default_modules/sync_server/sync_server_module.py @@ -1109,8 +1109,8 @@ class SyncServerModule(OpenPypeModule, ITrayModule): return provider sync_sett = self.sync_system_settings - for site, detail in sync_sett.get("sites", {}).items(): - sites[site] = detail.get("provider") + for conf_site, detail in sync_sett.get("sites", {}).items(): + sites[conf_site] = detail.get("provider") return sites.get(site, 'N/A') From 8d00883a04d22bb19454e6e18d57e8afe3e9bd91 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 4 Nov 2021 17:26:34 +0100 Subject: [PATCH 039/111] Hound --- .../sync_server/tray/widgets.py | 2 +- openpype/tests/mongo_performance.py | 22 +++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/openpype/modules/default_modules/sync_server/tray/widgets.py b/openpype/modules/default_modules/sync_server/tray/widgets.py index 01cc0d46d2..15da1b5d19 100644 --- a/openpype/modules/default_modules/sync_server/tray/widgets.py +++ b/openpype/modules/default_modules/sync_server/tray/widgets.py @@ -140,7 +140,7 @@ class SyncProjectListWidget(QtWidgets.QWidget): selected_index.isValid() and \ not self._selection_changed: mode = QtCore.QItemSelectionModel.Select | \ - QtCore.QItemSelectionModel.Rows + QtCore.QItemSelectionModel.Rows self.project_list.selectionModel().select(selected_index, mode) if self.current_project: diff --git a/openpype/tests/mongo_performance.py b/openpype/tests/mongo_performance.py index 9220c6c730..2df3363f4b 100644 --- a/openpype/tests/mongo_performance.py +++ b/openpype/tests/mongo_performance.py @@ -104,8 +104,8 @@ class TestPerformance(): "name": "mb", "parent": {"oid": '{}'.format(id)}, "data": { - "path": "C:\\projects\\test_performance\\Assets\\Cylinder\\publish\\workfile\\workfileLookdev\\{}\\{}".format(version_str, file_name), # noqa - "template": "{root[work]}\\{project[name]}\\{hierarchy}\\{asset}\\publish\\{family}\\{subset}\\v{version:0>3}\\{project[code]}_{asset}_{subset}_v{version:0>3}<_{output}><.{frame:0>4}>.{representation}" # noqa + "path": "C:\\projects\\test_performance\\Assets\\Cylinder\\publish\\workfile\\workfileLookdev\\{}\\{}".format(version_str, file_name), # noqa: E501 + "template": "{root[work]}\\{project[name]}\\{hierarchy}\\{asset}\\publish\\{family}\\{subset}\\v{version:0>3}\\{project[code]}_{asset}_{subset}_v{version:0>3}<_{output}><.{frame:0>4}>.{representation}" # noqa: E501 }, "type": "representation", "schema": "openpype:representation-2.0" @@ -188,21 +188,21 @@ class TestPerformance(): create_files=False): ret = [ { - "path": "{root[work]}" + "{root[work]}/test_performance/Assets/Cylinder/publish/workfile/workfileLookdev/v{:03d}/test_Cylinder_A_workfileLookdev_v{:03d}.dat".format(i, i), #noqa + "path": "{root[work]}" + "{root[work]}/test_performance/Assets/Cylinder/publish/workfile/workfileLookdev/v{:03d}/test_Cylinder_A_workfileLookdev_v{:03d}.dat".format(i, i), # noqa: E501 "_id": '{}'.format(file_id), "hash": "temphash", "sites": self.get_sites(self.MAX_NUMBER_OF_SITES), "size": random.randint(0, self.MAX_FILE_SIZE_B) }, { - "path": "{root[work]}" + "/test_performance/Assets/Cylinder/publish/workfile/workfileLookdev/v{:03d}/test_Cylinder_B_workfileLookdev_v{:03d}.dat".format(i, i), #noqa + "path": "{root[work]}" + "/test_performance/Assets/Cylinder/publish/workfile/workfileLookdev/v{:03d}/test_Cylinder_B_workfileLookdev_v{:03d}.dat".format(i, i), # noqa: E501 "_id": '{}'.format(file_id2), "hash": "temphash", "sites": self.get_sites(self.MAX_NUMBER_OF_SITES), "size": random.randint(0, self.MAX_FILE_SIZE_B) }, { - "path": "{root[work]}" + "/test_performance/Assets/Cylinder/publish/workfile/workfileLookdev/v{:03d}/test_Cylinder_C_workfileLookdev_v{:03d}.dat".format(i, i), #noqa + "path": "{root[work]}" + "/test_performance/Assets/Cylinder/publish/workfile/workfileLookdev/v{:03d}/test_Cylinder_C_workfileLookdev_v{:03d}.dat".format(i, i), # noqa: E501 "_id": '{}'.format(file_id3), "hash": "temphash", "sites": self.get_sites(self.MAX_NUMBER_OF_SITES), @@ -223,8 +223,8 @@ class TestPerformance(): ret = {} ret['{}'.format(file_id)] = { "path": "{root[work]}" + - "/test_performance/Assets/Cylinder/publish/workfile/workfileLookdev/" #noqa - "v{:03d}/test_CylinderA_workfileLookdev_v{:03d}.mb".format(i, i), # noqa + "/test_performance/Assets/Cylinder/publish/workfile/workfileLookdev/" # noqa: E501 + "v{:03d}/test_CylinderA_workfileLookdev_v{:03d}.mb".format(i, i), # noqa: E501 "hash": "temphash", "sites": ["studio"], "size": 87236 @@ -232,16 +232,16 @@ class TestPerformance(): ret['{}'.format(file_id2)] = { "path": "{root[work]}" + - "/test_performance/Assets/Cylinder/publish/workfile/workfileLookdev/" #noqa - "v{:03d}/test_CylinderB_workfileLookdev_v{:03d}.mb".format(i, i), # noqa + "/test_performance/Assets/Cylinder/publish/workfile/workfileLookdev/" # noqa: E501 + "v{:03d}/test_CylinderB_workfileLookdev_v{:03d}.mb".format(i, i), # noqa: E501 "hash": "temphash", "sites": ["studio"], "size": 87236 } ret['{}'.format(file_id3)] = { "path": "{root[work]}" + - "/test_performance/Assets/Cylinder/publish/workfile/workfileLookdev/" #noqa - "v{:03d}/test_CylinderC_workfileLookdev_v{:03d}.mb".format(i, i), # noqa + "/test_performance/Assets/Cylinder/publish/workfile/workfileLookdev/" # noqa: E501 + "v{:03d}/test_CylinderC_workfileLookdev_v{:03d}.mb".format(i, i), # noqa: E501 "hash": "temphash", "sites": ["studio"], "size": 87236 From 24c1aed73939a8641c5224e664a88f6b039abb90 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 4 Nov 2021 17:42:19 +0100 Subject: [PATCH 040/111] OP-1920 - renamed env var SITE_SYNC_LOCAL_ID to OPENPYPE_LOCAL_ID --- openpype/cli.py | 2 +- openpype/lib/local_settings.py | 4 ++-- openpype/pype_commands.py | 2 +- website/docs/module_site_sync.md | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/openpype/cli.py b/openpype/cli.py index 2a7e0c173b..f937d5818e 100644 --- a/openpype/cli.py +++ b/openpype/cli.py @@ -337,7 +337,7 @@ def syncserver(debug, active_site): Process mimics OP Tray with specific 'active_site' name, all configuration for this "dummy" user comes from Setting or Local Settings (configured by starting OP Tray with env - var SITE_SYNC_LOCAL_ID set to 'active_site'. + var OPENPYPE_LOCAL_ID set to 'active_site'. """ if debug: os.environ['OPENPYPE_DEBUG'] = '3' diff --git a/openpype/lib/local_settings.py b/openpype/lib/local_settings.py index af8c3cdbc8..97e99b4b5a 100644 --- a/openpype/lib/local_settings.py +++ b/openpype/lib/local_settings.py @@ -524,8 +524,8 @@ def get_local_site_id(): """ # override local id from environment # used for background syncing - if os.environ.get("SITE_SYNC_LOCAL_ID"): - return os.environ["SITE_SYNC_LOCAL_ID"] + if os.environ.get("OPENPYPE_LOCAL_ID"): + return os.environ["OPENPYPE_LOCAL_ID"] registry = OpenPypeSettingsRegistry() try: diff --git a/openpype/pype_commands.py b/openpype/pype_commands.py index e160db0f15..2ccb4c8a0b 100644 --- a/openpype/pype_commands.py +++ b/openpype/pype_commands.py @@ -332,7 +332,7 @@ class PypeCommands: def syncserver(self, active_site): """Start running sync_server in background.""" import signal - os.environ["SITE_SYNC_LOCAL_ID"] = active_site + os.environ["OPENPYPE_LOCAL_ID"] = active_site def signal_handler(sig, frame): print("You pressed Ctrl+C. Process ended.") diff --git a/website/docs/module_site_sync.md b/website/docs/module_site_sync.md index 31854e2729..d9b53e32fb 100644 --- a/website/docs/module_site_sync.md +++ b/website/docs/module_site_sync.md @@ -164,7 +164,7 @@ As current implementation relies heavily on Settings and Local Settings, backgro To do this: -- run OP `Tray` with environment variable SITE_SYNC_LOCAL_ID set to name of active (source) site. In most use cases it would be studio (for cases of backups of everything published to studio site to different cloud site etc.) +- run OP `Tray` with environment variable OPENPYPE_LOCAL_ID set to name of active (source) site. In most use cases it would be studio (for cases of backups of everything published to studio site to different cloud site etc.) - start `Tray` - check `Local ID` in information dialog after clicking on version number in the Tray - open `Local Settings` in the `Tray` From b0b695159ca21875ffe2dc110ae344b9df60c662 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 4 Nov 2021 19:30:52 +0100 Subject: [PATCH 041/111] OP-1923 - fix - correct choosing of Local Settings overrides --- openpype/lib/path_tools.py | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/openpype/lib/path_tools.py b/openpype/lib/path_tools.py index 3dc142c11b..6fd0ad0dfe 100644 --- a/openpype/lib/path_tools.py +++ b/openpype/lib/path_tools.py @@ -280,7 +280,6 @@ class HostDirmap: if not self.project_settings[self.host_name].get(dirmap_label) and \ not local_mapping: return [] - mapping = local_mapping or \ self.project_settings[self.host_name][dirmap_label]["paths"] or {} enbled = self.project_settings[self.host_name][dirmap_label]["enabled"] @@ -290,7 +289,6 @@ class HostDirmap: not mapping.get("destination-path") or \ not mapping.get("source-path"): return [] - return mapping def _get_local_sync_dirmap(self, project_settings): @@ -334,24 +332,25 @@ class HostDirmap: sync_settings = self.sync_module.get_sync_project_setting( os.getenv("AVALON_PROJECT"), exclude_locals=False, cached=False) - log.debug(json.dumps(sync_settings, indent=4)) - overrides = get_site_local_overrides(os.getenv("AVALON_PROJECT"), - active_site) - for root_name, value in overrides.items(): - remote_site_dir = \ + active_overrides = get_site_local_overrides( + os.getenv("AVALON_PROJECT"), active_site) + remote_overrides = get_site_local_overrides( + os.getenv("AVALON_PROJECT"), remote_site) + + log.debug("local overrides".format(active_overrides)) + log.debug("remote overrides".format(remote_overrides)) + for root_name, active_site_dir in active_overrides.items(): + remote_site_dir = remote_overrides.get(root_name) or\ sync_settings["sites"][remote_site]["root"][root_name] - if os.path.isdir(value): - try: - mapping["destination-path"] = [value] - mapping["source-path"] = [remote_site_dir] - except IndexError: - # missing corresponding destination path - log.debug("overrides".format(overrides)) - log.error( - ("invalid dirmap mapping, missing corresponding" - " destination directory.")) - break + if os.path.isdir(active_site_dir): + if not mapping.get("destination-path"): + mapping["destination-path"] = [] + mapping["destination-path"].append(active_site_dir) + + if not mapping.get("source-path"): + mapping["source-path"] = [] + mapping["source-path"].append(remote_site_dir) log.debug("local sync mapping:: {}".format(mapping)) return mapping From 0c04230c6930ffe901175ca838d1ea2ab991d9fc Mon Sep 17 00:00:00 2001 From: karimmozlia Date: Fri, 5 Nov 2021 16:32:59 +0200 Subject: [PATCH 042/111] int(start_frame) --- openpype/plugins/publish/extract_review.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openpype/plugins/publish/extract_review.py b/openpype/plugins/publish/extract_review.py index 7284483f5f..264b362558 100644 --- a/openpype/plugins/publish/extract_review.py +++ b/openpype/plugins/publish/extract_review.py @@ -649,6 +649,8 @@ class ExtractReview(pyblish.api.InstancePlugin): AssertionError: if more then one collection is obtained. """ + start_frame = int(start_frame) + end_frame = int(end_frame) collections = clique.assemble(files)[0] assert len(collections) == 1, "Multiple collections found." col = collections[0] From 6b4370c19d557e9a24877dc6418131a6ce508ed2 Mon Sep 17 00:00:00 2001 From: karimmozlia Date: Fri, 5 Nov 2021 17:51:47 +0200 Subject: [PATCH 043/111] Update preset with current panel setting --- openpype/hosts/maya/plugins/publish/extract_playblast.py | 7 +++++++ openpype/hosts/maya/plugins/publish/extract_thumbnail.py | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/openpype/hosts/maya/plugins/publish/extract_playblast.py b/openpype/hosts/maya/plugins/publish/extract_playblast.py index 57e3f478f1..341e50fa3d 100644 --- a/openpype/hosts/maya/plugins/publish/extract_playblast.py +++ b/openpype/hosts/maya/plugins/publish/extract_playblast.py @@ -45,6 +45,7 @@ class ExtractPlayblast(openpype.api.Extractor): # get cameras camera = instance.data['review_camera'] + override_viewport_options = self.capture_preset['Viewport Options']['override_viewport_options'] preset = lib.load_capture_preset(data=self.capture_preset) @@ -91,6 +92,12 @@ class ExtractPlayblast(openpype.api.Extractor): preset['viewer'] = False self.log.info('using viewport preset: {}'.format(preset)) + + # Update preset with current panel setting + # if override_viewport_options is turned off + if not override_viewport_options : + panel_preset = capture.parse_active_view() + preset.update(panel_preset) path = capture.capture(**preset) diff --git a/openpype/hosts/maya/plugins/publish/extract_thumbnail.py b/openpype/hosts/maya/plugins/publish/extract_thumbnail.py index aa8adc3986..526f65ae95 100644 --- a/openpype/hosts/maya/plugins/publish/extract_thumbnail.py +++ b/openpype/hosts/maya/plugins/publish/extract_thumbnail.py @@ -32,6 +32,7 @@ class ExtractThumbnail(openpype.api.Extractor): capture_preset = ( instance.context.data["project_settings"]['maya']['publish']['ExtractPlayblast']['capture_preset'] ) + override_viewport_options = capture_preset['Viewport Options']['override_viewport_options'] try: preset = lib.load_capture_preset(data=capture_preset) @@ -86,6 +87,12 @@ class ExtractThumbnail(openpype.api.Extractor): # playblast and viewer preset['viewer'] = False + # Update preset with current panel setting + # if override_viewport_options is turned off + if not override_viewport_options : + panel_preset = capture.parse_active_view() + preset.update(panel_preset) + path = capture.capture(**preset) playblast = self._fix_playblast_output_path(path) From 0d9e7a424c7e7db8c4e432fbc66546e0771cffb8 Mon Sep 17 00:00:00 2001 From: karimmozlia Date: Fri, 5 Nov 2021 17:54:37 +0200 Subject: [PATCH 044/111] hound --- openpype/hosts/maya/plugins/publish/extract_playblast.py | 8 +++++--- openpype/hosts/maya/plugins/publish/extract_thumbnail.py | 6 ++++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_playblast.py b/openpype/hosts/maya/plugins/publish/extract_playblast.py index 341e50fa3d..ffe595973e 100644 --- a/openpype/hosts/maya/plugins/publish/extract_playblast.py +++ b/openpype/hosts/maya/plugins/publish/extract_playblast.py @@ -45,7 +45,9 @@ class ExtractPlayblast(openpype.api.Extractor): # get cameras camera = instance.data['review_camera'] - override_viewport_options = self.capture_preset['Viewport Options']['override_viewport_options'] + override_viewport_options = ( + self.capture_preset['Viewport Options']['override_viewport_options'] + ) preset = lib.load_capture_preset(data=self.capture_preset) @@ -92,10 +94,10 @@ class ExtractPlayblast(openpype.api.Extractor): preset['viewer'] = False self.log.info('using viewport preset: {}'.format(preset)) - + # Update preset with current panel setting # if override_viewport_options is turned off - if not override_viewport_options : + if not override_viewport_options: panel_preset = capture.parse_active_view() preset.update(panel_preset) diff --git a/openpype/hosts/maya/plugins/publish/extract_thumbnail.py b/openpype/hosts/maya/plugins/publish/extract_thumbnail.py index 526f65ae95..36f6925203 100644 --- a/openpype/hosts/maya/plugins/publish/extract_thumbnail.py +++ b/openpype/hosts/maya/plugins/publish/extract_thumbnail.py @@ -32,7 +32,9 @@ class ExtractThumbnail(openpype.api.Extractor): capture_preset = ( instance.context.data["project_settings"]['maya']['publish']['ExtractPlayblast']['capture_preset'] ) - override_viewport_options = capture_preset['Viewport Options']['override_viewport_options'] + override_viewport_options = ( + capture_preset['Viewport Options']['override_viewport_options'] + ) try: preset = lib.load_capture_preset(data=capture_preset) @@ -89,7 +91,7 @@ class ExtractThumbnail(openpype.api.Extractor): # Update preset with current panel setting # if override_viewport_options is turned off - if not override_viewport_options : + if not override_viewport_options: panel_preset = capture.parse_active_view() preset.update(panel_preset) From 836b23372c41bf8b4f922e0761fff52cab119743 Mon Sep 17 00:00:00 2001 From: karimmozlia Date: Fri, 5 Nov 2021 17:55:56 +0200 Subject: [PATCH 045/111] hound --- openpype/hosts/maya/plugins/publish/extract_thumbnail.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_thumbnail.py b/openpype/hosts/maya/plugins/publish/extract_thumbnail.py index 36f6925203..c2cefc56f1 100644 --- a/openpype/hosts/maya/plugins/publish/extract_thumbnail.py +++ b/openpype/hosts/maya/plugins/publish/extract_thumbnail.py @@ -34,7 +34,7 @@ class ExtractThumbnail(openpype.api.Extractor): ) override_viewport_options = ( capture_preset['Viewport Options']['override_viewport_options'] - ) + ) try: preset = lib.load_capture_preset(data=capture_preset) From cc59f9bd3efc20c0cc946972164f4b88d2c1a5f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20LORRAIN?= Date: Fri, 5 Nov 2021 18:00:26 +0100 Subject: [PATCH 046/111] Add following workfile versioning option on publish --- .../publish/collect_anatomy_instance_data.py | 7 ++++++- openpype/plugins/publish/validate_version.py | 8 ++++---- .../settings/defaults/project_settings/global.json | 3 +++ .../schemas/schema_global_publish.json | 14 ++++++++++++++ 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/openpype/plugins/publish/collect_anatomy_instance_data.py b/openpype/plugins/publish/collect_anatomy_instance_data.py index 4fd657167c..e0eb1618b5 100644 --- a/openpype/plugins/publish/collect_anatomy_instance_data.py +++ b/openpype/plugins/publish/collect_anatomy_instance_data.py @@ -38,6 +38,8 @@ class CollectAnatomyInstanceData(pyblish.api.ContextPlugin): order = pyblish.api.CollectorOrder + 0.49 label = "Collect Anatomy Instance data" + follow_workfile_version = False + def process(self, context): self.log.info("Collecting anatomy data for all instances.") @@ -213,7 +215,10 @@ class CollectAnatomyInstanceData(pyblish.api.ContextPlugin): context_asset_doc = context.data["assetEntity"] for instance in context: - version_number = instance.data.get("version") + if self.follow_workfile_version: + version_number = context.data('version') + else: + version_number = instance.data.get("version") # If version is not specified for instance or context if version_number is None: # TODO we should be able to change default version by studio diff --git a/openpype/plugins/publish/validate_version.py b/openpype/plugins/publish/validate_version.py index 927e024476..b86d72a658 100644 --- a/openpype/plugins/publish/validate_version.py +++ b/openpype/plugins/publish/validate_version.py @@ -21,8 +21,8 @@ class ValidateVersion(pyblish.api.InstancePlugin): if latest_version is not None: msg = ( - "Version `{0}` that you are trying to publish, already exists" - " in the database. Version in database: `{1}`. Please version " - "up your workfile to a higher version number than: `{1}`." - ).format(version, latest_version) + "Version `{0}` from instance `{1}` that you are trying to publish, already exists" + " in the database. Version in database: `{2}`. Please version " + "up your workfile to a higher version number than: `{2}`." + ).format(version, instance.data["name"], latest_version) assert (int(version) > int(latest_version)), msg diff --git a/openpype/settings/defaults/project_settings/global.json b/openpype/settings/defaults/project_settings/global.json index 45c1a59d17..134435d909 100644 --- a/openpype/settings/defaults/project_settings/global.json +++ b/openpype/settings/defaults/project_settings/global.json @@ -1,5 +1,8 @@ { "publish": { + "CollectAnatomyInstanceData": { + "follow_workfile_version": false + }, "ValidateEditorialAssetName": { "enabled": true, "optional": false diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json index c50f383f02..375f0c26da 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json @@ -4,6 +4,20 @@ "key": "publish", "label": "Publish plugins", "children": [ + { + "type": "dict", + "collapsible": true, + "key": "CollectAnatomyInstanceData", + "label": "Collect Anatomy Instance Data", + "is_group": true, + "children": [ + { + "type": "boolean", + "key": "follow_workfile_version", + "label": "Follow workfile version" + } + ] + }, { "type": "dict", "collapsible": true, From a8da0df9de55a22b9f497a3d201af9e4e0a81289 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 8 Nov 2021 13:31:56 +0100 Subject: [PATCH 047/111] fix cases when parent of asset version is project --- .../default_modules/ftrack/lib/ftrack_base_handler.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/openpype/modules/default_modules/ftrack/lib/ftrack_base_handler.py b/openpype/modules/default_modules/ftrack/lib/ftrack_base_handler.py index a457b886ac..2130abc20c 100644 --- a/openpype/modules/default_modules/ftrack/lib/ftrack_base_handler.py +++ b/openpype/modules/default_modules/ftrack/lib/ftrack_base_handler.py @@ -570,9 +570,15 @@ class BaseHandler(object): if low_entity_type == "assetversion": asset = entity["asset"] + parent = None if asset: parent = asset["parent"] - if parent: + + if parent: + if parent.entity_type.lower() == "project": + return parent + + if "project" in parent: return parent["project"] project_data = entity["link"][0] From 25e912aedc52a3605e8bd05238cb2ce1ad7940bd Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Mon, 8 Nov 2021 17:35:42 +0100 Subject: [PATCH 048/111] modify publish command --- .../plugins/collect_sequences_from_job.py | 4 ++ .../royal_render/rr_root/README.md | 5 ++ .../perjob/m50__openpype_publish_render.py | 54 ++++++++++++++----- openpype/pype_commands.py | 16 ++++-- 4 files changed, 63 insertions(+), 16 deletions(-) create mode 100644 openpype/modules/default_modules/royal_render/plugins/collect_sequences_from_job.py create mode 100644 openpype/modules/default_modules/royal_render/rr_root/README.md rename openpype/modules/default_modules/royal_render/rr_root/plugins/{plugins => }/control_job/perjob/m50__openpype_publish_render.py (71%) diff --git a/openpype/modules/default_modules/royal_render/plugins/collect_sequences_from_job.py b/openpype/modules/default_modules/royal_render/plugins/collect_sequences_from_job.py new file mode 100644 index 0000000000..ac811696fa --- /dev/null +++ b/openpype/modules/default_modules/royal_render/plugins/collect_sequences_from_job.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +"""Collect sequences from Royal Render Job.""" +import rr # noqa +import rrGlobal # noqa \ No newline at end of file diff --git a/openpype/modules/default_modules/royal_render/rr_root/README.md b/openpype/modules/default_modules/royal_render/rr_root/README.md new file mode 100644 index 0000000000..0a9777833e --- /dev/null +++ b/openpype/modules/default_modules/royal_render/rr_root/README.md @@ -0,0 +1,5 @@ +## OpenPype RoyalRender integration plugins + +### Installation + +Copy content of this folder to your `RR_ROOT` (place where RoyalRender studio wide installation is). \ No newline at end of file diff --git a/openpype/modules/default_modules/royal_render/rr_root/plugins/plugins/control_job/perjob/m50__openpype_publish_render.py b/openpype/modules/default_modules/royal_render/rr_root/plugins/control_job/perjob/m50__openpype_publish_render.py similarity index 71% rename from openpype/modules/default_modules/royal_render/rr_root/plugins/plugins/control_job/perjob/m50__openpype_publish_render.py rename to openpype/modules/default_modules/royal_render/rr_root/plugins/control_job/perjob/m50__openpype_publish_render.py index 62aa1a59b6..81f3fb0a05 100644 --- a/openpype/modules/default_modules/royal_render/rr_root/plugins/plugins/control_job/perjob/m50__openpype_publish_render.py +++ b/openpype/modules/default_modules/royal_render/rr_root/plugins/control_job/perjob/m50__openpype_publish_render.py @@ -22,6 +22,10 @@ class OpenPypeContextSelector: self.job = rr.getJob() self.context = None + self.openpype_executable = "openpype_gui" + if platform.system().lower() == "windows": + op_exec = "{}.exe".format(self.openpype_executable) + op_path = os.environ.get("OPENPYPE_ROOT") print("initializing ... {}".format(op_path)) if not op_path: @@ -84,6 +88,9 @@ class OpenPypeContextSelector: if not self.context: self.show() + self.context["user"] = self.job.userName + self.process_job() + def show(self): """Show UI for context selection. @@ -91,25 +98,31 @@ class OpenPypeContextSelector: itself. """ - op_exec = "openpype_gui" - if platform.system().lower() == "windows": - op_exec = "{}.exe".format(op_exec) + tf = tempfile.TemporaryFile(delete=False) + context_file = tf.name + op_args = [os.path.join(self.openpype_root, self.openpype_executable), + "contextselection", tf.name] - with tempfile.TemporaryFile() as tf: - op_args = [os.path.join(self.openpype_root, op_exec), - "contextselection", tf.name] + tf.close() + print(">>> running {}".format(op_args)) - print(">>> running {}".format(op_args)) - subprocess.call(op_args) - self.context = json.load(tf) + subprocess.call(op_args) + + with open(context_file, "r") as cf: + self.context = json.load(cf) + + os.unlink(context_file) + print(">>> context: {}".format(self.context)) if not self.context or \ - not self.context.project or \ - not self.context.asset or \ - not self.context.task: + not self.context.get("project") or \ + not self.context.get("asset") or \ + not self.context.get("task"): self._show_rr_warning("Context selection failed.") return + self.context["app_name"] = self.job.renderer.name + @staticmethod def _show_rr_warning(text): warning_dialog = rrGlobal.getGenericUI() @@ -122,6 +135,23 @@ class OpenPypeContextSelector: warning_dialog.execute() del warning_dialog + def run_publish(self): + """Run publish process.""" + env = dict() + env["AVALON_PROJECT"] = self.context.get("project") + env["AVALON_ASSET"] = self.context.get("asset") + env["AVALON_TASK"] = self.context.get("task") + env["AVALON_APP_NAME"] = self.context.get("app_name") + + args = list() + args.append( + os.path.join(self.openpype_root, self.openpype_executable)) + args.append("publish") + args.append("-t") + args.append(self.job.imageDir) + print(">>> running {}".format(args)) + subprocess.call(args) + print("running selector") selector = OpenPypeContextSelector() diff --git a/openpype/pype_commands.py b/openpype/pype_commands.py index dfe821fd4a..b863f7ee82 100644 --- a/openpype/pype_commands.py +++ b/openpype/pype_commands.py @@ -73,9 +73,7 @@ class PypeCommands: Raises: RuntimeError: When there is no path to process. """ - if not any(paths): - raise RuntimeError("No publish paths specified") - + from openpype.modules import ModulesManager from openpype import install, uninstall from openpype.api import Logger @@ -83,6 +81,15 @@ class PypeCommands: import pyblish.api import pyblish.util + manager = ModulesManager() + enabled_modules = manager.get_enabled_modules() + for module in enabled_modules: + if hasattr(module, "get_plugin_paths"): + pyblish.api.register_plugin_path(module.get_plugin_paths()) + + if not any(paths): + raise RuntimeError("No publish paths specified") + env = get_app_environments_for_context( os.environ["AVALON_PROJECT"], os.environ["AVALON_ASSET"], @@ -95,12 +102,13 @@ class PypeCommands: install() - pyblish.api.register_target("filesequence") pyblish.api.register_host("shell") if targets: for target in targets: pyblish.api.register_target(target) + else: + pyblish.api.register_target("filesequence") os.environ["OPENPYPE_PUBLISH_DATA"] = os.pathsep.join(paths) From 2ff9ca21aace8d7e0727210b32a29e210bd6c90c Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Tue, 9 Nov 2021 09:31:54 +0100 Subject: [PATCH 049/111] fix hound --- .../plugins/control_job/perjob/m50__openpype_publish_render.py | 3 ++- openpype/pype_commands.py | 3 --- .../modules/default_modules/royal_render/test_rr_job.py | 1 - 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/openpype/modules/default_modules/royal_render/rr_root/plugins/control_job/perjob/m50__openpype_publish_render.py b/openpype/modules/default_modules/royal_render/rr_root/plugins/control_job/perjob/m50__openpype_publish_render.py index 81f3fb0a05..1a21cbdab5 100644 --- a/openpype/modules/default_modules/royal_render/rr_root/plugins/control_job/perjob/m50__openpype_publish_render.py +++ b/openpype/modules/default_modules/royal_render/rr_root/plugins/control_job/perjob/m50__openpype_publish_render.py @@ -24,7 +24,8 @@ class OpenPypeContextSelector: self.openpype_executable = "openpype_gui" if platform.system().lower() == "windows": - op_exec = "{}.exe".format(self.openpype_executable) + self.openpype_executable = "{}.exe".format( + self.openpype_executable) op_path = os.environ.get("OPENPYPE_ROOT") print("initializing ... {}".format(op_path)) diff --git a/openpype/pype_commands.py b/openpype/pype_commands.py index b863f7ee82..8793b3f2e9 100644 --- a/openpype/pype_commands.py +++ b/openpype/pype_commands.py @@ -360,6 +360,3 @@ class PypeCommands: cmd = "pytest {} {} {}".format(folder, mark_str, pyargs_str) print("Running {}".format(cmd)) subprocess.run(cmd) - - def show_context_selector(self): - ... \ No newline at end of file diff --git a/tests/openpype/modules/default_modules/royal_render/test_rr_job.py b/tests/openpype/modules/default_modules/royal_render/test_rr_job.py index a0e2c24671..ab8b1bfd50 100644 --- a/tests/openpype/modules/default_modules/royal_render/test_rr_job.py +++ b/tests/openpype/modules/default_modules/royal_render/test_rr_job.py @@ -8,4 +8,3 @@ def test_rr_job(): # manager = ModulesManager() # rr_module = manager.modules_by_name["royalrender"] ... - From 486732b4ff7003a9ab3efdb6e54a9f2535767fed Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Tue, 9 Nov 2021 09:40:52 +0100 Subject: [PATCH 050/111] remove hierarchy browser stub --- openpype/tools/hierarchy_browser/__init__.py | 0 openpype/tools/hierarchy_browser/__main__.py | 10 ---------- openpype/tools/hierarchy_browser/app.py | 0 3 files changed, 10 deletions(-) delete mode 100644 openpype/tools/hierarchy_browser/__init__.py delete mode 100644 openpype/tools/hierarchy_browser/__main__.py delete mode 100644 openpype/tools/hierarchy_browser/app.py diff --git a/openpype/tools/hierarchy_browser/__init__.py b/openpype/tools/hierarchy_browser/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/openpype/tools/hierarchy_browser/__main__.py b/openpype/tools/hierarchy_browser/__main__.py deleted file mode 100644 index ee23e9e1b6..0000000000 --- a/openpype/tools/hierarchy_browser/__main__.py +++ /dev/null @@ -1,10 +0,0 @@ -if __name__ == "__main__": - import sys - from Qt import QtWidgets - - app = QtWidgets.QApplication([]) - - window = ProjectManagerWindow() - window.show() - - sys.exit(app.exec_()) \ No newline at end of file diff --git a/openpype/tools/hierarchy_browser/app.py b/openpype/tools/hierarchy_browser/app.py deleted file mode 100644 index e69de29bb2..0000000000 From 4397dc1c80474c53b762bdfb8e3319e77766656b Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 9 Nov 2021 15:05:29 +0100 Subject: [PATCH 051/111] modified collect fps to not override instance fps if is already set --- openpype/hosts/webpublisher/plugins/publish/collect_fps.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/openpype/hosts/webpublisher/plugins/publish/collect_fps.py b/openpype/hosts/webpublisher/plugins/publish/collect_fps.py index 79fe53176a..b5e665c761 100644 --- a/openpype/hosts/webpublisher/plugins/publish/collect_fps.py +++ b/openpype/hosts/webpublisher/plugins/publish/collect_fps.py @@ -20,9 +20,8 @@ class CollectFPS(pyblish.api.InstancePlugin): hosts = ["webpublisher"] def process(self, instance): - fps = instance.context.data["fps"] + instance_fps = instance.data.get("fps") + if instance_fps is None: + instance.data["fps"] = instance.context.data["fps"] - instance.data.update({ - "fps": fps - }) self.log.debug(f"instance.data: {pformat(instance.data)}") From b33e8f0fbc8dfb932cdedc13cb8ac0ed3aa5f78e Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 9 Nov 2021 15:06:01 +0100 Subject: [PATCH 052/111] formatting changes --- .../plugins/publish/integrate_context_to_log.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openpype/hosts/webpublisher/plugins/publish/integrate_context_to_log.py b/openpype/hosts/webpublisher/plugins/publish/integrate_context_to_log.py index 419c065e16..261b7e9e0d 100644 --- a/openpype/hosts/webpublisher/plugins/publish/integrate_context_to_log.py +++ b/openpype/hosts/webpublisher/plugins/publish/integrate_context_to_log.py @@ -28,11 +28,11 @@ class IntegrateContextToLog(pyblish.api.ContextPlugin): "batch_id": instance.data.get("batch_id"), "status": "in_progress" }, - {"$set": - { + { + "$set": { "path": instance.data.get("ctx_path") - - }} + } + } ) return From 144b0d266e049e94fbaf10429f7ec19be168818c Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 9 Nov 2021 15:20:53 +0100 Subject: [PATCH 053/111] added new batch collector which collect batch data --- .../plugins/publish/collect_batch_data.py | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 openpype/hosts/webpublisher/plugins/publish/collect_batch_data.py diff --git a/openpype/hosts/webpublisher/plugins/publish/collect_batch_data.py b/openpype/hosts/webpublisher/plugins/publish/collect_batch_data.py new file mode 100644 index 0000000000..a710fcb3e8 --- /dev/null +++ b/openpype/hosts/webpublisher/plugins/publish/collect_batch_data.py @@ -0,0 +1,84 @@ +"""Loads batch context from json and continues in publish process. + +Provides: + context -> Loaded batch file. +""" + +import os + +import pyblish.api +from avalon import io +from openpype.lib.plugin_tools import ( + parse_json, + get_batch_asset_task_info +) +from openpype.lib.remote_publish import get_webpublish_conn + + +class CollectBatchData(pyblish.api.ContextPlugin): + """Collect batch data from json stored in 'OPENPYPE_PUBLISH_DATA' env dir. + + The directory must contain 'manifest.json' file where batch data should be + stored. + """ + # must be really early, context values are only in json file + order = pyblish.api.CollectorOrder - 0.495 + label = "Collect batch data" + host = ["webpublisher"] + + def process(self, context): + batch_dir = os.environ.get("OPENPYPE_PUBLISH_DATA") + + assert batch_dir, ( + "Missing `OPENPYPE_PUBLISH_DATA`") + + assert os.path.exists(batch_dir), \ + "Folder {} doesn't exist".format(batch_dir) + + project_name = os.environ.get("AVALON_PROJECT") + if project_name is None: + raise AssertionError( + "Environment `AVALON_PROJECT` was not found." + "Could not set project `root` which may cause issues." + ) + + batch_data = parse_json(os.path.join(batch_dir, "manifest.json")) + + context.data["batchDir"] = batch_dir + context.data["batchData"] = batch_data + + asset_name, task_name, task_type = get_batch_asset_task_info( + batch_data["context"] + ) + + os.environ["AVALON_ASSET"] = asset_name + io.Session["AVALON_ASSET"] = asset_name + os.environ["AVALON_TASK"] = task_name + io.Session["AVALON_TASK"] = task_name + + context.data["asset"] = asset_name + context.data["task"] = task_name + context.data["taskType"] = task_type + + self._set_ctx_path(batch_data) + + def _set_ctx_path(self, batch_data): + dbcon = get_webpublish_conn() + + batch_id = batch_data["batch"] + ctx_path = batch_data["context"]["path"] + self.log.info("ctx_path: {}".format(ctx_path)) + self.log.info("batch_id: {}".format(batch_id)) + if ctx_path and batch_id: + self.log.info("Updating log record") + dbcon.update_one( + { + "batch_id": batch_id, + "status": "in_progress" + }, + { + "$set": { + "path": ctx_path + } + } + ) From 1c7570cb799975ef7519454ad7f00aa659a09bed Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 9 Nov 2021 15:21:22 +0100 Subject: [PATCH 054/111] modified collect published files to use data from collect batch data --- .../publish/collect_published_files.py | 78 +++++++------------ 1 file changed, 26 insertions(+), 52 deletions(-) diff --git a/openpype/hosts/webpublisher/plugins/publish/collect_published_files.py b/openpype/hosts/webpublisher/plugins/publish/collect_published_files.py index ecd65ebae4..ac2f4d6e54 100644 --- a/openpype/hosts/webpublisher/plugins/publish/collect_published_files.py +++ b/openpype/hosts/webpublisher/plugins/publish/collect_published_files.py @@ -1,20 +1,21 @@ -"""Loads publishing context from json and continues in publish process. +"""Create instances from batch data and continues in publish process. Requires: - anatomy -> context["anatomy"] *(pyblish.api.CollectorOrder - 0.11) + CollectBatchData Provides: context, instances -> All data from previous publishing process. """ import os -import json import clique import tempfile - -import pyblish.api from avalon import io -from openpype.lib import prepare_template_data +import pyblish.api +from openpype.lib import ( + prepare_template_data, + OpenPypeMongoConnection +) from openpype.lib.plugin_tools import parse_json, get_batch_asset_task_info @@ -29,27 +30,26 @@ class CollectPublishedFiles(pyblish.api.ContextPlugin): label = "Collect rendered frames" host = ["webpublisher"] - _context = None - # from Settings task_type_to_family = {} - def _process_batch(self, dir_url): - task_subfolders = [ - os.path.join(dir_url, o) - for o in os.listdir(dir_url) - if os.path.isdir(os.path.join(dir_url, o))] + def process(self, context): + batch_dir = context.data["batchDir"] + task_subfolders = [] + for folder_name in os.listdir(batch_dir): + full_path = os.path.join(batch_dir, folder_name) + if os.path.isdir(full_path): + task_subfolders.append(full_path) + self.log.info("task_sub:: {}".format(task_subfolders)) + + asset_name = context.data["asset"] + task_name = context.data["task"] + task_type = context.data["taskType"] for task_dir in task_subfolders: task_data = parse_json(os.path.join(task_dir, "manifest.json")) self.log.info("task_data:: {}".format(task_data)) - ctx = task_data["context"] - - asset, task_name, task_type = get_batch_asset_task_info(ctx) - - if task_name: - os.environ["AVALON_TASK"] = task_name is_sequence = len(task_data["files"]) > 1 @@ -60,26 +60,20 @@ class CollectPublishedFiles(pyblish.api.ContextPlugin): is_sequence, extension.replace(".", '')) - subset = self._get_subset_name(family, subset_template, task_name, - task_data["variant"]) + subset = self._get_subset_name( + family, subset_template, task_name, task_data["variant"] + ) + version = self._get_last_version(asset_name, subset) + 1 - os.environ["AVALON_ASSET"] = asset - io.Session["AVALON_ASSET"] = asset - - instance = self._context.create_instance(subset) - instance.data["asset"] = asset + instance = context.create_instance(subset) + instance.data["asset"] = asset_name instance.data["subset"] = subset instance.data["family"] = family instance.data["families"] = families - instance.data["version"] = \ - self._get_last_version(asset, subset) + 1 + instance.data["version"] = version instance.data["stagingDir"] = tempfile.mkdtemp() instance.data["source"] = "webpublisher" - # to store logging info into DB openpype.webpublishes - instance.data["ctx_path"] = ctx["path"] - instance.data["batch_id"] = task_data["batch"] - # to convert from email provided into Ftrack username instance.data["user_email"] = task_data["user"] @@ -230,23 +224,3 @@ class CollectPublishedFiles(pyblish.api.ContextPlugin): return version[0].get("version") or 0 else: return 0 - - def process(self, context): - self._context = context - - batch_dir = os.environ.get("OPENPYPE_PUBLISH_DATA") - - assert batch_dir, ( - "Missing `OPENPYPE_PUBLISH_DATA`") - - assert os.path.exists(batch_dir), \ - "Folder {} doesn't exist".format(batch_dir) - - project_name = os.environ.get("AVALON_PROJECT") - if project_name is None: - raise AssertionError( - "Environment `AVALON_PROJECT` was not found." - "Could not set project `root` which may cause issues." - ) - - self._process_batch(batch_dir) From 59cf79d1ed80f198e08ba9cc73bbd05d622f3fbb Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 9 Nov 2021 15:52:23 +0100 Subject: [PATCH 055/111] extended post of webpublish service to be able run different commands and add different arguments based on extensions filter for studio publishing --- .../webserver_service/webpublish_routes.py | 89 +++++++++++++------ 1 file changed, 62 insertions(+), 27 deletions(-) diff --git a/openpype/hosts/webpublisher/webserver_service/webpublish_routes.py b/openpype/hosts/webpublisher/webserver_service/webpublish_routes.py index 920ed042dc..79015c2521 100644 --- a/openpype/hosts/webpublisher/webserver_service/webpublish_routes.py +++ b/openpype/hosts/webpublisher/webserver_service/webpublish_routes.py @@ -176,23 +176,56 @@ class TaskNode(Node): class WebpublisherBatchPublishEndpoint(_RestApiEndpoint): """Triggers headless publishing of batch.""" async def post(self, request) -> Response: - # for postprocessing in host, currently only PS - host_map = {"photoshop": [".psd", ".psb"]} + # Validate existence of openpype executable + openpype_app = self.resource.executable + if not openpype_app or not os.path.exists(openpype_app): + msg = "Non existent OpenPype executable {}".format(openpype_app) + raise RuntimeError(msg) + # for postprocessing in host, currently only PS output = {} log.info("WebpublisherBatchPublishEndpoint called") content = await request.json() - batch_path = os.path.join(self.resource.upload_dir, - content["batch"]) + # Each filter have extensions which are checked on first task item + # - first filter with extensions that are on first task is used + # - filter defines command and can extend arguments dictionary + # This is used only if 'studio_processing' is enabled on batch + studio_processing_filters = [ + # TVPaint filter + { + "extensions": [".tvpp"], + "command": "remotepublish", + "arguments": { + "targets": ["tvpaint"] + } + }, + # Photoshop filter + { + "extensions": [".psd", ".psb"], + "command": "remotepublishfromapp", + "arguments": { + # Command 'remotepublishfromapp' requires --host argument + "host": "photoshop", + # Make sure targets are set to None for cases that default + # would change + # - targets argument is not used in 'remotepublishfromapp' + "targets": None + } + } + ] - add_args = { - "host": "webpublisher", - "project": content["project_name"], - "user": content["user"] - } + batch_path = os.path.join(self.resource.upload_dir, content["batch"]) + # Default command and arguments command = "remotepublish" + add_args = { + # All commands need 'project' and 'user' + "project": content["project_name"], + "user": content["user"], + + "targets": None + } if content.get("studio_processing"): log.info("Post processing called") @@ -208,32 +241,34 @@ class WebpublisherBatchPublishEndpoint(_RestApiEndpoint): raise ValueError( "Cannot parse batch meta in {} folder".format(task_data)) - command = "remotepublishfromapp" - for host, extensions in host_map.items(): - for ext in extensions: - for file_name in task_data["files"]: - if ext in file_name: - add_args["host"] = host - break + for process_filter in studio_processing_filters: + filter_extensions = process_filter.get("extensions") or [] + for file_name in task_data["files"]: + file_ext = os.path.splitext(file_name)[-1].lower() + if file_ext in filter_extensions: + # Change command + command = process_filter["command"] + # Update arguments + add_args.update( + process_filter.get("arguments") or {} + ) + break - if not add_args.get("host"): - raise ValueError( - "Couldn't discern host from {}".format(task_data["files"])) - - openpype_app = self.resource.executable args = [ openpype_app, command, batch_path ] - if not openpype_app or not os.path.exists(openpype_app): - msg = "Non existent OpenPype executable {}".format(openpype_app) - raise RuntimeError(msg) - for key, value in add_args.items(): - args.append("--{}".format(key)) - args.append(value) + # Skip key values where value is None + if value is not None: + args.append("--{}".format(key)) + # Extend list into arguments (targets can be a list) + if isinstance(value, (tuple, list)): + args.extend(value) + else: + args.append(value) log.info("args:: {}".format(args)) From 209db29d552a1adc4105ea70f473265f8a574558 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 9 Nov 2021 15:52:54 +0100 Subject: [PATCH 056/111] added targets for default webpublisher --- .../hosts/webpublisher/webserver_service/webpublish_routes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/webpublisher/webserver_service/webpublish_routes.py b/openpype/hosts/webpublisher/webserver_service/webpublish_routes.py index 79015c2521..70d791b07f 100644 --- a/openpype/hosts/webpublisher/webserver_service/webpublish_routes.py +++ b/openpype/hosts/webpublisher/webserver_service/webpublish_routes.py @@ -224,7 +224,7 @@ class WebpublisherBatchPublishEndpoint(_RestApiEndpoint): "project": content["project_name"], "user": content["user"], - "targets": None + "targets": ["filespublish"] } if content.get("studio_processing"): From 40bf749f802beb8240328b1cc3db827a89378964 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 9 Nov 2021 15:53:05 +0100 Subject: [PATCH 057/111] added targets to collect published files --- .../webpublisher/plugins/publish/collect_published_files.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openpype/hosts/webpublisher/plugins/publish/collect_published_files.py b/openpype/hosts/webpublisher/plugins/publish/collect_published_files.py index ac2f4d6e54..5d6fe69c8d 100644 --- a/openpype/hosts/webpublisher/plugins/publish/collect_published_files.py +++ b/openpype/hosts/webpublisher/plugins/publish/collect_published_files.py @@ -29,6 +29,7 @@ class CollectPublishedFiles(pyblish.api.ContextPlugin): order = pyblish.api.CollectorOrder - 0.490 label = "Collect rendered frames" host = ["webpublisher"] + targets = ["filespublish"] # from Settings task_type_to_family = {} From 6e11db6cc204d2d0409e3f5ae561532698c6696e Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 9 Nov 2021 15:54:35 +0100 Subject: [PATCH 058/111] reorganized args order in remotepublishfromapp to match called function --- openpype/cli.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/openpype/cli.py b/openpype/cli.py index 512bd4663b..acf8c38d95 100644 --- a/openpype/cli.py +++ b/openpype/cli.py @@ -166,7 +166,7 @@ def publish(debug, paths, targets): @click.option("-p", "--project", help="Project") @click.option("-t", "--targets", help="Targets", default=None, multiple=True) -def remotepublishfromapp(debug, project, path, host, targets=None, user=None): +def remotepublishfromapp(debug, project, path, host, user=None, targets=None): """Start CLI publishing. Publish collects json from paths provided as an argument. @@ -174,8 +174,10 @@ def remotepublishfromapp(debug, project, path, host, targets=None, user=None): """ if debug: os.environ['OPENPYPE_DEBUG'] = '3' - PypeCommands.remotepublishfromapp(project, path, host, user, - targets=targets) + PypeCommands.remotepublishfromapp( + project, path, host, user, targets=targets + ) + @main.command() @click.argument("path") From cbb63a2d989979701ef253e1b9e27ffdd1d1a9ba Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 9 Nov 2021 15:55:42 +0100 Subject: [PATCH 059/111] do not trigger install/uninstall in 'remotepublishfromapp' as it's not needed --- openpype/pype_commands.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/openpype/pype_commands.py b/openpype/pype_commands.py index 5fac5cacc7..36302e77d2 100644 --- a/openpype/pype_commands.py +++ b/openpype/pype_commands.py @@ -137,16 +137,13 @@ class PypeCommands: SLEEP = 5 # seconds for another loop check for concurrently runs WAIT_FOR = 300 # seconds to wait for conc. runs - from openpype import install, uninstall from openpype.api import Logger + from openpype.lib import ApplicationManager log = Logger.get_logger() log.info("remotepublishphotoshop command") - install() - - from openpype.lib import ApplicationManager application_manager = ApplicationManager() found_variant_key = find_variant_key(application_manager, host) @@ -220,8 +217,6 @@ class PypeCommands: while launched_app.poll() is None: time.sleep(0.5) - uninstall() - @staticmethod def remotepublish(project, batch_path, host, user, targets=None): """Start headless publishing. From c9a0789b73f2800966ed267a5865aca4e8683891 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 9 Nov 2021 15:56:05 +0100 Subject: [PATCH 060/111] use already imported logger --- openpype/pype_commands.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/openpype/pype_commands.py b/openpype/pype_commands.py index 36302e77d2..8225452082 100644 --- a/openpype/pype_commands.py +++ b/openpype/pype_commands.py @@ -242,13 +242,12 @@ class PypeCommands: raise RuntimeError("No publish paths specified") from openpype import install, uninstall - from openpype.api import Logger # Register target and host import pyblish.api import pyblish.util - log = Logger.get_logger() + log = PypeLogger.get_logger() log.info("remotepublish command") From 69bf8071ba175c71a9b307d1377413698bcfa7d1 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 9 Nov 2021 16:03:42 +0100 Subject: [PATCH 061/111] host name in 'remotepublish command is always "webpublisher" --- openpype/pype_commands.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/openpype/pype_commands.py b/openpype/pype_commands.py index 8225452082..92076402c5 100644 --- a/openpype/pype_commands.py +++ b/openpype/pype_commands.py @@ -241,8 +241,6 @@ class PypeCommands: if not batch_path: raise RuntimeError("No publish paths specified") - from openpype import install, uninstall - # Register target and host import pyblish.api import pyblish.util @@ -251,10 +249,10 @@ class PypeCommands: log.info("remotepublish command") - install() + host_name = "webpublisher" + os.environ["AVALON_APP"] = host_name - if host: - pyblish.api.register_host(host) + pyblish.api.register_host(host_name) if targets: if isinstance(targets, str): @@ -264,7 +262,6 @@ class PypeCommands: os.environ["OPENPYPE_PUBLISH_DATA"] = batch_path os.environ["AVALON_PROJECT"] = project - os.environ["AVALON_APP"] = host import avalon.api from openpype.hosts.webpublisher import api as webpublisher @@ -280,7 +277,6 @@ class PypeCommands: publish_and_log(dbcon, _id, log) log.info("Publish finished.") - uninstall() @staticmethod def extractenvironments(output_json_path, project, asset, task, app): From 53e276d035ede34d594fc71c475631363700f285 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 9 Nov 2021 16:04:06 +0100 Subject: [PATCH 062/111] removed host argument from 'remotepublish' command --- openpype/cli.py | 5 ++--- openpype/pype_commands.py | 7 +++---- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/openpype/cli.py b/openpype/cli.py index acf8c38d95..e582d8e3af 100644 --- a/openpype/cli.py +++ b/openpype/cli.py @@ -182,12 +182,11 @@ def remotepublishfromapp(debug, project, path, host, user=None, targets=None): @main.command() @click.argument("path") @click.option("-d", "--debug", is_flag=True, help="Print debug messages") -@click.option("-h", "--host", help="Host") @click.option("-u", "--user", help="User email address") @click.option("-p", "--project", help="Project") @click.option("-t", "--targets", help="Targets", default=None, multiple=True) -def remotepublish(debug, project, path, host, targets=None, user=None): +def remotepublish(debug, project, path, user=None, targets=None): """Start CLI publishing. Publish collects json from paths provided as an argument. @@ -195,7 +194,7 @@ def remotepublish(debug, project, path, host, targets=None, user=None): """ if debug: os.environ['OPENPYPE_DEBUG'] = '3' - PypeCommands.remotepublish(project, path, host, user, targets=targets) + PypeCommands.remotepublish(project, path, user, targets=targets) @main.command() diff --git a/openpype/pype_commands.py b/openpype/pype_commands.py index 92076402c5..6d880a3301 100644 --- a/openpype/pype_commands.py +++ b/openpype/pype_commands.py @@ -218,7 +218,7 @@ class PypeCommands: time.sleep(0.5) @staticmethod - def remotepublish(project, batch_path, host, user, targets=None): + def remotepublish(project, batch_path, user, targets=None): """Start headless publishing. Used to publish rendered assets, workfiles etc. @@ -230,10 +230,9 @@ class PypeCommands: per call of remotepublish batch_path (str): Path batch folder. Contains subfolders with resources (workfile, another subfolder 'renders' etc.) - targets (string): What module should be targeted - (to choose validator for example) - host (string) user (string): email address for webpublisher + targets (list): Pyblish targets + (to choose validator for example) Raises: RuntimeError: When there is no path to process. From 94cce3567f5c14213d4f2f6d94ff7433e011b85c Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 9 Nov 2021 16:04:30 +0100 Subject: [PATCH 063/111] set all context information at one place --- openpype/pype_commands.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/openpype/pype_commands.py b/openpype/pype_commands.py index 6d880a3301..e355bb74a3 100644 --- a/openpype/pype_commands.py +++ b/openpype/pype_commands.py @@ -243,12 +243,16 @@ class PypeCommands: # Register target and host import pyblish.api import pyblish.util + import avalon.api + from openpype.hosts.webpublisher import api as webpublisher log = PypeLogger.get_logger() log.info("remotepublish command") host_name = "webpublisher" + os.environ["OPENPYPE_PUBLISH_DATA"] = batch_path + os.environ["AVALON_PROJECT"] = project os.environ["AVALON_APP"] = host_name pyblish.api.register_host(host_name) @@ -259,12 +263,6 @@ class PypeCommands: for target in targets: pyblish.api.register_target(target) - os.environ["OPENPYPE_PUBLISH_DATA"] = batch_path - os.environ["AVALON_PROJECT"] = project - - import avalon.api - from openpype.hosts.webpublisher import api as webpublisher - avalon.api.install(webpublisher) log.info("Running publish ...") From f05d97dcfbf29c2316e3745c2695eb3c87e05ae7 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 9 Nov 2021 16:18:45 +0100 Subject: [PATCH 064/111] removed tvpaint which is not yet used --- .../webpublisher/webserver_service/webpublish_routes.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/openpype/hosts/webpublisher/webserver_service/webpublish_routes.py b/openpype/hosts/webpublisher/webserver_service/webpublish_routes.py index 70d791b07f..73e5113f38 100644 --- a/openpype/hosts/webpublisher/webserver_service/webpublish_routes.py +++ b/openpype/hosts/webpublisher/webserver_service/webpublish_routes.py @@ -192,14 +192,6 @@ class WebpublisherBatchPublishEndpoint(_RestApiEndpoint): # - filter defines command and can extend arguments dictionary # This is used only if 'studio_processing' is enabled on batch studio_processing_filters = [ - # TVPaint filter - { - "extensions": [".tvpp"], - "command": "remotepublish", - "arguments": { - "targets": ["tvpaint"] - } - }, # Photoshop filter { "extensions": [".psd", ".psb"], From 5aa8b68cd0e9251f4cc073a895cec5b8246d90fe Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 9 Nov 2021 16:29:07 +0100 Subject: [PATCH 065/111] removed unused imports --- .../plugins/publish/collect_published_files.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/openpype/hosts/webpublisher/plugins/publish/collect_published_files.py b/openpype/hosts/webpublisher/plugins/publish/collect_published_files.py index 5d6fe69c8d..d2754b3df3 100644 --- a/openpype/hosts/webpublisher/plugins/publish/collect_published_files.py +++ b/openpype/hosts/webpublisher/plugins/publish/collect_published_files.py @@ -12,11 +12,8 @@ import clique import tempfile from avalon import io import pyblish.api -from openpype.lib import ( - prepare_template_data, - OpenPypeMongoConnection -) -from openpype.lib.plugin_tools import parse_json, get_batch_asset_task_info +from openpype.lib import prepare_template_data +from openpype.lib.plugin_tools import parse_json class CollectPublishedFiles(pyblish.api.ContextPlugin): From f8e594be800010b4e535de9e051a93982365f369 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 9 Nov 2021 16:55:11 +0100 Subject: [PATCH 066/111] added module command --- openpype/cli.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/openpype/cli.py b/openpype/cli.py index 512bd4663b..e1f9265c1f 100644 --- a/openpype/cli.py +++ b/openpype/cli.py @@ -57,6 +57,12 @@ def tray(debug=False): PypeCommands().launch_tray(debug) +@main.group(help="Run command line arguments of OpenPype modules") +@click.pass_context +def module(ctx): + pass + + @main.command() @click.option("-d", "--debug", is_flag=True, help="Print debug messages") @click.option("--ftrack-url", envvar="FTRACK_SERVER", From dee8156a0c2263ac4d75fba9a957ebfd582dff14 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 9 Nov 2021 16:56:17 +0100 Subject: [PATCH 067/111] implemented 'add_modules' which will call cli method on module to give ability to register custom cli commands --- openpype/cli.py | 1 + openpype/pype_commands.py | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/openpype/cli.py b/openpype/cli.py index e1f9265c1f..d68cba45c6 100644 --- a/openpype/cli.py +++ b/openpype/cli.py @@ -57,6 +57,7 @@ def tray(debug=False): PypeCommands().launch_tray(debug) +@PypeCommands.add_modules @main.group(help="Run command line arguments of OpenPype modules") @click.pass_context def module(ctx): diff --git a/openpype/pype_commands.py b/openpype/pype_commands.py index 5fac5cacc7..f4a29091d0 100644 --- a/openpype/pype_commands.py +++ b/openpype/pype_commands.py @@ -41,6 +41,17 @@ class PypeCommands: user_role = "manager" settings.main(user_role) + @staticmethod + def add_modules(click_func): + """Modules/Addons can add their cli commands dynamically.""" + from openpype.modules import ModulesManager + + manager = ModulesManager() + for module in manager.modules: + if hasattr(module, "cli"): + module.cli(click_func) + return click_func + @staticmethod def launch_eventservercli(*args): from openpype_modules.ftrack.ftrack_server.event_server_cli import ( From afd93a403567f9d79bf4569b8b98419993186c6d Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 9 Nov 2021 16:57:02 +0100 Subject: [PATCH 068/111] ftrack uses new cli option to register it's cli commands --- .../default_modules/ftrack/ftrack_module.py | 58 ++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/openpype/modules/default_modules/ftrack/ftrack_module.py b/openpype/modules/default_modules/ftrack/ftrack_module.py index 73a4dfee82..cc9210c216 100644 --- a/openpype/modules/default_modules/ftrack/ftrack_module.py +++ b/openpype/modules/default_modules/ftrack/ftrack_module.py @@ -1,8 +1,10 @@ import os import json import collections -from openpype.modules import OpenPypeModule +import click + +from openpype.modules import OpenPypeModule from openpype_interfaces import ( ITrayModule, IPluginPaths, @@ -409,3 +411,57 @@ class FtrackModule( return 0 hours_logged = (task_entity["time_logged"] / 60) / 60 return hours_logged + + def cli(self, click_group): + click_group.add_command(cli_main) + + +@click.group( + FtrackModule.name, + help="Application job server. Can be used as render farm." +) +def cli_main(): + pass + + +@cli_main.command() +@click.option("-d", "--debug", is_flag=True, help="Print debug messages") +@click.option("--ftrack-url", envvar="FTRACK_SERVER", + help="Ftrack server url") +@click.option("--ftrack-user", envvar="FTRACK_API_USER", + help="Ftrack api user") +@click.option("--ftrack-api-key", envvar="FTRACK_API_KEY", + help="Ftrack api key") +@click.option("--legacy", is_flag=True, + help="run event server without mongo storing") +@click.option("--clockify-api-key", envvar="CLOCKIFY_API_KEY", + help="Clockify API key.") +@click.option("--clockify-workspace", envvar="CLOCKIFY_WORKSPACE", + help="Clockify workspace") +def eventserver( + debug, + ftrack_url, + ftrack_user, + ftrack_api_key, + legacy, + clockify_api_key, + clockify_workspace +): + """Launch ftrack event server. + + This should be ideally used by system service (such us systemd or upstart + on linux and window service). + """ + if debug: + os.environ["OPENPYPE_DEBUG"] = "3" + + from .ftrack_server.event_server_cli import run_event_server + + return run_event_server( + ftrack_url, + ftrack_user, + ftrack_api_key, + legacy, + clockify_api_key, + clockify_workspace + ) From 88ac91c82c79f036108ccd37cb95103243588ce6 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 9 Nov 2021 17:50:44 +0100 Subject: [PATCH 069/111] fix help --- openpype/modules/default_modules/ftrack/ftrack_module.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/openpype/modules/default_modules/ftrack/ftrack_module.py b/openpype/modules/default_modules/ftrack/ftrack_module.py index cc9210c216..6db80e6c4a 100644 --- a/openpype/modules/default_modules/ftrack/ftrack_module.py +++ b/openpype/modules/default_modules/ftrack/ftrack_module.py @@ -416,10 +416,7 @@ class FtrackModule( click_group.add_command(cli_main) -@click.group( - FtrackModule.name, - help="Application job server. Can be used as render farm." -) +@click.group(FtrackModule.name, help="Ftrack module related commands.") def cli_main(): pass From 2f4ee4447e0d24b1213dc6290ea16af3e27e9531 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 9 Nov 2021 17:51:45 +0100 Subject: [PATCH 070/111] example addon has cli commands --- .../example_addons/example_addon/addon.py | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/openpype/modules/example_addons/example_addon/addon.py b/openpype/modules/example_addons/example_addon/addon.py index 5573e33cc1..f4a1aa4f4e 100644 --- a/openpype/modules/example_addons/example_addon/addon.py +++ b/openpype/modules/example_addons/example_addon/addon.py @@ -8,10 +8,12 @@ in global space here until are required or used. """ import os +import click from openpype.modules import ( JsonFilesSettingsDef, - OpenPypeAddOn + OpenPypeAddOn, + ModulesManager ) # Import interface defined by this addon to be able find other addons using it from openpype_interfaces import ( @@ -130,3 +132,32 @@ class ExampleAddon(OpenPypeAddOn, IPluginPaths, ITrayAction): return { "publish": [os.path.join(current_dir, "plugins", "publish")] } + + def cli(self, click_group): + click_group.add_command(cli_main) + + +@click.group(ExampleAddon.name, help="Example addon dynamic cli commands.") +def cli_main(): + pass + + +@cli_main.command() +def nothing(): + """Does nothing but print a message.""" + print("You've triggered \"nothing\" command.") + + +@cli_main.command() +def show_dialog(): + """Show ExampleAddon dialog. + + We don't have access to addon directly through cli so we have to create + it again. + """ + from openpype.tools.utils.lib import qt_app_context + + manager = ModulesManager() + example_addon = manager.modules_by_name[ExampleAddon.name] + with qt_app_context(): + example_addon.show_dialog() From bf9d4442ea904004ce080a550a5ea1b5aa476d93 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 9 Nov 2021 17:55:31 +0100 Subject: [PATCH 071/111] added cli info to modules readme --- openpype/modules/README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/openpype/modules/README.md b/openpype/modules/README.md index 5716324365..7c17025487 100644 --- a/openpype/modules/README.md +++ b/openpype/modules/README.md @@ -22,6 +22,10 @@ OpenPype modules should contain separated logic of specific kind of implementati - `__init__` should not be overridden and `initialize` should not do time consuming part but only prepare base data about module - also keep in mind that they may be initialized in headless mode - connection with other modules is made with help of interfaces +- `cli` method - can add cli commands specific for the module + - command line arguments are handled using `click` python module + - `cli` method should expect single argument which is click group on which can be called any group specific methods (e.g. `add_command` to add another click group as children see `ExampleAddon`) + - it is possible to add trigger cli commands using `./openpype_console module *args` ## Addon class `OpenPypeAddOn` - inherits from `OpenPypeModule` but is enabled by default and doesn't have to implement `initialize` and `connect_with_modules` methods @@ -140,4 +144,4 @@ class ClockifyModule( ### TrayModulesManager - inherits from `ModulesManager` -- has specific implementation for Pype Tray tool and handle `ITrayModule` methods \ No newline at end of file +- has specific implementation for Pype Tray tool and handle `ITrayModule` methods From 887e4ba004446392f89b605727d6f7447b1b5452 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 9 Nov 2021 17:55:51 +0100 Subject: [PATCH 072/111] do not crash of failed calling of 'cli' method --- openpype/pype_commands.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/openpype/pype_commands.py b/openpype/pype_commands.py index f4a29091d0..d4cba6f93e 100644 --- a/openpype/pype_commands.py +++ b/openpype/pype_commands.py @@ -47,9 +47,18 @@ class PypeCommands: from openpype.modules import ModulesManager manager = ModulesManager() + log = PypeLogger.get_logger("AddModulesCLI") for module in manager.modules: if hasattr(module, "cli"): - module.cli(click_func) + try: + module.cli(click_func) + + except Exception: + log.warning( + "Failed to add cli command for module \"{}\"".format( + module.name + ) + ) return click_func @staticmethod From 901eb5bc9dbd850a32c43d3e4f4ea0acfabb5aa3 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 9 Nov 2021 18:02:19 +0100 Subject: [PATCH 073/111] added cli method to default methods of openpypemodule --- openpype/modules/README.md | 2 +- openpype/modules/base.py | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/openpype/modules/README.md b/openpype/modules/README.md index 7c17025487..86afdb9d91 100644 --- a/openpype/modules/README.md +++ b/openpype/modules/README.md @@ -22,7 +22,7 @@ OpenPype modules should contain separated logic of specific kind of implementati - `__init__` should not be overridden and `initialize` should not do time consuming part but only prepare base data about module - also keep in mind that they may be initialized in headless mode - connection with other modules is made with help of interfaces -- `cli` method - can add cli commands specific for the module +- `cli` method - add cli commands specific for the module - command line arguments are handled using `click` python module - `cli` method should expect single argument which is click group on which can be called any group specific methods (e.g. `add_command` to add another click group as children see `ExampleAddon`) - it is possible to add trigger cli commands using `./openpype_console module *args` diff --git a/openpype/modules/base.py b/openpype/modules/base.py index 7779fff6ec..5773c684b6 100644 --- a/openpype/modules/base.py +++ b/openpype/modules/base.py @@ -431,6 +431,28 @@ class OpenPypeModule: """ return {} + def cli(self, module_click_group): + """Add commands to click group. + + The best practise is to create click group for whole module which is + used to separate commands. + + class MyPlugin(OpenPypeModule): + ... + def cli(self, module_click_group): + module_click_group.add_command(cli_main) + + + @click.group(, help="") + def cli_main(): + pass + + @cli_main.command() + def mycommand(): + print("my_command") + """ + pass + class OpenPypeAddOn(OpenPypeModule): # Enable Addon by default From 2709ece76ad9823921b668427b647958131a2110 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 9 Nov 2021 18:08:30 +0100 Subject: [PATCH 074/111] check of cli existence is not needed anymore --- openpype/pype_commands.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/openpype/pype_commands.py b/openpype/pype_commands.py index d4cba6f93e..5ff57ab6ad 100644 --- a/openpype/pype_commands.py +++ b/openpype/pype_commands.py @@ -49,16 +49,15 @@ class PypeCommands: manager = ModulesManager() log = PypeLogger.get_logger("AddModulesCLI") for module in manager.modules: - if hasattr(module, "cli"): - try: - module.cli(click_func) + try: + module.cli(click_func) - except Exception: - log.warning( - "Failed to add cli command for module \"{}\"".format( - module.name - ) + except Exception: + log.warning( + "Failed to add cli command for module \"{}\"".format( + module.name ) + ) return click_func @staticmethod From c424872f89249f592e2333613610dcd94a712974 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 9 Nov 2021 18:34:29 +0100 Subject: [PATCH 075/111] remove IntegrateContextToLog which does twhat is already done --- .../publish/integrate_context_to_log.py | 38 ------------------- 1 file changed, 38 deletions(-) delete mode 100644 openpype/hosts/webpublisher/plugins/publish/integrate_context_to_log.py diff --git a/openpype/hosts/webpublisher/plugins/publish/integrate_context_to_log.py b/openpype/hosts/webpublisher/plugins/publish/integrate_context_to_log.py deleted file mode 100644 index 261b7e9e0d..0000000000 --- a/openpype/hosts/webpublisher/plugins/publish/integrate_context_to_log.py +++ /dev/null @@ -1,38 +0,0 @@ -import os - -import pyblish.api -from openpype.lib import OpenPypeMongoConnection - - -class IntegrateContextToLog(pyblish.api.ContextPlugin): - """ Adds context information to log document for displaying in front end""" - - label = "Integrate Context to Log" - order = pyblish.api.IntegratorOrder - 0.1 - hosts = ["webpublisher"] - - def process(self, context): - self.log.info("Integrate Context to Log") - - mongo_client = OpenPypeMongoConnection.get_mongo_client() - database_name = os.environ["OPENPYPE_DATABASE_NAME"] - dbcon = mongo_client[database_name]["webpublishes"] - - for instance in context: - self.log.info("ctx_path: {}".format(instance.data.get("ctx_path"))) - self.log.info("batch_id: {}".format(instance.data.get("batch_id"))) - if instance.data.get("ctx_path") and instance.data.get("batch_id"): - self.log.info("Updating log record") - dbcon.update_one( - { - "batch_id": instance.data.get("batch_id"), - "status": "in_progress" - }, - { - "$set": { - "path": instance.data.get("ctx_path") - } - } - ) - - return From 565489db39c4f6a8e29111e0421db6cdbc1411b5 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Tue, 9 Nov 2021 19:01:16 +0100 Subject: [PATCH 076/111] OP-1923 - handle different case for Windows --- openpype/hosts/nuke/api/lib.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/nuke/api/lib.py b/openpype/hosts/nuke/api/lib.py index bfbb19ddcb..d88d7901fe 100644 --- a/openpype/hosts/nuke/api/lib.py +++ b/openpype/hosts/nuke/api/lib.py @@ -1823,7 +1823,12 @@ class NukeDirmap(HostDirmap): def dirmap_routine(self, source_path, destination_path): log.debug("{}: {}->{}".format(self.file_name, source_path, destination_path)) - self.file_name = self.file_name.replace(source_path, destination_path) + if platform.system().lower() == "windows": + self.file_name = self.file_name.lower().replace( + source_path.lower(), destination_path.lower()) + else: + self.file_name = self.file_name.replace( + source_path, destination_path) class DirmapCache: From bc149efe5e94fa5199a049ccd30fb55710d5f604 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Wed, 10 Nov 2021 00:02:01 +0100 Subject: [PATCH 077/111] add credential handling to ftrack module --- .../default_modules/ftrack/ftrack_module.py | 8 +++++++ .../publish/collect_local_ftrack_creds.py | 23 +++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 openpype/modules/default_modules/ftrack/plugins/publish/collect_local_ftrack_creds.py diff --git a/openpype/modules/default_modules/ftrack/ftrack_module.py b/openpype/modules/default_modules/ftrack/ftrack_module.py index 73a4dfee82..aca418e0b8 100644 --- a/openpype/modules/default_modules/ftrack/ftrack_module.py +++ b/openpype/modules/default_modules/ftrack/ftrack_module.py @@ -409,3 +409,11 @@ class FtrackModule( return 0 hours_logged = (task_entity["time_logged"] / 60) / 60 return hours_logged + + def get_credentials(self): + # type: () -> tuple + """Get local Ftrack credentials.""" + from .lib import credentials + + cred = credentials.get_credentials(self.ftrack_url) + return cred.get("username"), cred.get("api_key") diff --git a/openpype/modules/default_modules/ftrack/plugins/publish/collect_local_ftrack_creds.py b/openpype/modules/default_modules/ftrack/plugins/publish/collect_local_ftrack_creds.py new file mode 100644 index 0000000000..2093ebf18a --- /dev/null +++ b/openpype/modules/default_modules/ftrack/plugins/publish/collect_local_ftrack_creds.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +"""Collect default Deadline server.""" +import pyblish.api +import os + + +class CollectLocalFtrackCreds(pyblish.api.ContextPlugin): + """Collect default Royal Render path.""" + + order = pyblish.api.CollectorOrder + 0.01 + label = "Collect local ftrack credentials" + targets = ["rr_control"] + + def process(self, context): + if os.getenv("FTRACK_API_USER") and os.getenv("FTRACK_API_KEY") and \ + os.getenv("FTRACK_SERVER"): + return + ftrack_module = context.data["openPypeModules"]["ftrack"] + if ftrack_module.enabled: + creds = ftrack_module.get_credentials() + os.environ["FTRACK_API_USER"] = creds[0] + os.environ["FTRACK_API_KEY"] = creds[1] + os.environ["FTRACK_SERVER"] = ftrack_module.ftrack_url From 38ad390cd9c4e5a287cdab0ece903d42b873a7c0 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Wed, 10 Nov 2021 00:04:09 +0100 Subject: [PATCH 078/111] settings and publishing tweaks --- .../default_modules/royal_render/__init__.py | 6 ++++ .../royal_render/royal_render_module.py | 7 ++-- .../royal_render/rr_root/plugins/README.md | 5 --- .../perjob/m50__openpype_publish_render.py | 35 +++++++++++-------- openpype/pype_commands.py | 16 ++++++--- .../defaults/system_settings/modules.json | 6 ++++ .../schemas/system_schema/schema_modules.json | 25 +++++++++++++ 7 files changed, 72 insertions(+), 28 deletions(-) delete mode 100644 openpype/modules/default_modules/royal_render/rr_root/plugins/README.md diff --git a/openpype/modules/default_modules/royal_render/__init__.py b/openpype/modules/default_modules/royal_render/__init__.py index e69de29bb2..cc92e3b50d 100644 --- a/openpype/modules/default_modules/royal_render/__init__.py +++ b/openpype/modules/default_modules/royal_render/__init__.py @@ -0,0 +1,6 @@ +from .royal_render_module import RoyalRenderModule + + +__all__ = ( + "RoyalRenderModule", +) diff --git a/openpype/modules/default_modules/royal_render/royal_render_module.py b/openpype/modules/default_modules/royal_render/royal_render_module.py index 3c67cab514..4f72860ad6 100644 --- a/openpype/modules/default_modules/royal_render/royal_render_module.py +++ b/openpype/modules/default_modules/royal_render/royal_render_module.py @@ -9,8 +9,6 @@ from openpype_interfaces import IPluginPaths class RoyalRenderModule(OpenPypeModule, IPluginPaths): """Class providing basic Royal Render implementation logic.""" name = "royalrender" - _api = None - settings = None @property def api(self): @@ -24,6 +22,7 @@ class RoyalRenderModule(OpenPypeModule, IPluginPaths): def __init__(self, manager, settings): # type: (openpype.modules.base.ModulesManager, dict) -> None self.rr_paths = {} + self._api = None self.settings = settings super(RoyalRenderModule, self).__init__(manager, settings) @@ -34,8 +33,8 @@ class RoyalRenderModule(OpenPypeModule, IPluginPaths): self.rr_paths = rr_settings.get("rr_paths") @staticmethod - def get_plugin_paths(self): - # type: (None) -> dict + def get_plugin_paths(): + # type: () -> dict """Royal Render plugin paths. Returns: diff --git a/openpype/modules/default_modules/royal_render/rr_root/plugins/README.md b/openpype/modules/default_modules/royal_render/rr_root/plugins/README.md deleted file mode 100644 index 0a9777833e..0000000000 --- a/openpype/modules/default_modules/royal_render/rr_root/plugins/README.md +++ /dev/null @@ -1,5 +0,0 @@ -## OpenPype RoyalRender integration plugins - -### Installation - -Copy content of this folder to your `RR_ROOT` (place where RoyalRender studio wide installation is). \ No newline at end of file diff --git a/openpype/modules/default_modules/royal_render/rr_root/plugins/control_job/perjob/m50__openpype_publish_render.py b/openpype/modules/default_modules/royal_render/rr_root/plugins/control_job/perjob/m50__openpype_publish_render.py index 1a21cbdab5..cd53e4234f 100644 --- a/openpype/modules/default_modules/royal_render/rr_root/plugins/control_job/perjob/m50__openpype_publish_render.py +++ b/openpype/modules/default_modules/royal_render/rr_root/plugins/control_job/perjob/m50__openpype_publish_render.py @@ -90,7 +90,7 @@ class OpenPypeContextSelector: self.show() self.context["user"] = self.job.userName - self.process_job() + self.run_publish() def show(self): """Show UI for context selection. @@ -105,7 +105,7 @@ class OpenPypeContextSelector: "contextselection", tf.name] tf.close() - print(">>> running {}".format(op_args)) + print(">>> running {}".format(" ".join(op_args))) subprocess.call(op_args) @@ -138,20 +138,25 @@ class OpenPypeContextSelector: def run_publish(self): """Run publish process.""" - env = dict() - env["AVALON_PROJECT"] = self.context.get("project") - env["AVALON_ASSET"] = self.context.get("asset") - env["AVALON_TASK"] = self.context.get("task") - env["AVALON_APP_NAME"] = self.context.get("app_name") + env = {'AVALON_PROJECT': str(self.context.get("project")), + "AVALON_ASSET": str(self.context.get("asset")), + "AVALON_TASK": str(self.context.get("task")), + "AVALON_APP_NAME": str(self.context.get("app_name"))} - args = list() - args.append( - os.path.join(self.openpype_root, self.openpype_executable)) - args.append("publish") - args.append("-t") - args.append(self.job.imageDir) - print(">>> running {}".format(args)) - subprocess.call(args) + print(">>> setting environment:") + for k, v in env.items(): + print(" {}: {}".format(k, v)) + args = [os.path.join(self.openpype_root, self.openpype_executable), + 'publish', '-t', "rr_control", self.job.imageDir] + + print(">>> running {}".format(" ".join(args))) + out = None + try: + out = subprocess.check_output(args, env=env) + except subprocess.CalledProcessError as e: + self._show_rr_warning(" Publish failed [ {} ]\n{}".format( + e.returncode, out + )) print("running selector") diff --git a/openpype/pype_commands.py b/openpype/pype_commands.py index 8793b3f2e9..433aafe30d 100644 --- a/openpype/pype_commands.py +++ b/openpype/pype_commands.py @@ -80,12 +80,14 @@ class PypeCommands: # Register target and host import pyblish.api import pyblish.util + from pprint import pprint manager = ModulesManager() - enabled_modules = manager.get_enabled_modules() - for module in enabled_modules: - if hasattr(module, "get_plugin_paths"): - pyblish.api.register_plugin_path(module.get_plugin_paths()) + + publish_paths = manager.collect_plugin_paths()["publish"] + + for path in publish_paths: + pyblish.api.register_plugin_path(path) if not any(paths): raise RuntimeError("No publish paths specified") @@ -106,6 +108,7 @@ class PypeCommands: if targets: for target in targets: + print(f"setting target: {target}") pyblish.api.register_target(target) else: pyblish.api.register_target("filesequence") @@ -117,6 +120,11 @@ class PypeCommands: # Error exit as soon as any error occurs. error_format = "Failed {plugin.__name__}: {error} -- {error.traceback}" + plugins = pyblish.api.discover() + print("Using plugins:") + for plugin in plugins: + print(plugin) + for result in pyblish.util.publish_iter(): if result["error"]: log.error(error_format.format(**result)) diff --git a/openpype/settings/defaults/system_settings/modules.json b/openpype/settings/defaults/system_settings/modules.json index beb1eb4f24..1dc4c5879d 100644 --- a/openpype/settings/defaults/system_settings/modules.json +++ b/openpype/settings/defaults/system_settings/modules.json @@ -167,6 +167,12 @@ "ffmpeg": 48 } }, + "royalrender": { + "enabled": false, + "rr_paths": { + "default": "" + } + }, "log_viewer": { "enabled": true }, diff --git a/openpype/settings/entities/schemas/system_schema/schema_modules.json b/openpype/settings/entities/schemas/system_schema/schema_modules.json index a2b31772e9..aab1eea750 100644 --- a/openpype/settings/entities/schemas/system_schema/schema_modules.json +++ b/openpype/settings/entities/schemas/system_schema/schema_modules.json @@ -180,6 +180,31 @@ } ] }, + { + "type": "dict", + "key": "royalrender", + "label": "Royal Render", + "require_restart": true, + "collapsible": true, + "checkbox_key": "enabled", + "children": [ + { + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "dict-modifiable", + "object_type": { + "type": "path", + "multiplatform": true + }, + "key": "rr_paths", + "required_keys": ["default"], + "label": "Royal Render Root Paths" + } + ] + }, { "type": "dict", "key": "log_viewer", From 95d051e28c1ea3fe58f30543243a856a2010933c Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Wed, 10 Nov 2021 11:13:03 +0100 Subject: [PATCH 079/111] fix long line --- openpype/hosts/maya/plugins/publish/extract_playblast.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_playblast.py b/openpype/hosts/maya/plugins/publish/extract_playblast.py index ffe595973e..b233a57453 100644 --- a/openpype/hosts/maya/plugins/publish/extract_playblast.py +++ b/openpype/hosts/maya/plugins/publish/extract_playblast.py @@ -46,11 +46,11 @@ class ExtractPlayblast(openpype.api.Extractor): camera = instance.data['review_camera'] override_viewport_options = ( - self.capture_preset['Viewport Options']['override_viewport_options'] + self.capture_preset['Viewport Options'] + ['override_viewport_options'] ) preset = lib.load_capture_preset(data=self.capture_preset) - preset['camera'] = camera preset['start_frame'] = start preset['end_frame'] = end From d4f04f72da7a952cca2709df0fd6e42a6b374637 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20LORRAIN?= Date: Wed, 10 Nov 2021 12:07:07 +0100 Subject: [PATCH 080/111] fix line sizes --- openpype/plugins/publish/validate_version.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/openpype/plugins/publish/validate_version.py b/openpype/plugins/publish/validate_version.py index b86d72a658..e48ce6e3c3 100644 --- a/openpype/plugins/publish/validate_version.py +++ b/openpype/plugins/publish/validate_version.py @@ -21,8 +21,9 @@ class ValidateVersion(pyblish.api.InstancePlugin): if latest_version is not None: msg = ( - "Version `{0}` from instance `{1}` that you are trying to publish, already exists" - " in the database. Version in database: `{2}`. Please version " - "up your workfile to a higher version number than: `{2}`." + "Version `{0}` from instance `{1}` that you are trying to" + " publish, already exists in the database. Version in" + " database: `{2}`. Please version up your workfile to a higher" + " version number than: `{2}`." ).format(version, instance.data["name"], latest_version) assert (int(version) > int(latest_version)), msg From b87d3e3c6733a278d1ac71e2b00ddd720800dd8a Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Wed, 10 Nov 2021 12:56:36 +0100 Subject: [PATCH 081/111] OP-1923 - handle back slashes in Settings Replace only when target file exists. --- openpype/hosts/nuke/api/lib.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/nuke/api/lib.py b/openpype/hosts/nuke/api/lib.py index d88d7901fe..6d593ca588 100644 --- a/openpype/hosts/nuke/api/lib.py +++ b/openpype/hosts/nuke/api/lib.py @@ -1823,9 +1823,11 @@ class NukeDirmap(HostDirmap): def dirmap_routine(self, source_path, destination_path): log.debug("{}: {}->{}".format(self.file_name, source_path, destination_path)) + source_path = source_path.lower().replace(os.sep, '/') + destination_path = destination_path.lower().replace(os.sep, '/') if platform.system().lower() == "windows": self.file_name = self.file_name.lower().replace( - source_path.lower(), destination_path.lower()) + source_path, destination_path) else: self.file_name = self.file_name.replace( source_path, destination_path) @@ -1860,4 +1862,6 @@ def dirmap_file_name_filter(file_name): DirmapCache.sync_module(), file_name) dirmap_processor.process_dirmap() - return dirmap_processor.file_name + if os.path.exists(dirmap_processor.file_name): + return dirmap_processor.file_name + return file_name From ab85ba115bf605d109cca608fa059bb26b0e762d Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Wed, 10 Nov 2021 15:06:17 +0100 Subject: [PATCH 082/111] OP-1978 - fix - wrong site --- .../modules/default_modules/sync_server/sync_server_module.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/modules/default_modules/sync_server/sync_server_module.py b/openpype/modules/default_modules/sync_server/sync_server_module.py index d60147a989..b4c1729013 100644 --- a/openpype/modules/default_modules/sync_server/sync_server_module.py +++ b/openpype/modules/default_modules/sync_server/sync_server_module.py @@ -1039,8 +1039,8 @@ class SyncServerModule(OpenPypeModule, ITrayModule): sys_sett = get_system_settings() sync_sett = sys_sett["modules"].get("sync_server") - for site, detail in sync_sett.get("sites", {}).items(): - sites[site] = detail.get("provider") + for conf_site, detail in sync_sett.get("sites", {}).items(): + sites[conf_site] = detail.get("provider") return sites.get(site, 'N/A') From d7fed6f259dcf79b6e6253e6735a28bd8dfba352 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Wed, 10 Nov 2021 15:07:02 +0100 Subject: [PATCH 083/111] OP-1978 - updated Settings to use sync-server-sites --- .../defaults/project_settings/global.json | 2 +- .../schema_project_syncserver.json | 93 +------------------ 2 files changed, 3 insertions(+), 92 deletions(-) diff --git a/openpype/settings/defaults/project_settings/global.json b/openpype/settings/defaults/project_settings/global.json index 45c1a59d17..8cb31e8f2e 100644 --- a/openpype/settings/defaults/project_settings/global.json +++ b/openpype/settings/defaults/project_settings/global.json @@ -315,7 +315,7 @@ }, "project_folder_structure": "{\"__project_root__\": {\"prod\": {}, \"resources\": {\"footage\": {\"plates\": {}, \"offline\": {}}, \"audio\": {}, \"art_dept\": {}}, \"editorial\": {}, \"assets[ftrack.Library]\": {\"characters[ftrack]\": {}, \"locations[ftrack]\": {}}, \"shots[ftrack.Sequence]\": {\"scripts\": {}, \"editorial[ftrack.Folder]\": {}}}}", "sync_server": { - "enabled": true, + "enabled": false, "config": { "retry_cnt": "3", "loop_delay": "60", diff --git a/openpype/settings/entities/schemas/projects_schema/schema_project_syncserver.json b/openpype/settings/entities/schemas/projects_schema/schema_project_syncserver.json index 3211babd43..85121c471a 100644 --- a/openpype/settings/entities/schemas/projects_schema/schema_project_syncserver.json +++ b/openpype/settings/entities/schemas/projects_schema/schema_project_syncserver.json @@ -39,100 +39,11 @@ ] }, { - "type": "dict-modifiable", + "type": "sync-server-sites", "collapsible": true, "key": "sites", "label": "Sites", - "collapsible_key": false, - "object_type": { - "type": "dict", - "children": [ - { - "type": "dict", - "key": "gdrive", - "label": "Google Drive", - "collapsible": true, - "children": [ - { - "type": "path", - "key": "credentials_url", - "label": "Credentials url", - "multiplatform": true - } - ] - }, - { - "type": "dict", - "key": "dropbox", - "label": "Dropbox", - "collapsible": true, - "children": [ - { - "type": "text", - "key": "token", - "label": "Access Token" - }, - { - "type": "text", - "key": "team_folder_name", - "label": "Team Folder Name" - }, - { - "type": "text", - "key": "acting_as_member", - "label": "Acting As Member" - } - ] - }, - { - "type": "dict", - "key": "sftp", - "label": "SFTP", - "collapsible": true, - "children": [ - { - "type": "text", - "key": "sftp_host", - "label": "SFTP host" - }, - { - "type": "number", - "key": "sftp_port", - "label": "SFTP port" - }, - { - "type": "text", - "key": "sftp_user", - "label": "SFTP user" - }, - { - "type": "text", - "key": "sftp_pass", - "label": "SFTP pass" - }, - { - "type": "path", - "key": "sftp_key", - "label": "SFTP user ssh key", - "multiplatform": true - }, - { - "type": "text", - "key": "sftp_key_pass", - "label": "SFTP user ssh key password" - } - ] - }, - { - "type": "dict-modifiable", - "key": "root", - "label": "Roots", - "collapsable": false, - "collapsable_key": false, - "object_type": "text" - } - ] - } + "collapsible_key": false } ] } From 3594c8019af35af4a188ddbd055110742cc9c83d Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Wed, 10 Nov 2021 15:08:17 +0100 Subject: [PATCH 084/111] OP-1978 - updated sftp to use sync-server-sites Contains changes from #2206 --- .../sync_server/providers/sftp.py | 41 +++++++++---------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/openpype/modules/default_modules/sync_server/providers/sftp.py b/openpype/modules/default_modules/sync_server/providers/sftp.py index d737849cdc..094b14a859 100644 --- a/openpype/modules/default_modules/sync_server/providers/sftp.py +++ b/openpype/modules/default_modules/sync_server/providers/sftp.py @@ -1,8 +1,6 @@ import os import os.path import time -import sys -import six import threading import platform @@ -14,6 +12,7 @@ log = Logger().get_logger("SyncServer") pysftp = None try: import pysftp + import paramiko except (ImportError, SyntaxError): pass @@ -49,22 +48,15 @@ class SFTPHandler(AbstractProvider): format(site_name)) return - provider_presets = self.presets.get(self.CODE) - if not provider_presets: - msg = "Sync Server: No provider presets for {}".format(self.CODE) - log.warning(msg) - return - # store to instance for reconnect - self.sftp_host = provider_presets["sftp_host"] - self.sftp_port = provider_presets["sftp_port"] - self.sftp_user = provider_presets["sftp_user"] - self.sftp_pass = provider_presets["sftp_pass"] - self.sftp_key = provider_presets["sftp_key"] - self.sftp_key_pass = provider_presets["sftp_key_pass"] + self.sftp_host = presets["sftp_host"] + self.sftp_port = presets["sftp_port"] + self.sftp_user = presets["sftp_user"] + self.sftp_pass = presets["sftp_pass"] + self.sftp_key = presets["sftp_key"] + self.sftp_key_pass = presets["sftp_key_pass"] self._tree = None - self.active = True @property def conn(self): @@ -80,7 +72,7 @@ class SFTPHandler(AbstractProvider): Returns: (boolean) """ - return self.conn is not None + return self.presets["enabled"] and self.conn is not None @classmethod def get_system_settings_schema(cls): @@ -108,7 +100,7 @@ class SFTPHandler(AbstractProvider): editable = [ # credentials could be overriden on Project or User level { - 'key': "sftp_server", + 'key': "sftp_host", 'label': "SFTP host name", 'type': 'text' }, @@ -130,7 +122,8 @@ class SFTPHandler(AbstractProvider): { 'key': "sftp_key", 'label': "SFTP user ssh key", - 'type': 'path' + 'type': 'path', + "multiplatform": True }, { 'key': "sftp_key_pass", @@ -144,7 +137,7 @@ class SFTPHandler(AbstractProvider): "type": "dict-roots", "object_type": { "type": "path", - "multiplatform": True, + "multiplatform": False, "multipath": False } } @@ -176,7 +169,8 @@ class SFTPHandler(AbstractProvider): { 'key': "sftp_key", 'label': "SFTP user ssh key", - 'type': 'path' + 'type': 'path', + "multiplatform": True }, { 'key': "sftp_key_pass", @@ -199,7 +193,7 @@ class SFTPHandler(AbstractProvider): Format is importing for usage of python's format ** approach """ # roots cannot be locally overridden - return self.presets['root'] + return self.presets['roots'] def get_tree(self): """ @@ -426,7 +420,10 @@ class SFTPHandler(AbstractProvider): if self.sftp_key_pass: conn_params['private_key_pass'] = self.sftp_key_pass - return pysftp.Connection(**conn_params) + try: + return pysftp.Connection(**conn_params) + except paramiko.ssh_exception.SSHException: + log.warning("Couldn't connect", exc_info=True) def _mark_progress(self, collection, file, representation, server, site, source_path, target_path, direction): From 763adf5a53c80c5ec1eba556323085842344d974 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Wed, 10 Nov 2021 15:08:43 +0100 Subject: [PATCH 085/111] OP-1978 - updated gdrive to use sync-server-sites Contains changes from #2206 --- .../sync_server/providers/gdrive.py | 30 +++++++++---------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/openpype/modules/default_modules/sync_server/providers/gdrive.py b/openpype/modules/default_modules/sync_server/providers/gdrive.py index 8c8447f8f0..a5b68a12c3 100644 --- a/openpype/modules/default_modules/sync_server/providers/gdrive.py +++ b/openpype/modules/default_modules/sync_server/providers/gdrive.py @@ -73,13 +73,7 @@ class GDriveHandler(AbstractProvider): format(site_name)) return - provider_presets = self.presets.get(self.CODE) - if not provider_presets: - msg = "Sync Server: No provider presets for {}".format(self.CODE) - log.info(msg) - return - - cred_path = self.presets[self.CODE].get("credentials_url", {}).\ + cred_path = self.presets.get("credentials_url", {}).\ get(platform.system().lower()) or '' if not os.path.exists(cred_path): msg = "Sync Server: No credentials for gdrive provider " + \ @@ -87,10 +81,12 @@ class GDriveHandler(AbstractProvider): log.info(msg) return - self.service = self._get_gd_service(cred_path) + self.service = None + if self.presets["enabled"]: + self.service = self._get_gd_service(cred_path) - self._tree = tree - self.active = True + self._tree = tree + self.active = True def is_active(self): """ @@ -98,7 +94,7 @@ class GDriveHandler(AbstractProvider): Returns: (boolean) """ - return self.service is not None + return self.presets["enabled"] and self.service is not None @classmethod def get_system_settings_schema(cls): @@ -125,9 +121,11 @@ class GDriveHandler(AbstractProvider): editable = [ # credentials could be overriden on Project or User level { - 'key': "credentials_url", - 'label': "Credentials url", - 'type': 'text' + "type": "path", + "key": "credentials_url", + "label": "Credentials url", + "multiplatform": True, + "placeholder": "Credentials url" }, # roots could be overriden only on Project leve, User cannot { @@ -136,7 +134,7 @@ class GDriveHandler(AbstractProvider): "type": "dict-roots", "object_type": { "type": "path", - "multiplatform": True, + "multiplatform": False, "multipath": False } } @@ -176,7 +174,7 @@ class GDriveHandler(AbstractProvider): Format is importing for usage of python's format ** approach """ # GDrive roots cannot be locally overridden - return self.presets['root'] + return self.presets['roots'] def get_tree(self): """ From 965d798656f722ef7d08a7ee1f5f154167d5f060 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Wed, 10 Nov 2021 15:09:25 +0100 Subject: [PATCH 086/111] OP-1978 - updated dropbox to use sync-server-sites Contains changes from #2206 --- .../sync_server/providers/dropbox.py | 34 ++++++++----------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/openpype/modules/default_modules/sync_server/providers/dropbox.py b/openpype/modules/default_modules/sync_server/providers/dropbox.py index 2bc7a83a5b..84a540be5d 100644 --- a/openpype/modules/default_modules/sync_server/providers/dropbox.py +++ b/openpype/modules/default_modules/sync_server/providers/dropbox.py @@ -24,25 +24,19 @@ class DropboxHandler(AbstractProvider): ) return - provider_presets = self.presets.get(self.CODE) - if not provider_presets: - msg = "Sync Server: No provider presets for {}".format(self.CODE) - log.info(msg) - return - - token = self.presets[self.CODE].get("token", "") + token = self.presets.get("token", "") if not token: msg = "Sync Server: No access token for dropbox provider" log.info(msg) return - team_folder_name = self.presets[self.CODE].get("team_folder_name", "") + team_folder_name = self.presets.get("team_folder_name", "") if not team_folder_name: msg = "Sync Server: No team folder name for dropbox provider" log.info(msg) return - acting_as_member = self.presets[self.CODE].get("acting_as_member", "") + acting_as_member = self.presets.get("acting_as_member", "") if not acting_as_member: msg = ( "Sync Server: No acting member for dropbox provider" @@ -51,13 +45,15 @@ class DropboxHandler(AbstractProvider): return self.dbx = None - try: - self.dbx = self._get_service( - token, acting_as_member, team_folder_name - ) - except Exception as e: - log.info("Could not establish dropbox object: {}".format(e)) - return + + if self.presets["enabled"]: + try: + self.dbx = self._get_service( + token, acting_as_member, team_folder_name + ) + except Exception as e: + log.info("Could not establish dropbox object: {}".format(e)) + return super(AbstractProvider, self).__init__() @@ -106,7 +102,7 @@ class DropboxHandler(AbstractProvider): "type": "dict-roots", "object_type": { "type": "path", - "multiplatform": True, + "multiplatform": False, "multipath": False } } @@ -169,7 +165,7 @@ class DropboxHandler(AbstractProvider): Returns: (boolean) """ - return self.dbx is not None + return self.presets["enabled"] and self.dbx is not None @classmethod def get_configurable_items(cls): @@ -393,7 +389,7 @@ class DropboxHandler(AbstractProvider): {"root": {"root_ONE": "value", "root_TWO":"value}} Format is importing for usage of python's format ** approach """ - return self.presets['root'] + return self.presets['roots'] def resolve_path(self, path, root_config=None, anatomy=None): """ From 32ae5cc790f029f5104093deb9716f4d1e2d7464 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 10 Nov 2021 17:10:00 +0100 Subject: [PATCH 087/111] make sure targets contain default target --- openpype/tools/pyblish_pype/control.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/openpype/tools/pyblish_pype/control.py b/openpype/tools/pyblish_pype/control.py index 1fa3ee657b..2a9e67097e 100644 --- a/openpype/tools/pyblish_pype/control.py +++ b/openpype/tools/pyblish_pype/control.py @@ -190,7 +190,9 @@ class Controller(QtCore.QObject): plugins = pyblish.api.discover() - targets = pyblish.logic.registered_targets() or ["default"] + targets = set(pyblish.logic.registered_targets()) + targets.add("default") + targets = list(targets) plugins_by_targets = pyblish.logic.plugins_by_targets(plugins, targets) _plugins = [] From cc0672d42974a3381108d62fb175e7447dbca987 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Wed, 10 Nov 2021 17:38:17 +0100 Subject: [PATCH 088/111] OP-2017 - fix - enum for color coding in PS Some keys are really weird in PS --- .../projects_schema/schema_project_photoshop.json | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/openpype/settings/entities/schemas/projects_schema/schema_project_photoshop.json b/openpype/settings/entities/schemas/projects_schema/schema_project_photoshop.json index f00bf78fe4..ca388de60c 100644 --- a/openpype/settings/entities/schemas/projects_schema/schema_project_photoshop.json +++ b/openpype/settings/entities/schemas/projects_schema/schema_project_photoshop.json @@ -67,7 +67,17 @@ "type": "list", "key": "color_code", "label": "Color codes for layers", - "object_type": "text" + "type": "enum", + "multiselection": true, + "enum_items": [ + { "red": "red" }, + { "orange": "orange" }, + { "yellowColor": "yellow" }, + { "grain": "green" }, + { "blue": "blue" }, + { "violet": "violet" }, + { "gray": "gray" } + ] }, { "type": "list", From e7778c2d6b546aa1dcbfb9dce5947818f200dbe6 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 10 Nov 2021 17:44:03 +0100 Subject: [PATCH 089/111] replaced transparent image with really transparent image --- openpype/style/images/transparent.png | Bin 69 -> 1406 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/openpype/style/images/transparent.png b/openpype/style/images/transparent.png index 0f2e143b39a2e37e52841ff55d410a2000125eca..bf9514e88e64ed606ef8ade3a22641b524797a9b 100644 GIT binary patch literal 1406 zcmbVMO>fgM7|uYz7~2UU5E8=5E+9zkq+i5Zn6_rDmB^^NN*g!a#BHNBafscu-3@O0 z3y6P!#2?_mh2O%JD+k1I(lj767%WQSugA~({T{b=wpW&JFDZ($(rh?wIWDB%;$`{2 zd*jow9InQV=Uh>)T~EIS<;~k$igM{@(AgLJ?o;fsP$xd?QhgG}60Im}>ywyx2ULJA z?FW&qe);fG1%Yp?dleVCah(o=#!*6dk9IoV(Sc|A>iT1_Ho=l0q=JA+IE*-+*lNa$ zz*aX>fneWlfjUblsOg60A%sB9(rctf%u@9sFp+6M^avWJh7dL@*hCkmh_=vSr$YlG)+w+G(L?4nP?GToijL;dr1(B zfJGo>BwaQVwklPf*$~DBZNzgwNsqw^iJ_sR)TRvRdj&2YCBsa(??F1GA&mr=Sfjv7 zH@R*BKb1BN3p5v7hf<^5wo}o(GmR;1Q_e<-N4E~8#MQZC@qh`&2kZ}a6vu@%F|H?+ z2$pmh8_pxunzI1Y)GOfLUJ&_g%KHX#vM@3qAOj;bgSs*i zd?Ludfterlre{KZ5BFFS66vKNBz+3wsGmu5UEGYgAdyF#j;%^n^&s$ZLE*DPtY zY7(tvm8%-DY8A~d_o}2@F8gI<&F?$R8>JDP-}nFX{<9>IB}9hj=P4qD>ukspm-*7m zB^CVKZ`SLrg!O`NGE%UHUSg4Fizn7$#m? z2Da*@@u$9;ZwKdg;f!`Xppx`2c`<`=))Qlr(2c%y_nCPIrSdQ>*qI&hcN4R-Uy6GU zmmMRW7QIR?if%_E+2Rt}%dT{nU&%hW(sVXDi+8-QCnxI{mBnutzJFdmd6#y`=GKn$ Ie)GlaAHX}V_5c6? delta 50 zcmeyzEal|F*7+KApyu^VPIU$CHff1V(@hJb6Mw<&;$TF Czzj Date: Wed, 10 Nov 2021 17:44:12 +0100 Subject: [PATCH 090/111] rebuild resources --- openpype/style/pyqt5_resources.py | 1597 ++++++++++++------------ openpype/style/pyside2_resources.py | 1770 ++++++++++++++------------- 2 files changed, 1768 insertions(+), 1599 deletions(-) diff --git a/openpype/style/pyqt5_resources.py b/openpype/style/pyqt5_resources.py index 1ac4547ac2..55d4e3efcc 100644 --- a/openpype/style/pyqt5_resources.py +++ b/openpype/style/pyqt5_resources.py @@ -8,132 +8,8 @@ from PyQt5 import QtCore + qt_resource_data = b"\ -\x00\x00\x01\xfc\ -\x89\ -\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ -\x00\x00\x30\x00\x00\x00\x30\x08\x06\x00\x00\x00\x57\x02\xf9\x87\ -\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\ -\x01\x00\x9a\x9c\x18\x00\x00\x01\xae\x49\x44\x41\x54\x68\x81\xed\ -\x9a\xbd\x4a\x03\x41\x14\x46\x4f\x36\x1b\xb0\xd0\x4a\xf1\x01\x14\ -\xab\x68\x91\xc6\x2a\x58\xb8\x16\xb2\x88\x76\x0b\xe9\x7d\x01\x1f\ -\x40\x8b\xf8\x00\xbe\x80\x85\x9d\x30\x62\xa3\x32\x55\xc6\x42\xf2\ -\x02\x42\x92\x46\x83\x7d\x48\x27\x36\xf9\x01\x8b\xdd\x40\x12\xb2\ -\x89\x6b\x7e\x66\x37\xcc\xe9\x76\xef\x14\xdf\x59\xee\x0c\x0b\x77\ -\x52\x04\x38\xae\xb7\x01\x5c\x01\x79\x60\x17\xc8\x10\x2f\xda\x40\ -\x05\x28\x03\x45\x25\x45\x13\x20\x05\xe0\xb8\xde\x21\x70\x0f\x6c\ -\x6a\x8b\x17\x8d\x06\x50\x50\x52\xbc\xa6\x82\x2f\x5f\x25\x39\xe1\ -\x7b\x34\x80\xac\x85\xdf\x36\x49\x0b\x0f\x7e\xe6\x4b\x1b\xbf\xe7\ -\x87\xe9\x2e\x38\xcc\x5f\x49\x0f\x3d\xe7\x6d\xfc\x0d\xdb\x4f\x57\ -\x49\x61\x2f\x28\x50\x24\x1c\xd7\xeb\x30\x28\xb1\x67\x11\xbf\xd3\ -\x26\x0a\x19\x4b\x77\x82\x69\x31\x02\xba\x31\x02\xba\x31\x02\xba\ -\x31\x02\xba\x31\x02\xba\x31\x02\xba\x99\xf8\xdb\xec\xb8\xde\x11\ -\xb0\x0f\xac\xce\x3f\xce\x00\x1d\xa0\x06\x3c\x2b\x29\x7e\xc2\x16\ -\x85\x0a\x38\xae\x67\x03\x8f\xc0\xe9\xec\xb3\x45\xa2\xee\xb8\xde\ -\xb1\x92\xe2\x73\x54\x71\x5c\x0b\x5d\xa0\x3f\x3c\xc0\x36\x70\x1b\ -\x56\x1c\x27\x70\x32\xfb\x2c\xff\xe6\xc0\x71\xbd\xb5\x51\x85\xc4\ -\x6f\xe2\x71\x02\x2f\x0b\x4b\x31\x99\x37\x25\xc5\xf7\xa8\xc2\x38\ -\x81\x1b\xe0\x69\x3e\x79\x22\x51\x07\xce\xc3\x8a\xa1\xa7\x90\x92\ -\xa2\x03\x9c\x25\xf6\x18\xed\xa1\xa4\x28\x01\xa5\x19\x06\x9b\x29\ -\x4b\xbd\x89\x13\x81\x11\xd0\x8d\x11\xd0\x8d\x11\xd0\x8d\x11\xd0\ -\x8d\x11\xd0\xcd\x52\x08\xb4\x75\x87\x98\x82\x96\x8d\x3f\xbe\xcf\ -\xf5\xbd\x4c\x07\xd3\xc0\x38\x32\x3c\x66\xad\xd8\xf8\x77\x0f\x72\ -\x13\x16\xc6\x95\xb2\x05\x14\xf1\xc7\xf6\x49\xa3\x01\x5c\x5b\xc1\ -\xad\x8f\x02\xc9\x92\xe8\x5d\xf6\x68\xa6\x01\xbe\x3e\xaa\x5f\x5b\ -\x3b\xd9\x3b\x60\x05\x7f\xf0\xbd\x4e\xfc\xda\xa8\x05\xbc\x03\x0f\ -\x80\xa7\xa4\xa8\x01\xfc\x02\x51\xab\x5c\x8a\x3f\xde\xe3\x59\x00\ -\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ -\x00\x00\x00\xa6\ -\x89\ -\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ -\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce\x7c\x4e\ -\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ -\x02\x62\x4b\x47\x44\x00\xff\x87\x8f\xcc\xbf\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\x08\x17\x08\x15\x3b\xdc\ -\x3b\x0c\x9b\x00\x00\x00\x2a\x49\x44\x41\x54\x08\xd7\x63\x60\xc0\ -\x00\x8c\x0c\x0c\x73\x3e\x20\x0b\xa4\x08\x30\x32\x30\x20\x0b\xa6\ -\x08\x30\x30\x30\x42\x98\x10\xc1\x14\x01\x14\x13\x50\xb5\xa3\x01\ -\x00\xc6\xb9\x07\x90\x5d\x66\x1f\x83\x00\x00\x00\x00\x49\x45\x4e\ -\x44\xae\x42\x60\x82\ -\x00\x00\x03\xfb\ -\x89\ -\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ -\x00\x00\x30\x00\x00\x00\x30\x08\x06\x00\x00\x00\x57\x02\xf9\x87\ -\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\ -\x01\x00\x9a\x9c\x18\x00\x00\x03\xad\x49\x44\x41\x54\x68\x81\xed\ -\x9a\x4f\xa8\x15\x55\x1c\xc7\x3f\xf7\xbe\xab\xf2\x20\xa3\x22\x6d\ -\xa1\x7c\x21\x09\x2a\x4b\x28\xda\x44\xb9\x88\x52\x4c\xcc\x6a\x51\ -\xf9\xa4\x85\xf1\xa0\x16\x51\xe4\x2e\x10\x74\x51\x44\x8b\x16\x15\ -\x25\x81\xb5\x28\x04\xad\xc0\xe2\x61\x64\xf6\x97\xe0\x45\x10\xb4\ -\xa9\x27\x44\x45\xc4\x17\xa2\x12\x35\x0a\x2a\xff\x3c\xab\xc5\x99\ -\x5b\xd7\x79\x33\x73\xce\xdc\x6b\x6f\xee\x05\x3f\xbb\x39\xf3\x3b\ -\xbf\xf3\xfb\x9d\x33\xe7\x9c\xef\x9c\x99\x16\x19\xb6\x2f\x06\x76\ -\x00\xab\x81\xab\x81\x05\x0c\x17\xa7\x80\x19\x60\x1a\x78\x4c\xd2\ -\x11\x80\x16\x80\xed\x9b\x81\xbd\xc0\xd2\xc6\xc2\xab\xc7\x61\x60\ -\xb3\xa4\x0f\x5b\x59\xcf\x1f\x62\x74\x82\xef\x72\x18\xb8\xaa\x4d\ -\x78\x6c\x46\x2d\x78\x08\x31\x6f\xef\x10\x9e\xf9\x3c\xa7\xe7\x39\ -\x98\x54\xc6\x72\xd7\xab\x3b\x84\x09\xdb\xcb\x69\x49\x9d\x79\x0a\ -\xa8\x16\xb6\x67\x39\x33\x89\x55\x6d\x86\x6f\xb5\xa9\xc3\x82\x76\ -\xd3\x11\x0c\xca\xb9\x04\x9a\xe6\x5c\x02\xff\x07\xb6\xef\xb6\xbd\ -\xd7\xf6\xda\x98\xed\xd0\x25\x60\xfb\x11\xe0\x75\x60\x02\x38\x68\ -\x7b\xa7\xed\xd2\x95\x72\xa8\x12\xb0\x3d\x01\x3c\xdd\x53\xd4\x02\ -\x1e\x04\x5e\x2c\xab\x33\x34\x1b\x96\xed\x35\xc0\x2b\x64\x02\x33\ -\xc7\x16\xdb\x5f\x16\xd5\x1b\x8a\x11\xb0\x7d\x1d\xf0\x06\xb0\xb0\ -\xc2\x6c\x7d\x51\x61\xe3\x09\xd8\xbe\x0c\x78\x1b\x58\x1c\x31\x7d\ -\xa9\xa8\xb0\xd1\x04\x6c\x5f\x02\x1c\x24\xae\x86\x9f\x92\xf4\x6a\ -\xd1\x8d\xc6\x12\xb0\xbd\x18\x38\x00\xac\x88\x98\xee\x06\x1e\x2d\ -\xbb\xd9\x48\x02\xb6\x17\x02\x6f\x02\xd7\x46\x4c\xdf\x01\x26\x25\ -\xfd\x5d\x66\x30\xef\x09\xd8\x6e\x13\x7a\xf5\x96\x88\xe9\x67\xc0\ -\x5d\x92\x66\xab\x8c\x9a\x18\x81\x67\x80\x7b\x22\x36\x5f\x03\x1b\ -\x24\xfd\x1e\x73\x96\x94\x80\xed\x56\xd6\x73\x03\x61\x7b\x1b\xf0\ -\x70\xc4\xec\x47\x60\x5d\xf7\xd4\x21\x46\x65\x50\x59\xe0\x5b\x81\ -\x3f\x81\x19\xdb\xab\x92\x22\x2d\xf6\x35\x09\x3c\x11\x31\xfb\x15\ -\xb8\x55\xd2\xf7\xa9\x7e\x4b\x13\xc8\xf4\xc7\x14\x61\x6b\x5f\x04\ -\x5c\x09\xbc\x6f\xfb\xf2\x54\xe7\x3d\xbe\x36\x02\xbb\x22\x66\x27\ -\x80\x3b\x24\x7d\x51\xc7\x77\xd5\x08\x3c\x0f\x6c\xcc\x95\x2d\x05\ -\x3e\xb0\x7d\x69\x6a\x03\xb6\x6f\x00\x5e\x63\xee\x0b\x79\x2f\x7f\ -\x01\xf7\x4a\xfa\x38\xd5\x6f\x97\xc2\x04\xb2\x1e\x7b\xa0\xa4\xce\ -\x32\xc2\x48\x2c\x8b\x39\xb7\xbd\x12\xd8\x0f\x8c\x47\x4c\x1f\x92\ -\xb4\x2f\xe6\xaf\x88\xb2\x11\xb8\x28\x52\x6f\x05\x21\x89\x25\x65\ -\x06\xb6\x97\x13\x76\xd9\x98\xaf\xc7\x25\xbd\x10\xb1\x29\xa5\x2c\ -\x81\x3d\x84\x75\xb8\x8a\x2b\x80\x77\x6d\x5f\x90\xbf\x61\xfb\x42\ -\x42\xf0\xcb\x23\x3e\x76\x49\xda\x11\x8d\xb2\x82\xc2\x04\x24\x9d\ -\x22\xa8\xbf\x42\x09\xdb\xc3\x35\xc0\x01\xdb\xe7\x75\x0b\x6c\x8f\ -\x13\x1e\x9b\x95\x91\xba\x53\x04\xad\x3f\x10\xa5\x93\x58\xd2\x31\ -\x60\x2d\xf0\x4d\xc4\xc7\xf5\xc0\x7e\xdb\xe3\xb6\xc7\x08\x13\xf6\ -\xc6\x48\x9d\x69\x60\x42\xd2\xc0\x27\x80\x95\xfb\x80\xa4\x9f\x81\ -\x35\x80\x23\x7e\x6e\x02\xf6\x11\x96\xca\xfc\xca\x95\x67\x06\xb8\ -\x5d\xd2\xf1\xc4\x18\x2b\x89\xee\xae\x92\x4c\xd0\x2d\x3f\x45\x4c\ -\xd7\x03\x93\x11\x1b\x13\x36\xaa\x5f\xd2\xc2\x8b\x93\x24\x0f\x24\ -\x7d\x4b\x18\x89\xa3\x03\xb4\x75\x8c\x20\x11\x7e\x18\xc0\xc7\x1c\ -\x92\xf5\x8d\xa4\x43\xc0\x3a\xe0\xb7\x3e\xda\xf9\x03\xb8\x4d\xd2\ -\x57\x7d\xd4\xad\xa4\x96\x40\x93\xf4\x39\xb0\x21\x0b\x28\x95\x59\ -\x60\x93\xa4\x4f\xeb\xb4\x95\x4a\x6d\x85\x29\x69\x1a\xb8\x93\xa0\ -\x5d\x52\xb8\x5f\xd2\x5b\x75\xdb\x49\xa5\x2f\x89\x2c\xe9\x3d\x60\ -\x13\xa1\x77\xab\xd8\x26\xe9\xe5\x7e\xda\x48\xa5\x6f\x8d\x2f\x69\ -\x0a\xd8\x42\x10\x62\x45\x3c\x27\xe9\xc9\x7e\xfd\xa7\x32\xd0\x4b\ -\x8a\xa4\x3d\xc0\x7d\xcc\x9d\x13\x3b\x81\xad\x83\xf8\x4e\x65\xe0\ -\x93\x39\x49\xbb\x6d\x7f\x42\xd8\xc0\xce\x07\x3e\xca\xe6\xc9\xbc\ -\x70\x56\x8e\x16\x25\x7d\x07\x3c\x7b\x36\x7c\xd5\xa5\x4d\xf8\x02\ -\x3e\xaa\x9c\xec\x10\xb4\x49\xef\xf9\xcc\x58\xf6\x35\x70\x18\xc9\ -\xbf\xd5\xcd\x74\x08\xca\x30\x7f\xc0\x54\xf5\xfa\x37\x4c\x4c\x8f\ -\xfe\xaf\x06\xd9\xf9\xcb\xe6\xac\x60\x54\xe8\xfe\xec\x71\xe4\xdf\ -\x8f\x09\xd9\x48\x6c\xe7\xbf\xdf\x6d\xaa\xce\xea\x9b\xe0\x24\x67\ -\xfe\x6e\x73\x14\xe0\x1f\x0a\x43\x12\x6b\x4f\xfd\x3f\x13\x00\x00\ -\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ -\x00\x00\x00\x9f\ -\x89\ -\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ -\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce\x7c\x4e\ -\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ -\x02\x62\x4b\x47\x44\x00\xff\x87\x8f\xcc\xbf\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\x08\x17\x08\x14\x1f\xf9\ -\x23\xd9\x0b\x00\x00\x00\x23\x49\x44\x41\x54\x08\xd7\x63\x60\xc0\ -\x0d\xe6\x7c\x80\xb1\x18\x91\x05\x52\x04\xe0\x42\x08\x15\x29\x02\ -\x0c\x0c\x8c\xc8\x02\x08\x95\x68\x00\x00\xac\xac\x07\x90\x4e\x65\ -\x34\xac\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ \x00\x00\x07\xad\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ @@ -259,243 +135,6 @@ qt_resource_data = b"\ \x5e\x78\xa2\x9e\x0e\xa7\x20\x74\x47\x39\x1d\xf6\xe1\x95\x2b\xd6\ \xb1\x44\x8e\x0e\xcb\x58\xf0\x0f\x52\x8a\x79\x18\xdc\xe2\x02\x70\ \x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ -\x00\x00\x01\xef\ -\x89\ -\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ -\x00\x00\x30\x00\x00\x00\x30\x08\x06\x00\x00\x00\x57\x02\xf9\x87\ -\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\ -\x01\x00\x9a\x9c\x18\x00\x00\x01\xa1\x49\x44\x41\x54\x68\x81\xed\ -\x9a\xbf\x4e\xc2\x50\x14\x87\xbf\x96\xe2\xa4\x9b\x71\xbc\x8b\x1b\ -\xea\xc0\xe2\x44\x1c\x8c\x83\x83\xd1\x81\x89\x84\xd1\x17\xf0\x01\ -\x70\xc0\x07\xf0\x05\x1c\x49\x9c\xba\xa8\x23\x71\x30\x3c\x02\x76\ -\x92\xe5\x8e\x04\x27\xe3\xc2\x9f\xc4\xa1\x6d\x04\x42\x8b\x95\xc2\ -\xa1\xe4\x7e\x5b\x7b\xee\xf0\xfb\x9a\x7b\x6f\x9a\x9c\x63\x11\x50\ -\x75\xbd\x5d\xe0\x16\x28\x01\x87\x40\x9e\xf5\x62\x00\xb4\x81\x16\ -\x50\x6f\x94\x0b\x3d\x00\x0b\xa0\xea\x7a\xa7\xc0\x23\xb0\x27\x16\ -\x2f\x19\x5d\xa0\xd2\x28\x17\x5e\xad\xe0\xcb\xbf\x93\x9d\xf0\x21\ -\x5d\xe0\xc0\xc6\xdf\x36\x59\x0b\x0f\x7e\xe6\x9a\x83\xbf\xe7\xa7\ -\x19\xad\x38\xcc\x5f\xc9\x4d\x3d\x97\x1c\xfc\x03\x3b\xce\xa8\x51\ -\x2e\x38\x2b\x0a\x94\x88\xaa\xeb\x0d\x99\x94\x38\xb2\x59\xbf\xdb\ -\x26\x09\x79\x5b\x3a\xc1\xa2\x18\x01\x69\x8c\x80\x34\x46\x40\x1a\ -\x23\x20\x8d\x11\x90\xc6\x08\x48\x33\xf7\xb7\x59\x6b\x7d\x06\x1c\ -\x03\xdb\xcb\x8f\x33\xc1\x10\xf0\x80\x67\xa5\xd4\x77\xd4\xa2\x48\ -\x01\xad\xb5\x03\xb8\xc0\x65\xfa\xd9\x12\xd1\xd1\x5a\x9f\x2b\xa5\ -\x3e\x66\x15\xe3\xb6\xd0\x0d\xf2\xe1\x01\xf6\x81\x87\xa8\x62\x9c\ -\xc0\x45\xfa\x59\xfe\xcd\x89\xd6\x7a\x67\x56\x21\xf3\x87\x38\x4e\ -\xe0\x65\x65\x29\xe6\xf3\xa6\x94\xfa\x9a\x55\x88\x13\xb8\x07\x9e\ -\x96\x93\x27\x11\x1d\xe0\x3a\xaa\x18\x79\x0b\x29\xa5\x86\xc0\x55\ -\x66\xaf\xd1\x10\xa5\x54\x13\x68\xa6\x18\x2c\x55\x36\xfa\x10\x67\ -\x02\x23\x20\x8d\x11\x90\xc6\x08\x48\x63\x04\xa4\x31\x02\xd2\x6c\ -\x84\xc0\x40\x3a\xc4\x02\xf4\x1d\xfc\xf6\x7d\x71\xec\x65\x2e\xe8\ -\x06\xae\x23\xd3\x6d\xd6\xb6\x83\x3f\x7b\x50\x9c\xb3\x70\x5d\x69\ -\xd9\x40\x1d\xbf\x6d\x9f\x35\xba\xc0\x9d\x1d\x4c\x7d\x54\xc8\x96\ -\x44\x38\xec\xd1\xb3\xc2\x37\xc1\xd0\x47\x8d\xdf\x71\x9b\x2d\xa1\ -\x70\x51\xf4\x99\x1c\xb7\xf9\x04\xf8\x01\x6f\xed\x58\x63\x2d\xfd\ -\xb2\x59\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ -\x00\x00\x03\xff\ -\x89\ -\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ -\x00\x00\x30\x00\x00\x00\x30\x08\x06\x00\x00\x00\x57\x02\xf9\x87\ -\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\ -\x01\x00\x9a\x9c\x18\x00\x00\x03\xb1\x49\x44\x41\x54\x68\x81\xed\ -\x9a\x4f\x68\x1e\x45\x18\xc6\x7f\x9b\x26\x85\x82\x15\x15\xab\x42\ -\xcb\x03\x06\x05\xa9\x0a\x8a\xb7\x52\x3c\xd4\x96\xaa\xb5\xe0\x41\ -\xad\xc5\x43\x25\xa0\x07\x51\xcc\x4d\x28\xb4\x07\x45\x3c\x78\xb0\ -\xa0\x52\x50\x0f\x8a\x50\xf5\x50\xa5\x28\xc6\xbf\xa8\x34\x20\x08\ -\x9e\x4c\x41\xc5\x83\x3c\x20\xd2\x90\x2a\x0a\xfe\x69\x92\x3a\x1e\ -\x66\x8d\x5f\xd6\xdd\x9d\xfd\xf6\x8b\xd9\x2f\xd0\xdf\xed\x9b\x79\ -\xe7\x9d\xe7\x9d\xd9\x99\x79\x67\xbf\xcd\xc8\x09\x21\x5c\x0a\x1c\ -\x06\xb6\x03\xd7\x01\x63\x0c\x17\x0b\xc0\x0c\x30\x0d\x3c\x9e\x65\ -\xd9\xdc\x52\x4d\x08\x61\x47\x08\xe1\x74\x58\x3b\x9c\x0e\x21\xec\ -\x00\xc8\x42\x1c\xf9\x53\xc0\x65\x5d\x0c\xeb\x00\xcc\x02\xd7\x8e\ -\x10\x1f\x9b\xb5\x26\x1e\xa2\xe6\x43\xa3\xc4\x67\xbe\xc8\xb9\x55\ -\x16\xd3\x94\x75\x85\xdf\xdb\xb3\x10\xc2\x3c\xcb\x17\xec\xb9\x2c\ -\xcb\x46\x57\x51\x54\x63\x42\x08\x8b\x2c\x0f\x62\x61\x84\xe1\xdb\ -\x6d\xfa\x61\x6c\xa4\x6b\x05\x83\x72\x3e\x80\xae\x39\x1f\xc0\xff\ -\x81\xed\xbb\x6d\xbf\x66\x7b\x57\xca\x36\x0b\x21\x84\x42\x59\xa7\ -\xdb\xa8\xed\x47\x81\x23\xf9\xcf\x00\x1c\x05\x26\x25\x2d\x94\x6c\ -\xa3\xc3\x35\x03\xb6\xef\x05\x9e\xe9\x29\xca\x80\x87\x80\x17\xab\ -\xda\x0c\xcd\x81\x65\x7b\x27\xf0\x0a\x51\x74\x91\x03\xb6\xbf\x2a\ -\x6b\x37\x14\x33\x60\xfb\x26\xe0\x4d\x60\x7d\x8d\xd9\x6d\x65\x85\ -\x9d\x07\x60\xfb\x2a\xe0\x5d\x60\x63\xc2\xf4\xa5\xb2\xc2\x4e\x03\ -\xb0\x7d\x39\xf0\x3e\xe9\x6c\xf8\x69\x49\xaf\x97\x55\x74\x16\x80\ -\xed\x8d\xc0\x14\x30\x9e\x30\x7d\x15\x78\xac\xaa\xb2\x93\x00\x6c\ -\xaf\x07\xde\x02\x6e\x4c\x98\xbe\x07\x4c\x48\x2a\x6e\xf5\x4b\xac\ -\x7a\x00\xb6\x47\x88\xa3\x7a\x4b\xc2\xf4\x0b\xe0\x2e\x49\x8b\x75\ -\x46\x5d\xcc\xc0\x11\xe0\x9e\x84\xcd\xb7\xc0\x1e\x49\xbf\xa5\x9c\ -\x35\x0a\xc0\x76\x96\x8f\xdc\x40\xd8\x3e\x08\x3c\x92\x30\xfb\x11\ -\xd8\x2d\x69\x2e\x61\x07\x24\x02\xc8\x85\x4f\x02\x7f\x00\x33\xb6\ -\xaf\x6f\xa4\xb4\xdc\xd7\x04\xf0\x64\xc2\xec\x17\xe0\x56\x49\xdf\ -\x37\xf5\x5b\x99\x0b\xd9\x1e\x03\x8e\x03\x7b\x7b\xea\x66\x81\x9b\ -\x25\x7d\xd3\xb4\x03\x00\xdb\x7b\x89\x8b\xb6\x78\xa7\xed\xe5\x2c\ -\x71\xe4\x3f\xab\x32\xe8\x37\x17\x7a\x8e\xe5\xe2\x21\xee\xd7\x1f\ -\xdb\xbe\xb2\x56\x71\x0f\xb6\xb7\x01\x6f\x14\x3b\x2e\xf0\x17\x70\ -\x5f\x9d\xf8\x2a\x4a\x03\xc8\x47\xec\xc1\x8a\x36\x9b\x81\x8f\x6c\ -\x6f\x4e\x39\xb7\xbd\x15\x78\x1b\xd8\x90\x30\x7d\x58\xd2\xf1\x94\ -\xbf\x32\xaa\x66\xe0\x92\x44\xbb\x71\x62\x10\x9b\xaa\x0c\x6c\x6f\ -\x21\x9e\xb2\x29\x5f\x4f\x48\x3a\x9a\xb0\xa9\xa4\x2a\x80\x63\xc4\ -\x7d\xb8\x8e\x6b\x80\x0f\x6c\x5f\x54\xac\xb0\x7d\x31\x51\xfc\x96\ -\x84\x8f\x17\x24\x1d\x4e\xaa\xac\xa1\x34\x00\x49\x0b\xc4\xec\xaf\ -\x34\x85\xed\xe1\x06\x60\xca\xf6\x05\xff\x14\xd8\xde\x40\x7c\x6c\ -\xb6\x26\xda\x9e\x20\xe6\xfa\x03\x51\x7b\x23\xcb\x93\xad\x93\xc0\ -\xd5\x09\x3f\x9f\x02\xb7\x03\xf3\xc4\xdd\xa6\xb8\xf8\x8b\x4c\x03\ -\xbb\x24\xfd\xd9\x8f\xd8\xb2\x5d\x28\x79\xa5\xb4\x2d\x62\x10\x4a\ -\xf8\x9f\x22\x1e\x42\x13\x09\xbb\x19\xe2\x56\xfc\x73\x23\xd5\x3d\ -\xb4\x0a\x00\x96\x72\xf6\x93\xc0\x15\xfd\x76\x5a\xc0\xc0\x36\x49\ -\x3f\xb4\x69\xdc\xfa\x4e\x2c\xe9\x3b\x60\x27\x70\xa6\x4d\xc7\x39\ -\x3f\x11\x0f\xaa\x56\xe2\xab\x68\x9c\xdf\x48\x3a\x05\xec\x06\x7e\ -\x6d\xd1\xcf\xef\xc0\x1d\x92\xbe\x6e\xd1\xb6\x96\xbe\x12\x34\x49\ -\x5f\x02\x7b\x72\x41\x4d\x59\x04\xf6\x49\xfa\xbc\x9f\xbe\x9a\xd2\ -\x77\x86\x29\x69\x1a\xb8\x93\x98\xbb\x34\xe1\x01\x49\xef\xf4\xdb\ -\x4f\x53\x5a\xa5\xc8\x92\x3e\x04\xf6\x11\x47\xb7\x8e\x83\x92\x5e\ -\x6e\xd3\x47\x53\x5a\xe7\xf8\x92\x4e\x00\x07\x88\x89\x58\x19\xcf\ -\x4a\x7a\xaa\xad\xff\xa6\x0c\x74\x49\x91\x74\x0c\xb8\x9f\xff\xae\ -\x89\xe7\x81\xc9\x41\x7c\x37\x65\x45\xde\x8d\xda\x1e\x27\x9e\xbe\ -\x17\x02\x9f\xe4\xeb\x64\xc5\x69\x7d\x90\x0d\x0b\x55\x07\xd9\x42\ -\x37\x72\x56\x84\xf9\x51\x62\x6e\xd2\xfb\x7e\x66\x5d\x1e\xe9\x30\ -\x52\xbc\xd5\xcd\x8c\x12\x33\xc3\xe2\x0b\xa6\xba\xeb\xdf\x30\x31\ -\xbd\xf6\x3f\x35\xc8\xbf\xfa\xd8\x9f\x17\xac\x15\x66\x81\xfd\x59\ -\x96\xcd\x2d\xfd\x99\x90\xcf\xc4\x21\xfe\xfd\xdc\xa6\xee\x5d\x7d\ -\x17\xcc\xb3\xfc\x73\x9b\x33\x00\x7f\x03\xd9\x1a\xfb\xdb\xbb\xa7\ -\x8f\x07\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ -\x00\x00\x04\x12\ -\x89\ -\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ -\x00\x00\x30\x00\x00\x00\x30\x08\x06\x00\x00\x00\x57\x02\xf9\x87\ -\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\ -\x01\x00\x9a\x9c\x18\x00\x00\x03\xc4\x49\x44\x41\x54\x68\x81\xed\ -\x9a\x5f\x88\x94\x55\x18\xc6\x7f\x33\x3b\x1a\x0b\x19\x15\x66\x17\ -\xca\x03\x49\x50\x4d\x09\x4a\x37\x51\x5e\x44\x29\x26\x66\x05\x5b\ -\xb9\xd2\x82\xb1\x50\x17\x91\x24\x74\x11\x08\x7a\xa1\x44\x17\x5d\ -\x54\x94\x04\xd6\x45\xe1\xa2\x15\x4c\xb1\x18\x99\xfd\x25\xd8\x08\ -\x82\x6e\x6a\x5d\xa4\x22\xe2\x81\xa8\x96\xd5\x28\xe8\x9f\xae\xd5\ -\xc5\xf9\xb6\xc6\xd9\xf9\xbe\x73\x66\xc6\x76\x66\xc0\xdf\xdd\x9c\ -\xef\x3d\xef\x79\x9f\x73\xe6\x9c\xf3\x7e\xdf\x39\x25\x32\x46\x6a\ -\x53\x4b\x81\xdd\xc0\x5a\xe0\x3a\x60\x11\xbd\xc5\x69\x60\x12\x98\ -\x00\xf6\x8c\x0d\x55\x67\x00\x4a\x00\x23\xb5\xa9\x5b\x80\x43\xc0\ -\xb2\xae\x85\xd7\x1a\xd3\xc0\xd6\xb1\xa1\xea\x07\xa5\xac\xe7\x8f\ -\xd1\x3f\xc1\xcf\x31\x0d\x5c\x5b\x26\xfc\x6d\xfa\x2d\x78\x08\x31\ -\xef\xaa\x10\xfe\xf3\x8d\x9c\x59\xe0\x60\x52\x19\x68\xf8\xbd\xb6\ -\x42\x98\xb0\xf5\x9c\x19\x1b\xaa\x56\x16\x28\xa0\x96\x18\xa9\x4d\ -\xcd\x72\xb6\x88\x55\x65\x7a\x6f\xb5\x69\x85\x45\xe5\x6e\x47\xd0\ -\x29\xe7\x05\x74\x9b\xf3\x02\xfe\x0f\x6c\xdf\x63\xfb\x90\xed\xf5\ -\x31\xdb\x9e\x13\x60\xfb\x11\xe0\x35\x60\x18\x38\x6a\x7b\x9f\xed\ -\xdc\x95\xb2\xa7\x04\xd8\x1e\x06\x9e\xaa\x2b\x2a\x01\x0f\x01\x2f\ -\xe4\xd5\xe9\x19\x01\xb6\xd7\x01\x2f\x93\x25\x98\x0d\x6c\xb3\xfd\ -\x68\xb3\x7a\x3d\x21\xc0\xf6\xf5\xc0\xeb\xc0\xe2\x02\xb3\x8d\xcd\ -\x0a\xbb\x2e\xc0\xf6\x95\xc0\x5b\xc0\x92\x88\xe9\x8b\xcd\x0a\xbb\ -\x2a\xc0\xf6\xe5\xc0\x51\xe2\xd9\xf0\x93\x92\x5e\x69\xf6\xa0\x6b\ -\x02\x6c\x2f\x01\x8e\x00\x2b\x23\xa6\x07\x80\xc7\xf2\x1e\x76\x45\ -\x80\xed\xc5\xc0\x1b\xc0\x9a\x88\xe9\xdb\xc0\xa8\xa4\xbf\xf3\x0c\ -\x16\x5c\x80\xed\x32\xa1\x57\x6f\x8d\x98\x7e\x0a\xdc\x2d\x69\xb6\ -\xc8\xa8\x1b\x23\xf0\x34\x70\x6f\xc4\xe6\x4b\x60\x93\xa4\x5f\x63\ -\xce\x92\x04\xd8\x2e\x65\x3d\xd7\x11\xb6\x77\x02\xdb\x23\x66\xdf\ -\x03\x1b\x24\xcd\xa4\xf8\x2c\x0c\x2a\x0b\x7c\x07\xf0\x3b\x30\x69\ -\x7b\x55\x52\xa4\xcd\x7d\x8d\x02\x8f\x47\xcc\x7e\x06\x6e\x93\xf4\ -\x6d\xaa\xdf\x5c\x01\x59\xfe\x31\x4e\xd8\xda\x2f\x00\xae\x01\xde\ -\xb3\x7d\x55\xaa\xf3\x3a\x5f\x9b\x81\xfd\x11\xb3\x3f\x81\x3b\x25\ -\x7d\xde\x8a\xef\xa2\x11\x78\x0e\xd8\xdc\x50\xb6\x0c\x78\xdf\xf6\ -\x15\xa9\x0d\xd8\xbe\x11\x78\x95\xf9\x2f\xe4\xf5\xfc\x05\xdc\x27\ -\xe9\xa3\x54\xbf\x73\x34\x15\x90\xf5\xd8\x83\x39\x75\x96\x13\x46\ -\x62\x79\xcc\xb9\xed\x2a\x70\x18\x18\x8c\x98\x3e\x2c\xa9\x16\xf3\ -\xd7\x8c\xbc\x11\xb8\x34\x52\x6f\x25\x41\xc4\x65\x79\x06\xb6\x57\ -\x10\x76\xd9\x98\xaf\xbd\x92\x9e\x8f\xd8\xe4\x92\x27\xe0\x20\x61\ -\x1d\x2e\xe2\x6a\xe0\x1d\xdb\x17\x37\x3e\xb0\x7d\x09\x21\xf8\x15\ -\x11\x1f\xfb\x25\xed\x8e\x46\x59\x40\x53\x01\x92\x4e\x13\xb2\xbf\ -\x2f\x22\xf5\x57\x03\x47\x6c\x5f\x38\x57\x60\x7b\x90\xf0\xb7\xa9\ -\x46\xea\x8e\x13\x72\xfd\x8e\xc8\x9d\xc4\x92\x4e\x02\xeb\x81\xaf\ -\x22\x3e\x6e\x00\x0e\xdb\x1e\xb4\x3d\x40\x98\xb0\x37\x45\xea\x4c\ -\x00\xc3\x92\x3a\xfe\x02\x58\xb8\x0f\x48\xfa\x11\x58\x07\x38\xe2\ -\xe7\x66\xa0\x46\x58\x2a\x1b\x57\xae\x46\x26\x81\x3b\x24\xfd\x91\ -\x18\x63\x21\xd1\xdd\x55\x92\x09\x79\xcb\x0f\x11\xd3\x8d\xc0\x68\ -\xc4\xc6\x84\x8d\xea\xa7\xb4\xf0\xe2\x24\xa5\x07\x92\xbe\x26\x8c\ -\xc4\x89\x0e\xda\x3a\x49\x48\x11\xbe\xeb\xc0\xc7\x3c\x92\xf3\x1b\ -\x49\xc7\x80\x0d\xc0\x2f\x6d\xb4\xf3\x1b\x70\xbb\xa4\xe3\x6d\xd4\ -\x2d\xa4\xa5\x04\x4d\xd2\x67\xc0\xa6\x2c\xa0\x54\x66\x81\x2d\x92\ -\x3e\x69\xa5\xad\x54\x5a\xce\x30\x25\x4d\x00\x77\x11\x72\x97\x14\ -\x1e\x90\xf4\x66\xab\xed\xa4\xd2\x56\x8a\x2c\xe9\x5d\x60\x0b\xa1\ -\x77\x8b\xd8\x29\xe9\xa5\x76\xda\x48\xa5\xed\x1c\x5f\xd2\x38\xb0\ -\x8d\x90\x88\x35\xe3\x59\x49\x4f\xb4\xeb\x3f\x95\x8e\x5e\x52\x24\ -\x1d\x04\xee\x67\xfe\x9c\xd8\x07\xec\xe8\xc4\x77\x2a\x1d\x1f\x25\ -\x49\x3a\x60\xfb\x63\xc2\x06\x76\x11\xf0\x61\x36\x4f\x16\x84\x73\ -\x72\x16\x26\xe9\x1b\xe0\x99\x73\xe1\xab\x55\xca\x84\x13\xf0\x7e\ -\xe5\x54\x85\x90\x9b\xd4\x7f\x9f\x19\xc8\x4e\x03\x7b\x91\xc6\xb7\ -\xba\xc9\x0a\x21\x33\x6c\xfc\xc0\x54\xf4\xfa\xd7\x4b\x4c\x94\x81\ -\x3d\x84\x63\xfb\x7e\x63\x1a\xd8\x5b\xce\x6e\x7d\x6c\xa5\xbf\x44\ -\xcc\x5d\xf6\x98\xf9\xf7\x30\x21\xbb\xf4\xb1\x8b\xff\xae\xdb\x14\ -\x7d\xab\xef\x06\xa7\x38\xfb\xba\xcd\x09\x80\x7f\x00\xc4\x1e\x10\ -\x29\x33\x5b\x85\xf7\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\ -\x82\ -\x00\x00\x01\x69\ -\x89\ -\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ -\x00\x00\x30\x00\x00\x00\x30\x08\x06\x00\x00\x00\x57\x02\xf9\x87\ -\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\ -\x01\x00\x9a\x9c\x18\x00\x00\x01\x1b\x49\x44\x41\x54\x68\x81\xed\ -\xda\xb1\x6d\xc2\x40\x14\x87\xf1\xcf\xc7\x91\x09\x50\x86\x70\x42\ -\x41\x4f\xc5\x0a\xae\x90\xbc\x0a\x29\xc8\x2a\x96\x52\x79\x05\x2a\ -\x46\x20\x1e\xc2\x82\x05\x48\x90\x52\xdc\x59\x01\x4b\x51\x62\x45\ -\xe2\xef\x93\xde\xaf\xb3\x45\xf1\x3e\xcb\xa6\xb9\x97\x11\x95\x75\ -\x33\x03\x5e\x80\x25\xf0\x0c\x4c\x19\x97\x0f\xe0\x00\xec\x81\x6d\ -\x55\xe4\x47\x80\x0c\xa0\xac\x9b\x15\xf0\x06\x3c\xca\xc6\x1b\xa6\ -\x05\xd6\x55\x91\xef\xb2\xf8\xe4\xdf\x49\x67\xf8\x4e\x0b\x3c\x39\ -\xc2\x6b\x93\xda\xf0\x10\x66\xde\x78\xc2\x3b\xdf\x77\xb9\xf3\x30\ -\x7f\x35\xe9\x5d\x2f\x3d\xe1\x83\xbd\x76\xa9\x8a\xdc\xdf\x69\xa0\ -\x41\xca\xba\xf9\xe4\x36\x62\xee\x18\xdf\xbf\xcd\x10\x53\xa7\x9e\ -\xe0\xbf\x2c\x40\xcd\x02\xd4\x2c\x40\xcd\x02\xd4\x2c\x40\xcd\x02\ -\xd4\x2c\x40\xcd\x02\xd4\x2c\x40\xcd\x02\xd4\x2c\x40\xcd\x02\xd4\ -\x2c\x40\xcd\x02\xd4\x2c\x40\xcd\x02\xd4\x2c\x40\xcd\x11\x4e\xc0\ -\x53\x75\xf6\x84\xe3\xfb\xc5\xd5\xcd\x49\x3c\x0d\x1c\xa3\xfe\x31\ -\xeb\xc1\x13\x76\x0f\x16\xbf\xfc\x70\xac\xf6\x0e\xd8\x12\x8e\xed\ -\x53\xd3\x02\xaf\x2e\x6e\x7d\xac\x49\x2b\xa2\x5b\xf6\x38\x66\xdd\ -\x9d\xb8\xf4\xb1\xe1\x7b\xdd\xe6\x41\x34\xdc\x4f\xce\xdc\xae\xdb\ -\x9c\x00\xbe\x00\x9f\xf6\x34\x3e\x36\x4f\x37\x81\x00\x00\x00\x00\ -\x49\x45\x4e\x44\xae\x42\x60\x82\ -\x00\x00\x01\xdc\ -\x89\ -\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ -\x00\x00\x30\x00\x00\x00\x30\x08\x06\x00\x00\x00\x57\x02\xf9\x87\ -\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\ -\x01\x00\x9a\x9c\x18\x00\x00\x01\x8e\x49\x44\x41\x54\x68\x81\xed\ -\x9a\xaf\x4e\xc3\x50\x14\x87\xbf\x6e\x1d\x0a\x1c\x41\x1e\x83\x04\ -\xc4\x0c\x6a\x41\x10\x04\x82\x80\x9e\xe7\x05\x78\x80\x21\x78\x01\ -\x5e\x00\x8f\xc2\x00\x72\x41\x90\x3d\xc2\x40\x31\x73\xe4\x32\x14\ -\xc1\xec\x4f\x82\x68\x1b\xb6\x65\xed\x28\xeb\x76\xda\xe5\x7e\xae\ -\xf7\x5c\xf1\xfb\xda\x7b\x6f\x9a\xdc\xe3\x11\xa2\xaa\xdb\xc0\x35\ -\x50\x03\xf6\x81\x0a\xf9\x62\x00\xb4\x81\x16\x70\x23\x22\x3d\x00\ -\x0f\x40\x55\x8f\x81\x7b\x60\xc7\x2c\x5e\x3a\xba\x40\x5d\x44\x5e\ -\xbc\xf0\xcd\xbf\x51\x9c\xf0\x11\x5d\x60\xaf\x44\xb0\x6c\x8a\x16\ -\x1e\x82\xcc\x0d\x9f\x60\xcd\x4f\x33\x5a\x71\x98\xbf\x52\x9e\x7a\ -\xae\xf9\x04\x1b\x76\x9c\x91\x88\xf8\x2b\x0a\x94\x0a\x55\x1d\x32\ -\x29\x71\x50\x22\x7f\xa7\x4d\x1a\x2a\x25\xeb\x04\x8b\xe2\x04\xac\ -\x71\x02\xd6\x38\x01\x6b\x9c\x80\x35\x4e\xc0\x1a\x27\x60\xcd\xdc\ -\xdf\x66\x55\x3d\x01\x0e\x81\xcd\xe5\xc7\x99\x60\x08\xbc\x03\x4f\ -\x22\xf2\x1d\x37\x29\x56\x40\x55\x7d\xe0\x01\x38\xcf\x3e\x5b\x2a\ -\x3a\xaa\x7a\x2a\x22\x1f\xb3\x8a\x49\x4b\xe8\x0a\xfb\xf0\x00\xbb\ -\xc0\x5d\x5c\x31\x49\xe0\x2c\xfb\x2c\xff\xe6\x48\x55\xb7\x66\x15\ -\x0a\xbf\x89\x93\x04\x9e\x57\x96\x62\x3e\xaf\x22\xf2\x35\xab\x90\ -\x24\x70\x0b\x3c\x2e\x27\x4f\x2a\x3a\xc0\x65\x5c\x31\xf6\x14\x12\ -\x91\x21\x70\x51\xd8\x63\x34\x42\x44\x9a\x40\x33\xc3\x60\x99\xb2\ -\xd6\x9b\xb8\x10\x38\x01\x6b\x9c\x80\x35\x4e\xc0\x1a\x27\x60\x8d\ -\x13\xb0\x66\x2d\x04\x06\xd6\x21\x16\xa0\xef\x13\x5c\xdf\x57\xc7\ -\x06\xcb\xe1\x6d\x60\x1e\x99\xbe\x66\x6d\xfb\x04\xbd\x07\xd5\x39\ -\x13\xf3\x4a\xab\xf8\xad\x06\x61\xd7\x47\x3d\x1c\x28\x0a\x51\xb3\ -\x47\xcf\x8b\x46\xc2\x2f\xd1\xe0\xb7\xdd\x66\xc3\x28\x5c\x1c\x7d\ -\x26\xdb\x6d\x3e\x01\x7e\x00\x25\xf8\x5a\x43\x55\x4e\x3a\x7f\x00\ -\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ -\x00\x00\x00\xa6\ -\x89\ -\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ -\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce\x7c\x4e\ -\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ -\x02\x62\x4b\x47\x44\x00\xff\x87\x8f\xcc\xbf\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\x08\x17\x08\x15\x3b\xdc\ -\x3b\x0c\x9b\x00\x00\x00\x2a\x49\x44\x41\x54\x08\xd7\x63\x60\xc0\ -\x00\x8c\x0c\x0c\x73\x3e\x20\x0b\xa4\x08\x30\x32\x30\x20\x0b\xa6\ -\x08\x30\x30\x30\x42\x98\x10\xc1\x14\x01\x14\x13\x50\xb5\xa3\x01\ -\x00\xc6\xb9\x07\x90\x5d\x66\x1f\x83\x00\x00\x00\x00\x49\x45\x4e\ -\x44\xae\x42\x60\x82\ \x00\x00\x07\x06\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ @@ -611,19 +250,71 @@ qt_resource_data = b"\ \x85\x77\xf8\x5b\xe9\xf0\xbb\x9f\xfa\xd2\x83\x39\xdc\xa3\x5b\xf3\ \x19\x2e\xa8\x89\xb5\x30\xf7\x43\xa0\x00\x00\x00\x00\x49\x45\x4e\ \x44\xae\x42\x60\x82\ -\x00\x00\x00\xa6\ +\x00\x00\x01\xdc\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ -\x00\x00\x06\x00\x00\x00\x09\x08\x04\x00\x00\x00\xbb\x93\x95\x16\ -\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ -\x02\x62\x4b\x47\x44\x00\xff\x87\x8f\xcc\xbf\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\x08\x17\x14\x1f\x20\xb9\ -\x8d\x77\xe9\x00\x00\x00\x2a\x49\x44\x41\x54\x08\xd7\x63\x60\xc0\ -\x06\xe6\x7c\x60\x60\x60\x42\x30\xa1\x1c\x08\x93\x81\x81\x09\xc1\ -\x64\x60\x60\x62\x60\x48\x11\x40\xe2\x20\x73\x19\x90\x8d\x40\x02\ -\x00\x23\xed\x08\xaf\x64\x9f\x0f\x15\x00\x00\x00\x00\x49\x45\x4e\ -\x44\xae\x42\x60\x82\ +\x00\x00\x30\x00\x00\x00\x30\x08\x06\x00\x00\x00\x57\x02\xf9\x87\ +\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\ +\x01\x00\x9a\x9c\x18\x00\x00\x01\x8e\x49\x44\x41\x54\x68\x81\xed\ +\x9a\xaf\x4e\xc3\x50\x14\x87\xbf\x6e\x1d\x0a\x1c\x41\x1e\x83\x04\ +\xc4\x0c\x6a\x41\x10\x04\x82\x80\x9e\xe7\x05\x78\x80\x21\x78\x01\ +\x5e\x00\x8f\xc2\x00\x72\x41\x90\x3d\xc2\x40\x31\x73\xe4\x32\x14\ +\xc1\xec\x4f\x82\x68\x1b\xb6\x65\xed\x28\xeb\x76\xda\xe5\x7e\xae\ +\xf7\x5c\xf1\xfb\xda\x7b\x6f\x9a\xdc\xe3\x11\xa2\xaa\xdb\xc0\x35\ +\x50\x03\xf6\x81\x0a\xf9\x62\x00\xb4\x81\x16\x70\x23\x22\x3d\x00\ +\x0f\x40\x55\x8f\x81\x7b\x60\xc7\x2c\x5e\x3a\xba\x40\x5d\x44\x5e\ +\xbc\xf0\xcd\xbf\x51\x9c\xf0\x11\x5d\x60\xaf\x44\xb0\x6c\x8a\x16\ +\x1e\x82\xcc\x0d\x9f\x60\xcd\x4f\x33\x5a\x71\x98\xbf\x52\x9e\x7a\ +\xae\xf9\x04\x1b\x76\x9c\x91\x88\xf8\x2b\x0a\x94\x0a\x55\x1d\x32\ +\x29\x71\x50\x22\x7f\xa7\x4d\x1a\x2a\x25\xeb\x04\x8b\xe2\x04\xac\ +\x71\x02\xd6\x38\x01\x6b\x9c\x80\x35\x4e\xc0\x1a\x27\x60\xcd\xdc\ +\xdf\x66\x55\x3d\x01\x0e\x81\xcd\xe5\xc7\x99\x60\x08\xbc\x03\x4f\ +\x22\xf2\x1d\x37\x29\x56\x40\x55\x7d\xe0\x01\x38\xcf\x3e\x5b\x2a\ +\x3a\xaa\x7a\x2a\x22\x1f\xb3\x8a\x49\x4b\xe8\x0a\xfb\xf0\x00\xbb\ +\xc0\x5d\x5c\x31\x49\xe0\x2c\xfb\x2c\xff\xe6\x48\x55\xb7\x66\x15\ +\x0a\xbf\x89\x93\x04\x9e\x57\x96\x62\x3e\xaf\x22\xf2\x35\xab\x90\ +\x24\x70\x0b\x3c\x2e\x27\x4f\x2a\x3a\xc0\x65\x5c\x31\xf6\x14\x12\ +\x91\x21\x70\x51\xd8\x63\x34\x42\x44\x9a\x40\x33\xc3\x60\x99\xb2\ +\xd6\x9b\xb8\x10\x38\x01\x6b\x9c\x80\x35\x4e\xc0\x1a\x27\x60\x8d\ +\x13\xb0\x66\x2d\x04\x06\xd6\x21\x16\xa0\xef\x13\x5c\xdf\x57\xc7\ +\x06\xcb\xe1\x6d\x60\x1e\x99\xbe\x66\x6d\xfb\x04\xbd\x07\xd5\x39\ +\x13\xf3\x4a\xab\xf8\xad\x06\x61\xd7\x47\x3d\x1c\x28\x0a\x51\xb3\ +\x47\xcf\x8b\x46\xc2\x2f\xd1\xe0\xb7\xdd\x66\xc3\x28\x5c\x1c\x7d\ +\x26\xdb\x6d\x3e\x01\x7e\x00\x25\xf8\x5a\x43\x55\x4e\x3a\x7f\x00\ +\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x01\xef\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x30\x00\x00\x00\x30\x08\x06\x00\x00\x00\x57\x02\xf9\x87\ +\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\ +\x01\x00\x9a\x9c\x18\x00\x00\x01\xa1\x49\x44\x41\x54\x68\x81\xed\ +\x9a\xbf\x4e\xc2\x50\x14\x87\xbf\x96\xe2\xa4\x9b\x71\xbc\x8b\x1b\ +\xea\xc0\xe2\x44\x1c\x8c\x83\x83\xd1\x81\x89\x84\xd1\x17\xf0\x01\ +\x70\xc0\x07\xf0\x05\x1c\x49\x9c\xba\xa8\x23\x71\x30\x3c\x02\x76\ +\x92\xe5\x8e\x04\x27\xe3\xc2\x9f\xc4\xa1\x6d\x04\x42\x8b\x95\xc2\ +\xa1\xe4\x7e\x5b\x7b\xee\xf0\xfb\x9a\x7b\x6f\x9a\x9c\x63\x11\x50\ +\x75\xbd\x5d\xe0\x16\x28\x01\x87\x40\x9e\xf5\x62\x00\xb4\x81\x16\ +\x50\x6f\x94\x0b\x3d\x00\x0b\xa0\xea\x7a\xa7\xc0\x23\xb0\x27\x16\ +\x2f\x19\x5d\xa0\xd2\x28\x17\x5e\xad\xe0\xcb\xbf\x93\x9d\xf0\x21\ +\x5d\xe0\xc0\xc6\xdf\x36\x59\x0b\x0f\x7e\xe6\x9a\x83\xbf\xe7\xa7\ +\x19\xad\x38\xcc\x5f\xc9\x4d\x3d\x97\x1c\xfc\x03\x3b\xce\xa8\x51\ +\x2e\x38\x2b\x0a\x94\x88\xaa\xeb\x0d\x99\x94\x38\xb2\x59\xbf\xdb\ +\x26\x09\x79\x5b\x3a\xc1\xa2\x18\x01\x69\x8c\x80\x34\x46\x40\x1a\ +\x23\x20\x8d\x11\x90\xc6\x08\x48\x33\xf7\xb7\x59\x6b\x7d\x06\x1c\ +\x03\xdb\xcb\x8f\x33\xc1\x10\xf0\x80\x67\xa5\xd4\x77\xd4\xa2\x48\ +\x01\xad\xb5\x03\xb8\xc0\x65\xfa\xd9\x12\xd1\xd1\x5a\x9f\x2b\xa5\ +\x3e\x66\x15\xe3\xb6\xd0\x0d\xf2\xe1\x01\xf6\x81\x87\xa8\x62\x9c\ +\xc0\x45\xfa\x59\xfe\xcd\x89\xd6\x7a\x67\x56\x21\xf3\x87\x38\x4e\ +\xe0\x65\x65\x29\xe6\xf3\xa6\x94\xfa\x9a\x55\x88\x13\xb8\x07\x9e\ +\x96\x93\x27\x11\x1d\xe0\x3a\xaa\x18\x79\x0b\x29\xa5\x86\xc0\x55\ +\x66\xaf\xd1\x10\xa5\x54\x13\x68\xa6\x18\x2c\x55\x36\xfa\x10\x67\ +\x02\x23\x20\x8d\x11\x90\xc6\x08\x48\x63\x04\xa4\x31\x02\xd2\x6c\ +\x84\xc0\x40\x3a\xc4\x02\xf4\x1d\xfc\xf6\x7d\x71\xec\x65\x2e\xe8\ +\x06\xae\x23\xd3\x6d\xd6\xb6\x83\x3f\x7b\x50\x9c\xb3\x70\x5d\x69\ +\xd9\x40\x1d\xbf\x6d\x9f\x35\xba\xc0\x9d\x1d\x4c\x7d\x54\xc8\x96\ +\x44\x38\xec\xd1\xb3\xc2\x37\xc1\xd0\x47\x8d\xdf\x71\x9b\x2d\xa1\ +\x70\x51\xf4\x99\x1c\xb7\xf9\x04\xf8\x01\x6f\xed\x58\x63\x2d\xfd\ +\xb2\x59\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ \x00\x00\x00\xa5\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ @@ -637,6 +328,82 @@ qt_resource_data = b"\ \x32\x30\x30\x42\x98\x10\x41\x46\x43\x14\x13\x50\xb5\xa3\x01\x00\ \xd6\x10\x07\xd2\x2f\x48\xdf\x4a\x00\x00\x00\x00\x49\x45\x4e\x44\ \xae\x42\x60\x82\ +\x00\x00\x00\xa0\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x06\x00\x00\x00\x09\x08\x04\x00\x00\x00\xbb\x93\x95\x16\ +\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x02\x62\x4b\x47\x44\x00\xff\x87\x8f\xcc\xbf\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\x08\x17\x14\x1c\x1f\x24\ +\xc6\x09\x17\x00\x00\x00\x24\x49\x44\x41\x54\x08\xd7\x63\x60\x40\ +\x05\xff\xcf\xc3\x58\x4c\xc8\x5c\x26\x64\x59\x26\x64\xc5\x70\x0e\ +\xa3\x21\x9c\xc3\x68\x88\x61\x1a\x0a\x00\x00\x6d\x84\x09\x75\x37\ +\x9e\xd9\x23\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x00\xa5\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce\x7c\x4e\ +\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x02\x62\x4b\x47\x44\x00\x9c\x53\x34\xfc\x5d\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\x08\x17\x0b\x02\x04\x6d\ +\x98\x1b\x69\x00\x00\x00\x29\x49\x44\x41\x54\x08\xd7\x63\x60\xc0\ +\x00\x8c\x0c\x0c\xff\xcf\xa3\x08\x18\x32\x32\x30\x20\x0b\x32\x1a\ +\x32\x30\x30\x42\x98\x10\x41\x46\x43\x14\x13\x50\xb5\xa3\x01\x00\ +\xd6\x10\x07\xd2\x2f\x48\xdf\x4a\x00\x00\x00\x00\x49\x45\x4e\x44\ +\xae\x42\x60\x82\ +\x00\x00\x01\x69\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x30\x00\x00\x00\x30\x08\x06\x00\x00\x00\x57\x02\xf9\x87\ +\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\ +\x01\x00\x9a\x9c\x18\x00\x00\x01\x1b\x49\x44\x41\x54\x68\x81\xed\ +\xda\xb1\x6d\xc2\x40\x14\x87\xf1\xcf\xc7\x91\x09\x50\x86\x70\x42\ +\x41\x4f\xc5\x0a\xae\x90\xbc\x0a\x29\xc8\x2a\x96\x52\x79\x05\x2a\ +\x46\x20\x1e\xc2\x82\x05\x48\x90\x52\xdc\x59\x01\x4b\x51\x62\x45\ +\xe2\xef\x93\xde\xaf\xb3\x45\xf1\x3e\xcb\xa6\xb9\x97\x11\x95\x75\ +\x33\x03\x5e\x80\x25\xf0\x0c\x4c\x19\x97\x0f\xe0\x00\xec\x81\x6d\ +\x55\xe4\x47\x80\x0c\xa0\xac\x9b\x15\xf0\x06\x3c\xca\xc6\x1b\xa6\ +\x05\xd6\x55\x91\xef\xb2\xf8\xe4\xdf\x49\x67\xf8\x4e\x0b\x3c\x39\ +\xc2\x6b\x93\xda\xf0\x10\x66\xde\x78\xc2\x3b\xdf\x77\xb9\xf3\x30\ +\x7f\x35\xe9\x5d\x2f\x3d\xe1\x83\xbd\x76\xa9\x8a\xdc\xdf\x69\xa0\ +\x41\xca\xba\xf9\xe4\x36\x62\xee\x18\xdf\xbf\xcd\x10\x53\xa7\x9e\ +\xe0\xbf\x2c\x40\xcd\x02\xd4\x2c\x40\xcd\x02\xd4\x2c\x40\xcd\x02\ +\xd4\x2c\x40\xcd\x02\xd4\x2c\x40\xcd\x02\xd4\x2c\x40\xcd\x02\xd4\ +\x2c\x40\xcd\x02\xd4\x2c\x40\xcd\x02\xd4\x2c\x40\xcd\x11\x4e\xc0\ +\x53\x75\xf6\x84\xe3\xfb\xc5\xd5\xcd\x49\x3c\x0d\x1c\xa3\xfe\x31\ +\xeb\xc1\x13\x76\x0f\x16\xbf\xfc\x70\xac\xf6\x0e\xd8\x12\x8e\xed\ +\x53\xd3\x02\xaf\x2e\x6e\x7d\xac\x49\x2b\xa2\x5b\xf6\x38\x66\xdd\ +\x9d\xb8\xf4\xb1\xe1\x7b\xdd\xe6\x41\x34\xdc\x4f\xce\xdc\xae\xdb\ +\x9c\x00\xbe\x00\x9f\xf6\x34\x3e\x36\x4f\x37\x81\x00\x00\x00\x00\ +\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x00\xa6\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce\x7c\x4e\ +\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x02\x62\x4b\x47\x44\x00\xff\x87\x8f\xcc\xbf\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\x08\x17\x08\x15\x3b\xdc\ +\x3b\x0c\x9b\x00\x00\x00\x2a\x49\x44\x41\x54\x08\xd7\x63\x60\xc0\ +\x00\x8c\x0c\x0c\x73\x3e\x20\x0b\xa4\x08\x30\x32\x30\x20\x0b\xa6\ +\x08\x30\x30\x30\x42\x98\x10\xc1\x14\x01\x14\x13\x50\xb5\xa3\x01\ +\x00\xc6\xb9\x07\x90\x5d\x66\x1f\x83\x00\x00\x00\x00\x49\x45\x4e\ +\x44\xae\x42\x60\x82\ +\x00\x00\x00\xa6\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce\x7c\x4e\ +\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x02\x62\x4b\x47\x44\x00\xff\x87\x8f\xcc\xbf\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\x08\x17\x08\x15\x3b\xdc\ +\x3b\x0c\x9b\x00\x00\x00\x2a\x49\x44\x41\x54\x08\xd7\x63\x60\xc0\ +\x00\x8c\x0c\x0c\x73\x3e\x20\x0b\xa4\x08\x30\x32\x30\x20\x0b\xa6\ +\x08\x30\x30\x30\x42\x98\x10\xc1\x14\x01\x14\x13\x50\xb5\xa3\x01\ +\x00\xc6\xb9\x07\x90\x5d\x66\x1f\x83\x00\x00\x00\x00\x49\x45\x4e\ +\x44\xae\x42\x60\x82\ \x00\x00\x04\x33\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ @@ -707,46 +474,40 @@ qt_resource_data = b"\ \x9b\x46\x27\x81\xcf\x80\xd7\x01\xa7\xe2\xbf\x00\xf8\x17\x5d\x81\ \x0b\x38\xb3\xfa\x20\x9c\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\ \x60\x82\ -\x00\x00\x01\xe1\ +\x00\x00\x01\xfc\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ \x00\x00\x30\x00\x00\x00\x30\x08\x06\x00\x00\x00\x57\x02\xf9\x87\ \x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\ -\x01\x00\x9a\x9c\x18\x00\x00\x01\x93\x49\x44\x41\x54\x68\x81\xed\ -\x9a\x3b\x4e\xc3\x40\x10\x86\xbf\x71\x1c\x2a\xe8\x10\xe5\x36\x94\ -\xd0\xa4\xa1\x8a\x28\x22\x0a\x0a\x44\x9f\x9e\x0b\x70\x80\x50\x70\ -\x01\x2e\xc0\x15\x68\x80\x13\xa0\x1c\x21\x50\x91\x66\xbb\x44\xa1\ -\x42\x34\x79\x68\x28\x6c\x1e\xb1\xfc\x48\x08\xc9\xda\xd2\x7e\x9d\ -\x77\x5c\xfc\x9f\xb3\x1e\x39\xda\x11\x62\x54\x75\x17\xb8\x02\x9a\ -\xc0\x21\x50\xa7\x5c\x4c\x80\x1e\xd0\x05\xae\x45\x64\xf4\x5d\x51\ -\xd5\x96\xaa\x0e\xb4\x3a\x0c\x54\xb5\x05\x20\x1a\x3d\xf9\x67\x60\ -\xcf\xc5\x63\x5d\x81\x21\x70\x10\x10\x6d\x9b\xaa\x85\x87\x28\x73\ -\x27\x24\xda\xf3\x49\x66\x1b\x0e\xb3\x28\xb5\xc4\x75\x53\x54\x75\ -\xcc\xfc\x0b\x3b\x13\x91\x70\x83\xa1\x16\x46\x55\xa7\xcc\x4b\x4c\ -\x02\xca\xd7\x6d\x96\xa1\x1e\xb8\x4e\xb0\x2a\x5e\xc0\x35\x5e\xc0\ -\x35\x5e\xc0\x35\x5e\xc0\x35\x5e\xc0\x35\x5e\xc0\x35\x85\x9f\xcd\ -\xd6\xda\x13\xe0\x08\xd8\x5e\x7f\x9c\x39\xa6\xc0\x0b\xf0\x60\x8c\ -\xf9\xc8\xba\x49\x54\x55\x13\x6b\x33\x11\x09\xad\xb5\x21\x70\x07\ -\x9c\xaf\x31\xe4\x22\xf4\x81\x53\x63\xcc\x6b\xca\xff\x81\xdc\x2d\ -\x74\x89\xfb\xf0\x00\xfb\xc0\x6d\x56\x31\x4f\xe0\xec\xff\xb3\xfc\ -\x99\x63\x6b\xed\x4e\x5a\xa1\xf2\x2f\x71\x9e\xc0\xe3\xc6\x52\x14\ -\xf3\x64\x8c\x79\x4f\x2b\xe4\x09\xdc\x00\xf7\xeb\xc9\xb3\x14\x7d\ -\xe0\x22\xab\x98\xd9\x85\xbe\x2e\xca\xd4\x46\xd3\xba\x50\xa1\x40\ -\x99\x58\xb6\x8d\x56\x02\x2f\xe0\x1a\x2f\xe0\x1a\x2f\xe0\x1a\x2f\ -\xe0\x1a\x2f\xe0\x1a\x2f\xe0\x9a\x80\xe8\x04\xbc\xaa\x8c\x43\xa2\ -\xe3\xfb\xc6\xaf\xc5\x5a\xfc\xd9\x5a\x46\x92\xc7\xac\xbd\x90\x68\ -\xf6\xa0\x51\x70\x63\x59\xe9\x56\x7f\xd4\x20\x9e\xfa\x68\xc7\x0b\ -\x55\x61\x08\xb4\x45\x64\x24\x5f\x2b\xf1\x2f\xd1\xe1\x67\xdc\x66\ -\xcb\x51\xb8\x2c\xc6\xcc\x8f\xdb\xbc\x01\x7c\x02\x6d\x77\x23\xb3\ -\xd4\x95\x53\x76\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ -\ -\x00\x00\x00\x45\ -\x89\ -\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ -\x00\x00\x01\x00\x00\x00\x01\x08\x02\x00\x00\x00\x90\x77\x53\xde\ -\x00\x00\x00\x0c\x49\x44\x41\x54\x08\x99\x63\x60\x60\x60\x00\x00\ -\x00\x04\x00\x01\xa3\x0a\x15\xe3\x00\x00\x00\x00\x49\x45\x4e\x44\ -\xae\x42\x60\x82\ +\x01\x00\x9a\x9c\x18\x00\x00\x01\xae\x49\x44\x41\x54\x68\x81\xed\ +\x9a\xbd\x4a\x03\x41\x14\x46\x4f\x36\x1b\xb0\xd0\x4a\xf1\x01\x14\ +\xab\x68\x91\xc6\x2a\x58\xb8\x16\xb2\x88\x76\x0b\xe9\x7d\x01\x1f\ +\x40\x8b\xf8\x00\xbe\x80\x85\x9d\x30\x62\xa3\x32\x55\xc6\x42\xf2\ +\x02\x42\x92\x46\x83\x7d\x48\x27\x36\xf9\x01\x8b\xdd\x40\x12\xb2\ +\x89\x6b\x7e\x66\x37\xcc\xe9\x76\xef\x14\xdf\x59\xee\x0c\x0b\x77\ +\x52\x04\x38\xae\xb7\x01\x5c\x01\x79\x60\x17\xc8\x10\x2f\xda\x40\ +\x05\x28\x03\x45\x25\x45\x13\x20\x05\xe0\xb8\xde\x21\x70\x0f\x6c\ +\x6a\x8b\x17\x8d\x06\x50\x50\x52\xbc\xa6\x82\x2f\x5f\x25\x39\xe1\ +\x7b\x34\x80\xac\x85\xdf\x36\x49\x0b\x0f\x7e\xe6\x4b\x1b\xbf\xe7\ +\x87\xe9\x2e\x38\xcc\x5f\x49\x0f\x3d\xe7\x6d\xfc\x0d\xdb\x4f\x57\ +\x49\x61\x2f\x28\x50\x24\x1c\xd7\xeb\x30\x28\xb1\x67\x11\xbf\xd3\ +\x26\x0a\x19\x4b\x77\x82\x69\x31\x02\xba\x31\x02\xba\x31\x02\xba\ +\x31\x02\xba\x31\x02\xba\x31\x02\xba\x99\xf8\xdb\xec\xb8\xde\x11\ +\xb0\x0f\xac\xce\x3f\xce\x00\x1d\xa0\x06\x3c\x2b\x29\x7e\xc2\x16\ +\x85\x0a\x38\xae\x67\x03\x8f\xc0\xe9\xec\xb3\x45\xa2\xee\xb8\xde\ +\xb1\x92\xe2\x73\x54\x71\x5c\x0b\x5d\xa0\x3f\x3c\xc0\x36\x70\x1b\ +\x56\x1c\x27\x70\x32\xfb\x2c\xff\xe6\xc0\x71\xbd\xb5\x51\x85\xc4\ +\x6f\xe2\x71\x02\x2f\x0b\x4b\x31\x99\x37\x25\xc5\xf7\xa8\xc2\x38\ +\x81\x1b\xe0\x69\x3e\x79\x22\x51\x07\xce\xc3\x8a\xa1\xa7\x90\x92\ +\xa2\x03\x9c\x25\xf6\x18\xed\xa1\xa4\x28\x01\xa5\x19\x06\x9b\x29\ +\x4b\xbd\x89\x13\x81\x11\xd0\x8d\x11\xd0\x8d\x11\xd0\x8d\x11\xd0\ +\x8d\x11\xd0\xcd\x52\x08\xb4\x75\x87\x98\x82\x96\x8d\x3f\xbe\xcf\ +\xf5\xbd\x4c\x07\xd3\xc0\x38\x32\x3c\x66\xad\xd8\xf8\x77\x0f\x72\ +\x13\x16\xc6\x95\xb2\x05\x14\xf1\xc7\xf6\x49\xa3\x01\x5c\x5b\xc1\ +\xad\x8f\x02\xc9\x92\xe8\x5d\xf6\x68\xa6\x01\xbe\x3e\xaa\x5f\x5b\ +\x3b\xd9\x3b\x60\x05\x7f\xf0\xbd\x4e\xfc\xda\xa8\x05\xbc\x03\x0f\ +\x80\xa7\xa4\xa8\x01\xfc\x02\x51\xab\x5c\x8a\x3f\xde\xe3\x59\x00\ +\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ \x00\x00\x00\xa6\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ @@ -754,64 +515,12 @@ qt_resource_data = b"\ \x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ \x02\x62\x4b\x47\x44\x00\xff\x87\x8f\xcc\xbf\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\x08\x17\x14\x1d\x00\xb0\ -\xd5\x35\xa3\x00\x00\x00\x2a\x49\x44\x41\x54\x08\xd7\x63\x60\xc0\ -\x06\xfe\x9f\x67\x60\x60\x42\x30\xa1\x1c\x08\x93\x81\x81\x09\xc1\ -\x64\x60\x60\x62\x60\x60\x34\x44\xe2\x20\x73\x19\x90\x8d\x40\x02\ -\x00\x64\x40\x09\x75\x86\xb3\xad\x9c\x00\x00\x00\x00\x49\x45\x4e\ +\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xdc\x08\x17\x14\x1f\x20\xb9\ +\x8d\x77\xe9\x00\x00\x00\x2a\x49\x44\x41\x54\x08\xd7\x63\x60\xc0\ +\x06\xe6\x7c\x60\x60\x60\x42\x30\xa1\x1c\x08\x93\x81\x81\x09\xc1\ +\x64\x60\x60\x62\x60\x48\x11\x40\xe2\x20\x73\x19\x90\x8d\x40\x02\ +\x00\x23\xed\x08\xaf\x64\x9f\x0f\x15\x00\x00\x00\x00\x49\x45\x4e\ \x44\xae\x42\x60\x82\ -\x00\x00\x00\xa6\ -\x89\ -\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ -\x00\x00\x06\x00\x00\x00\x09\x08\x04\x00\x00\x00\xbb\x93\x95\x16\ -\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ -\x02\x62\x4b\x47\x44\x00\xff\x87\x8f\xcc\xbf\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\x08\x17\x14\x1d\x00\xb0\ -\xd5\x35\xa3\x00\x00\x00\x2a\x49\x44\x41\x54\x08\xd7\x63\x60\xc0\ -\x06\xfe\x9f\x67\x60\x60\x42\x30\xa1\x1c\x08\x93\x81\x81\x09\xc1\ -\x64\x60\x60\x62\x60\x60\x34\x44\xe2\x20\x73\x19\x90\x8d\x40\x02\ -\x00\x64\x40\x09\x75\x86\xb3\xad\x9c\x00\x00\x00\x00\x49\x45\x4e\ -\x44\xae\x42\x60\x82\ -\x00\x00\x01\x76\ -\x89\ -\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ -\x00\x00\x30\x00\x00\x00\x30\x08\x06\x00\x00\x00\x57\x02\xf9\x87\ -\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\ -\x01\x00\x9a\x9c\x18\x00\x00\x01\x28\x49\x44\x41\x54\x68\x81\xed\ -\xda\xb1\x4a\xc3\x50\x14\x87\xf1\x2f\x37\xb7\xe0\xae\xf8\x00\x82\ -\x53\x75\xe8\xde\xc9\x6c\x79\x80\x40\x1f\x46\x87\xfa\x22\x6e\x42\ -\xdc\xb3\xc5\xa9\x2f\x20\xb4\x5d\x3a\x74\x0f\x7d\x82\x6a\xc1\xe1\ -\xa6\x50\xb3\x68\x10\xfa\xcf\x85\xf3\xdb\x52\x3a\x9c\xaf\xdc\x66\ -\x39\x37\xa1\x95\xe5\xc5\x15\xf0\x04\x4c\x81\x3b\x60\xc4\xb0\x7c\ -\x02\x4b\x60\x01\xcc\xeb\xaa\xdc\x01\x24\x00\x59\x5e\x3c\x00\xaf\ -\xc0\xb5\x6c\xbc\x7e\x1a\x60\x56\x57\xe5\x7b\xd2\xfe\xf2\x2b\xe2\ -\x19\xfe\xa8\x01\xc6\x8e\x70\x6c\x62\x1b\x1e\xc2\xcc\x8f\x9e\x70\ -\xe6\xbb\x0e\x67\x1e\xe6\xaf\xd2\xce\xf3\xd4\x13\xfe\xb0\xa7\x0e\ -\x75\x55\xfa\x33\x0d\xd4\x4b\x96\x17\x5f\xfc\x8c\xb8\x77\x0c\xef\ -\x6d\xd3\xc7\xc8\xa9\x27\xf8\x2f\x0b\x50\xb3\x00\x35\x0b\x50\xb3\ -\x00\x35\x0b\x50\xb3\x00\x35\x0b\x50\xb3\x00\x35\x0b\x50\xb3\x00\ -\x35\x0b\x50\xb3\x00\x35\x0b\x50\xb3\x00\x35\x0b\x50\xb3\x00\x35\ -\x0b\x50\x73\x84\x0d\x78\xac\xf6\x9e\xb0\xbe\x9f\x9c\x7c\x98\xb6\ -\xdb\xc0\x21\xea\xae\x59\x97\x9e\x70\xf7\x60\xf2\xcb\x17\x87\x6a\ -\xe1\x80\x39\x61\x6d\x1f\x9b\x06\x78\x76\xed\xad\x8f\x19\x71\x45\ -\x1c\x2f\x7b\xec\x52\x80\xed\x66\xb5\xbd\xb9\x1d\xbf\x00\x17\x84\ -\xc5\xf7\x25\xc3\x3b\x46\x7b\xe0\x03\x78\x03\x8a\xba\x2a\xd7\x00\ -\xdf\xa4\xb5\x36\xa2\xca\x99\x74\x47\x00\x00\x00\x00\x49\x45\x4e\ -\x44\xae\x42\x60\x82\ -\x00\x00\x00\xa5\ -\x89\ -\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ -\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce\x7c\x4e\ -\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ -\x02\x62\x4b\x47\x44\x00\x9c\x53\x34\xfc\x5d\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\x08\x17\x0b\x02\x04\x6d\ -\x98\x1b\x69\x00\x00\x00\x29\x49\x44\x41\x54\x08\xd7\x63\x60\xc0\ -\x00\x8c\x0c\x0c\xff\xcf\xa3\x08\x18\x32\x32\x30\x20\x0b\x32\x1a\ -\x32\x30\x30\x42\x98\x10\x41\x46\x43\x14\x13\x50\xb5\xa3\x01\x00\ -\xd6\x10\x07\xd2\x2f\x48\xdf\x4a\x00\x00\x00\x00\x49\x45\x4e\x44\ -\xae\x42\x60\x82\ \x00\x00\x07\x30\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ @@ -929,92 +638,72 @@ qt_resource_data = b"\ \x23\xe0\x23\x37\xe1\xa8\x4f\x0e\x7f\xda\x60\xd7\xaf\x9f\xb9\x09\ \xdf\x63\x05\xff\xe5\x75\x4c\x65\xf5\xcc\x1f\x0d\x33\x2c\x83\xb6\ \x06\x44\x83\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ -\x00\x00\x00\xa6\ +\x00\x00\x03\xfb\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ -\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce\x7c\x4e\ -\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ -\x02\x62\x4b\x47\x44\x00\xff\x87\x8f\xcc\xbf\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\x08\x17\x08\x15\x3b\xdc\ -\x3b\x0c\x9b\x00\x00\x00\x2a\x49\x44\x41\x54\x08\xd7\x63\x60\xc0\ -\x00\x8c\x0c\x0c\x73\x3e\x20\x0b\xa4\x08\x30\x32\x30\x20\x0b\xa6\ -\x08\x30\x30\x30\x42\x98\x10\xc1\x14\x01\x14\x13\x50\xb5\xa3\x01\ -\x00\xc6\xb9\x07\x90\x5d\x66\x1f\x83\x00\x00\x00\x00\x49\x45\x4e\ -\x44\xae\x42\x60\x82\ -\x00\x00\x00\x9e\ -\x89\ -\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ -\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce\x7c\x4e\ -\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ -\x02\x62\x4b\x47\x44\x00\xff\x87\x8f\xcc\xbf\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\x08\x17\x08\x15\x0f\xfd\ -\x8f\xf8\x2e\x00\x00\x00\x22\x49\x44\x41\x54\x08\xd7\x63\x60\xc0\ -\x0d\xfe\x9f\x87\xb1\x18\x91\x05\x18\x0d\xe1\x42\x48\x2a\x0c\x19\ -\x18\x18\x91\x05\x10\x2a\xd1\x00\x00\xca\xb5\x07\xd2\x76\xbb\xb2\ -\xc5\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ -\x00\x00\x00\xa5\ -\x89\ -\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ -\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce\x7c\x4e\ -\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ -\x02\x62\x4b\x47\x44\x00\x9c\x53\x34\xfc\x5d\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\x08\x17\x0b\x02\x04\x6d\ -\x98\x1b\x69\x00\x00\x00\x29\x49\x44\x41\x54\x08\xd7\x63\x60\xc0\ -\x00\x8c\x0c\x0c\xff\xcf\xa3\x08\x18\x32\x32\x30\x20\x0b\x32\x1a\ -\x32\x30\x30\x42\x98\x10\x41\x46\x43\x14\x13\x50\xb5\xa3\x01\x00\ -\xd6\x10\x07\xd2\x2f\x48\xdf\x4a\x00\x00\x00\x00\x49\x45\x4e\x44\ -\xae\x42\x60\x82\ -\x00\x00\x00\xa0\ -\x89\ -\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ -\x00\x00\x06\x00\x00\x00\x09\x08\x04\x00\x00\x00\xbb\x93\x95\x16\ -\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ -\x02\x62\x4b\x47\x44\x00\xff\x87\x8f\xcc\xbf\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\x08\x17\x14\x1c\x1f\x24\ -\xc6\x09\x17\x00\x00\x00\x24\x49\x44\x41\x54\x08\xd7\x63\x60\x40\ -\x05\xff\xcf\xc3\x58\x4c\xc8\x5c\x26\x64\x59\x26\x64\xc5\x70\x0e\ -\xa3\x21\x9c\xc3\x68\x88\x61\x1a\x0a\x00\x00\x6d\x84\x09\x75\x37\ -\x9e\xd9\x23\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ -\x00\x00\x00\xa0\ -\x89\ -\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ -\x00\x00\x06\x00\x00\x00\x09\x08\x04\x00\x00\x00\xbb\x93\x95\x16\ -\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ -\x02\x62\x4b\x47\x44\x00\xff\x87\x8f\xcc\xbf\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\x08\x17\x14\x1c\x1f\x24\ -\xc6\x09\x17\x00\x00\x00\x24\x49\x44\x41\x54\x08\xd7\x63\x60\x40\ -\x05\xff\xcf\xc3\x58\x4c\xc8\x5c\x26\x64\x59\x26\x64\xc5\x70\x0e\ -\xa3\x21\x9c\xc3\x68\x88\x61\x1a\x0a\x00\x00\x6d\x84\x09\x75\x37\ -\x9e\xd9\x23\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ -\x00\x00\x00\xa0\ -\x89\ -\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ -\x00\x00\x06\x00\x00\x00\x09\x08\x04\x00\x00\x00\xbb\x93\x95\x16\ -\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ -\x02\x62\x4b\x47\x44\x00\xff\x87\x8f\xcc\xbf\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\x08\x17\x14\x1f\x0d\xfc\ -\x52\x2b\x9c\x00\x00\x00\x24\x49\x44\x41\x54\x08\xd7\x63\x60\x40\ -\x05\x73\x3e\xc0\x58\x4c\xc8\x5c\x26\x64\x59\x26\x64\xc5\x70\x4e\ -\x8a\x00\x9c\x93\x22\x80\x61\x1a\x0a\x00\x00\x29\x95\x08\xaf\x88\ -\xac\xba\x34\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ -\x00\x00\x00\x9e\ -\x89\ -\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ -\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce\x7c\x4e\ -\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ -\x02\x62\x4b\x47\x44\x00\xff\x87\x8f\xcc\xbf\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\x08\x17\x08\x15\x0f\xfd\ -\x8f\xf8\x2e\x00\x00\x00\x22\x49\x44\x41\x54\x08\xd7\x63\x60\xc0\ -\x0d\xfe\x9f\x87\xb1\x18\x91\x05\x18\x0d\xe1\x42\x48\x2a\x0c\x19\ -\x18\x18\x91\x05\x10\x2a\xd1\x00\x00\xca\xb5\x07\xd2\x76\xbb\xb2\ -\xc5\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x30\x00\x00\x00\x30\x08\x06\x00\x00\x00\x57\x02\xf9\x87\ +\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\ +\x01\x00\x9a\x9c\x18\x00\x00\x03\xad\x49\x44\x41\x54\x68\x81\xed\ +\x9a\x4f\xa8\x15\x55\x1c\xc7\x3f\xf7\xbe\xab\xf2\x20\xa3\x22\x6d\ +\xa1\x7c\x21\x09\x2a\x4b\x28\xda\x44\xb9\x88\x52\x4c\xcc\x6a\x51\ +\xf9\xa4\x85\xf1\xa0\x16\x51\xe4\x2e\x10\x74\x51\x44\x8b\x16\x15\ +\x25\x81\xb5\x28\x04\xad\xc0\xe2\x61\x64\xf6\x97\xe0\x45\x10\xb4\ +\xa9\x27\x44\x45\xc4\x17\xa2\x12\x35\x0a\x2a\xff\x3c\xab\xc5\x99\ +\x5b\xd7\x79\x33\x73\xce\xdc\x6b\x6f\xee\x05\x3f\xbb\x39\xf3\x3b\ +\xbf\xf3\xfb\x9d\x33\xe7\x9c\xef\x9c\x99\x16\x19\xb6\x2f\x06\x76\ +\x00\xab\x81\xab\x81\x05\x0c\x17\xa7\x80\x19\x60\x1a\x78\x4c\xd2\ +\x11\x80\x16\x80\xed\x9b\x81\xbd\xc0\xd2\xc6\xc2\xab\xc7\x61\x60\ +\xb3\xa4\x0f\x5b\x59\xcf\x1f\x62\x74\x82\xef\x72\x18\xb8\xaa\x4d\ +\x78\x6c\x46\x2d\x78\x08\x31\x6f\xef\x10\x9e\xf9\x3c\xa7\xe7\x39\ +\x98\x54\xc6\x72\xd7\xab\x3b\x84\x09\xdb\xcb\x69\x49\x9d\x79\x0a\ +\xa8\x16\xb6\x67\x39\x33\x89\x55\x6d\x86\x6f\xb5\xa9\xc3\x82\x76\ +\xd3\x11\x0c\xca\xb9\x04\x9a\xe6\x5c\x02\xff\x07\xb6\xef\xb6\xbd\ +\xd7\xf6\xda\x98\xed\xd0\x25\x60\xfb\x11\xe0\x75\x60\x02\x38\x68\ +\x7b\xa7\xed\xd2\x95\x72\xa8\x12\xb0\x3d\x01\x3c\xdd\x53\xd4\x02\ +\x1e\x04\x5e\x2c\xab\x33\x34\x1b\x96\xed\x35\xc0\x2b\x64\x02\x33\ +\xc7\x16\xdb\x5f\x16\xd5\x1b\x8a\x11\xb0\x7d\x1d\xf0\x06\xb0\xb0\ +\xc2\x6c\x7d\x51\x61\xe3\x09\xd8\xbe\x0c\x78\x1b\x58\x1c\x31\x7d\ +\xa9\xa8\xb0\xd1\x04\x6c\x5f\x02\x1c\x24\xae\x86\x9f\x92\xf4\x6a\ +\xd1\x8d\xc6\x12\xb0\xbd\x18\x38\x00\xac\x88\x98\xee\x06\x1e\x2d\ +\xbb\xd9\x48\x02\xb6\x17\x02\x6f\x02\xd7\x46\x4c\xdf\x01\x26\x25\ +\xfd\x5d\x66\x30\xef\x09\xd8\x6e\x13\x7a\xf5\x96\x88\xe9\x67\xc0\ +\x5d\x92\x66\xab\x8c\x9a\x18\x81\x67\x80\x7b\x22\x36\x5f\x03\x1b\ +\x24\xfd\x1e\x73\x96\x94\x80\xed\x56\xd6\x73\x03\x61\x7b\x1b\xf0\ +\x70\xc4\xec\x47\x60\x5d\xf7\xd4\x21\x46\x65\x50\x59\xe0\x5b\x81\ +\x3f\x81\x19\xdb\xab\x92\x22\x2d\xf6\x35\x09\x3c\x11\x31\xfb\x15\ +\xb8\x55\xd2\xf7\xa9\x7e\x4b\x13\xc8\xf4\xc7\x14\x61\x6b\x5f\x04\ +\x5c\x09\xbc\x6f\xfb\xf2\x54\xe7\x3d\xbe\x36\x02\xbb\x22\x66\x27\ +\x80\x3b\x24\x7d\x51\xc7\x77\xd5\x08\x3c\x0f\x6c\xcc\x95\x2d\x05\ +\x3e\xb0\x7d\x69\x6a\x03\xb6\x6f\x00\x5e\x63\xee\x0b\x79\x2f\x7f\ +\x01\xf7\x4a\xfa\x38\xd5\x6f\x97\xc2\x04\xb2\x1e\x7b\xa0\xa4\xce\ +\x32\xc2\x48\x2c\x8b\x39\xb7\xbd\x12\xd8\x0f\x8c\x47\x4c\x1f\x92\ +\xb4\x2f\xe6\xaf\x88\xb2\x11\xb8\x28\x52\x6f\x05\x21\x89\x25\x65\ +\x06\xb6\x97\x13\x76\xd9\x98\xaf\xc7\x25\xbd\x10\xb1\x29\xa5\x2c\ +\x81\x3d\x84\x75\xb8\x8a\x2b\x80\x77\x6d\x5f\x90\xbf\x61\xfb\x42\ +\x42\xf0\xcb\x23\x3e\x76\x49\xda\x11\x8d\xb2\x82\xc2\x04\x24\x9d\ +\x22\xa8\xbf\x42\x09\xdb\xc3\x35\xc0\x01\xdb\xe7\x75\x0b\x6c\x8f\ +\x13\x1e\x9b\x95\x91\xba\x53\x04\xad\x3f\x10\xa5\x93\x58\xd2\x31\ +\x60\x2d\xf0\x4d\xc4\xc7\xf5\xc0\x7e\xdb\xe3\xb6\xc7\x08\x13\xf6\ +\xc6\x48\x9d\x69\x60\x42\xd2\xc0\x27\x80\x95\xfb\x80\xa4\x9f\x81\ +\x35\x80\x23\x7e\x6e\x02\xf6\x11\x96\xca\xfc\xca\x95\x67\x06\xb8\ +\x5d\xd2\xf1\xc4\x18\x2b\x89\xee\xae\x92\x4c\xd0\x2d\x3f\x45\x4c\ +\xd7\x03\x93\x11\x1b\x13\x36\xaa\x5f\xd2\xc2\x8b\x93\x24\x0f\x24\ +\x7d\x4b\x18\x89\xa3\x03\xb4\x75\x8c\x20\x11\x7e\x18\xc0\xc7\x1c\ +\x92\xf5\x8d\xa4\x43\xc0\x3a\xe0\xb7\x3e\xda\xf9\x03\xb8\x4d\xd2\ +\x57\x7d\xd4\xad\xa4\x96\x40\x93\xf4\x39\xb0\x21\x0b\x28\x95\x59\ +\x60\x93\xa4\x4f\xeb\xb4\x95\x4a\x6d\x85\x29\x69\x1a\xb8\x93\xa0\ +\x5d\x52\xb8\x5f\xd2\x5b\x75\xdb\x49\xa5\x2f\x89\x2c\xe9\x3d\x60\ +\x13\xa1\x77\xab\xd8\x26\xe9\xe5\x7e\xda\x48\xa5\x6f\x8d\x2f\x69\ +\x0a\xd8\x42\x10\x62\x45\x3c\x27\xe9\xc9\x7e\xfd\xa7\x32\xd0\x4b\ +\x8a\xa4\x3d\xc0\x7d\xcc\x9d\x13\x3b\x81\xad\x83\xf8\x4e\x65\xe0\ +\x93\x39\x49\xbb\x6d\x7f\x42\xd8\xc0\xce\x07\x3e\xca\xe6\xc9\xbc\ +\x70\x56\x8e\x16\x25\x7d\x07\x3c\x7b\x36\x7c\xd5\xa5\x4d\xf8\x02\ +\x3e\xaa\x9c\xec\x10\xb4\x49\xef\xf9\xcc\x58\xf6\x35\x70\x18\xc9\ +\xbf\xd5\xcd\x74\x08\xca\x30\x7f\xc0\x54\xf5\xfa\x37\x4c\x4c\x8f\ +\xfe\xaf\x06\xd9\xf9\xcb\xe6\xac\x60\x54\xe8\xfe\xec\x71\xe4\xdf\ +\x8f\x09\xd9\x48\x6c\xe7\xbf\xdf\x6d\xaa\xce\xea\x9b\xe0\x24\x67\ +\xfe\x6e\x73\x14\xe0\x1f\x0a\x43\x12\x6b\x4f\xfd\x3f\x13\x00\x00\ +\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ \x00\x00\x01\x5b\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ @@ -1167,6 +856,56 @@ qt_resource_data = b"\ \x71\x5b\x73\x5c\x40\x48\xa5\xdd\x61\x81\x0d\x9e\x6b\x8e\xff\xfd\ \xcf\x3f\xcc\x31\xe9\x01\x1c\x00\x73\x52\x2d\x71\xe4\x4a\x1b\x69\ \x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x00\x9e\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce\x7c\x4e\ +\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x02\x62\x4b\x47\x44\x00\xff\x87\x8f\xcc\xbf\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\x08\x17\x08\x15\x0f\xfd\ +\x8f\xf8\x2e\x00\x00\x00\x22\x49\x44\x41\x54\x08\xd7\x63\x60\xc0\ +\x0d\xfe\x9f\x87\xb1\x18\x91\x05\x18\x0d\xe1\x42\x48\x2a\x0c\x19\ +\x18\x18\x91\x05\x10\x2a\xd1\x00\x00\xca\xb5\x07\xd2\x76\xbb\xb2\ +\xc5\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x00\xa6\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x06\x00\x00\x00\x09\x08\x04\x00\x00\x00\xbb\x93\x95\x16\ +\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x02\x62\x4b\x47\x44\x00\xff\x87\x8f\xcc\xbf\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\x08\x17\x14\x1d\x00\xb0\ +\xd5\x35\xa3\x00\x00\x00\x2a\x49\x44\x41\x54\x08\xd7\x63\x60\xc0\ +\x06\xfe\x9f\x67\x60\x60\x42\x30\xa1\x1c\x08\x93\x81\x81\x09\xc1\ +\x64\x60\x60\x62\x60\x60\x34\x44\xe2\x20\x73\x19\x90\x8d\x40\x02\ +\x00\x64\x40\x09\x75\x86\xb3\xad\x9c\x00\x00\x00\x00\x49\x45\x4e\ +\x44\xae\x42\x60\x82\ +\x00\x00\x00\xa5\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce\x7c\x4e\ +\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x02\x62\x4b\x47\x44\x00\x9c\x53\x34\xfc\x5d\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\x08\x17\x0b\x02\x04\x6d\ +\x98\x1b\x69\x00\x00\x00\x29\x49\x44\x41\x54\x08\xd7\x63\x60\xc0\ +\x00\x8c\x0c\x0c\xff\xcf\xa3\x08\x18\x32\x32\x30\x20\x0b\x32\x1a\ +\x32\x30\x30\x42\x98\x10\x41\x46\x43\x14\x13\x50\xb5\xa3\x01\x00\ +\xd6\x10\x07\xd2\x2f\x48\xdf\x4a\x00\x00\x00\x00\x49\x45\x4e\x44\ +\xae\x42\x60\x82\ +\x00\x00\x00\x9e\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce\x7c\x4e\ +\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x02\x62\x4b\x47\x44\x00\xff\x87\x8f\xcc\xbf\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\x08\x17\x08\x15\x0f\xfd\ +\x8f\xf8\x2e\x00\x00\x00\x22\x49\x44\x41\x54\x08\xd7\x63\x60\xc0\ +\x0d\xfe\x9f\x87\xb1\x18\x91\x05\x18\x0d\xe1\x42\x48\x2a\x0c\x19\ +\x18\x18\x91\x05\x10\x2a\xd1\x00\x00\xca\xb5\x07\xd2\x76\xbb\xb2\ +\xc5\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ \x00\x00\x01\x57\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ @@ -1191,6 +930,351 @@ qt_resource_data = b"\ \x97\xd8\xf0\x7d\xdc\xe6\xce\x34\xdc\x6f\x3a\xfa\xc7\x6d\xde\x00\ \x3e\x00\x47\xd7\xea\xb1\xad\x69\xe1\xd6\x00\x00\x00\x00\x49\x45\ \x4e\x44\xae\x42\x60\x82\ +\x00\x00\x04\x12\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x30\x00\x00\x00\x30\x08\x06\x00\x00\x00\x57\x02\xf9\x87\ +\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\ +\x01\x00\x9a\x9c\x18\x00\x00\x03\xc4\x49\x44\x41\x54\x68\x81\xed\ +\x9a\x5f\x88\x94\x55\x18\xc6\x7f\x33\x3b\x1a\x0b\x19\x15\x66\x17\ +\xca\x03\x49\x50\x4d\x09\x4a\x37\x51\x5e\x44\x29\x26\x66\x05\x5b\ +\xb9\xd2\x82\xb1\x50\x17\x91\x24\x74\x11\x08\x7a\xa1\x44\x17\x5d\ +\x54\x94\x04\xd6\x45\xe1\xa2\x15\x4c\xb1\x18\x99\xfd\x25\xd8\x08\ +\x82\x6e\x6a\x5d\xa4\x22\xe2\x81\xa8\x96\xd5\x28\xe8\x9f\xae\xd5\ +\xc5\xf9\xb6\xc6\xd9\xf9\xbe\x73\x66\xc6\x76\x66\xc0\xdf\xdd\x9c\ +\xef\x3d\xef\x79\x9f\x73\xe6\x9c\xf3\x7e\xdf\x39\x25\x32\x46\x6a\ +\x53\x4b\x81\xdd\xc0\x5a\xe0\x3a\x60\x11\xbd\xc5\x69\x60\x12\x98\ +\x00\xf6\x8c\x0d\x55\x67\x00\x4a\x00\x23\xb5\xa9\x5b\x80\x43\xc0\ +\xb2\xae\x85\xd7\x1a\xd3\xc0\xd6\xb1\xa1\xea\x07\xa5\xac\xe7\x8f\ +\xd1\x3f\xc1\xcf\x31\x0d\x5c\x5b\x26\xfc\x6d\xfa\x2d\x78\x08\x31\ +\xef\xaa\x10\xfe\xf3\x8d\x9c\x59\xe0\x60\x52\x19\x68\xf8\xbd\xb6\ +\x42\x98\xb0\xf5\x9c\x19\x1b\xaa\x56\x16\x28\xa0\x96\x18\xa9\x4d\ +\xcd\x72\xb6\x88\x55\x65\x7a\x6f\xb5\x69\x85\x45\xe5\x6e\x47\xd0\ +\x29\xe7\x05\x74\x9b\xf3\x02\xfe\x0f\x6c\xdf\x63\xfb\x90\xed\xf5\ +\x31\xdb\x9e\x13\x60\xfb\x11\xe0\x35\x60\x18\x38\x6a\x7b\x9f\xed\ +\xdc\x95\xb2\xa7\x04\xd8\x1e\x06\x9e\xaa\x2b\x2a\x01\x0f\x01\x2f\ +\xe4\xd5\xe9\x19\x01\xb6\xd7\x01\x2f\x93\x25\x98\x0d\x6c\xb3\xfd\ +\x68\xb3\x7a\x3d\x21\xc0\xf6\xf5\xc0\xeb\xc0\xe2\x02\xb3\x8d\xcd\ +\x0a\xbb\x2e\xc0\xf6\x95\xc0\x5b\xc0\x92\x88\xe9\x8b\xcd\x0a\xbb\ +\x2a\xc0\xf6\xe5\xc0\x51\xe2\xd9\xf0\x93\x92\x5e\x69\xf6\xa0\x6b\ +\x02\x6c\x2f\x01\x8e\x00\x2b\x23\xa6\x07\x80\xc7\xf2\x1e\x76\x45\ +\x80\xed\xc5\xc0\x1b\xc0\x9a\x88\xe9\xdb\xc0\xa8\xa4\xbf\xf3\x0c\ +\x16\x5c\x80\xed\x32\xa1\x57\x6f\x8d\x98\x7e\x0a\xdc\x2d\x69\xb6\ +\xc8\xa8\x1b\x23\xf0\x34\x70\x6f\xc4\xe6\x4b\x60\x93\xa4\x5f\x63\ +\xce\x92\x04\xd8\x2e\x65\x3d\xd7\x11\xb6\x77\x02\xdb\x23\x66\xdf\ +\x03\x1b\x24\xcd\xa4\xf8\x2c\x0c\x2a\x0b\x7c\x07\xf0\x3b\x30\x69\ +\x7b\x55\x52\xa4\xcd\x7d\x8d\x02\x8f\x47\xcc\x7e\x06\x6e\x93\xf4\ +\x6d\xaa\xdf\x5c\x01\x59\xfe\x31\x4e\xd8\xda\x2f\x00\xae\x01\xde\ +\xb3\x7d\x55\xaa\xf3\x3a\x5f\x9b\x81\xfd\x11\xb3\x3f\x81\x3b\x25\ +\x7d\xde\x8a\xef\xa2\x11\x78\x0e\xd8\xdc\x50\xb6\x0c\x78\xdf\xf6\ +\x15\xa9\x0d\xd8\xbe\x11\x78\x95\xf9\x2f\xe4\xf5\xfc\x05\xdc\x27\ +\xe9\xa3\x54\xbf\x73\x34\x15\x90\xf5\xd8\x83\x39\x75\x96\x13\x46\ +\x62\x79\xcc\xb9\xed\x2a\x70\x18\x18\x8c\x98\x3e\x2c\xa9\x16\xf3\ +\xd7\x8c\xbc\x11\xb8\x34\x52\x6f\x25\x41\xc4\x65\x79\x06\xb6\x57\ +\x10\x76\xd9\x98\xaf\xbd\x92\x9e\x8f\xd8\xe4\x92\x27\xe0\x20\x61\ +\x1d\x2e\xe2\x6a\xe0\x1d\xdb\x17\x37\x3e\xb0\x7d\x09\x21\xf8\x15\ +\x11\x1f\xfb\x25\xed\x8e\x46\x59\x40\x53\x01\x92\x4e\x13\xb2\xbf\ +\x2f\x22\xf5\x57\x03\x47\x6c\x5f\x38\x57\x60\x7b\x90\xf0\xb7\xa9\ +\x46\xea\x8e\x13\x72\xfd\x8e\xc8\x9d\xc4\x92\x4e\x02\xeb\x81\xaf\ +\x22\x3e\x6e\x00\x0e\xdb\x1e\xb4\x3d\x40\x98\xb0\x37\x45\xea\x4c\ +\x00\xc3\x92\x3a\xfe\x02\x58\xb8\x0f\x48\xfa\x11\x58\x07\x38\xe2\ +\xe7\x66\xa0\x46\x58\x2a\x1b\x57\xae\x46\x26\x81\x3b\x24\xfd\x91\ +\x18\x63\x21\xd1\xdd\x55\x92\x09\x79\xcb\x0f\x11\xd3\x8d\xc0\x68\ +\xc4\xc6\x84\x8d\xea\xa7\xb4\xf0\xe2\x24\xa5\x07\x92\xbe\x26\x8c\ +\xc4\x89\x0e\xda\x3a\x49\x48\x11\xbe\xeb\xc0\xc7\x3c\x92\xf3\x1b\ +\x49\xc7\x80\x0d\xc0\x2f\x6d\xb4\xf3\x1b\x70\xbb\xa4\xe3\x6d\xd4\ +\x2d\xa4\xa5\x04\x4d\xd2\x67\xc0\xa6\x2c\xa0\x54\x66\x81\x2d\x92\ +\x3e\x69\xa5\xad\x54\x5a\xce\x30\x25\x4d\x00\x77\x11\x72\x97\x14\ +\x1e\x90\xf4\x66\xab\xed\xa4\xd2\x56\x8a\x2c\xe9\x5d\x60\x0b\xa1\ +\x77\x8b\xd8\x29\xe9\xa5\x76\xda\x48\xa5\xed\x1c\x5f\xd2\x38\xb0\ +\x8d\x90\x88\x35\xe3\x59\x49\x4f\xb4\xeb\x3f\x95\x8e\x5e\x52\x24\ +\x1d\x04\xee\x67\xfe\x9c\xd8\x07\xec\xe8\xc4\x77\x2a\x1d\x1f\x25\ +\x49\x3a\x60\xfb\x63\xc2\x06\x76\x11\xf0\x61\x36\x4f\x16\x84\x73\ +\x72\x16\x26\xe9\x1b\xe0\x99\x73\xe1\xab\x55\xca\x84\x13\xf0\x7e\ +\xe5\x54\x85\x90\x9b\xd4\x7f\x9f\x19\xc8\x4e\x03\x7b\x91\xc6\xb7\ +\xba\xc9\x0a\x21\x33\x6c\xfc\xc0\x54\xf4\xfa\xd7\x4b\x4c\x94\x81\ +\x3d\x84\x63\xfb\x7e\x63\x1a\xd8\x5b\xce\x6e\x7d\x6c\xa5\xbf\x44\ +\xcc\x5d\xf6\x98\xf9\xf7\x30\x21\xbb\xf4\xb1\x8b\xff\xae\xdb\x14\ +\x7d\xab\xef\x06\xa7\x38\xfb\xba\xcd\x09\x80\x7f\x00\xc4\x1e\x10\ +\x29\x33\x5b\x85\xf7\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\ +\x82\ +\x00\x00\x01\xe1\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x30\x00\x00\x00\x30\x08\x06\x00\x00\x00\x57\x02\xf9\x87\ +\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\ +\x01\x00\x9a\x9c\x18\x00\x00\x01\x93\x49\x44\x41\x54\x68\x81\xed\ +\x9a\x3b\x4e\xc3\x40\x10\x86\xbf\x71\x1c\x2a\xe8\x10\xe5\x36\x94\ +\xd0\xa4\xa1\x8a\x28\x22\x0a\x0a\x44\x9f\x9e\x0b\x70\x80\x50\x70\ +\x01\x2e\xc0\x15\x68\x80\x13\xa0\x1c\x21\x50\x91\x66\xbb\x44\xa1\ +\x42\x34\x79\x68\x28\x6c\x1e\xb1\xfc\x48\x08\xc9\xda\xd2\x7e\x9d\ +\x77\x5c\xfc\x9f\xb3\x1e\x39\xda\x11\x62\x54\x75\x17\xb8\x02\x9a\ +\xc0\x21\x50\xa7\x5c\x4c\x80\x1e\xd0\x05\xae\x45\x64\xf4\x5d\x51\ +\xd5\x96\xaa\x0e\xb4\x3a\x0c\x54\xb5\x05\x20\x1a\x3d\xf9\x67\x60\ +\xcf\xc5\x63\x5d\x81\x21\x70\x10\x10\x6d\x9b\xaa\x85\x87\x28\x73\ +\x27\x24\xda\xf3\x49\x66\x1b\x0e\xb3\x28\xb5\xc4\x75\x53\x54\x75\ +\xcc\xfc\x0b\x3b\x13\x91\x70\x83\xa1\x16\x46\x55\xa7\xcc\x4b\x4c\ +\x02\xca\xd7\x6d\x96\xa1\x1e\xb8\x4e\xb0\x2a\x5e\xc0\x35\x5e\xc0\ +\x35\x5e\xc0\x35\x5e\xc0\x35\x5e\xc0\x35\x5e\xc0\x35\x85\x9f\xcd\ +\xd6\xda\x13\xe0\x08\xd8\x5e\x7f\x9c\x39\xa6\xc0\x0b\xf0\x60\x8c\ +\xf9\xc8\xba\x49\x54\x55\x13\x6b\x33\x11\x09\xad\xb5\x21\x70\x07\ +\x9c\xaf\x31\xe4\x22\xf4\x81\x53\x63\xcc\x6b\xca\xff\x81\xdc\x2d\ +\x74\x89\xfb\xf0\x00\xfb\xc0\x6d\x56\x31\x4f\xe0\xec\xff\xb3\xfc\ +\x99\x63\x6b\xed\x4e\x5a\xa1\xf2\x2f\x71\x9e\xc0\xe3\xc6\x52\x14\ +\xf3\x64\x8c\x79\x4f\x2b\xe4\x09\xdc\x00\xf7\xeb\xc9\xb3\x14\x7d\ +\xe0\x22\xab\x98\xd9\x85\xbe\x2e\xca\xd4\x46\xd3\xba\x50\xa1\x40\ +\x99\x58\xb6\x8d\x56\x02\x2f\xe0\x1a\x2f\xe0\x1a\x2f\xe0\x1a\x2f\ +\xe0\x1a\x2f\xe0\x1a\x2f\xe0\x9a\x80\xe8\x04\xbc\xaa\x8c\x43\xa2\ +\xe3\xfb\xc6\xaf\xc5\x5a\xfc\xd9\x5a\x46\x92\xc7\xac\xbd\x90\x68\ +\xf6\xa0\x51\x70\x63\x59\xe9\x56\x7f\xd4\x20\x9e\xfa\x68\xc7\x0b\ +\x55\x61\x08\xb4\x45\x64\x24\x5f\x2b\xf1\x2f\xd1\xe1\x67\xdc\x66\ +\xcb\x51\xb8\x2c\xc6\xcc\x8f\xdb\xbc\x01\x7c\x02\x6d\x77\x23\xb3\ +\xd4\x95\x53\x76\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +\ +\x00\x00\x01\x76\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x30\x00\x00\x00\x30\x08\x06\x00\x00\x00\x57\x02\xf9\x87\ +\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\ +\x01\x00\x9a\x9c\x18\x00\x00\x01\x28\x49\x44\x41\x54\x68\x81\xed\ +\xda\xb1\x4a\xc3\x50\x14\x87\xf1\x2f\x37\xb7\xe0\xae\xf8\x00\x82\ +\x53\x75\xe8\xde\xc9\x6c\x79\x80\x40\x1f\x46\x87\xfa\x22\x6e\x42\ +\xdc\xb3\xc5\xa9\x2f\x20\xb4\x5d\x3a\x74\x0f\x7d\x82\x6a\xc1\xe1\ +\xa6\x50\xb3\x68\x10\xfa\xcf\x85\xf3\xdb\x52\x3a\x9c\xaf\xdc\x66\ +\x39\x37\xa1\x95\xe5\xc5\x15\xf0\x04\x4c\x81\x3b\x60\xc4\xb0\x7c\ +\x02\x4b\x60\x01\xcc\xeb\xaa\xdc\x01\x24\x00\x59\x5e\x3c\x00\xaf\ +\xc0\xb5\x6c\xbc\x7e\x1a\x60\x56\x57\xe5\x7b\xd2\xfe\xf2\x2b\xe2\ +\x19\xfe\xa8\x01\xc6\x8e\x70\x6c\x62\x1b\x1e\xc2\xcc\x8f\x9e\x70\ +\xe6\xbb\x0e\x67\x1e\xe6\xaf\xd2\xce\xf3\xd4\x13\xfe\xb0\xa7\x0e\ +\x75\x55\xfa\x33\x0d\xd4\x4b\x96\x17\x5f\xfc\x8c\xb8\x77\x0c\xef\ +\x6d\xd3\xc7\xc8\xa9\x27\xf8\x2f\x0b\x50\xb3\x00\x35\x0b\x50\xb3\ +\x00\x35\x0b\x50\xb3\x00\x35\x0b\x50\xb3\x00\x35\x0b\x50\xb3\x00\ +\x35\x0b\x50\xb3\x00\x35\x0b\x50\xb3\x00\x35\x0b\x50\xb3\x00\x35\ +\x0b\x50\x73\x84\x0d\x78\xac\xf6\x9e\xb0\xbe\x9f\x9c\x7c\x98\xb6\ +\xdb\xc0\x21\xea\xae\x59\x97\x9e\x70\xf7\x60\xf2\xcb\x17\x87\x6a\ +\xe1\x80\x39\x61\x6d\x1f\x9b\x06\x78\x76\xed\xad\x8f\x19\x71\x45\ +\x1c\x2f\x7b\xec\x52\x80\xed\x66\xb5\xbd\xb9\x1d\xbf\x00\x17\x84\ +\xc5\xf7\x25\xc3\x3b\x46\x7b\xe0\x03\x78\x03\x8a\xba\x2a\xd7\x00\ +\xdf\xa4\xb5\x36\xa2\xca\x99\x74\x47\x00\x00\x00\x00\x49\x45\x4e\ +\x44\xae\x42\x60\x82\ +\x00\x00\x00\xa0\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x06\x00\x00\x00\x09\x08\x04\x00\x00\x00\xbb\x93\x95\x16\ +\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x02\x62\x4b\x47\x44\x00\xff\x87\x8f\xcc\xbf\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\x08\x17\x14\x1f\x0d\xfc\ +\x52\x2b\x9c\x00\x00\x00\x24\x49\x44\x41\x54\x08\xd7\x63\x60\x40\ +\x05\x73\x3e\xc0\x58\x4c\xc8\x5c\x26\x64\x59\x26\x64\xc5\x70\x4e\ +\x8a\x00\x9c\x93\x22\x80\x61\x1a\x0a\x00\x00\x29\x95\x08\xaf\x88\ +\xac\xba\x34\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x05\x7e\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x01\x00\x00\x00\x01\x08\x06\x00\x00\x00\x1f\x15\xc4\x89\ +\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\ +\x01\x00\x9a\x9c\x18\x00\x00\x05\x17\x69\x54\x58\x74\x58\x4d\x4c\ +\x3a\x63\x6f\x6d\x2e\x61\x64\x6f\x62\x65\x2e\x78\x6d\x70\x00\x00\ +\x00\x00\x00\x3c\x3f\x78\x70\x61\x63\x6b\x65\x74\x20\x62\x65\x67\ +\x69\x6e\x3d\x22\xef\xbb\xbf\x22\x20\x69\x64\x3d\x22\x57\x35\x4d\ +\x30\x4d\x70\x43\x65\x68\x69\x48\x7a\x72\x65\x53\x7a\x4e\x54\x63\ +\x7a\x6b\x63\x39\x64\x22\x3f\x3e\x20\x3c\x78\x3a\x78\x6d\x70\x6d\ +\x65\x74\x61\x20\x78\x6d\x6c\x6e\x73\x3a\x78\x3d\x22\x61\x64\x6f\ +\x62\x65\x3a\x6e\x73\x3a\x6d\x65\x74\x61\x2f\x22\x20\x78\x3a\x78\ +\x6d\x70\x74\x6b\x3d\x22\x41\x64\x6f\x62\x65\x20\x58\x4d\x50\x20\ +\x43\x6f\x72\x65\x20\x37\x2e\x31\x2d\x63\x30\x30\x30\x20\x37\x39\ +\x2e\x37\x61\x37\x61\x32\x33\x36\x2c\x20\x32\x30\x32\x31\x2f\x30\ +\x38\x2f\x31\x32\x2d\x30\x30\x3a\x32\x35\x3a\x32\x30\x20\x20\x20\ +\x20\x20\x20\x20\x20\x22\x3e\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\ +\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\x68\x74\x74\x70\ +\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\ +\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\x2d\x73\x79\x6e\ +\x74\x61\x78\x2d\x6e\x73\x23\x22\x3e\x20\x3c\x72\x64\x66\x3a\x44\ +\x65\x73\x63\x72\x69\x70\x74\x69\x6f\x6e\x20\x72\x64\x66\x3a\x61\ +\x62\x6f\x75\x74\x3d\x22\x22\x20\x78\x6d\x6c\x6e\x73\x3a\x78\x6d\ +\x70\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x6e\x73\x2e\x61\x64\x6f\ +\x62\x65\x2e\x63\x6f\x6d\x2f\x78\x61\x70\x2f\x31\x2e\x30\x2f\x22\ +\x20\x78\x6d\x6c\x6e\x73\x3a\x64\x63\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x65\x6c\ +\x65\x6d\x65\x6e\x74\x73\x2f\x31\x2e\x31\x2f\x22\x20\x78\x6d\x6c\ +\x6e\x73\x3a\x78\x6d\x70\x4d\x4d\x3d\x22\x68\x74\x74\x70\x3a\x2f\ +\x2f\x6e\x73\x2e\x61\x64\x6f\x62\x65\x2e\x63\x6f\x6d\x2f\x78\x61\ +\x70\x2f\x31\x2e\x30\x2f\x6d\x6d\x2f\x22\x20\x78\x6d\x6c\x6e\x73\ +\x3a\x73\x74\x45\x76\x74\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x6e\ +\x73\x2e\x61\x64\x6f\x62\x65\x2e\x63\x6f\x6d\x2f\x78\x61\x70\x2f\ +\x31\x2e\x30\x2f\x73\x54\x79\x70\x65\x2f\x52\x65\x73\x6f\x75\x72\ +\x63\x65\x45\x76\x65\x6e\x74\x23\x22\x20\x78\x6d\x6c\x6e\x73\x3a\ +\x70\x68\x6f\x74\x6f\x73\x68\x6f\x70\x3d\x22\x68\x74\x74\x70\x3a\ +\x2f\x2f\x6e\x73\x2e\x61\x64\x6f\x62\x65\x2e\x63\x6f\x6d\x2f\x70\ +\x68\x6f\x74\x6f\x73\x68\x6f\x70\x2f\x31\x2e\x30\x2f\x22\x20\x78\ +\x6d\x70\x3a\x43\x72\x65\x61\x74\x6f\x72\x54\x6f\x6f\x6c\x3d\x22\ +\x41\x64\x6f\x62\x65\x20\x50\x68\x6f\x74\x6f\x73\x68\x6f\x70\x20\ +\x32\x32\x2e\x35\x20\x28\x57\x69\x6e\x64\x6f\x77\x73\x29\x22\x20\ +\x78\x6d\x70\x3a\x43\x72\x65\x61\x74\x65\x44\x61\x74\x65\x3d\x22\ +\x32\x30\x32\x31\x2d\x31\x31\x2d\x31\x30\x54\x31\x37\x3a\x33\x39\ +\x3a\x30\x32\x2b\x30\x31\x3a\x30\x30\x22\x20\x78\x6d\x70\x3a\x4d\ +\x65\x74\x61\x64\x61\x74\x61\x44\x61\x74\x65\x3d\x22\x32\x30\x32\ +\x31\x2d\x31\x31\x2d\x31\x30\x54\x31\x37\x3a\x33\x39\x3a\x30\x32\ +\x2b\x30\x31\x3a\x30\x30\x22\x20\x78\x6d\x70\x3a\x4d\x6f\x64\x69\ +\x66\x79\x44\x61\x74\x65\x3d\x22\x32\x30\x32\x31\x2d\x31\x31\x2d\ +\x31\x30\x54\x31\x37\x3a\x33\x39\x3a\x30\x32\x2b\x30\x31\x3a\x30\ +\x30\x22\x20\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3d\x22\x69\x6d\ +\x61\x67\x65\x2f\x70\x6e\x67\x22\x20\x78\x6d\x70\x4d\x4d\x3a\x49\ +\x6e\x73\x74\x61\x6e\x63\x65\x49\x44\x3d\x22\x78\x6d\x70\x2e\x69\ +\x69\x64\x3a\x66\x31\x37\x65\x62\x62\x32\x33\x2d\x65\x36\x32\x61\ +\x2d\x33\x39\x34\x36\x2d\x61\x39\x37\x35\x2d\x64\x34\x66\x36\x61\ +\x62\x34\x34\x64\x34\x30\x39\x22\x20\x78\x6d\x70\x4d\x4d\x3a\x44\ +\x6f\x63\x75\x6d\x65\x6e\x74\x49\x44\x3d\x22\x78\x6d\x70\x2e\x64\ +\x69\x64\x3a\x66\x31\x37\x65\x62\x62\x32\x33\x2d\x65\x36\x32\x61\ +\x2d\x33\x39\x34\x36\x2d\x61\x39\x37\x35\x2d\x64\x34\x66\x36\x61\ +\x62\x34\x34\x64\x34\x30\x39\x22\x20\x78\x6d\x70\x4d\x4d\x3a\x4f\ +\x72\x69\x67\x69\x6e\x61\x6c\x44\x6f\x63\x75\x6d\x65\x6e\x74\x49\ +\x44\x3d\x22\x78\x6d\x70\x2e\x64\x69\x64\x3a\x66\x31\x37\x65\x62\ +\x62\x32\x33\x2d\x65\x36\x32\x61\x2d\x33\x39\x34\x36\x2d\x61\x39\ +\x37\x35\x2d\x64\x34\x66\x36\x61\x62\x34\x34\x64\x34\x30\x39\x22\ +\x20\x70\x68\x6f\x74\x6f\x73\x68\x6f\x70\x3a\x43\x6f\x6c\x6f\x72\ +\x4d\x6f\x64\x65\x3d\x22\x33\x22\x20\x70\x68\x6f\x74\x6f\x73\x68\ +\x6f\x70\x3a\x49\x43\x43\x50\x72\x6f\x66\x69\x6c\x65\x3d\x22\x73\ +\x52\x47\x42\x20\x49\x45\x43\x36\x31\x39\x36\x36\x2d\x32\x2e\x31\ +\x22\x3e\x20\x3c\x78\x6d\x70\x4d\x4d\x3a\x48\x69\x73\x74\x6f\x72\ +\x79\x3e\x20\x3c\x72\x64\x66\x3a\x53\x65\x71\x3e\x20\x3c\x72\x64\ +\x66\x3a\x6c\x69\x20\x73\x74\x45\x76\x74\x3a\x61\x63\x74\x69\x6f\ +\x6e\x3d\x22\x63\x72\x65\x61\x74\x65\x64\x22\x20\x73\x74\x45\x76\ +\x74\x3a\x69\x6e\x73\x74\x61\x6e\x63\x65\x49\x44\x3d\x22\x78\x6d\ +\x70\x2e\x69\x69\x64\x3a\x66\x31\x37\x65\x62\x62\x32\x33\x2d\x65\ +\x36\x32\x61\x2d\x33\x39\x34\x36\x2d\x61\x39\x37\x35\x2d\x64\x34\ +\x66\x36\x61\x62\x34\x34\x64\x34\x30\x39\x22\x20\x73\x74\x45\x76\ +\x74\x3a\x77\x68\x65\x6e\x3d\x22\x32\x30\x32\x31\x2d\x31\x31\x2d\ +\x31\x30\x54\x31\x37\x3a\x33\x39\x3a\x30\x32\x2b\x30\x31\x3a\x30\ +\x30\x22\x20\x73\x74\x45\x76\x74\x3a\x73\x6f\x66\x74\x77\x61\x72\ +\x65\x41\x67\x65\x6e\x74\x3d\x22\x41\x64\x6f\x62\x65\x20\x50\x68\ +\x6f\x74\x6f\x73\x68\x6f\x70\x20\x32\x32\x2e\x35\x20\x28\x57\x69\ +\x6e\x64\x6f\x77\x73\x29\x22\x2f\x3e\x20\x3c\x2f\x72\x64\x66\x3a\ +\x53\x65\x71\x3e\x20\x3c\x2f\x78\x6d\x70\x4d\x4d\x3a\x48\x69\x73\ +\x74\x6f\x72\x79\x3e\x20\x3c\x2f\x72\x64\x66\x3a\x44\x65\x73\x63\ +\x72\x69\x70\x74\x69\x6f\x6e\x3e\x20\x3c\x2f\x72\x64\x66\x3a\x52\ +\x44\x46\x3e\x20\x3c\x2f\x78\x3a\x78\x6d\x70\x6d\x65\x74\x61\x3e\ +\x20\x3c\x3f\x78\x70\x61\x63\x6b\x65\x74\x20\x65\x6e\x64\x3d\x22\ +\x72\x22\x3f\x3e\x07\x62\x0c\x81\x00\x00\x00\x0d\x49\x44\x41\x54\ +\x08\x1d\x63\xf8\xff\xff\x3f\x03\x00\x08\xfc\x02\xfe\xe6\x0c\xff\ +\xab\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x00\x9f\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce\x7c\x4e\ +\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x02\x62\x4b\x47\x44\x00\xff\x87\x8f\xcc\xbf\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\x08\x17\x08\x14\x1f\xf9\ +\x23\xd9\x0b\x00\x00\x00\x23\x49\x44\x41\x54\x08\xd7\x63\x60\xc0\ +\x0d\xe6\x7c\x80\xb1\x18\x91\x05\x52\x04\xe0\x42\x08\x15\x29\x02\ +\x0c\x0c\x8c\xc8\x02\x08\x95\x68\x00\x00\xac\xac\x07\x90\x4e\x65\ +\x34\xac\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x00\xa0\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x06\x00\x00\x00\x09\x08\x04\x00\x00\x00\xbb\x93\x95\x16\ +\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x02\x62\x4b\x47\x44\x00\xff\x87\x8f\xcc\xbf\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\x08\x17\x14\x1c\x1f\x24\ +\xc6\x09\x17\x00\x00\x00\x24\x49\x44\x41\x54\x08\xd7\x63\x60\x40\ +\x05\xff\xcf\xc3\x58\x4c\xc8\x5c\x26\x64\x59\x26\x64\xc5\x70\x0e\ +\xa3\x21\x9c\xc3\x68\x88\x61\x1a\x0a\x00\x00\x6d\x84\x09\x75\x37\ +\x9e\xd9\x23\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x00\xa6\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x06\x00\x00\x00\x09\x08\x04\x00\x00\x00\xbb\x93\x95\x16\ +\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x02\x62\x4b\x47\x44\x00\xff\x87\x8f\xcc\xbf\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\x08\x17\x14\x1d\x00\xb0\ +\xd5\x35\xa3\x00\x00\x00\x2a\x49\x44\x41\x54\x08\xd7\x63\x60\xc0\ +\x06\xfe\x9f\x67\x60\x60\x42\x30\xa1\x1c\x08\x93\x81\x81\x09\xc1\ +\x64\x60\x60\x62\x60\x60\x34\x44\xe2\x20\x73\x19\x90\x8d\x40\x02\ +\x00\x64\x40\x09\x75\x86\xb3\xad\x9c\x00\x00\x00\x00\x49\x45\x4e\ +\x44\xae\x42\x60\x82\ +\x00\x00\x00\xa6\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce\x7c\x4e\ +\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x02\x62\x4b\x47\x44\x00\xff\x87\x8f\xcc\xbf\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\x08\x17\x08\x15\x3b\xdc\ +\x3b\x0c\x9b\x00\x00\x00\x2a\x49\x44\x41\x54\x08\xd7\x63\x60\xc0\ +\x00\x8c\x0c\x0c\x73\x3e\x20\x0b\xa4\x08\x30\x32\x30\x20\x0b\xa6\ +\x08\x30\x30\x30\x42\x98\x10\xc1\x14\x01\x14\x13\x50\xb5\xa3\x01\ +\x00\xc6\xb9\x07\x90\x5d\x66\x1f\x83\x00\x00\x00\x00\x49\x45\x4e\ +\x44\xae\x42\x60\x82\ +\x00\x00\x03\xff\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x30\x00\x00\x00\x30\x08\x06\x00\x00\x00\x57\x02\xf9\x87\ +\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\ +\x01\x00\x9a\x9c\x18\x00\x00\x03\xb1\x49\x44\x41\x54\x68\x81\xed\ +\x9a\x4f\x68\x1e\x45\x18\xc6\x7f\x9b\x26\x85\x82\x15\x15\xab\x42\ +\xcb\x03\x06\x05\xa9\x0a\x8a\xb7\x52\x3c\xd4\x96\xaa\xb5\xe0\x41\ +\xad\xc5\x43\x25\xa0\x07\x51\xcc\x4d\x28\xb4\x07\x45\x3c\x78\xb0\ +\xa0\x52\x50\x0f\x8a\x50\xf5\x50\xa5\x28\xc6\xbf\xa8\x34\x20\x08\ +\x9e\x4c\x41\xc5\x83\x3c\x20\xd2\x90\x2a\x0a\xfe\x69\x92\x3a\x1e\ +\x66\x8d\x5f\xd6\xdd\x9d\xfd\xf6\x8b\xd9\x2f\xd0\xdf\xed\x9b\x79\ +\xe7\x9d\xe7\x9d\xd9\x99\x79\x67\xbf\xcd\xc8\x09\x21\x5c\x0a\x1c\ +\x06\xb6\x03\xd7\x01\x63\x0c\x17\x0b\xc0\x0c\x30\x0d\x3c\x9e\x65\ +\xd9\xdc\x52\x4d\x08\x61\x47\x08\xe1\x74\x58\x3b\x9c\x0e\x21\xec\ +\x00\xc8\x42\x1c\xf9\x53\xc0\x65\x5d\x0c\xeb\x00\xcc\x02\xd7\x8e\ +\x10\x1f\x9b\xb5\x26\x1e\xa2\xe6\x43\xa3\xc4\x67\xbe\xc8\xb9\x55\ +\x16\xd3\x94\x75\x85\xdf\xdb\xb3\x10\xc2\x3c\xcb\x17\xec\xb9\x2c\ +\xcb\x46\x57\x51\x54\x63\x42\x08\x8b\x2c\x0f\x62\x61\x84\xe1\xdb\ +\x6d\xfa\x61\x6c\xa4\x6b\x05\x83\x72\x3e\x80\xae\x39\x1f\xc0\xff\ +\x81\xed\xbb\x6d\xbf\x66\x7b\x57\xca\x36\x0b\x21\x84\x42\x59\xa7\ +\xdb\xa8\xed\x47\x81\x23\xf9\xcf\x00\x1c\x05\x26\x25\x2d\x94\x6c\ +\xa3\xc3\x35\x03\xb6\xef\x05\x9e\xe9\x29\xca\x80\x87\x80\x17\xab\ +\xda\x0c\xcd\x81\x65\x7b\x27\xf0\x0a\x51\x74\x91\x03\xb6\xbf\x2a\ +\x6b\x37\x14\x33\x60\xfb\x26\xe0\x4d\x60\x7d\x8d\xd9\x6d\x65\x85\ +\x9d\x07\x60\xfb\x2a\xe0\x5d\x60\x63\xc2\xf4\xa5\xb2\xc2\x4e\x03\ +\xb0\x7d\x39\xf0\x3e\xe9\x6c\xf8\x69\x49\xaf\x97\x55\x74\x16\x80\ +\xed\x8d\xc0\x14\x30\x9e\x30\x7d\x15\x78\xac\xaa\xb2\x93\x00\x6c\ +\xaf\x07\xde\x02\x6e\x4c\x98\xbe\x07\x4c\x48\x2a\x6e\xf5\x4b\xac\ +\x7a\x00\xb6\x47\x88\xa3\x7a\x4b\xc2\xf4\x0b\xe0\x2e\x49\x8b\x75\ +\x46\x5d\xcc\xc0\x11\xe0\x9e\x84\xcd\xb7\xc0\x1e\x49\xbf\xa5\x9c\ +\x35\x0a\xc0\x76\x96\x8f\xdc\x40\xd8\x3e\x08\x3c\x92\x30\xfb\x11\ +\xd8\x2d\x69\x2e\x61\x07\x24\x02\xc8\x85\x4f\x02\x7f\x00\x33\xb6\ +\xaf\x6f\xa4\xb4\xdc\xd7\x04\xf0\x64\xc2\xec\x17\xe0\x56\x49\xdf\ +\x37\xf5\x5b\x99\x0b\xd9\x1e\x03\x8e\x03\x7b\x7b\xea\x66\x81\x9b\ +\x25\x7d\xd3\xb4\x03\x00\xdb\x7b\x89\x8b\xb6\x78\xa7\xed\xe5\x2c\ +\x71\xe4\x3f\xab\x32\xe8\x37\x17\x7a\x8e\xe5\xe2\x21\xee\xd7\x1f\ +\xdb\xbe\xb2\x56\x71\x0f\xb6\xb7\x01\x6f\x14\x3b\x2e\xf0\x17\x70\ +\x5f\x9d\xf8\x2a\x4a\x03\xc8\x47\xec\xc1\x8a\x36\x9b\x81\x8f\x6c\ +\x6f\x4e\x39\xb7\xbd\x15\x78\x1b\xd8\x90\x30\x7d\x58\xd2\xf1\x94\ +\xbf\x32\xaa\x66\xe0\x92\x44\xbb\x71\x62\x10\x9b\xaa\x0c\x6c\x6f\ +\x21\x9e\xb2\x29\x5f\x4f\x48\x3a\x9a\xb0\xa9\xa4\x2a\x80\x63\xc4\ +\x7d\xb8\x8e\x6b\x80\x0f\x6c\x5f\x54\xac\xb0\x7d\x31\x51\xfc\x96\ +\x84\x8f\x17\x24\x1d\x4e\xaa\xac\xa1\x34\x00\x49\x0b\xc4\xec\xaf\ +\x34\x85\xed\xe1\x06\x60\xca\xf6\x05\xff\x14\xd8\xde\x40\x7c\x6c\ +\xb6\x26\xda\x9e\x20\xe6\xfa\x03\x51\x7b\x23\xcb\x93\xad\x93\xc0\ +\xd5\x09\x3f\x9f\x02\xb7\x03\xf3\xc4\xdd\xa6\xb8\xf8\x8b\x4c\x03\ +\xbb\x24\xfd\xd9\x8f\xd8\xb2\x5d\x28\x79\xa5\xb4\x2d\x62\x10\x4a\ +\xf8\x9f\x22\x1e\x42\x13\x09\xbb\x19\xe2\x56\xfc\x73\x23\xd5\x3d\ +\xb4\x0a\x00\x96\x72\xf6\x93\xc0\x15\xfd\x76\x5a\xc0\xc0\x36\x49\ +\x3f\xb4\x69\xdc\xfa\x4e\x2c\xe9\x3b\x60\x27\x70\xa6\x4d\xc7\x39\ +\x3f\x11\x0f\xaa\x56\xe2\xab\x68\x9c\xdf\x48\x3a\x05\xec\x06\x7e\ +\x6d\xd1\xcf\xef\xc0\x1d\x92\xbe\x6e\xd1\xb6\x96\xbe\x12\x34\x49\ +\x5f\x02\x7b\x72\x41\x4d\x59\x04\xf6\x49\xfa\xbc\x9f\xbe\x9a\xd2\ +\x77\x86\x29\x69\x1a\xb8\x93\x98\xbb\x34\xe1\x01\x49\xef\xf4\xdb\ +\x4f\x53\x5a\xa5\xc8\x92\x3e\x04\xf6\x11\x47\xb7\x8e\x83\x92\x5e\ +\x6e\xd3\x47\x53\x5a\xe7\xf8\x92\x4e\x00\x07\x88\x89\x58\x19\xcf\ +\x4a\x7a\xaa\xad\xff\xa6\x0c\x74\x49\x91\x74\x0c\xb8\x9f\xff\xae\ +\x89\xe7\x81\xc9\x41\x7c\x37\x65\x45\xde\x8d\xda\x1e\x27\x9e\xbe\ +\x17\x02\x9f\xe4\xeb\x64\xc5\x69\x7d\x90\x0d\x0b\x55\x07\xd9\x42\ +\x37\x72\x56\x84\xf9\x51\x62\x6e\xd2\xfb\x7e\x66\x5d\x1e\xe9\x30\ +\x52\xbc\xd5\xcd\x8c\x12\x33\xc3\xe2\x0b\xa6\xba\xeb\xdf\x30\x31\ +\xbd\xf6\x3f\x35\xc8\xbf\xfa\xd8\x9f\x17\xac\x15\x66\x81\xfd\x59\ +\x96\xcd\x2d\xfd\x99\x90\xcf\xc4\x21\xfe\xfd\xdc\xa6\xee\x5d\x7d\ +\x17\xcc\xb3\xfc\x73\x9b\x33\x00\x7f\x03\xd9\x1a\xfb\xdb\xbb\xa7\ +\x8f\x07\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ " qt_resource_name = b"\ @@ -1202,145 +1286,79 @@ qt_resource_name = b"\ \x07\x03\x7d\xc3\ \x00\x69\ \x00\x6d\x00\x61\x00\x67\x00\x65\x00\x73\ -\x00\x23\ -\x06\xf2\x1a\x47\ -\x00\x63\ -\x00\x68\x00\x65\x00\x63\x00\x6b\x00\x62\x00\x6f\x00\x78\x00\x5f\x00\x69\x00\x6e\x00\x64\x00\x65\x00\x74\x00\x65\x00\x72\x00\x6d\ -\x00\x69\x00\x6e\x00\x61\x00\x74\x00\x65\x00\x5f\x00\x64\x00\x69\x00\x73\x00\x61\x00\x62\x00\x6c\x00\x65\x00\x64\x00\x2e\x00\x70\ -\x00\x6e\x00\x67\ -\x00\x12\ -\x01\x2e\x03\x27\ -\x00\x63\ -\x00\x6f\x00\x6d\x00\x62\x00\x6f\x00\x62\x00\x6f\x00\x78\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2e\x00\x70\x00\x6e\ -\x00\x67\ -\x00\x14\ -\x07\xec\xd1\xc7\ -\x00\x63\ -\x00\x68\x00\x65\x00\x63\x00\x6b\x00\x62\x00\x6f\x00\x78\x00\x5f\x00\x63\x00\x68\x00\x65\x00\x63\x00\x6b\x00\x65\x00\x64\x00\x2e\ -\x00\x70\x00\x6e\x00\x67\ -\x00\x15\ -\x0f\xf3\xc0\x07\ -\x00\x75\ -\x00\x70\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x5f\x00\x64\x00\x69\x00\x73\x00\x61\x00\x62\x00\x6c\x00\x65\x00\x64\ -\x00\x2e\x00\x70\x00\x6e\x00\x67\ \x00\x11\ \x0b\xda\x30\xa7\ \x00\x62\ \x00\x72\x00\x61\x00\x6e\x00\x63\x00\x68\x00\x5f\x00\x63\x00\x6c\x00\x6f\x00\x73\x00\x65\x00\x64\x00\x2e\x00\x70\x00\x6e\x00\x67\ \ -\x00\x20\ -\x0f\xd4\x1b\xc7\ -\x00\x63\ -\x00\x68\x00\x65\x00\x63\x00\x6b\x00\x62\x00\x6f\x00\x78\x00\x5f\x00\x69\x00\x6e\x00\x64\x00\x65\x00\x74\x00\x65\x00\x72\x00\x6d\ -\x00\x69\x00\x6e\x00\x61\x00\x74\x00\x65\x00\x5f\x00\x68\x00\x6f\x00\x76\x00\x65\x00\x72\x00\x2e\x00\x70\x00\x6e\x00\x67\ -\x00\x1a\ -\x05\x11\xe0\xe7\ -\x00\x63\ -\x00\x68\x00\x65\x00\x63\x00\x6b\x00\x62\x00\x6f\x00\x78\x00\x5f\x00\x63\x00\x68\x00\x65\x00\x63\x00\x6b\x00\x65\x00\x64\x00\x5f\ -\x00\x66\x00\x6f\x00\x63\x00\x75\x00\x73\x00\x2e\x00\x70\x00\x6e\x00\x67\ -\x00\x1a\ -\x03\x0e\xe4\x87\ -\x00\x63\ -\x00\x68\x00\x65\x00\x63\x00\x6b\x00\x62\x00\x6f\x00\x78\x00\x5f\x00\x63\x00\x68\x00\x65\x00\x63\x00\x6b\x00\x65\x00\x64\x00\x5f\ -\x00\x68\x00\x6f\x00\x76\x00\x65\x00\x72\x00\x2e\x00\x70\x00\x6e\x00\x67\ -\x00\x1c\ -\x0e\x3c\xde\x07\ -\x00\x63\ -\x00\x68\x00\x65\x00\x63\x00\x6b\x00\x62\x00\x6f\x00\x78\x00\x5f\x00\x75\x00\x6e\x00\x63\x00\x68\x00\x65\x00\x63\x00\x6b\x00\x65\ -\x00\x64\x00\x5f\x00\x68\x00\x6f\x00\x76\x00\x65\x00\x72\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x0f\ +\x06\x53\x25\xa7\ +\x00\x62\ +\x00\x72\x00\x61\x00\x6e\x00\x63\x00\x68\x00\x5f\x00\x6f\x00\x70\x00\x65\x00\x6e\x00\x2e\x00\x70\x00\x6e\x00\x67\ \x00\x1a\ \x01\x87\xae\x67\ \x00\x63\ \x00\x68\x00\x65\x00\x63\x00\x6b\x00\x62\x00\x6f\x00\x78\x00\x5f\x00\x69\x00\x6e\x00\x64\x00\x65\x00\x74\x00\x65\x00\x72\x00\x6d\ \x00\x69\x00\x6e\x00\x61\x00\x74\x00\x65\x00\x2e\x00\x70\x00\x6e\x00\x67\ -\x00\x17\ -\x0c\xab\x51\x07\ -\x00\x64\ -\x00\x6f\x00\x77\x00\x6e\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x5f\x00\x64\x00\x69\x00\x73\x00\x61\x00\x62\x00\x6c\ -\x00\x65\x00\x64\x00\x2e\x00\x70\x00\x6e\x00\x67\ -\x00\x0f\ -\x06\x53\x25\xa7\ -\x00\x62\ -\x00\x72\x00\x61\x00\x6e\x00\x63\x00\x68\x00\x5f\x00\x6f\x00\x70\x00\x65\x00\x6e\x00\x2e\x00\x70\x00\x6e\x00\x67\ -\x00\x17\ -\x0c\x65\xce\x07\ -\x00\x6c\ -\x00\x65\x00\x66\x00\x74\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x5f\x00\x64\x00\x69\x00\x73\x00\x61\x00\x62\x00\x6c\ -\x00\x65\x00\x64\x00\x2e\x00\x70\x00\x6e\x00\x67\ -\x00\x0e\ -\x04\xa2\xfc\xa7\ -\x00\x64\ -\x00\x6f\x00\x77\x00\x6e\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2e\x00\x70\x00\x6e\x00\x67\ -\x00\x1d\ -\x09\x07\x81\x07\ -\x00\x63\ -\x00\x68\x00\x65\x00\x63\x00\x6b\x00\x62\x00\x6f\x00\x78\x00\x5f\x00\x63\x00\x68\x00\x65\x00\x63\x00\x6b\x00\x65\x00\x64\x00\x5f\ -\x00\x64\x00\x69\x00\x73\x00\x61\x00\x62\x00\x6c\x00\x65\x00\x64\x00\x2e\x00\x70\x00\x6e\x00\x67\ \x00\x20\ -\x09\xd7\x1f\xa7\ +\x0f\xd4\x1b\xc7\ \x00\x63\ \x00\x68\x00\x65\x00\x63\x00\x6b\x00\x62\x00\x6f\x00\x78\x00\x5f\x00\x69\x00\x6e\x00\x64\x00\x65\x00\x74\x00\x65\x00\x72\x00\x6d\ -\x00\x69\x00\x6e\x00\x61\x00\x74\x00\x65\x00\x5f\x00\x66\x00\x6f\x00\x63\x00\x75\x00\x73\x00\x2e\x00\x70\x00\x6e\x00\x67\ -\x00\x0f\ -\x0c\xe2\x68\x67\ -\x00\x74\ -\x00\x72\x00\x61\x00\x6e\x00\x73\x00\x70\x00\x61\x00\x72\x00\x65\x00\x6e\x00\x74\x00\x2e\x00\x70\x00\x6e\x00\x67\ -\x00\x0e\ -\x0e\xde\xfa\xc7\ -\x00\x6c\ -\x00\x65\x00\x66\x00\x74\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2e\x00\x70\x00\x6e\x00\x67\ -\x00\x11\ -\x00\xb8\x8c\x07\ -\x00\x6c\ -\x00\x65\x00\x66\x00\x74\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x5f\x00\x6f\x00\x6e\x00\x2e\x00\x70\x00\x6e\x00\x67\ -\ -\x00\x1f\ -\x0a\xae\x27\x47\ -\x00\x63\ -\x00\x68\x00\x65\x00\x63\x00\x6b\x00\x62\x00\x6f\x00\x78\x00\x5f\x00\x75\x00\x6e\x00\x63\x00\x68\x00\x65\x00\x63\x00\x6b\x00\x65\ -\x00\x64\x00\x5f\x00\x64\x00\x69\x00\x73\x00\x61\x00\x62\x00\x6c\x00\x65\x00\x64\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x69\x00\x6e\x00\x61\x00\x74\x00\x65\x00\x5f\x00\x68\x00\x6f\x00\x76\x00\x65\x00\x72\x00\x2e\x00\x70\x00\x6e\x00\x67\ \x00\x1b\ \x03\x5a\x32\x27\ \x00\x63\ \x00\x6f\x00\x6d\x00\x62\x00\x6f\x00\x62\x00\x6f\x00\x78\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x5f\x00\x64\x00\x69\ \x00\x73\x00\x61\x00\x62\x00\x6c\x00\x65\x00\x64\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x0f\ +\x02\x9f\x05\x87\ +\x00\x72\ +\x00\x69\x00\x67\x00\x68\x00\x74\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x0e\ +\x04\xa2\xfc\xa7\ +\x00\x64\ +\x00\x6f\x00\x77\x00\x6e\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x1c\ +\x0e\x3c\xde\x07\ +\x00\x63\ +\x00\x68\x00\x65\x00\x63\x00\x6b\x00\x62\x00\x6f\x00\x78\x00\x5f\x00\x75\x00\x6e\x00\x63\x00\x68\x00\x65\x00\x63\x00\x6b\x00\x65\ +\x00\x64\x00\x5f\x00\x68\x00\x6f\x00\x76\x00\x65\x00\x72\x00\x2e\x00\x70\x00\x6e\x00\x67\ \x00\x12\ -\x05\x8f\x9d\x07\ -\x00\x62\ -\x00\x72\x00\x61\x00\x6e\x00\x63\x00\x68\x00\x5f\x00\x6f\x00\x70\x00\x65\x00\x6e\x00\x5f\x00\x6f\x00\x6e\x00\x2e\x00\x70\x00\x6e\ +\x01\x2e\x03\x27\ +\x00\x63\ +\x00\x6f\x00\x6d\x00\x62\x00\x6f\x00\x62\x00\x6f\x00\x78\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2e\x00\x70\x00\x6e\ \x00\x67\ \x00\x15\ \x03\x27\x72\x67\ \x00\x63\ \x00\x6f\x00\x6d\x00\x62\x00\x6f\x00\x62\x00\x6f\x00\x78\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x5f\x00\x6f\x00\x6e\ \x00\x2e\x00\x70\x00\x6e\x00\x67\ -\x00\x0f\ -\x01\x73\x8b\x07\ -\x00\x75\ -\x00\x70\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x5f\x00\x6f\x00\x6e\x00\x2e\x00\x70\x00\x6e\x00\x67\ -\x00\x11\ -\x01\x1f\xc3\x87\ -\x00\x64\ -\x00\x6f\x00\x77\x00\x6e\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x5f\x00\x6f\x00\x6e\x00\x2e\x00\x70\x00\x6e\x00\x67\ -\ +\x00\x1d\ +\x09\x07\x81\x07\ +\x00\x63\ +\x00\x68\x00\x65\x00\x63\x00\x6b\x00\x62\x00\x6f\x00\x78\x00\x5f\x00\x63\x00\x68\x00\x65\x00\x63\x00\x6b\x00\x65\x00\x64\x00\x5f\ +\x00\x64\x00\x69\x00\x73\x00\x61\x00\x62\x00\x6c\x00\x65\x00\x64\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x23\ +\x06\xf2\x1a\x47\ +\x00\x63\ +\x00\x68\x00\x65\x00\x63\x00\x6b\x00\x62\x00\x6f\x00\x78\x00\x5f\x00\x69\x00\x6e\x00\x64\x00\x65\x00\x74\x00\x65\x00\x72\x00\x6d\ +\x00\x69\x00\x6e\x00\x61\x00\x74\x00\x65\x00\x5f\x00\x64\x00\x69\x00\x73\x00\x61\x00\x62\x00\x6c\x00\x65\x00\x64\x00\x2e\x00\x70\ +\x00\x6e\x00\x67\ +\x00\x17\ +\x0c\x65\xce\x07\ +\x00\x6c\ +\x00\x65\x00\x66\x00\x74\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x5f\x00\x64\x00\x69\x00\x73\x00\x61\x00\x62\x00\x6c\ +\x00\x65\x00\x64\x00\x2e\x00\x70\x00\x6e\x00\x67\ \x00\x12\ -\x03\x8d\x04\x47\ -\x00\x72\ -\x00\x69\x00\x67\x00\x68\x00\x74\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x5f\x00\x6f\x00\x6e\x00\x2e\x00\x70\x00\x6e\ +\x05\x8f\x9d\x07\ +\x00\x62\ +\x00\x72\x00\x61\x00\x6e\x00\x63\x00\x68\x00\x5f\x00\x6f\x00\x70\x00\x65\x00\x6e\x00\x5f\x00\x6f\x00\x6e\x00\x2e\x00\x70\x00\x6e\ \x00\x67\ -\x00\x0f\ -\x02\x9f\x05\x87\ -\x00\x72\ -\x00\x69\x00\x67\x00\x68\x00\x74\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2e\x00\x70\x00\x6e\x00\x67\ -\x00\x18\ -\x03\x8e\xde\x67\ -\x00\x72\ -\x00\x69\x00\x67\x00\x68\x00\x74\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x5f\x00\x64\x00\x69\x00\x73\x00\x61\x00\x62\ -\x00\x6c\x00\x65\x00\x64\x00\x2e\x00\x70\x00\x6e\x00\x67\ -\x00\x0c\ -\x06\xe6\xe6\x67\ -\x00\x75\ -\x00\x70\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x14\ +\x07\xec\xd1\xc7\ +\x00\x63\ +\x00\x68\x00\x65\x00\x63\x00\x6b\x00\x62\x00\x6f\x00\x78\x00\x5f\x00\x63\x00\x68\x00\x65\x00\x63\x00\x6b\x00\x65\x00\x64\x00\x2e\ +\x00\x70\x00\x6e\x00\x67\ \x00\x16\ \x01\x75\xcc\x87\ \x00\x63\ @@ -1351,49 +1369,115 @@ qt_resource_name = b"\ \x00\x62\ \x00\x72\x00\x61\x00\x6e\x00\x63\x00\x68\x00\x5f\x00\x63\x00\x6c\x00\x6f\x00\x73\x00\x65\x00\x64\x00\x5f\x00\x6f\x00\x6e\x00\x2e\ \x00\x70\x00\x6e\x00\x67\ +\x00\x0f\ +\x01\x73\x8b\x07\ +\x00\x75\ +\x00\x70\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x5f\x00\x6f\x00\x6e\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x11\ +\x00\xb8\x8c\x07\ +\x00\x6c\ +\x00\x65\x00\x66\x00\x74\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x5f\x00\x6f\x00\x6e\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\ +\x00\x11\ +\x01\x1f\xc3\x87\ +\x00\x64\ +\x00\x6f\x00\x77\x00\x6e\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x5f\x00\x6f\x00\x6e\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\ +\x00\x0c\ +\x06\xe6\xe6\x67\ +\x00\x75\ +\x00\x70\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2e\x00\x70\x00\x6e\x00\x67\ \x00\x1c\ \x08\x3f\xda\x67\ \x00\x63\ \x00\x68\x00\x65\x00\x63\x00\x6b\x00\x62\x00\x6f\x00\x78\x00\x5f\x00\x75\x00\x6e\x00\x63\x00\x68\x00\x65\x00\x63\x00\x6b\x00\x65\ \x00\x64\x00\x5f\x00\x66\x00\x6f\x00\x63\x00\x75\x00\x73\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x1a\ +\x03\x0e\xe4\x87\ +\x00\x63\ +\x00\x68\x00\x65\x00\x63\x00\x6b\x00\x62\x00\x6f\x00\x78\x00\x5f\x00\x63\x00\x68\x00\x65\x00\x63\x00\x6b\x00\x65\x00\x64\x00\x5f\ +\x00\x68\x00\x6f\x00\x76\x00\x65\x00\x72\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x20\ +\x09\xd7\x1f\xa7\ +\x00\x63\ +\x00\x68\x00\x65\x00\x63\x00\x6b\x00\x62\x00\x6f\x00\x78\x00\x5f\x00\x69\x00\x6e\x00\x64\x00\x65\x00\x74\x00\x65\x00\x72\x00\x6d\ +\x00\x69\x00\x6e\x00\x61\x00\x74\x00\x65\x00\x5f\x00\x66\x00\x6f\x00\x63\x00\x75\x00\x73\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x1f\ +\x0a\xae\x27\x47\ +\x00\x63\ +\x00\x68\x00\x65\x00\x63\x00\x6b\x00\x62\x00\x6f\x00\x78\x00\x5f\x00\x75\x00\x6e\x00\x63\x00\x68\x00\x65\x00\x63\x00\x6b\x00\x65\ +\x00\x64\x00\x5f\x00\x64\x00\x69\x00\x73\x00\x61\x00\x62\x00\x6c\x00\x65\x00\x64\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x18\ +\x03\x8e\xde\x67\ +\x00\x72\ +\x00\x69\x00\x67\x00\x68\x00\x74\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x5f\x00\x64\x00\x69\x00\x73\x00\x61\x00\x62\ +\x00\x6c\x00\x65\x00\x64\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x0f\ +\x0c\xe2\x68\x67\ +\x00\x74\ +\x00\x72\x00\x61\x00\x6e\x00\x73\x00\x70\x00\x61\x00\x72\x00\x65\x00\x6e\x00\x74\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x15\ +\x0f\xf3\xc0\x07\ +\x00\x75\ +\x00\x70\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x5f\x00\x64\x00\x69\x00\x73\x00\x61\x00\x62\x00\x6c\x00\x65\x00\x64\ +\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x12\ +\x03\x8d\x04\x47\ +\x00\x72\ +\x00\x69\x00\x67\x00\x68\x00\x74\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x5f\x00\x6f\x00\x6e\x00\x2e\x00\x70\x00\x6e\ +\x00\x67\ +\x00\x0e\ +\x0e\xde\xfa\xc7\ +\x00\x6c\ +\x00\x65\x00\x66\x00\x74\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x17\ +\x0c\xab\x51\x07\ +\x00\x64\ +\x00\x6f\x00\x77\x00\x6e\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x5f\x00\x64\x00\x69\x00\x73\x00\x61\x00\x62\x00\x6c\ +\x00\x65\x00\x64\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x1a\ +\x05\x11\xe0\xe7\ +\x00\x63\ +\x00\x68\x00\x65\x00\x63\x00\x6b\x00\x62\x00\x6f\x00\x78\x00\x5f\x00\x63\x00\x68\x00\x65\x00\x63\x00\x6b\x00\x65\x00\x64\x00\x5f\ +\x00\x66\x00\x6f\x00\x63\x00\x75\x00\x73\x00\x2e\x00\x70\x00\x6e\x00\x67\ " qt_resource_struct_v1 = b"\ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\ \x00\x00\x00\x16\x00\x02\x00\x00\x00\x20\x00\x00\x00\x03\ -\x00\x00\x03\xd0\x00\x00\x00\x00\x00\x01\x00\x00\x2c\x6c\ -\x00\x00\x04\xf6\x00\x00\x00\x00\x00\x01\x00\x00\x37\xb9\ -\x00\x00\x00\x74\x00\x00\x00\x00\x00\x01\x00\x00\x02\x00\ -\x00\x00\x04\xd2\x00\x00\x00\x00\x00\x01\x00\x00\x37\x17\ -\x00\x00\x05\xc0\x00\x00\x00\x00\x00\x01\x00\x00\x3a\xf0\ -\x00\x00\x02\x1c\x00\x00\x00\x00\x00\x01\x00\x00\x1a\x76\ -\x00\x00\x05\x48\x00\x00\x00\x00\x00\x01\x00\x00\x39\x06\ -\x00\x00\x01\xa4\x00\x00\x00\x00\x00\x01\x00\x00\x14\xf3\ -\x00\x00\x04\xa2\x00\x00\x00\x00\x00\x01\x00\x00\x36\x6d\ -\x00\x00\x04\x3c\x00\x00\x00\x00\x00\x01\x00\x00\x2e\x90\ -\x00\x00\x05\x1e\x00\x00\x00\x00\x00\x01\x00\x00\x38\x62\ -\x00\x00\x05\x6c\x00\x00\x00\x00\x00\x01\x00\x00\x39\xaa\ -\x00\x00\x05\xf2\x00\x00\x00\x00\x00\x01\x00\x00\x3c\x4f\ -\x00\x00\x02\xe2\x00\x00\x00\x00\x00\x01\x00\x00\x24\xb4\ -\x00\x00\x01\x6a\x00\x00\x00\x00\x00\x01\x00\x00\x10\xf0\ -\x00\x00\x04\x78\x00\x00\x00\x00\x00\x01\x00\x00\x2f\x39\ -\x00\x00\x02\x8a\x00\x00\x00\x00\x00\x01\x00\x00\x1d\x00\ -\x00\x00\x05\xa2\x00\x00\x00\x00\x00\x01\x00\x00\x3a\x4e\ +\x00\x00\x03\xaa\x00\x00\x00\x00\x00\x01\x00\x00\x33\x3b\ +\x00\x00\x03\xd2\x00\x00\x00\x00\x00\x01\x00\x00\x33\xe5\ +\x00\x00\x01\xb4\x00\x00\x00\x00\x00\x01\x00\x00\x15\xf1\ +\x00\x00\x03\x86\x00\x00\x00\x00\x00\x01\x00\x00\x32\x99\ +\x00\x00\x03\x26\x00\x00\x00\x00\x00\x01\x00\x00\x29\x59\ +\x00\x00\x00\x74\x00\x00\x00\x00\x00\x01\x00\x00\x0e\xbb\ +\x00\x00\x01\x30\x00\x00\x00\x00\x00\x01\x00\x00\x13\x37\ +\x00\x00\x04\x56\x00\x00\x00\x00\x00\x01\x00\x00\x36\x8b\ +\x00\x00\x01\xde\x00\x00\x00\x00\x00\x01\x00\x00\x16\x9b\ +\x00\x00\x00\xf4\x00\x00\x00\x00\x00\x01\x00\x00\x12\x8e\ +\x00\x00\x05\xa4\x00\x00\x00\x00\x00\x01\x00\x00\x44\xc9\ +\x00\x00\x05\x1a\x00\x00\x00\x00\x00\x01\x00\x00\x3e\x00\ +\x00\x00\x03\x58\x00\x00\x00\x00\x00\x01\x00\x00\x2a\xb8\ +\x00\x00\x01\x54\x00\x00\x00\x00\x00\x01\x00\x00\x13\xdb\ +\x00\x00\x06\x24\x00\x00\x00\x00\x00\x01\x00\x00\x46\xc1\ +\x00\x00\x02\xce\x00\x00\x00\x00\x00\x01\x00\x00\x1e\x26\ +\x00\x00\x00\x50\x00\x00\x00\x00\x00\x01\x00\x00\x07\xb1\ +\x00\x00\x03\xfa\x00\x00\x00\x00\x00\x01\x00\x00\x34\x8e\ +\x00\x00\x02\x4e\x00\x00\x00\x00\x00\x01\x00\x00\x1b\x7c\ +\x00\x00\x02\xf8\x00\x00\x00\x00\x00\x01\x00\x00\x25\x5a\ +\x00\x00\x04\x18\x00\x00\x00\x00\x00\x01\x00\x00\x35\x30\ +\x00\x00\x02\x0e\x00\x00\x00\x00\x00\x01\x00\x00\x17\x45\ +\x00\x00\x04\x90\x00\x00\x00\x00\x00\x01\x00\x00\x3a\xa1\ +\x00\x00\x04\xd6\x00\x00\x00\x00\x00\x01\x00\x00\x3c\x86\ \x00\x00\x00\x28\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ -\x00\x00\x00\x9e\x00\x00\x00\x00\x00\x01\x00\x00\x02\xaa\ -\x00\x00\x06\x20\x00\x00\x00\x00\x00\x01\x00\x00\x44\x30\ -\x00\x00\x03\x04\x00\x00\x00\x00\x00\x01\x00\x00\x25\x5d\ -\x00\x00\x03\x44\x00\x00\x00\x00\x00\x01\x00\x00\x29\x94\ -\x00\x00\x03\xf8\x00\x00\x00\x00\x00\x01\x00\x00\x2d\x16\ -\x00\x00\x00\xfc\x00\x00\x00\x00\x00\x01\x00\x00\x07\x4c\ -\x00\x00\x02\xae\x00\x00\x00\x00\x00\x01\x00\x00\x24\x0a\ -\x00\x00\x02\x56\x00\x00\x00\x00\x00\x01\x00\x00\x1c\x56\ -\x00\x00\x03\x8a\x00\x00\x00\x00\x00\x01\x00\x00\x2b\x79\ -\x00\x00\x01\xde\x00\x00\x00\x00\x00\x01\x00\x00\x19\x09\ -\x00\x00\x03\xae\x00\x00\x00\x00\x00\x01\x00\x00\x2b\xc2\ -\x00\x00\x01\x24\x00\x00\x00\x00\x00\x01\x00\x00\x0e\xfd\ -\x00\x00\x00\xcc\x00\x00\x00\x00\x00\x01\x00\x00\x06\xa9\ +\x00\x00\x02\x9a\x00\x00\x00\x00\x00\x01\x00\x00\x1d\x7c\ +\x00\x00\x05\xf0\x00\x00\x00\x00\x00\x01\x00\x00\x46\x17\ +\x00\x00\x05\x50\x00\x00\x00\x00\x00\x01\x00\x00\x3e\xa4\ +\x00\x00\x01\x76\x00\x00\x00\x00\x00\x01\x00\x00\x14\x84\ +\x00\x00\x05\xce\x00\x00\x00\x00\x00\x01\x00\x00\x45\x6d\ +\x00\x00\x00\xae\x00\x00\x00\x00\x00\x01\x00\x00\x10\x9b\ +\x00\x00\x05\x74\x00\x00\x00\x00\x00\x01\x00\x00\x44\x26\ " qt_resource_struct_v2 = b"\ @@ -1403,72 +1487,73 @@ qt_resource_struct_v2 = b"\ \x00\x00\x00\x00\x00\x00\x00\x00\ \x00\x00\x00\x16\x00\x02\x00\x00\x00\x20\x00\x00\x00\x03\ \x00\x00\x00\x00\x00\x00\x00\x00\ -\x00\x00\x03\xd0\x00\x00\x00\x00\x00\x01\x00\x00\x2c\x6c\ -\x00\x00\x01\x79\xcb\xc2\x92\x54\ -\x00\x00\x04\xf6\x00\x00\x00\x00\x00\x01\x00\x00\x37\xb9\ -\x00\x00\x01\x79\xcb\xc2\x92\x49\ -\x00\x00\x00\x74\x00\x00\x00\x00\x00\x01\x00\x00\x02\x00\ -\x00\x00\x01\x79\xcb\xc2\x92\x46\ -\x00\x00\x04\xd2\x00\x00\x00\x00\x00\x01\x00\x00\x37\x17\ -\x00\x00\x01\x79\xcb\xc2\x92\x68\ -\x00\x00\x05\xc0\x00\x00\x00\x00\x00\x01\x00\x00\x3a\xf0\ -\x00\x00\x01\x7c\xf0\xa2\x65\xc4\ -\x00\x00\x02\x1c\x00\x00\x00\x00\x00\x01\x00\x00\x1a\x76\ -\x00\x00\x01\x7c\xf0\xa1\xd7\xf4\ -\x00\x00\x05\x48\x00\x00\x00\x00\x00\x01\x00\x00\x39\x06\ -\x00\x00\x01\x79\xcb\xc2\x92\x58\ -\x00\x00\x01\xa4\x00\x00\x00\x00\x00\x01\x00\x00\x14\xf3\ -\x00\x00\x01\x7c\xf0\xa3\x96\xef\ -\x00\x00\x04\xa2\x00\x00\x00\x00\x00\x01\x00\x00\x36\x6d\ -\x00\x00\x01\x79\xcb\xc2\x92\x47\ -\x00\x00\x04\x3c\x00\x00\x00\x00\x00\x01\x00\x00\x2e\x90\ -\x00\x00\x01\x79\xcb\xc2\x92\x47\ -\x00\x00\x05\x1e\x00\x00\x00\x00\x00\x01\x00\x00\x38\x62\ -\x00\x00\x01\x79\xcb\xc2\x92\x5e\ -\x00\x00\x05\x6c\x00\x00\x00\x00\x00\x01\x00\x00\x39\xaa\ -\x00\x00\x01\x79\xcb\xc2\x92\x5d\ -\x00\x00\x05\xf2\x00\x00\x00\x00\x00\x01\x00\x00\x3c\x4f\ -\x00\x00\x01\x79\xcb\xc2\x92\x3a\ -\x00\x00\x02\xe2\x00\x00\x00\x00\x00\x01\x00\x00\x24\xb4\ -\x00\x00\x01\x79\xcb\xc2\x92\x48\ -\x00\x00\x01\x6a\x00\x00\x00\x00\x00\x01\x00\x00\x10\xf0\ -\x00\x00\x01\x7c\xf0\xa3\xb9\x9b\ -\x00\x00\x04\x78\x00\x00\x00\x00\x00\x01\x00\x00\x2f\x39\ -\x00\x00\x01\x79\xcb\xc2\x92\x45\ -\x00\x00\x02\x8a\x00\x00\x00\x00\x00\x01\x00\x00\x1d\x00\ -\x00\x00\x01\x79\xcb\xc2\x92\x40\ -\x00\x00\x05\xa2\x00\x00\x00\x00\x00\x01\x00\x00\x3a\x4e\ -\x00\x00\x01\x79\xcb\xc2\x92\x63\ +\x00\x00\x03\xaa\x00\x00\x00\x00\x00\x01\x00\x00\x33\x3b\ +\x00\x00\x01\x7b\xe9\x78\x46\xdd\ +\x00\x00\x03\xd2\x00\x00\x00\x00\x00\x01\x00\x00\x33\xe5\ +\x00\x00\x01\x7b\xe9\x78\x46\xdb\ +\x00\x00\x01\xb4\x00\x00\x00\x00\x00\x01\x00\x00\x15\xf1\ +\x00\x00\x01\x7b\xe9\x78\x46\xd9\ +\x00\x00\x03\x86\x00\x00\x00\x00\x00\x01\x00\x00\x32\x99\ +\x00\x00\x01\x7b\xe9\x78\x46\xe0\ +\x00\x00\x03\x26\x00\x00\x00\x00\x00\x01\x00\x00\x29\x59\ +\x00\x00\x01\x7d\x0a\x8c\xfa\xc7\ +\x00\x00\x00\x74\x00\x00\x00\x00\x00\x01\x00\x00\x0e\xbb\ +\x00\x00\x01\x7d\x0a\x8c\xfa\xc5\ +\x00\x00\x01\x30\x00\x00\x00\x00\x00\x01\x00\x00\x13\x37\ +\x00\x00\x01\x7b\xe9\x78\x46\xdd\ +\x00\x00\x04\x56\x00\x00\x00\x00\x00\x01\x00\x00\x36\x8b\ +\x00\x00\x01\x7d\x0a\x8c\xfa\xc4\ +\x00\x00\x01\xde\x00\x00\x00\x00\x00\x01\x00\x00\x16\x9b\ +\x00\x00\x01\x7b\xe9\x78\x46\xda\ +\x00\x00\x00\xf4\x00\x00\x00\x00\x00\x01\x00\x00\x12\x8e\ +\x00\x00\x01\x7b\xe9\x78\x46\xd9\ +\x00\x00\x05\xa4\x00\x00\x00\x00\x00\x01\x00\x00\x44\xc9\ +\x00\x00\x01\x7b\xe9\x78\x46\xde\ +\x00\x00\x05\x1a\x00\x00\x00\x00\x00\x01\x00\x00\x3e\x00\ +\x00\x00\x01\x7b\xe9\x78\x46\xde\ +\x00\x00\x03\x58\x00\x00\x00\x00\x00\x01\x00\x00\x2a\xb8\ +\x00\x00\x01\x7b\xe9\x78\x46\xd7\ +\x00\x00\x01\x54\x00\x00\x00\x00\x00\x01\x00\x00\x13\xdb\ +\x00\x00\x01\x7b\xe9\x78\x46\xda\ +\x00\x00\x06\x24\x00\x00\x00\x00\x00\x01\x00\x00\x46\xc1\ +\x00\x00\x01\x7d\x0a\x8c\xfa\xc4\ +\x00\x00\x02\xce\x00\x00\x00\x00\x00\x01\x00\x00\x1e\x26\ +\x00\x00\x01\x7b\xe9\x78\x46\xd8\ +\x00\x00\x00\x50\x00\x00\x00\x00\x00\x01\x00\x00\x07\xb1\ +\x00\x00\x01\x7b\xe9\x78\x46\xd8\ +\x00\x00\x03\xfa\x00\x00\x00\x00\x00\x01\x00\x00\x34\x8e\ +\x00\x00\x01\x7b\xe9\x78\x46\xdf\ +\x00\x00\x02\x4e\x00\x00\x00\x00\x00\x01\x00\x00\x1b\x7c\ +\x00\x00\x01\x7d\x0a\x8c\xfa\xc5\ +\x00\x00\x02\xf8\x00\x00\x00\x00\x00\x01\x00\x00\x25\x5a\ +\x00\x00\x01\x7d\x0a\x8c\xfa\xc2\ +\x00\x00\x04\x18\x00\x00\x00\x00\x00\x01\x00\x00\x35\x30\ +\x00\x00\x01\x7d\x0a\x8c\xfa\xc8\ +\x00\x00\x02\x0e\x00\x00\x00\x00\x00\x01\x00\x00\x17\x45\ +\x00\x00\x01\x7d\x0a\x8c\xfa\xc3\ +\x00\x00\x04\x90\x00\x00\x00\x00\x00\x01\x00\x00\x3a\xa1\ +\x00\x00\x01\x7d\x0a\x8c\xfa\xc6\ +\x00\x00\x04\xd6\x00\x00\x00\x00\x00\x01\x00\x00\x3c\x86\ +\x00\x00\x01\x7d\x0a\x8c\xfa\xc7\ \x00\x00\x00\x28\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ -\x00\x00\x01\x7c\xf0\xa2\xf1\xbb\ -\x00\x00\x00\x9e\x00\x00\x00\x00\x00\x01\x00\x00\x02\xaa\ -\x00\x00\x01\x7c\xf0\xa3\xe3\x5c\ -\x00\x00\x06\x20\x00\x00\x00\x00\x00\x01\x00\x00\x44\x30\ -\x00\x00\x01\x7c\xf0\xa2\x42\xcc\ -\x00\x00\x03\x04\x00\x00\x00\x00\x00\x01\x00\x00\x25\x5d\ -\x00\x00\x01\x7c\xf0\xa3\x72\x55\ -\x00\x00\x03\x44\x00\x00\x00\x00\x00\x01\x00\x00\x29\x94\ -\x00\x00\x01\x7c\xf0\xa1\xba\x22\ -\x00\x00\x03\xf8\x00\x00\x00\x00\x00\x01\x00\x00\x2d\x16\ -\x00\x00\x01\x7c\xf0\xa3\x17\x26\ -\x00\x00\x00\xfc\x00\x00\x00\x00\x00\x01\x00\x00\x07\x4c\ -\x00\x00\x01\x79\xcb\xc2\x92\x34\ -\x00\x00\x02\xae\x00\x00\x00\x00\x00\x01\x00\x00\x24\x0a\ -\x00\x00\x01\x79\xcb\xc2\x92\x53\ -\x00\x00\x02\x56\x00\x00\x00\x00\x00\x01\x00\x00\x1c\x56\ -\x00\x00\x01\x79\xcb\xc2\x92\x48\ -\x00\x00\x03\x8a\x00\x00\x00\x00\x00\x01\x00\x00\x2b\x79\ -\x00\x00\x01\x7c\xe1\xd3\xcf\x43\ -\x00\x00\x01\xde\x00\x00\x00\x00\x00\x01\x00\x00\x19\x09\ -\x00\x00\x01\x7c\xf0\x9d\x46\x1e\ -\x00\x00\x03\xae\x00\x00\x00\x00\x00\x01\x00\x00\x2b\xc2\ -\x00\x00\x01\x79\xcb\xc2\x92\x4e\ -\x00\x00\x01\x24\x00\x00\x00\x00\x00\x01\x00\x00\x0e\xfd\ -\x00\x00\x01\x7c\xf0\xa1\x99\xa2\ -\x00\x00\x00\xcc\x00\x00\x00\x00\x00\x01\x00\x00\x06\xa9\ -\x00\x00\x01\x79\xcb\xc2\x92\x68\ +\x00\x00\x01\x7b\xe9\x78\x46\xd7\ +\x00\x00\x02\x9a\x00\x00\x00\x00\x00\x01\x00\x00\x1d\x7c\ +\x00\x00\x01\x7b\xe9\x78\x46\xdc\ +\x00\x00\x05\xf0\x00\x00\x00\x00\x00\x01\x00\x00\x46\x17\ +\x00\x00\x01\x7b\xe9\x78\x46\xdb\ +\x00\x00\x05\x50\x00\x00\x00\x00\x00\x01\x00\x00\x3e\xa4\ +\x00\x00\x01\x7d\x0a\xb7\x38\x27\ +\x00\x00\x01\x76\x00\x00\x00\x00\x00\x01\x00\x00\x14\x84\ +\x00\x00\x01\x7d\x0a\x8c\xfa\xc9\ +\x00\x00\x05\xce\x00\x00\x00\x00\x00\x01\x00\x00\x45\x6d\ +\x00\x00\x01\x7b\xe9\x78\x46\xdc\ +\x00\x00\x00\xae\x00\x00\x00\x00\x00\x01\x00\x00\x10\x9b\ +\x00\x00\x01\x7d\x0a\x8c\xfa\xc6\ +\x00\x00\x05\x74\x00\x00\x00\x00\x00\x01\x00\x00\x44\x26\ +\x00\x00\x01\x7b\xe9\x78\x46\xdf\ " + qt_version = [int(v) for v in QtCore.qVersion().split('.')] if qt_version < [5, 8, 0]: rcc_version = 1 diff --git a/openpype/style/pyside2_resources.py b/openpype/style/pyside2_resources.py index 6dd843a6ce..2aa84d04f1 100644 --- a/openpype/style/pyside2_resources.py +++ b/openpype/style/pyside2_resources.py @@ -2,309 +2,28 @@ # Resource object code # -# Created: pá lis 5 16:14:21 2021 +# Created: Wed Nov 10 17:40:15 2021 # by: The Resource Compiler for PySide2 (Qt v5.12.5) # # WARNING! All changes made in this file will be lost! from PySide2 import QtCore + qt_resource_data = b"\ -\x00\x00\x04\x12\ +\x00\x00\x00\xa5\ \x89\ PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ -\x00\x000\x00\x00\x000\x08\x06\x00\x00\x00W\x02\xf9\x87\ -\x00\x00\x00\x09pHYs\x00\x00\x0b\x13\x00\x00\x0b\x13\ -\x01\x00\x9a\x9c\x18\x00\x00\x03\xc4IDATh\x81\xed\ -\x9a_\x88\x94U\x18\xc6\x7f3;\x1a\x0b\x19\x15f\x17\ -\xca\x03IPM\x09J7Q^D)&f\x05[\ -\xb9\xd2\x82\xb1P\x17\x91$t\x11\x08z\xa1D\x17]\ -T\x94\x04\xd6E\xe1\xa2\x15L\xb1\x18\x99\xfd%\xd8\x08\ -\x82nj]\xa4\x22\xe2\x81\xa8\x96\xd5(\xe8\x9f\xae\xd5\ -\xc5\xf9\xb6\xc6\xd9\xf9\xbesf\xc6vf\xc0\xdf\xdd\x9c\ -\xef=\xefy\x9fs\xe6\x9c\xf3~\xdf9%2Fj\ -SK\x81\xdd\xc0Z\xe0:`\x11\xbd\xc5i`\x12\x98\ -\x00\xf6\x8c\x0dUg\x00J\x00#\xb5\xa9[\x80C\xc0\ -\xb2\xae\x85\xd7\x1a\xd3\xc0\xd6\xb1\xa1\xea\x07\xa5\xac\xe7\x8f\ -\xd1?\xc1\xcf1\x0d\x5c[&\xfcm\xfa-x\x081\ -\xef\xaa\x10\xfe\xf3\x8d\x9cY\xe0`R\x19h\xf8\xbd\xb6\ -B\x98\xb0\xf5\x9c\x19\x1b\xaaV\x16(\xa0\x96\x18\xa9M\ -\xcdr\xb6\x88Uezo\xb5i\x85E\xe5nG\xd0\ -)\xe7\x05t\x9b\xf3\x02\xfe\x0fl\xdfc\xfb\x90\xed\xf5\ -1\xdb\x9e\x13`\xfb\x11\xe05`\x188j{\x9f\xed\ -\xdc\x95\xb2\xa7\x04\xd8\x1e\x06\x9e\xaa+*\x01\x0f\x01/\ -\xe4\xd5\xe9\x19\x01\xb6\xd7\x01/\x93%\x98\x0dl\xb3\xfd\ -h\xb3z=!\xc0\xf6\xf5\xc0\xeb\xc0\xe2\x02\xb3\x8d\xcd\ -\x0a\xbb.\xc0\xf6\x95\xc0[\xc0\x92\x88\xe9\x8b\xcd\x0a\xbb\ -*\xc0\xf6\xe5\xc0Q\xe2\xd9\xf0\x93\x92^i\xf6\xa0k\ -\x02l/\x01\x8e\x00+#\xa6\x07\x80\xc7\xf2\x1evE\ -\x80\xed\xc5\xc0\x1b\xc0\x9a\x88\xe9\xdb\xc0\xa8\xa4\xbf\xf3\x0c\ -\x16\x5c\x80\xed2\xa1Wo\x8d\x98~\x0a\xdc-i\xb6\ -\xc8\xa8\x1b#\xf04po\xc4\xe6K`\x93\xa4_c\ -\xce\x92\x04\xd8.e=\xd7\x11\xb6w\x02\xdb#f\xdf\ -\x03\x1b$\xcd\xa4\xf8,\x0c*\x0b|\x07\xf0;0i\ -{UR\xa4\xcd}\x8d\x02\x8fG\xcc~\x06n\x93\xf4\ -m\xaa\xdf\x5c\x01Y\xfe1N\xd8\xda/\x00\xae\x01\xde\ -\xb3}U\xaa\xf3:_\x9b\x81\xfd\x11\xb3?\x81;%\ -}\xde\x8a\xef\xa2\x11x\x0e\xd8\xdcP\xb6\x0cx\xdf\xf6\ -\x15\xa9\x0d\xd8\xbe\x11x\x95\xf9/\xe4\xf5\xfc\x05\xdc'\ -\xe9\xa3T\xbfs4\x15\x90\xf5\xd8\x839u\x96\x13F\ -by\xcc\xb9\xed*p\x18\x18\x8c\x98>,\xa9\x16\xf3\ -\xd7\x8c\xbc\x11\xb84Ro%A\xc4ey\x06\xb6W\ -\x10v\xd9\x98\xaf\xbd\x92\x9e\x8f\xd8\xe4\x92'\xe0 a\ -\x1d.\xe2j\xe0\x1d\xdb\x177>\xb0}\x09!\xf8\x15\ -\x11\x1f\xfb%\xed\x8eFY@S\x01\x92N\x13\xb2\xbf\ -/\x22\xf5W\x03Gl_8W`{\x90\xf0\xb7\xa9\ -F\xea\x8e\x13r\xfd\x8e\xc8\x9d\xc4\x92N\x02\xeb\x81\xaf\ -\x22>n\x00\x0e\xdb\x1e\xb4=@\x98\xb07E\xeaL\ -\x00\xc3\x92:\xfe\x02X\xb8\x0fH\xfa\x11X\x078\xe2\ -\xe7f\xa0FX*\x1bW\xaeF&\x81;$\xfd\x91\ -\x18c!\xd1\xddU\x92\x09y\xcb\x0f\x11\xd3\x8d\xc0h\ -\xc4\xc6\x84\x8d\xea\xa7\xb4\xf0\xe2$\xa5\x07\x92\xbe&\x8c\ -\xc4\x89\x0e\xda:IH\x11\xbe\xeb\xc0\xc7<\x92\xf3\x1b\ -I\xc7\x80\x0d\xc0/m\xb4\xf3\x1bp\xbb\xa4\xe3m\xd4\ --\xa4\xa5\x04M\xd2g\xc0\xa6,\xa0Tf\x81-\x92\ ->i\xa5\xadTZ\xce0%M\x00w\x11r\x97\x14\ -\x1e\x90\xf4f\xab\xed\xa4\xd2V\x8a,\xe9]`\x0b\xa1\ -w\x8b\xd8)\xe9\xa5v\xdaH\xa5\xed\x1c_\xd28\xb0\ -\x8d\x90\x885\xe3YIO\xb4\xeb?\x95\x8e^R$\ -\x1d\x04\xeeg\xfe\x9c\xd8\x07\xec\xe8\xc4w*\x1d\x1f%\ -I:`\xfbc\xc2\x06v\x11\xf0a6O\x16\x84s\ -r\x16&\xe9\x1b\xe0\x99s\xe1\xabU\xca\x84\x13\xf0~\ -\xe5T\x85\x90\x9b\xd4\x7f\x9f\x19\xc8N\x03{\x91\xc6\xb7\ -\xba\xc9\x0a!3l\xfc\xc0T\xf4\xfa\xd7KL\x94\x81\ -=\x84c\xfb~c\x1a\xd8[\xcen}l\xa5\xbfD\ -\xcc]\xf6\x98\xf9\xf70!\xbb\xf4\xb1\x8b\xff\xae\xdb\x14\ -}\xab\xef\x06\xa78\xfb\xba\xcd\x09\x80\x7f\x00\xc4\x1e\x10\ -)3[\x85\xf7\x00\x00\x00\x00IEND\xaeB`\ -\x82\ -\x00\x00\x07\x06\ -\x89\ -PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ -\x00\x00\x0a\x00\x00\x00\x07\x08\x06\x00\x00\x001\xac\xdcc\ -\x00\x00\x04\xb0iTXtXML:com.\ -adobe.xmp\x00\x00\x00\x00\x00\x0a\x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a\x0a\x85\x9d\x9f\x08\x00\x00\x01\x83\ -iCCPsRGB IEC6196\ -6-2.1\x00\x00(\x91u\x91\xcf+DQ\x14\ -\xc7?fh\xfc\x18\x8dba1e\x12\x16B\x83\x12\ -\x1b\x8b\x99\x18\x0a\x8b\x99Q~mf\x9ey3j\xde\ -x\xbd7\xd2d\xabl\xa7(\xb1\xf1k\xc1_\xc0V\ -Y+E\xa4d\xa7\xac\x89\x0dz\xce\x9bQ#\x99s\ -;\xf7|\xee\xf7\xdes\xba\xf7\x5cpD\xd3\x8afV\ -\xfaA\xcbd\x8dp(\xe0\x9b\x99\x9d\xf3\xb9\x9e\xa8\xa2\ -\x85\x1a:\xf1\xc6\x14S\x9f\x8c\x8cF)k\xef\xb7T\ -\xd8\xf1\xba\xdb\xaeU\xfe\xdc\xbfV\xb7\x980\x15\xa8\xa8\ -\x16\x1eVt#+<&<\xb1\x9a\xd5m\xde\x12n\ -RR\xb1E\xe1\x13\xe1.C.(|c\xeb\xf1\x22\ -?\xdb\x9c,\xf2\xa7\xcdF4\x1c\x04G\x83\xb0/\xf9\ -\x8b\xe3\xbfXI\x19\x9a\xb0\xbc\x9c6-\xbd\xa2\xfc\xdc\ -\xc7~\x89;\x91\x99\x8eHl\x15\xf7b\x12&D\x00\ -\x1f\xe3\x8c\x10d\x80^\x86d\x1e\xa0\x9b>zdE\ -\x99|\x7f!\x7f\x8ae\xc9Ud\xd6\xc9a\xb0D\x92\ -\x14Y\xbaD]\x91\xea\x09\x89\xaa\xe8\x09\x19irv\ -\xff\xff\xf6\xd5T\xfb\xfb\x8a\xd5\xdd\x01\xa8z\xb4\xac\xd7\ -vpm\xc2W\xde\xb2>\x0e,\xeb\xeb\x10\x9c\x0fp\ -\x9e)\xe5/\xef\xc3\xe0\x9b\xe8\xf9\x92\xd6\xb6\x07\x9eu\ -8\xbd(i\xf1m8\xdb\x80\xe6{=f\xc4\x0a\x92\ -S\xdc\xa1\xaa\xf0r\x0c\xf5\xb3\xd0x\x05\xb5\xf3\xc5\x9e\ -\xfd\xecst\x07\xd15\xf9\xaaK\xd8\xd9\x85\x0e9\xef\ -Y\xf8\x06\x8e\xfdg\xf8\xfd\x8a\x18\x97\x00\x00\x00\x09p\ -HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\ -\x00\x00\x00mIDAT\x18\x95u\xcf\xc1\x09\xc2P\ -\x10\x84\xe1\xd7\x85\x07\x9b\xd0C@\xd2\x82x\x14{0\ -W!\x8d\x84`?bKzH\xcc\x97\x83\xfb0\x04\ -\xdf\x9c\x86\x7fg\x99\xdd\x84\x0d\xaaT\x10jl\x13\x1e\ -\xbe\xba\xfe\x0951{\xe6\x8d\x0f&\x1c\x17\xa1S\xb0\ -\x11\x87\x0c/\x01\x07\xec\xb0\x0f?\xe1\xbc\xaei\xa3\xe6\ -\x85w\xf8[\xe9\xf0\xbb\x9f\xfa\xd2\x839\xdc\xa3[\xf3\ -\x19.\xa8\x89\xb50\xf7C\xa0\x00\x00\x00\x00IEN\ -D\xaeB`\x82\ -\x00\x00\x00\xa6\ -\x89\ -PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ -\x00\x00\x06\x00\x00\x00\x09\x08\x04\x00\x00\x00\xbb\x93\x95\x16\ +\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce|N\ \x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\ -\x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09p\ +\x02bKGD\x00\x9cS4\xfc]\x00\x00\x00\x09p\ HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\ -\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x14\x1d\x00\xb0\ -\xd55\xa3\x00\x00\x00*IDAT\x08\xd7c`\xc0\ -\x06\xfe\x9fg``B0\xa1\x1c\x08\x93\x81\x81\x09\xc1\ -d``b``4D\xe2 s\x19\x90\x8d@\x02\ -\x00d@\x09u\x86\xb3\xad\x9c\x00\x00\x00\x00IEN\ -D\xaeB`\x82\ -\x00\x00\x01\xe1\ -\x89\ -PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ -\x00\x000\x00\x00\x000\x08\x06\x00\x00\x00W\x02\xf9\x87\ -\x00\x00\x00\x09pHYs\x00\x00\x0b\x13\x00\x00\x0b\x13\ -\x01\x00\x9a\x9c\x18\x00\x00\x01\x93IDATh\x81\xed\ -\x9a;N\xc3@\x10\x86\xbfq\x1c*\xe8\x10\xe56\x94\ -\xd0\xa4\xa1\x8a(\x22\x0a\x0aD\x9f\x9e\x0bp\x80Pp\ -\x01.\xc0\x15h\x80\x13\xa0\x1c!P\x91f\xbbD\xa1\ -B4yh(l\x1e\xb1\xfcH\x08\xc9\xda\xd2~\x9d\ -w\x5c\xfc\x9f\xb3\x1e9\xda\x11bTu\x17\xb8\x02\x9a\ -\xc0!P\xa7\x5cL\x80\x1e\xd0\x05\xaeEd\xf4]Q\ -\xd5\x96\xaa\x0e\xb4:\x0cT\xb5\x05 \x1a=\xf9g`\ -\xcf\xc5c]\x81!p\x10\x10m\x9b\xaa\x85\x87(s\ -'$\xda\xf3If\x1b\x0e\xb3(\xb5\xc4uSTu\ -\xcc\xfc\x0b;\x13\x91p\x83\xa1\x16FU\xa7\xccKL\ -\x02\xca\xd7m\x96\xa1\x1e\xb8N\xb0*^\xc05^\xc0\ -5^\xc05^\xc05^\xc05^\xc05\x85\x9f\xcd\ -\xd6\xda\x13\xe0\x08\xd8^\x7f\x9c9\xa6\xc0\x0b\xf0`\x8c\ -\xf9\xc8\xbaITU\x13k3\x11\x09\xad\xb5!p\x07\ -\x9c\xaf1\xe4\x22\xf4\x81Sc\xcck\xca\xff\x81\xdc-\ -t\x89\xfb\xf0\x00\xfb\xc0mV1O\xe0\xec\xff\xb3\xfc\ -\x99ck\xedNZ\xa1\xf2/q\x9e\xc0\xe3\xc6R\x14\ -\xf3d\x8cyO+\xe4\x09\xdc\x00\xf7\xeb\xc9\xb3\x14}\ -\xe0\x22\xab\x98\xd9\x85\xbe.\xca\xd4F\xd3\xbaP\xa1@\ -\x99X\xb6\x8dV\x02/\xe0\x1a/\xe0\x1a/\xe0\x1a/\ -\xe0\x1a/\xe0\x1a/\xe0\x9a\x80\xe8\x04\xbc\xaa\x8cC\xa2\ -\xe3\xfb\xc6\xaf\xc5Z\xfc\xd9ZF\x92\xc7\xac\xbd\x90h\ -\xf6\xa0QpcY\xe9V\x7f\xd4 \x9e\xfah\xc7\x0b\ -Ua\x08\xb4Ed$_+\xf1/\xd1\xe1g\xdcf\ -\xcbQ\xb8,\xc6\xcc\x8f\xdb\xbc\x01|\x02mw#\xb3\ -\xd4\x95Sv\x00\x00\x00\x00IEND\xaeB`\x82\ -\ -\x00\x00\x03\xff\ -\x89\ -PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ -\x00\x000\x00\x00\x000\x08\x06\x00\x00\x00W\x02\xf9\x87\ -\x00\x00\x00\x09pHYs\x00\x00\x0b\x13\x00\x00\x0b\x13\ -\x01\x00\x9a\x9c\x18\x00\x00\x03\xb1IDATh\x81\xed\ -\x9aOh\x1eE\x18\xc6\x7f\x9b&\x85\x82\x15\x15\xabB\ -\xcb\x03\x06\x05\xa9\x0a\x8a\xb7R<\xd4\x96\xaa\xb5\xe0A\ -\xad\xc5C%\xa0\x07Q\xccM(\xb4\x07E\x80\xae9\x1f\xc0\xff\ -\x81\xed\xbbm\xbff{W\xca6\x0b!\x84BY\xa7\ -\xdb\xa8\xedG\x81#\xf9\xcf\x00\x1c\x05&%-\x94l\ -\xa3\xc35\x03\xb6\xef\x05\x9e\xe9)\xca\x80\x87\x80\x17\xab\ -\xda\x0c\xcd\x81e{'\xf0\x0aQt\x91\x03\xb6\xbf*\ -k7\x143`\xfb&\xe0M`}\x8d\xd9me\x85\ -\x9d\x07`\xfb*\xe0]`c\xc2\xf4\xa5\xb2\xc2N\x03\ -\xb0}9\xf0>\xe9l\xf8iI\xaf\x97Ut\x16\x80\ -\xed\x8d\xc0\x140\x9e0}\x15x\xac\xaa\xb2\x93\x00l\ -\xaf\x07\xde\x02nL\x98\xbe\x07LH*n\xf5K\xac\ -z\x00\xb6G\x88\xa3zK\xc2\xf4\x0b\xe0.I\x8bu\ -F]\xcc\xc0\x11\xe0\x9e\x84\xcd\xb7\xc0\x1eI\xbf\xa5\x9c\ -5\x0a\xc0v\x96\x8f\xdc@\xd8>\x08<\x920\xfb\x11\ -\xd8-i.a\x07$\x02\xc8\x85O\x02\x7f\x003\xb6\ -\xafo\xa4\xb4\xdc\xd7\x04\xf0d\xc2\xec\x17\xe0VI\xdf\ -7\xf5[\x99\x0b\xd9\x1e\x03\x8e\x03{{\xeaf\x81\x9b\ -%}\xd3\xb4\x03\x00\xdb{\x89\x8b\xb6x\xa7\xed\xe5,\ -q\xe4?\xab2\xe87\x17z\x8e\xe5\xe2!\xee\xd7\x1f\ -\xdb\xbe\xb2Vq\x0f\xb6\xb7\x01o\x14;.\xf0\x17p\ -_\x9d\xf8*J\x03\xc8G\xec\xc1\x8a6\x9b\x81\x8fl\ -oN9\xb7\xbd\x15x\x1b\xd8\x900}X\xd2\xf1\x94\ -\xbf2\xaaf\xe0\x92D\xbbqb\x10\x9b\xaa\x0clo\ -!\x9e\xb2)_OH:\x9a\xb0\xa9\xa4*\x80c\xc4\ -}\xb8\x8ek\x80\x0fl_T\xac\xb0}1Q\xfc\x96\ -\x84\x8f\x17$\x1dN\xaa\xac\xa14\x00I\x0b\xc4\xec\xaf\ -4\x85\xed\xe1\x06`\xca\xf6\x05\xff\x14\xd8\xde@|l\ -\xb6&\xda\x9e \xe6\xfa\x03Q{#\xcb\x93\xad\x93\xc0\ -\xd5\x09?\x9f\x02\xb7\x03\xf3\xc4\xdd\xa6\xb8\xf8\x8bL\x03\ -\xbb$\xfd\xd9\x8f\xd8\xb2](y\xa5\xb4-b\x10J\ -\xf8\x9f\x22\x1eB\x13\x09\xbb\x19\xe2V\xfcs#\xd5=\ -\xb4\x0a\x00\x96r\xf6\x93\xc0\x15\xfdvZ\xc0\xc06I\ -?\xb4i\xdc\xfaN,\xe9;`'p\xa6M\xc79\ -?\x11\x0f\xaaV\xe2\xabh\x9c\xdfH:\x05\xec\x06~\ -m\xd1\xcf\xef\xc0\x1d\x92\xben\xd1\xb6\x96\xbe\x124I\ -_\x02{rAMY\x04\xf6I\xfa\xbc\x9f\xbe\x9a\xd2\ -w\x86)i\x1a\xb8\x93\x98\xbb4\xe1\x01I\xef\xf4\xdb\ -OSZ\xa5\xc8\x92>\x04\xf6\x11G\xb7\x8e\x83\x92^\ -n\xd3GSZ\xe7\xf8\x92N\x00\x07\x88\x89X\x19\xcf\ -Jz\xaa\xad\xff\xa6\x0ctI\x91t\x0c\xb8\x9f\xff\xae\ -\x89\xe7\x81\xc9A|7eE\xde\x8d\xda\x1e'\x9e\xbe\ -\x17\x02\x9f\xe4\xebd\xc5i}\x90\x0d\x0bU\x07\xd9B\ -7rV\x84\xf9Qbn\xd2\xfb~f]\x1e\xe90\ -R\xbc\xd5\xcd\x8c\x123\xc3\xe2\x0b\xa6\xba\xeb\xdf01\ -\xbd\xf6?5\xc8\xbf\xfa\xd8\x9f\x17\xac\x15f\x81\xfdY\ -\x96\xcd-\xfd\x99\x90\xcf\xc4!\xfe\xfd\xdc\xa6\xee]}\ -\x17\xcc\xb3\xfcs\x9b3\x00\x7f\x03\xd9\x1a\xfb\xdb\xbb\xa7\ -\x8f\x07\x00\x00\x00\x00IEND\xaeB`\x82\ +\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x0b\x02\x04m\ +\x98\x1bi\x00\x00\x00)IDAT\x08\xd7c`\xc0\ +\x00\x8c\x0c\x0c\xff\xcf\xa3\x08\x18220 \x0b2\x1a\ +200B\x98\x10AFC\x14\x13P\xb5\xa3\x01\x00\ +\xd6\x10\x07\xd2/H\xdfJ\x00\x00\x00\x00IEND\ +\xaeB`\x82\ \x00\x00\x07\xad\ \x89\ PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ @@ -430,87 +149,76 @@ v)`\x8b\x07>\xa8\xe6\xd1\xfe\x0b\x9d\x85\x8eW\x0d\ ^x\xa2\x9e\x0e\xa7 tG9\x1d\xf6\xe1\x95+\xd6\ \xb1D\x8e\x0e\xcbX\xf0\x0fR\x8ay\x18\xdc\xe2\x02p\ \x00\x00\x00\x00IEND\xaeB`\x82\ -\x00\x00\x00\x9e\ -\x89\ -PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ -\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce|N\ -\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\ -\x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09p\ -HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\ -\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x08\x15\x0f\xfd\ -\x8f\xf8.\x00\x00\x00\x22IDAT\x08\xd7c`\xc0\ -\x0d\xfe\x9f\x87\xb1\x18\x91\x05\x18\x0d\xe1BH*\x0c\x19\ -\x18\x18\x91\x05\x10*\xd1\x00\x00\xca\xb5\x07\xd2v\xbb\xb2\ -\xc5\x00\x00\x00\x00IEND\xaeB`\x82\ -\x00\x00\x00\xa6\ -\x89\ -PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ -\x00\x00\x06\x00\x00\x00\x09\x08\x04\x00\x00\x00\xbb\x93\x95\x16\ -\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\ -\x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09p\ -HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\ -\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x14\x1d\x00\xb0\ -\xd55\xa3\x00\x00\x00*IDAT\x08\xd7c`\xc0\ -\x06\xfe\x9fg``B0\xa1\x1c\x08\x93\x81\x81\x09\xc1\ -d``b``4D\xe2 s\x19\x90\x8d@\x02\ -\x00d@\x09u\x86\xb3\xad\x9c\x00\x00\x00\x00IEN\ -D\xaeB`\x82\ -\x00\x00\x01\xdc\ +\x00\x00\x043\ \x89\ PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ \x00\x000\x00\x00\x000\x08\x06\x00\x00\x00W\x02\xf9\x87\ \x00\x00\x00\x09pHYs\x00\x00\x0b\x13\x00\x00\x0b\x13\ -\x01\x00\x9a\x9c\x18\x00\x00\x01\x8eIDATh\x81\xed\ -\x9a\xafN\xc3P\x14\x87\xbfn\x1d\x0a\x1cA\x1e\x83\x04\ -\xc4\x0cjA\x10\x04\x82\x80\x9e\xe7\x05x\x80!x\x01\ -^\x00\x8f\xc2\x00rA\x90=\xc2@1s\xe42\x14\ -\xc1\xecO\x82h\x1b\xb6e\xed(\xebv\xda\xe5~\xae\ -\xf7\x5c\xf1\xfb\xda{o\x9a\xdc\xe3\x11\xa2\xaa\xdb\xc05\ -P\x03\xf6\x81\x0a\xf9b\x00\xb4\x81\x16p#\x22=\x00\ -\x0f@U\x8f\x81{`\xc7,^:\xba@]D^\ -\xbc\xf0\xcd\xbfQ\x9c\xf0\x11]`\xafD\xb0l\x8a\x16\ -\x1e\x82\xcc\x0d\x9f`\xcdO3Zq\x98\xbfR\x9ez\ -\xae\xf9\x04\x1bv\x9c\x91\x88\xf8+\x0a\x94\x0aU\x1d2\ -)qP\x22\x7f\xa7M\x1a*%\xeb\x04\x8b\xe2\x04\xac\ -q\x02\xd68\x01k\x9c\x805N\xc0\x1a'`\xcd\xdc\ -\xdffU=\x01\x0e\x81\xcd\xe5\xc7\x99`\x08\xbc\x03O\ -\x22\xf2\x1d7)V@U}\xe0\x018\xcf>[*\ -:\xaaz*\x22\x1f\xb3\x8aIK\xe8\x0a\xfb\xf0\x00\xbb\ -\xc0]\x5c1I\xe0,\xfb,\xff\xe6HU\xb7f\x15\ -\x0a\xbf\x89\x93\x04\x9eW\x96b>\xaf\x22\xf25\xab\x90\ -$p\x0b<.'O*:\xc0e\x5c1\xf6\x14\x12\ -\x91!pQ\xd8c4BD\x9a@3\xc3`\x99\xb2\ -\xd6\x9b\xb8\x108\x01k\x9c\x805N\xc0\x1a'`\x8d\ -\x13\xb0f-\x04\x06\xd6!\x16\xa0\xef\x13\x5c\xdfW\xc7\ -\x06\xcb\xe1m`\x1e\x99\xbefm\xfb\x04\xbd\x07\xd59\ -\x13\xf3J\xab\xf8\xad\x06a\xd7G=\x1c(\x0aQ\xb3\ -G\xcf\x8bF\xc2/\xd1\xe0\xb7\xddf\xc3(\x5c\x1c}\ -&\xdbm>\x01~\x00%\xf8ZCUN:\x7f\x00\ -\x00\x00\x00IEND\xaeB`\x82\ -\x00\x00\x00\x9f\ -\x89\ -PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ -\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce|N\ -\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\ -\x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09p\ -HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\ -\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x08\x14\x1f\xf9\ -#\xd9\x0b\x00\x00\x00#IDAT\x08\xd7c`\xc0\ -\x0d\xe6|\x80\xb1\x18\x91\x05R\x04\xe0B\x08\x15)\x02\ -\x0c\x0c\x8c\xc8\x02\x08\x95h\x00\x00\xac\xac\x07\x90Ne\ -4\xac\x00\x00\x00\x00IEND\xaeB`\x82\ -\x00\x00\x00\x9e\ -\x89\ -PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ -\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce|N\ -\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\ -\x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09p\ -HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\ -\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x08\x15\x0f\xfd\ -\x8f\xf8.\x00\x00\x00\x22IDAT\x08\xd7c`\xc0\ -\x0d\xfe\x9f\x87\xb1\x18\x91\x05\x18\x0d\xe1BH*\x0c\x19\ -\x18\x18\x91\x05\x10*\xd1\x00\x00\xca\xb5\x07\xd2v\xbb\xb2\ -\xc5\x00\x00\x00\x00IEND\xaeB`\x82\ +\x01\x00\x9a\x9c\x18\x00\x00\x03\xe5IDATh\x81\xed\ +\x9aM\x88\x1cE\x14\xc7\x7f3;\x89.\x18\xf13\x1e\ +\x92\x8b\x8b\xa2&\x06\x14/\xa29\x88\x15\x89\xa9\x18\x15\ +\xd1\xca\x06\x0f\x91\x05=\x88bnB\xc0\x1c\x12\xc4\x83\ +\x07\x15\x0dB\x14\x89\x04\xa2\x96DY\x22/F}\x8a\ +\xb0\x22\x08\x1e4\xbb\x22F\x8c,\x88\xba\xc4\x88\x82_\ +\xc9F=T\x0f\x8c\xbd\xdd]\xdd\xd3a\xa7\x07\xfc\xdd\ +\xa6\xfa\xd5\xab\xf7\xea\xf3\xdf\xd5\xd3\x22\xc1Xw\x11\xb0\ +\x03X\x0b\x5c\x0d,\xa1Y\x9c\x02\xa6\x81)`\xa7\x8a\ +?\x0e\xd0\x020\xd6\xdd\x0c\xbc\x02,\x1fXx\xd5\x98\ +\x03\xb6\xa8\xf8\xf7[I\xcf\xcf0<\xc1w\x99\x03V\ +\xb7\x09\xd3f\xd8\x82\x87\x10\xf3c\x1d\xc2\x9cOsz\ +\x91\x83)\xcbH\xea\xf7\xda\x0ea\xc1\xf6rZ\xc5w\ +\x16)\xa0J\x18\xeb\xe6\xf9o\x12k\xda4o\xb7\xa9\ +\xc2\x92\xf6\xa0#\xa8\xcb\xff\x09\x0c\x9a\xa1O\xa0\xa9\xbb\ +\xcd=\xc0]\xc0K*\xfe\xdd\x22\xdb\xc6\x8d\x80\xb1\xee\ +\x11\xc0\x03\xe3\xc0ac\xddnc]\xeeN\xd9\xa8\x04\ +\x8cu\xe3\xc0S=E-\xe0A\xe0\x85\xbc:\x8d\x99\ +B\xc6\xbau\xc0\xcb$\x023\xc5Vc\xdd\x91\xacz\ +\x8d\x18\x01c\xddu\xc0\x1b\xc0\xd2\x02\xb3\x0dY\x85\x03\ +O\xc0Xw\x19 \xc0\xb2\x88\xe9\x8bY\x85\x03M\xc0\ +Xw\x09p\x98\xb8\x1a~R\xc5\xbf\x9a\xf5``\x09\ +\x18\xeb\x96\x01\x87\x80\xb1\x88\xe9>\xe0\xd1\xbc\x87\x03I\ +\xc0X\xb7\x14x\x13\xb86b\xfa60\xa1\xe2\xff\xc9\ +3X\xf4\x04\x8cumB\xaf\x9a\x88\xe9'\xc0\xdd*\ +~\xbe\xc8h\x10#\xf04\xe0\x226_\x01\x1bU\xfc\ +o1g\xa5\x120\xd6\xb5\x92\x9e\xab\x85\xb1n;\xf0\ +p\xc4\xec{`}\xf7\xd6!FaPI\xe0\xdb\x80\ +?\x80ic\xdd\x9aR\x91f\xfb\x9a\x00\x1e\x8f\x98\xfd\ +\x02\xdc\xaa\xe2\xbf-\xeb77\x81D\x7fL\x12\x8e\xf6\ +\xb3\x80\xab\x80\xf7\x8cuW\x94u\xde\xe3k\x13\xb0'\ +b\xf6\x17p\x87\x8a\xff\xbc\x8a\xef\xa2\x11x\x0e\xd8\x94\ +*[\x0e\xa8\xb1\xee\xd2\xb2\x0d\x18\xebn\x00^c\xe1\ +\x0by/\x7f\x03\xf7\xaa\xf8\x0f\xcb\xfa\xed\x92\x99@\xd2\ +c\x0f\xe4\xd4YA\x18\x89\x151\xe7\xc6\xbaU\xc0A\ +`4b\xfa\x90\x8a?\x10\xf3\x97E\xde\x08\x5c\x10\xa9\ +7FH\xe2\xe2<\x03c\xddJ\xc2)\x1b\xf3\xb5K\ +\xc5?\x1f\xb1\xc9%/\x81\xfd\x84}\xb8\x88+\x81w\ +\x8cu\xe7\xa5\x1f\x18\xeb\xce'\x04\xbf2\xe2c\x8f\x8a\ +\xdf\x11\x8d\xb2\x80\xcc\x04T\xfc)\x82\xfa\xcb\x94\xb0=\ +\x5c\x03\x1c2\xd6\x9d\xd3-0\xd6\x8d\x12\xa6\xcd\xaaH\ +\xddI\x82\xd6\xafE\xee\x22V\xf1'\x80[\x80\xa3\x11\ +\x1f\xd7\x03\x07\x8du\xa3\xc6\xba\x11\xc2\x82\xbd1Rg\ +\x0a\x18W\xf1\xb5o\x00\x0b\xcf\x01\x15\xff#\xb0\x0e\x98\ +\x8d\xf8\xb9\x098@\xd8*\xd3;W\x9ai\xe0v\x15\ +\xffg\xc9\x18\x0b\x89\x9e\xae*~\x96\xa0[~\x88\x98\ +n\x00&\x226\xb3\x84\x83\xea\xe7r\xe1\xc5)%\x0f\ +T\xfc\xd7\x84\x91\xf8\xa9F['\x08\x12\xe1\xbb\x1a>\ +\x16PZ\xdf\xa8\xf8\x19`=\xf0k\x1f\xed\xfc\x0e\xdc\ +\xa6\xe2\xbf\xec\xa3n!\x95\x04\x9a\x8a\xff\x14\xd8\x98\x04\ +T\x96y`\xb3\x8a\xff\xb8J[e\xa9\xac0U\xfc\ +\x14p'A\xbb\x94\xe1~\x15\xffV\xd5v\xca\xd2\x97\ +DNn\xcb6\x13z\xb7\x88\xed*~o?m\x94\ +\xa5o\x8d\xaf\xe2'\x81\xad\x04!\x96\xc5\xb3*\xfe\x89\ +~\xfd\x97\xa5\xd6K\x8a\x8a\xdf\x0f\xdc\xc7\xc25\xb1\x1b\ +\xd8V\xc7wYj\xdf\xcc\xa9\xf8}\xc6\xba\x8f\x08\x07\ +\xd8\xb9\xc0\x07\xc9:Y\x14\xce\xc8\xd5\xa2\x8a\xff\x06x\ +\xe6L\xf8\xaaJ\x9b\xf0\x05|X9\xd9!h\x93\xde\ +\xfb\x99\x91\xe4k`\x13I\xbf\xd5Mw\x08\xca0}\ +\xc1T\xf4\xfa\xd7$\xa6\xda\xc0N\xc2g\xfbac\x0e\ +\xd8\xd5N\xee_\xb60\x5cIt\xff\xecq|\x04\xe0\ +\xd8\xd1\x99cc\x97\xaf\xde\x0b\x9cM\xf8\xf0}!\xcd\ +\x9bF'\x81\xcf\x80\xd7\x01\xa7\xe2\xbf\x00\xf8\x17]\x81\ +\x0b8\xb3\xfa \x9c\x00\x00\x00\x00IEND\xaeB\ +`\x82\ \x00\x00\x01W\ \x89\ PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ @@ -535,6 +243,40 @@ xl(\x8f\xcd\xd4\x86\x872\xf3\xa6\xa5<\xf3C\xe7\ \x97\xd8\xf0}\xdc\xe6\xce4\xdco:\xfa\xc7m\xde\x00\ >\x00G\xd7\xea\xb1\xadi\xe1\xd6\x00\x00\x00\x00IE\ ND\xaeB`\x82\ +\x00\x00\x01\xfc\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x000\x00\x00\x000\x08\x06\x00\x00\x00W\x02\xf9\x87\ +\x00\x00\x00\x09pHYs\x00\x00\x0b\x13\x00\x00\x0b\x13\ +\x01\x00\x9a\x9c\x18\x00\x00\x01\xaeIDATh\x81\xed\ +\x9a\xbdJ\x03A\x14FO6\x1b\xb0\xd0J\xf1\x01\x14\ +\xabh\x91\xc6*X\xb8\x16\xb2\x88v\x0b\xe9}\x01\x1f\ +@\x8b\xf8\x00\xbe\x80\x85\x9d0b\xa32U\xc6B\xf2\ +\x02B\x92F\x83}H'6\xf9\x01\x8b\xdd@\x12\xb2\ +\x89k~f7\xcc\xe9v\xef\x14\xdfY\xee\x0c\x0bw\ +R\x048\xae\xb7\x01\x5c\x01y`\x17\xc8\x10/\xda@\ +\x05(\x03E%E\x13 \x05\xe0\xb8\xde!p\x0fl\ +j\x8b\x17\x8d\x06PPR\xbc\xa6\x82/_%9\xe1\ +{4\x80\xac\x85\xdf6I\x0b\x0f~\xe6K\x1b\xbf\xe7\ +\x87\xe9.8\xcc_I\x0f=\xe7m\xfc\x0d\xdbOW\ +Ia/(P$\x1c\xd7\xeb0(\xb1g\x11\xbf\xd3\ +&\x0a\x19Kw\x82i1\x02\xba1\x02\xba1\x02\xba\ +1\x02\xba1\x02\xba1\x02\xba\x99\xf8\xdb\xec\xb8\xde\x11\ +\xb0\x0f\xac\xce?\xce\x00\x1d\xa0\x06<+)~\xc2\x16\ +\x85\x0a8\xaeg\x03\x8f\xc0\xe9\xec\xb3E\xa2\xee\xb8\xde\ +\xb1\x92\xe2sTq\x5c\x0b]\xa0?<\xc06p\x1b\ +V\x1c'p2\xfb,\xff\xe6\xc0q\xbd\xb5Q\x85\xc4\ +o\xe2q\x02/\x0bK1\x997%\xc5\xf7\xa8\xc28\ +\x81\x1b\xe0i>y\x22Q\x07\xce\xc3\x8a\xa1\xa7\x90\x92\ +\xa2\x03\x9c%\xf6\x18\xed\xa1\xa4(\x01\xa5\x19\x06\x9b)\ +K\xbd\x89\x13\x81\x11\xd0\x8d\x11\xd0\x8d\x11\xd0\x8d\x11\xd0\ +\x8d\x11\xd0\xcdR\x08\xb4u\x87\x98\x82\x96\x8d?\xbe\xcf\ +\xf5\xbdL\x07\xd3\xc082\xaa_[\ +;\xd9;`\x05\x7f\xf0\xbdN\xfc\xda\xa8\x05\xbc\x03\x0f\ +\x80\xa7\xa4\xa8\x01\xfc\x02Q\xab\x5c\x8a?\xde\xe3Y\x00\ +\x00\x00\x00IEND\xaeB`\x82\ \x00\x00\x00\xa6\ \x89\ PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ @@ -548,136 +290,31 @@ HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\ \x08000B\x98\x10\xc1\x14\x01\x14\x13P\xb5\xa3\x01\ \x00\xc6\xb9\x07\x90]f\x1f\x83\x00\x00\x00\x00IEN\ D\xaeB`\x82\ -\x00\x00\x070\ +\x00\x00\x01i\ \x89\ PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ -\x00\x00\x0a\x00\x00\x00\x07\x08\x06\x00\x00\x001\xac\xdcc\ -\x00\x00\x04\xb0iTXtXML:com.\ -adobe.xmp\x00\x00\x00\x00\x00\x0a\x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a\x0aH\x8b[^\x00\x00\x01\x83\ -iCCPsRGB IEC6196\ -6-2.1\x00\x00(\x91u\x91\xcf+DQ\x14\ -\xc7?fh\xfc\x18\x8dba1e\x12\x16B\x83\x12\ -\x1b\x8b\x99\x18\x0a\x8b\x99Q~mf\x9ey3j\xde\ -x\xbd7\xd2d\xabl\xa7(\xb1\xf1k\xc1_\xc0V\ -Y+E\xa4d\xa7\xac\x89\x0dz\xce\x9bQ#\x99s\ -;\xf7|\xee\xf7\xdes\xba\xf7\x5cpD\xd3\x8afV\ -\xfaA\xcbd\x8dp(\xe0\x9b\x99\x9d\xf3\xb9\x9e\xa8\xa2\ -\x85\x1a:\xf1\xc6\x14S\x9f\x8c\x8cF)k\xef\xb7T\ -\xd8\xf1\xba\xdb\xaeU\xfe\xdc\xbfV\xb7\x980\x15\xa8\xa8\ -\x16\x1eVt#+<&<\xb1\x9a\xd5m\xde\x12n\ -RR\xb1E\xe1\x13\xe1.C.(|c\xeb\xf1\x22\ -?\xdb\x9c,\xf2\xa7\xcdF4\x1c\x04G\x83\xb0/\xf9\ -\x8b\xe3\xbfXI\x19\x9a\xb0\xbc\x9c6-\xbd\xa2\xfc\xdc\ -\xc7~\x89;\x91\x99\x8eHl\x15\xf7b\x12&D\x00\ -\x1f\xe3\x8c\x10d\x80^\x86d\x1e\xa0\x9b>zdE\ -\x99|\x7f!\x7f\x8ae\xc9Ud\xd6\xc9a\xb0D\x92\ -\x14Y\xbaD]\x91\xea\x09\x89\xaa\xe8\x09\x19irv\ -\xff\xff\xf6\xd5T\xfb\xfb\x8a\xd5\xdd\x01\xa8z\xb4\xac\xd7\ -vpm\xc2W\xde\xb2>\x0e,\xeb\xeb\x10\x9c\x0fp\ -\x9e)\xe5/\xef\xc3\xe0\x9b\xe8\xf9\x92\xd6\xb6\x07\x9eu\ -8\xbd(i\xf1m8\xdb\x80\xe6{=f\xc4\x0a\x92\ -S\xdc\xa1\xaa\xf0r\x0c\xf5\xb3\xd0x\x05\xb5\xf3\xc5\x9e\ -\xfd\xecst\x07\xd15\xf9\xaaK\xd8\xd9\x85\x0e9\xef\ -Y\xf8\x06\x8e\xfdg\xf8\xfd\x8a\x18\x97\x00\x00\x00\x09p\ -HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\ -\x00\x00\x00\x97IDAT\x18\x95m\xcf\xb1j\x02A\ -\x14\x85\xe1o\xb7\xb6\xd0'H=Vi\x03\xb1\xb4H\ -;l\xa5\xf19\xf6Y\x02VB\xbaa\x0a\x0b;\x1b\ -\x1bkA\x18\x02)m\xe3\xbe\x82\xcd\x06\x16\xd9\xdb\xdd\ -\x9f\xff\x5c\xee\xa9b*\x13Ls\x13nF&\xa6\xf2\ -\x82\xaeF\x8b\xdf\x98\xca\xfb\x88\xb4\xc0\x0f\xda\x1a[t\ -\xd8\xc7T\xc2@\x9ac\x8f?|U=|\xc5\x09w\ -\xbc\xa1\xc2\x193,r\x13.\xd5\xe0\xc2\x12\x07\x5cQ\ -#\xe0#7\xe1\xa8O\x0e\x7f\xda`\xd7\xaf\x9f\xb9\x09\ -\xdfc\x05\xff\xe5uLe\xf5\xcc\x1f\x0d3,\x83\xb6\ -\x06D\x83\x00\x00\x00\x00IEND\xaeB`\x82\ -\x00\x00\x00\xa5\ -\x89\ -PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ -\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce|N\ -\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\ -\x02bKGD\x00\x9cS4\xfc]\x00\x00\x00\x09p\ -HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\ -\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x0b\x02\x04m\ -\x98\x1bi\x00\x00\x00)IDAT\x08\xd7c`\xc0\ -\x00\x8c\x0c\x0c\xff\xcf\xa3\x08\x18220 \x0b2\x1a\ -200B\x98\x10AFC\x14\x13P\xb5\xa3\x01\x00\ -\xd6\x10\x07\xd2/H\xdfJ\x00\x00\x00\x00IEND\ -\xaeB`\x82\ +\x00\x000\x00\x00\x000\x08\x06\x00\x00\x00W\x02\xf9\x87\ +\x00\x00\x00\x09pHYs\x00\x00\x0b\x13\x00\x00\x0b\x13\ +\x01\x00\x9a\x9c\x18\x00\x00\x01\x1bIDATh\x81\xed\ +\xda\xb1m\xc2@\x14\x87\xf1\xcf\xc7\x91\x09P\x86pB\ +AO\xc5\x0a\xae\x90\xbc\x0a)\xc8*\x96Ry\x05*\ +F \x1e\xc2\x82\x05H\x90R\xdcY\x01KQbE\ +\xe2\xef\x93\xde\xaf\xb3E\xf1>\xcb\xa6\xb9\x97\x11\x95u\ +3\x03^\x80%\xf0\x0cL\x19\x97\x0f\xe0\x00\xec\x81m\ +U\xe4G\x80\x0c\xa0\xac\x9b\x15\xf0\x06<\xca\xc6\x1b\xa6\ +\x05\xd6U\x91\xef\xb2\xf8\xe4\xdfIg\xf8N\x0b<9\ +\xc2k\x93\xda\xf0\x10f\xdex\xc2;\xdfw\xb9\xf30\ +\x7f5\xe9]/=\xe1\x83\xbdv\xa9\x8a\xdc\xdfi\xa0\ +A\xca\xba\xf9\xe46b\xee\x18\xdf\xbf\xcd\x10S\xa7\x9e\ +\xe0\xbf,@\xcd\x02\xd4,@\xcd\x02\xd4,@\xcd\x02\ +\xd4,@\xcd\x02\xd4,@\xcd\x02\xd4,@\xcd\x02\xd4\ +,@\xcd\x02\xd4,@\xcd\x02\xd4,@\xcd\x11N\xc0\ +Su\xf6\x84\xe3\xfb\xc5\xd5\xcdI<\x0d\x1c\xa3\xfe1\ +\xeb\xc1\x13v\x0f\x16\xbf\xfcp\xac\xf6\x0e\xd8\x12\x8e\xed\ +S\xd3\x02\xaf.n}\xacI+\xa2[\xf68f\xdd\ +\x9d\xb8\xf4\xb1\xe1{\xdd\xe6A4\xdcO\xce\xdc\xae\xdb\ +\x9c\x00\xbe\x00\x9f\xf64>6O7\x81\x00\x00\x00\x00\ +IEND\xaeB`\x82\ \x00\x00\x03\xfb\ \x89\ PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ @@ -744,53 +381,84 @@ pV\x8e\x16%}\x07<{6|\xd5\xa5M\xf8\x02\ \x8f\x09\xd9Hl\xe7\xbf\xdfm\xaa\xce\xea\x9b\xe0$g\ \xfens\x14\xe0\x1f\x0aC\x12kO\xfd?\x13\x00\x00\ \x00\x00IEND\xaeB`\x82\ -\x00\x00\x01\xfc\ +\x00\x00\x03\xff\ \x89\ PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ \x00\x000\x00\x00\x000\x08\x06\x00\x00\x00W\x02\xf9\x87\ \x00\x00\x00\x09pHYs\x00\x00\x0b\x13\x00\x00\x0b\x13\ -\x01\x00\x9a\x9c\x18\x00\x00\x01\xaeIDATh\x81\xed\ -\x9a\xbdJ\x03A\x14FO6\x1b\xb0\xd0J\xf1\x01\x14\ -\xabh\x91\xc6*X\xb8\x16\xb2\x88v\x0b\xe9}\x01\x1f\ -@\x8b\xf8\x00\xbe\x80\x85\x9d0b\xa32U\xc6B\xf2\ -\x02B\x92F\x83}H'6\xf9\x01\x8b\xdd@\x12\xb2\ -\x89k~f7\xcc\xe9v\xef\x14\xdfY\xee\x0c\x0bw\ -R\x048\xae\xb7\x01\x5c\x01y`\x17\xc8\x10/\xda@\ -\x05(\x03E%E\x13 \x05\xe0\xb8\xde!p\x0fl\ -j\x8b\x17\x8d\x06PPR\xbc\xa6\x82/_%9\xe1\ -{4\x80\xac\x85\xdf6I\x0b\x0f~\xe6K\x1b\xbf\xe7\ -\x87\xe9.8\xcc_I\x0f=\xe7m\xfc\x0d\xdbOW\ -Ia/(P$\x1c\xd7\xeb0(\xb1g\x11\xbf\xd3\ -&\x0a\x19Kw\x82i1\x02\xba1\x02\xba1\x02\xba\ -1\x02\xba1\x02\xba1\x02\xba\x99\xf8\xdb\xec\xb8\xde\x11\ -\xb0\x0f\xac\xce?\xce\x00\x1d\xa0\x06<+)~\xc2\x16\ -\x85\x0a8\xaeg\x03\x8f\xc0\xe9\xec\xb3E\xa2\xee\xb8\xde\ -\xb1\x92\xe2sTq\x5c\x0b]\xa0?<\xc06p\x1b\ -V\x1c'p2\xfb,\xff\xe6\xc0q\xbd\xb5Q\x85\xc4\ -o\xe2q\x02/\x0bK1\x997%\xc5\xf7\xa8\xc28\ -\x81\x1b\xe0i>y\x22Q\x07\xce\xc3\x8a\xa1\xa7\x90\x92\ -\xa2\x03\x9c%\xf6\x18\xed\xa1\xa4(\x01\xa5\x19\x06\x9b)\ -K\xbd\x89\x13\x81\x11\xd0\x8d\x11\xd0\x8d\x11\xd0\x8d\x11\xd0\ -\x8d\x11\xd0\xcdR\x08\xb4u\x87\x98\x82\x96\x8d?\xbe\xcf\ -\xf5\xbdL\x07\xd3\xc082\xaa_[\ -;\xd9;`\x05\x7f\xf0\xbdN\xfc\xda\xa8\x05\xbc\x03\x0f\ -\x80\xa7\xa4\xa8\x01\xfc\x02Q\xab\x5c\x8a?\xde\xe3Y\x00\ -\x00\x00\x00IEND\xaeB`\x82\ -\x00\x00\x00\xa6\ +\x01\x00\x9a\x9c\x18\x00\x00\x03\xb1IDATh\x81\xed\ +\x9aOh\x1eE\x18\xc6\x7f\x9b&\x85\x82\x15\x15\xabB\ +\xcb\x03\x06\x05\xa9\x0a\x8a\xb7R<\xd4\x96\xaa\xb5\xe0A\ +\xad\xc5C%\xa0\x07Q\xccM(\xb4\x07E\x80\xae9\x1f\xc0\xff\ +\x81\xed\xbbm\xbff{W\xca6\x0b!\x84BY\xa7\ +\xdb\xa8\xedG\x81#\xf9\xcf\x00\x1c\x05&%-\x94l\ +\xa3\xc35\x03\xb6\xef\x05\x9e\xe9)\xca\x80\x87\x80\x17\xab\ +\xda\x0c\xcd\x81e{'\xf0\x0aQt\x91\x03\xb6\xbf*\ +k7\x143`\xfb&\xe0M`}\x8d\xd9me\x85\ +\x9d\x07`\xfb*\xe0]`c\xc2\xf4\xa5\xb2\xc2N\x03\ +\xb0}9\xf0>\xe9l\xf8iI\xaf\x97Ut\x16\x80\ +\xed\x8d\xc0\x140\x9e0}\x15x\xac\xaa\xb2\x93\x00l\ +\xaf\x07\xde\x02nL\x98\xbe\x07LH*n\xf5K\xac\ +z\x00\xb6G\x88\xa3zK\xc2\xf4\x0b\xe0.I\x8bu\ +F]\xcc\xc0\x11\xe0\x9e\x84\xcd\xb7\xc0\x1eI\xbf\xa5\x9c\ +5\x0a\xc0v\x96\x8f\xdc@\xd8>\x08<\x920\xfb\x11\ +\xd8-i.a\x07$\x02\xc8\x85O\x02\x7f\x003\xb6\ +\xafo\xa4\xb4\xdc\xd7\x04\xf0d\xc2\xec\x17\xe0VI\xdf\ +7\xf5[\x99\x0b\xd9\x1e\x03\x8e\x03{{\xeaf\x81\x9b\ +%}\xd3\xb4\x03\x00\xdb{\x89\x8b\xb6x\xa7\xed\xe5,\ +q\xe4?\xab2\xe87\x17z\x8e\xe5\xe2!\xee\xd7\x1f\ +\xdb\xbe\xb2Vq\x0f\xb6\xb7\x01o\x14;.\xf0\x17p\ +_\x9d\xf8*J\x03\xc8G\xec\xc1\x8a6\x9b\x81\x8fl\ +oN9\xb7\xbd\x15x\x1b\xd8\x900}X\xd2\xf1\x94\ +\xbf2\xaaf\xe0\x92D\xbbqb\x10\x9b\xaa\x0clo\ +!\x9e\xb2)_OH:\x9a\xb0\xa9\xa4*\x80c\xc4\ +}\xb8\x8ek\x80\x0fl_T\xac\xb0}1Q\xfc\x96\ +\x84\x8f\x17$\x1dN\xaa\xac\xa14\x00I\x0b\xc4\xec\xaf\ +4\x85\xed\xe1\x06`\xca\xf6\x05\xff\x14\xd8\xde@|l\ +\xb6&\xda\x9e \xe6\xfa\x03Q{#\xcb\x93\xad\x93\xc0\ +\xd5\x09?\x9f\x02\xb7\x03\xf3\xc4\xdd\xa6\xb8\xf8\x8bL\x03\ +\xbb$\xfd\xd9\x8f\xd8\xb2](y\xa5\xb4-b\x10J\ +\xf8\x9f\x22\x1eB\x13\x09\xbb\x19\xe2V\xfcs#\xd5=\ +\xb4\x0a\x00\x96r\xf6\x93\xc0\x15\xfdvZ\xc0\xc06I\ +?\xb4i\xdc\xfaN,\xe9;`'p\xa6M\xc79\ +?\x11\x0f\xaaV\xe2\xabh\x9c\xdfH:\x05\xec\x06~\ +m\xd1\xcf\xef\xc0\x1d\x92\xben\xd1\xb6\x96\xbe\x124I\ +_\x02{rAMY\x04\xf6I\xfa\xbc\x9f\xbe\x9a\xd2\ +w\x86)i\x1a\xb8\x93\x98\xbb4\xe1\x01I\xef\xf4\xdb\ +OSZ\xa5\xc8\x92>\x04\xf6\x11G\xb7\x8e\x83\x92^\ +n\xd3GSZ\xe7\xf8\x92N\x00\x07\x88\x89X\x19\xcf\ +Jz\xaa\xad\xff\xa6\x0ctI\x91t\x0c\xb8\x9f\xff\xae\ +\x89\xe7\x81\xc9A|7eE\xde\x8d\xda\x1e'\x9e\xbe\ +\x17\x02\x9f\xe4\xebd\xc5i}\x90\x0d\x0bU\x07\xd9B\ +7rV\x84\xf9Qbn\xd2\xfb~f]\x1e\xe90\ +R\xbc\xd5\xcd\x8c\x123\xc3\xe2\x0b\xa6\xba\xeb\xdf01\ +\xbd\xf6?5\xc8\xbf\xfa\xd8\x9f\x17\xac\x15f\x81\xfdY\ +\x96\xcd-\xfd\x99\x90\xcf\xc4!\xfe\xfd\xdc\xa6\xee]}\ +\x17\xcc\xb3\xfcs\x9b3\x00\x7f\x03\xd9\x1a\xfb\xdb\xbb\xa7\ +\x8f\x07\x00\x00\x00\x00IEND\xaeB`\x82\ +\x00\x00\x00\xa0\ \x89\ PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ \x00\x00\x06\x00\x00\x00\x09\x08\x04\x00\x00\x00\xbb\x93\x95\x16\ \x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\ \x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09p\ HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\ -\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x14\x1f \xb9\ -\x8dw\xe9\x00\x00\x00*IDAT\x08\xd7c`\xc0\ -\x06\xe6|```B0\xa1\x1c\x08\x93\x81\x81\x09\xc1\ -d``b`H\x11@\xe2 s\x19\x90\x8d@\x02\ -\x00#\xed\x08\xafd\x9f\x0f\x15\x00\x00\x00\x00IEN\ -D\xaeB`\x82\ +\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x14\x1f\x0d\xfc\ +R+\x9c\x00\x00\x00$IDAT\x08\xd7c`@\ +\x05s>\xc0XL\xc8\x5c&dY&d\xc5pN\ +\x8a\x00\x9c\x93\x22\x80a\x1a\x0a\x00\x00)\x95\x08\xaf\x88\ +\xac\xba4\x00\x00\x00\x00IEND\xaeB`\x82\ \x00\x00\x00\xa6\ \x89\ PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ @@ -816,6 +484,55 @@ HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\ \x05\xff\xcf\xc3XL\xc8\x5c&dY&d\xc5p\x0e\ \xa3!\x9c\xc3h\x88a\x1a\x0a\x00\x00m\x84\x09u7\ \x9e\xd9#\x00\x00\x00\x00IEND\xaeB`\x82\ +\x00\x00\x01[\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x000\x00\x00\x000\x08\x06\x00\x00\x00W\x02\xf9\x87\ +\x00\x00\x00\x09pHYs\x00\x00\x0b\x13\x00\x00\x0b\x13\ +\x01\x00\x9a\x9c\x18\x00\x00\x01\x0dIDATh\x81\xed\ +\xda\xb1m\x02A\x10F\xe1w\xc7\xe2\x0a,\x87\xd3\x00\ +8 'r\x17\x14\x83\x037\xe3.\x1cQ\x0240\ +!\xc2\x0d`\x90\x1c\xec\x9e\x0c'Y\xf6\x09\x89\xffV\ +\x9a/cE0\x0f\x0e\x92\x9d\x86\xc2\xdd\x1f\x81W`\ +\x09\xcc\x81)\xe3\xf2\x05l\x81\x0d\xf0ff\x07\x80\x06\ +\xc0\xdd_\x80w\xe0I6\xde0{`ef\x1fM\ +\xf9\xe4w\xd43|g\x0f\xccZ\xf2cS\xdb\xf0\x90\ +g^'\xf23\xdfw\xbe\xf30\xff5\xe9\xbd^&\ +\xf2\x0f\xf6\xd2\xd9\xcc\xd2\x9d\x06\x1a\xc4\xddO\x5cG<\ +\xb7\x8c\xef\xdff\x88i\xab\x9e\xe0V\x11\xa0\x16\x01j\ +\x11\xa0\x16\x01j\x11\xa0\x16\x01j\x11\xa0\x16\x01j\x11\ +\xa0\x16\x01j\x11\xa0\x16\x01j\x11\xa0\x16\x01j\x11\xa0\ +\x16\x01j\x11\xa0\xd6\x92o\xc0kuL\xe4\xeb\xfb\xc5\ +\xc5\xe1\xa4\xdc\x06\x8eQ\xff\x9au\x9b\xc8\xbb\x07\x8b?\ +\xde8V\x9b\xfaW\x0d\xca\xd6\xc7\xaa\x1c\xd4\xa2[\xf6\ +84\xddI\xf9&\xd6\xfc\xac\xdb<\x88\x86\xfb\xcd\x91\ +\xebu\x9bO\x80oV\x016\x1ew\x0d\xa5B\x00\x00\ +\x00\x00IEND\xaeB`\x82\ +\x00\x00\x00\xa6\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce|N\ +\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09p\ +HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\ +\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x08\x15;\xdc\ +;\x0c\x9b\x00\x00\x00*IDAT\x08\xd7c`\xc0\ +\x00\x8c\x0c\x0cs> \x0b\xa4\x08020 \x0b\xa6\ +\x08000B\x98\x10\xc1\x14\x01\x14\x13P\xb5\xa3\x01\ +\x00\xc6\xb9\x07\x90]f\x1f\x83\x00\x00\x00\x00IEN\ +D\xaeB`\x82\ +\x00\x00\x00\x9f\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce|N\ +\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09p\ +HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\ +\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x08\x14\x1f\xf9\ +#\xd9\x0b\x00\x00\x00#IDAT\x08\xd7c`\xc0\ +\x0d\xe6|\x80\xb1\x18\x91\x05R\x04\xe0B\x08\x15)\x02\ +\x0c\x0c\x8c\xc8\x02\x08\x95h\x00\x00\xac\xac\x07\x90Ne\ +4\xac\x00\x00\x00\x00IEND\xaeB`\x82\ \x00\x00\x07\xdd\ \x89\ PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ @@ -944,109 +661,147 @@ zpp\xf0\xe3\x0e.\xa4\xd2\xae\xf0\x8a\xf7\x9a\xe3V\ q[s\x5c@H\xa5\xdda\x81\x0d\x9ek\x8e\xff\xfd\ \xcf?\xcc1\xe9\x01\x1c\x00sR-q\xe4J\x1bi\ \x00\x00\x00\x00IEND\xaeB`\x82\ +\x00\x00\x07\x06\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00\x0a\x00\x00\x00\x07\x08\x06\x00\x00\x001\xac\xdcc\ +\x00\x00\x04\xb0iTXtXML:com.\ +adobe.xmp\x00\x00\x00\x00\x00\x0a\x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a\x0a\x85\x9d\x9f\x08\x00\x00\x01\x83\ +iCCPsRGB IEC6196\ +6-2.1\x00\x00(\x91u\x91\xcf+DQ\x14\ +\xc7?fh\xfc\x18\x8dba1e\x12\x16B\x83\x12\ +\x1b\x8b\x99\x18\x0a\x8b\x99Q~mf\x9ey3j\xde\ +x\xbd7\xd2d\xabl\xa7(\xb1\xf1k\xc1_\xc0V\ +Y+E\xa4d\xa7\xac\x89\x0dz\xce\x9bQ#\x99s\ +;\xf7|\xee\xf7\xdes\xba\xf7\x5cpD\xd3\x8afV\ +\xfaA\xcbd\x8dp(\xe0\x9b\x99\x9d\xf3\xb9\x9e\xa8\xa2\ +\x85\x1a:\xf1\xc6\x14S\x9f\x8c\x8cF)k\xef\xb7T\ +\xd8\xf1\xba\xdb\xaeU\xfe\xdc\xbfV\xb7\x980\x15\xa8\xa8\ +\x16\x1eVt#+<&<\xb1\x9a\xd5m\xde\x12n\ +RR\xb1E\xe1\x13\xe1.C.(|c\xeb\xf1\x22\ +?\xdb\x9c,\xf2\xa7\xcdF4\x1c\x04G\x83\xb0/\xf9\ +\x8b\xe3\xbfXI\x19\x9a\xb0\xbc\x9c6-\xbd\xa2\xfc\xdc\ +\xc7~\x89;\x91\x99\x8eHl\x15\xf7b\x12&D\x00\ +\x1f\xe3\x8c\x10d\x80^\x86d\x1e\xa0\x9b>zdE\ +\x99|\x7f!\x7f\x8ae\xc9Ud\xd6\xc9a\xb0D\x92\ +\x14Y\xbaD]\x91\xea\x09\x89\xaa\xe8\x09\x19irv\ +\xff\xff\xf6\xd5T\xfb\xfb\x8a\xd5\xdd\x01\xa8z\xb4\xac\xd7\ +vpm\xc2W\xde\xb2>\x0e,\xeb\xeb\x10\x9c\x0fp\ +\x9e)\xe5/\xef\xc3\xe0\x9b\xe8\xf9\x92\xd6\xb6\x07\x9eu\ +8\xbd(i\xf1m8\xdb\x80\xe6{=f\xc4\x0a\x92\ +S\xdc\xa1\xaa\xf0r\x0c\xf5\xb3\xd0x\x05\xb5\xf3\xc5\x9e\ +\xfd\xecst\x07\xd15\xf9\xaaK\xd8\xd9\x85\x0e9\xef\ +Y\xf8\x06\x8e\xfdg\xf8\xfd\x8a\x18\x97\x00\x00\x00\x09p\ +HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\ +\x00\x00\x00mIDAT\x18\x95u\xcf\xc1\x09\xc2P\ +\x10\x84\xe1\xd7\x85\x07\x9b\xd0C@\xd2\x82x\x14{0\ +W!\x8d\x84`?bKzH\xcc\x97\x83\xfb0\x04\ +\xdf\x9c\x86\x7fg\x99\xdd\x84\x0d\xaaT\x10jl\x13\x1e\ +\xbe\xba\xfe\x0951{\xe6\x8d\x0f&\x1c\x17\xa1S\xb0\ +\x11\x87\x0c/\x01\x07\xec\xb0\x0f?\xe1\xbc\xaei\xa3\xe6\ +\x85w\xf8[\xe9\xf0\xbb\x9f\xfa\xd2\x839\xdc\xa3[\xf3\ +\x19.\xa8\x89\xb50\xf7C\xa0\x00\x00\x00\x00IEN\ +D\xaeB`\x82\ \x00\x00\x00\xa6\ \x89\ PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ -\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce|N\ +\x00\x00\x06\x00\x00\x00\x09\x08\x04\x00\x00\x00\xbb\x93\x95\x16\ \x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\ \x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09p\ HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\ -\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x08\x15;\xdc\ -;\x0c\x9b\x00\x00\x00*IDAT\x08\xd7c`\xc0\ -\x00\x8c\x0c\x0cs> \x0b\xa4\x08020 \x0b\xa6\ -\x08000B\x98\x10\xc1\x14\x01\x14\x13P\xb5\xa3\x01\ -\x00\xc6\xb9\x07\x90]f\x1f\x83\x00\x00\x00\x00IEN\ +\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x14\x1f \xb9\ +\x8dw\xe9\x00\x00\x00*IDAT\x08\xd7c`\xc0\ +\x06\xe6|```B0\xa1\x1c\x08\x93\x81\x81\x09\xc1\ +d``b`H\x11@\xe2 s\x19\x90\x8d@\x02\ +\x00#\xed\x08\xafd\x9f\x0f\x15\x00\x00\x00\x00IEN\ D\xaeB`\x82\ -\x00\x00\x043\ +\x00\x00\x00\xa6\ \x89\ PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ -\x00\x000\x00\x00\x000\x08\x06\x00\x00\x00W\x02\xf9\x87\ -\x00\x00\x00\x09pHYs\x00\x00\x0b\x13\x00\x00\x0b\x13\ -\x01\x00\x9a\x9c\x18\x00\x00\x03\xe5IDATh\x81\xed\ -\x9aM\x88\x1cE\x14\xc7\x7f3;\x89.\x18\xf13\x1e\ -\x92\x8b\x8b\xa2&\x06\x14/\xa29\x88\x15\x89\xa9\x18\x15\ -\xd1\xca\x06\x0f\x91\x05=\x88bnB\xc0\x1c\x12\xc4\x83\ -\x07\x15\x0dB\x14\x89\x04\xa2\x96DY\x22/F}\x8a\ -\xb0\x22\x08\x1e4\xbb\x22F\x8c,\x88\xba\xc4\x88\x82_\ -\xc9F=T\x0f\x8c\xbd\xdd]\xdd\xd3a\xa7\x07\xfc\xdd\ -\xa6\xfa\xd5\xab\xf7\xea\xf3\xdf\xd5\xd3\x22\xc1Xw\x11\xb0\ -\x03X\x0b\x5c\x0d,\xa1Y\x9c\x02\xa6\x81)`\xa7\x8a\ -?\x0e\xd0\x020\xd6\xdd\x0c\xbc\x02,\x1fXx\xd5\x98\ -\x03\xb6\xa8\xf8\xf7[I\xcf\xcf0<\xc1w\x99\x03V\ -\xb7\x09\xd3f\xd8\x82\x87\x10\xf3c\x1d\xc2\x9cOsz\ -\x91\x83)\xcbH\xea\xf7\xda\x0ea\xc1\xf6rZ\xc5w\ -\x16)\xa0J\x18\xeb\xe6\xf9o\x12k\xda4o\xb7\xa9\ -\xc2\x92\xf6\xa0#\xa8\xcb\xff\x09\x0c\x9a\xa1O\xa0\xa9\xbb\ -\xcd=\xc0]\xc0K*\xfe\xdd\x22\xdb\xc6\x8d\x80\xb1\xee\ -\x11\xc0\x03\xe3\xc0ac\xddnc]\xeeN\xd9\xa8\x04\ -\x8cu\xe3\xc0S=E-\xe0A\xe0\x85\xbc:\x8d\x99\ -B\xc6\xbau\xc0\xcb$\x023\xc5Vc\xdd\x91\xacz\ -\x8d\x18\x01c\xddu\xc0\x1b\xc0\xd2\x02\xb3\x0dY\x85\x03\ -O\xc0Xw\x19 \xc0\xb2\x88\xe9\x8bY\x85\x03M\xc0\ -Xw\x09p\x98\xb8\x1a~R\xc5\xbf\x9a\xf5``\x09\ -\x18\xeb\x96\x01\x87\x80\xb1\x88\xe9>\xe0\xd1\xbc\x87\x03I\ -\xc0X\xb7\x14x\x13\xb86b\xfa60\xa1\xe2\xff\xc9\ -3X\xf4\x04\x8cumB\xaf\x9a\x88\xe9'\xc0\xdd*\ -~\xbe\xc8h\x10#\xf04\xe0\x226_\x01\x1bU\xfc\ -o1g\xa5\x120\xd6\xb5\x92\x9e\xab\x85\xb1n;\xf0\ -p\xc4\xec{`}\xf7\xd6!FaPI\xe0\xdb\x80\ -?\x80ic\xdd\x9aR\x91f\xfb\x9a\x00\x1e\x8f\x98\xfd\ -\x02\xdc\xaa\xe2\xbf-\xeb77\x81D\x7fL\x12\x8e\xf6\ -\xb3\x80\xab\x80\xf7\x8cuW\x94u\xde\xe3k\x13\xb0'\ -b\xf6\x17p\x87\x8a\xff\xbc\x8a\xef\xa2\x11x\x0e\xd8\x94\ -*[\x0e\xa8\xb1\xee\xd2\xb2\x0d\x18\xebn\x00^c\xe1\ -\x0by/\x7f\x03\xf7\xaa\xf8\x0f\xcb\xfa\xed\x92\x99@\xd2\ -c\x0f\xe4\xd4YA\x18\x89\x151\xe7\xc6\xbaU\xc0A\ -`4b\xfa\x90\x8a?\x10\xf3\x97E\xde\x08\x5c\x10\xa9\ -7FH\xe2\xe2<\x03c\xddJ\xc2)\x1b\xf3\xb5K\ -\xc5?\x1f\xb1\xc9%/\x81\xfd\x84}\xb8\x88+\x81w\ -\x8cu\xe7\xa5\x1f\x18\xeb\xce'\x04\xbf2\xe2c\x8f\x8a\ -\xdf\x11\x8d\xb2\x80\xcc\x04T\xfc)\x82\xfa\xcb\x94\xb0=\ -\x5c\x03\x1c2\xd6\x9d\xd3-0\xd6\x8d\x12\xa6\xcd\xaaH\ -\xddI\x82\xd6\xafE\xee\x22V\xf1'\x80[\x80\xa3\x11\ -\x1f\xd7\x03\x07\x8du\xa3\xc6\xba\x11\xc2\x82\xbd1Rg\ -\x0a\x18W\xf1\xb5o\x00\x0b\xcf\x01\x15\xff#\xb0\x0e\x98\ -\x8d\xf8\xb9\x098@\xd8*\xd3;W\x9ai\xe0v\x15\ -\xffg\xc9\x18\x0b\x89\x9e\xae*~\x96\xa0[~\x88\x98\ -n\x00&\x226\xb3\x84\x83\xea\xe7r\xe1\xc5)%\x0f\ -T\xfc\xd7\x84\x91\xf8\xa9F['\x08\x12\xe1\xbb\x1a>\ -\x16PZ\xdf\xa8\xf8\x19`=\xf0k\x1f\xed\xfc\x0e\xdc\ -\xa6\xe2\xbf\xec\xa3n!\x95\x04\x9a\x8a\xff\x14\xd8\x98\x04\ -T\x96y`\xb3\x8a\xff\xb8J[e\xa9\xac0U\xfc\ -\x14p'A\xbb\x94\xe1~\x15\xffV\xd5v\xca\xd2\x97\ -DNn\xcb6\x13z\xb7\x88\xed*~o?m\x94\ -\xa5o\x8d\xaf\xe2'\x81\xad\x04!\x96\xc5\xb3*\xfe\x89\ -~\xfd\x97\xa5\xd6K\x8a\x8a\xdf\x0f\xdc\xc7\xc25\xb1\x1b\ -\xd8V\xc7wYj\xdf\xcc\xa9\xf8}\xc6\xba\x8f\x08\x07\ -\xd8\xb9\xc0\x07\xc9:Y\x14\xce\xc8\xd5\xa2\x8a\xff\x06x\ -\xe6L\xf8\xaaJ\x9b\xf0\x05|X9\xd9!h\x93\xde\ -\xfb\x99\x91\xe4k`\x13I\xbf\xd5Mw\x08\xca0}\ -\xc1T\xf4\xfa\xd7$\xa6\xda\xc0N\xc2g\xfbac\x0e\ -\xd8\xd5N\xee_\xb60\x5cIt\xff\xecq|\x04\xe0\ -\xd8\xd1\x99cc\x97\xaf\xde\x0b\x9cM\xf8\xf0}!\xcd\ -\x9bF'\x81\xcf\x80\xd7\x01\xa7\xe2\xbf\x00\xf8\x17]\x81\ -\x0b8\xb3\xfa \x9c\x00\x00\x00\x00IEND\xaeB\ -`\x82\ -\x00\x00\x00\xa5\ -\x89\ -PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ -\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce|N\ +\x00\x00\x06\x00\x00\x00\x09\x08\x04\x00\x00\x00\xbb\x93\x95\x16\ \x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\ -\x02bKGD\x00\x9cS4\xfc]\x00\x00\x00\x09p\ +\x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09p\ HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\ -\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x0b\x02\x04m\ -\x98\x1bi\x00\x00\x00)IDAT\x08\xd7c`\xc0\ -\x00\x8c\x0c\x0c\xff\xcf\xa3\x08\x18220 \x0b2\x1a\ -200B\x98\x10AFC\x14\x13P\xb5\xa3\x01\x00\ -\xd6\x10\x07\xd2/H\xdfJ\x00\x00\x00\x00IEND\ -\xaeB`\x82\ -\x00\x00\x00E\ -\x89\ -PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ -\x00\x00\x01\x00\x00\x00\x01\x08\x02\x00\x00\x00\x90wS\xde\ -\x00\x00\x00\x0cIDAT\x08\x99c```\x00\x00\ -\x00\x04\x00\x01\xa3\x0a\x15\xe3\x00\x00\x00\x00IEND\ -\xaeB`\x82\ +\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x14\x1d\x00\xb0\ +\xd55\xa3\x00\x00\x00*IDAT\x08\xd7c`\xc0\ +\x06\xfe\x9fg``B0\xa1\x1c\x08\x93\x81\x81\x09\xc1\ +d``b``4D\xe2 s\x19\x90\x8d@\x02\ +\x00d@\x09u\x86\xb3\xad\x9c\x00\x00\x00\x00IEN\ +D\xaeB`\x82\ \x00\x00\x01v\ \x89\ PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ @@ -1073,6 +828,19 @@ m\xd3\xc7\xc8\xa9'\xf8/\x0bP\xb3\x005\x0bP\xb3\ \xc5\xf7%\xc3;F{\xe0\x03x\x03\x8a\xba*\xd7\x00\ \xdf\xa4\xb56\xa2\xca\x99tG\x00\x00\x00\x00IEN\ D\xaeB`\x82\ +\x00\x00\x00\xa6\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00\x06\x00\x00\x00\x09\x08\x04\x00\x00\x00\xbb\x93\x95\x16\ +\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09p\ +HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\ +\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x14\x1d\x00\xb0\ +\xd55\xa3\x00\x00\x00*IDAT\x08\xd7c`\xc0\ +\x06\xfe\x9fg``B0\xa1\x1c\x08\x93\x81\x81\x09\xc1\ +d``b``4D\xe2 s\x19\x90\x8d@\x02\ +\x00d@\x09u\x86\xb3\xad\x9c\x00\x00\x00\x00IEN\ +D\xaeB`\x82\ \x00\x00\x00\xa0\ \x89\ PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ @@ -1080,11 +848,11 @@ PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ \x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\ \x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09p\ HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\ -\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x14\x1f\x0d\xfc\ -R+\x9c\x00\x00\x00$IDAT\x08\xd7c`@\ -\x05s>\xc0XL\xc8\x5c&dY&d\xc5pN\ -\x8a\x00\x9c\x93\x22\x80a\x1a\x0a\x00\x00)\x95\x08\xaf\x88\ -\xac\xba4\x00\x00\x00\x00IEND\xaeB`\x82\ +\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x14\x1c\x1f$\ +\xc6\x09\x17\x00\x00\x00$IDAT\x08\xd7c`@\ +\x05\xff\xcf\xc3XL\xc8\x5c&dY&d\xc5p\x0e\ +\xa3!\x9c\xc3h\x88a\x1a\x0a\x00\x00m\x84\x09u7\ +\x9e\xd9#\x00\x00\x00\x00IEND\xaeB`\x82\ \x00\x00\x00\xa5\ \x89\ PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ @@ -1098,30 +866,18 @@ HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\ 200B\x98\x10AFC\x14\x13P\xb5\xa3\x01\x00\ \xd6\x10\x07\xd2/H\xdfJ\x00\x00\x00\x00IEND\ \xaeB`\x82\ -\x00\x00\x01[\ +\x00\x00\x00\x9e\ \x89\ PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ -\x00\x000\x00\x00\x000\x08\x06\x00\x00\x00W\x02\xf9\x87\ -\x00\x00\x00\x09pHYs\x00\x00\x0b\x13\x00\x00\x0b\x13\ -\x01\x00\x9a\x9c\x18\x00\x00\x01\x0dIDATh\x81\xed\ -\xda\xb1m\x02A\x10F\xe1w\xc7\xe2\x0a,\x87\xd3\x00\ -8 'r\x17\x14\x83\x037\xe3.\x1cQ\x0240\ -!\xc2\x0d`\x90\x1c\xec\x9e\x0c'Y\xf6\x09\x89\xffV\ -\x9a/cE0\x0f\x0e\x92\x9d\x86\xc2\xdd\x1f\x81W`\ -\x09\xcc\x81)\xe3\xf2\x05l\x81\x0d\xf0ff\x07\x80\x06\ -\xc0\xdd_\x80w\xe0I6\xde0{`ef\x1fM\ -\xf9\xe4w\xd43|g\x0f\xccZ\xf2cS\xdb\xf0\x90\ -g^'\xf23\xdfw\xbe\xf30\xff5\xe9\xbd^&\ -\xf2\x0f\xf6\xd2\xd9\xcc\xd2\x9d\x06\x1a\xc4\xddO\x5cG<\ -\xb7\x8c\xef\xdff\x88i\xab\x9e\xe0V\x11\xa0\x16\x01j\ -\x11\xa0\x16\x01j\x11\xa0\x16\x01j\x11\xa0\x16\x01j\x11\ -\xa0\x16\x01j\x11\xa0\x16\x01j\x11\xa0\x16\x01j\x11\xa0\ -\x16\x01j\x11\xa0\xd6\x92o\xc0kuL\xe4\xeb\xfb\xc5\ -\xc5\xe1\xa4\xdc\x06\x8eQ\xff\x9au\x9b\xc8\xbb\x07\x8b?\ -\xde8V\x9b\xfaW\x0d\xca\xd6\xc7\xaa\x1c\xd4\xa2[\xf6\ -84\xddI\xf9&\xd6\xfc\xac\xdb<\x88\x86\xfb\xcd\x91\ -\xebu\x9bO\x80oV\x016\x1ew\x0d\xa5B\x00\x00\ -\x00\x00IEND\xaeB`\x82\ +\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce|N\ +\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09p\ +HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\ +\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x08\x15\x0f\xfd\ +\x8f\xf8.\x00\x00\x00\x22IDAT\x08\xd7c`\xc0\ +\x0d\xfe\x9f\x87\xb1\x18\x91\x05\x18\x0d\xe1BH*\x0c\x19\ +\x18\x18\x91\x05\x10*\xd1\x00\x00\xca\xb5\x07\xd2v\xbb\xb2\ +\xc5\x00\x00\x00\x00IEND\xaeB`\x82\ \x00\x00\x01\xef\ \x89\ PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ @@ -1155,43 +911,371 @@ f\xaf\xd1\x10\xa5T\x13h\xa6\x18,U6\xfa\x10g\ D8\xec\xd1\xb3\xc27\xc1\xd0G\x8d\xdfq\x9b-\xa1\ pQ\xf4\x99\x1c\xb7\xf9\x04\xf8\x01o\xedXc-\xfd\ \xb2Y\x00\x00\x00\x00IEND\xaeB`\x82\ -\x00\x00\x00\xa0\ +\x00\x00\x070\ \x89\ PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ -\x00\x00\x06\x00\x00\x00\x09\x08\x04\x00\x00\x00\xbb\x93\x95\x16\ -\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\ -\x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09p\ +\x00\x00\x0a\x00\x00\x00\x07\x08\x06\x00\x00\x001\xac\xdcc\ +\x00\x00\x04\xb0iTXtXML:com.\ +adobe.xmp\x00\x00\x00\x00\x00\x0a\x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a\x0aH\x8b[^\x00\x00\x01\x83\ +iCCPsRGB IEC6196\ +6-2.1\x00\x00(\x91u\x91\xcf+DQ\x14\ +\xc7?fh\xfc\x18\x8dba1e\x12\x16B\x83\x12\ +\x1b\x8b\x99\x18\x0a\x8b\x99Q~mf\x9ey3j\xde\ +x\xbd7\xd2d\xabl\xa7(\xb1\xf1k\xc1_\xc0V\ +Y+E\xa4d\xa7\xac\x89\x0dz\xce\x9bQ#\x99s\ +;\xf7|\xee\xf7\xdes\xba\xf7\x5cpD\xd3\x8afV\ +\xfaA\xcbd\x8dp(\xe0\x9b\x99\x9d\xf3\xb9\x9e\xa8\xa2\ +\x85\x1a:\xf1\xc6\x14S\x9f\x8c\x8cF)k\xef\xb7T\ +\xd8\xf1\xba\xdb\xaeU\xfe\xdc\xbfV\xb7\x980\x15\xa8\xa8\ +\x16\x1eVt#+<&<\xb1\x9a\xd5m\xde\x12n\ +RR\xb1E\xe1\x13\xe1.C.(|c\xeb\xf1\x22\ +?\xdb\x9c,\xf2\xa7\xcdF4\x1c\x04G\x83\xb0/\xf9\ +\x8b\xe3\xbfXI\x19\x9a\xb0\xbc\x9c6-\xbd\xa2\xfc\xdc\ +\xc7~\x89;\x91\x99\x8eHl\x15\xf7b\x12&D\x00\ +\x1f\xe3\x8c\x10d\x80^\x86d\x1e\xa0\x9b>zdE\ +\x99|\x7f!\x7f\x8ae\xc9Ud\xd6\xc9a\xb0D\x92\ +\x14Y\xbaD]\x91\xea\x09\x89\xaa\xe8\x09\x19irv\ +\xff\xff\xf6\xd5T\xfb\xfb\x8a\xd5\xdd\x01\xa8z\xb4\xac\xd7\ +vpm\xc2W\xde\xb2>\x0e,\xeb\xeb\x10\x9c\x0fp\ +\x9e)\xe5/\xef\xc3\xe0\x9b\xe8\xf9\x92\xd6\xb6\x07\x9eu\ +8\xbd(i\xf1m8\xdb\x80\xe6{=f\xc4\x0a\x92\ +S\xdc\xa1\xaa\xf0r\x0c\xf5\xb3\xd0x\x05\xb5\xf3\xc5\x9e\ +\xfd\xecst\x07\xd15\xf9\xaaK\xd8\xd9\x85\x0e9\xef\ +Y\xf8\x06\x8e\xfdg\xf8\xfd\x8a\x18\x97\x00\x00\x00\x09p\ HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\ -\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x14\x1c\x1f$\ -\xc6\x09\x17\x00\x00\x00$IDAT\x08\xd7c`@\ -\x05\xff\xcf\xc3XL\xc8\x5c&dY&d\xc5p\x0e\ -\xa3!\x9c\xc3h\x88a\x1a\x0a\x00\x00m\x84\x09u7\ -\x9e\xd9#\x00\x00\x00\x00IEND\xaeB`\x82\ -\x00\x00\x01i\ +\x00\x00\x00\x97IDAT\x18\x95m\xcf\xb1j\x02A\ +\x14\x85\xe1o\xb7\xb6\xd0'H=Vi\x03\xb1\xb4H\ +;l\xa5\xf19\xf6Y\x02VB\xbaa\x0a\x0b;\x1b\ +\x1bkA\x18\x02)m\xe3\xbe\x82\xcd\x06\x16\xd9\xdb\xdd\ +\x9f\xff\x5c\xee\xa9b*\x13Ls\x13nF&\xa6\xf2\ +\x82\xaeF\x8b\xdf\x98\xca\xfb\x88\xb4\xc0\x0f\xda\x1a[t\ +\xd8\xc7T\xc2@\x9ac\x8f?|U=|\xc5\x09w\ +\xbc\xa1\xc2\x193,r\x13.\xd5\xe0\xc2\x12\x07\x5cQ\ +#\xe0#7\xe1\xa8O\x0e\x7f\xda`\xd7\xaf\x9f\xb9\x09\ +\xdfc\x05\xff\xe5uLe\xf5\xcc\x1f\x0d3,\x83\xb6\ +\x06D\x83\x00\x00\x00\x00IEND\xaeB`\x82\ +\x00\x00\x01\xdc\ \x89\ PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ \x00\x000\x00\x00\x000\x08\x06\x00\x00\x00W\x02\xf9\x87\ \x00\x00\x00\x09pHYs\x00\x00\x0b\x13\x00\x00\x0b\x13\ -\x01\x00\x9a\x9c\x18\x00\x00\x01\x1bIDATh\x81\xed\ -\xda\xb1m\xc2@\x14\x87\xf1\xcf\xc7\x91\x09P\x86pB\ -AO\xc5\x0a\xae\x90\xbc\x0a)\xc8*\x96Ry\x05*\ -F \x1e\xc2\x82\x05H\x90R\xdcY\x01KQbE\ -\xe2\xef\x93\xde\xaf\xb3E\xf1>\xcb\xa6\xb9\x97\x11\x95u\ -3\x03^\x80%\xf0\x0cL\x19\x97\x0f\xe0\x00\xec\x81m\ -U\xe4G\x80\x0c\xa0\xac\x9b\x15\xf0\x06<\xca\xc6\x1b\xa6\ -\x05\xd6U\x91\xef\xb2\xf8\xe4\xdfIg\xf8N\x0b<9\ -\xc2k\x93\xda\xf0\x10f\xdex\xc2;\xdfw\xb9\xf30\ -\x7f5\xe9]/=\xe1\x83\xbdv\xa9\x8a\xdc\xdfi\xa0\ -A\xca\xba\xf9\xe46b\xee\x18\xdf\xbf\xcd\x10S\xa7\x9e\ -\xe0\xbf,@\xcd\x02\xd4,@\xcd\x02\xd4,@\xcd\x02\ -\xd4,@\xcd\x02\xd4,@\xcd\x02\xd4,@\xcd\x02\xd4\ -,@\xcd\x02\xd4,@\xcd\x02\xd4,@\xcd\x11N\xc0\ -Su\xf6\x84\xe3\xfb\xc5\xd5\xcdI<\x0d\x1c\xa3\xfe1\ -\xeb\xc1\x13v\x0f\x16\xbf\xfcp\xac\xf6\x0e\xd8\x12\x8e\xed\ -S\xd3\x02\xaf.n}\xacI+\xa2[\xf68f\xdd\ -\x9d\xb8\xf4\xb1\xe1{\xdd\xe6A4\xdcO\xce\xdc\xae\xdb\ -\x9c\x00\xbe\x00\x9f\xf64>6O7\x81\x00\x00\x00\x00\ -IEND\xaeB`\x82\ +\x01\x00\x9a\x9c\x18\x00\x00\x01\x8eIDATh\x81\xed\ +\x9a\xafN\xc3P\x14\x87\xbfn\x1d\x0a\x1cA\x1e\x83\x04\ +\xc4\x0cjA\x10\x04\x82\x80\x9e\xe7\x05x\x80!x\x01\ +^\x00\x8f\xc2\x00rA\x90=\xc2@1s\xe42\x14\ +\xc1\xecO\x82h\x1b\xb6e\xed(\xebv\xda\xe5~\xae\ +\xf7\x5c\xf1\xfb\xda{o\x9a\xdc\xe3\x11\xa2\xaa\xdb\xc05\ +P\x03\xf6\x81\x0a\xf9b\x00\xb4\x81\x16p#\x22=\x00\ +\x0f@U\x8f\x81{`\xc7,^:\xba@]D^\ +\xbc\xf0\xcd\xbfQ\x9c\xf0\x11]`\xafD\xb0l\x8a\x16\ +\x1e\x82\xcc\x0d\x9f`\xcdO3Zq\x98\xbfR\x9ez\ +\xae\xf9\x04\x1bv\x9c\x91\x88\xf8+\x0a\x94\x0aU\x1d2\ +)qP\x22\x7f\xa7M\x1a*%\xeb\x04\x8b\xe2\x04\xac\ +q\x02\xd68\x01k\x9c\x805N\xc0\x1a'`\xcd\xdc\ +\xdffU=\x01\x0e\x81\xcd\xe5\xc7\x99`\x08\xbc\x03O\ +\x22\xf2\x1d7)V@U}\xe0\x018\xcf>[*\ +:\xaaz*\x22\x1f\xb3\x8aIK\xe8\x0a\xfb\xf0\x00\xbb\ +\xc0]\x5c1I\xe0,\xfb,\xff\xe6HU\xb7f\x15\ +\x0a\xbf\x89\x93\x04\x9eW\x96b>\xaf\x22\xf25\xab\x90\ +$p\x0b<.'O*:\xc0e\x5c1\xf6\x14\x12\ +\x91!pQ\xd8c4BD\x9a@3\xc3`\x99\xb2\ +\xd6\x9b\xb8\x108\x01k\x9c\x805N\xc0\x1a'`\x8d\ +\x13\xb0f-\x04\x06\xd6!\x16\xa0\xef\x13\x5c\xdfW\xc7\ +\x06\xcb\xe1m`\x1e\x99\xbefm\xfb\x04\xbd\x07\xd59\ +\x13\xf3J\xab\xf8\xad\x06a\xd7G=\x1c(\x0aQ\xb3\ +G\xcf\x8bF\xc2/\xd1\xe0\xb7\xddf\xc3(\x5c\x1c}\ +&\xdbm>\x01~\x00%\xf8ZCUN:\x7f\x00\ +\x00\x00\x00IEND\xaeB`\x82\ +\x00\x00\x05~\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00\x01\x00\x00\x00\x01\x08\x06\x00\x00\x00\x1f\x15\xc4\x89\ +\x00\x00\x00\x09pHYs\x00\x00\x0b\x13\x00\x00\x0b\x13\ +\x01\x00\x9a\x9c\x18\x00\x00\x05\x17iTXtXML\ +:com.adobe.xmp\x00\x00\ +\x00\x00\x00 \ + \x07b\x0c\x81\x00\x00\x00\x0dIDAT\ +\x08\x1dc\xf8\xff\xff?\x03\x00\x08\xfc\x02\xfe\xe6\x0c\xff\ +\xab\x00\x00\x00\x00IEND\xaeB`\x82\ +\x00\x00\x00\x9e\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce|N\ +\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09p\ +HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\ +\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x08\x15\x0f\xfd\ +\x8f\xf8.\x00\x00\x00\x22IDAT\x08\xd7c`\xc0\ +\x0d\xfe\x9f\x87\xb1\x18\x91\x05\x18\x0d\xe1BH*\x0c\x19\ +\x18\x18\x91\x05\x10*\xd1\x00\x00\xca\xb5\x07\xd2v\xbb\xb2\ +\xc5\x00\x00\x00\x00IEND\xaeB`\x82\ +\x00\x00\x01\xe1\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x000\x00\x00\x000\x08\x06\x00\x00\x00W\x02\xf9\x87\ +\x00\x00\x00\x09pHYs\x00\x00\x0b\x13\x00\x00\x0b\x13\ +\x01\x00\x9a\x9c\x18\x00\x00\x01\x93IDATh\x81\xed\ +\x9a;N\xc3@\x10\x86\xbfq\x1c*\xe8\x10\xe56\x94\ +\xd0\xa4\xa1\x8a(\x22\x0a\x0aD\x9f\x9e\x0bp\x80Pp\ +\x01.\xc0\x15h\x80\x13\xa0\x1c!P\x91f\xbbD\xa1\ +B4yh(l\x1e\xb1\xfcH\x08\xc9\xda\xd2~\x9d\ +w\x5c\xfc\x9f\xb3\x1e9\xda\x11bTu\x17\xb8\x02\x9a\ +\xc0!P\xa7\x5cL\x80\x1e\xd0\x05\xaeEd\xf4]Q\ +\xd5\x96\xaa\x0e\xb4:\x0cT\xb5\x05 \x1a=\xf9g`\ +\xcf\xc5c]\x81!p\x10\x10m\x9b\xaa\x85\x87(s\ +'$\xda\xf3If\x1b\x0e\xb3(\xb5\xc4uSTu\ +\xcc\xfc\x0b;\x13\x91p\x83\xa1\x16FU\xa7\xccKL\ +\x02\xca\xd7m\x96\xa1\x1e\xb8N\xb0*^\xc05^\xc0\ +5^\xc05^\xc05^\xc05^\xc05\x85\x9f\xcd\ +\xd6\xda\x13\xe0\x08\xd8^\x7f\x9c9\xa6\xc0\x0b\xf0`\x8c\ +\xf9\xc8\xbaITU\x13k3\x11\x09\xad\xb5!p\x07\ +\x9c\xaf1\xe4\x22\xf4\x81Sc\xcck\xca\xff\x81\xdc-\ +t\x89\xfb\xf0\x00\xfb\xc0mV1O\xe0\xec\xff\xb3\xfc\ +\x99ck\xedNZ\xa1\xf2/q\x9e\xc0\xe3\xc6R\x14\ +\xf3d\x8cyO+\xe4\x09\xdc\x00\xf7\xeb\xc9\xb3\x14}\ +\xe0\x22\xab\x98\xd9\x85\xbe.\xca\xd4F\xd3\xbaP\xa1@\ +\x99X\xb6\x8dV\x02/\xe0\x1a/\xe0\x1a/\xe0\x1a/\ +\xe0\x1a/\xe0\x1a/\xe0\x9a\x80\xe8\x04\xbc\xaa\x8cC\xa2\ +\xe3\xfb\xc6\xaf\xc5Z\xfc\xd9ZF\x92\xc7\xac\xbd\x90h\ +\xf6\xa0QpcY\xe9V\x7f\xd4 \x9e\xfah\xc7\x0b\ +Ua\x08\xb4Ed$_+\xf1/\xd1\xe1g\xdcf\ +\xcbQ\xb8,\xc6\xcc\x8f\xdb\xbc\x01|\x02mw#\xb3\ +\xd4\x95Sv\x00\x00\x00\x00IEND\xaeB`\x82\ +\ +\x00\x00\x00\xa5\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce|N\ +\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x02bKGD\x00\x9cS4\xfc]\x00\x00\x00\x09p\ +HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\ +\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x0b\x02\x04m\ +\x98\x1bi\x00\x00\x00)IDAT\x08\xd7c`\xc0\ +\x00\x8c\x0c\x0c\xff\xcf\xa3\x08\x18220 \x0b2\x1a\ +200B\x98\x10AFC\x14\x13P\xb5\xa3\x01\x00\ +\xd6\x10\x07\xd2/H\xdfJ\x00\x00\x00\x00IEND\ +\xaeB`\x82\ +\x00\x00\x04\x12\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x000\x00\x00\x000\x08\x06\x00\x00\x00W\x02\xf9\x87\ +\x00\x00\x00\x09pHYs\x00\x00\x0b\x13\x00\x00\x0b\x13\ +\x01\x00\x9a\x9c\x18\x00\x00\x03\xc4IDATh\x81\xed\ +\x9a_\x88\x94U\x18\xc6\x7f3;\x1a\x0b\x19\x15f\x17\ +\xca\x03IPM\x09J7Q^D)&f\x05[\ +\xb9\xd2\x82\xb1P\x17\x91$t\x11\x08z\xa1D\x17]\ +T\x94\x04\xd6E\xe1\xa2\x15L\xb1\x18\x99\xfd%\xd8\x08\ +\x82nj]\xa4\x22\xe2\x81\xa8\x96\xd5(\xe8\x9f\xae\xd5\ +\xc5\xf9\xb6\xc6\xd9\xf9\xbesf\xc6vf\xc0\xdf\xdd\x9c\ +\xef=\xefy\x9fs\xe6\x9c\xf3~\xdf9%2Fj\ +SK\x81\xdd\xc0Z\xe0:`\x11\xbd\xc5i`\x12\x98\ +\x00\xf6\x8c\x0dUg\x00J\x00#\xb5\xa9[\x80C\xc0\ +\xb2\xae\x85\xd7\x1a\xd3\xc0\xd6\xb1\xa1\xea\x07\xa5\xac\xe7\x8f\ +\xd1?\xc1\xcf1\x0d\x5c[&\xfcm\xfa-x\x081\ +\xef\xaa\x10\xfe\xf3\x8d\x9cY\xe0`R\x19h\xf8\xbd\xb6\ +B\x98\xb0\xf5\x9c\x19\x1b\xaaV\x16(\xa0\x96\x18\xa9M\ +\xcdr\xb6\x88Uezo\xb5i\x85E\xe5nG\xd0\ +)\xe7\x05t\x9b\xf3\x02\xfe\x0fl\xdfc\xfb\x90\xed\xf5\ +1\xdb\x9e\x13`\xfb\x11\xe05`\x188j{\x9f\xed\ +\xdc\x95\xb2\xa7\x04\xd8\x1e\x06\x9e\xaa+*\x01\x0f\x01/\ +\xe4\xd5\xe9\x19\x01\xb6\xd7\x01/\x93%\x98\x0dl\xb3\xfd\ +h\xb3z=!\xc0\xf6\xf5\xc0\xeb\xc0\xe2\x02\xb3\x8d\xcd\ +\x0a\xbb.\xc0\xf6\x95\xc0[\xc0\x92\x88\xe9\x8b\xcd\x0a\xbb\ +*\xc0\xf6\xe5\xc0Q\xe2\xd9\xf0\x93\x92^i\xf6\xa0k\ +\x02l/\x01\x8e\x00+#\xa6\x07\x80\xc7\xf2\x1evE\ +\x80\xed\xc5\xc0\x1b\xc0\x9a\x88\xe9\xdb\xc0\xa8\xa4\xbf\xf3\x0c\ +\x16\x5c\x80\xed2\xa1Wo\x8d\x98~\x0a\xdc-i\xb6\ +\xc8\xa8\x1b#\xf04po\xc4\xe6K`\x93\xa4_c\ +\xce\x92\x04\xd8.e=\xd7\x11\xb6w\x02\xdb#f\xdf\ +\x03\x1b$\xcd\xa4\xf8,\x0c*\x0b|\x07\xf0;0i\ +{UR\xa4\xcd}\x8d\x02\x8fG\xcc~\x06n\x93\xf4\ +m\xaa\xdf\x5c\x01Y\xfe1N\xd8\xda/\x00\xae\x01\xde\ +\xb3}U\xaa\xf3:_\x9b\x81\xfd\x11\xb3?\x81;%\ +}\xde\x8a\xef\xa2\x11x\x0e\xd8\xdcP\xb6\x0cx\xdf\xf6\ +\x15\xa9\x0d\xd8\xbe\x11x\x95\xf9/\xe4\xf5\xfc\x05\xdc'\ +\xe9\xa3T\xbfs4\x15\x90\xf5\xd8\x839u\x96\x13F\ +by\xcc\xb9\xed*p\x18\x18\x8c\x98>,\xa9\x16\xf3\ +\xd7\x8c\xbc\x11\xb84Ro%A\xc4ey\x06\xb6W\ +\x10v\xd9\x98\xaf\xbd\x92\x9e\x8f\xd8\xe4\x92'\xe0 a\ +\x1d.\xe2j\xe0\x1d\xdb\x177>\xb0}\x09!\xf8\x15\ +\x11\x1f\xfb%\xed\x8eFY@S\x01\x92N\x13\xb2\xbf\ +/\x22\xf5W\x03Gl_8W`{\x90\xf0\xb7\xa9\ +F\xea\x8e\x13r\xfd\x8e\xc8\x9d\xc4\x92N\x02\xeb\x81\xaf\ +\x22>n\x00\x0e\xdb\x1e\xb4=@\x98\xb07E\xeaL\ +\x00\xc3\x92:\xfe\x02X\xb8\x0fH\xfa\x11X\x078\xe2\ +\xe7f\xa0FX*\x1bW\xaeF&\x81;$\xfd\x91\ +\x18c!\xd1\xddU\x92\x09y\xcb\x0f\x11\xd3\x8d\xc0h\ +\xc4\xc6\x84\x8d\xea\xa7\xb4\xf0\xe2$\xa5\x07\x92\xbe&\x8c\ +\xc4\x89\x0e\xda:IH\x11\xbe\xeb\xc0\xc7<\x92\xf3\x1b\ +I\xc7\x80\x0d\xc0/m\xb4\xf3\x1bp\xbb\xa4\xe3m\xd4\ +-\xa4\xa5\x04M\xd2g\xc0\xa6,\xa0Tf\x81-\x92\ +>i\xa5\xadTZ\xce0%M\x00w\x11r\x97\x14\ +\x1e\x90\xf4f\xab\xed\xa4\xd2V\x8a,\xe9]`\x0b\xa1\ +w\x8b\xd8)\xe9\xa5v\xdaH\xa5\xed\x1c_\xd28\xb0\ +\x8d\x90\x885\xe3YIO\xb4\xeb?\x95\x8e^R$\ +\x1d\x04\xeeg\xfe\x9c\xd8\x07\xec\xe8\xc4w*\x1d\x1f%\ +I:`\xfbc\xc2\x06v\x11\xf0a6O\x16\x84s\ +r\x16&\xe9\x1b\xe0\x99s\xe1\xabU\xca\x84\x13\xf0~\ +\xe5T\x85\x90\x9b\xd4\x7f\x9f\x19\xc8N\x03{\x91\xc6\xb7\ +\xba\xc9\x0a!3l\xfc\xc0T\xf4\xfa\xd7KL\x94\x81\ +=\x84c\xfb~c\x1a\xd8[\xcen}l\xa5\xbfD\ +\xcc]\xf6\x98\xf9\xf70!\xbb\xf4\xb1\x8b\xff\xae\xdb\x14\ +}\xab\xef\x06\xa78\xfb\xba\xcd\x09\x80\x7f\x00\xc4\x1e\x10\ +)3[\x85\xf7\x00\x00\x00\x00IEND\xaeB`\ +\x82\ " qt_resource_name = b"\ @@ -1203,198 +1287,198 @@ qt_resource_name = b"\ \x07\x03}\xc3\ \x00i\ \x00m\x00a\x00g\x00e\x00s\ -\x00\x1a\ -\x03\x0e\xe4\x87\ -\x00c\ -\x00h\x00e\x00c\x00k\x00b\x00o\x00x\x00_\x00c\x00h\x00e\x00c\x00k\x00e\x00d\x00_\ -\x00h\x00o\x00v\x00e\x00r\x00.\x00p\x00n\x00g\ -\x00\x0f\ -\x06S%\xa7\ -\x00b\ -\x00r\x00a\x00n\x00c\x00h\x00_\x00o\x00p\x00e\x00n\x00.\x00p\x00n\x00g\ \x00\x0e\ -\x0e\xde\xfa\xc7\ -\x00l\ -\x00e\x00f\x00t\x00_\x00a\x00r\x00r\x00o\x00w\x00.\x00p\x00n\x00g\ -\x00 \ -\x09\xd7\x1f\xa7\ -\x00c\ -\x00h\x00e\x00c\x00k\x00b\x00o\x00x\x00_\x00i\x00n\x00d\x00e\x00t\x00e\x00r\x00m\ -\x00i\x00n\x00a\x00t\x00e\x00_\x00f\x00o\x00c\x00u\x00s\x00.\x00p\x00n\x00g\ -\x00\x1a\ -\x05\x11\xe0\xe7\ -\x00c\ -\x00h\x00e\x00c\x00k\x00b\x00o\x00x\x00_\x00c\x00h\x00e\x00c\x00k\x00e\x00d\x00_\ -\x00f\x00o\x00c\x00u\x00s\x00.\x00p\x00n\x00g\ +\x04\xa2\xfc\xa7\ +\x00d\ +\x00o\x00w\x00n\x00_\x00a\x00r\x00r\x00o\x00w\x00.\x00p\x00n\x00g\ \x00\x11\ \x0b\xda0\xa7\ \x00b\ \x00r\x00a\x00n\x00c\x00h\x00_\x00c\x00l\x00o\x00s\x00e\x00d\x00.\x00p\x00n\x00g\ \ -\x00\x0f\ -\x01s\x8b\x07\ -\x00u\ -\x00p\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00o\x00n\x00.\x00p\x00n\x00g\ -\x00\x11\ -\x00\xb8\x8c\x07\ -\x00l\ -\x00e\x00f\x00t\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00o\x00n\x00.\x00p\x00n\x00g\ -\ -\x00\x1a\ -\x01\x87\xaeg\ +\x00\x1d\ +\x09\x07\x81\x07\ \x00c\ -\x00h\x00e\x00c\x00k\x00b\x00o\x00x\x00_\x00i\x00n\x00d\x00e\x00t\x00e\x00r\x00m\ -\x00i\x00n\x00a\x00t\x00e\x00.\x00p\x00n\x00g\ -\x00\x15\ -\x0f\xf3\xc0\x07\ -\x00u\ -\x00p\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00d\x00i\x00s\x00a\x00b\x00l\x00e\x00d\ -\x00.\x00p\x00n\x00g\ -\x00\x0c\ -\x06\xe6\xe6g\ -\x00u\ -\x00p\x00_\x00a\x00r\x00r\x00o\x00w\x00.\x00p\x00n\x00g\ +\x00h\x00e\x00c\x00k\x00b\x00o\x00x\x00_\x00c\x00h\x00e\x00c\x00k\x00e\x00d\x00_\ +\x00d\x00i\x00s\x00a\x00b\x00l\x00e\x00d\x00.\x00p\x00n\x00g\ \x00\x1c\ \x08?\xdag\ \x00c\ \x00h\x00e\x00c\x00k\x00b\x00o\x00x\x00_\x00u\x00n\x00c\x00h\x00e\x00c\x00k\x00e\ \x00d\x00_\x00f\x00o\x00c\x00u\x00s\x00.\x00p\x00n\x00g\ -\x00\x12\ -\x01.\x03'\ -\x00c\ -\x00o\x00m\x00b\x00o\x00b\x00o\x00x\x00_\x00a\x00r\x00r\x00o\x00w\x00.\x00p\x00n\ -\x00g\ -\x00\x12\ -\x05\x8f\x9d\x07\ -\x00b\ -\x00r\x00a\x00n\x00c\x00h\x00_\x00o\x00p\x00e\x00n\x00_\x00o\x00n\x00.\x00p\x00n\ -\x00g\ -\x00\x1b\ -\x03Z2'\ -\x00c\ -\x00o\x00m\x00b\x00o\x00b\x00o\x00x\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00d\x00i\ -\x00s\x00a\x00b\x00l\x00e\x00d\x00.\x00p\x00n\x00g\ -\x00\x14\ -\x07\xec\xd1\xc7\ -\x00c\ -\x00h\x00e\x00c\x00k\x00b\x00o\x00x\x00_\x00c\x00h\x00e\x00c\x00k\x00e\x00d\x00.\ -\x00p\x00n\x00g\ \x00#\ \x06\xf2\x1aG\ \x00c\ \x00h\x00e\x00c\x00k\x00b\x00o\x00x\x00_\x00i\x00n\x00d\x00e\x00t\x00e\x00r\x00m\ \x00i\x00n\x00a\x00t\x00e\x00_\x00d\x00i\x00s\x00a\x00b\x00l\x00e\x00d\x00.\x00p\ \x00n\x00g\ -\x00\x17\ -\x0ce\xce\x07\ -\x00l\ -\x00e\x00f\x00t\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00d\x00i\x00s\x00a\x00b\x00l\ -\x00e\x00d\x00.\x00p\x00n\x00g\ -\x00\x17\ -\x0c\xabQ\x07\ -\x00d\ -\x00o\x00w\x00n\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00d\x00i\x00s\x00a\x00b\x00l\ -\x00e\x00d\x00.\x00p\x00n\x00g\ \x00\x12\ -\x03\x8d\x04G\ -\x00r\ -\x00i\x00g\x00h\x00t\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00o\x00n\x00.\x00p\x00n\ +\x01.\x03'\ +\x00c\ +\x00o\x00m\x00b\x00o\x00b\x00o\x00x\x00_\x00a\x00r\x00r\x00o\x00w\x00.\x00p\x00n\ \x00g\ -\x00\x14\ -\x04^-\xa7\ -\x00b\ -\x00r\x00a\x00n\x00c\x00h\x00_\x00c\x00l\x00o\x00s\x00e\x00d\x00_\x00o\x00n\x00.\ -\x00p\x00n\x00g\ -\x00\x15\ -\x03'rg\ -\x00c\ -\x00o\x00m\x00b\x00o\x00b\x00o\x00x\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00o\x00n\ -\x00.\x00p\x00n\x00g\ -\x00\x1d\ -\x09\x07\x81\x07\ -\x00c\ -\x00h\x00e\x00c\x00k\x00b\x00o\x00x\x00_\x00c\x00h\x00e\x00c\x00k\x00e\x00d\x00_\ -\x00d\x00i\x00s\x00a\x00b\x00l\x00e\x00d\x00.\x00p\x00n\x00g\ -\x00\x0e\ -\x04\xa2\xfc\xa7\ -\x00d\ -\x00o\x00w\x00n\x00_\x00a\x00r\x00r\x00o\x00w\x00.\x00p\x00n\x00g\ -\x00\x0f\ -\x0c\xe2hg\ -\x00t\ -\x00r\x00a\x00n\x00s\x00p\x00a\x00r\x00e\x00n\x00t\x00.\x00p\x00n\x00g\ -\x00\x1f\ -\x0a\xae'G\ -\x00c\ -\x00h\x00e\x00c\x00k\x00b\x00o\x00x\x00_\x00u\x00n\x00c\x00h\x00e\x00c\x00k\x00e\ -\x00d\x00_\x00d\x00i\x00s\x00a\x00b\x00l\x00e\x00d\x00.\x00p\x00n\x00g\ -\x00\x18\ -\x03\x8e\xdeg\ -\x00r\ -\x00i\x00g\x00h\x00t\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00d\x00i\x00s\x00a\x00b\ -\x00l\x00e\x00d\x00.\x00p\x00n\x00g\ -\x00\x11\ -\x01\x1f\xc3\x87\ -\x00d\ -\x00o\x00w\x00n\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00o\x00n\x00.\x00p\x00n\x00g\ -\ -\x00\x16\ -\x01u\xcc\x87\ -\x00c\ -\x00h\x00e\x00c\x00k\x00b\x00o\x00x\x00_\x00u\x00n\x00c\x00h\x00e\x00c\x00k\x00e\ -\x00d\x00.\x00p\x00n\x00g\ -\x00 \ -\x0f\xd4\x1b\xc7\ -\x00c\ -\x00h\x00e\x00c\x00k\x00b\x00o\x00x\x00_\x00i\x00n\x00d\x00e\x00t\x00e\x00r\x00m\ -\x00i\x00n\x00a\x00t\x00e\x00_\x00h\x00o\x00v\x00e\x00r\x00.\x00p\x00n\x00g\ -\x00\x0f\ -\x02\x9f\x05\x87\ -\x00r\ -\x00i\x00g\x00h\x00t\x00_\x00a\x00r\x00r\x00o\x00w\x00.\x00p\x00n\x00g\ \x00\x1c\ \x0e<\xde\x07\ \x00c\ \x00h\x00e\x00c\x00k\x00b\x00o\x00x\x00_\x00u\x00n\x00c\x00h\x00e\x00c\x00k\x00e\ \x00d\x00_\x00h\x00o\x00v\x00e\x00r\x00.\x00p\x00n\x00g\ +\x00\x14\ +\x07\xec\xd1\xc7\ +\x00c\ +\x00h\x00e\x00c\x00k\x00b\x00o\x00x\x00_\x00c\x00h\x00e\x00c\x00k\x00e\x00d\x00.\ +\x00p\x00n\x00g\ +\x00\x1a\ +\x05\x11\xe0\xe7\ +\x00c\ +\x00h\x00e\x00c\x00k\x00b\x00o\x00x\x00_\x00c\x00h\x00e\x00c\x00k\x00e\x00d\x00_\ +\x00f\x00o\x00c\x00u\x00s\x00.\x00p\x00n\x00g\ +\x00\x18\ +\x03\x8e\xdeg\ +\x00r\ +\x00i\x00g\x00h\x00t\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00d\x00i\x00s\x00a\x00b\ +\x00l\x00e\x00d\x00.\x00p\x00n\x00g\ +\x00\x15\ +\x03'rg\ +\x00c\ +\x00o\x00m\x00b\x00o\x00b\x00o\x00x\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00o\x00n\ +\x00.\x00p\x00n\x00g\ +\x00\x12\ +\x03\x8d\x04G\ +\x00r\ +\x00i\x00g\x00h\x00t\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00o\x00n\x00.\x00p\x00n\ +\x00g\ +\x00\x16\ +\x01u\xcc\x87\ +\x00c\ +\x00h\x00e\x00c\x00k\x00b\x00o\x00x\x00_\x00u\x00n\x00c\x00h\x00e\x00c\x00k\x00e\ +\x00d\x00.\x00p\x00n\x00g\ +\x00\x17\ +\x0c\xabQ\x07\ +\x00d\ +\x00o\x00w\x00n\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00d\x00i\x00s\x00a\x00b\x00l\ +\x00e\x00d\x00.\x00p\x00n\x00g\ +\x00\x15\ +\x0f\xf3\xc0\x07\ +\x00u\ +\x00p\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00d\x00i\x00s\x00a\x00b\x00l\x00e\x00d\ +\x00.\x00p\x00n\x00g\ +\x00\x14\ +\x04^-\xa7\ +\x00b\ +\x00r\x00a\x00n\x00c\x00h\x00_\x00c\x00l\x00o\x00s\x00e\x00d\x00_\x00o\x00n\x00.\ +\x00p\x00n\x00g\ +\x00\x0f\ +\x06S%\xa7\ +\x00b\ +\x00r\x00a\x00n\x00c\x00h\x00_\x00o\x00p\x00e\x00n\x00.\x00p\x00n\x00g\ +\x00\x17\ +\x0ce\xce\x07\ +\x00l\ +\x00e\x00f\x00t\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00d\x00i\x00s\x00a\x00b\x00l\ +\x00e\x00d\x00.\x00p\x00n\x00g\ +\x00\x0e\ +\x0e\xde\xfa\xc7\ +\x00l\ +\x00e\x00f\x00t\x00_\x00a\x00r\x00r\x00o\x00w\x00.\x00p\x00n\x00g\ +\x00\x1f\ +\x0a\xae'G\ +\x00c\ +\x00h\x00e\x00c\x00k\x00b\x00o\x00x\x00_\x00u\x00n\x00c\x00h\x00e\x00c\x00k\x00e\ +\x00d\x00_\x00d\x00i\x00s\x00a\x00b\x00l\x00e\x00d\x00.\x00p\x00n\x00g\ +\x00\x11\ +\x00\xb8\x8c\x07\ +\x00l\ +\x00e\x00f\x00t\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00o\x00n\x00.\x00p\x00n\x00g\ +\ +\x00\x0f\ +\x02\x9f\x05\x87\ +\x00r\ +\x00i\x00g\x00h\x00t\x00_\x00a\x00r\x00r\x00o\x00w\x00.\x00p\x00n\x00g\ +\x00\x1b\ +\x03Z2'\ +\x00c\ +\x00o\x00m\x00b\x00o\x00b\x00o\x00x\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00d\x00i\ +\x00s\x00a\x00b\x00l\x00e\x00d\x00.\x00p\x00n\x00g\ +\x00\x0f\ +\x01s\x8b\x07\ +\x00u\ +\x00p\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00o\x00n\x00.\x00p\x00n\x00g\ +\x00 \ +\x0f\xd4\x1b\xc7\ +\x00c\ +\x00h\x00e\x00c\x00k\x00b\x00o\x00x\x00_\x00i\x00n\x00d\x00e\x00t\x00e\x00r\x00m\ +\x00i\x00n\x00a\x00t\x00e\x00_\x00h\x00o\x00v\x00e\x00r\x00.\x00p\x00n\x00g\ +\x00\x12\ +\x05\x8f\x9d\x07\ +\x00b\ +\x00r\x00a\x00n\x00c\x00h\x00_\x00o\x00p\x00e\x00n\x00_\x00o\x00n\x00.\x00p\x00n\ +\x00g\ +\x00\x1a\ +\x01\x87\xaeg\ +\x00c\ +\x00h\x00e\x00c\x00k\x00b\x00o\x00x\x00_\x00i\x00n\x00d\x00e\x00t\x00e\x00r\x00m\ +\x00i\x00n\x00a\x00t\x00e\x00.\x00p\x00n\x00g\ +\x00\x0f\ +\x0c\xe2hg\ +\x00t\ +\x00r\x00a\x00n\x00s\x00p\x00a\x00r\x00e\x00n\x00t\x00.\x00p\x00n\x00g\ +\x00\x0c\ +\x06\xe6\xe6g\ +\x00u\ +\x00p\x00_\x00a\x00r\x00r\x00o\x00w\x00.\x00p\x00n\x00g\ +\x00 \ +\x09\xd7\x1f\xa7\ +\x00c\ +\x00h\x00e\x00c\x00k\x00b\x00o\x00x\x00_\x00i\x00n\x00d\x00e\x00t\x00e\x00r\x00m\ +\x00i\x00n\x00a\x00t\x00e\x00_\x00f\x00o\x00c\x00u\x00s\x00.\x00p\x00n\x00g\ +\x00\x11\ +\x01\x1f\xc3\x87\ +\x00d\ +\x00o\x00w\x00n\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00o\x00n\x00.\x00p\x00n\x00g\ +\ +\x00\x1a\ +\x03\x0e\xe4\x87\ +\x00c\ +\x00h\x00e\x00c\x00k\x00b\x00o\x00x\x00_\x00c\x00h\x00e\x00c\x00k\x00e\x00d\x00_\ +\x00h\x00o\x00v\x00e\x00r\x00.\x00p\x00n\x00g\ " 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\x01\x00\x00\x00\x02\ \x00\x00\x00\x16\x00\x02\x00\x00\x00 \x00\x00\x00\x03\ -\x00\x00\x01t\x00\x00\x00\x00\x00\x01\x00\x00\x1a\x05\ -\x00\x00\x05\x5c\x00\x00\x00\x00\x00\x01\x00\x00?\x7f\ -\x00\x00\x02b\x00\x00\x00\x00\x00\x01\x00\x00\x1f/\ -\x00\x00\x01P\x00\x00\x00\x00\x00\x01\x00\x00\x19c\ -\x00\x00\x05\x84\x00\x00\x00\x00\x00\x01\x00\x00@(\ -\x00\x00\x01\x9c\x00\x00\x00\x00\x00\x01\x00\x00\x1a\xaf\ -\x00\x00\x05\xfc\x00\x00\x00\x00\x00\x01\x00\x00Cz\ +\x00\x00\x04\x1e\x00\x00\x00\x00\x00\x01\x00\x000\x5c\ +\x00\x00\x05\xfc\x00\x00\x00\x00\x00\x01\x00\x00F\x05\ +\x00\x00\x01<\x00\x00\x00\x00\x00\x01\x00\x00\x0f\xec\ +\x00\x00\x04\xa6\x00\x00\x00\x00\x00\x01\x00\x002S\ +\x00\x00\x02\x9c\x00\x00\x00\x00\x00\x01\x00\x00\x1b\xf7\ +\x00\x00\x05:\x00\x00\x00\x00\x00\x01\x00\x00<\x1c\ +\x00\x00\x04F\x00\x00\x00\x00\x00\x01\x00\x001\x06\ +\x00\x00\x06$\x00\x00\x00\x00\x00\x01\x00\x00F\xae\ +\x00\x00\x02B\x00\x00\x00\x00\x00\x01\x00\x00\x1a\xa9\ +\x00\x00\x04j\x00\x00\x00\x00\x00\x01\x00\x001\xaa\ +\x00\x00\x02r\x00\x00\x00\x00\x00\x01\x00\x00\x1bS\ +\x00\x00\x02\x0c\x00\x00\x00\x00\x00\x01\x00\x00\x1a\x05\ +\x00\x00\x032\x00\x00\x00\x00\x00\x01\x00\x00\x1e\xa3\ \x00\x00\x00(\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ -\x00\x00\x04,\x00\x00\x00\x00\x00\x01\x00\x007\x8e\ -\x00\x00\x02\xb6\x00\x00\x00\x00\x00\x01\x00\x00'\x0d\ -\x00\x00\x03\xd4\x00\x00\x00\x00\x00\x01\x00\x00/\x09\ -\x00\x00\x05&\x00\x00\x00\x00\x00\x01\x00\x00>\xdb\ -\x00\x00\x03\xfe\x00\x00\x00\x00\x00\x01\x00\x00/\xad\ -\x00\x00\x04\x9c\x00\x00\x00\x00\x00\x01\x00\x00 Date: Wed, 10 Nov 2021 18:41:33 +0100 Subject: [PATCH 091/111] open publish gui --- openpype/cli.py | 6 ++++-- .../perjob/m50__openpype_publish_render.py | 12 +++++++---- openpype/pype_commands.py | 21 ++++++++++++------- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/openpype/cli.py b/openpype/cli.py index f6366f4b6b..b4b1b4481e 100644 --- a/openpype/cli.py +++ b/openpype/cli.py @@ -147,7 +147,9 @@ def extractenvironments(output_json_path, project, asset, task, app): @click.option("-d", "--debug", is_flag=True, help="Print debug messages") @click.option("-t", "--targets", help="Targets module", default=None, multiple=True) -def publish(debug, paths, targets): +@click.option("-g", "--gui", is_flag=True, + help="Show Publish UI", default=False) +def publish(debug, paths, targets, gui): """Start CLI publishing. Publish collects json from paths provided as an argument. @@ -155,7 +157,7 @@ def publish(debug, paths, targets): """ if debug: os.environ['OPENPYPE_DEBUG'] = '3' - PypeCommands.publish(list(paths), targets) + PypeCommands.publish(list(paths), targets, gui) @main.command() diff --git a/openpype/modules/default_modules/royal_render/rr_root/plugins/control_job/perjob/m50__openpype_publish_render.py b/openpype/modules/default_modules/royal_render/rr_root/plugins/control_job/perjob/m50__openpype_publish_render.py index cd53e4234f..b993bd9e68 100644 --- a/openpype/modules/default_modules/royal_render/rr_root/plugins/control_job/perjob/m50__openpype_publish_render.py +++ b/openpype/modules/default_modules/royal_render/rr_root/plugins/control_job/perjob/m50__openpype_publish_render.py @@ -8,6 +8,7 @@ run it needs `OPENPYPE_ROOT` to be set to know where to execute OpenPype. import rr # noqa import rrGlobal # noqa import subprocess +from subprocess import list2cmdline import os import glob import platform @@ -44,7 +45,7 @@ class OpenPypeContextSelector: # try to find in user local context op_path = os.path.join( os.environ.get("LOCALAPPDATA"), - "Programs" + "Programs", "OpenPype", "openpype_console.exe" ) if os.path.exists(op_path): @@ -122,7 +123,8 @@ class OpenPypeContextSelector: self._show_rr_warning("Context selection failed.") return - self.context["app_name"] = self.job.renderer.name + # self.context["app_name"] = self.job.renderer.name + self.context["app_name"] = "maya/2020" @staticmethod def _show_rr_warning(text): @@ -147,12 +149,14 @@ class OpenPypeContextSelector: for k, v in env.items(): print(" {}: {}".format(k, v)) args = [os.path.join(self.openpype_root, self.openpype_executable), - 'publish', '-t', "rr_control", self.job.imageDir] + 'publish', '-t', "rr_control", "--gui", self.job.imageDir] print(">>> running {}".format(" ".join(args))) out = None + orig = os.environ.copy() + orig.update(env) try: - out = subprocess.check_output(args, env=env) + subprocess.call(args, env=orig) except subprocess.CalledProcessError as e: self._show_rr_warning(" Publish failed [ {} ]\n{}".format( e.returncode, out diff --git a/openpype/pype_commands.py b/openpype/pype_commands.py index 433aafe30d..bad01396db 100644 --- a/openpype/pype_commands.py +++ b/openpype/pype_commands.py @@ -60,7 +60,7 @@ class PypeCommands: standalonepublish.main() @staticmethod - def publish(paths, targets=None): + def publish(paths, targets=None, gui=False): """Start headless publishing. Publish use json from passed paths argument. @@ -69,6 +69,7 @@ class PypeCommands: paths (list): Paths to jsons. targets (string): What module should be targeted (to choose validator for example) + gui (bool): Show publish UI. Raises: RuntimeError: When there is no path to process. @@ -76,6 +77,8 @@ class PypeCommands: from openpype.modules import ModulesManager from openpype import install, uninstall from openpype.api import Logger + from openpype.tools.utils.host_tools import show_publish + from openpype.tools.utils.lib import qt_app_context # Register target and host import pyblish.api @@ -125,14 +128,18 @@ class PypeCommands: for plugin in plugins: print(plugin) - for result in pyblish.util.publish_iter(): - if result["error"]: - log.error(error_format.format(**result)) - uninstall() - sys.exit(1) + if gui: + with qt_app_context(): + show_publish() + else: + for result in pyblish.util.publish_iter(): + if result["error"]: + log.error(error_format.format(**result)) + # uninstall() + sys.exit(1) log.info("Publish finished.") - uninstall() + # uninstall() @staticmethod def remotepublishfromapp(project, batch_dir, host, user, targets=None): From e6d76c5b580252a4eea6be22cf02de0380e2786d Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 11 Nov 2021 14:17:09 +0100 Subject: [PATCH 092/111] fix python 2 unicode conversion --- openpype/lib/python_module_tools.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openpype/lib/python_module_tools.py b/openpype/lib/python_module_tools.py index cb5f285ddd..69da4cc661 100644 --- a/openpype/lib/python_module_tools.py +++ b/openpype/lib/python_module_tools.py @@ -22,6 +22,9 @@ def import_filepath(filepath, module_name=None): if module_name is None: module_name = os.path.splitext(os.path.basename(filepath))[0] + # Make sure it is not 'unicode' in Python 2 + module_name = str(module_name) + # Prepare module object where content of file will be parsed module = types.ModuleType(module_name) From 5acdb6e182efede7d01d136c431c41329e77e203 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 11 Nov 2021 14:53:57 +0100 Subject: [PATCH 093/111] added docstring --- openpype/cli.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/openpype/cli.py b/openpype/cli.py index d68cba45c6..6a4d8f1120 100644 --- a/openpype/cli.py +++ b/openpype/cli.py @@ -61,6 +61,10 @@ def tray(debug=False): @main.group(help="Run command line arguments of OpenPype modules") @click.pass_context def module(ctx): + """Module specific commands created dynamically. + + These commands are generated dynamically by currently loaded addon/modules. + """ pass From adbd0b1c5e8b5d2d2a7a9a862798a373b982b431 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 11 Nov 2021 18:01:14 +0100 Subject: [PATCH 094/111] OP-2015 - added queue for studio processing in PS --- .../webserver_service/webpublish_routes.py | 20 ++++++++++++------- .../webserver_service/webserver_cli.py | 11 +++++++++- .../defaults/project_settings/photoshop.json | 3 +-- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/openpype/hosts/webpublisher/webserver_service/webpublish_routes.py b/openpype/hosts/webpublisher/webserver_service/webpublish_routes.py index 73e5113f38..a56b7c48c3 100644 --- a/openpype/hosts/webpublisher/webserver_service/webpublish_routes.py +++ b/openpype/hosts/webpublisher/webserver_service/webpublish_routes.py @@ -20,11 +20,16 @@ log = PypeLogger.get_logger("WebServer") class RestApiResource: """Resource carrying needed info and Avalon DB connection for publish.""" - def __init__(self, server_manager, executable, upload_dir): + def __init__(self, server_manager, executable, upload_dir, + studio_task_queue=None): self.server_manager = server_manager self.upload_dir = upload_dir self.executable = executable + if studio_task_queue is None: + studio_task_queue = collections.deque().dequeu + self.studio_task_queue = studio_task_queue + self.dbcon = AvalonMongoDB() self.dbcon.install() @@ -182,8 +187,6 @@ class WebpublisherBatchPublishEndpoint(_RestApiEndpoint): msg = "Non existent OpenPype executable {}".format(openpype_app) raise RuntimeError(msg) - # for postprocessing in host, currently only PS - output = {} log.info("WebpublisherBatchPublishEndpoint called") content = await request.json() @@ -225,13 +228,13 @@ class WebpublisherBatchPublishEndpoint(_RestApiEndpoint): batch_data = parse_json(os.path.join(batch_path, "manifest.json")) if not batch_data: raise ValueError( - "Cannot parse batch meta in {} folder".format(batch_path)) + "Cannot parse batch manifest in {}".format(batch_path)) task_dir_name = batch_data["tasks"][0] task_data = parse_json(os.path.join(batch_path, task_dir_name, "manifest.json")) if not task_data: raise ValueError( - "Cannot parse batch meta in {} folder".format(task_data)) + "Cannot parse task manifest in {}".format(task_data)) for process_filter in studio_processing_filters: filter_extensions = process_filter.get("extensions") or [] @@ -263,11 +266,14 @@ class WebpublisherBatchPublishEndpoint(_RestApiEndpoint): args.append(value) log.info("args:: {}".format(args)) + if content.get("studio_processing"): + log.debug("Adding to queue") + self.resource.studio_task_queue.append(args) + else: + subprocess.call(args) - subprocess.call(args) return Response( status=200, - body=self.resource.encode(output), content_type="application/json" ) diff --git a/openpype/hosts/webpublisher/webserver_service/webserver_cli.py b/openpype/hosts/webpublisher/webserver_service/webserver_cli.py index d00d269059..b784105461 100644 --- a/openpype/hosts/webpublisher/webserver_service/webserver_cli.py +++ b/openpype/hosts/webpublisher/webserver_service/webserver_cli.py @@ -1,8 +1,10 @@ +import collections import time import os from datetime import datetime import requests import json +import subprocess from openpype.lib import PypeLogger @@ -31,10 +33,13 @@ def run_webserver(*args, **kwargs): port = kwargs.get("port") or 8079 server_manager = webserver_module.create_new_server_manager(port, host) webserver_url = server_manager.url + # queue for remotepublishfromapp tasks + studio_task_queue = collections.deque() resource = RestApiResource(server_manager, upload_dir=kwargs["upload_dir"], - executable=kwargs["executable"]) + executable=kwargs["executable"], + studio_task_queue=studio_task_queue) projects_endpoint = WebpublisherProjectsEndpoint(resource) server_manager.add_route( "GET", @@ -88,6 +93,10 @@ def run_webserver(*args, **kwargs): if time.time() - last_reprocessed > 20: reprocess_failed(kwargs["upload_dir"], webserver_url) last_reprocessed = time.time() + if studio_task_queue: + args = studio_task_queue.popleft() + subprocess.call(args) # blocking call + time.sleep(1.0) diff --git a/openpype/settings/defaults/project_settings/photoshop.json b/openpype/settings/defaults/project_settings/photoshop.json index eb9f96e348..0c24c943ec 100644 --- a/openpype/settings/defaults/project_settings/photoshop.json +++ b/openpype/settings/defaults/project_settings/photoshop.json @@ -30,8 +30,7 @@ }, "ExtractReview": { "jpg_options": { - "tags": [ - ] + "tags": [] }, "mov_options": { "tags": [ From 79fce6a5b453ed88fe53374578fec797dded539a Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 11 Nov 2021 18:05:20 +0100 Subject: [PATCH 095/111] example addon is not using inteface --- .../example_addons/example_addon/addon.py | 16 ----------- .../example_addon/interfaces.py | 28 ------------------- .../example_addons/example_addon/widgets.py | 12 ++------ 3 files changed, 2 insertions(+), 54 deletions(-) delete mode 100644 openpype/modules/example_addons/example_addon/interfaces.py diff --git a/openpype/modules/example_addons/example_addon/addon.py b/openpype/modules/example_addons/example_addon/addon.py index 5573e33cc1..162868e4d4 100644 --- a/openpype/modules/example_addons/example_addon/addon.py +++ b/openpype/modules/example_addons/example_addon/addon.py @@ -15,7 +15,6 @@ from openpype.modules import ( ) # Import interface defined by this addon to be able find other addons using it from openpype_interfaces import ( - IExampleInterface, IPluginPaths, ITrayAction ) @@ -75,19 +74,6 @@ class ExampleAddon(OpenPypeAddOn, IPluginPaths, ITrayAction): self._create_dialog() - def connect_with_modules(self, enabled_modules): - """Method where you should find connected modules. - - It is triggered by OpenPype modules manager at the best possible time. - Some addons and modules may required to connect with other modules - before their main logic is executed so changes would require to restart - whole process. - """ - self._connected_modules = [] - for module in enabled_modules: - if isinstance(module, IExampleInterface): - self._connected_modules.append(module) - def _create_dialog(self): # Don't recreate dialog if already exists if self._dialog is not None: @@ -106,8 +92,6 @@ class ExampleAddon(OpenPypeAddOn, IPluginPaths, ITrayAction): """ # Make sure dialog is created self._create_dialog() - # Change value of dialog by current state - self._dialog.set_connected_modules(self.get_connected_modules()) # Show dialog self._dialog.open() diff --git a/openpype/modules/example_addons/example_addon/interfaces.py b/openpype/modules/example_addons/example_addon/interfaces.py deleted file mode 100644 index 371536efc7..0000000000 --- a/openpype/modules/example_addons/example_addon/interfaces.py +++ /dev/null @@ -1,28 +0,0 @@ -""" Using interfaces is one way of connecting multiple OpenPype Addons/Modules. - -Interfaces must be in `interfaces.py` file (or folder). Interfaces should not -import module logic or other module in global namespace. That is because -all of them must be imported before all OpenPype AddOns and Modules. - -Ideally they should just define abstract and helper methods. If interface -require any logic or connection it should be defined in module. - -Keep in mind that attributes and methods will be added to other addon -attributes and methods so they should be unique and ideally contain -addon name in it's name. -""" - -from abc import abstractmethod -from openpype.modules import OpenPypeInterface - - -class IExampleInterface(OpenPypeInterface): - """Example interface of addon.""" - _example_module = None - - def get_example_module(self): - return self._example_module - - @abstractmethod - def example_method_of_example_interface(self): - pass diff --git a/openpype/modules/example_addons/example_addon/widgets.py b/openpype/modules/example_addons/example_addon/widgets.py index 0acf238409..c0a0a7e510 100644 --- a/openpype/modules/example_addons/example_addon/widgets.py +++ b/openpype/modules/example_addons/example_addon/widgets.py @@ -9,7 +9,8 @@ class MyExampleDialog(QtWidgets.QDialog): self.setWindowTitle("Connected modules") - label_widget = QtWidgets.QLabel(self) + msg = "This is example dialog of example addon." + label_widget = QtWidgets.QLabel(msg, self) ok_btn = QtWidgets.QPushButton("OK", self) btns_layout = QtWidgets.QHBoxLayout() @@ -28,12 +29,3 @@ class MyExampleDialog(QtWidgets.QDialog): def _on_ok_clicked(self): self.done(1) - - def set_connected_modules(self, connected_modules): - if connected_modules: - message = "\n".join(connected_modules) - else: - message = ( - "Other enabled modules/addons are not using my interface." - ) - self._label_widget.setText(message) From f0a913e02493ba0c2a8885c69d77ec740d5d936d Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 11 Nov 2021 18:05:33 +0100 Subject: [PATCH 096/111] moved interfaces to modules directory --- openpype/modules/{default_modules => }/interfaces.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename openpype/modules/{default_modules => }/interfaces.py (100%) diff --git a/openpype/modules/default_modules/interfaces.py b/openpype/modules/interfaces.py similarity index 100% rename from openpype/modules/default_modules/interfaces.py rename to openpype/modules/interfaces.py From b2b532de36327c845da37cb4c8c30c88debbfdc1 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 11 Nov 2021 18:06:09 +0100 Subject: [PATCH 097/111] modifid current interfaces import to keep backwards compatibility --- openpype/modules/base.py | 55 +++++++--------------------------------- 1 file changed, 9 insertions(+), 46 deletions(-) diff --git a/openpype/modules/base.py b/openpype/modules/base.py index 7779fff6ec..01d54d9051 100644 --- a/openpype/modules/base.py +++ b/openpype/modules/base.py @@ -212,54 +212,17 @@ def _load_interfaces(): _InterfacesClass(modules_key) ) - log = PypeLogger.get_logger("InterfacesLoader") + from . import interfaces - dirpaths = get_module_dirs() - - interface_paths = [] - interface_paths.append( - os.path.join(get_default_modules_dir(), "interfaces.py") - ) - for dirpath in dirpaths: - if not os.path.exists(dirpath): + for attr_name in dir(interfaces): + attr = getattr(interfaces, attr_name) + if ( + not inspect.isclass(attr) + or attr is OpenPypeInterface + or not issubclass(attr, OpenPypeInterface) + ): continue - - for filename in os.listdir(dirpath): - if filename in ("__pycache__", ): - continue - - full_path = os.path.join(dirpath, filename) - if not os.path.isdir(full_path): - continue - - interfaces_path = os.path.join(full_path, "interfaces.py") - if os.path.exists(interfaces_path): - interface_paths.append(interfaces_path) - - for full_path in interface_paths: - if not os.path.exists(full_path): - continue - - try: - # Prepare module object where content of file will be parsed - module = import_filepath(full_path) - - except Exception: - log.warning( - "Failed to load path: \"{0}\"".format(full_path), - exc_info=True - ) - continue - - for attr_name in dir(module): - attr = getattr(module, attr_name) - if ( - not inspect.isclass(attr) - or attr is OpenPypeInterface - or not issubclass(attr, OpenPypeInterface) - ): - continue - setattr(openpype_interfaces, attr_name, attr) + setattr(openpype_interfaces, attr_name, attr) def load_modules(force=False): From a051f4e8b6cdc5f069bde46187d3583f13d8dc35 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 11 Nov 2021 18:18:04 +0100 Subject: [PATCH 098/111] moved 'ISettingsChangeListener' to global interfaces --- .../settings_module/interfaces.py | 30 ------------------- openpype/modules/interfaces.py | 28 +++++++++++++++++ 2 files changed, 28 insertions(+), 30 deletions(-) delete mode 100644 openpype/modules/default_modules/settings_module/interfaces.py diff --git a/openpype/modules/default_modules/settings_module/interfaces.py b/openpype/modules/default_modules/settings_module/interfaces.py deleted file mode 100644 index 42db395649..0000000000 --- a/openpype/modules/default_modules/settings_module/interfaces.py +++ /dev/null @@ -1,30 +0,0 @@ -from abc import abstractmethod -from openpype.modules import OpenPypeInterface - - -class ISettingsChangeListener(OpenPypeInterface): - """Module has plugin paths to return. - - Expected result is dictionary with keys "publish", "create", "load" or - "actions" and values as list or string. - { - "publish": ["path/to/publish_plugins"] - } - """ - @abstractmethod - def on_system_settings_save( - self, old_value, new_value, changes, new_value_metadata - ): - pass - - @abstractmethod - def on_project_settings_save( - self, old_value, new_value, changes, project_name, new_value_metadata - ): - pass - - @abstractmethod - def on_project_anatomy_save( - self, old_value, new_value, changes, project_name, new_value_metadata - ): - pass diff --git a/openpype/modules/interfaces.py b/openpype/modules/interfaces.py index a60c5fa606..e6e84a0d42 100644 --- a/openpype/modules/interfaces.py +++ b/openpype/modules/interfaces.py @@ -263,3 +263,31 @@ class ITrayService(ITrayModule): """Change icon of an QAction to orange circle.""" if self.menu_action: self.menu_action.setIcon(self.get_icon_idle()) + + +class ISettingsChangeListener(OpenPypeInterface): + """Module has plugin paths to return. + + Expected result is dictionary with keys "publish", "create", "load" or + "actions" and values as list or string. + { + "publish": ["path/to/publish_plugins"] + } + """ + @abstractmethod + def on_system_settings_save( + self, old_value, new_value, changes, new_value_metadata + ): + pass + + @abstractmethod + def on_project_settings_save( + self, old_value, new_value, changes, project_name, new_value_metadata + ): + pass + + @abstractmethod + def on_project_anatomy_save( + self, old_value, new_value, changes, project_name, new_value_metadata + ): + pass From 9a74a6a1e8602cb8000b088630c585927141851c Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 11 Nov 2021 18:18:19 +0100 Subject: [PATCH 099/111] removed unused import of ITimersManager --- .../modules/default_modules/timers_manager/timers_manager.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/openpype/modules/default_modules/timers_manager/timers_manager.py b/openpype/modules/default_modules/timers_manager/timers_manager.py index 7687d056f8..1aeccbb958 100644 --- a/openpype/modules/default_modules/timers_manager/timers_manager.py +++ b/openpype/modules/default_modules/timers_manager/timers_manager.py @@ -1,10 +1,7 @@ import os import platform from openpype.modules import OpenPypeModule -from openpype_interfaces import ( - ITimersManager, - ITrayService -) +from openpype_interfaces import ITrayService from avalon.api import AvalonMongoDB From b09382bf8dbd3c34666306bc5db8e2c5cf046d6d Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 11 Nov 2021 18:20:09 +0100 Subject: [PATCH 100/111] raise ImportError if interface does not exists --- openpype/modules/base.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/openpype/modules/base.py b/openpype/modules/base.py index 01d54d9051..cb39666626 100644 --- a/openpype/modules/base.py +++ b/openpype/modules/base.py @@ -107,12 +107,9 @@ class _InterfacesClass(_ModuleClass): if attr_name in ("__path__", "__file__"): return None - # Fake Interface if is not missing - self.__attributes__[attr_name] = type( - attr_name, - (MissingInteface, ), - {} - ) + raise ImportError(( + "cannot import name '{}' from 'openpype_interfaces'" + ).format(attr_name)) return self.__attributes__[attr_name] From d3fd330f944d212e90b3a5548bad38b78d6955e6 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 11 Nov 2021 18:21:38 +0100 Subject: [PATCH 101/111] removed unused 'MissingInterface' --- openpype/modules/base.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/openpype/modules/base.py b/openpype/modules/base.py index cb39666626..3f59d5900b 100644 --- a/openpype/modules/base.py +++ b/openpype/modules/base.py @@ -329,14 +329,6 @@ class OpenPypeInterface: pass -class MissingInteface(OpenPypeInterface): - """Class representing missing interface class. - - Used when interface is not available from currently registered paths. - """ - pass - - @six.add_metaclass(ABCMeta) class OpenPypeModule: """Base class of pype module. From 992986fd1be27612b95e4a3007aac926c53dbd77 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 11 Nov 2021 18:31:42 +0100 Subject: [PATCH 102/111] skip module directories without init file --- openpype/modules/base.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/openpype/modules/base.py b/openpype/modules/base.py index 7779fff6ec..692495600c 100644 --- a/openpype/modules/base.py +++ b/openpype/modules/base.py @@ -333,6 +333,15 @@ def _load_modules(): # - check manifest and content of manifest try: if os.path.isdir(fullpath): + # Module without init file can't be used as OpenPype module + # because the module class could not be imported + init_file = os.path.join(fullpath, "__init__.py") + if not os.path.exists(init_file): + log.info(( + "Skipping module directory because of" + " missing \"__init__.py\" file. \"{}\"" + ).format(fullpath)) + continue import_module_from_dirpath(dirpath, filename, modules_key) elif ext in (".py", ): From 40a72d511fca890add9c64d235320422cafdd93e Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Thu, 11 Nov 2021 18:42:15 +0100 Subject: [PATCH 103/111] collect file sequence --- .../plugins/collect_sequences_from_job.py | 4 - .../{ => publish}/collect_default_rr_path.py | 0 .../collect_rr_path_from_instance.py | 2 +- .../publish/collect_sequences_from_job.py | 222 ++++++++++++++++++ .../perjob/m50__openpype_publish_render.py | 6 +- openpype/pype_commands.py | 17 +- 6 files changed, 236 insertions(+), 15 deletions(-) delete mode 100644 openpype/modules/default_modules/royal_render/plugins/collect_sequences_from_job.py rename openpype/modules/default_modules/royal_render/plugins/{ => publish}/collect_default_rr_path.py (100%) rename openpype/modules/default_modules/royal_render/plugins/{ => publish}/collect_rr_path_from_instance.py (96%) create mode 100644 openpype/modules/default_modules/royal_render/plugins/publish/collect_sequences_from_job.py diff --git a/openpype/modules/default_modules/royal_render/plugins/collect_sequences_from_job.py b/openpype/modules/default_modules/royal_render/plugins/collect_sequences_from_job.py deleted file mode 100644 index ac811696fa..0000000000 --- a/openpype/modules/default_modules/royal_render/plugins/collect_sequences_from_job.py +++ /dev/null @@ -1,4 +0,0 @@ -# -*- coding: utf-8 -*- -"""Collect sequences from Royal Render Job.""" -import rr # noqa -import rrGlobal # noqa \ No newline at end of file diff --git a/openpype/modules/default_modules/royal_render/plugins/collect_default_rr_path.py b/openpype/modules/default_modules/royal_render/plugins/publish/collect_default_rr_path.py similarity index 100% rename from openpype/modules/default_modules/royal_render/plugins/collect_default_rr_path.py rename to openpype/modules/default_modules/royal_render/plugins/publish/collect_default_rr_path.py diff --git a/openpype/modules/default_modules/royal_render/plugins/collect_rr_path_from_instance.py b/openpype/modules/default_modules/royal_render/plugins/publish/collect_rr_path_from_instance.py similarity index 96% rename from openpype/modules/default_modules/royal_render/plugins/collect_rr_path_from_instance.py rename to openpype/modules/default_modules/royal_render/plugins/publish/collect_rr_path_from_instance.py index 939b7c6e00..fb27a76d11 100644 --- a/openpype/modules/default_modules/royal_render/plugins/collect_rr_path_from_instance.py +++ b/openpype/modules/default_modules/royal_render/plugins/publish/collect_rr_path_from_instance.py @@ -6,7 +6,7 @@ class CollectRRPathFromInstance(pyblish.api.InstancePlugin): """Collect RR Path from instance.""" order = pyblish.api.CollectorOrder - label = "Deadline Webservice from the Instance" + label = "Royal Render Path from the Instance" families = ["rendering"] def process(self, instance): diff --git a/openpype/modules/default_modules/royal_render/plugins/publish/collect_sequences_from_job.py b/openpype/modules/default_modules/royal_render/plugins/publish/collect_sequences_from_job.py new file mode 100644 index 0000000000..2b0e35b3b8 --- /dev/null +++ b/openpype/modules/default_modules/royal_render/plugins/publish/collect_sequences_from_job.py @@ -0,0 +1,222 @@ +# -*- coding: utf-8 -*- +"""Collect sequences from Royal Render Job.""" +import os +import re +import copy +import json +from pprint import pformat + +import pyblish.api +from avalon import api + + +def collect(root, + regex=None, + exclude_regex=None, + frame_start=None, + frame_end=None): + """Collect sequence collections in root""" + + from avalon.vendor import clique + + files = [] + for filename in os.listdir(root): + + # Must have extension + ext = os.path.splitext(filename)[1] + if not ext: + continue + + # Only files + if not os.path.isfile(os.path.join(root, filename)): + continue + + # Include and exclude regex + if regex and not re.search(regex, filename): + continue + if exclude_regex and re.search(exclude_regex, filename): + continue + + files.append(filename) + + # Match collections + # Support filenames like: projectX_shot01_0010.tiff with this regex + pattern = r"(?P(?P0*)\d+)\.\D+\d?$" + collections, remainder = clique.assemble(files, + patterns=[pattern], + minimum_items=1) + + # Ignore any remainders + if remainder: + print("Skipping remainder {}".format(remainder)) + + # Exclude any frames outside start and end frame. + for collection in collections: + for index in list(collection.indexes): + if frame_start is not None and index < frame_start: + collection.indexes.discard(index) + continue + if frame_end is not None and index > frame_end: + collection.indexes.discard(index) + continue + + # Keep only collections that have at least a single frame + collections = [c for c in collections if c.indexes] + + return collections + + +class CollectSequencesFromJob(pyblish.api.ContextPlugin): + """Gather file sequences from working directory + + When "FILESEQUENCE" environment variable is set these paths (folders or + .json files) are parsed for image sequences. Otherwise the current + working directory is searched for file sequences. + + The json configuration may have the optional keys: + asset (str): The asset to publish to. If not provided fall back to + api.Session["AVALON_ASSET"] + subset (str): The subset to publish to. If not provided the sequence's + head (up to frame number) will be used. + frame_start (int): The start frame for the sequence + frame_end (int): The end frame for the sequence + root (str): The path to collect from (can be relative to the .json) + regex (str): A regex for the sequence filename + exclude_regex (str): A regex for filename to exclude from collection + metadata (dict): Custom metadata for instance.data["metadata"] + + """ + + order = pyblish.api.CollectorOrder + targets = ["rr_control"] + label = "Collect Rendered Frames" + + def process(self, context): + if os.environ.get("OPENPYPE_PUBLISH_DATA"): + self.log.debug(os.environ.get("OPENPYPE_PUBLISH_DATA")) + paths = os.environ["OPENPYPE_PUBLISH_DATA"].split(os.pathsep) + self.log.info("Collecting paths: {}".format(paths)) + else: + cwd = context.get("workspaceDir", os.getcwd()) + paths = [cwd] + + for path in paths: + + self.log.info("Loading: {}".format(path)) + + if path.endswith(".json"): + # Search using .json configuration + with open(path, "r") as f: + try: + data = json.load(f) + except Exception as exc: + self.log.error("Error loading json: " + "{} - Exception: {}".format(path, exc)) + raise + + cwd = os.path.dirname(path) + root_override = data.get("root") + if root_override: + if os.path.isabs(root_override): + root = root_override + else: + root = os.path.join(cwd, root_override) + else: + root = cwd + + metadata = data.get("metadata") + if metadata: + session = metadata.get("session") + if session: + self.log.info("setting session using metadata") + api.Session.update(session) + os.environ.update(session) + + else: + # Search in directory + data = {} + root = path + + self.log.info("Collecting: {}".format(root)) + regex = data.get("regex") + if regex: + self.log.info("Using regex: {}".format(regex)) + + collections = collect(root=root, + regex=regex, + exclude_regex=data.get("exclude_regex"), + frame_start=data.get("frameStart"), + frame_end=data.get("frameEnd")) + + self.log.info("Found collections: {}".format(collections)) + + if data.get("subset") and len(collections) > 1: + self.log.error("Forced subset can only work with a single " + "found sequence") + raise RuntimeError("Invalid sequence") + + fps = data.get("fps", 25) + + # Get family from the data + families = data.get("families", ["render"]) + if "render" not in families: + families.append("render") + if "ftrack" not in families: + families.append("ftrack") + if "review" not in families: + families.append("review") + + for collection in collections: + instance = context.create_instance(str(collection)) + self.log.info("Collection: %s" % list(collection)) + + # Ensure each instance gets a unique reference to the data + data = copy.deepcopy(data) + + # If no subset provided, get it from collection's head + subset = data.get("subset", collection.head.rstrip("_. ")) + + # If no start or end frame provided, get it from collection + indices = list(collection.indexes) + start = data.get("frameStart", indices[0]) + end = data.get("frameEnd", indices[-1]) + + # root = os.path.normpath(root) + # self.log.info("Source: {}}".format(data.get("source", ""))) + + ext = list(collection)[0].split('.')[-1] + + instance.data.update({ + "name": str(collection), + "family": families[0], # backwards compatibility / pyblish + "families": list(families), + "subset": subset, + "asset": data.get("asset", api.Session["AVALON_ASSET"]), + "stagingDir": root, + "frameStart": start, + "frameEnd": end, + "fps": fps, + "source": data.get('source', '') + }) + instance.append(collection) + instance.context.data['fps'] = fps + + if "representations" not in instance.data: + instance.data["representations"] = [] + + representation = { + 'name': ext, + 'ext': '{}'.format(ext), + 'files': list(collection), + "stagingDir": root, + "anatomy_template": "render", + "fps": fps, + "tags": ['review'] + } + instance.data["representations"].append(representation) + + if data.get('user'): + context.data["user"] = data['user'] + + self.log.debug("Collected instance:\n" + "{}".format(pformat(instance.data))) diff --git a/openpype/modules/default_modules/royal_render/rr_root/plugins/control_job/perjob/m50__openpype_publish_render.py b/openpype/modules/default_modules/royal_render/rr_root/plugins/control_job/perjob/m50__openpype_publish_render.py index b993bd9e68..7e18695a7b 100644 --- a/openpype/modules/default_modules/royal_render/rr_root/plugins/control_job/perjob/m50__openpype_publish_render.py +++ b/openpype/modules/default_modules/royal_render/rr_root/plugins/control_job/perjob/m50__openpype_publish_render.py @@ -148,8 +148,12 @@ class OpenPypeContextSelector: print(">>> setting environment:") for k, v in env.items(): print(" {}: {}".format(k, v)) + args = [os.path.join(self.openpype_root, self.openpype_executable), - 'publish', '-t', "rr_control", "--gui", self.job.imageDir] + 'publish', '-t', "rr_control", "--gui", + os.path.join(self.job.imageDir, + os.path.dirname(self.job.imageFileName)) + ] print(">>> running {}".format(" ".join(args))) out = None diff --git a/openpype/pype_commands.py b/openpype/pype_commands.py index 53c842b7c4..8cc4b819ff 100644 --- a/openpype/pype_commands.py +++ b/openpype/pype_commands.py @@ -83,7 +83,10 @@ class PypeCommands: # Register target and host import pyblish.api import pyblish.util - from pprint import pprint + + log = Logger.get_logger() + + install() manager = ModulesManager() @@ -103,10 +106,6 @@ class PypeCommands: ) os.environ.update(env) - log = Logger.get_logger() - - install() - pyblish.api.register_host("shell") if targets: @@ -120,9 +119,6 @@ class PypeCommands: log.info("Running publish ...") - # Error exit as soon as any error occurs. - error_format = "Failed {plugin.__name__}: {error} -- {error.traceback}" - plugins = pyblish.api.discover() print("Using plugins:") for plugin in plugins: @@ -132,6 +128,10 @@ class PypeCommands: with qt_app_context(): show_publish() else: + # Error exit as soon as any error occurs. + error_format = ("Failed {plugin.__name__}: " + "{error} -- {error.traceback}") + for result in pyblish.util.publish_iter(): if result["error"]: log.error(error_format.format(**result)) @@ -139,7 +139,6 @@ class PypeCommands: sys.exit(1) log.info("Publish finished.") - # uninstall() @staticmethod def remotepublishfromapp(project, batch_dir, host, user, targets=None): From 23971e40e1442f9db19d0fda96dd485a261b8bda Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Fri, 12 Nov 2021 09:41:07 +0100 Subject: [PATCH 104/111] polishing --- .../publish/collect_sequences_from_job.py | 21 ++++--------------- .../perjob/m50__openpype_publish_render.py | 6 ++---- 2 files changed, 6 insertions(+), 21 deletions(-) diff --git a/openpype/modules/default_modules/royal_render/plugins/publish/collect_sequences_from_job.py b/openpype/modules/default_modules/royal_render/plugins/publish/collect_sequences_from_job.py index 2b0e35b3b8..d2754d1f92 100644 --- a/openpype/modules/default_modules/royal_render/plugins/publish/collect_sequences_from_job.py +++ b/openpype/modules/default_modules/royal_render/plugins/publish/collect_sequences_from_job.py @@ -67,26 +67,13 @@ def collect(root, class CollectSequencesFromJob(pyblish.api.ContextPlugin): - """Gather file sequences from working directory + """Gather file sequences from job directory. - When "FILESEQUENCE" environment variable is set these paths (folders or - .json files) are parsed for image sequences. Otherwise the current - working directory is searched for file sequences. - - The json configuration may have the optional keys: - asset (str): The asset to publish to. If not provided fall back to - api.Session["AVALON_ASSET"] - subset (str): The subset to publish to. If not provided the sequence's - head (up to frame number) will be used. - frame_start (int): The start frame for the sequence - frame_end (int): The end frame for the sequence - root (str): The path to collect from (can be relative to the .json) - regex (str): A regex for the sequence filename - exclude_regex (str): A regex for filename to exclude from collection - metadata (dict): Custom metadata for instance.data["metadata"] + When "OPENPYPE_PUBLISH_DATA" environment variable is set these paths + (folders or .json files) are parsed for image sequences. Otherwise the + current working directory is searched for file sequences. """ - order = pyblish.api.CollectorOrder targets = ["rr_control"] label = "Collect Rendered Frames" diff --git a/openpype/modules/default_modules/royal_render/rr_root/plugins/control_job/perjob/m50__openpype_publish_render.py b/openpype/modules/default_modules/royal_render/rr_root/plugins/control_job/perjob/m50__openpype_publish_render.py index 7e18695a7b..17e4fb38d1 100644 --- a/openpype/modules/default_modules/royal_render/rr_root/plugins/control_job/perjob/m50__openpype_publish_render.py +++ b/openpype/modules/default_modules/royal_render/rr_root/plugins/control_job/perjob/m50__openpype_publish_render.py @@ -8,7 +8,6 @@ run it needs `OPENPYPE_ROOT` to be set to know where to execute OpenPype. import rr # noqa import rrGlobal # noqa import subprocess -from subprocess import list2cmdline import os import glob import platform @@ -156,14 +155,13 @@ class OpenPypeContextSelector: ] print(">>> running {}".format(" ".join(args))) - out = None orig = os.environ.copy() orig.update(env) try: subprocess.call(args, env=orig) except subprocess.CalledProcessError as e: - self._show_rr_warning(" Publish failed [ {} ]\n{}".format( - e.returncode, out + self._show_rr_warning(" Publish failed [ {} ]".format( + e.returncode )) From 87191d8d300338defa81c3894af849d98562e5d3 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Fri, 12 Nov 2021 12:08:04 +0100 Subject: [PATCH 105/111] OP-1937 - fix alternate sites for default studio site --- .../sync_server/sync_server_module.py | 40 +++++++++++++------ 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/openpype/modules/default_modules/sync_server/sync_server_module.py b/openpype/modules/default_modules/sync_server/sync_server_module.py index ca322b9f64..c5649afec4 100644 --- a/openpype/modules/default_modules/sync_server/sync_server_module.py +++ b/openpype/modules/default_modules/sync_server/sync_server_module.py @@ -793,20 +793,34 @@ class SyncServerModule(OpenPypeModule, ITrayModule): by provider """ sites = self.sync_system_settings.get("sites", {}) - for site_name, site_info in sites.items(): - if processed_site in site_info.get("alternative_sites", []): - query = { - "_id": representation["_id"] - } - elem = {"name": "sftp", - "created_dt": datetime.now(), - "id": synced_file_id} + sites[self.DEFAULT_SITE] = {"provider": "local_drive", + "alternative_sites": []} - self.log.debug("Adding alternate {} to {}".format( - site_name, representation["_id"])) - self._add_site(collection, query, - [representation], elem, - site_name, file_id=file_id, force=True) + alternate_sites = [] + for site_name, site_info in sites.items(): + conf_alternative_sites = site_info.get("alternative_sites", []) + if processed_site in conf_alternative_sites: + alternate_sites.append(site_name) + continue + if processed_site == site_name and conf_alternative_sites: + alternate_sites.extend(conf_alternative_sites) + continue + + alternate_sites = set(alternate_sites) + + for alt_site in alternate_sites: + query = { + "_id": representation["_id"] + } + elem = {"name": alt_site, + "created_dt": datetime.now(), + "id": synced_file_id} + + self.log.debug("Adding alternate {} to {}".format( + alt_site, representation["_id"])) + self._add_site(collection, query, + [representation], elem, + site_name, file_id=file_id, force=True) """ End of Public API """ def get_local_file_path(self, collection, site_name, file_path): From ae66af2dfa5c25f16b526adb0b10c0ce6291833c Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 12 Nov 2021 12:55:45 +0100 Subject: [PATCH 106/111] resave default system settings --- openpype/settings/defaults/system_settings/modules.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/openpype/settings/defaults/system_settings/modules.json b/openpype/settings/defaults/system_settings/modules.json index 1dc4c5879d..9c72598ff2 100644 --- a/openpype/settings/defaults/system_settings/modules.json +++ b/openpype/settings/defaults/system_settings/modules.json @@ -170,7 +170,11 @@ "royalrender": { "enabled": false, "rr_paths": { - "default": "" + "default": { + "windows": "", + "darwin": "", + "linux": "" + } } }, "log_viewer": { From 1431bc5ac9887c6097cdc91887e4e1954cefecc3 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Fri, 12 Nov 2021 13:30:37 +0100 Subject: [PATCH 107/111] OP-2015 - fix - adding to queue decided by configuration --- .../webpublisher/webserver_service/webpublish_routes.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/webpublisher/webserver_service/webpublish_routes.py b/openpype/hosts/webpublisher/webserver_service/webpublish_routes.py index a56b7c48c3..445fa071c5 100644 --- a/openpype/hosts/webpublisher/webserver_service/webpublish_routes.py +++ b/openpype/hosts/webpublisher/webserver_service/webpublish_routes.py @@ -205,7 +205,10 @@ class WebpublisherBatchPublishEndpoint(_RestApiEndpoint): # Make sure targets are set to None for cases that default # would change # - targets argument is not used in 'remotepublishfromapp' - "targets": None + "targets": None, + # does publish need to be handled by a queue, eg. only + # single process running concurrently? + "add_to_queue": True } } ] @@ -222,6 +225,7 @@ class WebpublisherBatchPublishEndpoint(_RestApiEndpoint): "targets": ["filespublish"] } + add_to_queue = False if content.get("studio_processing"): log.info("Post processing called") @@ -247,6 +251,7 @@ class WebpublisherBatchPublishEndpoint(_RestApiEndpoint): add_args.update( process_filter.get("arguments") or {} ) + add_to_queue = process_filter["add_to_queue"] break args = [ @@ -266,7 +271,7 @@ class WebpublisherBatchPublishEndpoint(_RestApiEndpoint): args.append(value) log.info("args:: {}".format(args)) - if content.get("studio_processing"): + if add_to_queue: log.debug("Adding to queue") self.resource.studio_task_queue.append(args) else: From 27b6197ee8def8259080d0a90f0c12e3771c8324 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Fri, 12 Nov 2021 13:52:28 +0100 Subject: [PATCH 108/111] OP-2015 - fix - adding to queue decided by configuration --- .../webserver_service/webpublish_routes.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/openpype/hosts/webpublisher/webserver_service/webpublish_routes.py b/openpype/hosts/webpublisher/webserver_service/webpublish_routes.py index 445fa071c5..e34a899c4b 100644 --- a/openpype/hosts/webpublisher/webserver_service/webpublish_routes.py +++ b/openpype/hosts/webpublisher/webserver_service/webpublish_routes.py @@ -205,11 +205,11 @@ class WebpublisherBatchPublishEndpoint(_RestApiEndpoint): # Make sure targets are set to None for cases that default # would change # - targets argument is not used in 'remotepublishfromapp' - "targets": None, - # does publish need to be handled by a queue, eg. only - # single process running concurrently? - "add_to_queue": True - } + "targets": None + }, + # does publish need to be handled by a queue, eg. only + # single process running concurrently? + "add_to_queue": True } ] From 4d2bd5a8813e62e668be8abae05cd315bfd1e12b Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Fri, 12 Nov 2021 18:27:08 +0100 Subject: [PATCH 109/111] OP-1978 - fix wrong site name used if resynchronizing --- openpype/modules/default_modules/sync_server/sync_server.py | 2 +- .../modules/default_modules/sync_server/sync_server_module.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/modules/default_modules/sync_server/sync_server.py b/openpype/modules/default_modules/sync_server/sync_server.py index 8518c4a301..22eed01ef3 100644 --- a/openpype/modules/default_modules/sync_server/sync_server.py +++ b/openpype/modules/default_modules/sync_server/sync_server.py @@ -136,7 +136,7 @@ async def download(module, collection, file, representation, provider_name, True ) - module.handle_alternate_site(collection, representation, remote_site_name, + module.handle_alternate_site(collection, representation, local_site, file["_id"], file_id) return file_id diff --git a/openpype/modules/default_modules/sync_server/sync_server_module.py b/openpype/modules/default_modules/sync_server/sync_server_module.py index c5649afec4..f6b599d92c 100644 --- a/openpype/modules/default_modules/sync_server/sync_server_module.py +++ b/openpype/modules/default_modules/sync_server/sync_server_module.py @@ -820,7 +820,7 @@ class SyncServerModule(OpenPypeModule, ITrayModule): alt_site, representation["_id"])) self._add_site(collection, query, [representation], elem, - site_name, file_id=file_id, force=True) + alt_site, file_id=file_id, force=True) """ End of Public API """ def get_local_file_path(self, collection, site_name, file_path): From 22f428ffd42b76a43b0b49985bc1f91dc1fc3a4b Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Fri, 12 Nov 2021 18:27:38 +0100 Subject: [PATCH 110/111] OP-1978 - fix distinary change during loop --- openpype/plugins/publish/integrate_new.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openpype/plugins/publish/integrate_new.py b/openpype/plugins/publish/integrate_new.py index 6c51f640fb..7ff7466a2a 100644 --- a/openpype/plugins/publish/integrate_new.py +++ b/openpype/plugins/publish/integrate_new.py @@ -1120,9 +1120,10 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): for site_name, site_info in conf_sites.items(): alt_sites = set(site_info.get("alternative_sites", [])) - for added_site in already_attached_sites.keys(): + already_attached_keys = list(already_attached_sites.keys()) + for added_site in already_attached_keys: if added_site in alt_sites: - if site_name in already_attached_sites.keys(): + if site_name in already_attached_keys: continue meta = {"name": site_name} real_created = already_attached_sites[added_site] From dd519cec50b6ffe87b481670d249b5177b134051 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Fri, 12 Nov 2021 21:20:19 +0100 Subject: [PATCH 111/111] fix hound --- openpype/cli.py | 4 ++-- openpype/modules/default_modules/ftrack/ftrack_module.py | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/openpype/cli.py b/openpype/cli.py index 0ebf188498..3194723d4c 100644 --- a/openpype/cli.py +++ b/openpype/cli.py @@ -360,8 +360,8 @@ def runtests(folder, mark, pyargs): """Run all automatic tests after proper initialization via start.py""" PypeCommands().run_tests(folder, mark, pyargs) - -@main.command() + +@main.command() @click.option("-d", "--debug", is_flag=True, help=("Run process in debug mode")) @click.option("-a", "--active_site", required=True, diff --git a/openpype/modules/default_modules/ftrack/ftrack_module.py b/openpype/modules/default_modules/ftrack/ftrack_module.py index 4699ce2209..a9f6b836f8 100644 --- a/openpype/modules/default_modules/ftrack/ftrack_module.py +++ b/openpype/modules/default_modules/ftrack/ftrack_module.py @@ -470,4 +470,3 @@ def eventserver( clockify_api_key, clockify_workspace ) - \ No newline at end of file