diff --git a/.appveyor.yml b/.appveyor.yml index e63978a5f..821bbe7d3 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -1,5 +1,4 @@ environment: - global: # SDK v7.0 MSVC Express 2008's SetEnv.cmd script will fail if the # /E:ON and /V:ON options are not enabled in the batch script intepreter @@ -8,76 +7,11 @@ environment: matrix: - # Python 2.7.10 is the latest version and is not pre-installed. - - - PYTHON: "C:\\Python27.10" - PYTHON_VERSION: "2.7.10" + - PYTHON: "C:\\Python36" + PYTHON_VERSION: "3.6.x" PYTHON_ARCH: "32" - - #- PYTHON: "C:\\Python27.10-x64" - # PYTHON_VERSION: "2.7.10" - # PYTHON_ARCH: "64" - - # Pre-installed Python versions, which Appveyor may upgrade to - # a later point release. - # See: http://www.appveyor.com/docs/installed-software#python - - #- PYTHON: "C:\\Python27" - # PYTHON_VERSION: "2.7.x" # currently 2.7.9 - # PYTHON_ARCH: "32" - - #- PYTHON: "C:\\Python27-x64" - # PYTHON_VERSION: "2.7.x" # currently 2.7.9 - # PYTHON_ARCH: "64" - - #- PYTHON: "C:\\Python33" - # PYTHON_VERSION: "3.3.x" # currently 3.3.5 - # PYTHON_ARCH: "32" - - #- PYTHON: "C:\\Python33-x64" - # PYTHON_VERSION: "3.3.x" # currently 3.3.5 - # PYTHON_ARCH: "64" - - #- PYTHON: "C:\\Python34" - # PYTHON_VERSION: "3.4.x" # currently 3.4.3 - # PYTHON_ARCH: "32" - - #- PYTHON: "C:\\Python34-x64" - # PYTHON_VERSION: "3.4.x" # currently 3.4.3 - # PYTHON_ARCH: "64" - - # Python versions not pre-installed - - # Python 2.6.6 is the latest Python 2.6 with a Windows installer - # See: https://github.com/ogrisel/python-appveyor-demo/issues/10 - - #- PYTHON: "C:\\Python266" - # PYTHON_VERSION: "2.6.6" - # PYTHON_ARCH: "32" - - #- PYTHON: "C:\\Python266-x64" - # PYTHON_VERSION: "2.6.6" - # PYTHON_ARCH: "64" - - #- PYTHON: "C:\\Python35" - # PYTHON_VERSION: "3.5.0" - # PYTHON_ARCH: "32" - - #- PYTHON: "C:\\Python35-x64" - # PYTHON_VERSION: "3.5.0" - # PYTHON_ARCH: "64" - - # Major and minor releases (i.e x.0.0 and x.y.0) prior to 3.3.0 use - # a different naming scheme. - - #- PYTHON: "C:\\Python270" - # PYTHON_VERSION: "2.7.0" - # PYTHON_ARCH: "32" - - #- PYTHON: "C:\\Python270-x64" - # PYTHON_VERSION: "2.7.0" - # PYTHON_ARCH: "64" - +init: + - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) install: # If there is a newer build queued for the same PR, cancel this one. # The AppVeyor 'rollout builds' option is supposed to serve the same @@ -89,34 +23,23 @@ install: Where-Object pullRequestId -eq $env:APPVEYOR_PULL_REQUEST_NUMBER)[0].buildNumber) { ` throw "There are newer queued builds for this pull request, failing early." } - # Install wxPython - - 'ECHO Downloading wxPython.' - - "appveyor DownloadFile https://goo.gl/yvO8PB -FileName C:\\wxpython.exe" - #- "appveyor DownloadFile https://goo.gl/Uj0jV3 -FileName C:\\wxpython64.exe" - - - 'ECHO Install wxPython' - - "C:\\wxpython.exe /SP- /VERYSILENT /NORESTART" - #- "C:\\wxpython64.exe /SP- /VERYSILENT /NORESTART" - - ECHO "Filesystem root:" - ps: "ls \"C:/\"" + - ECHO "Filesystem projects root:" + - ps: "ls \"C:\\projects\\\"" + - ECHO "Filesystem pyfa root:" - - ps: "ls \"C:\\projects\\pyfa\\\"" + - ps: "ls \"C:\\projects\\$env:APPVEYOR_PROJECT_SLUG\"" - ECHO "Installed SDKs:" - ps: "ls \"C:/Program Files/Microsoft SDKs/Windows\"" - # Install Python (from the official .msi of http://python.org) and pip when - # not already installed. - # - ps: if (-not(Test-Path($env:PYTHON))) { & appveyor\install.ps1 } - # Prepend newly installed Python to the PATH of this build (this cannot be # done from inside the powershell script as it would require to restart # the parent CMD process). - "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%" - # Check that we have the expected version and architecture for Python - "python --version" - "python -c \"import struct; print(struct.calcsize('P') * 8)\"" @@ -128,19 +51,36 @@ install: # compiled extensions and are not provided as pre-built wheel packages, # pip will build them from source using the MSVC compiler matching the # target Python version and architecture - # C:\\projects\\eve-gnosis\\ - ECHO "Install pip requirements:" - "pip install -r requirements.txt" - - "pip install -r requirements_test.txt" - - "pip install -r requirements_build_windows.txt" + - "pip install PyInstaller" + +before_build: + # directory that will contain the built files + - ps: $env:PYFA_DIST_DIR = "c:\projects\$env:APPVEYOR_PROJECT_SLUG\dist" + - ps: $env:PYFA_VERSION = (python ./scripts/dump_version.py) + - ps: echo("pyfa version ") + - ps: echo ($env:PYFA_VERSION) build_script: - # Build the compiled extension - # - "python setup.py build" - ECHO "Build pyfa:" - #- copy C:\projects\pyfa\dist_assets\win\pyfa.spec C:\projects\pyfa\pyfa.spec - - "python C:\\projects\\pyfa\\setup.py build" + ########## + # PyInstaller - create binaries for pyfa + ########## + # Build command for PyInstaller + - "python -m PyInstaller --noupx --clean --windowed --noconsole -y pyfa.spec" + # Copy over manifest (See pyfa-org/pyfa#1622) + - ps: xcopy /y dist_assets\win\pyfa.exe.manifest $env:PYFA_DIST_DIR\pyfa\ + # Not really sure if this is needed, but why not + - ps: xcopy /y dist_assets\win\Microsoft.VC90.CRT.manifest $env:PYFA_DIST_DIR\pyfa\ + + ########## + # InnoScript EXE building + # This is in a separate script because I don't feel like copying over the logic to AppVeyor script right now... + ########## + - "python dist_assets/win/dist.py" + - ps: dir $env:PYFA_DIST_DIR/ #- ECHO "Build pyfa (Debug):" #- copy C:\projects\pyfa\dist_assets\win\pyfa_debug.spec C:\projects\pyfa\pyfa_debug.spec #- "pyinstaller.exe --clean --noconfirm --windowed --upx-dir=C:\\projects\\pyfa\\scripts\\upx.exe C:\\projects\\pyfa\\pyfa_debug.spec" @@ -150,12 +90,11 @@ build: on after_build: - ps: "ls \"./\"" #- ps: "ls \"C:\\projects\\pyfa\\build\\pyfa\\\"" - - ps: "ls \"C:\\projects\\pyfa\\build\\\"" - - ps: "ls \"C:\\projects\\pyfa\\build\\exe.win32-2.7\\\"" +# - ps: "ls \"C:\\projects\\$env:APPVEYOR_PROJECT_SLUG\\build\\exe.win32-2.7\\\"" # Zip # APPVEYOR_PULL_REQUEST_NUMBER -and $env:APPVEYOR_BUILD_NUMBER #- 7z a build.zip -r C:\projects\pyfa\build\pyfa\*.* - - 7z a pyfa.zip -r C:\projects\pyfa\build\exe.win32-2.7\*.* + - ps: 7z a "pyfa-$env:PYFA_VERSION-win.zip" -r "$env:PYFA_DIST_DIR\pyfa\*.*" #- 7z a pyfa_debug.zip -r C:\projects\pyfa\dist\pyfa_debug\*.* on_success: @@ -176,11 +115,21 @@ after_test: artifacts: # Archive the generated packages in the ci.appveyor.com build report. - - path: pyfa.zip - name: 'pyfa.zip' + - path: pyfa*-win.zip + - path: pyfa*-win.exe #- path: pyfa_debug.zip # name: Pyfa_debug - + +deploy: + tag: $(pyfa_version) + release: pyfa $(pyfa_version) + description: 'Release description' + provider: GitHub + auth_token: + secure: BfNHO66ff5hVx2O2ORbl49X0U/5h2V2T0IuRZDwm7fd1HvsVluF0wRCbl29oRp1M + draft: true + on: + APPVEYOR_REPO_TAG: true # deploy on tag push only #on_success: # - TODO: upload the content of dist/*.whl to a public wheelhouse # \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 889ad5544..9140c2f10 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,36 +1,29 @@ -dist: trusty -sudo: required +os: linux language: python -cache: pip python: - - '3.6' -env: - - TOXENV=pep8 -addons: - apt: - packages: + - 3.6 +matrix: + include: + - os: osx + osx_image: xcode7.3 + language: generic + env: PYTHON=3.6.1 before_install: - - sudo apt-get update && sudo apt-get --reinstall install -qq language-pack-en language-pack-ru language-pack-he language-pack-zh-hans - - pip install tox - # We're not actually installing Tox, but have to run it before we install wxPython via Conda. This is fugly but vOv - - tox - - pip install -U -f https://extras.wxpython.org/wxPython4/extras/linux/gtk2/ubuntu-14.04 wxPython==4.0.0b2 -# # get Conda -# - if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then -# wget https://repo.continuum.io/miniconda/Miniconda-latest-Linux-x86_64.sh -O miniconda.sh; -# else -# wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh; -# fi -# - bash miniconda.sh -b -p $HOME/miniconda -# - export PATH="$HOME/miniconda/bin:$PATH" -# - hash -r -# - conda config --set always_yes yes --set changeps1 no -# - conda update -q conda -# # Useful for debugging any issues with conda -# - conda info -a -#install: - # install wxPython 3.0.0.0 - # - conda install -c https://conda.anaconda.org/travis wxpython=4.0.0b2 -script: - - tox - + - bash scripts/setup-osx.sh +install: + - export PYFA_VERSION="$(python3 scripts/dump_version.py)" + - bash scripts/package-osx.sh +before_deploy: + - export RELEASE_PKG_FILE=$(ls *.deb) + - echo "deploying $RELEASE_PKG_FILE to GitHub releases" +deploy: + provider: releases + api_key: + secure: Xfu0xApoB0zUPLXl29aYUulVC3iA4/3bXQwwADKCfAKZwxgNon4dLbO7Rie5/7Ukf2POL0KwmRaQGN3kOr+XSoIVTE4M5sXxnhiaaLGKQ+48hDizLE6JuXcZGJvkxUaghaTzIdCwHsG7VGBsPfQgfGsjJcfBp8tFNLmRyM/Jpsr8T6BR2MxtBIEUVy8zrOWFNZqnmWrY2pWMsB9fYt3JFNdpqeIgRAYqbBsBcZQ1MngLTi3ztuYS5IaF+lk06RrnBlHmUsJu/5nCvIpvPvD0i2BLZ3Uu0+Fn+8QWUgjJEL9MNseXZMXynu05xd8YRk7Ajc9CUrzQIIbAktyteYp85kE3pUJHmrMLcXhh7nqkwttR5/47Zwa3OLJLJFKBxMx6wY5jFkJjkV08850B7aWrmTFl/Eqc3Q5nZMuiEt3wFRbjxHi9h1mTN/fkxfRRHg8u3ENGPR+ZPiFC3J18qtks/B/hsKjjHvZP1i79OYlET4V/zyLyyQkCbpDaARQANuotLYJyZ7tH+KWEyRsvTi0M9Yev9mNNw6aI4vzh4HfkEhvcvnWnYwckPj1dnjQ573Qpw0Z9wsconoWfHAn+hBDt3+YLMrrFZl++mCRskHH1mZChX3aGMDi49zD0kfxBUkYPOAhguc6PwudBxHUZP+O6T/SoHylff6EizCE/k5dGeAk= + file_glob: true + file: "dist/pyfa-*.zip" + skip_cleanup: true + draft: true + on: + tags: true + repo: pyfa-org/Pyfa diff --git a/config.py b/config.py index 9034e3d85..4e1234e90 100644 --- a/config.py +++ b/config.py @@ -1,5 +1,6 @@ import os import sys +import yaml from logbook import CRITICAL, DEBUG, ERROR, FingersCrossedHandler, INFO, Logger, NestedSetup, NullHandler, \ StreamHandler, TimedRotatingFileHandler, WARNING @@ -22,12 +23,6 @@ debug = False # Defines if our saveddata will be in pyfa root or not saveInRoot = False -# Version data - -version = "2.6.1" -tag = "Stable" -expansionName = "Onslaught" -expansionVersion = "1.5" evemonMinVersion = "4081" minItemSearchLength = 3 @@ -79,12 +74,7 @@ def getPyfaRoot(): def getVersion(): - if os.path.isfile(os.path.join(pyfaPath, '.version')): - with open(os.path.join(pyfaPath, '.version')) as f: - gitVersion = f.readline() - return gitVersion - # if no version file exists, then user is running from source or not an official build - return version + " (git)" + return version def getDefaultSave(): @@ -96,11 +86,12 @@ def defPaths(customSavePath=None): global pyfaPath global savePath global saveDB - global gameDB + global gameDB global saveInRoot global logPath global cipher global clientHash + global version pyfalog.debug("Configuring Pyfa") @@ -110,6 +101,12 @@ def defPaths(customSavePath=None): if pyfaPath is None: pyfaPath = getPyfaRoot() + # Version data + + with open(os.path.join(pyfaPath, "version.yml"), 'r') as file: + data = yaml.load(file) + version = data['version'] + # Where we store the saved fits etc, default is the current users home directory if saveInRoot is True: savePath = getattr(configforced, "savePath", None) diff --git a/dist_assets/mac/pyfa.spec b/dist_assets/mac/pyfa.spec index cf27cfe87..1e1f35711 100644 --- a/dist_assets/mac/pyfa.spec +++ b/dist_assets/mac/pyfa.spec @@ -24,11 +24,13 @@ added_files = [ ('../../eve.db', '.'), ('../../README.md', '.'), ('../../LICENSE', '.'), - ('../../.version', '.'), + ('../../version.yml', '.'), ] -import_these = [] +import_these = [ + 'numpy.core._dtype_ctypes' # https://github.com/pyinstaller/pyinstaller/issues/3982 +] icon = os.path.join(os.getcwd(), "dist_assets", "mac", "pyfa.icns") @@ -54,8 +56,10 @@ a = Analysis([r'../../pyfa.py'], win_no_prefer_redirects=False, win_private_assemblies=False, cipher=block_cipher) + pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) + exe = EXE(pyz, a.scripts, a.binaries, @@ -70,10 +74,16 @@ exe = EXE(pyz, icon=icon, ) -app = BUNDLE(exe, - name='pyfa.app', - icon=icon, - bundle_identifier=None, - info_plist={ - 'NSHighResolutionCapable': 'True' - }) +app = BUNDLE( + exe, + name='pyfa.app', + icon=icon, + bundle_identifier=None, + info_plist={ + 'NSHighResolutionCapable': 'True', + 'NSPrincipalClass': 'NSApplication', + 'CFBundleName': 'pyfa', + 'CFBundleDisplayName': 'pyfa', + 'CFBundleIdentifier': 'org.pyfaorg.pyfa', + } +) \ No newline at end of file diff --git a/dist_assets/win/dist.py b/dist_assets/win/dist.py index ec6da3928..bff55018a 100644 --- a/dist_assets/win/dist.py +++ b/dist_assets/win/dist.py @@ -3,44 +3,35 @@ import os.path from subprocess import call import zipfile +from packaging.version import Version +import yaml -def zipdir(path, zip): - for root, dirs, files in os.walk(path): - for file in files: - zip.write(os.path.join(root, file)) +with open("version.yml", 'r') as file: + data = yaml.load(file) + version = data['version'] -config = {} +os.environ["PYFA_DIST_DIR"] = os.path.join(os.getcwd(), 'dist') -exec(compile(open("config.py").read(), "config.py", 'exec'), config) +os.environ["PYFA_VERSION"] = version +iscc = "C:\Program Files (x86)\Inno Setup 5\ISCC.exe" # inno script location via wine -iscc = "C:\Program Files (x86)\Inno Setup 5\ISCC.exe" # inno script location via wine +source = os.path.join(os.environ["PYFA_DIST_DIR"], "pyfa") -print("Creating archive") - -source = os.path.join(os.getcwd(), "dist", "pyfa") - -fileName = "pyfa-{}-{}-{}-win".format( - config['version'], - config['expansionName'].lower(), - config['expansionVersion'] -) - -archive = zipfile.ZipFile(os.path.join(os.getcwd(), "dist", fileName + ".zip"), 'w', compression=zipfile.ZIP_DEFLATED) -zipdir(source, archive) -archive.close() +fileName = "pyfa-{}-win".format(os.environ["PYFA_VERSION"]) print("Compiling EXE") -expansion = "%s %s" % (config['expansionName'], config['expansionVersion']), +v = Version(version) + +print(v) call([ iscc, os.path.join(os.getcwd(), "dist_assets", "win", "pyfa-setup.iss"), - "/dMyAppVersion=%s" % (config['version']), - "/dMyAppExpansion=%s" % expansion, + "/dMyAppVersion=%s" % v, "/dMyAppDir=%s" % source, - "/dMyOutputDir=%s" % os.path.join(os.getcwd(), "dist"), + "/dMyOutputDir=%s" % os.path.join(os.getcwd()), "/dMyOutputFile=%s" % fileName]) # stdout=devnull, stderr=devnull print("Done") diff --git a/dist_assets/win/pyfa-setup.iss b/dist_assets/win/pyfa-setup.iss index 7984da087..e016b3a37 100644 --- a/dist_assets/win/pyfa-setup.iss +++ b/dist_assets/win/pyfa-setup.iss @@ -7,15 +7,12 @@ #ifndef MyAppVersion #define MyAppVersion "2.1.0" #endif -#ifndef MyAppExpansion - #define MyAppExpansion "Vanguard 1.0" -#endif ; Other config #define MyAppName "pyfa" #define MyAppPublisher "pyfa" -#define MyAppURL "https://forums.eveonline.com/t/27156" +#define MyAppURL "https://github.com/pyfa-org/Pyfa/" #define MyAppExeName "pyfa.exe" ; What version starts with the new structure (1.x.0). This is used to determine if we run directory structure cleanup @@ -23,7 +20,7 @@ #define MinorVersionFlag 0 #ifndef MyOutputFile - #define MyOutputFile LowerCase(StringChange(MyAppName+'-'+MyAppVersion+'-'+MyAppExpansion+'-win-wx3', " ", "-")) + #define MyOutputFile LowerCase(StringChange(MyAppName+'-'+MyAppVersion+'-win', " ", "-")) #endif #ifndef MyAppDir #define MyAppDir "pyfa" @@ -39,7 +36,7 @@ ; (To generate a new GUID, click Tools | Generate GUID inside the IDE.) AppId={{3DA39096-C08D-49CD-90E0-1D177F32C8AA} AppName={#MyAppName} -AppVersion={#MyAppVersion} ({#MyAppExpansion}) +AppVersion={#MyAppVersion} AppPublisher={#MyAppPublisher} AppPublisherURL={#MyAppURL} AppSupportURL={#MyAppURL} @@ -51,10 +48,8 @@ LicenseFile={#MyAppDir}\LICENSE OutputDir={#MyOutputDir} OutputBaseFilename={#MyOutputFile} SetupIconFile={#MyAppDir}\pyfa.ico -Compression=lzma SolidCompression=yes CloseApplications=yes -AppReadmeFile=https://github.com/pyfa-org/Pyfa/blob/v{#MyAppVersion}/readme.txt [Languages] Name: "english"; MessagesFile: "compiler:Default.isl" diff --git a/dist_assets/win/pyfa.spec b/dist_assets/win/pyfa.spec index d181a5eb9..1bdf820f0 100644 --- a/dist_assets/win/pyfa.spec +++ b/dist_assets/win/pyfa.spec @@ -5,8 +5,7 @@ from itertools import chain import subprocess import requests.certs -label = subprocess.check_output([ - "git", "describe", "--tags"]).strip() +label = subprocess.check_output(["git", "describe", "--tags"]).strip() with open('.version', 'w+') as f: f.write(label.decode()) @@ -18,7 +17,7 @@ added_files = [ ('../../imgs/gui/*.gif', 'imgs/gui'), ('../../imgs/icons/*.png', 'imgs/icons'), ('../../imgs/renders/*.png', 'imgs/renders'), - ('../../service/jargon/*.yaml', 'service/jargon'), + ('../../service/jargon/*.yaml', 'service/jargon'), ('../../dist_assets/win/pyfa.ico', '.'), ('../../dist_assets/win/pyfa.exe.manifest', '.'), ('../../dist_assets/win/Microsoft.VC90.CRT.manifest', '.'), @@ -26,10 +25,12 @@ added_files = [ ('../../eve.db', '.'), ('../../README.md', '.'), ('../../LICENSE', '.'), - ('../../.version', '.'), + ('../../version.yml', '.'), ] -import_these = [] +import_these = [ + 'numpy.core._dtype_ctypes' # https://github.com/pyinstaller/pyinstaller/issues/3982 +] # Walk directories that do dynamic importing paths = ('eos/effects', 'eos/db/migrations', 'service/conversions') diff --git a/eos/db/gamedata/item.py b/eos/db/gamedata/item.py index df7508e43..fd7be477d 100644 --- a/eos/db/gamedata/item.py +++ b/eos/db/gamedata/item.py @@ -40,7 +40,9 @@ items_table = Table("invtypes", gamedata_meta, Column("marketGroupID", Integer, ForeignKey("invmarketgroups.marketGroupID")), Column("iconID", Integer), Column("graphicID", Integer), - Column("groupID", Integer, ForeignKey("invgroups.groupID"), index=True)) + Column("groupID", Integer, ForeignKey("invgroups.groupID"), index=True), + Column("replaceSame", String), + Column("replaceBetter", String)) from .metaGroup import metatypes_table # noqa from .traits import traits_table # noqa diff --git a/eos/db/migrations/upgrade29.py b/eos/db/migrations/upgrade29.py new file mode 100644 index 000000000..d94365236 --- /dev/null +++ b/eos/db/migrations/upgrade29.py @@ -0,0 +1,18 @@ +""" +Migration 29 + +- adds spoolType and spoolAmount to modules table +""" +import sqlalchemy + + +def upgrade(saveddata_engine): + try: + saveddata_engine.execute("SELECT spoolType FROM modules LIMIT 1") + except sqlalchemy.exc.DatabaseError: + saveddata_engine.execute("ALTER TABLE modules ADD COLUMN spoolType INT;") + + try: + saveddata_engine.execute("SELECT spoolAmount FROM modules LIMIT 1") + except sqlalchemy.exc.DatabaseError: + saveddata_engine.execute("ALTER TABLE modules ADD COLUMN spoolAmount FLOAT;") diff --git a/eos/db/migrations/upgrade30.py b/eos/db/migrations/upgrade30.py new file mode 100644 index 000000000..7954f2d37 --- /dev/null +++ b/eos/db/migrations/upgrade30.py @@ -0,0 +1,17 @@ +""" +Migration 30 + +- changes to prices table +""" + + +import sqlalchemy + + +def upgrade(saveddata_engine): + try: + saveddata_engine.execute("SELECT status FROM prices LIMIT 1") + except sqlalchemy.exc.DatabaseError: + # Just drop table, table will be re-created by sqlalchemy and + # data will be re-fetched + saveddata_engine.execute("DROP TABLE prices;") diff --git a/eos/db/saveddata/module.py b/eos/db/saveddata/module.py index 220b208db..a0e511127 100644 --- a/eos/db/saveddata/module.py +++ b/eos/db/saveddata/module.py @@ -17,7 +17,7 @@ # along with eos. If not, see . # =============================================================================== -from sqlalchemy import Table, Column, Integer, ForeignKey, CheckConstraint, Boolean, DateTime +from sqlalchemy import Table, Column, Integer, Float, ForeignKey, CheckConstraint, Boolean, DateTime from sqlalchemy.orm.collections import attribute_mapped_collection from sqlalchemy.orm import relation, mapper import datetime @@ -40,6 +40,8 @@ modules_table = Table("modules", saveddata_meta, Column("position", Integer), Column("created", DateTime, nullable=True, default=datetime.datetime.now), Column("modified", DateTime, nullable=True, onupdate=datetime.datetime.now), + Column("spoolType", Integer, nullable=True), + Column("spoolAmount", Float, nullable=True), CheckConstraint('("dummySlot" = NULL OR "itemID" = NULL) AND "dummySlot" != "itemID"')) mapper(Module, modules_table, diff --git a/eos/db/saveddata/price.py b/eos/db/saveddata/price.py index 8be7f6519..8abd07132 100644 --- a/eos/db/saveddata/price.py +++ b/eos/db/saveddata/price.py @@ -17,17 +17,20 @@ # along with eos. If not, see . # =============================================================================== + from sqlalchemy import Table, Column, Float, Integer from sqlalchemy.orm import mapper from eos.db import saveddata_meta from eos.saveddata.price import Price + prices_table = Table("prices", saveddata_meta, Column("typeID", Integer, primary_key=True), Column("price", Float, default=0.0), Column("time", Integer, nullable=False), - Column("failed", Integer)) + Column("status", Integer, nullable=False)) + mapper(Price, prices_table, properties={ "_Price__price": prices_table.c.price, diff --git a/eos/db/saveddata/queries.py b/eos/db/saveddata/queries.py index e582eef87..448584420 100644 --- a/eos/db/saveddata/queries.py +++ b/eos/db/saveddata/queries.py @@ -542,8 +542,17 @@ def commit(): with sd_lock: try: saveddata_session.commit() - saveddata_session.flush() - except Exception as ex: + except Exception: + saveddata_session.rollback() + exc_info = sys.exc_info() + raise exc_info[0](exc_info[1]).with_traceback(exc_info[2]) + + +def flush(): + with sd_lock: + try: + saveddata_session.flush() + except Exception: saveddata_session.rollback() exc_info = sys.exc_info() raise exc_info[0](exc_info[1]).with_traceback(exc_info[2]) diff --git a/eos/effectHandlerHelpers.py b/eos/effectHandlerHelpers.py index 345234d38..efe4d7e38 100644 --- a/eos/effectHandlerHelpers.py +++ b/eos/effectHandlerHelpers.py @@ -141,6 +141,23 @@ class HandledModuleList(HandledList): self.remove(mod) return + def replaceRackPosition(self, rackPosition, mod): + listPositions = [] + for currMod in self: + if currMod.slot == mod.slot: + listPositions.append(currMod.position) + listPositions.sort() + try: + modListPosition = listPositions[rackPosition] + except IndexError: + self.appendIgnoreEmpty(mod) + else: + self.toDummy(modListPosition) + if not mod.isEmpty: + self.toModule(modListPosition, mod) + if mod.isInvalid: + self.toDummy(modListPosition) + def insert(self, index, mod): mod.position = index i = index diff --git a/eos/effects/ammoinfluencecapneed.py b/eos/effects/ammoinfluencecapneed.py index 587e55cd5..3bbb1103c 100644 --- a/eos/effects/ammoinfluencecapneed.py +++ b/eos/effects/ammoinfluencecapneed.py @@ -1,7 +1,7 @@ # ammoInfluenceCapNeed # # Used by: -# Items from category: Charge (493 of 947) +# Items from category: Charge (493 of 949) type = "passive" diff --git a/eos/effects/ammoinfluencerange.py b/eos/effects/ammoinfluencerange.py index 4358a6ff9..58c331911 100644 --- a/eos/effects/ammoinfluencerange.py +++ b/eos/effects/ammoinfluencerange.py @@ -1,7 +1,7 @@ # ammoInfluenceRange # # Used by: -# Items from category: Charge (587 of 947) +# Items from category: Charge (587 of 949) type = "passive" diff --git a/eos/effects/ammospeedmultiplier.py b/eos/effects/ammospeedmultiplier.py index 2a6c2e4d3..093953c11 100644 --- a/eos/effects/ammospeedmultiplier.py +++ b/eos/effects/ammospeedmultiplier.py @@ -1,10 +1,9 @@ # ammoSpeedMultiplier # # Used by: -# Charges from group: Festival Charges (23 of 23) +# Charges from group: Festival Charges (26 of 26) # Charges from group: Interdiction Probe (2 of 2) -# Charges from group: Structure Festival Charges (3 of 3) -# Special Edition Assetss from group: Festival Charges Expired (2 of 2) +# Items from market group: Special Edition Assets > Special Edition Festival Assets (30 of 33) type = "passive" diff --git a/eos/effects/ammotrackingmultiplier.py b/eos/effects/ammotrackingmultiplier.py index 6153af15c..95033d743 100644 --- a/eos/effects/ammotrackingmultiplier.py +++ b/eos/effects/ammotrackingmultiplier.py @@ -1,7 +1,7 @@ # ammoTrackingMultiplier # # Used by: -# Items from category: Charge (182 of 947) +# Items from category: Charge (182 of 949) # Charges from group: Projectile Ammo (128 of 128) type = "passive" diff --git a/eos/effects/armorrepair.py b/eos/effects/armorrepair.py index d65f26ca5..07c1926da 100644 --- a/eos/effects/armorrepair.py +++ b/eos/effects/armorrepair.py @@ -9,4 +9,7 @@ type = "active" def handler(fit, module, context): amount = module.getModifiedItemAttr("armorDamageAmount") speed = module.getModifiedItemAttr("duration") / 1000.0 - fit.extraAttributes.increase("armorRepair", amount / speed) + rps = amount / speed + fit.extraAttributes.increase("armorRepair", rps) + fit.extraAttributes.increase("armorRepairPreSpool", rps) + fit.extraAttributes.increase("armorRepairFullSpool", rps) diff --git a/eos/effects/boostermodifyboosterarmorpenalties.py b/eos/effects/boostermodifyboosterarmorpenalties.py index a8b30251b..0714422d4 100644 --- a/eos/effects/boostermodifyboosterarmorpenalties.py +++ b/eos/effects/boostermodifyboosterarmorpenalties.py @@ -4,6 +4,7 @@ # Implants named like: Eifyr and Co. 'Alchemist' Neurotoxin Control NC (2 of 2) # Implants named like: grade Edge (10 of 12) # Skill: Neurotoxin Control +runTime = 'early' type = "passive" diff --git a/eos/effects/boostershieldcapacitypenalty.py b/eos/effects/boostershieldcapacitypenalty.py index 90f290bc1..f93f04af9 100644 --- a/eos/effects/boostershieldcapacitypenalty.py +++ b/eos/effects/boostershieldcapacitypenalty.py @@ -1,7 +1,7 @@ # boosterShieldCapacityPenalty # # Used by: -# Implants from group: Booster (12 of 69) +# Implants from group: Booster (12 of 70) type = "boosterSideEffect" # User-friendly name for the side effect diff --git a/eos/effects/cynosuraldurationbonus.py b/eos/effects/cynosuraldurationbonus.py index 4f78ea09e..defbd9ca3 100644 --- a/eos/effects/cynosuraldurationbonus.py +++ b/eos/effects/cynosuraldurationbonus.py @@ -6,5 +6,5 @@ type = "passive" def handler(fit, ship, context): - fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Cynosural Field", + fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Cynosural Field Generator", "duration", ship.getModifiedItemAttr("durationBonus")) diff --git a/eos/effects/cynosuralgeneration.py b/eos/effects/cynosuralgeneration.py index b99325c0f..36e29c52d 100644 --- a/eos/effects/cynosuralgeneration.py +++ b/eos/effects/cynosuralgeneration.py @@ -1,7 +1,7 @@ # cynosuralGeneration # # Used by: -# Modules from group: Cynosural Field (2 of 2) +# Modules from group: Cynosural Field Generator (2 of 2) type = "active" diff --git a/eos/effects/cynosuraltheoryconsumptionbonus.py b/eos/effects/cynosuraltheoryconsumptionbonus.py index d67c969f8..d6bda31b7 100644 --- a/eos/effects/cynosuraltheoryconsumptionbonus.py +++ b/eos/effects/cynosuraltheoryconsumptionbonus.py @@ -8,6 +8,6 @@ type = "passive" def handler(fit, container, context): level = container.level if "skill" in context else 1 - fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Cynosural Field", + fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Cynosural Field Generator", "consumptionQuantity", container.getModifiedItemAttr("consumptionQuantityBonusPercentage") * level) diff --git a/eos/effects/damagecontrol.py b/eos/effects/damagecontrol.py index 05589e15a..f563fac03 100644 --- a/eos/effects/damagecontrol.py +++ b/eos/effects/damagecontrol.py @@ -11,6 +11,5 @@ def handler(fit, module, context): bonus = "%s%sDamageResonance" % (attrPrefix, damageType) bonus = "%s%s" % (bonus[0].lower(), bonus[1:]) booster = "%s%sDamageResonance" % (layer, damageType) - penalize = False if layer == 'hull' else True fit.ship.multiplyItemAttr(bonus, module.getModifiedItemAttr(booster), - stackingPenalties=penalize, penaltyGroup="preMul") + stackingPenalties=True, penaltyGroup="preMul") diff --git a/eos/effects/dohacking.py b/eos/effects/dohacking.py index 233d29404..ddd2a7205 100644 --- a/eos/effects/dohacking.py +++ b/eos/effects/dohacking.py @@ -1,7 +1,7 @@ # doHacking # # Used by: -# Modules from group: Data Miners (9 of 9) +# Modules from group: Data Miners (10 of 10) type = "active" diff --git a/eos/effects/dronearmordamagebonuseffect.py b/eos/effects/dronearmordamagebonuseffect.py index 144ad59d4..a5cfb52fe 100644 --- a/eos/effects/dronearmordamagebonuseffect.py +++ b/eos/effects/dronearmordamagebonuseffect.py @@ -1,7 +1,7 @@ # droneArmorDamageBonusEffect # # Used by: -# Ships from group: Logistics (5 of 6) +# Ships from group: Logistics (6 of 7) # Ship: Exequror # Ship: Scythe type = "passive" diff --git a/eos/effects/dronehullrepairbonuseffect.py b/eos/effects/dronehullrepairbonuseffect.py index e12dbbd2e..532f3e28e 100644 --- a/eos/effects/dronehullrepairbonuseffect.py +++ b/eos/effects/dronehullrepairbonuseffect.py @@ -1,7 +1,7 @@ # droneHullRepairBonusEffect # # Used by: -# Ships from group: Logistics (5 of 6) +# Ships from group: Logistics (6 of 7) # Ship: Exequror # Ship: Scythe type = "passive" diff --git a/eos/effects/droneshieldbonusbonuseffect.py b/eos/effects/droneshieldbonusbonuseffect.py index 1c83ed29d..2f2d1e6c5 100644 --- a/eos/effects/droneshieldbonusbonuseffect.py +++ b/eos/effects/droneshieldbonusbonuseffect.py @@ -1,7 +1,7 @@ # droneShieldBonusBonusEffect # # Used by: -# Ships from group: Logistics (5 of 6) +# Ships from group: Logistics (6 of 7) # Ship: Exequror # Ship: Scythe type = "passive" diff --git a/eos/effects/emergencyhullenergizer.py b/eos/effects/emergencyhullenergizer.py index 8a281f74c..c2de4f4f5 100644 --- a/eos/effects/emergencyhullenergizer.py +++ b/eos/effects/emergencyhullenergizer.py @@ -8,4 +8,6 @@ runtime = "late" def handler(fit, src, context): for dmgType in ('em', 'thermal', 'kinetic', 'explosive'): - fit.ship.forceItemAttr('{}DamageResonance'.format(dmgType), src.getModifiedItemAttr("hull{}DamageResonance".format(dmgType.title()))) + fit.ship.multiplyItemAttr('{}DamageResonance'.format(dmgType), + src.getModifiedItemAttr("hull{}DamageResonance".format(dmgType.title())), + stackingPenalties=True, penaltyGroup="postMul") diff --git a/eos/effects/fueledarmorrepair.py b/eos/effects/fueledarmorrepair.py index 049c799c1..79f9cf1e2 100644 --- a/eos/effects/fueledarmorrepair.py +++ b/eos/effects/fueledarmorrepair.py @@ -14,4 +14,7 @@ def handler(fit, module, context): amount = module.getModifiedItemAttr("armorDamageAmount") * multiplier speed = module.getModifiedItemAttr("duration") / 1000.0 - fit.extraAttributes.increase("armorRepair", amount / speed) + rps = amount / speed + fit.extraAttributes.increase("armorRepair", rps) + fit.extraAttributes.increase("armorRepairPreSpool", rps) + fit.extraAttributes.increase("armorRepairFullSpool", rps) diff --git a/eos/effects/iceharvestcycletimemodulesrequiringiceharvestingonline.py b/eos/effects/iceharvestcycletimemodulesrequiringiceharvestingonline.py index 19d58e81e..500775345 100644 --- a/eos/effects/iceharvestcycletimemodulesrequiringiceharvestingonline.py +++ b/eos/effects/iceharvestcycletimemodulesrequiringiceharvestingonline.py @@ -2,6 +2,7 @@ # # Used by: # Variations of module: Ice Harvester Upgrade I (5 of 5) +# Module: Frostline 'Omnivore' Harvester Upgrade type = "passive" diff --git a/eos/effects/implantwarpscramblerangebonus.py b/eos/effects/implantwarpscramblerangebonus.py new file mode 100644 index 000000000..8eea16959 --- /dev/null +++ b/eos/effects/implantwarpscramblerangebonus.py @@ -0,0 +1,10 @@ +# implantWarpScrambleRangeBonus +# +# Used by: +# Implants named like: Inquest 'Hedone' Entanglement Optimizer WS (3 of 3) +type = "passive" + + +def handler(fit, src, context): + fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Warp Scrambler", "maxRange", + src.getModifiedItemAttr("warpScrambleRangeBonus"), stackingPenalties=False) diff --git a/eos/effects/increasesignatureradiusonline.py b/eos/effects/increasesignatureradiusonline.py index bc58e44b9..1ae8fe69a 100644 --- a/eos/effects/increasesignatureradiusonline.py +++ b/eos/effects/increasesignatureradiusonline.py @@ -6,4 +6,4 @@ type = "passive" def handler(fit, module, context): - fit.ship.boostItemAttr("signatureRadius", module.getModifiedItemAttr("signatureRadiusBonus")) + fit.ship.boostItemAttr("signatureRadius", module.getModifiedItemAttr("signatureRadiusBonus"), stackingPenalties=True) diff --git a/eos/effects/minercpuusagemultiplypercent2.py b/eos/effects/minercpuusagemultiplypercent2.py index 7b8e6025a..7cba56603 100644 --- a/eos/effects/minercpuusagemultiplypercent2.py +++ b/eos/effects/minercpuusagemultiplypercent2.py @@ -2,6 +2,7 @@ # # Used by: # Variations of module: Mining Laser Upgrade I (5 of 5) +# Module: Frostline 'Omnivore' Harvester Upgrade type = "passive" diff --git a/eos/effects/miningdurationmultiplieronline.py b/eos/effects/miningdurationmultiplieronline.py new file mode 100644 index 000000000..3d4cad5a5 --- /dev/null +++ b/eos/effects/miningdurationmultiplieronline.py @@ -0,0 +1,10 @@ +# miningDurationMultiplierOnline +# +# Used by: +# Module: Frostline 'Omnivore' Harvester Upgrade +type = "passive" + + +def handler(fit, module, context): + fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Mining Laser", + "duration", module.getModifiedItemAttr("miningDurationMultiplier")) diff --git a/eos/effects/miningyieldmultiplypercent.py b/eos/effects/miningyieldmultiplypercent.py index 281b7169f..a02b4333b 100644 --- a/eos/effects/miningyieldmultiplypercent.py +++ b/eos/effects/miningyieldmultiplypercent.py @@ -2,6 +2,7 @@ # # Used by: # Variations of module: Mining Laser Upgrade I (5 of 5) +# Module: Frostline 'Omnivore' Harvester Upgrade type = "passive" diff --git a/eos/effects/missileaoevelocitybonusonline.py b/eos/effects/missileaoevelocitybonusonline.py index e5d0d27c9..03ddd6715 100644 --- a/eos/effects/missileaoevelocitybonusonline.py +++ b/eos/effects/missileaoevelocitybonusonline.py @@ -2,6 +2,7 @@ # # Used by: # Modules from group: Missile Guidance Enhancer (3 of 3) +# Module: ML-EKP 'Polybolos' Ballistic Control System type = "passive" diff --git a/eos/effects/missiledmgbonus.py b/eos/effects/missiledmgbonus.py index 263ba9834..4fca60500 100644 --- a/eos/effects/missiledmgbonus.py +++ b/eos/effects/missiledmgbonus.py @@ -1,7 +1,7 @@ # missileDMGBonus # # Used by: -# Modules from group: Ballistic Control system (21 of 21) +# Modules from group: Ballistic Control system (22 of 22) type = "passive" diff --git a/eos/effects/missilelauncherspeedmultiplier.py b/eos/effects/missilelauncherspeedmultiplier.py index 68a2bd707..2655e614e 100644 --- a/eos/effects/missilelauncherspeedmultiplier.py +++ b/eos/effects/missilelauncherspeedmultiplier.py @@ -1,7 +1,7 @@ # missileLauncherSpeedMultiplier # # Used by: -# Modules from group: Ballistic Control system (21 of 21) +# Modules from group: Ballistic Control system (22 of 22) type = "passive" diff --git a/eos/effects/npcentityremotearmorrepairer.py b/eos/effects/npcentityremotearmorrepairer.py index 689a1ac35..e74505c96 100644 --- a/eos/effects/npcentityremotearmorrepairer.py +++ b/eos/effects/npcentityremotearmorrepairer.py @@ -9,4 +9,7 @@ def handler(fit, container, context): if "projected" in context: bonus = container.getModifiedItemAttr("armorDamageAmount") duration = container.getModifiedItemAttr("duration") / 1000.0 - fit.extraAttributes.increase("armorRepair", bonus / duration) + rps = bonus / duration + fit.extraAttributes.increase("armorRepair", rps) + fit.extraAttributes.increase("armorRepairPreSpool", rps) + fit.extraAttributes.increase("armorRepairFullSpool", rps) diff --git a/eos/effects/overloadrofbonus.py b/eos/effects/overloadrofbonus.py index 47f64d418..c0fedef1a 100644 --- a/eos/effects/overloadrofbonus.py +++ b/eos/effects/overloadrofbonus.py @@ -2,7 +2,7 @@ # # Used by: # Modules from group: Missile Launcher Torpedo (22 of 22) -# Items from market group: Ship Equipment > Turrets & Bays (429 of 881) +# Items from market group: Ship Equipment > Turrets & Bays (429 of 883) # Module: Interdiction Sphere Launcher I type = "overheat" diff --git a/eos/effects/overloadselfdurationbonus.py b/eos/effects/overloadselfdurationbonus.py index fd4a5561c..e4ecde55c 100644 --- a/eos/effects/overloadselfdurationbonus.py +++ b/eos/effects/overloadselfdurationbonus.py @@ -1,17 +1,17 @@ # overloadSelfDurationBonus # # Used by: +# Modules from group: Ancillary Remote Shield Booster (4 of 4) # Modules from group: Capacitor Booster (59 of 59) # Modules from group: Energy Neutralizer (54 of 54) # Modules from group: Energy Nosferatu (54 of 54) # Modules from group: Hull Repair Unit (25 of 25) # Modules from group: Remote Armor Repairer (39 of 39) # Modules from group: Remote Capacitor Transmitter (41 of 41) -# Modules from group: Remote Hull Repairer (8 of 8) # Modules from group: Remote Shield Booster (38 of 38) # Modules from group: Smart Bomb (118 of 118) # Modules from group: Warp Disrupt Field Generator (7 of 7) -# Modules named like: Ancillary Remote (8 of 8) +# Modules named like: Remote Repairer (56 of 56) # Module: Reactive Armor Hardener # Module: Target Spectrum Breaker type = "overheat" diff --git a/eos/effects/remotecapacitortransmitterpowerneedbonuseffect.py b/eos/effects/remotecapacitortransmitterpowerneedbonuseffect.py index f9c254dd9..54897ba12 100644 --- a/eos/effects/remotecapacitortransmitterpowerneedbonuseffect.py +++ b/eos/effects/remotecapacitortransmitterpowerneedbonuseffect.py @@ -1,7 +1,7 @@ # remoteCapacitorTransmitterPowerNeedBonusEffect # # Used by: -# Ships from group: Logistics (3 of 6) +# Ships from group: Logistics (3 of 7) type = "passive" diff --git a/eos/effects/remotewebifiermaxrangebonus.py b/eos/effects/remotewebifiermaxrangebonus.py index 46e5887dd..531f18ded 100644 --- a/eos/effects/remotewebifiermaxrangebonus.py +++ b/eos/effects/remotewebifiermaxrangebonus.py @@ -2,6 +2,7 @@ # # Used by: # Implants named like: Inquest 'Eros' Stasis Webifier MR (3 of 3) +# Implants named like: Inquest 'Hedone' Entanglement Optimizer WS (3 of 3) type = "passive" diff --git a/eos/effects/shieldtransportcpuneedbonuseffect.py b/eos/effects/shieldtransportcpuneedbonuseffect.py index bd96b3efc..427290a3f 100644 --- a/eos/effects/shieldtransportcpuneedbonuseffect.py +++ b/eos/effects/shieldtransportcpuneedbonuseffect.py @@ -1,7 +1,7 @@ # shieldTransportCpuNeedBonusEffect # # Used by: -# Ships from group: Logistics (3 of 6) +# Ships from group: Logistics (3 of 7) type = "passive" diff --git a/eos/effects/shipbonusmutadaptiveremoterepairrangerole3.py b/eos/effects/shipbonusmutadaptiveremoterepairrangerole3.py new file mode 100644 index 000000000..64fca9ffb --- /dev/null +++ b/eos/effects/shipbonusmutadaptiveremoterepairrangerole3.py @@ -0,0 +1,7 @@ +# shipBonusMutadaptiveRemoteRepairRangeRole3 +# +# Used by: +# Ship: Rodiva +type = "passive" +def handler(fit, src, context): + fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Mutadaptive Remote Armor Repairer", "maxRange", src.getModifiedItemAttr("shipBonusRole3")) diff --git a/eos/effects/shipbonusmutadaptiveremoterepamountelitebonuslogisitics2.py b/eos/effects/shipbonusmutadaptiveremoterepamountelitebonuslogisitics2.py new file mode 100644 index 000000000..b8ae258c3 --- /dev/null +++ b/eos/effects/shipbonusmutadaptiveremoterepamountelitebonuslogisitics2.py @@ -0,0 +1,7 @@ +# shipBonusMutadaptiveRemoteRepAmounteliteBonusLogisitics2 +# +# Used by: +# Ship: Zarmazd +type = "passive" +def handler(fit, src, context): + fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Mutadaptive Remote Armor Repairer", "armorDamageAmount", src.getModifiedItemAttr("eliteBonusLogistics2"), skill="Logistics Cruisers") diff --git a/eos/effects/shipbonusmutadaptiveremoterepcapneedelitebonuslogisitics1.py b/eos/effects/shipbonusmutadaptiveremoterepcapneedelitebonuslogisitics1.py new file mode 100644 index 000000000..b936f644c --- /dev/null +++ b/eos/effects/shipbonusmutadaptiveremoterepcapneedelitebonuslogisitics1.py @@ -0,0 +1,7 @@ +# shipBonusMutadaptiveRemoteRepCapNeedeliteBonusLogisitics1 +# +# Used by: +# Ship: Zarmazd +type = "passive" +def handler(fit, src, context): + fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Mutadaptive Remote Armor Repairer", "capacitorNeed", src.getModifiedItemAttr("eliteBonusLogistics1"), skill="Logistics Cruisers") diff --git a/eos/effects/shipbonusmutadaptiveremotereprangepc1.py b/eos/effects/shipbonusmutadaptiveremotereprangepc1.py new file mode 100644 index 000000000..67b2da620 --- /dev/null +++ b/eos/effects/shipbonusmutadaptiveremotereprangepc1.py @@ -0,0 +1,7 @@ +# shipBonusMutadaptiveRemoteRepRangePC1 +# +# Used by: +# Ship: Zarmazd +type = "passive" +def handler(fit, src, context): + fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Mutadaptive Remote Armor Repairer", "maxRange", src.getModifiedItemAttr("shipBonusPC1"), skill="Precursor Cruiser") diff --git a/eos/effects/shipbonusmutadaptiverepamountpc1.py b/eos/effects/shipbonusmutadaptiverepamountpc1.py new file mode 100644 index 000000000..7e892f3e4 --- /dev/null +++ b/eos/effects/shipbonusmutadaptiverepamountpc1.py @@ -0,0 +1,7 @@ +# shipBonusMutadaptiveRepAmountPC1 +# +# Used by: +# Ship: Rodiva +type = "passive" +def handler(fit, src, context): + fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Mutadaptive Remote Armor Repairer", "armorDamageAmount", src.getModifiedItemAttr("shipBonusPC1"), skill="Precursor Cruiser") diff --git a/eos/effects/shipbonusmutadaptiverepcapneedpc2.py b/eos/effects/shipbonusmutadaptiverepcapneedpc2.py new file mode 100644 index 000000000..22348514a --- /dev/null +++ b/eos/effects/shipbonusmutadaptiverepcapneedpc2.py @@ -0,0 +1,7 @@ +# shipBonusMutadaptiveRepCapNeedPC2 +# +# Used by: +# Ship: Rodiva +type = "passive" +def handler(fit, src, context): + fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Mutadaptive Remote Armor Repairer", "capacitorNeed", src.getModifiedItemAttr("shipBonusPC2"), skill="Precursor Cruiser") diff --git a/eos/effects/shipbonusnosneutcapneedrolebonus2.py b/eos/effects/shipbonusnosneutcapneedrolebonus2.py new file mode 100644 index 000000000..ec427ec11 --- /dev/null +++ b/eos/effects/shipbonusnosneutcapneedrolebonus2.py @@ -0,0 +1,7 @@ +# shipBonusNosNeutCapNeedRoleBonus2 +# +# Used by: +# Variations of ship: Rodiva (2 of 2) +type = "passive" +def handler(fit, src, context): + fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capacitor Emission Systems"), "capacitorNeed", src.getModifiedItemAttr("shipBonusRole2")) diff --git a/eos/effects/shipbonusremotecapacitortransferrangerole1.py b/eos/effects/shipbonusremotecapacitortransferrangerole1.py new file mode 100644 index 000000000..bfd670862 --- /dev/null +++ b/eos/effects/shipbonusremotecapacitortransferrangerole1.py @@ -0,0 +1,7 @@ +# shipBonusRemoteCapacitorTransferRangeRole1 +# +# Used by: +# Variations of ship: Rodiva (2 of 2) +type = "passive" +def handler(fit, src, context): + fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Remote Capacitor Transmitter", "maxRange", src.getModifiedItemAttr("shipBonusRole1")) diff --git a/eos/effects/shipbonusrole5remotearmorrepairpowergridbonus.py b/eos/effects/shipbonusrole5remotearmorrepairpowergridbonus.py index 3f764d908..5e87c2241 100644 --- a/eos/effects/shipbonusrole5remotearmorrepairpowergridbonus.py +++ b/eos/effects/shipbonusrole5remotearmorrepairpowergridbonus.py @@ -1,7 +1,7 @@ # shipBonusRole5RemoteArmorRepairPowergridBonus # # Used by: -# Ships from group: Logistics (3 of 6) +# Ships from group: Logistics (3 of 7) type = "passive" diff --git a/eos/effects/shipbonussmartbombcapneedrolebonus2.py b/eos/effects/shipbonussmartbombcapneedrolebonus2.py index 62bd5dcba..69e4017a8 100644 --- a/eos/effects/shipbonussmartbombcapneedrolebonus2.py +++ b/eos/effects/shipbonussmartbombcapneedrolebonus2.py @@ -1,6 +1,7 @@ # shipBonusSmartbombCapNeedRoleBonus2 # # Used by: +# Variations of ship: Rodiva (2 of 2) # Ship: Damavik # Ship: Drekavac # Ship: Hydra diff --git a/eos/effects/shipmoduleancillaryremotearmorrepairer.py b/eos/effects/shipmoduleancillaryremotearmorrepairer.py index 4085aaeeb..a1697eec7 100644 --- a/eos/effects/shipmoduleancillaryremotearmorrepairer.py +++ b/eos/effects/shipmoduleancillaryremotearmorrepairer.py @@ -2,8 +2,9 @@ # # Used by: # Modules from group: Ancillary Remote Armor Repairer (4 of 4) -runTime = "late" + type = "projected", "active" +runTime = "late" def handler(fit, module, context, **kwargs): @@ -17,4 +18,7 @@ def handler(fit, module, context, **kwargs): amount = module.getModifiedItemAttr("armorDamageAmount") * multiplier speed = module.getModifiedItemAttr("duration") / 1000.0 - fit.extraAttributes.increase("armorRepair", amount / speed, **kwargs) + rps = amount / speed + fit.extraAttributes.increase("armorRepair", rps) + fit.extraAttributes.increase("armorRepairPreSpool", rps) + fit.extraAttributes.increase("armorRepairFullSpool", rps) diff --git a/eos/effects/shipmoduleancillaryremoteshieldbooster.py b/eos/effects/shipmoduleancillaryremoteshieldbooster.py index 5fbcb0ee0..dc135bc0a 100644 --- a/eos/effects/shipmoduleancillaryremoteshieldbooster.py +++ b/eos/effects/shipmoduleancillaryremoteshieldbooster.py @@ -2,8 +2,9 @@ # # Used by: # Modules from group: Ancillary Remote Shield Booster (4 of 4) -runTime = "late" + type = "projected", "active" +runTime = "late" def handler(fit, module, context, **kwargs): diff --git a/eos/effects/shipmoduleremotearmormutadaptiverepairer.py b/eos/effects/shipmoduleremotearmormutadaptiverepairer.py new file mode 100644 index 000000000..ec98c1e23 --- /dev/null +++ b/eos/effects/shipmoduleremotearmormutadaptiverepairer.py @@ -0,0 +1,28 @@ +# ShipModuleRemoteArmorMutadaptiveRepairer +# +# Used by: +# Modules from group: Mutadaptive Remote Armor Repairer (5 of 5) + + +from eos.utils.spoolSupport import SpoolType, SpoolOptions, calculateSpoolup, resolveSpoolOptions + + +type = "projected", "active" +runTime = "late" + + +def handler(fit, container, context, **kwargs): + if "projected" in context: + repAmountBase = container.getModifiedItemAttr("armorDamageAmount") + cycleTime = container.getModifiedItemAttr("duration") / 1000.0 + repSpoolMax = container.getModifiedItemAttr("repairMultiplierBonusMax") + repSpoolPerCycle = container.getModifiedItemAttr("repairMultiplierBonusPerCycle") + # TODO: fetch spoolup option + defaultSpoolValue = 1 + spoolType, spoolAmount = resolveSpoolOptions(SpoolOptions(SpoolType.SCALE, defaultSpoolValue, False), container) + rps = repAmountBase * (1 + calculateSpoolup(repSpoolMax, repSpoolPerCycle, cycleTime, spoolType, spoolAmount)[0]) / cycleTime + rpsPreSpool = repAmountBase * (1 + calculateSpoolup(repSpoolMax, repSpoolPerCycle, cycleTime, SpoolType.SCALE, 0)[0]) / cycleTime + rpsFullSpool = repAmountBase * (1 + calculateSpoolup(repSpoolMax, repSpoolPerCycle, cycleTime, SpoolType.SCALE, 1)[0]) / cycleTime + fit.extraAttributes.increase("armorRepair", rps, **kwargs) + fit.extraAttributes.increase("armorRepairPreSpool", rpsPreSpool, **kwargs) + fit.extraAttributes.increase("armorRepairFullSpool", rpsFullSpool, **kwargs) diff --git a/eos/effects/shipmoduleremotearmorrepairer.py b/eos/effects/shipmoduleremotearmorrepairer.py index 706dd74ee..220792812 100644 --- a/eos/effects/shipmoduleremotearmorrepairer.py +++ b/eos/effects/shipmoduleremotearmorrepairer.py @@ -2,11 +2,16 @@ # # Used by: # Modules from group: Remote Armor Repairer (39 of 39) + type = "projected", "active" +runTime = "late" def handler(fit, container, context, **kwargs): if "projected" in context: bonus = container.getModifiedItemAttr("armorDamageAmount") duration = container.getModifiedItemAttr("duration") / 1000.0 - fit.extraAttributes.increase("armorRepair", bonus / duration, **kwargs) + rps = bonus / duration + fit.extraAttributes.increase("armorRepair", rps) + fit.extraAttributes.increase("armorRepairPreSpool", rps) + fit.extraAttributes.increase("armorRepairFullSpool", rps) diff --git a/eos/effects/shipmoduleremotecapacitortransmitter.py b/eos/effects/shipmoduleremotecapacitortransmitter.py index 9ea44beb6..6b414da7e 100644 --- a/eos/effects/shipmoduleremotecapacitortransmitter.py +++ b/eos/effects/shipmoduleremotecapacitortransmitter.py @@ -2,8 +2,13 @@ # # Used by: # Modules from group: Remote Capacitor Transmitter (41 of 41) + + from eos.modifiedAttributeDict import ModifiedAttributeDict + + type = "projected", "active" +runTime = "late" def handler(fit, src, context, **kwargs): diff --git a/eos/effects/shipmoduleremotehullrepairer.py b/eos/effects/shipmoduleremotehullrepairer.py index 5b4cce596..94839fdff 100644 --- a/eos/effects/shipmoduleremotehullrepairer.py +++ b/eos/effects/shipmoduleremotehullrepairer.py @@ -2,6 +2,7 @@ # # Used by: # Modules from group: Remote Hull Repairer (8 of 8) + type = "projected", "active" runTime = "late" diff --git a/eos/effects/skillbombdeploymentmodulereactivationdelaybonus.py b/eos/effects/skillbombdeploymentmodulereactivationdelaybonus.py index e56b2fb94..4db900c9b 100644 --- a/eos/effects/skillbombdeploymentmodulereactivationdelaybonus.py +++ b/eos/effects/skillbombdeploymentmodulereactivationdelaybonus.py @@ -7,4 +7,4 @@ type = "passive" def handler(fit, skill, context): fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Missile Launcher Bomb", - "moduleReactivationDelay", skill.getModifiedItemAttr("rofBonus") * skill.level) + "moduleReactivationDelay", skill.getModifiedItemAttr("reactivationDelayBonus") * skill.level) diff --git a/eos/effects/skillbonusdronedurability.py b/eos/effects/skillbonusdronedurability.py index e68cb4254..f36e82a3f 100644 --- a/eos/effects/skillbonusdronedurability.py +++ b/eos/effects/skillbonusdronedurability.py @@ -1,7 +1,6 @@ # skillBonusDroneDurability # # Used by: -# Implants from group: Cyber Drones (4 of 4) # Skill: Drone Durability type = "passive" diff --git a/eos/effects/skillbonusdronedurabilitynotfighters.py b/eos/effects/skillbonusdronedurabilitynotfighters.py new file mode 100644 index 000000000..d2b8a0967 --- /dev/null +++ b/eos/effects/skillbonusdronedurabilitynotfighters.py @@ -0,0 +1,14 @@ +# skillBonusDroneDurabilityNotFighters +# +# Used by: +# Implants from group: Cyber Drones (4 of 4) +type = "passive" + + +def handler(fit, src, context): + fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Drones"), "hp", + src.getModifiedItemAttr("hullHpBonus")) + fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Drones"), "armorHP", + src.getModifiedItemAttr("armorHpBonus")) + fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Drones"), "shieldCapacity", + src.getModifiedItemAttr("shieldCapacityBonus")) diff --git a/eos/effects/skillbonusdroneinterfacing.py b/eos/effects/skillbonusdroneinterfacing.py index 93093efc3..d832d432b 100644 --- a/eos/effects/skillbonusdroneinterfacing.py +++ b/eos/effects/skillbonusdroneinterfacing.py @@ -1,8 +1,6 @@ # skillBonusDroneInterfacing # # Used by: -# Implant: CreoDron 'Bumblebee' Drone Tuner T10-5D -# Implant: CreoDron 'Yellowjacket' Drone Tuner D5-10T # Skill: Drone Interfacing type = "passive" diff --git a/eos/effects/skillbonusdroneinterfacingnotfighters.py b/eos/effects/skillbonusdroneinterfacingnotfighters.py new file mode 100644 index 000000000..01ab85de7 --- /dev/null +++ b/eos/effects/skillbonusdroneinterfacingnotfighters.py @@ -0,0 +1,11 @@ +# skillBonusDroneInterfacingNotFighters +# +# Used by: +# Implant: CreoDron 'Bumblebee' Drone Tuner T10-5D +# Implant: CreoDron 'Yellowjacket' Drone Tuner D5-10T +type = "passive" + + +def handler(fit, src, context): + fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Drones"), "damageMultiplier", + src.getModifiedItemAttr("damageMultiplierBonus")) diff --git a/eos/effects/stripminerdurationmultiplier.py b/eos/effects/stripminerdurationmultiplier.py new file mode 100644 index 000000000..c9d0179a6 --- /dev/null +++ b/eos/effects/stripminerdurationmultiplier.py @@ -0,0 +1,10 @@ +# stripMinerDurationMultiplier +# +# Used by: +# Module: Frostline 'Omnivore' Harvester Upgrade +type = "passive" + + +def handler(fit, module, context): + fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Strip Miner", + "duration", module.getModifiedItemAttr("miningDurationMultiplier")) diff --git a/eos/gamedata.py b/eos/gamedata.py index 4a1c73a67..1abb3f69b 100644 --- a/eos/gamedata.py +++ b/eos/gamedata.py @@ -239,7 +239,7 @@ class Item(EqBase): self.__offensive = None self.__assistive = None self.__overrides = None - self.__price = None + self.__priceObj = None @property def attributes(self): @@ -446,34 +446,33 @@ class Item(EqBase): @property def price(self): - # todo: use `from sqlalchemy import inspect` instead (mac-deprecated doesn't have inspect(), was imp[lemented in 0.8) - if self.__price is not None and getattr(self.__price, '_sa_instance_state', None) and self.__price._sa_instance_state.deleted: + if self.__priceObj is not None and getattr(self.__priceObj, '_sa_instance_state', None) and self.__priceObj._sa_instance_state.deleted: pyfalog.debug("Price data for {} was deleted (probably from a cache reset), resetting object".format(self.ID)) - self.__price = None + self.__priceObj = None - if self.__price is None: + if self.__priceObj is None: db_price = eos.db.getPrice(self.ID) # do not yet have a price in the database for this item, create one if db_price is None: pyfalog.debug("Creating a price for {}".format(self.ID)) - self.__price = types_Price(self.ID) - eos.db.add(self.__price) - eos.db.commit() + self.__priceObj = types_Price(self.ID) + eos.db.add(self.__priceObj) + eos.db.flush() else: - self.__price = db_price + self.__priceObj = db_price - return self.__price + return self.__priceObj @property def isAbyssal(self): if Item.ABYSSAL_TYPES is None: - Item.getAbyssalYypes() + Item.getAbyssalTypes() return self.ID in Item.ABYSSAL_TYPES @classmethod - def getAbyssalYypes(cls): + def getAbyssalTypes(cls): cls.ABYSSAL_TYPES = eos.db.getAbyssalTypes() @property diff --git a/eos/graph/fitDps.py b/eos/graph/fitDps.py index 61783fdc7..a8d6c4ec3 100644 --- a/eos/graph/fitDps.py +++ b/eos/graph/fitDps.py @@ -75,7 +75,7 @@ class FitDpsGraph(Graph): pyfalog.critical(e) for mod in fit.modules: - dps, _ = mod.damageStats(fit.targetResists) + dps = mod.getDps(targetResists=fit.targetResists).total if mod.hardpoint == Hardpoint.TURRET: if mod.state >= State.ACTIVE: total += dps * self.calculateTurretMultiplier(mod, data) @@ -88,7 +88,7 @@ class FitDpsGraph(Graph): for drone in fit.drones: multiplier = 1 if drone.getModifiedItemAttr("maxVelocity") > 1 else self.calculateTurretMultiplier( drone, data) - dps, _ = drone.damageStats(fit.targetResists) + dps = drone.getDps(targetResists=fit.targetResists).total total += dps * multiplier # this is janky as fuck @@ -98,7 +98,7 @@ class FitDpsGraph(Graph): for ability in fighter.abilities: if ability.dealsDamage and ability.active: multiplier = self.calculateFighterMissileMultiplier(ability, data) - dps, _ = ability.damageStats(fit.targetResists) + dps = ability.getDps(targetResists=fit.targetResists).total total += dps * multiplier return total diff --git a/eos/modifiedAttributeDict.py b/eos/modifiedAttributeDict.py index d660dd38b..756a9f806 100644 --- a/eos/modifiedAttributeDict.py +++ b/eos/modifiedAttributeDict.py @@ -215,6 +215,8 @@ class ModifiedAttributeDict(collections.MutableMapping): if force is not None: if cappingValue is not None: force = min(force, cappingValue) + if key in (50, 30, 48, 11): + force = round(force, 2) return force # Grab our values if they're there, otherwise we'll take default values preIncrease = self.__preIncreases.get(key, 0) @@ -268,7 +270,8 @@ class ModifiedAttributeDict(collections.MutableMapping): # Cap value if we have cap defined if cappingValue is not None: val = min(val, cappingValue) - + if key in (50, 30, 48, 11): + val = round(val, 2) return val def __handleSkill(self, skillName): diff --git a/eos/saveddata/damagePattern.py b/eos/saveddata/damagePattern.py index d7889f131..30015e715 100644 --- a/eos/saveddata/damagePattern.py +++ b/eos/saveddata/damagePattern.py @@ -42,13 +42,18 @@ class DamagePattern(object): return ehp def calculateEffectiveTank(self, fit, tankInfo): - ehps = {} - passiveShield = fit.calculateShieldRecharge() - ehps["passiveShield"] = self.effectivify(fit, passiveShield, "shield") - for type in ("shield", "armor", "hull"): - ehps["%sRepair" % type] = self.effectivify(fit, tankInfo["%sRepair" % type], type) - - return ehps + typeMap = { + "passiveShield": "shield", + "shieldRepair": "shield", + "armorRepair": "armor", + "armorRepairPreSpool": "armor", + "armorRepairFullSpool": "armor", + "hullRepair": "hull"} + ereps = {} + for field in tankInfo: + if field in typeMap: + ereps[field] = self.effectivify(fit, tankInfo[field], typeMap[field]) + return ereps def effectivify(self, fit, amount, type): type = type if type != "hull" else "" diff --git a/eos/saveddata/drone.py b/eos/saveddata/drone.py index 4cddbea42..2fec27fc9 100644 --- a/eos/saveddata/drone.py +++ b/eos/saveddata/drone.py @@ -24,12 +24,13 @@ from sqlalchemy.orm import validates, reconstructor import eos.db from eos.effectHandlerHelpers import HandledItem, HandledCharge from eos.modifiedAttributeDict import ModifiedAttributeDict, ItemAttrShortcut, ChargeAttrShortcut +from eos.utils.stats import DmgTypes + pyfalog = Logger(__name__) class Drone(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut): - DAMAGE_TYPES = ("em", "kinetic", "explosive", "thermal") MINING_ATTRIBUTES = ("miningAmount",) def __init__(self, item): @@ -65,8 +66,8 @@ class Drone(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut): def build(self): """ Build object. Assumes proper and valid item already set """ self.__charge = None - self.__dps = None - self.__volley = None + self.__baseVolley = None + self.__baseRemoteReps = None self.__miningyield = None self.__itemModifiedAttributes = ModifiedAttributeDict() self.__itemModifiedAttributes.original = self.__item.attributes @@ -120,37 +121,67 @@ class Drone(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut): def hasAmmo(self): return self.charge is not None - @property - def dps(self): - return self.damageStats() + def getVolley(self, targetResists=None): + if not self.dealsDamage or self.amountActive <= 0: + return DmgTypes(0, 0, 0, 0) + if self.__baseVolley is None: + dmgGetter = self.getModifiedChargeAttr if self.hasAmmo else self.getModifiedItemAttr + dmgMult = self.amountActive * (self.getModifiedItemAttr("damageMultiplier", 1)) + self.__baseVolley = DmgTypes( + em=(dmgGetter("emDamage", 0)) * dmgMult, + thermal=(dmgGetter("thermalDamage", 0)) * dmgMult, + kinetic=(dmgGetter("kineticDamage", 0)) * dmgMult, + explosive=(dmgGetter("explosiveDamage", 0)) * dmgMult) + volley = DmgTypes( + em=self.__baseVolley.em * (1 - getattr(targetResists, "emAmount", 0)), + thermal=self.__baseVolley.thermal * (1 - getattr(targetResists, "thermalAmount", 0)), + kinetic=self.__baseVolley.kinetic * (1 - getattr(targetResists, "kineticAmount", 0)), + explosive=self.__baseVolley.explosive * (1 - getattr(targetResists, "explosiveAmount", 0))) + return volley + + def getDps(self, targetResists=None): + volley = self.getVolley(targetResists=targetResists) + if not volley: + return DmgTypes(0, 0, 0, 0) + cycleAttr = "missileLaunchDuration" if self.hasAmmo else "speed" + cycleTime = self.getModifiedItemAttr(cycleAttr) + dpsFactor = 1 / (cycleTime / 1000) + dps = DmgTypes( + em=volley.em * dpsFactor, + thermal=volley.thermal * dpsFactor, + kinetic=volley.kinetic * dpsFactor, + explosive=volley.explosive * dpsFactor) + return dps + + def getRemoteReps(self, ignoreState=False): + if self.amountActive <= 0 and not ignoreState: + return (None, 0) + if self.__baseRemoteReps is None: + rrShield = self.getModifiedItemAttr("shieldBonus", 0) + rrArmor = self.getModifiedItemAttr("armorDamageAmount", 0) + rrHull = self.getModifiedItemAttr("structureDamageAmount", 0) + if rrShield: + rrType = "Shield" + rrAmount = rrShield + elif rrArmor: + rrType = "Armor" + rrAmount = rrArmor + elif rrHull: + rrType = "Hull" + rrAmount = rrHull + else: + rrType = None + rrAmount = 0 + if rrAmount: + droneAmount = self.amount if ignoreState else self.amountActive + rrAmount *= droneAmount / (self.cycleTime / 1000) + self.__baseRemoteReps = (rrType, rrAmount) + return self.__baseRemoteReps def changeType(self, typeID): self.itemID = typeID self.init() - def damageStats(self, targetResists=None): - if self.__dps is None: - self.__volley = 0 - self.__dps = 0 - if self.dealsDamage is True and self.amountActive > 0: - if self.hasAmmo: - attr = "missileLaunchDuration" - getter = self.getModifiedChargeAttr - else: - attr = "speed" - getter = self.getModifiedItemAttr - - cycleTime = self.getModifiedItemAttr(attr) - - volley = sum( - [(getter("%sDamage" % d) or 0) * (1 - getattr(targetResists, "%sAmount" % d, 0)) for d in self.DAMAGE_TYPES]) - volley *= self.amountActive - volley *= self.getModifiedItemAttr("damageMultiplier") or 1 - self.__volley = volley - self.__dps = volley / (cycleTime / 1000.0) - - return self.__dps, self.__volley - @property def miningStats(self): if self.__miningyield is None: @@ -208,8 +239,8 @@ class Drone(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut): return val def clear(self): - self.__dps = None - self.__volley = None + self.__baseVolley = None + self.__baseRemoteReps = None self.__miningyield = None self.itemModifiedAttributes.clear() self.chargeModifiedAttributes.clear() diff --git a/eos/saveddata/fighter.py b/eos/saveddata/fighter.py index 8c515b945..4b929d594 100644 --- a/eos/saveddata/fighter.py +++ b/eos/saveddata/fighter.py @@ -26,6 +26,7 @@ from eos.effectHandlerHelpers import HandledItem, HandledCharge from eos.modifiedAttributeDict import ModifiedAttributeDict, ItemAttrShortcut, ChargeAttrShortcut from eos.saveddata.fighterAbility import FighterAbility from eos.saveddata.module import Slot +from eos.utils.stats import DmgTypes pyfalog = Logger(__name__) @@ -87,8 +88,7 @@ class Fighter(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut): def build(self): """ Build object. Assumes proper and valid item already set """ self.__charge = None - self.__dps = None - self.__volley = None + self.__baseVolley = None self.__miningyield = None self.__itemModifiedAttributes = ModifiedAttributeDict() self.__chargeModifiedAttributes = ModifiedAttributeDict() @@ -172,43 +172,88 @@ class Fighter(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut): def hasAmmo(self): return self.charge is not None - @property - def dps(self): - return self.damageStats() + def getVolley(self, targetResists=None): + if not self.active or self.amountActive <= 0: + return DmgTypes(0, 0, 0, 0) + if self.__baseVolley is None: + em = 0 + therm = 0 + kin = 0 + exp = 0 + for ability in self.abilities: + # Not passing resists here as we want to calculate and store base volley + abilityVolley = ability.getVolley() + em += abilityVolley.em + therm += abilityVolley.thermal + kin += abilityVolley.kinetic + exp += abilityVolley.explosive + self.__baseVolley = DmgTypes(em, therm, kin, exp) + volley = DmgTypes( + em=self.__baseVolley.em * (1 - getattr(targetResists, "emAmount", 0)), + thermal=self.__baseVolley.thermal * (1 - getattr(targetResists, "thermalAmount", 0)), + kinetic=self.__baseVolley.kinetic * (1 - getattr(targetResists, "kineticAmount", 0)), + explosive=self.__baseVolley.explosive * (1 - getattr(targetResists, "explosiveAmount", 0))) + return volley - def damageStats(self, targetResists=None): - if self.__dps is None: - self.__volley = 0 - self.__dps = 0 - if self.active and self.amountActive > 0: - for ability in self.abilities: - dps, volley = ability.damageStats(targetResists) - self.__dps += dps - self.__volley += volley - - # For forward compatability this assumes a fighter - # can have more than 2 damaging abilities and/or - # multiple that use charges. - if self.owner.factorReload: - activeTimes = [] - reloadTimes = [] - constantDps = 0 - for ability in self.abilities: - if not ability.active: - continue - if ability.numShots == 0: - dps, volley = ability.damageStats(targetResists) - constantDps += dps - continue - activeTimes.append(ability.numShots * ability.cycleTime) - reloadTimes.append(ability.reloadTime) - - if len(activeTimes) > 0: - shortestActive = sorted(activeTimes)[0] - longestReload = sorted(reloadTimes, reverse=True)[0] - self.__dps = max(constantDps, self.__dps * shortestActive / (shortestActive + longestReload)) - - return self.__dps, self.__volley + def getDps(self, targetResists=None): + if not self.active or self.amountActive <= 0: + return DmgTypes(0, 0, 0, 0) + # Analyze cooldowns when reload is factored in + if self.owner.factorReload: + activeTimes = [] + reloadTimes = [] + peakEm = 0 + peakTherm = 0 + peakKin = 0 + peakExp = 0 + steadyEm = 0 + steadyTherm = 0 + steadyKin = 0 + steadyExp = 0 + for ability in self.abilities: + abilityDps = ability.getDps(targetResists=targetResists) + # Peak dps + peakEm += abilityDps.em + peakTherm += abilityDps.thermal + peakKin += abilityDps.kinetic + peakExp += abilityDps.explosive + # Infinite use - add to steady dps + if ability.numShots == 0: + steadyEm += abilityDps.em + steadyTherm += abilityDps.thermal + steadyKin += abilityDps.kinetic + steadyExp += abilityDps.explosive + else: + activeTimes.append(ability.numShots * ability.cycleTime) + reloadTimes.append(ability.reloadTime) + steadyDps = DmgTypes(steadyEm, steadyTherm, steadyKin, steadyExp) + if len(activeTimes) > 0: + shortestActive = sorted(activeTimes)[0] + longestReload = sorted(reloadTimes, reverse=True)[0] + peakDps = DmgTypes(peakEm, peakTherm, peakKin, peakExp) + peakAdjustFactor = shortestActive / (shortestActive + longestReload) + peakDpsAdjusted = DmgTypes( + em=peakDps.em * peakAdjustFactor, + thermal=peakDps.thermal * peakAdjustFactor, + kinetic=peakDps.kinetic * peakAdjustFactor, + explosive=peakDps.explosive * peakAdjustFactor) + dps = max(steadyDps, peakDpsAdjusted, key=lambda d: d.total) + return dps + else: + return steadyDps + # Just sum all abilities when not taking reload into consideration + else: + em = 0 + therm = 0 + kin = 0 + exp = 0 + for ability in self.abilities: + abilityDps = ability.getDps(targetResists=targetResists) + em += abilityDps.em + therm += abilityDps.thermal + kin += abilityDps.kinetic + exp += abilityDps.explosive + return DmgTypes(em, therm, kin, exp) @property def maxRange(self): @@ -251,8 +296,7 @@ class Fighter(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut): return val def clear(self): - self.__dps = None - self.__volley = None + self.__baseVolley = None self.__miningyield = None self.itemModifiedAttributes.clear() self.chargeModifiedAttributes.clear() diff --git a/eos/saveddata/fighterAbility.py b/eos/saveddata/fighterAbility.py index 8c32be23d..684ceec94 100644 --- a/eos/saveddata/fighterAbility.py +++ b/eos/saveddata/fighterAbility.py @@ -21,12 +21,12 @@ from logbook import Logger from sqlalchemy.orm import reconstructor +from eos.utils.stats import DmgTypes + pyfalog = Logger(__name__) class FighterAbility(object): - DAMAGE_TYPES = ("em", "kinetic", "explosive", "thermal") - DAMAGE_TYPES2 = ("EM", "Kin", "Exp", "Therm") # We aren't able to get data on the charges that can be stored with fighters. So we hardcode that data here, keyed # with the fighter squadron role @@ -118,30 +118,38 @@ class FighterAbility(object): return speed - def damageStats(self, targetResists=None): - if self.__dps is None: - self.__volley = 0 - self.__dps = 0 - if self.dealsDamage and self.active: - cycleTime = self.cycleTime + def getVolley(self, targetResists=None): + if not self.dealsDamage or not self.active: + return DmgTypes(0, 0, 0, 0) + if self.attrPrefix == "fighterAbilityLaunchBomb": + em = self.fighter.getModifiedChargeAttr("emDamage", 0) + therm = self.fighter.getModifiedChargeAttr("thermalDamage", 0) + kin = self.fighter.getModifiedChargeAttr("kineticDamage", 0) + exp = self.fighter.getModifiedChargeAttr("explosiveDamage", 0) + else: + em = self.fighter.getModifiedItemAttr("{}DamageEM".format(self.attrPrefix), 0) + therm = self.fighter.getModifiedItemAttr("{}DamageTherm".format(self.attrPrefix), 0) + kin = self.fighter.getModifiedItemAttr("{}DamageKin".format(self.attrPrefix), 0) + exp = self.fighter.getModifiedItemAttr("{}DamageExp".format(self.attrPrefix), 0) + dmgMult = self.fighter.amountActive * self.fighter.getModifiedItemAttr("{}DamageMultiplier".format(self.attrPrefix), 1) + volley = DmgTypes( + em=em * dmgMult * (1 - getattr(targetResists, "emAmount", 0)), + thermal=therm * dmgMult * (1 - getattr(targetResists, "thermalAmount", 0)), + kinetic=kin * dmgMult * (1 - getattr(targetResists, "kineticAmount", 0)), + explosive=exp * dmgMult * (1 - getattr(targetResists, "explosiveAmount", 0))) + return volley - if self.attrPrefix == "fighterAbilityLaunchBomb": - # bomb calcs - volley = sum([(self.fighter.getModifiedChargeAttr("%sDamage" % attr) or 0) * ( - 1 - getattr(targetResists, "%sAmount" % attr, 0)) for attr in self.DAMAGE_TYPES]) - else: - volley = sum(map(lambda d2, d: - (self.fighter.getModifiedItemAttr( - "{}Damage{}".format(self.attrPrefix, d2)) or 0) * - (1 - getattr(targetResists, "{}Amount".format(d), 0)), - self.DAMAGE_TYPES2, self.DAMAGE_TYPES)) - - volley *= self.fighter.amountActive - volley *= self.fighter.getModifiedItemAttr("{}DamageMultiplier".format(self.attrPrefix)) or 1 - self.__volley += volley - self.__dps += volley / (cycleTime / 1000.0) - - return self.__dps, self.__volley + def getDps(self, targetResists=None): + volley = self.getVolley(targetResists=targetResists) + if not volley: + return DmgTypes(0, 0, 0, 0) + dpsFactor = 1 / (self.cycleTime / 1000) + dps = DmgTypes( + em=volley.em * dpsFactor, + thermal=volley.thermal * dpsFactor, + kinetic=volley.kinetic * dpsFactor, + explosive=volley.explosive * dpsFactor) + return dps def clear(self): self.__dps = None diff --git a/eos/saveddata/fit.py b/eos/saveddata/fit.py index fa4620f26..f33a78651 100644 --- a/eos/saveddata/fit.py +++ b/eos/saveddata/fit.py @@ -34,6 +34,7 @@ from eos.saveddata.drone import Drone from eos.saveddata.character import Character from eos.saveddata.citadel import Citadel from eos.saveddata.module import Module, State, Slot, Hardpoint +from eos.utils.stats import DmgTypes from logbook import Logger pyfalog = Logger(__name__) @@ -120,10 +121,11 @@ class Fit(object): def build(self): self.__extraDrains = [] self.__ehp = None - self.__weaponDPS = None + self.__weaponDpsMap = {} + self.__weaponVolleyMap = {} + self.__remoteRepMap = {} self.__minerYield = None - self.__weaponVolley = None - self.__droneDPS = None + self.__droneDps = None self.__droneVolley = None self.__droneYield = None self.__sustainableTank = None @@ -135,12 +137,6 @@ class Fit(object): self.__capUsed = None self.__capRecharge = None self.__calculatedTargets = [] - self.__remoteReps = { - "Armor" : None, - "Shield" : None, - "Hull" : None, - "Capacitor": None, - } self.factorReload = False self.boostsFits = set() self.gangBoosts = None @@ -154,9 +150,9 @@ class Fit(object): @targetResists.setter def targetResists(self, targetResists): self.__targetResists = targetResists - self.__weaponDPS = None - self.__weaponVolley = None - self.__droneDPS = None + self.__weaponDpsMap = {} + self.__weaponVolleyMap = {} + self.__droneDps = None self.__droneVolley = None @property @@ -277,41 +273,31 @@ class Fit(object): def projectedFighters(self): return self.__projectedFighters - @property - def weaponDPS(self): - if self.__weaponDPS is None: - self.calculateWeaponStats() + def getWeaponDps(self, spoolOptions=None): + if spoolOptions not in self.__weaponDpsMap: + self.calculateWeaponDmgStats(spoolOptions) + return self.__weaponDpsMap[spoolOptions] - return self.__weaponDPS + def getWeaponVolley(self, spoolOptions=None): + if spoolOptions not in self.__weaponVolleyMap: + self.calculateWeaponDmgStats(spoolOptions) + return self.__weaponVolleyMap[spoolOptions] - @property - def weaponVolley(self): - if self.__weaponVolley is None: - self.calculateWeaponStats() + def getDroneDps(self): + if self.__droneDps is None: + self.calculateDroneDmgStats() + return self.__droneDps - return self.__weaponVolley - - @property - def droneDPS(self): - if self.__droneDPS is None: - self.calculateWeaponStats() - - return self.__droneDPS - - @property - def droneVolley(self): + def getDroneVolley(self): if self.__droneVolley is None: - self.calculateWeaponStats() - + self.calculateDroneDmgStats() return self.__droneVolley - @property - def totalDPS(self): - return self.droneDPS + self.weaponDPS + def getTotalDps(self, spoolOptions=None): + return self.getDroneDps() + self.getWeaponDps(spoolOptions=spoolOptions) - @property - def totalVolley(self): - return self.droneVolley + self.weaponVolley + def getTotalVolley(self, spoolOptions=None): + return self.getDroneVolley() + self.getWeaponVolley(spoolOptions=spoolOptions) @property def minerYield(self): @@ -409,12 +395,13 @@ class Fit(object): def clear(self, projected=False, command=False): self.__effectiveTank = None - self.__weaponDPS = None + self.__weaponDpsMap = {} + self.__weaponVolleyMap = {} + self.__remoteRepMap = {} self.__minerYield = None - self.__weaponVolley = None self.__effectiveSustainableTank = None self.__sustainableTank = None - self.__droneDPS = None + self.__droneDps = None self.__droneVolley = None self.__droneYield = None self.__ehp = None @@ -426,9 +413,6 @@ class Fit(object): self.ecmProjectedStr = 1 # self.commandBonuses = {} - for remoterep_type in self.__remoteReps: - self.__remoteReps[remoterep_type] = None - del self.__calculatedTargets[:] del self.__extraDrains[:] @@ -1032,11 +1016,11 @@ class Fit(object): @property def pgUsed(self): - return self.getItemAttrOnlineSum(self.modules, "power") + return round(self.getItemAttrOnlineSum(self.modules, "power"), 2) @property def cpuUsed(self): - return self.getItemAttrOnlineSum(self.modules, "cpu") + return round(self.getItemAttrOnlineSum(self.modules, "cpu"), 2) @property def droneBandwidthUsed(self): @@ -1151,149 +1135,6 @@ class Fit(object): return self.__capRecharge - @property - def sustainableTank(self): - if self.__sustainableTank is None: - self.calculateSustainableTank() - - return self.__sustainableTank - - def calculateSustainableTank(self, effective=True): - if self.__sustainableTank is None: - if self.capStable and not self.factorReload: - sustainable = { - "armorRepair" : self.extraAttributes["armorRepair"], - "shieldRepair": self.extraAttributes["shieldRepair"], - "hullRepair" : self.extraAttributes["hullRepair"] - } - else: - sustainable = {} - - repairers = [] - # Map a repairer type to the attribute it uses - groupAttrMap = { - "Shield Booster": "shieldBonus", - "Ancillary Shield Booster": "shieldBonus", - "Remote Shield Booster": "shieldBonus", - "Ancillary Remote Shield Booster": "shieldBonus", - - "Armor Repair Unit": "armorDamageAmount", - "Ancillary Armor Repairer": "armorDamageAmount", - "Remote Armor Repairer": "armorDamageAmount", - "Ancillary Remote Armor Repairer": "armorDamageAmount", - - "Hull Repair Unit": "structureDamageAmount", - "Remote Hull Repairer": "structureDamageAmount", - } - # Map repairer type to attribute - groupStoreMap = { - "Shield Booster": "shieldRepair", - "Remote Shield Booster": "shieldRepair", - "Ancillary Shield Booster": "shieldRepair", - "Ancillary Remote Shield Booster": "shieldRepair", - - "Armor Repair Unit": "armorRepair", - "Remote Armor Repairer": "armorRepair", - "Ancillary Armor Repairer": "armorRepair", - "Ancillary Remote Armor Repairer": "armorRepair", - - "Hull Repair Unit": "hullRepair", - "Remote Hull Repairer": "hullRepair", - } - - capUsed = self.capUsed - for attr in ("shieldRepair", "armorRepair", "hullRepair"): - sustainable[attr] = self.extraAttributes[attr] - dict = self.extraAttributes.getAfflictions(attr) - if self in dict: - for mod, _, amount, used in dict[self]: - if not used: - continue - if mod.projected is False: - usesCap = True - try: - if mod.capUse: - capUsed -= mod.capUse - else: - usesCap = False - except AttributeError: - usesCap = False - - # Normal Repairers - if usesCap and not mod.charge: - cycleTime = mod.rawCycleTime - amount = mod.getModifiedItemAttr(groupAttrMap[mod.item.group.name]) - sustainable[attr] -= amount / (cycleTime / 1000.0) - repairers.append(mod) - # Ancillary Armor reps etc - elif usesCap and mod.charge: - cycleTime = mod.rawCycleTime - amount = mod.getModifiedItemAttr(groupAttrMap[mod.item.group.name]) - if mod.charge.name == "Nanite Repair Paste": - multiplier = mod.getModifiedItemAttr("chargedArmorDamageMultiplier") or 1 - else: - multiplier = 1 - sustainable[attr] -= amount * multiplier / (cycleTime / 1000.0) - repairers.append(mod) - # Ancillary Shield boosters etc - elif not usesCap and mod.item.group.name in ("Ancillary Shield Booster", "Ancillary Remote Shield Booster"): - cycleTime = mod.rawCycleTime - amount = mod.getModifiedItemAttr(groupAttrMap[mod.item.group.name]) - if self.factorReload and mod.charge: - reloadtime = mod.reloadTime - else: - reloadtime = 0.0 - offdutycycle = reloadtime / ((max(mod.numShots, 1) * cycleTime) + reloadtime) - sustainable[attr] -= amount * offdutycycle / (cycleTime / 1000.0) - - # Sort repairers by efficiency. We want to use the most efficient repairers first - repairers.sort(key=lambda _mod: _mod.getModifiedItemAttr( - groupAttrMap[_mod.item.group.name]) * (_mod.getModifiedItemAttr( - "chargedArmorDamageMultiplier") or 1) / _mod.getModifiedItemAttr("capacitorNeed"), reverse=True) - - # Loop through every module until we're above peak recharge - # Most efficient first, as we sorted earlier. - # calculate how much the repper can rep stability & add to total - totalPeakRecharge = self.capRecharge - for mod in repairers: - if capUsed > totalPeakRecharge: - break - - if self.factorReload and mod.charge: - reloadtime = mod.reloadTime - else: - reloadtime = 0.0 - - cycleTime = mod.rawCycleTime - capPerSec = mod.capUse - - if capPerSec is not None and cycleTime is not None: - # Check how much this repper can work - sustainability = min(1, (totalPeakRecharge - capUsed) / capPerSec) - amount = mod.getModifiedItemAttr(groupAttrMap[mod.item.group.name]) - # Add the sustainable amount - - if not mod.charge: - sustainable[groupStoreMap[mod.item.group.name]] += sustainability * amount / ( - cycleTime / 1000.0) - else: - if mod.charge.name == "Nanite Repair Paste": - multiplier = mod.getModifiedItemAttr("chargedArmorDamageMultiplier") or 1 - else: - multiplier = 1 - ondutycycle = (max(mod.numShots, 1) * cycleTime) / ( - (max(mod.numShots, 1) * cycleTime) + reloadtime) - sustainable[groupStoreMap[ - mod.item.group.name]] += sustainability * amount * ondutycycle * multiplier / ( - cycleTime / 1000.0) - - capUsed += capPerSec - - sustainable["passiveShield"] = self.calculateShieldRecharge() - self.__sustainableTank = sustainable - - return self.__sustainableTank - def calculateCapRecharge(self, percent=PEAK_RECHARGE): capacity = self.ship.getModifiedItemAttr("capacitorCapacity") rechargeRate = self.ship.getModifiedItemAttr("rechargeRate") / 1000.0 @@ -1377,92 +1218,27 @@ class Fit(object): self.__capStable = True self.__capState = 100 - @property - def remoteReps(self): - force_recalc = False - for remote_type in self.__remoteReps: - if self.__remoteReps[remote_type] is None: - force_recalc = True - break + def getRemoteReps(self, spoolOptions=None): + if spoolOptions not in self.__remoteRepMap: + remoteReps = {} - if force_recalc is False: - return self.__remoteReps + for module in self.modules: + rrType, rrAmount = module.getRemoteReps(spoolOptions=spoolOptions) + if rrType: + if rrType not in remoteReps: + remoteReps[rrType] = 0 + remoteReps[rrType] += rrAmount - # We are rerunning the recalcs. Explicitly set to 0 to make sure we don't duplicate anything and correctly set - # all values to 0. - for remote_type in self.__remoteReps: - self.__remoteReps[remote_type] = 0 + for drone in self.drones: + rrType, rrAmount = drone.getRemoteReps() + if rrType: + if rrType not in remoteReps: + remoteReps[rrType] = 0 + remoteReps[rrType] += rrAmount - for stuff in chain(self.modules, self.drones): - if stuff.item: - if stuff.item.ID == 10250: - pass - remote_type = None + self.__remoteRepMap[spoolOptions] = remoteReps - # Only apply the charged multiplier if we have a charge in our ancil reppers (#1135) - if stuff.charge: - modifier = stuff.getModifiedItemAttr("chargedArmorDamageMultiplier", 1) - else: - modifier = 1 - - if isinstance(stuff, Module) and (stuff.isEmpty or stuff.state < State.ACTIVE): - continue - elif isinstance(stuff, Drone): - # drones don't have fueled charges, so simply override modifier with the amount of drones active - modifier = stuff.amountActive - - # Covert cycleTime to seconds - duration = stuff.cycleTime / 1000 - - # Skip modules with no duration. - if not duration: - continue - - remote_module_groups = { - "Remote Armor Repairer" : "Armor", - "Ancillary Remote Armor Repairer": "Armor", - "Remote Hull Repairer" : "Hull", - "Remote Shield Booster" : "Shield", - "Ancillary Remote Shield Booster": "Shield", - "Remote Capacitor Transmitter" : "Capacitor", - } - - module_group = stuff.item.group.name - - if module_group in remote_module_groups: - remote_type = remote_module_groups[module_group] - elif not isinstance(stuff, Drone): - # Module isn't in our list of remote rep modules, bail - continue - - if remote_type == "Hull": - hp = stuff.getModifiedItemAttr("structureDamageAmount", 0) - elif remote_type == "Armor": - hp = stuff.getModifiedItemAttr("armorDamageAmount", 0) - elif remote_type == "Shield": - hp = stuff.getModifiedItemAttr("shieldBonus", 0) - elif remote_type == "Capacitor": - hp = stuff.getModifiedItemAttr("powerTransferAmount", 0) - else: - droneShield = stuff.getModifiedItemAttr("shieldBonus", 0) - droneArmor = stuff.getModifiedItemAttr("armorDamageAmount", 0) - droneHull = stuff.getModifiedItemAttr("structureDamageAmount", 0) - if droneShield: - remote_type = "Shield" - hp = droneShield - elif droneArmor: - remote_type = "Armor" - hp = droneArmor - elif droneHull: - remote_type = "Hull" - hp = droneHull - else: - hp = 0 - - if hp > 0 and duration > 0: - self.__remoteReps[remote_type] += (hp * modifier) / duration - - return self.__remoteReps + return self.__remoteRepMap[spoolOptions] @property def hp(self): @@ -1485,11 +1261,14 @@ class Fit(object): @property def tank(self): - hps = {"passiveShield": self.calculateShieldRecharge()} - for type in ("shield", "armor", "hull"): - hps["%sRepair" % type] = self.extraAttributes["%sRepair" % type] - - return hps + reps = { + "passiveShield": self.calculateShieldRecharge(), + "shieldRepair": self.extraAttributes["shieldRepair"], + "armorRepair": self.extraAttributes["armorRepair"], + "armorRepairPreSpool": self.extraAttributes["armorRepairPreSpool"], + "armorRepairFullSpool": self.extraAttributes["armorRepairFullSpool"], + "hullRepair": self.extraAttributes["hullRepair"]} + return reps @property def effectiveTank(self): @@ -1497,24 +1276,153 @@ class Fit(object): if self.damagePattern is None: ehps = self.tank else: - ehps = self.damagePattern.calculateEffectiveTank(self, self.extraAttributes) + ehps = self.damagePattern.calculateEffectiveTank(self, self.tank) self.__effectiveTank = ehps return self.__effectiveTank + @property + def sustainableTank(self): + if self.__sustainableTank is None: + self.calculateSustainableTank() + + return self.__sustainableTank + @property def effectiveSustainableTank(self): if self.__effectiveSustainableTank is None: if self.damagePattern is None: - eshps = self.sustainableTank + tank = self.sustainableTank else: - eshps = self.damagePattern.calculateEffectiveTank(self, self.sustainableTank) - - self.__effectiveSustainableTank = eshps - + tank = self.damagePattern.calculateEffectiveTank(self, self.sustainableTank) + self.__effectiveSustainableTank = tank return self.__effectiveSustainableTank + def calculateSustainableTank(self): + if self.__sustainableTank is None: + sustainable = { + "passiveShield": self.calculateShieldRecharge(), + "shieldRepair": self.extraAttributes["shieldRepair"], + "armorRepair": self.extraAttributes["armorRepair"], + "armorRepairPreSpool": self.extraAttributes["armorRepairPreSpool"], + "armorRepairFullSpool": self.extraAttributes["armorRepairFullSpool"], + "hullRepair": self.extraAttributes["hullRepair"]} + if not self.capStable or self.factorReload: + # Map a local repairer type to the attribute it uses + groupAttrMap = { + "Shield Booster": "shieldBonus", + "Ancillary Shield Booster": "shieldBonus", + "Armor Repair Unit": "armorDamageAmount", + "Ancillary Armor Repairer": "armorDamageAmount", + "Hull Repair Unit": "structureDamageAmount"} + # Map local repairer type to tank type + groupStoreMap = { + "Shield Booster": "shieldRepair", + "Ancillary Shield Booster": "shieldRepair", + "Armor Repair Unit": "armorRepair", + "Ancillary Armor Repairer": "armorRepair", + "Hull Repair Unit": "hullRepair"} + repairers = [] + localAdjustment = {"shieldRepair": 0, "armorRepair": 0, "hullRepair": 0} + capUsed = self.capUsed + for tankType in localAdjustment: + dict = self.extraAttributes.getAfflictions(tankType) + if self in dict: + for mod, _, amount, used in dict[self]: + if not used: + continue + if mod.projected: + continue + if mod.item.group.name not in groupAttrMap: + continue + usesCap = True + try: + if mod.capUse: + capUsed -= mod.capUse + else: + usesCap = False + except AttributeError: + usesCap = False + + # Normal Repairers + if usesCap and not mod.charge: + cycleTime = mod.rawCycleTime + amount = mod.getModifiedItemAttr(groupAttrMap[mod.item.group.name]) + localAdjustment[tankType] -= amount / (cycleTime / 1000.0) + repairers.append(mod) + # Ancillary Armor reps etc + elif usesCap and mod.charge: + cycleTime = mod.rawCycleTime + amount = mod.getModifiedItemAttr(groupAttrMap[mod.item.group.name]) + if mod.charge.name == "Nanite Repair Paste": + multiplier = mod.getModifiedItemAttr("chargedArmorDamageMultiplier") or 1 + else: + multiplier = 1 + localAdjustment[tankType] -= amount * multiplier / (cycleTime / 1000.0) + repairers.append(mod) + # Ancillary Shield boosters etc + elif not usesCap and mod.item.group.name in ("Ancillary Shield Booster", "Ancillary Remote Shield Booster"): + cycleTime = mod.rawCycleTime + amount = mod.getModifiedItemAttr(groupAttrMap[mod.item.group.name]) + if self.factorReload and mod.charge: + reloadtime = mod.reloadTime + else: + reloadtime = 0.0 + offdutycycle = reloadtime / ((max(mod.numShots, 1) * cycleTime) + reloadtime) + localAdjustment[tankType] -= amount * offdutycycle / (cycleTime / 1000.0) + + # Sort repairers by efficiency. We want to use the most efficient repairers first + repairers.sort(key=lambda _mod: _mod.getModifiedItemAttr( + groupAttrMap[_mod.item.group.name]) * (_mod.getModifiedItemAttr( + "chargedArmorDamageMultiplier") or 1) / _mod.getModifiedItemAttr("capacitorNeed"), reverse=True) + + # Loop through every module until we're above peak recharge + # Most efficient first, as we sorted earlier. + # calculate how much the repper can rep stability & add to total + totalPeakRecharge = self.capRecharge + for mod in repairers: + if capUsed > totalPeakRecharge: + break + + if self.factorReload and mod.charge: + reloadtime = mod.reloadTime + else: + reloadtime = 0.0 + + cycleTime = mod.rawCycleTime + capPerSec = mod.capUse + + if capPerSec is not None and cycleTime is not None: + # Check how much this repper can work + sustainability = min(1, (totalPeakRecharge - capUsed) / capPerSec) + amount = mod.getModifiedItemAttr(groupAttrMap[mod.item.group.name]) + # Add the sustainable amount + if not mod.charge: + localAdjustment[groupStoreMap[mod.item.group.name]] += sustainability * amount / ( + cycleTime / 1000.0) + else: + if mod.charge.name == "Nanite Repair Paste": + multiplier = mod.getModifiedItemAttr("chargedArmorDamageMultiplier") or 1 + else: + multiplier = 1 + ondutycycle = (max(mod.numShots, 1) * cycleTime) / ( + (max(mod.numShots, 1) * cycleTime) + reloadtime) + localAdjustment[groupStoreMap[ + mod.item.group.name]] += sustainability * amount * ondutycycle * multiplier / ( + cycleTime / 1000.0) + + capUsed += capPerSec + sustainable["shieldRepair"] += localAdjustment["shieldRepair"] + sustainable["armorRepair"] += localAdjustment["armorRepair"] + sustainable["armorRepairPreSpool"] += localAdjustment["armorRepair"] + sustainable["armorRepairFullSpool"] += localAdjustment["armorRepair"] + sustainable["hullRepair"] += localAdjustment["hullRepair"] + + self.__sustainableTank = sustainable + + return self.__sustainableTank + def calculateLockTime(self, radius): scanRes = self.ship.getModifiedItemAttr("scanResolution") if scanRes is not None and scanRes > 0: @@ -1537,30 +1445,30 @@ class Fit(object): self.__minerYield = minerYield self.__droneYield = droneYield - def calculateWeaponStats(self): - weaponDPS = 0 - droneDPS = 0 - weaponVolley = 0 - droneVolley = 0 + def calculateWeaponDmgStats(self, spoolOptions): + weaponVolley = DmgTypes(0, 0, 0, 0) + weaponDps = DmgTypes(0, 0, 0, 0) for mod in self.modules: - dps, volley = mod.damageStats(self.targetResists) - weaponDPS += dps - weaponVolley += volley + weaponVolley += mod.getVolley(spoolOptions=spoolOptions, targetResists=self.targetResists) + weaponDps += mod.getDps(spoolOptions=spoolOptions, targetResists=self.targetResists) + + self.__weaponVolleyMap[spoolOptions] = weaponVolley + self.__weaponDpsMap[spoolOptions] = weaponDps + + def calculateDroneDmgStats(self): + droneVolley = DmgTypes(0, 0, 0, 0) + droneDps = DmgTypes(0, 0, 0, 0) for drone in self.drones: - dps, volley = drone.damageStats(self.targetResists) - droneDPS += dps - droneVolley += volley + droneVolley += drone.getVolley(targetResists=self.targetResists) + droneDps += drone.getDps(targetResists=self.targetResists) for fighter in self.fighters: - dps, volley = fighter.damageStats(self.targetResists) - droneDPS += dps - droneVolley += volley + droneVolley += fighter.getVolley(targetResists=self.targetResists) + droneDps += fighter.getDps(targetResists=self.targetResists) - self.__weaponDPS = weaponDPS - self.__weaponVolley = weaponVolley - self.__droneDPS = droneDPS + self.__droneDps = droneDps self.__droneVolley = droneVolley @property diff --git a/eos/saveddata/module.py b/eos/saveddata/module.py index 224ebe1d1..c4c2f0b00 100644 --- a/eos/saveddata/module.py +++ b/eos/saveddata/module.py @@ -28,6 +28,9 @@ from eos.enum import Enum from eos.modifiedAttributeDict import ChargeAttrShortcut, ItemAttrShortcut, ModifiedAttributeDict from eos.saveddata.citadel import Citadel from eos.saveddata.mutator import Mutator +from eos.utils.float import floatUnerr +from eos.utils.spoolSupport import calculateSpoolup, resolveSpoolOptions +from eos.utils.stats import DmgTypes pyfalog = Logger(__name__) @@ -95,7 +98,6 @@ class Hardpoint(Enum): class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut): """An instance of this class represents a module together with its charge and modified attributes""" - DAMAGE_TYPES = ("em", "thermal", "kinetic", "explosive") MINING_ATTRIBUTES = ("miningAmount",) SYSTEM_GROUPS = ("Effect Beacon", "MassiveEnvironments", "Abyssal Hazards", "Non-Interactable Object") @@ -168,9 +170,9 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut): if self.__charge and self.__charge.category.name != "Charge": self.__charge = None - self.__dps = None + self.__baseVolley = None + self.__baseRemoteReps = None self.__miningyield = None - self.__volley = None self.__reloadTime = None self.__reloadForce = None self.__chargeCycles = None @@ -247,8 +249,8 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut): if chargeVolume is None or containerCapacity is None: charges = 0 else: - charges = floor(containerCapacity / chargeVolume) - return int(charges) + charges = int(floatUnerr(containerCapacity / chargeVolume)) + return charges @property def numShots(self): @@ -411,35 +413,6 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut): self.__itemModifiedAttributes.clear() - def damageStats(self, targetResists): - if self.__dps is None: - self.__dps = 0 - self.__volley = 0 - - if not self.isEmpty and self.state >= State.ACTIVE: - if self.charge: - func = self.getModifiedChargeAttr - else: - func = self.getModifiedItemAttr - - volley = sum([(func("%sDamage" % attr) or 0) * (1 - getattr(targetResists, "%sAmount" % attr, 0)) for attr in self.DAMAGE_TYPES]) - volley *= self.getModifiedItemAttr("damageMultiplier") or 1 - # Disintegrator-specific ramp-up multiplier - volley *= (self.getModifiedItemAttr("damageMultiplierBonusMax") or 0) + 1 - if volley: - cycleTime = self.cycleTime - # Some weapons repeat multiple times in one cycle (think doomsdays) - # Get the number of times it fires off - weaponDoT = max( - self.getModifiedItemAttr("doomsdayDamageDuration", 1) / self.getModifiedItemAttr("doomsdayDamageCycleTime", 1), - 1 - ) - - self.__volley = volley - self.__dps = (volley * weaponDoT) / (cycleTime / 1000.0) - - return self.__dps, self.__volley - @property def miningStats(self): if self.__miningyield is None: @@ -459,13 +432,110 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut): return self.__miningyield - @property - def dps(self): - return self.damageStats(None)[0] + def getVolley(self, spoolOptions=None, targetResists=None, ignoreState=False): + if self.isEmpty or (self.state < State.ACTIVE and not ignoreState): + return DmgTypes(0, 0, 0, 0) + if self.__baseVolley is None: + dmgGetter = self.getModifiedChargeAttr if self.charge else self.getModifiedItemAttr + dmgMult = self.getModifiedItemAttr("damageMultiplier", 1) + self.__baseVolley = DmgTypes( + em=(dmgGetter("emDamage", 0)) * dmgMult, + thermal=(dmgGetter("thermalDamage", 0)) * dmgMult, + kinetic=(dmgGetter("kineticDamage", 0)) * dmgMult, + explosive=(dmgGetter("explosiveDamage", 0)) * dmgMult) + spoolType, spoolAmount = resolveSpoolOptions(spoolOptions, self) + spoolBoost = calculateSpoolup( + self.getModifiedItemAttr("damageMultiplierBonusMax", 0), + self.getModifiedItemAttr("damageMultiplierBonusPerCycle", 0), + self.rawCycleTime / 1000, spoolType, spoolAmount)[0] + spoolMultiplier = 1 + spoolBoost + volley = DmgTypes( + em=self.__baseVolley.em * spoolMultiplier * (1 - getattr(targetResists, "emAmount", 0)), + thermal=self.__baseVolley.thermal * spoolMultiplier * (1 - getattr(targetResists, "thermalAmount", 0)), + kinetic=self.__baseVolley.kinetic * spoolMultiplier * (1 - getattr(targetResists, "kineticAmount", 0)), + explosive=self.__baseVolley.explosive * spoolMultiplier * (1 - getattr(targetResists, "explosiveAmount", 0))) + return volley - @property - def volley(self): - return self.damageStats(None)[1] + def getDps(self, spoolOptions=None, targetResists=None, ignoreState=False): + volley = self.getVolley(spoolOptions=spoolOptions, targetResists=targetResists, ignoreState=ignoreState) + if not volley: + return DmgTypes(0, 0, 0, 0) + # Some weapons repeat multiple times in one cycle (bosonic doomsdays). Get the number of times it fires off + volleysPerCycle = max(self.getModifiedItemAttr("doomsdayDamageDuration", 1) / self.getModifiedItemAttr("doomsdayDamageCycleTime", 1), 1) + dpsFactor = volleysPerCycle / (self.cycleTime / 1000) + dps = DmgTypes( + em=volley.em * dpsFactor, + thermal=volley.thermal * dpsFactor, + kinetic=volley.kinetic * dpsFactor, + explosive=volley.explosive * dpsFactor) + return dps + + def getRemoteReps(self, spoolOptions=None, ignoreState=False): + if self.isEmpty or (self.state < State.ACTIVE and not ignoreState): + return None, 0 + + def getBaseRemoteReps(module): + remoteModuleGroups = { + "Remote Armor Repairer": "Armor", + "Ancillary Remote Armor Repairer": "Armor", + "Mutadaptive Remote Armor Repairer": "Armor", + "Remote Hull Repairer": "Hull", + "Remote Shield Booster": "Shield", + "Ancillary Remote Shield Booster": "Shield", + "Remote Capacitor Transmitter": "Capacitor"} + rrType = remoteModuleGroups.get(module.item.group.name, None) + if not rrType: + return None, 0 + if rrType == "Hull": + rrAmount = module.getModifiedItemAttr("structureDamageAmount", 0) + elif rrType == "Armor": + rrAmount = module.getModifiedItemAttr("armorDamageAmount", 0) + elif rrType == "Shield": + rrAmount = module.getModifiedItemAttr("shieldBonus", 0) + elif rrType == "Capacitor": + rrAmount = module.getModifiedItemAttr("powerTransferAmount", 0) + else: + return None, 0 + if rrAmount: + rrAmount *= 1 / (self.cycleTime / 1000) + if module.item.group.name == "Ancillary Remote Armor Repairer" and module.charge: + rrAmount *= module.getModifiedItemAttr("chargedArmorDamageMultiplier", 1) + + return rrType, rrAmount + + if self.__baseRemoteReps is None: + self.__baseRemoteReps = getBaseRemoteReps(self) + + rrType, rrAmount = self.__baseRemoteReps + + if rrType and rrAmount and self.item.group.name == "Mutadaptive Remote Armor Repairer": + spoolType, spoolAmount = resolveSpoolOptions(spoolOptions, self) + spoolBoost = calculateSpoolup( + self.getModifiedItemAttr("repairMultiplierBonusMax", 0), + self.getModifiedItemAttr("repairMultiplierBonusPerCycle", 0), + self.rawCycleTime / 1000, spoolType, spoolAmount)[0] + rrAmount *= (1 + spoolBoost) + + return rrType, rrAmount + + def getSpoolData(self, spoolOptions=None): + weaponMultMax = self.getModifiedItemAttr("damageMultiplierBonusMax", 0) + weaponMultPerCycle = self.getModifiedItemAttr("damageMultiplierBonusPerCycle", 0) + if weaponMultMax and weaponMultPerCycle: + spoolType, spoolAmount = resolveSpoolOptions(spoolOptions, self) + _, spoolCycles, spoolTime = calculateSpoolup( + weaponMultMax, weaponMultPerCycle, + self.rawCycleTime / 1000, spoolType, spoolAmount) + return spoolCycles, spoolTime + rrMultMax = self.getModifiedItemAttr("repairMultiplierBonusMax", 0) + rrMultPerCycle = self.getModifiedItemAttr("repairMultiplierBonusPerCycle", 0) + if rrMultMax and rrMultPerCycle: + spoolType, spoolAmount = resolveSpoolOptions(spoolOptions, self) + _, spoolCycles, spoolTime = calculateSpoolup( + rrMultMax, rrMultPerCycle, + self.rawCycleTime / 1000, spoolType, spoolAmount) + return spoolCycles, spoolTime + return 0, 0 @property def reloadTime(self): @@ -718,9 +788,9 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut): return val def clear(self): - self.__dps = None + self.__baseVolley = None + self.__baseRemoteReps = None self.__miningyield = None - self.__volley = None self.__reloadTime = None self.__reloadForce = None self.__chargeCycles = None diff --git a/eos/saveddata/price.py b/eos/saveddata/price.py index 6618119d0..a2a630c30 100644 --- a/eos/saveddata/price.py +++ b/eos/saveddata/price.py @@ -18,24 +18,30 @@ # along with eos. If not, see . # =============================================================================== -import time -from sqlalchemy.orm import reconstructor +import time +from enum import IntEnum, unique + from logbook import Logger + pyfalog = Logger(__name__) +@unique +class PriceStatus(IntEnum): + notFetched = 0 + success = 1 + fail = 2 + notSupported = 3 + + class Price(object): def __init__(self, typeID): self.typeID = typeID self.time = 0 self.__price = 0 - self.failed = None - - @reconstructor - def init(self): - self.__item = None + self.status = PriceStatus.notFetched @property def isValid(self): @@ -43,7 +49,10 @@ class Price(object): @property def price(self): - return self.__price or 0.0 + if self.status != PriceStatus.success: + return 0 + else: + return self.__price or 0 @price.setter def price(self, price): diff --git a/eos/saveddata/ship.py b/eos/saveddata/ship.py index a7cbc15b7..aecb95dc8 100644 --- a/eos/saveddata/ship.py +++ b/eos/saveddata/ship.py @@ -29,14 +29,16 @@ pyfalog = Logger(__name__) class Ship(ItemAttrShortcut, HandledItem): EXTRA_ATTRIBUTES = { - "armorRepair" : 0, - "hullRepair" : 0, - "shieldRepair" : 0, - "maxActiveDrones" : 0, + "armorRepair": 0, + "armorRepairPreSpool": 0, + "armorRepairFullSpool": 0, + "hullRepair": 0, + "shieldRepair": 0, + "maxActiveDrones": 0, "maxTargetsLockedFromSkills": 2, - "droneControlRange" : 20000, - "cloaked" : False, - "siege" : False + "droneControlRange": 20000, + "cloaked": False, + "siege": False # We also have speedLimit for Entosis Link, but there seems to be an # issue with naming it exactly "speedLimit" due to unknown reasons. # Regardless, we don't have to put it here anyways - it will come up diff --git a/eos/utils/__init__.py b/eos/utils/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/eos/utils/float.py b/eos/utils/float.py new file mode 100644 index 000000000..b7bd6cc61 --- /dev/null +++ b/eos/utils/float.py @@ -0,0 +1,26 @@ +""" +Sometimes use of floats may lead to undesirable results, e.g. + int(2.3 / 0.1) = 22. +We cannot afford to use different number representations (e.g. representations +provided by decimal or fraction modules), thus consequences are worked around by +this module. +""" + +import math +import sys + + +# As we will be rounding numbers after operations (which introduce higher error +# than base float representation error), we need to keep less significant +# numbers than for single float number w/o operations +keepDigits = int(sys.float_info.dig / 2) + + +def floatUnerr(value): + """Round possible float number error, killing some precision in process.""" + if value == 0: + return value + # Find round factor, taking into consideration that we want to keep at least + # predefined amount of significant digits + roundFactor = int(keepDigits - math.ceil(math.log10(abs(value)))) + return round(value, roundFactor) diff --git a/eos/utils/spoolSupport.py b/eos/utils/spoolSupport.py new file mode 100644 index 000000000..de265731f --- /dev/null +++ b/eos/utils/spoolSupport.py @@ -0,0 +1,70 @@ +# =============================================================================== +# Copyright (C) 2010 Diego Duclos +# +# This file is part of eos. +# +# eos is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# eos is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with eos. If not, see . +# =============================================================================== + + +from collections import namedtuple +from enum import IntEnum, unique + +from eos.utils.float import floatUnerr + + +SpoolOptions = namedtuple('SpoolOptions', ('spoolType', 'spoolAmount', 'force')) + + +@unique +class SpoolType(IntEnum): + SCALE = 0 # [0..1] + TIME = 1 # Expressed via time in seconds since spool up started + CYCLES = 2 # Expressed in amount of cycles since spool up started + + +def calculateSpoolup(modMaxValue, modStepValue, modCycleTime, spoolType, spoolAmount): + """ + Calculate damage multiplier increment based on passed parameters. Module cycle time + is specified in seconds. + + Returns spoolup value, amount of cycles to reach it and time to reach it. + """ + if not modMaxValue or not modStepValue: + return 0, 0, 0 + if spoolType == SpoolType.SCALE: + cycles = int(floatUnerr(spoolAmount * modMaxValue / modStepValue)) + return cycles * modStepValue, cycles, cycles * modCycleTime + elif spoolType == SpoolType.TIME: + cycles = min(int(floatUnerr(spoolAmount / modCycleTime)), int(floatUnerr(modMaxValue / modStepValue))) + return cycles * modStepValue, cycles, cycles * modCycleTime + elif spoolType == SpoolType.CYCLES: + cycles = min(int(spoolAmount), int(floatUnerr(modMaxValue / modStepValue))) + return cycles * modStepValue, cycles, cycles * modCycleTime + else: + return 0, 0, 0 + + +def resolveSpoolOptions(spoolOptions, module): + # Rely on passed options if they are forcing us to do so + if spoolOptions is not None and spoolOptions.force: + return spoolOptions.spoolType, spoolOptions.spoolAmount + # If we're not forced to use options and module has options set, prefer on-module values + elif module is not None and module.spoolType is not None: + return module.spoolType, module.spoolAmount + # Otherwise - rely on passed options + elif spoolOptions is not None: + return spoolOptions.spoolType, spoolOptions.spoolAmount + else: + return None, None diff --git a/eos/utils/stats.py b/eos/utils/stats.py new file mode 100644 index 000000000..cec0a2bdd --- /dev/null +++ b/eos/utils/stats.py @@ -0,0 +1,70 @@ +# =============================================================================== +# Copyright (C) 2010 Diego Duclos +# +# This file is part of eos. +# +# eos is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# eos is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with eos. If not, see . +# =============================================================================== + + +class DmgTypes: + """Container for damage data stats.""" + + def __init__(self, em, thermal, kinetic, explosive): + self.em = em + self.thermal = thermal + self.kinetic = kinetic + self.explosive = explosive + self._calcTotal() + + # Iterator is needed to support tuple-style unpacking + def __iter__(self): + yield self.em + yield self.thermal + yield self.kinetic + yield self.explosive + yield self.total + + def __eq__(self, other): + if not isinstance(other, DmgTypes): + return NotImplemented + return all(( + self.em == other.em, + self.thermal == other.thermal, + self.kinetic == other.kinetic, + self.explosive == other.explosive, + self.total == other.total)) + + def __bool__(self): + return any(( + self.em, self.thermal, self.kinetic, + self.explosive, self.total)) + + def _calcTotal(self): + self.total = self.em + self.thermal + self.kinetic + self.explosive + + def __add__(self, other): + return type(self)( + em=self.em + other.em, + thermal=self.thermal + other.thermal, + kinetic=self.kinetic + other.kinetic, + explosive=self.explosive + other.explosive) + + def __iadd__(self, other): + self.em += other.em + self.thermal += other.thermal + self.kinetic += other.kinetic + self.explosive += other.explosive + self._calcTotal() + return self diff --git a/eve.db b/eve.db index 7c61b27f8..417b53d1c 100644 Binary files a/eve.db and b/eve.db differ diff --git a/gui/aboutData.py b/gui/aboutData.py index 6e8ce07bc..2d658832f 100644 --- a/gui/aboutData.py +++ b/gui/aboutData.py @@ -19,7 +19,7 @@ import config -versionString = "{0} {1} - {2} {3}".format(config.version, config.tag, config.expansionName, config.expansionVersion) +versionString = "{0}".format(config.version) licenses = ( "pyfa is released under GNU GPLv3 - see included LICENSE file", "All EVE-Online related materials are property of CCP hf.", diff --git a/gui/builtinAdditionPanes/notesView.py b/gui/builtinAdditionPanes/notesView.py index 35a75b5a8..a4a807509 100644 --- a/gui/builtinAdditionPanes/notesView.py +++ b/gui/builtinAdditionPanes/notesView.py @@ -4,6 +4,7 @@ import wx from service.fit import Fit import gui.globalEvents as GE import gui.mainFrame +from gui.utils.helpers_wxPython import HandleCtrlBackspace class NotesView(wx.Panel): @@ -17,9 +18,16 @@ class NotesView(wx.Panel): self.SetSizer(mainSizer) self.mainFrame.Bind(GE.FIT_CHANGED, self.fitChanged) self.Bind(wx.EVT_TEXT, self.onText) + self.editNotes.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.saveTimer = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.delayedSave, self.saveTimer) + def OnKeyDown(self, event): + if event.RawControlDown() and event.GetKeyCode() == wx.WXK_BACK: + HandleCtrlBackspace(self.editNotes) + else: + event.Skip() + def fitChanged(self, event): sFit = Fit.getInstance() fit = sFit.getFit(event.fitID) diff --git a/gui/builtinContextMenus/fillWithModule.py b/gui/builtinContextMenus/fillWithModule.py new file mode 100644 index 000000000..0dd8d0d91 --- /dev/null +++ b/gui/builtinContextMenus/fillWithModule.py @@ -0,0 +1,34 @@ +from gui.contextMenu import ContextMenu +import gui.mainFrame +# noinspection PyPackageRequirements +import wx +import gui.globalEvents as GE +from service.settings import ContextMenuSettings +import gui.fitCommands as cmd + + +class FillWithModule(ContextMenu): + def __init__(self): + self.mainFrame = gui.mainFrame.MainFrame.getInstance() + self.settings = ContextMenuSettings.getInstance() + + def display(self, srcContext, selection): + if not self.settings.get('moduleFill'): + return False + return srcContext in ("fittingModule") + + def getText(self, itmContext, selection): + return u"Fill With {0}".format(itmContext if itmContext is not None else "Module") + + def activate(self, fullContext, selection, i): + + srcContext = fullContext[0] + fitID = self.mainFrame.getActiveFit() + + if srcContext == "fittingModule": + self.mainFrame.command.Submit(cmd.GuiFillWithModuleCommand(fitID, selection[0].itemID)) + return # the command takes care of the PostEvent + wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID)) + + +FillWithModule.register() diff --git a/gui/builtinContextMenus/marketJump.py b/gui/builtinContextMenus/marketJump.py index c630312c1..a5d5e8eeb 100644 --- a/gui/builtinContextMenus/marketJump.py +++ b/gui/builtinContextMenus/marketJump.py @@ -26,7 +26,10 @@ class MarketJump(ContextMenu): sMkt = Market.getInstance() item = getattr(selection[0], "item", selection[0]) + isMutated = getattr(selection[0], "isMutated", False) mktGrp = sMkt.getMarketGroupByItem(item) + if mktGrp is None and isMutated: + mktGrp = sMkt.getMarketGroupByItem(selection[0].baseItem) # 1663 is Special Edition Festival Assets, we don't have root group for it if mktGrp is None or mktGrp.ID == 1663: @@ -43,7 +46,10 @@ class MarketJump(ContextMenu): if srcContext in ("fittingCharge", "projectedCharge"): item = selection[0].charge elif hasattr(selection[0], "item"): - item = selection[0].item + if getattr(selection[0], "isMutated", False): + item = selection[0].baseItem + else: + item = selection[0].item else: item = selection[0] diff --git a/gui/builtinItemStatsViews/attributeSlider.py b/gui/builtinItemStatsViews/attributeSlider.py index 077f1cf12..9e3585ea9 100644 --- a/gui/builtinItemStatsViews/attributeSlider.py +++ b/gui/builtinItemStatsViews/attributeSlider.py @@ -1,7 +1,10 @@ +import math + import wx import wx.lib.newevent from gui.attribute_gauge import AttributeGauge +from eos.utils.float import floatUnerr _ValueChanged, EVT_VALUE_CHANGED = wx.lib.newevent.NewEvent() @@ -58,22 +61,41 @@ class AttributeSlider(wx.Panel): self.inverse = inverse - # The internal slider basically represents the percentage towards the end of the range. It has to be normalized - # in this way, otherwise when we start off with a base, if the range is skewed to one side, the base value won't - # be centered. We use a range of -100,100 so that we can depend on the SliderValue to contain the percentage - # toward one end + def getStep(valRange): + """ + Find step for the passed range, which is based on 1, 2 or 5. + Step returned will make sure that range fits 10..50 of them, + as close to 10 as possible. + """ + steps = {1: None, 2: None, 5: None} + for baseInc in steps: + baseIncAmount = valRange / baseInc + incScale = math.floor(math.log10(baseIncAmount) - 1) + steps[baseInc] = baseInc * 10 ** incScale + chosenBase = min(steps, key=lambda base: valRange / steps[base]) + chosenStep = steps[chosenBase] + if inverse: + chosenStep *= -1 + return chosenStep - # Additionally, since we want the slider to be accurate to 3 decimal places, we need to blow out the two ends here - # (if we have a slider that needs to land on 66.66% towards the right, it will actually be converted to 66%. Se we need it to support 6,666) - # - # self.SliderMinValue = -100 - # self.SliderMaxValue = 100 - # self.SliderValue = 0 + def getDigitPlaces(minValue, maxValue): + minDigits = 3 + maxDigits = 5 + currentDecision = minDigits + for value in (floatUnerr(minValue), floatUnerr(maxValue)): + for currentDigit in range(minDigits, maxDigits + 1): + if round(value, currentDigit) == value: + if currentDigit > currentDecision: + currentDecision = currentDigit + break + # Max decimal places we can afford to show was not enough + else: + return maxDigits + return currentDecision - range = [self.UserMinValue, self.UserMaxValue] + self.ctrl = wx.SpinCtrlDouble(self, min=minValue, max=maxValue, inc=getStep(maxValue - minValue)) + self.ctrl.SetDigits(getDigitPlaces(minValue, maxValue)) - self.ctrl = wx.SpinCtrlDouble(self, min=min(range), max=max(range)) - self.ctrl.SetDigits(3) self.ctrl.Bind(wx.EVT_SPINCTRLDOUBLE, self.UpdateValue) diff --git a/gui/builtinItemStatsViews/itemCompare.py b/gui/builtinItemStatsViews/itemCompare.py index 1561ed58b..97a4b953d 100644 --- a/gui/builtinItemStatsViews/itemCompare.py +++ b/gui/builtinItemStatsViews/itemCompare.py @@ -8,6 +8,10 @@ from service.attribute import Attribute from gui.utils.numberFormatter import formatAmount +def defaultSort(item): + return (item.attributes['metaLevel'].value if 'metaLevel' in item.attributes else 0, item.name) + + class ItemCompare(wx.Panel): def __init__(self, parent, stuff, item, items, context=None): # Start dealing with Price stuff to get that thread going @@ -27,8 +31,7 @@ class ItemCompare(wx.Panel): self.currentSort = None self.sortReverse = False self.item = item - self.items = sorted(items, - key=lambda x: x.attributes['metaLevel'].value if 'metaLevel' in x.attributes else 0) + self.items = sorted(items, key=defaultSort) self.attrs = {} # get a dict of attrName: attrInfo of all unique attributes across all items @@ -126,10 +129,15 @@ class ItemCompare(wx.Panel): # starts at 0 while the list has the item name as column 0. attr = str(list(self.attrs.keys())[sort - 1]) func = lambda _val: _val.attributes[attr].value if attr in _val.attributes else 0.0 + # Clicked on a column that's not part of our array (price most likely) except IndexError: - # Clicked on a column that's not part of our array (price most likely) - self.sortReverse = False - func = lambda _val: _val.attributes['metaLevel'].value if 'metaLevel' in _val.attributes else 0.0 + # Price + if sort == len(self.attrs) + 1: + func = lambda i: i.price.price if i.price.price != 0 else float("Inf") + # Something else + else: + self.sortReverse = False + func = defaultSort self.items = sorted(self.items, key=func, reverse=self.sortReverse) @@ -160,7 +168,7 @@ class ItemCompare(wx.Panel): self.paramList.SetItem(i, x + 1, valueUnit) # Add prices - self.paramList.SetItem(i, len(self.attrs) + 1, formatAmount(item.price.price, 3, 3, 9, currency=True)) + self.paramList.SetItem(i, len(self.attrs) + 1, formatAmount(item.price.price, 3, 3, 9, currency=True) if item.price.price else "") self.paramList.RefreshRows() self.Layout() diff --git a/gui/builtinItemStatsViews/itemDescription.py b/gui/builtinItemStatsViews/itemDescription.py index b03b892df..9c62dcc78 100644 --- a/gui/builtinItemStatsViews/itemDescription.py +++ b/gui/builtinItemStatsViews/itemDescription.py @@ -15,7 +15,6 @@ class ItemDescription(wx.Panel): fgcolor = wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOWTEXT) self.description = wx.html.HtmlWindow(self) - if not item.description: return @@ -24,8 +23,11 @@ class ItemDescription(wx.Panel): desc = re.sub("<( *)font( *)color( *)=(.*?)>(?P.*?)<( *)/( *)font( *)>", "\g", desc) # Strip URLs desc = re.sub("<( *)a(.*?)>(?P.*?)<( *)/( *)a( *)>", "\g", desc) - desc = "" + desc + "" + desc = "{}".format( + bgcolor.GetAsString(wx.C2S_CSS_SYNTAX), + fgcolor.GetAsString(wx.C2S_CSS_SYNTAX), + desc + ) self.description.SetPage(desc) diff --git a/gui/builtinItemStatsViews/itemMutator.py b/gui/builtinItemStatsViews/itemMutator.py index f2a635c79..dc91453fa 100644 --- a/gui/builtinItemStatsViews/itemMutator.py +++ b/gui/builtinItemStatsViews/itemMutator.py @@ -22,38 +22,67 @@ class ItemMutator(wx.Panel): self.item = item self.timer = None self.activeFit = gui.mainFrame.MainFrame.getInstance().getActiveFit() + + font = parent.GetFont() + font.SetWeight(wx.BOLD) + mainSizer = wx.BoxSizer(wx.VERTICAL) + sourceItemsSizer = wx.BoxSizer(wx.HORIZONTAL) + sourceItemsSizer.Add(BitmapLoader.getStaticBitmap(stuff.item.iconID, self, "icons"), 0, wx.LEFT, 5) + sourceItemsSizer.Add(BitmapLoader.getStaticBitmap(stuff.mutaplasmid.item.iconID, self, "icons"), 0, wx.LEFT, 0) + sourceItemShort = "{} {}".format(stuff.mutaplasmid.item.name.split(" ")[0], stuff.baseItem.name) + sourceItemText = wx.StaticText(self, wx.ID_ANY, sourceItemShort) + sourceItemText.SetFont(font) + sourceItemsSizer.Add(sourceItemText, 0, wx.LEFT, 10) + mainSizer.Add(sourceItemsSizer, 0, wx.TOP | wx.EXPAND, 10) + + mainSizer.Add(wx.StaticLine(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL), 0, wx.ALL | wx.EXPAND, 5) + self.goodColor = wx.Colour(96, 191, 0) self.badColor = wx.Colour(255, 64, 0) self.event_mapping = {} for m in sorted(stuff.mutators.values(), key=lambda x: x.attribute.displayName): - # create array for the two ranges - min_t = [m.minValue, m.minMod, None] - max_t = [m.maxValue, m.maxMod, None] + # Format: [raw value, modifier applied to base raw value, display value] + range1 = (m.minValue, m.attribute.unit.SimplifyValue(m.minValue)) + range2 = (m.maxValue, m.attribute.unit.SimplifyValue(m.maxValue)) - # Then we need to determine if it's better than original, which will be the color - min_t[2] = min_t[1] < 1 if not m.highIsGood else 1 < min_t[1] - max_t[2] = max_t[1] < 1 if not m.highIsGood else 1 < max_t[1] - - # Lastly, we need to determine which range value is "worse" (left side) or "better" (right side) - if (m.highIsGood and min_t[1] > max_t[1]) or (not m.highIsGood and min_t[1] < max_t[1]): - better_range = min_t + # minValue/maxValue do not always correspond to min/max, because these are + # just base value multiplied by minMod/maxMod, and in case base is negative + # minValue is actually bigger than maxValue + if range1[0] <= range2[0]: + minRange = range1 + maxRange = range2 else: - better_range = max_t + minRange = range2 + maxRange = range1 - if (m.highIsGood and max_t[1] < min_t[1]) or (not m.highIsGood and max_t[1] > min_t[1]): - worse_range = max_t + if (m.highIsGood and minRange[0] >= maxRange[0]) or (not m.highIsGood and minRange[0] <= maxRange[0]): + betterRange = minRange + worseRange = maxRange else: - worse_range = min_t + betterRange = maxRange + worseRange = minRange + + if minRange[1] >= maxRange[1]: + displayMaxRange = minRange + displayMinRange = maxRange + else: + displayMaxRange = maxRange + displayMinRange = minRange + + # If base value is outside of mutation range, make sure that center of slider + # corresponds to the value which is closest available to actual base value. It's + # how EVE handles it + if minRange[0] <= m.baseValue <= maxRange[0]: + sliderBaseValue = m.baseValue + else: + sliderBaseValue = max(minRange[0], min(maxRange[0], m.baseValue)) headingSizer = wx.BoxSizer(wx.HORIZONTAL) - font = parent.GetFont() - font.SetWeight(wx.BOLD) - headingSizer.Add(BitmapLoader.getStaticBitmap(m.attribute.iconID, self, "icons"), 0, wx.RIGHT, 10) displayName = wx.StaticText(self, wx.ID_ANY, m.attribute.displayName) @@ -61,25 +90,25 @@ class ItemMutator(wx.Panel): headingSizer.Add(displayName, 3, wx.ALL | wx.EXPAND, 0) - worst_val = ItemParams.FormatValue(*m.attribute.unit.PreformatValue(worse_range[0]), rounding='dec') - worst_text = wx.StaticText(self, wx.ID_ANY, worst_val) - worst_text.SetForegroundColour(self.goodColor if worse_range[2] else self.badColor) + worseVal = ItemParams.FormatValue(*m.attribute.unit.PreformatValue(worseRange[0]), rounding='dec') + worseText = wx.StaticText(self, wx.ID_ANY, worseVal) + worseText.SetForegroundColour(self.badColor) - best_val = ItemParams.FormatValue(*m.attribute.unit.PreformatValue(better_range[0]), rounding='dec') - best_text = wx.StaticText(self, wx.ID_ANY, best_val) - best_text.SetForegroundColour(self.goodColor if better_range[2] else self.badColor) + betterVal = ItemParams.FormatValue(*m.attribute.unit.PreformatValue(betterRange[0]), rounding='dec') + betterText = wx.StaticText(self, wx.ID_ANY, betterVal) + betterText.SetForegroundColour(self.goodColor) - headingSizer.Add(worst_text, 0, wx.ALL | wx.EXPAND, 0) + headingSizer.Add(worseText, 0, wx.ALL | wx.EXPAND, 0) headingSizer.Add(wx.StaticText(self, wx.ID_ANY, " ─ "), 0, wx.RIGHT | wx.LEFT | wx.EXPAND, 5) - headingSizer.Add(best_text, 0, wx.RIGHT | wx.EXPAND, 10) + headingSizer.Add(betterText, 0, wx.RIGHT | wx.EXPAND, 10) mainSizer.Add(headingSizer, 0, wx.ALL | wx.EXPAND, 5) slider = AttributeSlider(parent=self, - baseValue=m.attribute.unit.SimplifyValue(m.baseValue), - minValue=m.attribute.unit.SimplifyValue(min_t[0]), - maxValue=m.attribute.unit.SimplifyValue(max_t[0]), - inverse=better_range is min_t) + baseValue=m.attribute.unit.SimplifyValue(sliderBaseValue), + minValue=displayMinRange[1], + maxValue=displayMaxRange[1], + inverse=displayMaxRange is worseRange) slider.SetValue(m.attribute.unit.SimplifyValue(m.value), False) slider.Bind(EVT_VALUE_CHANGED, self.changeMutatedValue) self.event_mapping[slider] = m diff --git a/gui/builtinMarketBrowser/pfSearchBox.py b/gui/builtinMarketBrowser/pfSearchBox.py index 8d0871f6a..38706a34d 100644 --- a/gui/builtinMarketBrowser/pfSearchBox.py +++ b/gui/builtinMarketBrowser/pfSearchBox.py @@ -2,6 +2,7 @@ import wx import gui.utils.color as colorUtils import gui.utils.draw as drawUtils +from gui.utils.helpers_wxPython import HandleCtrlBackspace SearchButton, EVT_SEARCH_BTN = wx.lib.newevent.NewEvent() CancelButton, EVT_CANCEL_BTN = wx.lib.newevent.NewEvent() @@ -55,7 +56,7 @@ class PFSearchBox(wx.Window): self.EditBox.Bind(wx.EVT_SET_FOCUS, self.OnEditSetFocus) self.EditBox.Bind(wx.EVT_KILL_FOCUS, self.OnEditKillFocus) - + self.EditBox.Bind(wx.EVT_KEY_DOWN, self.OnKeyPress) self.EditBox.Bind(wx.EVT_TEXT, self.OnText) self.EditBox.Bind(wx.EVT_TEXT_ENTER, self.OnTextEnter) @@ -83,6 +84,12 @@ class PFSearchBox(wx.Window): self.Clear() event.Skip() + def OnKeyPress(self, event): + if event.RawControlDown() and event.GetKeyCode() == wx.WXK_BACK: + HandleCtrlBackspace(self.EditBox) + else: + event.Skip() + def Clear(self): self.EditBox.Clear() # self.EditBox.ChangeValue(self.descriptiveText) diff --git a/gui/builtinPreferenceViews/pyfaContextMenuPreferences.py b/gui/builtinPreferenceViews/pyfaContextMenuPreferences.py index 458424dce..7c767c5fb 100644 --- a/gui/builtinPreferenceViews/pyfaContextMenuPreferences.py +++ b/gui/builtinPreferenceViews/pyfaContextMenuPreferences.py @@ -81,6 +81,11 @@ class PFContextMenuPref(PreferenceView): rbSizerRow3.Add(self.rbBox7, 1, wx.TOP | wx.RIGHT, 5) self.rbBox7.Bind(wx.EVT_RADIOBOX, self.OnSetting7Change) + self.rbBox8 = wx.RadioBox(panel, -1, "Fill with module", wx.DefaultPosition, wx.DefaultSize, ['Disabled', 'Enabled'], 1, wx.RA_SPECIFY_COLS) + self.rbBox8.SetSelection(self.settings.get('moduleFill')) + rbSizerRow3.Add(self.rbBox8, 1, wx.TOP | wx.RIGHT, 5) + self.rbBox8.Bind(wx.EVT_RADIOBOX, self.OnSetting8Change) + mainSizer.Add(rbSizerRow3, 1, wx.ALL | wx.EXPAND, 0) panel.SetSizer(mainSizer) @@ -107,6 +112,9 @@ class PFContextMenuPref(PreferenceView): def OnSetting7Change(self, event): self.settings.set('project', event.GetInt()) + def OnSetting8Change(self, event): + self.settings.set('moduleFill', event.GetInt()) + def getImage(self): return BitmapLoader.getBitmap("settings_menu", "gui") diff --git a/gui/builtinPreferenceViews/pyfaGeneralPreferences.py b/gui/builtinPreferenceViews/pyfaGeneralPreferences.py index a31e56f8a..51d32ab5d 100644 --- a/gui/builtinPreferenceViews/pyfaGeneralPreferences.py +++ b/gui/builtinPreferenceViews/pyfaGeneralPreferences.py @@ -76,10 +76,6 @@ class PFGeneralPref(PreferenceView): self.cbGaugeAnimation = wx.CheckBox(panel, wx.ID_ANY, "Animate gauges", wx.DefaultPosition, wx.DefaultSize, 0) mainSizer.Add(self.cbGaugeAnimation, 0, wx.ALL | wx.EXPAND, 5) - self.cbExportCharges = wx.CheckBox(panel, wx.ID_ANY, "Export loaded charges", wx.DefaultPosition, - wx.DefaultSize, 0) - mainSizer.Add(self.cbExportCharges, 0, wx.ALL | wx.EXPAND, 5) - self.cbOpenFitInNew = wx.CheckBox(panel, wx.ID_ANY, "Open fittings in a new page by default", wx.DefaultPosition, wx.DefaultSize, 0) mainSizer.Add(self.cbOpenFitInNew, 0, wx.ALL | wx.EXPAND, 5) @@ -133,7 +129,6 @@ class PFGeneralPref(PreferenceView): self.cbShowTooltip.SetValue(self.sFit.serviceFittingOptions["showTooltip"] or False) self.cbMarketShortcuts.SetValue(self.sFit.serviceFittingOptions["showMarketShortcuts"] or False) self.cbGaugeAnimation.SetValue(self.sFit.serviceFittingOptions["enableGaugeAnimation"]) - self.cbExportCharges.SetValue(self.sFit.serviceFittingOptions["exportCharges"]) self.cbOpenFitInNew.SetValue(self.sFit.serviceFittingOptions["openFitInNew"]) self.chPriceSource.SetStringSelection(self.sFit.serviceFittingOptions["priceSource"]) self.chPriceSystem.SetStringSelection(self.sFit.serviceFittingOptions["priceSystem"]) @@ -151,7 +146,6 @@ class PFGeneralPref(PreferenceView): self.cbShowTooltip.Bind(wx.EVT_CHECKBOX, self.onCBShowTooltip) self.cbMarketShortcuts.Bind(wx.EVT_CHECKBOX, self.onCBShowShortcuts) self.cbGaugeAnimation.Bind(wx.EVT_CHECKBOX, self.onCBGaugeAnimation) - self.cbExportCharges.Bind(wx.EVT_CHECKBOX, self.onCBExportCharges) self.cbOpenFitInNew.Bind(wx.EVT_CHECKBOX, self.onCBOpenFitInNew) self.chPriceSource.Bind(wx.EVT_CHOICE, self.onPricesSourceSelection) self.chPriceSystem.Bind(wx.EVT_CHOICE, self.onPriceSelection) @@ -220,9 +214,6 @@ class PFGeneralPref(PreferenceView): def onCBGaugeAnimation(self, event): self.sFit.serviceFittingOptions["enableGaugeAnimation"] = self.cbGaugeAnimation.GetValue() - def onCBExportCharges(self, event): - self.sFit.serviceFittingOptions["exportCharges"] = self.cbExportCharges.GetValue() - def onCBOpenFitInNew(self, event): self.sFit.serviceFittingOptions["openFitInNew"] = self.cbOpenFitInNew.GetValue() diff --git a/gui/builtinShipBrowser/navigationPanel.py b/gui/builtinShipBrowser/navigationPanel.py index 204802c45..e7f339260 100644 --- a/gui/builtinShipBrowser/navigationPanel.py +++ b/gui/builtinShipBrowser/navigationPanel.py @@ -11,6 +11,7 @@ import gui.utils.fonts as fonts from .events import FitSelected, SearchSelected, ImportSelected, Stage1Selected, Stage2Selected, Stage3Selected from gui.bitmap_loader import BitmapLoader from service.fit import Fit +from gui.utils.helpers_wxPython import HandleCtrlBackspace pyfalog = Logger(__name__) @@ -72,7 +73,7 @@ class NavigationPanel(SFItem.SFBrowserItem): # self.BrowserSearchBox.Bind(wx.EVT_TEXT_ENTER, self.OnBrowserSearchBoxEnter) # self.BrowserSearchBox.Bind(wx.EVT_KILL_FOCUS, self.OnBrowserSearchBoxLostFocus) - self.BrowserSearchBox.Bind(wx.EVT_KEY_DOWN, self.OnBrowserSearchBoxEsc) + self.BrowserSearchBox.Bind(wx.EVT_KEY_DOWN, self.OnBrowserSearchBoxKeyPress) self.BrowserSearchBox.Bind(wx.EVT_TEXT, self.OnScheduleSearch) self.SetMinSize(size) @@ -103,9 +104,11 @@ class NavigationPanel(SFItem.SFBrowserItem): def OnBrowserSearchBoxLostFocus(self, event): self.BrowserSearchBox.Show(False) - def OnBrowserSearchBoxEsc(self, event): + def OnBrowserSearchBoxKeyPress(self, event): if event.GetKeyCode() == wx.WXK_ESCAPE: self.BrowserSearchBox.Show(False) + elif event.RawControlDown() and event.GetKeyCode() == wx.WXK_BACK: + HandleCtrlBackspace(self.BrowserSearchBox) else: event.Skip() diff --git a/gui/builtinStatsViews/firepowerViewFull.py b/gui/builtinStatsViews/firepowerViewFull.py index 29ce7a482..4c773c9f1 100644 --- a/gui/builtinStatsViews/firepowerViewFull.py +++ b/gui/builtinStatsViews/firepowerViewFull.py @@ -22,7 +22,8 @@ import wx import gui.mainFrame from gui.statsView import StatsView from gui.bitmap_loader import BitmapLoader -from gui.utils.numberFormatter import formatAmount +from gui.utils.numberFormatter import formatAmount, roundToPrec +from eos.utils.spoolSupport import SpoolType, SpoolOptions from service.fit import Fit @@ -148,27 +149,55 @@ class FirepowerViewFull(StatsView): else: self.stEff.Hide() - stats = (("labelFullDpsWeapon", lambda: fit.weaponDPS, 3, 0, 0, "%s DPS", None), - ("labelFullDpsDrone", lambda: fit.droneDPS, 3, 0, 0, "%s DPS", None), - ("labelFullVolleyTotal", lambda: fit.totalVolley, 3, 0, 0, "%s", "Volley: %.1f"), - ("labelFullDpsTotal", lambda: fit.totalDPS, 3, 0, 0, "%s", None)) - # See GH issue # - # if fit is not None and fit.totalYield > 0: - # self.miningyield.Show() - # else: - # self.miningyield.Hide() + def dpsToolTip(preSpool, fullSpool, prec, lowest, highest): + if roundToPrec(preSpool, prec) == roundToPrec(fullSpool, prec): + return "" + else: + return "Spool up: {}-{}".format( + formatAmount(preSpool, prec, lowest, highest), + formatAmount(fullSpool, prec, lowest, highest)) + + # TODO: fetch spoolup option + defaultSpoolValue = 1 + stats = ( + ( + "labelFullDpsWeapon", + lambda: fit.getWeaponDps(spoolOptions=SpoolOptions(SpoolType.SCALE, defaultSpoolValue, False)).total, + lambda: fit.getWeaponDps(spoolOptions=SpoolOptions(SpoolType.SCALE, 0, True)).total, + lambda: fit.getWeaponDps(spoolOptions=SpoolOptions(SpoolType.SCALE, 1, True)).total, + 3, 0, 0, "{}{} DPS"), + ( + "labelFullDpsDrone", + lambda: fit.getDroneDps().total, + lambda: fit.getDroneDps().total, + lambda: fit.getDroneDps().total, + 3, 0, 0, "{}{} DPS"), + ( + "labelFullVolleyTotal", + lambda: fit.getTotalVolley(spoolOptions=SpoolOptions(SpoolType.SCALE, defaultSpoolValue, False)).total, + lambda: fit.getTotalVolley(spoolOptions=SpoolOptions(SpoolType.SCALE, 0, True)).total, + lambda: fit.getTotalVolley(spoolOptions=SpoolOptions(SpoolType.SCALE, 1, True)).total, + 3, 0, 0, "{}{}"), + ( + "labelFullDpsTotal", + lambda: fit.getTotalDps(spoolOptions=SpoolOptions(SpoolType.SCALE, defaultSpoolValue, False)).total, + lambda: fit.getTotalDps(spoolOptions=SpoolOptions(SpoolType.SCALE, 0, True)).total, + lambda: fit.getTotalDps(spoolOptions=SpoolOptions(SpoolType.SCALE, 1, True)).total, + 3, 0, 0, "{}{}")) counter = 0 - for labelName, value, prec, lowest, highest, valueFormat, altFormat in stats: + for labelName, val, preSpoolVal, fullSpoolVal, prec, lowest, highest, valueFormat in stats: label = getattr(self, labelName) - value = value() if fit is not None else 0 - value = value if value is not None else 0 - if self._cachedValues[counter] != value: - valueStr = formatAmount(value, prec, lowest, highest) - label.SetLabel(valueFormat % valueStr) - tipStr = valueFormat % valueStr if altFormat is None else altFormat % value - label.SetToolTip(wx.ToolTip(tipStr)) - self._cachedValues[counter] = value + val = val() if fit is not None else 0 + preSpoolVal = preSpoolVal() if fit is not None else 0 + fullSpoolVal = fullSpoolVal() if fit is not None else 0 + if self._cachedValues[counter] != val: + tooltipText = dpsToolTip(preSpoolVal, fullSpoolVal, prec, lowest, highest) + label.SetLabel(valueFormat.format( + formatAmount(val, prec, lowest, highest), + "\u02e2" if tooltipText else "")) + label.SetToolTip(wx.ToolTip(tooltipText)) + self._cachedValues[counter] = val counter += 1 self.panel.Layout() diff --git a/gui/builtinStatsViews/outgoingViewFull.py b/gui/builtinStatsViews/outgoingViewFull.py index be24ee6af..3b6a6ce58 100644 --- a/gui/builtinStatsViews/outgoingViewFull.py +++ b/gui/builtinStatsViews/outgoingViewFull.py @@ -21,7 +21,35 @@ import wx from gui.statsView import StatsView from gui.bitmap_loader import BitmapLoader -from gui.utils.numberFormatter import formatAmount +from gui.utils.numberFormatter import formatAmount, roundToPrec +from eos.utils.spoolSupport import SpoolType, SpoolOptions + + +stats = [ + ( + "labelRemoteCapacitor", "Capacitor:", "{}{} GJ/s", "capacitorInfo", "Capacitor restored", + lambda fit, spool: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, spool, False)).get("Capacitor", 0), + lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, 0, True)).get("Capacitor", 0), + lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, 1, True)).get("Capacitor", 0), + 3, 0, 0), + ( + "labelRemoteShield", "Shield:", "{}{} HP/s", "shieldActive", "Shield restored", + lambda fit, spool: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, spool, False)).get("Shield", 0), + lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, 0, True)).get("Shield", 0), + lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, 1, True)).get("Shield", 0), + 3, 0, 0), + ( + "labelRemoteArmor", "Armor:", "{}{} HP/s", "armorActive", "Armor restored", + lambda fit, spool: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, spool, False)).get("Armor", 0), + lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, 0, True)).get("Armor", 0), + lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, 1, True)).get("Armor", 0), + 3, 0, 0), + ( + "labelRemoteHull", "Hull:", "{}{} HP/s", "hullActive", "Hull restored", + lambda fit, spool: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, spool, False)).get("Hull", 0), + lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, 0, True)).get("Hull", 0), + lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, 1, True)).get("Hull", 0), + 3, 0, 0)] class OutgoingViewFull(StatsView): @@ -48,56 +76,46 @@ class OutgoingViewFull(StatsView): contentSizer.Add(sizerOutgoing, 0, wx.EXPAND, 0) - counter = 0 - - rr_list = [ - ("RemoteCapacitor", "Capacitor:", "capacitorInfo", "Capacitor GJ/s per second transferred remotely."), - ("RemoteShield", "Shield:", "shieldActive", "Shield hitpoints per second repaired remotely."), - ("RemoteArmor", "Armor:", "armorActive", "Armor hitpoints per second repaired remotely."), - ("RemoteHull", "Hull:", "hullActive", "Hull hitpoints per second repaired remotely."), - ] - - for outgoingType, label, image, tooltip in rr_list: + for labelName, labelDesc, valueFormat, image, tooltip, val, preSpoolVal, fullSpoolVal, prec, lowest, highest in stats: baseBox = wx.BoxSizer(wx.VERTICAL) baseBox.Add(BitmapLoader.getStaticBitmap("%s_big" % image, parent, "gui"), 0, wx.ALIGN_CENTER) - if "Capacitor" in outgoingType: - lbl = wx.StaticText(parent, wx.ID_ANY, "0 GJ/s") - else: - lbl = wx.StaticText(parent, wx.ID_ANY, "0 HP/s") - + lbl = wx.StaticText(parent, wx.ID_ANY, valueFormat.format(0, "")) lbl.SetToolTip(wx.ToolTip(tooltip)) - - setattr(self, "label%s" % outgoingType, lbl) + setattr(self, labelName, lbl) baseBox.Add(lbl, 0, wx.ALIGN_CENTER) self._cachedValues.append(0) - counter += 1 sizerOutgoing.Add(baseBox, 1, wx.ALIGN_LEFT) def refreshPanel(self, fit): - # If we did anything intresting, we'd update our labels to reflect the new fit's stats here - stats = [ - ("labelRemoteArmor", lambda: fit.remoteReps["Armor"], 3, 0, 0, "%s HP/s", None), - ("labelRemoteShield", lambda: fit.remoteReps["Shield"], 3, 0, 0, "%s HP/s", None), - ("labelRemoteHull", lambda: fit.remoteReps["Hull"], 3, 0, 0, "%s HP/s", None), - ("labelRemoteCapacitor", lambda: fit.remoteReps["Capacitor"], 3, 0, 0, "%s GJ/s", None), - ] + def formatTooltip(text, preSpool, fullSpool, prec, lowest, highest): + if roundToPrec(preSpool, prec) == roundToPrec(fullSpool, prec): + return False, text + else: + return True, "{}\nSpool up: {}-{}".format( + text, + formatAmount(preSpool, prec, lowest, highest), + formatAmount(fullSpool, prec, lowest, highest)) + # TODO: fetch spoolup option + defaultSpoolValue = 1 counter = 0 - for labelName, value, prec, lowest, highest, valueFormat, altFormat in stats: + for labelName, labelDesc, valueFormat, image, tooltip, val, preSpoolVal, fullSpoolVal, prec, lowest, highest in stats: label = getattr(self, labelName) - value = value() if fit is not None else 0 - value = value if value is not None else 0 - if self._cachedValues[counter] != value: - valueStr = formatAmount(value, prec, lowest, highest) - label.SetLabel(valueFormat % valueStr) - tipStr = valueFormat % valueStr if altFormat is None else altFormat % value - label.SetToolTip(wx.ToolTip(tipStr)) - self._cachedValues[counter] = value + val = val(fit, defaultSpoolValue) if fit is not None else 0 + preSpoolVal = preSpoolVal(fit) if fit is not None else 0 + fullSpoolVal = fullSpoolVal(fit) if fit is not None else 0 + if self._cachedValues[counter] != val: + hasSpool, tooltipText = formatTooltip(tooltip, preSpoolVal, fullSpoolVal, prec, lowest, highest) + label.SetLabel(valueFormat.format( + formatAmount(val, prec, lowest, highest), + "\u02e2" if hasSpool else "")) + label.SetToolTip(wx.ToolTip(tooltipText)) + self._cachedValues[counter] = val counter += 1 self.panel.Layout() self.headerPanel.Layout() diff --git a/gui/builtinStatsViews/outgoingViewMinimal.py b/gui/builtinStatsViews/outgoingViewMinimal.py index 21fe9bede..055a65e9e 100644 --- a/gui/builtinStatsViews/outgoingViewMinimal.py +++ b/gui/builtinStatsViews/outgoingViewMinimal.py @@ -20,7 +20,35 @@ # noinspection PyPackageRequirements import wx from gui.statsView import StatsView -from gui.utils.numberFormatter import formatAmount +from gui.utils.numberFormatter import formatAmount, roundToPrec +from eos.utils.spoolSupport import SpoolType, SpoolOptions + + +stats = [ + ( + "labelRemoteCapacitor", "Capacitor:", "{}{} GJ/s", "capacitorInfo", "Capacitor restored", + lambda fit, spool: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, spool, False)).get("Capacitor", 0), + lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, 0, True)).get("Capacitor", 0), + lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, 1, True)).get("Capacitor", 0), + 3, 0, 0), + ( + "labelRemoteShield", "Shield:", "{}{} HP/s", "shieldActive", "Shield restored", + lambda fit, spool: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, spool, False)).get("Shield", 0), + lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, 0, True)).get("Shield", 0), + lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, 1, True)).get("Shield", 0), + 3, 0, 0), + ( + "labelRemoteArmor", "Armor:", "{}{} HP/s", "armorActive", "Armor restored", + lambda fit, spool: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, spool, False)).get("Armor", 0), + lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, 0, True)).get("Armor", 0), + lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, 1, True)).get("Armor", 0), + 3, 0, 0), + ( + "labelRemoteHull", "Hull:", "{}{} HP/s", "hullActive", "Hull restored", + lambda fit, spool: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, spool, False)).get("Hull", 0), + lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, 0, True)).get("Hull", 0), + lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, 1, True)).get("Hull", 0), + 3, 0, 0)] class OutgoingViewMinimal(StatsView): @@ -47,56 +75,46 @@ class OutgoingViewMinimal(StatsView): contentSizer.Add(sizerOutgoing, 0, wx.EXPAND, 0) - counter = 0 - - rr_list = [ - ("RemoteCapacitor", "Capacitor:", "capacitorInfo", "Capacitor GJ/s per second transferred remotely."), - ("RemoteShield", "Shield:", "shieldActive", "Shield hitpoints per second repaired remotely."), - ("RemoteArmor", "Armor:", "armorActive", "Armor hitpoints per second repaired remotely."), - ("RemoteHull", "Hull:", "hullActive", "Hull hitpoints per second repaired remotely."), - ] - - for outgoingType, label, image, tooltip in rr_list: + for labelName, labelDesc, valueFormat, image, tooltip, val, preSpoolVal, fullSpoolVal, prec, lowest, highest in stats: baseBox = wx.BoxSizer(wx.VERTICAL) - baseBox.Add(wx.StaticText(contentPanel, wx.ID_ANY, label), 0, wx.ALIGN_CENTER) - - if "Capacitor" in outgoingType: - lbl = wx.StaticText(parent, wx.ID_ANY, "0 GJ/s") - else: - lbl = wx.StaticText(parent, wx.ID_ANY, "0 HP/s") + baseBox.Add(wx.StaticText(contentPanel, wx.ID_ANY, labelDesc), 0, wx.ALIGN_CENTER) + lbl = wx.StaticText(parent, wx.ID_ANY, valueFormat.format(0, "")) lbl.SetToolTip(wx.ToolTip(tooltip)) - - setattr(self, "label%s" % outgoingType, lbl) + setattr(self, labelName, lbl) baseBox.Add(lbl, 0, wx.ALIGN_CENTER) self._cachedValues.append(0) - counter += 1 sizerOutgoing.Add(baseBox, 1, wx.ALIGN_LEFT) def refreshPanel(self, fit): - # If we did anything intresting, we'd update our labels to reflect the new fit's stats here - stats = [ - ("labelRemoteArmor", lambda: fit.remoteReps["Armor"], 3, 0, 0, "%s HP/s", None), - ("labelRemoteShield", lambda: fit.remoteReps["Shield"], 3, 0, 0, "%s HP/s", None), - ("labelRemoteHull", lambda: fit.remoteReps["Hull"], 3, 0, 0, "%s HP/s", None), - ("labelRemoteCapacitor", lambda: fit.remoteReps["Capacitor"], 3, 0, 0, "%s GJ/s", None), - ] + def formatTooltip(text, preSpool, fullSpool, prec, lowest, highest): + if roundToPrec(preSpool, prec) == roundToPrec(fullSpool, prec): + return False, text + else: + return True, "{}\nSpool up: {}-{}".format( + text, + formatAmount(preSpool, prec, lowest, highest), + formatAmount(fullSpool, prec, lowest, highest)) + # TODO: fetch spoolup option + defaultSpoolValue = 1 counter = 0 - for labelName, value, prec, lowest, highest, valueFormat, altFormat in stats: + for labelName, labelDesc, valueFormat, image, tooltip, val, preSpoolVal, fullSpoolVal, prec, lowest, highest in stats: label = getattr(self, labelName) - value = value() if fit is not None else 0 - value = value if value is not None else 0 - if self._cachedValues[counter] != value: - valueStr = formatAmount(value, prec, lowest, highest) - label.SetLabel(valueFormat % valueStr) - tipStr = valueFormat % valueStr if altFormat is None else altFormat % value - label.SetToolTip(wx.ToolTip(tipStr)) - self._cachedValues[counter] = value + val = val(fit, defaultSpoolValue) if fit is not None else 0 + preSpoolVal = preSpoolVal(fit) if fit is not None else 0 + fullSpoolVal = fullSpoolVal(fit) if fit is not None else 0 + if self._cachedValues[counter] != val: + hasSpool, tooltipText = formatTooltip(tooltip, preSpoolVal, fullSpoolVal, prec, lowest, highest) + label.SetLabel(valueFormat.format( + formatAmount(val, prec, lowest, highest), + "\u02e2" if hasSpool else "")) + label.SetToolTip(wx.ToolTip(tooltipText)) + self._cachedValues[counter] = val counter += 1 self.panel.Layout() self.headerPanel.Layout() diff --git a/gui/builtinStatsViews/rechargeViewFull.py b/gui/builtinStatsViews/rechargeViewFull.py index eadcf537f..ccc89f79f 100644 --- a/gui/builtinStatsViews/rechargeViewFull.py +++ b/gui/builtinStatsViews/rechargeViewFull.py @@ -63,15 +63,20 @@ class RechargeViewFull(StatsView): # Add an empty label first for correct alignment. sizerTankStats.Add(wx.StaticText(contentPanel, wx.ID_ANY, ""), 0) - toolTipText = {"shieldPassive": "Passive shield recharge", "shieldActive": "Active shield boost", - "armorActive": "Armor repair amount", "hullActive": "Hull repair amount"} + toolTipText = { + "shieldPassive": "Passive shield recharge", + "shieldActive": "Active shield boost", + "armorActive": "Armor repair amount", + "hullActive": "Hull repair amount"} for tankType in ("shieldPassive", "shieldActive", "armorActive", "hullActive"): bitmap = BitmapLoader.getStaticBitmap("%s_big" % tankType, contentPanel, "gui") tooltip = wx.ToolTip(toolTipText[tankType]) bitmap.SetToolTip(tooltip) sizerTankStats.Add(bitmap, 0, wx.ALIGN_CENTER) - toolTipText = {"reinforced": "Reinforced", "sustained": "Sustained"} + toolTipText = { + "reinforced": "Reinforced", + "sustained": "Sustained"} for stability in ("reinforced", "sustained"): bitmap = BitmapLoader.getStaticBitmap("regen%s_big" % stability.capitalize(), contentPanel, "gui") tooltip = wx.ToolTip(toolTipText[stability]) @@ -85,7 +90,6 @@ class RechargeViewFull(StatsView): tankTypeCap = tankType[0].capitalize() + tankType[1:] lbl = wx.StaticText(contentPanel, wx.ID_ANY, "0.0", style=wx.ALIGN_RIGHT) setattr(self, "labelTank%s%s" % (stability.capitalize(), tankTypeCap), lbl) - box = wx.BoxSizer(wx.HORIZONTAL) box.Add(lbl, 0, wx.EXPAND) @@ -115,9 +119,23 @@ class RechargeViewFull(StatsView): unitlbl = getattr(self, "unitLabelTank%s%sActive" % (stability.capitalize(), name.capitalize())) unitlbl.SetLabel(unit) if tank is not None: - lbl.SetLabel("%.1f" % tank["%sRepair" % name]) + amount = tank["{}Repair".format(name)] else: - lbl.SetLabel("0.0") + amount = 0 + + if tank is not None and name == "armor": + preSpoolAmount = tank["armorRepairPreSpool"] + fullSpoolAmount = tank["armorRepairFullSpool"] + if round(preSpoolAmount, 1) != round(fullSpoolAmount, 1): + ttText = "Spool up: {:.1f}-{:.1f}".format(preSpoolAmount, fullSpoolAmount) + else: + ttText = "" + else: + ttText = "" + + lbl.SetLabel("{:.1f}{}".format(amount, "\u02e2" if ttText else "")) + lbl.SetToolTip(wx.ToolTip(ttText)) + unitlbl.SetToolTip(wx.ToolTip(ttText)) if fit is not None: label = getattr(self, "labelTankSustainedShieldPassive") diff --git a/gui/builtinViewColumns/misc.py b/gui/builtinViewColumns/misc.py index d89db812e..e9bff3d56 100644 --- a/gui/builtinViewColumns/misc.py +++ b/gui/builtinViewColumns/misc.py @@ -27,7 +27,7 @@ from gui.viewColumn import ViewColumn from gui.bitmap_loader import BitmapLoader from gui.utils.numberFormatter import formatAmount from gui.utils.listFormatter import formatList -from eos.saveddata.drone import Drone +from eos.utils.spoolSupport import SpoolType, SpoolOptions class Miscellanea(ViewColumn): @@ -93,7 +93,9 @@ class Miscellanea(ViewColumn): text = "" tooltip = "" elif max(doomsday_duration / doomsday_dottime, 1) > 1: - text = "{0} dmg over {1} s".format(formatAmount(volley * (doomsday_duration / doomsday_dottime), 3, 0, 3), doomsday_duration / 1000) + text = "{} over {}s".format( + formatAmount(volley * (doomsday_duration / doomsday_dottime), 3, 0, 6), + formatAmount((doomsday_duration / 1000), 0, 0, 0)) tooltip = "Raw damage done over time" else: text = "{0} dmg".format(formatAmount(volley * (doomsday_duration / doomsday_dottime), 3, 0, 3)) @@ -115,16 +117,13 @@ class Miscellanea(ViewColumn): text = "{0}".format(formatAmount(trackingSpeed, 3, 0, 3)) tooltip = "tracking speed" info.append((text, tooltip)) - maxBonusDamage = stuff.getModifiedItemAttr("damageMultiplierBonusMax") - bonusDamagePerCycle = stuff.getModifiedItemAttr("damageMultiplierBonusPerCycle") - cycleTime = stuff.getModifiedItemAttr("speed") - if maxBonusDamage and bonusDamagePerCycle and cycleTime: - cyclesToFullDamage = int(maxBonusDamage / bonusDamagePerCycle) - timeToFullDamage = (cycleTime / 1000) * cyclesToFullDamage - if cyclesToFullDamage: - text = "{0}s".format(formatAmount(timeToFullDamage, 3, 0, 3)) - tooltip = "spool-up time" - info.append((text, tooltip)) + # TODO: fetch spoolup option + defaultSpoolValue = 1 + spoolTime = stuff.getSpoolData(spoolOptions=SpoolOptions(SpoolType.SCALE, defaultSpoolValue, False))[1] + if spoolTime: + text = "{0}s".format(formatAmount(spoolTime, 3, 0, 3)) + tooltip = "spool up time" + info.append((text, tooltip)) if not info: return "", None text = ' | '.join(i[0] for i in info) @@ -333,39 +332,61 @@ class Miscellanea(ViewColumn): tooltip = "Sensor recalibration time" return text, tooltip elif itemGroup == "Remote Armor Repairer": - repAmount = stuff.getModifiedItemAttr("armorDamageAmount") - cycleTime = stuff.getModifiedItemAttr("duration") - if not repAmount or not cycleTime: + rps = stuff.getRemoteReps(ignoreState=True)[1] + if not rps: return "", None - repPerSec = float(repAmount) * 1000 / cycleTime - text = "{0}/s".format(formatAmount(repPerSec, 3, 0, 3, forceSign=True)) + text = "{0}/s".format(formatAmount(rps, 3, 0, 3, forceSign=True)) tooltip = "Armor repaired per second" return text, tooltip - elif itemGroup == "Remote Shield Booster": - repAmount = stuff.getModifiedItemAttr("shieldBonus") - cycleTime = stuff.cycleTime - if not repAmount or not cycleTime: + elif itemGroup == "Mutadaptive Remote Armor Repairer": + # TODO: fetch spoolup option + defaultSpoolValue = 1 + spoolOptDefault = SpoolOptions(SpoolType.SCALE, defaultSpoolValue, False) + spoolOptPre = SpoolOptions(SpoolType.SCALE, 0, True) + spoolOptFull = SpoolOptions(SpoolType.SCALE, 1, True) + rrType, rps = stuff.getRemoteReps(spoolOptions=spoolOptDefault, ignoreState=True) + rrTypePre, rpsPre = stuff.getRemoteReps(spoolOptions=spoolOptPre, ignoreState=True) + rrTypeFull, rpsFull = stuff.getRemoteReps(spoolOptions=spoolOptFull, ignoreState=True) + if not rps: return "", None - repPerSec = float(repAmount) * 1000 / cycleTime - text = "{0}/s".format(formatAmount(repPerSec, 3, 0, 3, forceSign=True)) + text = [] + tooltip = [] + text.append("{}/s".format(formatAmount(rps, 3, 0, 3, forceSign=True))) + tooltip.append("Armor repaired per second") + spoolTime = stuff.getSpoolData(spoolOptDefault)[1] + if spoolTime: + text.append("{}s".format(formatAmount(spoolTime, 3, 0, 3))) + tooltip.append("spool up time") + text = " | ".join(text) + tooltip = " and ".join(tooltip) + spoolTimePre = stuff.getSpoolData(spoolOptPre)[1] + spoolTimeFull = stuff.getSpoolData(spoolOptFull)[1] + if spoolTimePre != spoolTimeFull: + tooltip = "{}\nSpool up: {}-{} over {}s".format( + tooltip, + formatAmount(rpsPre, 3, 0, 3), + formatAmount(rpsFull, 3, 0, 3), + formatAmount(spoolTimeFull - spoolTimePre, 3, 0, 3)) + return text, tooltip + elif itemGroup == "Remote Shield Booster": + rps = stuff.getRemoteReps(ignoreState=True)[1] + if not rps: + return "", None + text = "{0}/s".format(formatAmount(rps, 3, 0, 3, forceSign=True)) tooltip = "Shield transferred per second" return text, tooltip elif itemGroup == "Remote Capacitor Transmitter": - repAmount = stuff.getModifiedItemAttr("powerTransferAmount") - cycleTime = stuff.cycleTime - if not repAmount or not cycleTime: + rps = stuff.getRemoteReps(ignoreState=True)[1] + if not rps: return "", None - repPerSec = float(repAmount) * 1000 / cycleTime - text = "{0}/s".format(formatAmount(repPerSec, 3, 0, 3, forceSign=True)) + text = "{0}/s".format(formatAmount(rps, 3, 0, 3, forceSign=True)) tooltip = "Energy transferred per second" return text, tooltip elif itemGroup == "Remote Hull Repairer": - repAmount = stuff.getModifiedItemAttr("structureDamageAmount") - cycleTime = stuff.cycleTime - if not repAmount or not cycleTime: + rps = stuff.getRemoteReps(ignoreState=True)[1] + if not rps: return "", None - repPerSec = float(repAmount) * 1000 / cycleTime - text = "{0}/s".format(formatAmount(repPerSec, 3, 0, 3, forceSign=True)) + text = "{0}/s".format(formatAmount(rps, 3, 0, 3, forceSign=True)) tooltip = "Structure repaired per second" return text, tooltip elif itemGroup == "Gang Coordinator": @@ -463,28 +484,11 @@ class Miscellanea(ViewColumn): tooltip = "Mining Yield per second ({0} per hour)".format(formatAmount(minePerSec * 3600, 3, 0, 3)) return text, tooltip elif itemGroup == "Logistic Drone": - armorAmount = stuff.getModifiedItemAttr("armorDamageAmount") - shieldAmount = stuff.getModifiedItemAttr("shieldBonus") - hullAmount = stuff.getModifiedItemAttr("structureDamageAmount") - repAmount = armorAmount or shieldAmount or hullAmount - cycleTime = stuff.getModifiedItemAttr("duration") - if not repAmount or not cycleTime: + repType, rps = stuff.getRemoteReps(ignoreState=True) + if not repType: return "", None - repPerSecPerDrone = repPerSec = float(repAmount) * 1000 / cycleTime - - if isinstance(stuff, Drone): - repPerSec *= stuff.amount - - text = "{0}/s".format(formatAmount(repPerSec, 3, 0, 3)) - ttEntries = [] - if hullAmount is not None and repAmount == hullAmount: - ttEntries.append("structure") - if armorAmount is not None and repAmount == armorAmount: - ttEntries.append("armor") - if shieldAmount is not None and repAmount == shieldAmount: - ttEntries.append("shield") - - tooltip = "{0} HP repaired per second\n{1} HP/s per drone".format(formatList(ttEntries).capitalize(), repPerSecPerDrone) + text = "{}/s".format(formatAmount(rps, 3, 0, 3)) + tooltip = "{} HP repaired per second\n{} HP/s per drone".format(repType, formatAmount(rps / stuff.amount, 3, 0, 3)) return text, tooltip elif itemGroup == "Energy Neutralizer Drone": neutAmount = stuff.getModifiedItemAttr("energyNeutralizerAmount") @@ -500,7 +504,7 @@ class Miscellanea(ViewColumn): text = "{0}s".format(cycleTime) tooltip = "Spoolup time" return text, tooltip - elif itemGroup in ("Siege Module", "Cynosural Field"): + elif itemGroup in ("Siege Module", "Cynosural Field Generator"): amt = stuff.getModifiedItemAttr("consumptionQuantity") if amt: typeID = stuff.getModifiedItemAttr("consumptionType") diff --git a/gui/builtinViewColumns/price.py b/gui/builtinViewColumns/price.py index a68614b83..56901c172 100644 --- a/gui/builtinViewColumns/price.py +++ b/gui/builtinViewColumns/price.py @@ -22,6 +22,7 @@ import wx from eos.saveddata.cargo import Cargo from eos.saveddata.drone import Drone +from eos.saveddata.price import PriceStatus from service.price import Price as ServicePrice from gui.viewColumn import ViewColumn from gui.bitmap_loader import BitmapLoader @@ -45,13 +46,16 @@ class Price(ViewColumn): if stuff.isEmpty: return "" - price = stuff.item.price + priceObj = stuff.item.price - if not price or not price.isValid: + if not priceObj.isValid: return False # Fetch actual price as float to not modify its value on Price object - price = price.price + price = priceObj.price + + if price == 0: + return "" if isinstance(stuff, Drone) or isinstance(stuff, Cargo): price *= stuff.amount @@ -63,10 +67,12 @@ class Price(ViewColumn): def callback(item): price = item[0] - text = formatAmount(price.price, 3, 3, 9, currency=True) if price.price else "" - if price.failed: - text += " (!)" - colItem.SetText(text) + textItems = [] + if price.price: + textItems.append(formatAmount(price.price, 3, 3, 9, currency=True)) + if price.status == PriceStatus.fail: + textItems.append("(!)") + colItem.SetText(" ".join(textItems)) display.SetItem(colItem) diff --git a/gui/characterEditor.py b/gui/characterEditor.py index 6fe7c809a..2b4d59341 100644 --- a/gui/characterEditor.py +++ b/gui/characterEditor.py @@ -129,7 +129,12 @@ class CharacterEntityEditor(EntityEditor): def DoRename(self, entity, name): sChar = Character.getInstance() - sChar.rename(entity, name) + + if entity.alphaCloneID: + trimmed_name = re.sub('[ \(\u03B1\)]+$', '', name) + sChar.rename(entity, trimmed_name) + else: + sChar.rename(entity, name) def DoCopy(self, entity, name): sChar = Character.getInstance() diff --git a/gui/contextMenu.py b/gui/contextMenu.py index be972b0f8..7c1caf085 100644 --- a/gui/contextMenu.py +++ b/gui/contextMenu.py @@ -188,6 +188,7 @@ from gui.builtinContextMenus import ( # noqa: E402,F401 marketJump, # droneSplit, itemRemove, + fillWithModule, droneRemoveStack, ammoPattern, project, diff --git a/gui/copySelectDialog.py b/gui/copySelectDialog.py index 10eff2647..91725e048 100644 --- a/gui/copySelectDialog.py +++ b/gui/copySelectDialog.py @@ -18,9 +18,13 @@ # ============================================================================= +from collections import OrderedDict + # noinspection PyPackageRequirements import wx + from service.port.eft import EFT_OPTIONS +from service.port.multibuy import MULTIBUY_OPTIONS from service.settings import SettingsProvider @@ -37,39 +41,53 @@ class CopySelectDialog(wx.Dialog): style=wx.DEFAULT_DIALOG_STYLE) mainSizer = wx.BoxSizer(wx.VERTICAL) - self.settings = SettingsProvider.getInstance().getSettings("pyfaExport", {"format": 0, "options": 0}) + self.copyFormats = OrderedDict(( + ("EFT", (CopySelectDialog.copyFormatEft, EFT_OPTIONS)), + ("MultiBuy", (CopySelectDialog.copyFormatMultiBuy, MULTIBUY_OPTIONS)), + ("ESI", (CopySelectDialog.copyFormatEsi, None)), + ("EFS", (CopySelectDialog.copyFormatEfs, None)), + # ("XML", (CopySelectDialog.copyFormatXml, None)), + # ("DNA", (CopySelectDialog.copyFormatDna, None)), + )) - self.copyFormats = { - "EFT": CopySelectDialog.copyFormatEft, - "XML": CopySelectDialog.copyFormatXml, - "DNA": CopySelectDialog.copyFormatDna, - "ESI": CopySelectDialog.copyFormatEsi, - "MultiBuy": CopySelectDialog.copyFormatMultiBuy, - "EFS": CopySelectDialog.copyFormatEfs - } + defaultFormatOptions = {} + for formatId, formatOptions in self.copyFormats.values(): + if formatOptions is None: + continue + defaultFormatOptions[formatId] = {opt[0]: opt[3] for opt in formatOptions} + + self.settings = SettingsProvider.getInstance().getSettings("pyfaExport", {"format": 0, "options": defaultFormatOptions}) + # Options used to be stored as int (EFT export options only), + # overwrite them with new format when needed + if isinstance(self.settings["options"], int): + self.settings["options"] = defaultFormatOptions self.options = {} - for i, format in enumerate(self.copyFormats.keys()): - if i == 0: - rdo = wx.RadioButton(self, wx.ID_ANY, format, style=wx.RB_GROUP) + initialized = False + for formatName, formatData in self.copyFormats.items(): + formatId, formatOptions = formatData + if not initialized: + rdo = wx.RadioButton(self, wx.ID_ANY, formatName, style=wx.RB_GROUP) + initialized = True else: - rdo = wx.RadioButton(self, wx.ID_ANY, format) + rdo = wx.RadioButton(self, wx.ID_ANY, formatName) rdo.Bind(wx.EVT_RADIOBUTTON, self.Selected) - if self.settings['format'] == self.copyFormats[format]: + if self.settings['format'] == formatId: rdo.SetValue(True) - self.copyFormat = self.copyFormats[format] + self.copyFormat = formatId mainSizer.Add(rdo, 0, wx.EXPAND | wx.ALL, 5) - if format == "EFT": + if formatOptions: bsizer = wx.BoxSizer(wx.VERTICAL) + self.options[formatId] = {} - for x, v in EFT_OPTIONS.items(): - ch = wx.CheckBox(self, -1, v['name']) - self.options[x] = ch - if self.settings['options'] & x: - ch.SetValue(True) - bsizer.Add(ch, 1, wx.EXPAND | wx.TOP | wx.BOTTOM, 3) + for optId, optName, optDesc, _ in formatOptions: + checkbox = wx.CheckBox(self, -1, optName) + self.options[formatId][optId] = checkbox + if self.settings['options'].get(formatId, {}).get(optId, defaultFormatOptions.get(formatId, {}).get(optId)): + checkbox.SetValue(True) + bsizer.Add(checkbox, 1, wx.EXPAND | wx.TOP | wx.BOTTOM, 3) mainSizer.Add(bsizer, 1, wx.EXPAND | wx.LEFT, 20) buttonSizer = self.CreateButtonSizer(wx.OK | wx.CANCEL) @@ -83,21 +101,21 @@ class CopySelectDialog(wx.Dialog): def Selected(self, event): obj = event.GetEventObject() - format = obj.GetLabel() - self.copyFormat = self.copyFormats[format] + formatName = obj.GetLabel() + self.copyFormat = self.copyFormats[formatName][0] self.toggleOptions() self.Fit() def toggleOptions(self): - for ch in self.options.values(): - ch.Enable(self.GetSelected() == CopySelectDialog.copyFormatEft) + for formatId in self.options: + for checkbox in self.options[formatId].values(): + checkbox.Enable(self.GetSelected() == formatId) def GetSelected(self): return self.copyFormat def GetOptions(self): - i = 0 - for x, v in self.options.items(): - if v.IsChecked(): - i = i ^ x - return i + options = {} + for formatId in self.options: + options[formatId] = {optId: ch.IsChecked() for optId, ch in self.options[formatId].items()} + return options diff --git a/gui/errorDialog.py b/gui/errorDialog.py index d9112d4b8..240ab8da4 100644 --- a/gui/errorDialog.py +++ b/gui/errorDialog.py @@ -67,7 +67,7 @@ class ErrorFrame(wx.Frame): from eos.config import gamedata_version, gamedata_date time = datetime.datetime.fromtimestamp(int(gamedata_date)).strftime('%Y-%m-%d %H:%M:%S') - version = "pyfa v" + config.getVersion() + '\nEVE Data Version: {} ({})\n\n'.format(gamedata_version, time) # gui.aboutData.versionString + version = "pyfa " + config.getVersion() + '\nEVE Data Version: {} ({})\n\n'.format(gamedata_version, time) # gui.aboutData.versionString desc = "pyfa has experienced an unexpected issue. Below is a message that contains crucial\n" \ "information about how this was triggered. Please contact the developers with the\n" \ diff --git a/gui/fitCommands/__init__.py b/gui/fitCommands/__init__.py index 3501e8089..42b718c5d 100644 --- a/gui/fitCommands/__init__.py +++ b/gui/fitCommands/__init__.py @@ -2,6 +2,7 @@ from .guiToggleModuleState import GuiModuleStateChangeCommand from .guiAddModule import GuiModuleAddCommand from .guiRemoveModule import GuiModuleRemoveCommand from .guiAddCharge import GuiModuleAddChargeCommand +from .guiFillWithModule import GuiFillWithModuleCommand from .guiSwapCloneModule import GuiModuleSwapOrCloneCommand from .guiRemoveCargo import GuiRemoveCargoCommand from .guiAddCargo import GuiAddCargoCommand diff --git a/gui/fitCommands/guiFillWithModule.py b/gui/fitCommands/guiFillWithModule.py new file mode 100644 index 000000000..0fa962bef --- /dev/null +++ b/gui/fitCommands/guiFillWithModule.py @@ -0,0 +1,50 @@ +import wx +import gui.mainFrame +from gui import globalEvents as GE +from .calc.fitAddModule import FitAddModuleCommand +from service.fit import Fit +from logbook import Logger +pyfalog = Logger(__name__) + + +class GuiFillWithModuleCommand(wx.Command): + def __init__(self, fitID, itemID, position=None): + """ + Handles adding an item, usually a module, to the Fitting Window. + + :param fitID: The fit ID that we are modifying + :param itemID: The item that is to be added to the Fitting View. If this turns out to be a charge, we attempt to + set the charge on the underlying module (requires position) + :param position: Optional. The position in fit.modules that we are attempting to set the item to + """ + wx.Command.__init__(self, True, "Module Add: {}".format(itemID)) + self.mainFrame = gui.mainFrame.MainFrame.getInstance() + self.sFit = Fit.getInstance() + self.fitID = fitID + self.itemID = itemID + self.internal_history = wx.CommandProcessor() + self.position = position + self.old_mod = None + + def Do(self): + pyfalog.debug("{} Do()".format(self)) + pyfalog.debug("Trying to append a module") + added_modules = 0 + success = self.internal_history.Submit(FitAddModuleCommand(self.fitID, self.itemID)) + while (success): + added_modules += 1 + success = self.internal_history.Submit(FitAddModuleCommand(self.fitID, self.itemID)) + + if added_modules > 0: + self.sFit.recalc(self.fitID) + wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.fitID, action="modadd", typeID=self.itemID)) + return True + return False + + def Undo(self): + pyfalog.debug("{} Undo()".format(self)) + for _ in self.internal_history.Commands: + self.internal_history.Undo() + self.sFit.recalc(self.fitID) + wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.fitID, action="moddel", typeID=self.itemID)) + return True diff --git a/gui/itemStats.py b/gui/itemStats.py index 3768780e2..8ff858402 100644 --- a/gui/itemStats.py +++ b/gui/itemStats.py @@ -91,7 +91,7 @@ class ItemStatsDialog(wx.Dialog): self.SetMinSize((300, 200)) if "wxGTK" in wx.PlatformInfo: # GTK has huge tab widgets, give it a bit more room - self.SetSize((580, 500)) + self.SetSize((640, 620)) else: self.SetSize((550, 500)) # self.SetMaxSize((500, -1)) @@ -168,8 +168,9 @@ class ItemStatsContainer(wx.Panel): self.mutator = ItemMutator(self.nbContainer, stuff, item) self.nbContainer.AddPage(self.mutator, "Mutations") - self.desc = ItemDescription(self.nbContainer, stuff, item) - self.nbContainer.AddPage(self.desc, "Description") + if item.description: + self.desc = ItemDescription(self.nbContainer, stuff, item) + self.nbContainer.AddPage(self.desc, "Description") self.params = ItemParams(self.nbContainer, stuff, item, context) self.nbContainer.AddPage(self.params, "Attributes") diff --git a/gui/mainFrame.py b/gui/mainFrame.py index 5f3aa6441..d5bc8f0e9 100644 --- a/gui/mainFrame.py +++ b/gui/mainFrame.py @@ -703,10 +703,6 @@ class MainFrame(wx.Frame): fit = db_getFit(self.getActiveFit()) toClipboard(Port.exportEft(fit, options)) - def clipboardEftImps(self, options): - fit = db_getFit(self.getActiveFit()) - toClipboard(Port.exportEftImps(fit)) - def clipboardDna(self, options): fit = db_getFit(self.getActiveFit()) toClipboard(Port.exportDna(fit)) @@ -721,7 +717,7 @@ class MainFrame(wx.Frame): def clipboardMultiBuy(self, options): fit = db_getFit(self.getActiveFit()) - toClipboard(Port.exportMultiBuy(fit)) + toClipboard(Port.exportMultiBuy(fit, options)) def clipboardEfs(self, options): fit = db_getFit(self.getActiveFit()) @@ -744,22 +740,22 @@ class MainFrame(wx.Frame): def exportToClipboard(self, event): CopySelectDict = {CopySelectDialog.copyFormatEft: self.clipboardEft, - # CopySelectDialog.copyFormatEftImps: self.clipboardEftImps, CopySelectDialog.copyFormatXml: self.clipboardXml, CopySelectDialog.copyFormatDna: self.clipboardDna, CopySelectDialog.copyFormatEsi: self.clipboardEsi, CopySelectDialog.copyFormatMultiBuy: self.clipboardMultiBuy, CopySelectDialog.copyFormatEfs: self.clipboardEfs} dlg = CopySelectDialog(self) - dlg.ShowModal() - selected = dlg.GetSelected() - options = dlg.GetOptions() + btnPressed = dlg.ShowModal() - settings = SettingsProvider.getInstance().getSettings("pyfaExport") - settings["format"] = selected - settings["options"] = options + if btnPressed == wx.ID_OK: + selected = dlg.GetSelected() + options = dlg.GetOptions() - CopySelectDict[selected](options) + settings = SettingsProvider.getInstance().getSettings("pyfaExport") + settings["format"] = selected + settings["options"] = options + CopySelectDict[selected](options.get(selected)) try: dlg.Destroy() diff --git a/gui/utils/helpers_wxPython.py b/gui/utils/helpers_wxPython.py index e0f9d0ae0..26f98c35d 100644 --- a/gui/utils/helpers_wxPython.py +++ b/gui/utils/helpers_wxPython.py @@ -6,3 +6,23 @@ def YesNoDialog(question='Are you sure you want to do this?', caption='Yes or no result = dlg.ShowModal() == wx.ID_YES dlg.Destroy() return result + + +def HandleCtrlBackspace(textControl): + """ + Handles the behavior of Windows ctrl+space + deletes everything from the cursor to the left, + up to the next whitespace. + """ + curPos = textControl.GetInsertionPoint() + searchText = textControl.GetValue() + foundChar = False + for startIndex in range(curPos, -1, -1): + if startIndex - 1 < 0: + break + if searchText[startIndex - 1] != " ": + foundChar = True + elif foundChar: + break + textControl.Remove(startIndex, curPos) + textControl.SetInsertionPoint(startIndex) \ No newline at end of file diff --git a/imgs/icons/10012@2x.png b/imgs/icons/10012@2x.png index f87955112..721ee9cb1 100644 Binary files a/imgs/icons/10012@2x.png and b/imgs/icons/10012@2x.png differ diff --git a/imgs/icons/10013@2x.png b/imgs/icons/10013@2x.png index efab8c095..75699a504 100644 Binary files a/imgs/icons/10013@2x.png and b/imgs/icons/10013@2x.png differ diff --git a/imgs/icons/10016@2x.png b/imgs/icons/10016@2x.png index 53ac9a1e2..c60c36a60 100644 Binary files a/imgs/icons/10016@2x.png and b/imgs/icons/10016@2x.png differ diff --git a/imgs/icons/10017@2x.png b/imgs/icons/10017@2x.png index d88abfa3e..d2022dc6e 100644 Binary files a/imgs/icons/10017@2x.png and b/imgs/icons/10017@2x.png differ diff --git a/imgs/icons/10018@2x.png b/imgs/icons/10018@2x.png index 2c3588107..288b6cb0d 100644 Binary files a/imgs/icons/10018@2x.png and b/imgs/icons/10018@2x.png differ diff --git a/imgs/icons/10019@2x.png b/imgs/icons/10019@2x.png index 8288bda1f..ce8eaec74 100644 Binary files a/imgs/icons/10019@2x.png and b/imgs/icons/10019@2x.png differ diff --git a/imgs/icons/10020@1x.png b/imgs/icons/10020@1x.png index 325cc1ce5..7499f52f5 100644 Binary files a/imgs/icons/10020@1x.png and b/imgs/icons/10020@1x.png differ diff --git a/imgs/icons/10022@2x.png b/imgs/icons/10022@2x.png index a9809aaee..477f51e83 100644 Binary files a/imgs/icons/10022@2x.png and b/imgs/icons/10022@2x.png differ diff --git a/imgs/icons/10023@2x.png b/imgs/icons/10023@2x.png index 7fea2c526..b06dcbda4 100644 Binary files a/imgs/icons/10023@2x.png and b/imgs/icons/10023@2x.png differ diff --git a/imgs/icons/10025@2x.png b/imgs/icons/10025@2x.png index cb6d4c1f6..63a6f5404 100644 Binary files a/imgs/icons/10025@2x.png and b/imgs/icons/10025@2x.png differ diff --git a/imgs/icons/10026@2x.png b/imgs/icons/10026@2x.png index 7219c8dfa..b198a6163 100644 Binary files a/imgs/icons/10026@2x.png and b/imgs/icons/10026@2x.png differ diff --git a/imgs/icons/10027@2x.png b/imgs/icons/10027@2x.png index 788ccaec7..60c902f19 100644 Binary files a/imgs/icons/10027@2x.png and b/imgs/icons/10027@2x.png differ diff --git a/imgs/icons/10028@2x.png b/imgs/icons/10028@2x.png index 5a80979df..85b5267a9 100644 Binary files a/imgs/icons/10028@2x.png and b/imgs/icons/10028@2x.png differ diff --git a/imgs/icons/10029@1x.png b/imgs/icons/10029@1x.png index bbd67d9e9..7bd37c34b 100644 Binary files a/imgs/icons/10029@1x.png and b/imgs/icons/10029@1x.png differ diff --git a/imgs/icons/10029@2x.png b/imgs/icons/10029@2x.png index 8c50be9c6..9e17b9828 100644 Binary files a/imgs/icons/10029@2x.png and b/imgs/icons/10029@2x.png differ diff --git a/imgs/icons/10030@2x.png b/imgs/icons/10030@2x.png index 2ffa1b48d..f68113918 100644 Binary files a/imgs/icons/10030@2x.png and b/imgs/icons/10030@2x.png differ diff --git a/imgs/icons/10032@2x.png b/imgs/icons/10032@2x.png index ae05da7c9..581058dc9 100644 Binary files a/imgs/icons/10032@2x.png and b/imgs/icons/10032@2x.png differ diff --git a/imgs/icons/10033@2x.png b/imgs/icons/10033@2x.png index 052315bdd..03c90053b 100644 Binary files a/imgs/icons/10033@2x.png and b/imgs/icons/10033@2x.png differ diff --git a/imgs/icons/10034@2x.png b/imgs/icons/10034@2x.png index d053cfc5b..6fc3be5c9 100644 Binary files a/imgs/icons/10034@2x.png and b/imgs/icons/10034@2x.png differ diff --git a/imgs/icons/10035@2x.png b/imgs/icons/10035@2x.png index 406c44606..d6246c913 100644 Binary files a/imgs/icons/10035@2x.png and b/imgs/icons/10035@2x.png differ diff --git a/imgs/icons/10036@2x.png b/imgs/icons/10036@2x.png index cd840257f..7188e88a9 100644 Binary files a/imgs/icons/10036@2x.png and b/imgs/icons/10036@2x.png differ diff --git a/imgs/icons/10037@2x.png b/imgs/icons/10037@2x.png index f951be26f..0469528c2 100644 Binary files a/imgs/icons/10037@2x.png and b/imgs/icons/10037@2x.png differ diff --git a/imgs/icons/10038@2x.png b/imgs/icons/10038@2x.png index 5fdf380b9..9ac2d123f 100644 Binary files a/imgs/icons/10038@2x.png and b/imgs/icons/10038@2x.png differ diff --git a/imgs/icons/10039@2x.png b/imgs/icons/10039@2x.png index 5ddbeea04..56c0a169b 100644 Binary files a/imgs/icons/10039@2x.png and b/imgs/icons/10039@2x.png differ diff --git a/imgs/icons/10040@2x.png b/imgs/icons/10040@2x.png index a7ab3312c..2b456ebf7 100644 Binary files a/imgs/icons/10040@2x.png and b/imgs/icons/10040@2x.png differ diff --git a/imgs/icons/10041@2x.png b/imgs/icons/10041@2x.png index cb422d4dd..ff5f8ab4d 100644 Binary files a/imgs/icons/10041@2x.png and b/imgs/icons/10041@2x.png differ diff --git a/imgs/icons/10042@2x.png b/imgs/icons/10042@2x.png index 3703a9b1f..f8bca67dd 100644 Binary files a/imgs/icons/10042@2x.png and b/imgs/icons/10042@2x.png differ diff --git a/imgs/icons/10043@2x.png b/imgs/icons/10043@2x.png index 10ae26959..d3be5727b 100644 Binary files a/imgs/icons/10043@2x.png and b/imgs/icons/10043@2x.png differ diff --git a/imgs/icons/10044@2x.png b/imgs/icons/10044@2x.png index ed6313db5..7a880336a 100644 Binary files a/imgs/icons/10044@2x.png and b/imgs/icons/10044@2x.png differ diff --git a/imgs/icons/10045@2x.png b/imgs/icons/10045@2x.png index f18f9ee8a..1b2fb033f 100644 Binary files a/imgs/icons/10045@2x.png and b/imgs/icons/10045@2x.png differ diff --git a/imgs/icons/10046@2x.png b/imgs/icons/10046@2x.png index 0ba8b58ec..1d7600133 100644 Binary files a/imgs/icons/10046@2x.png and b/imgs/icons/10046@2x.png differ diff --git a/imgs/icons/10048@2x.png b/imgs/icons/10048@2x.png index f59ad4dc3..113dae1bd 100644 Binary files a/imgs/icons/10048@2x.png and b/imgs/icons/10048@2x.png differ diff --git a/imgs/icons/1004@2x.png b/imgs/icons/1004@2x.png index bf71d6bb0..715add0c8 100644 Binary files a/imgs/icons/1004@2x.png and b/imgs/icons/1004@2x.png differ diff --git a/imgs/icons/10050@2x.png b/imgs/icons/10050@2x.png index e4614e18d..2bda994d6 100644 Binary files a/imgs/icons/10050@2x.png and b/imgs/icons/10050@2x.png differ diff --git a/imgs/icons/10051@2x.png b/imgs/icons/10051@2x.png index 377ad189c..8d89b070b 100644 Binary files a/imgs/icons/10051@2x.png and b/imgs/icons/10051@2x.png differ diff --git a/imgs/icons/10052@2x.png b/imgs/icons/10052@2x.png index 86487825b..209e11232 100644 Binary files a/imgs/icons/10052@2x.png and b/imgs/icons/10052@2x.png differ diff --git a/imgs/icons/10054@2x.png b/imgs/icons/10054@2x.png index 9078bb17f..a3fe2db4c 100644 Binary files a/imgs/icons/10054@2x.png and b/imgs/icons/10054@2x.png differ diff --git a/imgs/icons/10055@2x.png b/imgs/icons/10055@2x.png index c2de9a541..8c79a591c 100644 Binary files a/imgs/icons/10055@2x.png and b/imgs/icons/10055@2x.png differ diff --git a/imgs/icons/10056@2x.png b/imgs/icons/10056@2x.png index c57352686..003b1c872 100644 Binary files a/imgs/icons/10056@2x.png and b/imgs/icons/10056@2x.png differ diff --git a/imgs/icons/10057@2x.png b/imgs/icons/10057@2x.png index 5e309e529..5ee0ecfbe 100644 Binary files a/imgs/icons/10057@2x.png and b/imgs/icons/10057@2x.png differ diff --git a/imgs/icons/10058@2x.png b/imgs/icons/10058@2x.png index f82c3e819..aa913c383 100644 Binary files a/imgs/icons/10058@2x.png and b/imgs/icons/10058@2x.png differ diff --git a/imgs/icons/10071@2x.png b/imgs/icons/10071@2x.png index 8606a89df..6a2b6215a 100644 Binary files a/imgs/icons/10071@2x.png and b/imgs/icons/10071@2x.png differ diff --git a/imgs/icons/10073@2x.png b/imgs/icons/10073@2x.png index 123d96c43..ce26fbf05 100644 Binary files a/imgs/icons/10073@2x.png and b/imgs/icons/10073@2x.png differ diff --git a/imgs/icons/10074@2x.png b/imgs/icons/10074@2x.png index d8061ccc0..9dd62f577 100644 Binary files a/imgs/icons/10074@2x.png and b/imgs/icons/10074@2x.png differ diff --git a/imgs/icons/10075@2x.png b/imgs/icons/10075@2x.png index ab9e16a31..5967d56c6 100644 Binary files a/imgs/icons/10075@2x.png and b/imgs/icons/10075@2x.png differ diff --git a/imgs/icons/10076@2x.png b/imgs/icons/10076@2x.png index fc0f8dd6e..450f27dd1 100644 Binary files a/imgs/icons/10076@2x.png and b/imgs/icons/10076@2x.png differ diff --git a/imgs/icons/10078@2x.png b/imgs/icons/10078@2x.png index 80822300e..b0378e862 100644 Binary files a/imgs/icons/10078@2x.png and b/imgs/icons/10078@2x.png differ diff --git a/imgs/icons/10079@2x.png b/imgs/icons/10079@2x.png index c1faf7622..5715fddb5 100644 Binary files a/imgs/icons/10079@2x.png and b/imgs/icons/10079@2x.png differ diff --git a/imgs/icons/10132@2x.png b/imgs/icons/10132@2x.png index 48c23f3a8..bbf384b68 100644 Binary files a/imgs/icons/10132@2x.png and b/imgs/icons/10132@2x.png differ diff --git a/imgs/icons/10144@2x.png b/imgs/icons/10144@2x.png index c8b2351a7..d8654ddc5 100644 Binary files a/imgs/icons/10144@2x.png and b/imgs/icons/10144@2x.png differ diff --git a/imgs/icons/10149@2x.png b/imgs/icons/10149@2x.png index 01607d5b5..5e485d56a 100644 Binary files a/imgs/icons/10149@2x.png and b/imgs/icons/10149@2x.png differ diff --git a/imgs/icons/10151@2x.png b/imgs/icons/10151@2x.png index dccddee0c..dcf4caa42 100644 Binary files a/imgs/icons/10151@2x.png and b/imgs/icons/10151@2x.png differ diff --git a/imgs/icons/10153@2x.png b/imgs/icons/10153@2x.png index 233b4a976..a2eeca8d7 100644 Binary files a/imgs/icons/10153@2x.png and b/imgs/icons/10153@2x.png differ diff --git a/imgs/icons/10158@2x.png b/imgs/icons/10158@2x.png index 5ec6c6d05..98023a8f3 100644 Binary files a/imgs/icons/10158@2x.png and b/imgs/icons/10158@2x.png differ diff --git a/imgs/icons/10159@2x.png b/imgs/icons/10159@2x.png index 48bab70c3..63503a11e 100644 Binary files a/imgs/icons/10159@2x.png and b/imgs/icons/10159@2x.png differ diff --git a/imgs/icons/10160@2x.png b/imgs/icons/10160@2x.png index 1d17b0fbf..9015ae817 100644 Binary files a/imgs/icons/10160@2x.png and b/imgs/icons/10160@2x.png differ diff --git a/imgs/icons/10162@2x.png b/imgs/icons/10162@2x.png index 2b6642e02..bae1f62f4 100644 Binary files a/imgs/icons/10162@2x.png and b/imgs/icons/10162@2x.png differ diff --git a/imgs/icons/10176@2x.png b/imgs/icons/10176@2x.png index b22ab99e0..ac722b5d8 100644 Binary files a/imgs/icons/10176@2x.png and b/imgs/icons/10176@2x.png differ diff --git a/imgs/icons/10190@2x.png b/imgs/icons/10190@2x.png index 2dcf1fc50..8cc51ead1 100644 Binary files a/imgs/icons/10190@2x.png and b/imgs/icons/10190@2x.png differ diff --git a/imgs/icons/10224@1x.png b/imgs/icons/10224@1x.png index bd315f777..63ae53aa3 100644 Binary files a/imgs/icons/10224@1x.png and b/imgs/icons/10224@1x.png differ diff --git a/imgs/icons/10224@2x.png b/imgs/icons/10224@2x.png index f505693b8..c2cca1a61 100644 Binary files a/imgs/icons/10224@2x.png and b/imgs/icons/10224@2x.png differ diff --git a/imgs/icons/10236@2x.png b/imgs/icons/10236@2x.png index b5d0e8b53..033459ea8 100644 Binary files a/imgs/icons/10236@2x.png and b/imgs/icons/10236@2x.png differ diff --git a/imgs/icons/10254@2x.png b/imgs/icons/10254@2x.png index 43c937518..f4fedaadd 100644 Binary files a/imgs/icons/10254@2x.png and b/imgs/icons/10254@2x.png differ diff --git a/imgs/icons/1029@2x.png b/imgs/icons/1029@2x.png index 82490f6dc..7924fc420 100644 Binary files a/imgs/icons/1029@2x.png and b/imgs/icons/1029@2x.png differ diff --git a/imgs/icons/1030@2x.png b/imgs/icons/1030@2x.png index 45df201fa..a2113a395 100644 Binary files a/imgs/icons/1030@2x.png and b/imgs/icons/1030@2x.png differ diff --git a/imgs/icons/1031@2x.png b/imgs/icons/1031@2x.png index 11b72bc59..23266648f 100644 Binary files a/imgs/icons/1031@2x.png and b/imgs/icons/1031@2x.png differ diff --git a/imgs/icons/1033@2x.png b/imgs/icons/1033@2x.png index 394c5e204..77b57c6ff 100644 Binary files a/imgs/icons/1033@2x.png and b/imgs/icons/1033@2x.png differ diff --git a/imgs/icons/1035@2x.png b/imgs/icons/1035@2x.png index d09ad69ce..21dd6674a 100644 Binary files a/imgs/icons/1035@2x.png and b/imgs/icons/1035@2x.png differ diff --git a/imgs/icons/1041@2x.png b/imgs/icons/1041@2x.png index 7b10108a6..698e93ebd 100644 Binary files a/imgs/icons/1041@2x.png and b/imgs/icons/1041@2x.png differ diff --git a/imgs/icons/1042@2x.png b/imgs/icons/1042@2x.png index 693604f3d..85d000660 100644 Binary files a/imgs/icons/1042@2x.png and b/imgs/icons/1042@2x.png differ diff --git a/imgs/icons/1044@2x.png b/imgs/icons/1044@2x.png index d0bdf62ed..8f7f4e422 100644 Binary files a/imgs/icons/1044@2x.png and b/imgs/icons/1044@2x.png differ diff --git a/imgs/icons/1046@2x.png b/imgs/icons/1046@2x.png index 54bb5e0a0..aeb931143 100644 Binary files a/imgs/icons/1046@2x.png and b/imgs/icons/1046@2x.png differ diff --git a/imgs/icons/1047@2x.png b/imgs/icons/1047@2x.png index a4a627745..4fb9c71e7 100644 Binary files a/imgs/icons/1047@2x.png and b/imgs/icons/1047@2x.png differ diff --git a/imgs/icons/1061@2x.png b/imgs/icons/1061@2x.png index 0df1fd5c3..10dd7ba79 100644 Binary files a/imgs/icons/1061@2x.png and b/imgs/icons/1061@2x.png differ diff --git a/imgs/icons/10624@2x.png b/imgs/icons/10624@2x.png index feea425d3..21042a04e 100644 Binary files a/imgs/icons/10624@2x.png and b/imgs/icons/10624@2x.png differ diff --git a/imgs/icons/10684@2x.png b/imgs/icons/10684@2x.png index 567befe3b..cdeb183fc 100644 Binary files a/imgs/icons/10684@2x.png and b/imgs/icons/10684@2x.png differ diff --git a/imgs/icons/106@2x.png b/imgs/icons/106@2x.png index 94a9c466e..b95bf479e 100644 Binary files a/imgs/icons/106@2x.png and b/imgs/icons/106@2x.png differ diff --git a/imgs/icons/10785@2x.png b/imgs/icons/10785@2x.png index e02fdef34..e372d9a1c 100644 Binary files a/imgs/icons/10785@2x.png and b/imgs/icons/10785@2x.png differ diff --git a/imgs/icons/107@2x.png b/imgs/icons/107@2x.png index 892d8b467..5d69cffc9 100644 Binary files a/imgs/icons/107@2x.png and b/imgs/icons/107@2x.png differ diff --git a/imgs/icons/10830@1x.png b/imgs/icons/10830@1x.png index 9f00e1b01..13c01959b 100644 Binary files a/imgs/icons/10830@1x.png and b/imgs/icons/10830@1x.png differ diff --git a/imgs/icons/10831@2x.png b/imgs/icons/10831@2x.png index 4f0bafd83..4d1b052a2 100644 Binary files a/imgs/icons/10831@2x.png and b/imgs/icons/10831@2x.png differ diff --git a/imgs/icons/10833@1x.png b/imgs/icons/10833@1x.png index 64c92ed61..e709ba318 100644 Binary files a/imgs/icons/10833@1x.png and b/imgs/icons/10833@1x.png differ diff --git a/imgs/icons/10833@2x.png b/imgs/icons/10833@2x.png index 823d02804..273c6fc81 100644 Binary files a/imgs/icons/10833@2x.png and b/imgs/icons/10833@2x.png differ diff --git a/imgs/icons/10834@2x.png b/imgs/icons/10834@2x.png index 50f632abd..00c186d68 100644 Binary files a/imgs/icons/10834@2x.png and b/imgs/icons/10834@2x.png differ diff --git a/imgs/icons/10835@2x.png b/imgs/icons/10835@2x.png index 9b5597915..85f98d888 100644 Binary files a/imgs/icons/10835@2x.png and b/imgs/icons/10835@2x.png differ diff --git a/imgs/icons/10836@2x.png b/imgs/icons/10836@2x.png index 6061b4508..9bb8d0470 100644 Binary files a/imgs/icons/10836@2x.png and b/imgs/icons/10836@2x.png differ diff --git a/imgs/icons/10886@2x.png b/imgs/icons/10886@2x.png index 72b667cce..1add3054c 100644 Binary files a/imgs/icons/10886@2x.png and b/imgs/icons/10886@2x.png differ diff --git a/imgs/icons/10887@2x.png b/imgs/icons/10887@2x.png index 8a85f1071..d82b04a84 100644 Binary files a/imgs/icons/10887@2x.png and b/imgs/icons/10887@2x.png differ diff --git a/imgs/icons/10934@2x.png b/imgs/icons/10934@2x.png index 0bef34277..2f11750fc 100644 Binary files a/imgs/icons/10934@2x.png and b/imgs/icons/10934@2x.png differ diff --git a/imgs/icons/10935@1x.png b/imgs/icons/10935@1x.png index 175ff15a9..c8d762e86 100644 Binary files a/imgs/icons/10935@1x.png and b/imgs/icons/10935@1x.png differ diff --git a/imgs/icons/10935@2x.png b/imgs/icons/10935@2x.png index 1f4d24bc3..78bcc68ae 100644 Binary files a/imgs/icons/10935@2x.png and b/imgs/icons/10935@2x.png differ diff --git a/imgs/icons/10940@2x.png b/imgs/icons/10940@2x.png index fc3137d3b..094f10a46 100644 Binary files a/imgs/icons/10940@2x.png and b/imgs/icons/10940@2x.png differ diff --git a/imgs/icons/10941@2x.png b/imgs/icons/10941@2x.png index e2bcf1df2..ca0eb9cb3 100644 Binary files a/imgs/icons/10941@2x.png and b/imgs/icons/10941@2x.png differ diff --git a/imgs/icons/10942@2x.png b/imgs/icons/10942@2x.png index 1f8733a78..105b9e06f 100644 Binary files a/imgs/icons/10942@2x.png and b/imgs/icons/10942@2x.png differ diff --git a/imgs/icons/110@2x.png b/imgs/icons/110@2x.png index 9c90f9128..d6a5695fa 100644 Binary files a/imgs/icons/110@2x.png and b/imgs/icons/110@2x.png differ diff --git a/imgs/icons/111@2x.png b/imgs/icons/111@2x.png index 355b63507..9cc5a23a8 100644 Binary files a/imgs/icons/111@2x.png and b/imgs/icons/111@2x.png differ diff --git a/imgs/icons/1131@1x.png b/imgs/icons/1131@1x.png index 0c658a338..b6ef372c6 100644 Binary files a/imgs/icons/1131@1x.png and b/imgs/icons/1131@1x.png differ diff --git a/imgs/icons/1131@2x.png b/imgs/icons/1131@2x.png index 32cb5dc38..4ed97605c 100644 Binary files a/imgs/icons/1131@2x.png and b/imgs/icons/1131@2x.png differ diff --git a/imgs/icons/1139@1x.png b/imgs/icons/1139@1x.png index 3be2655ea..8570ae9f5 100644 Binary files a/imgs/icons/1139@1x.png and b/imgs/icons/1139@1x.png differ diff --git a/imgs/icons/1139@2x.png b/imgs/icons/1139@2x.png index 890016224..77e3855c0 100644 Binary files a/imgs/icons/1139@2x.png and b/imgs/icons/1139@2x.png differ diff --git a/imgs/icons/1140@1x.png b/imgs/icons/1140@1x.png index 4c4aec39b..459c82619 100644 Binary files a/imgs/icons/1140@1x.png and b/imgs/icons/1140@1x.png differ diff --git a/imgs/icons/1140@2x.png b/imgs/icons/1140@2x.png index 7bc202695..4b55493d2 100644 Binary files a/imgs/icons/1140@2x.png and b/imgs/icons/1140@2x.png differ diff --git a/imgs/icons/1141@1x.png b/imgs/icons/1141@1x.png index 037a12b48..599eda4d1 100644 Binary files a/imgs/icons/1141@1x.png and b/imgs/icons/1141@1x.png differ diff --git a/imgs/icons/1141@2x.png b/imgs/icons/1141@2x.png index 8c595f0ba..2ef9c337f 100644 Binary files a/imgs/icons/1141@2x.png and b/imgs/icons/1141@2x.png differ diff --git a/imgs/icons/1142@1x.png b/imgs/icons/1142@1x.png index 72850a7e0..200954655 100644 Binary files a/imgs/icons/1142@1x.png and b/imgs/icons/1142@1x.png differ diff --git a/imgs/icons/1142@2x.png b/imgs/icons/1142@2x.png index cf3db5ea5..02583b0be 100644 Binary files a/imgs/icons/1142@2x.png and b/imgs/icons/1142@2x.png differ diff --git a/imgs/icons/1143@1x.png b/imgs/icons/1143@1x.png index 68cf5dbda..db9adc7e5 100644 Binary files a/imgs/icons/1143@1x.png and b/imgs/icons/1143@1x.png differ diff --git a/imgs/icons/1143@2x.png b/imgs/icons/1143@2x.png index a21543a6c..65f770eda 100644 Binary files a/imgs/icons/1143@2x.png and b/imgs/icons/1143@2x.png differ diff --git a/imgs/icons/1144@1x.png b/imgs/icons/1144@1x.png index 8f51f5641..6fb5cde5d 100644 Binary files a/imgs/icons/1144@1x.png and b/imgs/icons/1144@1x.png differ diff --git a/imgs/icons/1144@2x.png b/imgs/icons/1144@2x.png index 25526f64e..e29512122 100644 Binary files a/imgs/icons/1144@2x.png and b/imgs/icons/1144@2x.png differ diff --git a/imgs/icons/1145@2x.png b/imgs/icons/1145@2x.png index f4b1d236c..ef3914b0b 100644 Binary files a/imgs/icons/1145@2x.png and b/imgs/icons/1145@2x.png differ diff --git a/imgs/icons/1159@2x.png b/imgs/icons/1159@2x.png index d5a7e92c3..f1a8897bc 100644 Binary files a/imgs/icons/1159@2x.png and b/imgs/icons/1159@2x.png differ diff --git a/imgs/icons/1162@1x.png b/imgs/icons/1162@1x.png index ed4e2b79a..e3cac8243 100644 Binary files a/imgs/icons/1162@1x.png and b/imgs/icons/1162@1x.png differ diff --git a/imgs/icons/1162@2x.png b/imgs/icons/1162@2x.png index 2fd5b0f6c..4bb919558 100644 Binary files a/imgs/icons/1162@2x.png and b/imgs/icons/1162@2x.png differ diff --git a/imgs/icons/1164@2x.png b/imgs/icons/1164@2x.png index a5692f0aa..d1fe11eb4 100644 Binary files a/imgs/icons/1164@2x.png and b/imgs/icons/1164@2x.png differ diff --git a/imgs/icons/1171@2x.png b/imgs/icons/1171@2x.png index 9fe8d28eb..d7a1e4317 100644 Binary files a/imgs/icons/1171@2x.png and b/imgs/icons/1171@2x.png differ diff --git a/imgs/icons/1172@2x.png b/imgs/icons/1172@2x.png index 55e89efc2..b1db8b069 100644 Binary files a/imgs/icons/1172@2x.png and b/imgs/icons/1172@2x.png differ diff --git a/imgs/icons/1173@2x.png b/imgs/icons/1173@2x.png index fe14ab255..071e8427a 100644 Binary files a/imgs/icons/1173@2x.png and b/imgs/icons/1173@2x.png differ diff --git a/imgs/icons/1174@2x.png b/imgs/icons/1174@2x.png index dfeac172f..219c33955 100644 Binary files a/imgs/icons/1174@2x.png and b/imgs/icons/1174@2x.png differ diff --git a/imgs/icons/1175@2x.png b/imgs/icons/1175@2x.png index 211f69f3b..d886216c3 100644 Binary files a/imgs/icons/1175@2x.png and b/imgs/icons/1175@2x.png differ diff --git a/imgs/icons/1177@2x.png b/imgs/icons/1177@2x.png index 1478cfbc2..783e17600 100644 Binary files a/imgs/icons/1177@2x.png and b/imgs/icons/1177@2x.png differ diff --git a/imgs/icons/1178@2x.png b/imgs/icons/1178@2x.png index 6aa0ea717..617099797 100644 Binary files a/imgs/icons/1178@2x.png and b/imgs/icons/1178@2x.png differ diff --git a/imgs/icons/1179@2x.png b/imgs/icons/1179@2x.png index aa0c466e0..e4b20edf8 100644 Binary files a/imgs/icons/1179@2x.png and b/imgs/icons/1179@2x.png differ diff --git a/imgs/icons/1180@2x.png b/imgs/icons/1180@2x.png index 2c1034b7e..faae6e55d 100644 Binary files a/imgs/icons/1180@2x.png and b/imgs/icons/1180@2x.png differ diff --git a/imgs/icons/1181@2x.png b/imgs/icons/1181@2x.png index 482d69bc3..03b4f3fae 100644 Binary files a/imgs/icons/1181@2x.png and b/imgs/icons/1181@2x.png differ diff --git a/imgs/icons/1183@2x.png b/imgs/icons/1183@2x.png index 68ec06f78..4886967d5 100644 Binary files a/imgs/icons/1183@2x.png and b/imgs/icons/1183@2x.png differ diff --git a/imgs/icons/1184@2x.png b/imgs/icons/1184@2x.png index 42e732096..3c08ff427 100644 Binary files a/imgs/icons/1184@2x.png and b/imgs/icons/1184@2x.png differ diff --git a/imgs/icons/1185@2x.png b/imgs/icons/1185@2x.png index f9fb04924..a65d1f55a 100644 Binary files a/imgs/icons/1185@2x.png and b/imgs/icons/1185@2x.png differ diff --git a/imgs/icons/1186@2x.png b/imgs/icons/1186@2x.png index cef1779e9..0dfec2761 100644 Binary files a/imgs/icons/1186@2x.png and b/imgs/icons/1186@2x.png differ diff --git a/imgs/icons/1187@2x.png b/imgs/icons/1187@2x.png index 3cec0b8b7..59687591a 100644 Binary files a/imgs/icons/1187@2x.png and b/imgs/icons/1187@2x.png differ diff --git a/imgs/icons/1188@2x.png b/imgs/icons/1188@2x.png index 70064bd35..9e3c113a8 100644 Binary files a/imgs/icons/1188@2x.png and b/imgs/icons/1188@2x.png differ diff --git a/imgs/icons/1189@2x.png b/imgs/icons/1189@2x.png index b27308bf2..37e58bc4d 100644 Binary files a/imgs/icons/1189@2x.png and b/imgs/icons/1189@2x.png differ diff --git a/imgs/icons/1192@2x.png b/imgs/icons/1192@2x.png index f3b2a12db..45b55c34e 100644 Binary files a/imgs/icons/1192@2x.png and b/imgs/icons/1192@2x.png differ diff --git a/imgs/icons/1194@2x.png b/imgs/icons/1194@2x.png index ef435726b..01cf12b60 100644 Binary files a/imgs/icons/1194@2x.png and b/imgs/icons/1194@2x.png differ diff --git a/imgs/icons/1195@2x.png b/imgs/icons/1195@2x.png index f481fac6d..8cb149580 100644 Binary files a/imgs/icons/1195@2x.png and b/imgs/icons/1195@2x.png differ diff --git a/imgs/icons/1196@2x.png b/imgs/icons/1196@2x.png index f34d738ca..84f7116ba 100644 Binary files a/imgs/icons/1196@2x.png and b/imgs/icons/1196@2x.png differ diff --git a/imgs/icons/1198@2x.png b/imgs/icons/1198@2x.png index 737c16126..eecc9a268 100644 Binary files a/imgs/icons/1198@2x.png and b/imgs/icons/1198@2x.png differ diff --git a/imgs/icons/1199@2x.png b/imgs/icons/1199@2x.png index 8ade0ff37..03f48bed9 100644 Binary files a/imgs/icons/1199@2x.png and b/imgs/icons/1199@2x.png differ diff --git a/imgs/icons/1205@2x.png b/imgs/icons/1205@2x.png index 218039020..1fef4010e 100644 Binary files a/imgs/icons/1205@2x.png and b/imgs/icons/1205@2x.png differ diff --git a/imgs/icons/1207@2x.png b/imgs/icons/1207@2x.png index 27c4443e5..b4b49f289 100644 Binary files a/imgs/icons/1207@2x.png and b/imgs/icons/1207@2x.png differ diff --git a/imgs/icons/1209@2x.png b/imgs/icons/1209@2x.png index 8968973cb..c2d4b5737 100644 Binary files a/imgs/icons/1209@2x.png and b/imgs/icons/1209@2x.png differ diff --git a/imgs/icons/1277@2x.png b/imgs/icons/1277@2x.png index 6629a3891..5113a4835 100644 Binary files a/imgs/icons/1277@2x.png and b/imgs/icons/1277@2x.png differ diff --git a/imgs/icons/1279@2x.png b/imgs/icons/1279@2x.png index 254ebc3a6..5fe65a111 100644 Binary files a/imgs/icons/1279@2x.png and b/imgs/icons/1279@2x.png differ diff --git a/imgs/icons/1284@2x.png b/imgs/icons/1284@2x.png index 4760bc115..73b964ae6 100644 Binary files a/imgs/icons/1284@2x.png and b/imgs/icons/1284@2x.png differ diff --git a/imgs/icons/1285@2x.png b/imgs/icons/1285@2x.png index a4e7729c5..1cc078652 100644 Binary files a/imgs/icons/1285@2x.png and b/imgs/icons/1285@2x.png differ diff --git a/imgs/icons/1286@2x.png b/imgs/icons/1286@2x.png index 440e4feca..944395ac2 100644 Binary files a/imgs/icons/1286@2x.png and b/imgs/icons/1286@2x.png differ diff --git a/imgs/icons/1287@2x.png b/imgs/icons/1287@2x.png index 7091e19d3..c2b61ae3e 100644 Binary files a/imgs/icons/1287@2x.png and b/imgs/icons/1287@2x.png differ diff --git a/imgs/icons/1288@2x.png b/imgs/icons/1288@2x.png index c461b50e3..5334ed4b9 100644 Binary files a/imgs/icons/1288@2x.png and b/imgs/icons/1288@2x.png differ diff --git a/imgs/icons/1289@2x.png b/imgs/icons/1289@2x.png index 4343dc591..64342baee 100644 Binary files a/imgs/icons/1289@2x.png and b/imgs/icons/1289@2x.png differ diff --git a/imgs/icons/1290@2x.png b/imgs/icons/1290@2x.png index 457788439..ef1d3b99e 100644 Binary files a/imgs/icons/1290@2x.png and b/imgs/icons/1290@2x.png differ diff --git a/imgs/icons/1291@2x.png b/imgs/icons/1291@2x.png index 564c1e94d..d2048ad2c 100644 Binary files a/imgs/icons/1291@2x.png and b/imgs/icons/1291@2x.png differ diff --git a/imgs/icons/1292@2x.png b/imgs/icons/1292@2x.png index 51fa71cf0..e7dd3e91f 100644 Binary files a/imgs/icons/1292@2x.png and b/imgs/icons/1292@2x.png differ diff --git a/imgs/icons/1293@2x.png b/imgs/icons/1293@2x.png index 187ce277d..9a0c9ac0e 100644 Binary files a/imgs/icons/1293@2x.png and b/imgs/icons/1293@2x.png differ diff --git a/imgs/icons/1294@2x.png b/imgs/icons/1294@2x.png index b5a09a336..804d8c06e 100644 Binary files a/imgs/icons/1294@2x.png and b/imgs/icons/1294@2x.png differ diff --git a/imgs/icons/1296@2x.png b/imgs/icons/1296@2x.png index 91683a7d9..5586763e8 100644 Binary files a/imgs/icons/1296@2x.png and b/imgs/icons/1296@2x.png differ diff --git a/imgs/icons/1297@2x.png b/imgs/icons/1297@2x.png index 246937371..dc2f8eea8 100644 Binary files a/imgs/icons/1297@2x.png and b/imgs/icons/1297@2x.png differ diff --git a/imgs/icons/1298@2x.png b/imgs/icons/1298@2x.png index 19deb5ea3..e672de35e 100644 Binary files a/imgs/icons/1298@2x.png and b/imgs/icons/1298@2x.png differ diff --git a/imgs/icons/1299@2x.png b/imgs/icons/1299@2x.png index 9fd27c6b7..abada960b 100644 Binary files a/imgs/icons/1299@2x.png and b/imgs/icons/1299@2x.png differ diff --git a/imgs/icons/1300@2x.png b/imgs/icons/1300@2x.png index f9ab8a108..96be31184 100644 Binary files a/imgs/icons/1300@2x.png and b/imgs/icons/1300@2x.png differ diff --git a/imgs/icons/1301@2x.png b/imgs/icons/1301@2x.png index 23259bc3a..ab9c934e4 100644 Binary files a/imgs/icons/1301@2x.png and b/imgs/icons/1301@2x.png differ diff --git a/imgs/icons/1302@2x.png b/imgs/icons/1302@2x.png index 2e77952df..c169fae05 100644 Binary files a/imgs/icons/1302@2x.png and b/imgs/icons/1302@2x.png differ diff --git a/imgs/icons/1304@2x.png b/imgs/icons/1304@2x.png index de023e234..c994f7b7b 100644 Binary files a/imgs/icons/1304@2x.png and b/imgs/icons/1304@2x.png differ diff --git a/imgs/icons/1305@2x.png b/imgs/icons/1305@2x.png index e598b4fab..a60f8baf5 100644 Binary files a/imgs/icons/1305@2x.png and b/imgs/icons/1305@2x.png differ diff --git a/imgs/icons/1306@2x.png b/imgs/icons/1306@2x.png index 009bd8594..fdbf0828d 100644 Binary files a/imgs/icons/1306@2x.png and b/imgs/icons/1306@2x.png differ diff --git a/imgs/icons/1307@2x.png b/imgs/icons/1307@2x.png index 2e02b93a8..1e96380b1 100644 Binary files a/imgs/icons/1307@2x.png and b/imgs/icons/1307@2x.png differ diff --git a/imgs/icons/1310@2x.png b/imgs/icons/1310@2x.png index 1967871c0..9127e2ccd 100644 Binary files a/imgs/icons/1310@2x.png and b/imgs/icons/1310@2x.png differ diff --git a/imgs/icons/1311@2x.png b/imgs/icons/1311@2x.png index c8a3b2fd9..96a04303d 100644 Binary files a/imgs/icons/1311@2x.png and b/imgs/icons/1311@2x.png differ diff --git a/imgs/icons/1312@2x.png b/imgs/icons/1312@2x.png index 82e42be47..12f03e2e2 100644 Binary files a/imgs/icons/1312@2x.png and b/imgs/icons/1312@2x.png differ diff --git a/imgs/icons/1313@2x.png b/imgs/icons/1313@2x.png index 64a4a9caa..5d6a63d4b 100644 Binary files a/imgs/icons/1313@2x.png and b/imgs/icons/1313@2x.png differ diff --git a/imgs/icons/1314@2x.png b/imgs/icons/1314@2x.png index f307579bb..c0f03b740 100644 Binary files a/imgs/icons/1314@2x.png and b/imgs/icons/1314@2x.png differ diff --git a/imgs/icons/1315@2x.png b/imgs/icons/1315@2x.png index afe1700db..63b1ed686 100644 Binary files a/imgs/icons/1315@2x.png and b/imgs/icons/1315@2x.png differ diff --git a/imgs/icons/1316@2x.png b/imgs/icons/1316@2x.png index c966fff00..b1963fe21 100644 Binary files a/imgs/icons/1316@2x.png and b/imgs/icons/1316@2x.png differ diff --git a/imgs/icons/1317@2x.png b/imgs/icons/1317@2x.png index bccab5976..a0909b072 100644 Binary files a/imgs/icons/1317@2x.png and b/imgs/icons/1317@2x.png differ diff --git a/imgs/icons/1318@2x.png b/imgs/icons/1318@2x.png index 9c0bdd1a1..b76a47016 100644 Binary files a/imgs/icons/1318@2x.png and b/imgs/icons/1318@2x.png differ diff --git a/imgs/icons/1319@2x.png b/imgs/icons/1319@2x.png index e5f2d7fb8..d770a71da 100644 Binary files a/imgs/icons/1319@2x.png and b/imgs/icons/1319@2x.png differ diff --git a/imgs/icons/1320@2x.png b/imgs/icons/1320@2x.png index cc17b072b..067f932e3 100644 Binary files a/imgs/icons/1320@2x.png and b/imgs/icons/1320@2x.png differ diff --git a/imgs/icons/1321@2x.png b/imgs/icons/1321@2x.png index a9c68783d..d75a64f35 100644 Binary files a/imgs/icons/1321@2x.png and b/imgs/icons/1321@2x.png differ diff --git a/imgs/icons/1322@2x.png b/imgs/icons/1322@2x.png index e96e1d965..2028a938a 100644 Binary files a/imgs/icons/1322@2x.png and b/imgs/icons/1322@2x.png differ diff --git a/imgs/icons/1323@2x.png b/imgs/icons/1323@2x.png index c551b7c2e..ccd79fb6f 100644 Binary files a/imgs/icons/1323@2x.png and b/imgs/icons/1323@2x.png differ diff --git a/imgs/icons/1324@2x.png b/imgs/icons/1324@2x.png index 746ed3b8f..ba6c78043 100644 Binary files a/imgs/icons/1324@2x.png and b/imgs/icons/1324@2x.png differ diff --git a/imgs/icons/1326@2x.png b/imgs/icons/1326@2x.png index 1f62c987b..7012cce0f 100644 Binary files a/imgs/icons/1326@2x.png and b/imgs/icons/1326@2x.png differ diff --git a/imgs/icons/1327@2x.png b/imgs/icons/1327@2x.png index 3aa5b755d..48be452e1 100644 Binary files a/imgs/icons/1327@2x.png and b/imgs/icons/1327@2x.png differ diff --git a/imgs/icons/1329@2x.png b/imgs/icons/1329@2x.png index 304caaae7..9efe1f846 100644 Binary files a/imgs/icons/1329@2x.png and b/imgs/icons/1329@2x.png differ diff --git a/imgs/icons/1331@2x.png b/imgs/icons/1331@2x.png index 3b46c0085..b5af2bd8c 100644 Binary files a/imgs/icons/1331@2x.png and b/imgs/icons/1331@2x.png differ diff --git a/imgs/icons/1332@2x.png b/imgs/icons/1332@2x.png index 9bc39cc13..5a1e7dc8d 100644 Binary files a/imgs/icons/1332@2x.png and b/imgs/icons/1332@2x.png differ diff --git a/imgs/icons/1333@2x.png b/imgs/icons/1333@2x.png index 25dbd3cb1..1e3a6fff6 100644 Binary files a/imgs/icons/1333@2x.png and b/imgs/icons/1333@2x.png differ diff --git a/imgs/icons/1334@2x.png b/imgs/icons/1334@2x.png index 2a6b1eec8..9917f0cfe 100644 Binary files a/imgs/icons/1334@2x.png and b/imgs/icons/1334@2x.png differ diff --git a/imgs/icons/1335@2x.png b/imgs/icons/1335@2x.png index 8169c4121..0c92e662b 100644 Binary files a/imgs/icons/1335@2x.png and b/imgs/icons/1335@2x.png differ diff --git a/imgs/icons/1336@2x.png b/imgs/icons/1336@2x.png index fae7f1971..1deb7291e 100644 Binary files a/imgs/icons/1336@2x.png and b/imgs/icons/1336@2x.png differ diff --git a/imgs/icons/1337@2x.png b/imgs/icons/1337@2x.png index 1097972bd..87cdf7130 100644 Binary files a/imgs/icons/1337@2x.png and b/imgs/icons/1337@2x.png differ diff --git a/imgs/icons/1338@2x.png b/imgs/icons/1338@2x.png index 0227e983f..c480c38de 100644 Binary files a/imgs/icons/1338@2x.png and b/imgs/icons/1338@2x.png differ diff --git a/imgs/icons/1339@2x.png b/imgs/icons/1339@2x.png index 363f925f0..08618c40f 100644 Binary files a/imgs/icons/1339@2x.png and b/imgs/icons/1339@2x.png differ diff --git a/imgs/icons/1340@1x.png b/imgs/icons/1340@1x.png index 04593a424..2ec769ab7 100644 Binary files a/imgs/icons/1340@1x.png and b/imgs/icons/1340@1x.png differ diff --git a/imgs/icons/1340@2x.png b/imgs/icons/1340@2x.png index a66950fbb..3721a278c 100644 Binary files a/imgs/icons/1340@2x.png and b/imgs/icons/1340@2x.png differ diff --git a/imgs/icons/1341@2x.png b/imgs/icons/1341@2x.png index afac0b02c..dd21776dd 100644 Binary files a/imgs/icons/1341@2x.png and b/imgs/icons/1341@2x.png differ diff --git a/imgs/icons/1342@2x.png b/imgs/icons/1342@2x.png index 9adc3059a..5d5a17389 100644 Binary files a/imgs/icons/1342@2x.png and b/imgs/icons/1342@2x.png differ diff --git a/imgs/icons/1343@2x.png b/imgs/icons/1343@2x.png index fa7698400..03e54a873 100644 Binary files a/imgs/icons/1343@2x.png and b/imgs/icons/1343@2x.png differ diff --git a/imgs/icons/1344@2x.png b/imgs/icons/1344@2x.png index b98e98eef..c3f9a0040 100644 Binary files a/imgs/icons/1344@2x.png and b/imgs/icons/1344@2x.png differ diff --git a/imgs/icons/1345@2x.png b/imgs/icons/1345@2x.png index 7020f688d..b477939d0 100644 Binary files a/imgs/icons/1345@2x.png and b/imgs/icons/1345@2x.png differ diff --git a/imgs/icons/1346@2x.png b/imgs/icons/1346@2x.png index f42467f19..2e0db50fe 100644 Binary files a/imgs/icons/1346@2x.png and b/imgs/icons/1346@2x.png differ diff --git a/imgs/icons/1347@2x.png b/imgs/icons/1347@2x.png index 2e01c3ed0..65acac2c2 100644 Binary files a/imgs/icons/1347@2x.png and b/imgs/icons/1347@2x.png differ diff --git a/imgs/icons/1348@2x.png b/imgs/icons/1348@2x.png index c6f2e5c1f..fbab0189e 100644 Binary files a/imgs/icons/1348@2x.png and b/imgs/icons/1348@2x.png differ diff --git a/imgs/icons/1349@2x.png b/imgs/icons/1349@2x.png index cbd354bfb..cea007766 100644 Binary files a/imgs/icons/1349@2x.png and b/imgs/icons/1349@2x.png differ diff --git a/imgs/icons/1350@2x.png b/imgs/icons/1350@2x.png index 1a3d3d067..1cb83d93a 100644 Binary files a/imgs/icons/1350@2x.png and b/imgs/icons/1350@2x.png differ diff --git a/imgs/icons/1352@2x.png b/imgs/icons/1352@2x.png index 94f6496bf..b60dafb4e 100644 Binary files a/imgs/icons/1352@2x.png and b/imgs/icons/1352@2x.png differ diff --git a/imgs/icons/1353@2x.png b/imgs/icons/1353@2x.png index 90f4599b1..7ac735c72 100644 Binary files a/imgs/icons/1353@2x.png and b/imgs/icons/1353@2x.png differ diff --git a/imgs/icons/1356@2x.png b/imgs/icons/1356@2x.png index ec6f5a426..3ef299827 100644 Binary files a/imgs/icons/1356@2x.png and b/imgs/icons/1356@2x.png differ diff --git a/imgs/icons/1357@2x.png b/imgs/icons/1357@2x.png index c843be241..f6b495b5f 100644 Binary files a/imgs/icons/1357@2x.png and b/imgs/icons/1357@2x.png differ diff --git a/imgs/icons/1361@2x.png b/imgs/icons/1361@2x.png index 0c7d711cd..56abe9282 100644 Binary files a/imgs/icons/1361@2x.png and b/imgs/icons/1361@2x.png differ diff --git a/imgs/icons/1362@2x.png b/imgs/icons/1362@2x.png index 3516b8e88..a259580fc 100644 Binary files a/imgs/icons/1362@2x.png and b/imgs/icons/1362@2x.png differ diff --git a/imgs/icons/1365@2x.png b/imgs/icons/1365@2x.png index fd34582ba..7948bfb1a 100644 Binary files a/imgs/icons/1365@2x.png and b/imgs/icons/1365@2x.png differ diff --git a/imgs/icons/1366@2x.png b/imgs/icons/1366@2x.png index 095226965..415ad5a99 100644 Binary files a/imgs/icons/1366@2x.png and b/imgs/icons/1366@2x.png differ diff --git a/imgs/icons/1368@2x.png b/imgs/icons/1368@2x.png index 9968ee00e..5b3dca702 100644 Binary files a/imgs/icons/1368@2x.png and b/imgs/icons/1368@2x.png differ diff --git a/imgs/icons/1369@2x.png b/imgs/icons/1369@2x.png index d493ed617..31bcbd260 100644 Binary files a/imgs/icons/1369@2x.png and b/imgs/icons/1369@2x.png differ diff --git a/imgs/icons/1370@2x.png b/imgs/icons/1370@2x.png index 900aff1c6..46fcfbedc 100644 Binary files a/imgs/icons/1370@2x.png and b/imgs/icons/1370@2x.png differ diff --git a/imgs/icons/1382@1x.png b/imgs/icons/1382@1x.png index 95b171173..7038fea4e 100644 Binary files a/imgs/icons/1382@1x.png and b/imgs/icons/1382@1x.png differ diff --git a/imgs/icons/1384@1x.png b/imgs/icons/1384@1x.png index 33d423310..809e9e63a 100644 Binary files a/imgs/icons/1384@1x.png and b/imgs/icons/1384@1x.png differ diff --git a/imgs/icons/1386@1x.png b/imgs/icons/1386@1x.png index a04a38ad9..71abeaca7 100644 Binary files a/imgs/icons/1386@1x.png and b/imgs/icons/1386@1x.png differ diff --git a/imgs/icons/1388@1x.png b/imgs/icons/1388@1x.png index f2872d162..c145b4462 100644 Binary files a/imgs/icons/1388@1x.png and b/imgs/icons/1388@1x.png differ diff --git a/imgs/icons/138@2x.png b/imgs/icons/138@2x.png index c2b6ec2e3..8884eda4f 100644 Binary files a/imgs/icons/138@2x.png and b/imgs/icons/138@2x.png differ diff --git a/imgs/icons/1390@1x.png b/imgs/icons/1390@1x.png index 723419683..54c0cd437 100644 Binary files a/imgs/icons/1390@1x.png and b/imgs/icons/1390@1x.png differ diff --git a/imgs/icons/1405@2x.png b/imgs/icons/1405@2x.png index cbcce5914..fd1908d94 100644 Binary files a/imgs/icons/1405@2x.png and b/imgs/icons/1405@2x.png differ diff --git a/imgs/icons/1406@2x.png b/imgs/icons/1406@2x.png index 271236871..b768b608c 100644 Binary files a/imgs/icons/1406@2x.png and b/imgs/icons/1406@2x.png differ diff --git a/imgs/icons/1435@2x.png b/imgs/icons/1435@2x.png index c059e83c1..6a3de531e 100644 Binary files a/imgs/icons/1435@2x.png and b/imgs/icons/1435@2x.png differ diff --git a/imgs/icons/1443@2x.png b/imgs/icons/1443@2x.png index 2727ec3ca..b53e63217 100644 Binary files a/imgs/icons/1443@2x.png and b/imgs/icons/1443@2x.png differ diff --git a/imgs/icons/1444@2x.png b/imgs/icons/1444@2x.png index 98be32ea0..87743e565 100644 Binary files a/imgs/icons/1444@2x.png and b/imgs/icons/1444@2x.png differ diff --git a/imgs/icons/1446@2x.png b/imgs/icons/1446@2x.png index 815f1bf8a..58d252f23 100644 Binary files a/imgs/icons/1446@2x.png and b/imgs/icons/1446@2x.png differ diff --git a/imgs/icons/15@2x.png b/imgs/icons/15@2x.png index 041ae66b0..0e675cb01 100644 Binary files a/imgs/icons/15@2x.png and b/imgs/icons/15@2x.png differ diff --git a/imgs/icons/1639@2x.png b/imgs/icons/1639@2x.png index 22feeb323..ff3b45e29 100644 Binary files a/imgs/icons/1639@2x.png and b/imgs/icons/1639@2x.png differ diff --git a/imgs/icons/1640@2x.png b/imgs/icons/1640@2x.png index 88c37b967..bf1a3f997 100644 Binary files a/imgs/icons/1640@2x.png and b/imgs/icons/1640@2x.png differ diff --git a/imgs/icons/1641@2x.png b/imgs/icons/1641@2x.png index dae55e8cc..ce9155496 100644 Binary files a/imgs/icons/1641@2x.png and b/imgs/icons/1641@2x.png differ diff --git a/imgs/icons/1645@2x.png b/imgs/icons/1645@2x.png index 30910a04b..9a73ace7a 100644 Binary files a/imgs/icons/1645@2x.png and b/imgs/icons/1645@2x.png differ diff --git a/imgs/icons/1656@2x.png b/imgs/icons/1656@2x.png index c4e8accf7..e9428b715 100644 Binary files a/imgs/icons/1656@2x.png and b/imgs/icons/1656@2x.png differ diff --git a/imgs/icons/1666@2x.png b/imgs/icons/1666@2x.png index d36c8fd76..332a4d911 100644 Binary files a/imgs/icons/1666@2x.png and b/imgs/icons/1666@2x.png differ diff --git a/imgs/icons/168@2x.png b/imgs/icons/168@2x.png index bb26f1ffe..3187a697c 100644 Binary files a/imgs/icons/168@2x.png and b/imgs/icons/168@2x.png differ diff --git a/imgs/icons/16@2x.png b/imgs/icons/16@2x.png index 793b27329..a06439c51 100644 Binary files a/imgs/icons/16@2x.png and b/imgs/icons/16@2x.png differ diff --git a/imgs/icons/170@2x.png b/imgs/icons/170@2x.png index e994f1d96..938d36c95 100644 Binary files a/imgs/icons/170@2x.png and b/imgs/icons/170@2x.png differ diff --git a/imgs/icons/1721@2x.png b/imgs/icons/1721@2x.png index f15746d88..7c59e4ef8 100644 Binary files a/imgs/icons/1721@2x.png and b/imgs/icons/1721@2x.png differ diff --git a/imgs/icons/1722@2x.png b/imgs/icons/1722@2x.png index cc8e84b1e..c20bffbf4 100644 Binary files a/imgs/icons/1722@2x.png and b/imgs/icons/1722@2x.png differ diff --git a/imgs/icons/1723@2x.png b/imgs/icons/1723@2x.png index af0db3caa..4586ac7d5 100644 Binary files a/imgs/icons/1723@2x.png and b/imgs/icons/1723@2x.png differ diff --git a/imgs/icons/182@2x.png b/imgs/icons/182@2x.png index 8d5243fe6..318a18d70 100644 Binary files a/imgs/icons/182@2x.png and b/imgs/icons/182@2x.png differ diff --git a/imgs/icons/186@2x.png b/imgs/icons/186@2x.png index 588f90496..0bb6742af 100644 Binary files a/imgs/icons/186@2x.png and b/imgs/icons/186@2x.png differ diff --git a/imgs/icons/187@2x.png b/imgs/icons/187@2x.png index 497f90ab9..d6b8c00e2 100644 Binary files a/imgs/icons/187@2x.png and b/imgs/icons/187@2x.png differ diff --git a/imgs/icons/188@2x.png b/imgs/icons/188@2x.png index 97e08a1c4..232790af2 100644 Binary files a/imgs/icons/188@2x.png and b/imgs/icons/188@2x.png differ diff --git a/imgs/icons/189@2x.png b/imgs/icons/189@2x.png index 2b385052c..5a49da007 100644 Binary files a/imgs/icons/189@2x.png and b/imgs/icons/189@2x.png differ diff --git a/imgs/icons/190@2x.png b/imgs/icons/190@2x.png index 07a5f1621..90d8da29a 100644 Binary files a/imgs/icons/190@2x.png and b/imgs/icons/190@2x.png differ diff --git a/imgs/icons/191@2x.png b/imgs/icons/191@2x.png index 073f465b9..597e57e46 100644 Binary files a/imgs/icons/191@2x.png and b/imgs/icons/191@2x.png differ diff --git a/imgs/icons/192@2x.png b/imgs/icons/192@2x.png index 11b33b6dc..e9384bf88 100644 Binary files a/imgs/icons/192@2x.png and b/imgs/icons/192@2x.png differ diff --git a/imgs/icons/193@2x.png b/imgs/icons/193@2x.png index 67ba8d092..bf553e006 100644 Binary files a/imgs/icons/193@2x.png and b/imgs/icons/193@2x.png differ diff --git a/imgs/icons/2030@1x.png b/imgs/icons/2030@1x.png index f853ef5d6..d89ac63f1 100644 Binary files a/imgs/icons/2030@1x.png and b/imgs/icons/2030@1x.png differ diff --git a/imgs/icons/2031@1x.png b/imgs/icons/2031@1x.png index 28fa8f7d1..39d4a8c49 100644 Binary files a/imgs/icons/2031@1x.png and b/imgs/icons/2031@1x.png differ diff --git a/imgs/icons/2037@2x.png b/imgs/icons/2037@2x.png index 65c7301fc..ecab5aa3f 100644 Binary files a/imgs/icons/2037@2x.png and b/imgs/icons/2037@2x.png differ diff --git a/imgs/icons/2038@2x.png b/imgs/icons/2038@2x.png index 293fc5625..dbe50a061 100644 Binary files a/imgs/icons/2038@2x.png and b/imgs/icons/2038@2x.png differ diff --git a/imgs/icons/2039@1x.png b/imgs/icons/2039@1x.png index b936e17fc..4959352ba 100644 Binary files a/imgs/icons/2039@1x.png and b/imgs/icons/2039@1x.png differ diff --git a/imgs/icons/2039@2x.png b/imgs/icons/2039@2x.png index 3ce715cd5..bf20a6737 100644 Binary files a/imgs/icons/2039@2x.png and b/imgs/icons/2039@2x.png differ diff --git a/imgs/icons/2040@2x.png b/imgs/icons/2040@2x.png index eb532b2b1..91fd5233f 100644 Binary files a/imgs/icons/2040@2x.png and b/imgs/icons/2040@2x.png differ diff --git a/imgs/icons/2041@2x.png b/imgs/icons/2041@2x.png index ce4186845..754609fb9 100644 Binary files a/imgs/icons/2041@2x.png and b/imgs/icons/2041@2x.png differ diff --git a/imgs/icons/2042@2x.png b/imgs/icons/2042@2x.png index 95dfb3662..0a0966dfe 100644 Binary files a/imgs/icons/2042@2x.png and b/imgs/icons/2042@2x.png differ diff --git a/imgs/icons/2053@2x.png b/imgs/icons/2053@2x.png index 36b788edf..8240f98d9 100644 Binary files a/imgs/icons/2053@2x.png and b/imgs/icons/2053@2x.png differ diff --git a/imgs/icons/2054@2x.png b/imgs/icons/2054@2x.png index eeb4fa0d0..43d8d9509 100644 Binary files a/imgs/icons/2054@2x.png and b/imgs/icons/2054@2x.png differ diff --git a/imgs/icons/2060@2x.png b/imgs/icons/2060@2x.png index f91807576..41214d076 100644 Binary files a/imgs/icons/2060@2x.png and b/imgs/icons/2060@2x.png differ diff --git a/imgs/icons/2061@2x.png b/imgs/icons/2061@2x.png index f7bf80255..6233c7a4b 100644 Binary files a/imgs/icons/2061@2x.png and b/imgs/icons/2061@2x.png differ diff --git a/imgs/icons/2062@1x.png b/imgs/icons/2062@1x.png index 97f25f619..bc158a8e6 100644 Binary files a/imgs/icons/2062@1x.png and b/imgs/icons/2062@1x.png differ diff --git a/imgs/icons/2062@2x.png b/imgs/icons/2062@2x.png index 74b76e2e9..297718b9b 100644 Binary files a/imgs/icons/2062@2x.png and b/imgs/icons/2062@2x.png differ diff --git a/imgs/icons/2066@2x.png b/imgs/icons/2066@2x.png index 6bfa11e23..68ed76f74 100644 Binary files a/imgs/icons/2066@2x.png and b/imgs/icons/2066@2x.png differ diff --git a/imgs/icons/2093@2x.png b/imgs/icons/2093@2x.png index 263fce8f1..9b91d63f2 100644 Binary files a/imgs/icons/2093@2x.png and b/imgs/icons/2093@2x.png differ diff --git a/imgs/icons/20943@2x.png b/imgs/icons/20943@2x.png index c66a89d13..e97a5795f 100644 Binary files a/imgs/icons/20943@2x.png and b/imgs/icons/20943@2x.png differ diff --git a/imgs/icons/20944@2x.png b/imgs/icons/20944@2x.png index 70daf8465..48cb5faeb 100644 Binary files a/imgs/icons/20944@2x.png and b/imgs/icons/20944@2x.png differ diff --git a/imgs/icons/20945@2x.png b/imgs/icons/20945@2x.png index af0e0e1d5..d1fd66371 100644 Binary files a/imgs/icons/20945@2x.png and b/imgs/icons/20945@2x.png differ diff --git a/imgs/icons/20946@2x.png b/imgs/icons/20946@2x.png index eaaa7d1f2..9908370fb 100644 Binary files a/imgs/icons/20946@2x.png and b/imgs/icons/20946@2x.png differ diff --git a/imgs/icons/20947@2x.png b/imgs/icons/20947@2x.png index 47a0a5f0c..54643c1e1 100644 Binary files a/imgs/icons/20947@2x.png and b/imgs/icons/20947@2x.png differ diff --git a/imgs/icons/20948@2x.png b/imgs/icons/20948@2x.png index 1c9f273e4..08ad79b26 100644 Binary files a/imgs/icons/20948@2x.png and b/imgs/icons/20948@2x.png differ diff --git a/imgs/icons/20949@2x.png b/imgs/icons/20949@2x.png index 4658330aa..07e808876 100644 Binary files a/imgs/icons/20949@2x.png and b/imgs/icons/20949@2x.png differ diff --git a/imgs/icons/2094@2x.png b/imgs/icons/2094@2x.png index 53fd9db83..11c10488b 100644 Binary files a/imgs/icons/2094@2x.png and b/imgs/icons/2094@2x.png differ diff --git a/imgs/icons/20950@2x.png b/imgs/icons/20950@2x.png index a8bbf3d1c..d48759fd3 100644 Binary files a/imgs/icons/20950@2x.png and b/imgs/icons/20950@2x.png differ diff --git a/imgs/icons/20951@2x.png b/imgs/icons/20951@2x.png index 31709660f..2e71c8aca 100644 Binary files a/imgs/icons/20951@2x.png and b/imgs/icons/20951@2x.png differ diff --git a/imgs/icons/20952@2x.png b/imgs/icons/20952@2x.png index 292dd1b67..e91a7cc99 100644 Binary files a/imgs/icons/20952@2x.png and b/imgs/icons/20952@2x.png differ diff --git a/imgs/icons/20953@2x.png b/imgs/icons/20953@2x.png index cbd0bdb5e..ad1d91fcf 100644 Binary files a/imgs/icons/20953@2x.png and b/imgs/icons/20953@2x.png differ diff --git a/imgs/icons/20954@2x.png b/imgs/icons/20954@2x.png index 348422d6c..3b2dbf03d 100644 Binary files a/imgs/icons/20954@2x.png and b/imgs/icons/20954@2x.png differ diff --git a/imgs/icons/2095@2x.png b/imgs/icons/2095@2x.png index 08ffcf398..e1f08bd41 100644 Binary files a/imgs/icons/2095@2x.png and b/imgs/icons/2095@2x.png differ diff --git a/imgs/icons/2096@2x.png b/imgs/icons/2096@2x.png index 626d0d99e..47d107a6c 100644 Binary files a/imgs/icons/2096@2x.png and b/imgs/icons/2096@2x.png differ diff --git a/imgs/icons/20970@2x.png b/imgs/icons/20970@2x.png index 3342c01cc..7299e8090 100644 Binary files a/imgs/icons/20970@2x.png and b/imgs/icons/20970@2x.png differ diff --git a/imgs/icons/20971@1x.png b/imgs/icons/20971@1x.png index d3cfa6aed..668f0b3d3 100644 Binary files a/imgs/icons/20971@1x.png and b/imgs/icons/20971@1x.png differ diff --git a/imgs/icons/20971@2x.png b/imgs/icons/20971@2x.png index 8f026e603..b71d68ca2 100644 Binary files a/imgs/icons/20971@2x.png and b/imgs/icons/20971@2x.png differ diff --git a/imgs/icons/20973@2x.png b/imgs/icons/20973@2x.png index 22abcac85..c6f21a2f5 100644 Binary files a/imgs/icons/20973@2x.png and b/imgs/icons/20973@2x.png differ diff --git a/imgs/icons/20976@1x.png b/imgs/icons/20976@1x.png index 4f410cc6e..30940650b 100644 Binary files a/imgs/icons/20976@1x.png and b/imgs/icons/20976@1x.png differ diff --git a/imgs/icons/20976@2x.png b/imgs/icons/20976@2x.png index 8383a39ee..6a6b0bef1 100644 Binary files a/imgs/icons/20976@2x.png and b/imgs/icons/20976@2x.png differ diff --git a/imgs/icons/20977@2x.png b/imgs/icons/20977@2x.png index 8e2752920..6c320a52b 100644 Binary files a/imgs/icons/20977@2x.png and b/imgs/icons/20977@2x.png differ diff --git a/imgs/icons/2100@2x.png b/imgs/icons/2100@2x.png index b56b494c3..800213299 100644 Binary files a/imgs/icons/2100@2x.png and b/imgs/icons/2100@2x.png differ diff --git a/imgs/icons/2101@2x.png b/imgs/icons/2101@2x.png index c09d3e35c..4c52c839b 100644 Binary files a/imgs/icons/2101@2x.png and b/imgs/icons/2101@2x.png differ diff --git a/imgs/icons/21026@1x.png b/imgs/icons/21026@1x.png index 17eba237c..2ad14aa86 100644 Binary files a/imgs/icons/21026@1x.png and b/imgs/icons/21026@1x.png differ diff --git a/imgs/icons/21028@2x.png b/imgs/icons/21028@2x.png index 1c431b30b..99c413e8f 100644 Binary files a/imgs/icons/21028@2x.png and b/imgs/icons/21028@2x.png differ diff --git a/imgs/icons/21029@2x.png b/imgs/icons/21029@2x.png index 9231ccec9..1e95396d2 100644 Binary files a/imgs/icons/21029@2x.png and b/imgs/icons/21029@2x.png differ diff --git a/imgs/icons/2102@2x.png b/imgs/icons/2102@2x.png index 263ab408e..f4cd2cbee 100644 Binary files a/imgs/icons/2102@2x.png and b/imgs/icons/2102@2x.png differ diff --git a/imgs/icons/21030@2x.png b/imgs/icons/21030@2x.png index 441c0af47..8d270dc94 100644 Binary files a/imgs/icons/21030@2x.png and b/imgs/icons/21030@2x.png differ diff --git a/imgs/icons/21032@2x.png b/imgs/icons/21032@2x.png index 519e87754..9c9cd4cf5 100644 Binary files a/imgs/icons/21032@2x.png and b/imgs/icons/21032@2x.png differ diff --git a/imgs/icons/2103@2x.png b/imgs/icons/2103@2x.png index a975ebe1b..eb4d16a69 100644 Binary files a/imgs/icons/2103@2x.png and b/imgs/icons/2103@2x.png differ diff --git a/imgs/icons/21047@2x.png b/imgs/icons/21047@2x.png index b63f47625..5b68222c9 100644 Binary files a/imgs/icons/21047@2x.png and b/imgs/icons/21047@2x.png differ diff --git a/imgs/icons/21048@2x.png b/imgs/icons/21048@2x.png index 5378b211e..fd63e90e8 100644 Binary files a/imgs/icons/21048@2x.png and b/imgs/icons/21048@2x.png differ diff --git a/imgs/icons/2104@2x.png b/imgs/icons/2104@2x.png index 28cddc2e7..fa96018e5 100644 Binary files a/imgs/icons/2104@2x.png and b/imgs/icons/2104@2x.png differ diff --git a/imgs/icons/21057@2x.png b/imgs/icons/21057@2x.png index 574b82518..df27b0fa0 100644 Binary files a/imgs/icons/21057@2x.png and b/imgs/icons/21057@2x.png differ diff --git a/imgs/icons/2105@2x.png b/imgs/icons/2105@2x.png index c7efd5230..3c63be241 100644 Binary files a/imgs/icons/2105@2x.png and b/imgs/icons/2105@2x.png differ diff --git a/imgs/icons/21061@2x.png b/imgs/icons/21061@2x.png index c89a1b72a..bcf88db15 100644 Binary files a/imgs/icons/21061@2x.png and b/imgs/icons/21061@2x.png differ diff --git a/imgs/icons/21063@2x.png b/imgs/icons/21063@2x.png index 896e5ac97..aa7f585ab 100644 Binary files a/imgs/icons/21063@2x.png and b/imgs/icons/21063@2x.png differ diff --git a/imgs/icons/21064@2x.png b/imgs/icons/21064@2x.png index c602834d0..7c0aa8bec 100644 Binary files a/imgs/icons/21064@2x.png and b/imgs/icons/21064@2x.png differ diff --git a/imgs/icons/21065@2x.png b/imgs/icons/21065@2x.png index 0145eb4b6..ec38de586 100644 Binary files a/imgs/icons/21065@2x.png and b/imgs/icons/21065@2x.png differ diff --git a/imgs/icons/21066@2x.png b/imgs/icons/21066@2x.png index e0a416cd7..31e1cf216 100644 Binary files a/imgs/icons/21066@2x.png and b/imgs/icons/21066@2x.png differ diff --git a/imgs/icons/2106@2x.png b/imgs/icons/2106@2x.png index 1e1b2ef1a..5442fdcfd 100644 Binary files a/imgs/icons/2106@2x.png and b/imgs/icons/2106@2x.png differ diff --git a/imgs/icons/21075@2x.png b/imgs/icons/21075@2x.png index fa2cb2535..e471996ff 100644 Binary files a/imgs/icons/21075@2x.png and b/imgs/icons/21075@2x.png differ diff --git a/imgs/icons/21078@2x.png b/imgs/icons/21078@2x.png index 17f5ec26c..645a8ce7f 100644 Binary files a/imgs/icons/21078@2x.png and b/imgs/icons/21078@2x.png differ diff --git a/imgs/icons/21084@2x.png b/imgs/icons/21084@2x.png index 329934ae9..07886443b 100644 Binary files a/imgs/icons/21084@2x.png and b/imgs/icons/21084@2x.png differ diff --git a/imgs/icons/21085@2x.png b/imgs/icons/21085@2x.png index 321fed349..6779d9260 100644 Binary files a/imgs/icons/21085@2x.png and b/imgs/icons/21085@2x.png differ diff --git a/imgs/icons/21097@2x.png b/imgs/icons/21097@2x.png index ee863ef33..5ea5e285b 100644 Binary files a/imgs/icons/21097@2x.png and b/imgs/icons/21097@2x.png differ diff --git a/imgs/icons/21170@2x.png b/imgs/icons/21170@2x.png index 099667302..890f8abd0 100644 Binary files a/imgs/icons/21170@2x.png and b/imgs/icons/21170@2x.png differ diff --git a/imgs/icons/21186@2x.png b/imgs/icons/21186@2x.png index 2afca7482..7bb7fbf46 100644 Binary files a/imgs/icons/21186@2x.png and b/imgs/icons/21186@2x.png differ diff --git a/imgs/icons/21335@2x.png b/imgs/icons/21335@2x.png index 64589d1ba..f61e06f7b 100644 Binary files a/imgs/icons/21335@2x.png and b/imgs/icons/21335@2x.png differ diff --git a/imgs/icons/21336@2x.png b/imgs/icons/21336@2x.png index 9de0dbaa7..af0843d74 100644 Binary files a/imgs/icons/21336@2x.png and b/imgs/icons/21336@2x.png differ diff --git a/imgs/icons/21378@2x.png b/imgs/icons/21378@2x.png index b0f7295bd..03d4a05d6 100644 Binary files a/imgs/icons/21378@2x.png and b/imgs/icons/21378@2x.png differ diff --git a/imgs/icons/21379@2x.png b/imgs/icons/21379@2x.png index fb780b7e8..82ccd122c 100644 Binary files a/imgs/icons/21379@2x.png and b/imgs/icons/21379@2x.png differ diff --git a/imgs/icons/21380@2x.png b/imgs/icons/21380@2x.png index 688b42242..52597f988 100644 Binary files a/imgs/icons/21380@2x.png and b/imgs/icons/21380@2x.png differ diff --git a/imgs/icons/21381@2x.png b/imgs/icons/21381@2x.png index 4ac619d85..952b9db7c 100644 Binary files a/imgs/icons/21381@2x.png and b/imgs/icons/21381@2x.png differ diff --git a/imgs/icons/21408@2x.png b/imgs/icons/21408@2x.png index 85989da45..974591820 100644 Binary files a/imgs/icons/21408@2x.png and b/imgs/icons/21408@2x.png differ diff --git a/imgs/icons/21417@2x.png b/imgs/icons/21417@2x.png index 16d435ada..90707e5d1 100644 Binary files a/imgs/icons/21417@2x.png and b/imgs/icons/21417@2x.png differ diff --git a/imgs/icons/21418@2x.png b/imgs/icons/21418@2x.png index 8b3b9d678..588a153ad 100644 Binary files a/imgs/icons/21418@2x.png and b/imgs/icons/21418@2x.png differ diff --git a/imgs/icons/21419@2x.png b/imgs/icons/21419@2x.png index fe5af5900..d318d2c78 100644 Binary files a/imgs/icons/21419@2x.png and b/imgs/icons/21419@2x.png differ diff --git a/imgs/icons/21421@2x.png b/imgs/icons/21421@2x.png index cbc693694..99f8b7ad9 100644 Binary files a/imgs/icons/21421@2x.png and b/imgs/icons/21421@2x.png differ diff --git a/imgs/icons/21426@2x.png b/imgs/icons/21426@2x.png index f3cbb2a8a..bb9b542a2 100644 Binary files a/imgs/icons/21426@2x.png and b/imgs/icons/21426@2x.png differ diff --git a/imgs/icons/21428@2x.png b/imgs/icons/21428@2x.png index 805a5635f..1e61a27c0 100644 Binary files a/imgs/icons/21428@2x.png and b/imgs/icons/21428@2x.png differ diff --git a/imgs/icons/21437@2x.png b/imgs/icons/21437@2x.png index 457900490..61d910d51 100644 Binary files a/imgs/icons/21437@2x.png and b/imgs/icons/21437@2x.png differ diff --git a/imgs/icons/21439@2x.png b/imgs/icons/21439@2x.png index 4051dba69..1e4c3bf76 100644 Binary files a/imgs/icons/21439@2x.png and b/imgs/icons/21439@2x.png differ diff --git a/imgs/icons/21440@2x.png b/imgs/icons/21440@2x.png index 4f21cb686..b2e819c12 100644 Binary files a/imgs/icons/21440@2x.png and b/imgs/icons/21440@2x.png differ diff --git a/imgs/icons/21441@2x.png b/imgs/icons/21441@2x.png index 76bf8604d..80e7b252f 100644 Binary files a/imgs/icons/21441@2x.png and b/imgs/icons/21441@2x.png differ diff --git a/imgs/icons/21481@2x.png b/imgs/icons/21481@2x.png index 2b06aa81d..7bf848c45 100644 Binary files a/imgs/icons/21481@2x.png and b/imgs/icons/21481@2x.png differ diff --git a/imgs/icons/21482@2x.png b/imgs/icons/21482@2x.png index 5b80d4c0e..04ee090bd 100644 Binary files a/imgs/icons/21482@2x.png and b/imgs/icons/21482@2x.png differ diff --git a/imgs/icons/21483@2x.png b/imgs/icons/21483@2x.png index e1e840852..2ece90169 100644 Binary files a/imgs/icons/21483@2x.png and b/imgs/icons/21483@2x.png differ diff --git a/imgs/icons/21484@2x.png b/imgs/icons/21484@2x.png index 8fd179006..335a8e945 100644 Binary files a/imgs/icons/21484@2x.png and b/imgs/icons/21484@2x.png differ diff --git a/imgs/icons/21485@2x.png b/imgs/icons/21485@2x.png index 9ed416483..7260f3f3f 100644 Binary files a/imgs/icons/21485@2x.png and b/imgs/icons/21485@2x.png differ diff --git a/imgs/icons/21486@2x.png b/imgs/icons/21486@2x.png index 68105d19f..a869daef2 100644 Binary files a/imgs/icons/21486@2x.png and b/imgs/icons/21486@2x.png differ diff --git a/imgs/icons/21487@2x.png b/imgs/icons/21487@2x.png index 4d04e8513..b87ee74a2 100644 Binary files a/imgs/icons/21487@2x.png and b/imgs/icons/21487@2x.png differ diff --git a/imgs/icons/21489@2x.png b/imgs/icons/21489@2x.png index c147ebb3e..1185cde84 100644 Binary files a/imgs/icons/21489@2x.png and b/imgs/icons/21489@2x.png differ diff --git a/imgs/icons/21513@2x.png b/imgs/icons/21513@2x.png index 48eba04f8..e27495226 100644 Binary files a/imgs/icons/21513@2x.png and b/imgs/icons/21513@2x.png differ diff --git a/imgs/icons/21530@2x.png b/imgs/icons/21530@2x.png index eb0563da8..59420a4fc 100644 Binary files a/imgs/icons/21530@2x.png and b/imgs/icons/21530@2x.png differ diff --git a/imgs/icons/21531@2x.png b/imgs/icons/21531@2x.png index 8084bd72e..3633baa94 100644 Binary files a/imgs/icons/21531@2x.png and b/imgs/icons/21531@2x.png differ diff --git a/imgs/icons/21532@2x.png b/imgs/icons/21532@2x.png index bf57d2b17..3c52efd3d 100644 Binary files a/imgs/icons/21532@2x.png and b/imgs/icons/21532@2x.png differ diff --git a/imgs/icons/21533@2x.png b/imgs/icons/21533@2x.png index bc0538328..22bedb39e 100644 Binary files a/imgs/icons/21533@2x.png and b/imgs/icons/21533@2x.png differ diff --git a/imgs/icons/21534@2x.png b/imgs/icons/21534@2x.png index 55d2806ca..b496861c3 100644 Binary files a/imgs/icons/21534@2x.png and b/imgs/icons/21534@2x.png differ diff --git a/imgs/icons/21561@2x.png b/imgs/icons/21561@2x.png index 8261c50c3..92b66517b 100644 Binary files a/imgs/icons/21561@2x.png and b/imgs/icons/21561@2x.png differ diff --git a/imgs/icons/21562@2x.png b/imgs/icons/21562@2x.png index 65e0b109d..d756d677e 100644 Binary files a/imgs/icons/21562@2x.png and b/imgs/icons/21562@2x.png differ diff --git a/imgs/icons/21564@2x.png b/imgs/icons/21564@2x.png index 3a31e1a8f..115cdff8f 100644 Binary files a/imgs/icons/21564@2x.png and b/imgs/icons/21564@2x.png differ diff --git a/imgs/icons/21565@2x.png b/imgs/icons/21565@2x.png index 0c6e981d1..c7a0d0b72 100644 Binary files a/imgs/icons/21565@2x.png and b/imgs/icons/21565@2x.png differ diff --git a/imgs/icons/21566@2x.png b/imgs/icons/21566@2x.png index b7fd4a445..47353fcd0 100644 Binary files a/imgs/icons/21566@2x.png and b/imgs/icons/21566@2x.png differ diff --git a/imgs/icons/21567@2x.png b/imgs/icons/21567@2x.png index 22ec69068..e89ba5af1 100644 Binary files a/imgs/icons/21567@2x.png and b/imgs/icons/21567@2x.png differ diff --git a/imgs/icons/21568@2x.png b/imgs/icons/21568@2x.png index b99c74786..d66c500de 100644 Binary files a/imgs/icons/21568@2x.png and b/imgs/icons/21568@2x.png differ diff --git a/imgs/icons/21569@2x.png b/imgs/icons/21569@2x.png index 9655d3a21..11b31437b 100644 Binary files a/imgs/icons/21569@2x.png and b/imgs/icons/21569@2x.png differ diff --git a/imgs/icons/21570@2x.png b/imgs/icons/21570@2x.png index a73a8ca4f..a82c88b62 100644 Binary files a/imgs/icons/21570@2x.png and b/imgs/icons/21570@2x.png differ diff --git a/imgs/icons/21571@2x.png b/imgs/icons/21571@2x.png index f9c7a6e99..a5da4b577 100644 Binary files a/imgs/icons/21571@2x.png and b/imgs/icons/21571@2x.png differ diff --git a/imgs/icons/21574@2x.png b/imgs/icons/21574@2x.png index 97a91fce6..da5c0cac7 100644 Binary files a/imgs/icons/21574@2x.png and b/imgs/icons/21574@2x.png differ diff --git a/imgs/icons/21575@2x.png b/imgs/icons/21575@2x.png index 07bc128e3..ed08452fd 100644 Binary files a/imgs/icons/21575@2x.png and b/imgs/icons/21575@2x.png differ diff --git a/imgs/icons/21581@1x.png b/imgs/icons/21581@1x.png index 4d4a263e7..1007c0c39 100644 Binary files a/imgs/icons/21581@1x.png and b/imgs/icons/21581@1x.png differ diff --git a/imgs/icons/21581@2x.png b/imgs/icons/21581@2x.png index eab9b034f..73a6dcbf8 100644 Binary files a/imgs/icons/21581@2x.png and b/imgs/icons/21581@2x.png differ diff --git a/imgs/icons/21593@2x.png b/imgs/icons/21593@2x.png index c6f4d833f..470d706df 100644 Binary files a/imgs/icons/21593@2x.png and b/imgs/icons/21593@2x.png differ diff --git a/imgs/icons/21594@2x.png b/imgs/icons/21594@2x.png index 5d31ef653..a6dda0a08 100644 Binary files a/imgs/icons/21594@2x.png and b/imgs/icons/21594@2x.png differ diff --git a/imgs/icons/21595@2x.png b/imgs/icons/21595@2x.png index 8837d5131..77cada406 100644 Binary files a/imgs/icons/21595@2x.png and b/imgs/icons/21595@2x.png differ diff --git a/imgs/icons/21596@2x.png b/imgs/icons/21596@2x.png index 70f8c75be..7749e8841 100644 Binary files a/imgs/icons/21596@2x.png and b/imgs/icons/21596@2x.png differ diff --git a/imgs/icons/21599@2x.png b/imgs/icons/21599@2x.png index b102472b6..0f44c8820 100644 Binary files a/imgs/icons/21599@2x.png and b/imgs/icons/21599@2x.png differ diff --git a/imgs/icons/21601@2x.png b/imgs/icons/21601@2x.png index 5ad8bb9eb..e09717916 100644 Binary files a/imgs/icons/21601@2x.png and b/imgs/icons/21601@2x.png differ diff --git a/imgs/icons/21602@1x.png b/imgs/icons/21602@1x.png index c76cc4f0b..7cdbd5fe6 100644 Binary files a/imgs/icons/21602@1x.png and b/imgs/icons/21602@1x.png differ diff --git a/imgs/icons/21602@2x.png b/imgs/icons/21602@2x.png index e8d897700..b51ea99b3 100644 Binary files a/imgs/icons/21602@2x.png and b/imgs/icons/21602@2x.png differ diff --git a/imgs/icons/21603@2x.png b/imgs/icons/21603@2x.png index b1612f9eb..afd0a0ee5 100644 Binary files a/imgs/icons/21603@2x.png and b/imgs/icons/21603@2x.png differ diff --git a/imgs/icons/21604@2x.png b/imgs/icons/21604@2x.png index af4e48683..02f85b839 100644 Binary files a/imgs/icons/21604@2x.png and b/imgs/icons/21604@2x.png differ diff --git a/imgs/icons/21605@2x.png b/imgs/icons/21605@2x.png index c9a98118c..02d7f7116 100644 Binary files a/imgs/icons/21605@2x.png and b/imgs/icons/21605@2x.png differ diff --git a/imgs/icons/21607@2x.png b/imgs/icons/21607@2x.png index cc9401071..2507a32dd 100644 Binary files a/imgs/icons/21607@2x.png and b/imgs/icons/21607@2x.png differ diff --git a/imgs/icons/21608@1x.png b/imgs/icons/21608@1x.png index 24309b580..ff673eb74 100644 Binary files a/imgs/icons/21608@1x.png and b/imgs/icons/21608@1x.png differ diff --git a/imgs/icons/21608@2x.png b/imgs/icons/21608@2x.png index 3bb3d7b6e..c448525d3 100644 Binary files a/imgs/icons/21608@2x.png and b/imgs/icons/21608@2x.png differ diff --git a/imgs/icons/21609@2x.png b/imgs/icons/21609@2x.png index 555a806b7..2189b5005 100644 Binary files a/imgs/icons/21609@2x.png and b/imgs/icons/21609@2x.png differ diff --git a/imgs/icons/21610@2x.png b/imgs/icons/21610@2x.png index 2d1c2bd9a..a5fa5e039 100644 Binary files a/imgs/icons/21610@2x.png and b/imgs/icons/21610@2x.png differ diff --git a/imgs/icons/21611@2x.png b/imgs/icons/21611@2x.png index 8774e7488..604e2fd22 100644 Binary files a/imgs/icons/21611@2x.png and b/imgs/icons/21611@2x.png differ diff --git a/imgs/icons/21618@2x.png b/imgs/icons/21618@2x.png index bde9d90b1..b8d0e34a8 100644 Binary files a/imgs/icons/21618@2x.png and b/imgs/icons/21618@2x.png differ diff --git a/imgs/icons/21683@2x.png b/imgs/icons/21683@2x.png index 231f706c5..4ecd85e0d 100644 Binary files a/imgs/icons/21683@2x.png and b/imgs/icons/21683@2x.png differ diff --git a/imgs/icons/21684@2x.png b/imgs/icons/21684@2x.png index 65f7f6c70..2f3d05380 100644 Binary files a/imgs/icons/21684@2x.png and b/imgs/icons/21684@2x.png differ diff --git a/imgs/icons/21685@2x.png b/imgs/icons/21685@2x.png index ad87d2a3e..e4eba2a74 100644 Binary files a/imgs/icons/21685@2x.png and b/imgs/icons/21685@2x.png differ diff --git a/imgs/icons/21686@2x.png b/imgs/icons/21686@2x.png index 01d0eef24..aa7dd58e1 100644 Binary files a/imgs/icons/21686@2x.png and b/imgs/icons/21686@2x.png differ diff --git a/imgs/icons/21687@2x.png b/imgs/icons/21687@2x.png index 3f1d2be1b..1bec6fbfe 100644 Binary files a/imgs/icons/21687@2x.png and b/imgs/icons/21687@2x.png differ diff --git a/imgs/icons/21688@2x.png b/imgs/icons/21688@2x.png index f59a720ba..3ce9441c1 100644 Binary files a/imgs/icons/21688@2x.png and b/imgs/icons/21688@2x.png differ diff --git a/imgs/icons/21689@2x.png b/imgs/icons/21689@2x.png index 0764240fb..949b58deb 100644 Binary files a/imgs/icons/21689@2x.png and b/imgs/icons/21689@2x.png differ diff --git a/imgs/icons/21690@2x.png b/imgs/icons/21690@2x.png index ce17647a8..0dcc433c9 100644 Binary files a/imgs/icons/21690@2x.png and b/imgs/icons/21690@2x.png differ diff --git a/imgs/icons/21695@2x.png b/imgs/icons/21695@2x.png index 17e376a40..4cbfb3941 100644 Binary files a/imgs/icons/21695@2x.png and b/imgs/icons/21695@2x.png differ diff --git a/imgs/icons/21696@2x.png b/imgs/icons/21696@2x.png index fbd62f9f9..8e185cbac 100644 Binary files a/imgs/icons/21696@2x.png and b/imgs/icons/21696@2x.png differ diff --git a/imgs/icons/21698@2x.png b/imgs/icons/21698@2x.png index 6a7aa40dd..b37f97daa 100644 Binary files a/imgs/icons/21698@2x.png and b/imgs/icons/21698@2x.png differ diff --git a/imgs/icons/21699@2x.png b/imgs/icons/21699@2x.png index 0132046da..d87fb0826 100644 Binary files a/imgs/icons/21699@2x.png and b/imgs/icons/21699@2x.png differ diff --git a/imgs/icons/21700@2x.png b/imgs/icons/21700@2x.png index d3983ae61..e2aa72b89 100644 Binary files a/imgs/icons/21700@2x.png and b/imgs/icons/21700@2x.png differ diff --git a/imgs/icons/21701@2x.png b/imgs/icons/21701@2x.png index e2bf99ef2..05f88f09a 100644 Binary files a/imgs/icons/21701@2x.png and b/imgs/icons/21701@2x.png differ diff --git a/imgs/icons/21702@1x.png b/imgs/icons/21702@1x.png index 6b2340b2d..f42dfd67a 100644 Binary files a/imgs/icons/21702@1x.png and b/imgs/icons/21702@1x.png differ diff --git a/imgs/icons/21702@2x.png b/imgs/icons/21702@2x.png index 22b4e3403..4a383c08f 100644 Binary files a/imgs/icons/21702@2x.png and b/imgs/icons/21702@2x.png differ diff --git a/imgs/icons/21703@2x.png b/imgs/icons/21703@2x.png index 5c72c7cb9..83ade9259 100644 Binary files a/imgs/icons/21703@2x.png and b/imgs/icons/21703@2x.png differ diff --git a/imgs/icons/21725@2x.png b/imgs/icons/21725@2x.png index 561d624bd..63b740cab 100644 Binary files a/imgs/icons/21725@2x.png and b/imgs/icons/21725@2x.png differ diff --git a/imgs/icons/21729@2x.png b/imgs/icons/21729@2x.png index ebc095ad4..47babd0f2 100644 Binary files a/imgs/icons/21729@2x.png and b/imgs/icons/21729@2x.png differ diff --git a/imgs/icons/21730@2x.png b/imgs/icons/21730@2x.png index 25c474351..8bfc40349 100644 Binary files a/imgs/icons/21730@2x.png and b/imgs/icons/21730@2x.png differ diff --git a/imgs/icons/21731@2x.png b/imgs/icons/21731@2x.png index 52412dff7..2fb42c466 100644 Binary files a/imgs/icons/21731@2x.png and b/imgs/icons/21731@2x.png differ diff --git a/imgs/icons/21743@2x.png b/imgs/icons/21743@2x.png index 284bc3b24..248bda9f3 100644 Binary files a/imgs/icons/21743@2x.png and b/imgs/icons/21743@2x.png differ diff --git a/imgs/icons/2176@2x.png b/imgs/icons/2176@2x.png index 9bc2613e6..bd2e6cbd9 100644 Binary files a/imgs/icons/2176@2x.png and b/imgs/icons/2176@2x.png differ diff --git a/imgs/icons/21774@2x.png b/imgs/icons/21774@2x.png index 4d04b58ca..abf318fa1 100644 Binary files a/imgs/icons/21774@2x.png and b/imgs/icons/21774@2x.png differ diff --git a/imgs/icons/21783@2x.png b/imgs/icons/21783@2x.png index 4effb6456..42e64d5c0 100644 Binary files a/imgs/icons/21783@2x.png and b/imgs/icons/21783@2x.png differ diff --git a/imgs/icons/21784@2x.png b/imgs/icons/21784@2x.png index ac8ac72a6..3af7a7b37 100644 Binary files a/imgs/icons/21784@2x.png and b/imgs/icons/21784@2x.png differ diff --git a/imgs/icons/21785@2x.png b/imgs/icons/21785@2x.png index 5100c4ea0..7752ed4ef 100644 Binary files a/imgs/icons/21785@2x.png and b/imgs/icons/21785@2x.png differ diff --git a/imgs/icons/21787@2x.png b/imgs/icons/21787@2x.png index c4675ec92..a485434c9 100644 Binary files a/imgs/icons/21787@2x.png and b/imgs/icons/21787@2x.png differ diff --git a/imgs/icons/21788@2x.png b/imgs/icons/21788@2x.png index af775c221..e54879e40 100644 Binary files a/imgs/icons/21788@2x.png and b/imgs/icons/21788@2x.png differ diff --git a/imgs/icons/21789@2x.png b/imgs/icons/21789@2x.png index 53add03e1..1379941e3 100644 Binary files a/imgs/icons/21789@2x.png and b/imgs/icons/21789@2x.png differ diff --git a/imgs/icons/2178@2x.png b/imgs/icons/2178@2x.png index 462ca711e..575d0a455 100644 Binary files a/imgs/icons/2178@2x.png and b/imgs/icons/2178@2x.png differ diff --git a/imgs/icons/21790@2x.png b/imgs/icons/21790@2x.png index 22d8eec87..0d706b078 100644 Binary files a/imgs/icons/21790@2x.png and b/imgs/icons/21790@2x.png differ diff --git a/imgs/icons/21792@2x.png b/imgs/icons/21792@2x.png index 67e983ea5..6ac76c8ad 100644 Binary files a/imgs/icons/21792@2x.png and b/imgs/icons/21792@2x.png differ diff --git a/imgs/icons/21793@2x.png b/imgs/icons/21793@2x.png index 4b15b8921..0393887b1 100644 Binary files a/imgs/icons/21793@2x.png and b/imgs/icons/21793@2x.png differ diff --git a/imgs/icons/21794@2x.png b/imgs/icons/21794@2x.png index 23d8eb88f..aa26bc580 100644 Binary files a/imgs/icons/21794@2x.png and b/imgs/icons/21794@2x.png differ diff --git a/imgs/icons/21795@2x.png b/imgs/icons/21795@2x.png index 5bfa12b69..257df82b4 100644 Binary files a/imgs/icons/21795@2x.png and b/imgs/icons/21795@2x.png differ diff --git a/imgs/icons/21796@2x.png b/imgs/icons/21796@2x.png index 40a100a5b..8b51cc04d 100644 Binary files a/imgs/icons/21796@2x.png and b/imgs/icons/21796@2x.png differ diff --git a/imgs/icons/21797@2x.png b/imgs/icons/21797@2x.png index c2e9de34b..81ddc11b9 100644 Binary files a/imgs/icons/21797@2x.png and b/imgs/icons/21797@2x.png differ diff --git a/imgs/icons/21798@2x.png b/imgs/icons/21798@2x.png index 010a8d427..b5580b1fb 100644 Binary files a/imgs/icons/21798@2x.png and b/imgs/icons/21798@2x.png differ diff --git a/imgs/icons/21799@2x.png b/imgs/icons/21799@2x.png index 6fa0729e1..cf015ff8c 100644 Binary files a/imgs/icons/21799@2x.png and b/imgs/icons/21799@2x.png differ diff --git a/imgs/icons/2179@2x.png b/imgs/icons/2179@2x.png index 2ef08ef29..90f02f2d8 100644 Binary files a/imgs/icons/2179@2x.png and b/imgs/icons/2179@2x.png differ diff --git a/imgs/icons/21800@1x.png b/imgs/icons/21800@1x.png index 4c9edda62..89be3f624 100644 Binary files a/imgs/icons/21800@1x.png and b/imgs/icons/21800@1x.png differ diff --git a/imgs/icons/21801@2x.png b/imgs/icons/21801@2x.png index 72fb5d888..18f512ec4 100644 Binary files a/imgs/icons/21801@2x.png and b/imgs/icons/21801@2x.png differ diff --git a/imgs/icons/2180@2x.png b/imgs/icons/2180@2x.png index 1e500dc55..580323203 100644 Binary files a/imgs/icons/2180@2x.png and b/imgs/icons/2180@2x.png differ diff --git a/imgs/icons/2181@2x.png b/imgs/icons/2181@2x.png index 942e56eb6..0243c3e2c 100644 Binary files a/imgs/icons/2181@2x.png and b/imgs/icons/2181@2x.png differ diff --git a/imgs/icons/21823@2x.png b/imgs/icons/21823@2x.png index b0ddef23c..245b3ba38 100644 Binary files a/imgs/icons/21823@2x.png and b/imgs/icons/21823@2x.png differ diff --git a/imgs/icons/21829@2x.png b/imgs/icons/21829@2x.png index c0f973206..ca8b0d1e8 100644 Binary files a/imgs/icons/21829@2x.png and b/imgs/icons/21829@2x.png differ diff --git a/imgs/icons/21832@2x.png b/imgs/icons/21832@2x.png index 274d5e94a..b73da7da9 100644 Binary files a/imgs/icons/21832@2x.png and b/imgs/icons/21832@2x.png differ diff --git a/imgs/icons/21835@2x.png b/imgs/icons/21835@2x.png index d46d6d3f0..a29028cf9 100644 Binary files a/imgs/icons/21835@2x.png and b/imgs/icons/21835@2x.png differ diff --git a/imgs/icons/21839@2x.png b/imgs/icons/21839@2x.png index 31851c612..f2d9bc4bd 100644 Binary files a/imgs/icons/21839@2x.png and b/imgs/icons/21839@2x.png differ diff --git a/imgs/icons/2183@1x.png b/imgs/icons/2183@1x.png index 7604edeb8..80c73defd 100644 Binary files a/imgs/icons/2183@1x.png and b/imgs/icons/2183@1x.png differ diff --git a/imgs/icons/21840@2x.png b/imgs/icons/21840@2x.png index a0e0b7cc3..8e3d77f94 100644 Binary files a/imgs/icons/21840@2x.png and b/imgs/icons/21840@2x.png differ diff --git a/imgs/icons/21841@2x.png b/imgs/icons/21841@2x.png index 98f7d0698..552c7c52b 100644 Binary files a/imgs/icons/21841@2x.png and b/imgs/icons/21841@2x.png differ diff --git a/imgs/icons/21844@2x.png b/imgs/icons/21844@2x.png index 23c983409..e42fbf7aa 100644 Binary files a/imgs/icons/21844@2x.png and b/imgs/icons/21844@2x.png differ diff --git a/imgs/icons/2184@2x.png b/imgs/icons/2184@2x.png index fadbfd9d2..b78df3126 100644 Binary files a/imgs/icons/2184@2x.png and b/imgs/icons/2184@2x.png differ diff --git a/imgs/icons/2185@2x.png b/imgs/icons/2185@2x.png index 9ade13799..e885a6f7a 100644 Binary files a/imgs/icons/2185@2x.png and b/imgs/icons/2185@2x.png differ diff --git a/imgs/icons/21860@2x.png b/imgs/icons/21860@2x.png index ffc67de76..54293b78d 100644 Binary files a/imgs/icons/21860@2x.png and b/imgs/icons/21860@2x.png differ diff --git a/imgs/icons/2186@2x.png b/imgs/icons/2186@2x.png index 7fb2ea35c..46170e493 100644 Binary files a/imgs/icons/2186@2x.png and b/imgs/icons/2186@2x.png differ diff --git a/imgs/icons/2187@2x.png b/imgs/icons/2187@2x.png index 956de61e2..08be5528b 100644 Binary files a/imgs/icons/2187@2x.png and b/imgs/icons/2187@2x.png differ diff --git a/imgs/icons/2188@2x.png b/imgs/icons/2188@2x.png index 70eb7aed5..09e601321 100644 Binary files a/imgs/icons/2188@2x.png and b/imgs/icons/2188@2x.png differ diff --git a/imgs/icons/21891@2x.png b/imgs/icons/21891@2x.png index efd63779d..857441117 100644 Binary files a/imgs/icons/21891@2x.png and b/imgs/icons/21891@2x.png differ diff --git a/imgs/icons/21898@2x.png b/imgs/icons/21898@2x.png index faaa3fdd0..b46927359 100644 Binary files a/imgs/icons/21898@2x.png and b/imgs/icons/21898@2x.png differ diff --git a/imgs/icons/2189@2x.png b/imgs/icons/2189@2x.png index 0670973e9..fa1f5857a 100644 Binary files a/imgs/icons/2189@2x.png and b/imgs/icons/2189@2x.png differ diff --git a/imgs/icons/21903@2x.png b/imgs/icons/21903@2x.png index 4cc4b7bb2..f472abed7 100644 Binary files a/imgs/icons/21903@2x.png and b/imgs/icons/21903@2x.png differ diff --git a/imgs/icons/21904@2x.png b/imgs/icons/21904@2x.png index 68e342ad8..0369b6fa7 100644 Binary files a/imgs/icons/21904@2x.png and b/imgs/icons/21904@2x.png differ diff --git a/imgs/icons/21905@1x.png b/imgs/icons/21905@1x.png index 915da572a..b9e2a947c 100644 Binary files a/imgs/icons/21905@1x.png and b/imgs/icons/21905@1x.png differ diff --git a/imgs/icons/21905@2x.png b/imgs/icons/21905@2x.png index 00b67efd2..fd3f70d55 100644 Binary files a/imgs/icons/21905@2x.png and b/imgs/icons/21905@2x.png differ diff --git a/imgs/icons/21906@2x.png b/imgs/icons/21906@2x.png index 763ec8d4d..94f863655 100644 Binary files a/imgs/icons/21906@2x.png and b/imgs/icons/21906@2x.png differ diff --git a/imgs/icons/21907@2x.png b/imgs/icons/21907@2x.png index 7ecde9caf..38921f2d9 100644 Binary files a/imgs/icons/21907@2x.png and b/imgs/icons/21907@2x.png differ diff --git a/imgs/icons/2190@2x.png b/imgs/icons/2190@2x.png index dbb44332b..e9415e4cb 100644 Binary files a/imgs/icons/2190@2x.png and b/imgs/icons/2190@2x.png differ diff --git a/imgs/icons/21916@2x.png b/imgs/icons/21916@2x.png index 94f6a4dac..ed3e6b530 100644 Binary files a/imgs/icons/21916@2x.png and b/imgs/icons/21916@2x.png differ diff --git a/imgs/icons/21917@2x.png b/imgs/icons/21917@2x.png index c2516c6e9..ec29b60c6 100644 Binary files a/imgs/icons/21917@2x.png and b/imgs/icons/21917@2x.png differ diff --git a/imgs/icons/21918@2x.png b/imgs/icons/21918@2x.png index 940ceedec..60b9802e0 100644 Binary files a/imgs/icons/21918@2x.png and b/imgs/icons/21918@2x.png differ diff --git a/imgs/icons/21919@2x.png b/imgs/icons/21919@2x.png index 3b1e8bec7..8572309b2 100644 Binary files a/imgs/icons/21919@2x.png and b/imgs/icons/21919@2x.png differ diff --git a/imgs/icons/21920@2x.png b/imgs/icons/21920@2x.png index fd54daba0..6e35601f9 100644 Binary files a/imgs/icons/21920@2x.png and b/imgs/icons/21920@2x.png differ diff --git a/imgs/icons/21921@2x.png b/imgs/icons/21921@2x.png index 2300b0e42..b7ba70033 100644 Binary files a/imgs/icons/21921@2x.png and b/imgs/icons/21921@2x.png differ diff --git a/imgs/icons/21922@2x.png b/imgs/icons/21922@2x.png index 84007e3df..cea112c44 100644 Binary files a/imgs/icons/21922@2x.png and b/imgs/icons/21922@2x.png differ diff --git a/imgs/icons/21924@2x.png b/imgs/icons/21924@2x.png index 2af14f3a6..859a5b57b 100644 Binary files a/imgs/icons/21924@2x.png and b/imgs/icons/21924@2x.png differ diff --git a/imgs/icons/21925@2x.png b/imgs/icons/21925@2x.png index c6794a61a..fe8190866 100644 Binary files a/imgs/icons/21925@2x.png and b/imgs/icons/21925@2x.png differ diff --git a/imgs/icons/21926@2x.png b/imgs/icons/21926@2x.png index 26f3fbab8..858bc1e9f 100644 Binary files a/imgs/icons/21926@2x.png and b/imgs/icons/21926@2x.png differ diff --git a/imgs/icons/21927@2x.png b/imgs/icons/21927@2x.png index b5405a677..863969d56 100644 Binary files a/imgs/icons/21927@2x.png and b/imgs/icons/21927@2x.png differ diff --git a/imgs/icons/21928@2x.png b/imgs/icons/21928@2x.png index 4b212bf85..cbff05136 100644 Binary files a/imgs/icons/21928@2x.png and b/imgs/icons/21928@2x.png differ diff --git a/imgs/icons/2192@2x.png b/imgs/icons/2192@2x.png index cba536e36..ac9f358d4 100644 Binary files a/imgs/icons/2192@2x.png and b/imgs/icons/2192@2x.png differ diff --git a/imgs/icons/2193@2x.png b/imgs/icons/2193@2x.png index c4936828d..b3c32f439 100644 Binary files a/imgs/icons/2193@2x.png and b/imgs/icons/2193@2x.png differ diff --git a/imgs/icons/2194@2x.png b/imgs/icons/2194@2x.png index 384e03eb2..1f591e3ef 100644 Binary files a/imgs/icons/2194@2x.png and b/imgs/icons/2194@2x.png differ diff --git a/imgs/icons/2195@2x.png b/imgs/icons/2195@2x.png index 9635c5ef6..07ac5e8ba 100644 Binary files a/imgs/icons/2195@2x.png and b/imgs/icons/2195@2x.png differ diff --git a/imgs/icons/2196@2x.png b/imgs/icons/2196@2x.png index f24ebae3d..12a5a1b4b 100644 Binary files a/imgs/icons/2196@2x.png and b/imgs/icons/2196@2x.png differ diff --git a/imgs/icons/21980@2x.png b/imgs/icons/21980@2x.png index 17da8e0af..1f0ebfd81 100644 Binary files a/imgs/icons/21980@2x.png and b/imgs/icons/21980@2x.png differ diff --git a/imgs/icons/21983@2x.png b/imgs/icons/21983@2x.png index 611df3a45..675e63b64 100644 Binary files a/imgs/icons/21983@2x.png and b/imgs/icons/21983@2x.png differ diff --git a/imgs/icons/21985@2x.png b/imgs/icons/21985@2x.png index f5d7e0b58..6f1d8ba8c 100644 Binary files a/imgs/icons/21985@2x.png and b/imgs/icons/21985@2x.png differ diff --git a/imgs/icons/21986@2x.png b/imgs/icons/21986@2x.png index a17a8a1a3..482cee0b8 100644 Binary files a/imgs/icons/21986@2x.png and b/imgs/icons/21986@2x.png differ diff --git a/imgs/icons/21987@2x.png b/imgs/icons/21987@2x.png index 43424af20..1b36762c4 100644 Binary files a/imgs/icons/21987@2x.png and b/imgs/icons/21987@2x.png differ diff --git a/imgs/icons/21988@2x.png b/imgs/icons/21988@2x.png index 7cc1dcc1e..0d59df465 100644 Binary files a/imgs/icons/21988@2x.png and b/imgs/icons/21988@2x.png differ diff --git a/imgs/icons/2198@2x.png b/imgs/icons/2198@2x.png index c78ced1d0..389d7a7fe 100644 Binary files a/imgs/icons/2198@2x.png and b/imgs/icons/2198@2x.png differ diff --git a/imgs/icons/21990@2x.png b/imgs/icons/21990@2x.png index a5b931bf3..fe23bd294 100644 Binary files a/imgs/icons/21990@2x.png and b/imgs/icons/21990@2x.png differ diff --git a/imgs/icons/21992@2x.png b/imgs/icons/21992@2x.png index 624b12787..4fda25a32 100644 Binary files a/imgs/icons/21992@2x.png and b/imgs/icons/21992@2x.png differ diff --git a/imgs/icons/21993@2x.png b/imgs/icons/21993@2x.png index f0c4e5d3c..7ce1728cb 100644 Binary files a/imgs/icons/21993@2x.png and b/imgs/icons/21993@2x.png differ diff --git a/imgs/icons/21994@2x.png b/imgs/icons/21994@2x.png index 6630a8336..1f83219b6 100644 Binary files a/imgs/icons/21994@2x.png and b/imgs/icons/21994@2x.png differ diff --git a/imgs/icons/21996@2x.png b/imgs/icons/21996@2x.png index 2071018b4..6c84fb549 100644 Binary files a/imgs/icons/21996@2x.png and b/imgs/icons/21996@2x.png differ diff --git a/imgs/icons/21997@2x.png b/imgs/icons/21997@2x.png index f5909109d..901cc69dd 100644 Binary files a/imgs/icons/21997@2x.png and b/imgs/icons/21997@2x.png differ diff --git a/imgs/icons/21998@1x.png b/imgs/icons/21998@1x.png index 1975bd9cf..572544a12 100644 Binary files a/imgs/icons/21998@1x.png and b/imgs/icons/21998@1x.png differ diff --git a/imgs/icons/21998@2x.png b/imgs/icons/21998@2x.png index c65e6834c..98bf750b1 100644 Binary files a/imgs/icons/21998@2x.png and b/imgs/icons/21998@2x.png differ diff --git a/imgs/icons/21999@2x.png b/imgs/icons/21999@2x.png index 6df3d72ee..f563e2fb6 100644 Binary files a/imgs/icons/21999@2x.png and b/imgs/icons/21999@2x.png differ diff --git a/imgs/icons/2199@2x.png b/imgs/icons/2199@2x.png index b9afd8efc..c83b5fafc 100644 Binary files a/imgs/icons/2199@2x.png and b/imgs/icons/2199@2x.png differ diff --git a/imgs/icons/21@2x.png b/imgs/icons/21@2x.png index dc6604e18..d01c11544 100644 Binary files a/imgs/icons/21@2x.png and b/imgs/icons/21@2x.png differ diff --git a/imgs/icons/22000@2x.png b/imgs/icons/22000@2x.png index 9d593fca7..f1d2a6710 100644 Binary files a/imgs/icons/22000@2x.png and b/imgs/icons/22000@2x.png differ diff --git a/imgs/icons/22001@2x.png b/imgs/icons/22001@2x.png index 4494a863b..1a8068ba4 100644 Binary files a/imgs/icons/22001@2x.png and b/imgs/icons/22001@2x.png differ diff --git a/imgs/icons/22002@2x.png b/imgs/icons/22002@2x.png index a034ee452..cabbadf70 100644 Binary files a/imgs/icons/22002@2x.png and b/imgs/icons/22002@2x.png differ diff --git a/imgs/icons/22003@2x.png b/imgs/icons/22003@2x.png index 159446718..c18a7bd82 100644 Binary files a/imgs/icons/22003@2x.png and b/imgs/icons/22003@2x.png differ diff --git a/imgs/icons/22004@2x.png b/imgs/icons/22004@2x.png index 6b778a200..e8a4e2c99 100644 Binary files a/imgs/icons/22004@2x.png and b/imgs/icons/22004@2x.png differ diff --git a/imgs/icons/22005@2x.png b/imgs/icons/22005@2x.png index 5774f6441..8801fd9a1 100644 Binary files a/imgs/icons/22005@2x.png and b/imgs/icons/22005@2x.png differ diff --git a/imgs/icons/22006@2x.png b/imgs/icons/22006@2x.png index 45d5ddac4..5dc465c15 100644 Binary files a/imgs/icons/22006@2x.png and b/imgs/icons/22006@2x.png differ diff --git a/imgs/icons/22007@2x.png b/imgs/icons/22007@2x.png index 7cbd3326f..4eff04ba0 100644 Binary files a/imgs/icons/22007@2x.png and b/imgs/icons/22007@2x.png differ diff --git a/imgs/icons/22008@2x.png b/imgs/icons/22008@2x.png index 0756cfd8a..ca562d299 100644 Binary files a/imgs/icons/22008@2x.png and b/imgs/icons/22008@2x.png differ diff --git a/imgs/icons/22009@2x.png b/imgs/icons/22009@2x.png index 74b922c92..ee676d2a9 100644 Binary files a/imgs/icons/22009@2x.png and b/imgs/icons/22009@2x.png differ diff --git a/imgs/icons/2200@2x.png b/imgs/icons/2200@2x.png index ab8a1f5df..165efd718 100644 Binary files a/imgs/icons/2200@2x.png and b/imgs/icons/2200@2x.png differ diff --git a/imgs/icons/22010@2x.png b/imgs/icons/22010@2x.png index 1b2fca47c..f392f5b9d 100644 Binary files a/imgs/icons/22010@2x.png and b/imgs/icons/22010@2x.png differ diff --git a/imgs/icons/22011@2x.png b/imgs/icons/22011@2x.png index 52632b451..72faf12fc 100644 Binary files a/imgs/icons/22011@2x.png and b/imgs/icons/22011@2x.png differ diff --git a/imgs/icons/22012@2x.png b/imgs/icons/22012@2x.png index af5cd048d..08b5a3fd3 100644 Binary files a/imgs/icons/22012@2x.png and b/imgs/icons/22012@2x.png differ diff --git a/imgs/icons/22013@2x.png b/imgs/icons/22013@2x.png index 40401ea54..44a3becd1 100644 Binary files a/imgs/icons/22013@2x.png and b/imgs/icons/22013@2x.png differ diff --git a/imgs/icons/22014@2x.png b/imgs/icons/22014@2x.png index 57a33673c..73317a69e 100644 Binary files a/imgs/icons/22014@2x.png and b/imgs/icons/22014@2x.png differ diff --git a/imgs/icons/22016@1x.png b/imgs/icons/22016@1x.png index 4f4fdde46..153cdb191 100644 Binary files a/imgs/icons/22016@1x.png and b/imgs/icons/22016@1x.png differ diff --git a/imgs/icons/22016@2x.png b/imgs/icons/22016@2x.png index 115bbfdb4..7315e2ad9 100644 Binary files a/imgs/icons/22016@2x.png and b/imgs/icons/22016@2x.png differ diff --git a/imgs/icons/22018@2x.png b/imgs/icons/22018@2x.png index 51f73a70b..bf219c1c0 100644 Binary files a/imgs/icons/22018@2x.png and b/imgs/icons/22018@2x.png differ diff --git a/imgs/icons/2201@2x.png b/imgs/icons/2201@2x.png index 4aaade759..610e37a3e 100644 Binary files a/imgs/icons/2201@2x.png and b/imgs/icons/2201@2x.png differ diff --git a/imgs/icons/22020@2x.png b/imgs/icons/22020@2x.png index 821aa2c0f..51e424f20 100644 Binary files a/imgs/icons/22020@2x.png and b/imgs/icons/22020@2x.png differ diff --git a/imgs/icons/22029@2x.png b/imgs/icons/22029@2x.png index e76577620..fb6dc46c1 100644 Binary files a/imgs/icons/22029@2x.png and b/imgs/icons/22029@2x.png differ diff --git a/imgs/icons/2202@2x.png b/imgs/icons/2202@2x.png index e9ce2adde..cafe7d4c6 100644 Binary files a/imgs/icons/2202@2x.png and b/imgs/icons/2202@2x.png differ diff --git a/imgs/icons/22030@2x.png b/imgs/icons/22030@2x.png index 524af532a..735abe3e0 100644 Binary files a/imgs/icons/22030@2x.png and b/imgs/icons/22030@2x.png differ diff --git a/imgs/icons/22031@2x.png b/imgs/icons/22031@2x.png index 5e575a485..2075c1b29 100644 Binary files a/imgs/icons/22031@2x.png and b/imgs/icons/22031@2x.png differ diff --git a/imgs/icons/22036@2x.png b/imgs/icons/22036@2x.png index fb995e92c..52de3a9ab 100644 Binary files a/imgs/icons/22036@2x.png and b/imgs/icons/22036@2x.png differ diff --git a/imgs/icons/2203@2x.png b/imgs/icons/2203@2x.png index d43d5da5b..471319773 100644 Binary files a/imgs/icons/2203@2x.png and b/imgs/icons/2203@2x.png differ diff --git a/imgs/icons/22041@2x.png b/imgs/icons/22041@2x.png index 1ba6d39b4..e8ca6fa5b 100644 Binary files a/imgs/icons/22041@2x.png and b/imgs/icons/22041@2x.png differ diff --git a/imgs/icons/22042@2x.png b/imgs/icons/22042@2x.png index 064a09a3d..0d1f8fc22 100644 Binary files a/imgs/icons/22042@2x.png and b/imgs/icons/22042@2x.png differ diff --git a/imgs/icons/2204@1x.png b/imgs/icons/2204@1x.png index 071a54d87..ecb153066 100644 Binary files a/imgs/icons/2204@1x.png and b/imgs/icons/2204@1x.png differ diff --git a/imgs/icons/2204@2x.png b/imgs/icons/2204@2x.png index d7d89a5f4..9941430b7 100644 Binary files a/imgs/icons/2204@2x.png and b/imgs/icons/2204@2x.png differ diff --git a/imgs/icons/2205@2x.png b/imgs/icons/2205@2x.png index 26599dcb8..492d2d970 100644 Binary files a/imgs/icons/2205@2x.png and b/imgs/icons/2205@2x.png differ diff --git a/imgs/icons/22061@2x.png b/imgs/icons/22061@2x.png index 6515eab8d..bb240cb26 100644 Binary files a/imgs/icons/22061@2x.png and b/imgs/icons/22061@2x.png differ diff --git a/imgs/icons/22062@2x.png b/imgs/icons/22062@2x.png index 5446e1dfb..148b3cb0b 100644 Binary files a/imgs/icons/22062@2x.png and b/imgs/icons/22062@2x.png differ diff --git a/imgs/icons/22064@2x.png b/imgs/icons/22064@2x.png index 2d2ad5fea..c90a10e1c 100644 Binary files a/imgs/icons/22064@2x.png and b/imgs/icons/22064@2x.png differ diff --git a/imgs/icons/22065@2x.png b/imgs/icons/22065@2x.png index b975102b8..bb6e4f511 100644 Binary files a/imgs/icons/22065@2x.png and b/imgs/icons/22065@2x.png differ diff --git a/imgs/icons/22066@2x.png b/imgs/icons/22066@2x.png index 4a55905c8..e3015eb3c 100644 Binary files a/imgs/icons/22066@2x.png and b/imgs/icons/22066@2x.png differ diff --git a/imgs/icons/22068@2x.png b/imgs/icons/22068@2x.png index dcf478ac6..6dc5f6a0d 100644 Binary files a/imgs/icons/22068@2x.png and b/imgs/icons/22068@2x.png differ diff --git a/imgs/icons/22069@2x.png b/imgs/icons/22069@2x.png index 9aec8eede..2f421e641 100644 Binary files a/imgs/icons/22069@2x.png and b/imgs/icons/22069@2x.png differ diff --git a/imgs/icons/2206@2x.png b/imgs/icons/2206@2x.png index dc8a55277..1c3c8b8cb 100644 Binary files a/imgs/icons/2206@2x.png and b/imgs/icons/2206@2x.png differ diff --git a/imgs/icons/22073@1x.png b/imgs/icons/22073@1x.png index ee1670ff9..d560e33eb 100644 Binary files a/imgs/icons/22073@1x.png and b/imgs/icons/22073@1x.png differ diff --git a/imgs/icons/22073@2x.png b/imgs/icons/22073@2x.png index cee43430d..fb3f13f2f 100644 Binary files a/imgs/icons/22073@2x.png and b/imgs/icons/22073@2x.png differ diff --git a/imgs/icons/22074@1x.png b/imgs/icons/22074@1x.png new file mode 100644 index 000000000..d328b6475 Binary files /dev/null and b/imgs/icons/22074@1x.png differ diff --git a/imgs/icons/22074@2x.png b/imgs/icons/22074@2x.png new file mode 100644 index 000000000..75c5601df Binary files /dev/null and b/imgs/icons/22074@2x.png differ diff --git a/imgs/icons/22075@2x.png b/imgs/icons/22075@2x.png index f6fa83a1c..ba8b05d70 100644 Binary files a/imgs/icons/22075@2x.png and b/imgs/icons/22075@2x.png differ diff --git a/imgs/icons/22076@1x.png b/imgs/icons/22076@1x.png new file mode 100644 index 000000000..98f65be77 Binary files /dev/null and b/imgs/icons/22076@1x.png differ diff --git a/imgs/icons/22076@2x.png b/imgs/icons/22076@2x.png new file mode 100644 index 000000000..6eca10e4f Binary files /dev/null and b/imgs/icons/22076@2x.png differ diff --git a/imgs/icons/22091@1x.png b/imgs/icons/22091@1x.png new file mode 100644 index 000000000..188b855d0 Binary files /dev/null and b/imgs/icons/22091@1x.png differ diff --git a/imgs/icons/22091@2x.png b/imgs/icons/22091@2x.png new file mode 100644 index 000000000..eeaf226d3 Binary files /dev/null and b/imgs/icons/22091@2x.png differ diff --git a/imgs/icons/2210@2x.png b/imgs/icons/2210@2x.png index 7641e4eea..858bd7aaa 100644 Binary files a/imgs/icons/2210@2x.png and b/imgs/icons/2210@2x.png differ diff --git a/imgs/icons/2211@2x.png b/imgs/icons/2211@2x.png index fb82c9dc9..25ca2c728 100644 Binary files a/imgs/icons/2211@2x.png and b/imgs/icons/2211@2x.png differ diff --git a/imgs/icons/2213@2x.png b/imgs/icons/2213@2x.png index fd217f7f1..57502f030 100644 Binary files a/imgs/icons/2213@2x.png and b/imgs/icons/2213@2x.png differ diff --git a/imgs/icons/2214@2x.png b/imgs/icons/2214@2x.png index 438595b7e..5d913b6d9 100644 Binary files a/imgs/icons/2214@2x.png and b/imgs/icons/2214@2x.png differ diff --git a/imgs/icons/2215@2x.png b/imgs/icons/2215@2x.png index 7d07c5ea3..faeb26c95 100644 Binary files a/imgs/icons/2215@2x.png and b/imgs/icons/2215@2x.png differ diff --git a/imgs/icons/2216@2x.png b/imgs/icons/2216@2x.png index 3f3e98215..920f86c46 100644 Binary files a/imgs/icons/2216@2x.png and b/imgs/icons/2216@2x.png differ diff --git a/imgs/icons/2217@2x.png b/imgs/icons/2217@2x.png index 129d830ca..0754d7ad2 100644 Binary files a/imgs/icons/2217@2x.png and b/imgs/icons/2217@2x.png differ diff --git a/imgs/icons/2218@2x.png b/imgs/icons/2218@2x.png index 0b7818583..3cf919a05 100644 Binary files a/imgs/icons/2218@2x.png and b/imgs/icons/2218@2x.png differ diff --git a/imgs/icons/2219@2x.png b/imgs/icons/2219@2x.png index cff111ec4..3f9c2e74f 100644 Binary files a/imgs/icons/2219@2x.png and b/imgs/icons/2219@2x.png differ diff --git a/imgs/icons/2220@2x.png b/imgs/icons/2220@2x.png index 1702aa0ad..39028172e 100644 Binary files a/imgs/icons/2220@2x.png and b/imgs/icons/2220@2x.png differ diff --git a/imgs/icons/2221@2x.png b/imgs/icons/2221@2x.png index 1cfe40c8e..1bfb3de4a 100644 Binary files a/imgs/icons/2221@2x.png and b/imgs/icons/2221@2x.png differ diff --git a/imgs/icons/2222@2x.png b/imgs/icons/2222@2x.png index 65b715fba..c3fb24915 100644 Binary files a/imgs/icons/2222@2x.png and b/imgs/icons/2222@2x.png differ diff --git a/imgs/icons/2224@2x.png b/imgs/icons/2224@2x.png index dc61aa2f3..e7bacd337 100644 Binary files a/imgs/icons/2224@2x.png and b/imgs/icons/2224@2x.png differ diff --git a/imgs/icons/2226@2x.png b/imgs/icons/2226@2x.png index 2598ffbc3..1837560c1 100644 Binary files a/imgs/icons/2226@2x.png and b/imgs/icons/2226@2x.png differ diff --git a/imgs/icons/2228@2x.png b/imgs/icons/2228@2x.png index 7fbcf8a5c..18f69a8a8 100644 Binary files a/imgs/icons/2228@2x.png and b/imgs/icons/2228@2x.png differ diff --git a/imgs/icons/2229@2x.png b/imgs/icons/2229@2x.png index 145d68749..1a9c60832 100644 Binary files a/imgs/icons/2229@2x.png and b/imgs/icons/2229@2x.png differ diff --git a/imgs/icons/2230@2x.png b/imgs/icons/2230@2x.png index 9cdf9057a..f40bd6434 100644 Binary files a/imgs/icons/2230@2x.png and b/imgs/icons/2230@2x.png differ diff --git a/imgs/icons/2231@2x.png b/imgs/icons/2231@2x.png index e9db31b66..20dc0eea7 100644 Binary files a/imgs/icons/2231@2x.png and b/imgs/icons/2231@2x.png differ diff --git a/imgs/icons/2232@2x.png b/imgs/icons/2232@2x.png index 478c602d9..8267c5c18 100644 Binary files a/imgs/icons/2232@2x.png and b/imgs/icons/2232@2x.png differ diff --git a/imgs/icons/2234@2x.png b/imgs/icons/2234@2x.png index 54d9b125c..96303f387 100644 Binary files a/imgs/icons/2234@2x.png and b/imgs/icons/2234@2x.png differ diff --git a/imgs/icons/2244@2x.png b/imgs/icons/2244@2x.png index bca49745a..f7b12c3f7 100644 Binary files a/imgs/icons/2244@2x.png and b/imgs/icons/2244@2x.png differ diff --git a/imgs/icons/22@2x.png b/imgs/icons/22@2x.png index df9eb1347..c24b16b76 100644 Binary files a/imgs/icons/22@2x.png and b/imgs/icons/22@2x.png differ diff --git a/imgs/icons/2302@2x.png b/imgs/icons/2302@2x.png index b2cf13ea1..3c998c519 100644 Binary files a/imgs/icons/2302@2x.png and b/imgs/icons/2302@2x.png differ diff --git a/imgs/icons/2309@2x.png b/imgs/icons/2309@2x.png index d8aa17318..54d195df7 100644 Binary files a/imgs/icons/2309@2x.png and b/imgs/icons/2309@2x.png differ diff --git a/imgs/icons/230@2x.png b/imgs/icons/230@2x.png index 95a3ee52a..85daf8f72 100644 Binary files a/imgs/icons/230@2x.png and b/imgs/icons/230@2x.png differ diff --git a/imgs/icons/2310@2x.png b/imgs/icons/2310@2x.png index 76e17d689..c0624a2cb 100644 Binary files a/imgs/icons/2310@2x.png and b/imgs/icons/2310@2x.png differ diff --git a/imgs/icons/2311@2x.png b/imgs/icons/2311@2x.png index eabdefb96..a0b0788f1 100644 Binary files a/imgs/icons/2311@2x.png and b/imgs/icons/2311@2x.png differ diff --git a/imgs/icons/2312@2x.png b/imgs/icons/2312@2x.png index 4c6e68af6..851d0e33e 100644 Binary files a/imgs/icons/2312@2x.png and b/imgs/icons/2312@2x.png differ diff --git a/imgs/icons/2313@2x.png b/imgs/icons/2313@2x.png index 6c91961f4..47f83d535 100644 Binary files a/imgs/icons/2313@2x.png and b/imgs/icons/2313@2x.png differ diff --git a/imgs/icons/2314@2x.png b/imgs/icons/2314@2x.png index e71c229b4..be522a13a 100644 Binary files a/imgs/icons/2314@2x.png and b/imgs/icons/2314@2x.png differ diff --git a/imgs/icons/2315@2x.png b/imgs/icons/2315@2x.png index 7df852adf..6b85d3a6d 100644 Binary files a/imgs/icons/2315@2x.png and b/imgs/icons/2315@2x.png differ diff --git a/imgs/icons/2316@2x.png b/imgs/icons/2316@2x.png index 50163e61d..20b525297 100644 Binary files a/imgs/icons/2316@2x.png and b/imgs/icons/2316@2x.png differ diff --git a/imgs/icons/2317@2x.png b/imgs/icons/2317@2x.png index 05637990f..57dcf6006 100644 Binary files a/imgs/icons/2317@2x.png and b/imgs/icons/2317@2x.png differ diff --git a/imgs/icons/2318@2x.png b/imgs/icons/2318@2x.png index 84d434796..d238691ee 100644 Binary files a/imgs/icons/2318@2x.png and b/imgs/icons/2318@2x.png differ diff --git a/imgs/icons/2319@2x.png b/imgs/icons/2319@2x.png index 60ddfc7c6..aa63b8937 100644 Binary files a/imgs/icons/2319@2x.png and b/imgs/icons/2319@2x.png differ diff --git a/imgs/icons/2320@2x.png b/imgs/icons/2320@2x.png index caee6a41a..393dd9d5b 100644 Binary files a/imgs/icons/2320@2x.png and b/imgs/icons/2320@2x.png differ diff --git a/imgs/icons/2321@2x.png b/imgs/icons/2321@2x.png index f973a4e16..6c2163f12 100644 Binary files a/imgs/icons/2321@2x.png and b/imgs/icons/2321@2x.png differ diff --git a/imgs/icons/2322@2x.png b/imgs/icons/2322@2x.png index 2f3caddfb..7c1692ca5 100644 Binary files a/imgs/icons/2322@2x.png and b/imgs/icons/2322@2x.png differ diff --git a/imgs/icons/2323@2x.png b/imgs/icons/2323@2x.png index dda28d18d..9c31154ae 100644 Binary files a/imgs/icons/2323@2x.png and b/imgs/icons/2323@2x.png differ diff --git a/imgs/icons/2324@2x.png b/imgs/icons/2324@2x.png index 435529ede..eacb2d70f 100644 Binary files a/imgs/icons/2324@2x.png and b/imgs/icons/2324@2x.png differ diff --git a/imgs/icons/2325@2x.png b/imgs/icons/2325@2x.png index f7f3df55a..7d101f321 100644 Binary files a/imgs/icons/2325@2x.png and b/imgs/icons/2325@2x.png differ diff --git a/imgs/icons/2326@2x.png b/imgs/icons/2326@2x.png index a0bac727b..47014bb17 100644 Binary files a/imgs/icons/2326@2x.png and b/imgs/icons/2326@2x.png differ diff --git a/imgs/icons/2327@2x.png b/imgs/icons/2327@2x.png index f3bc777d1..15b0ae578 100644 Binary files a/imgs/icons/2327@2x.png and b/imgs/icons/2327@2x.png differ diff --git a/imgs/icons/2328@2x.png b/imgs/icons/2328@2x.png index 5026a07d5..35d09df6b 100644 Binary files a/imgs/icons/2328@2x.png and b/imgs/icons/2328@2x.png differ diff --git a/imgs/icons/2329@2x.png b/imgs/icons/2329@2x.png index be9a1a91b..c52fff2a6 100644 Binary files a/imgs/icons/2329@2x.png and b/imgs/icons/2329@2x.png differ diff --git a/imgs/icons/2330@2x.png b/imgs/icons/2330@2x.png index 54110d33c..2779db4d4 100644 Binary files a/imgs/icons/2330@2x.png and b/imgs/icons/2330@2x.png differ diff --git a/imgs/icons/2331@2x.png b/imgs/icons/2331@2x.png index 12052f74b..fa49f3bca 100644 Binary files a/imgs/icons/2331@2x.png and b/imgs/icons/2331@2x.png differ diff --git a/imgs/icons/2332@2x.png b/imgs/icons/2332@2x.png index aef3a094f..404215afb 100644 Binary files a/imgs/icons/2332@2x.png and b/imgs/icons/2332@2x.png differ diff --git a/imgs/icons/2333@1x.png b/imgs/icons/2333@1x.png index 5f2125b5a..661e63f15 100644 Binary files a/imgs/icons/2333@1x.png and b/imgs/icons/2333@1x.png differ diff --git a/imgs/icons/2333@2x.png b/imgs/icons/2333@2x.png index 281f573d2..4f4905f24 100644 Binary files a/imgs/icons/2333@2x.png and b/imgs/icons/2333@2x.png differ diff --git a/imgs/icons/2334@2x.png b/imgs/icons/2334@2x.png index b48d025f8..1835b2882 100644 Binary files a/imgs/icons/2334@2x.png and b/imgs/icons/2334@2x.png differ diff --git a/imgs/icons/2338@2x.png b/imgs/icons/2338@2x.png index ba5b5170d..192d37166 100644 Binary files a/imgs/icons/2338@2x.png and b/imgs/icons/2338@2x.png differ diff --git a/imgs/icons/2355@2x.png b/imgs/icons/2355@2x.png index b7a310028..b0a98bf8a 100644 Binary files a/imgs/icons/2355@2x.png and b/imgs/icons/2355@2x.png differ diff --git a/imgs/icons/2512@2x.png b/imgs/icons/2512@2x.png index c26c451bb..634b6b3c2 100644 Binary files a/imgs/icons/2512@2x.png and b/imgs/icons/2512@2x.png differ diff --git a/imgs/icons/2526@2x.png b/imgs/icons/2526@2x.png index 8a463fd14..2735eeee0 100644 Binary files a/imgs/icons/2526@2x.png and b/imgs/icons/2526@2x.png differ diff --git a/imgs/icons/2530@2x.png b/imgs/icons/2530@2x.png index b136984fc..626245440 100644 Binary files a/imgs/icons/2530@2x.png and b/imgs/icons/2530@2x.png differ diff --git a/imgs/icons/2532@2x.png b/imgs/icons/2532@2x.png index 538dc7cdc..2ec8afa75 100644 Binary files a/imgs/icons/2532@2x.png and b/imgs/icons/2532@2x.png differ diff --git a/imgs/icons/2536@2x.png b/imgs/icons/2536@2x.png index f93da8cd6..b01c2a2cf 100644 Binary files a/imgs/icons/2536@2x.png and b/imgs/icons/2536@2x.png differ diff --git a/imgs/icons/2538@2x.png b/imgs/icons/2538@2x.png index 8838454fe..050716cb2 100644 Binary files a/imgs/icons/2538@2x.png and b/imgs/icons/2538@2x.png differ diff --git a/imgs/icons/2539@2x.png b/imgs/icons/2539@2x.png index 972004cc1..4c06e53dc 100644 Binary files a/imgs/icons/2539@2x.png and b/imgs/icons/2539@2x.png differ diff --git a/imgs/icons/2540@2x.png b/imgs/icons/2540@2x.png index ae459602c..2640e74dd 100644 Binary files a/imgs/icons/2540@2x.png and b/imgs/icons/2540@2x.png differ diff --git a/imgs/icons/2541@2x.png b/imgs/icons/2541@2x.png index 9779498bb..d9c7e69c5 100644 Binary files a/imgs/icons/2541@2x.png and b/imgs/icons/2541@2x.png differ diff --git a/imgs/icons/2542@2x.png b/imgs/icons/2542@2x.png index 0a0e01119..f23154969 100644 Binary files a/imgs/icons/2542@2x.png and b/imgs/icons/2542@2x.png differ diff --git a/imgs/icons/2543@2x.png b/imgs/icons/2543@2x.png index 8f4ea4474..8b17bf537 100644 Binary files a/imgs/icons/2543@2x.png and b/imgs/icons/2543@2x.png differ diff --git a/imgs/icons/2544@2x.png b/imgs/icons/2544@2x.png index 92e51dc76..f37198222 100644 Binary files a/imgs/icons/2544@2x.png and b/imgs/icons/2544@2x.png differ diff --git a/imgs/icons/2545@2x.png b/imgs/icons/2545@2x.png index e9c6b41ca..c08bfa874 100644 Binary files a/imgs/icons/2545@2x.png and b/imgs/icons/2545@2x.png differ diff --git a/imgs/icons/2546@2x.png b/imgs/icons/2546@2x.png index 0e3ae6495..1cff3123b 100644 Binary files a/imgs/icons/2546@2x.png and b/imgs/icons/2546@2x.png differ diff --git a/imgs/icons/2547@2x.png b/imgs/icons/2547@2x.png index 080f71204..e8df6d6a2 100644 Binary files a/imgs/icons/2547@2x.png and b/imgs/icons/2547@2x.png differ diff --git a/imgs/icons/2548@2x.png b/imgs/icons/2548@2x.png index d475bc921..7d14da96c 100644 Binary files a/imgs/icons/2548@2x.png and b/imgs/icons/2548@2x.png differ diff --git a/imgs/icons/2549@2x.png b/imgs/icons/2549@2x.png index 95f6c991d..aed3ad785 100644 Binary files a/imgs/icons/2549@2x.png and b/imgs/icons/2549@2x.png differ diff --git a/imgs/icons/2550@1x.png b/imgs/icons/2550@1x.png index 12e6a9470..1186e3de4 100644 Binary files a/imgs/icons/2550@1x.png and b/imgs/icons/2550@1x.png differ diff --git a/imgs/icons/2550@2x.png b/imgs/icons/2550@2x.png index 3e5e65ab3..a1e0ca711 100644 Binary files a/imgs/icons/2550@2x.png and b/imgs/icons/2550@2x.png differ diff --git a/imgs/icons/2551@2x.png b/imgs/icons/2551@2x.png index 28dac8195..d720c7215 100644 Binary files a/imgs/icons/2551@2x.png and b/imgs/icons/2551@2x.png differ diff --git a/imgs/icons/2553@2x.png b/imgs/icons/2553@2x.png index 3b76ae376..0dfee28fa 100644 Binary files a/imgs/icons/2553@2x.png and b/imgs/icons/2553@2x.png differ diff --git a/imgs/icons/2554@2x.png b/imgs/icons/2554@2x.png index a963b53c1..024defe99 100644 Binary files a/imgs/icons/2554@2x.png and b/imgs/icons/2554@2x.png differ diff --git a/imgs/icons/2555@1x.png b/imgs/icons/2555@1x.png index b53e55bf9..69d95f96c 100644 Binary files a/imgs/icons/2555@1x.png and b/imgs/icons/2555@1x.png differ diff --git a/imgs/icons/2555@2x.png b/imgs/icons/2555@2x.png index 5770f3225..1271c5ee3 100644 Binary files a/imgs/icons/2555@2x.png and b/imgs/icons/2555@2x.png differ diff --git a/imgs/icons/2556@2x.png b/imgs/icons/2556@2x.png index 351c0c86b..803bb3949 100644 Binary files a/imgs/icons/2556@2x.png and b/imgs/icons/2556@2x.png differ diff --git a/imgs/icons/2557@2x.png b/imgs/icons/2557@2x.png index a876a42f7..5d87608ff 100644 Binary files a/imgs/icons/2557@2x.png and b/imgs/icons/2557@2x.png differ diff --git a/imgs/icons/2558@2x.png b/imgs/icons/2558@2x.png index c90b51c24..b412a0a35 100644 Binary files a/imgs/icons/2558@2x.png and b/imgs/icons/2558@2x.png differ diff --git a/imgs/icons/2559@2x.png b/imgs/icons/2559@2x.png index c0fce0999..f3da64949 100644 Binary files a/imgs/icons/2559@2x.png and b/imgs/icons/2559@2x.png differ diff --git a/imgs/icons/2560@1x.png b/imgs/icons/2560@1x.png index d65419db8..124b76572 100644 Binary files a/imgs/icons/2560@1x.png and b/imgs/icons/2560@1x.png differ diff --git a/imgs/icons/2560@2x.png b/imgs/icons/2560@2x.png index 47a151d62..4405997ed 100644 Binary files a/imgs/icons/2560@2x.png and b/imgs/icons/2560@2x.png differ diff --git a/imgs/icons/2563@2x.png b/imgs/icons/2563@2x.png index 3d612f426..d7985abe9 100644 Binary files a/imgs/icons/2563@2x.png and b/imgs/icons/2563@2x.png differ diff --git a/imgs/icons/2567@2x.png b/imgs/icons/2567@2x.png index 81531168d..4a447c25d 100644 Binary files a/imgs/icons/2567@2x.png and b/imgs/icons/2567@2x.png differ diff --git a/imgs/icons/2568@2x.png b/imgs/icons/2568@2x.png index e162bea87..8bae3f0a8 100644 Binary files a/imgs/icons/2568@2x.png and b/imgs/icons/2568@2x.png differ diff --git a/imgs/icons/2569@2x.png b/imgs/icons/2569@2x.png index ef6ae669b..87051fc33 100644 Binary files a/imgs/icons/2569@2x.png and b/imgs/icons/2569@2x.png differ diff --git a/imgs/icons/2570@2x.png b/imgs/icons/2570@2x.png index 0f78f470f..a3a60b167 100644 Binary files a/imgs/icons/2570@2x.png and b/imgs/icons/2570@2x.png differ diff --git a/imgs/icons/2571@2x.png b/imgs/icons/2571@2x.png index fad560c2b..558f872b3 100644 Binary files a/imgs/icons/2571@2x.png and b/imgs/icons/2571@2x.png differ diff --git a/imgs/icons/2572@2x.png b/imgs/icons/2572@2x.png index 369e95430..af6056960 100644 Binary files a/imgs/icons/2572@2x.png and b/imgs/icons/2572@2x.png differ diff --git a/imgs/icons/2573@2x.png b/imgs/icons/2573@2x.png index 0a91c6345..7198f631a 100644 Binary files a/imgs/icons/2573@2x.png and b/imgs/icons/2573@2x.png differ diff --git a/imgs/icons/2574@2x.png b/imgs/icons/2574@2x.png index 85037e521..bda0a8760 100644 Binary files a/imgs/icons/2574@2x.png and b/imgs/icons/2574@2x.png differ diff --git a/imgs/icons/2575@2x.png b/imgs/icons/2575@2x.png index 5dd0a7815..126d83985 100644 Binary files a/imgs/icons/2575@2x.png and b/imgs/icons/2575@2x.png differ diff --git a/imgs/icons/2576@2x.png b/imgs/icons/2576@2x.png index 429ce8fb5..6c3e01e54 100644 Binary files a/imgs/icons/2576@2x.png and b/imgs/icons/2576@2x.png differ diff --git a/imgs/icons/2577@2x.png b/imgs/icons/2577@2x.png index bb029e1a0..7daabf14b 100644 Binary files a/imgs/icons/2577@2x.png and b/imgs/icons/2577@2x.png differ diff --git a/imgs/icons/2578@2x.png b/imgs/icons/2578@2x.png index 2556b2bde..cad4ee6ef 100644 Binary files a/imgs/icons/2578@2x.png and b/imgs/icons/2578@2x.png differ diff --git a/imgs/icons/2579@2x.png b/imgs/icons/2579@2x.png index 316fb058a..9978bcccd 100644 Binary files a/imgs/icons/2579@2x.png and b/imgs/icons/2579@2x.png differ diff --git a/imgs/icons/2580@2x.png b/imgs/icons/2580@2x.png index abb502b87..d3e38338d 100644 Binary files a/imgs/icons/2580@2x.png and b/imgs/icons/2580@2x.png differ diff --git a/imgs/icons/2581@2x.png b/imgs/icons/2581@2x.png index 919d962f2..3a432bd6d 100644 Binary files a/imgs/icons/2581@2x.png and b/imgs/icons/2581@2x.png differ diff --git a/imgs/icons/2582@1x.png b/imgs/icons/2582@1x.png index 93ec9eacd..e6e344e95 100644 Binary files a/imgs/icons/2582@1x.png and b/imgs/icons/2582@1x.png differ diff --git a/imgs/icons/2582@2x.png b/imgs/icons/2582@2x.png index a046ca541..f751cbfc1 100644 Binary files a/imgs/icons/2582@2x.png and b/imgs/icons/2582@2x.png differ diff --git a/imgs/icons/2645@2x.png b/imgs/icons/2645@2x.png index ee0afea5a..18dce6ecc 100644 Binary files a/imgs/icons/2645@2x.png and b/imgs/icons/2645@2x.png differ diff --git a/imgs/icons/2646@2x.png b/imgs/icons/2646@2x.png index 446e13fae..3606d94dd 100644 Binary files a/imgs/icons/2646@2x.png and b/imgs/icons/2646@2x.png differ diff --git a/imgs/icons/2647@2x.png b/imgs/icons/2647@2x.png index 9ca09c00e..6b7d47ff5 100644 Binary files a/imgs/icons/2647@2x.png and b/imgs/icons/2647@2x.png differ diff --git a/imgs/icons/2649@2x.png b/imgs/icons/2649@2x.png index 5f3bea144..5fb6fa76b 100644 Binary files a/imgs/icons/2649@2x.png and b/imgs/icons/2649@2x.png differ diff --git a/imgs/icons/2652@2x.png b/imgs/icons/2652@2x.png index 5c948bd4e..2a191f271 100644 Binary files a/imgs/icons/2652@2x.png and b/imgs/icons/2652@2x.png differ diff --git a/imgs/icons/2653@2x.png b/imgs/icons/2653@2x.png index 786395c79..73a672c55 100644 Binary files a/imgs/icons/2653@2x.png and b/imgs/icons/2653@2x.png differ diff --git a/imgs/icons/2654@2x.png b/imgs/icons/2654@2x.png index 486503233..9516d96f3 100644 Binary files a/imgs/icons/2654@2x.png and b/imgs/icons/2654@2x.png differ diff --git a/imgs/icons/2655@2x.png b/imgs/icons/2655@2x.png index 01697cce4..ad32b4102 100644 Binary files a/imgs/icons/2655@2x.png and b/imgs/icons/2655@2x.png differ diff --git a/imgs/icons/2656@2x.png b/imgs/icons/2656@2x.png index 3e1d433d5..9e6215f2c 100644 Binary files a/imgs/icons/2656@2x.png and b/imgs/icons/2656@2x.png differ diff --git a/imgs/icons/2657@2x.png b/imgs/icons/2657@2x.png index 401eff704..d26068140 100644 Binary files a/imgs/icons/2657@2x.png and b/imgs/icons/2657@2x.png differ diff --git a/imgs/icons/2658@2x.png b/imgs/icons/2658@2x.png index 0b3836272..c8bec31b4 100644 Binary files a/imgs/icons/2658@2x.png and b/imgs/icons/2658@2x.png differ diff --git a/imgs/icons/2659@2x.png b/imgs/icons/2659@2x.png index 920bdd4f3..11439f0c3 100644 Binary files a/imgs/icons/2659@2x.png and b/imgs/icons/2659@2x.png differ diff --git a/imgs/icons/2660@2x.png b/imgs/icons/2660@2x.png index f4831166e..9aaf1fb43 100644 Binary files a/imgs/icons/2660@2x.png and b/imgs/icons/2660@2x.png differ diff --git a/imgs/icons/2661@2x.png b/imgs/icons/2661@2x.png index 2d1a4a321..f96db883e 100644 Binary files a/imgs/icons/2661@2x.png and b/imgs/icons/2661@2x.png differ diff --git a/imgs/icons/2663@2x.png b/imgs/icons/2663@2x.png index 4270c3668..339fb06d1 100644 Binary files a/imgs/icons/2663@2x.png and b/imgs/icons/2663@2x.png differ diff --git a/imgs/icons/2665@2x.png b/imgs/icons/2665@2x.png index 0952bd0d7..d74c1080a 100644 Binary files a/imgs/icons/2665@2x.png and b/imgs/icons/2665@2x.png differ diff --git a/imgs/icons/2666@2x.png b/imgs/icons/2666@2x.png index 3d0a6e3ee..3a21586e7 100644 Binary files a/imgs/icons/2666@2x.png and b/imgs/icons/2666@2x.png differ diff --git a/imgs/icons/2667@2x.png b/imgs/icons/2667@2x.png index ead868c5c..10e006ba8 100644 Binary files a/imgs/icons/2667@2x.png and b/imgs/icons/2667@2x.png differ diff --git a/imgs/icons/2668@2x.png b/imgs/icons/2668@2x.png index 64a31a939..ca21ab912 100644 Binary files a/imgs/icons/2668@2x.png and b/imgs/icons/2668@2x.png differ diff --git a/imgs/icons/2669@2x.png b/imgs/icons/2669@2x.png index afe622492..5f3aae4c1 100644 Binary files a/imgs/icons/2669@2x.png and b/imgs/icons/2669@2x.png differ diff --git a/imgs/icons/2670@2x.png b/imgs/icons/2670@2x.png index 625e98621..20bef6a78 100644 Binary files a/imgs/icons/2670@2x.png and b/imgs/icons/2670@2x.png differ diff --git a/imgs/icons/2674@2x.png b/imgs/icons/2674@2x.png index 8c19459f4..ca74a9209 100644 Binary files a/imgs/icons/2674@2x.png and b/imgs/icons/2674@2x.png differ diff --git a/imgs/icons/2677@2x.png b/imgs/icons/2677@2x.png index de42f4b6d..f910a6bb9 100644 Binary files a/imgs/icons/2677@2x.png and b/imgs/icons/2677@2x.png differ diff --git a/imgs/icons/2678@2x.png b/imgs/icons/2678@2x.png index b448300dc..894cdbde2 100644 Binary files a/imgs/icons/2678@2x.png and b/imgs/icons/2678@2x.png differ diff --git a/imgs/icons/2680@2x.png b/imgs/icons/2680@2x.png index 95978d6ec..26b43f3e0 100644 Binary files a/imgs/icons/2680@2x.png and b/imgs/icons/2680@2x.png differ diff --git a/imgs/icons/2681@2x.png b/imgs/icons/2681@2x.png index 8ccd0fb4d..bd2e32046 100644 Binary files a/imgs/icons/2681@2x.png and b/imgs/icons/2681@2x.png differ diff --git a/imgs/icons/2682@2x.png b/imgs/icons/2682@2x.png index 7c882479f..b26cec5a6 100644 Binary files a/imgs/icons/2682@2x.png and b/imgs/icons/2682@2x.png differ diff --git a/imgs/icons/2683@2x.png b/imgs/icons/2683@2x.png index e655fa953..84344865c 100644 Binary files a/imgs/icons/2683@2x.png and b/imgs/icons/2683@2x.png differ diff --git a/imgs/icons/2684@2x.png b/imgs/icons/2684@2x.png index dcc8a0909..751429c2d 100644 Binary files a/imgs/icons/2684@2x.png and b/imgs/icons/2684@2x.png differ diff --git a/imgs/icons/2685@2x.png b/imgs/icons/2685@2x.png index a57cd1afd..aaaa3bf99 100644 Binary files a/imgs/icons/2685@2x.png and b/imgs/icons/2685@2x.png differ diff --git a/imgs/icons/2686@2x.png b/imgs/icons/2686@2x.png index e705d3dd6..844898bbf 100644 Binary files a/imgs/icons/2686@2x.png and b/imgs/icons/2686@2x.png differ diff --git a/imgs/icons/2696@2x.png b/imgs/icons/2696@2x.png index 304944c73..ebbbeeaac 100644 Binary files a/imgs/icons/2696@2x.png and b/imgs/icons/2696@2x.png differ diff --git a/imgs/icons/2697@2x.png b/imgs/icons/2697@2x.png index 134845e12..bb6eeb8b5 100644 Binary files a/imgs/icons/2697@2x.png and b/imgs/icons/2697@2x.png differ diff --git a/imgs/icons/2698@2x.png b/imgs/icons/2698@2x.png index 5fce96d42..0292bb805 100644 Binary files a/imgs/icons/2698@2x.png and b/imgs/icons/2698@2x.png differ diff --git a/imgs/icons/2699@2x.png b/imgs/icons/2699@2x.png index 5b1cab18f..4287bfc39 100644 Binary files a/imgs/icons/2699@2x.png and b/imgs/icons/2699@2x.png differ diff --git a/imgs/icons/26@2x.png b/imgs/icons/26@2x.png index d06ca5748..3f2a92152 100644 Binary files a/imgs/icons/26@2x.png and b/imgs/icons/26@2x.png differ diff --git a/imgs/icons/2701@2x.png b/imgs/icons/2701@2x.png index bb878b1dc..94dfcd6b0 100644 Binary files a/imgs/icons/2701@2x.png and b/imgs/icons/2701@2x.png differ diff --git a/imgs/icons/2702@1x.png b/imgs/icons/2702@1x.png index a1232ca10..ba57a520c 100644 Binary files a/imgs/icons/2702@1x.png and b/imgs/icons/2702@1x.png differ diff --git a/imgs/icons/2702@2x.png b/imgs/icons/2702@2x.png index 11879a70a..b08dcbe10 100644 Binary files a/imgs/icons/2702@2x.png and b/imgs/icons/2702@2x.png differ diff --git a/imgs/icons/2703@2x.png b/imgs/icons/2703@2x.png index 779466c39..5ea0812bb 100644 Binary files a/imgs/icons/2703@2x.png and b/imgs/icons/2703@2x.png differ diff --git a/imgs/icons/2705@2x.png b/imgs/icons/2705@2x.png index 25d69fc23..912ff2321 100644 Binary files a/imgs/icons/2705@2x.png and b/imgs/icons/2705@2x.png differ diff --git a/imgs/icons/2732@2x.png b/imgs/icons/2732@2x.png index 5a9dc51f7..1358a6cba 100644 Binary files a/imgs/icons/2732@2x.png and b/imgs/icons/2732@2x.png differ diff --git a/imgs/icons/2754@2x.png b/imgs/icons/2754@2x.png index f0ca4678f..d0321c7ff 100644 Binary files a/imgs/icons/2754@2x.png and b/imgs/icons/2754@2x.png differ diff --git a/imgs/icons/2827@2x.png b/imgs/icons/2827@2x.png index cf74dc86c..97484cb82 100644 Binary files a/imgs/icons/2827@2x.png and b/imgs/icons/2827@2x.png differ diff --git a/imgs/icons/2828@2x.png b/imgs/icons/2828@2x.png index c26f96fd9..520afd27b 100644 Binary files a/imgs/icons/2828@2x.png and b/imgs/icons/2828@2x.png differ diff --git a/imgs/icons/2829@2x.png b/imgs/icons/2829@2x.png index 1ff22ee51..3fad3fd8a 100644 Binary files a/imgs/icons/2829@2x.png and b/imgs/icons/2829@2x.png differ diff --git a/imgs/icons/2830@2x.png b/imgs/icons/2830@2x.png index 58c4ede4e..3c8047a5d 100644 Binary files a/imgs/icons/2830@2x.png and b/imgs/icons/2830@2x.png differ diff --git a/imgs/icons/2831@2x.png b/imgs/icons/2831@2x.png index fba1c6ff8..d1aee102d 100644 Binary files a/imgs/icons/2831@2x.png and b/imgs/icons/2831@2x.png differ diff --git a/imgs/icons/2832@2x.png b/imgs/icons/2832@2x.png index 0e3b008f4..623868539 100644 Binary files a/imgs/icons/2832@2x.png and b/imgs/icons/2832@2x.png differ diff --git a/imgs/icons/2833@2x.png b/imgs/icons/2833@2x.png index dfc8a65e7..3c7b4e95b 100644 Binary files a/imgs/icons/2833@2x.png and b/imgs/icons/2833@2x.png differ diff --git a/imgs/icons/2834@2x.png b/imgs/icons/2834@2x.png index 9cd4b5ac8..864c8f144 100644 Binary files a/imgs/icons/2834@2x.png and b/imgs/icons/2834@2x.png differ diff --git a/imgs/icons/2836@2x.png b/imgs/icons/2836@2x.png index a735749be..5b3e79cca 100644 Binary files a/imgs/icons/2836@2x.png and b/imgs/icons/2836@2x.png differ diff --git a/imgs/icons/2837@2x.png b/imgs/icons/2837@2x.png index c60d843fe..4c1704b1c 100644 Binary files a/imgs/icons/2837@2x.png and b/imgs/icons/2837@2x.png differ diff --git a/imgs/icons/2839@2x.png b/imgs/icons/2839@2x.png index 686028ca2..3b9911877 100644 Binary files a/imgs/icons/2839@2x.png and b/imgs/icons/2839@2x.png differ diff --git a/imgs/icons/2843@2x.png b/imgs/icons/2843@2x.png index 333ffe46b..657247b5b 100644 Binary files a/imgs/icons/2843@2x.png and b/imgs/icons/2843@2x.png differ diff --git a/imgs/icons/2844@2x.png b/imgs/icons/2844@2x.png index 5182f8092..a0e8ab0fe 100644 Binary files a/imgs/icons/2844@2x.png and b/imgs/icons/2844@2x.png differ diff --git a/imgs/icons/2845@2x.png b/imgs/icons/2845@2x.png index 1eac60862..a4a670467 100644 Binary files a/imgs/icons/2845@2x.png and b/imgs/icons/2845@2x.png differ diff --git a/imgs/icons/2846@2x.png b/imgs/icons/2846@2x.png index 051039330..927318d37 100644 Binary files a/imgs/icons/2846@2x.png and b/imgs/icons/2846@2x.png differ diff --git a/imgs/icons/2847@2x.png b/imgs/icons/2847@2x.png index 99b940616..66e198723 100644 Binary files a/imgs/icons/2847@2x.png and b/imgs/icons/2847@2x.png differ diff --git a/imgs/icons/2848@2x.png b/imgs/icons/2848@2x.png index d3aa1f7e3..4a533cc59 100644 Binary files a/imgs/icons/2848@2x.png and b/imgs/icons/2848@2x.png differ diff --git a/imgs/icons/2849@2x.png b/imgs/icons/2849@2x.png index cfe2ebfcc..5b4dd6471 100644 Binary files a/imgs/icons/2849@2x.png and b/imgs/icons/2849@2x.png differ diff --git a/imgs/icons/2850@2x.png b/imgs/icons/2850@2x.png index 9e7dcb949..1e70c92dd 100644 Binary files a/imgs/icons/2850@2x.png and b/imgs/icons/2850@2x.png differ diff --git a/imgs/icons/2851@2x.png b/imgs/icons/2851@2x.png index 4d6279fc7..055fceb43 100644 Binary files a/imgs/icons/2851@2x.png and b/imgs/icons/2851@2x.png differ diff --git a/imgs/icons/2853@2x.png b/imgs/icons/2853@2x.png index d9221df98..99eb97624 100644 Binary files a/imgs/icons/2853@2x.png and b/imgs/icons/2853@2x.png differ diff --git a/imgs/icons/2855@2x.png b/imgs/icons/2855@2x.png index 83fce2feb..e6b5e6546 100644 Binary files a/imgs/icons/2855@2x.png and b/imgs/icons/2855@2x.png differ diff --git a/imgs/icons/2856@2x.png b/imgs/icons/2856@2x.png index 56e6606a9..34307c522 100644 Binary files a/imgs/icons/2856@2x.png and b/imgs/icons/2856@2x.png differ diff --git a/imgs/icons/2857@2x.png b/imgs/icons/2857@2x.png index 9b603ba88..f10afe38e 100644 Binary files a/imgs/icons/2857@2x.png and b/imgs/icons/2857@2x.png differ diff --git a/imgs/icons/2858@2x.png b/imgs/icons/2858@2x.png index 3342c01cc..7299e8090 100644 Binary files a/imgs/icons/2858@2x.png and b/imgs/icons/2858@2x.png differ diff --git a/imgs/icons/2859@2x.png b/imgs/icons/2859@2x.png index 0d8ca4560..b280ffbfd 100644 Binary files a/imgs/icons/2859@2x.png and b/imgs/icons/2859@2x.png differ diff --git a/imgs/icons/2861@2x.png b/imgs/icons/2861@2x.png index e0fb41c8f..f3a4295e8 100644 Binary files a/imgs/icons/2861@2x.png and b/imgs/icons/2861@2x.png differ diff --git a/imgs/icons/2862@2x.png b/imgs/icons/2862@2x.png index d45b4f9cf..b0d3f1577 100644 Binary files a/imgs/icons/2862@2x.png and b/imgs/icons/2862@2x.png differ diff --git a/imgs/icons/2863@1x.png b/imgs/icons/2863@1x.png index 8199c3613..690a8bd17 100644 Binary files a/imgs/icons/2863@1x.png and b/imgs/icons/2863@1x.png differ diff --git a/imgs/icons/2863@2x.png b/imgs/icons/2863@2x.png index f0a73e27f..42239d839 100644 Binary files a/imgs/icons/2863@2x.png and b/imgs/icons/2863@2x.png differ diff --git a/imgs/icons/2864@2x.png b/imgs/icons/2864@2x.png index 5b119ec43..96686ccaa 100644 Binary files a/imgs/icons/2864@2x.png and b/imgs/icons/2864@2x.png differ diff --git a/imgs/icons/2865@2x.png b/imgs/icons/2865@2x.png index ecf2ef777..1e4f10f6a 100644 Binary files a/imgs/icons/2865@2x.png and b/imgs/icons/2865@2x.png differ diff --git a/imgs/icons/2866@2x.png b/imgs/icons/2866@2x.png index 6d5684728..66c241db8 100644 Binary files a/imgs/icons/2866@2x.png and b/imgs/icons/2866@2x.png differ diff --git a/imgs/icons/2867@2x.png b/imgs/icons/2867@2x.png index ab30aab95..7c4598ea6 100644 Binary files a/imgs/icons/2867@2x.png and b/imgs/icons/2867@2x.png differ diff --git a/imgs/icons/2868@2x.png b/imgs/icons/2868@2x.png index cbb8802c9..2f66a10a9 100644 Binary files a/imgs/icons/2868@2x.png and b/imgs/icons/2868@2x.png differ diff --git a/imgs/icons/2869@2x.png b/imgs/icons/2869@2x.png index 9299e268c..4132c32c1 100644 Binary files a/imgs/icons/2869@2x.png and b/imgs/icons/2869@2x.png differ diff --git a/imgs/icons/2870@2x.png b/imgs/icons/2870@2x.png index 2be6d9bb0..e0bed2dd7 100644 Binary files a/imgs/icons/2870@2x.png and b/imgs/icons/2870@2x.png differ diff --git a/imgs/icons/2871@2x.png b/imgs/icons/2871@2x.png index 432643a7f..10bbaa222 100644 Binary files a/imgs/icons/2871@2x.png and b/imgs/icons/2871@2x.png differ diff --git a/imgs/icons/2872@2x.png b/imgs/icons/2872@2x.png index 4631b4b8e..cb1ce3011 100644 Binary files a/imgs/icons/2872@2x.png and b/imgs/icons/2872@2x.png differ diff --git a/imgs/icons/2873@2x.png b/imgs/icons/2873@2x.png index 497926906..63750465f 100644 Binary files a/imgs/icons/2873@2x.png and b/imgs/icons/2873@2x.png differ diff --git a/imgs/icons/2875@2x.png b/imgs/icons/2875@2x.png index ba8d882ed..66f762a78 100644 Binary files a/imgs/icons/2875@2x.png and b/imgs/icons/2875@2x.png differ diff --git a/imgs/icons/2876@2x.png b/imgs/icons/2876@2x.png index d7a4854e8..6fb1a0322 100644 Binary files a/imgs/icons/2876@2x.png and b/imgs/icons/2876@2x.png differ diff --git a/imgs/icons/2878@2x.png b/imgs/icons/2878@2x.png index 4fd6f537b..6ed13f826 100644 Binary files a/imgs/icons/2878@2x.png and b/imgs/icons/2878@2x.png differ diff --git a/imgs/icons/2879@2x.png b/imgs/icons/2879@2x.png index 7f22855d0..49a18c6c4 100644 Binary files a/imgs/icons/2879@2x.png and b/imgs/icons/2879@2x.png differ diff --git a/imgs/icons/2880@2x.png b/imgs/icons/2880@2x.png index acf3590a1..31c2bd7df 100644 Binary files a/imgs/icons/2880@2x.png and b/imgs/icons/2880@2x.png differ diff --git a/imgs/icons/2882@2x.png b/imgs/icons/2882@2x.png index 84f0f8a0f..06b5f5dd1 100644 Binary files a/imgs/icons/2882@2x.png and b/imgs/icons/2882@2x.png differ diff --git a/imgs/icons/2883@2x.png b/imgs/icons/2883@2x.png index 7032fe735..5e5071855 100644 Binary files a/imgs/icons/2883@2x.png and b/imgs/icons/2883@2x.png differ diff --git a/imgs/icons/2885@2x.png b/imgs/icons/2885@2x.png index 5a99cdd01..f1ef15f78 100644 Binary files a/imgs/icons/2885@2x.png and b/imgs/icons/2885@2x.png differ diff --git a/imgs/icons/2886@2x.png b/imgs/icons/2886@2x.png index cbb815732..0e1df9e7e 100644 Binary files a/imgs/icons/2886@2x.png and b/imgs/icons/2886@2x.png differ diff --git a/imgs/icons/2887@2x.png b/imgs/icons/2887@2x.png index 832fea9c9..90f10ba2f 100644 Binary files a/imgs/icons/2887@2x.png and b/imgs/icons/2887@2x.png differ diff --git a/imgs/icons/2889@2x.png b/imgs/icons/2889@2x.png index 0125f2843..696b298e4 100644 Binary files a/imgs/icons/2889@2x.png and b/imgs/icons/2889@2x.png differ diff --git a/imgs/icons/2890@2x.png b/imgs/icons/2890@2x.png index 52b8fcdba..39ba99d8c 100644 Binary files a/imgs/icons/2890@2x.png and b/imgs/icons/2890@2x.png differ diff --git a/imgs/icons/2891@2x.png b/imgs/icons/2891@2x.png index 7cf2ec22b..bb0a459ce 100644 Binary files a/imgs/icons/2891@2x.png and b/imgs/icons/2891@2x.png differ diff --git a/imgs/icons/2893@2x.png b/imgs/icons/2893@2x.png index ccd422d57..e410f3b15 100644 Binary files a/imgs/icons/2893@2x.png and b/imgs/icons/2893@2x.png differ diff --git a/imgs/icons/28@2x.png b/imgs/icons/28@2x.png index 62e81003a..8e38a7384 100644 Binary files a/imgs/icons/28@2x.png and b/imgs/icons/28@2x.png differ diff --git a/imgs/icons/2908@2x.png b/imgs/icons/2908@2x.png index 4309c2e2d..acafedef6 100644 Binary files a/imgs/icons/2908@2x.png and b/imgs/icons/2908@2x.png differ diff --git a/imgs/icons/2934@2x.png b/imgs/icons/2934@2x.png index b87ff9025..46862aad9 100644 Binary files a/imgs/icons/2934@2x.png and b/imgs/icons/2934@2x.png differ diff --git a/imgs/icons/293@2x.png b/imgs/icons/293@2x.png index 83da1e521..0ad87dfd7 100644 Binary files a/imgs/icons/293@2x.png and b/imgs/icons/293@2x.png differ diff --git a/imgs/icons/294@2x.png b/imgs/icons/294@2x.png index 510f1e4a8..ed241300f 100644 Binary files a/imgs/icons/294@2x.png and b/imgs/icons/294@2x.png differ diff --git a/imgs/icons/295@2x.png b/imgs/icons/295@2x.png index 142568c04..acd665f71 100644 Binary files a/imgs/icons/295@2x.png and b/imgs/icons/295@2x.png differ diff --git a/imgs/icons/2985@2x.png b/imgs/icons/2985@2x.png index 186c7bff6..c755114ee 100644 Binary files a/imgs/icons/2985@2x.png and b/imgs/icons/2985@2x.png differ diff --git a/imgs/icons/2986@2x.png b/imgs/icons/2986@2x.png index 7f43bcaf4..98e344cbf 100644 Binary files a/imgs/icons/2986@2x.png and b/imgs/icons/2986@2x.png differ diff --git a/imgs/icons/2988@2x.png b/imgs/icons/2988@2x.png index 501095a06..4171e79dd 100644 Binary files a/imgs/icons/2988@2x.png and b/imgs/icons/2988@2x.png differ diff --git a/imgs/icons/2989@2x.png b/imgs/icons/2989@2x.png index 121fdbf21..30efcc8d9 100644 Binary files a/imgs/icons/2989@2x.png and b/imgs/icons/2989@2x.png differ diff --git a/imgs/icons/2990@2x.png b/imgs/icons/2990@2x.png index 8f7c272a4..f6360d1c5 100644 Binary files a/imgs/icons/2990@2x.png and b/imgs/icons/2990@2x.png differ diff --git a/imgs/icons/2991@2x.png b/imgs/icons/2991@2x.png index fd6402846..faaef62a8 100644 Binary files a/imgs/icons/2991@2x.png and b/imgs/icons/2991@2x.png differ diff --git a/imgs/icons/2992@2x.png b/imgs/icons/2992@2x.png index dca479df3..73d9501ec 100644 Binary files a/imgs/icons/2992@2x.png and b/imgs/icons/2992@2x.png differ diff --git a/imgs/icons/29@2x.png b/imgs/icons/29@2x.png index 47ea3ded8..664c64de4 100644 Binary files a/imgs/icons/29@2x.png and b/imgs/icons/29@2x.png differ diff --git a/imgs/icons/3000@2x.png b/imgs/icons/3000@2x.png index 63679897b..8a01808c7 100644 Binary files a/imgs/icons/3000@2x.png and b/imgs/icons/3000@2x.png differ diff --git a/imgs/icons/3001@2x.png b/imgs/icons/3001@2x.png index 858245cb5..f5c84d682 100644 Binary files a/imgs/icons/3001@2x.png and b/imgs/icons/3001@2x.png differ diff --git a/imgs/icons/3010@2x.png b/imgs/icons/3010@2x.png index 0078a55fb..bbf526e8a 100644 Binary files a/imgs/icons/3010@2x.png and b/imgs/icons/3010@2x.png differ diff --git a/imgs/icons/3012@2x.png b/imgs/icons/3012@2x.png index a5aa7e5bc..b29ae8153 100644 Binary files a/imgs/icons/3012@2x.png and b/imgs/icons/3012@2x.png differ diff --git a/imgs/icons/3019@2x.png b/imgs/icons/3019@2x.png index 1fb124229..0ad333e28 100644 Binary files a/imgs/icons/3019@2x.png and b/imgs/icons/3019@2x.png differ diff --git a/imgs/icons/3025@2x.png b/imgs/icons/3025@2x.png index 828166088..ff97b29b1 100644 Binary files a/imgs/icons/3025@2x.png and b/imgs/icons/3025@2x.png differ diff --git a/imgs/icons/3031@2x.png b/imgs/icons/3031@2x.png index 2f3080cf0..ae64da9bb 100644 Binary files a/imgs/icons/3031@2x.png and b/imgs/icons/3031@2x.png differ diff --git a/imgs/icons/3036@2x.png b/imgs/icons/3036@2x.png index 66cfe33b4..5d57c08c0 100644 Binary files a/imgs/icons/3036@2x.png and b/imgs/icons/3036@2x.png differ diff --git a/imgs/icons/3181@2x.png b/imgs/icons/3181@2x.png index 8e0f60ba6..0c557545f 100644 Binary files a/imgs/icons/3181@2x.png and b/imgs/icons/3181@2x.png differ diff --git a/imgs/icons/3182@2x.png b/imgs/icons/3182@2x.png index 0b5443ca8..797a44317 100644 Binary files a/imgs/icons/3182@2x.png and b/imgs/icons/3182@2x.png differ diff --git a/imgs/icons/3183@2x.png b/imgs/icons/3183@2x.png index 685e27b5b..aeffaa2e4 100644 Binary files a/imgs/icons/3183@2x.png and b/imgs/icons/3183@2x.png differ diff --git a/imgs/icons/3184@2x.png b/imgs/icons/3184@2x.png index 7bf256351..93a07d5ec 100644 Binary files a/imgs/icons/3184@2x.png and b/imgs/icons/3184@2x.png differ diff --git a/imgs/icons/3185@2x.png b/imgs/icons/3185@2x.png index 96bf68d82..a99d1c578 100644 Binary files a/imgs/icons/3185@2x.png and b/imgs/icons/3185@2x.png differ diff --git a/imgs/icons/3186@2x.png b/imgs/icons/3186@2x.png index 2cf3d5a1a..b0386c47f 100644 Binary files a/imgs/icons/3186@2x.png and b/imgs/icons/3186@2x.png differ diff --git a/imgs/icons/3187@2x.png b/imgs/icons/3187@2x.png index 227ab19f8..2410b75e8 100644 Binary files a/imgs/icons/3187@2x.png and b/imgs/icons/3187@2x.png differ diff --git a/imgs/icons/3188@2x.png b/imgs/icons/3188@2x.png index f7d069d45..37717c810 100644 Binary files a/imgs/icons/3188@2x.png and b/imgs/icons/3188@2x.png differ diff --git a/imgs/icons/3189@2x.png b/imgs/icons/3189@2x.png index 99946eb01..d226624dd 100644 Binary files a/imgs/icons/3189@2x.png and b/imgs/icons/3189@2x.png differ diff --git a/imgs/icons/3190@2x.png b/imgs/icons/3190@2x.png index f8207ec59..4930f5cd5 100644 Binary files a/imgs/icons/3190@2x.png and b/imgs/icons/3190@2x.png differ diff --git a/imgs/icons/3191@1x.png b/imgs/icons/3191@1x.png index e6b3ca92b..116205c6e 100644 Binary files a/imgs/icons/3191@1x.png and b/imgs/icons/3191@1x.png differ diff --git a/imgs/icons/3191@2x.png b/imgs/icons/3191@2x.png index 7bda23b9f..2446fb3f8 100644 Binary files a/imgs/icons/3191@2x.png and b/imgs/icons/3191@2x.png differ diff --git a/imgs/icons/3192@2x.png b/imgs/icons/3192@2x.png index bce9c99f0..3ff80a87e 100644 Binary files a/imgs/icons/3192@2x.png and b/imgs/icons/3192@2x.png differ diff --git a/imgs/icons/3193@2x.png b/imgs/icons/3193@2x.png index d990a9818..e761dd870 100644 Binary files a/imgs/icons/3193@2x.png and b/imgs/icons/3193@2x.png differ diff --git a/imgs/icons/3194@2x.png b/imgs/icons/3194@2x.png index 8116f3eef..b1f0aee24 100644 Binary files a/imgs/icons/3194@2x.png and b/imgs/icons/3194@2x.png differ diff --git a/imgs/icons/3195@2x.png b/imgs/icons/3195@2x.png index 9bf6c173f..29e1bdc41 100644 Binary files a/imgs/icons/3195@2x.png and b/imgs/icons/3195@2x.png differ diff --git a/imgs/icons/3196@2x.png b/imgs/icons/3196@2x.png index 12733776d..d8277ea04 100644 Binary files a/imgs/icons/3196@2x.png and b/imgs/icons/3196@2x.png differ diff --git a/imgs/icons/3197@2x.png b/imgs/icons/3197@2x.png index 79f86331f..2c23f1a52 100644 Binary files a/imgs/icons/3197@2x.png and b/imgs/icons/3197@2x.png differ diff --git a/imgs/icons/3198@2x.png b/imgs/icons/3198@2x.png index 6c1303ee5..982f12884 100644 Binary files a/imgs/icons/3198@2x.png and b/imgs/icons/3198@2x.png differ diff --git a/imgs/icons/3199@2x.png b/imgs/icons/3199@2x.png index 56ab5f3be..de80b2b56 100644 Binary files a/imgs/icons/3199@2x.png and b/imgs/icons/3199@2x.png differ diff --git a/imgs/icons/3200@2x.png b/imgs/icons/3200@2x.png index 0edc96522..76e38c9b5 100644 Binary files a/imgs/icons/3200@2x.png and b/imgs/icons/3200@2x.png differ diff --git a/imgs/icons/3202@2x.png b/imgs/icons/3202@2x.png index 8ee56e1fd..5e1e7a0e6 100644 Binary files a/imgs/icons/3202@2x.png and b/imgs/icons/3202@2x.png differ diff --git a/imgs/icons/3203@2x.png b/imgs/icons/3203@2x.png index 413ead440..3642d4637 100644 Binary files a/imgs/icons/3203@2x.png and b/imgs/icons/3203@2x.png differ diff --git a/imgs/icons/3210@2x.png b/imgs/icons/3210@2x.png index 4dd8690e2..99ec577f1 100644 Binary files a/imgs/icons/3210@2x.png and b/imgs/icons/3210@2x.png differ diff --git a/imgs/icons/3211@2x.png b/imgs/icons/3211@2x.png index 8712477fd..fb5a7db24 100644 Binary files a/imgs/icons/3211@2x.png and b/imgs/icons/3211@2x.png differ diff --git a/imgs/icons/3212@2x.png b/imgs/icons/3212@2x.png index eb3a32f86..5f63bec2c 100644 Binary files a/imgs/icons/3212@2x.png and b/imgs/icons/3212@2x.png differ diff --git a/imgs/icons/3213@2x.png b/imgs/icons/3213@2x.png index 23183ffbc..3bcbe1bf9 100644 Binary files a/imgs/icons/3213@2x.png and b/imgs/icons/3213@2x.png differ diff --git a/imgs/icons/3214@2x.png b/imgs/icons/3214@2x.png index bc5eef6ad..920b76b36 100644 Binary files a/imgs/icons/3214@2x.png and b/imgs/icons/3214@2x.png differ diff --git a/imgs/icons/3215@2x.png b/imgs/icons/3215@2x.png index 2310737e4..d04f25070 100644 Binary files a/imgs/icons/3215@2x.png and b/imgs/icons/3215@2x.png differ diff --git a/imgs/icons/3216@2x.png b/imgs/icons/3216@2x.png index c87f9eaba..74460411e 100644 Binary files a/imgs/icons/3216@2x.png and b/imgs/icons/3216@2x.png differ diff --git a/imgs/icons/3217@2x.png b/imgs/icons/3217@2x.png index 7ffab845d..5cdb28125 100644 Binary files a/imgs/icons/3217@2x.png and b/imgs/icons/3217@2x.png differ diff --git a/imgs/icons/3218@2x.png b/imgs/icons/3218@2x.png index 528329e2d..994b097d8 100644 Binary files a/imgs/icons/3218@2x.png and b/imgs/icons/3218@2x.png differ diff --git a/imgs/icons/3220@2x.png b/imgs/icons/3220@2x.png index f209636b0..c0aaf6ff7 100644 Binary files a/imgs/icons/3220@2x.png and b/imgs/icons/3220@2x.png differ diff --git a/imgs/icons/3221@2x.png b/imgs/icons/3221@2x.png index 3c4191750..4cf405ad9 100644 Binary files a/imgs/icons/3221@2x.png and b/imgs/icons/3221@2x.png differ diff --git a/imgs/icons/3222@2x.png b/imgs/icons/3222@2x.png index f7636130b..d414906c1 100644 Binary files a/imgs/icons/3222@2x.png and b/imgs/icons/3222@2x.png differ diff --git a/imgs/icons/3223@2x.png b/imgs/icons/3223@2x.png index 82f8955d6..e8bf0cb87 100644 Binary files a/imgs/icons/3223@2x.png and b/imgs/icons/3223@2x.png differ diff --git a/imgs/icons/3224@2x.png b/imgs/icons/3224@2x.png index 8a327948f..ae5f5d5c6 100644 Binary files a/imgs/icons/3224@2x.png and b/imgs/icons/3224@2x.png differ diff --git a/imgs/icons/3225@2x.png b/imgs/icons/3225@2x.png index e167d789b..13a0bc526 100644 Binary files a/imgs/icons/3225@2x.png and b/imgs/icons/3225@2x.png differ diff --git a/imgs/icons/3230@2x.png b/imgs/icons/3230@2x.png index caffdf9f2..5f91a88a3 100644 Binary files a/imgs/icons/3230@2x.png and b/imgs/icons/3230@2x.png differ diff --git a/imgs/icons/3231@2x.png b/imgs/icons/3231@2x.png index dd6f02787..35cb91bd9 100644 Binary files a/imgs/icons/3231@2x.png and b/imgs/icons/3231@2x.png differ diff --git a/imgs/icons/3232@2x.png b/imgs/icons/3232@2x.png index 9a604a190..3c078aa57 100644 Binary files a/imgs/icons/3232@2x.png and b/imgs/icons/3232@2x.png differ diff --git a/imgs/icons/3234@2x.png b/imgs/icons/3234@2x.png index 833729894..ce4af8262 100644 Binary files a/imgs/icons/3234@2x.png and b/imgs/icons/3234@2x.png differ diff --git a/imgs/icons/3235@2x.png b/imgs/icons/3235@2x.png index 6886705b2..c20c2cfc5 100644 Binary files a/imgs/icons/3235@2x.png and b/imgs/icons/3235@2x.png differ diff --git a/imgs/icons/3236@2x.png b/imgs/icons/3236@2x.png index da998da6f..c772d1e41 100644 Binary files a/imgs/icons/3236@2x.png and b/imgs/icons/3236@2x.png differ diff --git a/imgs/icons/3237@2x.png b/imgs/icons/3237@2x.png index b47b713aa..07d6198f5 100644 Binary files a/imgs/icons/3237@2x.png and b/imgs/icons/3237@2x.png differ diff --git a/imgs/icons/3240@2x.png b/imgs/icons/3240@2x.png index 7dc860536..9ad0ac12e 100644 Binary files a/imgs/icons/3240@2x.png and b/imgs/icons/3240@2x.png differ diff --git a/imgs/icons/3241@2x.png b/imgs/icons/3241@2x.png index abc973ec8..131f6e9b7 100644 Binary files a/imgs/icons/3241@2x.png and b/imgs/icons/3241@2x.png differ diff --git a/imgs/icons/3247@2x.png b/imgs/icons/3247@2x.png index 089a9b6ba..a5fc8ec17 100644 Binary files a/imgs/icons/3247@2x.png and b/imgs/icons/3247@2x.png differ diff --git a/imgs/icons/3249@2x.png b/imgs/icons/3249@2x.png index 4d7323c27..eb58c0689 100644 Binary files a/imgs/icons/3249@2x.png and b/imgs/icons/3249@2x.png differ diff --git a/imgs/icons/3250@1x.png b/imgs/icons/3250@1x.png index 93a2210a5..7bb1d9004 100644 Binary files a/imgs/icons/3250@1x.png and b/imgs/icons/3250@1x.png differ diff --git a/imgs/icons/3251@2x.png b/imgs/icons/3251@2x.png index a716fa33f..529083dc5 100644 Binary files a/imgs/icons/3251@2x.png and b/imgs/icons/3251@2x.png differ diff --git a/imgs/icons/3253@2x.png b/imgs/icons/3253@2x.png index 235812359..4c04ac78a 100644 Binary files a/imgs/icons/3253@2x.png and b/imgs/icons/3253@2x.png differ diff --git a/imgs/icons/3255@2x.png b/imgs/icons/3255@2x.png index 5d55f72f5..fc2cc52fd 100644 Binary files a/imgs/icons/3255@2x.png and b/imgs/icons/3255@2x.png differ diff --git a/imgs/icons/3257@1x.png b/imgs/icons/3257@1x.png index 1104c6ff2..e89d49f6c 100644 Binary files a/imgs/icons/3257@1x.png and b/imgs/icons/3257@1x.png differ diff --git a/imgs/icons/3257@2x.png b/imgs/icons/3257@2x.png index cb69ddaea..488731eae 100644 Binary files a/imgs/icons/3257@2x.png and b/imgs/icons/3257@2x.png differ diff --git a/imgs/icons/3259@1x.png b/imgs/icons/3259@1x.png index 1169f2ba2..e902cabfc 100644 Binary files a/imgs/icons/3259@1x.png and b/imgs/icons/3259@1x.png differ diff --git a/imgs/icons/3259@2x.png b/imgs/icons/3259@2x.png index 73fa8c7d5..8db40be94 100644 Binary files a/imgs/icons/3259@2x.png and b/imgs/icons/3259@2x.png differ diff --git a/imgs/icons/3261@2x.png b/imgs/icons/3261@2x.png index 8531f716a..707579d86 100644 Binary files a/imgs/icons/3261@2x.png and b/imgs/icons/3261@2x.png differ diff --git a/imgs/icons/3263@2x.png b/imgs/icons/3263@2x.png index c50eaf87b..314d68629 100644 Binary files a/imgs/icons/3263@2x.png and b/imgs/icons/3263@2x.png differ diff --git a/imgs/icons/3265@2x.png b/imgs/icons/3265@2x.png index 08b33c663..97f015b49 100644 Binary files a/imgs/icons/3265@2x.png and b/imgs/icons/3265@2x.png differ diff --git a/imgs/icons/3266@2x.png b/imgs/icons/3266@2x.png index 782ef5bff..5a9347be0 100644 Binary files a/imgs/icons/3266@2x.png and b/imgs/icons/3266@2x.png differ diff --git a/imgs/icons/3278@2x.png b/imgs/icons/3278@2x.png index e2423a510..ee2461cee 100644 Binary files a/imgs/icons/3278@2x.png and b/imgs/icons/3278@2x.png differ diff --git a/imgs/icons/3279@2x.png b/imgs/icons/3279@2x.png index 7fc15d6a1..5fe55e749 100644 Binary files a/imgs/icons/3279@2x.png and b/imgs/icons/3279@2x.png differ diff --git a/imgs/icons/3280@1x.png b/imgs/icons/3280@1x.png index ca2c6ca67..a1a55fc46 100644 Binary files a/imgs/icons/3280@1x.png and b/imgs/icons/3280@1x.png differ diff --git a/imgs/icons/3280@2x.png b/imgs/icons/3280@2x.png index 6f097a9a1..54f9109de 100644 Binary files a/imgs/icons/3280@2x.png and b/imgs/icons/3280@2x.png differ diff --git a/imgs/icons/3281@2x.png b/imgs/icons/3281@2x.png index 55bf517d7..a2823da52 100644 Binary files a/imgs/icons/3281@2x.png and b/imgs/icons/3281@2x.png differ diff --git a/imgs/icons/3282@2x.png b/imgs/icons/3282@2x.png index 458601c60..95605d7cb 100644 Binary files a/imgs/icons/3282@2x.png and b/imgs/icons/3282@2x.png differ diff --git a/imgs/icons/3283@2x.png b/imgs/icons/3283@2x.png index 48a3965e3..7ba667dd2 100644 Binary files a/imgs/icons/3283@2x.png and b/imgs/icons/3283@2x.png differ diff --git a/imgs/icons/3300@2x.png b/imgs/icons/3300@2x.png index 908c64708..eefb451c0 100644 Binary files a/imgs/icons/3300@2x.png and b/imgs/icons/3300@2x.png differ diff --git a/imgs/icons/3303@2x.png b/imgs/icons/3303@2x.png index e317685f6..78813dfa4 100644 Binary files a/imgs/icons/3303@2x.png and b/imgs/icons/3303@2x.png differ diff --git a/imgs/icons/3304@2x.png b/imgs/icons/3304@2x.png index 0e65107d6..006230871 100644 Binary files a/imgs/icons/3304@2x.png and b/imgs/icons/3304@2x.png differ diff --git a/imgs/icons/3305@2x.png b/imgs/icons/3305@2x.png index 499be17de..c7cbec28b 100644 Binary files a/imgs/icons/3305@2x.png and b/imgs/icons/3305@2x.png differ diff --git a/imgs/icons/3306@1x.png b/imgs/icons/3306@1x.png index 1ef04fee6..4befef630 100644 Binary files a/imgs/icons/3306@1x.png and b/imgs/icons/3306@1x.png differ diff --git a/imgs/icons/3306@2x.png b/imgs/icons/3306@2x.png index 9234b9be9..ec32b2a2c 100644 Binary files a/imgs/icons/3306@2x.png and b/imgs/icons/3306@2x.png differ diff --git a/imgs/icons/3308@2x.png b/imgs/icons/3308@2x.png index 6201b2f4b..d7ce7bc15 100644 Binary files a/imgs/icons/3308@2x.png and b/imgs/icons/3308@2x.png differ diff --git a/imgs/icons/3310@2x.png b/imgs/icons/3310@2x.png index 0a57e88e1..b132790b5 100644 Binary files a/imgs/icons/3310@2x.png and b/imgs/icons/3310@2x.png differ diff --git a/imgs/icons/3311@2x.png b/imgs/icons/3311@2x.png index 9f29b8f38..5aaab016c 100644 Binary files a/imgs/icons/3311@2x.png and b/imgs/icons/3311@2x.png differ diff --git a/imgs/icons/3312@2x.png b/imgs/icons/3312@2x.png index a454d1c7c..bb490d2a1 100644 Binary files a/imgs/icons/3312@2x.png and b/imgs/icons/3312@2x.png differ diff --git a/imgs/icons/3313@2x.png b/imgs/icons/3313@2x.png index e12f9ed08..6b26c808f 100644 Binary files a/imgs/icons/3313@2x.png and b/imgs/icons/3313@2x.png differ diff --git a/imgs/icons/3314@2x.png b/imgs/icons/3314@2x.png index 67d476267..2bd00dd9f 100644 Binary files a/imgs/icons/3314@2x.png and b/imgs/icons/3314@2x.png differ diff --git a/imgs/icons/3316@2x.png b/imgs/icons/3316@2x.png index 5c78fdfe3..fb485fc68 100644 Binary files a/imgs/icons/3316@2x.png and b/imgs/icons/3316@2x.png differ diff --git a/imgs/icons/3317@2x.png b/imgs/icons/3317@2x.png index 718d316fe..28e2a2adb 100644 Binary files a/imgs/icons/3317@2x.png and b/imgs/icons/3317@2x.png differ diff --git a/imgs/icons/3319@2x.png b/imgs/icons/3319@2x.png index facbcfb16..c0c67c2b6 100644 Binary files a/imgs/icons/3319@2x.png and b/imgs/icons/3319@2x.png differ diff --git a/imgs/icons/3322@2x.png b/imgs/icons/3322@2x.png index 7c34e301b..b5eac71e0 100644 Binary files a/imgs/icons/3322@2x.png and b/imgs/icons/3322@2x.png differ diff --git a/imgs/icons/3323@1x.png b/imgs/icons/3323@1x.png index 3365cae85..8210e8973 100644 Binary files a/imgs/icons/3323@1x.png and b/imgs/icons/3323@1x.png differ diff --git a/imgs/icons/3323@2x.png b/imgs/icons/3323@2x.png index 8e7535eb8..2c2c7215e 100644 Binary files a/imgs/icons/3323@2x.png and b/imgs/icons/3323@2x.png differ diff --git a/imgs/icons/3329@2x.png b/imgs/icons/3329@2x.png index 33ef76488..012254912 100644 Binary files a/imgs/icons/3329@2x.png and b/imgs/icons/3329@2x.png differ diff --git a/imgs/icons/3330@2x.png b/imgs/icons/3330@2x.png index 104a2719a..041137835 100644 Binary files a/imgs/icons/3330@2x.png and b/imgs/icons/3330@2x.png differ diff --git a/imgs/icons/3333@2x.png b/imgs/icons/3333@2x.png index 52fd6e775..88ce887e2 100644 Binary files a/imgs/icons/3333@2x.png and b/imgs/icons/3333@2x.png differ diff --git a/imgs/icons/3334@2x.png b/imgs/icons/3334@2x.png index c99377b8b..c64bdc61b 100644 Binary files a/imgs/icons/3334@2x.png and b/imgs/icons/3334@2x.png differ diff --git a/imgs/icons/3336@2x.png b/imgs/icons/3336@2x.png index 374b0f3f2..2b3f2da89 100644 Binary files a/imgs/icons/3336@2x.png and b/imgs/icons/3336@2x.png differ diff --git a/imgs/icons/3337@2x.png b/imgs/icons/3337@2x.png index 495903647..80d5562b0 100644 Binary files a/imgs/icons/3337@2x.png and b/imgs/icons/3337@2x.png differ diff --git a/imgs/icons/3338@2x.png b/imgs/icons/3338@2x.png index d2489ee02..8ce9322ea 100644 Binary files a/imgs/icons/3338@2x.png and b/imgs/icons/3338@2x.png differ diff --git a/imgs/icons/3339@1x.png b/imgs/icons/3339@1x.png index 08dceaefa..e1831f50b 100644 Binary files a/imgs/icons/3339@1x.png and b/imgs/icons/3339@1x.png differ diff --git a/imgs/icons/3339@2x.png b/imgs/icons/3339@2x.png index 394ccb954..25e4af47d 100644 Binary files a/imgs/icons/3339@2x.png and b/imgs/icons/3339@2x.png differ diff --git a/imgs/icons/3340@2x.png b/imgs/icons/3340@2x.png index 8802fcd93..d761a381b 100644 Binary files a/imgs/icons/3340@2x.png and b/imgs/icons/3340@2x.png differ diff --git a/imgs/icons/3345@2x.png b/imgs/icons/3345@2x.png index f448325a0..f0a0cad9f 100644 Binary files a/imgs/icons/3345@2x.png and b/imgs/icons/3345@2x.png differ diff --git a/imgs/icons/3346@2x.png b/imgs/icons/3346@2x.png index df0828e8b..238b38fa0 100644 Binary files a/imgs/icons/3346@2x.png and b/imgs/icons/3346@2x.png differ diff --git a/imgs/icons/3347@2x.png b/imgs/icons/3347@2x.png index 8c0eeb54a..8c7db42e4 100644 Binary files a/imgs/icons/3347@2x.png and b/imgs/icons/3347@2x.png differ diff --git a/imgs/icons/3348@2x.png b/imgs/icons/3348@2x.png index 258e7a905..427686e3a 100644 Binary files a/imgs/icons/3348@2x.png and b/imgs/icons/3348@2x.png differ diff --git a/imgs/icons/33@2x.png b/imgs/icons/33@2x.png index 2093f5222..231f9a6ce 100644 Binary files a/imgs/icons/33@2x.png and b/imgs/icons/33@2x.png differ diff --git a/imgs/icons/3433@2x.png b/imgs/icons/3433@2x.png index 9fca69ebc..4eb13e3c6 100644 Binary files a/imgs/icons/3433@2x.png and b/imgs/icons/3433@2x.png differ diff --git a/imgs/icons/3435@2x.png b/imgs/icons/3435@2x.png index d46adc44a..991feec9c 100644 Binary files a/imgs/icons/3435@2x.png and b/imgs/icons/3435@2x.png differ diff --git a/imgs/icons/3436@2x.png b/imgs/icons/3436@2x.png index 6ef151762..470f9fc1f 100644 Binary files a/imgs/icons/3436@2x.png and b/imgs/icons/3436@2x.png differ diff --git a/imgs/icons/3437@2x.png b/imgs/icons/3437@2x.png index aa72ff4df..d12a5cce4 100644 Binary files a/imgs/icons/3437@2x.png and b/imgs/icons/3437@2x.png differ diff --git a/imgs/icons/3438@2x.png b/imgs/icons/3438@2x.png index 08bc7f5d8..4de732054 100644 Binary files a/imgs/icons/3438@2x.png and b/imgs/icons/3438@2x.png differ diff --git a/imgs/icons/3439@2x.png b/imgs/icons/3439@2x.png index bfde70208..e6dfae80c 100644 Binary files a/imgs/icons/3439@2x.png and b/imgs/icons/3439@2x.png differ diff --git a/imgs/icons/3440@2x.png b/imgs/icons/3440@2x.png index db0839bfa..8179957d3 100644 Binary files a/imgs/icons/3440@2x.png and b/imgs/icons/3440@2x.png differ diff --git a/imgs/icons/3441@2x.png b/imgs/icons/3441@2x.png index 9e32bbbba..ad451b88f 100644 Binary files a/imgs/icons/3441@2x.png and b/imgs/icons/3441@2x.png differ diff --git a/imgs/icons/3442@2x.png b/imgs/icons/3442@2x.png index 2504c9b17..93b49c37f 100644 Binary files a/imgs/icons/3442@2x.png and b/imgs/icons/3442@2x.png differ diff --git a/imgs/icons/3444@2x.png b/imgs/icons/3444@2x.png index ee70ae2b4..a58ab6030 100644 Binary files a/imgs/icons/3444@2x.png and b/imgs/icons/3444@2x.png differ diff --git a/imgs/icons/3445@2x.png b/imgs/icons/3445@2x.png index 7aecdbcca..dfe35ece7 100644 Binary files a/imgs/icons/3445@2x.png and b/imgs/icons/3445@2x.png differ diff --git a/imgs/icons/3446@2x.png b/imgs/icons/3446@2x.png index ad6a8c87b..8a256437e 100644 Binary files a/imgs/icons/3446@2x.png and b/imgs/icons/3446@2x.png differ diff --git a/imgs/icons/3448@2x.png b/imgs/icons/3448@2x.png index c144e4b94..4ca3805ea 100644 Binary files a/imgs/icons/3448@2x.png and b/imgs/icons/3448@2x.png differ diff --git a/imgs/icons/3450@2x.png b/imgs/icons/3450@2x.png index bc05ad81d..cf27f02b3 100644 Binary files a/imgs/icons/3450@2x.png and b/imgs/icons/3450@2x.png differ diff --git a/imgs/icons/349@2x.png b/imgs/icons/349@2x.png index 112981d9f..449659576 100644 Binary files a/imgs/icons/349@2x.png and b/imgs/icons/349@2x.png differ diff --git a/imgs/icons/34@2x.png b/imgs/icons/34@2x.png index 4ddff50c7..1167077d0 100644 Binary files a/imgs/icons/34@2x.png and b/imgs/icons/34@2x.png differ diff --git a/imgs/icons/350@2x.png b/imgs/icons/350@2x.png index cb2d7f9cf..63f2edfdb 100644 Binary files a/imgs/icons/350@2x.png and b/imgs/icons/350@2x.png differ diff --git a/imgs/icons/352@2x.png b/imgs/icons/352@2x.png index 63009485c..f602ec1d9 100644 Binary files a/imgs/icons/352@2x.png and b/imgs/icons/352@2x.png differ diff --git a/imgs/icons/355@2x.png b/imgs/icons/355@2x.png index d3dc75196..0ea8e7cd7 100644 Binary files a/imgs/icons/355@2x.png and b/imgs/icons/355@2x.png differ diff --git a/imgs/icons/356@2x.png b/imgs/icons/356@2x.png index 0777f64a1..9b301a9bd 100644 Binary files a/imgs/icons/356@2x.png and b/imgs/icons/356@2x.png differ diff --git a/imgs/icons/360@2x.png b/imgs/icons/360@2x.png index 9f80419b1..cbcdb5ea8 100644 Binary files a/imgs/icons/360@2x.png and b/imgs/icons/360@2x.png differ diff --git a/imgs/icons/361@2x.png b/imgs/icons/361@2x.png index 41bb2a10a..ce743287e 100644 Binary files a/imgs/icons/361@2x.png and b/imgs/icons/361@2x.png differ diff --git a/imgs/icons/365@2x.png b/imgs/icons/365@2x.png index e58e0eaeb..e0920452f 100644 Binary files a/imgs/icons/365@2x.png and b/imgs/icons/365@2x.png differ diff --git a/imgs/icons/366@2x.png b/imgs/icons/366@2x.png index ef0d636f5..9e3946483 100644 Binary files a/imgs/icons/366@2x.png and b/imgs/icons/366@2x.png differ diff --git a/imgs/icons/370@2x.png b/imgs/icons/370@2x.png index 8d62dd2ef..b94b4935a 100644 Binary files a/imgs/icons/370@2x.png and b/imgs/icons/370@2x.png differ diff --git a/imgs/icons/3716@2x.png b/imgs/icons/3716@2x.png index 579073a1d..4eac98457 100644 Binary files a/imgs/icons/3716@2x.png and b/imgs/icons/3716@2x.png differ diff --git a/imgs/icons/3717@2x.png b/imgs/icons/3717@2x.png index ccc6c9e50..59c08f05a 100644 Binary files a/imgs/icons/3717@2x.png and b/imgs/icons/3717@2x.png differ diff --git a/imgs/icons/3718@2x.png b/imgs/icons/3718@2x.png index 40960a0a9..63f709d68 100644 Binary files a/imgs/icons/3718@2x.png and b/imgs/icons/3718@2x.png differ diff --git a/imgs/icons/371@2x.png b/imgs/icons/371@2x.png index 889bd3bf2..56315e9d8 100644 Binary files a/imgs/icons/371@2x.png and b/imgs/icons/371@2x.png differ diff --git a/imgs/icons/3722@2x.png b/imgs/icons/3722@2x.png index 20aca3b9d..3e8d7b872 100644 Binary files a/imgs/icons/3722@2x.png and b/imgs/icons/3722@2x.png differ diff --git a/imgs/icons/3723@2x.png b/imgs/icons/3723@2x.png index 00e6cb67a..19b48dd71 100644 Binary files a/imgs/icons/3723@2x.png and b/imgs/icons/3723@2x.png differ diff --git a/imgs/icons/3724@2x.png b/imgs/icons/3724@2x.png index cb2c1ad51..a62648a55 100644 Binary files a/imgs/icons/3724@2x.png and b/imgs/icons/3724@2x.png differ diff --git a/imgs/icons/3725@2x.png b/imgs/icons/3725@2x.png index a1ca76ba0..7da3fdefc 100644 Binary files a/imgs/icons/3725@2x.png and b/imgs/icons/3725@2x.png differ diff --git a/imgs/icons/3726@2x.png b/imgs/icons/3726@2x.png index 6e744dfb1..71e6e09b4 100644 Binary files a/imgs/icons/3726@2x.png and b/imgs/icons/3726@2x.png differ diff --git a/imgs/icons/3727@2x.png b/imgs/icons/3727@2x.png index 85a565fc0..5860dc046 100644 Binary files a/imgs/icons/3727@2x.png and b/imgs/icons/3727@2x.png differ diff --git a/imgs/icons/3729@2x.png b/imgs/icons/3729@2x.png index 0332863cb..be64739e2 100644 Binary files a/imgs/icons/3729@2x.png and b/imgs/icons/3729@2x.png differ diff --git a/imgs/icons/3730@2x.png b/imgs/icons/3730@2x.png index 507f73025..9bc48e1b9 100644 Binary files a/imgs/icons/3730@2x.png and b/imgs/icons/3730@2x.png differ diff --git a/imgs/icons/3733@2x.png b/imgs/icons/3733@2x.png index 2ee6b51ac..741c5938d 100644 Binary files a/imgs/icons/3733@2x.png and b/imgs/icons/3733@2x.png differ diff --git a/imgs/icons/3734@2x.png b/imgs/icons/3734@2x.png index 82047473a..2de9f116c 100644 Binary files a/imgs/icons/3734@2x.png and b/imgs/icons/3734@2x.png differ diff --git a/imgs/icons/3736@2x.png b/imgs/icons/3736@2x.png index 551b1a042..17c10a117 100644 Binary files a/imgs/icons/3736@2x.png and b/imgs/icons/3736@2x.png differ diff --git a/imgs/icons/3737@2x.png b/imgs/icons/3737@2x.png index 103a99927..e297281d2 100644 Binary files a/imgs/icons/3737@2x.png and b/imgs/icons/3737@2x.png differ diff --git a/imgs/icons/3739@2x.png b/imgs/icons/3739@2x.png index b2a43657c..45d63d9c7 100644 Binary files a/imgs/icons/3739@2x.png and b/imgs/icons/3739@2x.png differ diff --git a/imgs/icons/3740@2x.png b/imgs/icons/3740@2x.png index c82da981f..2491588d2 100644 Binary files a/imgs/icons/3740@2x.png and b/imgs/icons/3740@2x.png differ diff --git a/imgs/icons/3741@2x.png b/imgs/icons/3741@2x.png index ac5b0b74e..2ea7317e8 100644 Binary files a/imgs/icons/3741@2x.png and b/imgs/icons/3741@2x.png differ diff --git a/imgs/icons/3744@2x.png b/imgs/icons/3744@2x.png index ac2c67d57..d8df9ca47 100644 Binary files a/imgs/icons/3744@2x.png and b/imgs/icons/3744@2x.png differ diff --git a/imgs/icons/3745@2x.png b/imgs/icons/3745@2x.png index 7b1fdffbd..8cd979f16 100644 Binary files a/imgs/icons/3745@2x.png and b/imgs/icons/3745@2x.png differ diff --git a/imgs/icons/3746@2x.png b/imgs/icons/3746@2x.png index 69b6c9547..58009f554 100644 Binary files a/imgs/icons/3746@2x.png and b/imgs/icons/3746@2x.png differ diff --git a/imgs/icons/3750@2x.png b/imgs/icons/3750@2x.png index c10c638d7..606b48950 100644 Binary files a/imgs/icons/3750@2x.png and b/imgs/icons/3750@2x.png differ diff --git a/imgs/icons/3751@2x.png b/imgs/icons/3751@2x.png index 825e0cf5c..ba640592e 100644 Binary files a/imgs/icons/3751@2x.png and b/imgs/icons/3751@2x.png differ diff --git a/imgs/icons/3753@2x.png b/imgs/icons/3753@2x.png index cee4f948e..af1a30d71 100644 Binary files a/imgs/icons/3753@2x.png and b/imgs/icons/3753@2x.png differ diff --git a/imgs/icons/3754@2x.png b/imgs/icons/3754@2x.png index 2946f3585..9b44f8a1a 100644 Binary files a/imgs/icons/3754@2x.png and b/imgs/icons/3754@2x.png differ diff --git a/imgs/icons/3759@2x.png b/imgs/icons/3759@2x.png index f1cd4efa9..8bffe76f3 100644 Binary files a/imgs/icons/3759@2x.png and b/imgs/icons/3759@2x.png differ diff --git a/imgs/icons/3764@2x.png b/imgs/icons/3764@2x.png index 594c34bae..19be62ce8 100644 Binary files a/imgs/icons/3764@2x.png and b/imgs/icons/3764@2x.png differ diff --git a/imgs/icons/3765@1x.png b/imgs/icons/3765@1x.png index 2b7790645..f5134aee1 100644 Binary files a/imgs/icons/3765@1x.png and b/imgs/icons/3765@1x.png differ diff --git a/imgs/icons/376@2x.png b/imgs/icons/376@2x.png index 614425f1b..e7c2f916c 100644 Binary files a/imgs/icons/376@2x.png and b/imgs/icons/376@2x.png differ diff --git a/imgs/icons/381@2x.png b/imgs/icons/381@2x.png index 5a7262486..12dfdb410 100644 Binary files a/imgs/icons/381@2x.png and b/imgs/icons/381@2x.png differ diff --git a/imgs/icons/384@2x.png b/imgs/icons/384@2x.png index 140362d38..a8179e6f9 100644 Binary files a/imgs/icons/384@2x.png and b/imgs/icons/384@2x.png differ diff --git a/imgs/icons/386@2x.png b/imgs/icons/386@2x.png index 5094c458d..fc8da9e43 100644 Binary files a/imgs/icons/386@2x.png and b/imgs/icons/386@2x.png differ diff --git a/imgs/icons/387@2x.png b/imgs/icons/387@2x.png index 666a1b2af..e3068328e 100644 Binary files a/imgs/icons/387@2x.png and b/imgs/icons/387@2x.png differ diff --git a/imgs/icons/389@2x.png b/imgs/icons/389@2x.png index 54155d177..833b86a05 100644 Binary files a/imgs/icons/389@2x.png and b/imgs/icons/389@2x.png differ diff --git a/imgs/icons/3943@2x.png b/imgs/icons/3943@2x.png index 5926b3d23..72fc7c58a 100644 Binary files a/imgs/icons/3943@2x.png and b/imgs/icons/3943@2x.png differ diff --git a/imgs/icons/3945@2x.png b/imgs/icons/3945@2x.png index d473f5c02..532ee2a38 100644 Binary files a/imgs/icons/3945@2x.png and b/imgs/icons/3945@2x.png differ diff --git a/imgs/icons/3946@2x.png b/imgs/icons/3946@2x.png index df72cbbe4..debc14494 100644 Binary files a/imgs/icons/3946@2x.png and b/imgs/icons/3946@2x.png differ diff --git a/imgs/icons/3947@2x.png b/imgs/icons/3947@2x.png index afed04c1d..4af4bf379 100644 Binary files a/imgs/icons/3947@2x.png and b/imgs/icons/3947@2x.png differ diff --git a/imgs/icons/3948@2x.png b/imgs/icons/3948@2x.png index 4b6bbd722..8689e02a1 100644 Binary files a/imgs/icons/3948@2x.png and b/imgs/icons/3948@2x.png differ diff --git a/imgs/icons/3950@2x.png b/imgs/icons/3950@2x.png index 5affc1701..415970050 100644 Binary files a/imgs/icons/3950@2x.png and b/imgs/icons/3950@2x.png differ diff --git a/imgs/icons/3951@2x.png b/imgs/icons/3951@2x.png index a8ac8d79f..3af3c459c 100644 Binary files a/imgs/icons/3951@2x.png and b/imgs/icons/3951@2x.png differ diff --git a/imgs/icons/3952@2x.png b/imgs/icons/3952@2x.png index 2b3833575..cf37d794c 100644 Binary files a/imgs/icons/3952@2x.png and b/imgs/icons/3952@2x.png differ diff --git a/imgs/icons/3953@2x.png b/imgs/icons/3953@2x.png index f3d9c3a6f..b7d79c05d 100644 Binary files a/imgs/icons/3953@2x.png and b/imgs/icons/3953@2x.png differ diff --git a/imgs/icons/398@2x.png b/imgs/icons/398@2x.png index 514db4b32..1f42188ab 100644 Binary files a/imgs/icons/398@2x.png and b/imgs/icons/398@2x.png differ diff --git a/imgs/icons/400@2x.png b/imgs/icons/400@2x.png index 65118cfe7..345a577c6 100644 Binary files a/imgs/icons/400@2x.png and b/imgs/icons/400@2x.png differ diff --git a/imgs/icons/402@2x.png b/imgs/icons/402@2x.png index c9f0090d2..b0def8f66 100644 Binary files a/imgs/icons/402@2x.png and b/imgs/icons/402@2x.png differ diff --git a/imgs/icons/404@2x.png b/imgs/icons/404@2x.png index 18cae10b6..f805fc881 100644 Binary files a/imgs/icons/404@2x.png and b/imgs/icons/404@2x.png differ diff --git a/imgs/icons/405@2x.png b/imgs/icons/405@2x.png index 22caf4e4f..f2dacafb5 100644 Binary files a/imgs/icons/405@2x.png and b/imgs/icons/405@2x.png differ diff --git a/imgs/icons/413@2x.png b/imgs/icons/413@2x.png index d3a74d702..206e005d8 100644 Binary files a/imgs/icons/413@2x.png and b/imgs/icons/413@2x.png differ diff --git a/imgs/icons/67@2x.png b/imgs/icons/67@2x.png index 61b5e6527..ba7fea0bf 100644 Binary files a/imgs/icons/67@2x.png and b/imgs/icons/67@2x.png differ diff --git a/imgs/icons/69@2x.png b/imgs/icons/69@2x.png index ec60e4d33..d5d202524 100644 Binary files a/imgs/icons/69@2x.png and b/imgs/icons/69@2x.png differ diff --git a/imgs/icons/73@2x.png b/imgs/icons/73@2x.png index 2397d1b53..8fba4570a 100644 Binary files a/imgs/icons/73@2x.png and b/imgs/icons/73@2x.png differ diff --git a/imgs/icons/76@2x.png b/imgs/icons/76@2x.png index d9ad94806..a471c45dc 100644 Binary files a/imgs/icons/76@2x.png and b/imgs/icons/76@2x.png differ diff --git a/imgs/icons/77@2x.png b/imgs/icons/77@2x.png index bfb06da09..4f892e9b8 100644 Binary files a/imgs/icons/77@2x.png and b/imgs/icons/77@2x.png differ diff --git a/imgs/icons/79@2x.png b/imgs/icons/79@2x.png index 79999ed60..9fc9a95ba 100644 Binary files a/imgs/icons/79@2x.png and b/imgs/icons/79@2x.png differ diff --git a/imgs/icons/80@2x.png b/imgs/icons/80@2x.png index 6444ff240..2fa31e140 100644 Binary files a/imgs/icons/80@2x.png and b/imgs/icons/80@2x.png differ diff --git a/imgs/icons/81@1x.png b/imgs/icons/81@1x.png index 8a23bb13a..ae7988a6d 100644 Binary files a/imgs/icons/81@1x.png and b/imgs/icons/81@1x.png differ diff --git a/imgs/icons/81@2x.png b/imgs/icons/81@2x.png index 84e29b598..58ca04ed8 100644 Binary files a/imgs/icons/81@2x.png and b/imgs/icons/81@2x.png differ diff --git a/imgs/icons/82@2x.png b/imgs/icons/82@2x.png index f85b363f5..7bae950d2 100644 Binary files a/imgs/icons/82@2x.png and b/imgs/icons/82@2x.png differ diff --git a/imgs/icons/83@2x.png b/imgs/icons/83@2x.png index e1d07ac65..c72eadeca 100644 Binary files a/imgs/icons/83@2x.png and b/imgs/icons/83@2x.png differ diff --git a/imgs/icons/84@2x.png b/imgs/icons/84@2x.png index 3f5f1dbc6..7b933dbd1 100644 Binary files a/imgs/icons/84@2x.png and b/imgs/icons/84@2x.png differ diff --git a/imgs/icons/86@2x.png b/imgs/icons/86@2x.png index b91cb449c..053ff76a8 100644 Binary files a/imgs/icons/86@2x.png and b/imgs/icons/86@2x.png differ diff --git a/imgs/icons/92@2x.png b/imgs/icons/92@2x.png index 65ee58139..f31d05fb7 100644 Binary files a/imgs/icons/92@2x.png and b/imgs/icons/92@2x.png differ diff --git a/imgs/icons/94@2x.png b/imgs/icons/94@2x.png index 31711e399..9c768901d 100644 Binary files a/imgs/icons/94@2x.png and b/imgs/icons/94@2x.png differ diff --git a/imgs/icons/97@2x.png b/imgs/icons/97@2x.png index e17f74be5..d4be02dad 100644 Binary files a/imgs/icons/97@2x.png and b/imgs/icons/97@2x.png differ diff --git a/imgs/icons/98@2x.png b/imgs/icons/98@2x.png index 3cc11c18d..b778cafe5 100644 Binary files a/imgs/icons/98@2x.png and b/imgs/icons/98@2x.png differ diff --git a/imgs/renders/10006@1x.png b/imgs/renders/10006@1x.png index 1cd52cf34..031f87706 100644 Binary files a/imgs/renders/10006@1x.png and b/imgs/renders/10006@1x.png differ diff --git a/imgs/renders/10013@1x.png b/imgs/renders/10013@1x.png index 4dc9ee83d..5f9926eef 100644 Binary files a/imgs/renders/10013@1x.png and b/imgs/renders/10013@1x.png differ diff --git a/imgs/renders/10038@1x.png b/imgs/renders/10038@1x.png index 5220d5d2a..b39588f08 100644 Binary files a/imgs/renders/10038@1x.png and b/imgs/renders/10038@1x.png differ diff --git a/imgs/renders/10040@1x.png b/imgs/renders/10040@1x.png index 34d55fe8a..db90467be 100644 Binary files a/imgs/renders/10040@1x.png and b/imgs/renders/10040@1x.png differ diff --git a/imgs/renders/1053@1x.png b/imgs/renders/1053@1x.png index 0ec471b5f..77dfb863c 100644 Binary files a/imgs/renders/1053@1x.png and b/imgs/renders/1053@1x.png differ diff --git a/imgs/renders/1064@1x.png b/imgs/renders/1064@1x.png index 9239a3ac7..54d5146de 100644 Binary files a/imgs/renders/1064@1x.png and b/imgs/renders/1064@1x.png differ diff --git a/imgs/renders/1065@1x.png b/imgs/renders/1065@1x.png index fca1b7e30..0a8e06b0c 100644 Binary files a/imgs/renders/1065@1x.png and b/imgs/renders/1065@1x.png differ diff --git a/imgs/renders/1065@2x.png b/imgs/renders/1065@2x.png index dae0b90e9..772c524cc 100644 Binary files a/imgs/renders/1065@2x.png and b/imgs/renders/1065@2x.png differ diff --git a/imgs/renders/1066@1x.png b/imgs/renders/1066@1x.png index 31c68f8fe..d74b134a1 100644 Binary files a/imgs/renders/1066@1x.png and b/imgs/renders/1066@1x.png differ diff --git a/imgs/renders/1067@1x.png b/imgs/renders/1067@1x.png index 23ea76dbd..6079d95d9 100644 Binary files a/imgs/renders/1067@1x.png and b/imgs/renders/1067@1x.png differ diff --git a/imgs/renders/10950@1x.png b/imgs/renders/10950@1x.png index 7b3cc06b0..b5f18f8e5 100644 Binary files a/imgs/renders/10950@1x.png and b/imgs/renders/10950@1x.png differ diff --git a/imgs/renders/11775@1x.png b/imgs/renders/11775@1x.png index 723891576..d484982b1 100644 Binary files a/imgs/renders/11775@1x.png and b/imgs/renders/11775@1x.png differ diff --git a/imgs/renders/11776@1x.png b/imgs/renders/11776@1x.png index e68378ca0..cfebfe5a4 100644 Binary files a/imgs/renders/11776@1x.png and b/imgs/renders/11776@1x.png differ diff --git a/imgs/renders/11777@1x.png b/imgs/renders/11777@1x.png index ffe72de06..f387adf8a 100644 Binary files a/imgs/renders/11777@1x.png and b/imgs/renders/11777@1x.png differ diff --git a/imgs/renders/11777@2x.png b/imgs/renders/11777@2x.png index b24471030..0e837466d 100644 Binary files a/imgs/renders/11777@2x.png and b/imgs/renders/11777@2x.png differ diff --git a/imgs/renders/11778@1x.png b/imgs/renders/11778@1x.png index 8828106d7..983aceb91 100644 Binary files a/imgs/renders/11778@1x.png and b/imgs/renders/11778@1x.png differ diff --git a/imgs/renders/11859@1x.png b/imgs/renders/11859@1x.png index dd922a8da..2e129f838 100644 Binary files a/imgs/renders/11859@1x.png and b/imgs/renders/11859@1x.png differ diff --git a/imgs/renders/11863@1x.png b/imgs/renders/11863@1x.png index eda9d7a51..6c267b862 100644 Binary files a/imgs/renders/11863@1x.png and b/imgs/renders/11863@1x.png differ diff --git a/imgs/renders/11869@1x.png b/imgs/renders/11869@1x.png index dcfdb3fa2..a2eebb432 100644 Binary files a/imgs/renders/11869@1x.png and b/imgs/renders/11869@1x.png differ diff --git a/imgs/renders/11869@2x.png b/imgs/renders/11869@2x.png index 8cd685759..712c22f20 100644 Binary files a/imgs/renders/11869@2x.png and b/imgs/renders/11869@2x.png differ diff --git a/imgs/renders/1236@1x.png b/imgs/renders/1236@1x.png index 346d175db..c92f8483c 100644 Binary files a/imgs/renders/1236@1x.png and b/imgs/renders/1236@1x.png differ diff --git a/imgs/renders/1237@1x.png b/imgs/renders/1237@1x.png index 80cd573b4..dd6890380 100644 Binary files a/imgs/renders/1237@1x.png and b/imgs/renders/1237@1x.png differ diff --git a/imgs/renders/1240@1x.png b/imgs/renders/1240@1x.png index 4b7d2612a..6e24f52b9 100644 Binary files a/imgs/renders/1240@1x.png and b/imgs/renders/1240@1x.png differ diff --git a/imgs/renders/1730@1x.png b/imgs/renders/1730@1x.png index 43f6ba8b9..65edceb85 100644 Binary files a/imgs/renders/1730@1x.png and b/imgs/renders/1730@1x.png differ diff --git a/imgs/renders/1731@1x.png b/imgs/renders/1731@1x.png index 9d6e1678e..ca78e2de0 100644 Binary files a/imgs/renders/1731@1x.png and b/imgs/renders/1731@1x.png differ diff --git a/imgs/renders/1731@2x.png b/imgs/renders/1731@2x.png index e7a487c08..9c0050dd1 100644 Binary files a/imgs/renders/1731@2x.png and b/imgs/renders/1731@2x.png differ diff --git a/imgs/renders/1733@1x.png b/imgs/renders/1733@1x.png index 3efd2fbaa..543a2917b 100644 Binary files a/imgs/renders/1733@1x.png and b/imgs/renders/1733@1x.png differ diff --git a/imgs/renders/1751@1x.png b/imgs/renders/1751@1x.png index 13b64bf56..8612a7f29 100644 Binary files a/imgs/renders/1751@1x.png and b/imgs/renders/1751@1x.png differ diff --git a/imgs/renders/1771@1x.png b/imgs/renders/1771@1x.png index 594a31207..9b833b1bf 100644 Binary files a/imgs/renders/1771@1x.png and b/imgs/renders/1771@1x.png differ diff --git a/imgs/renders/1773@1x.png b/imgs/renders/1773@1x.png index e7f6eabd9..f1bd20435 100644 Binary files a/imgs/renders/1773@1x.png and b/imgs/renders/1773@1x.png differ diff --git a/imgs/renders/1777@1x.png b/imgs/renders/1777@1x.png index fd3f55b38..b7f35dd3c 100644 Binary files a/imgs/renders/1777@1x.png and b/imgs/renders/1777@1x.png differ diff --git a/imgs/renders/1778@1x.png b/imgs/renders/1778@1x.png index 5ed72ed56..f6b119af7 100644 Binary files a/imgs/renders/1778@1x.png and b/imgs/renders/1778@1x.png differ diff --git a/imgs/renders/1779@1x.png b/imgs/renders/1779@1x.png index 652cce032..7dc9b8047 100644 Binary files a/imgs/renders/1779@1x.png and b/imgs/renders/1779@1x.png differ diff --git a/imgs/renders/1784@1x.png b/imgs/renders/1784@1x.png index 2f81fe1b2..4cda6d898 100644 Binary files a/imgs/renders/1784@1x.png and b/imgs/renders/1784@1x.png differ diff --git a/imgs/renders/1786@1x.png b/imgs/renders/1786@1x.png index 786c8707d..ec9011ab5 100644 Binary files a/imgs/renders/1786@1x.png and b/imgs/renders/1786@1x.png differ diff --git a/imgs/renders/1789@1x.png b/imgs/renders/1789@1x.png index 45007e9cf..025ff73d0 100644 Binary files a/imgs/renders/1789@1x.png and b/imgs/renders/1789@1x.png differ diff --git a/imgs/renders/1802@1x.png b/imgs/renders/1802@1x.png index c2dcf1390..1085c4d0e 100644 Binary files a/imgs/renders/1802@1x.png and b/imgs/renders/1802@1x.png differ diff --git a/imgs/renders/1803@1x.png b/imgs/renders/1803@1x.png index 3cf9b9871..fb9e11b3c 100644 Binary files a/imgs/renders/1803@1x.png and b/imgs/renders/1803@1x.png differ diff --git a/imgs/renders/1803@2x.png b/imgs/renders/1803@2x.png index 6a480eb5b..a4c2e9bf5 100644 Binary files a/imgs/renders/1803@2x.png and b/imgs/renders/1803@2x.png differ diff --git a/imgs/renders/1814@1x.png b/imgs/renders/1814@1x.png index d121e411e..c1b87b6ba 100644 Binary files a/imgs/renders/1814@1x.png and b/imgs/renders/1814@1x.png differ diff --git a/imgs/renders/1814@2x.png b/imgs/renders/1814@2x.png index 44981e73e..d25f59af8 100644 Binary files a/imgs/renders/1814@2x.png and b/imgs/renders/1814@2x.png differ diff --git a/imgs/renders/1815@1x.png b/imgs/renders/1815@1x.png index ae16df32e..3d0598460 100644 Binary files a/imgs/renders/1815@1x.png and b/imgs/renders/1815@1x.png differ diff --git a/imgs/renders/1816@1x.png b/imgs/renders/1816@1x.png index bc3195087..888af9c06 100644 Binary files a/imgs/renders/1816@1x.png and b/imgs/renders/1816@1x.png differ diff --git a/imgs/renders/1824@1x.png b/imgs/renders/1824@1x.png index 95be1c8e7..184fe2bf1 100644 Binary files a/imgs/renders/1824@1x.png and b/imgs/renders/1824@1x.png differ diff --git a/imgs/renders/1825@1x.png b/imgs/renders/1825@1x.png index 10785a55f..c9c6c2040 100644 Binary files a/imgs/renders/1825@1x.png and b/imgs/renders/1825@1x.png differ diff --git a/imgs/renders/1825@2x.png b/imgs/renders/1825@2x.png index 5da5c2ffd..9bff04718 100644 Binary files a/imgs/renders/1825@2x.png and b/imgs/renders/1825@2x.png differ diff --git a/imgs/renders/1829@1x.png b/imgs/renders/1829@1x.png index 22388c686..5bcd595b2 100644 Binary files a/imgs/renders/1829@1x.png and b/imgs/renders/1829@1x.png differ diff --git a/imgs/renders/1831@1x.png b/imgs/renders/1831@1x.png index a80817437..326033772 100644 Binary files a/imgs/renders/1831@1x.png and b/imgs/renders/1831@1x.png differ diff --git a/imgs/renders/1835@1x.png b/imgs/renders/1835@1x.png index 86323ccb8..1762b7f90 100644 Binary files a/imgs/renders/1835@1x.png and b/imgs/renders/1835@1x.png differ diff --git a/imgs/renders/1840@1x.png b/imgs/renders/1840@1x.png index d66c9ea5f..cec322f54 100644 Binary files a/imgs/renders/1840@1x.png and b/imgs/renders/1840@1x.png differ diff --git a/imgs/renders/1841@1x.png b/imgs/renders/1841@1x.png index ff81219f3..81bbc07cd 100644 Binary files a/imgs/renders/1841@1x.png and b/imgs/renders/1841@1x.png differ diff --git a/imgs/renders/1847@1x.png b/imgs/renders/1847@1x.png index 80c5b977c..128c4f301 100644 Binary files a/imgs/renders/1847@1x.png and b/imgs/renders/1847@1x.png differ diff --git a/imgs/renders/1848@1x.png b/imgs/renders/1848@1x.png index c09733d8c..94c7ae05e 100644 Binary files a/imgs/renders/1848@1x.png and b/imgs/renders/1848@1x.png differ diff --git a/imgs/renders/1854@1x.png b/imgs/renders/1854@1x.png index b1ad27934..797ed5898 100644 Binary files a/imgs/renders/1854@1x.png and b/imgs/renders/1854@1x.png differ diff --git a/imgs/renders/1860@1x.png b/imgs/renders/1860@1x.png index 2a715dc21..73d34b1bf 100644 Binary files a/imgs/renders/1860@1x.png and b/imgs/renders/1860@1x.png differ diff --git a/imgs/renders/1861@1x.png b/imgs/renders/1861@1x.png index 7e9b53bc1..7c1d7d9f4 100644 Binary files a/imgs/renders/1861@1x.png and b/imgs/renders/1861@1x.png differ diff --git a/imgs/renders/1861@2x.png b/imgs/renders/1861@2x.png index b160b03cd..91c9e9e27 100644 Binary files a/imgs/renders/1861@2x.png and b/imgs/renders/1861@2x.png differ diff --git a/imgs/renders/1872@1x.png b/imgs/renders/1872@1x.png index 75bb2921c..074260721 100644 Binary files a/imgs/renders/1872@1x.png and b/imgs/renders/1872@1x.png differ diff --git a/imgs/renders/1878@1x.png b/imgs/renders/1878@1x.png index f08cadb2e..81786f12f 100644 Binary files a/imgs/renders/1878@1x.png and b/imgs/renders/1878@1x.png differ diff --git a/imgs/renders/1894@1x.png b/imgs/renders/1894@1x.png index 970a02611..0089148a7 100644 Binary files a/imgs/renders/1894@1x.png and b/imgs/renders/1894@1x.png differ diff --git a/imgs/renders/1901@1x.png b/imgs/renders/1901@1x.png index 14cfd3c7b..7465266e4 100644 Binary files a/imgs/renders/1901@1x.png and b/imgs/renders/1901@1x.png differ diff --git a/imgs/renders/1909@1x.png b/imgs/renders/1909@1x.png index b8ab771c2..66e596f25 100644 Binary files a/imgs/renders/1909@1x.png and b/imgs/renders/1909@1x.png differ diff --git a/imgs/renders/1912@1x.png b/imgs/renders/1912@1x.png index 77b402bb0..18b86a696 100644 Binary files a/imgs/renders/1912@1x.png and b/imgs/renders/1912@1x.png differ diff --git a/imgs/renders/1913@1x.png b/imgs/renders/1913@1x.png index a125e26ca..2bfdae68f 100644 Binary files a/imgs/renders/1913@1x.png and b/imgs/renders/1913@1x.png differ diff --git a/imgs/renders/1914@1x.png b/imgs/renders/1914@1x.png index 463d1c4ee..806b377ef 100644 Binary files a/imgs/renders/1914@1x.png and b/imgs/renders/1914@1x.png differ diff --git a/imgs/renders/1920@1x.png b/imgs/renders/1920@1x.png index bfa0f9a4f..75bda4f0e 100644 Binary files a/imgs/renders/1920@1x.png and b/imgs/renders/1920@1x.png differ diff --git a/imgs/renders/1921@1x.png b/imgs/renders/1921@1x.png index ccc0187e4..65ba5d4bb 100644 Binary files a/imgs/renders/1921@1x.png and b/imgs/renders/1921@1x.png differ diff --git a/imgs/renders/1925@1x.png b/imgs/renders/1925@1x.png index 24ac7d767..f35c8e761 100644 Binary files a/imgs/renders/1925@1x.png and b/imgs/renders/1925@1x.png differ diff --git a/imgs/renders/1928@1x.png b/imgs/renders/1928@1x.png index 556796c13..53be91f35 100644 Binary files a/imgs/renders/1928@1x.png and b/imgs/renders/1928@1x.png differ diff --git a/imgs/renders/1931@1x.png b/imgs/renders/1931@1x.png index dba9566a8..50070a64c 100644 Binary files a/imgs/renders/1931@1x.png and b/imgs/renders/1931@1x.png differ diff --git a/imgs/renders/1943@1x.png b/imgs/renders/1943@1x.png index af7244e09..e7092b0b1 100644 Binary files a/imgs/renders/1943@1x.png and b/imgs/renders/1943@1x.png differ diff --git a/imgs/renders/1945@1x.png b/imgs/renders/1945@1x.png index 5a1ffe9c2..ac3e9b639 100644 Binary files a/imgs/renders/1945@1x.png and b/imgs/renders/1945@1x.png differ diff --git a/imgs/renders/1948@1x.png b/imgs/renders/1948@1x.png index e1353bdbe..856e2249d 100644 Binary files a/imgs/renders/1948@1x.png and b/imgs/renders/1948@1x.png differ diff --git a/imgs/renders/1950@1x.png b/imgs/renders/1950@1x.png index df28a58af..8797231a0 100644 Binary files a/imgs/renders/1950@1x.png and b/imgs/renders/1950@1x.png differ diff --git a/imgs/renders/1966@1x.png b/imgs/renders/1966@1x.png index e3402e414..d5c114bed 100644 Binary files a/imgs/renders/1966@1x.png and b/imgs/renders/1966@1x.png differ diff --git a/imgs/renders/1973@1x.png b/imgs/renders/1973@1x.png index 25b5b933f..ac5c8d803 100644 Binary files a/imgs/renders/1973@1x.png and b/imgs/renders/1973@1x.png differ diff --git a/imgs/renders/1976@1x.png b/imgs/renders/1976@1x.png index 15e933736..555811eff 100644 Binary files a/imgs/renders/1976@1x.png and b/imgs/renders/1976@1x.png differ diff --git a/imgs/renders/20136@1x.png b/imgs/renders/20136@1x.png index 719af2bfe..cda198f62 100644 Binary files a/imgs/renders/20136@1x.png and b/imgs/renders/20136@1x.png differ diff --git a/imgs/renders/20137@1x.png b/imgs/renders/20137@1x.png index f3e96ae7a..fcc60feba 100644 Binary files a/imgs/renders/20137@1x.png and b/imgs/renders/20137@1x.png differ diff --git a/imgs/renders/20137@2x.png b/imgs/renders/20137@2x.png index 1779892e0..ac8f82651 100644 Binary files a/imgs/renders/20137@2x.png and b/imgs/renders/20137@2x.png differ diff --git a/imgs/renders/20199@1x.png b/imgs/renders/20199@1x.png index 35d5e3c50..bd602bd08 100644 Binary files a/imgs/renders/20199@1x.png and b/imgs/renders/20199@1x.png differ diff --git a/imgs/renders/20201@1x.png b/imgs/renders/20201@1x.png index dc846c435..7b0c22a57 100644 Binary files a/imgs/renders/20201@1x.png and b/imgs/renders/20201@1x.png differ diff --git a/imgs/renders/20202@1x.png b/imgs/renders/20202@1x.png index 4b2db9cbe..99b5ba634 100644 Binary files a/imgs/renders/20202@1x.png and b/imgs/renders/20202@1x.png differ diff --git a/imgs/renders/20216@1x.png b/imgs/renders/20216@1x.png index 327e1a170..91ee1825b 100644 Binary files a/imgs/renders/20216@1x.png and b/imgs/renders/20216@1x.png differ diff --git a/imgs/renders/20217@1x.png b/imgs/renders/20217@1x.png index 0aac1bd9e..d754540b0 100644 Binary files a/imgs/renders/20217@1x.png and b/imgs/renders/20217@1x.png differ diff --git a/imgs/renders/20218@1x.png b/imgs/renders/20218@1x.png index 26c13bfa8..a134d833f 100644 Binary files a/imgs/renders/20218@1x.png and b/imgs/renders/20218@1x.png differ diff --git a/imgs/renders/20227@1x.png b/imgs/renders/20227@1x.png index 338d14f3f..5d6832b87 100644 Binary files a/imgs/renders/20227@1x.png and b/imgs/renders/20227@1x.png differ diff --git a/imgs/renders/20229@1x.png b/imgs/renders/20229@1x.png index 7d31a8f50..b91771724 100644 Binary files a/imgs/renders/20229@1x.png and b/imgs/renders/20229@1x.png differ diff --git a/imgs/renders/20230@1x.png b/imgs/renders/20230@1x.png index 5a504135e..b9ffdf061 100644 Binary files a/imgs/renders/20230@1x.png and b/imgs/renders/20230@1x.png differ diff --git a/imgs/renders/20231@1x.png b/imgs/renders/20231@1x.png index 9afef8547..9f283601f 100644 Binary files a/imgs/renders/20231@1x.png and b/imgs/renders/20231@1x.png differ diff --git a/imgs/renders/20277@1x.png b/imgs/renders/20277@1x.png index 2305a869c..2f4ddccfa 100644 Binary files a/imgs/renders/20277@1x.png and b/imgs/renders/20277@1x.png differ diff --git a/imgs/renders/20301@1x.png b/imgs/renders/20301@1x.png index f9c232256..8de2c1e65 100644 Binary files a/imgs/renders/20301@1x.png and b/imgs/renders/20301@1x.png differ diff --git a/imgs/renders/20344@1x.png b/imgs/renders/20344@1x.png index a3b03f7da..0c1e6810f 100644 Binary files a/imgs/renders/20344@1x.png and b/imgs/renders/20344@1x.png differ diff --git a/imgs/renders/20345@1x.png b/imgs/renders/20345@1x.png index a671e16c1..92a45e6c2 100644 Binary files a/imgs/renders/20345@1x.png and b/imgs/renders/20345@1x.png differ diff --git a/imgs/renders/20384@1x.png b/imgs/renders/20384@1x.png index ff3460893..fcccbe657 100644 Binary files a/imgs/renders/20384@1x.png and b/imgs/renders/20384@1x.png differ diff --git a/imgs/renders/20384@2x.png b/imgs/renders/20384@2x.png index 825ec73d6..673b57c76 100644 Binary files a/imgs/renders/20384@2x.png and b/imgs/renders/20384@2x.png differ diff --git a/imgs/renders/20385@1x.png b/imgs/renders/20385@1x.png index 6dc632bfd..3ba024e5b 100644 Binary files a/imgs/renders/20385@1x.png and b/imgs/renders/20385@1x.png differ diff --git a/imgs/renders/20385@2x.png b/imgs/renders/20385@2x.png index 97c4632de..8b666632e 100644 Binary files a/imgs/renders/20385@2x.png and b/imgs/renders/20385@2x.png differ diff --git a/imgs/renders/20386@1x.png b/imgs/renders/20386@1x.png index 2ed36cabd..b58f2abb7 100644 Binary files a/imgs/renders/20386@1x.png and b/imgs/renders/20386@1x.png differ diff --git a/imgs/renders/20386@2x.png b/imgs/renders/20386@2x.png index 4bad4be1d..2715f7fa5 100644 Binary files a/imgs/renders/20386@2x.png and b/imgs/renders/20386@2x.png differ diff --git a/imgs/renders/20402@1x.png b/imgs/renders/20402@1x.png index beafc27b8..5c5b20621 100644 Binary files a/imgs/renders/20402@1x.png and b/imgs/renders/20402@1x.png differ diff --git a/imgs/renders/20403@1x.png b/imgs/renders/20403@1x.png index ed4a2a255..c2ee71895 100644 Binary files a/imgs/renders/20403@1x.png and b/imgs/renders/20403@1x.png differ diff --git a/imgs/renders/20403@2x.png b/imgs/renders/20403@2x.png index 05ffccb7b..4e8abd391 100644 Binary files a/imgs/renders/20403@2x.png and b/imgs/renders/20403@2x.png differ diff --git a/imgs/renders/2043@1x.png b/imgs/renders/2043@1x.png index ea2b62de3..53b3d43f4 100644 Binary files a/imgs/renders/2043@1x.png and b/imgs/renders/2043@1x.png differ diff --git a/imgs/renders/2044@1x.png b/imgs/renders/2044@1x.png index 47e790acf..c4805e758 100644 Binary files a/imgs/renders/2044@1x.png and b/imgs/renders/2044@1x.png differ diff --git a/imgs/renders/2045@1x.png b/imgs/renders/2045@1x.png index 7ced44a15..b1584f85a 100644 Binary files a/imgs/renders/2045@1x.png and b/imgs/renders/2045@1x.png differ diff --git a/imgs/renders/20605@1x.png b/imgs/renders/20605@1x.png index 724645b65..05206f67e 100644 Binary files a/imgs/renders/20605@1x.png and b/imgs/renders/20605@1x.png differ diff --git a/imgs/renders/20614@1x.png b/imgs/renders/20614@1x.png index 7b2f49fd3..635929f42 100644 Binary files a/imgs/renders/20614@1x.png and b/imgs/renders/20614@1x.png differ diff --git a/imgs/renders/20614@2x.png b/imgs/renders/20614@2x.png index 0e79f28f0..550d37d7d 100644 Binary files a/imgs/renders/20614@2x.png and b/imgs/renders/20614@2x.png differ diff --git a/imgs/renders/20616@1x.png b/imgs/renders/20616@1x.png index c3ed0de77..6b2f832c2 100644 Binary files a/imgs/renders/20616@1x.png and b/imgs/renders/20616@1x.png differ diff --git a/imgs/renders/20616@2x.png b/imgs/renders/20616@2x.png index be8cd9f81..3318fa719 100644 Binary files a/imgs/renders/20616@2x.png and b/imgs/renders/20616@2x.png differ diff --git a/imgs/renders/20980@1x.png b/imgs/renders/20980@1x.png index c8c6653a5..2621e58cc 100644 Binary files a/imgs/renders/20980@1x.png and b/imgs/renders/20980@1x.png differ diff --git a/imgs/renders/21052@1x.png b/imgs/renders/21052@1x.png index 5ae1cc314..6bb1ae776 100644 Binary files a/imgs/renders/21052@1x.png and b/imgs/renders/21052@1x.png differ diff --git a/imgs/renders/21076@1x.png b/imgs/renders/21076@1x.png index b2f31ff50..9c5396a2b 100644 Binary files a/imgs/renders/21076@1x.png and b/imgs/renders/21076@1x.png differ diff --git a/imgs/renders/21135@1x.png b/imgs/renders/21135@1x.png index fff7d9114..41fb288a0 100644 Binary files a/imgs/renders/21135@1x.png and b/imgs/renders/21135@1x.png differ diff --git a/imgs/renders/21135@2x.png b/imgs/renders/21135@2x.png index 54fbbce65..28f066457 100644 Binary files a/imgs/renders/21135@2x.png and b/imgs/renders/21135@2x.png differ diff --git a/imgs/renders/21155@1x.png b/imgs/renders/21155@1x.png index dc01dec6b..b32febd1b 100644 Binary files a/imgs/renders/21155@1x.png and b/imgs/renders/21155@1x.png differ diff --git a/imgs/renders/21156@1x.png b/imgs/renders/21156@1x.png index 301607cd4..61e45ded4 100644 Binary files a/imgs/renders/21156@1x.png and b/imgs/renders/21156@1x.png differ diff --git a/imgs/renders/21217@1x.png b/imgs/renders/21217@1x.png index 1db6f4399..642713b07 100644 Binary files a/imgs/renders/21217@1x.png and b/imgs/renders/21217@1x.png differ diff --git a/imgs/renders/21219@1x.png b/imgs/renders/21219@1x.png index 2447b0126..f08e45df0 100644 Binary files a/imgs/renders/21219@1x.png and b/imgs/renders/21219@1x.png differ diff --git a/imgs/renders/21221@1x.png b/imgs/renders/21221@1x.png index 7d8c5bf25..323667cb2 100644 Binary files a/imgs/renders/21221@1x.png and b/imgs/renders/21221@1x.png differ diff --git a/imgs/renders/21222@1x.png b/imgs/renders/21222@1x.png index 663aeb07e..e7f20fb63 100644 Binary files a/imgs/renders/21222@1x.png and b/imgs/renders/21222@1x.png differ diff --git a/imgs/renders/21223@1x.png b/imgs/renders/21223@1x.png index 83351f499..a49f7b457 100644 Binary files a/imgs/renders/21223@1x.png and b/imgs/renders/21223@1x.png differ diff --git a/imgs/renders/21224@1x.png b/imgs/renders/21224@1x.png index cf9bbd2aa..8c565dc51 100644 Binary files a/imgs/renders/21224@1x.png and b/imgs/renders/21224@1x.png differ diff --git a/imgs/renders/2122@1x.png b/imgs/renders/2122@1x.png index 60d932abd..fbe2944d5 100644 Binary files a/imgs/renders/2122@1x.png and b/imgs/renders/2122@1x.png differ diff --git a/imgs/renders/2123@1x.png b/imgs/renders/2123@1x.png index 6996dfe2a..f29d521d6 100644 Binary files a/imgs/renders/2123@1x.png and b/imgs/renders/2123@1x.png differ diff --git a/imgs/renders/21252@1x.png b/imgs/renders/21252@1x.png index ba3c372bd..c10ce17a5 100644 Binary files a/imgs/renders/21252@1x.png and b/imgs/renders/21252@1x.png differ diff --git a/imgs/renders/21254@1x.png b/imgs/renders/21254@1x.png index df1a462d6..2cc628248 100644 Binary files a/imgs/renders/21254@1x.png and b/imgs/renders/21254@1x.png differ diff --git a/imgs/renders/21254@2x.png b/imgs/renders/21254@2x.png index 3f7ab3b7e..3ac160c23 100644 Binary files a/imgs/renders/21254@2x.png and b/imgs/renders/21254@2x.png differ diff --git a/imgs/renders/21255@1x.png b/imgs/renders/21255@1x.png index 2636806d7..1e3a6b9cb 100644 Binary files a/imgs/renders/21255@1x.png and b/imgs/renders/21255@1x.png differ diff --git a/imgs/renders/21256@1x.png b/imgs/renders/21256@1x.png index ba4ec4cc9..e25ed452c 100644 Binary files a/imgs/renders/21256@1x.png and b/imgs/renders/21256@1x.png differ diff --git a/imgs/renders/21277@1x.png b/imgs/renders/21277@1x.png index d431ecd64..1a7acf8b6 100644 Binary files a/imgs/renders/21277@1x.png and b/imgs/renders/21277@1x.png differ diff --git a/imgs/renders/21278@1x.png b/imgs/renders/21278@1x.png index f40192c09..75d480d9c 100644 Binary files a/imgs/renders/21278@1x.png and b/imgs/renders/21278@1x.png differ diff --git a/imgs/renders/21279@1x.png b/imgs/renders/21279@1x.png index a9217b225..ed9bb9a71 100644 Binary files a/imgs/renders/21279@1x.png and b/imgs/renders/21279@1x.png differ diff --git a/imgs/renders/21280@1x.png b/imgs/renders/21280@1x.png index a69ccc58f..869bc5484 100644 Binary files a/imgs/renders/21280@1x.png and b/imgs/renders/21280@1x.png differ diff --git a/imgs/renders/21282@1x.png b/imgs/renders/21282@1x.png index 42a868297..3048d86d3 100644 Binary files a/imgs/renders/21282@1x.png and b/imgs/renders/21282@1x.png differ diff --git a/imgs/renders/21315@1x.png b/imgs/renders/21315@1x.png index 533c0e8b0..885e56a25 100644 Binary files a/imgs/renders/21315@1x.png and b/imgs/renders/21315@1x.png differ diff --git a/imgs/renders/21354@1x.png b/imgs/renders/21354@1x.png index fcf115099..d9aa34a18 100644 Binary files a/imgs/renders/21354@1x.png and b/imgs/renders/21354@1x.png differ diff --git a/imgs/renders/21358@1x.png b/imgs/renders/21358@1x.png index 895870881..774039d1d 100644 Binary files a/imgs/renders/21358@1x.png and b/imgs/renders/21358@1x.png differ diff --git a/imgs/renders/21360@1x.png b/imgs/renders/21360@1x.png index c4a71c94e..139a07470 100644 Binary files a/imgs/renders/21360@1x.png and b/imgs/renders/21360@1x.png differ diff --git a/imgs/renders/21362@1x.png b/imgs/renders/21362@1x.png index f6dff6ea2..e7f5e210e 100644 Binary files a/imgs/renders/21362@1x.png and b/imgs/renders/21362@1x.png differ diff --git a/imgs/renders/2138@1x.png b/imgs/renders/2138@1x.png index 0a79c4e31..d1117e792 100644 Binary files a/imgs/renders/2138@1x.png and b/imgs/renders/2138@1x.png differ diff --git a/imgs/renders/2138@2x.png b/imgs/renders/2138@2x.png index 8188ae96d..928bebef3 100644 Binary files a/imgs/renders/2138@2x.png and b/imgs/renders/2138@2x.png differ diff --git a/imgs/renders/21406@1x.png b/imgs/renders/21406@1x.png index e9d8d8610..9e9935849 100644 Binary files a/imgs/renders/21406@1x.png and b/imgs/renders/21406@1x.png differ diff --git a/imgs/renders/2141@1x.png b/imgs/renders/2141@1x.png index cc244366b..c4eb4dc2a 100644 Binary files a/imgs/renders/2141@1x.png and b/imgs/renders/2141@1x.png differ diff --git a/imgs/renders/21490@1x.png b/imgs/renders/21490@1x.png index b121e6b03..978dcf73e 100644 Binary files a/imgs/renders/21490@1x.png and b/imgs/renders/21490@1x.png differ diff --git a/imgs/renders/21493@1x.png b/imgs/renders/21493@1x.png index 1228da8de..91f18d0e1 100644 Binary files a/imgs/renders/21493@1x.png and b/imgs/renders/21493@1x.png differ diff --git a/imgs/renders/21493@2x.png b/imgs/renders/21493@2x.png index bdeef99c4..24a68480a 100644 Binary files a/imgs/renders/21493@2x.png and b/imgs/renders/21493@2x.png differ diff --git a/imgs/renders/2160@1x.png b/imgs/renders/2160@1x.png index 3699c211a..4f01413d0 100644 Binary files a/imgs/renders/2160@1x.png and b/imgs/renders/2160@1x.png differ diff --git a/imgs/renders/2160@2x.png b/imgs/renders/2160@2x.png index 3b02baf32..d69d6cdb0 100644 Binary files a/imgs/renders/2160@2x.png and b/imgs/renders/2160@2x.png differ diff --git a/imgs/renders/21766@1x.png b/imgs/renders/21766@1x.png index c4dacd372..147ebef74 100644 Binary files a/imgs/renders/21766@1x.png and b/imgs/renders/21766@1x.png differ diff --git a/imgs/renders/21821@1x.png b/imgs/renders/21821@1x.png index 642cebf71..cf9bdd6a0 100644 Binary files a/imgs/renders/21821@1x.png and b/imgs/renders/21821@1x.png differ diff --git a/imgs/renders/21976@1x.png b/imgs/renders/21976@1x.png index 29d5502a0..c9d378b60 100644 Binary files a/imgs/renders/21976@1x.png and b/imgs/renders/21976@1x.png differ diff --git a/imgs/renders/22001@1x.png b/imgs/renders/22001@1x.png index 394338889..4740cc12d 100644 Binary files a/imgs/renders/22001@1x.png and b/imgs/renders/22001@1x.png differ diff --git a/imgs/renders/22007@1x.png b/imgs/renders/22007@1x.png index 9fd047486..0ef3d407f 100644 Binary files a/imgs/renders/22007@1x.png and b/imgs/renders/22007@1x.png differ diff --git a/imgs/renders/22142@1x.png b/imgs/renders/22142@1x.png index bbd81ce5a..c1312a531 100644 Binary files a/imgs/renders/22142@1x.png and b/imgs/renders/22142@1x.png differ diff --git a/imgs/renders/22150@1x.png b/imgs/renders/22150@1x.png index 3f0a62a40..1de182096 100644 Binary files a/imgs/renders/22150@1x.png and b/imgs/renders/22150@1x.png differ diff --git a/imgs/renders/22161@1x.png b/imgs/renders/22161@1x.png index 2d5a611d2..8319243a8 100644 Binary files a/imgs/renders/22161@1x.png and b/imgs/renders/22161@1x.png differ diff --git a/imgs/renders/22189@1x.png b/imgs/renders/22189@1x.png index b247ba1a4..3586e2c15 100644 Binary files a/imgs/renders/22189@1x.png and b/imgs/renders/22189@1x.png differ diff --git a/imgs/renders/22234@1x.png b/imgs/renders/22234@1x.png index 27ffbbbd0..562027e35 100644 Binary files a/imgs/renders/22234@1x.png and b/imgs/renders/22234@1x.png differ diff --git a/imgs/renders/22252@1x.png b/imgs/renders/22252@1x.png index 7fe241945..722ff915e 100644 Binary files a/imgs/renders/22252@1x.png and b/imgs/renders/22252@1x.png differ diff --git a/imgs/renders/22316@1x.png b/imgs/renders/22316@1x.png index 6a800a6ab..788274ff3 100644 Binary files a/imgs/renders/22316@1x.png and b/imgs/renders/22316@1x.png differ diff --git a/imgs/renders/22317@1x.png b/imgs/renders/22317@1x.png new file mode 100644 index 000000000..bc44a744b Binary files /dev/null and b/imgs/renders/22317@1x.png differ diff --git a/imgs/renders/22317@2x.png b/imgs/renders/22317@2x.png new file mode 100644 index 000000000..5a7a8d6df Binary files /dev/null and b/imgs/renders/22317@2x.png differ diff --git a/imgs/renders/22325@1x.png b/imgs/renders/22325@1x.png new file mode 100644 index 000000000..e004e89d5 Binary files /dev/null and b/imgs/renders/22325@1x.png differ diff --git a/imgs/renders/22325@2x.png b/imgs/renders/22325@2x.png new file mode 100644 index 000000000..06e2f4d0b Binary files /dev/null and b/imgs/renders/22325@2x.png differ diff --git a/imgs/renders/2295@1x.png b/imgs/renders/2295@1x.png index a818b6b36..9fa61c3f1 100644 Binary files a/imgs/renders/2295@1x.png and b/imgs/renders/2295@1x.png differ diff --git a/imgs/renders/2382@1x.png b/imgs/renders/2382@1x.png index f788027e8..cfc0681c3 100644 Binary files a/imgs/renders/2382@1x.png and b/imgs/renders/2382@1x.png differ diff --git a/imgs/renders/2384@1x.png b/imgs/renders/2384@1x.png index 2d159cd80..de9053432 100644 Binary files a/imgs/renders/2384@1x.png and b/imgs/renders/2384@1x.png differ diff --git a/imgs/renders/2385@1x.png b/imgs/renders/2385@1x.png index 747c39f97..4ec49486d 100644 Binary files a/imgs/renders/2385@1x.png and b/imgs/renders/2385@1x.png differ diff --git a/imgs/renders/2387@1x.png b/imgs/renders/2387@1x.png index 91c63d231..c76063161 100644 Binary files a/imgs/renders/2387@1x.png and b/imgs/renders/2387@1x.png differ diff --git a/imgs/renders/2388@1x.png b/imgs/renders/2388@1x.png index 5c8d536e6..0f3755a49 100644 Binary files a/imgs/renders/2388@1x.png and b/imgs/renders/2388@1x.png differ diff --git a/imgs/renders/2390@1x.png b/imgs/renders/2390@1x.png index 082750fb9..4f781687a 100644 Binary files a/imgs/renders/2390@1x.png and b/imgs/renders/2390@1x.png differ diff --git a/imgs/renders/2523@1x.png b/imgs/renders/2523@1x.png index d64be2c8c..25e624558 100644 Binary files a/imgs/renders/2523@1x.png and b/imgs/renders/2523@1x.png differ diff --git a/imgs/renders/2632@1x.png b/imgs/renders/2632@1x.png index 6ce3fae3b..07d96500b 100644 Binary files a/imgs/renders/2632@1x.png and b/imgs/renders/2632@1x.png differ diff --git a/imgs/renders/2634@1x.png b/imgs/renders/2634@1x.png index 32de7e243..4ba2108aa 100644 Binary files a/imgs/renders/2634@1x.png and b/imgs/renders/2634@1x.png differ diff --git a/imgs/renders/2635@1x.png b/imgs/renders/2635@1x.png index 83b77b0aa..b4fb20731 100644 Binary files a/imgs/renders/2635@1x.png and b/imgs/renders/2635@1x.png differ diff --git a/imgs/renders/2642@1x.png b/imgs/renders/2642@1x.png index 0385a2fd2..7057a4c76 100644 Binary files a/imgs/renders/2642@1x.png and b/imgs/renders/2642@1x.png differ diff --git a/imgs/renders/2709@1x.png b/imgs/renders/2709@1x.png index 0bb43ac77..78f94be3c 100644 Binary files a/imgs/renders/2709@1x.png and b/imgs/renders/2709@1x.png differ diff --git a/imgs/renders/2710@1x.png b/imgs/renders/2710@1x.png index 7423caceb..48e3f2225 100644 Binary files a/imgs/renders/2710@1x.png and b/imgs/renders/2710@1x.png differ diff --git a/imgs/renders/2711@1x.png b/imgs/renders/2711@1x.png index 644459c8f..5331cea9b 100644 Binary files a/imgs/renders/2711@1x.png and b/imgs/renders/2711@1x.png differ diff --git a/imgs/renders/2712@1x.png b/imgs/renders/2712@1x.png index 361f98d65..2e46134b8 100644 Binary files a/imgs/renders/2712@1x.png and b/imgs/renders/2712@1x.png differ diff --git a/imgs/renders/2713@1x.png b/imgs/renders/2713@1x.png index e5c2fcbd6..f176380a4 100644 Binary files a/imgs/renders/2713@1x.png and b/imgs/renders/2713@1x.png differ diff --git a/imgs/renders/2714@1x.png b/imgs/renders/2714@1x.png index dfed49028..acd66a190 100644 Binary files a/imgs/renders/2714@1x.png and b/imgs/renders/2714@1x.png differ diff --git a/imgs/renders/2715@1x.png b/imgs/renders/2715@1x.png index e2b157b37..99553258c 100644 Binary files a/imgs/renders/2715@1x.png and b/imgs/renders/2715@1x.png differ diff --git a/imgs/renders/2716@1x.png b/imgs/renders/2716@1x.png index 880dca8f5..a192868d0 100644 Binary files a/imgs/renders/2716@1x.png and b/imgs/renders/2716@1x.png differ diff --git a/imgs/renders/2716@2x.png b/imgs/renders/2716@2x.png index 402baf61f..f546c3113 100644 Binary files a/imgs/renders/2716@2x.png and b/imgs/renders/2716@2x.png differ diff --git a/imgs/renders/2737@1x.png b/imgs/renders/2737@1x.png index fd4694f0c..188433d34 100644 Binary files a/imgs/renders/2737@1x.png and b/imgs/renders/2737@1x.png differ diff --git a/imgs/renders/2738@1x.png b/imgs/renders/2738@1x.png index 748126a42..68d236154 100644 Binary files a/imgs/renders/2738@1x.png and b/imgs/renders/2738@1x.png differ diff --git a/imgs/renders/2738@2x.png b/imgs/renders/2738@2x.png index 6d5a9cacc..3206a958c 100644 Binary files a/imgs/renders/2738@2x.png and b/imgs/renders/2738@2x.png differ diff --git a/imgs/renders/2740@1x.png b/imgs/renders/2740@1x.png index c890051c0..426174e5d 100644 Binary files a/imgs/renders/2740@1x.png and b/imgs/renders/2740@1x.png differ diff --git a/imgs/renders/2743@1x.png b/imgs/renders/2743@1x.png index 992742625..efa6bae78 100644 Binary files a/imgs/renders/2743@1x.png and b/imgs/renders/2743@1x.png differ diff --git a/imgs/renders/2744@1x.png b/imgs/renders/2744@1x.png index cc0f586bc..a5c1544d2 100644 Binary files a/imgs/renders/2744@1x.png and b/imgs/renders/2744@1x.png differ diff --git a/imgs/renders/2755@1x.png b/imgs/renders/2755@1x.png index 0285ebfbb..94bd2c53e 100644 Binary files a/imgs/renders/2755@1x.png and b/imgs/renders/2755@1x.png differ diff --git a/imgs/renders/2786@1x.png b/imgs/renders/2786@1x.png index c08540b89..f8c63a73b 100644 Binary files a/imgs/renders/2786@1x.png and b/imgs/renders/2786@1x.png differ diff --git a/imgs/renders/2794@1x.png b/imgs/renders/2794@1x.png index 649b65724..078b99f2c 100644 Binary files a/imgs/renders/2794@1x.png and b/imgs/renders/2794@1x.png differ diff --git a/imgs/renders/2804@1x.png b/imgs/renders/2804@1x.png index 622e4e663..0a777ddaf 100644 Binary files a/imgs/renders/2804@1x.png and b/imgs/renders/2804@1x.png differ diff --git a/imgs/renders/2805@1x.png b/imgs/renders/2805@1x.png index 4869cc2b3..690cc7aca 100644 Binary files a/imgs/renders/2805@1x.png and b/imgs/renders/2805@1x.png differ diff --git a/imgs/renders/2811@1x.png b/imgs/renders/2811@1x.png index 067888b85..ff513dd74 100644 Binary files a/imgs/renders/2811@1x.png and b/imgs/renders/2811@1x.png differ diff --git a/imgs/renders/2814@1x.png b/imgs/renders/2814@1x.png index bbb2f1b51..e482495f7 100644 Binary files a/imgs/renders/2814@1x.png and b/imgs/renders/2814@1x.png differ diff --git a/imgs/renders/2894@1x.png b/imgs/renders/2894@1x.png index 213accd0f..80e83802f 100644 Binary files a/imgs/renders/2894@1x.png and b/imgs/renders/2894@1x.png differ diff --git a/imgs/renders/2905@1x.png b/imgs/renders/2905@1x.png index 1c6c411b0..0752e38b6 100644 Binary files a/imgs/renders/2905@1x.png and b/imgs/renders/2905@1x.png differ diff --git a/imgs/renders/2906@1x.png b/imgs/renders/2906@1x.png index 6a6fc75f1..68c76b627 100644 Binary files a/imgs/renders/2906@1x.png and b/imgs/renders/2906@1x.png differ diff --git a/imgs/renders/2909@1x.png b/imgs/renders/2909@1x.png index 736894a34..e454beb7b 100644 Binary files a/imgs/renders/2909@1x.png and b/imgs/renders/2909@1x.png differ diff --git a/imgs/renders/2910@1x.png b/imgs/renders/2910@1x.png index ae229638e..760a4aad0 100644 Binary files a/imgs/renders/2910@1x.png and b/imgs/renders/2910@1x.png differ diff --git a/imgs/renders/2912@1x.png b/imgs/renders/2912@1x.png index 503fdfd20..db4632283 100644 Binary files a/imgs/renders/2912@1x.png and b/imgs/renders/2912@1x.png differ diff --git a/imgs/renders/2912@2x.png b/imgs/renders/2912@2x.png index 13193e340..b33f0a30a 100644 Binary files a/imgs/renders/2912@2x.png and b/imgs/renders/2912@2x.png differ diff --git a/imgs/renders/2925@1x.png b/imgs/renders/2925@1x.png index affff46ed..3270530f7 100644 Binary files a/imgs/renders/2925@1x.png and b/imgs/renders/2925@1x.png differ diff --git a/imgs/renders/2926@1x.png b/imgs/renders/2926@1x.png index 1eb3c1b4e..8e1323bd8 100644 Binary files a/imgs/renders/2926@1x.png and b/imgs/renders/2926@1x.png differ diff --git a/imgs/renders/2928@1x.png b/imgs/renders/2928@1x.png index 9bdce46ad..c0b4b627b 100644 Binary files a/imgs/renders/2928@1x.png and b/imgs/renders/2928@1x.png differ diff --git a/imgs/renders/2929@1x.png b/imgs/renders/2929@1x.png index 0295ddd2d..ff8f03272 100644 Binary files a/imgs/renders/2929@1x.png and b/imgs/renders/2929@1x.png differ diff --git a/imgs/renders/2930@1x.png b/imgs/renders/2930@1x.png index 38633f3c3..bde466bf3 100644 Binary files a/imgs/renders/2930@1x.png and b/imgs/renders/2930@1x.png differ diff --git a/imgs/renders/2931@1x.png b/imgs/renders/2931@1x.png index d26f5a1eb..2dc65eac7 100644 Binary files a/imgs/renders/2931@1x.png and b/imgs/renders/2931@1x.png differ diff --git a/imgs/renders/2932@1x.png b/imgs/renders/2932@1x.png index c71e6177a..84d3ab142 100644 Binary files a/imgs/renders/2932@1x.png and b/imgs/renders/2932@1x.png differ diff --git a/imgs/renders/2939@1x.png b/imgs/renders/2939@1x.png index ff69c1f5d..a0a297ab6 100644 Binary files a/imgs/renders/2939@1x.png and b/imgs/renders/2939@1x.png differ diff --git a/imgs/renders/296@1x.png b/imgs/renders/296@1x.png index c9c775197..4d134bd08 100644 Binary files a/imgs/renders/296@1x.png and b/imgs/renders/296@1x.png differ diff --git a/imgs/renders/298@1x.png b/imgs/renders/298@1x.png index 9be1318ae..d6cfd08e6 100644 Binary files a/imgs/renders/298@1x.png and b/imgs/renders/298@1x.png differ diff --git a/imgs/renders/300@1x.png b/imgs/renders/300@1x.png index 17a4f727a..99ecd8677 100644 Binary files a/imgs/renders/300@1x.png and b/imgs/renders/300@1x.png differ diff --git a/imgs/renders/301@1x.png b/imgs/renders/301@1x.png index ca566e6b9..658776e56 100644 Binary files a/imgs/renders/301@1x.png and b/imgs/renders/301@1x.png differ diff --git a/imgs/renders/301@2x.png b/imgs/renders/301@2x.png index de7f133cf..f85f678f3 100644 Binary files a/imgs/renders/301@2x.png and b/imgs/renders/301@2x.png differ diff --git a/imgs/renders/302@1x.png b/imgs/renders/302@1x.png index d600bf8d2..ca225bfde 100644 Binary files a/imgs/renders/302@1x.png and b/imgs/renders/302@1x.png differ diff --git a/imgs/renders/303@1x.png b/imgs/renders/303@1x.png index 5f8158adf..4a12216d8 100644 Binary files a/imgs/renders/303@1x.png and b/imgs/renders/303@1x.png differ diff --git a/imgs/renders/304@1x.png b/imgs/renders/304@1x.png index 58eee6e34..8622010c7 100644 Binary files a/imgs/renders/304@1x.png and b/imgs/renders/304@1x.png differ diff --git a/imgs/renders/305@1x.png b/imgs/renders/305@1x.png index be6f1e952..613e60f26 100644 Binary files a/imgs/renders/305@1x.png and b/imgs/renders/305@1x.png differ diff --git a/imgs/renders/306@1x.png b/imgs/renders/306@1x.png index 87b6bf145..92d1dd761 100644 Binary files a/imgs/renders/306@1x.png and b/imgs/renders/306@1x.png differ diff --git a/imgs/renders/308@1x.png b/imgs/renders/308@1x.png index a4166ca7e..76f347a97 100644 Binary files a/imgs/renders/308@1x.png and b/imgs/renders/308@1x.png differ diff --git a/imgs/renders/309@1x.png b/imgs/renders/309@1x.png index 4272d403e..8dae0b42a 100644 Binary files a/imgs/renders/309@1x.png and b/imgs/renders/309@1x.png differ diff --git a/imgs/renders/310@1x.png b/imgs/renders/310@1x.png index e810a525a..ad1f1b0a9 100644 Binary files a/imgs/renders/310@1x.png and b/imgs/renders/310@1x.png differ diff --git a/imgs/renders/311@1x.png b/imgs/renders/311@1x.png index 7bac7bfbe..8e157e261 100644 Binary files a/imgs/renders/311@1x.png and b/imgs/renders/311@1x.png differ diff --git a/imgs/renders/312@1x.png b/imgs/renders/312@1x.png index 93be20fc6..4a4b593a8 100644 Binary files a/imgs/renders/312@1x.png and b/imgs/renders/312@1x.png differ diff --git a/imgs/renders/3132@1x.png b/imgs/renders/3132@1x.png index 21b3f8146..7edb2689f 100644 Binary files a/imgs/renders/3132@1x.png and b/imgs/renders/3132@1x.png differ diff --git a/imgs/renders/3133@1x.png b/imgs/renders/3133@1x.png index bc2d28f76..06cddffa9 100644 Binary files a/imgs/renders/3133@1x.png and b/imgs/renders/3133@1x.png differ diff --git a/imgs/renders/3134@1x.png b/imgs/renders/3134@1x.png index 20e6f9e07..39fe0bece 100644 Binary files a/imgs/renders/3134@1x.png and b/imgs/renders/3134@1x.png differ diff --git a/imgs/renders/3135@1x.png b/imgs/renders/3135@1x.png index 3c6349623..472c32d14 100644 Binary files a/imgs/renders/3135@1x.png and b/imgs/renders/3135@1x.png differ diff --git a/imgs/renders/314@1x.png b/imgs/renders/314@1x.png index 9b0420410..2e320c555 100644 Binary files a/imgs/renders/314@1x.png and b/imgs/renders/314@1x.png differ diff --git a/imgs/renders/3168@1x.png b/imgs/renders/3168@1x.png index afd6849a8..42158d868 100644 Binary files a/imgs/renders/3168@1x.png and b/imgs/renders/3168@1x.png differ diff --git a/imgs/renders/3170@1x.png b/imgs/renders/3170@1x.png index 1e7620b4c..16bb79a2a 100644 Binary files a/imgs/renders/3170@1x.png and b/imgs/renders/3170@1x.png differ diff --git a/imgs/renders/318@1x.png b/imgs/renders/318@1x.png index c17afcdd8..0757872ec 100644 Binary files a/imgs/renders/318@1x.png and b/imgs/renders/318@1x.png differ diff --git a/imgs/renders/318@2x.png b/imgs/renders/318@2x.png index c945194c8..4a520d7db 100644 Binary files a/imgs/renders/318@2x.png and b/imgs/renders/318@2x.png differ diff --git a/imgs/renders/3204@1x.png b/imgs/renders/3204@1x.png index cfbde7a4e..a6d00758d 100644 Binary files a/imgs/renders/3204@1x.png and b/imgs/renders/3204@1x.png differ diff --git a/imgs/renders/3205@1x.png b/imgs/renders/3205@1x.png index eee980b50..98c238a52 100644 Binary files a/imgs/renders/3205@1x.png and b/imgs/renders/3205@1x.png differ diff --git a/imgs/renders/3207@1x.png b/imgs/renders/3207@1x.png index 9409b80fb..ff462a79f 100644 Binary files a/imgs/renders/3207@1x.png and b/imgs/renders/3207@1x.png differ diff --git a/imgs/renders/320@1x.png b/imgs/renders/320@1x.png index b820a724a..f40bb87e0 100644 Binary files a/imgs/renders/320@1x.png and b/imgs/renders/320@1x.png differ diff --git a/imgs/renders/321@1x.png b/imgs/renders/321@1x.png index 580e39d2b..f34caa57f 100644 Binary files a/imgs/renders/321@1x.png and b/imgs/renders/321@1x.png differ diff --git a/imgs/renders/323@1x.png b/imgs/renders/323@1x.png index e921f3b8e..75d90e240 100644 Binary files a/imgs/renders/323@1x.png and b/imgs/renders/323@1x.png differ diff --git a/imgs/renders/325@1x.png b/imgs/renders/325@1x.png index 3bab3c461..f3b17d5ce 100644 Binary files a/imgs/renders/325@1x.png and b/imgs/renders/325@1x.png differ diff --git a/imgs/renders/326@1x.png b/imgs/renders/326@1x.png index 4c2b5d201..e3cadd47c 100644 Binary files a/imgs/renders/326@1x.png and b/imgs/renders/326@1x.png differ diff --git a/imgs/renders/328@1x.png b/imgs/renders/328@1x.png index 0d2b4f28a..37f7e5cbf 100644 Binary files a/imgs/renders/328@1x.png and b/imgs/renders/328@1x.png differ diff --git a/imgs/renders/330@1x.png b/imgs/renders/330@1x.png index ffaa4d1a3..c00c15691 100644 Binary files a/imgs/renders/330@1x.png and b/imgs/renders/330@1x.png differ diff --git a/imgs/renders/3350@1x.png b/imgs/renders/3350@1x.png index b0b983b40..795678f81 100644 Binary files a/imgs/renders/3350@1x.png and b/imgs/renders/3350@1x.png differ diff --git a/imgs/renders/3351@1x.png b/imgs/renders/3351@1x.png index 97f5d21b3..417cb251e 100644 Binary files a/imgs/renders/3351@1x.png and b/imgs/renders/3351@1x.png differ diff --git a/imgs/renders/3351@2x.png b/imgs/renders/3351@2x.png index 678dc06d4..e99ed09e9 100644 Binary files a/imgs/renders/3351@2x.png and b/imgs/renders/3351@2x.png differ diff --git a/imgs/renders/3353@1x.png b/imgs/renders/3353@1x.png index 34d808844..66b9f4d02 100644 Binary files a/imgs/renders/3353@1x.png and b/imgs/renders/3353@1x.png differ diff --git a/imgs/renders/3354@1x.png b/imgs/renders/3354@1x.png index 4f06805cc..df3505688 100644 Binary files a/imgs/renders/3354@1x.png and b/imgs/renders/3354@1x.png differ diff --git a/imgs/renders/3355@1x.png b/imgs/renders/3355@1x.png index d6c18617d..cb6324d81 100644 Binary files a/imgs/renders/3355@1x.png and b/imgs/renders/3355@1x.png differ diff --git a/imgs/renders/3355@2x.png b/imgs/renders/3355@2x.png index 771362023..126b7750d 100644 Binary files a/imgs/renders/3355@2x.png and b/imgs/renders/3355@2x.png differ diff --git a/imgs/renders/335@1x.png b/imgs/renders/335@1x.png index 12946c678..13d6e5b8a 100644 Binary files a/imgs/renders/335@1x.png and b/imgs/renders/335@1x.png differ diff --git a/imgs/renders/3360@1x.png b/imgs/renders/3360@1x.png index 9f2d144c7..ad3e63203 100644 Binary files a/imgs/renders/3360@1x.png and b/imgs/renders/3360@1x.png differ diff --git a/imgs/renders/3361@1x.png b/imgs/renders/3361@1x.png index d59b14e2a..2664dbcaf 100644 Binary files a/imgs/renders/3361@1x.png and b/imgs/renders/3361@1x.png differ diff --git a/imgs/renders/3363@1x.png b/imgs/renders/3363@1x.png index 1bc577f2a..b292f8e7b 100644 Binary files a/imgs/renders/3363@1x.png and b/imgs/renders/3363@1x.png differ diff --git a/imgs/renders/3364@1x.png b/imgs/renders/3364@1x.png index 9f76b9c73..6e419d926 100644 Binary files a/imgs/renders/3364@1x.png and b/imgs/renders/3364@1x.png differ diff --git a/imgs/renders/3365@1x.png b/imgs/renders/3365@1x.png index 30fd81f9c..0c7a163bd 100644 Binary files a/imgs/renders/3365@1x.png and b/imgs/renders/3365@1x.png differ diff --git a/imgs/renders/337@1x.png b/imgs/renders/337@1x.png index a07e99639..5d9042484 100644 Binary files a/imgs/renders/337@1x.png and b/imgs/renders/337@1x.png differ diff --git a/imgs/renders/338@1x.png b/imgs/renders/338@1x.png index cd6d95ce8..a5adec6c0 100644 Binary files a/imgs/renders/338@1x.png and b/imgs/renders/338@1x.png differ diff --git a/imgs/renders/341@1x.png b/imgs/renders/341@1x.png index 567d10c98..ec325a05e 100644 Binary files a/imgs/renders/341@1x.png and b/imgs/renders/341@1x.png differ diff --git a/imgs/renders/343@1x.png b/imgs/renders/343@1x.png index 9802dcaae..990466dc1 100644 Binary files a/imgs/renders/343@1x.png and b/imgs/renders/343@1x.png differ diff --git a/imgs/renders/3466@1x.png b/imgs/renders/3466@1x.png index 80c5ec991..0e842d0ee 100644 Binary files a/imgs/renders/3466@1x.png and b/imgs/renders/3466@1x.png differ diff --git a/imgs/renders/3714@1x.png b/imgs/renders/3714@1x.png index bfcc08609..51aa66a81 100644 Binary files a/imgs/renders/3714@1x.png and b/imgs/renders/3714@1x.png differ diff --git a/imgs/renders/3799@1x.png b/imgs/renders/3799@1x.png index a0de48c35..42869ab2e 100644 Binary files a/imgs/renders/3799@1x.png and b/imgs/renders/3799@1x.png differ diff --git a/imgs/renders/3800@1x.png b/imgs/renders/3800@1x.png index 7746c0eb9..87f41c339 100644 Binary files a/imgs/renders/3800@1x.png and b/imgs/renders/3800@1x.png differ diff --git a/imgs/renders/3815@1x.png b/imgs/renders/3815@1x.png index 5555e1d58..005071d69 100644 Binary files a/imgs/renders/3815@1x.png and b/imgs/renders/3815@1x.png differ diff --git a/imgs/renders/38@1x.png b/imgs/renders/38@1x.png index 6d17e8f06..1506c7e2b 100644 Binary files a/imgs/renders/38@1x.png and b/imgs/renders/38@1x.png differ diff --git a/imgs/renders/39@1x.png b/imgs/renders/39@1x.png index 169d189c4..dd4ec0491 100644 Binary files a/imgs/renders/39@1x.png and b/imgs/renders/39@1x.png differ diff --git a/imgs/renders/40@1x.png b/imgs/renders/40@1x.png index 1f168195c..303dcfefe 100644 Binary files a/imgs/renders/40@1x.png and b/imgs/renders/40@1x.png differ diff --git a/imgs/renders/42@1x.png b/imgs/renders/42@1x.png index 348b594b6..1f62dc960 100644 Binary files a/imgs/renders/42@1x.png and b/imgs/renders/42@1x.png differ diff --git a/imgs/renders/43@1x.png b/imgs/renders/43@1x.png index d74477001..823e10c45 100644 Binary files a/imgs/renders/43@1x.png and b/imgs/renders/43@1x.png differ diff --git a/imgs/renders/44@1x.png b/imgs/renders/44@1x.png index da8d39686..bd58dc771 100644 Binary files a/imgs/renders/44@1x.png and b/imgs/renders/44@1x.png differ diff --git a/imgs/renders/4517@1x.png b/imgs/renders/4517@1x.png index 1027aa7cb..4bf32b107 100644 Binary files a/imgs/renders/4517@1x.png and b/imgs/renders/4517@1x.png differ diff --git a/imgs/renders/45@1x.png b/imgs/renders/45@1x.png index f6703c4af..0fa5cb8a8 100644 Binary files a/imgs/renders/45@1x.png and b/imgs/renders/45@1x.png differ diff --git a/imgs/renders/46@1x.png b/imgs/renders/46@1x.png index 4c1d16dd9..3a0edd6c5 100644 Binary files a/imgs/renders/46@1x.png and b/imgs/renders/46@1x.png differ diff --git a/imgs/renders/48@1x.png b/imgs/renders/48@1x.png index 9de44dde9..4614cbd71 100644 Binary files a/imgs/renders/48@1x.png and b/imgs/renders/48@1x.png differ diff --git a/imgs/renders/51@1x.png b/imgs/renders/51@1x.png index 8deaf09df..346e6e453 100644 Binary files a/imgs/renders/51@1x.png and b/imgs/renders/51@1x.png differ diff --git a/imgs/renders/53@1x.png b/imgs/renders/53@1x.png index efbf8b8ed..81b65324f 100644 Binary files a/imgs/renders/53@1x.png and b/imgs/renders/53@1x.png differ diff --git a/imgs/renders/54@1x.png b/imgs/renders/54@1x.png index 601dac8cc..a094df2aa 100644 Binary files a/imgs/renders/54@1x.png and b/imgs/renders/54@1x.png differ diff --git a/imgs/renders/56@1x.png b/imgs/renders/56@1x.png index 713382762..11850319e 100644 Binary files a/imgs/renders/56@1x.png and b/imgs/renders/56@1x.png differ diff --git a/imgs/renders/57@1x.png b/imgs/renders/57@1x.png index 935429e08..5c750c597 100644 Binary files a/imgs/renders/57@1x.png and b/imgs/renders/57@1x.png differ diff --git a/imgs/renders/58@1x.png b/imgs/renders/58@1x.png index 17bcc1c34..b3ac3c9d0 100644 Binary files a/imgs/renders/58@1x.png and b/imgs/renders/58@1x.png differ diff --git a/imgs/renders/61@1x.png b/imgs/renders/61@1x.png index 8be84d9a0..72be3b11f 100644 Binary files a/imgs/renders/61@1x.png and b/imgs/renders/61@1x.png differ diff --git a/imgs/renders/62@1x.png b/imgs/renders/62@1x.png index b44fbffeb..6190a5a92 100644 Binary files a/imgs/renders/62@1x.png and b/imgs/renders/62@1x.png differ diff --git a/imgs/renders/62@2x.png b/imgs/renders/62@2x.png index a047591f2..9d17475bc 100644 Binary files a/imgs/renders/62@2x.png and b/imgs/renders/62@2x.png differ diff --git a/imgs/renders/63@1x.png b/imgs/renders/63@1x.png index 75490116d..d5fb13ab8 100644 Binary files a/imgs/renders/63@1x.png and b/imgs/renders/63@1x.png differ diff --git a/imgs/renders/65@1x.png b/imgs/renders/65@1x.png index 311b7bf45..b13ee7bf3 100644 Binary files a/imgs/renders/65@1x.png and b/imgs/renders/65@1x.png differ diff --git a/pyfa.spec b/pyfa.spec new file mode 100644 index 000000000..d3156bb80 --- /dev/null +++ b/pyfa.spec @@ -0,0 +1,121 @@ +# -*- mode: python -*- + +import os +from itertools import chain +import subprocess +import requests.certs +import platform + +os_name = platform.system() +block_cipher = None + +added_files = [ + ('imgs/gui/*.png', 'imgs/gui'), + ('imgs/gui/*.gif', 'imgs/gui'), + ('imgs/icons/*.png', 'imgs/icons'), + ('imgs/renders/*.png', 'imgs/renders'), + ('service/jargon/*.yaml', 'service/jargon'), + (requests.certs.where(), '.'), # is this needed anymore? + ('eve.db', '.'), + ('README.md', '.'), + ('LICENSE', '.'), + ('version.yml', '.'), +] + +icon = None +pathex = [] +upx = True +debug = False + +if os_name == 'Windows': + added_files.extend([ + ('dist_assets/win/pyfa.ico', '.'), + ('dist_assets/win/pyfa.exe.manifest', '.'), + ('dist_assets/win/Microsoft.VC90.CRT.manifest', '.') + ]) + + icon = 'dist_assets/win/pyfa.ico' + + pathex.extend([ + # Need this, see https://github.com/pyinstaller/pyinstaller/issues/1566 + # To get this, download and install windows 10 SDK + # If not building on Windows 10, this might be optional + r'C:\Program Files (x86)\Windows Kits\10\Redist\ucrt\DLLs\x86' + ]) + +if os_name == 'Darwin': + added_files.extend([ + ('dist_assets/win/pyfa.ico', '.'), # osx only + ]) + + icon = 'dist_assets/mac/pyfa.icns' + +import_these = [ + 'numpy.core._dtype_ctypes' # https://github.com/pyinstaller/pyinstaller/issues/3982 +] + +# Walk directories that do dynamic importing +paths = ('eos/effects', 'eos/db/migrations', 'service/conversions') +for root, folders, files in chain.from_iterable(os.walk(path) for path in paths): + for file_ in files: + if file_.endswith(".py") and not file_.startswith("_"): + mod_name = "{}.{}".format( + root.replace("/", "."), + file_.split(".py")[0], + ) + import_these.append(mod_name) + +a = Analysis(['pyfa.py'], + pathex= pathex, + binaries=[], + datas=added_files, + hiddenimports=import_these, + hookspath=['dist_assets/pyinstaller_hooks'], + runtime_hooks=[], + excludes=['Tkinter'], + win_no_prefer_redirects=False, + win_private_assemblies=False, + cipher=block_cipher) + +pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) + + +exe = EXE( + pyz, + a.scripts, + exclude_binaries=True, + name='pyfa', + debug=debug, + strip=False, + upx=upx, + icon= icon, + # version='win-version-info.txt', + console=False +) + +coll = COLLECT( + exe, + a.binaries, + a.zipfiles, + a.datas, + strip=False, + upx=upx, + name='pyfa', +) + +if platform.system() == 'Darwin': + info_plist = { + 'NSHighResolutionCapable': 'True', + 'NSPrincipalClass': 'NSApplication', + 'CFBundleName': 'pyfa', + 'CFBundleDisplayName': 'pyfa', + 'CFBundleIdentifier': 'org.pyfaorg.pyfa', + 'CFBundleVersion': '1.2.3', + 'CFBundleShortVersionString': '1.2.3', + } + app = BUNDLE(exe, + name='pyfa.app', + icon=icon, + bundle_identifier=None, + info_plist=info_plist + ) diff --git a/requirements.txt b/requirements.txt index a938d0217..0f75a043c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,11 +3,11 @@ logbook >= 1.0.0 matplotlib >= 2.0.0 python-dateutil requests >= 2.0.0 -sqlalchemy >= 1.0.5 -cryptography -diskcache -markdown2 -packaging -roman -beautifulsoup4 -PyYAML +sqlalchemy == 1.0.5 +cryptography ==2.2.2 +markdown2==2.3.5 +packaging==16.8 +roman==2.0.0 +beautifulsoup4==4.6.0 +PyYAML==3.12 +PyInstaller == 3.3 \ No newline at end of file diff --git a/scripts/dump_version.py b/scripts/dump_version.py new file mode 100644 index 000000000..4b3a9583e --- /dev/null +++ b/scripts/dump_version.py @@ -0,0 +1,23 @@ +""" +This script is solely used when generating builds. It generates a version number automatically using +git tags as it's basis. Whenever a build is created, run this file beforehand and it should replace +the old version number with the new one in VERSION.YML +""" + +import yaml +import subprocess +import os + + +with open("version.yml", 'r+') as file: + data = yaml.load(file) + file.seek(0) + file.truncate() + # todo: run Version() on the tag to ensure that it's of proper formatting - fail a test if not and prevent building + # python's versioning spec doesn't handle the same format git describe outputs, so convert it. + label = os.environ["PYFA_VERSION"].split('-') if "PYFA_VERSION" in os.environ else subprocess.check_output(["git", "describe", "--tags"]).strip().decode().split('-') + label = '-'.join(label[:-2])+'+'+'-'.join(label[-2:]) if len(label) > 1 else label[0] + print(label) + data['version'] = label + yaml.dump(data, file, default_flow_style=False) + diff --git a/scripts/iconIDs.yaml b/scripts/iconIDs.yaml index f8a5d696c..a2bdfc349 100644 --- a/scripts/iconIDs.yaml +++ b/scripts/iconIDs.yaml @@ -706,7 +706,7 @@ - tech2 iconFile: res:/ui/texture/icons/12_64_13.png 398: - description: Corpse floating in space (male?). - Corpse + description: chemical item iconFile: res:/ui/texture/icons/11_64_5.png 400: description: Mineral - Pyerite @@ -10432,3 +10432,66 @@ 22076: description: Gift Box with Ribbon iconFile: res:/ui/texture/icons/76_64_3.png +22077: + description: 49978_Male_outer_ExplorationSuit_M01_Types_ExplorationSuit_M01_W.png + iconFile: res:/UI/Asset/mannequin/outer/49978_Male_outer_ExplorationSuit_M01_Types_ExplorationSuit_M01_W.png +22078: + description: 49980_Female_Outer_ExplorationSuit_F01_Types_ExplorationSuit_F01_W.png + iconFile: res:/UI/Asset/mannequin/outer/49980_Female_Outer_ExplorationSuit_F01_Types_ExplorationSuit_F01_W.png +22079: + description: Preview for reward track augmentations + iconFile: res:/UI/Texture/Icons/RewardTrack/reward_Holiday2018_Augmentation1.png +22080: + description: Preview for reward track augmentations + iconFile: res:/UI/Texture/Icons/RewardTrack/reward_Holiday2018_Augmentation2.png +22081: + description: Holiday'18 Crate - Drake/Rupture Splash + iconFile: res:/UI/Texture/classes/ItemPacks/SplashImages/Holiday2018/splash_Holiday2018_DrakeRupture.png +22082: + description: Holiday'18 Crate - ExpSuits + iconFile: res:/UI/Texture/classes/ItemPacks/SplashImages/Holiday2018/splash_Holiday2018_ExplorationSuits.png +22084: + description: Holiday'18 Crate - Augmentation Set 1 + iconFile: res:/UI/Texture/classes/ItemPacks/SplashImages/Holiday2018/splash_Holiday2018_FaceAugmentation1.png +22085: + description: Holiday'18 Crate - Augmentation Set 2 + iconFile: res:/UI/Texture/classes/ItemPacks/SplashImages/Holiday2018/splash_Holiday2018_FaceAugmentation2.png +22086: + description: Holiday'18 Crate - Gnosis/Punisher Splash + iconFile: res:/UI/Texture/classes/ItemPacks/SplashImages/Holiday2018/splash_Holiday2018_GnosisPunisher.png +22087: + description: 49978_Male_outer_ExplorationSuit_M01_Types_ExplorationSuit_M01_W.png + iconFile: res:/UI/Asset/mannequin/outer/49978_Male_outer_ExplorationSuit_M01_Types_ExplorationSuit_M01_W.png +22088: + description: 49980_Female_Outer_ExplorationSuit_F01_Types_ExplorationSuit_F01_W.png + iconFile: res:/UI/Asset/mannequin/outer/49980_Female_Outer_ExplorationSuit_F01_Types_ExplorationSuit_F01_W.png +22089: + description: 49984_Female_Makeup_Augmentations_Face_Paint_F01_Types_Face_Paint_F01_V0_Blue.png + iconFile: res:/UI/Asset/mannequin/makeup_augmentations/49984_Female_Makeup_Augmentations_Face_Paint_F01_Types_Face_Paint_F01_V0_Blue.png +22090: + description: 49985_Female_Makeup_Augmentations_Face_Paint_F01_Types_Face_Paint_F01_V10_W.png + iconFile: res:/UI/Asset/mannequin/makeup_augmentations/49985_Female_Makeup_Augmentations_Face_Paint_F01_Types_Face_Paint_F01_V10_W.png +22091: + backgrounds: + - blueprint + - blueprintCopy + description: Mutadaptive Remote Repairer + foregrounds: + - faction + - tech2 + iconFile: res:/ui/texture/icons/modules/abyssalRemoteRepairer.png +22092: + description: 49987_Male_Makeup_Augmentations_Face_Paint_M01_Types_Face_Paint_M01_V6_Blue.png + iconFile: res:/UI/Asset/mannequin/makeup_augmentations/49987_Male_Makeup_Augmentations_Face_Paint_M01_Types_Face_Paint_M01_V6_Blue.png +22093: + description: Generic SKIN icon for crates containing multiple SKINs + iconFile: res:/UI/Texture/Icons/RewardTrack/crateSkinContainer.png +22094: + description: Preview icon for exploration suit reward track winter'18 + iconFile: res:/UI/Texture/Icons/RewardTrack/crateWinterExplorationSuit.png +22095: + description: 49986_male_Makeup_Augmentations_Face_Paint_M01_Types_Face_Paint_M01_V10_W.png + iconFile: res:/UI/Asset/mannequin/makeup_augmentations/49986_male_Makeup_Augmentations_Face_Paint_M01_Types_Face_Paint_M01_V10_W.png +22096: + description: Winter Login Campaign Banner + iconFile: res:/UI/Texture/LoginCampaigns/Winter_2018.png diff --git a/scripts/jsonToSql.py b/scripts/jsonToSql.py index 39e51d198..913b74b1c 100755 --- a/scripts/jsonToSql.py +++ b/scripts/jsonToSql.py @@ -28,6 +28,8 @@ sys.path.insert(0, os.path.realpath(os.path.join(path, '..'))) import json import argparse +import itertools + CATEGORIES_TO_REMOVE = [ 30 # Apparel @@ -174,6 +176,119 @@ def main(db, json_path): newData.append(newRow) return newData + def fillReplacements(tables): + + def compareAttrs(attrs1, attrs2, attrHig): + """ + Compares received attribute sets. Returns: + - 0 if sets are different + - 1 if sets are exactly the same + - 2 if first set is strictly better + - 3 if second set is strictly better + """ + if set(attrs1) != set(attrs2): + return 0 + if all(attrs1[aid] == attrs2[aid] for aid in attrs1): + return 1 + if all( + (attrs1[aid] >= attrs2[aid] and attrHig[aid]) or + (attrs1[aid] <= attrs2[aid] and not attrHig[aid]) + for aid in attrs1 + ): + return 2 + if all( + (attrs2[aid] >= attrs1[aid] and attrHig[aid]) or + (attrs2[aid] <= attrs1[aid] and not attrHig[aid]) + for aid in attrs1 + ): + return 3 + return 0 + + skillReqAttribs = { + 182: 277, + 183: 278, + 184: 279, + 1285: 1286, + 1289: 1287, + 1290: 1288} + skillReqAttribsFlat = set(skillReqAttribs.keys()).union(skillReqAttribs.values()) + # Get data on type groups + typesGroups = {} + for row in tables['evetypes']: + typesGroups[row['typeID']] = row['groupID'] + # Get data on type attributes + typesNormalAttribs = {} + typesSkillAttribs = {} + for row in tables['dgmtypeattribs']: + attributeID = row['attributeID'] + if attributeID in skillReqAttribsFlat: + typeSkillAttribs = typesSkillAttribs.setdefault(row['typeID'], {}) + typeSkillAttribs[row['attributeID']] = row['value'] + # Ignore these attributes for comparison purposes + elif attributeID in ( + 422, # techLevel + 633, # metaLevel + 1692 # metaGroupID + ): + continue + else: + typeNormalAttribs = typesNormalAttribs.setdefault(row['typeID'], {}) + typeNormalAttribs[row['attributeID']] = row['value'] + # Get data on skill requirements + typesSkillReqs = {} + for typeID, typeAttribs in typesSkillAttribs.items(): + typeSkillAttribs = typesSkillAttribs.get(typeID, {}) + if not typeSkillAttribs: + continue + typeSkillReqs = typesSkillReqs.setdefault(typeID, {}) + for skillreqTypeAttr, skillreqLevelAttr in skillReqAttribs.items(): + try: + skillType = int(typeSkillAttribs[skillreqTypeAttr]) + skillLevel = int(typeSkillAttribs[skillreqLevelAttr]) + except (KeyError, ValueError): + continue + typeSkillReqs[skillType] = skillLevel + # Get data on attribute highIsGood flag + attrHig = {} + for row in tables['dgmattribs']: + attrHig[row['attributeID']] = bool(row['highIsGood']) + # As EVE affects various types mostly depending on their group or skill requirements, + # we're going to group various types up this way + groupedData = {} + for row in tables['evetypes']: + typeID = row['typeID'] + typeAttribs = typesNormalAttribs.get(typeID, {}) + # Ignore stuff w/o attributes + if not typeAttribs: + continue + # We need only skill types, not levels for keys + typeSkillreqs = frozenset(typesSkillReqs.get(typeID, {})) + typeGroup = typesGroups[typeID] + groupData = groupedData.setdefault((typeGroup, typeSkillreqs), []) + groupData.append((typeID, typeAttribs)) + same = {} + better = {} + # Now, go through composed groups and for every item within it find items which are + # the same and which are better + for groupData in groupedData.values(): + for type1, type2 in itertools.combinations(groupData, 2): + comparisonResult = compareAttrs(type1[1], type2[1], attrHig) + # Equal + if comparisonResult == 1: + same.setdefault(type1[0], set()).add(type2[0]) + same.setdefault(type2[0], set()).add(type1[0]) + # First is better + elif comparisonResult == 2: + better.setdefault(type2[0], set()).add(type1[0]) + # Second is better + elif comparisonResult == 3: + better.setdefault(type1[0], set()).add(type2[0]) + # Put this data into types table so that normal process hooks it up + for row in tables['evetypes']: + typeID = row['typeID'] + row['replaceSame'] = ','.join('{}'.format(tid) for tid in sorted(same.get(typeID, ()))) + row['replaceBetter'] = ','.join('{}'.format(tid) for tid in sorted(better.get(typeID, ()))) + data = {} # Dump all data to memory so we can easely cross check ignored rows @@ -190,6 +305,8 @@ def main(db, json_path): tableData = convertClones(tableData) data[jsonName] = tableData + fillReplacements(data) + # Set with typeIDs which we will have in our database # Sometimes CCP unpublishes some items we want to have published, we # can do it here - just add them to initial set diff --git a/scripts/package-osx.sh b/scripts/package-osx.sh new file mode 100644 index 000000000..35a87a007 --- /dev/null +++ b/scripts/package-osx.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +echo "${PYFA_VERSION}" + +cat version.yml +python3 -m PyInstaller -y --clean --windowed dist_assets/mac/pyfa.spec +cd dist +zip -r "pyfa-$PYFA_VERSION-mac.zip" pyfa.app +curl --upload-file "pyfa-$PYFA_VERSION-mac.zip" https://transfer.sh/ +echo -e "\n" +md5 -r "pyfa-$PYFA_VERSION-mac.zip" \ No newline at end of file diff --git a/scripts/setup-osx.sh b/scripts/setup-osx.sh new file mode 100644 index 000000000..97d477b50 --- /dev/null +++ b/scripts/setup-osx.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash +wget "https://www.python.org/ftp/python/${PYTHON}/python-${PYTHON}-macosx10.6.pkg" +sudo installer -pkg python-${PYTHON}-macosx10.6.pkg -target / +sudo python3 -m ensurepip +# A manual check that the correct version of Python is running. +python3 --version +pip3 install -r requirements.txt diff --git a/service/esiAccess.py b/service/esiAccess.py index db1931fa2..8ec3dd95d 100644 --- a/service/esiAccess.py +++ b/service/esiAccess.py @@ -95,7 +95,7 @@ class EsiAccess(object): @property def esi_url(self): - return "https://esi.tech.ccp.is" + return "https://esi.evetech.net" @property def oauth_verify(self): diff --git a/service/fit.py b/service/fit.py index ad1e5c4dd..035bb50ee 100644 --- a/service/fit.py +++ b/service/fit.py @@ -89,7 +89,6 @@ class Fit(FitDeprecated): "showTooltip": True, "showMarketShortcuts": False, "enableGaugeAnimation": True, - "exportCharges": True, "openFitInNew": False, "priceSystem": "Jita", "priceSource": "eve-marketdata.com", diff --git a/service/jargon/defaults.yaml b/service/jargon/defaults.yaml index 804c55909..761fc8473 100644 --- a/service/jargon/defaults.yaml +++ b/service/jargon/defaults.yaml @@ -1,9 +1,8 @@ -#Default jargon - comment out as necessary. +# Default jargon - comment out as necessary. -#Note that some of these are experimental abbreviations which don't have any real purpose and are simply there to play with - -#shortcuts +# Note that some of these are experimental abbreviations which don't have any real purpose and are simply there to play with +# shortcuts 1: I 2: II lrg: Large @@ -13,27 +12,28 @@ sml: Small # mic: Micro # (ineffective) xl: X-Large -# Derp. +# sizes large: heavy heavy: large -#language fixes (american/british differences) - +# language fixes (american/british differences) armour: armor neutraliser: neutralizer stabiliser: stabilizer energised: energized economiser: economizer -#definitions - +# races cn: Caldari Navy rf: Republic Fleet in: Imperial Navy fn: Federation Navy +ts: True Sansha +db: Dark Blood +dg: Dread Guristas +ss: Shadow Serpentis -#weapons - +# weapons ac: AutoCannon rt: Artillery arty: Artillery @@ -125,8 +125,7 @@ rp: Reaper disco: Smartbomb sbomb: Smartbomb -#Propulsion Modules - +# Propulsion Modules ab: Afterburner mwd: Microwarpdrive smwd: 5mn @@ -147,8 +146,7 @@ nano: Nanofiber Internal Structure boosh: Micro Jump Field Generator mjfg: Micro Jump Field Generator -#Tank Modules - +# Tank Modules 100pl: 100mm Plates 200pl: 200mm Plates 400pl: 400mm Plates @@ -195,8 +193,7 @@ knra: Kinetic Deflection Amplifier emra: EM Ward Amplifier exra: Explosive Deflection Amplifier -#Weapon Upgrades - +# Weapon Upgrades bcs: Ballistic Control System bcu: Ballistic Control System bc: Ballistic Control System @@ -218,9 +215,10 @@ gs: Gyrostabilizer hs: Heat Sink # Fleet Assistance - rsebo: Remote Sensor Booster +reccm: Remote Sensor Booster rct: Remote Capacitor Transmitter +et: Remote Capacitor Transmitter rar: Remote Armor Repairer rsb: Remote Shield Booster rr: Remote @@ -231,7 +229,6 @@ cdb: Command Burst cp: Command Processor # EWAR - wd: Warp Disruptor ws: Warp Scrambler sw: Stasis Webifier @@ -250,24 +247,24 @@ md: Guidance Disruptor point: Warp Disruptor # Engineering - cpr: Capacitor Power Relay cpu: Co-Processor coproc: Co-Processor eccm: Sensor Booster jam: ECM -pdu: Power Diagnostic Unit +pdu: Power Diagnostic System +pds: Power Diagnostic System rcu: Reactor Control Unit sebo: Sensor Booster spr: Shield Power Relay cb: Capacitor Booster cbat: Cap Battery cbst: Capacitor Booster +sa: Signal Amplifier sigamp: Signal Amplifier mapc: Micro Auxiliary Power Core # Ammo/Charges - am: Antimatter cnam: Caldari Navy Antimatter fnam: Federation Navy Antimatter @@ -290,7 +287,6 @@ bubble: Warp Disrupt Probe ars: Armor Resistance Script # Rigs - acr: Ancillary Current Router ccc: Capacitor Control Circuit smc: Semiconductor Memory Cell diff --git a/service/marketSources/evemarketdata.py b/service/marketSources/evemarketdata.py index bd1f8f3af..15edc92ef 100644 --- a/service/marketSources/evemarketdata.py +++ b/service/marketSources/evemarketdata.py @@ -22,6 +22,7 @@ from xml.dom import minidom from logbook import Logger +from eos.saveddata.price import PriceStatus from service.network import Network from service.price import Price, TIMEOUT, VALIDITY @@ -52,6 +53,7 @@ class EveMarketData(object): price = float(type_.firstChild.data) except (TypeError, ValueError): pyfalog.warning("Failed to get price for: {0}", type_) + continue # Fill price data priceobj = priceMap[typeID] @@ -61,11 +63,10 @@ class EveMarketData(object): if price != 0: priceobj.price = price priceobj.time = time.time() + VALIDITY + priceobj.status = PriceStatus.success else: priceobj.time = time.time() + TIMEOUT - priceobj.failed = None - # delete price from working dict del priceMap[typeID] diff --git a/service/marketSources/evemarketer.py b/service/marketSources/evemarketer.py index a2728ddfb..478de4371 100644 --- a/service/marketSources/evemarketer.py +++ b/service/marketSources/evemarketer.py @@ -22,13 +22,14 @@ from xml.dom import minidom from logbook import Logger +from eos.saveddata.price import PriceStatus from service.network import Network from service.price import Price, VALIDITY pyfalog = Logger(__name__) -class EveCentral(object): +class EveMarketer(object): name = "evemarketer" @@ -61,10 +62,10 @@ class EveCentral(object): priceobj = priceMap[typeID] priceobj.price = percprice priceobj.time = time.time() + VALIDITY - priceobj.failed = None + priceobj.status = PriceStatus.success # delete price from working dict del priceMap[typeID] -Price.register(EveCentral) +Price.register(EveMarketer) diff --git a/service/network.py b/service/network.py index 0c3bfb2b9..5554eadec 100644 --- a/service/network.py +++ b/service/network.py @@ -83,8 +83,7 @@ class Network(object): raise Error("Access not enabled - please enable in Preferences > Network") # Set up some things for the request - versionString = "{0} {1} - {2} {3}".format(config.version, config.tag, config.expansionName, - config.expansionVersion) + versionString = "{0}".format(config.version) headers = {"User-Agent": "pyfa {0} (python-requests {1})".format(versionString, requests.__version__)} # user-agent: pyfa 2.0.0b4 git -YC120.2 1.2 (python-requests 2.18.4) diff --git a/service/port/dna.py b/service/port/dna.py index bd2645ef8..bc64e9e99 100644 --- a/service/port/dna.py +++ b/service/port/dna.py @@ -138,7 +138,7 @@ def exportDna(fit): mods[mod.itemID] = 0 mods[mod.itemID] += 1 - if mod.charge and sFit.serviceFittingOptions["exportCharges"]: + if mod.charge: if mod.chargeID not in charges: charges[mod.chargeID] = 0 # `or 1` because some charges (ie scripts) are without qty diff --git a/service/port/efs.py b/service/port/efs.py index b572e5376..c93c7d87d 100755 --- a/service/port/efs.py +++ b/service/port/efs.py @@ -1,13 +1,8 @@ -import inspect -import os -import platform -import re -import sys -import traceback import json import eos.db from math import log +from numbers import Number from config import version as pyfaVersion from service.fit import Fit from service.market import Market @@ -15,8 +10,11 @@ from eos.enum import Enum from eos.saveddata.module import Hardpoint, Slot, Module, State from eos.saveddata.drone import Drone from eos.effectHandlerHelpers import HandledList -from eos.db import gamedata_session, getItemsByCategory, getCategory, getAttributeInfo, getGroup -from eos.gamedata import Category, Group, Item, Traits, Attribute, Effect, ItemEffect +from eos.db import gamedata_session, getCategory, getAttributeInfo, getGroup +from eos.gamedata import Attribute, Effect, Group, Item, ItemEffect +from eos.utils.spoolSupport import SpoolType, SpoolOptions +from gui.fitCommands.calc.fitAddModule import FitAddModuleCommand +from gui.fitCommands.calc.fitRemoveModule import FitRemoveModuleCommand from logbook import Logger pyfalog = Logger(__name__) @@ -29,9 +27,9 @@ class RigSize(Enum): CAPITAL = 4 -class EfsPort(): +class EfsPort: wepTestSet = {} - version = 0.02 + version = 0.03 @staticmethod def attrDirectMap(values, target, source): @@ -71,12 +69,12 @@ class EfsPort(): if propID is None: return None - sFit.appendModule(fitID, propID) + FitAddModuleCommand(fitID, propID).Do() sFit.recalc(fit) fit = eos.db.getFit(fitID) mwdPropSpeed = fit.maxSpeed mwdPosition = list(filter(lambda mod: mod.item and mod.item.ID == propID, fit.modules))[0].position - sFit.removeModule(fitID, mwdPosition) + FitRemoveModuleCommand(fitID, [mwdPosition]).Do() sFit.recalc(fit) fit = eos.db.getFit(fitID) return mwdPropSpeed @@ -111,9 +109,12 @@ class EfsPort(): "Burst Projectors", "Warp Disrupt Field Generator", "Armor Resistance Shift Hardener", "Target Breaker", "Micro Jump Drive", "Ship Modifiers", "Stasis Grappler", "Ancillary Remote Shield Booster", "Ancillary Remote Armor Repairer", - "Titan Phenomena Generator", "Non-Repeating Hardeners" + "Titan Phenomena Generator", "Non-Repeating Hardeners", "Mutadaptive Remote Armor Repairer" ] projectedMods = list(filter(lambda mod: mod.item and mod.item.group.name in modGroupNames, fit.modules)) + # Sort projections to prevent the order needlessly changing as pyfa updates. + projectedMods.sort(key=lambda mod: mod.item.ID) + projectedMods.sort(key=lambda mod: mod.item.group.ID) projections = [] for mod in projectedMods: maxRangeDefault = 0 @@ -144,7 +145,9 @@ class EfsPort(): elif mod.item.group.name in ["Remote Shield Booster", "Ancillary Remote Shield Booster"]: stats["type"] = "Remote Shield Booster" EfsPort.attrDirectMap(["shieldBonus"], stats, mod) - elif mod.item.group.name in ["Remote Armor Repairer", "Ancillary Remote Armor Repairer"]: + elif mod.item.group.name in [ + "Remote Armor Repairer", "Ancillary Remote Armor Repairer", "Mutadaptive Remote Armor Repairer" + ]: stats["type"] = "Remote Armor Repairer" EfsPort.attrDirectMap(["armorDamageAmount"], stats, mod) elif mod.item.group.name == "Warp Scrambler": @@ -190,7 +193,7 @@ class EfsPort(): return projections # Note that unless padTypeIDs is True all 0s will be removed from modTypeIDs in the return. - # They always are added initally for the sake of brevity, as this option may not be retained long term. + # They always are added initially for the sake of brevity, as this option may not be retained long term. @staticmethod def getModuleInfo(fit, padTypeIDs=False): moduleNames = [] @@ -302,8 +305,11 @@ class EfsPort(): def getWeaponSystemData(fit): weaponSystems = [] groups = {} + # Export at maximum spool for consistency, spoolup data is exported anyway. + defaultSpoolValue = 1 + spoolOptions = SpoolOptions(SpoolType.SCALE, defaultSpoolValue, True) for mod in fit.modules: - if mod.dps > 0: + if mod.getDps(spoolOptions=spoolOptions).total > 0: # Group weapon + ammo combinations that occur more than once keystr = str(mod.itemID) + "-" + str(mod.chargeID) if keystr in groups: @@ -320,6 +326,7 @@ class EfsPort(): explosionRadius = 0 explosionVelocity = 0 aoeFieldRange = 0 + typeing = 'None' if stats.charge: name = stats.item.name + ", " + stats.charge.name else: @@ -339,16 +346,16 @@ class EfsPort(): aoeFieldRange = stats.getModifiedItemAttr("empFieldRange") # This also covers non-bomb weapons with dps values and no hardpoints, most notably targeted doomsdays. typeing = "SmartBomb" - # Targeted DDs are the only non drone/fighter weapon without an explict max range + # Targeted DDs are the only non drone/fighter weapon without an explicit max range if stats.item.group.name == 'Super Weapon' and stats.maxRange is None: maxRange = 300000 else: maxRange = stats.maxRange statDict = { - "dps": stats.dps * n, "capUse": stats.capUse * n, "falloff": stats.falloff, + "dps": stats.getDps(spoolOptions=spoolOptions).total * n, "capUse": stats.capUse * n, "falloff": stats.falloff, "type": typeing, "name": name, "optimal": maxRange, "numCharges": stats.numCharges, "numShots": stats.numShots, "reloadTime": stats.reloadTime, - "cycleTime": stats.cycleTime, "volley": stats.volley * n, "tracking": tracking, + "cycleTime": stats.cycleTime, "volley": stats.getVolley(spoolOptions=spoolOptions).total * n, "tracking": tracking, "maxVelocity": maxVelocity, "explosionDelay": explosionDelay, "damageReductionFactor": damageReductionFactor, "explosionRadius": explosionRadius, "explosionVelocity": explosionVelocity, "aoeFieldRange": aoeFieldRange, "damageMultiplierBonusMax": stats.getModifiedItemAttr("damageMultiplierBonusMax"), @@ -356,19 +363,19 @@ class EfsPort(): } weaponSystems.append(statDict) for drone in fit.drones: - if drone.dps[0] > 0 and drone.amountActive > 0: + if drone.getDps().total > 0 and drone.amountActive > 0: droneAttr = drone.getModifiedItemAttr # Drones are using the old tracking formula for trackingSpeed. This updates it to match turrets. newTracking = droneAttr("trackingSpeed") / (droneAttr("optimalSigRadius") / 40000) statDict = { - "dps": drone.dps[0], "cycleTime": drone.cycleTime, "type": "Drone", + "dps": drone.getDps().total, "cycleTime": drone.cycleTime, "type": "Drone", "optimal": drone.maxRange, "name": drone.item.name, "falloff": drone.falloff, "maxSpeed": droneAttr("maxVelocity"), "tracking": newTracking, - "volley": drone.dps[1] + "volley": drone.getVolley().total } weaponSystems.append(statDict) for fighter in fit.fighters: - if fighter.dps[0] > 0 and fighter.amountActive > 0: + if fighter.getDps().total > 0 and fighter.amountActive > 0: fighterAttr = fighter.getModifiedItemAttr abilities = [] if "fighterAbilityAttackMissileDamageEM" in fighter.item.attributes.keys(): @@ -380,10 +387,10 @@ class EfsPort(): ability = EfsPort.getFighterAbilityData(fighterAttr, fighter, baseRef) abilities.append(ability) statDict = { - "dps": fighter.dps[0], "type": "Fighter", "name": fighter.item.name, + "dps": fighter.getDps().total, "type": "Fighter", "name": fighter.item.name, "maxSpeed": fighterAttr("maxVelocity"), "abilities": abilities, "ehp": fighterAttr("shieldCapacity") / 0.8875 * fighter.amountActive, - "volley": fighter.dps[1], "signatureRadius": fighterAttr("signatureRadius") + "volley": fighter.getVolley().total, "signatureRadius": fighterAttr("signatureRadius") } weaponSystems.append(statDict) return weaponSystems @@ -510,7 +517,7 @@ class EfsPort(): # Since the effect modules are fairly opaque a mock test fit is used to test the impact of traits. # standin class used to prevent . notation causing issues when used as an arg - class standin(): + class standin: pass tf = standin() tf.modules = HandledList(turrets + launchers) @@ -546,7 +553,7 @@ class EfsPort(): @staticmethod def getShipSize(groupID): - # Size groupings are somewhat arbitrary but allow for a more managable number of top level groupings in a tree structure. + # Size groupings are somewhat arbitrary but allow for a more manageable number of top level groupings in a tree structure. frigateGroupNames = ["Frigate", "Shuttle", "Corvette", "Assault Frigate", "Covert Ops", "Interceptor", "Stealth Bomber", "Electronic Attack Ship", "Expedition Frigate", "Logistics Frigate"] destroyerGroupNames = ["Destroyer", "Interdictor", "Tactical Destroyer", "Command Destroyer"] @@ -620,15 +627,38 @@ class EfsPort(): } resonance = {"hull": hullResonance, "armor": armorResonance, "shield": shieldResonance} shipSize = EfsPort.getShipSize(fit.ship.item.groupID) + # Export at maximum spool for consistency, spoolup data is exported anyway. + defaultSpoolValue = 1 + spoolOptions = SpoolOptions(SpoolType.SCALE, defaultSpoolValue, True) + + def roundNumbers(data, digits): + if isinstance(data, str): + return + if isinstance(data, dict): + for key in data: + if isinstance(data[key], Number): + data[key] = round(data[key], digits) + else: + roundNumbers(data[key], digits) + if isinstance(data, list) or isinstance(data, tuple): + for val in data: + roundNumbers(val, digits) + if isinstance(data, Number): + rounded = round(data, digits) + if data != rounded: + pyfalog.error("Error rounding numbers for EFS export, export may be inconsistent." + "This suggests the format has been broken somewhere.") + return + try: dataDict = { - "name": fitName, "ehp": fit.ehp, "droneDPS": fit.droneDPS, - "droneVolley": fit.droneVolley, "hp": fit.hp, "maxTargets": fit.maxTargets, - "maxSpeed": fit.maxSpeed, "weaponVolley": fit.weaponVolley, "totalVolley": fit.totalVolley, - "maxTargetRange": fit.maxTargetRange, "scanStrength": fit.scanStrength, - "weaponDPS": fit.weaponDPS, "alignTime": fit.alignTime, "signatureRadius": fitModAttr("signatureRadius"), - "weapons": weaponSystems, "scanRes": fitModAttr("scanResolution"), - "capUsed": fit.capUsed, "capRecharge": fit.capRecharge, + "name": fitName, "ehp": fit.ehp, "droneDPS": fit.getDroneDps().total, + "droneVolley": fit.getDroneVolley().total, "hp": fit.hp, "maxTargets": fit.maxTargets, + "maxSpeed": fit.maxSpeed, "weaponVolley": fit.getWeaponVolley(spoolOptions=spoolOptions).total, + "totalVolley": fit.getTotalVolley(spoolOptions=spoolOptions).total, "maxTargetRange": fit.maxTargetRange, + "scanStrength": fit.scanStrength, "weaponDPS": fit.getWeaponDps(spoolOptions=spoolOptions).total, + "alignTime": fit.alignTime, "signatureRadius": fitModAttr("signatureRadius"), "weapons": weaponSystems, + "scanRes": fitModAttr("scanResolution"), "capUsed": fit.capUsed, "capRecharge": fit.capRecharge, "rigSlots": fitModAttr("rigSlots"), "lowSlots": fitModAttr("lowSlots"), "midSlots": fitModAttr("medSlots"), "highSlots": fitModAttr("hiSlots"), "turretSlots": fitModAttr("turretSlotsLeft"), "launcherSlots": fitModAttr("launcherSlotsLeft"), @@ -642,9 +672,12 @@ class EfsPort(): "modTypeIDs": modTypeIDs, "moduleNames": moduleNames, "pyfaVersion": pyfaVersion, "efsExportVersion": EfsPort.version } - except TypeError: + # Recursively round any numbers in dicts to 6 decimal places. + # This prevents meaningless rounding errors from changing the output whenever pyfa changes. + roundNumbers(dataDict, 6) + except TypeError as e: pyfalog.error("Error parsing fit:" + str(fit)) - pyfalog.error(TypeError) + pyfalog.error(e) dataDict = {"name": fitName + "Fit could not be correctly parsed"} export = json.dumps(dataDict, skipkeys=True) return export diff --git a/service/port/eft.py b/service/port/eft.py index a1e99f45c..0d8a0a706 100644 --- a/service/port/eft.py +++ b/service/port/eft.py @@ -19,6 +19,7 @@ import re +from enum import Enum from logbook import Logger @@ -36,7 +37,6 @@ from service.fit import Fit as svcFit from service.market import Market from service.port.muta import parseMutant, renderMutant from service.port.shared import IPortUser, fetchItem, processing_notify -from enum import Enum pyfalog = Logger(__name__) @@ -45,23 +45,20 @@ pyfalog = Logger(__name__) class Options(Enum): IMPLANTS = 1 MUTATIONS = 2 + LOADED_CHARGES = 3 + + +EFT_OPTIONS = ( + (Options.LOADED_CHARGES.value, 'Loaded Charges', 'Export charges loaded into modules', True), + (Options.MUTATIONS.value, 'Mutated Attributes', 'Export mutated modules\' stats', True), + (Options.IMPLANTS.value, 'Implants && Boosters', 'Export implants and boosters', True), +) MODULE_CATS = ('Module', 'Subsystem', 'Structure Module') SLOT_ORDER = (Slot.LOW, Slot.MED, Slot.HIGH, Slot.RIG, Slot.SUBSYSTEM, Slot.SERVICE) OFFLINE_SUFFIX = '/OFFLINE' -EFT_OPTIONS = { - Options.IMPLANTS.value: { - "name": "Implants", - "description": "Exports implants" - }, - Options.MUTATIONS.value: { - "name": "Mutated Attributes", - "description": "Exports Abyssal stats" - } -} - def exportEft(fit, options): # EFT formatted export is split in several sections, each section is @@ -73,7 +70,6 @@ def exportEft(fit, options): # Section 1: modules, rigs, subsystems, services modsBySlotType = {} - sFit = svcFit.getInstance() for module in fit.modules: modsBySlotType.setdefault(module.slot, []).append(module) modSection = [] @@ -85,20 +81,19 @@ def exportEft(fit, options): modules = modsBySlotType.get(slotType, ()) for module in modules: if module.item: - mutated = bool(module.mutators) # if module was mutated, use base item name for export - if mutated: + if module.isMutated: modName = module.baseItem.name else: modName = module.item.name - if mutated and options & Options.MUTATIONS.value: + if module.isMutated and options[Options.MUTATIONS.value]: mutants[mutantReference] = module mutationSuffix = ' [{}]'.format(mutantReference) mutantReference += 1 else: mutationSuffix = '' modOfflineSuffix = ' {}'.format(OFFLINE_SUFFIX) if module.state == State.OFFLINE else '' - if module.charge and sFit.serviceFittingOptions['exportCharges']: + if module.charge and options[Options.LOADED_CHARGES.value]: rackLines.append('{}, {}{}{}'.format( modName, module.charge.name, modOfflineSuffix, mutationSuffix)) else: @@ -127,7 +122,7 @@ def exportEft(fit, options): sections.append('\n\n'.join(minionSection)) # Section 3: implants, boosters - if options & Options.IMPLANTS.value: + if options[Options.IMPLANTS.value]: charSection = [] implantLines = [] for implant in fit.implants: @@ -154,7 +149,7 @@ def exportEft(fit, options): # Section 5: mutated modules' details mutationLines = [] - if mutants and options & Options.MUTATIONS.value: + if mutants and options[Options.MUTATIONS.value]: for mutantReference in sorted(mutants): mutant = mutants[mutantReference] mutationLines.append(renderMutant(mutant, firstPrefix='[{}] '.format(mutantReference), prefix=' ')) @@ -164,8 +159,8 @@ def exportEft(fit, options): return '{}\n\n{}'.format(header, '\n\n\n'.join(sections)) -def importEft(eftString): - lines = _importPrepareString(eftString) +def importEft(lines): + lines = _importPrepare(lines) try: fit = _importCreateFit(lines) except EftImportError: @@ -251,14 +246,14 @@ def importEft(eftString): aFit.addCargo(itemSpec) # Subsystems first because they modify slot amount - for m in aFit.subsystems: + for i, m in enumerate(aFit.subsystems): if m is None: dummy = Module.buildEmpty(aFit.getSlotByContainer(aFit.subsystems)) dummy.owner = fit - fit.modules.appendIgnoreEmpty(dummy) + fit.modules.replaceRackPosition(i, dummy) elif m.fits(fit): m.owner = fit - fit.modules.appendIgnoreEmpty(m) + fit.modules.replaceRackPosition(i, m) svcFit.getInstance().recalc(fit) # Other stuff @@ -269,16 +264,16 @@ def importEft(eftString): aFit.modulesMed, aFit.modulesLow, ): - for m in modRack: + for i, m in enumerate(modRack): if m is None: dummy = Module.buildEmpty(aFit.getSlotByContainer(modRack)) dummy.owner = fit - fit.modules.appendIgnoreEmpty(dummy) + fit.modules.replaceRackPosition(i, dummy) elif m.fits(fit): m.owner = fit if not m.isValidState(m.state): pyfalog.warning('service.port.eft.importEft: module {} cannot have state {}', m, m.state) - fit.modules.appendIgnoreEmpty(m) + fit.modules.replaceRackPosition(i, m) for implant in aFit.implants: fit.implants.append(implant) for booster in aFit.boosters: @@ -293,7 +288,7 @@ def importEft(eftString): return fit -def importEftCfg(shipname, contents, iportuser): +def importEftCfg(shipname, lines, iportuser): """Handle import from EFT config store file""" # Check if we have such ship in database, bail if we don't @@ -305,7 +300,6 @@ def importEftCfg(shipname, contents, iportuser): fits = [] # List for fits fitIndices = [] # List for starting line numbers for each fit - lines = re.split('[\n\r]+', contents) # Separate string into lines for line in lines: # Detect fit header @@ -486,8 +480,7 @@ def importEftCfg(shipname, contents, iportuser): return fits -def _importPrepareString(eftString): - lines = eftString.splitlines() +def _importPrepare(lines): for i in range(len(lines)): lines[i] = lines[i].strip() while lines and not lines[0]: diff --git a/service/port/esi.py b/service/port/esi.py index f1e02d13a..a97480624 100644 --- a/service/port/esi.py +++ b/service/port/esi.py @@ -97,7 +97,7 @@ def exportESI(ofit): item['type_id'] = module.item.ID fit['items'].append(item) - if module.charge and sFit.serviceFittingOptions["exportCharges"]: + if module.charge: if module.chargeID not in charges: charges[module.chargeID] = 0 # `or 1` because some charges (ie scripts) are without qty @@ -137,11 +137,11 @@ def exportESI(ofit): return json.dumps(fit) -def importESI(str_): +def importESI(string): sMkt = Market.getInstance() fitobj = Fit() - refobj = json.loads(str_) + refobj = json.loads(string) items = refobj['items'] # "<" and ">" is replace to "<", ">" by EVE client fitobj.name = refobj['name'] diff --git a/service/port/multibuy.py b/service/port/multibuy.py index 2bf2d7a8a..1c6b78836 100644 --- a/service/port/multibuy.py +++ b/service/port/multibuy.py @@ -18,51 +18,63 @@ # ============================================================================= -from service.fit import Fit as svcFit -from service.port.eft import SLOT_ORDER as EFT_SLOT_ORDER +from enum import Enum -def exportMultiBuy(fit): - export = "%s\n" % fit.ship.item.name - stuff = {} - sFit = svcFit.getInstance() +class Options(Enum): + IMPLANTS = 1 + CARGO = 2 + LOADED_CHARGES = 3 + + +MULTIBUY_OPTIONS = ( + (Options.LOADED_CHARGES.value, 'Loaded Charges', 'Export charges loaded into modules', True), + (Options.IMPLANTS.value, 'Implants && Boosters', 'Export implants and boosters', False), + (Options.CARGO.value, 'Cargo', 'Export cargo contents', True), +) + + +def exportMultiBuy(fit, options): + itemCounts = {} + + def addItem(item, quantity=1): + if item not in itemCounts: + itemCounts[item] = 0 + itemCounts[item] += quantity + for module in fit.modules: - slot = module.slot - if slot not in stuff: - stuff[slot] = [] - curr = "%s\n" % module.item.name if module.item else "" - if module.charge and sFit.serviceFittingOptions["exportCharges"]: - curr += "%s x%s\n" % (module.charge.name, module.numCharges) - stuff[slot].append(curr) + if module.item: + # Mutated items are of no use for multibuy + if module.isMutated: + continue + addItem(module.item) + if module.charge and options[Options.LOADED_CHARGES.value]: + addItem(module.charge, module.numCharges) - for slotType in EFT_SLOT_ORDER: - data = stuff.get(slotType) - if data is not None: - # export += "\n" - for curr in data: - export += curr + for drone in fit.drones: + addItem(drone.item, drone.amount) - if len(fit.drones) > 0: - for drone in fit.drones: - export += "%s x%s\n" % (drone.item.name, drone.amount) + for fighter in fit.fighters: + addItem(fighter.item, fighter.amountActive) - if len(fit.cargo) > 0: + if options[Options.CARGO.value]: for cargo in fit.cargo: - export += "%s x%s\n" % (cargo.item.name, cargo.amount) + addItem(cargo.item, cargo.amount) - if len(fit.implants) > 0: + if options[Options.IMPLANTS.value]: for implant in fit.implants: - export += "%s\n" % implant.item.name + addItem(implant.item) - if len(fit.boosters) > 0: for booster in fit.boosters: - export += "%s\n" % booster.item.name + addItem(booster.item) - if len(fit.fighters) > 0: - for fighter in fit.fighters: - export += "%s x%s\n" % (fighter.item.name, fighter.amountActive) + exportLines = [] + exportLines.append(fit.ship.item.name) + for item in sorted(itemCounts, key=lambda i: (i.group.category.name, i.group.name, i.name)): + count = itemCounts[item] + if count == 1: + exportLines.append(item.name) + else: + exportLines.append('{} x{}'.format(item.name, count)) - if export[-1] == "\n": - export = export[:-1] - - return export + return "\n".join(exportLines) diff --git a/service/port/port.py b/service/port/port.py index cad3dfae2..8038cab8e 100644 --- a/service/port/port.py +++ b/service/port/port.py @@ -207,9 +207,14 @@ class Port(object): @classmethod def importAuto(cls, string, path=None, activeFit=None, iportuser=None): # type: (Port, str, str, object, IPortUser) -> object + lines = string.splitlines() # Get first line and strip space symbols of it to avoid possible detection errors - firstLine = re.split("[\n\r]+", string.strip(), maxsplit=1)[0] - firstLine = firstLine.strip() + firstLine = '' + for line in lines: + line = line.strip() + if line: + firstLine = line + break # If XML-style start of tag encountered, detect as XML if re.search(RE_XML_START, firstLine): @@ -224,12 +229,12 @@ class Port(object): if re.match("\[.*\]", firstLine) and path is not None: filename = os.path.split(path)[1] shipName = filename.rsplit('.')[0] - return "EFT Config", cls.importEftCfg(shipName, string, iportuser) + return "EFT Config", cls.importEftCfg(shipName, lines, iportuser) # If no file is specified and there's comma between brackets, # consider that we have [ship, setup name] and detect like eft export format if re.match("\[.*,.*\]", firstLine): - return "EFT", (cls.importEft(string),) + return "EFT", (cls.importEft(lines),) # Check if string is in DNA format if re.match("\d+(:\d+(;\d+))*::", firstLine): @@ -237,19 +242,19 @@ class Port(object): # Assume that we import stand-alone abyssal module if all else fails try: - return "MutatedItem", (parseMutant(string.split("\n")),) + return "MutatedItem", (parseMutant(lines),) except: pass # EFT-related methods @staticmethod - def importEft(eftString): - return importEft(eftString) + def importEft(lines): + return importEft(lines) @staticmethod - def importEftCfg(shipname, contents, iportuser=None): - return importEftCfg(shipname, contents, iportuser) + def importEftCfg(shipname, lines, iportuser=None): + return importEftCfg(shipname, lines, iportuser) @classmethod def exportEft(cls, fit, options): @@ -284,5 +289,5 @@ class Port(object): # Multibuy-related methods @staticmethod - def exportMultiBuy(fit): - return exportMultiBuy(fit) + def exportMultiBuy(fit, options): + return exportMultiBuy(fit, options) diff --git a/service/port/xml.py b/service/port/xml.py index 54d5a98eb..432bbcdd8 100644 --- a/service/port/xml.py +++ b/service/port/xml.py @@ -283,7 +283,7 @@ def exportXml(iportuser, *fits): hardware.setAttribute("slot", "%s slot %d" % (slotName, slotId)) fitting.appendChild(hardware) - if module.charge and sFit.serviceFittingOptions["exportCharges"]: + if module.charge: if module.charge.name not in charges: charges[module.charge.name] = 0 # `or 1` because some charges (ie scripts) are without qty diff --git a/service/price.py b/service/price.py index 9a8485274..3028b74ad 100644 --- a/service/price.py +++ b/service/price.py @@ -26,6 +26,7 @@ import wx from logbook import Logger from eos import db +from eos.saveddata.price import PriceStatus from service.fit import Fit from service.market import Market from service.network import TimeoutError @@ -85,13 +86,18 @@ class Price(object): toRequest = set() # Compose list of items we're going to request - for typeID in priceMap: + for typeID in tuple(priceMap): # Get item object item = db.getItem(typeID) # We're not going to request items only with market group, as eve-central # doesn't provide any data for items not on the market - if item is not None and item.marketGroupID: - toRequest.add(typeID) + if item is None: + continue + if not item.marketGroupID: + priceMap[typeID].status = PriceStatus.notSupported + del priceMap[typeID] + continue + toRequest.add(typeID) # Do not waste our time if all items are not on the market if len(toRequest) == 0: @@ -117,11 +123,10 @@ class Price(object): except TimeoutError: # Timeout error deserves special treatment pyfalog.warning("Price fetch timout") - for typeID in priceMap.keys(): + for typeID in tuple(priceMap): priceobj = priceMap[typeID] priceobj.time = time.time() + TIMEOUT - priceobj.failed = True - + priceobj.status = PriceStatus.fail del priceMap[typeID] except Exception as ex: # something happened, try another source @@ -134,7 +139,7 @@ class Price(object): for typeID in priceMap.keys(): priceobj = priceMap[typeID] priceobj.time = time.time() + REREQUEST - priceobj.failed = True + priceobj.status = PriceStatus.fail @classmethod def fitItemsList(cls, fit): @@ -172,8 +177,8 @@ class Price(object): def getPrices(self, objitems, callback, waitforthread=False): """Get prices for multiple typeIDs""" requests = [] + sMkt = Market.getInstance() for objitem in objitems: - sMkt = Market.getInstance() item = sMkt.getItem(objitem) requests.append(item.price) @@ -197,6 +202,7 @@ class Price(object): class PriceWorkerThread(threading.Thread): + def __init__(self): threading.Thread.__init__(self) self.name = "PriceWorker" diff --git a/service/settings.py b/service/settings.py index 39f8def9c..df5038d1f 100644 --- a/service/settings.py +++ b/service/settings.py @@ -525,6 +525,7 @@ class ContextMenuSettings(object): "tacticalMode" : 1, "targetResists" : 1, "whProjector" : 1, + "moduleFill" : 1, } self.ContextMenuDefaultSettings = SettingsProvider.getInstance().getSettings("pyfaContextMenuSettings", ContextMenuDefaultSettings) diff --git a/version.yml b/version.yml new file mode 100644 index 000000000..e35fb355c --- /dev/null +++ b/version.yml @@ -0,0 +1 @@ +version: v2.7.5