aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/build.yml83
-rw-r--r--.github/workflows/codeql.yml35
-rw-r--r--.github/workflows/trigger_builds.yml4
-rw-r--r--.github/workflows/trigger_release.yml1
-rw-r--r--CMakeLists.txt9
-rw-r--r--COPYING.md17
-rw-r--r--README.md8
-rw-r--r--flake.nix4
-rw-r--r--flatpak/org.prismlauncher.PrismLauncher.yml83
-rw-r--r--flatpak/prime-run4
-rw-r--r--flatpak/prismlauncher11
-rw-r--r--launcher/Application.cpp121
-rw-r--r--launcher/Application.h1
-rw-r--r--launcher/BaseInstance.h2
-rw-r--r--launcher/BaseVersionList.cpp4
-rw-r--r--launcher/CMakeLists.txt7
-rw-r--r--launcher/DataMigrationTask.cpp96
-rw-r--r--launcher/DataMigrationTask.h42
-rw-r--r--launcher/FileSystem.cpp204
-rw-r--r--launcher/FileSystem.h36
-rw-r--r--launcher/InstanceCopyTask.cpp6
-rw-r--r--launcher/VersionProxyModel.cpp4
-rw-r--r--launcher/icons/IconList.cpp4
-rw-r--r--launcher/main.cpp2
-rw-r--r--launcher/meta/Index.cpp4
-rw-r--r--launcher/meta/JsonFormat.h5
-rw-r--r--launcher/minecraft/MinecraftInstance.cpp41
-rw-r--r--launcher/minecraft/MinecraftInstance.h4
-rw-r--r--launcher/minecraft/MojangVersionFormat.cpp17
-rw-r--r--launcher/minecraft/OneSixVersionFormat.cpp29
-rw-r--r--launcher/minecraft/PackProfile.cpp6
-rw-r--r--launcher/minecraft/Rule.h2
-rw-r--r--launcher/minecraft/WorldList.cpp6
-rw-r--r--launcher/minecraft/WorldList.h2
-rw-r--r--launcher/minecraft/auth/AccountList.cpp10
-rw-r--r--launcher/minecraft/mod/ModFolderModel.cpp2
-rw-r--r--launcher/minecraft/mod/ResourceFolderModel.cpp2
-rw-r--r--launcher/minecraft/mod/ResourceFolderModel.h6
-rw-r--r--launcher/minecraft/mod/ResourcePackFolderModel.cpp2
-rw-r--r--launcher/minecraft/mod/tasks/LocalModParseTask.cpp2
-rw-r--r--launcher/modplatform/flame/FlameInstanceCreationTask.cpp59
-rw-r--r--launcher/modplatform/flame/FlameInstanceCreationTask.h3
-rw-r--r--launcher/modplatform/helpers/HashUtils.cpp58
-rw-r--r--launcher/modplatform/helpers/HashUtils.h15
-rw-r--r--launcher/modplatform/modpacksch/FTBPackInstallTask.cpp63
-rw-r--r--launcher/modplatform/modpacksch/FTBPackInstallTask.h3
-rw-r--r--launcher/net/HttpMetaCache.cpp72
-rw-r--r--launcher/net/HttpMetaCache.h58
-rw-r--r--launcher/pathmatcher/SimplePrefixMatcher.h25
-rw-r--r--launcher/resources/OSX/OSX.qrc1
-rw-r--r--launcher/resources/OSX/scalable/shortcut.svg14
-rw-r--r--launcher/resources/breeze_dark/breeze_dark.qrc44
-rw-r--r--launcher/resources/breeze_dark/index.theme11
-rw-r--r--launcher/resources/breeze_dark/scalable/about.svg12
-rw-r--r--launcher/resources/breeze_dark/scalable/accounts.svg17
-rw-r--r--launcher/resources/breeze_dark/scalable/bug.svg13
-rw-r--r--launcher/resources/breeze_dark/scalable/centralmods.svg1
-rw-r--r--launcher/resources/breeze_dark/scalable/checkupdate.svg14
-rw-r--r--launcher/resources/breeze_dark/scalable/copy.svg11
-rw-r--r--launcher/resources/breeze_dark/scalable/coremods.svg1
-rw-r--r--launcher/resources/breeze_dark/scalable/custom-commands.svg13
-rw-r--r--launcher/resources/breeze_dark/scalable/delete.svg13
-rw-r--r--launcher/resources/breeze_dark/scalable/discord.svg1
-rw-r--r--launcher/resources/breeze_dark/scalable/export.svg11
-rw-r--r--launcher/resources/breeze_dark/scalable/externaltools.svg13
-rw-r--r--launcher/resources/breeze_dark/scalable/help.svg13
-rw-r--r--launcher/resources/breeze_dark/scalable/instance-settings.svg13
-rw-r--r--launcher/resources/breeze_dark/scalable/jarmods.svg1
-rw-r--r--launcher/resources/breeze_dark/scalable/java.svg10
-rw-r--r--launcher/resources/breeze_dark/scalable/language.svg13
-rw-r--r--launcher/resources/breeze_dark/scalable/launch.svg8
-rw-r--r--launcher/resources/breeze_dark/scalable/launcher.svg57
-rw-r--r--launcher/resources/breeze_dark/scalable/loadermods.svg13
-rw-r--r--launcher/resources/breeze_dark/scalable/log.svg13
-rw-r--r--launcher/resources/breeze_dark/scalable/matrix.svg9
-rw-r--r--launcher/resources/breeze_dark/scalable/minecraft.svg13
-rw-r--r--launcher/resources/breeze_dark/scalable/new.svg18
-rw-r--r--launcher/resources/breeze_dark/scalable/news.svg13
-rw-r--r--launcher/resources/breeze_dark/scalable/notes.svg13
-rw-r--r--launcher/resources/breeze_dark/scalable/patreon.svg3
-rw-r--r--launcher/resources/breeze_dark/scalable/proxy.svg14
-rw-r--r--launcher/resources/breeze_dark/scalable/reddit-alien.svg3
-rw-r--r--launcher/resources/breeze_dark/scalable/refresh.svg8
-rw-r--r--launcher/resources/breeze_dark/scalable/rename.svg13
-rw-r--r--launcher/resources/breeze_dark/scalable/resourcepacks.svg11
-rw-r--r--launcher/resources/breeze_dark/scalable/screenshots.svg13
-rw-r--r--launcher/resources/breeze_dark/scalable/settings.svg17
-rw-r--r--launcher/resources/breeze_dark/scalable/shaderpacks.svg13
-rw-r--r--launcher/resources/breeze_dark/scalable/shortcut.svg18
-rw-r--r--launcher/resources/breeze_dark/scalable/status-bad.svg9
-rw-r--r--launcher/resources/breeze_dark/scalable/status-good.svg10
-rw-r--r--launcher/resources/breeze_dark/scalable/status-yellow.svg9
-rw-r--r--launcher/resources/breeze_dark/scalable/tag.svg17
-rw-r--r--launcher/resources/breeze_dark/scalable/viewfolder.svg13
-rw-r--r--launcher/resources/breeze_dark/scalable/worlds.svg16
-rw-r--r--launcher/resources/breeze_light/breeze_light.qrc44
-rw-r--r--launcher/resources/breeze_light/index.theme11
-rw-r--r--launcher/resources/breeze_light/scalable/about.svg12
-rw-r--r--launcher/resources/breeze_light/scalable/accounts.svg17
-rw-r--r--launcher/resources/breeze_light/scalable/bug.svg13
-rw-r--r--launcher/resources/breeze_light/scalable/centralmods.svg1
-rw-r--r--launcher/resources/breeze_light/scalable/checkupdate.svg14
-rw-r--r--launcher/resources/breeze_light/scalable/copy.svg11
-rw-r--r--launcher/resources/breeze_light/scalable/coremods.svg1
-rw-r--r--launcher/resources/breeze_light/scalable/custom-commands.svg13
-rw-r--r--launcher/resources/breeze_light/scalable/delete.svg13
-rw-r--r--launcher/resources/breeze_light/scalable/discord.svg1
-rw-r--r--launcher/resources/breeze_light/scalable/export.svg11
-rw-r--r--launcher/resources/breeze_light/scalable/externaltools.svg13
-rw-r--r--launcher/resources/breeze_light/scalable/help.svg13
-rw-r--r--launcher/resources/breeze_light/scalable/instance-settings.svg13
-rw-r--r--launcher/resources/breeze_light/scalable/jarmods.svg1
-rw-r--r--launcher/resources/breeze_light/scalable/java.svg10
-rw-r--r--launcher/resources/breeze_light/scalable/language.svg13
-rw-r--r--launcher/resources/breeze_light/scalable/launch.svg8
-rw-r--r--launcher/resources/breeze_light/scalable/loadermods.svg13
-rw-r--r--launcher/resources/breeze_light/scalable/log.svg13
-rw-r--r--launcher/resources/breeze_light/scalable/matrix.svg9
-rw-r--r--launcher/resources/breeze_light/scalable/minecraft.svg13
-rw-r--r--launcher/resources/breeze_light/scalable/new.svg18
-rw-r--r--launcher/resources/breeze_light/scalable/news.svg13
-rw-r--r--launcher/resources/breeze_light/scalable/notes.svg13
-rw-r--r--launcher/resources/breeze_light/scalable/patreon.svg3
-rw-r--r--launcher/resources/breeze_light/scalable/proxy.svg14
-rw-r--r--launcher/resources/breeze_light/scalable/reddit-alien.svg3
-rw-r--r--launcher/resources/breeze_light/scalable/refresh.svg8
-rw-r--r--launcher/resources/breeze_light/scalable/rename.svg13
-rw-r--r--launcher/resources/breeze_light/scalable/resourcepacks.svg11
-rw-r--r--launcher/resources/breeze_light/scalable/screenshots.svg13
-rw-r--r--launcher/resources/breeze_light/scalable/settings.svg17
-rw-r--r--launcher/resources/breeze_light/scalable/shaderpacks.svg13
-rw-r--r--launcher/resources/breeze_light/scalable/shortcut.svg18
-rw-r--r--launcher/resources/breeze_light/scalable/status-bad.svg9
-rw-r--r--launcher/resources/breeze_light/scalable/status-good.svg10
-rw-r--r--launcher/resources/breeze_light/scalable/status-yellow.svg9
-rw-r--r--launcher/resources/breeze_light/scalable/tag.svg17
-rw-r--r--launcher/resources/breeze_light/scalable/viewfolder.svg13
-rw-r--r--launcher/resources/breeze_light/scalable/worlds.svg16
-rw-r--r--launcher/resources/flat/flat.qrc1
-rw-r--r--launcher/resources/flat/scalable/shortcut.svg3
-rw-r--r--launcher/resources/flat_white/flat_white.qrc1
-rw-r--r--launcher/resources/flat_white/scalable/shortcut.svg3
-rw-r--r--launcher/resources/iOS/iOS.qrc1
-rw-r--r--launcher/resources/iOS/scalable/shortcut.svg13
-rw-r--r--launcher/resources/multimc/128x128/instances/chicken_legacy.png (renamed from launcher/resources/multimc/128x128/instances/chicken.png)bin6369 -> 6369 bytes
-rw-r--r--launcher/resources/multimc/128x128/instances/creeper_legacy.png (renamed from launcher/resources/multimc/128x128/instances/creeper.png)bin9046 -> 9046 bytes
-rw-r--r--launcher/resources/multimc/128x128/instances/enderpearl_legacy.png (renamed from launcher/resources/multimc/128x128/instances/enderpearl.png)bin21425 -> 21425 bytes
-rw-r--r--launcher/resources/multimc/128x128/instances/flame_legacy.png (renamed from launcher/resources/multimc/128x128/instances/flame.png)bin6226 -> 6226 bytes
-rw-r--r--launcher/resources/multimc/128x128/instances/ftb_logo_legacy.png (renamed from launcher/resources/multimc/128x128/instances/ftb_logo.png)bin7883 -> 7883 bytes
-rw-r--r--launcher/resources/multimc/128x128/instances/gear_legacy.png (renamed from launcher/resources/multimc/128x128/instances/gear.png)bin18321 -> 18321 bytes
-rw-r--r--launcher/resources/multimc/128x128/instances/herobrine_legacy.png (renamed from launcher/resources/multimc/128x128/instances/herobrine.png)bin4937 -> 4937 bytes
-rw-r--r--launcher/resources/multimc/128x128/instances/infinity_legacy.png (renamed from launcher/resources/multimc/128x128/instances/infinity.png)bin8012 -> 8012 bytes
-rw-r--r--launcher/resources/multimc/128x128/instances/magitech_legacy.png (renamed from launcher/resources/multimc/128x128/instances/magitech.png)bin23097 -> 23097 bytes
-rw-r--r--launcher/resources/multimc/128x128/instances/meat_legacy.png (renamed from launcher/resources/multimc/128x128/instances/meat.png)bin10583 -> 10583 bytes
-rw-r--r--launcher/resources/multimc/128x128/instances/netherstar_legacy.png (renamed from launcher/resources/multimc/128x128/instances/netherstar.png)bin14062 -> 14062 bytes
-rw-r--r--launcher/resources/multimc/128x128/instances/skeleton_legacy.png (renamed from launcher/resources/multimc/128x128/instances/skeleton.png)bin3673 -> 3673 bytes
-rw-r--r--launcher/resources/multimc/128x128/instances/squarecreeper_legacy.png (renamed from launcher/resources/multimc/128x128/instances/squarecreeper.png)bin9136 -> 9136 bytes
-rw-r--r--launcher/resources/multimc/128x128/instances/steve_legacy.png (renamed from launcher/resources/multimc/128x128/instances/steve.png)bin4312 -> 4312 bytes
-rw-r--r--launcher/resources/multimc/32x32/instances/brick_legacy.png (renamed from launcher/resources/multimc/32x32/instances/brick.png)bin2388 -> 2388 bytes
-rw-r--r--launcher/resources/multimc/32x32/instances/chicken_legacy.png (renamed from launcher/resources/multimc/32x32/instances/chicken.png)bin1181 -> 1181 bytes
-rw-r--r--launcher/resources/multimc/32x32/instances/creeper_legacy.png (renamed from launcher/resources/multimc/32x32/instances/creeper.png)bin1524 -> 1524 bytes
-rw-r--r--launcher/resources/multimc/32x32/instances/diamond_legacy.png (renamed from launcher/resources/multimc/32x32/instances/diamond.png)bin2444 -> 2444 bytes
-rw-r--r--launcher/resources/multimc/32x32/instances/dirt_legacy.png (renamed from launcher/resources/multimc/32x32/instances/dirt.png)bin482 -> 482 bytes
-rw-r--r--launcher/resources/multimc/32x32/instances/enderpearl_legacy.png (renamed from launcher/resources/multimc/32x32/instances/enderpearl.png)bin2120 -> 2120 bytes
-rw-r--r--launcher/resources/multimc/32x32/instances/ftb_logo_legacy.png (renamed from launcher/resources/multimc/32x32/instances/ftb_logo.png)bin1607 -> 1607 bytes
-rw-r--r--launcher/resources/multimc/32x32/instances/gear_legacy.png (renamed from launcher/resources/multimc/32x32/instances/gear.png)bin2414 -> 2414 bytes
-rw-r--r--launcher/resources/multimc/32x32/instances/gold_legacy.png (renamed from launcher/resources/multimc/32x32/instances/gold.png)bin2366 -> 2366 bytes
-rw-r--r--launcher/resources/multimc/32x32/instances/grass_legacy.png (renamed from launcher/resources/multimc/32x32/instances/grass.png)bin618 -> 618 bytes
-rw-r--r--launcher/resources/multimc/32x32/instances/herobrine_legacy.png (renamed from launcher/resources/multimc/32x32/instances/herobrine.png)bin1034 -> 1034 bytes
-rw-r--r--launcher/resources/multimc/32x32/instances/infinity_legacy.png (renamed from launcher/resources/multimc/32x32/instances/infinity.png)bin1714 -> 1714 bytes
-rw-r--r--launcher/resources/multimc/32x32/instances/iron_legacy.png (renamed from launcher/resources/multimc/32x32/instances/iron.png)bin1772 -> 1772 bytes
-rw-r--r--launcher/resources/multimc/32x32/instances/magitech_legacy.png (renamed from launcher/resources/multimc/32x32/instances/magitech.png)bin2646 -> 2646 bytes
-rw-r--r--launcher/resources/multimc/32x32/instances/meat_legacy.png (renamed from launcher/resources/multimc/32x32/instances/meat.png)bin1514 -> 1514 bytes
-rw-r--r--launcher/resources/multimc/32x32/instances/netherstar_legacy.png (renamed from launcher/resources/multimc/32x32/instances/netherstar.png)bin1942 -> 1942 bytes
-rw-r--r--launcher/resources/multimc/32x32/instances/planks_legacy.png (renamed from launcher/resources/multimc/32x32/instances/planks.png)bin2299 -> 2299 bytes
-rw-r--r--launcher/resources/multimc/32x32/instances/skeleton_legacy.png (renamed from launcher/resources/multimc/32x32/instances/skeleton.png)bin696 -> 696 bytes
-rw-r--r--launcher/resources/multimc/32x32/instances/squarecreeper_legacy.png (renamed from launcher/resources/multimc/32x32/instances/squarecreeper.png)bin1623 -> 1623 bytes
-rw-r--r--launcher/resources/multimc/32x32/instances/steve_legacy.png (renamed from launcher/resources/multimc/32x32/instances/steve.png)bin969 -> 969 bytes
-rw-r--r--launcher/resources/multimc/32x32/instances/stone_legacy.png (renamed from launcher/resources/multimc/32x32/instances/stone.png)bin1866 -> 1866 bytes
-rw-r--r--launcher/resources/multimc/32x32/instances/tnt_legacy.png (renamed from launcher/resources/multimc/32x32/instances/tnt.png)bin378 -> 378 bytes
-rw-r--r--launcher/resources/multimc/50x50/instances/enderman_legacy.png (renamed from launcher/resources/multimc/50x50/instances/enderman.png)bin2429 -> 2429 bytes
-rw-r--r--launcher/resources/multimc/multimc.qrc114
-rw-r--r--launcher/resources/multimc/scalable/delete.svg282
-rw-r--r--launcher/resources/multimc/scalable/export.svg466
-rw-r--r--launcher/resources/multimc/scalable/instances/bee.svg289
-rw-r--r--launcher/resources/multimc/scalable/instances/bee_legacy.svg159
-rw-r--r--launcher/resources/multimc/scalable/instances/brick.svg67
-rw-r--r--launcher/resources/multimc/scalable/instances/chicken.svg130
-rw-r--r--launcher/resources/multimc/scalable/instances/creeper.svg68
-rw-r--r--launcher/resources/multimc/scalable/instances/diamond.svg62
-rw-r--r--launcher/resources/multimc/scalable/instances/dirt.svg52
-rw-r--r--launcher/resources/multimc/scalable/instances/enderman.svg96
-rw-r--r--launcher/resources/multimc/scalable/instances/enderpearl.svg95
-rw-r--r--launcher/resources/multimc/scalable/instances/flame.svg49
-rw-r--r--launcher/resources/multimc/scalable/instances/fox.svg435
-rw-r--r--launcher/resources/multimc/scalable/instances/fox_legacy.svg290
-rw-r--r--launcher/resources/multimc/scalable/instances/ftb_logo.svg82
-rw-r--r--launcher/resources/multimc/scalable/instances/gear.svg68
-rw-r--r--launcher/resources/multimc/scalable/instances/gold.svg63
-rw-r--r--launcher/resources/multimc/scalable/instances/grass.svg84
-rw-r--r--launcher/resources/multimc/scalable/instances/herobrine.svg111
-rw-r--r--launcher/resources/multimc/scalable/instances/iron.svg178
-rw-r--r--launcher/resources/multimc/scalable/instances/magitech.svg85
-rw-r--r--launcher/resources/multimc/scalable/instances/meat.svg121
-rw-r--r--launcher/resources/multimc/scalable/instances/modrinth.svg74
-rw-r--r--launcher/resources/multimc/scalable/instances/netherstar.svg81
-rw-r--r--launcher/resources/multimc/scalable/instances/planks.svg93
-rw-r--r--launcher/resources/multimc/scalable/instances/skeleton.svg134
-rw-r--r--launcher/resources/multimc/scalable/instances/squarecreeper.svg81
-rw-r--r--launcher/resources/multimc/scalable/instances/steve.svg154
-rw-r--r--launcher/resources/multimc/scalable/instances/stone.svg55
-rw-r--r--launcher/resources/multimc/scalable/instances/tnt.svg126
-rw-r--r--launcher/resources/multimc/scalable/launch.svg96
-rw-r--r--launcher/resources/multimc/scalable/rename.svg437
-rw-r--r--launcher/resources/multimc/scalable/shortcut.svg157
-rw-r--r--launcher/resources/multimc/scalable/tag.svg398
-rw-r--r--launcher/resources/pe_blue/pe_blue.qrc1
-rw-r--r--launcher/resources/pe_blue/scalable/shortcut.svg41
-rw-r--r--launcher/resources/pe_colored/pe_colored.qrc1
-rw-r--r--launcher/resources/pe_colored/scalable/shortcut.svg13
-rw-r--r--launcher/resources/pe_dark/pe_dark.qrc1
-rw-r--r--launcher/resources/pe_dark/scalable/shortcut.svg41
-rw-r--r--launcher/resources/pe_light/pe_light.qrc1
-rw-r--r--launcher/resources/pe_light/scalable/shortcut.svg41
-rw-r--r--launcher/translations/TranslationsModel.cpp9
-rw-r--r--launcher/ui/MainWindow.cpp236
-rw-r--r--launcher/ui/MainWindow.h8
-rw-r--r--launcher/ui/dialogs/BlockedModsDialog.cpp315
-rw-r--r--launcher/ui/dialogs/BlockedModsDialog.h46
-rw-r--r--launcher/ui/dialogs/BlockedModsDialog.ui96
-rw-r--r--launcher/ui/dialogs/ProgressDialog.cpp3
-rw-r--r--launcher/ui/pages/global/LauncherPage.cpp29
-rw-r--r--launcher/ui/pages/global/LauncherPage.ui10
-rw-r--r--launcher/ui/pages/instance/ExternalResourcesPage.cpp11
-rw-r--r--launcher/ui/pages/instance/ExternalResourcesPage.h1
-rw-r--r--launcher/ui/pages/instance/ExternalResourcesPage.ui6
-rw-r--r--launcher/ui/pages/instance/ModFolderPage.cpp2
-rw-r--r--launcher/ui/pages/instance/ModFolderPage.h2
-rw-r--r--launcher/ui/pages/instance/ServersPage.cpp4
-rw-r--r--launcher/ui/pages/instance/VersionPage.ui6
-rw-r--r--launcher/ui/pages/modplatform/ModModel.h8
-rw-r--r--launcher/ui/pages/modplatform/ModPage.cpp4
-rw-r--r--launcher/ui/pages/modplatform/atlauncher/AtlListModel.cpp4
-rw-r--r--launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp4
-rw-r--r--launcher/ui/pages/modplatform/flame/FlameModel.cpp4
-rw-r--r--launcher/ui/pages/modplatform/ftb/FtbListModel.cpp4
-rw-r--r--launcher/ui/pages/modplatform/legacy_ftb/ListModel.cpp4
-rw-r--r--launcher/ui/pages/modplatform/modrinth/ModrinthModel.h6
-rw-r--r--launcher/ui/pages/modplatform/technic/TechnicModel.cpp8
-rw-r--r--libraries/README.md68
-rw-r--r--libraries/launcher/.gitignore1
-rw-r--r--libraries/launcher/CMakeLists.txt15
-rw-r--r--libraries/launcher/net/minecraft/Launcher.java181
-rw-r--r--libraries/launcher/org/prismlauncher/EntryPoint.java160
-rw-r--r--libraries/launcher/org/prismlauncher/Launcher.java23
-rw-r--r--libraries/launcher/org/prismlauncher/applet/LegacyFrame.java163
-rw-r--r--libraries/launcher/org/prismlauncher/exception/ParameterNotFoundException.java45
-rw-r--r--libraries/launcher/org/prismlauncher/exception/ParseException.java47
-rw-r--r--libraries/launcher/org/prismlauncher/impl/OneSixLauncher.java190
-rw-r--r--libraries/launcher/org/prismlauncher/launcher/Launcher.java44
-rw-r--r--libraries/launcher/org/prismlauncher/launcher/impl/AbstractLauncher.java110
-rw-r--r--libraries/launcher/org/prismlauncher/launcher/impl/StandardLauncher.java91
-rw-r--r--libraries/launcher/org/prismlauncher/launcher/impl/legacy/LegacyFrame.java190
-rw-r--r--libraries/launcher/org/prismlauncher/launcher/impl/legacy/LegacyLauncher.java126
-rw-r--r--libraries/launcher/org/prismlauncher/utils/Parameters.java84
-rw-r--r--libraries/launcher/org/prismlauncher/utils/ReflectionUtils.java154
-rw-r--r--libraries/launcher/org/prismlauncher/utils/Utils.java49
-rw-r--r--libraries/launcher/org/prismlauncher/utils/logging/Level.java (renamed from libraries/launcher/org/prismlauncher/LauncherFactory.java)57
-rw-r--r--libraries/launcher/org/prismlauncher/utils/logging/Log.java104
m---------libraries/tomlplusplus0
-rw-r--r--nix/default.nix95
-rw-r--r--program_info/instance_icons.svg2720
-rw-r--r--program_info/win_install.nsi.in167
-rw-r--r--tests/FileSystem_test.cpp37
274 files changed, 12047 insertions, 1578 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 3225cf1e..79221531 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -7,10 +7,17 @@ on:
description: Type of build (Debug, Release, RelWithDebInfo, MinSizeRel)
type: string
default: Debug
+ is_qt_cached:
+ description: Enable Qt caching or not
+ type: string
+ default: true
secrets:
SPARKLE_ED25519_KEY:
description: Private key for signing Sparkle updates
required: false
+ CACHIX_AUTH_TOKEN:
+ description: Private token for authenticating against Cachix cache
+ required: false
jobs:
build:
@@ -102,14 +109,6 @@ jobs:
with:
submodules: 'true'
- - name: Initialize CodeQL
- if: runner.os == 'Linux' && matrix.qt_ver == 6
- uses: github/codeql-action/init@v2
- with:
- config-file: ./.github/codeql/codeql-config.yml
- queries: security-and-quality
- languages: cpp, java
-
- name: 'Setup MSYS2'
if: runner.os == 'Windows' && matrix.msystem != ''
uses: msys2/setup-msys2@v2
@@ -200,8 +199,7 @@ jobs:
arch: ${{ matrix.qt_arch }}
modules: ${{ matrix.qt_modules }}
tools: ${{ matrix.qt_tools }}
- cache: true
- cache-key-prefix: ${{ matrix.qt_host }}-${{ matrix.qt_version }}-"${{ matrix.qt_modules }}"-qt_cache
+ cache: ${{ inputs.is_qt_cached }}
- name: Prepare AppImage (Linux)
if: runner.os == 'Linux' && matrix.qt_ver != 5
@@ -235,7 +233,7 @@ jobs:
- name: Configure CMake (Windows MSVC)
if: runner.os == 'Windows' && matrix.msystem == ''
run: |
- cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_DIR }} -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DENABLE_LTO=ON -DLauncher_BUILD_PLATFORM=${{ matrix.name }} -DLauncher_QT_VERSION_MAJOR=${{ matrix.qt_ver }} -DCMAKE_MSVC_RUNTIME_LIBRARY="MultiThreadedDLL" -A${{ matrix.architecture}}
+ cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_DIR }} -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DENABLE_LTO=ON -DLauncher_BUILD_PLATFORM=${{ matrix.name }} -DLauncher_QT_VERSION_MAJOR=${{ matrix.qt_ver }} -DCMAKE_MSVC_RUNTIME_LIBRARY="MultiThreadedDLL" -A${{ matrix.architecture}} -DLauncher_FORCE_BUNDLED_LIBS=ON
# https://github.com/ccache/ccache/wiki/MS-Visual-Studio (I coudn't figure out the compiler prefix)
if ("${{ env.CCACHE_VAR }}")
{
@@ -293,14 +291,6 @@ jobs:
ctest -E "^example64|example$" --test-dir build --output-on-failure -C ${{ inputs.build_type }}
##
- # CODE SCAN
- ##
-
- - name: Perform CodeQL Analysis
- if: runner.os == 'Linux' && matrix.qt_ver == 6
- uses: github/codeql-action/analyze@v2
-
- ##
# PACKAGE BUILDS
##
@@ -500,21 +490,72 @@ jobs:
runs-on: ubuntu-20.04
steps:
- name: Checkout
+ if: inputs.build_type == 'Debug'
uses: actions/checkout@v3
with:
submodules: 'true'
- name: Set short version
shell: bash
+ if: inputs.build_type == 'Debug'
run: |
ver_short=`git rev-parse --short HEAD`
echo "VERSION=$ver_short" >> $GITHUB_ENV
- name: Package Snap (Linux)
id: snapcraft
- if: runner.os == 'Linux' && matrix.qt_ver != 5
+ if: inputs.build_type == 'Debug'
uses: snapcore/action-build@v1
- name: Upload Snap (Linux)
- if: runner.os == 'Linux' && matrix.qt_ver != 5
+ if: inputs.build_type == 'Debug'
uses: actions/upload-artifact@v3
with:
name: prismlauncher_${{ env.VERSION }}_amd64.snap
path: ${{ steps.snapcraft.outputs.snap }}
+
+ flatpak:
+ runs-on: ubuntu-latest
+ container:
+ image: bilelmoussaoui/flatpak-github-actions:kde-5.15-22.08
+ options: --privileged
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3
+ if: inputs.build_type == 'Debug'
+ with:
+ submodules: 'true'
+ - name: Build Flatpak (Linux)
+ if: inputs.build_type == 'Debug'
+ uses: flatpak/flatpak-github-actions/flatpak-builder@v4
+ with:
+ bundle: "Prism Launcher.flatpak"
+ manifest-path: flatpak/org.prismlauncher.PrismLauncher.yml
+ cache-key: flatpak-${{ github.sha }}-x86_64
+
+ nix:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ package:
+ - prismlauncher
+ - prismlauncher-qt5
+ steps:
+ - name: Clone repository
+ if: inputs.build_type == 'Debug'
+ uses: actions/checkout@v3
+ with:
+ submodules: 'true'
+ - name: Install nix
+ if: inputs.build_type == 'Debug'
+ uses: cachix/install-nix-action@v18
+ with:
+ install_url: https://nixos.org/nix/install
+ extra_nix_config: |
+ auto-optimise-store = true
+ experimental-features = nix-command flakes
+ - uses: cachix/cachix-action@v12
+ if: inputs.build_type == 'Debug'
+ with:
+ name: prismlauncher
+ authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
+ - name: Build
+ if: inputs.build_type == 'Debug'
+ run: nix build .#${{ matrix.package }} --print-build-logs
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
new file mode 100644
index 00000000..0cd1f6e4
--- /dev/null
+++ b/.github/workflows/codeql.yml
@@ -0,0 +1,35 @@
+name: "CodeQL Code Scanning"
+
+on: [ push, pull_request, workflow_dispatch ]
+
+jobs:
+ CodeQL:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v3
+ with:
+ submodules: 'true'
+
+ - name: Initialize CodeQL
+ uses: github/codeql-action/init@v2
+ with:
+ config-file: ./.github/codeql/codeql-config.yml
+ queries: security-and-quality
+ languages: cpp, java
+
+ - name: Install Dependencies
+ run:
+ sudo apt-get -y update
+
+ sudo apt-get -y install ninja-build extra-cmake-modules scdoc qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools libqt5core5a libqt5network5 libqt5gui5
+
+ - name: Configure and Build
+ run: |
+ cmake -S . -B build -DCMAKE_INSTALL_PREFIX=/usr -DLauncher_QT_VERSION_MAJOR=5 -G Ninja
+
+ cmake --build build
+
+ - name: Perform CodeQL Analysis
+ uses: github/codeql-action/analyze@v2
diff --git a/.github/workflows/trigger_builds.yml b/.github/workflows/trigger_builds.yml
index 8adaa5e5..a08193a0 100644
--- a/.github/workflows/trigger_builds.yml
+++ b/.github/workflows/trigger_builds.yml
@@ -8,7 +8,6 @@ on:
- '**.md'
- '**/LICENSE'
- 'flake.lock'
- - '**.nix'
- 'packages/**'
- '.github/ISSUE_TEMPLATE/**'
- '.markdownlint**'
@@ -17,7 +16,6 @@ on:
- '**.md'
- '**/LICENSE'
- 'flake.lock'
- - '**.nix'
- 'packages/**'
- '.github/ISSUE_TEMPLATE/**'
- '.markdownlint**'
@@ -30,5 +28,7 @@ jobs:
uses: ./.github/workflows/build.yml
with:
build_type: Debug
+ is_qt_cached: true
secrets:
SPARKLE_ED25519_KEY: ${{ secrets.SPARKLE_ED25519_KEY }}
+ CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }}
diff --git a/.github/workflows/trigger_release.yml b/.github/workflows/trigger_release.yml
index d415b2b1..8baa9693 100644
--- a/.github/workflows/trigger_release.yml
+++ b/.github/workflows/trigger_release.yml
@@ -12,6 +12,7 @@ jobs:
uses: ./.github/workflows/build.yml
with:
build_type: Release
+ is_qt_cached: false
secrets:
SPARKLE_ED25519_KEY: ${{ secrets.SPARKLE_ED25519_KEY }}
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0db05f98..f04b733b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -70,6 +70,9 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DQT_NO_DEPRECATED_WARNINGS=Y")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DQT_DISABLE_DEPRECATED_BEFORE=0x050C00")
+# Fix aarch64 build for toml++
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DTOML_ENABLE_FLOAT16=0")
+
# set CXXFLAGS for build targets
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -D_FORTIFY_SOURCE=2 ${CMAKE_CXX_FLAGS_RELEASE}")
@@ -365,11 +368,11 @@ if(NOT ZLIB_FOUND)
set(SKIP_INSTALL_ALL ON)
add_subdirectory(libraries/zlib EXCLUDE_FROM_ALL)
- set(ZLIB_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/libraries/zlib" "${CMAKE_CURRENT_BINARY_DIR}/libraries/zlib")
+ set(ZLIB_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/libraries/zlib" "${CMAKE_CURRENT_BINARY_DIR}/libraries/zlib" CACHE STRING "")
set_target_properties(zlibstatic PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${ZLIB_INCLUDE_DIR}")
add_library(ZLIB::ZLIB ALIAS zlibstatic)
- set(ZLIB_LIBRARY ZLIB::ZLIB)
- set(ZLIB_FOUND true)
+ set(ZLIB_LIBRARY ZLIB::ZLIB CACHE STRING "zlib library name")
+
find_package(ZLIB REQUIRED)
else()
message(STATUS "Using system zlib")
diff --git a/COPYING.md b/COPYING.md
index 3e35c579..dde3c727 100644
--- a/COPYING.md
+++ b/COPYING.md
@@ -398,3 +398,20 @@
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+
+## Breeze icons
+
+ Copyright (C) 2014 Uri Herrera <uri_herrera@nitrux.in> and others
+
+ This library 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 3 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library. If not, see <http://www.gnu.org/licenses/>.
diff --git a/README.md b/README.md
index f8ea2e84..f02b5695 100644
--- a/README.md
+++ b/README.md
@@ -29,19 +29,19 @@ Prebuilt Development builds are provided for **Linux**, **Windows** and **macOS*
For **Arch**, **Debian**, **Fedora**, **OpenSUSE (Tumbleweed)** and **Gentoo**, respectively, you can use these packages for the latest development versions:
-[![prismlauncher-git](https://img.shields.io/badge/aur-prismlauncher--git-1793D1?style=flat-square&logo=archlinux&logoColor=white)](https://aur.archlinux.org/packages/prismlauncher-qt5-git/) [![prismlauncher-git](https://img.shields.io/badge/aur-prismlauncher--qt5--git-1793D1?style=flat-square&logo=archlinux&logoColor=white)](https://aur.archlinux.org/packages/prismlauncher-git/) [![prismlauncher-git](https://img.shields.io/badge/mpr-prismlauncher--git-A80030?style=flat-square&logo=debian&logoColor=white)](https://mpr.makedeb.org/packages/prismlauncher-git) [![prismlauncher-nightly](https://img.shields.io/badge/copr-prismlauncher--nightly-51A2DA?style=flat-square&logo=fedora&logoColor=white)](https://copr.fedorainfracloud.org/coprs/g3tchoo/prismlauncher/) [![prismlauncher-nightly](https://img.shields.io/badge/OBS-prismlauncher--nightly-3AB6A9?style=flat-square&logo=opensuse&logoColor=white)](https://build.opensuse.org/project/show/home:getchoo) [![prismlauncher-9999](https://img.shields.io/badge/gentoo-prismlauncher--9999-4D4270?style=flat-square&logo=gentoo&logoColor=white)](https://packages.gentoo.org/packages/games-action/prismlauncher)
+[![prismlauncher-git](https://img.shields.io/badge/aur-prismlauncher--git-1793D1?style=flat-square&logo=archlinux&logoColor=white)](https://aur.archlinux.org/packages/prismlauncher-git/) [![prismlauncher-git](https://img.shields.io/badge/aur-prismlauncher--qt5--git-1793D1?style=flat-square&logo=archlinux&logoColor=white)](https://aur.archlinux.org/packages/prismlauncher-qt5-git/) [![prismlauncher-git](https://img.shields.io/badge/mpr-prismlauncher--git-A80030?style=flat-square&logo=debian&logoColor=white)](https://mpr.makedeb.org/packages/prismlauncher-git) [![prismlauncher-nightly](https://img.shields.io/badge/copr-prismlauncher--nightly-51A2DA?style=flat-square&logo=fedora&logoColor=white)](https://copr.fedorainfracloud.org/coprs/g3tchoo/prismlauncher/) [![prismlauncher-nightly](https://img.shields.io/badge/OBS-prismlauncher--nightly-3AB6A9?style=flat-square&logo=opensuse&logoColor=white)](https://build.opensuse.org/project/show/home:getchoo) [![prismlauncher-9999](https://img.shields.io/badge/gentoo-prismlauncher--9999-4D4270?style=flat-square&logo=gentoo&logoColor=white)](https://packages.gentoo.org/packages/games-action/prismlauncher)
## Community & Support
-Feel free to create a GitHub issue if you find a bug or want to suggest a new feature. We have multiple communities that can also help you.
+Feel free to create a GitHub issue if you find a bug or want to suggest a new feature. We have multiple community spaces where other community members can help you.
#### Join our Discord server:
[![Prism Launcher Discord server](https://discordapp.com/api/guilds/1031648380885147709/widget.png?style=banner2)](https://discord.gg/prismlauncher)
-#### Join our Matrix space (Will be opened at a later date):
+#### Join our Matrix space:
[![PrismLauncher Space](https://img.shields.io/matrix/prismlauncher:matrix.org?style=for-the-badge&logo=matrix)](https://matrix.to/#/#prismlauncher:matrix.org)
-#### Join our SubReddit:
+#### Join our Subreddit:
[![r/PrismLauncher](https://img.shields.io/reddit/subreddit-subscribers/prismlauncher?style=for-the-badge&logo=reddit)](https://www.reddit.com/r/PrismLauncher/)
## Building
diff --git a/flake.nix b/flake.nix
index d4a25338..b1e07c91 100644
--- a/flake.nix
+++ b/flake.nix
@@ -23,8 +23,8 @@
pkgs = forAllSystems (system: nixpkgs.legacyPackages.${system});
packagesFn = pkgs: rec {
- prismlauncher = pkgs.libsForQt5.callPackage ./nix { inherit version self libnbtplusplus tomlplusplus; };
- prismlauncher-qt6 = pkgs.qt6Packages.callPackage ./nix { inherit version self libnbtplusplus tomlplusplus; };
+ prismlauncher-qt5 = pkgs.libsForQt5.callPackage ./nix { inherit version self libnbtplusplus tomlplusplus; };
+ prismlauncher = pkgs.qt6Packages.callPackage ./nix { inherit version self libnbtplusplus tomlplusplus; };
};
in
{
diff --git a/flatpak/org.prismlauncher.PrismLauncher.yml b/flatpak/org.prismlauncher.PrismLauncher.yml
new file mode 100644
index 00000000..fca306d7
--- /dev/null
+++ b/flatpak/org.prismlauncher.PrismLauncher.yml
@@ -0,0 +1,83 @@
+id: org.prismlauncher.PrismLauncher
+runtime: org.kde.Platform
+runtime-version: "5.15-22.08"
+sdk: org.kde.Sdk
+sdk-extensions:
+ - org.freedesktop.Sdk.Extension.openjdk17
+ - org.freedesktop.Sdk.Extension.openjdk8
+add-extensions:
+ com.valvesoftware.Steam.Utility.gamescope:
+ version: stable
+ add-ld-path: lib
+ no-autodownload: true
+ autodelete: false
+ directory: utils/gamescope
+
+command: prismlauncher
+finish-args:
+ - --share=ipc
+ - --socket=x11
+ - --socket=wayland
+ - --device=all
+ - --share=network
+ - --socket=pulseaudio
+ # for Discord RPC mods
+ - --filesystem=xdg-run/app/com.discordapp.Discord:create
+ # Mod drag&drop
+ - --filesystem=xdg-download:ro
+
+modules:
+ - name: prismlauncher
+ buildsystem: cmake-ninja
+ config-opts:
+ - -DLauncher_BUILD_PLATFORM=flatpak
+ - -DCMAKE_BUILD_TYPE=Debug
+ build-options:
+ env:
+ JAVA_HOME: /usr/lib/sdk/openjdk17/jvm/openjdk-17
+ JAVA_COMPILER: /usr/lib/sdk/openjdk17/jvm/openjdk-17/bin/javac
+ sources:
+ - type: dir
+ path: ../
+ - name: openjdk
+ buildsystem: simple
+ build-commands:
+ - mkdir -p /app/jdk/
+ - /usr/lib/sdk/openjdk17/install.sh
+ - mv /app/jre /app/jdk/17
+ - /usr/lib/sdk/openjdk8/install.sh
+ - mv /app/jre /app/jdk/8
+ cleanup: [/jre]
+ - name: xrandr
+ buildsystem: autotools
+ sources:
+ - type: archive
+ url: https://xorg.freedesktop.org/archive/individual/app/xrandr-1.5.1.tar.xz
+ sha256: 7bc76daf9d72f8aff885efad04ce06b90488a1a169d118dea8a2b661832e8762
+ cleanup: [/share/man, /bin/xkeystone]
+ - name: gamemode
+ buildsystem: meson
+ config-opts:
+ - -Dwith-sd-bus-provider=no-daemon
+ - -Dwith-examples=false
+ post-install:
+ # gamemoderun is installed for users who want to use wrapper commands
+ # post-install is running inside the build dir, we need it from the source though
+ - install -Dm755 ../data/gamemoderun -t /app/bin
+ sources:
+ - type: git
+ url: https://github.com/FeralInteractive/gamemode
+ tag: "1.7"
+ commit: 4dc99dff76218718763a6b07fc1900fa6d1dafd9
+ - name: enhance
+ buildsystem: simple
+ build-commands:
+ - mkdir -p /app/utils/gamescope
+ - install -Dm755 prime-run /app/bin/prime-run
+ - mv /app/bin/prismlauncher /app/bin/prismrun
+ - install -Dm755 prismlauncher /app/bin/prismlauncher
+ sources:
+ - type: file
+ path: ../flatpak/prime-run
+ - type: file
+ path: ../flatpak/prismlauncher
diff --git a/flatpak/prime-run b/flatpak/prime-run
new file mode 100644
index 00000000..946c28dd
--- /dev/null
+++ b/flatpak/prime-run
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+export __NV_PRIME_RENDER_OFFLOAD=1 __VK_LAYER_NV_optimus=NVIDIA_only __GLX_VENDOR_LIBRARY_NAME=nvidia
+exec "$@"
diff --git a/flatpak/prismlauncher b/flatpak/prismlauncher
new file mode 100644
index 00000000..bb876711
--- /dev/null
+++ b/flatpak/prismlauncher
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+# discord RPC
+for i in {0..9}; do
+ test -S "$XDG_RUNTIME_DIR"/discord-ipc-"$i" || ln -sf {app/com.discordapp.Discord,"$XDG_RUNTIME_DIR"}/discord-ipc-"$i";
+done
+
+export PATH="${PATH}${PATH:+:}/app/utils/gamescope/bin:/usr/lib/extensions/vulkan/MangoHud/bin"
+export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}${LD_LIBRARY_PATH:+:}/usr/lib/extensions/vulkan/MangoHud/\$LIB/"
+
+exec /app/bin/prismrun "$@"
diff --git a/launcher/Application.cpp b/launcher/Application.cpp
index 45cd9422..ea8d2326 100644
--- a/launcher/Application.cpp
+++ b/launcher/Application.cpp
@@ -1,4 +1,7 @@
-// SPDX-License-Identifier: GPL-3.0-only
+// SPDX-FileCopyrightText: 2022 Sefa Eyeoglu <contact@scrumplex.net>
+//
+// SPDX-License-Identifier: GPL-3.0-only AND Apache-2.0
+
/*
* Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
@@ -38,10 +41,14 @@
#include "Application.h"
#include "BuildConfig.h"
+#include "DataMigrationTask.h"
#include "net/PasteUpload.h"
+#include "pathmatcher/MultiMatcher.h"
+#include "pathmatcher/SimplePrefixMatcher.h"
#include "ui/MainWindow.h"
#include "ui/InstanceWindow.h"
+#include "ui/dialogs/ProgressDialog.h"
#include "ui/instanceview/AccessibleInstanceView.h"
#include "ui/pages/BasePageProvider.h"
@@ -226,7 +233,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
setOrganizationDomain(BuildConfig.LAUNCHER_DOMAIN);
setApplicationName(BuildConfig.LAUNCHER_NAME);
setApplicationDisplayName(QString("%1 %2").arg(BuildConfig.LAUNCHER_DISPLAYNAME, BuildConfig.printableVersionString()));
- setApplicationVersion(BuildConfig.printableVersionString());
+ setApplicationVersion(BuildConfig.printableVersionString() + "\n" + BuildConfig.GIT_COMMIT);
setDesktopFileName(BuildConfig.LAUNCHER_DESKTOPFILENAME);
startTime = QDateTime::currentDateTime();
@@ -301,22 +308,6 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
dataPath = foo.absolutePath();
adjustedBy = "Persistent data path";
- QDir polymcData(FS::PathCombine(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation), "PolyMC"));
- if (polymcData.exists()) {
- dataPath = polymcData.absolutePath();
- adjustedBy = "PolyMC data path";
- }
-
-#ifdef Q_OS_LINUX
- // TODO: this should be removed in a future version
- // TODO: provide a migration path similar to macOS migration
- QDir bar(FS::PathCombine(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation), "polymc"));
- if (bar.exists()) {
- dataPath = bar.absolutePath();
- adjustedBy = "Legacy data path";
- }
-#endif
-
#ifndef Q_OS_MACOS
if (QFile::exists(FS::PathCombine(m_rootPath, "portable.txt"))) {
dataPath = m_rootPath;
@@ -440,6 +431,15 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
}
{
+ bool migrated = false;
+
+ if (!migrated)
+ migrated = handleDataMigration(dataPath, FS::PathCombine(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation), "../../PolyMC"), "PolyMC", "polymc.cfg");
+ if (!migrated)
+ migrated = handleDataMigration(dataPath, FS::PathCombine(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation), "../../multimc"), "MultiMC", "multimc.cfg");
+ }
+
+ {
qDebug() << BuildConfig.LAUNCHER_DISPLAYNAME << ", (c) 2013-2021 " << BuildConfig.LAUNCHER_COPYRIGHT;
qDebug() << "Version : " << BuildConfig.printableVersionString();
@@ -1605,3 +1605,88 @@ int Application::suitableMaxMem()
return maxMemoryAlloc;
}
+
+bool Application::handleDataMigration(const QString& currentData,
+ const QString& oldData,
+ const QString& name,
+ const QString& configFile) const
+{
+ QString nomigratePath = FS::PathCombine(currentData, name + "_nomigrate.txt");
+ QStringList configPaths = { FS::PathCombine(oldData, configFile), FS::PathCombine(oldData, BuildConfig.LAUNCHER_CONFIGFILE) };
+
+ QLocale locale;
+
+ // Is there a valid config at the old location?
+ bool configExists = false;
+ for (QString configPath : configPaths) {
+ configExists |= QFileInfo::exists(configPath);
+ }
+
+ if (!configExists || QFileInfo::exists(nomigratePath)) {
+ qDebug() << "<> No migration needed from" << name;
+ return false;
+ }
+
+ QString message;
+ bool currentExists = QFileInfo::exists(FS::PathCombine(currentData, BuildConfig.LAUNCHER_CONFIGFILE));
+
+ if (currentExists) {
+ message = tr("Old data from %1 was found, but you already have existing data for %2. Sadly you will need to migrate yourself. Do "
+ "you want to be reminded of the pending data migration next time you start %2?")
+ .arg(name, BuildConfig.LAUNCHER_DISPLAYNAME);
+ } else {
+ message = tr("It looks like you used %1 before. Do you want to migrate your data to the new location of %2?")
+ .arg(name, BuildConfig.LAUNCHER_DISPLAYNAME);
+
+ QFileInfo logInfo(FS::PathCombine(oldData, name + "-0.log"));
+ if (logInfo.exists()) {
+ QString lastModified = logInfo.lastModified().toString(locale.dateFormat());
+ message = tr("It looks like you used %1 on %2 before. Do you want to migrate your data to the new location of %3?")
+ .arg(name, lastModified, BuildConfig.LAUNCHER_DISPLAYNAME);
+ }
+ }
+
+ QMessageBox::StandardButton askMoveDialogue =
+ QMessageBox::question(nullptr, BuildConfig.LAUNCHER_DISPLAYNAME, message, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
+
+ auto setDoNotMigrate = [&nomigratePath] {
+ QFile file(nomigratePath);
+ file.open(QIODevice::WriteOnly);
+ };
+
+ // create no-migrate file if user doesn't want to migrate
+ if (askMoveDialogue != QMessageBox::Yes) {
+ qDebug() << "<> Migration declined for" << name;
+ setDoNotMigrate();
+ return currentExists; // cancel further migrations, if we already have a data directory
+ }
+
+ if (!currentExists) {
+ // Migrate!
+ auto matcher = std::make_shared<MultiMatcher>();
+ matcher->add(std::make_shared<SimplePrefixMatcher>(configFile));
+ matcher->add(std::make_shared<SimplePrefixMatcher>(
+ BuildConfig.LAUNCHER_CONFIGFILE)); // it's possible that we already used that directory before
+ matcher->add(std::make_shared<SimplePrefixMatcher>("accounts.json"));
+ matcher->add(std::make_shared<SimplePrefixMatcher>("accounts/"));
+ matcher->add(std::make_shared<SimplePrefixMatcher>("assets/"));
+ matcher->add(std::make_shared<SimplePrefixMatcher>("icons/"));
+ matcher->add(std::make_shared<SimplePrefixMatcher>("instances/"));
+ matcher->add(std::make_shared<SimplePrefixMatcher>("libraries/"));
+ matcher->add(std::make_shared<SimplePrefixMatcher>("mods/"));
+ matcher->add(std::make_shared<SimplePrefixMatcher>("themes/"));
+
+ ProgressDialog diag;
+ DataMigrationTask task(nullptr, oldData, currentData, matcher);
+ if (diag.execWithTask(&task)) {
+ qDebug() << "<> Migration succeeded";
+ setDoNotMigrate();
+ } else {
+ QString reason = task.failReason();
+ QMessageBox::critical(nullptr, BuildConfig.LAUNCHER_DISPLAYNAME, tr("Migration failed! Reason: %1").arg(reason));
+ }
+ } else {
+ qWarning() << "<> Migration was skipped, due to existing data";
+ }
+ return true;
+}
diff --git a/launcher/Application.h b/launcher/Application.h
index 4c2f62d4..7884227a 100644
--- a/launcher/Application.h
+++ b/launcher/Application.h
@@ -231,6 +231,7 @@ private slots:
void setupWizardFinished(int status);
private:
+ bool handleDataMigration(const QString & currentData, const QString & oldData, const QString & name, const QString & configFile) const;
bool createSetupWizard();
void performMainStartupAction();
diff --git a/launcher/BaseInstance.h b/launcher/BaseInstance.h
index 307240e0..a2a4f824 100644
--- a/launcher/BaseInstance.h
+++ b/launcher/BaseInstance.h
@@ -151,7 +151,7 @@ public:
void copyManagedPack(BaseInstance& other);
/// guess log level from a line of game log
- virtual MessageLevel::Enum guessLevel(const QString &line, MessageLevel::Enum level)
+ virtual MessageLevel::Enum guessLevel([[maybe_unused]] const QString &line, MessageLevel::Enum level)
{
return level;
};
diff --git a/launcher/BaseVersionList.cpp b/launcher/BaseVersionList.cpp
index 4ed82612..dc95e7ea 100644
--- a/launcher/BaseVersionList.cpp
+++ b/launcher/BaseVersionList.cpp
@@ -95,12 +95,12 @@ BaseVersionList::RoleList BaseVersionList::providesRoles() const
int BaseVersionList::rowCount(const QModelIndex &parent) const
{
// Return count
- return count();
+ return parent.isValid() ? 0 : count();
}
int BaseVersionList::columnCount(const QModelIndex &parent) const
{
- return 1;
+ return parent.isValid() ? 0 : 1;
}
QHash<int, QByteArray> BaseVersionList::roleNames() const
diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt
index 8db93429..e8afa6b8 100644
--- a/launcher/CMakeLists.txt
+++ b/launcher/CMakeLists.txt
@@ -97,6 +97,7 @@ set(PATHMATCHER_SOURCES
pathmatcher/IPathMatcher.h
pathmatcher/MultiMatcher.h
pathmatcher/RegexpMatcher.h
+ pathmatcher/SimplePrefixMatcher.h
)
set(NET_SOURCES
@@ -575,6 +576,8 @@ SET(LAUNCHER_SOURCES
# Application base
Application.h
Application.cpp
+ DataMigrationTask.h
+ DataMigrationTask.cpp
UpdateController.cpp
UpdateController.h
ApplicationMessage.h
@@ -598,6 +601,8 @@ SET(LAUNCHER_SOURCES
resources/pe_light/pe_light.qrc
resources/pe_colored/pe_colored.qrc
resources/pe_blue/pe_blue.qrc
+ resources/breeze_dark/breeze_dark.qrc
+ resources/breeze_light/breeze_light.qrc
resources/OSX/OSX.qrc
resources/iOS/iOS.qrc
resources/flat/flat.qrc
@@ -957,6 +962,8 @@ qt_add_resources(LAUNCHER_RESOURCES
resources/pe_light/pe_light.qrc
resources/pe_colored/pe_colored.qrc
resources/pe_blue/pe_blue.qrc
+ resources/breeze_dark/breeze_dark.qrc
+ resources/breeze_light/breeze_light.qrc
resources/OSX/OSX.qrc
resources/iOS/iOS.qrc
resources/flat/flat.qrc
diff --git a/launcher/DataMigrationTask.cpp b/launcher/DataMigrationTask.cpp
new file mode 100644
index 00000000..27ce5f01
--- /dev/null
+++ b/launcher/DataMigrationTask.cpp
@@ -0,0 +1,96 @@
+// SPDX-FileCopyrightText: 2022 Sefa Eyeoglu <contact@scrumplex.net>
+//
+// SPDX-License-Identifier: GPL-3.0-only
+
+#include "DataMigrationTask.h"
+
+#include "FileSystem.h"
+
+#include <QDirIterator>
+#include <QFileInfo>
+#include <QMap>
+
+#include <QtConcurrent>
+
+DataMigrationTask::DataMigrationTask(QObject* parent,
+ const QString& sourcePath,
+ const QString& targetPath,
+ const IPathMatcher::Ptr pathMatcher)
+ : Task(parent), m_sourcePath(sourcePath), m_targetPath(targetPath), m_pathMatcher(pathMatcher), m_copy(sourcePath, targetPath)
+{
+ m_copy.matcher(m_pathMatcher.get()).whitelist(true);
+}
+
+void DataMigrationTask::executeTask()
+{
+ setStatus(tr("Scanning files..."));
+
+ // 1. Scan
+ // Check how many files we gotta copy
+ m_copyFuture = QtConcurrent::run(QThreadPool::globalInstance(), [&] {
+ return m_copy(true); // dry run to collect amount of files
+ });
+ connect(&m_copyFutureWatcher, &QFutureWatcher<bool>::finished, this, &DataMigrationTask::dryRunFinished);
+ connect(&m_copyFutureWatcher, &QFutureWatcher<bool>::canceled, this, &DataMigrationTask::dryRunAborted);
+ m_copyFutureWatcher.setFuture(m_copyFuture);
+}
+
+void DataMigrationTask::dryRunFinished()
+{
+ disconnect(&m_copyFutureWatcher, &QFutureWatcher<bool>::finished, this, &DataMigrationTask::dryRunFinished);
+ disconnect(&m_copyFutureWatcher, &QFutureWatcher<bool>::canceled, this, &DataMigrationTask::dryRunAborted);
+
+#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
+ if (!m_copyFuture.isValid() || !m_copyFuture.result()) {
+#else
+ if (!m_copyFuture.result()) {
+#endif
+ emitFailed(tr("Failed to scan source path."));
+ return;
+ }
+
+ // 2. Copy
+ // Actually copy all files now.
+ m_toCopy = m_copy.totalCopied();
+ connect(&m_copy, &FS::copy::fileCopied, [&, this](const QString& relativeName) {
+ QString shortenedName = relativeName;
+ // shorten the filename to hopefully fit into one line
+ if (shortenedName.length() > 50)
+ shortenedName = relativeName.left(20) + "…" + relativeName.right(29);
+ setProgress(m_copy.totalCopied(), m_toCopy);
+ setStatus(tr("Copying %1…").arg(shortenedName));
+ });
+ m_copyFuture = QtConcurrent::run(QThreadPool::globalInstance(), [&] {
+ return m_copy(false); // actually copy now
+ });
+ connect(&m_copyFutureWatcher, &QFutureWatcher<bool>::finished, this, &DataMigrationTask::copyFinished);
+ connect(&m_copyFutureWatcher, &QFutureWatcher<bool>::canceled, this, &DataMigrationTask::copyAborted);
+ m_copyFutureWatcher.setFuture(m_copyFuture);
+}
+
+void DataMigrationTask::dryRunAborted()
+{
+ emitFailed(tr("Aborted"));
+}
+
+void DataMigrationTask::copyFinished()
+{
+ disconnect(&m_copyFutureWatcher, &QFutureWatcher<bool>::finished, this, &DataMigrationTask::copyFinished);
+ disconnect(&m_copyFutureWatcher, &QFutureWatcher<bool>::canceled, this, &DataMigrationTask::copyAborted);
+
+#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
+ if (!m_copyFuture.isValid() || !m_copyFuture.result()) {
+#else
+ if (!m_copyFuture.result()) {
+#endif
+ emitFailed(tr("Some paths could not be copied!"));
+ return;
+ }
+
+ emitSucceeded();
+}
+
+void DataMigrationTask::copyAborted()
+{
+ emitFailed(tr("Aborted"));
+}
diff --git a/launcher/DataMigrationTask.h b/launcher/DataMigrationTask.h
new file mode 100644
index 00000000..6cc23b1a
--- /dev/null
+++ b/launcher/DataMigrationTask.h
@@ -0,0 +1,42 @@
+// SPDX-FileCopyrightText: 2022 Sefa Eyeoglu <contact@scrumplex.net>
+//
+// SPDX-License-Identifier: GPL-3.0-only
+
+#pragma once
+
+#include "FileSystem.h"
+#include "pathmatcher/IPathMatcher.h"
+#include "tasks/Task.h"
+
+#include <QFuture>
+#include <QFutureWatcher>
+
+/*
+ * Migrate existing data from other MMC-like launchers.
+ */
+
+class DataMigrationTask : public Task {
+ Q_OBJECT
+ public:
+ explicit DataMigrationTask(QObject* parent, const QString& sourcePath, const QString& targetPath, const IPathMatcher::Ptr pathmatcher);
+ ~DataMigrationTask() override = default;
+
+ protected:
+ virtual void executeTask() override;
+
+ protected slots:
+ void dryRunFinished();
+ void dryRunAborted();
+ void copyFinished();
+ void copyAborted();
+
+ private:
+ const QString& m_sourcePath;
+ const QString& m_targetPath;
+ const IPathMatcher::Ptr m_pathMatcher;
+
+ FS::copy m_copy;
+ int m_toCopy = 0;
+ QFuture<bool> m_copyFuture;
+ QFutureWatcher<bool> m_copyFutureWatcher;
+};
diff --git a/launcher/FileSystem.cpp b/launcher/FileSystem.cpp
index 1cbb538c..1da50e21 100644
--- a/launcher/FileSystem.cpp
+++ b/launcher/FileSystem.cpp
@@ -49,6 +49,7 @@
#include "StringUtils.h"
#if defined Q_OS_WIN32
+#define WIN32_LEAN_AND_MEAN
#include <objbase.h>
#include <objidl.h>
#include <shlguid.h>
@@ -149,9 +150,13 @@ bool ensureFolderPathExists(QString foldernamepath)
return success;
}
-bool copy::operator()(const QString& offset)
+/// @brief Copies a directory and it's contents from src to dest
+/// @param offset subdirectory form src to copy to dest
+/// @return if there was an error during the filecopy
+bool copy::operator()(const QString& offset, bool dryRun)
{
using copy_opts = fs::copy_options;
+ m_copied = 0; // reset counter
// NOTE always deep copy on windows. the alternatives are too messy.
#if defined Q_OS_WIN32
@@ -171,18 +176,21 @@ bool copy::operator()(const QString& offset)
// Function that'll do the actual copying
auto copy_file = [&](QString src_path, QString relative_dst_path) {
- if (m_blacklist && m_blacklist->matches(relative_dst_path))
+ if (m_matcher && (m_matcher->matches(relative_dst_path) != m_whitelist))
return;
auto dst_path = PathCombine(dst, relative_dst_path);
- ensureFilePathExists(dst_path);
-
- fs::copy(StringUtils::toStdString(src_path), StringUtils::toStdString(dst_path), opt, err);
+ if (!dryRun) {
+ ensureFilePathExists(dst_path);
+ fs::copy(StringUtils::toStdString(src_path), StringUtils::toStdString(dst_path), opt, err);
+ }
if (err) {
qWarning() << "Failed to copy files:" << QString::fromStdString(err.message());
qDebug() << "Source file:" << src_path;
qDebug() << "Destination file:" << dst_path;
}
+ m_copied++;
+ emit fileCopied(relative_dst_path);
};
// We can't use copy_opts::recursive because we need to take into account the
@@ -336,12 +344,37 @@ QString getDesktopDir()
}
// Cross-platform Shortcut creation
-bool createShortCut(QString location, QString dest, QStringList args, QString name, QString icon)
+bool createShortcut(QString destination, QString target, QStringList args, QString name, QString icon)
{
-#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
- location = PathCombine(location, name + ".desktop");
+#if defined(Q_OS_MACOS)
+ destination += ".command";
- QFile f(location);
+ QFile f(destination);
+ f.open(QIODevice::WriteOnly | QIODevice::Text);
+ QTextStream stream(&f);
+
+ QString argstring;
+ if (!args.empty())
+ argstring = " \"" + args.join("\" \"") + "\"";
+
+ stream << "#!/bin/bash"
+ << "\n";
+ stream << "\""
+ << target
+ << "\" "
+ << argstring
+ << "\n";
+
+ stream.flush();
+ f.close();
+
+ f.setPermissions(f.permissions() | QFileDevice::ExeOwner | QFileDevice::ExeGroup | QFileDevice::ExeOther);
+
+ return true;
+#elif defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD)
+ destination += ".desktop";
+
+ QFile f(destination);
f.open(QIODevice::WriteOnly | QIODevice::Text);
QTextStream stream(&f);
@@ -353,10 +386,12 @@ bool createShortCut(QString location, QString dest, QStringList args, QString na
<< "\n";
stream << "Type=Application"
<< "\n";
- stream << "TryExec=" << dest.toLocal8Bit() << "\n";
- stream << "Exec=" << dest.toLocal8Bit() << argstring.toLocal8Bit() << "\n";
+ stream << "Exec=\"" << target.toLocal8Bit() << "\"" << argstring.toLocal8Bit() << "\n";
stream << "Name=" << name.toLocal8Bit() << "\n";
- stream << "Icon=" << icon.toLocal8Bit() << "\n";
+ if (!icon.isEmpty())
+ {
+ stream << "Icon=" << icon.toLocal8Bit() << "\n";
+ }
stream.flush();
f.close();
@@ -364,25 +399,132 @@ bool createShortCut(QString location, QString dest, QStringList args, QString na
f.setPermissions(f.permissions() | QFileDevice::ExeOwner | QFileDevice::ExeGroup | QFileDevice::ExeOther);
return true;
-#elif defined Q_OS_WIN
- // TODO: Fix
- // QFile file(PathCombine(location, name + ".lnk"));
- // WCHAR *file_w;
- // WCHAR *dest_w;
- // WCHAR *args_w;
- // file.fileName().toWCharArray(file_w);
- // dest.toWCharArray(dest_w);
-
- // QString argStr;
- // for (int i = 0; i < args.count(); i++)
- // {
- // argStr.append(args[i]);
- // argStr.append(" ");
- // }
- // argStr.toWCharArray(args_w);
-
- // return SUCCEEDED(CreateLink(file_w, dest_w, args_w));
- return false;
+#elif defined(Q_OS_WIN)
+ QFileInfo targetInfo(target);
+
+ if (!targetInfo.exists())
+ {
+ qWarning() << "Target file does not exist!";
+ return false;
+ }
+
+ target = targetInfo.absoluteFilePath();
+
+ if (target.length() >= MAX_PATH)
+ {
+ qWarning() << "Target file path is too long!";
+ return false;
+ }
+
+ if (!icon.isEmpty() && icon.length() >= MAX_PATH)
+ {
+ qWarning() << "Icon path is too long!";
+ return false;
+ }
+
+ destination += ".lnk";
+
+ if (destination.length() >= MAX_PATH)
+ {
+ qWarning() << "Destination path is too long!";
+ return false;
+ }
+
+ QString argStr;
+ int argCount = args.count();
+ for (int i = 0; i < argCount; i++)
+ {
+ if (args[i].contains(' '))
+ {
+ argStr.append('"').append(args[i]).append('"');
+ }
+ else
+ {
+ argStr.append(args[i]);
+ }
+
+ if (i < argCount - 1)
+ {
+ argStr.append(" ");
+ }
+ }
+
+ if (argStr.length() >= MAX_PATH)
+ {
+ qWarning() << "Arguments string is too long!";
+ return false;
+ }
+
+ HRESULT hres;
+
+ // ...yes, you need to initialize the entire COM stack just to make a shortcut
+ hres = CoInitialize(nullptr);
+ if (FAILED(hres))
+ {
+ qWarning() << "Failed to initialize COM!";
+ return false;
+ }
+
+ WCHAR wsz[MAX_PATH];
+
+ IShellLink* psl;
+
+ // create an IShellLink instance - this stores the shortcut's attributes
+ hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl);
+ if (SUCCEEDED(hres))
+ {
+ wmemset(wsz, 0, MAX_PATH);
+ target.toWCharArray(wsz);
+ psl->SetPath(wsz);
+
+ wmemset(wsz, 0, MAX_PATH);
+ argStr.toWCharArray(wsz);
+ psl->SetArguments(wsz);
+
+ wmemset(wsz, 0, MAX_PATH);
+ targetInfo.absolutePath().toWCharArray(wsz);
+ psl->SetWorkingDirectory(wsz); // "Starts in" attribute
+
+ if (!icon.isEmpty())
+ {
+ wmemset(wsz, 0, MAX_PATH);
+ icon.toWCharArray(wsz);
+ psl->SetIconLocation(wsz, 0);
+ }
+
+ // query an IPersistFile interface from our IShellLink instance
+ // this is the interface that will actually let us save the shortcut to disk!
+ IPersistFile* ppf;
+ hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf);
+ if (SUCCEEDED(hres))
+ {
+ wmemset(wsz, 0, MAX_PATH);
+ destination.toWCharArray(wsz);
+ hres = ppf->Save(wsz, TRUE);
+ if (FAILED(hres))
+ {
+ qWarning() << "IPresistFile->Save() failed";
+ qWarning() << "hres = " << hres;
+ }
+ ppf->Release();
+ }
+ else
+ {
+ qWarning() << "Failed to query IPersistFile interface from IShellLink instance";
+ qWarning() << "hres = " << hres;
+ }
+ psl->Release();
+ }
+ else
+ {
+ qWarning() << "Failed to create IShellLink instance";
+ qWarning() << "hres = " << hres;
+ }
+
+ // go away COM, nobody likes you
+ CoUninitialize();
+
+ return SUCCEEDED(hres);
#else
qWarning("Desktop Shortcuts not supported on your platform!");
return false;
diff --git a/launcher/FileSystem.h b/launcher/FileSystem.h
index b46f3281..ac893725 100644
--- a/launcher/FileSystem.h
+++ b/launcher/FileSystem.h
@@ -40,6 +40,7 @@
#include <QDir>
#include <QFlags>
+#include <QObject>
namespace FS {
@@ -75,9 +76,11 @@ bool ensureFilePathExists(QString filenamepath);
*/
bool ensureFolderPathExists(QString filenamepath);
-class copy {
+/// @brief Copies a directory and it's contents from src to dest
+class copy : public QObject {
+ Q_OBJECT
public:
- copy(const QString& src, const QString& dst)
+ copy(const QString& src, const QString& dst, QObject* parent = nullptr) : QObject(parent)
{
m_src.setPath(src);
m_dst.setPath(dst);
@@ -87,21 +90,35 @@ class copy {
m_followSymlinks = follow;
return *this;
}
- copy& blacklist(const IPathMatcher* filter)
+ copy& matcher(const IPathMatcher* filter)
{
- m_blacklist = filter;
+ m_matcher = filter;
return *this;
}
- bool operator()() { return operator()(QString()); }
+ copy& whitelist(bool whitelist)
+ {
+ m_whitelist = whitelist;
+ return *this;
+ }
+
+ bool operator()(bool dryRun = false) { return operator()(QString(), dryRun); }
+
+ int totalCopied() { return m_copied; }
+
+ signals:
+ void fileCopied(const QString& relativeName);
+ // TODO: maybe add a "shouldCopy" signal in the future?
private:
- bool operator()(const QString& offset);
+ bool operator()(const QString& offset, bool dryRun = false);
private:
bool m_followSymlinks = true;
- const IPathMatcher* m_blacklist = nullptr;
+ const IPathMatcher* m_matcher = nullptr;
+ bool m_whitelist = false;
QDir m_src;
QDir m_dst;
+ int m_copied;
};
/**
@@ -155,4 +172,9 @@ QString getDesktopDir();
// Overrides one folder with the contents of another, preserving items exclusive to the first folder
// Equivalent to doing QDir::rename, but allowing for overrides
bool overrideFolder(QString overwritten_path, QString override_path);
+
+/**
+ * Creates a shortcut to the specified target file at the specified destination path.
+ */
+bool createShortcut(QString destination, QString target, QStringList args, QString name, QString icon);
}
diff --git a/launcher/InstanceCopyTask.cpp b/launcher/InstanceCopyTask.cpp
index a4ea947d..0a83ed9c 100644
--- a/launcher/InstanceCopyTask.cpp
+++ b/launcher/InstanceCopyTask.cpp
@@ -26,9 +26,11 @@ void InstanceCopyTask::executeTask()
setStatus(tr("Copying instance %1").arg(m_origInstance->name()));
FS::copy folderCopy(m_origInstance->instanceRoot(), m_stagingPath);
- folderCopy.followSymlinks(false).blacklist(m_matcher.get());
+ folderCopy.followSymlinks(false).matcher(m_matcher.get());
- m_copyFuture = QtConcurrent::run(QThreadPool::globalInstance(), folderCopy);
+ m_copyFuture = QtConcurrent::run(QThreadPool::globalInstance(), [&folderCopy]{
+ return folderCopy();
+ });
connect(&m_copyFutureWatcher, &QFutureWatcher<bool>::finished, this, &InstanceCopyTask::copyFinished);
connect(&m_copyFutureWatcher, &QFutureWatcher<bool>::canceled, this, &InstanceCopyTask::copyAborted);
m_copyFutureWatcher.setFuture(m_copyFuture);
diff --git a/launcher/VersionProxyModel.cpp b/launcher/VersionProxyModel.cpp
index 032f21f9..6aba268d 100644
--- a/launcher/VersionProxyModel.cpp
+++ b/launcher/VersionProxyModel.cpp
@@ -311,14 +311,14 @@ QModelIndex VersionProxyModel::index(int row, int column, const QModelIndex &par
int VersionProxyModel::columnCount(const QModelIndex &parent) const
{
- return m_columns.size();
+ return parent.isValid() ? 0 : m_columns.size();
}
int VersionProxyModel::rowCount(const QModelIndex &parent) const
{
if(sourceModel())
{
- return sourceModel()->rowCount();
+ return sourceModel()->rowCount(parent);
}
return 0;
}
diff --git a/launcher/icons/IconList.cpp b/launcher/icons/IconList.cpp
index 3a223d1b..01043ad2 100644
--- a/launcher/icons/IconList.cpp
+++ b/launcher/icons/IconList.cpp
@@ -242,7 +242,7 @@ Qt::DropActions IconList::supportedDropActions() const
return Qt::CopyAction;
}
-bool IconList::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
+bool IconList::dropMimeData(const QMimeData *data, Qt::DropAction action, [[maybe_unused]] int row, [[maybe_unused]] int column, [[maybe_unused]] const QModelIndex &parent)
{
if (action == Qt::IgnoreAction)
return true;
@@ -302,7 +302,7 @@ QVariant IconList::data(const QModelIndex &index, int role) const
int IconList::rowCount(const QModelIndex &parent) const
{
- return icons.size();
+ return parent.isValid() ? 0 : icons.size();
}
void IconList::installIcons(const QStringList &iconFiles)
diff --git a/launcher/main.cpp b/launcher/main.cpp
index df596449..b63f8bfd 100644
--- a/launcher/main.cpp
+++ b/launcher/main.cpp
@@ -81,6 +81,8 @@ int main(int argc, char *argv[])
Q_INIT_RESOURCE(pe_light);
Q_INIT_RESOURCE(pe_blue);
Q_INIT_RESOURCE(pe_colored);
+ Q_INIT_RESOURCE(breeze_dark);
+ Q_INIT_RESOURCE(breeze_light);
Q_INIT_RESOURCE(OSX);
Q_INIT_RESOURCE(iOS);
Q_INIT_RESOURCE(flat);
diff --git a/launcher/meta/Index.cpp b/launcher/meta/Index.cpp
index eec1b329..242aad9f 100644
--- a/launcher/meta/Index.cpp
+++ b/launcher/meta/Index.cpp
@@ -58,11 +58,11 @@ QVariant Index::data(const QModelIndex &index, int role) const
}
int Index::rowCount(const QModelIndex &parent) const
{
- return m_lists.size();
+ return parent.isValid() ? 0 : m_lists.size();
}
int Index::columnCount(const QModelIndex &parent) const
{
- return 1;
+ return parent.isValid() ? 0 : 1;
}
QVariant Index::headerData(int section, Qt::Orientation orientation, int role) const
{
diff --git a/launcher/meta/JsonFormat.h b/launcher/meta/JsonFormat.h
index 93217b7e..63128a4e 100644
--- a/launcher/meta/JsonFormat.h
+++ b/launcher/meta/JsonFormat.h
@@ -60,11 +60,6 @@ struct Require
QString suggests;
};
-inline Q_DECL_PURE_FUNCTION uint qHash(const Require &key, uint seed = 0) Q_DECL_NOTHROW
-{
- return qHash(key.uid, seed);
-}
-
using RequireSet = std::set<Require>;
void parseIndex(const QJsonObject &obj, Index *ptr);
diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp
index de22b365..a3adb268 100644
--- a/launcher/minecraft/MinecraftInstance.cpp
+++ b/launcher/minecraft/MinecraftInstance.cpp
@@ -1,8 +1,9 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
- * PolyMC - Minecraft Launcher
+ * Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
* Copyright (C) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
+ * Copyright (C) 2022 TheKodeToad <TheKodeToad@proton.me>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -436,6 +437,17 @@ QStringList MinecraftInstance::javaArguments()
return args;
}
+QString MinecraftInstance::getLauncher()
+{
+ auto profile = m_components->getProfile();
+
+ // use legacy launcher if the traits are set
+ if (profile->getTraits().contains("legacyLaunch") || profile->getTraits().contains("alphaLaunch"))
+ return "legacy";
+
+ return "standard";
+}
+
QMap<QString, QString> MinecraftInstance::getVariables()
{
QMap<QString, QString> out;
@@ -627,26 +639,13 @@ QString MinecraftInstance::createLaunchScript(AuthSessionPtr session, MinecraftS
launchScript += "sessionId " + session->session + "\n";
}
- // libraries and class path.
- {
- QStringList jars, nativeJars;
- profile->getLibraryFiles(runtimeContext(), jars, nativeJars, getLocalLibraryPath(), binRoot());
- for(auto file: jars)
- {
- launchScript += "cp " + file + "\n";
- }
- for(auto file: nativeJars)
- {
- launchScript += "ext " + file + "\n";
- }
- launchScript += "natives " + getNativePath() + "\n";
- }
-
for (auto trait : profile->getTraits())
{
launchScript += "traits " + trait + "\n";
}
- launchScript += "launcher onesix\n";
+
+ launchScript += "launcher " + getLauncher() + "\n";
+
// qDebug() << "Generated launch script:" << launchScript;
return launchScript;
}
@@ -782,6 +781,8 @@ QStringList MinecraftInstance::verboseDescription(AuthSessionPtr session, Minecr
out << "Window size: " + QString::number(width) + " x " + QString::number(height);
}
out << "";
+ out << "Launcher: " + getLauncher();
+ out << "";
return out;
}
@@ -1109,8 +1110,6 @@ std::shared_ptr<ResourcePackFolderModel> MinecraftInstance::resourcePackList() c
if (!m_resource_pack_list)
{
m_resource_pack_list.reset(new ResourcePackFolderModel(resourcePacksDir()));
- m_resource_pack_list->enableInteraction(!isRunning());
- connect(this, &BaseInstance::runningStatusChanged, m_resource_pack_list.get(), &ResourcePackFolderModel::disableInteraction);
}
return m_resource_pack_list;
}
@@ -1120,8 +1119,6 @@ std::shared_ptr<TexturePackFolderModel> MinecraftInstance::texturePackList() con
if (!m_texture_pack_list)
{
m_texture_pack_list.reset(new TexturePackFolderModel(texturePacksDir()));
- m_texture_pack_list->disableInteraction(isRunning());
- connect(this, &BaseInstance::runningStatusChanged, m_texture_pack_list.get(), &ModFolderModel::disableInteraction);
}
return m_texture_pack_list;
}
@@ -1131,8 +1128,6 @@ std::shared_ptr<ShaderPackFolderModel> MinecraftInstance::shaderPackList() const
if (!m_shader_pack_list)
{
m_shader_pack_list.reset(new ShaderPackFolderModel(shaderPacksDir()));
- m_shader_pack_list->disableInteraction(isRunning());
- connect(this, &BaseInstance::runningStatusChanged, m_shader_pack_list.get(), &ModFolderModel::disableInteraction);
}
return m_shader_pack_list;
}
diff --git a/launcher/minecraft/MinecraftInstance.h b/launcher/minecraft/MinecraftInstance.h
index 1895d187..1bbd7b83 100644
--- a/launcher/minecraft/MinecraftInstance.h
+++ b/launcher/minecraft/MinecraftInstance.h
@@ -1,7 +1,8 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
- * PolyMC - Minecraft Launcher
+ * Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
+ * Copyright (C) 2022 TheKodeToad <TheKodeToad@proton.me>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -130,6 +131,7 @@ public:
QString createLaunchScript(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin);
/// get arguments passed to java
QStringList javaArguments();
+ QString getLauncher();
/// get variables for launch command variable substitution/environment
QMap<QString, QString> getVariables() override;
diff --git a/launcher/minecraft/MojangVersionFormat.cpp b/launcher/minecraft/MojangVersionFormat.cpp
index 9bbb4ada..623dcdfa 100644
--- a/launcher/minecraft/MojangVersionFormat.cpp
+++ b/launcher/minecraft/MojangVersionFormat.cpp
@@ -135,7 +135,7 @@ QJsonObject libDownloadInfoToJson(MojangLibraryDownloadInfo::Ptr libinfo)
{
out.insert("artifact", downloadInfoToJson(libinfo->artifact));
}
- if(libinfo->classifiers.size())
+ if(!libinfo->classifiers.isEmpty())
{
QJsonObject classifiersOut;
for(auto iter = libinfo->classifiers.begin(); iter != libinfo->classifiers.end(); iter++)
@@ -297,7 +297,7 @@ void MojangVersionFormat::writeVersionProperties(const VersionFile* in, QJsonObj
{
out.insert("assetIndex", assetIndexToJson(in->mojangAssetIndex));
}
- if(in->mojangDownloads.size())
+ if(!in->mojangDownloads.isEmpty())
{
QJsonObject downloadsOut;
for(auto iter = in->mojangDownloads.begin(); iter != in->mojangDownloads.end(); iter++)
@@ -306,6 +306,15 @@ void MojangVersionFormat::writeVersionProperties(const VersionFile* in, QJsonObj
}
out.insert("downloads", downloadsOut);
}
+ if(!in->compatibleJavaMajors.isEmpty())
+ {
+ QJsonArray compatibleJavaMajorsOut;
+ for(auto compatibleJavaMajor : in->compatibleJavaMajors)
+ {
+ compatibleJavaMajorsOut.append(compatibleJavaMajor);
+ }
+ out.insert("compatibleJavaMajors", compatibleJavaMajorsOut);
+ }
}
QJsonDocument MojangVersionFormat::versionFileToJson(const VersionFilePtr &patch)
@@ -396,7 +405,7 @@ QJsonObject MojangVersionFormat::libraryToJson(Library *library)
iter++;
}
libRoot.insert("natives", nativeList);
- if (library->m_extractExcludes.size())
+ if (!library->m_extractExcludes.isEmpty())
{
QJsonArray excludes;
QJsonObject extract;
@@ -408,7 +417,7 @@ QJsonObject MojangVersionFormat::libraryToJson(Library *library)
libRoot.insert("extract", extract);
}
}
- if (library->m_rules.size())
+ if (!library->m_rules.isEmpty())
{
QJsonArray allRules;
for (auto &rule : library->m_rules)
diff --git a/launcher/minecraft/OneSixVersionFormat.cpp b/launcher/minecraft/OneSixVersionFormat.cpp
index cec4a55b..280f6b26 100644
--- a/launcher/minecraft/OneSixVersionFormat.cpp
+++ b/launcher/minecraft/OneSixVersionFormat.cpp
@@ -63,13 +63,13 @@ LibraryPtr OneSixVersionFormat::libraryFromJson(ProblemContainer & problems, con
QJsonObject OneSixVersionFormat::libraryToJson(Library *library)
{
QJsonObject libRoot = MojangVersionFormat::libraryToJson(library);
- if (library->m_absoluteURL.size())
+ if (!library->m_absoluteURL.isEmpty())
libRoot.insert("MMC-absoluteUrl", library->m_absoluteURL);
- if (library->m_hint.size())
+ if (!library->m_hint.isEmpty())
libRoot.insert("MMC-hint", library->m_hint);
- if (library->m_filename.size())
+ if (!library->m_filename.isEmpty())
libRoot.insert("MMC-filename", library->m_filename);
- if (library->m_displayname.size())
+ if (!library->m_displayname.isEmpty())
libRoot.insert("MMC-displayname", library->m_displayname);
return libRoot;
}
@@ -225,11 +225,10 @@ VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument &doc
{
QJsonObject agentObj = requireObject(agentVal);
auto lib = libraryFromJson(*out, agentObj, filename);
+
QString arg = "";
- if (agentObj.contains("argument"))
- {
- readString(agentObj, "argument", arg);
- }
+ readString(agentObj, "argument", arg);
+
AgentPtr agent(new Agent(lib, arg));
out->agents.append(agent);
}
@@ -332,6 +331,20 @@ QJsonDocument OneSixVersionFormat::versionFileToJson(const VersionFilePtr &patch
writeString(root, "appletClass", patch->appletClass);
writeStringList(root, "+tweakers", patch->addTweakers);
writeStringList(root, "+traits", patch->traits.values());
+ writeStringList(root, "+jvmArgs", patch->addnJvmArguments);
+ if (!patch->agents.isEmpty())
+ {
+ QJsonArray array;
+ for (auto value: patch->agents)
+ {
+ QJsonObject agentOut = OneSixVersionFormat::libraryToJson(value->library().get());
+ if (!value->argument().isEmpty())
+ agentOut.insert("argument", value->argument());
+
+ array.append(agentOut);
+ }
+ root.insert("+agents", array);
+ }
if (!patch->libraries.isEmpty())
{
QJsonArray array;
diff --git a/launcher/minecraft/PackProfile.cpp b/launcher/minecraft/PackProfile.cpp
index 1618458f..6ce525eb 100644
--- a/launcher/minecraft/PackProfile.cpp
+++ b/launcher/minecraft/PackProfile.cpp
@@ -613,7 +613,7 @@ QVariant PackProfile::data(const QModelIndex &index, int role) const
bool PackProfile::setData(const QModelIndex& index, const QVariant& value, int role)
{
- if (!index.isValid() || index.row() < 0 || index.row() >= rowCount(index))
+ if (!index.isValid() || index.row() < 0 || index.row() >= rowCount(index.parent()))
{
return false;
}
@@ -675,12 +675,12 @@ Qt::ItemFlags PackProfile::flags(const QModelIndex &index) const
int PackProfile::rowCount(const QModelIndex &parent) const
{
- return d->components.size();
+ return parent.isValid() ? 0 : d->components.size();
}
int PackProfile::columnCount(const QModelIndex &parent) const
{
- return NUM_COLUMNS;
+ return parent.isValid() ? 0 : NUM_COLUMNS;
}
void PackProfile::move(const int index, const MoveDirection direction)
diff --git a/launcher/minecraft/Rule.h b/launcher/minecraft/Rule.h
index 236f9a87..846e8e42 100644
--- a/launcher/minecraft/Rule.h
+++ b/launcher/minecraft/Rule.h
@@ -104,7 +104,7 @@ public:
class ImplicitRule : public Rule
{
protected:
- virtual bool applies(const Library *, const RuntimeContext & runtimeContext)
+ virtual bool applies(const Library *, [[maybe_unused]] const RuntimeContext & runtimeContext)
{
return true;
}
diff --git a/launcher/minecraft/WorldList.cpp b/launcher/minecraft/WorldList.cpp
index aee7be35..ae29a972 100644
--- a/launcher/minecraft/WorldList.cpp
+++ b/launcher/minecraft/WorldList.cpp
@@ -173,7 +173,7 @@ bool WorldList::resetIcon(int row)
int WorldList::columnCount(const QModelIndex &parent) const
{
- return 4;
+ return parent.isValid()? 0 : 4;
}
QVariant WorldList::data(const QModelIndex &index, int role) const
@@ -398,8 +398,8 @@ void WorldList::installWorld(QFileInfo filename)
w.install(m_dir.absolutePath());
}
-bool WorldList::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
- const QModelIndex &parent)
+bool WorldList::dropMimeData(const QMimeData *data, Qt::DropAction action, [[maybe_unused]] int row, [[maybe_unused]] int column,
+ [[maybe_unused]] const QModelIndex &parent)
{
if (action == Qt::IgnoreAction)
return true;
diff --git a/launcher/minecraft/WorldList.h b/launcher/minecraft/WorldList.h
index 5138e583..08294755 100644
--- a/launcher/minecraft/WorldList.h
+++ b/launcher/minecraft/WorldList.h
@@ -54,7 +54,7 @@ public:
virtual int rowCount(const QModelIndex &parent = QModelIndex()) const
{
- return size();
+ return parent.isValid() ? 0 : static_cast<int>(size());
};
virtual QVariant headerData(int section, Qt::Orientation orientation,
int role = Qt::DisplayRole) const;
diff --git a/launcher/minecraft/auth/AccountList.cpp b/launcher/minecraft/auth/AccountList.cpp
index b3b57c74..9e2fd111 100644
--- a/launcher/minecraft/auth/AccountList.cpp
+++ b/launcher/minecraft/auth/AccountList.cpp
@@ -408,20 +408,20 @@ QVariant AccountList::headerData(int section, Qt::Orientation orientation, int r
}
}
-int AccountList::rowCount(const QModelIndex &) const
+int AccountList::rowCount(const QModelIndex &parent) const
{
// Return count
- return count();
+ return parent.isValid() ? 0 : count();
}
-int AccountList::columnCount(const QModelIndex &) const
+int AccountList::columnCount(const QModelIndex &parent) const
{
- return NUM_COLUMNS;
+ return parent.isValid() ? 0 : NUM_COLUMNS;
}
Qt::ItemFlags AccountList::flags(const QModelIndex &index) const
{
- if (index.row() < 0 || index.row() >= rowCount(index) || !index.isValid())
+ if (index.row() < 0 || index.row() >= rowCount(index.parent()) || !index.isValid())
{
return Qt::NoItemFlags;
}
diff --git a/launcher/minecraft/mod/ModFolderModel.cpp b/launcher/minecraft/mod/ModFolderModel.cpp
index 66e80f4a..4ccc5d4d 100644
--- a/launcher/minecraft/mod/ModFolderModel.cpp
+++ b/launcher/minecraft/mod/ModFolderModel.cpp
@@ -144,7 +144,7 @@ QVariant ModFolderModel::headerData(int section, Qt::Orientation orientation, in
int ModFolderModel::columnCount(const QModelIndex &parent) const
{
- return NUM_COLUMNS;
+ return parent.isValid() ? 0 : NUM_COLUMNS;
}
Task* ModFolderModel::createUpdateTask()
diff --git a/launcher/minecraft/mod/ResourceFolderModel.cpp b/launcher/minecraft/mod/ResourceFolderModel.cpp
index b2356309..0310c8f6 100644
--- a/launcher/minecraft/mod/ResourceFolderModel.cpp
+++ b/launcher/minecraft/mod/ResourceFolderModel.cpp
@@ -426,7 +426,7 @@ QVariant ResourceFolderModel::data(const QModelIndex& index, int role) const
bool ResourceFolderModel::setData(const QModelIndex& index, const QVariant& value, int role)
{
int row = index.row();
- if (row < 0 || row >= rowCount(index) || !index.isValid())
+ if (row < 0 || row >= rowCount(index.parent()) || !index.isValid())
return false;
if (role == Qt::CheckStateRole)
diff --git a/launcher/minecraft/mod/ResourceFolderModel.h b/launcher/minecraft/mod/ResourceFolderModel.h
index 25095a45..fe283b04 100644
--- a/launcher/minecraft/mod/ResourceFolderModel.h
+++ b/launcher/minecraft/mod/ResourceFolderModel.h
@@ -90,8 +90,8 @@ class ResourceFolderModel : public QAbstractListModel {
/* Basic columns */
enum Columns { ACTIVE_COLUMN = 0, NAME_COLUMN, DATE_COLUMN, NUM_COLUMNS };
- [[nodiscard]] int rowCount(const QModelIndex& = {}) const override { return size(); }
- [[nodiscard]] int columnCount(const QModelIndex& = {}) const override { return NUM_COLUMNS; };
+ [[nodiscard]] int rowCount(const QModelIndex& parent = {}) const override { return parent.isValid() ? 0 : static_cast<int>(size()); }
+ [[nodiscard]] int columnCount(const QModelIndex& parent = {}) const override { return parent.isValid() ? 0 : NUM_COLUMNS; };
[[nodiscard]] Qt::DropActions supportedDropActions() const override;
@@ -176,7 +176,7 @@ class ResourceFolderModel : public QAbstractListModel {
* if the resource is complex and has more stuff to parse.
*/
virtual void onParseSucceeded(int ticket, QString resource_id);
- virtual void onParseFailed(int ticket, QString resource_id) {}
+ virtual void onParseFailed(int ticket, QString resource_id) { Q_UNUSED(ticket); Q_UNUSED(resource_id); }
protected:
// Represents the relationship between a column's index (represented by the list index), and it's sorting key.
diff --git a/launcher/minecraft/mod/ResourcePackFolderModel.cpp b/launcher/minecraft/mod/ResourcePackFolderModel.cpp
index f8a6c1cf..ebac707d 100644
--- a/launcher/minecraft/mod/ResourcePackFolderModel.cpp
+++ b/launcher/minecraft/mod/ResourcePackFolderModel.cpp
@@ -137,7 +137,7 @@ QVariant ResourcePackFolderModel::headerData(int section, Qt::Orientation orient
int ResourcePackFolderModel::columnCount(const QModelIndex& parent) const
{
- return NUM_COLUMNS;
+ return parent.isValid() ? 0 : NUM_COLUMNS;
}
Task* ResourcePackFolderModel::createUpdateTask()
diff --git a/launcher/minecraft/mod/tasks/LocalModParseTask.cpp b/launcher/minecraft/mod/tasks/LocalModParseTask.cpp
index a694e7b2..774f6114 100644
--- a/launcher/minecraft/mod/tasks/LocalModParseTask.cpp
+++ b/launcher/minecraft/mod/tasks/LocalModParseTask.cpp
@@ -121,7 +121,7 @@ ModDetails ReadMCModTOML(QByteArray contents)
return {};
}
auto modsTable = tomlModsTable0->as_table();
- if (!tomlModsTable0) {
+ if (!modsTable) {
qWarning() << "Corrupted mods.toml? [[mods]] was not a table!";
return {};
}
diff --git a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp
index 48ac02e0..91554b58 100644
--- a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp
+++ b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp
@@ -372,13 +372,20 @@ void FlameCreationTask::idResolverSucceeded(QEventLoop& loop)
auto results = m_mod_id_resolver->getResults();
// first check for blocked mods
- QString text;
- QList<QUrl> urls;
+ QList<BlockedMod> blocked_mods;
auto anyBlocked = false;
for (const auto& result : results.files.values()) {
if (!result.resolved || result.url.isEmpty()) {
- text += QString("%1: <a href='%2'>%2</a><br/>").arg(result.fileName, result.websiteUrl);
- urls.append(QUrl(result.websiteUrl));
+
+ BlockedMod blocked_mod;
+ blocked_mod.name = result.fileName;
+ blocked_mod.websiteUrl = result.websiteUrl;
+ blocked_mod.hash = result.hash;
+ blocked_mod.matched = false;
+ blocked_mod.localPath = "";
+
+ blocked_mods.append(blocked_mod);
+
anyBlocked = true;
}
}
@@ -386,13 +393,15 @@ void FlameCreationTask::idResolverSucceeded(QEventLoop& loop)
qWarning() << "Blocked mods found, displaying mod list";
auto message_dialog = new BlockedModsDialog(m_parent, tr("Blocked mods found"),
- tr("The following mods were blocked on third party launchers.<br/>"
- "You will need to manually download them and add them to the modpack"),
- text,
- urls);
+ tr("The following files are not available for download in third party launchers.<br/>"
+ "You will need to manually download them and add them to the instance."),
+ blocked_mods);
+
message_dialog->setModal(true);
if (message_dialog->exec()) {
+ qDebug() << "Post dialog blocked mods list: " << blocked_mods;
+ copyBlockedMods(blocked_mods);
setupDownloadJob(loop);
} else {
m_mod_id_resolver.reset();
@@ -404,6 +413,38 @@ void FlameCreationTask::idResolverSucceeded(QEventLoop& loop)
}
}
+/// @brief copy the matched blocked mods to the instance staging area
+/// @param blocked_mods list of the blocked mods and their matched paths
+void FlameCreationTask::copyBlockedMods(QList<BlockedMod> const& blocked_mods)
+{
+ setStatus(tr("Copying Blocked Mods..."));
+ setAbortable(false);
+ int i = 0;
+ int total = blocked_mods.length();
+ setProgress(i, total);
+ for (auto const& mod : blocked_mods) {
+ if (!mod.matched) {
+ qDebug() << mod.name << "was not matched to a local file, skipping copy";
+ continue;
+ }
+
+ auto dest_path = FS::PathCombine(m_stagingPath, "minecraft", "mods", mod.name);
+
+ setStatus(tr("Copying Blocked Mods (%1 out of %2 are done)").arg(QString::number(i), QString::number(total)));
+
+ qDebug() << "Will try to copy" << mod.localPath << "to" << dest_path;
+
+ if (!FS::copy(mod.localPath, dest_path)()) {
+ qDebug() << "Copy of" << mod.localPath << "to" << dest_path << "Failed";
+ }
+
+ i++;
+ setProgress(i, total);
+ }
+
+ setAbortable(true);
+}
+
void FlameCreationTask::setupDownloadJob(QEventLoop& loop)
{
m_files_job = new NetJob(tr("Mod download"), APPLICATION->network());
@@ -449,7 +490,7 @@ void FlameCreationTask::setupDownloadJob(QEventLoop& loop)
m_files_job.reset();
setError(reason);
});
- connect(m_files_job.get(), &NetJob::progress, [&](qint64 current, qint64 total) { setProgress(current, total); });
+ connect(m_files_job.get(), &NetJob::progress, this, &FlameCreationTask::setProgress);
connect(m_files_job.get(), &NetJob::finished, &loop, &QEventLoop::quit);
setStatus(tr("Downloading mods..."));
diff --git a/launcher/modplatform/flame/FlameInstanceCreationTask.h b/launcher/modplatform/flame/FlameInstanceCreationTask.h
index ded0e2ce..fbc7d5bf 100644
--- a/launcher/modplatform/flame/FlameInstanceCreationTask.h
+++ b/launcher/modplatform/flame/FlameInstanceCreationTask.h
@@ -10,6 +10,8 @@
#include "net/NetJob.h"
+#include "ui/dialogs/BlockedModsDialog.h"
+
class FlameCreationTask final : public InstanceCreationTask {
Q_OBJECT
@@ -29,6 +31,7 @@ class FlameCreationTask final : public InstanceCreationTask {
private slots:
void idResolverSucceeded(QEventLoop&);
void setupDownloadJob(QEventLoop&);
+ void copyBlockedMods(QList<BlockedMod> const& blocked_mods);
private:
QWidget* m_parent = nullptr;
diff --git a/launcher/modplatform/helpers/HashUtils.cpp b/launcher/modplatform/helpers/HashUtils.cpp
index b18c87af..f1e4759e 100644
--- a/launcher/modplatform/helpers/HashUtils.cpp
+++ b/launcher/modplatform/helpers/HashUtils.cpp
@@ -36,6 +36,18 @@ Hasher::Ptr createFlameHasher(QString file_path)
return new FlameHasher(file_path);
}
+Hasher::Ptr createBlockedModHasher(QString file_path, ModPlatform::Provider provider)
+{
+ return new BlockedModHasher(file_path, provider);
+}
+
+Hasher::Ptr createBlockedModHasher(QString file_path, ModPlatform::Provider provider, QString type)
+{
+ auto hasher = new BlockedModHasher(file_path, provider);
+ hasher->useHashType(type);
+ return hasher;
+}
+
void ModrinthHasher::executeTask()
{
QFile file(m_path);
@@ -79,4 +91,50 @@ void FlameHasher::executeTask()
}
}
+
+BlockedModHasher::BlockedModHasher(QString file_path, ModPlatform::Provider provider)
+ : Hasher(file_path), provider(provider) {
+ setObjectName(QString("BlockedModHasher: %1").arg(file_path));
+ hash_type = ProviderCaps.hashType(provider).first();
+}
+
+void BlockedModHasher::executeTask()
+{
+ QFile file(m_path);
+
+ try {
+ file.open(QFile::ReadOnly);
+ } catch (FS::FileSystemException& e) {
+ qCritical() << QString("Failed to open JAR file in %1").arg(m_path);
+ qCritical() << QString("Reason: ") << e.cause();
+
+ emitFailed("Failed to open file for hashing.");
+ return;
+ }
+
+ m_hash = ProviderCaps.hash(provider, &file, hash_type);
+
+ file.close();
+
+ if (m_hash.isEmpty()) {
+ emitFailed("Empty hash!");
+ } else {
+ emitSucceeded();
+ }
+}
+
+QStringList BlockedModHasher::getHashTypes() {
+ return ProviderCaps.hashType(provider);
+}
+
+bool BlockedModHasher::useHashType(QString type) {
+ auto types = ProviderCaps.hashType(provider);
+ if (types.contains(type)) {
+ hash_type = type;
+ return true;
+ }
+ qDebug() << "Bad hash type " << type << " for provider";
+ return false;
+}
+
} // namespace Hashing
diff --git a/launcher/modplatform/helpers/HashUtils.h b/launcher/modplatform/helpers/HashUtils.h
index 38fddf03..fa3244f6 100644
--- a/launcher/modplatform/helpers/HashUtils.h
+++ b/launcher/modplatform/helpers/HashUtils.h
@@ -40,8 +40,23 @@ class ModrinthHasher : public Hasher {
void executeTask() override;
};
+class BlockedModHasher : public Hasher {
+ public:
+ BlockedModHasher(QString file_path, ModPlatform::Provider provider);
+
+ void executeTask() override;
+
+ QStringList getHashTypes();
+ bool useHashType(QString type);
+ private:
+ ModPlatform::Provider provider;
+ QString hash_type;
+};
+
Hasher::Ptr createHasher(QString file_path, ModPlatform::Provider provider);
Hasher::Ptr createFlameHasher(QString file_path);
Hasher::Ptr createModrinthHasher(QString file_path);
+Hasher::Ptr createBlockedModHasher(QString file_path, ModPlatform::Provider provider);
+Hasher::Ptr createBlockedModHasher(QString file_path, ModPlatform::Provider provider, QString type);
} // namespace Hashing
diff --git a/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp b/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp
index 7b112d8f..4c7b7a4f 100644
--- a/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp
+++ b/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp
@@ -176,8 +176,6 @@ void PackInstallTask::resolveMods()
void PackInstallTask::onResolveModsSucceeded()
{
- QString text;
- QList<QUrl> urls;
auto anyBlocked = false;
Flame::Manifest results = m_mod_id_resolver_task->getResults();
@@ -191,11 +189,16 @@ void PackInstallTask::onResolveModsSucceeded()
// First check for blocked mods
if (!results_file.resolved || results_file.url.isEmpty()) {
- QString type(local_file.type);
- type[0] = type[0].toUpper();
- text += QString("%1: %2 - <a href='%3'>%3</a><br/>").arg(type, local_file.name, results_file.websiteUrl);
- urls.append(QUrl(results_file.websiteUrl));
+ BlockedMod blocked_mod;
+ blocked_mod.name = local_file.name;
+ blocked_mod.websiteUrl = results_file.websiteUrl;
+ blocked_mod.hash = results_file.hash;
+ blocked_mod.matched = false;
+ blocked_mod.localPath = "";
+
+ m_blocked_mods.append(blocked_mod);
+
anyBlocked = true;
} else {
local_file.url = results_file.url.toString();
@@ -208,15 +211,17 @@ void PackInstallTask::onResolveModsSucceeded()
qDebug() << "Blocked files found, displaying file list";
auto message_dialog = new BlockedModsDialog(m_parent, tr("Blocked files found"),
- tr("The following files are not available for download in third party launchers.<br/>"
- "You will need to manually download them and add them to the instance."),
- text,
- urls);
+ tr("The following files are not available for download in third party launchers.<br/>"
+ "You will need to manually download them and add them to the instance."),
+ m_blocked_mods);
- if (message_dialog->exec() == QDialog::Accepted)
+ if (message_dialog->exec() == QDialog::Accepted) {
+ qDebug() << "Post dialog blocked mods list: " << m_blocked_mods;
createInstance();
- else
+ } else {
abort();
+ }
+
} else {
createInstance();
}
@@ -320,6 +325,9 @@ void PackInstallTask::downloadPack()
void PackInstallTask::onModDownloadSucceeded()
{
m_net_job.reset();
+ if (!m_blocked_mods.isEmpty()) {
+ copyBlockedMods();
+ }
emitSucceeded();
}
@@ -343,4 +351,35 @@ void PackInstallTask::onModDownloadFailed(QString reason)
emitFailed(reason);
}
+/// @brief copy the matched blocked mods to the instance staging area
+void PackInstallTask::copyBlockedMods()
+{
+ setStatus(tr("Copying Blocked Mods..."));
+ setAbortable(false);
+ int i = 0;
+ int total = m_blocked_mods.length();
+ setProgress(i, total);
+ for (auto const& mod : m_blocked_mods) {
+ if (!mod.matched) {
+ qDebug() << mod.name << "was not matched to a local file, skipping copy";
+ continue;
+ }
+
+ auto dest_path = FS::PathCombine(m_stagingPath, ".minecraft", "mods", mod.name);
+
+ setStatus(tr("Copying Blocked Mods (%1 out of %2 are done)").arg(QString::number(i), QString::number(total)));
+
+ qDebug() << "Will try to copy" << mod.localPath << "to" << dest_path;
+
+ if (!FS::copy(mod.localPath, dest_path)()) {
+ qDebug() << "Copy of" << mod.localPath << "to" << dest_path << "Failed";
+ }
+
+ i++;
+ setProgress(i, total);
+ }
+
+ setAbortable(true);
+}
+
} // namespace ModpacksCH
diff --git a/launcher/modplatform/modpacksch/FTBPackInstallTask.h b/launcher/modplatform/modpacksch/FTBPackInstallTask.h
index 7c6fbeb9..2cd4d729 100644
--- a/launcher/modplatform/modpacksch/FTBPackInstallTask.h
+++ b/launcher/modplatform/modpacksch/FTBPackInstallTask.h
@@ -43,6 +43,7 @@
#include "QObjectPtr.h"
#include "modplatform/flame/FileResolvingTask.h"
#include "net/NetJob.h"
+#include "ui/dialogs/BlockedModsDialog.h"
#include <QWidget>
@@ -76,6 +77,7 @@ private:
void resolveMods();
void createInstance();
void downloadPack();
+ void copyBlockedMods();
private:
NetJob::Ptr m_net_job = nullptr;
@@ -90,6 +92,7 @@ private:
Version m_version;
QMap<QString, QString> m_files_to_copy;
+ QList<BlockedMod> m_blocked_mods;
//FIXME: nuke
QWidget* m_parent;
diff --git a/launcher/net/HttpMetaCache.cpp b/launcher/net/HttpMetaCache.cpp
index e242dcf4..0d7ca769 100644
--- a/launcher/net/HttpMetaCache.cpp
+++ b/launcher/net/HttpMetaCache.cpp
@@ -47,7 +47,7 @@
auto MetaEntry::getFullPath() -> QString
{
// FIXME: make local?
- return FS::PathCombine(basePath, relativePath);
+ return FS::PathCombine(m_basePath, m_relativePath);
}
HttpMetaCache::HttpMetaCache(QString path) : QObject(), m_index_file(path)
@@ -99,7 +99,7 @@ auto HttpMetaCache::resolveEntry(QString base, QString resource_path, QString ex
return staleEntry(base, resource_path);
}
- if (!expected_etag.isEmpty() && expected_etag != entry->etag) {
+ if (!expected_etag.isEmpty() && expected_etag != entry->m_etag) {
// if the etag doesn't match expected, we disown the entry
selected_base.entry_list.remove(resource_path);
return staleEntry(base, resource_path);
@@ -107,17 +107,17 @@ auto HttpMetaCache::resolveEntry(QString base, QString resource_path, QString ex
// if the file changed, check md5sum
qint64 file_last_changed = finfo.lastModified().toUTC().toMSecsSinceEpoch();
- if (file_last_changed != entry->local_changed_timestamp) {
+ if (file_last_changed != entry->m_local_changed_timestamp) {
QFile input(real_path);
input.open(QIODevice::ReadOnly);
QString md5sum = QCryptographicHash::hash(input.readAll(), QCryptographicHash::Md5).toHex().constData();
- if (entry->md5sum != md5sum) {
+ if (entry->m_md5sum != md5sum) {
selected_base.entry_list.remove(resource_path);
return staleEntry(base, resource_path);
}
// md5sums matched... keep entry and save the new state to file
- entry->local_changed_timestamp = file_last_changed;
+ entry->m_local_changed_timestamp = file_last_changed;
SaveEventually();
}
@@ -130,23 +130,23 @@ auto HttpMetaCache::resolveEntry(QString base, QString resource_path, QString ex
}
// entry passed all the checks we cared about.
- entry->basePath = getBasePath(base);
+ entry->m_basePath = getBasePath(base);
return entry;
}
auto HttpMetaCache::updateEntry(MetaEntryPtr stale_entry) -> bool
{
- if (!m_entries.contains(stale_entry->baseId)) {
- qCritical() << "Cannot add entry with unknown base: " << stale_entry->baseId.toLocal8Bit();
+ if (!m_entries.contains(stale_entry->m_baseId)) {
+ qCritical() << "Cannot add entry with unknown base: " << stale_entry->m_baseId.toLocal8Bit();
return false;
}
- if (stale_entry->stale) {
+ if (stale_entry->m_stale) {
qCritical() << "Cannot add stale entry: " << stale_entry->getFullPath().toLocal8Bit();
return false;
}
- m_entries[stale_entry->baseId].entry_list[stale_entry->relativePath] = stale_entry;
+ m_entries[stale_entry->m_baseId].entry_list[stale_entry->m_relativePath] = stale_entry;
SaveEventually();
return true;
@@ -157,7 +157,7 @@ auto HttpMetaCache::evictEntry(MetaEntryPtr entry) -> bool
if (!entry)
return false;
- entry->stale = true;
+ entry->m_stale = true;
SaveEventually();
return true;
}
@@ -169,7 +169,7 @@ void HttpMetaCache::evictAll()
qDebug() << "Evicting base" << base;
for (MetaEntryPtr entry : map.entry_list) {
if (!evictEntry(entry))
- qWarning() << "Unexpected missing cache entry" << entry->basePath;
+ qWarning() << "Unexpected missing cache entry" << entry->m_basePath;
}
}
}
@@ -177,10 +177,10 @@ void HttpMetaCache::evictAll()
auto HttpMetaCache::staleEntry(QString base, QString resource_path) -> MetaEntryPtr
{
auto foo = new MetaEntry();
- foo->baseId = base;
- foo->basePath = getBasePath(base);
- foo->relativePath = resource_path;
- foo->stale = true;
+ foo->m_baseId = base;
+ foo->m_basePath = getBasePath(base);
+ foo->m_relativePath = resource_path;
+ foo->m_stale = true;
return MetaEntryPtr(foo);
}
@@ -235,23 +235,23 @@ void HttpMetaCache::Load()
auto& entrymap = m_entries[base];
auto foo = new MetaEntry();
- foo->baseId = base;
- foo->relativePath = Json::ensureString(element_obj, "path");
- foo->md5sum = Json::ensureString(element_obj, "md5sum");
- foo->etag = Json::ensureString(element_obj, "etag");
- foo->local_changed_timestamp = Json::ensureDouble(element_obj, "last_changed_timestamp");
- foo->remote_changed_timestamp = Json::ensureString(element_obj, "remote_changed_timestamp");
+ foo->m_baseId = base;
+ foo->m_relativePath = Json::ensureString(element_obj, "path");
+ foo->m_md5sum = Json::ensureString(element_obj, "md5sum");
+ foo->m_etag = Json::ensureString(element_obj, "etag");
+ foo->m_local_changed_timestamp = Json::ensureDouble(element_obj, "last_changed_timestamp");
+ foo->m_remote_changed_timestamp = Json::ensureString(element_obj, "remote_changed_timestamp");
foo->makeEternal(Json::ensureBoolean(element_obj, (const QString)QStringLiteral("eternal"), false));
if (!foo->isEternal()) {
- foo->current_age = Json::ensureDouble(element_obj, "current_age");
- foo->max_age = Json::ensureDouble(element_obj, "max_age");
+ foo->m_current_age = Json::ensureDouble(element_obj, "current_age");
+ foo->m_max_age = Json::ensureDouble(element_obj, "max_age");
}
// presumed innocent until closer examination
- foo->stale = false;
+ foo->m_stale = false;
- entrymap.entry_list[foo->relativePath] = MetaEntryPtr(foo);
+ entrymap.entry_list[foo->m_relativePath] = MetaEntryPtr(foo);
}
}
@@ -276,23 +276,23 @@ void HttpMetaCache::SaveNow()
for (auto group : m_entries) {
for (auto entry : group.entry_list) {
// do not save stale entries. they are dead.
- if (entry->stale) {
+ if (entry->m_stale) {
continue;
}
QJsonObject entryObj;
- Json::writeString(entryObj, "base", entry->baseId);
- Json::writeString(entryObj, "path", entry->relativePath);
- Json::writeString(entryObj, "md5sum", entry->md5sum);
- Json::writeString(entryObj, "etag", entry->etag);
- entryObj.insert("last_changed_timestamp", QJsonValue(double(entry->local_changed_timestamp)));
- if (!entry->remote_changed_timestamp.isEmpty())
- entryObj.insert("remote_changed_timestamp", QJsonValue(entry->remote_changed_timestamp));
+ Json::writeString(entryObj, "base", entry->m_baseId);
+ Json::writeString(entryObj, "path", entry->m_relativePath);
+ Json::writeString(entryObj, "md5sum", entry->m_md5sum);
+ Json::writeString(entryObj, "etag", entry->m_etag);
+ entryObj.insert("last_changed_timestamp", QJsonValue(double(entry->m_local_changed_timestamp)));
+ if (!entry->m_remote_changed_timestamp.isEmpty())
+ entryObj.insert("remote_changed_timestamp", QJsonValue(entry->m_remote_changed_timestamp));
if (entry->isEternal()) {
entryObj.insert("eternal", true);
} else {
- entryObj.insert("current_age", QJsonValue(double(entry->current_age)));
- entryObj.insert("max_age", QJsonValue(double(entry->max_age)));
+ entryObj.insert("current_age", QJsonValue(double(entry->m_current_age)));
+ entryObj.insert("max_age", QJsonValue(double(entry->m_max_age)));
}
entriesArr.append(entryObj);
}
diff --git a/launcher/net/HttpMetaCache.h b/launcher/net/HttpMetaCache.h
index 2a07d65a..37f4b49a 100644
--- a/launcher/net/HttpMetaCache.h
+++ b/launcher/net/HttpMetaCache.h
@@ -49,47 +49,47 @@ class MetaEntry {
MetaEntry() = default;
public:
- auto isStale() -> bool { return stale; }
- void setStale(bool stale) { this->stale = stale; }
+ auto isStale() -> bool { return m_stale; }
+ void setStale(bool stale) { m_stale = stale; }
auto getFullPath() -> QString;
- auto getRemoteChangedTimestamp() -> QString { return remote_changed_timestamp; }
- void setRemoteChangedTimestamp(QString remote_changed_timestamp) { this->remote_changed_timestamp = remote_changed_timestamp; }
- void setLocalChangedTimestamp(qint64 timestamp) { local_changed_timestamp = timestamp; }
+ auto getRemoteChangedTimestamp() -> QString { return m_remote_changed_timestamp; }
+ void setRemoteChangedTimestamp(QString remote_changed_timestamp) { m_remote_changed_timestamp = remote_changed_timestamp; }
+ void setLocalChangedTimestamp(qint64 timestamp) { m_local_changed_timestamp = timestamp; }
- auto getETag() -> QString { return etag; }
- void setETag(QString etag) { this->etag = etag; }
+ auto getETag() -> QString { return m_etag; }
+ void setETag(QString etag) { m_etag = etag; }
- auto getMD5Sum() -> QString { return md5sum; }
- void setMD5Sum(QString md5sum) { this->md5sum = md5sum; }
+ auto getMD5Sum() -> QString { return m_md5sum; }
+ void setMD5Sum(QString md5sum) { m_md5sum = md5sum; }
/* Whether the entry expires after some time (false) or not (true). */
- void makeEternal(bool eternal) { is_eternal = eternal; }
- [[nodiscard]] bool isEternal() const { return is_eternal; }
+ void makeEternal(bool eternal) { m_is_eternal = eternal; }
+ [[nodiscard]] bool isEternal() const { return m_is_eternal; }
- auto getCurrentAge() -> qint64 { return current_age; }
- void setCurrentAge(qint64 age) { current_age = age; }
+ auto getCurrentAge() -> qint64 { return m_current_age; }
+ void setCurrentAge(qint64 age) { m_current_age = age; }
- auto getMaximumAge() -> qint64 { return max_age; }
- void setMaximumAge(qint64 age) { max_age = age; }
+ auto getMaximumAge() -> qint64 { return m_max_age; }
+ void setMaximumAge(qint64 age) { m_max_age = age; }
- bool isExpired(qint64 offset) { return !is_eternal && (current_age >= max_age - offset); };
+ bool isExpired(qint64 offset) { return !m_is_eternal && (m_current_age >= m_max_age - offset); };
protected:
- QString baseId;
- QString basePath;
- QString relativePath;
- QString md5sum;
- QString etag;
-
- qint64 local_changed_timestamp = 0;
- QString remote_changed_timestamp; // QString for now, RFC 2822 encoded time
- qint64 current_age = 0;
- qint64 max_age = 0;
- bool is_eternal = false;
-
- bool stale = true;
+ QString m_baseId;
+ QString m_basePath;
+ QString m_relativePath;
+ QString m_md5sum;
+ QString m_etag;
+
+ qint64 m_local_changed_timestamp = 0;
+ QString m_remote_changed_timestamp; // QString for now, RFC 2822 encoded time
+ qint64 m_current_age = 0;
+ qint64 m_max_age = 0;
+ bool m_is_eternal = false;
+
+ bool m_stale = true;
};
using MetaEntryPtr = std::shared_ptr<MetaEntry>;
diff --git a/launcher/pathmatcher/SimplePrefixMatcher.h b/launcher/pathmatcher/SimplePrefixMatcher.h
new file mode 100644
index 00000000..fc1f5ced
--- /dev/null
+++ b/launcher/pathmatcher/SimplePrefixMatcher.h
@@ -0,0 +1,25 @@
+// SPDX-FileCopyrightText: 2022 Sefa Eyeoglu <contact@scrumplex.net>
+//
+// SPDX-License-Identifier: GPL-3.0-only
+
+#include <QRegularExpression>
+#include "IPathMatcher.h"
+
+class SimplePrefixMatcher : public IPathMatcher {
+ public:
+ virtual ~SimplePrefixMatcher(){};
+ SimplePrefixMatcher(const QString& prefix)
+ {
+ m_prefix = prefix;
+ m_isPrefix = prefix.endsWith('/');
+ }
+
+ virtual bool matches(const QString& string) const override
+ {
+ if (m_isPrefix)
+ return string.startsWith(m_prefix);
+ return string == m_prefix;
+ }
+ QString m_prefix;
+ bool m_isPrefix = false;
+};
diff --git a/launcher/resources/OSX/OSX.qrc b/launcher/resources/OSX/OSX.qrc
index 19fe312b..9d4511d1 100644
--- a/launcher/resources/OSX/OSX.qrc
+++ b/launcher/resources/OSX/OSX.qrc
@@ -39,5 +39,6 @@
<file>scalable/export.svg</file>
<file>scalable/rename.svg</file>
<file>scalable/launch.svg</file>
+ <file>scalable/shortcut.svg</file>
</qresource>
</RCC>
diff --git a/launcher/resources/OSX/scalable/shortcut.svg b/launcher/resources/OSX/scalable/shortcut.svg
new file mode 100644
index 00000000..a2b7488e
--- /dev/null
+++ b/launcher/resources/OSX/scalable/shortcut.svg
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 18.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Calque_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
+<rect fill="none" width="24" height="24"/>
+<g id="_x35__1_">
+ <g>
+ <path fill="#585858" d="M9.5,9.5C9.8,9.5,10,9.2,10,9l0-2.4l7.6,7.3c0.2,0.2,0.5,0.2,0.7,0c0.2-0.2,0.2-0.5,0-0.7L10.8,6L13,6
+ c0.3,0,0.5-0.2,0.5-0.5S13.3,5,13,5H9.5C9.2,5,9,5.2,9,5.5V9C9,9.2,9.2,9.5,9.5,9.5z M21,5h-5.5v1H21c0.5,0,1,0.5,1,1l0,10
+ c0,0.5-0.4,1-1,1l-10,0c-0.5,0-1-0.5-1-1v-5.5H9V17c0,1.1,1.1,2,2.2,2H21c1.1,0,2-0.9,2-2V7.2C23,6.1,22.1,5,21,5z"/>
+ </g>
+</g>
+</svg>
diff --git a/launcher/resources/breeze_dark/breeze_dark.qrc b/launcher/resources/breeze_dark/breeze_dark.qrc
new file mode 100644
index 00000000..97434abc
--- /dev/null
+++ b/launcher/resources/breeze_dark/breeze_dark.qrc
@@ -0,0 +1,44 @@
+<RCC>
+ <qresource prefix="/icons/breeze_dark">
+ <file>index.theme</file>
+ <file>scalable/about.svg</file>
+ <file>scalable/accounts.svg</file>
+ <file>scalable/bug.svg</file>
+ <file>scalable/centralmods.svg</file>
+ <file>scalable/checkupdate.svg</file>
+ <file>scalable/copy.svg</file>
+ <file>scalable/coremods.svg</file>
+ <file>scalable/custom-commands.svg</file>
+ <file>scalable/discord.svg</file>
+ <file>scalable/externaltools.svg</file>
+ <file>scalable/help.svg</file>
+ <file>scalable/instance-settings.svg</file>
+ <file>scalable/jarmods.svg</file>
+ <file>scalable/java.svg</file>
+ <file>scalable/language.svg</file>
+ <file>scalable/loadermods.svg</file>
+ <file>scalable/log.svg</file>
+ <file>scalable/minecraft.svg</file>
+ <file>scalable/new.svg</file>
+ <file>scalable/news.svg</file>
+ <file>scalable/notes.svg</file>
+ <file>scalable/proxy.svg</file>
+ <file>scalable/reddit-alien.svg</file>
+ <file>scalable/refresh.svg</file>
+ <file>scalable/resourcepacks.svg</file>
+ <file>scalable/shaderpacks.svg</file>
+ <file>scalable/shortcut.svg</file>
+ <file>scalable/screenshots.svg</file>
+ <file>scalable/settings.svg</file>
+ <file>scalable/status-bad.svg</file>
+ <file>scalable/status-good.svg</file>
+ <file>scalable/status-yellow.svg</file>
+ <file>scalable/viewfolder.svg</file>
+ <file>scalable/worlds.svg</file>
+ <file>scalable/delete.svg</file>
+ <file>scalable/tag.svg</file>
+ <file>scalable/export.svg</file>
+ <file>scalable/rename.svg</file>
+ <file>scalable/launch.svg</file>
+ </qresource>
+</RCC>
diff --git a/launcher/resources/breeze_dark/index.theme b/launcher/resources/breeze_dark/index.theme
new file mode 100644
index 00000000..f9f6f4dc
--- /dev/null
+++ b/launcher/resources/breeze_dark/index.theme
@@ -0,0 +1,11 @@
+[Icon Theme]
+Name=Breeze Dark
+Comment=Breeze Dark Icons
+Inherits=multimc
+Directories=scalable
+
+[scalable]
+Size=48
+Type=Scalable
+MinSize=16
+MaxSize=256
diff --git a/launcher/resources/breeze_dark/scalable/about.svg b/launcher/resources/breeze_dark/scalable/about.svg
new file mode 100644
index 00000000..856d1b2b
--- /dev/null
+++ b/launcher/resources/breeze_dark/scalable/about.svg
@@ -0,0 +1,12 @@
+<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#eff0f1;
+ }
+ </style>
+ <g class="ColorScheme-Text" fill="currentColor" fill-rule="evenodd">
+ <path d="m8 2a6 6 0 0 0 -6 6 6 6 0 0 0 6 6 6 6 0 0 0 6-6 6 6 0 0 0 -6-6zm0 1a5 5 0 0 1 5 5 5 5 0 0 1 -5 5 5 5 0 0 1 -5-5 5 5 0 0 1 5-5z"/>
+ <path d="m7 4h2v2h-2z"/>
+ <path d="m7 7h2v5h-2z"/>
+ </g>
+</svg>
diff --git a/launcher/resources/breeze_dark/scalable/accounts.svg b/launcher/resources/breeze_dark/scalable/accounts.svg
new file mode 100644
index 00000000..fbb51959
--- /dev/null
+++ b/launcher/resources/breeze_dark/scalable/accounts.svg
@@ -0,0 +1,17 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
+ <defs
+ id="defs3051">
+ <style
+ type="text/css"
+ id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#eff0f1;
+ }
+ </style>
+ </defs>
+ <path
+ style="fill:currentColor;fill-opacity:1;stroke:none"
+ d="M 20.5,4 A 4.5,4.5 0 0 0 16,8.5 4.5,4.5 0 0 0 20.5,13 4.5,4.5 0 0 0 25,8.5 4.5,4.5 0 0 0 20.5,4 Z m 0,1 A 3.5,3.5 0 0 1 24,8.5 3.5,3.5 0 0 1 20.5,12 3.5,3.5 0 0 1 17,8.5 3.5,3.5 0 0 1 20.5,5 Z m -9,4 C 9.014719,9 7,11.01472 7,13.5 7,15.98528 9.014719,18 11.5,18 13.985281,18 16,15.98528 16,13.5 16,11.01472 13.985281,9 11.5,9 Z m 0,1 A 3.5,3.5 0 0 1 15,13.5 3.5,3.5 0 0 1 11.5,17 3.5,3.5 0 0 1 8,13.5 3.5,3.5 0 0 1 11.5,10 Z m 9,4 c -0.88285,0.003 -1.758266,0.17228 -2.585938,0.5 -0.06618,0.42368 -0.174132,0.83977 -0.322265,1.24219 C 18.494507,15.25488 19.490227,15.00077 20.5,15 c 3.589851,0 6.5,3.13401 6.5,7 l -8.341797,0 c 0.170323,0.32329 0.325499,0.65711 0.464844,1 L 28,23 28,22 c 0,-4.41828 -3.357864,-8 -7.5,-8 z m -9,5 C 7.357864,19 4,22.58172 4,27 l 0,1 15,0 0,-1 c 0,-4.41828 -3.357864,-8 -7.5,-8 z m 0,1 c 3.589851,0 6.5,3.13401 6.5,7 L 5,27 c 0,-3.86599 2.910149,-7 6.5,-7 z"
+ class="ColorScheme-Text"
+ />
+</svg>
diff --git a/launcher/resources/breeze_dark/scalable/bug.svg b/launcher/resources/breeze_dark/scalable/bug.svg
new file mode 100644
index 00000000..6ddf482f
--- /dev/null
+++ b/launcher/resources/breeze_dark/scalable/bug.svg
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
+ <defs id="defs3051">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#eff0f1;
+ }
+ </style>
+ </defs>
+ <path style="fill:currentColor;fill-opacity:1;stroke:none"
+ d="m2 2v12h12v-12zm1 1h10v10h-10zm1 2v2h2v-2zm6 0v2h2v-2zm-4 4v1h4v-1zm4 1v1h1v-1zm1 1v1h1v-1zm-5-1h-1v1h1zm-1 1h-1v1h1z"
+ class="ColorScheme-Text"
+ />
+</svg>
diff --git a/launcher/resources/breeze_dark/scalable/centralmods.svg b/launcher/resources/breeze_dark/scalable/centralmods.svg
new file mode 100644
index 00000000..4035e51c
--- /dev/null
+++ b/launcher/resources/breeze_dark/scalable/centralmods.svg
@@ -0,0 +1 @@
+<svg width="8" height="8" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M3 3.5v.25h-.5V6h3V3.75H5V3.5h-.75v.25h-.5V3.5H3Zm-.25.5h2.5v1.75h-2.5V4Z" fill="#EFF0F1"/><path d="M1 1v6h6l-.25-.25h-5.5V3.5H2.5l.75-.75h3.5v4L7 7V1.75H4.5L3.75 1H1Z" fill="#EFF0F1"/></svg> \ No newline at end of file
diff --git a/launcher/resources/breeze_dark/scalable/checkupdate.svg b/launcher/resources/breeze_dark/scalable/checkupdate.svg
new file mode 100644
index 00000000..cc5dfc16
--- /dev/null
+++ b/launcher/resources/breeze_dark/scalable/checkupdate.svg
@@ -0,0 +1,14 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
+ <defs id="defs3051">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#eff0f1;
+ }
+ </style>
+ </defs>
+ <path
+ style="fill:currentColor"
+ d="M 6 2 L 6 3 L 6 6 L 7 6 L 7 3 L 9 3 L 9 6 L 10 6 L 10 3 L 10 2 L 6 2 z M 3.7 6 L 3 6.7 L 6.3 10 L 8 11.7 L 9.7 10 L 13 6.7 L 12.3 6 L 9 9.3 L 8 10.3 L 7 9.3 L 3.7 6 z M 2 12 L 2 14 L 3 14 L 14 14 L 14 13 L 14 12 L 13 12 L 13 13 L 3 13 L 3 12 L 2 12 z "
+ class="ColorScheme-Text"
+ />
+</svg>
diff --git a/launcher/resources/breeze_dark/scalable/copy.svg b/launcher/resources/breeze_dark/scalable/copy.svg
new file mode 100644
index 00000000..fe4a36ac
--- /dev/null
+++ b/launcher/resources/breeze_dark/scalable/copy.svg
@@ -0,0 +1,11 @@
+<!DOCTYPE svg>
+<svg viewBox="0 0 22 22" version="1.1" xmlns="http://www.w3.org/2000/svg">
+ <defs>
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#eff0f1;
+ }
+ </style>
+ </defs>
+ <path class="ColorScheme-Text" style="fill:currentColor; fill-opacity:1; stroke:none" d="M 3 3 L 3 17 L 7 17 L 7 19 L 17 19 L 17 10 L 13 6 L 12 6 L 9 3 L 3 3 Z M 4 4 L 8 4 L 8 6 L 7 6 L 7 16 L 4 16 L 4 4 Z M 8 7 L 12 7 L 12 11 L 16 11 L 16 18 L 8 18 L 8 7 Z"/>
+</svg>
diff --git a/launcher/resources/breeze_dark/scalable/coremods.svg b/launcher/resources/breeze_dark/scalable/coremods.svg
new file mode 100644
index 00000000..ec4ecea8
--- /dev/null
+++ b/launcher/resources/breeze_dark/scalable/coremods.svg
@@ -0,0 +1 @@
+<svg width="8" height="8" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M3.167 2.46v.208H2.75v1.875h2.5V2.668h-.417V2.46h-.625v.208h-.416V2.46h-.625Zm-.209.417h2.084v1.458H2.958V2.877Z" fill="#EFF0F1"/><path d="M1.5 1v6h5V1h-5Zm1.5.5h2a1 1 0 0 1 1 1V3a.5.5 0 1 0 0 1v1l-.5.5h-3L2 5V4a.5.5 0 1 0 0-1v-.5a1 1 0 0 1 1-1ZM2 6h2v.5H2V6Zm3 0h1v.5H5V6Z" fill="#EFF0F1"/></svg> \ No newline at end of file
diff --git a/launcher/resources/breeze_dark/scalable/custom-commands.svg b/launcher/resources/breeze_dark/scalable/custom-commands.svg
new file mode 100644
index 00000000..44efd39e
--- /dev/null
+++ b/launcher/resources/breeze_dark/scalable/custom-commands.svg
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
+ <defs id="defs3051">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#eff0f1;
+ }
+ </style>
+ </defs>
+ <path style="fill:currentColor;fill-opacity:1;stroke:none"
+ d="M 2 2 L 2 14 L 14 14 L 14 2 L 2 2 z M 3 3 L 13 3 L 13 13 L 3 13 L 3 3 z M 4.71875 4 L 4 4.6875 L 6.625 7.5 L 4.03125 10.3125 L 4.71875 11 L 7.6875 7.84375 L 8 7.5 L 7.6875 7.15625 L 4.71875 4 z M 8 11 L 8 12 L 12 12 L 12 11 L 8 11 z "
+ class="ColorScheme-Text"
+ />
+</svg>
diff --git a/launcher/resources/breeze_dark/scalable/delete.svg b/launcher/resources/breeze_dark/scalable/delete.svg
new file mode 100644
index 00000000..c7074585
--- /dev/null
+++ b/launcher/resources/breeze_dark/scalable/delete.svg
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
+ <defs id="defs3051">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#eff0f1;
+ }
+ </style>
+ </defs>
+ <path
+ style="fill:currentColor;fill-opacity:1;stroke:none"
+ d="M 6 2 L 6 3 L 2 3 L 2 4 L 3 4 L 3 14 L 4 14 L 13 14 L 13 13 L 13 4 L 14 4 L 14 3 L 10 3 L 10 2 L 6 2 z M 7 3 L 9 3 L 9 4 L 10 4 L 12 4 L 12 13 L 4 13 L 4 4 L 7 4 L 7 3 z M 6 6 L 6 11 L 7 11 L 7 6 L 6 6 z M 9 6 L 9 11 L 10 11 L 10 6 L 9 6 z "
+ class="ColorScheme-Text"/>
+</svg>
diff --git a/launcher/resources/breeze_dark/scalable/discord.svg b/launcher/resources/breeze_dark/scalable/discord.svg
new file mode 100644
index 00000000..22ee27ba
--- /dev/null
+++ b/launcher/resources/breeze_dark/scalable/discord.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 127.14 96.36"><defs><style>.cls-1{fill:#fff;}</style></defs><g id="图层_2" data-name="图层 2"><g id="Discord_Logos" data-name="Discord Logos"><g id="Discord_Logo_-_Large_-_White" data-name="Discord Logo - Large - White"><path class="cls-1" d="M107.7,8.07A105.15,105.15,0,0,0,81.47,0a72.06,72.06,0,0,0-3.36,6.83A97.68,97.68,0,0,0,49,6.83,72.37,72.37,0,0,0,45.64,0,105.89,105.89,0,0,0,19.39,8.09C2.79,32.65-1.71,56.6.54,80.21h0A105.73,105.73,0,0,0,32.71,96.36,77.7,77.7,0,0,0,39.6,85.25a68.42,68.42,0,0,1-10.85-5.18c.91-.66,1.8-1.34,2.66-2a75.57,75.57,0,0,0,64.32,0c.87.71,1.76,1.39,2.66,2a68.68,68.68,0,0,1-10.87,5.19,77,77,0,0,0,6.89,11.1A105.25,105.25,0,0,0,126.6,80.22h0C129.24,52.84,122.09,29.11,107.7,8.07ZM42.45,65.69C36.18,65.69,31,60,31,53s5-12.74,11.43-12.74S54,46,53.89,53,48.84,65.69,42.45,65.69Zm42.24,0C78.41,65.69,73.25,60,73.25,53s5-12.74,11.44-12.74S96.23,46,96.12,53,91.08,65.69,84.69,65.69Z"/></g></g></g></svg> \ No newline at end of file
diff --git a/launcher/resources/breeze_dark/scalable/export.svg b/launcher/resources/breeze_dark/scalable/export.svg
new file mode 100644
index 00000000..b1fe39d1
--- /dev/null
+++ b/launcher/resources/breeze_dark/scalable/export.svg
@@ -0,0 +1,11 @@
+<!DOCTYPE svg>
+<svg viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg">
+ <defs>
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#eff0f1;
+ }
+ </style>
+ </defs>
+ <path class="ColorScheme-Text" style="fill:currentColor; fill-opacity:1; stroke:none" d="M 7 12 L 11.0859 12 L 9.46484 13.6211 L 10.1719 14.3281 L 13 11.5 L 10.1719 8.67187 L 9.46484 9.37891 L 11.0859 11 L 7 11 L 7 12 Z M 4 13 L 4 3 L 9 3 L 9 6 L 12 6 L 12 9 L 13 9 L 13 5 L 10 2 L 3 2 L 3 14 L 8 14 L 8 13 L 4 13 Z"/>
+</svg>
diff --git a/launcher/resources/breeze_dark/scalable/externaltools.svg b/launcher/resources/breeze_dark/scalable/externaltools.svg
new file mode 100644
index 00000000..dd19fb90
--- /dev/null
+++ b/launcher/resources/breeze_dark/scalable/externaltools.svg
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
+ <defs id="defs3051">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#eff0f1;
+ }
+ </style>
+ </defs>
+ <path style="fill:currentColor;fill-opacity:1;stroke:none"
+ d="M 4 5 L 4 7 L 2 7 L 2 8 L 4 8 L 4 10 L 5 10 L 7 10 L 7 9 L 5 9 L 5 6 L 7 6 L 7 5 L 5 5 L 4 5 z M 9 5 L 9 6 L 11 6 L 11 9 L 9 9 L 9 10 L 11 10 L 12 10 L 12 9 L 12 8 L 14 8 L 14 7 L 12 7 L 12 6 L 12 5 L 11 5 L 9 5 z M 7 7 L 7 8 L 9 8 L 9 7 L 7 7 z "
+ class="ColorScheme-Text"
+ />
+</svg>
diff --git a/launcher/resources/breeze_dark/scalable/help.svg b/launcher/resources/breeze_dark/scalable/help.svg
new file mode 100644
index 00000000..b273a8bc
--- /dev/null
+++ b/launcher/resources/breeze_dark/scalable/help.svg
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22">
+ <defs id="defs3051">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#eff0f1;
+ }
+ </style>
+ </defs>
+ <path style="fill:currentColor;fill-opacity:1;stroke:none"
+ d="M 3 4 L 3 16 L 6 20 L 6 17 L 6 16 L 19 16 L 19 4 L 3 4 z M 4 5 L 18 5 L 18 15 L 4 15 L 4 5 z M 10.5 6 A 2.5 2.5 0 0 0 8 8.5 L 8 9 L 9 9 L 9 8.5 A 1.5 1.5 0 0 1 10.5 7 A 1.5 1.5 0 0 1 12 8.5 A 1.5 1.5 0 0 1 10.5 10 L 10 10 L 10 12 L 11 12 L 11 10.949219 A 2.5 2.5 0 0 0 13 8.5 A 2.5 2.5 0 0 0 10.5 6 z M 10 13 L 10 14 L 11 14 L 11 13 L 10 13 z "
+ class="ColorScheme-Text"
+ />
+</svg>
diff --git a/launcher/resources/breeze_dark/scalable/instance-settings.svg b/launcher/resources/breeze_dark/scalable/instance-settings.svg
new file mode 100644
index 00000000..c5f0504b
--- /dev/null
+++ b/launcher/resources/breeze_dark/scalable/instance-settings.svg
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
+ <defs id="defs3051">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#eff0f1;
+ }
+ </style>
+ </defs>
+ <path style="fill:currentColor;fill-opacity:1;stroke:none"
+ d="M 2 2 L 2 5 L 2 14 L 3 14 L 14 14 L 14 13 L 14 2 L 3 2 L 2 2 z M 3 5 L 13 5 L 13 13 L 3 13 L 3 5 z M 4 6 L 4 12 L 6 12 L 6 6 L 4 6 z M 7 7 L 7 8 L 12 8 L 12 7 L 7 7 z M 7 10 L 7 11 L 12 11 L 12 10 L 7 10 z "
+ class="ColorScheme-Text"
+ />
+</svg>
diff --git a/launcher/resources/breeze_dark/scalable/jarmods.svg b/launcher/resources/breeze_dark/scalable/jarmods.svg
new file mode 100644
index 00000000..49a45d36
--- /dev/null
+++ b/launcher/resources/breeze_dark/scalable/jarmods.svg
@@ -0,0 +1 @@
+<svg width="8" height="8" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M2 1.5V2H1v4.5h6V2H6v-.5H4.5V2h-1v-.5H2Zm-.5 1h5V6h-5V2.5Z" fill="#EFF0F1"/><path d="M3.93 4.37s-.19-.364-.183-.63c.005-.19.434-.378.603-.651.168-.273-.022-.54-.022-.54s.043.197-.07.4c-.112.203-.525.322-.686.672-.16.35.357.75.357.75Z" fill="#EFF0F1"/><path d="M4.637 3.264s-.645.246-.645.525c0 .28.175.372.203.463.028.091-.049.245-.049.245s.252-.175.21-.378c-.042-.203-.238-.267-.126-.47.075-.136.407-.385.407-.385Z" fill="#EFF0F1"/><path d="M3.859 4.741c.595-.021.812-.209.812-.209-.385.105-1.407.098-1.415.021-.006-.077.316-.14.316-.14s-.505 0-.546.126c-.043.126.238.223.833.202ZM4.72 5.036s.583-.124.526-.44c-.07-.386-.477-.169-.477-.169s.288 0 .316.175c.028.175-.364.434-.364.434ZM4.434 4.868s-.147.038-.364.063c-.292.033-.645.007-.673-.042-.028-.05.05-.077.05-.077-.35.084-.16.23.251.26.352.023.876-.106.876-.106l-.14-.098ZM3.53 5.174s-.159.004-.168.088c-.01.084.098.159.49.182.392.024.668-.107.668-.107l-.178-.107s-.112.023-.285.046c-.173.024-.527-.018-.541-.051-.014-.032.014-.051.014-.051Z" fill="#EFF0F1"/><path d="M5.057 5.552c.06-.065-.019-.117-.019-.117s.028.033-.009.07c-.037.037-.378.13-.924.158-.546.028-1.14-.05-1.159-.121-.018-.07.304-.126.304-.126-.037.005-.485.014-.5.136-.013.12.197.22 1.037.22.84 0 1.21-.155 1.27-.22Z" fill="#EFF0F1"/><path d="M4.73 5.828c-.368.074-1.489.027-1.489.027s.728.173 1.56.029c.397-.07.42-.262.42-.262s-.122.13-.49.206Z" fill="#EFF0F1"/></svg> \ No newline at end of file
diff --git a/launcher/resources/breeze_dark/scalable/java.svg b/launcher/resources/breeze_dark/scalable/java.svg
new file mode 100644
index 00000000..7149981c
--- /dev/null
+++ b/launcher/resources/breeze_dark/scalable/java.svg
@@ -0,0 +1,10 @@
+<svg width="1000" height="1000" viewBox="0 0 1000 1000" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M479.6 536.2C479.6 536.2 425 430.9 427 354C428.5 299 552.4 244.7 601.1 165.8C649.7 86.9 595 10 595 10C595 10 607.2 66.7 574.8 125.3C542.4 184 422.9 218.5 376.4 319.6C329.9 420.9 479.6 536.2 479.6 536.2Z" fill="#eff0f1"/>
+<path d="M684.099 216.4C684.099 216.4 497.899 287.3 497.899 368.2C497.899 449.2 548.499 475.5 556.599 501.8C564.699 528.2 542.399 572.7 542.399 572.7C542.399 572.7 615.199 522.1 602.999 463.4C590.799 404.7 534.199 386.4 566.599 327.8C588.399 288.4 684.099 216.4 684.099 216.4Z" fill="#eff0f1"/>
+<path d="M459.399 643.2C631.499 637.1 694.2 582.8 694.2 582.8C582.9 613.1 287.399 611.1 285.299 588.9C283.299 566.6 376.399 548.4 376.399 548.4C376.399 548.4 230.7 548.4 218.6 584.8C206.4 621.2 287.499 649.2 459.399 643.2Z" fill="#eff0f1"/>
+<path d="M708.399 728.5C708.399 728.5 876.799 692.6 860.099 601.1C839.899 489.7 722.499 552.5 722.499 552.5C722.499 552.5 805.599 552.5 813.599 603.1C821.699 653.6 708.399 728.5 708.399 728.5Z" fill="#eff0f1"/>
+<path d="M625.4 679.9C625.4 679.9 583 691 520.1 698.1C435.8 707.6 333.9 700.1 325.8 685.9C317.8 671.7 340 663.7 340 663.7C238.8 688 294.2 730.4 412.8 738.6C514.5 745.5 665.9 708.2 665.9 708.2L625.4 679.9Z" fill="#eff0f1"/>
+<path d="M364.299 768.3C364.299 768.3 318.399 769.6 315.699 793.9C313.099 818 343.999 839.7 457.299 846.5C570.599 853.2 650.299 815.5 650.299 815.5L598.999 784.4C598.999 784.4 566.599 791.2 516.699 797.9C466.699 804.7 364.299 792.5 360.199 783.1C356.199 773.7 364.299 768.3 364.299 768.3Z" fill="#eff0f1"/>
+<path d="M805.5 877.6C823 858.7 800.099 843.8 800.099 843.8C800.099 843.8 808.2 853.3 797.5 864C786.7 874.8 688.199 901.7 530.299 909.8C372.499 917.9 201.1 895 195.6 874.7C190.3 854.5 283.4 838.3 283.4 838.3C272.6 839.6 143.1 842.3 139 877.5C135 912.5 195.7 940.9 438.6 940.9C681.4 941 788 896.4 805.5 877.6Z" fill="#eff0f1"/>
+<path d="M711.099 957.2C604.499 978.7 280.699 965.2 280.699 965.2C280.699 965.2 491.099 1015.2 731.299 973.4C846.099 953.4 852.799 897.8 852.799 897.8C852.799 897.8 817.699 935.6 711.099 957.2Z" fill="#eff0f1"/>
+</svg>
diff --git a/launcher/resources/breeze_dark/scalable/language.svg b/launcher/resources/breeze_dark/scalable/language.svg
new file mode 100644
index 00000000..239cdf94
--- /dev/null
+++ b/launcher/resources/breeze_dark/scalable/language.svg
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
+ <defs id="defs3051">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#eff0f1;
+ }
+ </style>
+ </defs>
+ <path style="fill:currentColor;fill-opacity:1;stroke:none"
+ d="M 2 2 L 2 3 L 2 8 L 3 8 L 6 8 L 6 10 L 6 11 L 9 14 L 9 11 L 13 11 L 14 11 L 14 6 L 14 5 L 13 5 L 10 5 L 10 2 L 3 2 L 2 2 z M 3 3 L 9 3 L 9 5 L 9 6 L 9 7 L 7 7 L 6 7 L 3 7 L 3 3 z M 10 6 L 13 6 L 13 10 L 8 10 L 7 10 L 7 8 L 8 8 L 8 10 L 10 8 L 10 7 L 10 6 z "
+ class="ColorScheme-Text"
+ />
+</svg>
diff --git a/launcher/resources/breeze_dark/scalable/launch.svg b/launcher/resources/breeze_dark/scalable/launch.svg
new file mode 100644
index 00000000..25c5fabc
--- /dev/null
+++ b/launcher/resources/breeze_dark/scalable/launch.svg
@@ -0,0 +1,8 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#eff0f1;
+ }
+ </style>
+ <path d="m2 2v12l12-6z" class="ColorScheme-Text" fill="currentColor"/>
+</svg>
diff --git a/launcher/resources/breeze_dark/scalable/launcher.svg b/launcher/resources/breeze_dark/scalable/launcher.svg
new file mode 100644
index 00000000..aeee8433
--- /dev/null
+++ b/launcher/resources/breeze_dark/scalable/launcher.svg
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg width="48" height="48" version="1.1" viewBox="0 0 12.7 12.7" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+ <title>Prism Launcher Logo</title>
+ <g stroke-width=".26458">
+ <path d="m6.35 6.35" fill="#99cd61"/>
+ <path d="m6.35 0.52917-2.5208 4.3656 2.5208 1.4552 2.5203-1.4552 0.10955-3.0996c-1.1511-0.66459-2.3388-1.2661-2.6298-1.2661z" fill="#df6277"/>
+ <path d="m8.9798 1.7952-2.6298 4.5548 2.5203 1.4552 2.5208-4.3656c-0.14552-0.25205-1.2601-0.97975-2.4112-1.6443z" fill="#fb9168"/>
+ <path d="m11.391 3.4396-5.041 2.9104 2.5203 1.4552 2.7389-1.4552c0-1.3292-0.072554-2.6584-0.21808-2.9104z" fill="#f3db6c"/>
+ <path d="m6.35 6.35v2.9104h5.041c0.14552-0.25205 0.21807-1.5812 0.21808-2.9104h-5.2591z" fill="#7ab392"/>
+ <path d="m6.35 6.35v2.9104l2.6298 1.6443c1.1511-0.66459 2.2657-1.3923 2.4112-1.6443l-5.041-2.9104z" fill="#4b7cbc"/>
+ <path d="m6.35 6.35-2.5208 1.4552 2.5208 4.3656c0.29104 0 1.4787-0.60148 2.6298-1.2661l-2.6298-4.5548z" fill="#6f488c"/>
+ <path d="m3.8292 4.8948-2.5203 4.3656c0.29104 0.5041 4.459 2.9104 5.041 2.9104v-5.8208l-2.5208-1.4552z" fill="#4d3f33"/>
+ <path d="m1.309 3.4396c-0.29104 0.5041-0.29104 5.3167 0 5.8208l5.041-2.9104v-2.9104h-5.041z" fill="#7a573b"/>
+ <path d="m6.35 0.52917c-0.58208-2e-8 -4.75 2.4063-5.041 2.9104l5.041 2.9104v-5.8208z" fill="#99cd61"/>
+ </g>
+ <g transform="matrix(.88 0 0 .88 -10.906 -1.2421)">
+ <g transform="translate(13.26 2.2776)">
+ <path transform="matrix(.96975 0 0 .96975 .1921 .1921)" d="m6.3498 2.9393c-0.34105 0-2.7827 1.4099-2.9532 1.7052l2.9532 5.1157 2.9538-5.1157c-0.17052-0.29535-2.6127-1.7052-2.9538-1.7052z" fill="#fff" stroke-width=".26458"/>
+ </g>
+ <path d="m16.746 6.9737 2.8639 4.9609c0.33073 0 2.6991-1.3672 2.8644-1.6536 0.16536-0.28642 0.16536-3.0209 0-3.3073l-2.8644 1.6536z" fill="#dfdfdf" stroke-width=".26458"/>
+ </g>
+ <path d="m3.8299 4.8948c-0.14551 0.25205-0.14553 2.6584 0 2.9104 0.14553 0.25204 2.2292 1.4552 2.5203 1.4552v-2.9104z" fill="#d6d2d2" stroke-width=".26458"/>
+ <metadata>
+ <rdf:RDF>
+ <cc:Work rdf:about="">
+ <dc:title>Prism Launcher Logo</dc:title>
+ <dc:date>19/10/2022</dc:date>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Prism Launcher</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ <dc:source>https://github.com/PrismLauncher/PrismLauncher</dc:source>
+ <dc:publisher>
+ <cc:Agent>
+ <dc:title>Prism Launcher</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <cc:license rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/"/>
+ </cc:Work>
+ <cc:License rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits rdf:resource="http://creativecommons.org/ns#Reproduction"/>
+ <cc:permits rdf:resource="http://creativecommons.org/ns#Distribution"/>
+ <cc:requires rdf:resource="http://creativecommons.org/ns#Notice"/>
+ <cc:requires rdf:resource="http://creativecommons.org/ns#Attribution"/>
+ <cc:permits rdf:resource="http://creativecommons.org/ns#DerivativeWorks"/>
+ <cc:requires rdf:resource="http://creativecommons.org/ns#ShareAlike"/>
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+</svg>
diff --git a/launcher/resources/breeze_dark/scalable/loadermods.svg b/launcher/resources/breeze_dark/scalable/loadermods.svg
new file mode 100644
index 00000000..7bd87188
--- /dev/null
+++ b/launcher/resources/breeze_dark/scalable/loadermods.svg
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
+ <defs id="defs3051">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#eff0f1;
+ }
+ </style>
+ </defs>
+ <path
+ style="fill:currentColor;fill-opacity:1;stroke:none"
+ d="m4 3v1h-2v9h12v-9h-2v-1h-3v1h-2v-1zm-1 2h10v7h-10z"
+ class="ColorScheme-Text"/>
+</svg>
diff --git a/launcher/resources/breeze_dark/scalable/log.svg b/launcher/resources/breeze_dark/scalable/log.svg
new file mode 100644
index 00000000..fcd83c4d
--- /dev/null
+++ b/launcher/resources/breeze_dark/scalable/log.svg
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
+ <defs id="defs3051">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#eff0f1;
+ }
+ </style>
+ </defs>
+ <path style="fill:currentColor;fill-opacity:1;stroke:none"
+ d="M 11 2 L 11 14 L 14 14 L 14 2 L 11 2 z M 6 5 L 6 14 L 9 14 L 9 5 L 6 5 z M 1 8 L 1 14 L 4 14 L 4 8 L 1 8 z "
+ class="ColorScheme-Text"
+ />
+</svg>
diff --git a/launcher/resources/breeze_dark/scalable/matrix.svg b/launcher/resources/breeze_dark/scalable/matrix.svg
new file mode 100644
index 00000000..214f5708
--- /dev/null
+++ b/launcher/resources/breeze_dark/scalable/matrix.svg
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg version="1.1" viewBox="0 0 27.9 32" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+ <title>Matrix (protocol) logo</title>
+ <g transform="translate(-.095 .005)" fill="#eff0f1">
+ <path d="m27.1 31.2v-30.5h-2.19v-0.732h3.04v32h-3.04v-0.732z"/>
+ <path d="m8.23 10.4v1.54h0.044c0.385-0.564 0.893-1.03 1.49-1.37 0.58-0.323 1.25-0.485 1.99-0.485 0.72 0 1.38 0.14 1.97 0.42 0.595 0.279 1.05 0.771 1.36 1.48 0.338-0.5 0.796-0.941 1.38-1.32 0.58-0.383 1.27-0.574 2.06-0.574 0.602 0 1.16 0.074 1.67 0.22 0.514 0.148 0.954 0.383 1.32 0.707 0.366 0.323 0.653 0.746 0.859 1.27 0.205 0.522 0.308 1.15 0.308 1.89v7.63h-3.13v-6.46c0-0.383-0.015-0.743-0.044-1.08-0.0209-0.307-0.103-0.607-0.242-0.882-0.133-0.251-0.336-0.458-0.584-0.596-0.257-0.146-0.606-0.22-1.05-0.22-0.44 0-0.796 0.085-1.07 0.253-0.272 0.17-0.485 0.39-0.639 0.662-0.159 0.287-0.264 0.602-0.308 0.927-0.052 0.347-0.078 0.697-0.078 1.05v6.35h-3.13v-6.4c0-0.338-7e-3 -0.673-0.021-1-0.0114-0.314-0.0749-0.623-0.188-0.916-0.108-0.277-0.3-0.512-0.55-0.673-0.258-0.168-0.636-0.253-1.14-0.253-0.198 0.0083-0.394 0.042-0.584 0.1-0.258 0.0745-0.498 0.202-0.705 0.374-0.228 0.184-0.422 0.449-0.584 0.794-0.161 0.346-0.242 0.798-0.242 1.36v6.62h-3.13v-11.4z"/>
+ <path d="m0.936 0.732v30.5h2.19v0.732h-3.04v-32h3.03v0.732z"/>
+ </g>
+</svg> \ No newline at end of file
diff --git a/launcher/resources/breeze_dark/scalable/minecraft.svg b/launcher/resources/breeze_dark/scalable/minecraft.svg
new file mode 100644
index 00000000..1d8d0167
--- /dev/null
+++ b/launcher/resources/breeze_dark/scalable/minecraft.svg
@@ -0,0 +1,13 @@
+<svg version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+ <defs>
+ <style type="text/css" id="current-color-scheme">.ColorScheme-Text {
+ color:#eff0f1;
+ }</style>
+ </defs>
+ <g fill="currentColor">
+ <path class="ColorScheme-Text" d="m8.2746408 13.953029c0.00833 0 1.1494866-0.753825 2.5359342-1.674795l2.520534-1.674794v-2.6001033c0-1.4307351-0.0074-2.6013858-0.01668-2.6013858-0.0093 0-1.150413 0.7546842-2.535934 1.6773611l-2.5192543 1.6773619v2.5988191c0 1.429027 0.00706 2.597536 0.015402 2.597536z" fill="currentColor" fill-opacity=".2"/>
+ <path class="ColorScheme-Text" d="m7.9409649 8.3549799c0.0753873-0.0030883 5.0483591-3.3585525 5.0192511-3.3868071-0.014404-0.0138645-1.1312-0.7652159-2.482034-1.6683781-1.3508332-0.9031623-2.4637176-1.6377305-2.4730489-1.6311596-0.4205404 0.2725585-4.9953997 3.3678436-4.9999993 3.3829565-0.00988 0.032723 4.8804389 3.3033883 4.9358311 3.3033883z" fill="currentColor" fill-opacity=".4"/>
+ <path class="ColorScheme-Text" d="m7.7189427 13.994097c0.00828 0 0.015875-1.150637 0.015402-2.556468l-0.0013141-2.5551853-2.517967-1.6850615c-1.3845486-0.9264887-2.5204415-1.6863448-2.524384-1.6863448-0.00421-0.00112-0.0077 1.1516957-0.0077 2.5616013v2.5628853l2.5102968 1.679928c1.3808361 0.923532 2.5173881 1.678645 2.5256673 1.678645z" fill="currentColor" fill-opacity=".6"/>
+ <path class="ColorScheme-Text" d="m 8,15 c 5.76994,-3.758469 4.07772,-2.720917 6,-4 V 5 C 12.707222,4.143927 10.030643,2.3424577 8,1 5,3 4.3571975,3.3856408 2,5 v 6 z M 8.508315,13.412447 8.4963301,9 C 10.411258,7.652439 11.772087,6.8337528 13,6 v 4.594435 z M 7.5156547,13.400462 3,10.570466 V 6 L 7.5276396,9 Z M 8,8 3.4485124,5 8,2 12.477901,5 C 10.956071,6.0867591 9.5367568,6.9353406 8,8 Z" fill="currentColor"/>
+ </g>
+</svg>
diff --git a/launcher/resources/breeze_dark/scalable/new.svg b/launcher/resources/breeze_dark/scalable/new.svg
new file mode 100644
index 00000000..9ee910e7
--- /dev/null
+++ b/launcher/resources/breeze_dark/scalable/new.svg
@@ -0,0 +1,18 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
+ <defs
+ id="defs3051">
+ <style
+ type="text/css"
+ id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#eff0f1;
+ }
+ </style>
+ </defs>
+ <path
+ style="fill:currentColor;fill-opacity:1;stroke:none"
+ d="M 4 4 L 4 28 L 17 28 L 17 27 L 5 27 L 5 14 L 10 14 L 13 11 L 27 11 L 27 17 L 28 17 L 28 7 L 18 7 L 15 4 L 4 4 z M 22 17 L 22 22 L 17 22 L 17 23 L 22 23 L 22 28 L 23 28 L 23 23 L 28 23 L 28 22 L 23 22 L 23 17 L 22 17 z "
+ id="path99"
+ class="ColorScheme-Text"
+ />
+</svg>
diff --git a/launcher/resources/breeze_dark/scalable/news.svg b/launcher/resources/breeze_dark/scalable/news.svg
new file mode 100644
index 00000000..a2ff0c8d
--- /dev/null
+++ b/launcher/resources/breeze_dark/scalable/news.svg
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
+ <defs id="defs3051">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#eff0f1;
+ }
+ </style>
+ </defs>
+ <path style="fill:currentColor;fill-opacity:1;stroke:none"
+ d="m2 2v12h12v-12zm1 1h10v10h-10zm1 1v3h3v-3zm4 0v1h4v-1zm0 2v1h4v-1zm-4 2v4h8v-4z"
+ class="ColorScheme-Text"
+ />
+</svg>
diff --git a/launcher/resources/breeze_dark/scalable/notes.svg b/launcher/resources/breeze_dark/scalable/notes.svg
new file mode 100644
index 00000000..6452d3c8
--- /dev/null
+++ b/launcher/resources/breeze_dark/scalable/notes.svg
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
+ <defs id="defs3051">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#eff0f1;
+ }
+ </style>
+ </defs>
+ <path style="fill:currentColor;fill-opacity:1;stroke:none"
+ d="M 3 2 L 3 3 L 2 3 L 2 14 L 14 14 L 14 3 L 13 3 L 13 2 L 12 2 L 12 3 L 11 3 L 11 2 L 10 2 L 10 3 L 6 3 L 6 2 L 5 2 L 5 3 L 4 3 L 4 2 L 3 2 z M 3 4 L 13 4 L 13 13 L 3 13 L 3 4 z M 4 5 L 4 6 L 12 6 L 12 5 L 4 5 z M 4 7 L 4 8 L 8 8 L 8 7 L 4 7 z M 4 9 L 4 10 L 10 10 L 10 9 L 4 9 z M 10 11 L 10 12 L 12 12 L 12 11 L 10 11 z "
+ class="ColorScheme-Text"
+ />
+</svg>
diff --git a/launcher/resources/breeze_dark/scalable/patreon.svg b/launcher/resources/breeze_dark/scalable/patreon.svg
new file mode 100644
index 00000000..7f98dd13
--- /dev/null
+++ b/launcher/resources/breeze_dark/scalable/patreon.svg
@@ -0,0 +1,3 @@
+<svg fill="#eff0f1" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M12,3h0a9,9,0,0,0-9,9v9H5.09V12a6.91,6.91,0,1,1,7.23,6.9,5.9,5.9,0,0,1-2.59-.47v-3A4.13,4.13,0,1,0,7.85,12v9H12A9,9,0,1,0,12,3Zm0,15.91h0Z"/>
+</svg>
diff --git a/launcher/resources/breeze_dark/scalable/proxy.svg b/launcher/resources/breeze_dark/scalable/proxy.svg
new file mode 100644
index 00000000..c6efb171
--- /dev/null
+++ b/launcher/resources/breeze_dark/scalable/proxy.svg
@@ -0,0 +1,14 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
+ <defs id="defs3051">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#eff0f1;
+ }
+ </style>
+ </defs>
+ <path
+ style="fill:currentColor;fill-opacity:1;stroke:none"
+ d="M 7 2 L 7 3 L 13 3 L 13 10 L 7 10 L 7 12 L 7 13 L 6 13 C 5.4459904 13 5 12.55401 5 12 L 5 10 L 5 8 L 5 7 L 6 7 L 6 3 L 3 3 L 3 7 L 4 7 L 4 8 L 4 10 L 4 12 C 4 13.108 4.892 14 6 14 L 7 14 L 9 14 L 11 14 L 11 13 L 9 13 L 9 12 L 14 12 L 14 11 L 14 10 L 14 2 L 7 2 z M 4 5 L 5 5 L 5 6 L 4 6 L 4 5 z M 2 8 L 2 12 L 3 12 L 3 10 L 3 8 L 2 8 z "
+ class="ColorScheme-Text"
+ />
+</svg>
diff --git a/launcher/resources/breeze_dark/scalable/reddit-alien.svg b/launcher/resources/breeze_dark/scalable/reddit-alien.svg
new file mode 100644
index 00000000..00f82bb3
--- /dev/null
+++ b/launcher/resources/breeze_dark/scalable/reddit-alien.svg
@@ -0,0 +1,3 @@
+<svg fill="#eff0f1" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M20,11.86a1.76,1.76,0,0,0-1.75-1.75,1.73,1.73,0,0,0-1.22.51,9,9,0,0,0-4.67-1.38l1-3.16L16,6.71s0,0,0,0a1.46,1.46,0,1,0,.1-.53l-2.89-.68a.25.25,0,0,0-.29.17L11.83,9.23a9.16,9.16,0,0,0-4.88,1.36,1.75,1.75,0,1,0-2.07,2.79,3,3,0,0,0-.06.58C4.82,16.58,8,18.7,12,18.7s7.14-2.13,7.14-4.74a2.94,2.94,0,0,0-.05-.55A1.74,1.74,0,0,0,20,11.86ZM8.51,13.08a1.06,1.06,0,1,1,1.06,1.06A1.06,1.06,0,0,1,8.51,13.08Zm6.06,3.14A3.48,3.48,0,0,1,12,17h0a3.48,3.48,0,0,1-2.56-.79.25.25,0,0,1,.35-.35,3,3,0,0,0,2.2.65h0a3,3,0,0,0,2.2-.65.25.25,0,1,1,.35.35Zm-.13-2.08a1.06,1.06,0,1,1,1.06-1.06A1.06,1.06,0,0,1,14.44,14.14Z"/>
+</svg>
diff --git a/launcher/resources/breeze_dark/scalable/refresh.svg b/launcher/resources/breeze_dark/scalable/refresh.svg
new file mode 100644
index 00000000..7b486463
--- /dev/null
+++ b/launcher/resources/breeze_dark/scalable/refresh.svg
@@ -0,0 +1,8 @@
+<svg version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+ <defs>
+ <style type="text/css" id="current-color-scheme">.ColorScheme-Text {
+ color:#eff0f1;
+ }</style>
+ </defs>
+ <path class="ColorScheme-Text" fill="currentColor" d="m14 8c0 1.1088173-0.319333 2.140071-0.84375 3.03125l-2.6875-2.6875 0.71875-0.71875 1.625 1.625c0.05109-0.19534 0.097716-0.3898623 0.125-0.59375 0.007789-0.0524063 0.025184-0.1032787 0.03125-0.15625 0.01707-0.1680854 0.03125-0.327411 0.03125-0.5 0-2.761424-2.238576-5-5-5-0.243024 0-0.4855082 0.02845-0.71875 0.0625-0.1362493 0.019955-0.2738032 0.031786-0.40625 0.0625-0.2865815 0.06695-0.547624 0.166647-0.8125 0.28125-0.030675 0.013272-0.063399 0.017376-0.09375 0.03125-0.09166 0.040961-0.163333 0.108255-0.25 0.15625-8e-3 0.00445-0.02305-0.00433-0.03125 0l-0.71875-0.75c0.891179-0.524417 1.922432-0.84375 3.03125-0.84375 3.313709 0 6 2.686293 6 6zm-2.96875 5.15625c-0.891179 0.524417-1.922432 0.84375-3.03125 0.84375-3.313709 0-6-2.686293-6-6 0-1.1088173 0.319333-2.140071 0.84375-3.03125l0.75 0.75 1.90625 1.9375-0.6875 0.6875-1.625-1.59375c-0.05109 0.19534-0.09772 0.3898623-0.125 0.59375-0.0078 0.052406-0.02518 0.1032787-0.03125 0.15625-0.01707 0.1680854-0.03125 0.327411-0.03125 0.5s0.01418 0.3319146 0.03125 0.5c0.01707 0.1680853 0.029198 0.337256 0.0625 0.5 0.466231 2.278415 2.490004 4 4.90625 4 0.2482626 0 0.4801862-0.02756 0.71875-0.0625 0.1362493-0.01995 0.2738032-0.03179 0.40625-0.0625 0.2865815-0.06695 0.547624-0.166647 0.8125-0.28125 0.030718-0.01299 0.063349-0.01766 0.09375-0.03125 0.08886-0.04062 0.164735-0.108612 0.25-0.15625h0.03125z"/>
+</svg>
diff --git a/launcher/resources/breeze_dark/scalable/rename.svg b/launcher/resources/breeze_dark/scalable/rename.svg
new file mode 100644
index 00000000..6a844965
--- /dev/null
+++ b/launcher/resources/breeze_dark/scalable/rename.svg
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
+ <defs id="defs3051">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#eff0f1;
+ }
+ </style>
+ </defs>
+ <path style="fill:currentColor;fill-opacity:1;stroke:none"
+ d="M 10.398438 2 L 5.2871094 7.1113281 L 2 10.398438 L 2 14 L 5.6015625 14 L 14 5.6015625 L 10.398438 2 z M 8.3496094 5.4902344 L 10.509766 7.6503906 L 7.3359375 10.826172 L 7.3359375 10.150391 L 6.3222656 10.171875 L 5.2871094 10.171875 L 5.2871094 9.1367188 L 5.2871094 8.5507812 L 6.7285156 7.1113281 L 8.3496094 5.4902344 z M 4.2734375 9.5644531 L 4.2734375 11.185547 L 5.3085938 11.185547 L 6.3007812 11.185547 L 6.3222656 11.837891 L 5.2421875 12.919922 L 3.8007812 12.919922 L 3.0800781 12.199219 L 3.0800781 10.757812 L 4.2734375 9.5644531 z "
+ class="ColorScheme-Text"
+ />
+</svg>
diff --git a/launcher/resources/breeze_dark/scalable/resourcepacks.svg b/launcher/resources/breeze_dark/scalable/resourcepacks.svg
new file mode 100644
index 00000000..0986c216
--- /dev/null
+++ b/launcher/resources/breeze_dark/scalable/resourcepacks.svg
@@ -0,0 +1,11 @@
+<!DOCTYPE svg>
+<svg version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+ <defs>
+ <style id="current-color-scheme" type="text/css">
+ .ColorScheme-Text {
+ color:#eff0f1;
+ }
+ </style>
+ </defs>
+ <path class="ColorScheme-Text" style="fill:currentColor; fill-opacity:1; stroke:none" d="M 8 3 L 13 3 L 13 13 L 8 13 L 8 3 Z M 3 3 L 13 3 L 13 9 L 11 7 L 7.65625 10.3438 L 6.3125 9 L 6.2813 9 L 3 12.2813 L 3 3 Z M 2 2 L 2 13.2813 L 2 14 L 14 14 L 14 13 L 14 12 L 14 11 L 14 10 L 14 2 L 2 2 Z M 6 4 C 4.89543 4 4 4.89543 4 6 C 4 7.10457 4.89543 8 6 8 C 7.10457 8 8 7.10457 8 6 C 8 4.89543 7.10457 4 6 4 Z"/>
+</svg>
diff --git a/launcher/resources/breeze_dark/scalable/screenshots.svg b/launcher/resources/breeze_dark/scalable/screenshots.svg
new file mode 100644
index 00000000..a10ed713
--- /dev/null
+++ b/launcher/resources/breeze_dark/scalable/screenshots.svg
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
+ <defs id="defs3051">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#eff0f1;
+ }
+ </style>
+ </defs>
+ <path style="fill:currentColor;fill-opacity:1;stroke:none"
+ d="M 2 2 L 2 13.28125 L 2 14 L 14 14 L 14 13 L 14 12 L 14 11 L 14 10 L 14 2 L 2 2 z M 3 3 L 13 3 L 13 9 L 11 7 L 7.65625 10.34375 L 6.3125 9 L 6.28125 9 L 3 12.28125 L 3 3 z M 6 4 C 4.8954305 4 4 4.8954305 4 6 C 4 7.1045695 4.8954305 8 6 8 C 7.1045695 8 8 7.1045695 8 6 C 8 4.8954305 7.1045695 4 6 4 z "
+ class="ColorScheme-Text"
+ />
+</svg>
diff --git a/launcher/resources/breeze_dark/scalable/settings.svg b/launcher/resources/breeze_dark/scalable/settings.svg
new file mode 100644
index 00000000..009d8154
--- /dev/null
+++ b/launcher/resources/breeze_dark/scalable/settings.svg
@@ -0,0 +1,17 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
+ <defs id="defs3051">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#eff0f1;
+ }
+ .ColorScheme-Highlight {
+ color:#3daee9;
+ }
+ </style>
+ </defs>
+ <path
+ style="fill:currentColor;fill-opacity:1;stroke:none"
+ d="M18.5 6A3.5 3.5 0 0 0 15.04102 9H4V10H15.04A3.5 3.5 0 0 0 18.5 13 3.5 3.5 0 0 0 21.958984 10H28V9H21.961A3.5 3.5 0 0 0 18.5 6M7.5 19A3.5 3.5 0 0 0 4 22.5 3.5 3.5 0 0 0 7.5 26 3.5 3.5 0 0 0 10.960938 23H28V22H10.959A3.5 3.5 0 0 0 7.5 19m0 1A2.5 2.5 0 0 1 10 22.5 2.5 2.5 0 0 1 7.5 25 2.5 2.5 0 0 1 5 22.5 2.5 2.5 0 0 1 7.5 20"
+ class="ColorScheme-Text"
+ />
+</svg>
diff --git a/launcher/resources/breeze_dark/scalable/shaderpacks.svg b/launcher/resources/breeze_dark/scalable/shaderpacks.svg
new file mode 100644
index 00000000..b2887947
--- /dev/null
+++ b/launcher/resources/breeze_dark/scalable/shaderpacks.svg
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
+ <defs id="defs3051">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#eff0f1;
+ }
+ </style>
+ </defs>
+ <path style="fill:currentColor;fill-opacity:1;stroke:none"
+ d="M 2 2 L 2 14 L 5.15625 10.84375 C 4.43239 10.11989 4 9.10457 4 8 C 4 5.79086 5.79086 4 8 4 C 9.10457 4 10.11989 4.43239 10.84375 5.15625 L 14 2 L 2 2 z M 10.84375 5.15625 L 5.15625 10.84375 C 5.88011 11.56761 6.89543 12 8 12 C 10.20914 12 12 10.20914 12 8 C 12 6.89543 11.56761 5.88011 10.84375 5.15625 z "
+ class="ColorScheme-Text"
+ />
+</svg>
diff --git a/launcher/resources/breeze_dark/scalable/shortcut.svg b/launcher/resources/breeze_dark/scalable/shortcut.svg
new file mode 100644
index 00000000..5559be1d
--- /dev/null
+++ b/launcher/resources/breeze_dark/scalable/shortcut.svg
@@ -0,0 +1,18 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
+ <defs id="defs3051">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#eff0f1;
+ }
+ </style>
+ </defs>
+ <g
+ transform="translate(-3,-1033.3622)">
+ <path
+ style="fill:currentColor;fill-opacity:1;stroke:none"
+ d="M 4,7 C 3.4459904,7 3,7.4459904 3,8 l 0,6 c 0,0.55401 0.4459904,1 1,1 l 5,0 c 0.55401,0 1,-0.44599 1,-1 l 0,-1 2,0 0,1 c 0,0.554 0.44599,1 1,1 l 5,0 c 0.55401,0 1,-0.446 1,-1 L 19,8 C 19,7.446 18.55401,7 18,7 l -5,0 c -0.55401,0 -1,0.446 -1,1 l 0,1 -2,0 0,-1 C 10,7.4459904 9.55401,7 9,7 Z M 4,8 7,8 9,8 9,9 C 8.4459904,9 8,9.4459904 8,10 l 0,2 c 0,0.55401 0.4459904,1 1,1 l 0,1 -2,0 -3,0 z m 9,0 3,0 2,0 0,6 -2,0 -3,0 0,-1 c 0.55401,0 1,-0.44599 1,-1 l 0,-2 C 14,9.4459904 13.55401,9 13,9 Z m -4,2 4,0 0,2 -4,0 z"
+ transform="translate(0,1030.3622)"
+ id="rect4161"
+ class="ColorScheme-Text" />
+ </g>
+</svg>
diff --git a/launcher/resources/breeze_dark/scalable/status-bad.svg b/launcher/resources/breeze_dark/scalable/status-bad.svg
new file mode 100644
index 00000000..6fc3137e
--- /dev/null
+++ b/launcher/resources/breeze_dark/scalable/status-bad.svg
@@ -0,0 +1,9 @@
+<svg version="1.1" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-NegativeText {
+ color:#da4453;
+ }
+ </style>
+ <rect class="ColorScheme-NegativeText" x="3" y="3" width="16" height="16" rx="2" fill="currentColor"/>
+ <path d="M 6.414,5 5,6.414 9.586,11 5,15.586 6.414,17 11,12.414 15.586,17 17,15.586 12.414,11 17,6.414 15.586,5 11,9.586 Z" fill="#fff"/>
+</svg>
diff --git a/launcher/resources/breeze_dark/scalable/status-good.svg b/launcher/resources/breeze_dark/scalable/status-good.svg
new file mode 100644
index 00000000..eb8bc03b
--- /dev/null
+++ b/launcher/resources/breeze_dark/scalable/status-good.svg
@@ -0,0 +1,10 @@
+<svg id="svg9" version="1.1" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg">
+ <style id="current-color-scheme" type="text/css">.ColorScheme-PositiveText {
+ color:#27ae60;
+ }
+ .ColorScheme-Text {
+ color:#232629;
+ }</style>
+ <rect id="rect3" class="ColorScheme-PositiveText" x="3" y="3" width="16" height="16" rx="1.4545455" fill="currentColor"/>
+ <path id="path5" d="M 18.99323,4.3805651 9,14 5.7332785,10.623339 4.3852425,12.059327 9,16.828 l 10,-10 z" fill="#fff"/>
+</svg>
diff --git a/launcher/resources/breeze_dark/scalable/status-yellow.svg b/launcher/resources/breeze_dark/scalable/status-yellow.svg
new file mode 100644
index 00000000..1dc4d0f5
--- /dev/null
+++ b/launcher/resources/breeze_dark/scalable/status-yellow.svg
@@ -0,0 +1,9 @@
+<svg version="1.1" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-NeutralText {
+ color:#f67400;
+ }
+ </style>
+ <path class="ColorScheme-NeutralText" d="m11.006318 3.0000261a0.72728737 0.72727154 0 0 0-0.65674 0.4021811l-7.2728738 14.545431a0.72728737 0.72727154 0 0 0 0.6509222 1.052362h14.545748a0.72728737 0.72727154 0 0 0 0.650922-1.052362l-7.272874-14.545431a0.72728737 0.72727154 0 0 0-0.645104-0.4021811z" fill="currentColor"/>
+ <path d="m10 7v6h2v-6zm0 8v2h2v-2z" fill="#fff"/>
+</svg>
diff --git a/launcher/resources/breeze_dark/scalable/tag.svg b/launcher/resources/breeze_dark/scalable/tag.svg
new file mode 100644
index 00000000..b54b515f
--- /dev/null
+++ b/launcher/resources/breeze_dark/scalable/tag.svg
@@ -0,0 +1,17 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22">
+ <defs id="defs3051">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#eff0f1;
+ }
+ .ColorScheme-Highlight {
+ color:#3daee9;
+ }
+ </style>
+ </defs>
+ <path
+ style="fill:currentColor;fill-opacity:1;stroke:none"
+ d="M 9 3 L 3 5 L 5 11 L 15 16 L 19 8 L 9 3 z M 3 5 L 3 11 L 11 19 L 13.705078 16.294922 L 4 11 L 3 5 z M 6.5 5 C 7.331 5 8 5.669 8 6.5 C 8 7.331 7.331 8 6.5 8 C 5.669 8 5 7.331 5 6.5 C 5 5.669 5.669 5 6.5 5 z "
+ class="ColorScheme-Text"
+ />
+</svg>
diff --git a/launcher/resources/breeze_dark/scalable/viewfolder.svg b/launcher/resources/breeze_dark/scalable/viewfolder.svg
new file mode 100644
index 00000000..0189b954
--- /dev/null
+++ b/launcher/resources/breeze_dark/scalable/viewfolder.svg
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
+ <defs id="defs3051">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#eff0f1;
+ }
+ </style>
+ </defs>
+ <path style="fill:currentColor;fill-opacity:1;stroke:none"
+ d="m4 4v24h24l-1-1h-22v-13h5l3-3h14v16l1 1v-21h-10l-3-3z"
+ class="ColorScheme-Text"
+ />
+</svg>
diff --git a/launcher/resources/breeze_dark/scalable/worlds.svg b/launcher/resources/breeze_dark/scalable/worlds.svg
new file mode 100644
index 00000000..0cff8266
--- /dev/null
+++ b/launcher/resources/breeze_dark/scalable/worlds.svg
@@ -0,0 +1,16 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
+ <defs id="defs3051">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#eff0f1;
+ }
+ </style>
+ </defs>
+ <g transform="translate(0,-1036.3622)">
+ <path
+ style="fill:currentColor;fill-opacity:1;fill-rule:nonzero"
+ d="M 8 2 C 4.6862915 2 2 4.6862868 2 8 C 2 11.313713 4.6862915 14 8 14 C 11.313708 14 14 11.313713 14 8 C 14 4.6862868 11.313708 2 8 2 z M 8 3 C 8.172589 3 8.3319146 3.01418 8.5 3.03125 C 8.5403398 3.0352163 8.5849592 3.0263276 8.625 3.03125 C 8.6776214 3.0379183 8.7291519 3.0542091 8.78125 3.0625 C 8.9249022 3.0850796 9.0482753 3.1217241 9.1875 3.15625 C 9.4440966 3.2195469 9.6982233 3.3050445 9.9375 3.40625 C 10.069426 3.4620498 10.186649 3.5272356 10.3125 3.59375 C 10.312425 3.60275 10.3133 3.614 10.3125 3.625 C 10.34148 3.638 10.35728 3.69175 10.40625 3.71875 C 10.42423 3.72875 10.42056 3.741 10.4375 3.75 C 10.46648 3.766 10.50599 3.7835 10.5 3.8125 C 10.492 3.8525 10.43425 3.844 10.40625 3.875 C 10.41005 3.933 10.35871 3.92975 10.34375 3.96875 C 10.35275 3.99375 10.40229 4.00125 10.40625 4.03125 C 10.40135 4.06325 10.33173 4.06075 10.34375 4.09375 C 10.39776 4.13575 10.449004 4.10375 10.5 4.09375 C 10.611991 4.07975 10.712253 4.08825 10.78125 4.03125 C 10.77225 3.97825 10.88099 3.9856 10.875 3.9375 C 10.90366 3.9583822 10.9403 3.9788168 10.96875 4 C 10.957987 4.01008 10.949578 4.02585 10.9375 4.03125 C 10.91649 4.04125 10.89401 4.0505 10.875 4.0625 C 10.847 4.0805 10.81328 4.104 10.78125 4.125 C 10.75826 4.141 10.711504 4.21875 10.6875 4.21875 C 10.65851 4.21875 10.61475 4.1815 10.59375 4.1875 C 10.56372 4.1975 10.56519 4.238 10.53125 4.25 C 10.46526 4.274 10.335495 4.2135 10.3125 4.3125 C 10.3405 4.3695 10.450005 4.343 10.5 4.375 C 10.53102 4.395 10.58575 4.466 10.59375 4.5 C 10.60175 4.528 10.60574 4.6575 10.59375 4.6875 C 10.56273 4.7675 10.466988 4.751 10.375 4.75 L 10.3125 4.75 C 10.157516 4.74 10.007499 4.67025 9.9375 4.78125 C 9.94245 4.86625 9.95653 4.926 9.9375 5 C 9.92353 5.054 9.840752 5.10965 9.84375 5.15625 C 9.84485 5.18025 9.900255 5.216 9.90625 5.25 C 9.9101 5.268 9.89818 5.2955 9.90625 5.3125 C 9.932265 5.3615 9.9852535 5.3025 10.03125 5.3125 C 10.07525 5.3225 10.125 5.3883 10.125 5.4375 C 10.125 5.4725 10.11575 5.5286 10.09375 5.5625 C 10.04975 5.6285 9.969247 5.62025 9.90625 5.65625 C 9.854275 5.68625 9.843502 5.7609 9.8125 5.8125 C 9.7795 5.8685 9.736983 5.88865 9.75 5.96875 C 9.70501 6.05775 9.655488 6.11325 9.5625 6.15625 C 9.535495 6.16825 9.493747 6.1695 9.46875 6.1875 C 9.44873 6.2015 9.434272 6.24925 9.40625 6.28125 C 9.37127 6.32025 9.331497 6.345 9.3125 6.375 C 9.298475 6.398 9.29621 6.43675 9.28125 6.46875 C 9.25925 6.51075 9.215494 6.5203 9.1875 6.5625 C 9.17452 6.5825 9.17022 6.63025 9.15625 6.65625 C 9.12424 6.71425 9.087749 6.7615 9.09375 6.8125 C 9.0987 6.8605 9.153252 6.86225 9.15625 6.90625 C 9.159 6.93025 9.12401 6.94175 9.125 6.96875 C 9.1261 7.00675 9.15328 7.0325 9.15625 7.0625 C 9.16324 7.1365 9.10772 7.16815 9.09375 7.21875 C 9.08676 7.24275 9.09975 7.26125 9.09375 7.28125 C 9.08176 7.31825 9.032251 7.36205 9.03125 7.40625 C 9.03015 7.43725 9.09078 7.456 9.09375 7.5 C 9.09595 7.529 9.056505 7.56575 9.0625 7.59375 C 9.0735 7.64775 9.1767575 7.708 9.21875 7.75 C 9.275747 7.807 9.350008 7.84625 9.375 7.90625 C 9.39601 7.95725 9.398533 8.05565 9.4375 8.09375 C 9.466485 8.12175 9.525507 8.12625 9.5625 8.15625 C 9.59748 8.18325 9.619253 8.18875 9.65625 8.21875 C 9.717245 8.26675 9.809252 8.382 9.90625 8.375 C 9.957235 8.365 10.005504 8.3225 10.0625 8.3125 C 10.1215 8.3025 10.190006 8.27625 10.25 8.28125 C 10.29598 8.29125 10.358253 8.3155 10.40625 8.3125 C 10.45624 8.3025 10.505509 8.30625 10.5625 8.28125 C 10.6615 8.23825 10.824766 8.1668 10.96875 8.1875 C 11.078739 8.2035 11.079255 8.326 11.15625 8.375 C 11.24424 8.385 11.305007 8.358 11.375 8.375 C 11.42802 8.388 11.495001 8.4584 11.5 8.5 C 11.505 8.543 11.44349 8.5978 11.4375 8.625 C 11.42353 8.683 11.44746 8.74425 11.4375 8.78125 C 11.4295 8.81025 11.40526 8.846 11.40625 8.875 C 11.40625 8.901 11.44173 8.9658 11.46875 9 C 11.50175 9.042 11.55375 9.0798 11.59375 9.125 C 11.66674 9.209 11.699004 9.29525 11.75 9.40625 C 11.76298 9.43425 11.73801 9.464 11.75 9.5 C 11.728 9.6679 11.672491 9.78285 11.5625 9.96875 C 11.51052 10.02875 11.436499 10.08135 11.4375 10.15625 C 11.4337 10.33625 11.53925 10.451 11.53125 10.625 C 11.51327 10.8589 11.54929 10.8751 11.53125 11 C 11.61025 11.04 11.55424 11.1669 11.53125 11.25 C 11.49726 11.349 11.4565 11.3715 11.4375 11.4375 C 11.490583 11.460643 11.566021 11.451092 11.625 11.4375 C 11.595204 11.468874 11.561843 11.500657 11.53125 11.53125 C 11.305044 11.757456 11.047252 11.976543 10.78125 12.15625 C 10.265207 12.504882 9.6912413 12.769698 9.0625 12.90625 C 8.718961 12.980861 8.3658887 13 8 13 C 7.8096669 13 7.6218651 12.989959 7.4375 12.96875 C 7.2906389 12.951989 7.1427139 12.935453 7 12.90625 C 6.7168255 12.848304 6.4510281 12.728616 6.1875 12.625 C 6.1781304 12.60785 6.1541244 12.582618 6.15625 12.5625 C 6.208225 12.5405 6.305756 12.6365 6.34375 12.5625 C 6.36278 12.5275 6.318725 12.44125 6.34375 12.40625 C 6.361735 12.38225 6.463007 12.382 6.5 12.375 C 6.55302 12.365 6.626253 12.35775 6.65625 12.34375 C 6.68925 12.32275 6.724751 12.2491 6.71875 12.1875 C 6.716 12.1585 6.679185 12.151 6.65625 12.125 C 6.637275 12.103 6.66923 12.0835 6.65625 12.0625 C 6.63227 12.0275 6.572499 12.01975 6.5625 11.96875 C 6.634495 11.95475 6.7397615 12.029 6.84375 12 C 6.892755 11.986 6.976999 11.88985 7 11.84375 C 7.00699 11.82975 6.99202 11.79925 7 11.78125 C 7.00902 11.76325 7.028225 11.72875 7.03125 11.71875 C 7.03823 11.69175 7.02525 11.7055 7.03125 11.6875 C 7.049235 11.6365 7.094997 11.5988 7.125 11.5625 C 7.14799 11.5345 7.197723 11.49775 7.21875 11.46875 C 7.24273 11.43775 7.23405 11.43425 7.25 11.40625 C 7.265015 11.31525 7.19675 11.23615 7.21875 11.15625 C 7.24273 11.06625 7.381762 11.00975 7.46875 10.96875 C 7.498725 10.95475 7.537502 10.9465 7.5625 10.9375 C 7.622494 10.9165 7.6940045 10.895 7.75 10.875 C 7.843995 10.841 7.860248 10.7734 7.90625 10.6875 C 7.92825 10.6475 7.964735 10.5918 7.96875 10.5625 C 7.9726 10.5365 7.9638 10.531 7.96875 10.5 C 7.9737 10.471 7.960775 10.44025 7.96875 10.40625 C 7.97975 10.36325 8 10.26665 8 10.21875 C 8 10.17875 7.96974 10.161 7.96875 10.125 C 7.96176 9.995 8.014512 10.0085 8.0625 9.9375 C 8.08648 9.9025 8.10806 9.8376 8.125 9.8125 C 8.205993 9.6925 8.353749 9.65075 8.34375 9.46875 C 8.3399 9.40875 8.293978 9.269 8.25 9.25 C 8.224975 9.239 8.1932485 9.23175 8.15625 9.21875 C 8.0382585 9.17475 7.9354855 9.04125 7.8125 9.03125 L 7.75 9.03125 C 7.701985 9.03125 7.6477435 9.007 7.59375 9 C 7.55976 8.99 7.4887485 9.01 7.46875 9 C 7.43773 8.985 7.43122 8.92325 7.40625 8.90625 C 7.38623 8.89225 7.343493 8.886 7.3125 8.875 C 7.263495 8.857 7.2444965 8.8165 7.1875 8.8125 C 7.169515 8.8125 7.144982 8.8225 7.125 8.8125 C 7.09398 8.8025 7.060246 8.79925 7.03125 8.78125 C 6.99528 8.75925 6.952498 8.74975 6.9375 8.71875 C 6.9705 8.61085 6.86575 8.59425 6.84375 8.53125 C 6.83374 8.50225 6.85376 8.43225 6.84375 8.40625 C 6.83077 8.36925 6.791002 8.3435 6.75 8.3125 C 6.678005 8.2565 6.634243 8.23165 6.53125 8.21875 C 6.48527 8.20875 6.4299945 8.22875 6.375 8.21875 C 6.317008 8.20875 6.2314945 8.175 6.1875 8.125 C 6.14548 8.076 6.130744 8.0231 6.09375 8 C 6.05877 7.978 6.0239965 7.9605 6 7.9375 C 5.989 7.9275 5.97876 7.92925 5.96875 7.90625 C 5.950765 7.86925 5.9155 7.8575 5.9375 7.8125 C 5.897515 7.7925 5.917993 7.85075 5.875 7.84375 C 5.836005 7.78875 5.8067385 7.734 5.71875 7.75 C 5.678765 7.76 5.640747 7.84275 5.59375 7.84375 C 5.554755 7.84375 5.519746 7.758 5.46875 7.75 C 5.429755 7.74 5.3707495 7.78625 5.34375 7.78125 C 5.30074 7.77125 5.288973 7.74475 5.25 7.71875 C 5.221015 7.69975 5.17225 7.65525 5.15625 7.65625 C 5.106255 7.65625 5.0689915 7.75515 5 7.71875 C 4.96601 7.67575 5.071268 7.665 5.03125 7.625 C 5.001275 7.596 4.992763 7.64225 4.96875 7.65625 C 4.940755 7.67425 4.905993 7.6765 4.875 7.6875 C 4.806002 7.7135 4.7414935 7.721 4.6875 7.75 C 4.637505 7.776 4.622747 7.79245 4.59375 7.84375 C 4.57076 7.88575 4.534997 7.96675 4.5 7.96875 C 4.45798 7.96875 4.4442495 7.92325 4.40625 7.90625 C 4.2912615 7.85625 4.2199905 7.9355 4.125 7.9375 C 4.037006 7.9375 3.9022515 7.80175 3.90625 7.71875 C 3.909 7.66775 3.931505 7.59425 3.9375 7.53125 C 3.94245 7.48125 3.999065 7.4206 4 7.375 C 4.0011 7.313 3.883746 7.28835 3.84375 7.28125 C 3.749755 7.26425 3.6382415 7.32325 3.53125 7.28125 C 3.51123 7.24725 3.55051 7.2215 3.5625 7.1875 C 3.56948 7.1695 3.55551 7.146 3.5625 7.125 C 3.57449 7.093 3.641257 7.06525 3.65625 7.03125 C 3.66725 7.00525 3.64525 6.9705 3.65625 6.9375 C 3.66923 6.9015 3.715725 6.86975 3.71875 6.84375 C 3.7226 6.80975 3.6832 6.772 3.65625 6.75 C 3.573255 6.76 3.5167485 6.75725 3.46875 6.78125 C 3.360763 6.83025 3.3902435 6.966 3.28125 7 C 3.244235 7.012 3.198248 7.02425 3.15625 7.03125 C 3.137935 7.04125 3.11427 7.02925 3.09375 7.03125 C 3.0956963 7.0211336 3.0917443 7.0100944 3.09375 7 C 3.0984123 6.9772158 3.1200289 6.9601701 3.125 6.9375 C 3.1962653 6.6125035 3.3063949 6.2979344 3.4375 6 L 3.46875 6 C 3.506755 6.01 3.529505 6.0595 3.5625 6.0625 C 3.654493 6.0725 3.674001 5.9777 3.75 5.9375 C 3.827996 5.9485 3.866506 5.9275 3.9375 5.9375 C 3.985515 5.9475 4.055756 5.996 4.09375 6 C 4.12576 6 4.126248 5.96475 4.15625 5.96875 C 4.186225 5.97875 4.245 6.0265 4.25 6.0625 C 4.25495 6.1075 4.205715 6.16915 4.21875 6.21875 C 4.265775 6.26675 4.3705045 6.2845 4.4375 6.3125 C 4.4815 6.2755 4.44448 6.20825 4.4375 6.15625 C 4.4364 6.13325 4.44025 6.0835 4.4375 6.0625 C 4.43255 6.0265 4.40625 5.99975 4.40625 5.96875 C 4.40625 5.82575 4.5290085 5.77465 4.625 5.71875 C 4.665975 5.69475 4.7140025 5.643 4.75 5.625 C 4.800985 5.6 4.8330025 5.61775 4.875 5.59375 C 4.950988 5.55075 5.0035015 5.4862 5.0625 5.4375 C 5.089505 5.3725 5.05975 5.28275 5.0625 5.21875 C 5.089505 5.20175 5.127282 5.21875 5.15625 5.21875 C 5.20223 5.20875 5.223996 5.151 5.25 5.125 C 5.265015 5.11 5.294482 5.10875 5.3125 5.09375 C 5.35848 5.05775 5.366237 5.016 5.40625 5 C 5.420275 4.99 5.446723 4.97575 5.46875 4.96875 C 5.49878 4.95875 5.545757 4.9555 5.59375 4.9375 C 5.62477 4.9265 5.706749 4.91925 5.71875 4.90625 C 5.733765 4.89125 5.7149 4.8355 5.71875 4.8125 C 5.74273 4.6996 5.899009 4.69435 6 4.65625 C 6.069993 4.63025 6.1407545 4.5485 6.21875 4.5625 C 6.203735 4.6165 6.143249 4.6224 6.15625 4.6875 C 6.173245 4.7785 6.280501 4.66925 6.3125 4.65625 C 6.373495 4.63025 6.4825025 4.5925 6.5625 4.5625 C 6.632493 4.5375 6.753489 4.5181 6.6875 4.4375 C 6.6325 4.4275 6.6104935 4.48 6.5625 4.5 C 6.5295 4.51 6.527978 4.47175 6.5 4.46875 C 6.472995 4.46875 6.464527 4.505 6.4375 4.5 C 6.410495 4.49 6.378998 4.43925 6.375 4.40625 C 6.364 4.32225 6.43476 4.3119 6.46875 4.25 C 6.44576 4.174 6.3452425 4.2175 6.28125 4.1875 C 6.28824 4.1425 6.322007 4.10375 6.375 4.09375 C 6.41801 4.08375 6.5365015 4.102 6.5625 4.125 C 6.577515 4.138 6.5395595 4.1665 6.5625 4.1875 C 6.588515 4.2105 6.622254 4.1975 6.65625 4.1875 C 6.66824 4.1305 6.583751 4.162 6.59375 4.125 C 6.661741 4.081 6.792005 4.10475 6.875 4.09375 C 6.923015 4.08375 6.988251 4.05425 7.03125 4.03125 C 7.071235 4.00825 7.0830015 3.962 7.125 4 C 7.13699 4.041 7.116685 4.07175 7.09375 4.09375 C 7.016756 4.16175 6.934994 4.2336 6.875 4.3125 C 6.912015 4.3485 6.969254 4.33675 7.03125 4.34375 C 7.05523 4.35375 7.099997 4.33875 7.125 4.34375 C 7.15503 4.35375 7.194748 4.33375 7.21875 4.34375 C 7.26077 4.35375 7.270507 4.4375 7.3125 4.4375 C 7.380496 4.4375 7.351523 4.3577 7.3125 4.3125 C 7.32449 4.2655 7.3608 4.2207 7.34375 4.1875 C 7.31273 4.1255 7.1935005 4.206 7.1875 4.125 C 7.18365 4.075 7.231993 4.06925 7.25 4.03125 C 7.24202 3.93525 7.322499 3.93075 7.3125 3.84375 C 7.30755 3.80775 7.275008 3.81525 7.25 3.78125 C 7.23702 3.76325 7.23371 3.7015 7.21875 3.6875 C 7.166775 3.6435 7.0685005 3.67795 7.0625 3.59375 C 7.05975 3.54375 7.06948 3.4911 7.0625 3.4375 C 7.05551 3.3865 7.012728 3.22875 6.96875 3.21875 C 6.912755 3.20675 6.8794955 3.31245 6.8125 3.34375 C 6.77653 3.36075 6.693243 3.381 6.65625 3.375 C 6.63227 3.365 6.596753 3.3595 6.59375 3.3125 C 6.58979 3.2701 6.6405966 3.2512172 6.65625 3.21875 C 6.6601634 3.2106332 6.654259 3.19872 6.65625 3.1875 C 6.7288164 3.1672517 6.8012164 3.1422715 6.875 3.125 C 6.9169167 3.1152798 6.9576866 3.1024086 7 3.09375 C 7.0298771 3.0875279 7.0636852 3.0994569 7.09375 3.09375 C 7.2273044 3.0689879 7.3629458 3.0451686 7.5 3.03125 C 7.6662387 3.0137812 7.8289018 3 8 3 z M 5.96875 3.46875 C 5.9369162 3.6513239 5.7660026 3.7240206 5.5625 3.71875 C 5.51652 3.76275 5.55622 3.84525 5.53125 3.90625 C 5.51024 3.95725 5.425991 4.004 5.375 4 C 5.337985 4 5.28125 3.94125 5.28125 3.90625 C 5.28125 3.86325 5.349521 3.8617 5.3125 3.8125 C 5.31415 3.8025 5.333355 3.79125 5.34375 3.78125 C 5.3639901 3.7685049 5.3858533 3.762493 5.40625 3.75 C 5.5874525 3.6384834 5.7732114 3.5568279 5.96875 3.46875 z M 10.15625 3.65625 C 10.13782 3.66625 10.14122 3.6775 10.125 3.6875 C 10.08699 3.7105 10.06026 3.739 10.03125 3.75 C 9.99028 3.765 9.943504 3.7755 9.9375 3.8125 C 9.93255 3.8435 9.969795 3.846 9.96875 3.875 C 9.953735 3.912 9.94553 3.92375 9.9375 3.96875 C 9.988485 4.05175 10.093258 3.9505 10.15625 3.9375 C 10.18425 3.9275 10.20375 3.93025 10.21875 3.90625 C 10.23574 3.87925 10.23706 3.8507 10.25 3.8125 C 10.26403 3.7705 10.31751 3.75575 10.3125 3.71875 C 10.3087 3.68175 10.218244 3.65125 10.15625 3.65625 z M 4.6875 4.28125 C 4.7349118 4.319347 4.8015588 4.40185 4.71875 4.4375 C 4.70874 4.4475 4.5864965 4.47275 4.5625 4.46875 C 4.55282 4.46875 4.5397337 4.44475 4.53125 4.4375 C 4.5829129 4.3871923 4.6337069 4.3293033 4.6875 4.28125 z M 4.875 4.46875 C 4.89898 4.46875 4.909483 4.52925 4.9375 4.53125 C 4.964505 4.53125 4.983973 4.496 5 4.5 C 5.04202 4.511 5.071268 4.5938 5.03125 4.625 C 4.99825 4.635 4.992713 4.58975 4.96875 4.59375 C 4.900754 4.60575 4.8634955 4.754 4.8125 4.75 C 4.764485 4.74 4.732228 4.62875 4.78125 4.59375 C 4.78235 4.56375 4.779215 4.56225 4.78125 4.53125 C 4.796265 4.51325 4.834982 4.46575 4.875 4.46875 z M 4.625 4.5 C 4.639025 4.5 4.651245 4.49 4.65625 4.5 C 4.64927 4.553 4.634708 4.56875 4.59375 4.59375 C 4.522756 4.63675 4.460501 4.68975 4.4375 4.78125 C 4.43051 4.80825 4.3464955 4.8817 4.3125 4.875 C 4.233504 4.858 4.357015 4.7104 4.375 4.6875 C 4.39502 4.6625 4.414526 4.654 4.4375 4.625 C 4.46049 4.597 4.478055 4.54725 4.5 4.53125 C 4.52398 4.51425 4.5830075 4.498 4.625 4.5 z M 11.40625 4.65625 C 11.48524 4.64625 11.526502 4.73365 11.5625 4.78125 C 11.59248 4.82025 11.669746 4.87905 11.71875 4.90625 C 11.74675 4.92125 11.7815 4.95475 11.8125 4.96875 C 11.87749 4.99775 11.996996 5.09225 12 5.15625 C 12.0011 5.18825 11.96374 5.22 11.96875 5.25 C 12.01776 5.26 12.0615 5.1742 12.0625 5.125 C 12.15441 5.2550064 12.233102 5.3926596 12.3125 5.53125 C 12.35 5.5967067 12.402944 5.6512957 12.4375 5.71875 C 12.39339 5.73175 12.38209 5.73825 12.375 5.78125 C 12.36499 5.83725 12.39649 5.9276 12.3125 5.9375 C 12.25953 5.9475 12.19799 5.892 12.125 5.875 C 12.09502 5.865 12.05525 5.885 12.03125 5.875 C 11.97625 5.857 11.9845 5.7833 11.9375 5.75 C 11.91049 5.731 11.824253 5.6925 11.78125 5.6875 C 11.75424 5.6875 11.74673 5.6975 11.71875 5.6875 C 11.68476 5.6775 11.621749 5.7015 11.59375 5.6875 C 11.56674 5.6705 11.50701 5.61675 11.5 5.59375 C 11.489 5.55675 11.59175 5.5313 11.59375 5.5 C 11.59595 5.476 11.5675 5.44325 11.5625 5.40625 C 11.5587 5.38425 11.5674 5.35875 11.5625 5.34375 C 11.5555 5.31775 11.50974 5.3135 11.46875 5.3125 C 11.43272 5.3125 11.40599 5.3125 11.375 5.3125 C 11.331 5.3125 11.242494 5.3085 11.1875 5.3125 C 11.1545 5.3125 11.12475 5.3095 11.09375 5.3125 C 11.00676 5.3225 10.942997 5.3025 10.875 5.3125 C 10.82599 5.3125 10.733496 5.354 10.6875 5.375 C 10.66451 5.386 10.65501 5.39125 10.625 5.40625 C 10.61103 5.41625 10.58054 5.4295 10.5625 5.4375 C 10.53451 5.4505 10.49575 5.492 10.46875 5.5 C 10.42976 5.51 10.38349 5.49 10.3125 5.5 C 10.26152 5.5 10.188501 5.46725 10.1875 5.40625 C 10.1864 5.31325 10.349511 5.36075 10.4375 5.34375 C 10.4705 5.33375 10.49123 5.30525 10.53125 5.28125 C 10.55028 5.27025 10.54451 5.262 10.5625 5.25 C 10.59247 5.229 10.65125 5.18025 10.65625 5.15625 C 10.66005 5.13425 10.65323 5.11075 10.65625 5.09375 C 10.66005 5.07275 10.69175 5.05925 10.71875 5.03125 C 10.76077 4.98925 10.791747 4.93345 10.84375 4.90625 C 10.87873 4.88825 10.9215 4.87275 10.9375 4.84375 C 10.9413 4.81175 10.9364 4.81125 10.9375 4.78125 C 10.9595 4.76125 10.98202 4.754 11 4.75 C 11.05401 4.738 11.093259 4.753 11.15625 4.75 C 11.18325 4.75 11.221 4.763 11.25 4.75 C 11.27398 4.734 11.2885 4.6995 11.3125 4.6875 C 11.33851 4.6735 11.37422 4.65825 11.40625 4.65625 z M 11.96875 5.25 L 11.84375 5.25 C 11.79975 5.25 11.744749 5.227 11.71875 5.25 C 11.75577 5.31 11.823255 5.32875 11.90625 5.34375 C 11.93623 5.32175 11.95478 5.2883 11.96875 5.25 z M 5.125 4.6875 L 5.21875 4.6875 C 5.243775 4.6875 5.271251 4.6775 5.28125 4.6875 C 5.265245 4.7535 5.114497 4.74275 5.0625 4.71875 C 5.06525 4.69375 5.092968 4.6915 5.125 4.6875 z M 4.90625 4.8125 C 4.8625672 4.8442816 4.8193312 4.8845833 4.75 4.90625 C 4.711995 4.91825 4.663252 4.917 4.65625 4.875 C 4.64822 4.823 4.715988 4.84875 4.75 4.84375 C 4.794 4.83375 4.855254 4.8145 4.90625 4.8125 z M 11.40625 4.8125 C 11.37325 4.8235 11.35724 4.89625 11.40625 4.90625 C 11.42924 4.89225 11.44355 4.8555 11.4375 4.8125 C 11.42452 4.7985 11.41621 4.8025 11.40625 4.8125 z M 11.34375 4.96875 C 11.34485 5.02475 11.35475 5.0764 11.34375 5.125 C 11.37576 5.187 11.452756 5.13575 11.46875 5.09375 C 11.48778 4.98975 11.45425 4.95575 11.40625 4.96875 C 11.39025 4.97875 11.36069 4.95575 11.34375 4.96875 z M 3.0625 7.3125 C 3.118864 7.3635 3.1512925 7.43535 3.21875 7.46875 C 3.243775 7.48175 3.280501 7.492 3.3125 7.5 C 3.338515 7.51 3.350013 7.492 3.375 7.5 C 3.42802 7.518 3.4892575 7.5435 3.53125 7.5625 C 3.595248 7.5905 3.66375 7.68675 3.71875 7.71875 C 3.7215 7.75075 3.70874 7.7885 3.71875 7.8125 C 3.744765 7.8475 3.7704965 7.88225 3.8125 7.90625 C 3.863485 7.93425 3.8895065 7.9778 3.9375 8 C 3.954495 8.01 3.973963 7.99 4 8 C 4.065994 8.02 4.099253 8.11055 4.15625 8.09375 C 4.193265 8.08275 4.181505 8.036 4.1875 8 C 4.212525 7.973 4.242222 7.9375 4.28125 7.9375 C 4.34324 7.9375 4.351999 8.03315 4.375 8.09375 C 4.38798 8.12775 4.428535 8.1515 4.4375 8.1875 C 4.452515 8.2495 4.45048 8.43175 4.4375 8.46875 C 4.421495 8.51475 4.3504995 8.5122 4.3125 8.5625 C 4.294515 8.5865 4.29522 8.63925 4.28125 8.65625 C 4.25727 8.68525 4.236773 8.69075 4.21875 8.71875 C 4.20874 8.73375 4.196465 8.76025 4.1875 8.78125 C 4.15747 8.84525 4.099986 8.89175 4.125 8.96875 C 4.13501 8.99975 4.1875 9.0255 4.1875 9.0625 C 4.1875 9.1065 4.100751 9.1393 4.09375 9.1875 C 4.0888 9.2225 4.114055 9.2658 4.125 9.3125 C 4.13298 9.3475 4.197751 9.38325 4.21875 9.40625 C 4.25373 9.44525 4.280501 9.513 4.3125 9.5625 C 4.375491 9.6595 4.406765 9.78 4.46875 9.875 C 4.50175 9.924 4.57175 9.9484 4.59375 10 C 4.60475 10.026 4.58374 10.06975 4.59375 10.09375 C 4.62972 10.17475 4.794007 10.2726 4.875 10.3125 C 4.913005 10.3315 4.965009 10.32375 5 10.34375 C 5.05302 10.37375 5.160506 10.4534 5.1875 10.5 C 5.21148 10.542 5.20676 10.65185 5.21875 10.71875 C 5.233765 10.80675 5.2149 10.87365 5.21875 10.96875 C 5.2215 11.02075 5.25 11.04215 5.25 11.09375 C 5.25 11.11175 5.2511 11.1685 5.25 11.1875 C 5.2489 11.2495 5.25495 11.312 5.25 11.375 C 5.24725 11.409 5.2478 11.43975 5.25 11.46875 C 5.25275 11.49975 5.27927 11.50325 5.28125 11.53125 C 5.28345 11.56025 5.246975 11.602 5.25 11.625 C 5.25699 11.688 5.300499 11.72315 5.3125 11.78125 C 5.32251 11.82725 5.349745 11.945 5.34375 12 C 5.3399 12.029 5.316515 12.06075 5.3125 12.09375 C 5.30975 12.11975 5.31635 12.13225 5.3125 12.15625 C 5.30975 12.17925 5.31844 12.19975 5.3125 12.21875 C 5.2806543 12.198271 5.2500951 12.177426 5.21875 12.15625 C 4.9527483 11.976543 4.6949555 11.757456 4.46875 11.53125 C 4.4381566 11.500657 4.4047959 11.468874 4.375 11.4375 C 4.1944191 11.247353 4.0241375 11.029182 3.875 10.8125 C 3.8614865 10.792866 3.8569888 10.769835 3.84375 10.75 C 3.6707036 10.490733 3.5290643 10.227866 3.40625 9.9375 C 3.3973945 9.9165633 3.3835772 9.8960813 3.375 9.875 C 3.2696226 9.6160011 3.1860736 9.3410185 3.125 9.0625 C 3.1134736 9.0099352 3.1036081 8.9594198 3.09375 8.90625 C 3.0689879 8.7726956 3.0451686 8.6370542 3.03125 8.5 C 3.01418 8.3319146 3 8.172589 3 8 C 3 7.7623582 3.030436 7.5413039 3.0625 7.3125 z M 5 7.84375 C 5.048015 7.82175 5.038995 7.89925 5 7.90625 C 4.962985 7.91625 4.96403 7.86175 5 7.84375 z " transform="translate(0,1036.3622)"
+ id="path26"
+ class="ColorScheme-Text"/>
+ </g>
+</svg>
diff --git a/launcher/resources/breeze_light/breeze_light.qrc b/launcher/resources/breeze_light/breeze_light.qrc
new file mode 100644
index 00000000..6d868b18
--- /dev/null
+++ b/launcher/resources/breeze_light/breeze_light.qrc
@@ -0,0 +1,44 @@
+<RCC>
+ <qresource prefix="/icons/breeze_light">
+ <file>index.theme</file>
+ <file>scalable/about.svg</file>
+ <file>scalable/accounts.svg</file>
+ <file>scalable/bug.svg</file>
+ <file>scalable/centralmods.svg</file>
+ <file>scalable/checkupdate.svg</file>
+ <file>scalable/copy.svg</file>
+ <file>scalable/coremods.svg</file>
+ <file>scalable/custom-commands.svg</file>
+ <file>scalable/discord.svg</file>
+ <file>scalable/externaltools.svg</file>
+ <file>scalable/help.svg</file>
+ <file>scalable/instance-settings.svg</file>
+ <file>scalable/jarmods.svg</file>
+ <file>scalable/java.svg</file>
+ <file>scalable/language.svg</file>
+ <file>scalable/loadermods.svg</file>
+ <file>scalable/log.svg</file>
+ <file>scalable/minecraft.svg</file>
+ <file>scalable/new.svg</file>
+ <file>scalable/news.svg</file>
+ <file>scalable/notes.svg</file>
+ <file>scalable/proxy.svg</file>
+ <file>scalable/reddit-alien.svg</file>
+ <file>scalable/refresh.svg</file>
+ <file>scalable/resourcepacks.svg</file>
+ <file>scalable/shaderpacks.svg</file>
+ <file>scalable/shortcut.svg</file>
+ <file>scalable/screenshots.svg</file>
+ <file>scalable/settings.svg</file>
+ <file>scalable/status-bad.svg</file>
+ <file>scalable/status-good.svg</file>
+ <file>scalable/status-yellow.svg</file>
+ <file>scalable/viewfolder.svg</file>
+ <file>scalable/worlds.svg</file>
+ <file>scalable/delete.svg</file>
+ <file>scalable/tag.svg</file>
+ <file>scalable/export.svg</file>
+ <file>scalable/rename.svg</file>
+ <file>scalable/launch.svg</file>
+ </qresource>
+</RCC>
diff --git a/launcher/resources/breeze_light/index.theme b/launcher/resources/breeze_light/index.theme
new file mode 100644
index 00000000..126d42d7
--- /dev/null
+++ b/launcher/resources/breeze_light/index.theme
@@ -0,0 +1,11 @@
+[Icon Theme]
+Name=Breeze Light
+Comment=Breeze Light Icons
+Inherits=multimc
+Directories=scalable
+
+[scalable]
+Size=48
+Type=Scalable
+MinSize=16
+MaxSize=256
diff --git a/launcher/resources/breeze_light/scalable/about.svg b/launcher/resources/breeze_light/scalable/about.svg
new file mode 100644
index 00000000..ea1dc02c
--- /dev/null
+++ b/launcher/resources/breeze_light/scalable/about.svg
@@ -0,0 +1,12 @@
+<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#232629;
+ }
+ </style>
+ <g class="ColorScheme-Text" fill="currentColor" fill-rule="evenodd">
+ <path d="m8 2a6 6 0 0 0 -6 6 6 6 0 0 0 6 6 6 6 0 0 0 6-6 6 6 0 0 0 -6-6zm0 1a5 5 0 0 1 5 5 5 5 0 0 1 -5 5 5 5 0 0 1 -5-5 5 5 0 0 1 5-5z"/>
+ <path d="m7 4h2v2h-2z"/>
+ <path d="m7 7h2v5h-2z"/>
+ </g>
+</svg>
diff --git a/launcher/resources/breeze_light/scalable/accounts.svg b/launcher/resources/breeze_light/scalable/accounts.svg
new file mode 100644
index 00000000..8a542f36
--- /dev/null
+++ b/launcher/resources/breeze_light/scalable/accounts.svg
@@ -0,0 +1,17 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
+ <defs
+ id="defs3051">
+ <style
+ type="text/css"
+ id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#232629;
+ }
+ </style>
+ </defs>
+ <path
+ style="fill:currentColor;fill-opacity:1;stroke:none"
+ d="M 20.5,4 A 4.5,4.5 0 0 0 16,8.5 4.5,4.5 0 0 0 20.5,13 4.5,4.5 0 0 0 25,8.5 4.5,4.5 0 0 0 20.5,4 Z m 0,1 A 3.5,3.5 0 0 1 24,8.5 3.5,3.5 0 0 1 20.5,12 3.5,3.5 0 0 1 17,8.5 3.5,3.5 0 0 1 20.5,5 Z m -9,4 C 9.014719,9 7,11.01472 7,13.5 7,15.98528 9.014719,18 11.5,18 13.985281,18 16,15.98528 16,13.5 16,11.01472 13.985281,9 11.5,9 Z m 0,1 A 3.5,3.5 0 0 1 15,13.5 3.5,3.5 0 0 1 11.5,17 3.5,3.5 0 0 1 8,13.5 3.5,3.5 0 0 1 11.5,10 Z m 9,4 c -0.88285,0.003 -1.758266,0.17228 -2.585938,0.5 -0.06618,0.42368 -0.174132,0.83977 -0.322265,1.24219 C 18.494507,15.25488 19.490227,15.00077 20.5,15 c 3.589851,0 6.5,3.13401 6.5,7 l -8.341797,0 c 0.170323,0.32329 0.325499,0.65711 0.464844,1 L 28,23 28,22 c 0,-4.41828 -3.357864,-8 -7.5,-8 z m -9,5 C 7.357864,19 4,22.58172 4,27 l 0,1 15,0 0,-1 c 0,-4.41828 -3.357864,-8 -7.5,-8 z m 0,1 c 3.589851,0 6.5,3.13401 6.5,7 L 5,27 c 0,-3.86599 2.910149,-7 6.5,-7 z"
+ class="ColorScheme-Text"
+ />
+</svg>
diff --git a/launcher/resources/breeze_light/scalable/bug.svg b/launcher/resources/breeze_light/scalable/bug.svg
new file mode 100644
index 00000000..4f41ad6b
--- /dev/null
+++ b/launcher/resources/breeze_light/scalable/bug.svg
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
+ <defs id="defs3051">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#232629;
+ }
+ </style>
+ </defs>
+ <path style="fill:currentColor;fill-opacity:1;stroke:none"
+ d="m2 2v12h12v-12zm1 1h10v10h-10zm1 2v2h2v-2zm6 0v2h2v-2zm-4 4v1h4v-1zm4 1v1h1v-1zm1 1v1h1v-1zm-5-1h-1v1h1zm-1 1h-1v1h1z"
+ class="ColorScheme-Text"
+ />
+</svg>
diff --git a/launcher/resources/breeze_light/scalable/centralmods.svg b/launcher/resources/breeze_light/scalable/centralmods.svg
new file mode 100644
index 00000000..4035e51c
--- /dev/null
+++ b/launcher/resources/breeze_light/scalable/centralmods.svg
@@ -0,0 +1 @@
+<svg width="8" height="8" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M3 3.5v.25h-.5V6h3V3.75H5V3.5h-.75v.25h-.5V3.5H3Zm-.25.5h2.5v1.75h-2.5V4Z" fill="#EFF0F1"/><path d="M1 1v6h6l-.25-.25h-5.5V3.5H2.5l.75-.75h3.5v4L7 7V1.75H4.5L3.75 1H1Z" fill="#EFF0F1"/></svg> \ No newline at end of file
diff --git a/launcher/resources/breeze_light/scalable/checkupdate.svg b/launcher/resources/breeze_light/scalable/checkupdate.svg
new file mode 100644
index 00000000..06b31827
--- /dev/null
+++ b/launcher/resources/breeze_light/scalable/checkupdate.svg
@@ -0,0 +1,14 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
+ <defs id="defs3051">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#232629;
+ }
+ </style>
+ </defs>
+ <path
+ style="fill:currentColor"
+ d="M 6 2 L 6 3 L 6 6 L 7 6 L 7 3 L 9 3 L 9 6 L 10 6 L 10 3 L 10 2 L 6 2 z M 3.7 6 L 3 6.7 L 6.3 10 L 8 11.7 L 9.7 10 L 13 6.7 L 12.3 6 L 9 9.3 L 8 10.3 L 7 9.3 L 3.7 6 z M 2 12 L 2 14 L 3 14 L 14 14 L 14 13 L 14 12 L 13 12 L 13 13 L 3 13 L 3 12 L 2 12 z "
+ class="ColorScheme-Text"
+ />
+</svg>
diff --git a/launcher/resources/breeze_light/scalable/copy.svg b/launcher/resources/breeze_light/scalable/copy.svg
new file mode 100644
index 00000000..2557953b
--- /dev/null
+++ b/launcher/resources/breeze_light/scalable/copy.svg
@@ -0,0 +1,11 @@
+<!DOCTYPE svg>
+<svg viewBox="0 0 22 22" version="1.1" xmlns="http://www.w3.org/2000/svg">
+ <defs>
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#232629;
+ }
+ </style>
+ </defs>
+ <path class="ColorScheme-Text" style="fill:currentColor; fill-opacity:1; stroke:none" d="M 3 3 L 3 17 L 7 17 L 7 19 L 17 19 L 17 10 L 13 6 L 12 6 L 9 3 L 3 3 Z M 4 4 L 8 4 L 8 6 L 7 6 L 7 16 L 4 16 L 4 4 Z M 8 7 L 12 7 L 12 11 L 16 11 L 16 18 L 8 18 L 8 7 Z"/>
+</svg>
diff --git a/launcher/resources/breeze_light/scalable/coremods.svg b/launcher/resources/breeze_light/scalable/coremods.svg
new file mode 100644
index 00000000..ec4ecea8
--- /dev/null
+++ b/launcher/resources/breeze_light/scalable/coremods.svg
@@ -0,0 +1 @@
+<svg width="8" height="8" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M3.167 2.46v.208H2.75v1.875h2.5V2.668h-.417V2.46h-.625v.208h-.416V2.46h-.625Zm-.209.417h2.084v1.458H2.958V2.877Z" fill="#EFF0F1"/><path d="M1.5 1v6h5V1h-5Zm1.5.5h2a1 1 0 0 1 1 1V3a.5.5 0 1 0 0 1v1l-.5.5h-3L2 5V4a.5.5 0 1 0 0-1v-.5a1 1 0 0 1 1-1ZM2 6h2v.5H2V6Zm3 0h1v.5H5V6Z" fill="#EFF0F1"/></svg> \ No newline at end of file
diff --git a/launcher/resources/breeze_light/scalable/custom-commands.svg b/launcher/resources/breeze_light/scalable/custom-commands.svg
new file mode 100644
index 00000000..b2ac78c5
--- /dev/null
+++ b/launcher/resources/breeze_light/scalable/custom-commands.svg
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
+ <defs id="defs3051">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#232629;
+ }
+ </style>
+ </defs>
+ <path style="fill:currentColor;fill-opacity:1;stroke:none"
+ d="M 2 2 L 2 14 L 14 14 L 14 2 L 2 2 z M 3 3 L 13 3 L 13 13 L 3 13 L 3 3 z M 4.71875 4 L 4 4.6875 L 6.625 7.5 L 4.03125 10.3125 L 4.71875 11 L 7.6875 7.84375 L 8 7.5 L 7.6875 7.15625 L 4.71875 4 z M 8 11 L 8 12 L 12 12 L 12 11 L 8 11 z "
+ class="ColorScheme-Text"
+ />
+</svg>
diff --git a/launcher/resources/breeze_light/scalable/delete.svg b/launcher/resources/breeze_light/scalable/delete.svg
new file mode 100644
index 00000000..f2aea6e8
--- /dev/null
+++ b/launcher/resources/breeze_light/scalable/delete.svg
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
+ <defs id="defs3051">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#232629;
+ }
+ </style>
+ </defs>
+ <path
+ style="fill:currentColor;fill-opacity:1;stroke:none"
+ d="M 6 2 L 6 3 L 2 3 L 2 4 L 3 4 L 3 14 L 4 14 L 13 14 L 13 13 L 13 4 L 14 4 L 14 3 L 10 3 L 10 2 L 6 2 z M 7 3 L 9 3 L 9 4 L 10 4 L 12 4 L 12 13 L 4 13 L 4 4 L 7 4 L 7 3 z M 6 6 L 6 11 L 7 11 L 7 6 L 6 6 z M 9 6 L 9 11 L 10 11 L 10 6 L 9 6 z "
+ class="ColorScheme-Text"/>
+</svg>
diff --git a/launcher/resources/breeze_light/scalable/discord.svg b/launcher/resources/breeze_light/scalable/discord.svg
new file mode 100644
index 00000000..22ee27ba
--- /dev/null
+++ b/launcher/resources/breeze_light/scalable/discord.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 127.14 96.36"><defs><style>.cls-1{fill:#fff;}</style></defs><g id="图层_2" data-name="图层 2"><g id="Discord_Logos" data-name="Discord Logos"><g id="Discord_Logo_-_Large_-_White" data-name="Discord Logo - Large - White"><path class="cls-1" d="M107.7,8.07A105.15,105.15,0,0,0,81.47,0a72.06,72.06,0,0,0-3.36,6.83A97.68,97.68,0,0,0,49,6.83,72.37,72.37,0,0,0,45.64,0,105.89,105.89,0,0,0,19.39,8.09C2.79,32.65-1.71,56.6.54,80.21h0A105.73,105.73,0,0,0,32.71,96.36,77.7,77.7,0,0,0,39.6,85.25a68.42,68.42,0,0,1-10.85-5.18c.91-.66,1.8-1.34,2.66-2a75.57,75.57,0,0,0,64.32,0c.87.71,1.76,1.39,2.66,2a68.68,68.68,0,0,1-10.87,5.19,77,77,0,0,0,6.89,11.1A105.25,105.25,0,0,0,126.6,80.22h0C129.24,52.84,122.09,29.11,107.7,8.07ZM42.45,65.69C36.18,65.69,31,60,31,53s5-12.74,11.43-12.74S54,46,53.89,53,48.84,65.69,42.45,65.69Zm42.24,0C78.41,65.69,73.25,60,73.25,53s5-12.74,11.44-12.74S96.23,46,96.12,53,91.08,65.69,84.69,65.69Z"/></g></g></g></svg> \ No newline at end of file
diff --git a/launcher/resources/breeze_light/scalable/export.svg b/launcher/resources/breeze_light/scalable/export.svg
new file mode 100644
index 00000000..d6314bd7
--- /dev/null
+++ b/launcher/resources/breeze_light/scalable/export.svg
@@ -0,0 +1,11 @@
+<!DOCTYPE svg>
+<svg viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg">
+ <defs>
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#232629;
+ }
+ </style>
+ </defs>
+ <path class="ColorScheme-Text" style="fill:currentColor; fill-opacity:1; stroke:none" d="M 7 12 L 11.0859 12 L 9.46484 13.6211 L 10.1719 14.3281 L 13 11.5 L 10.1719 8.67187 L 9.46484 9.37891 L 11.0859 11 L 7 11 L 7 12 Z M 4 13 L 4 3 L 9 3 L 9 6 L 12 6 L 12 9 L 13 9 L 13 5 L 10 2 L 3 2 L 3 14 L 8 14 L 8 13 L 4 13 Z"/>
+</svg>
diff --git a/launcher/resources/breeze_light/scalable/externaltools.svg b/launcher/resources/breeze_light/scalable/externaltools.svg
new file mode 100644
index 00000000..c965b6c3
--- /dev/null
+++ b/launcher/resources/breeze_light/scalable/externaltools.svg
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
+ <defs id="defs3051">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#232629;
+ }
+ </style>
+ </defs>
+ <path style="fill:currentColor;fill-opacity:1;stroke:none"
+ d="M 4 5 L 4 7 L 2 7 L 2 8 L 4 8 L 4 10 L 5 10 L 7 10 L 7 9 L 5 9 L 5 6 L 7 6 L 7 5 L 5 5 L 4 5 z M 9 5 L 9 6 L 11 6 L 11 9 L 9 9 L 9 10 L 11 10 L 12 10 L 12 9 L 12 8 L 14 8 L 14 7 L 12 7 L 12 6 L 12 5 L 11 5 L 9 5 z M 7 7 L 7 8 L 9 8 L 9 7 L 7 7 z "
+ class="ColorScheme-Text"
+ />
+</svg>
diff --git a/launcher/resources/breeze_light/scalable/help.svg b/launcher/resources/breeze_light/scalable/help.svg
new file mode 100644
index 00000000..bcd14e05
--- /dev/null
+++ b/launcher/resources/breeze_light/scalable/help.svg
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22">
+ <defs id="defs3051">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#232629;
+ }
+ </style>
+ </defs>
+ <path style="fill:currentColor;fill-opacity:1;stroke:none"
+ d="M 3 4 L 3 16 L 6 20 L 6 17 L 6 16 L 19 16 L 19 4 L 3 4 z M 4 5 L 18 5 L 18 15 L 4 15 L 4 5 z M 10.5 6 A 2.5 2.5 0 0 0 8 8.5 L 8 9 L 9 9 L 9 8.5 A 1.5 1.5 0 0 1 10.5 7 A 1.5 1.5 0 0 1 12 8.5 A 1.5 1.5 0 0 1 10.5 10 L 10 10 L 10 12 L 11 12 L 11 10.949219 A 2.5 2.5 0 0 0 13 8.5 A 2.5 2.5 0 0 0 10.5 6 z M 10 13 L 10 14 L 11 14 L 11 13 L 10 13 z "
+ class="ColorScheme-Text"
+ />
+</svg>
diff --git a/launcher/resources/breeze_light/scalable/instance-settings.svg b/launcher/resources/breeze_light/scalable/instance-settings.svg
new file mode 100644
index 00000000..69854d73
--- /dev/null
+++ b/launcher/resources/breeze_light/scalable/instance-settings.svg
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
+ <defs id="defs3051">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#232629;
+ }
+ </style>
+ </defs>
+ <path style="fill:currentColor;fill-opacity:1;stroke:none"
+ d="M 2 2 L 2 5 L 2 14 L 3 14 L 14 14 L 14 13 L 14 2 L 3 2 L 2 2 z M 3 5 L 13 5 L 13 13 L 3 13 L 3 5 z M 4 6 L 4 12 L 6 12 L 6 6 L 4 6 z M 7 7 L 7 8 L 12 8 L 12 7 L 7 7 z M 7 10 L 7 11 L 12 11 L 12 10 L 7 10 z "
+ class="ColorScheme-Text"
+ />
+</svg>
diff --git a/launcher/resources/breeze_light/scalable/jarmods.svg b/launcher/resources/breeze_light/scalable/jarmods.svg
new file mode 100644
index 00000000..49a45d36
--- /dev/null
+++ b/launcher/resources/breeze_light/scalable/jarmods.svg
@@ -0,0 +1 @@
+<svg width="8" height="8" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M2 1.5V2H1v4.5h6V2H6v-.5H4.5V2h-1v-.5H2Zm-.5 1h5V6h-5V2.5Z" fill="#EFF0F1"/><path d="M3.93 4.37s-.19-.364-.183-.63c.005-.19.434-.378.603-.651.168-.273-.022-.54-.022-.54s.043.197-.07.4c-.112.203-.525.322-.686.672-.16.35.357.75.357.75Z" fill="#EFF0F1"/><path d="M4.637 3.264s-.645.246-.645.525c0 .28.175.372.203.463.028.091-.049.245-.049.245s.252-.175.21-.378c-.042-.203-.238-.267-.126-.47.075-.136.407-.385.407-.385Z" fill="#EFF0F1"/><path d="M3.859 4.741c.595-.021.812-.209.812-.209-.385.105-1.407.098-1.415.021-.006-.077.316-.14.316-.14s-.505 0-.546.126c-.043.126.238.223.833.202ZM4.72 5.036s.583-.124.526-.44c-.07-.386-.477-.169-.477-.169s.288 0 .316.175c.028.175-.364.434-.364.434ZM4.434 4.868s-.147.038-.364.063c-.292.033-.645.007-.673-.042-.028-.05.05-.077.05-.077-.35.084-.16.23.251.26.352.023.876-.106.876-.106l-.14-.098ZM3.53 5.174s-.159.004-.168.088c-.01.084.098.159.49.182.392.024.668-.107.668-.107l-.178-.107s-.112.023-.285.046c-.173.024-.527-.018-.541-.051-.014-.032.014-.051.014-.051Z" fill="#EFF0F1"/><path d="M5.057 5.552c.06-.065-.019-.117-.019-.117s.028.033-.009.07c-.037.037-.378.13-.924.158-.546.028-1.14-.05-1.159-.121-.018-.07.304-.126.304-.126-.037.005-.485.014-.5.136-.013.12.197.22 1.037.22.84 0 1.21-.155 1.27-.22Z" fill="#EFF0F1"/><path d="M4.73 5.828c-.368.074-1.489.027-1.489.027s.728.173 1.56.029c.397-.07.42-.262.42-.262s-.122.13-.49.206Z" fill="#EFF0F1"/></svg> \ No newline at end of file
diff --git a/launcher/resources/breeze_light/scalable/java.svg b/launcher/resources/breeze_light/scalable/java.svg
new file mode 100644
index 00000000..ff86c9cc
--- /dev/null
+++ b/launcher/resources/breeze_light/scalable/java.svg
@@ -0,0 +1,10 @@
+<svg width="1000" height="1000" viewBox="0 0 1000 1000" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M479.6 536.2C479.6 536.2 425 430.9 427 354C428.5 299 552.4 244.7 601.1 165.8C649.7 86.9 595 10 595 10C595 10 607.2 66.7 574.8 125.3C542.4 184 422.9 218.5 376.4 319.6C329.9 420.9 479.6 536.2 479.6 536.2Z" fill="#232629"/>
+<path d="M684.099 216.4C684.099 216.4 497.899 287.3 497.899 368.2C497.899 449.2 548.499 475.5 556.599 501.8C564.699 528.2 542.399 572.7 542.399 572.7C542.399 572.7 615.199 522.1 602.999 463.4C590.799 404.7 534.199 386.4 566.599 327.8C588.399 288.4 684.099 216.4 684.099 216.4Z" fill="#232629"/>
+<path d="M459.399 643.2C631.499 637.1 694.2 582.8 694.2 582.8C582.9 613.1 287.399 611.1 285.299 588.9C283.299 566.6 376.399 548.4 376.399 548.4C376.399 548.4 230.7 548.4 218.6 584.8C206.4 621.2 287.499 649.2 459.399 643.2Z" fill="#232629"/>
+<path d="M708.399 728.5C708.399 728.5 876.799 692.6 860.099 601.1C839.899 489.7 722.499 552.5 722.499 552.5C722.499 552.5 805.599 552.5 813.599 603.1C821.699 653.6 708.399 728.5 708.399 728.5Z" fill="#232629"/>
+<path d="M625.4 679.9C625.4 679.9 583 691 520.1 698.1C435.8 707.6 333.9 700.1 325.8 685.9C317.8 671.7 340 663.7 340 663.7C238.8 688 294.2 730.4 412.8 738.6C514.5 745.5 665.9 708.2 665.9 708.2L625.4 679.9Z" fill="#232629"/>
+<path d="M364.299 768.3C364.299 768.3 318.399 769.6 315.699 793.9C313.099 818 343.999 839.7 457.299 846.5C570.599 853.2 650.299 815.5 650.299 815.5L598.999 784.4C598.999 784.4 566.599 791.2 516.699 797.9C466.699 804.7 364.299 792.5 360.199 783.1C356.199 773.7 364.299 768.3 364.299 768.3Z" fill="#232629"/>
+<path d="M805.5 877.6C823 858.7 800.099 843.8 800.099 843.8C800.099 843.8 808.2 853.3 797.5 864C786.7 874.8 688.199 901.7 530.299 909.8C372.499 917.9 201.1 895 195.6 874.7C190.3 854.5 283.4 838.3 283.4 838.3C272.6 839.6 143.1 842.3 139 877.5C135 912.5 195.7 940.9 438.6 940.9C681.4 941 788 896.4 805.5 877.6Z" fill="#232629"/>
+<path d="M711.099 957.2C604.499 978.7 280.699 965.2 280.699 965.2C280.699 965.2 491.099 1015.2 731.299 973.4C846.099 953.4 852.799 897.8 852.799 897.8C852.799 897.8 817.699 935.6 711.099 957.2Z" fill="#232629"/>
+</svg>
diff --git a/launcher/resources/breeze_light/scalable/language.svg b/launcher/resources/breeze_light/scalable/language.svg
new file mode 100644
index 00000000..3d56d33e
--- /dev/null
+++ b/launcher/resources/breeze_light/scalable/language.svg
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
+ <defs id="defs3051">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#232629;
+ }
+ </style>
+ </defs>
+ <path style="fill:currentColor;fill-opacity:1;stroke:none"
+ d="M 2 2 L 2 3 L 2 8 L 3 8 L 6 8 L 6 10 L 6 11 L 9 14 L 9 11 L 13 11 L 14 11 L 14 6 L 14 5 L 13 5 L 10 5 L 10 2 L 3 2 L 2 2 z M 3 3 L 9 3 L 9 5 L 9 6 L 9 7 L 7 7 L 6 7 L 3 7 L 3 3 z M 10 6 L 13 6 L 13 10 L 8 10 L 7 10 L 7 8 L 8 8 L 8 10 L 10 8 L 10 7 L 10 6 z "
+ class="ColorScheme-Text"
+ />
+</svg>
diff --git a/launcher/resources/breeze_light/scalable/launch.svg b/launcher/resources/breeze_light/scalable/launch.svg
new file mode 100644
index 00000000..678fd098
--- /dev/null
+++ b/launcher/resources/breeze_light/scalable/launch.svg
@@ -0,0 +1,8 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#232629;
+ }
+ </style>
+ <path d="m2 2v12l12-6z" class="ColorScheme-Text" fill="currentColor"/>
+</svg>
diff --git a/launcher/resources/breeze_light/scalable/loadermods.svg b/launcher/resources/breeze_light/scalable/loadermods.svg
new file mode 100644
index 00000000..4fb0f96d
--- /dev/null
+++ b/launcher/resources/breeze_light/scalable/loadermods.svg
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
+ <defs id="defs3051">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#232629;
+ }
+ </style>
+ </defs>
+ <path
+ style="fill:currentColor;fill-opacity:1;stroke:none"
+ d="m4 3v1h-2v9h12v-9h-2v-1h-3v1h-2v-1zm-1 2h10v7h-10z"
+ class="ColorScheme-Text"/>
+</svg>
diff --git a/launcher/resources/breeze_light/scalable/log.svg b/launcher/resources/breeze_light/scalable/log.svg
new file mode 100644
index 00000000..cf9c9b22
--- /dev/null
+++ b/launcher/resources/breeze_light/scalable/log.svg
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
+ <defs id="defs3051">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#232629;
+ }
+ </style>
+ </defs>
+ <path style="fill:currentColor;fill-opacity:1;stroke:none"
+ d="M 11 2 L 11 14 L 14 14 L 14 2 L 11 2 z M 6 5 L 6 14 L 9 14 L 9 5 L 6 5 z M 1 8 L 1 14 L 4 14 L 4 8 L 1 8 z "
+ class="ColorScheme-Text"
+ />
+</svg>
diff --git a/launcher/resources/breeze_light/scalable/matrix.svg b/launcher/resources/breeze_light/scalable/matrix.svg
new file mode 100644
index 00000000..4745efc1
--- /dev/null
+++ b/launcher/resources/breeze_light/scalable/matrix.svg
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg version="1.1" viewBox="0 0 27.9 32" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+ <title>Matrix (protocol) logo</title>
+ <g transform="translate(-.095 .005)" fill="#232629">
+ <path d="m27.1 31.2v-30.5h-2.19v-0.732h3.04v32h-3.04v-0.732z"/>
+ <path d="m8.23 10.4v1.54h0.044c0.385-0.564 0.893-1.03 1.49-1.37 0.58-0.323 1.25-0.485 1.99-0.485 0.72 0 1.38 0.14 1.97 0.42 0.595 0.279 1.05 0.771 1.36 1.48 0.338-0.5 0.796-0.941 1.38-1.32 0.58-0.383 1.27-0.574 2.06-0.574 0.602 0 1.16 0.074 1.67 0.22 0.514 0.148 0.954 0.383 1.32 0.707 0.366 0.323 0.653 0.746 0.859 1.27 0.205 0.522 0.308 1.15 0.308 1.89v7.63h-3.13v-6.46c0-0.383-0.015-0.743-0.044-1.08-0.0209-0.307-0.103-0.607-0.242-0.882-0.133-0.251-0.336-0.458-0.584-0.596-0.257-0.146-0.606-0.22-1.05-0.22-0.44 0-0.796 0.085-1.07 0.253-0.272 0.17-0.485 0.39-0.639 0.662-0.159 0.287-0.264 0.602-0.308 0.927-0.052 0.347-0.078 0.697-0.078 1.05v6.35h-3.13v-6.4c0-0.338-7e-3 -0.673-0.021-1-0.0114-0.314-0.0749-0.623-0.188-0.916-0.108-0.277-0.3-0.512-0.55-0.673-0.258-0.168-0.636-0.253-1.14-0.253-0.198 0.0083-0.394 0.042-0.584 0.1-0.258 0.0745-0.498 0.202-0.705 0.374-0.228 0.184-0.422 0.449-0.584 0.794-0.161 0.346-0.242 0.798-0.242 1.36v6.62h-3.13v-11.4z"/>
+ <path d="m0.936 0.732v30.5h2.19v0.732h-3.04v-32h3.03v0.732z"/>
+ </g>
+</svg> \ No newline at end of file
diff --git a/launcher/resources/breeze_light/scalable/minecraft.svg b/launcher/resources/breeze_light/scalable/minecraft.svg
new file mode 100644
index 00000000..1ffb4565
--- /dev/null
+++ b/launcher/resources/breeze_light/scalable/minecraft.svg
@@ -0,0 +1,13 @@
+<svg version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+ <defs>
+ <style type="text/css" id="current-color-scheme">.ColorScheme-Text {
+ color:#232629;
+ }</style>
+ </defs>
+ <g fill="currentColor">
+ <path class="ColorScheme-Text" d="m8.2746408 13.953029c0.00833 0 1.1494866-0.753825 2.5359342-1.674795l2.520534-1.674794v-2.6001033c0-1.4307351-0.0074-2.6013858-0.01668-2.6013858-0.0093 0-1.150413 0.7546842-2.535934 1.6773611l-2.5192543 1.6773619v2.5988191c0 1.429027 0.00706 2.597536 0.015402 2.597536z" fill="currentColor" fill-opacity=".2"/>
+ <path class="ColorScheme-Text" d="m7.9409649 8.3549799c0.0753873-0.0030883 5.0483591-3.3585525 5.0192511-3.3868071-0.014404-0.0138645-1.1312-0.7652159-2.482034-1.6683781-1.3508332-0.9031623-2.4637176-1.6377305-2.4730489-1.6311596-0.4205404 0.2725585-4.9953997 3.3678436-4.9999993 3.3829565-0.00988 0.032723 4.8804389 3.3033883 4.9358311 3.3033883z" fill="currentColor" fill-opacity=".4"/>
+ <path class="ColorScheme-Text" d="m7.7189427 13.994097c0.00828 0 0.015875-1.150637 0.015402-2.556468l-0.0013141-2.5551853-2.517967-1.6850615c-1.3845486-0.9264887-2.5204415-1.6863448-2.524384-1.6863448-0.00421-0.00112-0.0077 1.1516957-0.0077 2.5616013v2.5628853l2.5102968 1.679928c1.3808361 0.923532 2.5173881 1.678645 2.5256673 1.678645z" fill="currentColor" fill-opacity=".6"/>
+ <path class="ColorScheme-Text" d="m 8,15 c 5.76994,-3.758469 4.07772,-2.720917 6,-4 V 5 C 12.707222,4.143927 10.030643,2.3424577 8,1 5,3 4.3571975,3.3856408 2,5 v 6 z M 8.508315,13.412447 8.4963301,9 C 10.411258,7.652439 11.772087,6.8337528 13,6 v 4.594435 z M 7.5156547,13.400462 3,10.570466 V 6 L 7.5276396,9 Z M 8,8 3.4485124,5 8,2 12.477901,5 C 10.956071,6.0867591 9.5367568,6.9353406 8,8 Z" fill="currentColor"/>
+ </g>
+</svg>
diff --git a/launcher/resources/breeze_light/scalable/new.svg b/launcher/resources/breeze_light/scalable/new.svg
new file mode 100644
index 00000000..51babd76
--- /dev/null
+++ b/launcher/resources/breeze_light/scalable/new.svg
@@ -0,0 +1,18 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
+ <defs
+ id="defs3051">
+ <style
+ type="text/css"
+ id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#232629;
+ }
+ </style>
+ </defs>
+ <path
+ style="fill:currentColor;fill-opacity:1;stroke:none"
+ d="M 4 4 L 4 28 L 17 28 L 17 27 L 5 27 L 5 14 L 10 14 L 13 11 L 27 11 L 27 17 L 28 17 L 28 7 L 18 7 L 15 4 L 4 4 z M 22 17 L 22 22 L 17 22 L 17 23 L 22 23 L 22 28 L 23 28 L 23 23 L 28 23 L 28 22 L 23 22 L 23 17 L 22 17 z "
+ id="path99"
+ class="ColorScheme-Text"
+ />
+</svg>
diff --git a/launcher/resources/breeze_light/scalable/news.svg b/launcher/resources/breeze_light/scalable/news.svg
new file mode 100644
index 00000000..3e3ebe95
--- /dev/null
+++ b/launcher/resources/breeze_light/scalable/news.svg
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
+ <defs id="defs3051">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#232629;
+ }
+ </style>
+ </defs>
+ <path style="fill:currentColor;fill-opacity:1;stroke:none"
+ d="m2 2v12h12v-12zm1 1h10v10h-10zm1 1v3h3v-3zm4 0v1h4v-1zm0 2v1h4v-1zm-4 2v4h8v-4z"
+ class="ColorScheme-Text"
+ />
+</svg>
diff --git a/launcher/resources/breeze_light/scalable/notes.svg b/launcher/resources/breeze_light/scalable/notes.svg
new file mode 100644
index 00000000..a8eaf279
--- /dev/null
+++ b/launcher/resources/breeze_light/scalable/notes.svg
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
+ <defs id="defs3051">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#232629;
+ }
+ </style>
+ </defs>
+ <path style="fill:currentColor;fill-opacity:1;stroke:none"
+ d="M 3 2 L 3 3 L 2 3 L 2 14 L 14 14 L 14 3 L 13 3 L 13 2 L 12 2 L 12 3 L 11 3 L 11 2 L 10 2 L 10 3 L 6 3 L 6 2 L 5 2 L 5 3 L 4 3 L 4 2 L 3 2 z M 3 4 L 13 4 L 13 13 L 3 13 L 3 4 z M 4 5 L 4 6 L 12 6 L 12 5 L 4 5 z M 4 7 L 4 8 L 8 8 L 8 7 L 4 7 z M 4 9 L 4 10 L 10 10 L 10 9 L 4 9 z M 10 11 L 10 12 L 12 12 L 12 11 L 10 11 z "
+ class="ColorScheme-Text"
+ />
+</svg>
diff --git a/launcher/resources/breeze_light/scalable/patreon.svg b/launcher/resources/breeze_light/scalable/patreon.svg
new file mode 100644
index 00000000..e12f1f8d
--- /dev/null
+++ b/launcher/resources/breeze_light/scalable/patreon.svg
@@ -0,0 +1,3 @@
+<svg fill="#232629" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M12,3h0a9,9,0,0,0-9,9v9H5.09V12a6.91,6.91,0,1,1,7.23,6.9,5.9,5.9,0,0,1-2.59-.47v-3A4.13,4.13,0,1,0,7.85,12v9H12A9,9,0,1,0,12,3Zm0,15.91h0Z"/>
+</svg>
diff --git a/launcher/resources/breeze_light/scalable/proxy.svg b/launcher/resources/breeze_light/scalable/proxy.svg
new file mode 100644
index 00000000..2e67ff6c
--- /dev/null
+++ b/launcher/resources/breeze_light/scalable/proxy.svg
@@ -0,0 +1,14 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
+ <defs id="defs3051">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#232629;
+ }
+ </style>
+ </defs>
+ <path
+ style="fill:currentColor;fill-opacity:1;stroke:none"
+ d="M 7 2 L 7 3 L 13 3 L 13 10 L 7 10 L 7 12 L 7 13 L 6 13 C 5.4459904 13 5 12.55401 5 12 L 5 10 L 5 8 L 5 7 L 6 7 L 6 3 L 3 3 L 3 7 L 4 7 L 4 8 L 4 10 L 4 12 C 4 13.108 4.892 14 6 14 L 7 14 L 9 14 L 11 14 L 11 13 L 9 13 L 9 12 L 14 12 L 14 11 L 14 10 L 14 2 L 7 2 z M 4 5 L 5 5 L 5 6 L 4 6 L 4 5 z M 2 8 L 2 12 L 3 12 L 3 10 L 3 8 L 2 8 z "
+ class="ColorScheme-Text"
+ />
+</svg>
diff --git a/launcher/resources/breeze_light/scalable/reddit-alien.svg b/launcher/resources/breeze_light/scalable/reddit-alien.svg
new file mode 100644
index 00000000..93b8eedc
--- /dev/null
+++ b/launcher/resources/breeze_light/scalable/reddit-alien.svg
@@ -0,0 +1,3 @@
+<svg fill="#232629" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M20,11.86a1.76,1.76,0,0,0-1.75-1.75,1.73,1.73,0,0,0-1.22.51,9,9,0,0,0-4.67-1.38l1-3.16L16,6.71s0,0,0,0a1.46,1.46,0,1,0,.1-.53l-2.89-.68a.25.25,0,0,0-.29.17L11.83,9.23a9.16,9.16,0,0,0-4.88,1.36,1.75,1.75,0,1,0-2.07,2.79,3,3,0,0,0-.06.58C4.82,16.58,8,18.7,12,18.7s7.14-2.13,7.14-4.74a2.94,2.94,0,0,0-.05-.55A1.74,1.74,0,0,0,20,11.86ZM8.51,13.08a1.06,1.06,0,1,1,1.06,1.06A1.06,1.06,0,0,1,8.51,13.08Zm6.06,3.14A3.48,3.48,0,0,1,12,17h0a3.48,3.48,0,0,1-2.56-.79.25.25,0,0,1,.35-.35,3,3,0,0,0,2.2.65h0a3,3,0,0,0,2.2-.65.25.25,0,1,1,.35.35Zm-.13-2.08a1.06,1.06,0,1,1,1.06-1.06A1.06,1.06,0,0,1,14.44,14.14Z"/>
+</svg>
diff --git a/launcher/resources/breeze_light/scalable/refresh.svg b/launcher/resources/breeze_light/scalable/refresh.svg
new file mode 100644
index 00000000..ecd2b394
--- /dev/null
+++ b/launcher/resources/breeze_light/scalable/refresh.svg
@@ -0,0 +1,8 @@
+<svg version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+ <defs>
+ <style type="text/css" id="current-color-scheme">.ColorScheme-Text {
+ color:#232629;
+ }</style>
+ </defs>
+ <path class="ColorScheme-Text" fill="currentColor" d="m14 8c0 1.1088173-0.319333 2.140071-0.84375 3.03125l-2.6875-2.6875 0.71875-0.71875 1.625 1.625c0.05109-0.19534 0.097716-0.3898623 0.125-0.59375 0.007789-0.0524063 0.025184-0.1032787 0.03125-0.15625 0.01707-0.1680854 0.03125-0.327411 0.03125-0.5 0-2.761424-2.238576-5-5-5-0.243024 0-0.4855082 0.02845-0.71875 0.0625-0.1362493 0.019955-0.2738032 0.031786-0.40625 0.0625-0.2865815 0.06695-0.547624 0.166647-0.8125 0.28125-0.030675 0.013272-0.063399 0.017376-0.09375 0.03125-0.09166 0.040961-0.163333 0.108255-0.25 0.15625-8e-3 0.00445-0.02305-0.00433-0.03125 0l-0.71875-0.75c0.891179-0.524417 1.922432-0.84375 3.03125-0.84375 3.313709 0 6 2.686293 6 6zm-2.96875 5.15625c-0.891179 0.524417-1.922432 0.84375-3.03125 0.84375-3.313709 0-6-2.686293-6-6 0-1.1088173 0.319333-2.140071 0.84375-3.03125l0.75 0.75 1.90625 1.9375-0.6875 0.6875-1.625-1.59375c-0.05109 0.19534-0.09772 0.3898623-0.125 0.59375-0.0078 0.052406-0.02518 0.1032787-0.03125 0.15625-0.01707 0.1680854-0.03125 0.327411-0.03125 0.5s0.01418 0.3319146 0.03125 0.5c0.01707 0.1680853 0.029198 0.337256 0.0625 0.5 0.466231 2.278415 2.490004 4 4.90625 4 0.2482626 0 0.4801862-0.02756 0.71875-0.0625 0.1362493-0.01995 0.2738032-0.03179 0.40625-0.0625 0.2865815-0.06695 0.547624-0.166647 0.8125-0.28125 0.030718-0.01299 0.063349-0.01766 0.09375-0.03125 0.08886-0.04062 0.164735-0.108612 0.25-0.15625h0.03125z"/>
+</svg>
diff --git a/launcher/resources/breeze_light/scalable/rename.svg b/launcher/resources/breeze_light/scalable/rename.svg
new file mode 100644
index 00000000..18ccc58a
--- /dev/null
+++ b/launcher/resources/breeze_light/scalable/rename.svg
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
+ <defs id="defs3051">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#232629;
+ }
+ </style>
+ </defs>
+ <path style="fill:currentColor;fill-opacity:1;stroke:none"
+ d="M 10.398438 2 L 5.2871094 7.1113281 L 2 10.398438 L 2 14 L 5.6015625 14 L 14 5.6015625 L 10.398438 2 z M 8.3496094 5.4902344 L 10.509766 7.6503906 L 7.3359375 10.826172 L 7.3359375 10.150391 L 6.3222656 10.171875 L 5.2871094 10.171875 L 5.2871094 9.1367188 L 5.2871094 8.5507812 L 6.7285156 7.1113281 L 8.3496094 5.4902344 z M 4.2734375 9.5644531 L 4.2734375 11.185547 L 5.3085938 11.185547 L 6.3007812 11.185547 L 6.3222656 11.837891 L 5.2421875 12.919922 L 3.8007812 12.919922 L 3.0800781 12.199219 L 3.0800781 10.757812 L 4.2734375 9.5644531 z "
+ class="ColorScheme-Text"
+ />
+</svg>
diff --git a/launcher/resources/breeze_light/scalable/resourcepacks.svg b/launcher/resources/breeze_light/scalable/resourcepacks.svg
new file mode 100644
index 00000000..913d3c1f
--- /dev/null
+++ b/launcher/resources/breeze_light/scalable/resourcepacks.svg
@@ -0,0 +1,11 @@
+<!DOCTYPE svg>
+<svg version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+ <defs>
+ <style id="current-color-scheme" type="text/css">
+ .ColorScheme-Text {
+ color:#232629;
+ }
+ </style>
+ </defs>
+ <path class="ColorScheme-Text" style="fill:currentColor; fill-opacity:1; stroke:none" d="M 8 3 L 13 3 L 13 13 L 8 13 L 8 3 Z M 3 3 L 13 3 L 13 9 L 11 7 L 7.65625 10.3438 L 6.3125 9 L 6.2813 9 L 3 12.2813 L 3 3 Z M 2 2 L 2 13.2813 L 2 14 L 14 14 L 14 13 L 14 12 L 14 11 L 14 10 L 14 2 L 2 2 Z M 6 4 C 4.89543 4 4 4.89543 4 6 C 4 7.10457 4.89543 8 6 8 C 7.10457 8 8 7.10457 8 6 C 8 4.89543 7.10457 4 6 4 Z"/>
+</svg>
diff --git a/launcher/resources/breeze_light/scalable/screenshots.svg b/launcher/resources/breeze_light/scalable/screenshots.svg
new file mode 100644
index 00000000..d984b330
--- /dev/null
+++ b/launcher/resources/breeze_light/scalable/screenshots.svg
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
+ <defs id="defs3051">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#232629;
+ }
+ </style>
+ </defs>
+ <path style="fill:currentColor;fill-opacity:1;stroke:none"
+ d="M 2 2 L 2 13.28125 L 2 14 L 14 14 L 14 13 L 14 12 L 14 11 L 14 10 L 14 2 L 2 2 z M 3 3 L 13 3 L 13 9 L 11 7 L 7.65625 10.34375 L 6.3125 9 L 6.28125 9 L 3 12.28125 L 3 3 z M 6 4 C 4.8954305 4 4 4.8954305 4 6 C 4 7.1045695 4.8954305 8 6 8 C 7.1045695 8 8 7.1045695 8 6 C 8 4.8954305 7.1045695 4 6 4 z "
+ class="ColorScheme-Text"
+ />
+</svg>
diff --git a/launcher/resources/breeze_light/scalable/settings.svg b/launcher/resources/breeze_light/scalable/settings.svg
new file mode 100644
index 00000000..19e86e26
--- /dev/null
+++ b/launcher/resources/breeze_light/scalable/settings.svg
@@ -0,0 +1,17 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
+ <defs id="defs3051">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#232629;
+ }
+ .ColorScheme-Highlight {
+ color:#3daee9;
+ }
+ </style>
+ </defs>
+ <path
+ style="fill:currentColor;fill-opacity:1;stroke:none"
+ d="M18.5 6A3.5 3.5 0 0 0 15.04102 9H4V10H15.04A3.5 3.5 0 0 0 18.5 13 3.5 3.5 0 0 0 21.958984 10H28V9H21.961A3.5 3.5 0 0 0 18.5 6M7.5 19A3.5 3.5 0 0 0 4 22.5 3.5 3.5 0 0 0 7.5 26 3.5 3.5 0 0 0 10.960938 23H28V22H10.959A3.5 3.5 0 0 0 7.5 19m0 1A2.5 2.5 0 0 1 10 22.5 2.5 2.5 0 0 1 7.5 25 2.5 2.5 0 0 1 5 22.5 2.5 2.5 0 0 1 7.5 20"
+ class="ColorScheme-Text"
+ />
+</svg>
diff --git a/launcher/resources/breeze_light/scalable/shaderpacks.svg b/launcher/resources/breeze_light/scalable/shaderpacks.svg
new file mode 100644
index 00000000..591c6af5
--- /dev/null
+++ b/launcher/resources/breeze_light/scalable/shaderpacks.svg
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
+ <defs id="defs3051">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#232629;
+ }
+ </style>
+ </defs>
+ <path style="fill:currentColor;fill-opacity:1;stroke:none"
+ d="M 2 2 L 2 14 L 5.15625 10.84375 C 4.43239 10.11989 4 9.10457 4 8 C 4 5.79086 5.79086 4 8 4 C 9.10457 4 10.11989 4.43239 10.84375 5.15625 L 14 2 L 2 2 z M 10.84375 5.15625 L 5.15625 10.84375 C 5.88011 11.56761 6.89543 12 8 12 C 10.20914 12 12 10.20914 12 8 C 12 6.89543 11.56761 5.88011 10.84375 5.15625 z "
+ class="ColorScheme-Text"
+ />
+</svg>
diff --git a/launcher/resources/breeze_light/scalable/shortcut.svg b/launcher/resources/breeze_light/scalable/shortcut.svg
new file mode 100644
index 00000000..426769d1
--- /dev/null
+++ b/launcher/resources/breeze_light/scalable/shortcut.svg
@@ -0,0 +1,18 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
+ <defs id="defs3051">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#232629;
+ }
+ </style>
+ </defs>
+ <g
+ transform="translate(-3,-1033.3622)">
+ <path
+ style="fill:currentColor;fill-opacity:1;stroke:none"
+ d="M 4,7 C 3.4459904,7 3,7.4459904 3,8 l 0,6 c 0,0.55401 0.4459904,1 1,1 l 5,0 c 0.55401,0 1,-0.44599 1,-1 l 0,-1 2,0 0,1 c 0,0.554 0.44599,1 1,1 l 5,0 c 0.55401,0 1,-0.446 1,-1 L 19,8 C 19,7.446 18.55401,7 18,7 l -5,0 c -0.55401,0 -1,0.446 -1,1 l 0,1 -2,0 0,-1 C 10,7.4459904 9.55401,7 9,7 Z M 4,8 7,8 9,8 9,9 C 8.4459904,9 8,9.4459904 8,10 l 0,2 c 0,0.55401 0.4459904,1 1,1 l 0,1 -2,0 -3,0 z m 9,0 3,0 2,0 0,6 -2,0 -3,0 0,-1 c 0.55401,0 1,-0.44599 1,-1 l 0,-2 C 14,9.4459904 13.55401,9 13,9 Z m -4,2 4,0 0,2 -4,0 z"
+ transform="translate(0,1030.3622)"
+ id="rect4161"
+ class="ColorScheme-Text" />
+ </g>
+</svg>
diff --git a/launcher/resources/breeze_light/scalable/status-bad.svg b/launcher/resources/breeze_light/scalable/status-bad.svg
new file mode 100644
index 00000000..6fc3137e
--- /dev/null
+++ b/launcher/resources/breeze_light/scalable/status-bad.svg
@@ -0,0 +1,9 @@
+<svg version="1.1" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-NegativeText {
+ color:#da4453;
+ }
+ </style>
+ <rect class="ColorScheme-NegativeText" x="3" y="3" width="16" height="16" rx="2" fill="currentColor"/>
+ <path d="M 6.414,5 5,6.414 9.586,11 5,15.586 6.414,17 11,12.414 15.586,17 17,15.586 12.414,11 17,6.414 15.586,5 11,9.586 Z" fill="#fff"/>
+</svg>
diff --git a/launcher/resources/breeze_light/scalable/status-good.svg b/launcher/resources/breeze_light/scalable/status-good.svg
new file mode 100644
index 00000000..eb8bc03b
--- /dev/null
+++ b/launcher/resources/breeze_light/scalable/status-good.svg
@@ -0,0 +1,10 @@
+<svg id="svg9" version="1.1" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg">
+ <style id="current-color-scheme" type="text/css">.ColorScheme-PositiveText {
+ color:#27ae60;
+ }
+ .ColorScheme-Text {
+ color:#232629;
+ }</style>
+ <rect id="rect3" class="ColorScheme-PositiveText" x="3" y="3" width="16" height="16" rx="1.4545455" fill="currentColor"/>
+ <path id="path5" d="M 18.99323,4.3805651 9,14 5.7332785,10.623339 4.3852425,12.059327 9,16.828 l 10,-10 z" fill="#fff"/>
+</svg>
diff --git a/launcher/resources/breeze_light/scalable/status-yellow.svg b/launcher/resources/breeze_light/scalable/status-yellow.svg
new file mode 100644
index 00000000..1dc4d0f5
--- /dev/null
+++ b/launcher/resources/breeze_light/scalable/status-yellow.svg
@@ -0,0 +1,9 @@
+<svg version="1.1" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-NeutralText {
+ color:#f67400;
+ }
+ </style>
+ <path class="ColorScheme-NeutralText" d="m11.006318 3.0000261a0.72728737 0.72727154 0 0 0-0.65674 0.4021811l-7.2728738 14.545431a0.72728737 0.72727154 0 0 0 0.6509222 1.052362h14.545748a0.72728737 0.72727154 0 0 0 0.650922-1.052362l-7.272874-14.545431a0.72728737 0.72727154 0 0 0-0.645104-0.4021811z" fill="currentColor"/>
+ <path d="m10 7v6h2v-6zm0 8v2h2v-2z" fill="#fff"/>
+</svg>
diff --git a/launcher/resources/breeze_light/scalable/tag.svg b/launcher/resources/breeze_light/scalable/tag.svg
new file mode 100644
index 00000000..4887d126
--- /dev/null
+++ b/launcher/resources/breeze_light/scalable/tag.svg
@@ -0,0 +1,17 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22">
+ <defs id="defs3051">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#232629;
+ }
+ .ColorScheme-Highlight {
+ color:#3daee9;
+ }
+ </style>
+ </defs>
+ <path
+ style="fill:currentColor;fill-opacity:1;stroke:none"
+ d="M 9 3 L 3 5 L 5 11 L 15 16 L 19 8 L 9 3 z M 3 5 L 3 11 L 11 19 L 13.705078 16.294922 L 4 11 L 3 5 z M 6.5 5 C 7.331 5 8 5.669 8 6.5 C 8 7.331 7.331 8 6.5 8 C 5.669 8 5 7.331 5 6.5 C 5 5.669 5.669 5 6.5 5 z "
+ class="ColorScheme-Text"
+ />
+</svg>
diff --git a/launcher/resources/breeze_light/scalable/viewfolder.svg b/launcher/resources/breeze_light/scalable/viewfolder.svg
new file mode 100644
index 00000000..4a8498ce
--- /dev/null
+++ b/launcher/resources/breeze_light/scalable/viewfolder.svg
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
+ <defs id="defs3051">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#232629;
+ }
+ </style>
+ </defs>
+ <path style="fill:currentColor;fill-opacity:1;stroke:none"
+ d="m4 4v24h24l-1-1h-22v-13h5l3-3h14v16l1 1v-21h-10l-3-3z"
+ class="ColorScheme-Text"
+ />
+</svg>
diff --git a/launcher/resources/breeze_light/scalable/worlds.svg b/launcher/resources/breeze_light/scalable/worlds.svg
new file mode 100644
index 00000000..543cc55e
--- /dev/null
+++ b/launcher/resources/breeze_light/scalable/worlds.svg
@@ -0,0 +1,16 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
+ <defs id="defs3051">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#232629;
+ }
+ </style>
+ </defs>
+ <g transform="translate(0,-1036.3622)">
+ <path
+ style="fill:currentColor;fill-opacity:1;fill-rule:nonzero"
+ d="M 8 2 C 4.6862915 2 2 4.6862868 2 8 C 2 11.313713 4.6862915 14 8 14 C 11.313708 14 14 11.313713 14 8 C 14 4.6862868 11.313708 2 8 2 z M 8 3 C 8.172589 3 8.3319146 3.01418 8.5 3.03125 C 8.5403398 3.0352163 8.5849592 3.0263276 8.625 3.03125 C 8.6776214 3.0379183 8.7291519 3.0542091 8.78125 3.0625 C 8.9249022 3.0850796 9.0482753 3.1217241 9.1875 3.15625 C 9.4440966 3.2195469 9.6982233 3.3050445 9.9375 3.40625 C 10.069426 3.4620498 10.186649 3.5272356 10.3125 3.59375 C 10.312425 3.60275 10.3133 3.614 10.3125 3.625 C 10.34148 3.638 10.35728 3.69175 10.40625 3.71875 C 10.42423 3.72875 10.42056 3.741 10.4375 3.75 C 10.46648 3.766 10.50599 3.7835 10.5 3.8125 C 10.492 3.8525 10.43425 3.844 10.40625 3.875 C 10.41005 3.933 10.35871 3.92975 10.34375 3.96875 C 10.35275 3.99375 10.40229 4.00125 10.40625 4.03125 C 10.40135 4.06325 10.33173 4.06075 10.34375 4.09375 C 10.39776 4.13575 10.449004 4.10375 10.5 4.09375 C 10.611991 4.07975 10.712253 4.08825 10.78125 4.03125 C 10.77225 3.97825 10.88099 3.9856 10.875 3.9375 C 10.90366 3.9583822 10.9403 3.9788168 10.96875 4 C 10.957987 4.01008 10.949578 4.02585 10.9375 4.03125 C 10.91649 4.04125 10.89401 4.0505 10.875 4.0625 C 10.847 4.0805 10.81328 4.104 10.78125 4.125 C 10.75826 4.141 10.711504 4.21875 10.6875 4.21875 C 10.65851 4.21875 10.61475 4.1815 10.59375 4.1875 C 10.56372 4.1975 10.56519 4.238 10.53125 4.25 C 10.46526 4.274 10.335495 4.2135 10.3125 4.3125 C 10.3405 4.3695 10.450005 4.343 10.5 4.375 C 10.53102 4.395 10.58575 4.466 10.59375 4.5 C 10.60175 4.528 10.60574 4.6575 10.59375 4.6875 C 10.56273 4.7675 10.466988 4.751 10.375 4.75 L 10.3125 4.75 C 10.157516 4.74 10.007499 4.67025 9.9375 4.78125 C 9.94245 4.86625 9.95653 4.926 9.9375 5 C 9.92353 5.054 9.840752 5.10965 9.84375 5.15625 C 9.84485 5.18025 9.900255 5.216 9.90625 5.25 C 9.9101 5.268 9.89818 5.2955 9.90625 5.3125 C 9.932265 5.3615 9.9852535 5.3025 10.03125 5.3125 C 10.07525 5.3225 10.125 5.3883 10.125 5.4375 C 10.125 5.4725 10.11575 5.5286 10.09375 5.5625 C 10.04975 5.6285 9.969247 5.62025 9.90625 5.65625 C 9.854275 5.68625 9.843502 5.7609 9.8125 5.8125 C 9.7795 5.8685 9.736983 5.88865 9.75 5.96875 C 9.70501 6.05775 9.655488 6.11325 9.5625 6.15625 C 9.535495 6.16825 9.493747 6.1695 9.46875 6.1875 C 9.44873 6.2015 9.434272 6.24925 9.40625 6.28125 C 9.37127 6.32025 9.331497 6.345 9.3125 6.375 C 9.298475 6.398 9.29621 6.43675 9.28125 6.46875 C 9.25925 6.51075 9.215494 6.5203 9.1875 6.5625 C 9.17452 6.5825 9.17022 6.63025 9.15625 6.65625 C 9.12424 6.71425 9.087749 6.7615 9.09375 6.8125 C 9.0987 6.8605 9.153252 6.86225 9.15625 6.90625 C 9.159 6.93025 9.12401 6.94175 9.125 6.96875 C 9.1261 7.00675 9.15328 7.0325 9.15625 7.0625 C 9.16324 7.1365 9.10772 7.16815 9.09375 7.21875 C 9.08676 7.24275 9.09975 7.26125 9.09375 7.28125 C 9.08176 7.31825 9.032251 7.36205 9.03125 7.40625 C 9.03015 7.43725 9.09078 7.456 9.09375 7.5 C 9.09595 7.529 9.056505 7.56575 9.0625 7.59375 C 9.0735 7.64775 9.1767575 7.708 9.21875 7.75 C 9.275747 7.807 9.350008 7.84625 9.375 7.90625 C 9.39601 7.95725 9.398533 8.05565 9.4375 8.09375 C 9.466485 8.12175 9.525507 8.12625 9.5625 8.15625 C 9.59748 8.18325 9.619253 8.18875 9.65625 8.21875 C 9.717245 8.26675 9.809252 8.382 9.90625 8.375 C 9.957235 8.365 10.005504 8.3225 10.0625 8.3125 C 10.1215 8.3025 10.190006 8.27625 10.25 8.28125 C 10.29598 8.29125 10.358253 8.3155 10.40625 8.3125 C 10.45624 8.3025 10.505509 8.30625 10.5625 8.28125 C 10.6615 8.23825 10.824766 8.1668 10.96875 8.1875 C 11.078739 8.2035 11.079255 8.326 11.15625 8.375 C 11.24424 8.385 11.305007 8.358 11.375 8.375 C 11.42802 8.388 11.495001 8.4584 11.5 8.5 C 11.505 8.543 11.44349 8.5978 11.4375 8.625 C 11.42353 8.683 11.44746 8.74425 11.4375 8.78125 C 11.4295 8.81025 11.40526 8.846 11.40625 8.875 C 11.40625 8.901 11.44173 8.9658 11.46875 9 C 11.50175 9.042 11.55375 9.0798 11.59375 9.125 C 11.66674 9.209 11.699004 9.29525 11.75 9.40625 C 11.76298 9.43425 11.73801 9.464 11.75 9.5 C 11.728 9.6679 11.672491 9.78285 11.5625 9.96875 C 11.51052 10.02875 11.436499 10.08135 11.4375 10.15625 C 11.4337 10.33625 11.53925 10.451 11.53125 10.625 C 11.51327 10.8589 11.54929 10.8751 11.53125 11 C 11.61025 11.04 11.55424 11.1669 11.53125 11.25 C 11.49726 11.349 11.4565 11.3715 11.4375 11.4375 C 11.490583 11.460643 11.566021 11.451092 11.625 11.4375 C 11.595204 11.468874 11.561843 11.500657 11.53125 11.53125 C 11.305044 11.757456 11.047252 11.976543 10.78125 12.15625 C 10.265207 12.504882 9.6912413 12.769698 9.0625 12.90625 C 8.718961 12.980861 8.3658887 13 8 13 C 7.8096669 13 7.6218651 12.989959 7.4375 12.96875 C 7.2906389 12.951989 7.1427139 12.935453 7 12.90625 C 6.7168255 12.848304 6.4510281 12.728616 6.1875 12.625 C 6.1781304 12.60785 6.1541244 12.582618 6.15625 12.5625 C 6.208225 12.5405 6.305756 12.6365 6.34375 12.5625 C 6.36278 12.5275 6.318725 12.44125 6.34375 12.40625 C 6.361735 12.38225 6.463007 12.382 6.5 12.375 C 6.55302 12.365 6.626253 12.35775 6.65625 12.34375 C 6.68925 12.32275 6.724751 12.2491 6.71875 12.1875 C 6.716 12.1585 6.679185 12.151 6.65625 12.125 C 6.637275 12.103 6.66923 12.0835 6.65625 12.0625 C 6.63227 12.0275 6.572499 12.01975 6.5625 11.96875 C 6.634495 11.95475 6.7397615 12.029 6.84375 12 C 6.892755 11.986 6.976999 11.88985 7 11.84375 C 7.00699 11.82975 6.99202 11.79925 7 11.78125 C 7.00902 11.76325 7.028225 11.72875 7.03125 11.71875 C 7.03823 11.69175 7.02525 11.7055 7.03125 11.6875 C 7.049235 11.6365 7.094997 11.5988 7.125 11.5625 C 7.14799 11.5345 7.197723 11.49775 7.21875 11.46875 C 7.24273 11.43775 7.23405 11.43425 7.25 11.40625 C 7.265015 11.31525 7.19675 11.23615 7.21875 11.15625 C 7.24273 11.06625 7.381762 11.00975 7.46875 10.96875 C 7.498725 10.95475 7.537502 10.9465 7.5625 10.9375 C 7.622494 10.9165 7.6940045 10.895 7.75 10.875 C 7.843995 10.841 7.860248 10.7734 7.90625 10.6875 C 7.92825 10.6475 7.964735 10.5918 7.96875 10.5625 C 7.9726 10.5365 7.9638 10.531 7.96875 10.5 C 7.9737 10.471 7.960775 10.44025 7.96875 10.40625 C 7.97975 10.36325 8 10.26665 8 10.21875 C 8 10.17875 7.96974 10.161 7.96875 10.125 C 7.96176 9.995 8.014512 10.0085 8.0625 9.9375 C 8.08648 9.9025 8.10806 9.8376 8.125 9.8125 C 8.205993 9.6925 8.353749 9.65075 8.34375 9.46875 C 8.3399 9.40875 8.293978 9.269 8.25 9.25 C 8.224975 9.239 8.1932485 9.23175 8.15625 9.21875 C 8.0382585 9.17475 7.9354855 9.04125 7.8125 9.03125 L 7.75 9.03125 C 7.701985 9.03125 7.6477435 9.007 7.59375 9 C 7.55976 8.99 7.4887485 9.01 7.46875 9 C 7.43773 8.985 7.43122 8.92325 7.40625 8.90625 C 7.38623 8.89225 7.343493 8.886 7.3125 8.875 C 7.263495 8.857 7.2444965 8.8165 7.1875 8.8125 C 7.169515 8.8125 7.144982 8.8225 7.125 8.8125 C 7.09398 8.8025 7.060246 8.79925 7.03125 8.78125 C 6.99528 8.75925 6.952498 8.74975 6.9375 8.71875 C 6.9705 8.61085 6.86575 8.59425 6.84375 8.53125 C 6.83374 8.50225 6.85376 8.43225 6.84375 8.40625 C 6.83077 8.36925 6.791002 8.3435 6.75 8.3125 C 6.678005 8.2565 6.634243 8.23165 6.53125 8.21875 C 6.48527 8.20875 6.4299945 8.22875 6.375 8.21875 C 6.317008 8.20875 6.2314945 8.175 6.1875 8.125 C 6.14548 8.076 6.130744 8.0231 6.09375 8 C 6.05877 7.978 6.0239965 7.9605 6 7.9375 C 5.989 7.9275 5.97876 7.92925 5.96875 7.90625 C 5.950765 7.86925 5.9155 7.8575 5.9375 7.8125 C 5.897515 7.7925 5.917993 7.85075 5.875 7.84375 C 5.836005 7.78875 5.8067385 7.734 5.71875 7.75 C 5.678765 7.76 5.640747 7.84275 5.59375 7.84375 C 5.554755 7.84375 5.519746 7.758 5.46875 7.75 C 5.429755 7.74 5.3707495 7.78625 5.34375 7.78125 C 5.30074 7.77125 5.288973 7.74475 5.25 7.71875 C 5.221015 7.69975 5.17225 7.65525 5.15625 7.65625 C 5.106255 7.65625 5.0689915 7.75515 5 7.71875 C 4.96601 7.67575 5.071268 7.665 5.03125 7.625 C 5.001275 7.596 4.992763 7.64225 4.96875 7.65625 C 4.940755 7.67425 4.905993 7.6765 4.875 7.6875 C 4.806002 7.7135 4.7414935 7.721 4.6875 7.75 C 4.637505 7.776 4.622747 7.79245 4.59375 7.84375 C 4.57076 7.88575 4.534997 7.96675 4.5 7.96875 C 4.45798 7.96875 4.4442495 7.92325 4.40625 7.90625 C 4.2912615 7.85625 4.2199905 7.9355 4.125 7.9375 C 4.037006 7.9375 3.9022515 7.80175 3.90625 7.71875 C 3.909 7.66775 3.931505 7.59425 3.9375 7.53125 C 3.94245 7.48125 3.999065 7.4206 4 7.375 C 4.0011 7.313 3.883746 7.28835 3.84375 7.28125 C 3.749755 7.26425 3.6382415 7.32325 3.53125 7.28125 C 3.51123 7.24725 3.55051 7.2215 3.5625 7.1875 C 3.56948 7.1695 3.55551 7.146 3.5625 7.125 C 3.57449 7.093 3.641257 7.06525 3.65625 7.03125 C 3.66725 7.00525 3.64525 6.9705 3.65625 6.9375 C 3.66923 6.9015 3.715725 6.86975 3.71875 6.84375 C 3.7226 6.80975 3.6832 6.772 3.65625 6.75 C 3.573255 6.76 3.5167485 6.75725 3.46875 6.78125 C 3.360763 6.83025 3.3902435 6.966 3.28125 7 C 3.244235 7.012 3.198248 7.02425 3.15625 7.03125 C 3.137935 7.04125 3.11427 7.02925 3.09375 7.03125 C 3.0956963 7.0211336 3.0917443 7.0100944 3.09375 7 C 3.0984123 6.9772158 3.1200289 6.9601701 3.125 6.9375 C 3.1962653 6.6125035 3.3063949 6.2979344 3.4375 6 L 3.46875 6 C 3.506755 6.01 3.529505 6.0595 3.5625 6.0625 C 3.654493 6.0725 3.674001 5.9777 3.75 5.9375 C 3.827996 5.9485 3.866506 5.9275 3.9375 5.9375 C 3.985515 5.9475 4.055756 5.996 4.09375 6 C 4.12576 6 4.126248 5.96475 4.15625 5.96875 C 4.186225 5.97875 4.245 6.0265 4.25 6.0625 C 4.25495 6.1075 4.205715 6.16915 4.21875 6.21875 C 4.265775 6.26675 4.3705045 6.2845 4.4375 6.3125 C 4.4815 6.2755 4.44448 6.20825 4.4375 6.15625 C 4.4364 6.13325 4.44025 6.0835 4.4375 6.0625 C 4.43255 6.0265 4.40625 5.99975 4.40625 5.96875 C 4.40625 5.82575 4.5290085 5.77465 4.625 5.71875 C 4.665975 5.69475 4.7140025 5.643 4.75 5.625 C 4.800985 5.6 4.8330025 5.61775 4.875 5.59375 C 4.950988 5.55075 5.0035015 5.4862 5.0625 5.4375 C 5.089505 5.3725 5.05975 5.28275 5.0625 5.21875 C 5.089505 5.20175 5.127282 5.21875 5.15625 5.21875 C 5.20223 5.20875 5.223996 5.151 5.25 5.125 C 5.265015 5.11 5.294482 5.10875 5.3125 5.09375 C 5.35848 5.05775 5.366237 5.016 5.40625 5 C 5.420275 4.99 5.446723 4.97575 5.46875 4.96875 C 5.49878 4.95875 5.545757 4.9555 5.59375 4.9375 C 5.62477 4.9265 5.706749 4.91925 5.71875 4.90625 C 5.733765 4.89125 5.7149 4.8355 5.71875 4.8125 C 5.74273 4.6996 5.899009 4.69435 6 4.65625 C 6.069993 4.63025 6.1407545 4.5485 6.21875 4.5625 C 6.203735 4.6165 6.143249 4.6224 6.15625 4.6875 C 6.173245 4.7785 6.280501 4.66925 6.3125 4.65625 C 6.373495 4.63025 6.4825025 4.5925 6.5625 4.5625 C 6.632493 4.5375 6.753489 4.5181 6.6875 4.4375 C 6.6325 4.4275 6.6104935 4.48 6.5625 4.5 C 6.5295 4.51 6.527978 4.47175 6.5 4.46875 C 6.472995 4.46875 6.464527 4.505 6.4375 4.5 C 6.410495 4.49 6.378998 4.43925 6.375 4.40625 C 6.364 4.32225 6.43476 4.3119 6.46875 4.25 C 6.44576 4.174 6.3452425 4.2175 6.28125 4.1875 C 6.28824 4.1425 6.322007 4.10375 6.375 4.09375 C 6.41801 4.08375 6.5365015 4.102 6.5625 4.125 C 6.577515 4.138 6.5395595 4.1665 6.5625 4.1875 C 6.588515 4.2105 6.622254 4.1975 6.65625 4.1875 C 6.66824 4.1305 6.583751 4.162 6.59375 4.125 C 6.661741 4.081 6.792005 4.10475 6.875 4.09375 C 6.923015 4.08375 6.988251 4.05425 7.03125 4.03125 C 7.071235 4.00825 7.0830015 3.962 7.125 4 C 7.13699 4.041 7.116685 4.07175 7.09375 4.09375 C 7.016756 4.16175 6.934994 4.2336 6.875 4.3125 C 6.912015 4.3485 6.969254 4.33675 7.03125 4.34375 C 7.05523 4.35375 7.099997 4.33875 7.125 4.34375 C 7.15503 4.35375 7.194748 4.33375 7.21875 4.34375 C 7.26077 4.35375 7.270507 4.4375 7.3125 4.4375 C 7.380496 4.4375 7.351523 4.3577 7.3125 4.3125 C 7.32449 4.2655 7.3608 4.2207 7.34375 4.1875 C 7.31273 4.1255 7.1935005 4.206 7.1875 4.125 C 7.18365 4.075 7.231993 4.06925 7.25 4.03125 C 7.24202 3.93525 7.322499 3.93075 7.3125 3.84375 C 7.30755 3.80775 7.275008 3.81525 7.25 3.78125 C 7.23702 3.76325 7.23371 3.7015 7.21875 3.6875 C 7.166775 3.6435 7.0685005 3.67795 7.0625 3.59375 C 7.05975 3.54375 7.06948 3.4911 7.0625 3.4375 C 7.05551 3.3865 7.012728 3.22875 6.96875 3.21875 C 6.912755 3.20675 6.8794955 3.31245 6.8125 3.34375 C 6.77653 3.36075 6.693243 3.381 6.65625 3.375 C 6.63227 3.365 6.596753 3.3595 6.59375 3.3125 C 6.58979 3.2701 6.6405966 3.2512172 6.65625 3.21875 C 6.6601634 3.2106332 6.654259 3.19872 6.65625 3.1875 C 6.7288164 3.1672517 6.8012164 3.1422715 6.875 3.125 C 6.9169167 3.1152798 6.9576866 3.1024086 7 3.09375 C 7.0298771 3.0875279 7.0636852 3.0994569 7.09375 3.09375 C 7.2273044 3.0689879 7.3629458 3.0451686 7.5 3.03125 C 7.6662387 3.0137812 7.8289018 3 8 3 z M 5.96875 3.46875 C 5.9369162 3.6513239 5.7660026 3.7240206 5.5625 3.71875 C 5.51652 3.76275 5.55622 3.84525 5.53125 3.90625 C 5.51024 3.95725 5.425991 4.004 5.375 4 C 5.337985 4 5.28125 3.94125 5.28125 3.90625 C 5.28125 3.86325 5.349521 3.8617 5.3125 3.8125 C 5.31415 3.8025 5.333355 3.79125 5.34375 3.78125 C 5.3639901 3.7685049 5.3858533 3.762493 5.40625 3.75 C 5.5874525 3.6384834 5.7732114 3.5568279 5.96875 3.46875 z M 10.15625 3.65625 C 10.13782 3.66625 10.14122 3.6775 10.125 3.6875 C 10.08699 3.7105 10.06026 3.739 10.03125 3.75 C 9.99028 3.765 9.943504 3.7755 9.9375 3.8125 C 9.93255 3.8435 9.969795 3.846 9.96875 3.875 C 9.953735 3.912 9.94553 3.92375 9.9375 3.96875 C 9.988485 4.05175 10.093258 3.9505 10.15625 3.9375 C 10.18425 3.9275 10.20375 3.93025 10.21875 3.90625 C 10.23574 3.87925 10.23706 3.8507 10.25 3.8125 C 10.26403 3.7705 10.31751 3.75575 10.3125 3.71875 C 10.3087 3.68175 10.218244 3.65125 10.15625 3.65625 z M 4.6875 4.28125 C 4.7349118 4.319347 4.8015588 4.40185 4.71875 4.4375 C 4.70874 4.4475 4.5864965 4.47275 4.5625 4.46875 C 4.55282 4.46875 4.5397337 4.44475 4.53125 4.4375 C 4.5829129 4.3871923 4.6337069 4.3293033 4.6875 4.28125 z M 4.875 4.46875 C 4.89898 4.46875 4.909483 4.52925 4.9375 4.53125 C 4.964505 4.53125 4.983973 4.496 5 4.5 C 5.04202 4.511 5.071268 4.5938 5.03125 4.625 C 4.99825 4.635 4.992713 4.58975 4.96875 4.59375 C 4.900754 4.60575 4.8634955 4.754 4.8125 4.75 C 4.764485 4.74 4.732228 4.62875 4.78125 4.59375 C 4.78235 4.56375 4.779215 4.56225 4.78125 4.53125 C 4.796265 4.51325 4.834982 4.46575 4.875 4.46875 z M 4.625 4.5 C 4.639025 4.5 4.651245 4.49 4.65625 4.5 C 4.64927 4.553 4.634708 4.56875 4.59375 4.59375 C 4.522756 4.63675 4.460501 4.68975 4.4375 4.78125 C 4.43051 4.80825 4.3464955 4.8817 4.3125 4.875 C 4.233504 4.858 4.357015 4.7104 4.375 4.6875 C 4.39502 4.6625 4.414526 4.654 4.4375 4.625 C 4.46049 4.597 4.478055 4.54725 4.5 4.53125 C 4.52398 4.51425 4.5830075 4.498 4.625 4.5 z M 11.40625 4.65625 C 11.48524 4.64625 11.526502 4.73365 11.5625 4.78125 C 11.59248 4.82025 11.669746 4.87905 11.71875 4.90625 C 11.74675 4.92125 11.7815 4.95475 11.8125 4.96875 C 11.87749 4.99775 11.996996 5.09225 12 5.15625 C 12.0011 5.18825 11.96374 5.22 11.96875 5.25 C 12.01776 5.26 12.0615 5.1742 12.0625 5.125 C 12.15441 5.2550064 12.233102 5.3926596 12.3125 5.53125 C 12.35 5.5967067 12.402944 5.6512957 12.4375 5.71875 C 12.39339 5.73175 12.38209 5.73825 12.375 5.78125 C 12.36499 5.83725 12.39649 5.9276 12.3125 5.9375 C 12.25953 5.9475 12.19799 5.892 12.125 5.875 C 12.09502 5.865 12.05525 5.885 12.03125 5.875 C 11.97625 5.857 11.9845 5.7833 11.9375 5.75 C 11.91049 5.731 11.824253 5.6925 11.78125 5.6875 C 11.75424 5.6875 11.74673 5.6975 11.71875 5.6875 C 11.68476 5.6775 11.621749 5.7015 11.59375 5.6875 C 11.56674 5.6705 11.50701 5.61675 11.5 5.59375 C 11.489 5.55675 11.59175 5.5313 11.59375 5.5 C 11.59595 5.476 11.5675 5.44325 11.5625 5.40625 C 11.5587 5.38425 11.5674 5.35875 11.5625 5.34375 C 11.5555 5.31775 11.50974 5.3135 11.46875 5.3125 C 11.43272 5.3125 11.40599 5.3125 11.375 5.3125 C 11.331 5.3125 11.242494 5.3085 11.1875 5.3125 C 11.1545 5.3125 11.12475 5.3095 11.09375 5.3125 C 11.00676 5.3225 10.942997 5.3025 10.875 5.3125 C 10.82599 5.3125 10.733496 5.354 10.6875 5.375 C 10.66451 5.386 10.65501 5.39125 10.625 5.40625 C 10.61103 5.41625 10.58054 5.4295 10.5625 5.4375 C 10.53451 5.4505 10.49575 5.492 10.46875 5.5 C 10.42976 5.51 10.38349 5.49 10.3125 5.5 C 10.26152 5.5 10.188501 5.46725 10.1875 5.40625 C 10.1864 5.31325 10.349511 5.36075 10.4375 5.34375 C 10.4705 5.33375 10.49123 5.30525 10.53125 5.28125 C 10.55028 5.27025 10.54451 5.262 10.5625 5.25 C 10.59247 5.229 10.65125 5.18025 10.65625 5.15625 C 10.66005 5.13425 10.65323 5.11075 10.65625 5.09375 C 10.66005 5.07275 10.69175 5.05925 10.71875 5.03125 C 10.76077 4.98925 10.791747 4.93345 10.84375 4.90625 C 10.87873 4.88825 10.9215 4.87275 10.9375 4.84375 C 10.9413 4.81175 10.9364 4.81125 10.9375 4.78125 C 10.9595 4.76125 10.98202 4.754 11 4.75 C 11.05401 4.738 11.093259 4.753 11.15625 4.75 C 11.18325 4.75 11.221 4.763 11.25 4.75 C 11.27398 4.734 11.2885 4.6995 11.3125 4.6875 C 11.33851 4.6735 11.37422 4.65825 11.40625 4.65625 z M 11.96875 5.25 L 11.84375 5.25 C 11.79975 5.25 11.744749 5.227 11.71875 5.25 C 11.75577 5.31 11.823255 5.32875 11.90625 5.34375 C 11.93623 5.32175 11.95478 5.2883 11.96875 5.25 z M 5.125 4.6875 L 5.21875 4.6875 C 5.243775 4.6875 5.271251 4.6775 5.28125 4.6875 C 5.265245 4.7535 5.114497 4.74275 5.0625 4.71875 C 5.06525 4.69375 5.092968 4.6915 5.125 4.6875 z M 4.90625 4.8125 C 4.8625672 4.8442816 4.8193312 4.8845833 4.75 4.90625 C 4.711995 4.91825 4.663252 4.917 4.65625 4.875 C 4.64822 4.823 4.715988 4.84875 4.75 4.84375 C 4.794 4.83375 4.855254 4.8145 4.90625 4.8125 z M 11.40625 4.8125 C 11.37325 4.8235 11.35724 4.89625 11.40625 4.90625 C 11.42924 4.89225 11.44355 4.8555 11.4375 4.8125 C 11.42452 4.7985 11.41621 4.8025 11.40625 4.8125 z M 11.34375 4.96875 C 11.34485 5.02475 11.35475 5.0764 11.34375 5.125 C 11.37576 5.187 11.452756 5.13575 11.46875 5.09375 C 11.48778 4.98975 11.45425 4.95575 11.40625 4.96875 C 11.39025 4.97875 11.36069 4.95575 11.34375 4.96875 z M 3.0625 7.3125 C 3.118864 7.3635 3.1512925 7.43535 3.21875 7.46875 C 3.243775 7.48175 3.280501 7.492 3.3125 7.5 C 3.338515 7.51 3.350013 7.492 3.375 7.5 C 3.42802 7.518 3.4892575 7.5435 3.53125 7.5625 C 3.595248 7.5905 3.66375 7.68675 3.71875 7.71875 C 3.7215 7.75075 3.70874 7.7885 3.71875 7.8125 C 3.744765 7.8475 3.7704965 7.88225 3.8125 7.90625 C 3.863485 7.93425 3.8895065 7.9778 3.9375 8 C 3.954495 8.01 3.973963 7.99 4 8 C 4.065994 8.02 4.099253 8.11055 4.15625 8.09375 C 4.193265 8.08275 4.181505 8.036 4.1875 8 C 4.212525 7.973 4.242222 7.9375 4.28125 7.9375 C 4.34324 7.9375 4.351999 8.03315 4.375 8.09375 C 4.38798 8.12775 4.428535 8.1515 4.4375 8.1875 C 4.452515 8.2495 4.45048 8.43175 4.4375 8.46875 C 4.421495 8.51475 4.3504995 8.5122 4.3125 8.5625 C 4.294515 8.5865 4.29522 8.63925 4.28125 8.65625 C 4.25727 8.68525 4.236773 8.69075 4.21875 8.71875 C 4.20874 8.73375 4.196465 8.76025 4.1875 8.78125 C 4.15747 8.84525 4.099986 8.89175 4.125 8.96875 C 4.13501 8.99975 4.1875 9.0255 4.1875 9.0625 C 4.1875 9.1065 4.100751 9.1393 4.09375 9.1875 C 4.0888 9.2225 4.114055 9.2658 4.125 9.3125 C 4.13298 9.3475 4.197751 9.38325 4.21875 9.40625 C 4.25373 9.44525 4.280501 9.513 4.3125 9.5625 C 4.375491 9.6595 4.406765 9.78 4.46875 9.875 C 4.50175 9.924 4.57175 9.9484 4.59375 10 C 4.60475 10.026 4.58374 10.06975 4.59375 10.09375 C 4.62972 10.17475 4.794007 10.2726 4.875 10.3125 C 4.913005 10.3315 4.965009 10.32375 5 10.34375 C 5.05302 10.37375 5.160506 10.4534 5.1875 10.5 C 5.21148 10.542 5.20676 10.65185 5.21875 10.71875 C 5.233765 10.80675 5.2149 10.87365 5.21875 10.96875 C 5.2215 11.02075 5.25 11.04215 5.25 11.09375 C 5.25 11.11175 5.2511 11.1685 5.25 11.1875 C 5.2489 11.2495 5.25495 11.312 5.25 11.375 C 5.24725 11.409 5.2478 11.43975 5.25 11.46875 C 5.25275 11.49975 5.27927 11.50325 5.28125 11.53125 C 5.28345 11.56025 5.246975 11.602 5.25 11.625 C 5.25699 11.688 5.300499 11.72315 5.3125 11.78125 C 5.32251 11.82725 5.349745 11.945 5.34375 12 C 5.3399 12.029 5.316515 12.06075 5.3125 12.09375 C 5.30975 12.11975 5.31635 12.13225 5.3125 12.15625 C 5.30975 12.17925 5.31844 12.19975 5.3125 12.21875 C 5.2806543 12.198271 5.2500951 12.177426 5.21875 12.15625 C 4.9527483 11.976543 4.6949555 11.757456 4.46875 11.53125 C 4.4381566 11.500657 4.4047959 11.468874 4.375 11.4375 C 4.1944191 11.247353 4.0241375 11.029182 3.875 10.8125 C 3.8614865 10.792866 3.8569888 10.769835 3.84375 10.75 C 3.6707036 10.490733 3.5290643 10.227866 3.40625 9.9375 C 3.3973945 9.9165633 3.3835772 9.8960813 3.375 9.875 C 3.2696226 9.6160011 3.1860736 9.3410185 3.125 9.0625 C 3.1134736 9.0099352 3.1036081 8.9594198 3.09375 8.90625 C 3.0689879 8.7726956 3.0451686 8.6370542 3.03125 8.5 C 3.01418 8.3319146 3 8.172589 3 8 C 3 7.7623582 3.030436 7.5413039 3.0625 7.3125 z M 5 7.84375 C 5.048015 7.82175 5.038995 7.89925 5 7.90625 C 4.962985 7.91625 4.96403 7.86175 5 7.84375 z " transform="translate(0,1036.3622)"
+ id="path26"
+ class="ColorScheme-Text"/>
+ </g>
+</svg>
diff --git a/launcher/resources/flat/flat.qrc b/launcher/resources/flat/flat.qrc
index 508e0a9f..a846bd2d 100644
--- a/launcher/resources/flat/flat.qrc
+++ b/launcher/resources/flat/flat.qrc
@@ -35,6 +35,7 @@
<file>scalable/screenshot-placeholder.svg</file>
<file>scalable/screenshots.svg</file>
<file>scalable/settings.svg</file>
+ <file>scalable/shortcut.svg</file>
<file>scalable/star.svg</file>
<file>scalable/status-bad.svg</file>
<file>scalable/status-good.svg</file>
diff --git a/launcher/resources/flat/scalable/shortcut.svg b/launcher/resources/flat/scalable/shortcut.svg
new file mode 100644
index 00000000..83878d19
--- /dev/null
+++ b/launcher/resources/flat/scalable/shortcut.svg
@@ -0,0 +1,3 @@
+<svg fill="#757575" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M5 21q-.825 0-1.413-.587Q3 19.825 3 19V5q0-.825.587-1.413Q4.175 3 5 3h7v2H5v14h14v-7h2v7q0 .825-.587 1.413Q19.825 21 19 21Zm4.7-5.3-1.4-1.4L17.6 5H14V3h7v7h-2V6.4Z"/>
+</svg>
diff --git a/launcher/resources/flat_white/flat_white.qrc b/launcher/resources/flat_white/flat_white.qrc
index e11d6316..b0759d8f 100644
--- a/launcher/resources/flat_white/flat_white.qrc
+++ b/launcher/resources/flat_white/flat_white.qrc
@@ -35,6 +35,7 @@
<file>scalable/screenshot-placeholder.svg</file>
<file>scalable/screenshots.svg</file>
<file>scalable/settings.svg</file>
+ <file>scalable/shortcut.svg</file>
<file>scalable/star.svg</file>
<file>scalable/status-bad.svg</file>
<file>scalable/status-good.svg</file>
diff --git a/launcher/resources/flat_white/scalable/shortcut.svg b/launcher/resources/flat_white/scalable/shortcut.svg
new file mode 100644
index 00000000..b419a77d
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/shortcut.svg
@@ -0,0 +1,3 @@
+<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M5 21q-.825 0-1.413-.587Q3 19.825 3 19V5q0-.825.587-1.413Q4.175 3 5 3h7v2H5v14h14v-7h2v7q0 .825-.587 1.413Q19.825 21 19 21Zm4.7-5.3-1.4-1.4L17.6 5H14V3h7v7h-2V6.4Z"/>
+</svg>
diff --git a/launcher/resources/iOS/iOS.qrc b/launcher/resources/iOS/iOS.qrc
index aa08d811..0b79efb2 100644
--- a/launcher/resources/iOS/iOS.qrc
+++ b/launcher/resources/iOS/iOS.qrc
@@ -39,5 +39,6 @@
<file>scalable/export.svg</file>
<file>scalable/rename.svg</file>
<file>scalable/launch.svg</file>
+ <file>scalable/shortcut.svg</file>
</qresource>
</RCC>
diff --git a/launcher/resources/iOS/scalable/shortcut.svg b/launcher/resources/iOS/scalable/shortcut.svg
new file mode 100644
index 00000000..16e9fa48
--- /dev/null
+++ b/launcher/resources/iOS/scalable/shortcut.svg
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 18.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Calque_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 32 32" enable-background="new 0 0 32 32" xml:space="preserve">
+<g id="_x35__5_">
+ <g>
+ <path fill="#3366CC" d="M3,11c0.6,0,1-0.5,1-1l0-4.8l15.2,14.5c0.4,0.4,1,0.4,1.4,0c0.4-0.4,0.4-1,0-1.4L5.6,4L10,4
+ c0.6,0,1-0.5,1-1s-0.4-1-1-1H3C2.5,2,2,2.4,2,3v7C2,10.5,2.4,11,3,11z M26,2H15v2h11c1.1,0,2,0.9,2,2l0,20.1c0,1.1-0.9,2-2,2L6,28
+ c-1.1,0-2-0.9-2-2V15H2v11c0,2.2,2.2,4,4.4,4h19.7c2.2,0,3.9-1.8,3.9-3.9V6.4C30,4.2,28.2,2,26,2z"/>
+ </g>
+</g>
+</svg>
diff --git a/launcher/resources/multimc/128x128/instances/chicken.png b/launcher/resources/multimc/128x128/instances/chicken_legacy.png
index 71f6dedc..71f6dedc 100644
--- a/launcher/resources/multimc/128x128/instances/chicken.png
+++ b/launcher/resources/multimc/128x128/instances/chicken_legacy.png
Binary files differ
diff --git a/launcher/resources/multimc/128x128/instances/creeper.png b/launcher/resources/multimc/128x128/instances/creeper_legacy.png
index 41b7d07d..41b7d07d 100644
--- a/launcher/resources/multimc/128x128/instances/creeper.png
+++ b/launcher/resources/multimc/128x128/instances/creeper_legacy.png
Binary files differ
diff --git a/launcher/resources/multimc/128x128/instances/enderpearl.png b/launcher/resources/multimc/128x128/instances/enderpearl_legacy.png
index 0a5bf91a..0a5bf91a 100644
--- a/launcher/resources/multimc/128x128/instances/enderpearl.png
+++ b/launcher/resources/multimc/128x128/instances/enderpearl_legacy.png
Binary files differ
diff --git a/launcher/resources/multimc/128x128/instances/flame.png b/launcher/resources/multimc/128x128/instances/flame_legacy.png
index 6482975c..6482975c 100644
--- a/launcher/resources/multimc/128x128/instances/flame.png
+++ b/launcher/resources/multimc/128x128/instances/flame_legacy.png
Binary files differ
diff --git a/launcher/resources/multimc/128x128/instances/ftb_logo.png b/launcher/resources/multimc/128x128/instances/ftb_logo_legacy.png
index e725b7fe..e725b7fe 100644
--- a/launcher/resources/multimc/128x128/instances/ftb_logo.png
+++ b/launcher/resources/multimc/128x128/instances/ftb_logo_legacy.png
Binary files differ
diff --git a/launcher/resources/multimc/128x128/instances/gear.png b/launcher/resources/multimc/128x128/instances/gear_legacy.png
index 75c68a66..75c68a66 100644
--- a/launcher/resources/multimc/128x128/instances/gear.png
+++ b/launcher/resources/multimc/128x128/instances/gear_legacy.png
Binary files differ
diff --git a/launcher/resources/multimc/128x128/instances/herobrine.png b/launcher/resources/multimc/128x128/instances/herobrine_legacy.png
index 13f1494c..13f1494c 100644
--- a/launcher/resources/multimc/128x128/instances/herobrine.png
+++ b/launcher/resources/multimc/128x128/instances/herobrine_legacy.png
Binary files differ
diff --git a/launcher/resources/multimc/128x128/instances/infinity.png b/launcher/resources/multimc/128x128/instances/infinity_legacy.png
index 63e06e5b..63e06e5b 100644
--- a/launcher/resources/multimc/128x128/instances/infinity.png
+++ b/launcher/resources/multimc/128x128/instances/infinity_legacy.png
Binary files differ
diff --git a/launcher/resources/multimc/128x128/instances/magitech.png b/launcher/resources/multimc/128x128/instances/magitech_legacy.png
index 0f81a199..0f81a199 100644
--- a/launcher/resources/multimc/128x128/instances/magitech.png
+++ b/launcher/resources/multimc/128x128/instances/magitech_legacy.png
Binary files differ
diff --git a/launcher/resources/multimc/128x128/instances/meat.png b/launcher/resources/multimc/128x128/instances/meat_legacy.png
index fefc9bf1..fefc9bf1 100644
--- a/launcher/resources/multimc/128x128/instances/meat.png
+++ b/launcher/resources/multimc/128x128/instances/meat_legacy.png
Binary files differ
diff --git a/launcher/resources/multimc/128x128/instances/netherstar.png b/launcher/resources/multimc/128x128/instances/netherstar_legacy.png
index 132085f0..132085f0 100644
--- a/launcher/resources/multimc/128x128/instances/netherstar.png
+++ b/launcher/resources/multimc/128x128/instances/netherstar_legacy.png
Binary files differ
diff --git a/launcher/resources/multimc/128x128/instances/skeleton.png b/launcher/resources/multimc/128x128/instances/skeleton_legacy.png
index 55fcf5a9..55fcf5a9 100644
--- a/launcher/resources/multimc/128x128/instances/skeleton.png
+++ b/launcher/resources/multimc/128x128/instances/skeleton_legacy.png
Binary files differ
diff --git a/launcher/resources/multimc/128x128/instances/squarecreeper.png b/launcher/resources/multimc/128x128/instances/squarecreeper_legacy.png
index c82d8406..c82d8406 100644
--- a/launcher/resources/multimc/128x128/instances/squarecreeper.png
+++ b/launcher/resources/multimc/128x128/instances/squarecreeper_legacy.png
Binary files differ
diff --git a/launcher/resources/multimc/128x128/instances/steve.png b/launcher/resources/multimc/128x128/instances/steve_legacy.png
index a07cbd2f..a07cbd2f 100644
--- a/launcher/resources/multimc/128x128/instances/steve.png
+++ b/launcher/resources/multimc/128x128/instances/steve_legacy.png
Binary files differ
diff --git a/launcher/resources/multimc/32x32/instances/brick.png b/launcher/resources/multimc/32x32/instances/brick_legacy.png
index c324fda0..c324fda0 100644
--- a/launcher/resources/multimc/32x32/instances/brick.png
+++ b/launcher/resources/multimc/32x32/instances/brick_legacy.png
Binary files differ
diff --git a/launcher/resources/multimc/32x32/instances/chicken.png b/launcher/resources/multimc/32x32/instances/chicken_legacy.png
index f870467a..f870467a 100644
--- a/launcher/resources/multimc/32x32/instances/chicken.png
+++ b/launcher/resources/multimc/32x32/instances/chicken_legacy.png
Binary files differ
diff --git a/launcher/resources/multimc/32x32/instances/creeper.png b/launcher/resources/multimc/32x32/instances/creeper_legacy.png
index a67ecfc3..a67ecfc3 100644
--- a/launcher/resources/multimc/32x32/instances/creeper.png
+++ b/launcher/resources/multimc/32x32/instances/creeper_legacy.png
Binary files differ
diff --git a/launcher/resources/multimc/32x32/instances/diamond.png b/launcher/resources/multimc/32x32/instances/diamond_legacy.png
index 1eb26469..1eb26469 100644
--- a/launcher/resources/multimc/32x32/instances/diamond.png
+++ b/launcher/resources/multimc/32x32/instances/diamond_legacy.png
Binary files differ
diff --git a/launcher/resources/multimc/32x32/instances/dirt.png b/launcher/resources/multimc/32x32/instances/dirt_legacy.png
index 9e19eb8f..9e19eb8f 100644
--- a/launcher/resources/multimc/32x32/instances/dirt.png
+++ b/launcher/resources/multimc/32x32/instances/dirt_legacy.png
Binary files differ
diff --git a/launcher/resources/multimc/32x32/instances/enderpearl.png b/launcher/resources/multimc/32x32/instances/enderpearl_legacy.png
index a818eb8e..a818eb8e 100644
--- a/launcher/resources/multimc/32x32/instances/enderpearl.png
+++ b/launcher/resources/multimc/32x32/instances/enderpearl_legacy.png
Binary files differ
diff --git a/launcher/resources/multimc/32x32/instances/ftb_logo.png b/launcher/resources/multimc/32x32/instances/ftb_logo_legacy.png
index 20df7171..20df7171 100644
--- a/launcher/resources/multimc/32x32/instances/ftb_logo.png
+++ b/launcher/resources/multimc/32x32/instances/ftb_logo_legacy.png
Binary files differ
diff --git a/launcher/resources/multimc/32x32/instances/gear.png b/launcher/resources/multimc/32x32/instances/gear_legacy.png
index da9ba2f9..da9ba2f9 100644
--- a/launcher/resources/multimc/32x32/instances/gear.png
+++ b/launcher/resources/multimc/32x32/instances/gear_legacy.png
Binary files differ
diff --git a/launcher/resources/multimc/32x32/instances/gold.png b/launcher/resources/multimc/32x32/instances/gold_legacy.png
index 593410fa..593410fa 100644
--- a/launcher/resources/multimc/32x32/instances/gold.png
+++ b/launcher/resources/multimc/32x32/instances/gold_legacy.png
Binary files differ
diff --git a/launcher/resources/multimc/32x32/instances/grass.png b/launcher/resources/multimc/32x32/instances/grass_legacy.png
index f1694547..f1694547 100644
--- a/launcher/resources/multimc/32x32/instances/grass.png
+++ b/launcher/resources/multimc/32x32/instances/grass_legacy.png
Binary files differ
diff --git a/launcher/resources/multimc/32x32/instances/herobrine.png b/launcher/resources/multimc/32x32/instances/herobrine_legacy.png
index e5460da3..e5460da3 100644
--- a/launcher/resources/multimc/32x32/instances/herobrine.png
+++ b/launcher/resources/multimc/32x32/instances/herobrine_legacy.png
Binary files differ
diff --git a/launcher/resources/multimc/32x32/instances/infinity.png b/launcher/resources/multimc/32x32/instances/infinity_legacy.png
index bd94a3dc..bd94a3dc 100644
--- a/launcher/resources/multimc/32x32/instances/infinity.png
+++ b/launcher/resources/multimc/32x32/instances/infinity_legacy.png
Binary files differ
diff --git a/launcher/resources/multimc/32x32/instances/iron.png b/launcher/resources/multimc/32x32/instances/iron_legacy.png
index 3e811bd6..3e811bd6 100644
--- a/launcher/resources/multimc/32x32/instances/iron.png
+++ b/launcher/resources/multimc/32x32/instances/iron_legacy.png
Binary files differ
diff --git a/launcher/resources/multimc/32x32/instances/magitech.png b/launcher/resources/multimc/32x32/instances/magitech_legacy.png
index 6fd8ff60..6fd8ff60 100644
--- a/launcher/resources/multimc/32x32/instances/magitech.png
+++ b/launcher/resources/multimc/32x32/instances/magitech_legacy.png
Binary files differ
diff --git a/launcher/resources/multimc/32x32/instances/meat.png b/launcher/resources/multimc/32x32/instances/meat_legacy.png
index 6694859d..6694859d 100644
--- a/launcher/resources/multimc/32x32/instances/meat.png
+++ b/launcher/resources/multimc/32x32/instances/meat_legacy.png
Binary files differ
diff --git a/launcher/resources/multimc/32x32/instances/netherstar.png b/launcher/resources/multimc/32x32/instances/netherstar_legacy.png
index 43cb5113..43cb5113 100644
--- a/launcher/resources/multimc/32x32/instances/netherstar.png
+++ b/launcher/resources/multimc/32x32/instances/netherstar_legacy.png
Binary files differ
diff --git a/launcher/resources/multimc/32x32/instances/planks.png b/launcher/resources/multimc/32x32/instances/planks_legacy.png
index a94b7502..a94b7502 100644
--- a/launcher/resources/multimc/32x32/instances/planks.png
+++ b/launcher/resources/multimc/32x32/instances/planks_legacy.png
Binary files differ
diff --git a/launcher/resources/multimc/32x32/instances/skeleton.png b/launcher/resources/multimc/32x32/instances/skeleton_legacy.png
index 0c8d3505..0c8d3505 100644
--- a/launcher/resources/multimc/32x32/instances/skeleton.png
+++ b/launcher/resources/multimc/32x32/instances/skeleton_legacy.png
Binary files differ
diff --git a/launcher/resources/multimc/32x32/instances/squarecreeper.png b/launcher/resources/multimc/32x32/instances/squarecreeper_legacy.png
index b78c4ae0..b78c4ae0 100644
--- a/launcher/resources/multimc/32x32/instances/squarecreeper.png
+++ b/launcher/resources/multimc/32x32/instances/squarecreeper_legacy.png
Binary files differ
diff --git a/launcher/resources/multimc/32x32/instances/steve.png b/launcher/resources/multimc/32x32/instances/steve_legacy.png
index 07c6acde..07c6acde 100644
--- a/launcher/resources/multimc/32x32/instances/steve.png
+++ b/launcher/resources/multimc/32x32/instances/steve_legacy.png
Binary files differ
diff --git a/launcher/resources/multimc/32x32/instances/stone.png b/launcher/resources/multimc/32x32/instances/stone_legacy.png
index 1b6ef7a4..1b6ef7a4 100644
--- a/launcher/resources/multimc/32x32/instances/stone.png
+++ b/launcher/resources/multimc/32x32/instances/stone_legacy.png
Binary files differ
diff --git a/launcher/resources/multimc/32x32/instances/tnt.png b/launcher/resources/multimc/32x32/instances/tnt_legacy.png
index e40d404d..e40d404d 100644
--- a/launcher/resources/multimc/32x32/instances/tnt.png
+++ b/launcher/resources/multimc/32x32/instances/tnt_legacy.png
Binary files differ
diff --git a/launcher/resources/multimc/50x50/instances/enderman.png b/launcher/resources/multimc/50x50/instances/enderman_legacy.png
index 9f3a72b3..9f3a72b3 100644
--- a/launcher/resources/multimc/50x50/instances/enderman.png
+++ b/launcher/resources/multimc/50x50/instances/enderman_legacy.png
Binary files differ
diff --git a/launcher/resources/multimc/multimc.qrc b/launcher/resources/multimc/multimc.qrc
index 3f3d22fc..42b496da 100644
--- a/launcher/resources/multimc/multimc.qrc
+++ b/launcher/resources/multimc/multimc.qrc
@@ -6,9 +6,6 @@
<!-- REDDIT logo icon, needs reddit license! -->
<file>scalable/reddit-alien.svg</file>
- <!-- Icon for CurseForge. CC0 -->
- <file alias="128x128/flame.png">128x128/instances/flame.png</file>
-
<!-- launcher settings page -->
<file>scalable/launcher.svg</file>
@@ -254,63 +251,100 @@
<!-- discord logo icon thing. from discord. traced from bitmap -->
<file>scalable/discord.svg</file>
+ <!-- flat instance icons CC BY-SA 4.0, Santiago Cézar -->
+ <file alias="128x128/flame.png">scalable/instances/flame.svg</file>
+ <file>scalable/instances/chicken.svg</file>
+ <file>scalable/instances/creeper.svg</file>
+ <file>scalable/instances/enderpearl.svg</file>
+ <file>scalable/instances/ftb_logo.svg</file>
+ <file>scalable/instances/flame.svg</file>
+ <file>scalable/instances/gear.svg</file>
+ <file>scalable/instances/herobrine.svg</file>
+ <file>scalable/instances/magitech.svg</file>
+ <file>scalable/instances/meat.svg</file>
+ <file>scalable/instances/netherstar.svg</file>
+ <file>scalable/instances/skeleton.svg</file>
+ <file>scalable/instances/squarecreeper.svg</file>
+ <file>scalable/instances/steve.svg</file>
+ <file>scalable/instances/diamond.svg</file>
+ <file>scalable/instances/dirt.svg</file>
+ <file>scalable/instances/grass.svg</file>
+ <file>scalable/instances/brick.svg</file>
+ <file>scalable/instances/gold.svg</file>
+ <file>scalable/instances/iron.svg</file>
+ <file>scalable/instances/planks.svg</file>
+ <file>scalable/instances/stone.svg</file>
+ <file>scalable/instances/tnt.svg</file>
+ <file>scalable/instances/enderman.svg</file>
+ <file>scalable/instances/fox.svg</file>
+ <file>scalable/instances/bee.svg</file>
+
<!-- instance icons -->
- <file>32x32/instances/chicken.png</file>
- <file>128x128/instances/chicken.png</file>
+ <file>32x32/instances/chicken_legacy.png</file>
+ <file>128x128/instances/chicken_legacy.png</file>
- <file>32x32/instances/creeper.png</file>
- <file>128x128/instances/creeper.png</file>
+ <file>32x32/instances/creeper_legacy.png</file>
+ <file>128x128/instances/creeper_legacy.png</file>
- <file>32x32/instances/enderpearl.png</file>
- <file>128x128/instances/enderpearl.png</file>
+ <file>32x32/instances/enderpearl_legacy.png</file>
+ <file>128x128/instances/enderpearl_legacy.png</file>
<file>32x32/instances/ftb_glow.png</file>
<file>128x128/instances/ftb_glow.png</file>
- <file>32x32/instances/ftb_logo.png</file>
- <file>128x128/instances/ftb_logo.png</file>
+ <file>32x32/instances/ftb_logo_legacy.png</file>
+ <file>128x128/instances/ftb_logo_legacy.png</file>
- <file>128x128/instances/flame.png</file>
+ <file>128x128/instances/flame_legacy.png</file>
- <file>32x32/instances/gear.png</file>
- <file>128x128/instances/gear.png</file>
+ <file>32x32/instances/gear_legacy.png</file>
+ <file>128x128/instances/gear_legacy.png</file>
- <file>32x32/instances/herobrine.png</file>
- <file>128x128/instances/herobrine.png</file>
+ <file>32x32/instances/herobrine_legacy.png</file>
+ <file>128x128/instances/herobrine_legacy.png</file>
- <file>32x32/instances/magitech.png</file>
- <file>128x128/instances/magitech.png</file>
+ <file>32x32/instances/magitech_legacy.png</file>
+ <file>128x128/instances/magitech_legacy.png</file>
- <file>32x32/instances/meat.png</file>
- <file>128x128/instances/meat.png</file>
+ <file>32x32/instances/meat_legacy.png</file>
+ <file>128x128/instances/meat_legacy.png</file>
- <file>32x32/instances/netherstar.png</file>
- <file>128x128/instances/netherstar.png</file>
+ <file>32x32/instances/netherstar_legacy.png</file>
+ <file>128x128/instances/netherstar_legacy.png</file>
- <file>32x32/instances/skeleton.png</file>
- <file>128x128/instances/skeleton.png</file>
+ <file>32x32/instances/skeleton_legacy.png</file>
+ <file>128x128/instances/skeleton_legacy.png</file>
- <file>32x32/instances/squarecreeper.png</file>
- <file>128x128/instances/squarecreeper.png</file>
+ <file>32x32/instances/squarecreeper_legacy.png</file>
+ <file>128x128/instances/squarecreeper_legacy.png</file>
- <file>32x32/instances/steve.png</file>
- <file>128x128/instances/steve.png</file>
+ <file>32x32/instances/steve_legacy.png</file>
+ <file>128x128/instances/steve_legacy.png</file>
- <file>32x32/instances/brick.png</file>
- <file>32x32/instances/diamond.png</file>
- <file>32x32/instances/dirt.png</file>
- <file>32x32/instances/gold.png</file>
- <file>32x32/instances/grass.png</file>
- <file>32x32/instances/iron.png</file>
- <file>32x32/instances/planks.png</file>
- <file>32x32/instances/stone.png</file>
- <file>32x32/instances/tnt.png</file>
+ <file>32x32/instances/brick_legacy.png</file>
+ <file>32x32/instances/diamond_legacy.png</file>
+ <file>32x32/instances/dirt_legacy.png</file>
+ <file>32x32/instances/gold_legacy.png</file>
+ <file>32x32/instances/grass_legacy.png</file>
+ <file>32x32/instances/iron_legacy.png</file>
+ <file>32x32/instances/planks_legacy.png</file>
+ <file>32x32/instances/stone_legacy.png</file>
+ <file>32x32/instances/tnt_legacy.png</file>
- <file>50x50/instances/enderman.png</file>
+ <file>50x50/instances/enderman_legacy.png</file>
- <file>scalable/instances/fox.svg</file>
- <file>scalable/instances/bee.svg</file>
<file>scalable/instances/prismlauncher.svg</file>
+ <file>scalable/instances/fox_legacy.svg</file>
+ <file>scalable/instances/bee_legacy.svg</file>
+
+ <!-- delete, tag, rename, shortcut CC-BY-SA 3.0, Oxygen icons.-->
+ <file>scalable/delete.svg</file>
+ <file>scalable/tag.svg</file>
+ <file>scalable/rename.svg</file>
+ <file>scalable/shortcut.svg</file>
+
+ <file>scalable/export.svg</file>
+ <file>scalable/launch.svg</file>
</qresource>
</RCC>
diff --git a/launcher/resources/multimc/scalable/delete.svg b/launcher/resources/multimc/scalable/delete.svg
new file mode 100644
index 00000000..414cbd5c
--- /dev/null
+++ b/launcher/resources/multimc/scalable/delete.svg
@@ -0,0 +1,282 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="33.866665mm"
+ height="33.866665mm"
+ viewBox="0 0 33.866665 33.866665"
+ version="1.1"
+ id="svg2411"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <defs
+ id="defs2408">
+ <linearGradient
+ xlink:href="#linearGradient3315"
+ id="linearGradient3321"
+ x1="20.961376"
+ y1="70.875"
+ x2="106.96138"
+ y2="70.875"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.26458333,0,0,0.26458333,-152.84859,113.94802)" />
+ <linearGradient
+ id="linearGradient3315">
+ <stop
+ style="stop-color:#bf0303;stop-opacity:1;"
+ offset="0"
+ id="stop3317" />
+ <stop
+ id="stop3323"
+ offset="0.375"
+ style="stop-color:#fc3d3d;stop-opacity:1;" />
+ <stop
+ style="stop-color:#bf0303;stop-opacity:1;"
+ offset="0.75"
+ id="stop3325" />
+ <stop
+ style="stop-color:#bf0303;stop-opacity:1;"
+ offset="1"
+ id="stop3319" />
+ </linearGradient>
+ <linearGradient
+ xlink:href="#linearGradient3335"
+ id="linearGradient3341"
+ x1="22.032"
+ y1="39.036999"
+ x2="105.967"
+ y2="39.036999"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.26458333,0,0,0.26458333,-152.84859,113.94802)" />
+ <linearGradient
+ id="linearGradient3335">
+ <stop
+ style="stop-color:#9c0f0f;stop-opacity:0.28301886;"
+ offset="0"
+ id="stop3337" />
+ <stop
+ id="stop3343"
+ offset="0.5"
+ style="stop-color:#9c0f0f;stop-opacity:1;" />
+ <stop
+ style="stop-color:#9c0f0f;stop-opacity:0.1981132;"
+ offset="1"
+ id="stop3339" />
+ </linearGradient>
+ <linearGradient
+ xlink:href="#linearGradient3347"
+ id="linearGradient3353"
+ x1="12.190286"
+ y1="21.738001"
+ x2="115.80972"
+ y2="21.738001"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.26458333,0,0,0.26458333,-152.84859,113.94802)" />
+ <linearGradient
+ id="linearGradient3347">
+ <stop
+ style="stop-color:#d50303;stop-opacity:1;"
+ offset="0"
+ id="stop3349" />
+ <stop
+ id="stop3355"
+ offset="0.5"
+ style="stop-color:#feaeae;stop-opacity:1;" />
+ <stop
+ style="stop-color:#d50303;stop-opacity:1;"
+ offset="1"
+ id="stop3351" />
+ </linearGradient>
+ <linearGradient
+ xlink:href="#linearGradient3371"
+ id="linearGradient3377"
+ x1="68.617584"
+ y1="9.6200819"
+ x2="68.617584"
+ y2="34.302147"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.26458333,0,0,0.26458333,-152.84859,113.94802)" />
+ <linearGradient
+ id="linearGradient3371">
+ <stop
+ style="stop-color:#950000;stop-opacity:1;"
+ offset="0"
+ id="stop3373" />
+ <stop
+ style="stop-color:#350000;stop-opacity:1;"
+ offset="1"
+ id="stop3375" />
+ </linearGradient>
+ <linearGradient
+ xlink:href="#linearGradient3418"
+ id="linearGradient3432"
+ gradientUnits="userSpaceOnUse"
+ x1="41.25"
+ y1="85.302696"
+ x2="86.75"
+ y2="85.302696"
+ gradientTransform="matrix(0.26458333,0,0,0.26458333,-152.84859,113.94802)" />
+ <linearGradient
+ id="linearGradient3418">
+ <stop
+ id="stop3420"
+ offset="0"
+ style="stop-color:#390000;stop-opacity:1;" />
+ <stop
+ style="stop-color:#da0303;stop-opacity:1;"
+ offset="0.375"
+ id="stop3422" />
+ <stop
+ id="stop3424"
+ offset="0.75"
+ style="stop-color:#7b0101;stop-opacity:1;" />
+ <stop
+ id="stop3426"
+ offset="1"
+ style="stop-color:#390000;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ xlink:href="#linearGradient3418"
+ id="linearGradient3429"
+ gradientUnits="userSpaceOnUse"
+ x1="41.25"
+ y1="85.651398"
+ x2="86.75"
+ y2="85.651398"
+ gradientTransform="matrix(0.26458333,0,0,0.26458333,-152.84859,113.94802)" />
+ <linearGradient
+ xlink:href="#linearGradient3418"
+ id="linearGradient3416"
+ gradientUnits="userSpaceOnUse"
+ x1="41.25"
+ y1="64.263702"
+ x2="86.75"
+ y2="64.263702"
+ gradientTransform="matrix(0.26458333,0,0,0.26458333,-152.84859,113.94802)" />
+ <radialGradient
+ r="63.912209"
+ fy="115.7093"
+ fx="63.912209"
+ cy="115.70919"
+ cx="63.912209"
+ gradientTransform="matrix(1,0,0,0.197802,0,92.82166)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient3336"
+ xlink:href="#linearGradient3291" />
+ <linearGradient
+ id="linearGradient3291">
+ <stop
+ id="stop3293"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop3295"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ </defs>
+ <g
+ id="layer1"
+ transform="translate(196.3033,-17.933071)">
+ <g
+ id="g6686"
+ transform="translate(-43.45471,-96.01495)">
+ <path
+ d="m -135.91552,144.90744 c -3.41895,0 -6.36323,-0.76173 -8.22219,-1.87536 -0.49954,-0.0998 -0.96044,-0.2032 -1.37795,-0.3048 1.48722,1.68248 5.14376,2.97391 9.60014,2.97391 4.45664,0 8.11318,-1.29143 9.6004,-2.97391 -0.41751,0.10186 -0.87841,0.20505 -1.37795,0.3048 -1.85896,1.11363 -4.80298,1.87536 -8.22245,1.87536 z"
+ id="path202"
+ style="opacity:0.1;fill:#004d00;stroke-width:0.264583" />
+ <path
+ d="m -135.91552,145.17203 c -3.80127,0 -7.01569,-0.94112 -8.80295,-2.26192 -0.27993,-0.0606 -0.54743,-0.12198 -0.79719,-0.18283 1.48722,1.68248 5.14376,2.97391 9.60014,2.97391 4.45664,0 8.11318,-1.29143 9.6004,-2.97391 -0.24976,0.0608 -0.51726,0.1225 -0.79718,0.18283 -1.78727,1.3208 -5.00169,2.26192 -8.80322,2.26192 z"
+ id="path204"
+ style="opacity:0.2;fill:#004d00;stroke-width:0.264583" />
+ <path
+ d="m -135.91552,145.43661 c -4.1447,0 -7.59513,-1.11786 -9.25433,-2.62784 -0.11748,-0.027 -0.23442,-0.0542 -0.34581,-0.0818 1.48722,1.68249 5.14376,2.97392 9.60014,2.97392 4.45664,0 8.11318,-1.29143 9.6004,-2.97392 -0.11138,0.0275 -0.22833,0.0548 -0.34607,0.0818 -1.65894,1.50998 -5.10937,2.62784 -9.25433,2.62784 z"
+ id="path206"
+ style="opacity:0.3;fill:#004d00;stroke-width:0.264583" />
+ <path
+ style="fill:url(#linearGradient3321);fill-opacity:1;stroke-width:0.264583"
+ id="path3962"
+ d="m -147.30256,119.69953 1.05833,21.36828 c 0,2.41274 4.47384,4.63338 10.31849,4.63338 5.84517,0 10.31901,-2.22064 10.31901,-4.63338 l 1.05834,-21.36828 z" />
+ <rect
+ id="_x3C_Sezione_x3E_"
+ width="33.866665"
+ height="33.866665"
+ x="-152.84859"
+ y="113.94802"
+ style="fill:none;stroke-width:0.264583" />
+ <path
+ d="m -124.84059,122.62688 0.0291,-0.322 c -1.12712,2.10397 -5.6679,3.67851 -11.1043,3.67851 -5.43586,0 -9.9769,-1.57454 -11.1035,-3.67851 l 0.0288,0.322 c 1.17792,2.07539 5.68801,3.62135 11.07466,3.62135 5.38745,-2.6e-4 9.89727,-1.54596 11.0752,-3.62135 z"
+ id="path66"
+ style="opacity:0.5;fill:url(#linearGradient3341);fill-opacity:1;stroke-width:0.264583" />
+ <ellipse
+ cx="-135.91525"
+ cy="119.69953"
+ rx="11.377083"
+ ry="4.6963539"
+ id="ellipse75"
+ style="fill:url(#linearGradient3353);fill-opacity:1;stroke-width:0.264583" />
+ <path
+ d="m -146.34804,119.44606 c 0,1.9222 4.19206,3.97986 10.43252,3.97986 6.24073,0 10.43305,-2.05766 10.43305,-3.97986 0,-1.92193 -4.19232,-3.71528 -10.43305,-3.71528 -6.24046,0 -10.43252,1.79361 -10.43252,3.71528 z"
+ id="path90"
+ style="opacity:0.727778;fill:url(#linearGradient3377);fill-opacity:1;stroke-width:0.264583" />
+ <path
+ d="m -135.91552,115.73801 c -6.24046,0 -10.43252,1.92905 -10.43252,3.73061 0,0.47023 0.28786,0.94865 0.82074,1.39978 -0.0302,-0.13616 -0.0453,-0.27207 -0.0453,-0.40773 0,-2.65478 5.59455,-4.47464 9.65703,-4.47464 7.90334,0 11.98846,2.51962 9.65755,4.47464 -0.10375,0.087 -0.0153,0.27157 -0.0455,0.40773 0.53313,-0.45088 0.821,-0.92955 0.821,-1.39978 0,-1.80132 -4.19232,-3.73061 -10.43305,-3.73061 z"
+ id="path99"
+ style="opacity:0.494444;fill:#000000;fill-opacity:1;stroke-width:0.264583" />
+ <g
+ id="g335"
+ transform="matrix(0.26458333,0,0,0.26458333,-152.84859,113.94802)">
+ <path
+ d="m 63.999,32.22 c -21.36,0 -36.348,-6.18 -38.912,-12.556 -0.258,0.642 -0.393,1.286 -0.393,1.925 0,6.994 15.793,14.482 39.305,14.482 23.513,0 39.307,-7.488 39.307,-14.482 0,-0.639 -0.136,-1.283 -0.394,-1.925 C 100.35,26.04 85.36,32.22 63.999,32.22 Z"
+ id="path337"
+ style="opacity:0.1;fill:#555555" />
+ <path
+ d="m 63.999,33.184 c -21.897,0 -37.093,-6.496 -39.077,-13.037 -0.147,0.481 -0.228,0.964 -0.228,1.443 0,6.994 15.793,14.482 39.305,14.482 23.513,0 39.307,-7.488 39.307,-14.482 0,-0.479 -0.082,-0.962 -0.228,-1.443 -1.983,6.541 -17.18,13.037 -39.079,13.037 z"
+ id="path339"
+ style="opacity:0.15;fill:#555555" />
+ <path
+ d="m 63.999,34.146 c -22.435,0 -37.832,-6.818 -39.195,-13.519 -0.065,0.321 -0.109,0.642 -0.109,0.962 0,6.994 15.793,14.482 39.305,14.482 23.513,0 39.307,-7.488 39.307,-14.482 0,-0.32 -0.044,-0.641 -0.11,-0.962 -1.364,6.701 -16.762,13.519 -39.198,13.519 z"
+ id="path341"
+ style="opacity:0.2;fill:#555555" />
+ <path
+ d="m 63.999,35.109 c -22.973,0 -38.568,-7.148 -39.271,-14 -0.017,0.161 -0.034,0.321 -0.034,0.481 0,6.994 15.793,14.482 39.305,14.482 23.513,0 39.307,-7.488 39.307,-14.482 0,-0.16 -0.018,-0.32 -0.034,-0.481 -0.704,6.851 -16.299,14 -39.273,14 z"
+ id="path343"
+ style="opacity:0.25;fill:#555555" />
+ </g>
+ <path
+ style="fill:url(#linearGradient3432);fill-opacity:1;stroke-width:0.264583"
+ d="m -139.65779,133.54386 -2.07539,0.27648 c -0.11033,0.0148 -0.20214,0.0968 -0.22595,0.20559 -0.004,0.0196 -0.006,0.0389 -0.006,0.0587 0,0.0886 0.0437,0.17304 0.12091,0.22199 0,0 0.42333,0.26776 0.66067,0.41778 -0.22728,0.47334 -0.6657,1.50389 -0.6657,2.19233 0,0.11033 0.0114,0.2122 0.0368,0.3011 0.40323,1.76503 1.81531,2.08624 2.23838,2.14233 0.045,0.006 0.0937,0.0116 0.14208,0.0114 0.948,0.068 1.91452,0.10927 2.87284,0.12276 0.0722,0.001 0.14155,-0.0275 0.19235,-0.0788 0.0508,-0.0513 0.0781,-0.12118 0.0759,-0.19315 l -0.0389,-1.33561 c -0.004,-0.14156 -0.11907,-0.25506 -0.26062,-0.25718 -1.0459,-0.0151 -2.09841,-0.063 -3.1287,-0.1434 -0.008,-5.3e-4 -0.0241,-5.3e-4 -0.0325,-5.3e-4 -0.0894,0.002 -0.28787,-0.0352 -0.32676,-0.32306 0.14023,-0.3638 0.43524,-1.00912 0.60431,-1.36684 0.0132,0.008 0.51064,0.31883 0.51064,0.31883 0.0963,0.0603 0.22093,0.054 0.30877,-0.0183 0.0878,-0.072 0.12039,-0.1905 0.0799,-0.2966 l -0.79666,-2.09179 c -0.0442,-0.11483 -0.16431,-0.18018 -0.28602,-0.16404 z m 0.47546,5.68774 c -0.0243,0.0458 -0.0616,0.0807 -0.10478,0.10478 0.0397,-0.0214 0.0767,-0.0519 0.10478,-0.10478 z m -0.18627,0.12727 c -0.0217,0.004 -0.0413,0.014 -0.064,0.0127 0.0222,-2.7e-4 0.0426,-0.009 0.064,-0.0127 z"
+ id="path368" />
+ <path
+ style="fill:url(#linearGradient3429);fill-opacity:1;stroke-width:0.264583"
+ d="m -131.65414,133.01786 -1.30969,0.79058 c -0.0823,0.0497 -0.12806,0.13758 -0.12806,0.22728 0,0.0434 0.0109,0.0873 0.0333,0.12779 0.52229,0.94112 0.98028,1.88145 1.36155,2.79532 0.003,0.007 0.0135,0.0265 0.0172,0.0336 0.0151,0.028 0.0328,0.0733 0.0328,0.127 0,0.0815 -0.0529,0.18257 -0.20717,0.27676 -0.40719,0.0392 -1.1348,0.0815 -1.5404,0.10186 0.0198,-0.24394 0.0431,-0.52863 0.0431,-0.52863 5.2e-4,-0.007 7.9e-4,-0.0146 7.9e-4,-0.0217 0,-0.10425 -0.0611,-0.1995 -0.15769,-0.24209 -0.10345,-0.0453 -0.22384,-0.0204 -0.30057,0.0619 l -1.44251,1.55284 c -0.0897,0.0966 -0.0939,0.24447 -0.0111,0.34687 l 1.19459,1.47426 c 0.068,0.0839 0.18045,0.11826 0.28364,0.0865 0.10345,-0.032 0.177,-0.12329 0.186,-0.23098 0,0 0.0439,-0.53313 0.0529,-0.64214 0.92101,-0.0299 2.02935,-0.13917 2.47597,-0.4789 0.96811,-0.67574 1.20517,-1.55072 1.20517,-2.20054 0,-0.38893 -0.0847,-0.69717 -0.14869,-0.83423 -0.36407,-0.90302 -0.7882,-1.81583 -1.27027,-2.72203 -0.0341,-0.064 -0.0937,-0.11113 -0.16351,-0.13044 -0.0699,-0.0193 -0.14526,-0.008 -0.20743,0.0291 z"
+ id="path391" />
+ <path
+ style="fill:url(#linearGradient3416);fill-opacity:1;stroke-width:0.264583"
+ d="m -137.7004,129.01816 c -0.10319,0.0844 -0.61569,0.51832 -0.55933,0.77708 -0.0154,-0.0704 -7.9e-4,-0.14314 0.0392,-0.20294 -0.61595,0.92049 -1.18057,1.84785 -1.67852,2.7567 -0.0696,0.12673 -0.0254,0.28548 0.10028,0.35666 l 1.34488,0.7612 c 0.12673,0.0717 0.28707,0.0273 0.3593,-0.0998 0.53419,-0.93636 1.14459,-1.90367 1.81478,-2.87496 0.005,-0.007 0.0146,-0.0249 0.0188,-0.0325 8e-4,-0.001 0.0807,-0.13997 0.2167,-0.17542 0.0825,-0.0214 0.18388,0.0101 0.29368,0.0709 0.26644,0.39767 0.69956,1.11733 0.92393,1.49436 -0.15849,0.0791 -0.57706,0.28734 -0.57706,0.28734 -0.0905,0.0452 -0.14631,0.13758 -0.14631,0.2368 0,0.0108 7.9e-4,0.022 0.002,0.0328 0.0138,0.11139 0.0966,0.20214 0.20612,0.22596 l 2.2217,0.48762 c 0.12303,0.0273 0.24871,-0.0357 0.29977,-0.15055 l 0.92366,-2.08359 c 0.0455,-0.10266 0.0209,-0.22251 -0.0608,-0.29951 -0.0818,-0.077 -0.20373,-0.0937 -0.30321,-0.0421 0,0 -0.42598,0.22067 -0.69321,0.35904 -0.33232,-0.6932 -1.22555,-1.97696 -1.81451,-2.22197 -1.42187,-0.62838 -2.4474,-0.059 -2.93185,0.33682 z m 4.88527,2.27197 c 0,-0.0148 -0.0132,-0.0455 -0.0167,-0.0645 0.003,0.0148 0.0193,0.0235 0.0193,0.0386 0,0.0161 -0.002,0.0323 -0.005,0.0487 0.001,-0.007 0.002,-0.0146 0.002,-0.0228 z"
+ id="path414" />
+ <path
+ d="m -139.74034,137.74994 c -2.6e-4,7.9e-4 -0.57309,0.0283 -0.61277,-0.61278 0.18573,-0.50482 0.76094,-1.72111 0.76993,-1.72111 0.25665,0.16007 0.50906,0.31856 0.75883,0.47413 -0.25162,-0.69162 -0.51594,-1.38589 -0.79375,-2.08465 -0.70882,0.10715 -1.40414,0.19923 -2.08465,0.27781 0.29157,0.18494 0.57891,0.36698 0.86227,0.54557 -0.0275,-10e-4 -0.9144,1.82986 -0.71807,2.51619 0.43471,1.90077 2.13809,1.97062 2.14259,1.96241 0.95118,0.0683 1.905,0.10875 2.86015,0.12224 -0.0127,-0.44582 -0.0262,-0.89059 -0.0389,-1.33562 -1.05092,-0.0151 -2.10052,-0.0627 -3.14563,-0.14419 z"
+ id="path416"
+ style="fill:#ffffff;stroke-width:0.264583" />
+ <path
+ d="m -131.45279,136.8575 c 0.003,-8e-4 0.2794,0.48392 -0.30507,0.79613 -0.56171,0.0593 -1.92378,0.12647 -1.92431,0.12197 0.023,-0.27596 0.0672,-0.82682 0.0672,-0.82682 -0.48101,0.51541 -0.9615,1.03293 -1.44198,1.55204 0.3982,0.48922 0.79719,0.98108 1.19539,1.47532 0.0238,-0.2921 0.0487,-0.58473 0.0722,-0.87736 0,-0.005 1.99893,-0.006 2.56064,-0.43259 1.60179,-1.11866 0.99404,-2.74426 0.96149,-2.73553 -0.35586,-0.89588 -0.77232,-1.79017 -1.24909,-2.68658 -0.44477,0.27041 -0.88265,0.5342 -1.31075,0.79137 0.52335,0.94377 0.9824,1.88278 1.37425,2.82205 z"
+ id="path418"
+ style="fill:#ffffff;stroke-width:0.264583" />
+ <path
+ d="m -136.4976,130.3416 c -0.003,-5.3e-4 0.30612,-0.58552 0.92471,-0.19817 0.36486,0.53366 1.11919,1.81557 1.11919,1.81557 -0.27675,0.13838 -0.55483,0.27649 -0.83185,0.41434 0.74163,0.1606 1.48326,0.32253 2.22356,0.48815 0.30771,-0.69241 0.61569,-1.38668 0.9234,-2.08332 0,0 -0.62971,0.32755 -0.93928,0.48604 0.0201,-5.3e-4 -1.03928,-2.02645 -1.79228,-2.33945 -2.02301,-0.89323 -3.16124,0.80566 -3.13082,0.81412 -0.61462,0.91837 -1.16919,1.82907 -1.66634,2.73659 0.45693,0.26194 0.90434,0.51408 1.34249,0.75988 0.54637,-0.95647 1.15464,-1.91876 1.82722,-2.89375 z"
+ id="path420"
+ style="fill:#ffffff;stroke-width:0.264583" />
+ <g
+ id="layer1-3"
+ transform="matrix(0.26458333,0,0,0.26458333,-152.84859,113.94802)">
+ <path
+ transform="matrix(1.001374,0,0,0.410363,-2.393169e-5,75.32943)"
+ d="m 127.82442,115.70919 a 63.91221,12.641975 0 1 1 -127.82442,0 63.91221,12.641975 0 1 1 127.82442,0 z"
+ id="path1563"
+ style="opacity:0.381395;fill:url(#radialGradient3336);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ </g>
+ </g>
+ </g>
+</svg>
diff --git a/launcher/resources/multimc/scalable/export.svg b/launcher/resources/multimc/scalable/export.svg
new file mode 100644
index 00000000..2605de14
--- /dev/null
+++ b/launcher/resources/multimc/scalable/export.svg
@@ -0,0 +1,466 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ height="128"
+ id="svg2811"
+ version="1.0"
+ width="128"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/">
+ <metadata
+ id="metadata2">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:description />
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>unsorted</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://www.openclipart.org/">
+ <dc:title>Open Clip Art Library, Source: Oxygen Icons, Source: Oxygen Icons, Source: Oxygen Icons, Source: Oxygen Icons</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title />
+ </cc:Agent>
+ </dc:creator>
+ <dc:rights>
+ <cc:Agent>
+ <dc:title />
+ </cc:Agent>
+ </dc:rights>
+ <dc:date />
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/3.0/ or http://creativecommons.org/licenses/LGPL/2.1/" />
+ <dc:language>en</dc:language>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs2813">
+ <linearGradient
+ gradientTransform="matrix(1.0033808,0,0,1,-8.2378002,8)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2937"
+ x1="122.74438"
+ x2="122.39215"
+ y1="96.721588"
+ y2="20.043535">
+ <stop
+ id="stop2939"
+ offset="0"
+ style="stop-color:#72b4f4;stop-opacity:1" />
+ <stop
+ id="stop2941"
+ offset="0.13053299"
+ style="stop-color:#b3d9ff;stop-opacity:1" />
+ <stop
+ id="stop2943"
+ offset="0.34621301"
+ style="stop-color:#b3d9ff;stop-opacity:1" />
+ <stop
+ id="stop2945"
+ offset="0.72006166"
+ style="stop-color:#71a8f5;stop-opacity:1" />
+ <stop
+ id="stop2947"
+ offset="1"
+ style="stop-color:#508ed9;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ gradientTransform="translate(242.00093,332.5)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2927"
+ x1="-178"
+ x2="-178"
+ y1="-228.3945"
+ y2="-304.61469">
+ <stop
+ id="stop2929"
+ offset="0"
+ style="stop-color:#cfe7ff;stop-opacity:1" />
+ <stop
+ id="stop2931"
+ offset="0.1"
+ style="stop-color:#71a8f5;stop-opacity:1" />
+ <stop
+ id="stop2933"
+ offset="1"
+ style="stop-color:#2c72c7;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2822">
+ <stop
+ id="stop2824"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1" />
+ <stop
+ id="stop2826"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0" />
+ </linearGradient>
+ <linearGradient
+ gradientTransform="matrix(1.0033404,0,0,1,-8.2374684,8)"
+ gradientUnits="userSpaceOnUse"
+ id="XMLID_9_"
+ x1="71.999496"
+ x2="71.999496"
+ y1="14.2578"
+ y2="19.9583">
+ <stop
+ id="stop46"
+ offset="0.25"
+ style="stop-color:#71a8f5;stop-opacity:0" />
+ <stop
+ id="stop48"
+ offset="1"
+ style="stop-color:#0057ae;stop-opacity:1" />
+ </linearGradient>
+ <filter
+ height="1.768"
+ id="filter2807"
+ width="1.0512"
+ x="-0.025599999"
+ y="-0.38399999">
+ <feGaussianBlur
+ id="feGaussianBlur2809"
+ stdDeviation="1.28" />
+ </filter>
+ <linearGradient
+ gradientTransform="translate(-6.999995,8)"
+ gradientUnits="userSpaceOnUse"
+ id="XMLID_6_"
+ x1="72.000504"
+ x2="72.000504"
+ y1="96"
+ y2="0.00048828119">
+ <stop
+ id="stop7"
+ offset="0"
+ style="stop-color:#00479e;stop-opacity:1" />
+ <stop
+ id="stop9"
+ offset="0.0769"
+ style="stop-color:#2c72c7;stop-opacity:1" />
+ <stop
+ id="stop11"
+ offset="0.58579999"
+ style="stop-color:#6ea1df;stop-opacity:1" />
+ <stop
+ id="stop13"
+ offset="0.96450001"
+ style="stop-color:#adcbee;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ gradientTransform="matrix(1.0033808,0,0,1,-8.2378,8)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient3109"
+ x1="122.74438"
+ x2="122.74438"
+ xlink:href="#linearGradient2937"
+ y1="96"
+ y2="20" />
+ <linearGradient
+ gradientTransform="translate(242.00093,332.5)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2923"
+ x1="-168.99216"
+ x2="-168.99216"
+ xlink:href="#linearGradient2822"
+ y1="-300.5"
+ y2="-296.48441" />
+ <linearGradient
+ gradientTransform="translate(242.00093,332.5)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2925"
+ x1="-178"
+ x2="-178"
+ xlink:href="#linearGradient2927"
+ y1="-228.5"
+ y2="-304.61469" />
+ <linearGradient
+ gradientTransform="translate(242.00093,364.5)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2197"
+ x1="-168.99216"
+ x2="-168.99216"
+ xlink:href="#linearGradient2822"
+ y1="-300.5"
+ y2="-296.48441" />
+ <linearGradient
+ gradientTransform="matrix(1,0,0,0.7368421,242.00093,284.36842)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2201"
+ x1="-178"
+ x2="-178"
+ xlink:href="#linearGradient2927"
+ y1="-228.5"
+ y2="-304.61469" />
+ <linearGradient
+ gradientTransform="matrix(1.0033404,0,0,1,-7.2374684,40)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2204"
+ x1="71.999496"
+ x2="71.999496"
+ xlink:href="#XMLID_9_"
+ y1="14.2578"
+ y2="19.9583" />
+ <linearGradient
+ gradientTransform="matrix(1.0033808,0,0,0.7368421,-8.2378,45.263158)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2207"
+ x1="122.74438"
+ x2="122.74438"
+ xlink:href="#linearGradient2937"
+ y1="96"
+ y2="20" />
+ <linearGradient
+ gradientTransform="translate(-6.999995,20)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2212"
+ x1="72.000504"
+ x2="72.000504"
+ xlink:href="#XMLID_6_"
+ y1="96"
+ y2="0.00048828119" />
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient10213"
+ x1="98.617439"
+ x2="91.228737"
+ xlink:href="#linearGradient10207"
+ y1="106.41443"
+ y2="99.254974" />
+ <radialGradient
+ cx="102"
+ cy="112.3047"
+ fx="102"
+ fy="112.3047"
+ gradientTransform="matrix(1.295034,1.3831431e-7,-1.3627884e-7,1.2946006,-30.093452,-33.119615)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient9437"
+ r="139.55859"
+ xlink:href="#XMLID_8_" />
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath7084">
+ <path
+ d="M 72,88 L 40,120 L 32,120 L 32,80 L 72,80 L 72,88 z"
+ id="path7086"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ </clipPath>
+ <radialGradient
+ cx="102"
+ cy="112.3047"
+ gradientUnits="userSpaceOnUse"
+ id="XMLID_8_"
+ r="139.55859">
+ <stop
+ id="stop41"
+ offset="0"
+ style="stop-color:#b7b8b9;stop-opacity:1;" />
+ <stop
+ id="stop47"
+ offset="0.18851049"
+ style="stop-color:#ECECEC" />
+ <stop
+ id="stop49"
+ offset="0.25718147"
+ style="stop-color:#FAFAFA" />
+ <stop
+ id="stop51"
+ offset="0.30111277"
+ style="stop-color:#FFFFFF" />
+ <stop
+ id="stop53"
+ offset="0.5313"
+ style="stop-color:#FAFAFA" />
+ <stop
+ id="stop55"
+ offset="0.8449"
+ style="stop-color:#EBECEC" />
+ <stop
+ id="stop57"
+ offset="1"
+ style="stop-color:#E1E2E3" />
+ </radialGradient>
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ id="XMLID_12_"
+ x1="96"
+ x2="88.000198"
+ y1="104"
+ y2="96.000198">
+ <stop
+ id="stop83"
+ offset="0"
+ style="stop-color:#888A85" />
+ <stop
+ id="stop85"
+ offset="0.0072"
+ style="stop-color:#8C8E89" />
+ <stop
+ id="stop87"
+ offset="0.0673"
+ style="stop-color:#ABACA9" />
+ <stop
+ id="stop89"
+ offset="0.1347"
+ style="stop-color:#C5C6C4" />
+ <stop
+ id="stop91"
+ offset="0.2652576"
+ style="stop-color:#DBDBDA" />
+ <stop
+ id="stop93"
+ offset="0.37646064"
+ style="stop-color:#EBEBEB" />
+ <stop
+ id="stop95"
+ offset="0.48740286"
+ style="stop-color:#F7F7F6" />
+ <stop
+ id="stop97"
+ offset="0.6324091"
+ style="stop-color:#FDFDFD" />
+ <stop
+ id="stop99"
+ offset="1"
+ style="stop-color:#FFFFFF" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient10207">
+ <stop
+ id="stop10209"
+ offset="0"
+ style="stop-color:#a2a2a2;stop-opacity:1;" />
+ <stop
+ id="stop10211"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ gradientTransform="matrix(1.0172054,0,0,1.5,246.03226,514.75)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient3385"
+ x1="-168.99216"
+ x2="-168.99216"
+ xlink:href="#linearGradient2822"
+ y1="-300.5"
+ y2="-296.48441" />
+ <linearGradient
+ gradientTransform="matrix(1,0,0,0.7368421,242.00093,284.36842)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient3387"
+ x1="-178"
+ x2="-178"
+ xlink:href="#linearGradient2927"
+ y1="-232.84966"
+ y2="-304.61469" />
+ <linearGradient
+ xlink:href="#linearGradient9732"
+ id="linearGradient3302"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0017056,0,0,1.0011229,34.393692,27.039518)"
+ x1="66.635262"
+ y1="48.579208"
+ x2="13.134155"
+ y2="48.579208" />
+ <linearGradient
+ id="linearGradient9732">
+ <stop
+ id="stop9734"
+ offset="0"
+ style="stop-color:white;stop-opacity:1;" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0.5"
+ id="stop9740" />
+ <stop
+ id="stop9736"
+ offset="1"
+ style="stop-color:white;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ xlink:href="#linearGradient3317"
+ id="linearGradient3299"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.464058,0,0,1.464058,34.761082,27.326693)"
+ x1="49.087219"
+ y1="28.30368"
+ x2="-3.3878942"
+ y2="29.14728" />
+ <linearGradient
+ id="linearGradient3317">
+ <stop
+ style="stop-color:#646464;stop-opacity:1;"
+ offset="0"
+ id="stop3319" />
+ <stop
+ id="stop3321"
+ offset="0.086"
+ style="stop-color:#7e7e7e;stop-opacity:1;" />
+ <stop
+ id="stop3323"
+ offset="0.86000001"
+ style="stop-color:#999;stop-opacity:0.58762884;" />
+ <stop
+ style="stop-color:white;stop-opacity:0;"
+ offset="1"
+ id="stop3325" />
+ </linearGradient>
+ </defs>
+ <path
+ d="M 118.983,31 C 118.992,29.35 117.64999,28 115.99999,28 L 40.961007,28 C 40.961007,28 32.061006,20 30.961,20 L 14.999998,20 C 12.799996,20 10.999999,21.8 10.999999,24 L 10.999999,31 C 10.999999,31 11.999999,116 8,116 L 122,116 C 117.99999,116 118.983,31 118.983,31 z "
+ id="path15"
+ style="fill:url(#linearGradient2212)" />
+ <g
+ id="g17"
+ style="opacity:0.6;filter:url(#filter2807)"
+ transform="matrix(1.0033404,0,0,1,-8.2374684,20)">
+ <path
+ d="M 132,96 C 132,98.2 128.4,100 124,100 L 20,100 C 15.6,100 12,98.2 12,96 C 12,93.8 15.6,92 20,92 L 124,92 C 128.4,92 132,93.8 132,96 z "
+ id="path19" />
+ </g>
+ <path
+ d="M 10.884862,54 C 10.893892,55.75 10.902922,57.755 10.910952,60 L 119.09511,60 C 119.10414,57.755 119.11317,55.75 119.1212,54 L 10.884862,54 z "
+ id="path50"
+ style="opacity:0.5;fill:url(#linearGradient2204)" />
+ <path
+ d="M 119.99722,31 C 120.00622,29.35 118.66422,28 117.01422,28 L 42.975222,28 L 36.389222,21.414 C 35.611222,20.636 34.075222,20 32.975222,20 L 12.014222,20 C 9.8142222,20 8.0142222,21.8 8.0142222,24 C 8.0142222,24 7.9822222,54.499299 8.0142222,60.031299 L 12.014222,60.031299 C 12.014222,53.222299 12.014222,24 12.014222,24 L 32.901222,23.997 C 33.083222,24.019 33.470222,24.179 33.560222,24.243 L 41.318222,32 C 41.318222,32 114.02722,32 115.99922,32 C 115.99922,32.435 116.00022,56.400299 116.00222,60.031299 L 120.01422,60.031299 C 120.04522,54.499299 119.99722,31 119.99722,31 z "
+ id="path2896"
+ style="fill:#5e95e3;fill-opacity:1" />
+ <path
+ d="M 124.36598,113.79242 C 124.27969,115.00674 122.85389,116 121.19831,116 L 6.812906,116 C 5.157329,116 3.731522,115.00674 3.644228,113.79242 L 0.007982,62.204632 C -0.112423,60.992526 1.143808,60 2.799384,60 L 125.21183,60 C 126.86741,60 128.11762,60.991789 127.9912,62.203895 L 124.36598,113.79242 z "
+ id="path30"
+ style="opacity:0.9;fill:url(#linearGradient2207);fill-opacity:1" />
+ <path
+ d="M 125.21293,60 L 2.7999261,60 C 1.1449261,60 -0.11207393,60.992526 0.0079260701,62.204632 L 3.6439261,113.79242 C 3.7309261,115.00674 5.1569261,116 6.8129261,116 L 121.19793,116 C 122.85393,116 124.27993,115.00674 124.36593,113.79242 L 127.99093,62.203895 C 128.11893,60.991789 126.86793,60 125.21293,60 z M 120.41393,113.05263 C 118.87493,113.05263 9.1349261,113.05263 7.5979261,113.05263 C 7.2299261,107.83726 4.5229261,70.627562 4.0659261,64.149246 C 6.5189261,64.149246 121.45793,64.149246 123.93493,64.149246 C 123.81393,65.85872 120.49293,111.92821 120.41393,113.05263 z "
+ id="path2894"
+ style="fill:url(#linearGradient3387)" />
+ <path
+ d="M 4,64 C 4.0273488,64.775875 4.1802721,68.801119 4.2225137,70 C 7.123925,70 122.78934,70 125.71499,70 C 125.74343,69.191222 125.93026,64.204735 125.9375,64 C 123.41788,64 6.4952049,64 4,64 z "
+ id="path2908"
+ style="fill:url(#linearGradient3385);fill-opacity:1;opacity:0.835" />
+ <path
+ style="fill:url(#linearGradient3302);fill-opacity:1"
+ d="m 69.898474,103.45771 5.856232,5.85623 30.761814,-32.21825 -30.761814,-32.2003 -5.856232,5.85623 11.712465,17.5687 H 40.617313 v 17.56869 h 40.993626 z"
+ id="polygon3477_2_" />
+ <path
+ style="fill:url(#linearGradient3299);fill-opacity:1;stroke:none"
+ d="m 75.800458,39.03916 c -1.573495,-0.0241 -3.090514,0.58597 -4.209166,1.69281 l -5.856231,5.85624 C 63.749307,48.56552 63.442452,51.67243 65.003031,54 l 5.627473,8.46409 H 40.617313 v 29.281159 h 30.013191 l -5.627473,8.464081 c -1.56058,2.32757 -1.253725,5.43448 0.73203,7.4118 l 5.856231,5.85623 c 1.121886,1.12264 2.668011,1.76444 4.254918,1.73857 1.586907,-0.0259 3.078725,-0.71721 4.163416,-1.87583 L 110.75484,81.13083 c 2.16677,-2.26455 2.16677,-5.83354 0,-8.09808 L 80.009626,40.86923 c -1.095643,-1.15728 -2.615555,-1.81812 -4.209168,-1.83007 z m -0.04583,5.85623 30.745222,32.20928 -30.745222,32.20927 -5.856231,-5.85623 11.712464,-17.5687 H 40.617236 V 68.32032 h 40.993625 l -11.712459,-17.5687 5.856231,-5.85623 z"
+ id="path3616" />
+</svg>
diff --git a/launcher/resources/multimc/scalable/instances/bee.svg b/launcher/resources/multimc/scalable/instances/bee.svg
index 49f216c8..110b224c 100644
--- a/launcher/resources/multimc/scalable/instances/bee.svg
+++ b/launcher/resources/multimc/scalable/instances/bee.svg
@@ -1,159 +1,136 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
+ width="24"
+ height="24"
version="1.1"
- viewBox="0 0 25.399999 25.4"
- height="96"
- width="96">
- <g transform="translate(-33.928467,-255.46043)">
- <g transform="rotate(-9.9635201,-96.932986,622.95265)">
- <path style="fill:#f1f2e0;fill-opacity:1;fill-rule:evenodd;stroke:#999999;stroke-width:0.28753757px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="m 101.98199,286.42583 -1.1502,0.57512 1.14992,0.5755 2.30058,1.14996 1.15019,-0.57514 -2.30058,-1.14995 z m 2.3003,2.30058 -1.1502,0.57512 1.15002,0.57493 1.15019,-0.57513 z m -1.8e-4,1.15005 -1.1502,0.57512 1.15057,0.57502 1.15019,-0.57512 z m 3.7e-4,1.15014 -1.15019,0.57514 -1.1502,0.57512 1.15001,0.57493 1.1502,-0.57513 1.15019,-0.57512 z m -2.30039,1.15026 -1.15001,-0.57494 -1.150566,-0.57502 -1.150193,0.57512 1.150565,0.57502 1.150014,0.57494 z m -2.300576,-1.14996 1.150196,-0.57513 -1.150014,-0.57493 -1.150097,0.57456 z m -1.149915,-0.5755 1.150193,-0.57512 -1.150012,-0.57492 -1.150194,0.57512 z m 1.81e-4,-1.15004 1.150194,-0.57513 -1.150567,-0.57503 -1.150193,0.57512 z m -3.73e-4,-1.15016 1.150194,-0.57512 1.150189,-0.57513 -1.150008,-0.57492 -1.150193,0.57512 -1.150194,0.57512 z m 1.150567,0.57503 1.149916,0.57548 1.15001,0.57494 1.15019,-0.57512 -1.15001,-0.57494 -1.15047,-0.57558 z" />
- </g>
- <g style="fill:none;stroke:#999999" transform="matrix(1.0012918,0.26829532,-0.26829532,1.0012918,86.112205,-31.978257)">
- <path style="stroke:#999999;stroke-width:1.03661346px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 85.501953 51.128906 C 82.473901 51.748417 79.445938 52.368362 76.417969 52.988281 L 79.886719 56.064453 C 82.914656 55.444381 85.942682 54.824742 88.970703 54.205078 L 85.501953 51.128906 z "
- transform="matrix(0.24654113,-0.06606049,0.06606049,0.24654113,23.141685,280.86706)" />
- <path style="stroke:#999999;stroke-width:1.03661346px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 79.636719 40.972656 L 75.095703 41.902344 C 78.563735 44.978675 82.032556 48.054115 85.501953 51.128906 L 90.042969 50.201172 L 79.636719 40.972656 z "
- transform="matrix(0.24654113,-0.06606049,0.06606049,0.24654113,23.141685,280.86706)" />
- </g>
- <path style="fill:#fed668" d="m 41.865965,262.07502 -4.233333,2.11667 7.408333,3.70417 4.233334,-2.11667 z" />
- <path style="fill:#0a0707" d="m 50.332633,272.39378 v 1.32291 l 1.058333,0.52917 v -1.32292 z" />
- <path style="fill:#422117" d="m 50.332633,273.7167 v 1.32291 l 1.058333,0.52917 v -1.32292 z" />
- <path style="fill:#0a0707" d="m 48.215966,273.45211 v 1.32291 l 1.058333,0.52917 v -1.32292 z" />
- <path style="fill:#422117" d="m 48.215966,274.77503 v 1.32291 l 1.058333,0.52917 v -1.32292 z" />
- <path style="fill:#422117" d="m 45.040966,275.3042 v 1.32291 l 1.058333,0.52917 v -1.32292 z" />
- <path style="fill:#78621d" d="m 45.040965,277.15626 4.233334,-2.11665 v -9.26042 l -4.233334,2.11667 z" />
- <path style="fill:#1d0c08" d="m 50.332632,265.25002 -1.058333,0.52917 v 9.26042 l 1.058333,-0.52917 z" />
- <path style="fill:#1d0c08" d="m 52.449299,264.19169 -1.058333,0.52917 v 9.26042 l 1.058333,-0.52917 z" />
- <path style="fill:#edc343" d="m 38.690965,263.66252 1.058334,0.52917 1.058333,-0.52917 1.058333,0.52917 2.116667,-1.05834 -2.116667,-1.05833 z" />
- <path style="fill:#fed668" d="m 42.924299,261.54586 7.408334,3.70417 1.058333,-0.52917 -7.408334,-3.70417 z" />
- <path style="fill:#e4ae3b" d="m 40.807633,262.60419 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
- <path style="fill:#fed668" d="m 45.040966,260.48752 7.408333,3.70417 1.058333,-0.52917 -7.408333,-3.70417 z" />
- <path style="fill:#5f3225" d="m 42.924299,261.54585 -1.058334,0.52917 7.408333,3.70417 1.058334,-0.52917 z" />
- <path style="fill:#e4ae3b" d="m 42.9243,261.54585 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
- <path style="fill:#5f3225" d="m 45.040965,260.48752 -1.058333,0.52917 7.408333,3.70416 1.058333,-0.52916 z" />
- <path style="fill:#e4ae3b" d="m 45.040966,260.48752 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
- <path style="fill:#5f3225" d="m 46.099299,259.95835 7.408333,3.70417 2.116666,-1.05833 -7.408333,-3.70417 z" />
- <path style="fill:#552e22" d="m 47.157633,259.42919 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
- <path style="fill:#edc343" d="m 43.982633,262.07502 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
- <path style="fill:#edc343" d="m 46.099299,261.01669 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
- <path style="fill:#edc343" d="m 40.807633,264.72086 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
- <path style="fill:#e4ae3b" d="m 45.040967,262.60419 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
- <path style="fill:#552e22" d="m 49.2743,260.48753 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
- <path style="fill:#edc343" d="m 48.215966,262.07502 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
- <path style="fill:#edc343" d="m 41.865966,266.30836 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
- <path style="fill:#552e22" d="m 50.332633,262.07502 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
- <path style="fill:#edc343" d="m 46.099299,265.25002 -1.058334,0.52917 1.058334,0.52916 -2.116667,1.05834 1.058333,0.52916 3.175,-1.5875 z" />
- <path style="fill:#edc343" d="m 48.215967,264.19169 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
- <path style="fill:#edc343" d="m 50.332633,263.13336 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
- <path style="fill:#e4ae3b" d="m 47.157633,265.77919 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
- <path style="fill:#e4ae3b" d="m 49.2743,264.72085 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
- <path style="fill:#e4ae3b" d="m 51.390966,263.66252 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
- <path style="fill:#edc343" d="m 38.690966,264.72086 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
- <path style="fill:#ac8d2e" d="m 37.632633,273.45211 7.408333,3.70415 v -9.2604 l -7.408333,-3.70417 z" />
- <path style="fill:#12121a" d="m 37.632633,268.16044 2.116666,1.05834 v 3.96875 l -2.116666,-1.05834 z" />
- <path style="fill:#78621d" d="m 50.332633,265.25002 v 9.26041 l 1.058333,-0.52916 v -9.26042 z" />
- <path style="fill:#78621d" d="m 52.449299,264.19169 v 9.26041 l 1.058333,-0.52916 v -9.26042 z" />
- <path style="fill:#27120b" d="m 49.274299,265.77919 v 2.64583 l 1.058333,-0.52916 v -2.64584 z" />
- <path style="fill:#09090e" d="m 45.040966,271.86461 1.058333,-0.52917 v 3.96875 l -1.058333,0.52917 -2.116667,-1.05834 v -3.96875 z" />
- <path style="fill:#150704" d="m 49.2743,271.07085 v 2.64583 l 1.058333,-0.52916 v -2.64584 z" />
- <path style="fill:#050303" d="m 49.2743,273.71669 v 1.32291 l 1.058333,-0.52916 v -1.32292 z" />
- <path style="fill:#150704" d="m 51.390966,268.68961 v 2.64583 l 1.058333,-0.52916 v -2.64584 z" />
- <path style="fill:#050303" d="m 51.390966,271.33544 v 2.64583 l 1.058333,-0.52916 v -2.64584 z" />
- <path style="fill:#2c140d" d="m 51.390966,264.72086 v 1.32291 l 1.058333,-0.52916 v -1.32292 z" />
- <path style="fill:#1d0c08" d="m 55.624299,262.60419 -2.116666,1.05833 v 9.26042 l 2.116666,-1.05833 z" />
- <path style="fill:#150704" d="m 53.507633,268.95419 v 1.32291 l 1.058333,-0.52916 v -1.32292 z" />
- <path style="fill:#050303" d="m 53.507633,270.2771 v 2.64583 l 1.058333,-0.52916 v -2.64584 z" />
- <path style="fill:#2c140d" d="m 53.507633,263.66252 v 1.32291 l 1.058333,-0.52916 v -1.32292 z" />
- <path style="fill:#27120b" d="m 54.565966,263.13335 v 2.64583 l 1.058333,-0.52916 v -2.64584 z" />
- <path style="fill:#150704" d="m 54.565966,269.74794 v 2.64583 l 1.058333,-0.52916 v -2.64584 z" />
- <path style="fill:#27120b" d="m 54.565966,267.10211 v 1.32291 l 1.058333,-0.52916 v -1.32292 z" />
- <path style="fill:#633f19" d="m 45.040965,277.15626 3.175,-1.58749 v -1.32291 l -3.175,1.5875 z" />
- <path style="fill:#55300a" d="m 48.215966,274.24586 v 1.32291 l 1.058333,-0.52916 v -1.32292 z" />
- <path style="fill:#694520" d="m 48.215966,272.92294 v 1.32291 l 1.058333,-0.52916 v -1.32292 z" />
- <path style="fill:#735619" d="m 48.215966,271.60002 v 1.32291 l 1.058333,-0.52916 v -1.32292 z" />
- <path style="fill:#735619" d="m 47.157633,273.45211 v 1.32291 l 1.058333,-0.52916 v -1.32292 z" />
- <path style="fill:#131016" d="m 45.040966,271.86461 v 1.32291 l 1.058333,-0.52916 v -1.32292 z" />
- <path style="fill:#131016" d="m 45.040966,274.51044 v 1.32291 l 1.058333,-0.52916 v -1.32292 z" />
- <path style="fill:#694520" d="m 45.040966,270.54169 v 1.32291 l 1.058333,-0.52916 v -1.32292 z" />
- <path style="fill:#735619" d="m 46.0993,270.01252 v 1.32291 l 1.058333,-0.52916 v -1.32292 z" />
- <path style="fill:#816c31" d="m 45.040966,267.89586 v 1.32291 l 1.058333,-0.52916 v 1.32291 l 1.058334,-0.52916 v -1.32292 l 2.116666,-1.05833 v -1.32292 z" />
- <path style="fill:#49250c" d="m 50.332633,273.18752 v 1.32291 l 1.058333,-0.52916 v -1.32292 z" />
- <path style="fill:#633f19" d="m 50.332633,271.86461 v 1.32291 l 1.058333,-0.52916 v -1.32292 z" />
- <path style="fill:#735619" d="m 50.332633,269.21878 v 2.64582 l 1.058333,-0.52916 v -2.64583 z" />
- <path style="fill:#816c31" d="m 50.332633,265.25002 v 1.32291 l 1.058333,-0.52916 v -1.32292 z" />
- <path style="fill:#49250c" d="m 52.449299,270.80627 10e-7,2.64583 1.058333,-0.52916 -10e-7,-2.64584 z" />
- <path style="fill:#55300a" d="m 52.4493,269.48336 v 1.32291 l 1.058333,-0.52916 v -1.32292 z" />
- <path style="fill:#694520" d="m 52.4493,268.16044 v 1.32291 l 1.058333,-0.52916 v -1.32292 z" />
- <path style="fill:#755719" d="m 52.4493,266.83752 v 1.32291 l 1.058333,-0.52916 v -1.32292 z" />
- <path style="fill:#816c31" d="m 52.4493,264.19169 v 1.32291 l 1.058333,-0.52916 v -1.32292 z" />
- <path style="fill:#b89b49" d="m 37.632632,265.51461 2.116667,1.05833 v -1.32292 l -2.116667,-1.05833 z" />
- <path style="fill:#b89b49" d="m 40.807633,267.10211 2.116667,1.05833 v -1.32292 l -2.116667,-1.05833 z" />
- <path style="fill:#b89b49" d="m 43.982633,270.01253 1.058333,0.52916 v -2.64584 l -1.058333,-0.52916 z" />
- <path style="fill:#966531" d="m 43.982632,271.33545 1.058334,0.52916 v -1.32292 l -1.058334,-0.52916 z" />
- <path style="fill:#a57d28" d="m 42.924299,270.80627 1.058334,0.52916 v -1.32292 l -1.058334,-0.52916 z" />
- <path style="fill:#b89b49" d="m 41.865965,270.27712 1.058334,0.52916 v -1.32292 l -1.058334,-0.52916 z" />
- <path style="fill:#966531" d="m 43.982632,271.33545 1.058334,0.52916 v -1.32292 l -1.058334,-0.52916 z" />
- <path style="fill:#a57d28" d="m 39.749299,273.18753 1.058334,0.52916 v -1.32292 l -1.058334,-0.52916 z" />
- <path style="fill:#a57d28" d="m 41.865965,274.24587 1.058334,0.52916 v -1.32292 l -1.058334,-0.52916 z" />
- <path style="fill:#a57d28" d="m 40.807633,275.03961 1.058334,0.52916 v -1.32292 l -1.058334,-0.52916 z" />
- <path style="fill:#8e5c28" d="m 43.982633,276.62711 1.058334,0.52916 v -1.32292 l -1.058334,-0.52916 z" />
- <path style="fill:#966531" d="m 41.865966,275.56877 2.116667,1.05833 v -1.32292 l -2.116667,-1.05833 z" />
- <path style="fill:#966531" d="m 38.690966,273.98128 2.116667,1.05833 v -1.32292 l -2.116667,-1.05833 z" />
- <path style="fill:#8e5c28" d="m 37.632632,273.45212 1.058334,0.52916 v -1.32292 l -1.058334,-0.52916 z" />
- <path style="fill:#956531" d="m 37.632633,268.16044 1.058334,0.52916 v -1.32292 l -1.058334,-0.52916 z" />
- <path style="fill:#b89b49" d="m 39.749299,267.89587 1.058334,0.52916 v -1.32292 l -1.058334,-0.52916 z" />
- <path style="fill:#1f1c25" d="m 38.690966,267.36669 1.058334,0.52916 v -1.32292 l -1.058334,-0.52916 z" />
- <path style="fill:#1f1c25" d="m 42.924299,269.48337 1.058334,0.52916 v -1.32292 l -1.058334,-0.52916 z" />
- <path style="fill:#589197" d="m 42.924299,272.12919 1.058334,0.52916 v -1.32292 l -1.058334,-0.52916 z" />
- <path style="fill:#589197" d="m 38.690966,270.01252 1.058334,0.52916 v -1.32292 l -1.058334,-0.52916 z" />
- <path style="fill:#12121a" d="m 43.982633,272.65836 1.058334,0.52916 v -1.32292 l -1.058334,-0.52916 z" />
- <path style="fill:#12121a" d="m 42.924299,273.45211 1.058334,0.52916 v -1.32292 l -1.058334,-0.52916 z" />
- <path style="fill:#12121a" d="m 43.982633,275.30419 1.058334,0.52916 v -1.32292 l -1.058334,-0.52916 z" />
- <path style="fill:#1f1c25" d="m 43.982633,273.98127 1.058334,0.52916 v -1.32292 l -1.058334,-0.52916 z" />
- <path style="fill:#1f1c25" d="m 42.924299,274.77503 1.058334,0.52916 v -1.32292 l -1.058334,-0.52916 z" />
- <path style="fill:#1f1c25" d="m 38.690966,272.65836 1.058334,0.52916 v -1.32292 l -1.058334,-0.52916 z" />
- <path style="fill:#1f1c25" d="m 37.632633,270.80627 1.058334,0.52916 v -1.32292 l -1.058334,-0.52916 z" />
- <path style="fill:#131016" d="m 38.690966,267.10211 v 1.32291 l 1.058333,-0.52916 v -1.32292 z" />
- <path style="fill:#131016" d="m 36.574299,266.83752 v 1.32291 l 2.116667,-1.05832 v -1.32292 z" />
- <path style="fill:#131016" d="m 41.865966,268.68961 v 1.32291 l 1.058333,-0.52916 v -1.32292 z" />
- <path style="fill:#131016" d="m 39.749299,268.42502 v 1.32291 l 2.116667,-1.05832 v -1.32292 z" />
- <g transform="matrix(1.0012918,0.26829532,-0.26829532,1.0012918,86.112205,-31.978257)">
- <path style="fill:#f1f2e0" d="m 38.073986,286.23688 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
- <path style="fill:#5f3225" d="m 37.015652,286.76606 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
- <path style="fill:#5f3225" d="m 37.015652,287.82438 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
- <path style="fill:#f7fdfd" d="m 38.073986,288.35355 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
- <path style="fill:#f1f2e0" d="m 40.190652,286.23689 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
- <path style="fill:#f7fdfd" d="m 42.307319,286.23688 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
- <path style="fill:#f1f2e0" d="m 42.307319,287.29521 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
- <path style="fill:#f7fdfd" d="m 43.365653,287.82437 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
- <path style="fill:#f1f2e0" d="m 43.365653,288.88271 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
- <path style="fill:#f1f2e0" d="m 41.248986,288.88271 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
- <path style="fill:#f7fdfd" d="m 40.190653,288.35354 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
- <path style="fill:#f7fdfd" d="m 45.482319,288.88271 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
- <path style="fill:#f1f2e0" d="m 46.540653,288.35355 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
- <path style="fill:#f1f2e0" d="m 46.540653,287.29521 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
- <path style="fill:#f7fdfd" d="m 44.423986,286.23688 2.116667,1.05833 1.058333,-0.52917 -2.116667,-1.05833 z" />
- </g>
- <g transform="matrix(1.0703659,-0.18803179,0.18803179,1.0703659,-63.348962,-38.123102)">
- <path style="fill:#f1f2e0" d="m 48.392735,288.88271 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
- <path style="fill:#5f3225" d="m 47.334402,289.41187 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
- <path style="fill:#5f3225" d="m 45.217735,289.41188 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
- <path style="fill:#f7fdfd" d="m 44.159402,288.8827 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
- <path style="fill:#f1f2e0" d="m 43.101069,286.23687 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
- <path style="fill:#f7fdfd" d="m 43.101068,285.17854 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
- <path style="fill:#f1f2e0" d="m 46.276068,284.64938 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
- <path style="fill:#f7fdfd" d="m 45.217735,286.23688 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
- <path style="fill:#f1f2e0" d="m 44.159402,284.64937 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
- <path style="fill:#f1f2e0" d="m 43.101068,287.2952 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
- <path style="fill:#f7fdfd" d="m 44.159402,287.82438 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
- <path style="fill:#f7fdfd" d="m 48.392735,286.76604 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
- <path style="fill:#f1f2e0" d="m 48.392735,287.82438 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
- <path style="fill:#f1f2e0" d="m 46.276068,286.76604 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
- <path style="fill:#f7fdfd" d="m 47.334402,285.17854 2.116667,1.05833 1.058333,-0.52917 -2.116667,-1.05833 z" />
- </g>
- </g>
-</svg>
+ viewBox="0 0 24 24"
+ id="svg168"
+ xml:space="preserve"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"><defs
+ id="defs172"><linearGradient
+ xlink:href="#linearGradient1308"
+ id="linearGradient1310"
+ x1="16"
+ y1="27"
+ x2="16"
+ y2="5"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ id="linearGradient1308"><stop
+ style="stop-color:#f3db6c;stop-opacity:1;"
+ offset="0"
+ id="stop1304" /><stop
+ style="stop-color:#ffeea9;stop-opacity:1;"
+ offset="1"
+ id="stop1306" /></linearGradient><linearGradient
+ xlink:href="#linearGradient1440"
+ id="linearGradient1442"
+ x1="7"
+ y1="24"
+ x2="11"
+ y2="14"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ id="linearGradient1440"><stop
+ style="stop-color:#2c251f;stop-opacity:1;"
+ offset="0"
+ id="stop1436" /><stop
+ style="stop-color:#4d3f33;stop-opacity:1;"
+ offset="1"
+ id="stop1438" /></linearGradient><linearGradient
+ xlink:href="#linearGradient1460"
+ id="linearGradient1462"
+ x1="10"
+ y1="18"
+ x2="12"
+ y2="14"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1)" /><linearGradient
+ id="linearGradient1460"><stop
+ style="stop-color:#4c7aba;stop-opacity:1;"
+ offset="0"
+ id="stop1456" /><stop
+ style="stop-color:#86c3cf;stop-opacity:1;"
+ offset="1"
+ id="stop1458" /></linearGradient></defs><title
+ id="title132">Prism Launcher Logo</title><metadata
+ id="metadata166"><rdf:RDF><cc:Work
+ rdf:about=""><dc:title>Prism Launcher Logo</dc:title><dc:date>19/10/2022</dc:date><dc:creator><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:creator><dc:contributor><cc:Agent><dc:title>AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke</dc:title></cc:Agent></dc:contributor><dc:source>https://github.com/PrismLauncher/PrismLauncher</dc:source><dc:rights><cc:Agent><dc:title>CC BY-SA 4.0</dc:title></cc:Agent></dc:rights><dc:publisher><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:publisher></cc:Work></rdf:RDF></metadata><g
+ id="i_bee"
+ transform="translate(-4,-4)"><rect
+ style="fill:url(#linearGradient1310);fill-opacity:1;stroke-width:0.277182;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect543"
+ width="18"
+ height="18"
+ x="7"
+ y="7"
+ ry="3" /><g
+ id="g7050"
+ clip-path="none"
+ transform="translate(2,-1)"><rect
+ style="fill:url(#linearGradient1442);fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect3612"
+ width="5"
+ height="9"
+ x="6"
+ y="14"
+ ry="1" /><path
+ id="rect4739"
+ style="fill:url(#linearGradient1462);fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 8,14 v 4 h 3 v -3 c 0,-0.553999 -0.446001,-1 -1,-1 z" /></g><use
+ x="0"
+ y="0"
+ xlink:href="#g7050"
+ id="use7056"
+ transform="matrix(-1,0,0,1,32,0)" /><g
+ id="g10049"
+ transform="translate(0,-1)"
+ style="fill:#2c251f;fill-opacity:1"><rect
+ style="fill:#2c251f;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect9308"
+ width="3"
+ height="3"
+ x="9"
+ y="10"
+ ry="1" /><rect
+ style="fill:#2c251f;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect9310"
+ width="5"
+ height="3"
+ x="4"
+ y="7"
+ ry="1" /><path
+ id="path9312"
+ style="fill:#2c251f;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 8,9 v 1 c 0.5539988,0 1,0.446001 1,1 h 1 V 10 C 9.4460006,10 9,9.5539994 9,9 Z" /></g><g
+ id="g10057"
+ transform="matrix(-1,0,0,1,31,-1)"
+ style="fill:#2c251f;fill-opacity:1"><rect
+ style="fill:#2c251f;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect10051"
+ width="3"
+ height="3"
+ x="8"
+ y="10"
+ ry="1" /><rect
+ style="fill:#2c251f;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect10053"
+ width="5"
+ height="3"
+ x="3"
+ y="7"
+ ry="1" /><path
+ id="path10055"
+ style="fill:#2c251f;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 7,9 v 1 c 0.5539988,0 1,0.446001 1,1 H 9 V 10 C 8.4460006,10 8,9.5539994 8,9 Z" /></g><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412"
+ width="24"
+ height="24"
+ x="4"
+ y="4" /></g></svg>
diff --git a/launcher/resources/multimc/scalable/instances/bee_legacy.svg b/launcher/resources/multimc/scalable/instances/bee_legacy.svg
new file mode 100644
index 00000000..49f216c8
--- /dev/null
+++ b/launcher/resources/multimc/scalable/instances/bee_legacy.svg
@@ -0,0 +1,159 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.1"
+ viewBox="0 0 25.399999 25.4"
+ height="96"
+ width="96">
+ <g transform="translate(-33.928467,-255.46043)">
+ <g transform="rotate(-9.9635201,-96.932986,622.95265)">
+ <path style="fill:#f1f2e0;fill-opacity:1;fill-rule:evenodd;stroke:#999999;stroke-width:0.28753757px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="m 101.98199,286.42583 -1.1502,0.57512 1.14992,0.5755 2.30058,1.14996 1.15019,-0.57514 -2.30058,-1.14995 z m 2.3003,2.30058 -1.1502,0.57512 1.15002,0.57493 1.15019,-0.57513 z m -1.8e-4,1.15005 -1.1502,0.57512 1.15057,0.57502 1.15019,-0.57512 z m 3.7e-4,1.15014 -1.15019,0.57514 -1.1502,0.57512 1.15001,0.57493 1.1502,-0.57513 1.15019,-0.57512 z m -2.30039,1.15026 -1.15001,-0.57494 -1.150566,-0.57502 -1.150193,0.57512 1.150565,0.57502 1.150014,0.57494 z m -2.300576,-1.14996 1.150196,-0.57513 -1.150014,-0.57493 -1.150097,0.57456 z m -1.149915,-0.5755 1.150193,-0.57512 -1.150012,-0.57492 -1.150194,0.57512 z m 1.81e-4,-1.15004 1.150194,-0.57513 -1.150567,-0.57503 -1.150193,0.57512 z m -3.73e-4,-1.15016 1.150194,-0.57512 1.150189,-0.57513 -1.150008,-0.57492 -1.150193,0.57512 -1.150194,0.57512 z m 1.150567,0.57503 1.149916,0.57548 1.15001,0.57494 1.15019,-0.57512 -1.15001,-0.57494 -1.15047,-0.57558 z" />
+ </g>
+ <g style="fill:none;stroke:#999999" transform="matrix(1.0012918,0.26829532,-0.26829532,1.0012918,86.112205,-31.978257)">
+ <path style="stroke:#999999;stroke-width:1.03661346px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 85.501953 51.128906 C 82.473901 51.748417 79.445938 52.368362 76.417969 52.988281 L 79.886719 56.064453 C 82.914656 55.444381 85.942682 54.824742 88.970703 54.205078 L 85.501953 51.128906 z "
+ transform="matrix(0.24654113,-0.06606049,0.06606049,0.24654113,23.141685,280.86706)" />
+ <path style="stroke:#999999;stroke-width:1.03661346px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 79.636719 40.972656 L 75.095703 41.902344 C 78.563735 44.978675 82.032556 48.054115 85.501953 51.128906 L 90.042969 50.201172 L 79.636719 40.972656 z "
+ transform="matrix(0.24654113,-0.06606049,0.06606049,0.24654113,23.141685,280.86706)" />
+ </g>
+ <path style="fill:#fed668" d="m 41.865965,262.07502 -4.233333,2.11667 7.408333,3.70417 4.233334,-2.11667 z" />
+ <path style="fill:#0a0707" d="m 50.332633,272.39378 v 1.32291 l 1.058333,0.52917 v -1.32292 z" />
+ <path style="fill:#422117" d="m 50.332633,273.7167 v 1.32291 l 1.058333,0.52917 v -1.32292 z" />
+ <path style="fill:#0a0707" d="m 48.215966,273.45211 v 1.32291 l 1.058333,0.52917 v -1.32292 z" />
+ <path style="fill:#422117" d="m 48.215966,274.77503 v 1.32291 l 1.058333,0.52917 v -1.32292 z" />
+ <path style="fill:#422117" d="m 45.040966,275.3042 v 1.32291 l 1.058333,0.52917 v -1.32292 z" />
+ <path style="fill:#78621d" d="m 45.040965,277.15626 4.233334,-2.11665 v -9.26042 l -4.233334,2.11667 z" />
+ <path style="fill:#1d0c08" d="m 50.332632,265.25002 -1.058333,0.52917 v 9.26042 l 1.058333,-0.52917 z" />
+ <path style="fill:#1d0c08" d="m 52.449299,264.19169 -1.058333,0.52917 v 9.26042 l 1.058333,-0.52917 z" />
+ <path style="fill:#edc343" d="m 38.690965,263.66252 1.058334,0.52917 1.058333,-0.52917 1.058333,0.52917 2.116667,-1.05834 -2.116667,-1.05833 z" />
+ <path style="fill:#fed668" d="m 42.924299,261.54586 7.408334,3.70417 1.058333,-0.52917 -7.408334,-3.70417 z" />
+ <path style="fill:#e4ae3b" d="m 40.807633,262.60419 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
+ <path style="fill:#fed668" d="m 45.040966,260.48752 7.408333,3.70417 1.058333,-0.52917 -7.408333,-3.70417 z" />
+ <path style="fill:#5f3225" d="m 42.924299,261.54585 -1.058334,0.52917 7.408333,3.70417 1.058334,-0.52917 z" />
+ <path style="fill:#e4ae3b" d="m 42.9243,261.54585 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
+ <path style="fill:#5f3225" d="m 45.040965,260.48752 -1.058333,0.52917 7.408333,3.70416 1.058333,-0.52916 z" />
+ <path style="fill:#e4ae3b" d="m 45.040966,260.48752 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
+ <path style="fill:#5f3225" d="m 46.099299,259.95835 7.408333,3.70417 2.116666,-1.05833 -7.408333,-3.70417 z" />
+ <path style="fill:#552e22" d="m 47.157633,259.42919 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
+ <path style="fill:#edc343" d="m 43.982633,262.07502 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
+ <path style="fill:#edc343" d="m 46.099299,261.01669 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
+ <path style="fill:#edc343" d="m 40.807633,264.72086 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
+ <path style="fill:#e4ae3b" d="m 45.040967,262.60419 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
+ <path style="fill:#552e22" d="m 49.2743,260.48753 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
+ <path style="fill:#edc343" d="m 48.215966,262.07502 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
+ <path style="fill:#edc343" d="m 41.865966,266.30836 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
+ <path style="fill:#552e22" d="m 50.332633,262.07502 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
+ <path style="fill:#edc343" d="m 46.099299,265.25002 -1.058334,0.52917 1.058334,0.52916 -2.116667,1.05834 1.058333,0.52916 3.175,-1.5875 z" />
+ <path style="fill:#edc343" d="m 48.215967,264.19169 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
+ <path style="fill:#edc343" d="m 50.332633,263.13336 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
+ <path style="fill:#e4ae3b" d="m 47.157633,265.77919 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
+ <path style="fill:#e4ae3b" d="m 49.2743,264.72085 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
+ <path style="fill:#e4ae3b" d="m 51.390966,263.66252 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
+ <path style="fill:#edc343" d="m 38.690966,264.72086 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
+ <path style="fill:#ac8d2e" d="m 37.632633,273.45211 7.408333,3.70415 v -9.2604 l -7.408333,-3.70417 z" />
+ <path style="fill:#12121a" d="m 37.632633,268.16044 2.116666,1.05834 v 3.96875 l -2.116666,-1.05834 z" />
+ <path style="fill:#78621d" d="m 50.332633,265.25002 v 9.26041 l 1.058333,-0.52916 v -9.26042 z" />
+ <path style="fill:#78621d" d="m 52.449299,264.19169 v 9.26041 l 1.058333,-0.52916 v -9.26042 z" />
+ <path style="fill:#27120b" d="m 49.274299,265.77919 v 2.64583 l 1.058333,-0.52916 v -2.64584 z" />
+ <path style="fill:#09090e" d="m 45.040966,271.86461 1.058333,-0.52917 v 3.96875 l -1.058333,0.52917 -2.116667,-1.05834 v -3.96875 z" />
+ <path style="fill:#150704" d="m 49.2743,271.07085 v 2.64583 l 1.058333,-0.52916 v -2.64584 z" />
+ <path style="fill:#050303" d="m 49.2743,273.71669 v 1.32291 l 1.058333,-0.52916 v -1.32292 z" />
+ <path style="fill:#150704" d="m 51.390966,268.68961 v 2.64583 l 1.058333,-0.52916 v -2.64584 z" />
+ <path style="fill:#050303" d="m 51.390966,271.33544 v 2.64583 l 1.058333,-0.52916 v -2.64584 z" />
+ <path style="fill:#2c140d" d="m 51.390966,264.72086 v 1.32291 l 1.058333,-0.52916 v -1.32292 z" />
+ <path style="fill:#1d0c08" d="m 55.624299,262.60419 -2.116666,1.05833 v 9.26042 l 2.116666,-1.05833 z" />
+ <path style="fill:#150704" d="m 53.507633,268.95419 v 1.32291 l 1.058333,-0.52916 v -1.32292 z" />
+ <path style="fill:#050303" d="m 53.507633,270.2771 v 2.64583 l 1.058333,-0.52916 v -2.64584 z" />
+ <path style="fill:#2c140d" d="m 53.507633,263.66252 v 1.32291 l 1.058333,-0.52916 v -1.32292 z" />
+ <path style="fill:#27120b" d="m 54.565966,263.13335 v 2.64583 l 1.058333,-0.52916 v -2.64584 z" />
+ <path style="fill:#150704" d="m 54.565966,269.74794 v 2.64583 l 1.058333,-0.52916 v -2.64584 z" />
+ <path style="fill:#27120b" d="m 54.565966,267.10211 v 1.32291 l 1.058333,-0.52916 v -1.32292 z" />
+ <path style="fill:#633f19" d="m 45.040965,277.15626 3.175,-1.58749 v -1.32291 l -3.175,1.5875 z" />
+ <path style="fill:#55300a" d="m 48.215966,274.24586 v 1.32291 l 1.058333,-0.52916 v -1.32292 z" />
+ <path style="fill:#694520" d="m 48.215966,272.92294 v 1.32291 l 1.058333,-0.52916 v -1.32292 z" />
+ <path style="fill:#735619" d="m 48.215966,271.60002 v 1.32291 l 1.058333,-0.52916 v -1.32292 z" />
+ <path style="fill:#735619" d="m 47.157633,273.45211 v 1.32291 l 1.058333,-0.52916 v -1.32292 z" />
+ <path style="fill:#131016" d="m 45.040966,271.86461 v 1.32291 l 1.058333,-0.52916 v -1.32292 z" />
+ <path style="fill:#131016" d="m 45.040966,274.51044 v 1.32291 l 1.058333,-0.52916 v -1.32292 z" />
+ <path style="fill:#694520" d="m 45.040966,270.54169 v 1.32291 l 1.058333,-0.52916 v -1.32292 z" />
+ <path style="fill:#735619" d="m 46.0993,270.01252 v 1.32291 l 1.058333,-0.52916 v -1.32292 z" />
+ <path style="fill:#816c31" d="m 45.040966,267.89586 v 1.32291 l 1.058333,-0.52916 v 1.32291 l 1.058334,-0.52916 v -1.32292 l 2.116666,-1.05833 v -1.32292 z" />
+ <path style="fill:#49250c" d="m 50.332633,273.18752 v 1.32291 l 1.058333,-0.52916 v -1.32292 z" />
+ <path style="fill:#633f19" d="m 50.332633,271.86461 v 1.32291 l 1.058333,-0.52916 v -1.32292 z" />
+ <path style="fill:#735619" d="m 50.332633,269.21878 v 2.64582 l 1.058333,-0.52916 v -2.64583 z" />
+ <path style="fill:#816c31" d="m 50.332633,265.25002 v 1.32291 l 1.058333,-0.52916 v -1.32292 z" />
+ <path style="fill:#49250c" d="m 52.449299,270.80627 10e-7,2.64583 1.058333,-0.52916 -10e-7,-2.64584 z" />
+ <path style="fill:#55300a" d="m 52.4493,269.48336 v 1.32291 l 1.058333,-0.52916 v -1.32292 z" />
+ <path style="fill:#694520" d="m 52.4493,268.16044 v 1.32291 l 1.058333,-0.52916 v -1.32292 z" />
+ <path style="fill:#755719" d="m 52.4493,266.83752 v 1.32291 l 1.058333,-0.52916 v -1.32292 z" />
+ <path style="fill:#816c31" d="m 52.4493,264.19169 v 1.32291 l 1.058333,-0.52916 v -1.32292 z" />
+ <path style="fill:#b89b49" d="m 37.632632,265.51461 2.116667,1.05833 v -1.32292 l -2.116667,-1.05833 z" />
+ <path style="fill:#b89b49" d="m 40.807633,267.10211 2.116667,1.05833 v -1.32292 l -2.116667,-1.05833 z" />
+ <path style="fill:#b89b49" d="m 43.982633,270.01253 1.058333,0.52916 v -2.64584 l -1.058333,-0.52916 z" />
+ <path style="fill:#966531" d="m 43.982632,271.33545 1.058334,0.52916 v -1.32292 l -1.058334,-0.52916 z" />
+ <path style="fill:#a57d28" d="m 42.924299,270.80627 1.058334,0.52916 v -1.32292 l -1.058334,-0.52916 z" />
+ <path style="fill:#b89b49" d="m 41.865965,270.27712 1.058334,0.52916 v -1.32292 l -1.058334,-0.52916 z" />
+ <path style="fill:#966531" d="m 43.982632,271.33545 1.058334,0.52916 v -1.32292 l -1.058334,-0.52916 z" />
+ <path style="fill:#a57d28" d="m 39.749299,273.18753 1.058334,0.52916 v -1.32292 l -1.058334,-0.52916 z" />
+ <path style="fill:#a57d28" d="m 41.865965,274.24587 1.058334,0.52916 v -1.32292 l -1.058334,-0.52916 z" />
+ <path style="fill:#a57d28" d="m 40.807633,275.03961 1.058334,0.52916 v -1.32292 l -1.058334,-0.52916 z" />
+ <path style="fill:#8e5c28" d="m 43.982633,276.62711 1.058334,0.52916 v -1.32292 l -1.058334,-0.52916 z" />
+ <path style="fill:#966531" d="m 41.865966,275.56877 2.116667,1.05833 v -1.32292 l -2.116667,-1.05833 z" />
+ <path style="fill:#966531" d="m 38.690966,273.98128 2.116667,1.05833 v -1.32292 l -2.116667,-1.05833 z" />
+ <path style="fill:#8e5c28" d="m 37.632632,273.45212 1.058334,0.52916 v -1.32292 l -1.058334,-0.52916 z" />
+ <path style="fill:#956531" d="m 37.632633,268.16044 1.058334,0.52916 v -1.32292 l -1.058334,-0.52916 z" />
+ <path style="fill:#b89b49" d="m 39.749299,267.89587 1.058334,0.52916 v -1.32292 l -1.058334,-0.52916 z" />
+ <path style="fill:#1f1c25" d="m 38.690966,267.36669 1.058334,0.52916 v -1.32292 l -1.058334,-0.52916 z" />
+ <path style="fill:#1f1c25" d="m 42.924299,269.48337 1.058334,0.52916 v -1.32292 l -1.058334,-0.52916 z" />
+ <path style="fill:#589197" d="m 42.924299,272.12919 1.058334,0.52916 v -1.32292 l -1.058334,-0.52916 z" />
+ <path style="fill:#589197" d="m 38.690966,270.01252 1.058334,0.52916 v -1.32292 l -1.058334,-0.52916 z" />
+ <path style="fill:#12121a" d="m 43.982633,272.65836 1.058334,0.52916 v -1.32292 l -1.058334,-0.52916 z" />
+ <path style="fill:#12121a" d="m 42.924299,273.45211 1.058334,0.52916 v -1.32292 l -1.058334,-0.52916 z" />
+ <path style="fill:#12121a" d="m 43.982633,275.30419 1.058334,0.52916 v -1.32292 l -1.058334,-0.52916 z" />
+ <path style="fill:#1f1c25" d="m 43.982633,273.98127 1.058334,0.52916 v -1.32292 l -1.058334,-0.52916 z" />
+ <path style="fill:#1f1c25" d="m 42.924299,274.77503 1.058334,0.52916 v -1.32292 l -1.058334,-0.52916 z" />
+ <path style="fill:#1f1c25" d="m 38.690966,272.65836 1.058334,0.52916 v -1.32292 l -1.058334,-0.52916 z" />
+ <path style="fill:#1f1c25" d="m 37.632633,270.80627 1.058334,0.52916 v -1.32292 l -1.058334,-0.52916 z" />
+ <path style="fill:#131016" d="m 38.690966,267.10211 v 1.32291 l 1.058333,-0.52916 v -1.32292 z" />
+ <path style="fill:#131016" d="m 36.574299,266.83752 v 1.32291 l 2.116667,-1.05832 v -1.32292 z" />
+ <path style="fill:#131016" d="m 41.865966,268.68961 v 1.32291 l 1.058333,-0.52916 v -1.32292 z" />
+ <path style="fill:#131016" d="m 39.749299,268.42502 v 1.32291 l 2.116667,-1.05832 v -1.32292 z" />
+ <g transform="matrix(1.0012918,0.26829532,-0.26829532,1.0012918,86.112205,-31.978257)">
+ <path style="fill:#f1f2e0" d="m 38.073986,286.23688 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
+ <path style="fill:#5f3225" d="m 37.015652,286.76606 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
+ <path style="fill:#5f3225" d="m 37.015652,287.82438 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
+ <path style="fill:#f7fdfd" d="m 38.073986,288.35355 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
+ <path style="fill:#f1f2e0" d="m 40.190652,286.23689 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
+ <path style="fill:#f7fdfd" d="m 42.307319,286.23688 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
+ <path style="fill:#f1f2e0" d="m 42.307319,287.29521 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
+ <path style="fill:#f7fdfd" d="m 43.365653,287.82437 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
+ <path style="fill:#f1f2e0" d="m 43.365653,288.88271 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
+ <path style="fill:#f1f2e0" d="m 41.248986,288.88271 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
+ <path style="fill:#f7fdfd" d="m 40.190653,288.35354 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
+ <path style="fill:#f7fdfd" d="m 45.482319,288.88271 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
+ <path style="fill:#f1f2e0" d="m 46.540653,288.35355 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
+ <path style="fill:#f1f2e0" d="m 46.540653,287.29521 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
+ <path style="fill:#f7fdfd" d="m 44.423986,286.23688 2.116667,1.05833 1.058333,-0.52917 -2.116667,-1.05833 z" />
+ </g>
+ <g transform="matrix(1.0703659,-0.18803179,0.18803179,1.0703659,-63.348962,-38.123102)">
+ <path style="fill:#f1f2e0" d="m 48.392735,288.88271 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
+ <path style="fill:#5f3225" d="m 47.334402,289.41187 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
+ <path style="fill:#5f3225" d="m 45.217735,289.41188 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
+ <path style="fill:#f7fdfd" d="m 44.159402,288.8827 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
+ <path style="fill:#f1f2e0" d="m 43.101069,286.23687 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
+ <path style="fill:#f7fdfd" d="m 43.101068,285.17854 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
+ <path style="fill:#f1f2e0" d="m 46.276068,284.64938 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
+ <path style="fill:#f7fdfd" d="m 45.217735,286.23688 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
+ <path style="fill:#f1f2e0" d="m 44.159402,284.64937 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
+ <path style="fill:#f1f2e0" d="m 43.101068,287.2952 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
+ <path style="fill:#f7fdfd" d="m 44.159402,287.82438 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
+ <path style="fill:#f7fdfd" d="m 48.392735,286.76604 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
+ <path style="fill:#f1f2e0" d="m 48.392735,287.82438 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
+ <path style="fill:#f1f2e0" d="m 46.276068,286.76604 1.058333,0.52917 1.058333,-0.52917 -1.058333,-0.52917 z" />
+ <path style="fill:#f7fdfd" d="m 47.334402,285.17854 2.116667,1.05833 1.058333,-0.52917 -2.116667,-1.05833 z" />
+ </g>
+ </g>
+</svg>
diff --git a/launcher/resources/multimc/scalable/instances/brick.svg b/launcher/resources/multimc/scalable/instances/brick.svg
new file mode 100644
index 00000000..b600eba8
--- /dev/null
+++ b/launcher/resources/multimc/scalable/instances/brick.svg
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="24"
+ height="24"
+ version="1.1"
+ viewBox="0 0 24 24"
+ id="svg168"
+ xml:space="preserve"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"><defs
+ id="defs172"><linearGradient
+ id="linearGradient288023"><stop
+ style="stop-color:#c1c1c1;stop-opacity:1;"
+ offset="0"
+ id="stop288019" /><stop
+ style="stop-color:#dfdfdf;stop-opacity:1;"
+ offset="1"
+ id="stop288021" /></linearGradient><linearGradient
+ xlink:href="#linearGradient84376"
+ id="linearGradient84368"
+ x1="48"
+ y1="26"
+ x2="48"
+ y2="6"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ id="linearGradient84376"><stop
+ style="stop-color:#a63649;stop-opacity:1;"
+ offset="0"
+ id="stop84370" /><stop
+ style="stop-color:#df6277;stop-opacity:1;"
+ offset="1"
+ id="stop84381" /></linearGradient><linearGradient
+ xlink:href="#linearGradient288023"
+ id="linearGradient85182"
+ x1="48"
+ y1="6"
+ x2="48"
+ y2="26"
+ gradientUnits="userSpaceOnUse" /></defs><title
+ id="title132">Prism Launcher Logo</title><metadata
+ id="metadata166"><rdf:RDF><cc:Work
+ rdf:about=""><dc:title>Prism Launcher Logo</dc:title><dc:date>19/10/2022</dc:date><dc:creator><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:creator><dc:contributor><cc:Agent><dc:title>AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke</dc:title></cc:Agent></dc:contributor><dc:source>https://github.com/PrismLauncher/PrismLauncher</dc:source><dc:rights><cc:Agent><dc:title>CC BY-SA 4.0</dc:title></cc:Agent></dc:rights><dc:publisher><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:publisher></cc:Work></rdf:RDF></metadata><g
+ id="i_brick"
+ style="fill:#ff0000"
+ transform="translate(-36,-4)"><rect
+ style="fill:#ff0000;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-7"
+ width="24"
+ height="24"
+ x="36"
+ y="4" /><rect
+ style="fill:url(#linearGradient84368);fill-opacity:1;stroke-width:0.277182;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect13011-3"
+ width="20"
+ height="20"
+ x="38"
+ y="6"
+ ry="3" /><path
+ id="rect13933-4"
+ style="fill:url(#linearGradient85182);fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 47,6 v 5 h -9 v 2 h 4 v 6 h -4 v 2 h 9 v 5 h 2 v -5 h 9 v -2 h -4 v -6 h 4 V 11 H 49 V 6 Z m -3,7 h 8 v 6 h -8 z" /></g></svg>
diff --git a/launcher/resources/multimc/scalable/instances/chicken.svg b/launcher/resources/multimc/scalable/instances/chicken.svg
new file mode 100644
index 00000000..0b5bf017
--- /dev/null
+++ b/launcher/resources/multimc/scalable/instances/chicken.svg
@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="24"
+ height="24"
+ version="1.1"
+ viewBox="0 0 24 24"
+ id="svg168"
+ xml:space="preserve"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"><defs
+ id="defs172"><linearGradient
+ id="linearGradient2085"><stop
+ style="stop-color:#261a0a;stop-opacity:1;"
+ offset="0"
+ id="stop2081" /><stop
+ style="stop-color:#3c2b13;stop-opacity:1;"
+ offset="1"
+ id="stop2083" /></linearGradient><linearGradient
+ xlink:href="#linearGradient292700"
+ id="linearGradient292686"
+ x1="86.052681"
+ y1="26.999552"
+ x2="86"
+ y2="5"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ id="linearGradient292700"><stop
+ style="stop-color:#d0d0d0;stop-opacity:1;"
+ offset="0.23078403"
+ id="stop292702" /><stop
+ style="stop-color:#eeeeee;stop-opacity:1;"
+ offset="0.83153141"
+ id="stop292698" /></linearGradient><linearGradient
+ xlink:href="#linearGradient293074"
+ id="linearGradient293076"
+ x1="80"
+ y1="31"
+ x2="80"
+ y2="21"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ id="linearGradient293074"><stop
+ style="stop-color:#a63649;stop-opacity:1;"
+ offset="0"
+ id="stop293070" /><stop
+ style="stop-color:#df6277;stop-opacity:1;"
+ offset="0.52521378"
+ id="stop293078" /><stop
+ style="stop-color:#a63649;stop-opacity:1;"
+ offset="1"
+ id="stop293072" /></linearGradient><linearGradient
+ xlink:href="#linearGradient2085"
+ id="linearGradient42830"
+ x1="77"
+ y1="17"
+ x2="77"
+ y2="14"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ xlink:href="#linearGradient292039"
+ id="linearGradient292041"
+ x1="88"
+ y1="24"
+ x2="88"
+ y2="18"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ id="linearGradient292039"><stop
+ style="stop-color:#fb9168;stop-opacity:1;"
+ offset="0"
+ id="stop292035" /><stop
+ style="stop-color:#f3db6c;stop-opacity:1;"
+ offset="1"
+ id="stop292037" /></linearGradient><linearGradient
+ xlink:href="#linearGradient2085"
+ id="linearGradient82810"
+ gradientUnits="userSpaceOnUse"
+ x1="77"
+ y1="17"
+ x2="77"
+ y2="14" /></defs><title
+ id="title132">Prism Launcher Logo</title><metadata
+ id="metadata166"><rdf:RDF><cc:Work
+ rdf:about=""><dc:title>Prism Launcher Logo</dc:title><dc:date>19/10/2022</dc:date><dc:creator><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:creator><dc:contributor><cc:Agent><dc:title>AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke</dc:title></cc:Agent></dc:contributor><dc:source>https://github.com/PrismLauncher/PrismLauncher</dc:source><dc:rights><cc:Agent><dc:title>CC BY-SA 4.0</dc:title></cc:Agent></dc:rights><dc:publisher><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:publisher></cc:Work></rdf:RDF></metadata><g
+ id="i_chicken"
+ transform="translate(-68,-4)"><rect
+ style="fill:url(#linearGradient292686);fill-opacity:1;stroke-width:0.277182;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect18469"
+ width="16"
+ height="20"
+ x="72"
+ y="6"
+ ry="3" /><rect
+ style="fill:url(#linearGradient293076);fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect22620"
+ width="6"
+ height="6"
+ x="77"
+ y="21"
+ ry="1" /><g
+ id="g23887"
+ clip-path="none"
+ style="fill:url(#linearGradient42830);fill-opacity:1"
+ transform="translate(1,1)"><path
+ id="rect3612-5"
+ style="fill:url(#linearGradient82810);fill-opacity:1;stroke-width:0.170787;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 73,12 c -0.553999,0 -1,0.446001 -1,1 v 3 c 0,0.553999 0.446001,1 1,1 h 3 c 0.553999,0 1,-0.446001 1,-1 v -2 h -2 v -2 z" /><path
+ id="rect42884"
+ style="fill:#ffffff;fill-opacity:1;stroke:none;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 75,12 v 2 h 2 v -1 c 0,-0.553999 -0.446001,-1 -1,-1 z" /></g><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-8"
+ width="24"
+ height="24"
+ x="68"
+ y="4" /><use
+ x="0"
+ y="0"
+ xlink:href="#g23887"
+ id="use42929"
+ transform="translate(9)" /><rect
+ style="fill:url(#linearGradient292041);fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect37390"
+ width="18"
+ height="5"
+ x="71"
+ y="17"
+ ry="1" /></g></svg>
diff --git a/launcher/resources/multimc/scalable/instances/creeper.svg b/launcher/resources/multimc/scalable/instances/creeper.svg
new file mode 100644
index 00000000..4a9fe380
--- /dev/null
+++ b/launcher/resources/multimc/scalable/instances/creeper.svg
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="24"
+ height="24"
+ version="1.1"
+ viewBox="0 0 24 24"
+ id="svg168"
+ xml:space="preserve"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"><defs
+ id="defs172"><linearGradient
+ xlink:href="#linearGradient11855"
+ id="linearGradient11859"
+ x1="111"
+ y1="25"
+ x2="111"
+ y2="7"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ id="linearGradient11855"><stop
+ style="stop-color:#57965f;stop-opacity:1;"
+ offset="0"
+ id="stop11851" /><stop
+ style="stop-color:#78bf6e;stop-opacity:1;"
+ offset="1"
+ id="stop11853" /></linearGradient><radialGradient
+ xlink:href="#linearGradient10455"
+ id="radialGradient10457"
+ cx="112"
+ cy="17"
+ fx="112"
+ fy="17"
+ r="6"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1666668,-6.8921104e-7,5.6666669e-7,1.1666667,-18.666684,-2.8332561)" /><linearGradient
+ id="linearGradient10455"><stop
+ style="stop-color:#1b2719;stop-opacity:1;"
+ offset="0"
+ id="stop10451" /><stop
+ style="stop-color:#0f150e;stop-opacity:1;"
+ offset="1"
+ id="stop10453" /></linearGradient></defs><title
+ id="title132">Prism Launcher Logo</title><metadata
+ id="metadata166"><rdf:RDF><cc:Work
+ rdf:about=""><dc:title>Prism Launcher Logo</dc:title><dc:date>19/10/2022</dc:date><dc:creator><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:creator><dc:contributor><cc:Agent><dc:title>AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke</dc:title></cc:Agent></dc:contributor><dc:source>https://github.com/PrismLauncher/PrismLauncher</dc:source><dc:rights><cc:Agent><dc:title>CC BY-SA 4.0</dc:title></cc:Agent></dc:rights><dc:publisher><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:publisher></cc:Work></rdf:RDF></metadata><g
+ id="i_creeper"
+ transform="translate(-100,-4)"><rect
+ style="fill:url(#linearGradient11859);fill-opacity:1;stroke-width:0.226785;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect543-0-2-3"
+ width="18"
+ height="18"
+ x="103"
+ y="7"
+ ry="2.4545455" /><path
+ id="rect29291"
+ style="fill:url(#radialGradient10457);fill-opacity:1;stroke-width:0.529166;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 106,12 v 4 h 4 v -4 z m 4,4 v 2 h -2 v 6 h 2 v -2 h 4 v 2 h 2 v -6 h -2 v -2 z m 4,0 h 4 v -4 h -4 z" /><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-7-6"
+ width="24"
+ height="24"
+ x="100"
+ y="4" /></g></svg>
diff --git a/launcher/resources/multimc/scalable/instances/diamond.svg b/launcher/resources/multimc/scalable/instances/diamond.svg
new file mode 100644
index 00000000..1d490b91
--- /dev/null
+++ b/launcher/resources/multimc/scalable/instances/diamond.svg
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="24"
+ height="24"
+ version="1.1"
+ viewBox="0 0 24 24"
+ id="svg168"
+ xml:space="preserve"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"><defs
+ id="defs172"><linearGradient
+ id="linearGradient41693"><stop
+ style="stop-color:#64d5df;stop-opacity:1;"
+ offset="0"
+ id="stop41689" /><stop
+ style="stop-color:#17c2d6;stop-opacity:1;"
+ offset="0.35665122"
+ id="stop41711" /><stop
+ style="stop-color:#89edf6;stop-opacity:1;"
+ offset="0.71356344"
+ id="stop41709" /><stop
+ style="stop-color:#2bc4d4;stop-opacity:1;"
+ offset="1"
+ id="stop41691" /></linearGradient><linearGradient
+ xlink:href="#linearGradient41693"
+ id="linearGradient2973"
+ gradientUnits="userSpaceOnUse"
+ x1="153"
+ y1="25"
+ x2="135"
+ y2="7" /></defs><title
+ id="title132">Prism Launcher Logo</title><metadata
+ id="metadata166"><rdf:RDF><cc:Work
+ rdf:about=""><dc:title>Prism Launcher Logo</dc:title><dc:date>19/10/2022</dc:date><dc:creator><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:creator><dc:contributor><cc:Agent><dc:title>AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke</dc:title></cc:Agent></dc:contributor><dc:source>https://github.com/PrismLauncher/PrismLauncher</dc:source><dc:rights><cc:Agent><dc:title>CC BY-SA 4.0</dc:title></cc:Agent></dc:rights><dc:publisher><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:publisher></cc:Work></rdf:RDF></metadata><g
+ id="i_diamond"
+ transform="translate(-132,-4)"><rect
+ style="fill:#1bc3d7;fill-opacity:1;stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect15088-8-0"
+ width="20"
+ height="20"
+ x="134"
+ y="6"
+ ry="3" /><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-88"
+ width="24"
+ height="24"
+ x="132"
+ y="4" /><rect
+ style="fill:url(#linearGradient2973);fill-opacity:1;stroke:none;stroke-width:1;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect40970-3-3"
+ width="18"
+ height="18"
+ x="135"
+ y="7"
+ ry="2" /></g></svg>
diff --git a/launcher/resources/multimc/scalable/instances/dirt.svg b/launcher/resources/multimc/scalable/instances/dirt.svg
new file mode 100644
index 00000000..df28ae92
--- /dev/null
+++ b/launcher/resources/multimc/scalable/instances/dirt.svg
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="24"
+ height="24"
+ version="1.1"
+ viewBox="0 0 24 24"
+ id="svg168"
+ xml:space="preserve"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"><defs
+ id="defs172"><linearGradient
+ id="linearGradient53203"><stop
+ style="stop-color:#77563b;stop-opacity:1;"
+ offset="0"
+ id="stop53199" /><stop
+ style="stop-color:#86674f;stop-opacity:1;"
+ offset="1"
+ id="stop53201" /></linearGradient><linearGradient
+ xlink:href="#linearGradient53203"
+ id="linearGradient39079"
+ gradientUnits="userSpaceOnUse"
+ x1="785"
+ y1="26"
+ x2="785"
+ y2="6" /></defs><title
+ id="title132">Prism Launcher Logo</title><metadata
+ id="metadata166"><rdf:RDF><cc:Work
+ rdf:about=""><dc:title>Prism Launcher Logo</dc:title><dc:date>19/10/2022</dc:date><dc:creator><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:creator><dc:contributor><cc:Agent><dc:title>AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke</dc:title></cc:Agent></dc:contributor><dc:source>https://github.com/PrismLauncher/PrismLauncher</dc:source><dc:rights><cc:Agent><dc:title>CC BY-SA 4.0</dc:title></cc:Agent></dc:rights><dc:publisher><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:publisher></cc:Work></rdf:RDF></metadata><g
+ id="i_dirt"
+ transform="translate(-772,-4)"><rect
+ style="fill:url(#linearGradient39079);fill-opacity:1;stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect15088-9-1"
+ width="20"
+ height="20"
+ x="774"
+ y="6"
+ ry="3" /><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-4-1-0"
+ width="24"
+ height="24"
+ x="772"
+ y="4" /><path
+ id="rect48773"
+ style="opacity:0.268946;fill:#a88356;fill-opacity:1;stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ d="M 776.13672,8 C 776.05936,8.00781 776,8.07286 776,8.15234 V 9.84766 C 776,9.93244 776.06756,10 776.15234,10 h 1.69532 C 777.93244,10 778,9.93244 778,9.84766 V 8.15234 C 778,8.06756 777.93244,8 777.84766,8 h -1.69532 c -0.005,0 -0.0105,-5.2e-4 -0.0156,0 z m 10,2 C 786.05936,10.00781 786,10.07286 786,10.15234 v 1.69532 C 786,11.93244 786.06756,12 786.15234,12 h 1.69532 C 787.93244,12 788,11.93244 788,11.84766 V 10.15234 C 788,10.06756 787.93244,10 787.84766,10 h -1.69532 c -0.005,0 -0.0105,-5.2e-4 -0.0156,0 z m -8,4 C 778.05936,14.00781 778,14.07286 778,14.15234 v 1.69532 C 778,15.93244 778.06756,16 778.15234,16 h 1.69532 C 779.93244,16 780,15.93244 780,15.84766 V 14.15234 C 780,14.06756 779.93244,14 779.84766,14 h -1.69532 c -0.005,0 -0.0105,-5.2e-4 -0.0156,0 z m 13,2 C 791.05936,16.00781 791,16.07286 791,16.15234 v 1.69532 C 791,17.93244 791.06756,18 791.15234,18 h 1.69532 C 792.93244,18 793,17.93244 793,17.84766 V 16.15234 C 793,16.06756 792.93244,16 792.84766,16 h -1.69532 c -0.005,0 -0.0105,-5.2e-4 -0.0156,0 z m -7,2 C 784.05936,18.00781 784,18.07286 784,18.15234 v 1.69532 C 784,19.93244 784.06756,20 784.15234,20 h 1.69532 C 785.93244,20 786,19.93244 786,19.84766 V 18.15234 C 786,18.06756 785.93244,18 785.84766,18 h -1.69532 c -0.005,0 -0.0105,-5.2e-4 -0.0156,0 z m -9,2 C 775.05936,20.00781 775,20.07286 775,20.15234 v 1.69532 C 775,21.93244 775.06756,22 775.15234,22 h 1.69532 C 776.93244,22 777,21.93244 777,21.84766 V 20.15234 C 777,20.06756 776.93244,20 776.84766,20 h -1.69532 c -0.005,0 -0.0105,-5.2e-4 -0.0156,0 z m 15,2 C 790.05936,22.00781 790,22.07286 790,22.15234 v 1.69532 C 790,23.93244 790.06756,24 790.15234,24 h 1.69532 C 791.93244,24 792,23.93244 792,23.84766 V 22.15234 C 792,22.06756 791.93244,22 791.84766,22 h -1.69532 c -0.005,0 -0.0105,-5.2e-4 -0.0156,0 z m -9,2 C 781.05936,24.00781 781,24.07286 781,24.15234 v 1.69532 C 781,25.93244 781.06756,26 781.15234,26 h 1.69532 C 782.93244,26 783,25.93244 783,25.84766 V 24.15234 C 783,24.06756 782.93244,24 782.84766,24 h -1.69532 c -0.005,0 -0.0105,-5.2e-4 -0.0156,0 z" /></g></svg>
diff --git a/launcher/resources/multimc/scalable/instances/enderman.svg b/launcher/resources/multimc/scalable/instances/enderman.svg
new file mode 100644
index 00000000..29f25a2f
--- /dev/null
+++ b/launcher/resources/multimc/scalable/instances/enderman.svg
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="24"
+ height="24"
+ version="1.1"
+ viewBox="0 0 24 24"
+ id="svg168"
+ xml:space="preserve"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"><defs
+ id="defs172"><linearGradient
+ xlink:href="#linearGradient5295"
+ id="linearGradient5297"
+ x1="239"
+ y1="5"
+ x2="239"
+ y2="27"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ id="linearGradient5295"><stop
+ style="stop-color:#25262d;stop-opacity:1;"
+ offset="0"
+ id="stop5291" /><stop
+ style="stop-color:#141519;stop-opacity:1;"
+ offset="1"
+ id="stop5293" /></linearGradient><linearGradient
+ xlink:href="#linearGradient5303"
+ id="linearGradient5316"
+ x1="243"
+ y1="17"
+ x2="243"
+ y2="20"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ id="linearGradient5303"><stop
+ style="stop-color:#bd44b3;stop-opacity:1;"
+ offset="0"
+ id="stop5299" /><stop
+ style="stop-color:#d84ecd;stop-opacity:1;"
+ offset="1"
+ id="stop5301" /></linearGradient><linearGradient
+ xlink:href="#linearGradient5303"
+ id="linearGradient5305"
+ x1="236"
+ y1="17"
+ x2="236"
+ y2="20"
+ gradientUnits="userSpaceOnUse" /></defs><title
+ id="title132">Prism Launcher Logo</title><metadata
+ id="metadata166"><rdf:RDF><cc:Work
+ rdf:about=""><dc:title>Prism Launcher Logo</dc:title><dc:date>19/10/2022</dc:date><dc:creator><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:creator><dc:contributor><cc:Agent><dc:title>AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke</dc:title></cc:Agent></dc:contributor><dc:source>https://github.com/PrismLauncher/PrismLauncher</dc:source><dc:rights><cc:Agent><dc:title>CC BY-SA 4.0</dc:title></cc:Agent></dc:rights><dc:publisher><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:publisher></cc:Work></rdf:RDF></metadata><g
+ id="i_enderman"
+ transform="translate(-228,-4)"><rect
+ style="fill:url(#linearGradient5297);fill-opacity:1;stroke-width:0.277182;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect543-0-2"
+ width="22"
+ height="22"
+ x="229"
+ y="5"
+ ry="3" /><rect
+ style="fill:url(#linearGradient5316);fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect63182-8"
+ width="7"
+ height="3"
+ x="242"
+ y="17"
+ ry="1" /><rect
+ style="fill:url(#linearGradient5305);fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect63184-7"
+ width="7"
+ height="3"
+ x="231"
+ y="17"
+ ry="1" /><rect
+ style="fill:#792aac;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect75119"
+ width="2"
+ height="2"
+ x="234"
+ y="18" /><rect
+ style="fill:#792aac;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect75474"
+ width="2"
+ height="2"
+ x="244"
+ y="18" /><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-7-6-1"
+ width="24"
+ height="24"
+ x="228"
+ y="4" /></g></svg>
diff --git a/launcher/resources/multimc/scalable/instances/enderpearl.svg b/launcher/resources/multimc/scalable/instances/enderpearl.svg
new file mode 100644
index 00000000..e4c1e104
--- /dev/null
+++ b/launcher/resources/multimc/scalable/instances/enderpearl.svg
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="24"
+ height="24"
+ version="1.1"
+ viewBox="0 0 24 24"
+ id="svg168"
+ xml:space="preserve"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"><defs
+ id="defs172"><linearGradient
+ id="linearGradient3853"><stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="0.39989081"
+ id="stop3851" /><stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop3849" /></linearGradient><linearGradient
+ id="linearGradient3405"><stop
+ style="stop-color:#27414e;stop-opacity:1;"
+ offset="0.16041158"
+ id="stop3401" /><stop
+ style="stop-color:#27414e;stop-opacity:0.74901961;"
+ offset="0.50162286"
+ id="stop39443" /><stop
+ style="stop-color:#27414e;stop-opacity:0;"
+ offset="1"
+ id="stop3403" /></linearGradient><linearGradient
+ id="linearGradient3000"><stop
+ style="stop-color:#62b397;stop-opacity:1;"
+ offset="0.47770822"
+ id="stop2996" /><stop
+ style="stop-color:#3a7a81;stop-opacity:1;"
+ offset="1"
+ id="stop2998" /></linearGradient><radialGradient
+ xlink:href="#linearGradient3000"
+ id="radialGradient3002-5"
+ cx="272"
+ cy="16"
+ fx="272"
+ fy="16"
+ r="12"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.75,0,0,0.75,68,4)" /><radialGradient
+ xlink:href="#linearGradient3405"
+ id="radialGradient3407-4"
+ cx="272"
+ cy="16"
+ fx="272"
+ fy="16"
+ r="5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2,0,0,1.2,-54.4,-3.2)" /><radialGradient
+ xlink:href="#linearGradient3853"
+ id="radialGradient3855-4"
+ cx="272"
+ cy="16"
+ fx="272"
+ fy="16"
+ r="5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.8,0,0,1.8,-217.6,-12.8)" /></defs><title
+ id="title132">Prism Launcher Logo</title><metadata
+ id="metadata166"><rdf:RDF><cc:Work
+ rdf:about=""><dc:title>Prism Launcher Logo</dc:title><dc:date>19/10/2022</dc:date><dc:creator><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:creator><dc:contributor><cc:Agent><dc:title>AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke</dc:title></cc:Agent></dc:contributor><dc:source>https://github.com/PrismLauncher/PrismLauncher</dc:source><dc:rights><cc:Agent><dc:title>CC BY-SA 4.0</dc:title></cc:Agent></dc:rights><dc:publisher><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:publisher></cc:Work></rdf:RDF></metadata><g
+ id="i_enderpearl"
+ transform="translate(-260,-4)"><circle
+ style="fill:url(#radialGradient3002-5);fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="path78788-8"
+ cx="272"
+ cy="16"
+ r="9" /><path
+ id="circle80343-2-6"
+ style="fill:#62b397;fill-opacity:1;stroke-width:0.220486;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 272,9.0000001 c -3.866,0 -7,3.1340069 -7,6.9999999 0,3.865993 3.134,7 7,7 3.86599,0 7,-3.134007 7,-7 0,-3.865993 -3.13401,-6.9999999 -7,-6.9999999 z" /><circle
+ style="fill:url(#radialGradient3407-4);fill-opacity:1;stroke-width:0.187412;paint-order:stroke markers fill;stop-color:#000000"
+ id="circle81814-8"
+ cx="272"
+ cy="16"
+ r="6" /><path
+ id="circle80343-8"
+ style="fill:url(#radialGradient3855-4);fill-opacity:1;stroke-width:0.220486;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 272,9 c -3.86599,0 -7,3.134011 -7,7 h 2 c 0,-2.761421 2.23858,-5 5,-5 z" /><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-4-4"
+ width="24"
+ height="24"
+ x="260"
+ y="4" /></g></svg>
diff --git a/launcher/resources/multimc/scalable/instances/flame.svg b/launcher/resources/multimc/scalable/instances/flame.svg
new file mode 100644
index 00000000..775914b8
--- /dev/null
+++ b/launcher/resources/multimc/scalable/instances/flame.svg
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="24"
+ height="24"
+ version="1.1"
+ viewBox="0 0 24 24"
+ id="svg168"
+ xml:space="preserve"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"><defs
+ id="defs172"><linearGradient
+ xlink:href="#linearGradient1468"
+ id="linearGradient1470"
+ x1="300"
+ y1="26"
+ x2="300"
+ y2="10"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1,-2)" /><linearGradient
+ id="linearGradient1468"><stop
+ style="stop-color:#d63954;stop-opacity:1;"
+ offset="0"
+ id="stop1464" /><stop
+ style="stop-color:#e6812b;stop-opacity:1;"
+ offset="1"
+ id="stop1466" /></linearGradient></defs><title
+ id="title132">Prism Launcher Logo</title><metadata
+ id="metadata166"><rdf:RDF><cc:Work
+ rdf:about=""><dc:title>Prism Launcher Logo</dc:title><dc:date>19/10/2022</dc:date><dc:creator><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:creator><dc:contributor><cc:Agent><dc:title>AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke</dc:title></cc:Agent></dc:contributor><dc:source>https://github.com/PrismLauncher/PrismLauncher</dc:source><dc:rights><cc:Agent><dc:title>CC BY-SA 4.0</dc:title></cc:Agent></dc:rights><dc:publisher><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:publisher></cc:Work></rdf:RDF></metadata><g
+ id="i_flame"
+ transform="translate(-292,-4)"><path
+ id="path5010"
+ style="fill:url(#linearGradient1470);fill-opacity:1;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 299,9 c -1.10457,0 -2,0.895431 -2,2 h -1 -4 c 0,2.209137 1.79086,4 4,4 h 2 v 1 c 0,1.656852 1.34315,3 3,3 v 1 c -1.10457,0 -2,0.895438 -2,2 v 2 h 11 v -2 c 0,-1.104562 -0.89543,-2 -2,-2 v -1 c 1.10457,0 2,-1.053227 2,-2 0,-3.313684 2.68629,-6 6,-6 V 9 Z" /><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-7-9"
+ width="24"
+ height="24"
+ x="292"
+ y="4" /><path
+ id="path225757"
+ style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ d="M 305.94922,10 C 304.86851,10.02738 304,10.912691 304,12 v 1 a 1,1 0 0 1 -1,-1 v 2 c 0,0.552284 0.44772,1 1,1 0,0.552284 -0.44772,1 -1,1 -0.55228,0 -1,-0.447716 -1,-1 -0.55228,0 -1,0.447716 -1,1 0,1.104568 0.89543,2 2,2 0.55228,0 1,0.447716 1,1 0,-0.552284 0.44772,-1 1,-1 h 1 c 0.55228,0 1,-0.447716 1,-1 v -1 c 0,0.552284 -0.44772,1 -1,1 -0.55228,0 -1,-0.447716 -1,-1 0.55228,0 1,-0.447716 1,-1 v -1 c 0,-0.552284 -0.44772,-1 -1,-1 v -1 c 0,-1.087309 0.86851,-1.97262 1.94922,-2 H 306 c -0.0173,0 -0.0336,-4.35e-4 -0.0508,0 z" /></g></svg>
diff --git a/launcher/resources/multimc/scalable/instances/fox.svg b/launcher/resources/multimc/scalable/instances/fox.svg
index fcf16b2f..95ca6ef9 100644
--- a/launcher/resources/multimc/scalable/instances/fox.svg
+++ b/launcher/resources/multimc/scalable/instances/fox.svg
@@ -1,290 +1,151 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- id="svg8"
+ width="24"
+ height="24"
version="1.1"
- viewBox="0 0 33.866666 33.866666"
- height="128"
- width="128">
- <defs
- id="defs2" />
- <metadata
- id="metadata5">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- transform="translate(0,-263.13334)"
- id="layer1">
- <path
- id="rect4750"
- d="m 4.233333,267.36667 v 6.35 6.35 3.175 3.175 3.175 3.175 h 25.4 v -3.175 -3.175 -3.175 -3.175 -6.35 -6.35 h -6.35 v 6.35 h -12.7 v -3.175 -3.175 z"
- style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#800000;stroke-width:0.79375;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
- <g
- id="g4748">
- <rect
- style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#f9f4f4;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.19062567;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
- id="rect4553"
- width="6.3500032"
- height="6.3499975"
- x="4.233326"
- y="267.36667" />
- <rect
- style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#b48f83;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.59531283;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
- id="rect4553-6-2"
- width="3.1750014"
- height="3.1749992"
- x="7.4083276"
- y="270.54166" />
- <rect
- y="267.36667"
- x="23.283335"
- height="6.3499975"
- width="6.3500032"
- id="rect4623"
- style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#f9f4f4;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.19062567;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
- <rect
- y="270.54166"
- x="23.283335"
- height="3.1749992"
- width="3.1750014"
- id="rect4627"
- style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#b48f83;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.59531283;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
- <rect
- style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#e27c21;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.59531283;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
- id="rect4672"
- width="25.400013"
- height="15.875009"
- x="4.233326"
- y="273.71667" />
- <rect
- style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#cc6920;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.59531283;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
- id="rect4629"
- width="3.1750016"
- height="6.3500032"
- x="4.2333255"
- y="273.71667" />
- <rect
- y="273.71667"
- x="26.458338"
- height="6.3500032"
- width="3.1750016"
- id="rect4631"
- style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#cc6920;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.59531283;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
- <rect
- style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#e78f41;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.59531283;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
- id="rect4636"
- width="6.3500032"
- height="3.1750016"
- x="13.758331"
- y="283.24167" />
- <rect
- style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#b05122;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.59531283;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
- id="rect4638"
- width="3.1750016"
- height="3.1750016"
- x="4.2333255"
- y="280.06668" />
- <rect
- style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#cc6920;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.59531283;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
- id="rect4640"
- width="3.1750016"
- height="3.1750016"
- x="7.4083276"
- y="280.06668" />
- <rect
- style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#f9f4f4;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.84189939;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
- id="rect4644"
- width="6.3500028"
- height="3.1750016"
- x="4.233326"
- y="283.24167" />
- <rect
- style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#06040e;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.59531283;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
- id="rect4642"
- width="3.1750016"
- height="3.1750016"
- x="4.2333255"
- y="283.24167" />
- <rect
- style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#f9f4f4;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.84189939;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
- id="rect4646"
- width="6.3500028"
- height="3.1750016"
- x="23.283337"
- y="283.24167" />
- <rect
- style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#06040e;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.59531283;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
- id="rect4648"
- width="3.1750016"
- height="3.1750016"
- x="26.45834"
- y="283.24167" />
- <rect
- style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#cc6920;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.59531283;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
- id="rect4650"
- width="3.1750016"
- height="3.1750016"
- x="23.283337"
- y="280.06668" />
- <rect
- style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#b05122;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.59531283;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
- id="rect4652"
- width="3.1750016"
- height="3.1750016"
- x="26.45834"
- y="280.06668" />
- <rect
- style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#cc6920;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.59531283;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
- id="rect4654"
- width="25.400013"
- height="3.1750016"
- x="4.2333255"
- y="286.41666" />
- <rect
- style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#e7d9d3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.59531283;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
- id="rect4656"
- width="25.400013"
- height="3.1750016"
- x="4.2333255"
- y="289.59167" />
- <rect
- style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.25;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.5612604;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
- id="rect4917"
- width="25.4"
- height="0.26457807"
- x="4.2333331"
- y="273.71667" />
- <rect
- style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.25;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.48607069;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
- id="rect4921"
- width="0.2645835"
- height="19.049997"
- x="4.2333331"
- y="273.71667" />
- <rect
- style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#f9f4f4;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.19062555;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
- id="rect4658"
- width="12.700007"
- height="6.3500013"
- x="10.583333"
- y="286.41666" />
- <rect
- style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#06040e;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.19062555;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
- id="rect4660"
- width="6.3500037"
- height="3.1750007"
- x="13.758333"
- y="286.41669" />
- <rect
- style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#e7d9d3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.19062555;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
- id="rect4662"
- width="3.1750019"
- height="3.1750007"
- x="10.583333"
- y="286.41669" />
- <rect
- style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#e7d9d3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.19062555;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
- id="rect4664"
- width="3.1750019"
- height="3.1750007"
- x="20.108334"
- y="286.41669" />
- <rect
- y="286.41669"
- x="10.583333"
- height="6.3499832"
- width="0.2645835"
- id="rect4923"
- style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.25;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2806327;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
- <rect
- style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.25;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.39686465;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
- id="rect4951"
- width="12.699996"
- height="0.26456967"
- x="10.583333"
- y="286.41669" />
- <rect
- y="273.71667"
- x="29.36875"
- height="19.049982"
- width="0.26458356"
- id="rect4953"
- style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.48607057;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
- <rect
- y="292.50208"
- x="23.283333"
- height="0.26457682"
- width="6.3499994"
- id="rect4957"
- style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.28062955;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
- <rect
- style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2806325;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
- id="rect4959"
- width="0.2645838"
- height="6.3499656"
- x="23.018749"
- y="286.41669" />
- <rect
- y="292.50208"
- x="4.2333331"
- height="0.26457968"
- width="6.3499999"
- id="rect4961"
- style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.28063107;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
- <rect
- y="267.36667"
- x="4.2333331"
- height="6.3499956"
- width="0.2645835"
- id="rect4963"
- style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.25;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.28063297;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
- <rect
- style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.25;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.28063536;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
- id="rect4965"
- width="6.349998"
- height="0.26458791"
- x="4.2333331"
- y="267.36667" />
- <rect
- y="267.36667"
- x="23.283333"
- height="6.3499956"
- width="0.2645835"
- id="rect4963-9"
- style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.25;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.280633;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
- <rect
- style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.25;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.28063536;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
- id="rect4965-1"
- width="6.349998"
- height="0.26458791"
- x="23.283333"
- y="267.36667" />
- <rect
- style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.28063306;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
- id="rect4985"
- width="0.26458356"
- height="6.3499975"
- x="29.36875"
- y="267.36667" />
- <rect
- y="267.36667"
- x="10.318749"
- height="6.3499975"
- width="0.26458356"
- id="rect4987"
- style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.28063306;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
- </g>
- </g>
-</svg>
+ viewBox="0 0 24 24"
+ id="svg168"
+ xml:space="preserve"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"><defs
+ id="defs172"><linearGradient
+ id="linearGradient288023"><stop
+ style="stop-color:#c1c1c1;stop-opacity:1;"
+ offset="0"
+ id="stop288019" /><stop
+ style="stop-color:#dfdfdf;stop-opacity:1;"
+ offset="1"
+ id="stop288021" /></linearGradient><linearGradient
+ xlink:href="#linearGradient288023"
+ id="linearGradient288033"
+ x1="183"
+ y1="11"
+ x2="183"
+ y2="7"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ xlink:href="#linearGradient288023"
+ id="linearGradient288025"
+ x1="171"
+ y1="11"
+ x2="171"
+ y2="7"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ xlink:href="#linearGradient287141"
+ id="linearGradient287143"
+ x1="181.38519"
+ y1="21.999998"
+ x2="181.38519"
+ y2="5.9999976"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-12.385191,4.0000023)" /><linearGradient
+ id="linearGradient287141"><stop
+ style="stop-color:#fb6a32;stop-opacity:1;"
+ offset="0"
+ id="stop287137" /><stop
+ style="stop-color:#fb9168;stop-opacity:1;"
+ offset="1"
+ id="stop287139" /></linearGradient><linearGradient
+ xlink:href="#linearGradient287169"
+ id="linearGradient287171"
+ x1="178.38519"
+ y1="21.999998"
+ x2="198.38519"
+ y2="21.999998"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-12.385191,4.0000023)" /><linearGradient
+ id="linearGradient287169"><stop
+ style="stop-color:#d6d2d2;stop-opacity:1;"
+ offset="0"
+ id="stop287165" /><stop
+ style="stop-color:#aca7a7;stop-opacity:1;"
+ offset="0.49945405"
+ id="stop287173" /><stop
+ style="stop-color:#d6d2d2;stop-opacity:1;"
+ offset="0.9989081"
+ id="stop287167" /></linearGradient><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath51465-6-2-8-5-5-4-9-7"><rect
+ style="fill:#dfdfdf;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect51467-3-9-5-9-9-2-3-5"
+ width="10.000002"
+ height="5.0000005"
+ x="183.38519"
+ y="17.999998"
+ ry="0.99999958" /></clipPath><linearGradient
+ xlink:href="#linearGradient287187"
+ id="linearGradient287189"
+ x1="192.38519"
+ y1="22.999998"
+ x2="192.38519"
+ y2="17.999998"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ id="linearGradient287187"><stop
+ style="stop-color:#dfdfdf;stop-opacity:1;"
+ offset="0"
+ id="stop287183" /><stop
+ style="stop-color:#f3f3f3;stop-opacity:1;"
+ offset="1"
+ id="stop287185" /></linearGradient></defs><title
+ id="title132">Prism Launcher Logo</title><metadata
+ id="metadata166"><rdf:RDF><cc:Work
+ rdf:about=""><dc:title>Prism Launcher Logo</dc:title><dc:date>19/10/2022</dc:date><dc:creator><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:creator><dc:contributor><cc:Agent><dc:title>AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke</dc:title></cc:Agent></dc:contributor><dc:source>https://github.com/PrismLauncher/PrismLauncher</dc:source><dc:rights><cc:Agent><dc:title>CC BY-SA 4.0</dc:title></cc:Agent></dc:rights><dc:publisher><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:publisher></cc:Work></rdf:RDF></metadata><g
+ id="i_fox"
+ transform="translate(-164,-4)"><path
+ id="path51543"
+ style="fill:url(#linearGradient288033);fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 180,7 v 2 1 1 c 0,1.107999 0.892,2 2,2 h 2 c 1.108,0 2,-0.892001 2,-2 V 9 c 0,-1.1079989 -0.892,-2 -2,-2 h -1 -1 z" /><path
+ id="rect51469"
+ style="fill:url(#linearGradient288025);fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 172,7 v 2 1 1 c 0,1.107999 -0.892,2 -2,2 h -2 c -1.108,0 -2,-0.892001 -2,-2 V 9 c 0,-1.1079989 0.892,-2 2,-2 h 1 1 z" /><rect
+ style="fill:url(#linearGradient287143);fill-opacity:1;stroke-width:0.271456;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect50678"
+ width="19.999996"
+ height="16"
+ x="166"
+ y="10"
+ ry="3" /><path
+ id="rect51545"
+ style="fill:url(#linearGradient287171);fill-opacity:1;stroke-width:0.258767;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 167,24 c -0.27416,0 -0.53402,0.05531 -0.77148,0.154297 C 166.67906,25.23997 167.74758,26 169,26 h 14 c 1.25242,0 2.32094,-0.76003 2.77148,-1.845703 C 185.53402,24.055314 185.27416,24 185,24 Z" /><g
+ id="g51463"
+ clip-path="url(#clipPath51465-6-2-8-5-5-4-9-7)"
+ transform="translate(-12.385191,4.0000023)"><rect
+ style="fill:url(#linearGradient287189);fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect51033"
+ width="10.000002"
+ height="5.0000005"
+ x="183.38519"
+ y="17.999998" /><rect
+ style="fill:#4d3f33;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect51319"
+ width="6"
+ height="3"
+ x="185.38519"
+ y="16.999998"
+ ry="0.99999958" /></g><g
+ id="g52513"
+ clip-path="none"
+ transform="matrix(-1,0,0,1,352.38519,4.0000023)"><path
+ id="rect52365"
+ style="fill:#e9ecec;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 184.38519,13.999998 c 0.554,0 1,0.446 1,1 v 1 c 0,0.553999 -0.446,1 -1,1 h -2 v -3 z" /><path
+ id="path102360"
+ style="fill:#141519;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 180.38519,13.999998 c -0.554,0 -1,0.446 -1,1 v 1 c 0,0.553999 0.446,1 1,1 h 2 v -3 z" /></g><use
+ x="0"
+ y="0"
+ xlink:href="#g52513"
+ id="use55252"
+ transform="matrix(-1,0,0,1,352,0)" /><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-7-4"
+ width="24"
+ height="24"
+ x="164"
+ y="4" /></g></svg>
diff --git a/launcher/resources/multimc/scalable/instances/fox_legacy.svg b/launcher/resources/multimc/scalable/instances/fox_legacy.svg
new file mode 100644
index 00000000..fcf16b2f
--- /dev/null
+++ b/launcher/resources/multimc/scalable/instances/fox_legacy.svg
@@ -0,0 +1,290 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ id="svg8"
+ version="1.1"
+ viewBox="0 0 33.866666 33.866666"
+ height="128"
+ width="128">
+ <defs
+ id="defs2" />
+ <metadata
+ id="metadata5">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ transform="translate(0,-263.13334)"
+ id="layer1">
+ <path
+ id="rect4750"
+ d="m 4.233333,267.36667 v 6.35 6.35 3.175 3.175 3.175 3.175 h 25.4 v -3.175 -3.175 -3.175 -3.175 -6.35 -6.35 h -6.35 v 6.35 h -12.7 v -3.175 -3.175 z"
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#800000;stroke-width:0.79375;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
+ <g
+ id="g4748">
+ <rect
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#f9f4f4;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.19062567;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
+ id="rect4553"
+ width="6.3500032"
+ height="6.3499975"
+ x="4.233326"
+ y="267.36667" />
+ <rect
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#b48f83;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.59531283;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
+ id="rect4553-6-2"
+ width="3.1750014"
+ height="3.1749992"
+ x="7.4083276"
+ y="270.54166" />
+ <rect
+ y="267.36667"
+ x="23.283335"
+ height="6.3499975"
+ width="6.3500032"
+ id="rect4623"
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#f9f4f4;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.19062567;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
+ <rect
+ y="270.54166"
+ x="23.283335"
+ height="3.1749992"
+ width="3.1750014"
+ id="rect4627"
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#b48f83;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.59531283;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
+ <rect
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#e27c21;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.59531283;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
+ id="rect4672"
+ width="25.400013"
+ height="15.875009"
+ x="4.233326"
+ y="273.71667" />
+ <rect
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#cc6920;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.59531283;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
+ id="rect4629"
+ width="3.1750016"
+ height="6.3500032"
+ x="4.2333255"
+ y="273.71667" />
+ <rect
+ y="273.71667"
+ x="26.458338"
+ height="6.3500032"
+ width="3.1750016"
+ id="rect4631"
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#cc6920;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.59531283;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
+ <rect
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#e78f41;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.59531283;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
+ id="rect4636"
+ width="6.3500032"
+ height="3.1750016"
+ x="13.758331"
+ y="283.24167" />
+ <rect
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#b05122;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.59531283;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
+ id="rect4638"
+ width="3.1750016"
+ height="3.1750016"
+ x="4.2333255"
+ y="280.06668" />
+ <rect
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#cc6920;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.59531283;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
+ id="rect4640"
+ width="3.1750016"
+ height="3.1750016"
+ x="7.4083276"
+ y="280.06668" />
+ <rect
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#f9f4f4;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.84189939;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
+ id="rect4644"
+ width="6.3500028"
+ height="3.1750016"
+ x="4.233326"
+ y="283.24167" />
+ <rect
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#06040e;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.59531283;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
+ id="rect4642"
+ width="3.1750016"
+ height="3.1750016"
+ x="4.2333255"
+ y="283.24167" />
+ <rect
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#f9f4f4;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.84189939;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
+ id="rect4646"
+ width="6.3500028"
+ height="3.1750016"
+ x="23.283337"
+ y="283.24167" />
+ <rect
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#06040e;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.59531283;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
+ id="rect4648"
+ width="3.1750016"
+ height="3.1750016"
+ x="26.45834"
+ y="283.24167" />
+ <rect
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#cc6920;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.59531283;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
+ id="rect4650"
+ width="3.1750016"
+ height="3.1750016"
+ x="23.283337"
+ y="280.06668" />
+ <rect
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#b05122;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.59531283;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
+ id="rect4652"
+ width="3.1750016"
+ height="3.1750016"
+ x="26.45834"
+ y="280.06668" />
+ <rect
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#cc6920;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.59531283;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
+ id="rect4654"
+ width="25.400013"
+ height="3.1750016"
+ x="4.2333255"
+ y="286.41666" />
+ <rect
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#e7d9d3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.59531283;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
+ id="rect4656"
+ width="25.400013"
+ height="3.1750016"
+ x="4.2333255"
+ y="289.59167" />
+ <rect
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.25;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.5612604;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
+ id="rect4917"
+ width="25.4"
+ height="0.26457807"
+ x="4.2333331"
+ y="273.71667" />
+ <rect
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.25;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.48607069;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
+ id="rect4921"
+ width="0.2645835"
+ height="19.049997"
+ x="4.2333331"
+ y="273.71667" />
+ <rect
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#f9f4f4;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.19062555;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
+ id="rect4658"
+ width="12.700007"
+ height="6.3500013"
+ x="10.583333"
+ y="286.41666" />
+ <rect
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#06040e;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.19062555;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
+ id="rect4660"
+ width="6.3500037"
+ height="3.1750007"
+ x="13.758333"
+ y="286.41669" />
+ <rect
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#e7d9d3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.19062555;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
+ id="rect4662"
+ width="3.1750019"
+ height="3.1750007"
+ x="10.583333"
+ y="286.41669" />
+ <rect
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#e7d9d3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.19062555;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
+ id="rect4664"
+ width="3.1750019"
+ height="3.1750007"
+ x="20.108334"
+ y="286.41669" />
+ <rect
+ y="286.41669"
+ x="10.583333"
+ height="6.3499832"
+ width="0.2645835"
+ id="rect4923"
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.25;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2806327;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
+ <rect
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.25;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.39686465;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
+ id="rect4951"
+ width="12.699996"
+ height="0.26456967"
+ x="10.583333"
+ y="286.41669" />
+ <rect
+ y="273.71667"
+ x="29.36875"
+ height="19.049982"
+ width="0.26458356"
+ id="rect4953"
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.48607057;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
+ <rect
+ y="292.50208"
+ x="23.283333"
+ height="0.26457682"
+ width="6.3499994"
+ id="rect4957"
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.28062955;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
+ <rect
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2806325;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
+ id="rect4959"
+ width="0.2645838"
+ height="6.3499656"
+ x="23.018749"
+ y="286.41669" />
+ <rect
+ y="292.50208"
+ x="4.2333331"
+ height="0.26457968"
+ width="6.3499999"
+ id="rect4961"
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.28063107;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
+ <rect
+ y="267.36667"
+ x="4.2333331"
+ height="6.3499956"
+ width="0.2645835"
+ id="rect4963"
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.25;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.28063297;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
+ <rect
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.25;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.28063536;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
+ id="rect4965"
+ width="6.349998"
+ height="0.26458791"
+ x="4.2333331"
+ y="267.36667" />
+ <rect
+ y="267.36667"
+ x="23.283333"
+ height="6.3499956"
+ width="0.2645835"
+ id="rect4963-9"
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.25;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.280633;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
+ <rect
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.25;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.28063536;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
+ id="rect4965-1"
+ width="6.349998"
+ height="0.26458791"
+ x="23.283333"
+ y="267.36667" />
+ <rect
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.28063306;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
+ id="rect4985"
+ width="0.26458356"
+ height="6.3499975"
+ x="29.36875"
+ y="267.36667" />
+ <rect
+ y="267.36667"
+ x="10.318749"
+ height="6.3499975"
+ width="0.26458356"
+ id="rect4987"
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.28063306;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
+ </g>
+ </g>
+</svg>
diff --git a/launcher/resources/multimc/scalable/instances/ftb_logo.svg b/launcher/resources/multimc/scalable/instances/ftb_logo.svg
new file mode 100644
index 00000000..85e8295e
--- /dev/null
+++ b/launcher/resources/multimc/scalable/instances/ftb_logo.svg
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="24"
+ height="24"
+ version="1.1"
+ viewBox="0 0 24 24"
+ id="svg168"
+ xml:space="preserve"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"><defs
+ id="defs172"><linearGradient
+ xlink:href="#linearGradient12453"
+ id="linearGradient12455"
+ x1="352.5"
+ y1="26.5"
+ x2="352.5"
+ y2="13"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.66666666,0,0,0.66666666,111,4.3333334)" /><linearGradient
+ id="linearGradient12453"><stop
+ style="stop-color:#b11917;stop-opacity:1;"
+ offset="0"
+ id="stop12449" /><stop
+ style="stop-color:#e65014;stop-opacity:1;"
+ offset="1"
+ id="stop12451" /></linearGradient><linearGradient
+ xlink:href="#linearGradient12299"
+ id="linearGradient12301"
+ x1="323"
+ y1="26.5"
+ x2="323"
+ y2="16"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.66666666,0,0,0.66666666,111.66666,4.3333334)" /><linearGradient
+ id="linearGradient12299"><stop
+ style="stop-color:#0787c1;stop-opacity:1;"
+ offset="0"
+ id="stop12295" /><stop
+ style="stop-color:#65adb9;stop-opacity:1;"
+ offset="1"
+ id="stop12297" /></linearGradient><linearGradient
+ xlink:href="#linearGradient12445"
+ id="linearGradient12447"
+ x1="333"
+ y1="26.000002"
+ x2="333"
+ y2="15.500002"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.66666666,0,0,0.66666666,111,4.6666654)" /><linearGradient
+ id="linearGradient12445"><stop
+ style="stop-color:#798b2f;stop-opacity:1;"
+ offset="0"
+ id="stop12441" /><stop
+ style="stop-color:#9fc41e;stop-opacity:1;"
+ offset="1"
+ id="stop12443" /></linearGradient></defs><title
+ id="title132">Prism Launcher Logo</title><metadata
+ id="metadata166"><rdf:RDF><cc:Work
+ rdf:about=""><dc:title>Prism Launcher Logo</dc:title><dc:date>19/10/2022</dc:date><dc:creator><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:creator><dc:contributor><cc:Agent><dc:title>AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke</dc:title></cc:Agent></dc:contributor><dc:source>https://github.com/PrismLauncher/PrismLauncher</dc:source><dc:rights><cc:Agent><dc:title>CC BY-SA 4.0</dc:title></cc:Agent></dc:rights><dc:publisher><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:publisher></cc:Work></rdf:RDF></metadata><g
+ id="i_ftb_logo"
+ transform="translate(-324,-4)"><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-8-2"
+ width="24"
+ height="24"
+ x="324"
+ y="4" /><path
+ id="path15348-5"
+ style="fill:url(#linearGradient12455);fill-opacity:1;stroke:none;stroke-width:0.869508;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 339,11 v 2 7.666666 c 0,0.736383 0.59696,1.333338 1.33334,1.333334 H 345 v -4.333332 c -1.5e-4,-0.671316 -0.3371,-1.297777 -0.89712,-1.667968 0.55925,-0.369682 0.89609,-0.994972 0.89712,-1.665366 v -2 C 345,11.596959 344.40305,11.000007 343.66668,11 Z m 2,2 h 2 v 2 h -2 z m 0,4 h 2 v 3 h -2 z" /><path
+ id="path15342-4"
+ style="fill:url(#linearGradient12301);fill-opacity:1;stroke:none;stroke-width:0.869508;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 327,11 c -0.73638,-4e-6 -1.33334,0.596951 -1.33334,1.333334 V 22 h 2 V 17 H 330 v -2 h -2.33334 V 13 H 331 v -2 z" /><path
+ style="fill:url(#linearGradient12447);fill-opacity:1;stroke:none;stroke-width:0.869508;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 332,11 v 2 h 2 V 20.394205 22 h 2 v -9 h 2 v -2 z"
+ id="rect10933-8" /></g></svg>
diff --git a/launcher/resources/multimc/scalable/instances/gear.svg b/launcher/resources/multimc/scalable/instances/gear.svg
new file mode 100644
index 00000000..b2923d67
--- /dev/null
+++ b/launcher/resources/multimc/scalable/instances/gear.svg
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="24"
+ height="24"
+ version="1.1"
+ viewBox="0 0 24 24"
+ id="svg168"
+ xml:space="preserve"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"><defs
+ id="defs172"><radialGradient
+ xlink:href="#linearGradient21157"
+ id="radialGradient21159"
+ cx="368"
+ cy="16"
+ fx="368"
+ fy="16"
+ r="7"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ id="linearGradient21157"><stop
+ style="stop-color:#e1edf2;stop-opacity:1;"
+ offset="0"
+ id="stop21153" /><stop
+ style="stop-color:#abbdc4;stop-opacity:1;"
+ offset="0.72112602"
+ id="stop21161" /><stop
+ style="stop-color:#95acb6;stop-opacity:1;"
+ offset="1"
+ id="stop21155" /></linearGradient><radialGradient
+ xlink:href="#linearGradient21167"
+ id="radialGradient21309"
+ gradientUnits="userSpaceOnUse"
+ cx="400"
+ cy="16"
+ fx="400"
+ fy="16"
+ r="11"
+ gradientTransform="matrix(1.3636364,0,0,1.3636364,-177.45455,-5.8181818)" /><linearGradient
+ id="linearGradient21167"><stop
+ style="stop-color:#e5e6e9;stop-opacity:1;"
+ offset="0.13595749"
+ id="stop21163" /><stop
+ style="stop-color:#c5c7cf;stop-opacity:1;"
+ offset="0.86267382"
+ id="stop21165" /></linearGradient></defs><title
+ id="title132">Prism Launcher Logo</title><metadata
+ id="metadata166"><rdf:RDF><cc:Work
+ rdf:about=""><dc:title>Prism Launcher Logo</dc:title><dc:date>19/10/2022</dc:date><dc:creator><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:creator><dc:contributor><cc:Agent><dc:title>AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke</dc:title></cc:Agent></dc:contributor><dc:source>https://github.com/PrismLauncher/PrismLauncher</dc:source><dc:rights><cc:Agent><dc:title>CC BY-SA 4.0</dc:title></cc:Agent></dc:rights><dc:publisher><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:publisher></cc:Work></rdf:RDF></metadata><g
+ id="i_gear"
+ transform="translate(-356,-4)"><path
+ id="path26489"
+ style="opacity:1;fill:url(#radialGradient21159);fill-opacity:1;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 368,9 c -3.86599,0 -7,3.134007 -7,7 0,3.865993 3.13401,7 7,7 3.86599,0 7,-3.134007 7,-7 0,-3.865993 -3.13401,-7 -7,-7 z m 0,5 c 1.10456,0 2,0.89543 2,2 0,1.10457 -0.89544,2 -2,2 -1.10456,0 -2,-0.89543 -2,-2 0,-1.10457 0.89544,-2 2,-2 z" /><path
+ id="path23199"
+ style="fill:url(#radialGradient21309);fill-opacity:1;stroke:none;stroke-width:0.148828;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 366,5 v 2.2265625 c -1.00464,0.2280151 -1.94322,0.6232232 -2.78906,1.15625 l -1.57422,-1.5742187 -2.82813,2.828125 1.57422,1.5742192 C 359.84979,12.056778 359.45458,12.995357 359.22656,14 H 357 v 4 h 2.22656 c 0.22802,1.004643 0.62323,1.943222 1.15625,2.789062 l -1.57422,1.574219 2.82813,2.830078 1.57422,-1.576171 c 0.84584,0.533026 1.78442,0.928234 2.78906,1.15625 V 27 h 4 v -2.226562 c 1.00464,-0.228016 1.94322,-0.623224 2.78906,-1.15625 l 1.57422,1.576171 2.83008,-2.830078 -1.57617,-1.574219 C 376.15021,19.943222 376.54542,19.004643 376.77344,18 H 379 v -4 h -2.22656 c -0.22802,-1.004643 -0.62323,-1.943222 -1.15625,-2.789062 l 1.57617,-1.5742192 -2.83008,-2.828125 -1.57422,1.5742187 C 371.94322,7.8497857 371.00464,7.4545776 370,7.2265625 V 5 Z m 2,5 c 3.31371,0 6,2.686295 6,6 0,3.313705 -2.68629,6 -6,6 -3.31371,0 -6,-2.686295 -6,-6 0,-3.313705 2.68629,-6 6,-6 z" /><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-7-6-0"
+ width="24"
+ height="24"
+ x="356"
+ y="4" /></g></svg>
diff --git a/launcher/resources/multimc/scalable/instances/gold.svg b/launcher/resources/multimc/scalable/instances/gold.svg
new file mode 100644
index 00000000..f1513d70
--- /dev/null
+++ b/launcher/resources/multimc/scalable/instances/gold.svg
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="24"
+ height="24"
+ version="1.1"
+ viewBox="0 0 24 24"
+ id="svg168"
+ xml:space="preserve"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"><defs
+ id="defs172"><linearGradient
+ id="linearGradient48524"><stop
+ style="stop-color:#dfcd64;stop-opacity:1;"
+ offset="0"
+ id="stop48516" /><stop
+ style="stop-color:#d6b917;stop-opacity:1;"
+ offset="0.11879402"
+ id="stop48518" /><stop
+ style="stop-color:#f6e689;stop-opacity:1;"
+ offset="0.71356344"
+ id="stop48520" /><stop
+ style="stop-color:#d4bb2b;stop-opacity:1;"
+ offset="1"
+ id="stop48522" /></linearGradient><linearGradient
+ xlink:href="#linearGradient48524"
+ id="linearGradient48512"
+ gradientUnits="userSpaceOnUse"
+ x1="153"
+ y1="25"
+ x2="135"
+ y2="7"
+ gradientTransform="translate(256)" /></defs><title
+ id="title132">Prism Launcher Logo</title><metadata
+ id="metadata166"><rdf:RDF><cc:Work
+ rdf:about=""><dc:title>Prism Launcher Logo</dc:title><dc:date>19/10/2022</dc:date><dc:creator><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:creator><dc:contributor><cc:Agent><dc:title>AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke</dc:title></cc:Agent></dc:contributor><dc:source>https://github.com/PrismLauncher/PrismLauncher</dc:source><dc:rights><cc:Agent><dc:title>CC BY-SA 4.0</dc:title></cc:Agent></dc:rights><dc:publisher><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:publisher></cc:Work></rdf:RDF></metadata><g
+ id="i_gold"
+ transform="translate(-388,-4)"><rect
+ style="fill:#d7bc21;fill-opacity:1;stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect15088-8"
+ width="20"
+ height="20"
+ x="390"
+ y="6"
+ ry="3" /><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-88-6"
+ width="24"
+ height="24"
+ x="388"
+ y="4" /><rect
+ style="fill:url(#linearGradient48512);fill-opacity:1;stroke:none;stroke-width:1;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect40970-3"
+ width="18"
+ height="18"
+ x="391"
+ y="7"
+ ry="2" /></g></svg>
diff --git a/launcher/resources/multimc/scalable/instances/grass.svg b/launcher/resources/multimc/scalable/instances/grass.svg
new file mode 100644
index 00000000..cd29fd83
--- /dev/null
+++ b/launcher/resources/multimc/scalable/instances/grass.svg
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="24"
+ height="24"
+ version="1.1"
+ viewBox="0 0 24 24"
+ id="svg168"
+ xml:space="preserve"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"><defs
+ id="defs172"><linearGradient
+ id="linearGradient53203"><stop
+ style="stop-color:#77563b;stop-opacity:1;"
+ offset="0"
+ id="stop53199" /><stop
+ style="stop-color:#86674f;stop-opacity:1;"
+ offset="1"
+ id="stop53201" /></linearGradient><linearGradient
+ id="linearGradient29505"><stop
+ style="stop-color:#99cd61;stop-opacity:1;"
+ offset="0"
+ id="stop29501" /><stop
+ style="stop-color:#bccd61;stop-opacity:1;"
+ offset="1"
+ id="stop29503" /></linearGradient><linearGradient
+ xlink:href="#linearGradient53203"
+ id="linearGradient56913"
+ gradientUnits="userSpaceOnUse"
+ x1="785"
+ y1="26"
+ x2="785"
+ y2="6"
+ gradientTransform="translate(-352)" /><linearGradient
+ xlink:href="#linearGradient56992"
+ id="linearGradient56984"
+ x1="433"
+ y1="11"
+ x2="433"
+ y2="20"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ id="linearGradient56992"><stop
+ style="stop-color:#4d3f33;stop-opacity:0.5;"
+ offset="0"
+ id="stop56986" /><stop
+ style="stop-color:#4d3f33;stop-opacity:0;"
+ offset="1"
+ id="stop56990" /></linearGradient><linearGradient
+ xlink:href="#linearGradient29505"
+ id="linearGradient29507"
+ x1="428"
+ y1="14"
+ x2="428"
+ y2="4"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(2,2)" /></defs><title
+ id="title132">Prism Launcher Logo</title><metadata
+ id="metadata166"><rdf:RDF><cc:Work
+ rdf:about=""><dc:title>Prism Launcher Logo</dc:title><dc:date>19/10/2022</dc:date><dc:creator><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:creator><dc:contributor><cc:Agent><dc:title>AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke</dc:title></cc:Agent></dc:contributor><dc:source>https://github.com/PrismLauncher/PrismLauncher</dc:source><dc:rights><cc:Agent><dc:title>CC BY-SA 4.0</dc:title></cc:Agent></dc:rights><dc:publisher><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:publisher></cc:Work></rdf:RDF></metadata><g
+ id="i_grass"
+ transform="translate(-420,-4)"><path
+ id="rect15088-9-1-7"
+ style="fill:url(#linearGradient56913);stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 425,8 h 14 l 3,1 v 14 c 0,1.662 -1.338,3 -3,3 h -14 c -1.662,0 -3,-1.338 -3,-3 V 9 Z" /><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-7-4-8"
+ width="24"
+ height="24"
+ x="420"
+ y="4" /><path
+ id="rect48773-2"
+ style="opacity:0.268946;fill:#a88356;fill-opacity:1;stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ d="M 424.13672,8 C 424.05936,8.00781 424,8.07286 424,8.15234 V 9.84766 C 424,9.93244 424.06756,10 424.15234,10 h 1.69532 C 425.93244,10 426,9.93244 426,9.84766 V 8.15234 C 426,8.06756 425.93244,8 425.84766,8 h -1.69532 c -0.005,0 -0.0105,-5.2e-4 -0.0156,0 z m 10,2 C 434.05936,10.00781 434,10.07286 434,10.15234 v 1.69532 C 434,11.93244 434.06756,12 434.15234,12 h 1.69532 C 435.93244,12 436,11.93244 436,11.84766 V 10.15234 C 436,10.06756 435.93244,10 435.84766,10 h -1.69532 c -0.005,0 -0.0105,-5.2e-4 -0.0156,0 z m -8,4 C 426.05936,14.00781 426,14.07286 426,14.15234 v 1.69532 C 426,15.93244 426.06756,16 426.15234,16 h 1.69532 C 427.93244,16 428,15.93244 428,15.84766 V 14.15234 C 428,14.06756 427.93244,14 427.84766,14 h -1.69532 c -0.005,0 -0.0105,-5.2e-4 -0.0156,0 z m 13,2 C 439.05936,16.00781 439,16.07286 439,16.15234 v 1.69532 C 439,17.93244 439.06756,18 439.15234,18 h 1.69532 C 440.93244,18 441,17.93244 441,17.84766 V 16.15234 C 441,16.06756 440.93244,16 440.84766,16 h -1.69532 c -0.005,0 -0.0105,-5.2e-4 -0.0156,0 z m -7,2 C 432.05936,18.00781 432,18.07286 432,18.15234 v 1.69532 C 432,19.93244 432.06756,20 432.15234,20 h 1.69532 C 433.93244,20 434,19.93244 434,19.84766 V 18.15234 C 434,18.06756 433.93244,18 433.84766,18 h -1.69532 c -0.005,0 -0.0105,-5.2e-4 -0.0156,0 z m -9,2 C 423.05936,20.00781 423,20.07286 423,20.15234 v 1.69532 C 423,21.93244 423.06756,22 423.15234,22 h 1.69532 C 424.93244,22 425,21.93244 425,21.84766 V 20.15234 C 425,20.06756 424.93244,20 424.84766,20 h -1.69532 c -0.005,0 -0.0105,-5.2e-4 -0.0156,0 z m 15,2 C 438.05936,22.00781 438,22.07286 438,22.15234 v 1.69532 C 438,23.93244 438.06756,24 438.15234,24 h 1.69532 C 439.93244,24 440,23.93244 440,23.84766 V 22.15234 C 440,22.06756 439.93244,22 439.84766,22 h -1.69532 c -0.005,0 -0.0105,-5.2e-4 -0.0156,0 z m -9,2 C 429.05936,24.00781 429,24.07286 429,24.15234 v 1.69532 C 429,25.93244 429.06756,26 429.15234,26 h 1.69532 C 430.93244,26 431,25.93244 431,25.84766 V 24.15234 C 431,24.06756 430.93244,24 430.84766,24 h -1.69532 c -0.005,0 -0.0105,-5.2e-4 -0.0156,0 z" /><path
+ id="rect56976"
+ style="fill:url(#linearGradient56984);stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 425,8 h 7 7 l 3,1 v 14 l -3,3 h -14 l -3,-3 V 9 Z" /><path
+ id="rect24023"
+ style="fill:url(#linearGradient29507);fill-opacity:1;stroke:none;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 425,6 c -1.662,0 -3,1.3380037 -3,3 v 3 2 h 2 v -2 h 2 v 2 h 4 v 2 h 2 v -2 -2 -2 h 2 v 2 2 h 2 v -2 h 2 v 2 2 h 2 v -2 h 2 V 9 c 0,-1.6619983 -1.338,-3 -3,-3 h -7 z" /></g></svg>
diff --git a/launcher/resources/multimc/scalable/instances/herobrine.svg b/launcher/resources/multimc/scalable/instances/herobrine.svg
new file mode 100644
index 00000000..24f4d2c9
--- /dev/null
+++ b/launcher/resources/multimc/scalable/instances/herobrine.svg
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="24"
+ height="24"
+ version="1.1"
+ viewBox="0 0 24 24"
+ id="svg168"
+ xml:space="preserve"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"><defs
+ id="defs172"><linearGradient
+ id="linearGradient2085"><stop
+ style="stop-color:#261a0a;stop-opacity:1;"
+ offset="0"
+ id="stop2081" /><stop
+ style="stop-color:#3c2b13;stop-opacity:1;"
+ offset="1"
+ id="stop2083" /></linearGradient><radialGradient
+ xlink:href="#linearGradient2066"
+ id="radialGradient2757-3"
+ cx="496.06177"
+ cy="17.211182"
+ fx="495.87827"
+ fy="18.730774"
+ r="11"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.5554022,0,0,1.2337313,-807.57556,-8.2669434)" /><linearGradient
+ id="linearGradient2066"><stop
+ style="stop-color:#ceb8aa;stop-opacity:1;"
+ offset="0.23876573"
+ id="stop2062" /><stop
+ style="stop-color:#b39888;stop-opacity:1;"
+ offset="0.51858544"
+ id="stop2064" /></linearGradient><linearGradient
+ xlink:href="#linearGradient2085"
+ id="linearGradient94741"
+ gradientUnits="userSpaceOnUse"
+ x1="504"
+ y1="15"
+ x2="504"
+ y2="5"
+ gradientTransform="translate(-36,-4)" /><linearGradient
+ xlink:href="#linearGradient2564"
+ id="linearGradient2566"
+ x1="466"
+ y1="27"
+ x2="466"
+ y2="22"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-4,-4)" /><linearGradient
+ id="linearGradient2564"><stop
+ style="stop-color:#45362e;stop-opacity:1;"
+ offset="0"
+ id="stop2560" /><stop
+ style="stop-color:#59463c;stop-opacity:1;"
+ offset="1"
+ id="stop2562" /></linearGradient></defs><title
+ id="title132">Prism Launcher Logo</title><metadata
+ id="metadata166"><rdf:RDF><cc:Work
+ rdf:about=""><dc:title>Prism Launcher Logo</dc:title><dc:date>19/10/2022</dc:date><dc:creator><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:creator><dc:contributor><cc:Agent><dc:title>AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke</dc:title></cc:Agent></dc:contributor><dc:source>https://github.com/PrismLauncher/PrismLauncher</dc:source><dc:rights><cc:Agent><dc:title>CC BY-SA 4.0</dc:title></cc:Agent></dc:rights><dc:publisher><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:publisher></cc:Work></rdf:RDF></metadata><g
+ id="i_herobrine"
+ transform="translate(-448)"><path
+ id="rect56542-7-5"
+ style="fill:url(#radialGradient2757-3);stroke-width:0.277182;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 452,1 h 16 l 3,2.999999 V 20.000001 C 471,21.662 469.662,23 468,23 h -16 c -1.662,0 -3,-1.338 -3,-2.999999 V 3.999999 Z" /><path
+ id="rect56552"
+ style="fill:url(#linearGradient94741);fill-opacity:1;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 452,1 c -1.662,0 -3,1.3380017 -3,3 v 7 h 2 c 1.108,0 2,-0.892002 2,-2 V 8 h 14 v 1 c 0,1.107998 0.892,2 2,2 h 2 V 4 c 0,-1.6619983 -1.338,-3 -3,-3 h -1 -14 z" /><rect
+ style="opacity:1;fill:#8a5d54;fill-opacity:1;stroke:none;stroke-width:0.396874;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect53396"
+ width="6"
+ height="3"
+ x="457"
+ y="18"
+ ry="0" /><rect
+ style="fill:#ffffff;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect63182-8-0"
+ width="7"
+ height="3"
+ x="462"
+ y="13"
+ ry="1" /><rect
+ style="fill:#ffffff;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect63184-7-9"
+ width="7"
+ height="3"
+ x="451"
+ y="13"
+ ry="1" /><rect
+ style="opacity:1;fill:#6a493c;fill-opacity:1;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect50123"
+ width="4"
+ height="2"
+ x="458"
+ y="16"
+ ry="0" /><path
+ id="path195645-9"
+ style="fill:url(#linearGradient2566);fill-opacity:1;stroke:none;stroke-width:0.362295;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 457,18 a 2,2 0 0 0 -2,2 v 3 h 3 4 3 v -3 a 2,2 0 0 0 -2,-2 h -1 v 2 h -4 v -2 z" /><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-8-3-9"
+ width="24"
+ height="24"
+ x="448"
+ y="0" /></g></svg>
diff --git a/launcher/resources/multimc/scalable/instances/iron.svg b/launcher/resources/multimc/scalable/instances/iron.svg
new file mode 100644
index 00000000..6a6faf77
--- /dev/null
+++ b/launcher/resources/multimc/scalable/instances/iron.svg
@@ -0,0 +1,178 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="24"
+ height="24"
+ version="1.1"
+ viewBox="0 0 24 24"
+ id="svg168"
+ xml:space="preserve"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"><defs
+ id="defs172"><linearGradient
+ id="linearGradient27992"><stop
+ style="stop-color:#c5c7cf;stop-opacity:1;"
+ offset="0"
+ id="stop27990" /><stop
+ style="stop-color:#d8d9e0;stop-opacity:1;"
+ offset="1"
+ id="stop27988" /></linearGradient><linearGradient
+ id="linearGradient56358"><stop
+ style="stop-color:#ededed;stop-opacity:1;"
+ offset="0"
+ id="stop56354" /><stop
+ style="stop-color:#f4f4f4;stop-opacity:1;"
+ offset="1"
+ id="stop56356" /></linearGradient><linearGradient
+ xlink:href="#linearGradient27992"
+ id="linearGradient17901"
+ x1="496"
+ y1="26"
+ x2="496"
+ y2="6"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ xlink:href="#linearGradient56358"
+ id="linearGradient18032"
+ gradientUnits="userSpaceOnUse"
+ x1="503"
+ y1="25"
+ x2="503"
+ y2="23"
+ gradientTransform="translate(0,-4)" /><linearGradient
+ xlink:href="#linearGradient56358"
+ id="linearGradient18124"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-8)"
+ x1="503"
+ y1="25"
+ x2="503"
+ y2="23" /><linearGradient
+ xlink:href="#linearGradient18539"
+ id="linearGradient18530"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-6)"
+ x1="503"
+ y1="25"
+ x2="503"
+ y2="23" /><linearGradient
+ id="linearGradient18539"><stop
+ style="stop-color:#27414e;stop-opacity:0;"
+ offset="0"
+ id="stop18537" /><stop
+ style="stop-color:#27414e;stop-opacity:0.74901961;"
+ offset="0.49837714"
+ id="stop18535" /><stop
+ style="stop-color:#27414e;stop-opacity:1;"
+ offset="0.83958842"
+ id="stop18533" /></linearGradient><linearGradient
+ xlink:href="#linearGradient18539"
+ id="linearGradient18590"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-10)"
+ x1="503"
+ y1="25"
+ x2="503"
+ y2="23" /><linearGradient
+ xlink:href="#linearGradient18539"
+ id="linearGradient18615"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-14)"
+ x1="503"
+ y1="25"
+ x2="503"
+ y2="23" /><linearGradient
+ xlink:href="#linearGradient18539"
+ id="linearGradient18640"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-2)"
+ x1="503"
+ y1="25"
+ x2="503"
+ y2="23" /><linearGradient
+ xlink:href="#linearGradient56358"
+ id="linearGradient18124-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-12)"
+ x1="503"
+ y1="25"
+ x2="503"
+ y2="23" /><linearGradient
+ xlink:href="#linearGradient56358"
+ id="linearGradient18124-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-16)"
+ x1="503"
+ y1="25"
+ x2="503"
+ y2="23" /></defs><title
+ id="title132">Prism Launcher Logo</title><metadata
+ id="metadata166"><rdf:RDF><cc:Work
+ rdf:about=""><dc:title>Prism Launcher Logo</dc:title><dc:date>19/10/2022</dc:date><dc:creator><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:creator><dc:contributor><cc:Agent><dc:title>AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke</dc:title></cc:Agent></dc:contributor><dc:source>https://github.com/PrismLauncher/PrismLauncher</dc:source><dc:rights><cc:Agent><dc:title>CC BY-SA 4.0</dc:title></cc:Agent></dc:rights><dc:publisher><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:publisher></cc:Work></rdf:RDF></metadata><g
+ id="i_iron"
+ transform="translate(-484,-4)"><rect
+ style="fill:url(#linearGradient17901);fill-opacity:1;stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect15088"
+ width="20"
+ height="20"
+ x="486"
+ y="6"
+ ry="3" /><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-7-6-1-2"
+ width="24"
+ height="24"
+ x="484"
+ y="4" /><path
+ id="rect17965"
+ style="fill:#efefef;fill-opacity:1;stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 487,23 c 0,1.107999 0.892,2 2,2 h 14 c 1.108,0 2,-0.892001 2,-2 z" /><rect
+ style="fill:url(#linearGradient18032);fill-opacity:1;stroke-width:0.999996;stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect15357-7-8"
+ width="18"
+ height="2"
+ x="487"
+ y="19" /><rect
+ style="fill:url(#linearGradient18124);fill-opacity:1;stroke-width:0.999996;stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect15357-7-8-4"
+ width="18"
+ height="2"
+ x="487"
+ y="15" /><rect
+ style="opacity:0.1;fill:url(#linearGradient18530);fill-opacity:1;stroke-width:0.999996;stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect15357-7-8-4-7"
+ width="18"
+ height="2"
+ x="487"
+ y="17" /><rect
+ style="opacity:0.1;fill:url(#linearGradient18590);fill-opacity:1;stroke-width:0.999996;stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect15357-7-8-4-7-5"
+ width="18"
+ height="2"
+ x="487"
+ y="13" /><rect
+ style="opacity:0.1;fill:url(#linearGradient18615);fill-opacity:1;stroke-width:0.999996;stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect15357-7-8-4-7-6"
+ width="18"
+ height="2"
+ x="487"
+ y="9" /><rect
+ style="opacity:0.1;fill:url(#linearGradient18640);fill-opacity:1;stroke-width:0.999996;stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect15357-7-8-4-7-56"
+ width="18"
+ height="2"
+ x="487"
+ y="21" /><rect
+ style="fill:url(#linearGradient18124-2);fill-opacity:1;stroke-width:0.999996;stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect15357-7-8-4-1"
+ width="18"
+ height="2"
+ x="487"
+ y="11" /><path
+ id="rect15357-7-8-4-5"
+ style="fill:url(#linearGradient18124-0);fill-opacity:1;stroke-width:0.999996;stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 489,7 c -1.108,0 -2,0.8920011 -2,2 h 18 c 0,-1.1079989 -0.892,-2 -2,-2 z" /></g></svg>
diff --git a/launcher/resources/multimc/scalable/instances/magitech.svg b/launcher/resources/multimc/scalable/instances/magitech.svg
new file mode 100644
index 00000000..57ef6df1
--- /dev/null
+++ b/launcher/resources/multimc/scalable/instances/magitech.svg
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="24"
+ height="24"
+ version="1.1"
+ viewBox="0 0 24 24"
+ id="svg168"
+ xml:space="preserve"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"><defs
+ id="defs172"><radialGradient
+ xlink:href="#linearGradient16441"
+ id="radialGradient16443"
+ cx="559.9212"
+ cy="16.022875"
+ fx="559.9212"
+ fy="16.022875"
+ r="11.80246"
+ gradientTransform="matrix(1,0,0,1.0119015,0,-0.19069696)"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ id="linearGradient16441"><stop
+ style="stop-color:#9f0bff;stop-opacity:1;"
+ offset="0.4400529"
+ id="stop16439" /><stop
+ style="stop-color:#7111f8;stop-opacity:1;"
+ offset="1"
+ id="stop16437" /></linearGradient><radialGradient
+ xlink:href="#linearGradient14255"
+ id="radialGradient14257"
+ cx="560"
+ cy="16"
+ fx="560"
+ fy="16"
+ r="9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.91538385,0,0,0.91538385,15.375434,1.3532593)" /><linearGradient
+ id="linearGradient14255"><stop
+ style="stop-color:#e570f7;stop-opacity:1;"
+ offset="0"
+ id="stop14251" /><stop
+ style="stop-color:#d829c8;stop-opacity:1;"
+ offset="1"
+ id="stop14253" /></linearGradient><linearGradient
+ xlink:href="#linearGradient16452"
+ id="linearGradient16454"
+ x1="560"
+ y1="25"
+ x2="560"
+ y2="11"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-32)" /><linearGradient
+ id="linearGradient16452"><stop
+ style="stop-color:#f6cff4;stop-opacity:1;"
+ offset="0"
+ id="stop16450" /><stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop16448" /></linearGradient></defs><title
+ id="title132">Prism Launcher Logo</title><metadata
+ id="metadata166"><rdf:RDF><cc:Work
+ rdf:about=""><dc:title>Prism Launcher Logo</dc:title><dc:date>19/10/2022</dc:date><dc:creator><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:creator><dc:contributor><cc:Agent><dc:title>AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke</dc:title></cc:Agent></dc:contributor><dc:source>https://github.com/PrismLauncher/PrismLauncher</dc:source><dc:rights><cc:Agent><dc:title>CC BY-SA 4.0</dc:title></cc:Agent></dc:rights><dc:publisher><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:publisher></cc:Work></rdf:RDF></metadata><g
+ id="i_magitech"
+ transform="translate(-516,-4)"><path
+ style="opacity:1;fill:url(#radialGradient16443);fill-opacity:1;stroke:none;stroke-width:0.328827;paint-order:stroke markers fill;stop-color:#000000"
+ id="path63885"
+ d="m 567.75822,23.780557 c -1.02129,1.017197 -1.40469,3.26498 -2.72399,3.814557 -1.3193,0.549578 -3.76804,-0.657585 -5.20836,-0.687167 -1.44032,-0.02958 -3.32578,1.488919 -4.65697,0.936933 -1.33119,-0.551986 -2.06769,-2.91036 -3.08281,-3.927341 -1.01511,-1.016982 -3.30517,-1.550442 -3.83572,-2.877061 -0.53055,-1.326619 0.75095,-3.615262 0.76004,-5.050859 0.009,-1.435596 -1.30602,-3.611418 -0.75806,-4.936294 0.54796,-1.3248769 2.7981,-1.6627753 3.83368,-2.6540083 1.03559,-0.9912328 1.77327,-3.6016077 3.08037,-4.1709394 1.3071,-0.5693318 3.41767,0.6823629 4.85198,0.6871672 1.43432,0.0048 3.67769,-1.1020263 5.01335,-0.5805511 1.33567,0.5214752 1.68844,2.9320874 2.72643,3.9273412 1.03799,0.9952536 3.30533,1.5532379 3.83572,2.8770604 0.53039,1.323824 -0.73478,3.255376 -0.76004,4.694477 -0.0253,1.439101 1.28343,3.594239 0.75806,4.936295 -0.52537,1.342056 -2.8124,1.993192 -3.83368,3.01039 z"
+ transform="matrix(0.77720995,0.20825278,-0.20825278,0.77720995,96.078534,-113.04768)" /><path
+ id="rect68163"
+ style="fill:url(#radialGradient14257);fill-opacity:1;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 528.64654,8.1238816 c -0.88525,-0.058796 -2.03882,1.1746971 -2.89455,1.4267114 -0.85572,0.2520155 -2.19516,-0.2057082 -2.87666,0.3700866 -0.68152,0.5757944 -0.57701,2.1554034 -0.99227,2.9463914 -0.41525,0.79099 -1.77713,1.689562 -1.86295,2.574518 -0.0858,0.884955 1.02746,1.834893 1.29799,2.687153 0.27054,0.85226 0.002,2.366339 0.58106,3.051875 0.57813,0.685534 2.05494,0.383747 2.84269,0.811687 0.78774,0.427941 1.79544,1.795111 2.68179,1.868314 0.88635,0.07321 1.74074,-1.059712 2.59597,-1.330167 0.85524,-0.270456 2.30644,0.02321 2.98037,-0.56854 0.67391,-0.591748 0.56704,-2.156299 0.99225,-2.944604 0.42521,-0.788304 1.67594,-1.494488 1.76105,-2.377852 0.0851,-0.883365 -1.0086,-1.840366 -1.29799,-2.687153 -0.2894,-0.846786 0.20315,-2.280018 -0.38618,-2.949967 -0.58933,-0.669948 -2.14415,-0.699521 -2.93567,-1.1120483 -0.7915,-0.4125278 -1.60167,-1.7076097 -2.4869,-1.7664051 z" /><path
+ id="rect67092"
+ style="fill:url(#linearGradient16454);fill-opacity:1;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ d="M 530,11.419922 V 15 l -2,1 -2,-1 v -3.576172 c -1.82001,0.79431 -2.99746,2.590392 -3,4.576172 0,2.049733 1.2349,3.810136 3,4.582031 v 2.435547 c 0.47576,0.420763 0.96578,0.80592 1.42383,0.84375 0.87952,0.07265 1.72754,-1.040827 2.57617,-1.322266 v -1.957031 c 1.7651,-0.771895 3,-2.532298 3,-4.582031 -9.9e-4,-1.987198 -1.1787,-3.785199 -3,-4.580078 z" /><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-0"
+ width="24"
+ height="24"
+ x="516"
+ y="4" /></g></svg>
diff --git a/launcher/resources/multimc/scalable/instances/meat.svg b/launcher/resources/multimc/scalable/instances/meat.svg
new file mode 100644
index 00000000..36f0551b
--- /dev/null
+++ b/launcher/resources/multimc/scalable/instances/meat.svg
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="24"
+ height="24"
+ version="1.1"
+ viewBox="0 0 24 24"
+ id="svg168"
+ xml:space="preserve"
+ sodipodi:docname="meat.svg"
+ inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"><sodipodi:namedview
+ id="namedview68946"
+ pagecolor="#ffffff"
+ bordercolor="#000000"
+ borderopacity="0.25"
+ inkscape:showpageshadow="2"
+ inkscape:pageopacity="0.0"
+ inkscape:pagecheckerboard="0"
+ inkscape:deskcolor="#d1d1d1"
+ showgrid="false"
+ inkscape:zoom="9.8333333"
+ inkscape:cx="12"
+ inkscape:cy="12"
+ inkscape:window-width="1366"
+ inkscape:window-height="699"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="i_meat" /><defs
+ id="defs172"><linearGradient
+ id="linearGradient6068"><stop
+ style="stop-color:#cdcdcd;stop-opacity:1;"
+ offset="0"
+ id="stop6064" /><stop
+ style="stop-color:#eeeeee;stop-opacity:1;"
+ offset="1"
+ id="stop6066" /></linearGradient><linearGradient
+ xlink:href="#linearGradient6068"
+ id="linearGradient39389"
+ x1="565"
+ y1="23"
+ x2="567"
+ y2="21"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ xlink:href="#linearGradient38100"
+ id="linearGradient38102"
+ x1="408.70773"
+ y1="-379.00925"
+ x2="408.70773"
+ y2="-389.8125"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ id="linearGradient38100"><stop
+ style="stop-color:#956c4a;stop-opacity:1;"
+ offset="0"
+ id="stop38096" /><stop
+ style="stop-color:#bb7c47;stop-opacity:1;"
+ offset="1"
+ id="stop38098" /></linearGradient><linearGradient
+ xlink:href="#linearGradient39375"
+ id="linearGradient39377"
+ x1="401.63666"
+ y1="-379.00925"
+ x2="401.63666"
+ y2="-389.8125"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ id="linearGradient39375"><stop
+ style="stop-color:#d15e65;stop-opacity:1;"
+ offset="0"
+ id="stop39371" /><stop
+ style="stop-color:#b2594e;stop-opacity:1;"
+ offset="1"
+ id="stop39373" /></linearGradient></defs><title
+ id="title132">Prism Launcher Logo</title><metadata
+ id="metadata166"><rdf:RDF><cc:Work
+ rdf:about=""><dc:title>Prism Launcher Logo</dc:title><dc:date>19/10/2022</dc:date><dc:creator><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:creator><dc:contributor><cc:Agent><dc:title>AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke</dc:title></cc:Agent></dc:contributor><dc:source>https://github.com/PrismLauncher/PrismLauncher</dc:source><dc:rights><cc:Agent><dc:title>CC BY-SA 4.0</dc:title></cc:Agent></dc:rights><dc:publisher><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:publisher></cc:Work></rdf:RDF></metadata><g
+ id="i_meat"
+ transform="translate(-548,-4)"><path
+ id="rect80640"
+ style="opacity:1;fill:url(#linearGradient39389);fill-opacity:1;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 568.48528,21.449747 a 1.5,1.5 0 0 0 -1.70424,-0.290027 l -2.18485,-2.184846 c -0.39173,-0.391738 -1.02247,-0.391737 -1.41421,0 l -0.70711,0.707106 c -0.39173,0.391737 -0.39173,1.022477 0,1.414214 l 2.18485,2.184847 a 1.5,1.5 0 0 0 0.29003,1.70424 1.5,1.5 0 0 0 2.12132,0 1.5,1.5 0 0 0 0.4378,-0.979175 1.5,1.5 0 0 0 0.97641,-0.435038 1.5,1.5 0 0 0 0,-2.121321 z" /><rect
+ style="opacity:1;fill:url(#linearGradient38102);fill-opacity:1;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect74200"
+ width="16"
+ height="11"
+ x="397.64703"
+ y="-389.8125"
+ ry="4"
+ rx="4"
+ transform="rotate(45)" /><rect
+ style="opacity:1;fill:url(#linearGradient39377);fill-opacity:1;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect74196"
+ width="8"
+ height="11"
+ x="396.64703"
+ y="-389.8125"
+ ry="4"
+ rx="3"
+ transform="rotate(45)" /><rect
+ style="opacity:1;fill:#dfdfdf;fill-opacity:1;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect79410"
+ width="2"
+ height="3"
+ x="399.64703"
+ y="-385.8125"
+ ry="1"
+ transform="rotate(45)" /><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-7-61"
+ width="24"
+ height="24"
+ x="548"
+ y="4" /></g></svg>
diff --git a/launcher/resources/multimc/scalable/instances/modrinth.svg b/launcher/resources/multimc/scalable/instances/modrinth.svg
index a40f0e72..7982b6d4 100644
--- a/launcher/resources/multimc/scalable/instances/modrinth.svg
+++ b/launcher/resources/multimc/scalable/instances/modrinth.svg
@@ -1,4 +1,70 @@
-<svg width="512" height="514" viewBox="0 0 512 514" fill="none" xmlns="http://www.w3.org/2000/svg">
- <path fill-rule="evenodd" clip-rule="evenodd" d="M503.16 323.56C514.55 281.47 515.32 235.91 503.2 190.76C466.57 54.2299 326.04 -26.8001 189.33 9.77991C83.8101 38.0199 11.3899 128.07 0.689941 230.47H43.99C54.29 147.33 113.74 74.7298 199.75 51.7098C306.05 23.2598 415.13 80.6699 453.17 181.38L411.03 192.65C391.64 145.8 352.57 111.45 306.3 96.8198L298.56 140.66C335.09 154.13 364.72 184.5 375.56 224.91C391.36 283.8 361.94 344.14 308.56 369.17L320.09 412.16C390.25 383.21 432.4 310.3 422.43 235.14L464.41 223.91C468.91 252.62 467.35 281.16 460.55 308.07L503.16 323.56Z" fill="#30b27b"/>
- <path d="M321.99 504.22C185.27 540.8 44.7501 459.77 8.11011 323.24C3.84011 307.31 1.17 291.33 0 275.46H43.27C44.36 287.37 46.4699 299.35 49.6799 311.29C53.0399 323.8 57.45 335.75 62.79 347.07L101.38 323.92C98.1299 316.42 95.39 308.6 93.21 300.47C69.17 210.87 122.41 118.77 212.13 94.7601C229.13 90.2101 246.23 88.4401 262.93 89.1501L255.19 133C244.73 133.05 234.11 134.42 223.53 137.25C157.31 154.98 118.01 222.95 135.75 289.09C136.85 293.16 138.13 297.13 139.59 300.99L188.94 271.38L174.07 231.95L220.67 184.08L279.57 171.39L296.62 192.38L269.47 219.88L245.79 227.33L228.87 244.72L237.16 267.79C237.16 267.79 253.95 285.63 253.98 285.64L277.7 279.33L294.58 260.79L331.44 249.12L342.42 273.82L304.39 320.45L240.66 340.63L212.08 308.81L162.26 338.7C187.8 367.78 226.2 383.93 266.01 380.56L277.54 423.55C218.13 431.41 160.1 406.82 124.05 361.64L85.6399 384.68C136.25 451.17 223.84 484.11 309.61 461.16C371.35 444.64 419.4 402.56 445.42 349.38L488.06 364.88C457.17 431.16 398.22 483.82 321.99 504.22Z" fill="#30b27b"/>
-</svg>
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="32"
+ height="32"
+ version="1.1"
+ viewBox="0 0 32 32"
+ id="svg168"
+ xml:space="preserve"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"><defs
+ id="defs172"><linearGradient
+ id="linearGradient3108"><stop
+ style="stop-color:#1bd96a;stop-opacity:1;"
+ offset="0"
+ id="stop3104" /><stop
+ style="stop-color:#1bd9a1;stop-opacity:1;"
+ offset="1"
+ id="stop3106" /></linearGradient><linearGradient
+ xlink:href="#linearGradient3108"
+ id="linearGradient3110"
+ x1="70.852509"
+ y1="141.75883"
+ x2="70.852509"
+ y2="0.053809531"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ xlink:href="#linearGradient3108"
+ id="linearGradient50774"
+ gradientUnits="userSpaceOnUse"
+ x1="70.852509"
+ y1="141.75883"
+ x2="70.852509"
+ y2="0.053809531" /><linearGradient
+ xlink:href="#linearGradient3108"
+ id="linearGradient50776"
+ gradientUnits="userSpaceOnUse"
+ x1="70.852509"
+ y1="141.75883"
+ x2="70.852509"
+ y2="0.053809531" /></defs><title
+ id="title132">Prism Launcher Logo</title><metadata
+ id="metadata166"><rdf:RDF><cc:Work
+ rdf:about=""><dc:title>Prism Launcher Logo</dc:title><dc:date>19/10/2022</dc:date><dc:creator><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:creator><dc:contributor><cc:Agent><dc:title>AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke</dc:title></cc:Agent></dc:contributor><dc:source>https://github.com/PrismLauncher/PrismLauncher</dc:source><dc:rights><cc:Agent><dc:title>CC BY-SA 4.0</dc:title></cc:Agent></dc:rights><dc:publisher><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:publisher></cc:Work></rdf:RDF></metadata><g
+ id="i_modrinth"
+ transform="translate(-576)"><g
+ id="g83832"
+ transform="matrix(0.16936591,0,0,0.16936591,580,3.9908865)"
+ style="fill:url(#linearGradient3110);fill-opacity:1"><path
+ d="M 159.07,89.29 A 70.94,70.94 0 1 0 20,63.52 H 32 A 58.78,58.78 0 0 1 145.23,49.93 l -11.66,3.12 a 46.54,46.54 0 0 0 -29,-26.52 l -2.15,12.13 a 34.31,34.31 0 0 1 2.77,63.26 l 3.19,11.9 a 46.52,46.52 0 0 0 28.33,-49 l 11.62,-3.1 A 57.94,57.94 0 0 1 147.27,85 Z"
+ transform="translate(-19.79)"
+ fill="var(--color-brand)"
+ fill-rule="evenodd"
+ id="path83828"
+ style="fill:url(#linearGradient50774);fill-opacity:1" /><path
+ d="M 108.92,139.3 A 70.93,70.93 0 0 1 19.79,76 h 12 a 59.48,59.48 0 0 0 1.78,9.91 58.73,58.73 0 0 0 3.63,9.91 l 10.68,-6.41 a 46.58,46.58 0 0 1 44.72,-65 L 90.43,36.54 A 34.38,34.38 0 0 0 57.36,79.75 C 57.67,80.88 58,82 58.43,83 L 72.09,74.81 68,63.93 80.9,50.68 97.21,47.17 101.9,53 l -7.52,7.61 -6.55,2.06 -4.69,4.82 2.3,6.38 c 0,0 4.64,4.94 4.65,4.94 l 6.57,-1.74 4.67,-5.13 10.2,-3.24 3,6.84 L 104.05,88.43 86.41,94 78.49,85.19 64.7,93.48 a 34.44,34.44 0 0 0 28.72,11.59 L 96.61,117 A 46.6,46.6 0 0 1 54.13,99.83 l -10.64,6.38 a 58.81,58.81 0 0 0 99.6,-9.77 l 11.8,4.29 a 70.77,70.77 0 0 1 -45.97,38.57 z"
+ fill="var(--color-brand)"
+ id="path83830"
+ style="fill:url(#linearGradient50776);fill-opacity:1"
+ transform="translate(-19.79)" /></g><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-8-5"
+ width="32"
+ height="32"
+ x="576"
+ y="0" /></g></svg>
diff --git a/launcher/resources/multimc/scalable/instances/netherstar.svg b/launcher/resources/multimc/scalable/instances/netherstar.svg
new file mode 100644
index 00000000..a5d9606e
--- /dev/null
+++ b/launcher/resources/multimc/scalable/instances/netherstar.svg
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="24"
+ height="24"
+ version="1.1"
+ viewBox="0 0 24 24"
+ id="svg168"
+ xml:space="preserve"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"><defs
+ id="defs172"><linearGradient
+ id="linearGradient13104"><stop
+ style="stop-color:#e7e3fb;stop-opacity:1;"
+ offset="0"
+ id="stop13100" /><stop
+ style="stop-color:#e7e3fb;stop-opacity:0;"
+ offset="1"
+ id="stop13102" /></linearGradient><radialGradient
+ xlink:href="#linearGradient62774"
+ id="radialGradient62776"
+ cx="624"
+ cy="14"
+ fx="624"
+ fy="14"
+ r="12"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ id="linearGradient62774"><stop
+ style="stop-color:#f2effd;stop-opacity:1;"
+ offset="0.45171013"
+ id="stop62772" /><stop
+ style="stop-color:#d2cbf3;stop-opacity:1;"
+ offset="1"
+ id="stop62770" /></linearGradient><radialGradient
+ xlink:href="#linearGradient62766"
+ id="radialGradient62768"
+ cx="624"
+ cy="16"
+ fx="624"
+ fy="16"
+ r="6"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ id="linearGradient62766"><stop
+ style="stop-color:#fafbb9;stop-opacity:1;"
+ offset="0"
+ id="stop62762" /><stop
+ style="stop-color:#fafbb9;stop-opacity:0;"
+ offset="1"
+ id="stop62764" /></linearGradient><linearGradient
+ xlink:href="#linearGradient13104"
+ id="linearGradient13106"
+ x1="624"
+ y1="7"
+ x2="624"
+ y2="25"
+ gradientUnits="userSpaceOnUse" /></defs><title
+ id="title132">Prism Launcher Logo</title><metadata
+ id="metadata166"><rdf:RDF><cc:Work
+ rdf:about=""><dc:title>Prism Launcher Logo</dc:title><dc:date>19/10/2022</dc:date><dc:creator><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:creator><dc:contributor><cc:Agent><dc:title>AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke</dc:title></cc:Agent></dc:contributor><dc:source>https://github.com/PrismLauncher/PrismLauncher</dc:source><dc:rights><cc:Agent><dc:title>CC BY-SA 4.0</dc:title></cc:Agent></dc:rights><dc:publisher><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:publisher></cc:Work></rdf:RDF></metadata><g
+ id="i_netherstar"
+ transform="translate(-612,-4)"><path
+ id="path87169-8-4"
+ style="fill:url(#radialGradient62776);fill-opacity:1;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 624,7 c -1,2.999997 -2,2.5857914 -2,4 0,0.999999 0,1.000001 -1,2 -1,0.999997 -1,1 -2,1 -1.41421,0 -1,1.000001 -4,2 3,0.999999 2.58579,2 4,2 1,0 1,3e-6 2,1 1,0.999999 1,1.000001 1,2 0,1.414209 1,1.000003 2,4 1,-2.999997 2,-2.585791 2,-4 0,-0.999999 0,-1.000001 1,-2 1,-0.999997 1,-1 2,-1 1.41421,0 1,-1.000001 4,-2 -3,-0.999999 -2.58579,-2 -4,-2 -1,0 -1,-3e-6 -2,-1 -1,-0.999999 -1,-1.000001 -1,-2 0,-1.4142086 -1,-1.000003 -2,-4 z" /><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-7-6-9"
+ width="24"
+ height="24"
+ x="612"
+ y="4" /><path
+ style="fill:url(#radialGradient62768);fill-opacity:1;stroke:none;stroke-width:0.132291;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 624,19 c 1,-2 1,-2 3,-3 -2,-1 -2,-1 -3,-3 -1,2 -1,2 -3,3 2,1 2,1 3,3 z"
+ id="path88076" /><path
+ id="path12156"
+ style="color:#000000;fill:url(#linearGradient13106);fill-opacity:1;paint-order:stroke markers fill"
+ d="m 624,7 c -1,2.999994 -2,2.5857928 -2,4 0,0.999998 0,1.000002 -1,2 -1,0.999996 -1,1 -2,1 -1.41421,0 -1,1.000002 -4,2 3,0.999998 2.58579,2 4,2 1,0 1,4e-6 2,1 1,0.999998 1,1.000002 1,2 0,1.414208 1,1.000006 2,4 1,-2.999994 2,-2.585792 2,-4 0,-0.999998 0,-1.000002 1,-2 1,-0.999996 1,-1 2,-1 1.41421,0 1,-1.000002 4,-2 -3,-0.999998 -2.58579,-2 -4,-2 -1,0 -1,-4e-6 -2,-1 -1,-0.999998 -1,-1.000002 -1,-2 0,-1.4142072 -1,-1.000006 -2,-4 z m 0,2.0976562 c 0.20512,0.3196583 0.45222,0.9531658 0.60742,1.1386718 C 625.00535,10.711958 625,10.528599 625,11 c 0,0.499999 -0.0138,0.958752 0.23047,1.447266 0.24426,0.488512 0.5625,0.759767 1.0625,1.259765 0.5,0.499998 0.77125,0.818243 1.25976,1.0625 C 628.04125,15.013788 628.5,15 629,15 c 0.4714,0 0.28804,-0.0054 0.76367,0.392578 0.18551,0.155201 0.81901,0.402302 1.13867,0.607422 -0.31966,0.20512 -0.95316,0.452221 -1.13867,0.607422 C 629.28804,17.00535 629.4714,17 629,17 c -0.5,0 -0.95875,-0.01379 -1.44727,0.230469 -0.48851,0.244257 -0.75976,0.562502 -1.25976,1.0625 -0.5,0.499998 -0.81824,0.771253 -1.0625,1.259765 C 624.98621,20.041248 625,20.500001 625,21 c 0,0.471401 0.005,0.288042 -0.39258,0.763672 -0.1552,0.185506 -0.4023,0.819013 -0.60742,1.138672 -0.20512,-0.319659 -0.45222,-0.953166 -0.60742,-1.138672 C 622.99465,21.288042 623,21.471401 623,21 c 0,-0.499999 0.0138,-0.958752 -0.23047,-1.447266 -0.24426,-0.488512 -0.5625,-0.759767 -1.0625,-1.259765 -0.5,-0.499998 -0.77125,-0.818243 -1.25976,-1.0625 C 619.95875,16.986212 619.5,17 619,17 c -0.4714,0 -0.28804,0.0054 -0.76367,-0.392578 C 618.05082,16.452221 617.41732,16.20512 617.09766,16 c 0.31966,-0.20512 0.95316,-0.452221 1.13867,-0.607422 C 618.71196,14.99465 618.5286,15 619,15 c 0.5,0 0.95875,0.01379 1.44727,-0.230469 0.48851,-0.244257 0.75976,-0.562502 1.25976,-1.0625 0.5,-0.499998 0.81824,-0.771253 1.0625,-1.259765 C 623.01379,11.958752 623,11.499999 623,11 c 0,-0.471401 -0.005,-0.288042 0.39258,-0.763672 0.1552,-0.185506 0.4023,-0.8190135 0.60742,-1.1386718 z" /></g></svg>
diff --git a/launcher/resources/multimc/scalable/instances/planks.svg b/launcher/resources/multimc/scalable/instances/planks.svg
new file mode 100644
index 00000000..8febfa6b
--- /dev/null
+++ b/launcher/resources/multimc/scalable/instances/planks.svg
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="24"
+ height="24"
+ version="1.1"
+ viewBox="0 0 24 24"
+ id="svg168"
+ xml:space="preserve"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"><defs
+ id="defs172"><linearGradient
+ xlink:href="#linearGradient19391"
+ id="linearGradient19373"
+ x1="690"
+ y1="22"
+ x2="690"
+ y2="21"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ id="linearGradient19391"><stop
+ style="stop-color:#cfaf6b;stop-opacity:1;"
+ offset="0"
+ id="stop19387" /><stop
+ style="stop-color:#ddc694;stop-opacity:1;"
+ offset="1"
+ id="stop19389" /></linearGradient><linearGradient
+ xlink:href="#linearGradient19391"
+ id="linearGradient19435"
+ gradientUnits="userSpaceOnUse"
+ x1="690"
+ y1="22"
+ x2="690"
+ y2="21"
+ gradientTransform="translate(0,-5)" /><linearGradient
+ xlink:href="#linearGradient19391"
+ id="linearGradient19458"
+ gradientUnits="userSpaceOnUse"
+ x1="690"
+ y1="22"
+ x2="690"
+ y2="21"
+ gradientTransform="translate(0,-10)" /><linearGradient
+ xlink:href="#linearGradient19391"
+ id="linearGradient19481"
+ gradientUnits="userSpaceOnUse"
+ x1="690"
+ y1="22"
+ x2="690"
+ y2="21"
+ gradientTransform="translate(0,-15)" /></defs><title
+ id="title132">Prism Launcher Logo</title><metadata
+ id="metadata166"><rdf:RDF><cc:Work
+ rdf:about=""><dc:title>Prism Launcher Logo</dc:title><dc:date>19/10/2022</dc:date><dc:creator><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:creator><dc:contributor><cc:Agent><dc:title>AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke</dc:title></cc:Agent></dc:contributor><dc:source>https://github.com/PrismLauncher/PrismLauncher</dc:source><dc:rights><cc:Agent><dc:title>CC BY-SA 4.0</dc:title></cc:Agent></dc:rights><dc:publisher><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:publisher></cc:Work></rdf:RDF></metadata><g
+ id="i_planks"
+ transform="translate(-676,-4)"><rect
+ style="fill:#a88a4a;fill-opacity:1;stroke-width:0.277182;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect56542-7-5-0"
+ width="20"
+ height="20"
+ x="678"
+ y="6"
+ ry="3" /><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-7-4-9"
+ width="24"
+ height="24"
+ x="676"
+ y="4" /><path
+ id="rect15086"
+ style="fill:url(#linearGradient19373);fill-opacity:1;stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 678,21 v 2 c 0,0.771066 0.2909,1.469665 0.76562,2 h 18.46876 C 697.7091,24.469665 698,23.771066 698,23 v -2 z" /><rect
+ style="fill:url(#linearGradient19435);fill-opacity:1;stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect15086-4"
+ width="20"
+ height="4"
+ x="678"
+ y="16"
+ ry="0" /><rect
+ style="fill:url(#linearGradient19458);fill-opacity:1;stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect15086-2"
+ width="20"
+ height="4"
+ x="678"
+ y="11"
+ ry="0" /><path
+ id="rect15086-9"
+ style="fill:url(#linearGradient19481);fill-opacity:1;stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 681,6 c -1.662,0 -3,1.3380017 -3,3 v 1 h 20 V 9 c 0,-1.6619983 -1.338,-3 -3,-3 z" /></g></svg>
diff --git a/launcher/resources/multimc/scalable/instances/skeleton.svg b/launcher/resources/multimc/scalable/instances/skeleton.svg
new file mode 100644
index 00000000..ca9e8dd4
--- /dev/null
+++ b/launcher/resources/multimc/scalable/instances/skeleton.svg
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="24"
+ height="24"
+ version="1.1"
+ viewBox="0 0 24 24"
+ id="svg168"
+ xml:space="preserve"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"><defs
+ id="defs172"><linearGradient
+ xlink:href="#linearGradient6068"
+ id="linearGradient6070"
+ x1="656"
+ y1="27"
+ x2="656"
+ y2="5"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ id="linearGradient6068"><stop
+ style="stop-color:#cdcdcd;stop-opacity:1;"
+ offset="0"
+ id="stop6064" /><stop
+ style="stop-color:#eeeeee;stop-opacity:1;"
+ offset="1"
+ id="stop6066" /></linearGradient><linearGradient
+ xlink:href="#linearGradient7624"
+ id="linearGradient7626"
+ x1="658"
+ y1="20"
+ x2="658"
+ y2="24"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ id="linearGradient7624"><stop
+ style="stop-color:#8e8e86;stop-opacity:1;"
+ offset="0"
+ id="stop7620" /><stop
+ style="stop-color:#8e8e86;stop-opacity:0;"
+ offset="1"
+ id="stop7622" /></linearGradient><linearGradient
+ xlink:href="#linearGradient7155"
+ id="linearGradient7165"
+ x1="656"
+ y1="25"
+ x2="656"
+ y2="22"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ id="linearGradient7155"><stop
+ style="stop-color:#3e4447;stop-opacity:1;"
+ offset="0"
+ id="stop7151" /><stop
+ style="stop-color:#2e3134;stop-opacity:1;"
+ offset="1"
+ id="stop7153" /></linearGradient><radialGradient
+ xlink:href="#linearGradient6078"
+ id="radialGradient6080"
+ cx="662"
+ cy="18"
+ fx="662"
+ fy="18"
+ r="3"
+ gradientTransform="matrix(0.99999794,-1.7103091e-6,1.7879388e-6,1.0000015,0.0013367,0.00110992)"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ id="linearGradient6078"><stop
+ style="stop-color:#006868;stop-opacity:1;"
+ offset="0"
+ id="stop6074" /><stop
+ style="stop-color:#3e4447;stop-opacity:1;"
+ offset="1"
+ id="stop6076" /></linearGradient><linearGradient
+ xlink:href="#linearGradient7155"
+ id="linearGradient7157"
+ x1="651"
+ y1="20"
+ x2="651"
+ y2="16"
+ gradientUnits="userSpaceOnUse" /></defs><title
+ id="title132">Prism Launcher Logo</title><metadata
+ id="metadata166"><rdf:RDF><cc:Work
+ rdf:about=""><dc:title>Prism Launcher Logo</dc:title><dc:date>19/10/2022</dc:date><dc:creator><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:creator><dc:contributor><cc:Agent><dc:title>AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke</dc:title></cc:Agent></dc:contributor><dc:source>https://github.com/PrismLauncher/PrismLauncher</dc:source><dc:rights><cc:Agent><dc:title>CC BY-SA 4.0</dc:title></cc:Agent></dc:rights><dc:publisher><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:publisher></cc:Work></rdf:RDF></metadata><g
+ id="i_skeleton"
+ transform="translate(-644,-4)"><rect
+ style="fill:url(#linearGradient6070);fill-opacity:1;stroke-width:0.277182;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect543-0"
+ width="22"
+ height="22"
+ x="645"
+ y="5"
+ ry="3" /><rect
+ style="fill:url(#linearGradient7626);fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect61092"
+ width="6"
+ height="3"
+ x="653"
+ y="20"
+ ry="1" /><rect
+ style="fill:url(#linearGradient7165);fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect60969"
+ width="16"
+ height="3"
+ x="648"
+ y="22"
+ ry="1" /><rect
+ style="fill:url(#radialGradient6080);fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect63182"
+ width="6"
+ height="4"
+ x="659"
+ y="16"
+ ry="1" /><rect
+ style="fill:url(#linearGradient7157);fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect63184"
+ width="6"
+ height="4"
+ x="647"
+ y="16"
+ ry="1" /><rect
+ style="fill:#00ffff;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect63186"
+ width="2"
+ height="2"
+ x="661"
+ y="17" /><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-88-4"
+ width="24"
+ height="24"
+ x="644"
+ y="4" /></g></svg>
diff --git a/launcher/resources/multimc/scalable/instances/squarecreeper.svg b/launcher/resources/multimc/scalable/instances/squarecreeper.svg
new file mode 100644
index 00000000..ddb9aec8
--- /dev/null
+++ b/launcher/resources/multimc/scalable/instances/squarecreeper.svg
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="24"
+ height="24"
+ version="1.1"
+ viewBox="0 0 24 24"
+ id="svg168"
+ xml:space="preserve"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"><defs
+ id="defs172"><radialGradient
+ xlink:href="#linearGradient36865"
+ id="radialGradient10457-1"
+ cx="112"
+ cy="17"
+ fx="112"
+ fy="17"
+ r="6"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1666668,-6.8921104e-7,5.6666669e-7,1.1666667,589.33332,-2.8332561)" /><linearGradient
+ id="linearGradient36865"><stop
+ style="stop-color:#63271f;stop-opacity:1;"
+ offset="0"
+ id="stop36861" /><stop
+ style="stop-color:#3d1212;stop-opacity:1;"
+ offset="1"
+ id="stop36863" /></linearGradient><linearGradient
+ xlink:href="#linearGradient36859"
+ id="linearGradient11859-1"
+ x1="111"
+ y1="25"
+ x2="111"
+ y2="7"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(608)" /><linearGradient
+ id="linearGradient36859"><stop
+ style="stop-color:#729657;stop-opacity:1;"
+ offset="0"
+ id="stop36855" /><stop
+ style="stop-color:#a5bf6e;stop-opacity:1;"
+ offset="1"
+ id="stop36857" /></linearGradient></defs><title
+ id="title132">Prism Launcher Logo</title><metadata
+ id="metadata166"><rdf:RDF><cc:Work
+ rdf:about=""><dc:title>Prism Launcher Logo</dc:title><dc:date>19/10/2022</dc:date><dc:creator><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:creator><dc:contributor><cc:Agent><dc:title>AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke</dc:title></cc:Agent></dc:contributor><dc:source>https://github.com/PrismLauncher/PrismLauncher</dc:source><dc:rights><cc:Agent><dc:title>CC BY-SA 4.0</dc:title></cc:Agent></dc:rights><dc:publisher><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:publisher></cc:Work></rdf:RDF></metadata><g
+ id="i_squarecreeper"
+ transform="translate(-708,-4)"><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-8-3-0"
+ width="24"
+ height="24"
+ x="708"
+ y="4" /><rect
+ style="fill:url(#linearGradient11859-1);fill-opacity:1;stroke-width:0.226785;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect543-0-2-3-9"
+ width="18"
+ height="18"
+ x="711"
+ y="7"
+ ry="2.4545455" /><path
+ id="rect29291-0"
+ style="fill:url(#radialGradient10457-1);fill-opacity:1;stroke-width:0.529166;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 714,12 v 4 h 4 v -4 z m 4,4 v 2 h -2 v 6 h 2 v -2 h 4 v 2 h 2 v -6 h -2 v -2 z m 4,0 h 4 v -4 h -4 z" /><rect
+ style="opacity:1;fill:#ff0000;fill-opacity:1;stroke:none;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect37478"
+ width="2"
+ height="2"
+ x="722"
+ y="14" /><rect
+ style="fill:#ff0000;fill-opacity:1;stroke:none;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect37478-7"
+ width="2"
+ height="2"
+ x="716"
+ y="14" /></g></svg>
diff --git a/launcher/resources/multimc/scalable/instances/steve.svg b/launcher/resources/multimc/scalable/instances/steve.svg
new file mode 100644
index 00000000..9b6d2595
--- /dev/null
+++ b/launcher/resources/multimc/scalable/instances/steve.svg
@@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="24"
+ height="24"
+ version="1.1"
+ viewBox="0 0 24 24"
+ id="svg168"
+ xml:space="preserve"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"><defs
+ id="defs172"><linearGradient
+ id="linearGradient2739"><stop
+ style="stop-color:#cca997;stop-opacity:1;"
+ offset="0.23748928"
+ id="stop2755" /><stop
+ style="stop-color:#bd8e74;stop-opacity:1;"
+ offset="0.51858547"
+ id="stop2735" /></linearGradient><linearGradient
+ id="linearGradient1330"><stop
+ style="stop-color:#261a0a;stop-opacity:1;"
+ offset="0"
+ id="stop1326" /><stop
+ style="stop-color:#422e11;stop-opacity:1;"
+ offset="1"
+ id="stop1328" /></linearGradient><linearGradient
+ id="linearGradient1463"><stop
+ style="stop-color:#45220e;stop-opacity:1;"
+ offset="0"
+ id="stop1459" /><stop
+ style="stop-color:#552910;stop-opacity:1;"
+ offset="1"
+ id="stop1461" /></linearGradient><linearGradient
+ id="linearGradient1503"><stop
+ style="stop-color:#5c3874;stop-opacity:1;"
+ offset="0"
+ id="stop1499" /><stop
+ style="stop-color:#3c3874;stop-opacity:1;"
+ offset="1"
+ id="stop1501" /></linearGradient><radialGradient
+ xlink:href="#linearGradient2739"
+ id="radialGradient2757-6"
+ cx="496.06177"
+ cy="17.211182"
+ fx="495.87827"
+ fy="18.730774"
+ r="11"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.5554022,0,0,1.2337313,-519.57556,-16.266943)" /><linearGradient
+ xlink:href="#linearGradient1330"
+ id="linearGradient1332-1"
+ x1="487"
+ y1="15"
+ x2="487"
+ y2="5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(252,-12)" /><linearGradient
+ xlink:href="#linearGradient1463"
+ id="linearGradient1465-0"
+ x1="755"
+ y1="27"
+ x2="755"
+ y2="22"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-4,-12)" /><linearGradient
+ xlink:href="#linearGradient1503"
+ id="linearGradient1505-6"
+ x1="748"
+ y1="20"
+ x2="748"
+ y2="17"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ xlink:href="#linearGradient1503"
+ id="linearGradient5294"
+ gradientUnits="userSpaceOnUse"
+ x1="748"
+ y1="20"
+ x2="748"
+ y2="17" /><linearGradient
+ xlink:href="#linearGradient1503"
+ id="linearGradient5296"
+ gradientUnits="userSpaceOnUse"
+ x1="748"
+ y1="20"
+ x2="748"
+ y2="17" /></defs><title
+ id="title132">Prism Launcher Logo</title><metadata
+ id="metadata166"><rdf:RDF><cc:Work
+ rdf:about=""><dc:title>Prism Launcher Logo</dc:title><dc:date>19/10/2022</dc:date><dc:creator><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:creator><dc:contributor><cc:Agent><dc:title>AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke</dc:title></cc:Agent></dc:contributor><dc:source>https://github.com/PrismLauncher/PrismLauncher</dc:source><dc:rights><cc:Agent><dc:title>CC BY-SA 4.0</dc:title></cc:Agent></dc:rights><dc:publisher><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:publisher></cc:Work></rdf:RDF></metadata><g
+ id="i_steve"
+ transform="translate(-736,8)"><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-8-3-9-5"
+ width="24"
+ height="24"
+ x="736"
+ y="-8" /><path
+ id="rect56542-7-1"
+ style="fill:url(#radialGradient2757-6);stroke-width:0.277182;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 740,-7 h 16 l 3,3 v 16 c 0,1.662 -1.338,3 -3,3 h -16 c -1.662,0 -3,-1.338 -3,-3 V -4 Z" /><path
+ id="rect56552-6-8"
+ style="fill:url(#linearGradient1332-1);fill-opacity:1;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 740,-7 c -1.662,0 -3,1.338002 -3,3 v 7 h 2 c 1.108,0 2,-0.892003 2,-2 V 0 h 14 v 1 c 0,1.107997 0.892,2 2,2 h 2 v -7 c 0,-1.661998 -1.338,-3 -3,-3 h -1 -14 z" /><rect
+ style="fill:#8a4c3d;fill-opacity:1;stroke:none;stroke-width:0.396874;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect53396-9-7"
+ width="6"
+ height="3"
+ x="745"
+ y="10"
+ ry="0" /><rect
+ style="fill:#ffffff;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect63182-8-0-3-9"
+ width="7"
+ height="3"
+ x="750"
+ y="5"
+ ry="1" /><rect
+ style="fill:#ffffff;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect63184-7-9-7-2"
+ width="7"
+ height="3"
+ x="739"
+ y="5"
+ ry="1" /><rect
+ style="fill:#6a4030;fill-opacity:1;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect50123-4-0"
+ width="4"
+ height="2"
+ x="746"
+ y="8"
+ ry="0" /><path
+ id="path195645-2"
+ style="fill:url(#linearGradient1465-0);fill-opacity:1;stroke:none;stroke-width:0.362295;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 745,10 a 2,2 0 0 0 -2,2 v 3 h 3 4 3 v -3 a 2,2 0 0 0 -2,-2 h -1 v 2 h -4 v -2 z" /><g
+ id="g1469-3"
+ style="fill:url(#linearGradient1505-6);fill-opacity:1"
+ transform="translate(-4,-12)"><rect
+ style="fill:url(#linearGradient5294);fill-opacity:1;stroke-width:0.396874;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect75119-2-7"
+ width="3"
+ height="3"
+ x="746"
+ y="17" /><rect
+ style="fill:url(#linearGradient5296);fill-opacity:1;stroke-width:0.396874;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect112219-5"
+ width="3"
+ height="3"
+ x="755"
+ y="17" /></g></g></svg>
diff --git a/launcher/resources/multimc/scalable/instances/stone.svg b/launcher/resources/multimc/scalable/instances/stone.svg
new file mode 100644
index 00000000..6df534d2
--- /dev/null
+++ b/launcher/resources/multimc/scalable/instances/stone.svg
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="24"
+ height="24"
+ version="1.1"
+ viewBox="0 0 24 24"
+ id="svg168"
+ xml:space="preserve"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"><defs
+ id="defs172"><linearGradient
+ xlink:href="#linearGradient25803"
+ id="linearGradient25805"
+ x1="785"
+ y1="26"
+ x2="785"
+ y2="6"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ id="linearGradient25803"><stop
+ style="stop-color:#8e8e86;stop-opacity:1;"
+ offset="0"
+ id="stop25799" /><stop
+ style="stop-color:#a2a29b;stop-opacity:1;"
+ offset="1"
+ id="stop25801" /></linearGradient></defs><title
+ id="title132">Prism Launcher Logo</title><metadata
+ id="metadata166"><rdf:RDF><cc:Work
+ rdf:about=""><dc:title>Prism Launcher Logo</dc:title><dc:date>19/10/2022</dc:date><dc:creator><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:creator><dc:contributor><cc:Agent><dc:title>AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke</dc:title></cc:Agent></dc:contributor><dc:source>https://github.com/PrismLauncher/PrismLauncher</dc:source><dc:rights><cc:Agent><dc:title>CC BY-SA 4.0</dc:title></cc:Agent></dc:rights><dc:publisher><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:publisher></cc:Work></rdf:RDF></metadata><g
+ id="i_stone"
+ transform="translate(-772,-4)"><rect
+ style="fill:url(#linearGradient25805);fill-opacity:1;stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect15088-9"
+ width="20"
+ height="20"
+ x="774"
+ y="6"
+ ry="3" /><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-4-1"
+ width="24"
+ height="24"
+ x="772"
+ y="4" /><path
+ id="path47261"
+ style="opacity:0.5;fill:#bfbfbb;fill-opacity:1;stroke-width:0.999997;stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 777,11 v 1 h 12 v -1 z m 14,2 v 1 h 2 v -1 z m -17,2 v 1 h 8 v -1 z m 16,4 v 1 h 4 v -1 z m -8,2 v 1 h 2 v -1 z m 2,3 v 1 h 5 v -1 z" /><path
+ id="path47259"
+ style="opacity:0.5;fill:#7e7e77;fill-opacity:1;stroke-width:0.999997;stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 774,8 v 1 h 7 V 8 Z m 15,0 v 1 h 5 V 8 Z m -4,8 v 1 h 5 v -1 z m -11,4 v 1 h 6 v -1 z m 3,3 v 1 h 2 v -1 z m 14,0 v 1 h 3 v -1 z" /></g></svg>
diff --git a/launcher/resources/multimc/scalable/instances/tnt.svg b/launcher/resources/multimc/scalable/instances/tnt.svg
new file mode 100644
index 00000000..e876eba3
--- /dev/null
+++ b/launcher/resources/multimc/scalable/instances/tnt.svg
@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="24"
+ height="24"
+ version="1.1"
+ viewBox="0 0 24 24"
+ id="svg168"
+ xml:space="preserve"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"><defs
+ id="defs172"><linearGradient
+ xlink:href="#linearGradient18899"
+ id="linearGradient18901"
+ x1="805"
+ y1="16"
+ x2="812"
+ y2="16"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ id="linearGradient18899"><stop
+ style="stop-color:#bf454c;stop-opacity:1;"
+ offset="0"
+ id="stop18895" /><stop
+ style="stop-color:#df6277;stop-opacity:1;"
+ offset="0.5"
+ id="stop18972" /><stop
+ style="stop-color:#bf454c;stop-opacity:1;"
+ offset="1"
+ id="stop18897" /></linearGradient><linearGradient
+ xlink:href="#linearGradient18899"
+ id="linearGradient19011"
+ x1="812"
+ y1="16"
+ x2="820"
+ y2="16"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ xlink:href="#linearGradient18899"
+ id="linearGradient19015"
+ gradientUnits="userSpaceOnUse"
+ x1="805"
+ y1="16"
+ x2="812"
+ y2="16"
+ gradientTransform="matrix(-1,0,0,1,1632,0)" /><linearGradient
+ xlink:href="#linearGradient19917"
+ id="linearGradient22848"
+ gradientUnits="userSpaceOnUse"
+ x1="816"
+ y1="27"
+ x2="816"
+ y2="20" /><linearGradient
+ id="linearGradient19917"><stop
+ style="stop-color:#a02722;stop-opacity:1;"
+ offset="0"
+ id="stop19913" /><stop
+ style="stop-color:#a02722;stop-opacity:0;"
+ offset="1"
+ id="stop19915" /></linearGradient><radialGradient
+ xlink:href="#linearGradient19935"
+ id="radialGradient19929"
+ cx="816"
+ cy="14"
+ fx="816"
+ fy="14"
+ r="11"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1570249,0,0,1,-128.13223,0)" /><linearGradient
+ id="linearGradient19935"><stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop19933" /><stop
+ style="stop-color:#f6cff4;stop-opacity:1;"
+ offset="1"
+ id="stop19931" /></linearGradient></defs><title
+ id="title132">Prism Launcher Logo</title><metadata
+ id="metadata166"><rdf:RDF><cc:Work
+ rdf:about=""><dc:title>Prism Launcher Logo</dc:title><dc:date>19/10/2022</dc:date><dc:creator><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:creator><dc:contributor><cc:Agent><dc:title>AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke</dc:title></cc:Agent></dc:contributor><dc:source>https://github.com/PrismLauncher/PrismLauncher</dc:source><dc:rights><cc:Agent><dc:title>CC BY-SA 4.0</dc:title></cc:Agent></dc:rights><dc:publisher><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:publisher></cc:Work></rdf:RDF></metadata><g
+ id="i_tnt"
+ transform="translate(-804,-4)"><rect
+ style="fill:#a02722;fill-opacity:1;stroke-width:0.277182;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect13011-7"
+ width="20"
+ height="20"
+ x="806"
+ y="6"
+ ry="3" /><g
+ id="g19020"><path
+ id="rect18703"
+ style="opacity:1;fill:url(#linearGradient18901);fill-opacity:1;stroke:none;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 809,6 c -1.662,0 -3,1.3380017 -3,3 v 14 c 0,1.661998 1.338,3 3,3 h 3 V 6 Z" /><rect
+ style="opacity:1;fill:url(#linearGradient19011);fill-opacity:1;stroke:none;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect19003"
+ width="6"
+ height="20"
+ x="813"
+ y="6" /><path
+ id="path19013"
+ style="opacity:1;fill:url(#linearGradient19015);fill-opacity:1;stroke:none;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 823,6 c 1.662,0 3,1.3380017 3,3 v 14 c 0,1.661998 -1.338,3 -3,3 h -3 V 6 Z" /></g><rect
+ style="opacity:1;fill:url(#linearGradient22848);fill-opacity:1;stroke:none;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect19910"
+ width="20"
+ height="20"
+ x="806"
+ y="6"
+ ry="3" /><rect
+ style="opacity:1;fill:url(#radialGradient19929);fill-opacity:1;stroke:none;stroke-width:0.295813;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect121411"
+ width="20"
+ height="10"
+ x="806"
+ y="11" /><path
+ id="rect122467"
+ style="opacity:1;fill:#4d3f33;fill-opacity:1;stroke:none;stroke-width:0.374177;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 808,13 v 2 h 1 v 4 h 2 v -4 h 1 v -2 z m 5,0 v 6 h 2 v -3.171875 l 2,2 V 19 h 2 v -6 h -2 v 2 l -2,-2 z m 7,0 v 2 h 1 v 4 h 2 v -4 h 1 v -2 z" /><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-7-9-7"
+ width="24"
+ height="24"
+ x="804"
+ y="4" /></g></svg>
diff --git a/launcher/resources/multimc/scalable/launch.svg b/launcher/resources/multimc/scalable/launch.svg
new file mode 100644
index 00000000..321647a0
--- /dev/null
+++ b/launcher/resources/multimc/scalable/launch.svg
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="32"
+ height="32"
+ viewBox="0 0 8.4666667 8.4666667"
+ version="1.1"
+ id="svg19142"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <defs
+ id="defs19139">
+ <radialGradient
+ xlink:href="#linearGradient3801"
+ id="radialGradient11398"
+ cx="16.288221"
+ cy="1036.3623"
+ fx="16.288221"
+ fy="1036.3623"
+ r="12.356801"
+ gradientTransform="matrix(1,0,0,1.1851852,0,-191.91894)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient3801">
+ <stop
+ style="stop-color:#00b81a;stop-opacity:1;"
+ offset="0"
+ id="stop3803" />
+ <stop
+ style="stop-color:#00600d;stop-opacity:1;"
+ offset="1"
+ id="stop3805" />
+ </linearGradient>
+ <radialGradient
+ xlink:href="#linearGradient3801"
+ id="radialGradient20362"
+ cx="16.288221"
+ cy="1036.3623"
+ fx="16.288221"
+ fy="1036.3623"
+ r="12.356801"
+ gradientTransform="matrix(1,0,0,1.1851852,0,-191.91894)"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ xlink:href="#linearGradient15792"
+ id="radialGradient12126"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.745076,0.97121566,-0.94714744,0.72661186,979.1198,272.32494)"
+ cx="7.3809543"
+ cy="1029.1321"
+ fx="7.3809543"
+ fy="1029.1321"
+ r="12.356801" />
+ <linearGradient
+ id="linearGradient15792">
+ <stop
+ style="stop-color:#00b81a;stop-opacity:1;"
+ offset="0"
+ id="stop15788" />
+ <stop
+ style="stop-color:#008311;stop-opacity:1;"
+ offset="1"
+ id="stop15790" />
+ </linearGradient>
+ <radialGradient
+ xlink:href="#linearGradient3801"
+ id="radialGradient20379"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.1851852,0,-191.91894)"
+ cx="16.288221"
+ cy="1036.3623"
+ fx="16.288221"
+ fy="1036.3623"
+ r="12.356801" />
+ </defs>
+ <g
+ id="layer1"
+ transform="translate(-107.77091,-124.13108)">
+ <g
+ transform="matrix(0.26458333,0,0,0.26458333,107.69465,-145.83977)"
+ id="layer1-3"
+ style="fill:#00c900;fill-opacity:1;stroke:url(#radialGradient11398)">
+ <g
+ id="g4187"
+ transform="matrix(1.6112635,0,0,1.6112635,-11.986846,-633.49032)"
+ style="fill:#00c900;fill-opacity:1;stroke:url(#radialGradient20379);stroke-width:0.620631">
+ <path
+ style="opacity:1;fill:#0ebb0e;fill-opacity:1;stroke:url(#radialGradient12126);stroke-width:1.24126;stroke-dasharray:none;stroke-opacity:1"
+ id="path3809-3"
+ d="m 10.5,1044.3622 v -16 l 13.5,8 z" />
+ </g>
+ </g>
+ </g>
+</svg>
diff --git a/launcher/resources/multimc/scalable/rename.svg b/launcher/resources/multimc/scalable/rename.svg
new file mode 100644
index 00000000..a585e264
--- /dev/null
+++ b/launcher/resources/multimc/scalable/rename.svg
@@ -0,0 +1,437 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="33.072914mm"
+ height="33.072918mm"
+ viewBox="0 0 33.072914 33.072918"
+ version="1.1"
+ id="svg30785"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <sodipodi:namedview
+ id="namedview30787"
+ pagecolor="#505050"
+ bordercolor="#ffffff"
+ borderopacity="1"
+ inkscape:showpageshadow="0"
+ inkscape:pageopacity="0"
+ inkscape:pagecheckerboard="1"
+ inkscape:deskcolor="#505050"
+ inkscape:document-units="mm"
+ showgrid="false"
+ inkscape:zoom="1.1893044"
+ inkscape:cx="14.714484"
+ inkscape:cy="139.15697"
+ inkscape:window-width="1440"
+ inkscape:window-height="827"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="layer1" />
+ <defs
+ id="defs30782">
+ <linearGradient
+ y2="93.999413"
+ x2="87.757362"
+ y1="79.998817"
+ x1="63.911137"
+ gradientTransform="matrix(1.3755238,0,0,1.8570645,-22.548199,-92.562977)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient6028"
+ xlink:href="#linearGradient3291" />
+ <linearGradient
+ id="linearGradient3291">
+ <stop
+ style="stop-color:black;stop-opacity:1"
+ offset="0"
+ id="stop3293" />
+ <stop
+ style="stop-color:black;stop-opacity:0"
+ offset="1"
+ id="stop3295" />
+ </linearGradient>
+ <filter
+ id="filter12295"
+ x="-0.061093309"
+ y="-0.057532126"
+ width="1.1221866"
+ height="1.1150643">
+ <feGaussianBlur
+ stdDeviation="1.4758613"
+ id="feGaussianBlur12297" />
+ </filter>
+ <radialGradient
+ r="3.406888"
+ fy="120.64188"
+ fx="42.617531"
+ cy="120.64188"
+ cx="42.617531"
+ gradientTransform="matrix(1.909059,1.8392116,-8.6222515,7.5766472,1009.8522,-881.36145)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient6030"
+ xlink:href="#linearGradient2257" />
+ <linearGradient
+ id="linearGradient2257">
+ <stop
+ style="stop-color:#b4942a;stop-opacity:1;"
+ offset="0"
+ id="stop2259" />
+ <stop
+ style="stop-color:#e4dcc9;stop-opacity:1"
+ offset="1"
+ id="stop2261" />
+ </linearGradient>
+ <linearGradient
+ y2="77.047241"
+ x2="81.452583"
+ y1="72.804123"
+ x1="75.848022"
+ gradientTransform="matrix(0.9986497,0,0,0.9998891,0.1404398,0.00532324)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient6032"
+ xlink:href="#linearGradient2598" />
+ <linearGradient
+ id="linearGradient2598">
+ <stop
+ id="stop2600"
+ offset="0"
+ style="stop-color:#252525;stop-opacity:1;" />
+ <stop
+ style="stop-color:#252525;stop-opacity:1;"
+ offset="0.5"
+ id="stop2606" />
+ <stop
+ id="stop2608"
+ offset="0.75"
+ style="stop-color:#252525;stop-opacity:1;" />
+ <stop
+ id="stop2602"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ y2="87.154587"
+ x2="80.579521"
+ y1="83.325729"
+ x1="76.708534"
+ gradientTransform="matrix(0.9986497,0,0,0.9998891,0.1404398,0.00532324)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient6034"
+ xlink:href="#linearGradient7364" />
+ <linearGradient
+ id="linearGradient7364">
+ <stop
+ id="stop7366"
+ offset="0"
+ style="stop-color:#d4a100;stop-opacity:0.97647059;" />
+ <stop
+ id="stop7368"
+ offset="1"
+ style="stop-color:#ffc712;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ y2="57.383999"
+ x2="14.493531"
+ y1="57.383999"
+ x1="11.326384"
+ gradientTransform="matrix(1.2875994,1.1737414,-0.5465891,0.6213041,81.686465,27.89447)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient6036"
+ xlink:href="#linearGradient3058" />
+ <linearGradient
+ id="linearGradient3058">
+ <stop
+ id="stop3060"
+ offset="0"
+ style="stop-color:#9a7600;stop-opacity:1;" />
+ <stop
+ style="stop-color:#e3ad00;stop-opacity:1;"
+ offset="0.09292036"
+ id="stop3066" />
+ <stop
+ id="stop3070"
+ offset="0.5043171"
+ style="stop-color:#ffcd2c;stop-opacity:1;" />
+ <stop
+ id="stop3068"
+ offset="0.91571385"
+ style="stop-color:#e3ad00;stop-opacity:1;" />
+ <stop
+ id="stop3062"
+ offset="1"
+ style="stop-color:#b98d00;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ y2="-22.052734"
+ x2="100.65602"
+ y1="-22.560064"
+ x1="114.92793"
+ gradientTransform="matrix(0.9992082,0,0,0.9993395,0.1083622,-0.09037494)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient6038"
+ xlink:href="#linearGradient5826" />
+ <linearGradient
+ id="linearGradient5826">
+ <stop
+ style="stop-color:#980000;stop-opacity:1;"
+ offset="0"
+ id="stop5828" />
+ <stop
+ style="stop-color:#db5c5c;stop-opacity:1;"
+ offset="1"
+ id="stop5830" />
+ </linearGradient>
+ <linearGradient
+ y2="7.4622769"
+ x2="82.172836"
+ y1="7.4622769"
+ x1="-12.817558"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient6040"
+ xlink:href="#linearGradient3303" />
+ <linearGradient
+ id="linearGradient3303">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.68345326;"
+ offset="0"
+ id="stop3305" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3307" />
+ </linearGradient>
+ <filter
+ id="filter3849"
+ x="-0.0079507314"
+ y="-0.38873081"
+ width="1.0159015"
+ height="1.7774616">
+ <feGaussianBlur
+ stdDeviation="0.31468463"
+ id="feGaussianBlur3851" />
+ </filter>
+ <radialGradient
+ r="47.595196"
+ fy="7.4622769"
+ fx="34.677639"
+ cy="7.4622769"
+ cx="34.677639"
+ gradientTransform="matrix(-1.5103,0.00264127,-1.167078e-4,-0.00911022,87.0522,7.438666)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient6042"
+ xlink:href="#linearGradient3325" />
+ <linearGradient
+ id="linearGradient3325">
+ <stop
+ id="stop3327"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop3329"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ y2="107.35519"
+ x2="24.450998"
+ y1="117.83894"
+ x1="33.342377"
+ gradientTransform="matrix(0.6182226,0,0,0.6232687,24.10803,47.993844)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient6044"
+ xlink:href="#linearGradient2922" />
+ <linearGradient
+ id="linearGradient2922">
+ <stop
+ id="stop2924"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop2926"
+ offset="1"
+ style="stop-color:#515151;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ y2="2.3657269"
+ x2="48.732723"
+ y1="0.81150496"
+ x1="48.498562"
+ gradientTransform="matrix(1.6732108,1.5189394,-1.5009523,1.6928488,18.675678,-24.465565)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient6046"
+ xlink:href="#linearGradient3325" />
+ <linearGradient
+ y2="57.15118"
+ x2="96.579895"
+ y1="54.119438"
+ x1="92.226158"
+ gradientTransform="matrix(0.9973012,0,0,0.9997782,0.28069,0.0106459)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient6048"
+ xlink:href="#linearGradient5433" />
+ <linearGradient
+ id="linearGradient5433">
+ <stop
+ id="stop5435"
+ offset="0"
+ style="stop-color:#ea3838;stop-opacity:1;" />
+ <stop
+ id="stop5437"
+ offset="1"
+ style="stop-color:#c40000;stop-opacity:1;" />
+ </linearGradient>
+ <radialGradient
+ r="1.7246193"
+ fy="2.6743078"
+ fx="49.011971"
+ cy="2.6743078"
+ cx="49.011971"
+ gradientTransform="matrix(2.2600183,0,0,0.2752449,-2.2590409,-25.415382)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient6050"
+ xlink:href="#linearGradient3207" />
+ <linearGradient
+ id="linearGradient3207">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3209" />
+ <stop
+ style="stop-color:#252525;stop-opacity:0;"
+ offset="1"
+ id="stop3211" />
+ </linearGradient>
+ <radialGradient
+ r="1.7246193"
+ fy="2.6743078"
+ fx="49.011971"
+ cy="2.6743078"
+ cx="49.011971"
+ gradientTransform="matrix(1.550633,0,0,0.1873121,21.621938,-31.864287)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient6052"
+ xlink:href="#linearGradient3207" />
+ <radialGradient
+ r="1.7246193"
+ fy="2.6743078"
+ fx="49.011971"
+ cy="2.6743078"
+ cx="49.011971"
+ gradientTransform="matrix(1.5495914,0,0,0.1876849,-193.24041,-23.535874)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient6054"
+ xlink:href="#linearGradient3207" />
+ </defs>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-62.462199,-187.28812)">
+ <g
+ id="g4356"
+ transform="matrix(0.43758532,0,0,0.43516994,47.592708,166.39996)"
+ style="stroke-width:0.879897">
+ <path
+ id="path3180"
+ d="m 90.067703,48.28801 c 0.613642,-0.692125 4.648657,-0.363057 8.944253,3.536477 4.337724,3.937759 5.210074,7.748115 4.441394,8.615025 -0.5003,0.564284 -1.00061,1.128566 -1.50092,1.692851 -4.461914,-4.050501 -8.9238,-8.101002 -13.385691,-12.151503 0.500309,-0.564283 1.000624,-1.128565 1.500964,-1.69285 0,0 0,0 0,0"
+ style="fill:#bf0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.879897px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ style="fill:#b3925d;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 36.000762,124 20.247,-9.42653 0.09417,-0.10772 -13.269004,-12.28446 -0.127672,0.1459 z"
+ id="path3299" />
+ <path
+ id="path7753"
+ d="m 97.750257,56.002191 c -1.025821,-0.04502 -1.882013,0.614542 -2.665637,0.986566 -4.174912,3.698786 -21.569273,21.653428 -22.000397,22.168708 l -17.273332,20.659839 -0.106627,0.116066 -9.682256,17.6334 23.598527,-5.26172 29.942357,-36.049248 3.589728,-4.294461 c 0.64726,-1.199814 1.23861,-7.813473 -1.74155,-12.76732 -1.452992,-2.415269 -2.634989,-3.146806 -3.660813,-3.19183 z m 5.402363,15.95915 c -0.0266,0.04924 -0.0446,0.143824 -0.0711,0.174098 -0.0129,0.01476 1.49247,-1.049396 0.6753,-0.870498 z"
+ style="fill:url(#linearGradient6028);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.879897px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter12295)" />
+ <path
+ id="path2247"
+ d="m 37.004018,123.01573 18.885171,-8.78019 0.09416,-0.10769 -12.551842,-11.60866 -0.12769,0.14592 z"
+ style="fill:url(#radialGradient6030);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ id="rect2192"
+ d="m 49.164276,108.94499 c 1.648961,1.50106 2.755448,1.51054 3.34488,2.0471 0.09525,0.0867 0.175312,0.18851 0.243795,0.29167 L 97.392942,60.017302 90.912418,54.117987 46.187555,105.48147 c 0.214748,0.0564 0.415855,0.13454 0.602285,0.30424 0.538767,0.49045 0.717813,1.65124 2.374436,3.15928 z"
+ style="fill:url(#linearGradient6032);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.439949;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ style="opacity:0.353488;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.439949;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ d="m 54.219542,109.12044 -1.750182,2.00168 c 0.538752,0.53092 0.431653,1.46553 1.421976,2.36702 1.067261,0.97156 1.630178,0.45849 2.321697,1.08447 l 1.771382,-2.02599 z"
+ id="path2233" />
+ <path
+ id="rect2190"
+ d="M 97.156354,59.801933 52.550305,111.02955 c 0.541583,0.53354 0.517441,1.37742 1.512824,2.28353 1.072712,0.97652 1.555044,0.55628 2.250088,1.18547 L 100.94048,63.246681 Z"
+ style="fill:url(#linearGradient6034);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.439949;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ style="opacity:0.386047;fill:#252525;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.439949;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ d="m 47.641192,104.81388 -0.897802,1.02682 -0.0345,0.0376 c 0.447512,0.42018 0.395724,1.39005 1.878296,2.86086 l 0.08229,0.0749 0.586334,0.53373 0.0823,0.0749 c 1.616252,1.35012 2.54668,1.16726 3.136095,1.7038 l 0.947655,-1.09585 z"
+ id="path2231" />
+ <path
+ style="opacity:0.353488;fill:#131313;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.439949;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ d="m 43.884886,101.37497 -0.940801,0.95531 c 0.02064,0.0187 -0.05311,0.1047 -0.03237,0.12358 0.423005,0.38509 0.412824,1.36825 1.189787,2.20191 l 0.072,0.0655 0.318878,0.29029 0.04115,0.0374 c 0.925767,0.72156 1.702344,0.46358 2.175362,0.82926 l 0.940872,-1.07609 z"
+ id="path2229" />
+ <path
+ id="rect1315"
+ d="m 44.501995,104.6749 c 1.032229,0.92922 1.738227,0.6105 2.287845,1.11081 L 91.395905,54.558106 87.571444,51.076654 42.944168,102.32853 c 0.02096,0.019 0.04162,0.0379 0.06269,0.0571 0.42971,0.39116 0.455145,1.35294 1.495139,2.28929 z"
+ style="fill:url(#linearGradient6036);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.439949;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <rect
+ transform="matrix(0.7409346,0.6715772,-0.6655662,0.7463388,0,0)"
+ y="-24.64492"
+ x="99.380959"
+ height="4.2522693"
+ width="18.073059"
+ id="rect2069"
+ style="fill:url(#linearGradient6038);fill-opacity:1;stroke:none;stroke-width:0.879897;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <ellipse
+ transform="matrix(0.3854946,-0.4403693,-1.7345162,-1.5764895,62.874028,110.46407)"
+ id="path5963"
+ style="fill:url(#linearGradient6040);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.175979;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1;filter:url(#filter3849)"
+ cx="34.677639"
+ cy="7.4622769"
+ rx="47.495197"
+ ry="0.97142172" />
+ <path
+ style="fill:url(#radialGradient6042);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.175979;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="path3321"
+ d="M 106.56087,7.4622769 A 71.883232,0.4230493 0 0 1 35.242273,7.8853132 71.883232,0.4230493 0 0 1 -37.196723,7.4689227 71.883232,0.4230493 0 0 1 32.983878,7.0393451 71.883232,0.4230493 0 0 1 106.52539,7.448987"
+ transform="matrix(0.3184879,-0.3665274,-1.2576415,-1.1452705,66.925762,101.47904)" />
+ <path
+ id="path2265"
+ d="m 44.721041,119.98334 c -1.894932,-0.77816 -4.469372,-3.93608 -5.787909,-5.07837 l -2.933131,9.08971 z"
+ style="fill:url(#linearGradient6044);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ id="path3233"
+ d="m 97.676422,50.957862 c 2.773338,2.157871 4.754818,5.136648 4.863888,5.422718 0.10904,0.286071 -2.586875,-3.046365 -4.878244,-4.572341 -2.273846,-1.514326 -5.450917,-1.552229 -5.685693,-1.736594 -0.234782,-0.184361 -1.822614,-1.877275 -0.38221,-1.814774 1.506596,0.06537 3.94013,1.035831 6.082259,2.700991 z"
+ style="fill:url(#linearGradient6046);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.879897px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ style="fill:url(#linearGradient6048);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.439949;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ d="m 93.653015,51.592952 -2.773744,3.218036 6.482458,5.873697 2.773741,-3.186793 z"
+ id="path5045" />
+ <rect
+ transform="matrix(0.7404161,0.6721488,-0.6634233,0.7482443,0,0)"
+ y="-25.364759"
+ x="104.60918"
+ height="1.7080779"
+ width="7.795228"
+ id="rect3205"
+ style="fill:url(#radialGradient6050);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <rect
+ style="fill:url(#radialGradient6052);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="rect2956"
+ width="5.3484583"
+ height="1.162492"
+ x="94.946716"
+ y="-31.829779"
+ transform="matrix(0.6942228,0.7197602,-0.7693435,0.6388354,0,0)" />
+ <rect
+ transform="matrix(-0.7514575,-0.6597815,-0.5893147,0.8079036,0,0)"
+ y="-23.501301"
+ x="-119.96733"
+ height="1.1647878"
+ width="5.3448997"
+ id="rect2961"
+ style="fill:url(#radialGradient6054);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ </g>
+ </g>
+</svg>
diff --git a/launcher/resources/multimc/scalable/shortcut.svg b/launcher/resources/multimc/scalable/shortcut.svg
new file mode 100644
index 00000000..549c3724
--- /dev/null
+++ b/launcher/resources/multimc/scalable/shortcut.svg
@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="128"
+ height="128"
+ id="svg2"
+ version="1.0"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/">
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient3185">
+ <stop
+ style="stop-color:#eeeeee;stop-opacity:1;"
+ offset="0"
+ id="stop3187" />
+ <stop
+ style="stop-color:#eeeeee;stop-opacity:0;"
+ offset="1"
+ id="stop3189" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3133">
+ <stop
+ style="stop-color:#646661;stop-opacity:1"
+ offset="0"
+ id="stop3135" />
+ <stop
+ style="stop-color:#111111;stop-opacity:1"
+ offset="1"
+ id="stop3137" />
+ </linearGradient>
+ <radialGradient
+ xlink:href="#linearGradient3133"
+ id="radialGradient3139"
+ cx="64"
+ cy="35.686314"
+ fx="64"
+ fy="35.686314"
+ r="40"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.1360441,0,0,1.446027,-72.706823,-26.184217)" />
+ <linearGradient
+ xlink:href="#linearGradient3185"
+ id="linearGradient3191"
+ x1="112"
+ y1="98.41069"
+ x2="61.978939"
+ y2="11.771669"
+ gradientUnits="userSpaceOnUse" />
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath3393">
+ <path
+ style="opacity:1;fill:#dbdbdb;fill-opacity:1;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 13.8125,8 C 10.584167,8 8,10.584167 8,13.8125 L 8,114.1875 C 8,117.41583 10.584167,120 13.8125,120 L 114.1875,120 C 117.41583,120 120,117.41583 120,114.1875 L 120,13.8125 C 120,10.584167 117.41583,8 114.1875,8 L 13.8125,8 z M 21.8125,16 L 106.1875,16 C 109.41583,16 112,18.584167 112,21.8125 L 112,106.1875 C 112,109.41583 109.41583,112 106.1875,112 L 21.8125,112 C 18.584166,112 16,109.41583 16,106.1875 L 16,21.8125 C 16,18.584166 18.584167,16 21.8125,16 z "
+ id="path3395" />
+ </clipPath>
+ <radialGradient
+ xlink:href="#linearGradient3133"
+ id="radialGradient3413"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.1360441,0,0,-1.446027,-72.706823,154.18422)"
+ cx="64"
+ cy="35.686314"
+ fx="64"
+ fy="35.686314"
+ r="40" />
+ <radialGradient
+ xlink:href="#linearGradient3133"
+ id="radialGradient3417"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.1360441,0,0,1.446027,-72.706823,-25.184217)"
+ cx="64"
+ cy="35.686314"
+ fx="64"
+ fy="35.686314"
+ r="40" />
+ <filter
+ id="filter3351"
+ x="-0.048"
+ y="-0.048"
+ width="1.096"
+ height="1.096">
+ <feGaussianBlur
+ stdDeviation="2"
+ id="feGaussianBlur3353" />
+ </filter>
+ </defs>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1">
+ <rect
+ style="opacity:0.7;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3351)"
+ id="rect3305"
+ width="100"
+ height="100"
+ x="14"
+ y="14"
+ rx="7.4348507"
+ ry="7.4348507"
+ clip-path="url(#clipPath3393)" />
+ <rect
+ ry="5.6263733"
+ rx="5.6263733"
+ y="16"
+ x="16"
+ height="96"
+ width="96"
+ id="rect3141"
+ style="opacity:0.7;fill:#eeeeee;fill-opacity:1;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ style="opacity:1;fill:url(#radialGradient3139);fill-opacity:1.0;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect2160"
+ width="80"
+ height="80"
+ x="24"
+ y="24"
+ rx="5.6263733"
+ ry="5.6263733" />
+ <rect
+ style="opacity:0.7;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect3178"
+ width="95"
+ height="95"
+ x="16.5"
+ y="16.5"
+ rx="5.6263733"
+ ry="5.6263733" />
+ <g
+ id="g3160"
+ transform="matrix(1.6656201,0,0,1.6656201,-62.574569,-26.624804)"
+ style="fill:#ffffff;fill-opacity:1">
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 44.03125 40 L 55.34375 51.3125 C 43.467571 59.035057 35.734919 71.703669 57.34375 93.3125 C 52.734046 74.873684 60.878036 66.021115 70.75 66.71875 L 84 79.96875 L 84 73.3125 L 84 40 L 44.03125 40 z "
+ transform="matrix(0.600377,0,0,0.600377,37.568332,15.98492)"
+ id="path2179" />
+ </g>
+ </g>
+</svg>
diff --git a/launcher/resources/multimc/scalable/tag.svg b/launcher/resources/multimc/scalable/tag.svg
new file mode 100644
index 00000000..81b5d545
--- /dev/null
+++ b/launcher/resources/multimc/scalable/tag.svg
@@ -0,0 +1,398 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="33.866665mm"
+ height="33.866665mm"
+ viewBox="0 0 33.866665 33.866665"
+ version="1.1"
+ id="svg5"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <sodipodi:namedview
+ id="namedview7"
+ pagecolor="#505050"
+ bordercolor="#ffffff"
+ borderopacity="1"
+ inkscape:showpageshadow="0"
+ inkscape:pageopacity="0"
+ inkscape:pagecheckerboard="1"
+ inkscape:deskcolor="#505050"
+ inkscape:document-units="mm"
+ showgrid="false"
+ inkscape:zoom="1.6819304"
+ inkscape:cx="97.209729"
+ inkscape:cy="104.93894"
+ inkscape:window-width="1440"
+ inkscape:window-height="827"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="layer1" />
+ <defs
+ id="defs2">
+ <radialGradient
+ xlink:href="#linearGradient3291"
+ id="radialGradient10686"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.197802,0,92.82166)"
+ cx="63.912209"
+ cy="115.70919"
+ fx="42.094791"
+ fy="115.7093"
+ r="63.912209" />
+ <linearGradient
+ id="linearGradient3291">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop3293" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop3295" />
+ </linearGradient>
+ <radialGradient
+ xlink:href="#linearGradient3075"
+ id="radialGradient11644"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.844258,0,0,1.606667,44.38044,-98.18508)"
+ spreadMethod="reflect"
+ cx="-52.250774"
+ cy="128.00081"
+ fx="-52.250774"
+ fy="128.00081"
+ r="36.937431" />
+ <linearGradient
+ id="linearGradient3075">
+ <stop
+ id="stop3077"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0.42597079"
+ id="stop3093" />
+ <stop
+ style="stop-color:#f1f1f1;stop-opacity:1;"
+ offset="0.5892781"
+ id="stop3085" />
+ <stop
+ id="stop3087"
+ offset="0.80219781"
+ style="stop-color:#eaeaea;stop-opacity:1;" />
+ <stop
+ id="stop3079"
+ offset="1"
+ style="stop-color:#dfdfdf;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ xlink:href="#linearGradient2316"
+ id="linearGradient11646"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.835095,0,0,0.835095,6.816147,12.32049)"
+ x1="32.39278"
+ y1="79.018364"
+ x2="83.208656"
+ y2="79.018364" />
+ <linearGradient
+ id="linearGradient2316">
+ <stop
+ id="stop2318"
+ offset="0"
+ style="stop-color:#dd6a0e;stop-opacity:1;" />
+ <stop
+ id="stop2320"
+ offset="1"
+ style="stop-color:#ffb66d;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ xlink:href="#linearGradient5259"
+ id="linearGradient11648"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.267368,-0.06264141)"
+ x1="24.851341"
+ y1="60.846405"
+ x2="-35.981007"
+ y2="112.08296" />
+ <linearGradient
+ id="linearGradient5259">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop5261" />
+ <stop
+ id="stop5267"
+ offset="0.5"
+ style="stop-color:#7f7f7f;stop-opacity:0.33935019;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop5263" />
+ </linearGradient>
+ <linearGradient
+ xlink:href="#linearGradient2316"
+ id="linearGradient11654"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.835095,0,0,0.835095,7.613067,13.11741)"
+ x1="32.39278"
+ y1="79.018364"
+ x2="83.208656"
+ y2="79.018364" />
+ <linearGradient
+ xlink:href="#linearGradient7033"
+ id="linearGradient11656"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.144757,-0.233352)"
+ x1="96.437851"
+ y1="14.713447"
+ x2="96.397697"
+ y2="23.267729" />
+ <linearGradient
+ id="linearGradient7033">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop7035" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop7037" />
+ </linearGradient>
+ <linearGradient
+ xlink:href="#linearGradient2959"
+ id="linearGradient11658"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.965789,0,0,0.944211,3.248297,-0.448682)"
+ x1="111.30237"
+ y1="-18.911451"
+ x2="108.5625"
+ y2="26.541067" />
+ <linearGradient
+ y2="3.1118"
+ x2="17.0464"
+ y1="7.6073999"
+ x1="17.0464"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2959">
+ <stop
+ id="stop2961"
+ style="stop-color:#EEEEEE"
+ offset="0" />
+ <stop
+ id="stop2963"
+ style="stop-color:#CECECE"
+ offset="0.2909" />
+ <stop
+ id="stop2965"
+ style="stop-color:#888888"
+ offset="0.85" />
+ <stop
+ id="stop2967"
+ style="stop-color:#555555"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ xlink:href="#linearGradient7033"
+ id="linearGradient11660"
+ gradientUnits="userSpaceOnUse"
+ x1="65.073738"
+ y1="53.097416"
+ x2="62.605522"
+ y2="102.24165" />
+ <linearGradient
+ xlink:href="#linearGradient2959"
+ id="linearGradient11662"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.989491,0.144757,0.128566)"
+ x1="112.14121"
+ y1="0.22972308"
+ x2="108.5625"
+ y2="41.496986" />
+ <linearGradient
+ xlink:href="#linearGradient7033"
+ id="linearGradient11664"
+ gradientUnits="userSpaceOnUse"
+ x1="236.57014"
+ y1="-50.274925"
+ x2="2.61567"
+ y2="111.73157" />
+ <linearGradient
+ xlink:href="#linearGradient7033"
+ id="linearGradient11666"
+ gradientUnits="userSpaceOnUse"
+ x1="95.915977"
+ y1="-33.667568"
+ x2="32.102207"
+ y2="129.69464" />
+ <radialGradient
+ xlink:href="#linearGradient3291"
+ id="radialGradient11668"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.381766,0.111574,-0.139672,0.47791,70.02209,5.232857)"
+ cx="99.498825"
+ cy="33.076019"
+ fx="92.406448"
+ fy="33.504173"
+ r="17.845808" />
+ <linearGradient
+ xlink:href="#linearGradient2316"
+ id="linearGradient15192"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.835095,0,0,0.835095,5.637308,11.14165)"
+ x1="32.39278"
+ y1="79.018364"
+ x2="83.208656"
+ y2="79.018364" />
+ <linearGradient
+ xlink:href="#linearGradient3291"
+ id="linearGradient12566"
+ x1="96.686058"
+ y1="28.999111"
+ x2="109.04183"
+ y2="41.42416"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5259"
+ id="linearGradient3805"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.267368,-0.06264141)"
+ x1="24.851341"
+ y1="60.846405"
+ x2="-35.981007"
+ y2="112.08296" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5259"
+ id="linearGradient3807"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.267368,-0.06264141)"
+ x1="24.851341"
+ y1="60.846405"
+ x2="-35.981007"
+ y2="112.08296" />
+ </defs>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1">
+ <g
+ id="layer1-3"
+ transform="matrix(0.26458333,0,0,0.26458333,-0.0150732,-0.07996336)">
+ <path
+ id="path2276"
+ d="M 50.892799,3.2812959 V 0.48658747 Z"
+ style="fill:#ffffff;fill-opacity:0.756881;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ style="opacity:0.381395;fill:url(#radialGradient10686);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="path3289"
+ d="m 127.82442,115.70919 a 63.91221,12.641975 0 1 1 -127.82442,0 63.91221,12.641975 0 1 1 127.82442,0 z"
+ transform="matrix(1,0,0,0.416667,0.144757,74.63816)" />
+ <g
+ id="g11627"
+ transform="matrix(0.99373,0,0,0.99373,9.698994e-4,0.76812)">
+ <path
+ id="rect1410"
+ d="m 65.957252,16.860398 c -3.049556,-0.275801 -6.186939,0.749438 -8.53125,3.09375 l -54.125,54.09375 c -4.19508499,4.195085 -4.19508509,10.961163 0,15.15625 l 30.15625,30.156252 c 4.195085,4.19509 10.961166,4.19508 15.15625,0 L 102.70726,65.235398 c 2.49083,-2.490832 3.13273,-5.870037 3.125,-9.09375 l -0.0625,-28.6875 c 0,-5.932749 -4.786,-10.71875 -10.718753,-10.71875 0,0 -28.607642,0.09192 -29.093755,0.125 z m 28.843755,5.125 c 3.66262,-0.16143 6.156253,2.485447 6.156253,5.5625 0,3.077053 -2.485453,5.5625 -5.562503,5.5625 -3.07706,10e-7 -5.59375,-2.485447 -5.59375,-5.5625 0,-2.884737 2.18203,-5.438298 5,-5.5625 z"
+ style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.6;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:0.0431373" />
+ <rect
+ transform="rotate(-45)"
+ rx="7.8982348"
+ ry="7.8982348"
+ y="64.655273"
+ x="-51.673248"
+ height="44.167801"
+ width="73.874908"
+ id="rect3166"
+ style="opacity:1;fill:url(#radialGradient11644);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.6;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:0.0431373" />
+ <path
+ id="path3173"
+ d="M 75.885718,57.507812 34.284739,99.108794"
+ style="opacity:0.356557;fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:url(#linearGradient11646);stroke-width:6.681;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ style="opacity:0.229508;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient3805);stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="rect5257"
+ width="73.874908"
+ height="44.167801"
+ x="-51.673248"
+ y="64.655273"
+ ry="7.8982348"
+ rx="7.8982348"
+ transform="rotate(-45)" />
+ <rect
+ transform="rotate(-45)"
+ rx="7.8982348"
+ ry="7.8982348"
+ y="64.655273"
+ x="-51.673248"
+ height="44.167801"
+ width="73.874908"
+ id="rect5269"
+ style="opacity:0.229508;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient3807);stroke-width:4.7;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <rect
+ style="opacity:0.229508;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient11648);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="rect5271"
+ width="73.874908"
+ height="44.167801"
+ x="-51.673248"
+ y="64.655273"
+ ry="7.8982348"
+ rx="7.8982348"
+ transform="rotate(-45)" />
+ <path
+ style="opacity:0.356557;fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:url(#linearGradient11654);stroke-width:4.281;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 76.682637,58.304731 35.081658,99.905718"
+ id="path6146" />
+ <path
+ id="path7023"
+ d="m 95.974287,17.823297 c -10.492771,0 -20.733943,-0.08387 -31.226713,-0.08387 -1.762073,0 -4.255833,0.942555 -5.871767,2.558489 -1.660248,1.726659 -3.404362,3.117855 -5.064611,4.844513 2.414223,-2.414222 7.212846,-5.724904 11.093084,-5.724904 7.421011,0 27.351047,-0.0983 31.070007,-0.03189 3.71177,0 7.055473,2.121104 8.954723,5.410703 -0.68877,-1.943344 -4.67334,-6.973043 -8.954723,-6.973043 z"
+ style="fill:url(#linearGradient11656);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ style="opacity:1;fill:url(#linearGradient11658);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.281;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ d="m 100.82818,26.326961 c -1.890153,-1.727837 -3.415423,-4.670514 -3.415423,-7.920927 0,-3.533359 1.96775,-6.823917 4.142823,-9.4743797 2.17506,-2.6504632 5.28768,-4.1241296 7.58345,-4.64867 2.29577,-0.5245403 5.79507,-0.1221965 7.97013,1.534343 2.17508,1.6565394 3.47363,4.2591447 3.47363,7.7925027 0,3.533359 -2.02809,6.984823 -4.20316,9.635286 -2.17507,2.650461 -5.98704,4.450271 -8.28282,4.974812 -0.90522,0.206827 -1.39525,0.258815 -2.34919,0.16418 v 3.641114 c 0.90698,-0.07736 1.37675,-0.178048 2.34919,-0.400232 5.41187,-1.236508 9.82659,-4.36931 12.70617,-7.878262 2.87957,-3.508952 4.52714,-7.616269 4.52714,-11.71412 0,-4.0978497 -1.64757,-7.4555617 -4.52714,-9.6486567 -2.22718,-1.69622208 -5.36254,-2.77457075 -9.175,-2.59658065 -1.11678,0.0521386 -2.30504,0.22146591 -3.53117,0.50161219 -5.41185,1.23650756 -9.856773,4.39881646 -12.736353,7.90776816 -2.87957,3.508952 -4.49695,7.586762 -4.49695,11.684613 -1e-5,4.09785 1.61738,7.485066 4.49695,9.678163 0.53992,0.411206 2.4878,1.271962 1.78068,1.091745 -0.0068,-0.0017 1.96319,1.251665 1.85535,0.684439 1.810883,-0.738325 2.208813,-3.477697 1.831693,-5.00875 z"
+ id="path9411" />
+ <path
+ id="path10706"
+ d="m 90.5625,16.75 c -8.068686,0.0274 -24.229165,0.100191 -24.59375,0.125 -3.049557,-0.2758 -6.186939,0.749438 -8.53125,3.09375 L 7.84375,69.53125 c 11.529551,1.982326 27.892323,4.585247 51.125,7.96875 8.273982,1.204986 18.293655,2.036346 28.90625,2.59375 L 102.71875,65.25 c 2.49083,-2.490831 3.13273,-5.870037 3.125,-9.09375 l -0.0625,-28.6875 c 0,-5.932748 -4.786,-10.71875 -10.71875,-10.71875 -10e-7,0 -1.810438,-0.0091 -4.5,0 z m 4.3125,5.21875 c 3.6158,-0.116775 6.09375,2.540736 6.09375,5.59375 0,3.077054 -2.48545,5.5625 -5.5625,5.5625 -3.077063,2e-6 -5.59375,-2.485447 -5.59375,-5.5625 -3e-6,-2.884736 2.18203,-5.438298 5,-5.5625 0.02861,-0.0013 0.03403,-0.03033 0.0625,-0.03125 z"
+ style="opacity:0.110656;fill:url(#linearGradient11660);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.6;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:0.0431373" />
+ <path
+ id="path7046"
+ d="m 97.375359,32.751517 c 2.10015,-0.773731 3.390351,-2.538598 3.560031,-4.734753 -1.957113,-1.810695 -3.290633,-4.723021 -3.290633,-8.129308 -1e-5,-3.702801 2.03744,-7.151156 4.289563,-9.9287217 2.25211,-2.7775654 5.47498,-4.3219011 7.85207,-4.8715958 2.3771,-0.5496945 6.00035,-0.1280564 8.25246,1.6079222 2.25212,1.7359783 3.59667,4.4633913 3.59667,8.1661903 0,3.702801 -2.09993,7.319779 -4.35205,10.097344 -2.25211,2.777565 -6.19911,4.663684 -8.57621,5.213379 -0.93729,0.216746 -1.96089,0.315625 -2.94862,0.216451 v 3.815723 c 0.93911,-0.08107 1.94173,-0.230984 2.94862,-0.463824 5.60357,-1.295804 10.17467,-4.578839 13.15625,-8.256062 2.98157,-3.677222 4.6875,-7.981505 4.6875,-12.275868 0,-4.2943614 -1.70593,-7.8130918 -4.6875,-10.1113563 -2.30607,-1.7775641 -5.5525,-2.90762479 -9.5,-2.72109918 -1.15634,0.0546388 -2.38669,0.23208625 -3.65625,0.52566685 C 103.1037,2.1974095 98.501327,5.5113663 95.519757,9.1885892 c -2.98158,3.6772228 -4.65625,7.9505838 -4.65625,12.2449458 -1e-5,4.294362 1.67467,7.844014 4.65625,10.142279 0.55904,0.430925 1.186172,0.832604 1.855602,1.175703 z"
+ style="opacity:1;fill:url(#linearGradient11662);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.281;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ id="path11592"
+ d="m 87.21875,16.75 c -8.50359,0.03263 -20.930988,0.103292 -21.25,0.125 -3.049557,-0.2758 -6.186939,0.749438 -8.53125,3.09375 L 7.84375,69.53125 c 6.512962,1.119802 14.566555,2.45529 24.53125,4 11.012521,-17.30544 27.351155,-37.289448 38.8125,-46.875 4.644801,-3.884621 11.982929,-7.180912 20.34375,-9.90625 -0.306904,6.24e-4 -0.632555,-0.0011 -0.96875,0 -1.008586,0.0034 -2.128951,-0.0047 -3.34375,0 z m 18.375,8.6875 c -1.5547,0.686392 -3.10706,1.369523 -4.625,2.0625 3e-4,0.0238 0,0.03865 0,0.0625 0,3.077054 -2.48545,5.5625 -5.5625,5.5625 -1.334195,10e-7 -2.567233,-0.469835 -3.53125,-1.25 -6.682325,3.356446 -12.081361,6.518861 -14.59375,9.03125 -8.240797,8.240798 -15.526075,23.751079 -20.6875,36.25 0.784476,0.114764 1.574287,0.227138 2.375,0.34375 8.273982,1.204986 18.293655,2.036346 28.90625,2.59375 L 102.71875,65.25 c 2.49083,-2.490831 3.13273,-5.870037 3.125,-9.09375 l -0.0625,-28.6875 c 0,-0.695244 -0.0619,-1.373359 -0.1875,-2.03125 z"
+ style="opacity:0.20082;fill:url(#linearGradient11664);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.6;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:0.0431373" />
+ <path
+ style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.281;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ d="m 100.93539,27.951048 c -1.957113,-1.829927 -3.290633,-4.773185 -3.290633,-8.21565 -1e-5,-3.742128 1.49788,-7.442934 3.750003,-10.2499997 2.25211,-2.8070662 4.93541,-4.475717 7.3125,-5.03125 2.3771,-0.5555328 5.02914,-0.1294165 7.28125,1.625 2.25212,1.7544162 3.8125,4.7266227 3.8125,8.4687497 0,3.742128 -1.56038,7.505434 -3.8125,10.3125 -2.25211,2.807065 -4.90415,4.413217 -7.28125,4.96875 -0.93729,0.219048 -1.91852,0.318977 -2.90625,0.21875 v 4.15625 c 0.93911,-0.08193 1.89936,-0.233437 2.90625,-0.46875 5.60357,-1.309567 10.17467,-4.627471 13.15625,-8.34375 2.98157,-3.716278 4.6875,-8.066277 4.6875,-12.40625 0,-4.3399723 -1.70593,-7.8960753 -4.6875,-10.2187497 -2.30607,-1.79644362 -5.5525,-2.93850675 -9.5,-2.75000004 -1.15634,0.05521916 -2.38669,0.23455125 -3.65625,0.53125001 C 103.1037,1.8574651 98.501327,5.2066196 95.519757,8.9228983 c -2.98158,3.7162787 -4.65625,8.0350267 -4.65625,12.3749997 -1e-5,4.339973 1.67467,7.927325 4.65625,10.25 0.55904,0.435502 1.17432,0.809507 1.84375,1.15625 0.0064,0.0033 0.0248,-0.0033 0.03125,0 2.0689,-0.781949 3.370953,-2.53362 3.540633,-4.7531 z"
+ id="path8516" />
+ <path
+ style="opacity:0.143443;fill:url(#linearGradient11666);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.6;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:0.0431373"
+ d="m 87.21875,16.75 c -8.50359,0.03263 -20.930988,0.103292 -21.25,0.125 -3.049557,-0.2758 -6.186939,0.749438 -8.53125,3.09375 L 7.84375,69.53125 c 6.512962,1.119802 51.882405,-33.289448 63.34375,-42.875 4.644801,-3.884621 11.982929,-7.180912 20.34375,-9.90625 -0.306904,6.24e-4 -0.632555,-0.0011 -0.96875,0 -1.008586,0.0034 -2.128951,-0.0047 -3.34375,0 z m 18.375,8.6875 c -1.5547,0.686392 -3.10706,1.369523 -4.625,2.0625 3e-4,0.0238 0,0.03865 0,0.0625 0,3.077054 -2.48545,5.5625 -5.5625,5.5625 -1.334195,10e-7 -2.567233,-0.469835 -3.53125,-1.25 -6.682325,3.356446 -12.081361,6.518861 -14.59375,9.03125 -8.240797,8.240798 -0.01884,38.630096 10.59375,39.1875 L 102.71875,65.25 c 2.49083,-2.490831 3.13273,-5.870037 3.125,-9.09375 l -0.0625,-28.6875 c 0,-0.695244 -0.0619,-1.373359 -0.1875,-2.03125 z"
+ id="path11602" />
+ <path
+ style="opacity:0.606557;fill:url(#radialGradient11668);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.281;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ d="m 90.96875,26.46875 c 0.743967,2.297267 2.100743,4.216351 3.96875,5.65625 0.555536,0.428222 1.147267,0.846552 1.8125,1.1875 2.656083,-0.950513 4.01114,-3.505137 3.46875,-6.40625 -0.15257,-0.139467 -0.321073,-0.282994 -0.46875,-0.4375 z m 21.71875,0 c -1.83753,1.211058 -3.85538,2.017967 -5.28125,2.34375 -0.89954,0.205529 -1.36454,0.250292 -2.3125,0.15625 v 1.96875 1.65625 2.1875 c 0.93322,-0.08056 1.93692,-0.23737 2.9375,-0.46875 5.36542,-1.24073 9.78487,-4.350662 12.75,-7.84375 z"
+ transform="matrix(1.00631,0,0,1.00631,-9.76019e-4,-0.772966)"
+ id="path11610" />
+ <path
+ id="path14317"
+ d="M 74.706878,56.328972 33.105899,97.929959"
+ style="opacity:0.356557;fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:url(#linearGradient15192);stroke-width:10.0168;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ </g>
+ <path
+ style="opacity:0.536885;fill:#c5c5c5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ d="m 89.656712,30.354292 c 0.49124,2.325735 2.588013,4.056766 5.131181,4.056767 2.543162,0 4.679407,-1.731031 5.170643,-4.056767 -0.854771,1.932015 -2.866287,3.291339 -5.170643,3.291339 -2.30436,0 -4.276402,-1.359324 -5.131181,-3.291339 z"
+ id="path11672" />
+ <path
+ style="opacity:0.303279;fill:url(#linearGradient12566);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 100.18163,26.901091 c 1.15086,4.050666 3.65645,3.092196 4.93347,6.825449 v 2.355173 c -4.56581,-1.437505 -6.222135,-1.137689 -8.429042,-2.759676 2.139037,-0.83309 4.052592,-2.587176 3.495572,-6.420946 z"
+ id="path12550" />
+ </g>
+ </g>
+</svg>
diff --git a/launcher/resources/pe_blue/pe_blue.qrc b/launcher/resources/pe_blue/pe_blue.qrc
index 3121ffe6..639675f0 100644
--- a/launcher/resources/pe_blue/pe_blue.qrc
+++ b/launcher/resources/pe_blue/pe_blue.qrc
@@ -39,5 +39,6 @@
<file>scalable/export.svg</file>
<file>scalable/rename.svg</file>
<file>scalable/launch.svg</file>
+ <file>scalable/shortcut.svg</file>
</qresource>
</RCC>
diff --git a/launcher/resources/pe_blue/scalable/shortcut.svg b/launcher/resources/pe_blue/scalable/shortcut.svg
new file mode 100644
index 00000000..45b73496
--- /dev/null
+++ b/launcher/resources/pe_blue/scalable/shortcut.svg
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 18.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Calque_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 32 32" enable-background="new 0 0 32 32" xml:space="preserve">
+<path fill-rule="evenodd" clip-rule="evenodd" fill="#3366CC" d="M6,32h20c3.3,0,6-2.7,6-6V6c0-3.3-2.7-6-6-6h-9.1
+ C17.6,1.2,18,2.6,18,4h8c1.1,0,2,0.9,2,2v20c0,1.1-0.9,2-2,2H6c-1.1,0-2-0.9-2-2v-4.5l-4-3V26C0,29.3,2.7,32,6,32z"/>
+<path fill-rule="evenodd" clip-rule="evenodd" fill="#39B54A" d="M8.8,17.6C9.2,17.9,9.6,18,10,18c0.3,0,0.6-0.1,0.9-0.2
+ c0.7-0.3,1.1-1,1.1-1.8v-1.9V14c6.3,0,11.7,4.2,13.4,10c0.4-1.3,0.6-2.6,0.6-4c0-7.7-6.3-14-14-14V4c0-0.8-0.4-1.5-1.1-1.8
+ C10.6,2.1,10.3,2,10,2C9.6,2,9.2,2.1,8.8,2.4l-8,6C0.3,8.8,0,9.4,0,10c0,0.6,0.3,1.2,0.8,1.6L8.8,17.6z"/>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+</svg>
diff --git a/launcher/resources/pe_colored/pe_colored.qrc b/launcher/resources/pe_colored/pe_colored.qrc
index ce5ad8e2..fac58da8 100644
--- a/launcher/resources/pe_colored/pe_colored.qrc
+++ b/launcher/resources/pe_colored/pe_colored.qrc
@@ -39,5 +39,6 @@
<file>scalable/export.svg</file>
<file>scalable/rename.svg</file>
<file>scalable/launch.svg</file>
+ <file>scalable/shortcut.svg</file>
</qresource>
</RCC>
diff --git a/launcher/resources/pe_colored/scalable/shortcut.svg b/launcher/resources/pe_colored/scalable/shortcut.svg
new file mode 100644
index 00000000..1469674f
--- /dev/null
+++ b/launcher/resources/pe_colored/scalable/shortcut.svg
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 18.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Calque_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 32 32" enable-background="new 0 0 32 32" xml:space="preserve">
+<g>
+ <path fill="#39B54A" d="M26,0h-9.1C17.6,1.2,18,2.6,18,4h8c1.1,0,2,0.9,2,2v3h4V6C32,2.7,29.3,0,26,0z"/>
+ <path fill="#8C6239" d="M28,26c0,1.1-0.9,2-2,2H6c-1.1,0-2-0.9-2-2v-4.5l-4-3V26c0,3.3,2.7,6,6,6h20c3.3,0,6-2.7,6-6V9h-4V26z"/>
+</g>
+<path fill-rule="evenodd" clip-rule="evenodd" fill="#009245" d="M8.8,17.6C9.2,17.9,9.6,18,10,18c0.3,0,0.6-0.1,0.9-0.2
+ c0.7-0.3,1.1-1,1.1-1.8v-1.9V14c6.3,0,11.7,4.2,13.4,10c0.4-1.3,0.6-2.6,0.6-4c0-7.7-6.3-14-14-14V4c0-0.8-0.4-1.5-1.1-1.8
+ C10.6,2.1,10.3,2,10,2C9.6,2,9.2,2.1,8.8,2.4l-8,6C0.3,8.8,0,9.4,0,10c0,0.6,0.3,1.2,0.8,1.6L8.8,17.6z"/>
+</svg>
diff --git a/launcher/resources/pe_dark/pe_dark.qrc b/launcher/resources/pe_dark/pe_dark.qrc
index 156d8f8b..c0c6ee6c 100644
--- a/launcher/resources/pe_dark/pe_dark.qrc
+++ b/launcher/resources/pe_dark/pe_dark.qrc
@@ -39,5 +39,6 @@
<file>scalable/export.svg</file>
<file>scalable/rename.svg</file>
<file>scalable/launch.svg</file>
+ <file>scalable/shortcut.svg</file>
</qresource>
</RCC>
diff --git a/launcher/resources/pe_dark/scalable/shortcut.svg b/launcher/resources/pe_dark/scalable/shortcut.svg
new file mode 100644
index 00000000..29b45f26
--- /dev/null
+++ b/launcher/resources/pe_dark/scalable/shortcut.svg
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 18.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Calque_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 32 32" enable-background="new 0 0 32 32" xml:space="preserve">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M6,32h20c3.3,0,6-2.7,6-6V6c0-3.3-2.7-6-6-6h-9.1C17.6,1.2,18,2.6,18,4h8
+ c1.1,0,2,0.9,2,2v20c0,1.1-0.9,2-2,2H6c-1.1,0-2-0.9-2-2v-4.5l-4-3V26C0,29.3,2.7,32,6,32z"/>
+<path fill-rule="evenodd" clip-rule="evenodd" fill="#666666" d="M8.8,17.6C9.2,17.9,9.6,18,10,18c0.3,0,0.6-0.1,0.9-0.2
+ c0.7-0.3,1.1-1,1.1-1.8v-1.9V14c6.3,0,11.7,4.2,13.4,10c0.4-1.3,0.6-2.6,0.6-4c0-7.7-6.3-14-14-14V4c0-0.8-0.4-1.5-1.1-1.8
+ C10.6,2.1,10.3,2,10,2C9.6,2,9.2,2.1,8.8,2.4l-8,6C0.3,8.8,0,9.4,0,10c0,0.6,0.3,1.2,0.8,1.6L8.8,17.6z"/>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+</svg>
diff --git a/launcher/resources/pe_light/pe_light.qrc b/launcher/resources/pe_light/pe_light.qrc
index d8e4a1bd..bd6a2496 100644
--- a/launcher/resources/pe_light/pe_light.qrc
+++ b/launcher/resources/pe_light/pe_light.qrc
@@ -39,5 +39,6 @@
<file>scalable/export.svg</file>
<file>scalable/rename.svg</file>
<file>scalable/launch.svg</file>
+ <file>scalable/shortcut.svg</file>
</qresource>
</RCC>
diff --git a/launcher/resources/pe_light/scalable/shortcut.svg b/launcher/resources/pe_light/scalable/shortcut.svg
new file mode 100644
index 00000000..4d232bcf
--- /dev/null
+++ b/launcher/resources/pe_light/scalable/shortcut.svg
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 18.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Calque_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 32 32" enable-background="new 0 0 32 32" xml:space="preserve">
+<path fill-rule="evenodd" clip-rule="evenodd" fill="#F2F2F2" d="M6,32h20c3.3,0,6-2.7,6-6V6c0-3.3-2.7-6-6-6h-9.1
+ C17.6,1.2,18,2.6,18,4h8c1.1,0,2,0.9,2,2v20c0,1.1-0.9,2-2,2H6c-1.1,0-2-0.9-2-2v-4.5l-4-3V26C0,29.3,2.7,32,6,32z"/>
+<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" d="M8.8,17.6C9.2,17.9,9.6,18,10,18c0.3,0,0.6-0.1,0.9-0.2
+ c0.7-0.3,1.1-1,1.1-1.8v-1.9V14c6.3,0,11.7,4.2,13.4,10c0.4-1.3,0.6-2.6,0.6-4c0-7.7-6.3-14-14-14V4c0-0.8-0.4-1.5-1.1-1.8
+ C10.6,2.1,10.3,2,10,2C9.6,2,9.2,2.1,8.8,2.4l-8,6C0.3,8.8,0,9.4,0,10c0,0.6,0.3,1.2,0.8,1.6L8.8,17.6z"/>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+</svg>
diff --git a/launcher/translations/TranslationsModel.cpp b/launcher/translations/TranslationsModel.cpp
index 20aa6d04..38f48296 100644
--- a/launcher/translations/TranslationsModel.cpp
+++ b/launcher/translations/TranslationsModel.cpp
@@ -83,12 +83,21 @@ struct Language
else if(key == "es_UY") {
result = u8"español de Latinoamérica";
}
+ else if(key == "en_NZ") {
+ result = u8"New Zealand English"; // No idea why qt translates this to just english and not to New Zealand English
+ }
else if(key == "en@pirate") {
result = u8"Tongue of the High Seas";
}
else if(key == "en@uwu") {
result = u8"Cute Engwish";
}
+ else if(key == "tok") {
+ result = u8"toki pona";
+ }
+ else if(key == "nan") {
+ result = u8"閩南語"; // Using traditional Chinese script. Not sure if we should use simplified instead?
+ }
else {
result = locale.nativeLanguageName();
}
diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp
index 85b00b67..34c2ad22 100644
--- a/launcher/ui/MainWindow.cpp
+++ b/launcher/ui/MainWindow.cpp
@@ -39,6 +39,7 @@
#include "Application.h"
#include "BuildConfig.h"
+#include "FileSystem.h"
#include "MainWindow.h"
@@ -49,7 +50,7 @@
#include <QKeyEvent>
#include <QAction>
-
+#include <QActionGroup>
#include <QApplication>
#include <QButtonGroup>
#include <QHBoxLayout>
@@ -61,6 +62,7 @@
#include <QMenu>
#include <QMenuBar>
#include <QMessageBox>
+#include <QFileDialog>
#include <QInputDialog>
#include <QLabel>
#include <QToolButton>
@@ -105,6 +107,7 @@
#include "ui/dialogs/UpdateDialog.h"
#include "ui/dialogs/EditAccountDialog.h"
#include "ui/dialogs/ExportInstanceDialog.h"
+#include "ui/themes/ITheme.h"
#include "UpdateController.h"
#include "KonamiCode.h"
@@ -237,6 +240,7 @@ public:
TranslatedAction actionLaunchInstanceOffline;
TranslatedAction actionLaunchInstanceDemo;
TranslatedAction actionExportInstance;
+ TranslatedAction actionCreateInstanceShortcut;
QVector<TranslatedAction *> all_actions;
LabeledToolButton *renameButton = nullptr;
@@ -253,6 +257,9 @@ public:
QMenu * helpMenu = nullptr;
TranslatedToolButton helpMenuButton;
TranslatedAction actionClearMetadata;
+ #ifdef Q_OS_MAC
+ TranslatedAction actionAddToPATH;
+ #endif
TranslatedAction actionReportBug;
TranslatedAction actionDISCORD;
TranslatedAction actionMATRIX;
@@ -264,6 +271,8 @@ public:
TranslatedAction actionLockToolbars;
+ TranslatedAction actionChangeTheme;
+
QVector<TranslatedToolButton *> all_toolbuttons;
QWidget *centralWidget = nullptr;
@@ -290,7 +299,6 @@ public:
actionAddInstance = TranslatedAction(MainWindow);
actionAddInstance->setObjectName(QStringLiteral("actionAddInstance"));
actionAddInstance->setIcon(APPLICATION->getThemedIcon("new"));
- actionAddInstance->setIconVisibleInMenu(false);
actionAddInstance.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Add Instanc&e..."));
actionAddInstance.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Add a new instance."));
actionAddInstance->setShortcut(QKeySequence::New);
@@ -350,6 +358,14 @@ public:
actionClearMetadata.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Clear cached metadata"));
all_actions.append(&actionClearMetadata);
+ #ifdef Q_OS_MAC
+ actionAddToPATH = TranslatedAction(MainWindow);
+ actionAddToPATH->setObjectName(QStringLiteral("actionAddToPATH"));
+ actionAddToPATH.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Install to &PATH"));
+ actionAddToPATH.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Install a prismlauncher symlink to /usr/local/bin"));
+ all_actions.append(&actionAddToPATH);
+ #endif
+
if (!BuildConfig.BUG_TRACKER_URL.isEmpty()) {
actionReportBug = TranslatedAction(MainWindow);
actionReportBug->setObjectName(QStringLiteral("actionReportBug"));
@@ -428,6 +444,11 @@ public:
actionLockToolbars.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Lock Toolbars"));
actionLockToolbars->setCheckable(true);
all_actions.append(&actionLockToolbars);
+
+ actionChangeTheme = TranslatedAction(MainWindow);
+ actionChangeTheme->setObjectName(QStringLiteral("actionChangeTheme"));
+ actionChangeTheme.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Themes"));
+ all_actions.append(&actionChangeTheme);
}
void createMainToolbar(QMainWindow *MainWindow)
@@ -455,6 +476,10 @@ public:
helpMenu->addAction(actionClearMetadata);
+ #ifdef Q_OS_MAC
+ helpMenu->addAction(actionAddToPATH);
+ #endif
+
if (!BuildConfig.BUG_TRACKER_URL.isEmpty()) {
helpMenu->addAction(actionReportBug);
}
@@ -509,8 +534,6 @@ public:
fileMenu->setSeparatorsCollapsible(false);
fileMenu->addAction(actionAddInstance);
fileMenu->addAction(actionLaunchInstance);
- fileMenu->addAction(actionLaunchInstanceOffline);
- fileMenu->addAction(actionLaunchInstanceDemo);
fileMenu->addAction(actionKillInstance);
fileMenu->addAction(actionCloseWindow);
fileMenu->addSeparator();
@@ -528,6 +551,8 @@ public:
viewMenu = menuBar->addMenu(tr("&View"));
viewMenu->setSeparatorsCollapsible(false);
+ viewMenu->addAction(actionChangeTheme);
+ viewMenu->addSeparator();
viewMenu->addAction(actionCAT);
viewMenu->addSeparator();
@@ -542,6 +567,9 @@ public:
helpMenu = menuBar->addMenu(tr("&Help"));
helpMenu->setSeparatorsCollapsible(false);
helpMenu->addAction(actionClearMetadata);
+ #ifdef Q_OS_MAC
+ helpMenu->addAction(actionAddToPATH);
+ #endif
helpMenu->addSeparator();
helpMenu->addAction(actionAbout);
helpMenu->addAction(actionOpenWiki);
@@ -555,10 +583,11 @@ public:
helpMenu->addAction(actionDISCORD);
if (!BuildConfig.SUBREDDIT_URL.isEmpty())
helpMenu->addAction(actionREDDIT);
- helpMenu->addSeparator();
if(BuildConfig.UPDATER_ENABLED)
+ {
+ helpMenu->addSeparator();
helpMenu->addAction(actionCheckUpdate);
-
+ }
MainWindow->setMenuBar(menuBar);
}
@@ -576,6 +605,7 @@ public:
actionOpenWiki->setObjectName(QStringLiteral("actionOpenWiki"));
actionOpenWiki.setTextId(QT_TRANSLATE_NOOP("MainWindow", "%1 &Help"));
actionOpenWiki.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open the %1 wiki"));
+ actionOpenWiki->setIcon(APPLICATION->getThemedIcon("help"));
connect(actionOpenWiki, &QAction::triggered, MainWindow, &MainWindow::on_actionOpenWiki_triggered);
all_actions.append(&actionOpenWiki);
@@ -583,6 +613,7 @@ public:
actionNewsMenuBar->setObjectName(QStringLiteral("actionNewsMenuBar"));
actionNewsMenuBar.setTextId(QT_TRANSLATE_NOOP("MainWindow", "%1 &News"));
actionNewsMenuBar.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open the %1 wiki"));
+ actionNewsMenuBar->setIcon(APPLICATION->getThemedIcon("news"));
connect(actionNewsMenuBar, &QAction::triggered, MainWindow, &MainWindow::on_actionMoreNews_triggered);
all_actions.append(&actionNewsMenuBar);
}
@@ -597,6 +628,7 @@ public:
actionExportInstance->setEnabled(enabled);
actionDeleteInstance->setEnabled(enabled);
actionCopyInstance->setEnabled(enabled);
+ actionCreateInstanceShortcut->setEnabled(enabled);
}
void createStatusBar(QMainWindow *MainWindow)
@@ -735,6 +767,15 @@ public:
actionCopyInstance->setIcon(APPLICATION->getThemedIcon("copy"));
all_actions.append(&actionCopyInstance);
+ actionCreateInstanceShortcut = TranslatedAction(MainWindow);
+ actionCreateInstanceShortcut->setObjectName(QStringLiteral("actionCreateInstanceShortcut"));
+ actionCreateInstanceShortcut.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Create Shortcut"));
+ actionCreateInstanceShortcut.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Creates a shortcut on your desktop to launch the selected instance."));
+ //actionCreateInstanceShortcut->setShortcut(QKeySequence(tr("Ctrl+D"))); // TODO
+ // FIXME missing on Legacy, Flat and Flat (White)
+ actionCreateInstanceShortcut->setIcon(APPLICATION->getThemedIcon("shortcut"));
+ all_actions.append(&actionCreateInstanceShortcut);
+
setInstanceActionsEnabled(false);
}
@@ -773,6 +814,8 @@ public:
instanceToolBar->addAction(actionCopyInstance);
instanceToolBar->addAction(actionDeleteInstance);
+ instanceToolBar->addAction(actionCreateInstanceShortcut); // TODO find better position for this
+
QLayout * lay = instanceToolBar->layout();
for(int i = 0; i < lay->count(); i++)
{
@@ -822,6 +865,7 @@ public:
createInstanceToolbar(MainWindow);
MainWindow->updateToolsMenu();
+ MainWindow->updateThemeMenu();
retranslateUi(MainWindow);
@@ -1271,6 +1315,38 @@ void MainWindow::updateToolsMenu()
ui->actionLaunchInstance->setMenu(launchMenu);
}
+void MainWindow::updateThemeMenu()
+{
+ QMenu *themeMenu = ui->actionChangeTheme->menu();
+
+ if (themeMenu) {
+ themeMenu->clear();
+ } else {
+ themeMenu = new QMenu(this);
+ }
+
+ auto themes = APPLICATION->getValidApplicationThemes();
+
+ QActionGroup* themesGroup = new QActionGroup( this );
+
+ for (auto* theme : themes) {
+ QAction * themeAction = themeMenu->addAction(theme->name());
+
+ themeAction->setCheckable(true);
+ if (APPLICATION->settings()->get("ApplicationTheme").toString() == theme->id()) {
+ themeAction->setChecked(true);
+ }
+ themeAction->setActionGroup(themesGroup);
+
+ connect(themeAction, &QAction::triggered, [theme]() {
+ APPLICATION->setApplicationTheme(theme->id(),false);
+ APPLICATION->settings()->set("ApplicationTheme", theme->id());
+ });
+ }
+
+ ui->actionChangeTheme->setMenu(themeMenu);
+}
+
void MainWindow::repopulateAccountsMenu()
{
accountMenu->clear();
@@ -1901,6 +1977,7 @@ void MainWindow::globalSettingsClosed()
proxymodel->sort(0);
updateMainToolBar();
updateToolsMenu();
+ updateThemeMenu();
updateStatusCenter();
// This needs to be done to prevent UI elements disappearing in the event the config is changed
// but Prism Launcher exits abnormally, causing the window state to never be saved:
@@ -1929,6 +2006,29 @@ void MainWindow::on_actionClearMetadata_triggered()
APPLICATION->metacache()->SaveNow();
}
+#ifdef Q_OS_MAC
+void MainWindow::on_actionAddToPATH_triggered()
+{
+ auto binaryPath = APPLICATION->applicationFilePath();
+ auto targetPath = QString("/usr/local/bin/%1").arg(BuildConfig.LAUNCHER_APP_BINARY_NAME);
+ qDebug() << "Symlinking" << binaryPath << "to" << targetPath;
+
+ QStringList args;
+ args << "-e";
+ args << QString("do shell script \"mkdir -p /usr/local/bin && ln -sf '%1' '%2'\" with administrator privileges")
+ .arg(binaryPath, targetPath);
+ auto outcome = QProcess::execute("/usr/bin/osascript", args);
+ if (!outcome) {
+ QMessageBox::information(this, tr("Successfully added %1 to PATH").arg(BuildConfig.LAUNCHER_DISPLAYNAME),
+ tr("%1 was successfully added to your PATH. You can now start it by running `%2`.")
+ .arg(BuildConfig.LAUNCHER_DISPLAYNAME, BuildConfig.LAUNCHER_APP_BINARY_NAME));
+ } else {
+ QMessageBox::critical(this, tr("Failed to add %1 to PATH").arg(BuildConfig.LAUNCHER_DISPLAYNAME),
+ tr("An error occurred while trying to add %1 to PATH").arg(BuildConfig.LAUNCHER_DISPLAYNAME));
+ }
+}
+#endif
+
void MainWindow::on_actionOpenWiki_triggered()
{
DesktopServices::openUrl(QUrl(BuildConfig.HELP_URL.arg("")));
@@ -2075,6 +2175,130 @@ void MainWindow::on_actionKillInstance_triggered()
}
}
+void MainWindow::on_actionCreateInstanceShortcut_triggered()
+{
+ if (m_selectedInstance)
+ {
+ auto desktopPath = FS::getDesktopDir();
+ if (desktopPath.isEmpty()) {
+ // TODO come up with an alternative solution (open "save file" dialog)
+ QMessageBox::critical(this, tr("Create instance shortcut"), tr("Couldn't find desktop?!"));
+ return;
+ }
+
+#if defined(Q_OS_MACOS)
+ QString appPath = QApplication::applicationFilePath();
+ if (appPath.startsWith("/private/var/")) {
+ QMessageBox::critical(this, tr("Create instance shortcut"), tr("The launcher is in the folder it was extracted from, therefore it cannot create shortcuts."));
+ return;
+ }
+
+ if (FS::createShortcut(FS::PathCombine(desktopPath, m_selectedInstance->name()),
+ appPath, { "--launch", m_selectedInstance->id() },
+ m_selectedInstance->name(), "")) {
+ QMessageBox::information(this, tr("Create instance shortcut"), tr("Created a shortcut to this instance on your desktop!"));
+ }
+ else
+ {
+ QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create instance shortcut!"));
+ }
+#elif defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD)
+ QString appPath = QApplication::applicationFilePath();
+ if (appPath.startsWith("/tmp/.mount_")) {
+ // AppImage!
+ appPath = QProcessEnvironment::systemEnvironment().value(QStringLiteral("APPIMAGE"));
+ if (appPath.isEmpty())
+ {
+ QMessageBox::critical(this, tr("Create instance shortcut"), tr("Launcher is running as misconfigured AppImage? ($APPIMAGE environment variable is missing)"));
+ }
+ else if (appPath.endsWith("/"))
+ {
+ appPath.chop(1);
+ }
+ }
+
+ auto icon = APPLICATION->icons()->icon(m_selectedInstance->iconKey());
+ if (icon == nullptr)
+ {
+ icon = APPLICATION->icons()->icon("grass");
+ }
+
+ QString iconPath = FS::PathCombine(m_selectedInstance->instanceRoot(), "icon.png");
+
+ QFile iconFile(iconPath);
+ if (!iconFile.open(QFile::WriteOnly))
+ {
+ QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create icon for shortcut."));
+ return;
+ }
+ bool success = icon->icon().pixmap(64, 64).save(&iconFile, "PNG");
+ iconFile.close();
+
+ if (!success)
+ {
+ iconFile.remove();
+ QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create icon for shortcut."));
+ return;
+ }
+
+ if (FS::createShortcut(FS::PathCombine(desktopPath, m_selectedInstance->name()),
+ appPath, { "--launch", m_selectedInstance->id() },
+ m_selectedInstance->name(), iconPath)) {
+ QMessageBox::information(this, tr("Create instance shortcut"), tr("Created a shortcut to this instance on your desktop!"));
+ }
+ else
+ {
+ iconFile.remove();
+ QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create instance shortcut!"));
+ }
+#elif defined(Q_OS_WIN)
+ auto icon = APPLICATION->icons()->icon(m_selectedInstance->iconKey());
+ if (icon == nullptr)
+ {
+ icon = APPLICATION->icons()->icon("grass");
+ }
+
+ QString iconPath = FS::PathCombine(m_selectedInstance->instanceRoot(), "icon.ico");
+
+ // part of fix for weird bug involving the window icon being replaced
+ // dunno why it happens, but this 2-line fix seems to be enough, so w/e
+ auto appIcon = APPLICATION->getThemedIcon("logo");
+
+ QFile iconFile(iconPath);
+ if (!iconFile.open(QFile::WriteOnly))
+ {
+ QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create icon for shortcut."));
+ return;
+ }
+ bool success = icon->icon().pixmap(64, 64).save(&iconFile, "ICO");
+ iconFile.close();
+
+ // restore original window icon
+ QGuiApplication::setWindowIcon(appIcon);
+
+ if (!success)
+ {
+ iconFile.remove();
+ QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create icon for shortcut."));
+ return;
+ }
+
+ if (FS::createShortcut(FS::PathCombine(desktopPath, m_selectedInstance->name()),
+ QApplication::applicationFilePath(), { "--launch", m_selectedInstance->id() },
+ m_selectedInstance->name(), iconPath)) {
+ QMessageBox::information(this, tr("Create instance shortcut"), tr("Created a shortcut to this instance on your desktop!"));
+ }
+ else
+ {
+ iconFile.remove();
+ QMessageBox::critical(this, tr("Create instance shortcut"), tr("Failed to create instance shortcut!"));
+ }
+#else
+ QMessageBox::critical(this, tr("Create instance shortcut"), tr("Not supported on your platform!"));
+#endif
+ }
+}
+
void MainWindow::taskEnd()
{
QObject *sender = QObject::sender();
diff --git a/launcher/ui/MainWindow.h b/launcher/ui/MainWindow.h
index f9d1f1c7..f96f641d 100644
--- a/launcher/ui/MainWindow.h
+++ b/launcher/ui/MainWindow.h
@@ -128,6 +128,10 @@ private slots:
void on_actionClearMetadata_triggered();
+ #ifdef Q_OS_MAC
+ void on_actionAddToPATH_triggered();
+ #endif
+
void on_actionOpenWiki_triggered();
void on_actionMoreNews_triggered();
@@ -157,6 +161,8 @@ private slots:
void on_actionEditInstance_triggered();
+ void on_actionCreateInstanceShortcut_triggered();
+
void taskEnd();
/**
@@ -170,6 +176,8 @@ private slots:
void updateToolsMenu();
+ void updateThemeMenu();
+
void instanceActivated(QModelIndex);
void instanceChanged(const QModelIndex &current, const QModelIndex &previous);
diff --git a/launcher/ui/dialogs/BlockedModsDialog.cpp b/launcher/ui/dialogs/BlockedModsDialog.cpp
index fe87b517..edb4ff7d 100644
--- a/launcher/ui/dialogs/BlockedModsDialog.cpp
+++ b/launcher/ui/dialogs/BlockedModsDialog.cpp
@@ -1,28 +1,321 @@
#include "BlockedModsDialog.h"
-#include "ui_BlockedModsDialog.h"
-#include <QPushButton>
-#include <QDialogButtonBox>
#include <QDesktopServices>
+#include <QDialogButtonBox>
+#include <QPushButton>
+#include "Application.h"
+#include "ui_BlockedModsDialog.h"
+#include <QDebug>
+#include <QDragEnterEvent>
+#include <QFileDialog>
+#include <QFileInfo>
+#include <QStandardPaths>
+
+BlockedModsDialog::BlockedModsDialog(QWidget* parent, const QString& title, const QString& text, QList<BlockedMod>& mods)
+ : QDialog(parent), ui(new Ui::BlockedModsDialog), m_mods(mods)
+{
+ m_hashing_task = shared_qobject_ptr<ConcurrentTask>(new ConcurrentTask(this, "MakeHashesTask", 10));
+ connect(m_hashing_task.get(), &Task::finished, this, &BlockedModsDialog::hashTaskFinished);
-BlockedModsDialog::BlockedModsDialog(QWidget *parent, const QString &title, const QString &text, const QString &body, const QList<QUrl> &urls) :
- QDialog(parent), ui(new Ui::BlockedModsDialog), urls(urls) {
ui->setupUi(this);
auto openAllButton = ui->buttonBox->addButton(tr("Open All"), QDialogButtonBox::ActionRole);
connect(openAllButton, &QPushButton::clicked, this, &BlockedModsDialog::openAll);
+ auto downloadFolderButton = ui->buttonBox->addButton(tr("Add Download Folder"), QDialogButtonBox::ActionRole);
+ connect(downloadFolderButton, &QPushButton::clicked, this, &BlockedModsDialog::addDownloadFolder);
+
+ connect(&m_watcher, &QFileSystemWatcher::directoryChanged, this, &BlockedModsDialog::directoryChanged);
+
+ qDebug() << "[Blocked Mods Dialog] Mods List: " << mods;
+
+ setupWatch();
+ scanPaths();
+
this->setWindowTitle(title);
- ui->label->setText(text);
- ui->textBrowser->setText(body);
+ ui->labelDescription->setText(text);
+ ui->labelExplain->setText(
+ QString(tr("Your configured global mods folder and default downloads folder "
+ "are automatically checked for the downloaded mods and they will be copied to the instance if found.<br/>"
+ "Optionally, you may drag and drop the downloaded mods onto this dialog or add a folder to watch "
+ "if you did not download the mods to a default location."))
+ .arg(APPLICATION->settings()->get("CentralModsDir").toString(),
+ QStandardPaths::writableLocation(QStandardPaths::DownloadLocation)));
+
+ // force all URL handeling as external
+ connect(ui->textBrowserWatched, &QTextBrowser::anchorClicked, this, [](const QUrl url) { QDesktopServices::openUrl(url); });
+
+ setAcceptDrops(true);
+
+ update();
}
-BlockedModsDialog::~BlockedModsDialog() {
+BlockedModsDialog::~BlockedModsDialog()
+{
delete ui;
}
-void BlockedModsDialog::openAll() {
- for(auto &url : urls) {
- QDesktopServices::openUrl(url);
+void BlockedModsDialog::dragEnterEvent(QDragEnterEvent* e)
+{
+ if (e->mimeData()->hasUrls()) {
+ e->acceptProposedAction();
+ }
+}
+
+void BlockedModsDialog::dropEvent(QDropEvent* e)
+{
+ for (const QUrl& url : e->mimeData()->urls()) {
+ QString filePath = url.toLocalFile();
+ qDebug() << "[Blocked Mods Dialog] Dropped file:" << filePath;
+ addHashTask(filePath);
+
+ // watch for changes
+ QFileInfo file = QFileInfo(filePath);
+ QString path = file.dir().absolutePath();
+ qDebug() << "[Blocked Mods Dialog] Adding watch path:" << path;
+ m_watcher.addPath(path);
+ }
+ scanPaths();
+ update();
+}
+
+void BlockedModsDialog::openAll()
+{
+ for (auto& mod : m_mods) {
+ QDesktopServices::openUrl(mod.websiteUrl);
+ }
+}
+
+void BlockedModsDialog::addDownloadFolder()
+{
+ QString dir =
+ QFileDialog::getExistingDirectory(this, tr("Select directory where you downloaded the mods"),
+ QStandardPaths::writableLocation(QStandardPaths::DownloadLocation), QFileDialog::ShowDirsOnly);
+ qDebug() << "[Blocked Mods Dialog] Adding watch path:" << dir;
+ m_watcher.addPath(dir);
+ scanPath(dir, true);
+ update();
+}
+
+/// @brief update UI with current status of the blocked mod detection
+void BlockedModsDialog::update()
+{
+ QString text;
+ QString span;
+
+ for (auto& mod : m_mods) {
+ if (mod.matched) {
+ // &#x2714; -> html for HEAVY CHECK MARK : ✔
+ span = QString(tr("<span style=\"color:green\"> &#x2714; Found at %1 </span>")).arg(mod.localPath);
+ } else {
+ // &#x2718; -> html for HEAVY BALLOT X : ✘
+ span = QString(tr("<span style=\"color:red\"> &#x2718; Not Found </span>"));
+ }
+ text += QString(tr("%1: <a href='%2'>%2</a> <p>Hash: %3 %4</p> <br/>")).arg(mod.name, mod.websiteUrl, mod.hash, span);
+ }
+
+ ui->textBrowserModsListing->setText(text);
+
+ QString watching;
+ for (auto& dir : m_watcher.directories()) {
+ watching += QString("<a href=\"%1\">%1</a><br/>").arg(dir);
+ }
+
+ ui->textBrowserWatched->setText(watching);
+
+ if (allModsMatched()) {
+ ui->labelModsFound->setText("<span style=\"color:green\">✔</span>" + tr("All mods found"));
+ } else {
+ ui->labelModsFound->setText(tr("Please download the missing mods."));
+ }
+}
+
+/// @brief Signal fired when a watched direcotry has changed
+/// @param path the path to the changed directory
+void BlockedModsDialog::directoryChanged(QString path)
+{
+ qDebug() << "[Blocked Mods Dialog] Directory changed: " << path;
+ validateMatchedMods();
+ scanPath(path, true);
+}
+
+/// @brief add the user downloads folder and the global mods folder to the filesystem watcher
+void BlockedModsDialog::setupWatch()
+{
+ const QString downloadsFolder = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
+ const QString modsFolder = APPLICATION->settings()->get("CentralModsDir").toString();
+ m_watcher.addPath(downloadsFolder);
+ m_watcher.addPath(modsFolder);
+}
+
+/// @brief scan all watched folder
+void BlockedModsDialog::scanPaths()
+{
+ for (auto& dir : m_watcher.directories()) {
+ scanPath(dir, false);
}
+ runHashTask();
+}
+
+/// @brief Scan the directory at path, skip paths that do not contain a file name
+/// of a blocked mod we are looking for
+/// @param path the directory to scan
+void BlockedModsDialog::scanPath(QString path, bool start_task)
+{
+ QDir scan_dir(path);
+ QDirIterator scan_it(path, QDir::Filter::Files | QDir::Filter::Hidden, QDirIterator::NoIteratorFlags);
+ while (scan_it.hasNext()) {
+ QString file = scan_it.next();
+
+ if (!checkValidPath(file)) {
+ continue;
+ }
+
+ addHashTask(file);
+ }
+
+ if (start_task) {
+ runHashTask();
+ }
+}
+
+/// @brief add a hashing task for the file located at path, add the path to the pending set if the hasing task is already running
+/// @param path the path to the local file being hashed
+void BlockedModsDialog::addHashTask(QString path)
+{
+ qDebug() << "[Blocked Mods Dialog] adding a Hash task for" << path << "to the pending set.";
+ m_pending_hash_paths.insert(path);
+}
+
+/// @brief add a hashing task for the file located at path and connect it to check that hash against
+/// our blocked mods list
+/// @param path the path to the local file being hashed
+void BlockedModsDialog::buildHashTask(QString path)
+{
+ auto hash_task = Hashing::createBlockedModHasher(path, ModPlatform::Provider::FLAME, "sha1");
+
+ qDebug() << "[Blocked Mods Dialog] Creating Hash task for path: " << path;
+
+ connect(hash_task.get(), &Task::succeeded, this, [this, hash_task, path] { checkMatchHash(hash_task->getResult(), path); });
+ connect(hash_task.get(), &Task::failed, this, [path] { qDebug() << "Failed to hash path: " << path; });
+
+ m_hashing_task->addTask(hash_task);
+}
+
+/// @brief check if the computed hash for the provided path matches a blocked
+/// mod we are looking for
+/// @param hash the computed hash for the provided path
+/// @param path the path to the local file being compared
+void BlockedModsDialog::checkMatchHash(QString hash, QString path)
+{
+ bool match = false;
+
+ qDebug() << "[Blocked Mods Dialog] Checking for match on hash: " << hash << "| From path:" << path;
+
+ for (auto& mod : m_mods) {
+ if (mod.matched) {
+ continue;
+ }
+ if (mod.hash.compare(hash, Qt::CaseInsensitive) == 0) {
+ mod.matched = true;
+ mod.localPath = path;
+ match = true;
+
+ qDebug() << "[Blocked Mods Dialog] Hash match found:" << mod.name << hash << "| From path:" << path;
+
+ break;
+ }
+ }
+
+ if (match) {
+ update();
+ }
+}
+
+/// @brief Check if the name of the file at path matches the name of a blocked mod we are searching for
+/// @param path the path to check
+/// @return boolean: did the path match the name of a blocked mod?
+bool BlockedModsDialog::checkValidPath(QString path)
+{
+ QFileInfo file = QFileInfo(path);
+ QString filename = file.fileName();
+
+ for (auto& mod : m_mods) {
+ if (mod.name.compare(filename, Qt::CaseInsensitive) == 0) {
+ qDebug() << "[Blocked Mods Dialog] Name match found:" << mod.name << "| From path:" << path;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool BlockedModsDialog::allModsMatched()
+{
+ return std::all_of(m_mods.begin(), m_mods.end(), [](auto const& mod) { return mod.matched; });
+}
+
+/// @brief ensure matched file paths still exist
+void BlockedModsDialog::validateMatchedMods()
+{
+ bool changed = false;
+ for (auto& mod : m_mods) {
+ if (mod.matched) {
+ QFileInfo file = QFileInfo(mod.localPath);
+ if (!file.exists() || !file.isFile()) {
+ qDebug() << "[Blocked Mods Dialog] File" << mod.localPath << "for mod" << mod.name
+ << "has vanshed! marking as not matched.";
+ mod.localPath = "";
+ mod.matched = false;
+ changed = true;
+ }
+ }
+ }
+ if (changed) {
+ update();
+ }
+}
+
+/// @brief run hash task or mark a pending run if it is already runing
+void BlockedModsDialog::runHashTask()
+{
+ if (!m_hashing_task->isRunning()) {
+ m_rehash_pending = false;
+
+ if (!m_pending_hash_paths.isEmpty()) {
+ qDebug() << "[Blocked Mods Dialog] there are pending hash tasks, building and running tasks";
+
+ auto path = m_pending_hash_paths.begin();
+ while (path != m_pending_hash_paths.end()) {
+ buildHashTask(*path);
+ path = m_pending_hash_paths.erase(path);
+ }
+
+ m_hashing_task->start();
+ }
+ } else {
+ qDebug() << "[Blocked Mods Dialog] queueing another run of the hashing task";
+ qDebug() << "[Blocked Mods Dialog] pending hash tasks:" << m_pending_hash_paths;
+ m_rehash_pending = true;
+ }
+}
+
+void BlockedModsDialog::hashTaskFinished()
+{
+ qDebug() << "[Blocked Mods Dialog] All hash tasks finished";
+ if (m_rehash_pending) {
+ qDebug() << "[Blocked Mods Dialog] task finished with a rehash pending, rerunning";
+ runHashTask();
+ }
+}
+
+/// qDebug print support for the BlockedMod struct
+QDebug operator<<(QDebug debug, const BlockedMod& m)
+{
+ QDebugStateSaver saver(debug);
+
+ debug.nospace() << "{ name: " << m.name << ", websiteUrl: " << m.websiteUrl << ", hash: " << m.hash << ", matched: " << m.matched
+ << ", localPath: " << m.localPath << "}";
+
+ return debug;
}
diff --git a/launcher/ui/dialogs/BlockedModsDialog.h b/launcher/ui/dialogs/BlockedModsDialog.h
index 5f5bd61b..dac43cba 100644
--- a/launcher/ui/dialogs/BlockedModsDialog.h
+++ b/launcher/ui/dialogs/BlockedModsDialog.h
@@ -1,7 +1,23 @@
#pragma once
#include <QDialog>
+#include <QString>
+#include <QList>
+#include <QFileSystemWatcher>
+
+#include "modplatform/helpers/HashUtils.h"
+
+#include "tasks/ConcurrentTask.h"
+
+struct BlockedMod {
+ QString name;
+ QString websiteUrl;
+ QString hash;
+ bool matched;
+ QString localPath;
+
+};
QT_BEGIN_NAMESPACE
namespace Ui { class BlockedModsDialog; }
@@ -11,12 +27,38 @@ class BlockedModsDialog : public QDialog {
Q_OBJECT
public:
- BlockedModsDialog(QWidget *parent, const QString &title, const QString &text, const QString &body, const QList<QUrl> &urls);
+ BlockedModsDialog(QWidget *parent, const QString &title, const QString &text, QList<BlockedMod> &mods);
~BlockedModsDialog() override;
+protected:
+ void dragEnterEvent(QDragEnterEvent *event) override;
+ void dropEvent(QDropEvent *event) override;
+
private:
Ui::BlockedModsDialog *ui;
- const QList<QUrl> &urls;
+ QList<BlockedMod> &m_mods;
+ QFileSystemWatcher m_watcher;
+ shared_qobject_ptr<ConcurrentTask> m_hashing_task;
+ QSet<QString> m_pending_hash_paths;
+ bool m_rehash_pending;
+
void openAll();
+ void addDownloadFolder();
+ void update();
+ void directoryChanged(QString path);
+ void setupWatch();
+ void scanPaths();
+ void scanPath(QString path, bool start_task);
+ void addHashTask(QString path);
+ void buildHashTask(QString path);
+ void checkMatchHash(QString hash, QString path);
+ void validateMatchedMods();
+ void runHashTask();
+ void hashTaskFinished();
+
+ bool checkValidPath(QString path);
+ bool allModsMatched();
};
+
+QDebug operator<<(QDebug debug, const BlockedMod &m);
diff --git a/launcher/ui/dialogs/BlockedModsDialog.ui b/launcher/ui/dialogs/BlockedModsDialog.ui
index f4ae95b6..88105178 100644
--- a/launcher/ui/dialogs/BlockedModsDialog.ui
+++ b/launcher/ui/dialogs/BlockedModsDialog.ui
@@ -13,29 +13,41 @@
<property name="windowTitle">
<string notr="true">BlockedModsDialog</string>
</property>
- <layout class="QGridLayout" name="gridLayout">
- <item row="0" column="0">
- <widget class="QLabel" name="label">
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="labelDescription">
<property name="text">
<string notr="true"/>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
</widget>
</item>
- <item row="2" column="0">
- <widget class="QDialogButtonBox" name="buttonBox">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
+ <item>
+ <widget class="QLabel" name="labelExplain">
+ <property name="text">
+ <string/>
</property>
- <property name="standardButtons">
- <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ <property name="openExternalLinks">
+ <bool>true</bool>
</property>
</widget>
</item>
- <item row="1" column="0">
- <widget class="QTextBrowser" name="textBrowser">
+ <item>
+ <widget class="QTextBrowser" name="textBrowserModsListing">
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>165</height>
+ </size>
+ </property>
<property name="acceptRichText">
<bool>true</bool>
</property>
@@ -44,6 +56,68 @@
</property>
</widget>
</item>
+ <item>
+ <widget class="QLabel" name="labelWatched">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>1</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Watched Folders:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QTextBrowser" name="textBrowserWatched">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="baseSize">
+ <size>
+ <width>0</width>
+ <height>12</height>
+ </size>
+ </property>
+ <property name="openExternalLinks">
+ <bool>true</bool>
+ </property>
+ <property name="openLinks">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="bottomBoxH">
+ <item>
+ <widget class="QLabel" name="labelModsFound">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
</layout>
</widget>
<resources/>
diff --git a/launcher/ui/dialogs/ProgressDialog.cpp b/launcher/ui/dialogs/ProgressDialog.cpp
index 05269f62..da73a449 100644
--- a/launcher/ui/dialogs/ProgressDialog.cpp
+++ b/launcher/ui/dialogs/ProgressDialog.cpp
@@ -44,7 +44,8 @@ void ProgressDialog::setSkipButton(bool present, QString label)
void ProgressDialog::on_skipButton_clicked(bool checked)
{
Q_UNUSED(checked);
- task->abort();
+ if (ui->skipButton->isEnabled()) // prevent other triggers from aborting
+ task->abort();
}
ProgressDialog::~ProgressDialog()
diff --git a/launcher/ui/pages/global/LauncherPage.cpp b/launcher/ui/pages/global/LauncherPage.cpp
index 6661bf0f..cae0635f 100644
--- a/launcher/ui/pages/global/LauncherPage.cpp
+++ b/launcher/ui/pages/global/LauncherPage.cpp
@@ -303,21 +303,27 @@ void LauncherPage::applySettings()
s->set("IconTheme", "pe_blue");
break;
case 4:
- s->set("IconTheme", "OSX");
+ s->set("IconTheme", "breeze_light");
break;
case 5:
- s->set("IconTheme", "iOS");
+ s->set("IconTheme", "breeze_dark");
break;
case 6:
- s->set("IconTheme", "flat");
+ s->set("IconTheme", "OSX");
break;
case 7:
- s->set("IconTheme", "flat_white");
+ s->set("IconTheme", "iOS");
break;
case 8:
- s->set("IconTheme", "multimc");
+ s->set("IconTheme", "flat");
break;
case 9:
+ s->set("IconTheme", "flat_white");
+ break;
+ case 10:
+ s->set("IconTheme", "multimc");
+ break;
+ case 11:
s->set("IconTheme", "custom");
break;
}
@@ -397,7 +403,18 @@ void LauncherPage::loadSettings()
m_currentUpdateChannel = s->get("UpdateChannel").toString();
//FIXME: make generic
auto theme = s->get("IconTheme").toString();
- QStringList iconThemeOptions{"pe_colored", "pe_light", "pe_dark", "pe_blue", "OSX", "iOS", "flat", "flat_white", "multimc", "custom"};
+ QStringList iconThemeOptions{"pe_colored",
+ "pe_light",
+ "pe_dark",
+ "pe_blue",
+ "breeze_light",
+ "breeze_dark",
+ "OSX",
+ "iOS",
+ "flat",
+ "flat_white",
+ "multimc",
+ "custom"};
ui->themeComboBox->setCurrentIndex(iconThemeOptions.indexOf(theme));
auto cat = s->get("BackgroundCat").toString();
diff --git a/launcher/ui/pages/global/LauncherPage.ui b/launcher/ui/pages/global/LauncherPage.ui
index 6de644ee..c44718a1 100644
--- a/launcher/ui/pages/global/LauncherPage.ui
+++ b/launcher/ui/pages/global/LauncherPage.ui
@@ -287,6 +287,16 @@
</item>
<item>
<property name="text">
+ <string>Breeze Light</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Breeze Dark</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
<string notr="true">OSX</string>
</property>
</item>
diff --git a/launcher/ui/pages/instance/ExternalResourcesPage.cpp b/launcher/ui/pages/instance/ExternalResourcesPage.cpp
index b6c873cc..5c919573 100644
--- a/launcher/ui/pages/instance/ExternalResourcesPage.cpp
+++ b/launcher/ui/pages/instance/ExternalResourcesPage.cpp
@@ -14,8 +14,6 @@ ExternalResourcesPage::ExternalResourcesPage(BaseInstance* instance, std::shared
{
ui->setupUi(this);
- ExternalResourcesPage::runningStateChanged(m_instance && m_instance->isRunning());
-
ui->actionsToolbar->insertSpacer(ui->actionViewConfigs);
m_filterModel = model->createFilterProxyModel(this);
@@ -45,7 +43,6 @@ ExternalResourcesPage::ExternalResourcesPage(BaseInstance* instance, std::shared
auto selection_model = ui->treeView->selectionModel();
connect(selection_model, &QItemSelectionModel::currentChanged, this, &ExternalResourcesPage::current);
connect(ui->filterEdit, &QLineEdit::textChanged, this, &ExternalResourcesPage::filterTextChanged);
- connect(m_instance, &BaseInstance::runningStatusChanged, this, &ExternalResourcesPage::runningStateChanged);
}
ExternalResourcesPage::~ExternalResourcesPage()
@@ -97,14 +94,6 @@ void ExternalResourcesPage::filterTextChanged(const QString& newContents)
m_filterModel->setFilterRegularExpression(m_viewFilter);
}
-void ExternalResourcesPage::runningStateChanged(bool running)
-{
- if (m_controlsEnabled == !running)
- return;
-
- m_controlsEnabled = !running;
-}
-
bool ExternalResourcesPage::shouldDisplay() const
{
return true;
diff --git a/launcher/ui/pages/instance/ExternalResourcesPage.h b/launcher/ui/pages/instance/ExternalResourcesPage.h
index 8e352cef..11058bf6 100644
--- a/launcher/ui/pages/instance/ExternalResourcesPage.h
+++ b/launcher/ui/pages/instance/ExternalResourcesPage.h
@@ -47,7 +47,6 @@ class ExternalResourcesPage : public QMainWindow, public BasePage {
protected slots:
void itemActivated(const QModelIndex& index);
void filterTextChanged(const QString& newContents);
- virtual void runningStateChanged(bool running);
virtual void addItem();
virtual void removeItem();
diff --git a/launcher/ui/pages/instance/ExternalResourcesPage.ui b/launcher/ui/pages/instance/ExternalResourcesPage.ui
index 76f8ec18..33a03336 100644
--- a/launcher/ui/pages/instance/ExternalResourcesPage.ui
+++ b/launcher/ui/pages/instance/ExternalResourcesPage.ui
@@ -27,11 +27,7 @@
<item row="4" column="1" colspan="3">
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="1">
- <widget class="QLineEdit" name="filterEdit">
- <property name="clearButtonEnabled">
- <bool>true</bool>
- </property>
- </widget>
+ <widget class="QLineEdit" name="filterEdit"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="filterLabel">
diff --git a/launcher/ui/pages/instance/ModFolderPage.cpp b/launcher/ui/pages/instance/ModFolderPage.cpp
index f0106066..0a2e6155 100644
--- a/launcher/ui/pages/instance/ModFolderPage.cpp
+++ b/launcher/ui/pages/instance/ModFolderPage.cpp
@@ -108,13 +108,13 @@ ModFolderPage::ModFolderPage(BaseInstance* inst, std::shared_ptr<ModFolderModel>
disconnect(mods.get(), &ModFolderModel::updateFinished, this, 0);
});
+ connect(m_instance, &BaseInstance::runningStatusChanged, this, &ModFolderPage::runningStateChanged);
ModFolderPage::runningStateChanged(m_instance && m_instance->isRunning());
}
}
void ModFolderPage::runningStateChanged(bool running)
{
- ExternalResourcesPage::runningStateChanged(running);
ui->actionDownloadItem->setEnabled(!running);
ui->actionUpdateItem->setEnabled(!running);
ui->actionAddItem->setEnabled(!running);
diff --git a/launcher/ui/pages/instance/ModFolderPage.h b/launcher/ui/pages/instance/ModFolderPage.h
index c9a55bde..f20adf34 100644
--- a/launcher/ui/pages/instance/ModFolderPage.h
+++ b/launcher/ui/pages/instance/ModFolderPage.h
@@ -53,12 +53,12 @@ class ModFolderPage : public ExternalResourcesPage {
virtual QString helpPage() const override { return "Loader-mods"; }
virtual bool shouldDisplay() const override;
- void runningStateChanged(bool running) override;
public slots:
bool onSelectionChanged(const QModelIndex& current, const QModelIndex& previous) override;
private slots:
+ void runningStateChanged(bool running);
void removeItem() override;
void installMods();
diff --git a/launcher/ui/pages/instance/ServersPage.cpp b/launcher/ui/pages/instance/ServersPage.cpp
index 5e8bd7cc..d64bcb76 100644
--- a/launcher/ui/pages/instance/ServersPage.cpp
+++ b/launcher/ui/pages/instance/ServersPage.cpp
@@ -400,11 +400,11 @@ public:
virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override
{
- return m_servers.size();
+ return parent.isValid() ? 0 : m_servers.size();
}
int columnCount(const QModelIndex & parent) const override
{
- return COLUMN_COUNT;
+ return parent.isValid() ? 0 : COLUMN_COUNT;
}
Server * at(int index)
diff --git a/launcher/ui/pages/instance/VersionPage.ui b/launcher/ui/pages/instance/VersionPage.ui
index fcba5598..14b7cd9f 100644
--- a/launcher/ui/pages/instance/VersionPage.ui
+++ b/launcher/ui/pages/instance/VersionPage.ui
@@ -48,11 +48,7 @@
<item>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="1">
- <widget class="QLineEdit" name="filterEdit">
- <property name="clearButtonEnabled">
- <bool>true</bool>
- </property>
- </widget>
+ <widget class="QLineEdit" name="filterEdit"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="filterLabel">
diff --git a/launcher/ui/pages/modplatform/ModModel.h b/launcher/ui/pages/modplatform/ModModel.h
index d2636d87..36840649 100644
--- a/launcher/ui/pages/modplatform/ModModel.h
+++ b/launcher/ui/pages/modplatform/ModModel.h
@@ -20,8 +20,8 @@ class ListModel : public QAbstractListModel {
ListModel(ModPage* parent);
~ListModel() override;
- inline auto rowCount(const QModelIndex& parent) const -> int override { return modpacks.size(); };
- inline auto columnCount(const QModelIndex& parent) const -> int override { return 1; };
+ inline auto rowCount(const QModelIndex& parent) const -> int override { return parent.isValid() ? 0 : modpacks.size(); };
+ inline auto columnCount(const QModelIndex& parent) const -> int override { return parent.isValid() ? 0 : 1; };
inline auto flags(const QModelIndex& index) const -> Qt::ItemFlags override { return QAbstractListModel::flags(index); };
auto debugName() const -> QString;
@@ -41,12 +41,12 @@ class ListModel : public QAbstractListModel {
void requestModVersions(const ModPlatform::IndexedPack& current, QModelIndex index);
virtual void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) = 0;
- virtual void loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj) {};
+ virtual void loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj) = 0;
virtual void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) = 0;
void getLogo(const QString& logo, const QString& logoUrl, LogoCallback callback);
- inline auto canFetchMore(const QModelIndex& parent) const -> bool override { return searchState == CanPossiblyFetchMore; };
+ inline auto canFetchMore(const QModelIndex& parent) const -> bool override { return parent.isValid() ? false : searchState == CanPossiblyFetchMore; };
public slots:
void searchRequestFinished(QJsonDocument& doc);
diff --git a/launcher/ui/pages/modplatform/ModPage.cpp b/launcher/ui/pages/modplatform/ModPage.cpp
index 234f9f36..677bc4d6 100644
--- a/launcher/ui/pages/modplatform/ModPage.cpp
+++ b/launcher/ui/pages/modplatform/ModPage.cpp
@@ -262,7 +262,7 @@ void ModPage::openUrl(const QUrl& url)
const QString address = url.host() + url.path();
QRegularExpressionMatch match;
- const char* page;
+ QString page;
match = modrinth.match(address);
if (match.hasMatch())
@@ -276,7 +276,7 @@ void ModPage::openUrl(const QUrl& url)
page = "curseforge";
}
- if (match.hasMatch()) {
+ if (!page.isNull()) {
const QString slug = match.captured(1);
// ensure the user isn't opening the same mod
diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlListModel.cpp b/launcher/ui/pages/modplatform/atlauncher/AtlListModel.cpp
index ef9a9268..2ce04068 100644
--- a/launcher/ui/pages/modplatform/atlauncher/AtlListModel.cpp
+++ b/launcher/ui/pages/modplatform/atlauncher/AtlListModel.cpp
@@ -32,12 +32,12 @@ ListModel::~ListModel()
int ListModel::rowCount(const QModelIndex &parent) const
{
- return modpacks.size();
+ return parent.isValid() ? 0 : modpacks.size();
}
int ListModel::columnCount(const QModelIndex &parent) const
{
- return 1;
+ return parent.isValid() ? 0 : 1;
}
QVariant ListModel::data(const QModelIndex &index, int role) const
diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp b/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp
index 9138dcbb..cdb4532c 100644
--- a/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp
+++ b/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp
@@ -75,12 +75,12 @@ QVector<QString> AtlOptionalModListModel::getResult() {
}
int AtlOptionalModListModel::rowCount(const QModelIndex &parent) const {
- return m_mods.size();
+ return parent.isValid() ? 0 : m_mods.size();
}
int AtlOptionalModListModel::columnCount(const QModelIndex &parent) const {
// Enabled, Name, Description
- return 3;
+ return parent.isValid() ? 0 : 3;
}
QVariant AtlOptionalModListModel::data(const QModelIndex &index, int role) const {
diff --git a/launcher/ui/pages/modplatform/flame/FlameModel.cpp b/launcher/ui/pages/modplatform/flame/FlameModel.cpp
index debae8c3..127c3de5 100644
--- a/launcher/ui/pages/modplatform/flame/FlameModel.cpp
+++ b/launcher/ui/pages/modplatform/flame/FlameModel.cpp
@@ -15,12 +15,12 @@ ListModel::~ListModel() {}
int ListModel::rowCount(const QModelIndex& parent) const
{
- return modpacks.size();
+ return parent.isValid() ? 0 : modpacks.size();
}
int ListModel::columnCount(const QModelIndex& parent) const
{
- return 1;
+ return parent.isValid() ? 0 : 1;
}
QVariant ListModel::data(const QModelIndex& index, int role) const
diff --git a/launcher/ui/pages/modplatform/ftb/FtbListModel.cpp b/launcher/ui/pages/modplatform/ftb/FtbListModel.cpp
index 3a149944..ce2b2b18 100644
--- a/launcher/ui/pages/modplatform/ftb/FtbListModel.cpp
+++ b/launcher/ui/pages/modplatform/ftb/FtbListModel.cpp
@@ -34,12 +34,12 @@ ListModel::~ListModel()
int ListModel::rowCount(const QModelIndex &parent) const
{
- return modpacks.size();
+ return parent.isValid() ? 0 : modpacks.size();
}
int ListModel::columnCount(const QModelIndex &parent) const
{
- return 1;
+ return parent.isValid() ? 0 : 1;
}
QVariant ListModel::data(const QModelIndex &index, int role) const
diff --git a/launcher/ui/pages/modplatform/legacy_ftb/ListModel.cpp b/launcher/ui/pages/modplatform/legacy_ftb/ListModel.cpp
index 6f11cc95..6b1f6b89 100644
--- a/launcher/ui/pages/modplatform/legacy_ftb/ListModel.cpp
+++ b/launcher/ui/pages/modplatform/legacy_ftb/ListModel.cpp
@@ -125,12 +125,12 @@ QString ListModel::translatePackType(PackType type) const
int ListModel::rowCount(const QModelIndex &parent) const
{
- return modpacks.size();
+ return parent.isValid() ? 0 : modpacks.size();
}
int ListModel::columnCount(const QModelIndex &parent) const
{
- return 1;
+ return parent.isValid() ? 0 : 1;
}
QVariant ListModel::data(const QModelIndex &index, int role) const
diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h
index 6f33e11e..3be377a1 100644
--- a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h
+++ b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h
@@ -55,8 +55,8 @@ class ModpackListModel : public QAbstractListModel {
ModpackListModel(ModrinthPage* parent);
~ModpackListModel() override = default;
- inline auto rowCount(const QModelIndex& parent) const -> int override { return modpacks.size(); };
- inline auto columnCount(const QModelIndex& parent) const -> int override { return 1; };
+ inline auto rowCount(const QModelIndex& parent) const -> int override { return parent.isValid() ? 0 : modpacks.size(); };
+ inline auto columnCount(const QModelIndex& parent) const -> int override { return parent.isValid() ? 0 : 1; };
inline auto flags(const QModelIndex& index) const -> Qt::ItemFlags override { return QAbstractListModel::flags(index); };
auto debugName() const -> QString;
@@ -74,7 +74,7 @@ class ModpackListModel : public QAbstractListModel {
void getLogo(const QString& logo, const QString& logoUrl, LogoCallback callback);
- inline auto canFetchMore(const QModelIndex& parent) const -> bool override { return searchState == CanPossiblyFetchMore; };
+ inline auto canFetchMore(const QModelIndex& parent) const -> bool override { return parent.isValid() ? false : searchState == CanPossiblyFetchMore; };
public slots:
void searchRequestFinished(QJsonDocument& doc_all);
diff --git a/launcher/ui/pages/modplatform/technic/TechnicModel.cpp b/launcher/ui/pages/modplatform/technic/TechnicModel.cpp
index 742f4f2a..b2af1ac0 100644
--- a/launcher/ui/pages/modplatform/technic/TechnicModel.cpp
+++ b/launcher/ui/pages/modplatform/technic/TechnicModel.cpp
@@ -80,14 +80,14 @@ QVariant Technic::ListModel::data(const QModelIndex& index, int role) const
return QVariant();
}
-int Technic::ListModel::columnCount(const QModelIndex&) const
+int Technic::ListModel::columnCount(const QModelIndex& parent) const
{
- return 1;
+ return parent.isValid() ? 0 : 1;
}
-int Technic::ListModel::rowCount(const QModelIndex&) const
+int Technic::ListModel::rowCount(const QModelIndex& parent) const
{
- return modpacks.size();
+ return parent.isValid() ? 0 : modpacks.size();
}
void Technic::ListModel::searchWithTerm(const QString& term)
diff --git a/libraries/README.md b/libraries/README.md
index dc38477b..ac5a3618 100644
--- a/libraries/README.md
+++ b/libraries/README.md
@@ -42,19 +42,20 @@ MIT licensed.
Java launcher part for Minecraft.
-It:
+It does the following:
-- Starts a process
-- Waits for a launch script on stdin
-- Consumes the launch script you feed it
-- Proceeds with launch when it gets the `launcher` command
+- Waits for a launch script on stdin.
+- Consumes the launch script you feed it.
+- Proceeds with launch when it gets the `launcher` command.
+
+If "abort" is sent, the process will exit.
This means the process is essentially idle until the final command is sent. You can, for example, attach a profiler before you send it.
-A `legacy` and `onesix` launchers are available.
+The `standard` and `legacy` launchers are available.
+- `standard` can handle launching any Minecraft version, at the cost of some extra features `legacy` enables (custom window icon and title).
- `legacy` is intended for use with Minecraft versions < 1.6 and is deprecated.
-- `onesix` can handle launching any Minecraft version, at the cost of some extra features `legacy` enables (custom window icon and title).
Example (some parts have been censored):
@@ -64,7 +65,7 @@ mainClass net.minecraft.launchwrapper.Launch
param --username
param CENSORED
param --version
-param MultiMC5
+param Prism Launcher
param --gameDir
param /home/peterix/minecraft/FTB/17ForgeTest/minecraft
param --assetsDir
@@ -81,58 +82,11 @@ param --userType
param mojang
param --tweakClass
param cpw.mods.fml.common.launcher.FMLTweaker
-windowTitle MultiMC: 172ForgeTest
+windowTitle Prism Launcher: 172ForgeTest
windowParams 854x480
userName CENSORED
sessionId token:CENSORED:CENSORED
-cp /home/peterix/minecraft/FTB/libraries/com/mojang/realms/1.3.5/realms-1.3.5.jar
-cp /home/peterix/minecraft/FTB/libraries/org/apache/commons/commons-compress/1.8.1/commons-compress-1.8.1.jar
-cp /home/peterix/minecraft/FTB/libraries/org/apache/httpcomponents/httpclient/4.3.3/httpclient-4.3.3.jar
-cp /home/peterix/minecraft/FTB/libraries/commons-logging/commons-logging/1.1.3/commons-logging-1.1.3.jar
-cp /home/peterix/minecraft/FTB/libraries/org/apache/httpcomponents/httpcore/4.3.2/httpcore-4.3.2.jar
-cp /home/peterix/minecraft/FTB/libraries/java3d/vecmath/1.3.1/vecmath-1.3.1.jar
-cp /home/peterix/minecraft/FTB/libraries/net/sf/trove4j/trove4j/3.0.3/trove4j-3.0.3.jar
-cp /home/peterix/minecraft/FTB/libraries/com/ibm/icu/icu4j-core-mojang/51.2/icu4j-core-mojang-51.2.jar
-cp /home/peterix/minecraft/FTB/libraries/net/sf/jopt-simple/jopt-simple/4.5/jopt-simple-4.5.jar
-cp /home/peterix/minecraft/FTB/libraries/com/paulscode/codecjorbis/20101023/codecjorbis-20101023.jar
-cp /home/peterix/minecraft/FTB/libraries/com/paulscode/codecwav/20101023/codecwav-20101023.jar
-cp /home/peterix/minecraft/FTB/libraries/com/paulscode/libraryjavasound/20101123/libraryjavasound-20101123.jar
-cp /home/peterix/minecraft/FTB/libraries/com/paulscode/librarylwjglopenal/20100824/librarylwjglopenal-20100824.jar
-cp /home/peterix/minecraft/FTB/libraries/com/paulscode/soundsystem/20120107/soundsystem-20120107.jar
-cp /home/peterix/minecraft/FTB/libraries/io/netty/netty-all/4.0.10.Final/netty-all-4.0.10.Final.jar
-cp /home/peterix/minecraft/FTB/libraries/com/google/guava/guava/16.0/guava-16.0.jar
-cp /home/peterix/minecraft/FTB/libraries/org/apache/commons/commons-lang3/3.2.1/commons-lang3-3.2.1.jar
-cp /home/peterix/minecraft/FTB/libraries/commons-io/commons-io/2.4/commons-io-2.4.jar
-cp /home/peterix/minecraft/FTB/libraries/commons-codec/commons-codec/1.9/commons-codec-1.9.jar
-cp /home/peterix/minecraft/FTB/libraries/net/java/jinput/jinput/2.0.5/jinput-2.0.5.jar
-cp /home/peterix/minecraft/FTB/libraries/net/java/jutils/jutils/1.0.0/jutils-1.0.0.jar
-cp /home/peterix/minecraft/FTB/libraries/com/google/code/gson/gson/2.2.4/gson-2.2.4.jar
-cp /home/peterix/minecraft/FTB/libraries/com/mojang/authlib/1.5.16/authlib-1.5.16.jar
-cp /home/peterix/minecraft/FTB/libraries/org/apache/logging/log4j/log4j-api/2.0-beta9/log4j-api-2.0-beta9.jar
-cp /home/peterix/minecraft/FTB/libraries/org/apache/logging/log4j/log4j-core/2.0-beta9/log4j-core-2.0-beta9.jar
-cp /home/peterix/minecraft/FTB/libraries/org/lwjgl/lwjgl/lwjgl/2.9.1/lwjgl-2.9.1.jar
-cp /home/peterix/minecraft/FTB/libraries/org/lwjgl/lwjgl/lwjgl_util/2.9.1/lwjgl_util-2.9.1.jar
-cp /home/peterix/minecraft/FTB/libraries/tv/twitch/twitch/5.16/twitch-5.16.jar
-cp /home/peterix/minecraft/FTB/libraries/net/minecraftforge/forge/1.7.10-10.13.0.1178/forge-1.7.10-10.13.0.1178.jar
-cp /home/peterix/minecraft/FTB/libraries/net/minecraft/launchwrapper/1.9/launchwrapper-1.9.jar
-cp /home/peterix/minecraft/FTB/libraries/org/ow2/asm/asm-all/4.1/asm-all-4.1.jar
-cp /home/peterix/minecraft/FTB/libraries/com/typesafe/akka/akka-actor_2.11/2.3.3/akka-actor_2.11-2.3.3.jar
-cp /home/peterix/minecraft/FTB/libraries/com/typesafe/config/1.2.1/config-1.2.1.jar
-cp /home/peterix/minecraft/FTB/libraries/org/scala-lang/scala-actors-migration_2.11/1.1.0/scala-actors-migration_2.11-1.1.0.jar
-cp /home/peterix/minecraft/FTB/libraries/org/scala-lang/scala-compiler/2.11.1/scala-compiler-2.11.1.jar
-cp /home/peterix/minecraft/FTB/libraries/org/scala-lang/plugins/scala-continuations-library_2.11/1.0.2/scala-continuations-library_2.11-1.0.2.jar
-cp /home/peterix/minecraft/FTB/libraries/org/scala-lang/plugins/scala-continuations-plugin_2.11.1/1.0.2/scala-continuations-plugin_2.11.1-1.0.2.jar
-cp /home/peterix/minecraft/FTB/libraries/org/scala-lang/scala-library/2.11.1/scala-library-2.11.1.jar
-cp /home/peterix/minecraft/FTB/libraries/org/scala-lang/scala-parser-combinators_2.11/1.0.1/scala-parser-combinators_2.11-1.0.1.jar
-cp /home/peterix/minecraft/FTB/libraries/org/scala-lang/scala-reflect/2.11.1/scala-reflect-2.11.1.jar
-cp /home/peterix/minecraft/FTB/libraries/org/scala-lang/scala-swing_2.11/1.0.1/scala-swing_2.11-1.0.1.jar
-cp /home/peterix/minecraft/FTB/libraries/org/scala-lang/scala-xml_2.11/1.0.2/scala-xml_2.11-1.0.2.jar
-cp /home/peterix/minecraft/FTB/libraries/lzma/lzma/0.0.1/lzma-0.0.1.jar
-ext /home/peterix/minecraft/FTB/libraries/org/lwjgl/lwjgl/lwjgl-platform/2.9.1/lwjgl-platform-2.9.1-natives-linux.jar
-ext /home/peterix/minecraft/FTB/libraries/net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-linux.jar
-natives /home/peterix/minecraft/FTB/17ForgeTest/natives
-cp /home/peterix/minecraft/FTB/versions/1.7.10/1.7.10.jar
-launcher onesix
+launcher standard
```
Available under `GPL-3.0-only` (with classpath exception), sublicensed from its original `Apache-2.0` codebase
diff --git a/libraries/launcher/.gitignore b/libraries/launcher/.gitignore
index cc1c52bf..dda456e3 100644
--- a/libraries/launcher/.gitignore
+++ b/libraries/launcher/.gitignore
@@ -4,3 +4,4 @@ out
.classpath
.idea
.project
+bin/
diff --git a/libraries/launcher/CMakeLists.txt b/libraries/launcher/CMakeLists.txt
index df25414f..55ed5875 100644
--- a/libraries/launcher/CMakeLists.txt
+++ b/libraries/launcher/CMakeLists.txt
@@ -4,18 +4,21 @@ find_package(Java 1.7 REQUIRED COMPONENTS Development)
include(UseJava)
set(CMAKE_JAVA_JAR_ENTRY_POINT org.prismlauncher.EntryPoint)
-set(CMAKE_JAVA_COMPILE_FLAGS -target 7 -source 7 -Xlint:deprecation -Xlint:unchecked)
+set(CMAKE_JAVA_COMPILE_FLAGS -target 7 -source 7)
set(SRC
org/prismlauncher/EntryPoint.java
- org/prismlauncher/Launcher.java
- org/prismlauncher/LauncherFactory.java
- org/prismlauncher/impl/OneSixLauncher.java
- org/prismlauncher/applet/LegacyFrame.java
+ org/prismlauncher/launcher/Launcher.java
+ org/prismlauncher/launcher/impl/AbstractLauncher.java
+ org/prismlauncher/launcher/impl/StandardLauncher.java
+ org/prismlauncher/launcher/impl/legacy/LegacyLauncher.java
+ org/prismlauncher/launcher/impl/legacy/LegacyFrame.java
org/prismlauncher/exception/ParameterNotFoundException.java
org/prismlauncher/exception/ParseException.java
org/prismlauncher/utils/Parameters.java
- org/prismlauncher/utils/Utils.java
+ org/prismlauncher/utils/ReflectionUtils.java
+ org/prismlauncher/utils/logging/Level.java
+ org/prismlauncher/utils/logging/Log.java
net/minecraft/Launcher.java
)
add_jar(NewLaunch ${SRC})
diff --git a/libraries/launcher/net/minecraft/Launcher.java b/libraries/launcher/net/minecraft/Launcher.java
index 6bf671be..646e2e3e 100644
--- a/libraries/launcher/net/minecraft/Launcher.java
+++ b/libraries/launcher/net/minecraft/Launcher.java
@@ -1,41 +1,83 @@
+// SPDX-License-Identifier: GPL-3.0-only
/*
- * Copyright 2012-2021 MultiMC Contributors
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (C) 2022 icelimetea <fr3shtea@outlook.com>
+ * Copyright (C) 2022 TheKodeToad <TheKodeToad@proton.me>
+ * Copyright (C) 2022 solonovamax <solonovamax@12oclockpoint.com>
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3.
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * This program 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 General Public License for more details.
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Linking this library statically or dynamically with other modules is
+ * making a combined work based on this library. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give
+ * you permission to link this library with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also meet,
+ * for each linked independent module, the terms and conditions of the
+ * license of that module. An independent module is a module which is
+ * not derived from or based on this library. If you modify this
+ * library, you may extend this exception to your version of the
+ * library, but you are not obliged to do so. If you do not wish to do
+ * so, delete this exception statement from your version.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *
+ * Copyright 2013-2021 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
package net.minecraft;
import java.applet.Applet;
import java.applet.AppletStub;
-import java.awt.*;
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.Graphics;
import java.net.MalformedURLException;
import java.net.URL;
+import java.util.HashMap;
import java.util.Map;
-import java.util.TreeMap;
-/*
+/**
* WARNING: This class is reflectively accessed by legacy Forge versions.
- * Changing field and method declarations without further testing is not recommended.
+ * <p>
+ * Changing field and method declarations without further testing is not
+ * recommended.
*/
public final class Launcher extends Applet implements AppletStub {
- private final Map<String, String> params = new TreeMap<>();
-
- private Applet wrappedApplet;
+ private static final long serialVersionUID = 1L;
- private URL documentBase;
+ private final Map<String, String> params = new HashMap<>();
+ private Applet wrappedApplet;
+ private final URL documentBase;
private boolean active = false;
public Launcher(Applet applet) {
@@ -43,35 +85,36 @@ public final class Launcher extends Applet implements AppletStub {
}
public Launcher(Applet applet, URL documentBase) {
- this.setLayout(new BorderLayout());
+ setLayout(new BorderLayout());
- this.add(applet, "Center");
+ add(applet, "Center");
- this.wrappedApplet = applet;
+ wrappedApplet = applet;
try {
- if (documentBase != null) {
- this.documentBase = documentBase;
- } else if (applet.getClass().getPackage().getName().startsWith("com.mojang")) {
- // Special case only for Classic versions
-
- this.documentBase = new URL("http", "www.minecraft.net", 80, "/game/");
- } else {
- this.documentBase = new URL("http://www.minecraft.net/game/");
+ if (documentBase == null) {
+ if (applet.getClass().getPackage().getName().startsWith("com.mojang.")) {
+ // Special case only for Classic versions
+ documentBase = new URL("http://www.minecraft.net:80/game/");
+ } else {
+ documentBase = new URL("http://www.minecraft.net/game/");
+ }
}
} catch (MalformedURLException e) {
- throw new RuntimeException(e);
+ throw new AssertionError(e);
}
+
+ this.documentBase = documentBase;
}
public void replace(Applet applet) {
- this.wrappedApplet = applet;
+ wrappedApplet = applet;
applet.setStub(this);
applet.setSize(getWidth(), getHeight());
- this.setLayout(new BorderLayout());
- this.add(applet, "Center");
+ setLayout(new BorderLayout());
+ add(applet, "Center");
applet.init();
@@ -82,42 +125,48 @@ public final class Launcher extends Applet implements AppletStub {
validate();
}
- public void setParameter(String name, String value) {
- params.put(name, value);
+ @Override
+ public boolean isActive() {
+ return active;
+ }
+
+ @Override
+ public URL getDocumentBase() {
+ return documentBase;
+ }
+
+ @Override
+ public URL getCodeBase() {
+ try {
+ return new URL("http://www.minecraft.net/game/");
+ } catch (MalformedURLException e) {
+ throw new AssertionError(e);
+ }
}
@Override
- public String getParameter(String name) {
- String param = params.get(name);
+ public String getParameter(String key) {
+ String param = params.get(key);
if (param != null)
return param;
try {
- return super.getParameter(name);
- } catch (Exception ignored) {}
+ return super.getParameter(key);
+ } catch (Throwable ignored) {
+ }
return null;
}
@Override
- public boolean isActive() {
- return active;
- }
-
- @Override
- public void appletResize(int width, int height) {
- wrappedApplet.resize(width, height);
- }
-
- @Override
public void resize(int width, int height) {
wrappedApplet.resize(width, height);
}
@Override
- public void resize(Dimension d) {
- wrappedApplet.resize(d);
+ public void resize(Dimension size) {
+ wrappedApplet.resize(size);
}
@Override
@@ -140,33 +189,37 @@ public final class Launcher extends Applet implements AppletStub {
active = false;
}
+ @Override
public void destroy() {
wrappedApplet.destroy();
}
@Override
- public URL getCodeBase() {
- try {
- return new URL("http://www.minecraft.net/game/");
- } catch (MalformedURLException e) {
- throw new RuntimeException(e);
- }
+ public void appletResize(int width, int height) {
+ wrappedApplet.resize(width, height);
}
@Override
- public URL getDocumentBase() {
- return documentBase;
+ public void setVisible(boolean visible) {
+ super.setVisible(visible);
+
+ wrappedApplet.setVisible(visible);
}
@Override
- public void setVisible(boolean b) {
- super.setVisible(b);
+ public void paint(Graphics graphics) {
+ }
- wrappedApplet.setVisible(b);
+ @Override
+ public void update(Graphics graphics) {
}
- public void update(Graphics paramGraphics) {}
+ public void setParameter(String key, String value) {
+ params.put(key, value);
+ }
- public void paint(Graphics paramGraphics) {}
+ public void setParameter(String key, boolean value) {
+ setParameter(key, value ? "true" : "false");
+ }
}
diff --git a/libraries/launcher/org/prismlauncher/EntryPoint.java b/libraries/launcher/org/prismlauncher/EntryPoint.java
index 9144e1f1..78804b3e 100644
--- a/libraries/launcher/org/prismlauncher/EntryPoint.java
+++ b/libraries/launcher/org/prismlauncher/EntryPoint.java
@@ -1,7 +1,9 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
- * PolyMC - Minecraft Launcher
- * Copyright (C) 2022 icelimetea, <fr3shtea@outlook.com>
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (C) 2022 icelimetea <fr3shtea@outlook.com>
+ * Copyright (C) 2022 TheKodeToad <TheKodeToad@proton.me>
+ * Copyright (C) 2022 solonovamax <solonovamax@12oclockpoint.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -52,113 +54,125 @@
package org.prismlauncher;
-import org.prismlauncher.exception.ParseException;
-import org.prismlauncher.utils.Parameters;
-
import java.io.BufferedReader;
-import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-public final class EntryPoint {
- private static final Logger LOGGER = Logger.getLogger("EntryPoint");
+import org.prismlauncher.exception.ParseException;
+import org.prismlauncher.launcher.Launcher;
+import org.prismlauncher.launcher.impl.StandardLauncher;
+import org.prismlauncher.launcher.impl.legacy.LegacyLauncher;
+import org.prismlauncher.utils.Parameters;
+import org.prismlauncher.utils.logging.Log;
- private final Parameters params = new Parameters();
+public final class EntryPoint {
public static void main(String[] args) {
- EntryPoint listener = new EntryPoint();
-
- int retCode = listener.listen();
+ ExitCode code = listen();
- if (retCode != 0) {
- LOGGER.info("Exiting with " + retCode);
+ if (code != ExitCode.NORMAL) {
+ Log.fatal("Exiting with " + code);
- System.exit(retCode);
+ System.exit(code.numeric);
}
}
- private Action parseLine(String inData) throws ParseException {
- String[] tokens = inData.split("\\s+", 2);
+ private static ExitCode listen() {
+ Parameters params = new Parameters();
+ PreLaunchAction action = PreLaunchAction.PROCEED;
- if (tokens.length == 0)
- throw new ParseException("Unexpected empty string!");
+ try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in, StandardCharsets.UTF_8))) {
+ String line;
- switch (tokens[0]) {
- case "launch": {
- return Action.Launch;
+ while (action == PreLaunchAction.PROCEED) {
+ if ((line = reader.readLine()) != null)
+ action = parseLine(line, params);
+ else
+ action = PreLaunchAction.ABORT;
}
+ } catch (IllegalArgumentException e) {
+ Log.fatal("Aborting due to wrong argument", e);
- case "abort": {
- return Action.Abort;
- }
+ return ExitCode.ILLEGAL_ARGUMENT;
+ } catch (Throwable e) {
+ Log.fatal("Aborting due to exception", e);
- default: {
- if (tokens.length != 2)
- throw new ParseException("Error while parsing:" + inData);
+ return ExitCode.ABORT;
+ }
- params.add(tokens[0], tokens[1]);
+ if (action == PreLaunchAction.ABORT) {
+ Log.fatal("Launch aborted by the launcher");
- return Action.Proceed;
- }
+ return ExitCode.ABORT;
}
- }
- public int listen() {
- Action action = Action.Proceed;
+ try {
+ Launcher launcher;
+ String type = params.getString("launcher");
- try (BufferedReader reader = new BufferedReader(new InputStreamReader(
- System.in,
- StandardCharsets.UTF_8
- ))) {
- String line;
+ switch (type) {
+ case "standard":
+ launcher = new StandardLauncher(params);
+ break;
- while (action == Action.Proceed) {
- if ((line = reader.readLine()) != null) {
- action = parseLine(line);
- } else {
- action = Action.Abort;
- }
+ case "legacy":
+ launcher = new LegacyLauncher(params);
+ break;
+
+ default:
+ throw new IllegalArgumentException("Invalid launcher type: " + type);
}
- } catch (IOException | ParseException e) {
- LOGGER.log(Level.SEVERE, "Launcher ABORT due to exception:", e);
- return 1;
- }
+ launcher.launch();
+
+ return ExitCode.NORMAL;
+ } catch (IllegalArgumentException e) {
+ Log.fatal("Illegal argument", e);
- // Main loop
- if (action == Action.Abort) {
- LOGGER.info("Launch aborted by the launcher.");
+ return ExitCode.ILLEGAL_ARGUMENT;
+ } catch (Throwable e) {
+ Log.fatal("Exception caught from launcher", e);
- return 1;
+ return ExitCode.ERROR;
}
+ }
- try {
- Launcher launcher =
- LauncherFactory
- .getInstance()
- .createLauncher(params);
+ private static PreLaunchAction parseLine(String input, Parameters params) throws ParseException {
+ switch (input) {
+ case "":
+ break;
- launcher.launch();
+ case "launch":
+ return PreLaunchAction.LAUNCH;
- return 0;
- } catch (IllegalArgumentException e) {
- LOGGER.log(Level.SEVERE, "Wrong argument.", e);
+ case "abort":
+ return PreLaunchAction.ABORT;
- return 1;
- } catch (Exception e) {
- LOGGER.log(Level.SEVERE, "Exception caught from launcher.", e);
+ default:
+ String[] pair = input.split(" ", 2);
- return 1;
+ if (pair.length != 2)
+ throw new ParseException(input, "[key] [value]");
+
+ params.add(pair[0], pair[1]);
}
+
+ return PreLaunchAction.PROCEED;
+ }
+
+ private enum PreLaunchAction {
+ PROCEED, LAUNCH, ABORT
}
- private enum Action {
- Proceed,
- Launch,
- Abort
+ private enum ExitCode {
+ NORMAL(0), ABORT(1), ERROR(2), ILLEGAL_ARGUMENT(65);
+
+ private final int numeric;
+
+ ExitCode(int numeric) {
+ this.numeric = numeric;
+ }
+
}
}
diff --git a/libraries/launcher/org/prismlauncher/Launcher.java b/libraries/launcher/org/prismlauncher/Launcher.java
deleted file mode 100644
index 7f25717b..00000000
--- a/libraries/launcher/org/prismlauncher/Launcher.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright 2012-2021 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.prismlauncher;
-
-public interface Launcher {
-
- void launch() throws Exception;
-
-}
diff --git a/libraries/launcher/org/prismlauncher/applet/LegacyFrame.java b/libraries/launcher/org/prismlauncher/applet/LegacyFrame.java
deleted file mode 100644
index 4413efa8..00000000
--- a/libraries/launcher/org/prismlauncher/applet/LegacyFrame.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright 2012-2021 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.prismlauncher.applet;
-
-import net.minecraft.Launcher;
-
-import javax.imageio.ImageIO;
-import java.applet.Applet;
-import java.awt.*;
-import java.awt.event.WindowAdapter;
-import java.awt.event.WindowEvent;
-import java.io.File;
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.StandardCopyOption;
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-public final class LegacyFrame extends Frame {
-
- private static final Logger LOGGER = Logger.getLogger("LegacyFrame");
-
- private final Launcher appletWrap;
-
- public LegacyFrame(String title, Applet mcApplet) {
- super(title);
-
- appletWrap = new Launcher(mcApplet);
-
- mcApplet.setStub(appletWrap);
-
- try {
- setIconImage(ImageIO.read(new File("icon.png")));
- } catch (IOException e) {
- LOGGER.log(Level.WARNING, "Unable to read Minecraft icon!", e);
- }
-
- addWindowListener(new ForceExitHandler());
- }
-
- public void start (
- String user,
- String session,
- int winSizeW,
- int winSizeH,
- boolean maximize,
- String serverAddress,
- String serverPort,
- boolean isDemo
- ) {
- // Implements support for launching in to multiplayer on classic servers using a mpticket
- // file generated by an external program and stored in the instance's root folder.
-
- Path mpticketFile =
- Paths.get(System.getProperty("user.dir"), "..", "mpticket");
-
- Path mpticketFileCorrupt =
- Paths.get(System.getProperty("user.dir"), "..", "mpticket.corrupt");
-
- if (Files.exists(mpticketFile)) {
- try {
- List<String> lines = Files.readAllLines(mpticketFile, StandardCharsets.UTF_8);
-
- if (lines.size() < 3) {
- Files.move(
- mpticketFile,
- mpticketFileCorrupt,
- StandardCopyOption.REPLACE_EXISTING
- );
-
- LOGGER.warning("Mpticket file is corrupted!");
- } else {
- // Assumes parameters are valid and in the correct order
- appletWrap.setParameter("server", lines.get(0));
- appletWrap.setParameter("port", lines.get(1));
- appletWrap.setParameter("mppass", lines.get(2));
- }
- } catch (IOException e) {
- LOGGER.log(Level.WARNING, "Unable to read mpticket file!", e);
- }
- }
-
- if (serverAddress != null) {
- appletWrap.setParameter("server", serverAddress);
- appletWrap.setParameter("port", serverPort);
- }
-
- appletWrap.setParameter("username", user);
- appletWrap.setParameter("sessionid", session);
- appletWrap.setParameter("stand-alone", "true"); // Show the quit button.
- appletWrap.setParameter("haspaid", "true"); // Some old versions need this for world saves to work.
- appletWrap.setParameter("demo", isDemo ? "true" : "false");
- appletWrap.setParameter("fullscreen", "false");
-
- add(appletWrap);
-
- appletWrap.setPreferredSize(new Dimension(winSizeW, winSizeH));
-
- pack();
-
- setLocationRelativeTo(null);
- setResizable(true);
-
- if (maximize)
- this.setExtendedState(MAXIMIZED_BOTH);
-
- validate();
-
- appletWrap.init();
- appletWrap.start();
-
- setVisible(true);
- }
-
- private final class ForceExitHandler extends WindowAdapter {
-
- @Override
- public void windowClosing(WindowEvent e) {
- new Thread(new Runnable() {
- @Override
- public void run() {
- try {
- Thread.sleep(30000L);
- } catch (InterruptedException localInterruptedException) {
- localInterruptedException.printStackTrace();
- }
-
- LOGGER.info("Forcing exit!");
-
- System.exit(0);
- }
- }).start();
-
- if (appletWrap != null) {
- appletWrap.stop();
- appletWrap.destroy();
- }
-
- // old minecraft versions can hang without this >_<
- System.exit(0);
- }
-
- }
-
-}
diff --git a/libraries/launcher/org/prismlauncher/exception/ParameterNotFoundException.java b/libraries/launcher/org/prismlauncher/exception/ParameterNotFoundException.java
index 641e0c99..524076ff 100644
--- a/libraries/launcher/org/prismlauncher/exception/ParameterNotFoundException.java
+++ b/libraries/launcher/org/prismlauncher/exception/ParameterNotFoundException.java
@@ -1,25 +1,48 @@
+// SPDX-License-Identifier: GPL-3.0-only
/*
- * Copyright 2012-2021 MultiMC Contributors
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (C) 2022 icelimetea <fr3shtea@outlook.com>
+ * Copyright (C) 2022 solonovamax <solonovamax@12oclockpoint.com>
+ * Copyright (C) 2022 TheKodeToad <TheKodeToad@proton.me>
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3.
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * This program 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 General Public License for more details.
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Linking this library statically or dynamically with other modules is
+ * making a combined work based on this library. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give
+ * you permission to link this library with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also meet,
+ * for each linked independent module, the terms and conditions of the
+ * license of that module. An independent module is a module which is
+ * not derived from or based on this library. If you modify this
+ * library, you may extend this exception to your version of the
+ * library, but you are not obliged to do so. If you do not wish to do
+ * so, delete this exception statement from your version.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.prismlauncher.exception;
public final class ParameterNotFoundException extends IllegalArgumentException {
+ private static final long serialVersionUID = 1L;
+
public ParameterNotFoundException(String key) {
- super("Unknown parameter name: " + key);
+ super(String.format("Required parameter '%s' was not found", key));
}
}
diff --git a/libraries/launcher/org/prismlauncher/exception/ParseException.java b/libraries/launcher/org/prismlauncher/exception/ParseException.java
index 51d25a62..4608fdd1 100644
--- a/libraries/launcher/org/prismlauncher/exception/ParseException.java
+++ b/libraries/launcher/org/prismlauncher/exception/ParseException.java
@@ -1,25 +1,48 @@
+// SPDX-License-Identifier: GPL-3.0-only
/*
- * Copyright 2012-2021 MultiMC Contributors
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (C) 2022 icelimetea <fr3shtea@outlook.com>
+ * Copyright (C) 2022 solonovamax <solonovamax@12oclockpoint.com>
+ * Copyright (C) 2022 TheKodeToad <TheKodeToad@proton.me>
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3.
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * This program 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 General Public License for more details.
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Linking this library statically or dynamically with other modules is
+ * making a combined work based on this library. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give
+ * you permission to link this library with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also meet,
+ * for each linked independent module, the terms and conditions of the
+ * license of that module. An independent module is a module which is
+ * not derived from or based on this library. If you modify this
+ * library, you may extend this exception to your version of the
+ * library, but you are not obliged to do so. If you do not wish to do
+ * so, delete this exception statement from your version.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.prismlauncher.exception;
public final class ParseException extends IllegalArgumentException {
- public ParseException(String message) {
- super(message);
+ private static final long serialVersionUID = 1L;
+
+ public ParseException(String input, String format) {
+ super(String.format("For input '%s' - should match '%s'", input, format));
}
}
diff --git a/libraries/launcher/org/prismlauncher/impl/OneSixLauncher.java b/libraries/launcher/org/prismlauncher/impl/OneSixLauncher.java
deleted file mode 100644
index d6443826..00000000
--- a/libraries/launcher/org/prismlauncher/impl/OneSixLauncher.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/* Copyright 2012-2021 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.prismlauncher.impl;
-
-import org.prismlauncher.Launcher;
-import org.prismlauncher.applet.LegacyFrame;
-import org.prismlauncher.utils.Parameters;
-import org.prismlauncher.utils.Utils;
-
-import java.applet.Applet;
-import java.io.File;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-public final class OneSixLauncher implements Launcher {
-
- private static final int DEFAULT_WINDOW_WIDTH = 854;
- private static final int DEFAULT_WINDOW_HEIGHT = 480;
-
- private static final Logger LOGGER = Logger.getLogger("OneSixLauncher");
-
- // parameters, separated from ParamBucket
- private final List<String> mcParams;
- private final List<String> traits;
- private final String appletClass;
- private final String mainClass;
- private final String userName, sessionId;
- private final String windowTitle;
-
- // secondary parameters
- private final int winSizeW;
- private final int winSizeH;
- private final boolean maximize;
- private final String cwd;
-
- private final String serverAddress;
- private final String serverPort;
-
- private final ClassLoader classLoader;
-
- public OneSixLauncher(Parameters params) {
- classLoader = ClassLoader.getSystemClassLoader();
-
- mcParams = params.allSafe("param", new ArrayList<String>());
- mainClass = params.firstSafe("mainClass", "net.minecraft.client.Minecraft");
- appletClass = params.firstSafe("appletClass", "net.minecraft.client.MinecraftApplet");
- traits = params.allSafe("traits", new ArrayList<String>());
-
- userName = params.first("userName");
- sessionId = params.first("sessionId");
- windowTitle = params.firstSafe("windowTitle", "Minecraft");
-
- serverAddress = params.firstSafe("serverAddress", null);
- serverPort = params.firstSafe("serverPort", null);
-
- cwd = System.getProperty("user.dir");
-
- String windowParams = params.firstSafe("windowParams", null);
-
- if (windowParams != null) {
- String[] dimStrings = windowParams.split("x");
-
- if (windowParams.equalsIgnoreCase("max")) {
- maximize = true;
-
- winSizeW = DEFAULT_WINDOW_WIDTH;
- winSizeH = DEFAULT_WINDOW_HEIGHT;
- } else if (dimStrings.length == 2) {
- maximize = false;
-
- winSizeW = Integer.parseInt(dimStrings[0]);
- winSizeH = Integer.parseInt(dimStrings[1]);
- } else {
- throw new IllegalArgumentException("Unexpected window size parameter value: " + windowParams);
- }
- } else {
- maximize = false;
-
- winSizeW = DEFAULT_WINDOW_WIDTH;
- winSizeH = DEFAULT_WINDOW_HEIGHT;
- }
- }
-
- private void invokeMain(Class<?> mainClass) throws Exception {
- Method method = mainClass.getMethod("main", String[].class);
-
- method.invoke(null, (Object) mcParams.toArray(new String[0]));
- }
-
- private void legacyLaunch() throws Exception {
- // Get the Minecraft Class and set the base folder
- Class<?> minecraftClass = classLoader.loadClass(mainClass);
-
- Field baseDirField = Utils.getMinecraftBaseDirField(minecraftClass);
-
- if (baseDirField == null) {
- LOGGER.warning("Could not find Minecraft path field.");
- } else {
- baseDirField.setAccessible(true);
-
- baseDirField.set(null, new File(cwd));
- }
-
- System.setProperty("minecraft.applet.TargetDirectory", cwd);
-
- if (!traits.contains("noapplet")) {
- LOGGER.info("Launching with applet wrapper...");
-
- try {
- Class<?> mcAppletClass = classLoader.loadClass(appletClass);
-
- Applet mcApplet = (Applet) mcAppletClass.getConstructor().newInstance();
-
- LegacyFrame mcWindow = new LegacyFrame(windowTitle, mcApplet);
-
- mcWindow.start(
- userName,
- sessionId,
- winSizeW,
- winSizeH,
- maximize,
- serverAddress,
- serverPort,
- mcParams.contains("--demo")
- );
-
- return;
- } catch (Exception e) {
- LOGGER.log(Level.SEVERE, "Applet wrapper failed: ", e);
-
- LOGGER.warning("Falling back to using main class.");
- }
- }
-
- invokeMain(minecraftClass);
- }
-
- private void launchWithMainClass() throws Exception {
- // window size, title and state, onesix
-
- // FIXME: there is no good way to maximize the minecraft window in onesix.
- // the following often breaks linux screen setups
- // mcparams.add("--fullscreen");
-
- if (!maximize) {
- mcParams.add("--width");
- mcParams.add(Integer.toString(winSizeW));
- mcParams.add("--height");
- mcParams.add(Integer.toString(winSizeH));
- }
-
- if (serverAddress != null) {
- mcParams.add("--server");
- mcParams.add(serverAddress);
- mcParams.add("--port");
- mcParams.add(serverPort);
- }
-
- invokeMain(classLoader.loadClass(mainClass));
- }
-
- @Override
- public void launch() throws Exception {
- if (traits.contains("legacyLaunch") || traits.contains("alphaLaunch")) {
- // legacy launch uses the applet wrapper
- legacyLaunch();
- } else {
- // normal launch just calls main()
- launchWithMainClass();
- }
- }
-
-}
diff --git a/libraries/launcher/org/prismlauncher/launcher/Launcher.java b/libraries/launcher/org/prismlauncher/launcher/Launcher.java
new file mode 100644
index 00000000..049a83d8
--- /dev/null
+++ b/libraries/launcher/org/prismlauncher/launcher/Launcher.java
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-3.0-only
+/*
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (C) 2022 icelimetea <fr3shtea@outlook.com>
+ * Copyright (C) 2022 TheKodeToad <TheKodeToad@proton.me>
+ * Copyright (C) 2022 solonovamax <solonovamax@12oclockpoint.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * Linking this library statically or dynamically with other modules is
+ * making a combined work based on this library. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give
+ * you permission to link this library with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also meet,
+ * for each linked independent module, the terms and conditions of the
+ * license of that module. An independent module is a module which is
+ * not derived from or based on this library. If you modify this
+ * library, you may extend this exception to your version of the
+ * library, but you are not obliged to do so. If you do not wish to do
+ * so, delete this exception statement from your version.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package org.prismlauncher.launcher;
+
+public interface Launcher {
+
+ void launch() throws Throwable;
+
+}
diff --git a/libraries/launcher/org/prismlauncher/launcher/impl/AbstractLauncher.java b/libraries/launcher/org/prismlauncher/launcher/impl/AbstractLauncher.java
new file mode 100644
index 00000000..0c2153a9
--- /dev/null
+++ b/libraries/launcher/org/prismlauncher/launcher/impl/AbstractLauncher.java
@@ -0,0 +1,110 @@
+// SPDX-License-Identifier: GPL-3.0-only
+/*
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (C) 2022 icelimetea <fr3shtea@outlook.com>
+ * Copyright (C) 2022 TheKodeToad <TheKodeToad@proton.me>
+ * Copyright (C) 2022 solonovamax <solonovamax@12oclockpoint.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * Linking this library statically or dynamically with other modules is
+ * making a combined work based on this library. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give
+ * you permission to link this library with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also meet,
+ * for each linked independent module, the terms and conditions of the
+ * license of that module. An independent module is a module which is
+ * not derived from or based on this library. If you modify this
+ * library, you may extend this exception to your version of the
+ * library, but you are not obliged to do so. If you do not wish to do
+ * so, delete this exception statement from your version.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *
+ * Copyright 2013-2021 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.prismlauncher.launcher.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.prismlauncher.exception.ParseException;
+import org.prismlauncher.launcher.Launcher;
+import org.prismlauncher.utils.Parameters;
+
+public abstract class AbstractLauncher implements Launcher {
+
+ private static final int DEFAULT_WINDOW_WIDTH = 854, DEFAULT_WINDOW_HEIGHT = 480;
+
+ // parameters, separated from ParamBucket
+ protected final List<String> gameArgs;
+
+ // secondary parameters
+ protected final int width, height;
+ protected final boolean maximize;
+ protected final String serverAddress, serverPort;
+
+ protected final String mainClassName;
+
+ protected AbstractLauncher(Parameters params) {
+ gameArgs = params.getList("param", new ArrayList<String>());
+ mainClassName = params.getString("mainClass", "net.minecraft.client.Minecraft");
+
+ serverAddress = params.getString("serverAddress", null);
+ serverPort = params.getString("serverPort", null);
+
+ String windowParams = params.getString("windowParams", null);
+
+ if ("max".equals(windowParams) || windowParams == null) {
+ maximize = windowParams != null;
+
+ width = DEFAULT_WINDOW_WIDTH;
+ height = DEFAULT_WINDOW_HEIGHT;
+ } else {
+ maximize = false;
+
+ String[] sizePair = windowParams.split("x", 2);
+
+ if (sizePair.length == 2) {
+ try {
+ width = Integer.parseInt(sizePair[0]);
+ height = Integer.parseInt(sizePair[1]);
+ return;
+ } catch (NumberFormatException ignored) {
+ }
+ }
+
+ throw new ParseException(windowParams, "[width]x[height]");
+ }
+ }
+
+}
diff --git a/libraries/launcher/org/prismlauncher/launcher/impl/StandardLauncher.java b/libraries/launcher/org/prismlauncher/launcher/impl/StandardLauncher.java
new file mode 100644
index 00000000..9436ff15
--- /dev/null
+++ b/libraries/launcher/org/prismlauncher/launcher/impl/StandardLauncher.java
@@ -0,0 +1,91 @@
+// SPDX-License-Identifier: GPL-3.0-only
+/*
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (C) 2022 icelimetea <fr3shtea@outlook.com>
+ * Copyright (C) 2022 TheKodeToad <TheKodeToad@proton.me>
+ * Copyright (C) 2022 solonovamax <solonovamax@12oclockpoint.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * Linking this library statically or dynamically with other modules is
+ * making a combined work based on this library. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give
+ * you permission to link this library with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also meet,
+ * for each linked independent module, the terms and conditions of the
+ * license of that module. An independent module is a module which is
+ * not derived from or based on this library. If you modify this
+ * library, you may extend this exception to your version of the
+ * library, but you are not obliged to do so. If you do not wish to do
+ * so, delete this exception statement from your version.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *
+ * Copyright 2013-2021 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.prismlauncher.launcher.impl;
+
+import java.lang.invoke.MethodHandle;
+
+import org.prismlauncher.utils.Parameters;
+import org.prismlauncher.utils.ReflectionUtils;
+
+public final class StandardLauncher extends AbstractLauncher {
+
+ public StandardLauncher(Parameters params) {
+ super(params);
+ }
+
+ @Override
+ public void launch() throws Throwable {
+ // window size, title and state
+ // FIXME doesn't support maximisation
+ if (!maximize) {
+ gameArgs.add("--width");
+ gameArgs.add(Integer.toString(width));
+ gameArgs.add("--height");
+ gameArgs.add(Integer.toString(height));
+ }
+
+ if (serverAddress != null) {
+ gameArgs.add("--server");
+ gameArgs.add(serverAddress);
+ gameArgs.add("--port");
+ gameArgs.add(serverPort);
+ }
+
+ // find and invoke the main method
+ MethodHandle method = ReflectionUtils.findMainMethod(mainClassName);
+ method.invokeExact(gameArgs.toArray(new String[0]));
+ }
+
+}
diff --git a/libraries/launcher/org/prismlauncher/launcher/impl/legacy/LegacyFrame.java b/libraries/launcher/org/prismlauncher/launcher/impl/legacy/LegacyFrame.java
new file mode 100644
index 00000000..c215e7fe
--- /dev/null
+++ b/libraries/launcher/org/prismlauncher/launcher/impl/legacy/LegacyFrame.java
@@ -0,0 +1,190 @@
+// SPDX-License-Identifier: GPL-3.0-only
+/*
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (C) 2022 icelimetea <fr3shtea@outlook.com>
+ * Copyright (C) 2022 flow <flowlnlnln@gmail.com>
+ * Copyright (C) 2022 TheKodeToad <TheKodeToad@proton.me>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * Linking this library statically or dynamically with other modules is
+ * making a combined work based on this library. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give
+ * you permission to link this library with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also meet,
+ * for each linked independent module, the terms and conditions of the
+ * license of that module. An independent module is a module which is
+ * not derived from or based on this library. If you modify this
+ * library, you may extend this exception to your version of the
+ * library, but you are not obliged to do so. If you do not wish to do
+ * so, delete this exception statement from your version.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *
+ * Copyright 2013-2021 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.prismlauncher.launcher.impl.legacy;
+
+import java.applet.Applet;
+import java.awt.Dimension;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.util.List;
+
+import javax.imageio.ImageIO;
+import javax.swing.JFrame;
+
+import org.prismlauncher.utils.logging.Log;
+
+import net.minecraft.Launcher;
+
+public final class LegacyFrame extends JFrame {
+
+ private static final long serialVersionUID = 1L;
+
+ private final Launcher launcher;
+
+ public LegacyFrame(String title, Applet applet) {
+ super(title);
+
+ launcher = new Launcher(applet);
+
+ applet.setStub(launcher);
+
+ try {
+ setIconImage(ImageIO.read(new File("icon.png")));
+ } catch (IOException e) {
+ Log.error("Failed to read window icon", e);
+ }
+
+ addWindowListener(new ForceExitHandler());
+ }
+
+ public void start(String user, String session, int width, int height, boolean maximize, String serverAddress,
+ String serverPort, boolean demo) {
+ // Implements support for launching in to multiplayer on classic servers using a
+ // mpticket file generated by an external program and stored in the instance's
+ // root folder.
+ Path instanceFolder = Paths.get("..");
+ Path mpticket = instanceFolder.resolve("mpticket");
+ Path mpticketCorrupt = instanceFolder.resolve("mpticket.corrupt");
+
+ if (Files.exists(mpticket)) {
+ try {
+ List<String> lines = Files.readAllLines(mpticket, StandardCharsets.UTF_8);
+
+ if (lines.size() < 3) {
+ Files.move(mpticket, mpticketCorrupt, StandardCopyOption.REPLACE_EXISTING);
+
+ Log.warning("mpticket file is corrupted");
+ } else {
+ // Assumes parameters are valid and in the correct order
+ launcher.setParameter("server", lines.get(0));
+ launcher.setParameter("port", lines.get(1));
+ launcher.setParameter("mppass", lines.get(2));
+ }
+ } catch (IOException e) {
+ Log.error("Failed to read mpticket file", e);
+ }
+ }
+
+ if (serverAddress != null) {
+ launcher.setParameter("server", serverAddress);
+ launcher.setParameter("port", serverPort);
+ }
+
+ launcher.setParameter("username", user);
+ launcher.setParameter("sessionid", session);
+ launcher.setParameter("stand-alone", true); // Show the quit button. TODO: why won't this work?
+ launcher.setParameter("haspaid", true); // Some old versions need this for world saves to work.
+ launcher.setParameter("demo", demo);
+ launcher.setParameter("fullscreen", false);
+
+ add(launcher);
+
+ launcher.setPreferredSize(new Dimension(width, height));
+
+ pack();
+
+ setLocationRelativeTo(null);
+ setResizable(true);
+
+ if (maximize)
+ setExtendedState(MAXIMIZED_BOTH);
+
+ validate();
+
+ launcher.init();
+ launcher.start();
+
+ setVisible(true);
+ }
+
+ private final class ForceExitHandler extends WindowAdapter {
+
+ @Override
+ public void windowClosing(WindowEvent event) {
+ // FIXME better solution
+
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ Thread.sleep(30000L);
+ } catch (InterruptedException e) {
+ Log.error("Thread interrupted", e);
+ }
+
+ Log.warning("Forcing exit");
+ System.exit(0);
+ }
+ }).start();
+
+ if (launcher != null) {
+ launcher.stop();
+ launcher.destroy();
+ }
+
+ // old minecraft versions can hang without this >_<
+ System.exit(0);
+ }
+
+ }
+
+}
diff --git a/libraries/launcher/org/prismlauncher/launcher/impl/legacy/LegacyLauncher.java b/libraries/launcher/org/prismlauncher/launcher/impl/legacy/LegacyLauncher.java
new file mode 100644
index 00000000..d349177b
--- /dev/null
+++ b/libraries/launcher/org/prismlauncher/launcher/impl/legacy/LegacyLauncher.java
@@ -0,0 +1,126 @@
+// SPDX-License-Identifier: GPL-3.0-only
+/*
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (C) 2022 icelimetea <fr3shtea@outlook.com>
+ * Copyright (C) 2022 flow <flowlnlnln@gmail.com>
+ * Copyright (C) 2022 TheKodeToad <TheKodeToad@proton.me>
+ * Copyright (C) 2022 solonovamax <solonovamax@12oclockpoint.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * Linking this library statically or dynamically with other modules is
+ * making a combined work based on this library. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give
+ * you permission to link this library with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also meet,
+ * for each linked independent module, the terms and conditions of the
+ * license of that module. An independent module is a module which is
+ * not derived from or based on this library. If you modify this
+ * library, you may extend this exception to your version of the
+ * library, but you are not obliged to do so. If you do not wish to do
+ * so, delete this exception statement from your version.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *
+ * Copyright 2013-2021 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.prismlauncher.launcher.impl.legacy;
+
+import java.io.File;
+import java.lang.invoke.MethodHandle;
+import java.lang.reflect.Field;
+import java.util.Collections;
+import java.util.List;
+
+import org.prismlauncher.launcher.impl.AbstractLauncher;
+import org.prismlauncher.utils.Parameters;
+import org.prismlauncher.utils.ReflectionUtils;
+import org.prismlauncher.utils.logging.Log;
+
+/**
+ * Used to launch old versions that support applets.
+ */
+public final class LegacyLauncher extends AbstractLauncher {
+
+ private final String user, session;
+ private final String title;
+ private final String appletClass;
+ private final boolean useApplet;
+ private final String gameDir;
+
+ public LegacyLauncher(Parameters params) {
+ super(params);
+
+ user = params.getString("userName");
+ session = params.getString("sessionId");
+ title = params.getString("windowTitle", "Minecraft");
+ appletClass = params.getString("appletClass", "net.minecraft.client.MinecraftApplet");
+
+ List<String> traits = params.getList("traits", Collections.<String>emptyList());
+ useApplet = !traits.contains("noapplet");
+
+ gameDir = System.getProperty("user.dir");
+ }
+
+ @Override
+ public void launch() throws Throwable {
+ Class<?> main = ClassLoader.getSystemClassLoader().loadClass(mainClassName);
+ Field gameDirField = ReflectionUtils.findMinecraftGameDirField(main);
+
+ if (gameDirField == null)
+ Log.warning("Could not find Minecraft folder field");
+ else {
+ gameDirField.setAccessible(true);
+ gameDirField.set(null, new File(gameDir));
+ }
+
+ if (useApplet) {
+ System.setProperty("minecraft.applet.TargetDirectory", gameDir);
+
+ try {
+ LegacyFrame window = new LegacyFrame(title, ReflectionUtils.createAppletClass(appletClass));
+
+ window.start(user, session, width, height, maximize, serverAddress, serverPort,
+ gameArgs.contains("--demo"));
+ return;
+ } catch (Throwable e) {
+ Log.error("Running applet wrapper failed with exception; falling back to main class", e);
+ }
+ }
+
+ // find and invoke the main method, this time without size parameters
+ // in all versions that support applets, these are ignored
+ MethodHandle method = ReflectionUtils.findMainMethod(main);
+ method.invokeExact(gameArgs.toArray(new String[0]));
+ }
+
+}
diff --git a/libraries/launcher/org/prismlauncher/utils/Parameters.java b/libraries/launcher/org/prismlauncher/utils/Parameters.java
index 98a40c28..6365753e 100644
--- a/libraries/launcher/org/prismlauncher/utils/Parameters.java
+++ b/libraries/launcher/org/prismlauncher/utils/Parameters.java
@@ -1,46 +1,84 @@
+// SPDX-License-Identifier: GPL-3.0-only
/*
- * Copyright 2012-2021 MultiMC Contributors
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (C) 2022 icelimetea <fr3shtea@outlook.com>
+ * Copyright (C) 2022 TheKodeToad <TheKodeToad@proton.me>
+ * Copyright (C) 2022 solonovamax <solonovamax@12oclockpoint.com>
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3.
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * This program 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 General Public License for more details.
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Linking this library statically or dynamically with other modules is
+ * making a combined work based on this library. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give
+ * you permission to link this library with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also meet,
+ * for each linked independent module, the terms and conditions of the
+ * license of that module. An independent module is a module which is
+ * not derived from or based on this library. If you modify this
+ * library, you may extend this exception to your version of the
+ * library, but you are not obliged to do so. If you do not wish to do
+ * so, delete this exception statement from your version.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *
+ * Copyright 2013-2021 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
package org.prismlauncher.utils;
-import org.prismlauncher.exception.ParameterNotFoundException;
-
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import org.prismlauncher.exception.ParameterNotFoundException;
+
public final class Parameters {
- private final Map<String, List<String>> paramsMap = new HashMap<>();
+ private final Map<String, List<String>> map = new HashMap<>();
public void add(String key, String value) {
- List<String> params = paramsMap.get(key);
+ List<String> params = map.get(key);
if (params == null) {
params = new ArrayList<>();
- paramsMap.put(key, params);
+ map.put(key, params);
}
params.add(value);
}
- public List<String> all(String key) throws ParameterNotFoundException {
- List<String> params = paramsMap.get(key);
+ public List<String> getList(String key) throws ParameterNotFoundException {
+ List<String> params = map.get(key);
if (params == null)
throw new ParameterNotFoundException(key);
@@ -48,8 +86,8 @@ public final class Parameters {
return params;
}
- public List<String> allSafe(String key, List<String> def) {
- List<String> params = paramsMap.get(key);
+ public List<String> getList(String key, List<String> def) {
+ List<String> params = map.get(key);
if (params == null || params.isEmpty())
return def;
@@ -57,8 +95,8 @@ public final class Parameters {
return params;
}
- public String first(String key) throws ParameterNotFoundException {
- List<String> list = all(key);
+ public String getString(String key) throws ParameterNotFoundException {
+ List<String> list = getList(key);
if (list.isEmpty())
throw new ParameterNotFoundException(key);
@@ -66,8 +104,8 @@ public final class Parameters {
return list.get(0);
}
- public String firstSafe(String key, String def) {
- List<String> params = paramsMap.get(key);
+ public String getString(String key, String def) {
+ List<String> params = map.get(key);
if (params == null || params.isEmpty())
return def;
diff --git a/libraries/launcher/org/prismlauncher/utils/ReflectionUtils.java b/libraries/launcher/org/prismlauncher/utils/ReflectionUtils.java
new file mode 100644
index 00000000..dd212ef9
--- /dev/null
+++ b/libraries/launcher/org/prismlauncher/utils/ReflectionUtils.java
@@ -0,0 +1,154 @@
+// SPDX-License-Identifier: GPL-3.0-only
+/*
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (C) 2022 icelimetea <fr3shtea@outlook.com>
+ * Copyright (C) 2022 solonovamax <solonovamax@12oclockpoint.com>
+ * Copyright (C) 2022 TheKodeToad <TheKodeToad@proton.me>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * Linking this library statically or dynamically with other modules is
+ * making a combined work based on this library. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give
+ * you permission to link this library with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also meet,
+ * for each linked independent module, the terms and conditions of the
+ * license of that module. An independent module is a module which is
+ * not derived from or based on this library. If you modify this
+ * library, you may extend this exception to your version of the
+ * library, but you are not obliged to do so. If you do not wish to do
+ * so, delete this exception statement from your version.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *
+ * Copyright 2013-2021 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.prismlauncher.utils;
+
+import java.applet.Applet;
+import java.io.File;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+
+import org.prismlauncher.utils.logging.Log;
+
+public final class ReflectionUtils {
+
+ private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
+ private static final ClassLoader LOADER = ClassLoader.getSystemClassLoader();
+
+ /**
+ * Construct a Java applet by its class name.
+ *
+ * @param clazz The class name
+ * @return The applet instance
+ * @throws Throwable
+ */
+ public static Applet createAppletClass(String clazz) throws Throwable {
+ Class<?> appletClass = LOADER.loadClass(clazz);
+
+ MethodHandle appletConstructor = LOOKUP.findConstructor(appletClass, MethodType.methodType(void.class));
+ return (Applet) appletConstructor.invoke();
+ }
+
+ /**
+ * Best guess of the game directory field within net.minecraft.client.Minecraft.
+ * Designed for legacy versions - newer versions do not use a static field.
+ *
+ * @param clazz The class
+ * @return The first field matching criteria
+ */
+ public static Field findMinecraftGameDirField(Class<?> clazz) {
+ Log.debug("Resolving minecraft game directory field");
+
+ // search for private static File
+ for (Field field : clazz.getDeclaredFields()) {
+ if (field.getType() != File.class) {
+ continue;
+ }
+
+ int fieldModifiers = field.getModifiers();
+
+ if (!Modifier.isStatic(fieldModifiers)) {
+ Log.debug("Rejecting field " + field.getName() + " because it is not static");
+ continue;
+ }
+
+ if (!Modifier.isPrivate(fieldModifiers)) {
+ Log.debug("Rejecting field " + field.getName() + " because it is not private");
+ continue;
+ }
+
+ if (Modifier.isFinal(fieldModifiers)) {
+ Log.debug("Rejecting field " + field.getName() + " because it is final");
+ continue;
+ }
+
+ Log.debug("Identified field " + field.getName() + " to match conditions for game directory field");
+
+ return field;
+ }
+
+ return null;
+ }
+
+ /**
+ * Gets the main method within a class.
+ *
+ * @param clazz The class
+ * @return A method matching the descriptor of a main method
+ * @throws ClassNotFoundException
+ * @throws NoSuchMethodException
+ * @throws IllegalAccessException
+ */
+ public static MethodHandle findMainMethod(Class<?> clazz) throws NoSuchMethodException, IllegalAccessException {
+ return LOOKUP.findStatic(clazz, "main", MethodType.methodType(void.class, String[].class));
+ }
+
+ /**
+ * Gets the main method within a class by its name.
+ *
+ * @param clazz The class name
+ * @return A method matching the descriptor of a main method
+ * @throws ClassNotFoundException
+ * @throws NoSuchMethodException
+ * @throws IllegalAccessException
+ */
+ public static MethodHandle findMainMethod(String clazz)
+ throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException {
+ return findMainMethod(LOADER.loadClass(clazz));
+ }
+
+}
diff --git a/libraries/launcher/org/prismlauncher/utils/Utils.java b/libraries/launcher/org/prismlauncher/utils/Utils.java
deleted file mode 100644
index ae9a4de2..00000000
--- a/libraries/launcher/org/prismlauncher/utils/Utils.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright 2012-2021 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.prismlauncher.utils;
-
-import java.io.File;
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-
-public final class Utils {
-
- private Utils() {}
-
- /**
- * Finds a field that looks like a Minecraft base folder in a supplied class
- *
- * @param clazz the class to scan
- */
- public static Field getMinecraftBaseDirField(Class<?> clazz) {
- for (Field f : clazz.getDeclaredFields()) {
- // Has to be File
- if (f.getType() != File.class)
- continue;
-
- // And Private Static.
- if (!Modifier.isStatic(f.getModifiers()) || !Modifier.isPrivate(f.getModifiers()))
- continue;
-
- return f;
- }
-
- return null;
- }
-
-}
-
diff --git a/libraries/launcher/org/prismlauncher/LauncherFactory.java b/libraries/launcher/org/prismlauncher/utils/logging/Level.java
index 98f2bbba..552b0b55 100644
--- a/libraries/launcher/org/prismlauncher/LauncherFactory.java
+++ b/libraries/launcher/org/prismlauncher/utils/logging/Level.java
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
- * PolyMC - Minecraft Launcher
- * Copyright (C) 2022 icelimetea, <fr3shtea@outlook.com>
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (C) 2022 TheKodeToad <TheKodeToad@proton.me>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -33,48 +33,27 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-package org.prismlauncher;
+package org.prismlauncher.utils.logging;
-import org.prismlauncher.impl.OneSixLauncher;
-import org.prismlauncher.utils.Parameters;
+public enum Level {
+ LAUNCHER("Launcher"),
+ DEBUG("Debug"),
+ INFO("Info"),
+ MESSAGE("Message"),
+ WARNING("Warning"),
+ ERROR("Error", true),
+ FATAL("Fatal", true);
-import java.util.HashMap;
-import java.util.Map;
+ String name;
+ boolean stderr;
-public final class LauncherFactory {
-
- private static final LauncherFactory INSTANCE = new LauncherFactory();
-
- private final Map<String, LauncherProvider> launcherRegistry = new HashMap<>();
-
- private LauncherFactory() {
- launcherRegistry.put("onesix", new LauncherProvider() {
- @Override
- public Launcher provide(Parameters parameters) {
- return new OneSixLauncher(parameters);
- }
- });
- }
-
- public Launcher createLauncher(Parameters parameters) {
- String name = parameters.first("launcher");
-
- LauncherProvider launcherProvider = launcherRegistry.get(name);
-
- if (launcherProvider == null)
- throw new IllegalArgumentException("Invalid launcher type: " + name);
-
- return launcherProvider.provide(parameters);
- }
-
- public static LauncherFactory getInstance() {
- return INSTANCE;
+ Level(String name) {
+ this(name, false);
}
- public interface LauncherProvider {
-
- Launcher provide(Parameters parameters);
-
+ Level(String name, boolean stderr) {
+ this.name = name;
+ this.stderr = stderr;
}
}
diff --git a/libraries/launcher/org/prismlauncher/utils/logging/Log.java b/libraries/launcher/org/prismlauncher/utils/logging/Log.java
new file mode 100644
index 00000000..e3aa538b
--- /dev/null
+++ b/libraries/launcher/org/prismlauncher/utils/logging/Log.java
@@ -0,0 +1,104 @@
+// SPDX-License-Identifier: GPL-3.0-only
+/*
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (C) 2022 TheKodeToad <TheKodeToad@proton.me>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * Linking this library statically or dynamically with other modules is
+ * making a combined work based on this library. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * As a special exception, the copyright holders of this library give
+ * you permission to link this library with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also meet,
+ * for each linked independent module, the terms and conditions of the
+ * license of that module. An independent module is a module which is
+ * not derived from or based on this library. If you modify this
+ * library, you may extend this exception to your version of the
+ * library, but you are not obliged to do so. If you do not wish to do
+ * so, delete this exception statement from your version.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package org.prismlauncher.utils.logging;
+
+import java.io.PrintStream;
+
+/**
+ * Used to print messages with different levels used to colourise the output.
+ * Used instead of a logging framework, as the launcher knows how to parse these
+ * messages.
+ */
+public final class Log {
+
+ // original before possibly overridden by MC
+ private static final PrintStream OUT = new PrintStream(System.out), ERR = new PrintStream(System.err);
+ private static final boolean DEBUG = Boolean.getBoolean("org.prismlauncher.debug");
+
+ public static void launcher(String message) {
+ log(message, Level.LAUNCHER);
+ }
+
+ public static void error(String message) {
+ log(message, Level.ERROR);
+ }
+
+ public static void debug(String message) {
+ log(message, Level.DEBUG);
+ }
+
+ public static void warning(String message) {
+ log(message, Level.WARNING);
+ }
+
+ public static void error(String message, Throwable e) {
+ error(message);
+ e.printStackTrace(ERR);
+ }
+
+ public static void fatal(String message) {
+ log(message, Level.FATAL);
+ }
+
+ public static void fatal(String message, Throwable e) {
+ fatal(message);
+ e.printStackTrace(ERR);
+ }
+
+ /**
+ * Logs a message with the prefix <code>!![LEVEL]!</code>. This is picked up by
+ * the log viewer to give it nice colours.
+ *
+ * @param message The message
+ * @param level The level
+ */
+ public static void log(String message, Level level) {
+ if (!DEBUG && level == Level.DEBUG)
+ return;
+
+ String prefix = "!![" + level.name + "]!";
+ // prefix first line
+ message = prefix + message;
+ // prefix subsequent lines
+ message = message.replace("\n", "\n" + prefix);
+
+ if (level.stderr)
+ ERR.println(message);
+ else
+ OUT.println(message);
+ }
+
+}
diff --git a/libraries/tomlplusplus b/libraries/tomlplusplus
-Subproject cc741c9f5f2a62856a2a2e9e275f61eb0591c09
+Subproject 0a90913abf9390b9e08ab6d3b40ac11634553f3
diff --git a/nix/default.nix b/nix/default.nix
index c7fc7576..6050fd37 100644
--- a/nix/default.nix
+++ b/nix/default.nix
@@ -1,100 +1,99 @@
-{ stdenv
-, lib
-, fetchFromGitHub
+{ lib
+, stdenv
, cmake
-, ninja
, jdk8
, jdk
-, ghc_filesystem
, zlib
, file
, wrapQtAppsHook
, xorg
, libpulseaudio
, qtbase
-, quazip
+, qtsvg
+, qtwayland
, libGL
-, msaClientID ? ""
-, extraJDKs ? [ ]
+, quazip
+, glfw
+, openal
, extra-cmake-modules
+, ghc_filesystem
+, msaClientID ? ""
+, jdks ? [ jdk jdk8 ]
# flake
, self
, version
, libnbtplusplus
, tomlplusplus
-, enableLTO ? false
}:
-let
- # Libraries required to run Minecraft
- libpath = with xorg; lib.makeLibraryPath [
- libX11
- libXext
- libXcursor
- libXrandr
- libXxf86vm
- libpulseaudio
- libGL
- ];
-
- # This variable will be passed to Minecraft by Prism Launcher
- gameLibraryPath = libpath + ":/run/opengl-driver/lib";
-
- javaPaths = lib.makeSearchPath "bin/java" ([ jdk jdk8 ] ++ extraJDKs);
-in
-
stdenv.mkDerivation rec {
pname = "prismlauncher";
inherit version;
src = lib.cleanSource self;
- nativeBuildInputs = [ cmake extra-cmake-modules ninja jdk ghc_filesystem file wrapQtAppsHook ];
- buildInputs = [ qtbase quazip zlib ];
+ nativeBuildInputs = [ extra-cmake-modules cmake file jdk wrapQtAppsHook ];
+ buildInputs = [
+ qtbase
+ qtsvg
+ zlib
+ quazip
+ ghc_filesystem
+ ] ++ lib.optional (lib.versionAtLeast qtbase.version "6") qtwayland;
+ cmakeFlags = lib.optionals (msaClientID != "") [ "-DLauncher_MSA_CLIENT_ID=${msaClientID}" ]
+ ++ lib.optionals (lib.versionAtLeast qtbase.version "6") [ "-DLauncher_QT_VERSION_MAJOR=6" ];
dontWrapQtApps = true;
postUnpack = ''
- # Copy libnbtplusplus
rm -rf source/libraries/libnbtplusplus
mkdir source/libraries/libnbtplusplus
ln -s ${libnbtplusplus}/* source/libraries/libnbtplusplus
chmod -R +r+w source/libraries/libnbtplusplus
- # Copy tomlplusplus
+ chown -R $USER: source/libraries/libnbtplusplus
rm -rf source/libraries/tomlplusplus
mkdir source/libraries/tomlplusplus
ln -s ${tomlplusplus}/* source/libraries/tomlplusplus
chmod -R +r+w source/libraries/tomlplusplus
+ chown -R $USER: source/libraries/tomlplusplus
'';
- cmakeFlags = [
- "-GNinja"
- "-DLauncher_QT_VERSION_MAJOR=${lib.versions.major qtbase.version}"
- ] ++ lib.optionals enableLTO [ "-DENABLE_LTO=on" ]
- ++ lib.optionals (msaClientID != "") [ "-DLauncher_MSA_CLIENT_ID=${msaClientID}" ];
+ postInstall =
+ let
+ libpath = with xorg;
+ lib.makeLibraryPath [
+ libX11
+ libXext
+ libXcursor
+ libXrandr
+ libXxf86vm
+ libpulseaudio
+ libGL
+ glfw
+ openal
+ stdenv.cc.cc.lib
+ ];
+ in
+ ''
+ # xorg.xrandr needed for LWJGL [2.9.2, 3) https://github.com/LWJGL/lwjgl/issues/128
+ wrapQtApp $out/bin/prismlauncher \
+ --set LD_LIBRARY_PATH /run/opengl-driver/lib:${libpath} \
+ --prefix PRISMLAUNCHER_JAVA_PATHS : ${lib.makeSearchPath "bin/java" jdks} \
+ --prefix PATH : ${lib.makeBinPath [xorg.xrandr]}
+ '';
- # we have to check if the system is NixOS before adding stdenv.cc.cc.lib (#923)
- postInstall = ''
- # xorg.xrandr needed for LWJGL [2.9.2, 3) https://github.com/LWJGL/lwjgl/issues/128
- wrapQtApp $out/bin/prismlauncher \
- --run '[ -f /etc/NIXOS ] && export LD_LIBRARY_PATH="${stdenv.cc.cc.lib}/lib:$LD_LIBRARY_PATH"' \
- --prefix LD_LIBRARY_PATH : ${gameLibraryPath} \
- --prefix PRISMLAUNCHER_JAVA_PATHS : ${javaPaths} \
- --prefix PATH : ${lib.makeBinPath [ xorg.xrandr ]}
- '';
meta = with lib; {
homepage = "https://prismlauncher.org/";
- downloadPage = "https://prismlauncher.org/download/";
- changelog = "https://github.com/PrismLauncher/PrismLauncher/releases";
description = "A free, open source launcher for Minecraft";
longDescription = ''
Allows you to have multiple, separate instances of Minecraft (each with
their own mods, texture packs, saves, etc) and helps you manage them and
their associated options with a simple interface.
'';
- platforms = platforms.unix;
+ platforms = platforms.linux;
+ changelog = "https://github.com/PrismLauncher/PrismLauncher/releases/tag/${version}";
license = licenses.gpl3Only;
maintainers = with maintainers; [ minion3665 Scrumplex ];
};
diff --git a/program_info/instance_icons.svg b/program_info/instance_icons.svg
new file mode 100644
index 00000000..84c0ef6f
--- /dev/null
+++ b/program_info/instance_icons.svg
@@ -0,0 +1,2720 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="1024"
+ height="1024"
+ version="1.1"
+ viewBox="0 0 1024 1024"
+ id="svg168"
+ sodipodi:docname="instance_icons.svg"
+ inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
+ xml:space="preserve"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"><defs
+ id="defs172"><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath7052"><rect
+ style="fill:#ff0000;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect7054"
+ width="6"
+ height="10"
+ x="6"
+ y="14"
+ ry="1" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath24641"><rect
+ style="fill:#ffffff;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect24643"
+ width="5"
+ height="6"
+ x="72"
+ y="12"
+ ry="1" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath37388"><rect
+ style="fill:#537a64;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect37390"
+ width="20"
+ height="7"
+ x="70"
+ y="16"
+ ry="1" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath51465"><rect
+ style="fill:#dfdfdf;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect51467"
+ width="10.000002"
+ height="5.0000005"
+ x="183.38519"
+ y="17.999998"
+ ry="0.99999958" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath51555"><rect
+ style="fill:#fb9168;fill-opacity:1;stroke-width:0.271456;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect51557"
+ width="19.999996"
+ height="16"
+ x="178.38519"
+ y="5.9999976"
+ ry="3" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath52515"><rect
+ style="fill:#d6d2d2;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect52517"
+ width="6"
+ height="3"
+ x="179.38519"
+ y="13.999998"
+ ry="0.99999958" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath40516"><rect
+ style="opacity:1;fill:#f3db6c;fill-opacity:1;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect40518"
+ width="16"
+ height="16"
+ x="200"
+ y="8"
+ ry="2" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath44346"><rect
+ style="opacity:1;fill:#f3db6c;fill-opacity:1;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect44348"
+ width="16"
+ height="16"
+ x="456"
+ y="8"
+ ry="2" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath56548"><rect
+ style="fill:#bd8e74;fill-opacity:1;stroke-width:0.277182;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect56550"
+ width="22"
+ height="22"
+ x="485"
+ y="5"
+ ry="3" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath70915"><path
+ sodipodi:type="star"
+ style="opacity:1;fill:#bd44b3;fill-opacity:1;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="path70917"
+ inkscape:flatsided="false"
+ sodipodi:sides="8"
+ sodipodi:cx="560"
+ sodipodi:cy="16"
+ sodipodi:r1="10.946013"
+ sodipodi:r2="12.727922"
+ sodipodi:arg1="0.78539816"
+ sodipodi:arg2="1.1780972"
+ inkscape:rounded="0.29"
+ inkscape:randomized="0.014"
+ d="m 567.75822,23.780557 c -1.02129,1.017197 -1.40469,3.26498 -2.72399,3.814557 -1.3193,0.549578 -3.76804,-0.657585 -5.20836,-0.687167 -1.44032,-0.02958 -3.32578,1.488919 -4.65697,0.936933 -1.33119,-0.551986 -2.06769,-2.91036 -3.08281,-3.927341 -1.01511,-1.016982 -3.30517,-1.550442 -3.83572,-2.877061 -0.53055,-1.326619 0.75095,-3.615262 0.76004,-5.050859 0.009,-1.435596 -1.30602,-3.611418 -0.75806,-4.936294 0.54796,-1.3248769 2.7981,-1.6627753 3.83368,-2.6540083 1.03559,-0.9912328 1.77327,-3.6016077 3.08037,-4.1709394 1.3071,-0.5693318 3.41767,0.6823629 4.85198,0.6871672 1.43432,0.0048 3.67769,-1.1020263 5.01335,-0.5805511 1.33567,0.5214752 1.68844,2.9320874 2.72643,3.9273412 1.03799,0.9952536 3.30533,1.5532379 3.83572,2.8770604 0.53039,1.323824 -0.73478,3.255376 -0.76004,4.694477 -0.0253,1.439101 1.28343,3.594239 0.75806,4.936295 -0.52537,1.342056 -2.8124,1.993192 -3.83368,3.01039 z"
+ transform="matrix(0.60389168,0.3121766,-0.3121766,0.60389168,226.77688,-168.46627)" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath56548-5"><rect
+ style="fill:#bd8e74;fill-opacity:1;stroke-width:0.277182;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect56550-5"
+ width="22"
+ height="22"
+ x="485"
+ y="5"
+ ry="3" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath40516-7"><rect
+ style="opacity:1;fill:#f3db6c;fill-opacity:1;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect40518-3"
+ width="16"
+ height="16"
+ x="200"
+ y="8"
+ ry="2" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath51555-6"><rect
+ style="fill:#fb9168;fill-opacity:1;stroke-width:0.271456;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect51557-5"
+ width="19.999996"
+ height="16"
+ x="178.38519"
+ y="5.9999976"
+ ry="3" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath51465-6"><rect
+ style="fill:#dfdfdf;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect51467-3"
+ width="10.000002"
+ height="5.0000005"
+ x="183.38519"
+ y="17.999998"
+ ry="0.99999958" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath52515-9"><rect
+ style="fill:#d6d2d2;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect52517-4"
+ width="6"
+ height="3"
+ x="179.38519"
+ y="13.999998"
+ ry="0.99999958" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath130950"><rect
+ style="fill:#d6d2d2;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect130948"
+ width="6"
+ height="3"
+ x="179.38519"
+ y="13.999998"
+ ry="0.99999958" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath130954"><rect
+ style="fill:#d6d2d2;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect130952"
+ width="6"
+ height="3"
+ x="179.38519"
+ y="13.999998"
+ ry="0.99999958" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath51555-6-8"><rect
+ style="fill:#fb9168;fill-opacity:1;stroke-width:0.271456;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect51557-5-1"
+ width="19.999996"
+ height="16"
+ x="178.38519"
+ y="5.9999976"
+ ry="3" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath51465-6-2"><rect
+ style="fill:#dfdfdf;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect51467-3-9"
+ width="10.000002"
+ height="5.0000005"
+ x="183.38519"
+ y="17.999998"
+ ry="0.99999958" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath52515-9-3"><rect
+ style="fill:#d6d2d2;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect52517-4-9"
+ width="6"
+ height="3"
+ x="179.38519"
+ y="13.999998"
+ ry="0.99999958" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath131121"><rect
+ style="fill:#d6d2d2;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect131119"
+ width="6"
+ height="3"
+ x="179.38519"
+ y="13.999998"
+ ry="0.99999958" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath131125"><rect
+ style="fill:#d6d2d2;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect131123"
+ width="6"
+ height="3"
+ x="179.38519"
+ y="13.999998"
+ ry="0.99999958" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath51555-6-8-0"><rect
+ style="fill:#fb9168;fill-opacity:1;stroke-width:0.271456;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect51557-5-1-8"
+ width="19.999996"
+ height="16"
+ x="178.38519"
+ y="5.9999976"
+ ry="3" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath51465-6-2-8"><rect
+ style="fill:#dfdfdf;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect51467-3-9-5"
+ width="10.000002"
+ height="5.0000005"
+ x="183.38519"
+ y="17.999998"
+ ry="0.99999958" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath52515-9-3-0"><rect
+ style="fill:#d6d2d2;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect52517-4-9-9"
+ width="6"
+ height="3"
+ x="179.38519"
+ y="13.999998"
+ ry="0.99999958" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath131331"><rect
+ style="fill:#d6d2d2;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect131329"
+ width="6"
+ height="3"
+ x="179.38519"
+ y="13.999998"
+ ry="0.99999958" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath131335"><rect
+ style="fill:#d6d2d2;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect131333"
+ width="6"
+ height="3"
+ x="179.38519"
+ y="13.999998"
+ ry="0.99999958" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath44346-0"><rect
+ style="opacity:1;fill:#f3db6c;fill-opacity:1;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect44348-4"
+ width="16"
+ height="16"
+ x="456"
+ y="8"
+ ry="2" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath56548-4"><rect
+ style="fill:#bd8e74;fill-opacity:1;stroke-width:0.277182;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect56550-4"
+ width="22"
+ height="22"
+ x="485"
+ y="5"
+ ry="3" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath70915-4"><path
+ sodipodi:type="star"
+ style="opacity:1;fill:#bd44b3;fill-opacity:1;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="path70917-7"
+ inkscape:flatsided="false"
+ sodipodi:sides="8"
+ sodipodi:cx="560"
+ sodipodi:cy="16"
+ sodipodi:r1="10.946013"
+ sodipodi:r2="12.727922"
+ sodipodi:arg1="0.78539816"
+ sodipodi:arg2="1.1780972"
+ inkscape:rounded="0.29"
+ inkscape:randomized="0.014"
+ d="m 567.75822,23.780557 c -1.02129,1.017197 -1.40469,3.26498 -2.72399,3.814557 -1.3193,0.549578 -3.76804,-0.657585 -5.20836,-0.687167 -1.44032,-0.02958 -3.32578,1.488919 -4.65697,0.936933 -1.33119,-0.551986 -2.06769,-2.91036 -3.08281,-3.927341 -1.01511,-1.016982 -3.30517,-1.550442 -3.83572,-2.877061 -0.53055,-1.326619 0.75095,-3.615262 0.76004,-5.050859 0.009,-1.435596 -1.30602,-3.611418 -0.75806,-4.936294 0.54796,-1.3248769 2.7981,-1.6627753 3.83368,-2.6540083 1.03559,-0.9912328 1.77327,-3.6016077 3.08037,-4.1709394 1.3071,-0.5693318 3.41767,0.6823629 4.85198,0.6871672 1.43432,0.0048 3.67769,-1.1020263 5.01335,-0.5805511 1.33567,0.5214752 1.68844,2.9320874 2.72643,3.9273412 1.03799,0.9952536 3.30533,1.5532379 3.83572,2.8770604 0.53039,1.323824 -0.73478,3.255376 -0.76004,4.694477 -0.0253,1.439101 1.28343,3.594239 0.75806,4.936295 -0.52537,1.342056 -2.8124,1.993192 -3.83368,3.01039 z"
+ transform="matrix(0.60389168,0.3121766,-0.3121766,0.60389168,226.77688,-168.46627)" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath56548-5-6"><rect
+ style="fill:#bd8e74;fill-opacity:1;stroke-width:0.277182;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect56550-5-3"
+ width="22"
+ height="22"
+ x="485"
+ y="5"
+ ry="3" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath51555-6-8-0-1"><rect
+ style="fill:#fb9168;fill-opacity:1;stroke-width:0.271456;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect51557-5-1-8-7"
+ width="19.999996"
+ height="16"
+ x="178.38519"
+ y="5.9999976"
+ ry="3" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath51465-6-2-8-5"><rect
+ style="fill:#dfdfdf;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect51467-3-9-5-9"
+ width="10.000002"
+ height="5.0000005"
+ x="183.38519"
+ y="17.999998"
+ ry="0.99999958" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath52515-9-3-0-6"><rect
+ style="fill:#d6d2d2;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect52517-4-9-9-2"
+ width="6"
+ height="3"
+ x="179.38519"
+ y="13.999998"
+ ry="0.99999958" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath166658"><rect
+ style="fill:#d6d2d2;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect166656"
+ width="6"
+ height="3"
+ x="179.38519"
+ y="13.999998"
+ ry="0.99999958" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath166662"><rect
+ style="fill:#d6d2d2;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect166660"
+ width="6"
+ height="3"
+ x="179.38519"
+ y="13.999998"
+ ry="0.99999958" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath70915-4-5"><path
+ sodipodi:type="star"
+ style="opacity:1;fill:#bd44b3;fill-opacity:1;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="path70917-7-9"
+ inkscape:flatsided="false"
+ sodipodi:sides="8"
+ sodipodi:cx="560"
+ sodipodi:cy="16"
+ sodipodi:r1="10.946013"
+ sodipodi:r2="12.727922"
+ sodipodi:arg1="0.78539816"
+ sodipodi:arg2="1.1780972"
+ inkscape:rounded="0.29"
+ inkscape:randomized="0.014"
+ d="m 567.75822,23.780557 c -1.02129,1.017197 -1.40469,3.26498 -2.72399,3.814557 -1.3193,0.549578 -3.76804,-0.657585 -5.20836,-0.687167 -1.44032,-0.02958 -3.32578,1.488919 -4.65697,0.936933 -1.33119,-0.551986 -2.06769,-2.91036 -3.08281,-3.927341 -1.01511,-1.016982 -3.30517,-1.550442 -3.83572,-2.877061 -0.53055,-1.326619 0.75095,-3.615262 0.76004,-5.050859 0.009,-1.435596 -1.30602,-3.611418 -0.75806,-4.936294 0.54796,-1.3248769 2.7981,-1.6627753 3.83368,-2.6540083 1.03559,-0.9912328 1.77327,-3.6016077 3.08037,-4.1709394 1.3071,-0.5693318 3.41767,0.6823629 4.85198,0.6871672 1.43432,0.0048 3.67769,-1.1020263 5.01335,-0.5805511 1.33567,0.5214752 1.68844,2.9320874 2.72643,3.9273412 1.03799,0.9952536 3.30533,1.5532379 3.83572,2.8770604 0.53039,1.323824 -0.73478,3.255376 -0.76004,4.694477 -0.0253,1.439101 1.28343,3.594239 0.75806,4.936295 -0.52537,1.342056 -2.8124,1.993192 -3.83368,3.01039 z"
+ transform="matrix(0.60389168,0.3121766,-0.3121766,0.60389168,226.77688,-168.46627)" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath56548-5-6-7"><rect
+ style="fill:#bd8e74;fill-opacity:1;stroke-width:0.277182;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect56550-5-3-5"
+ width="22"
+ height="22"
+ x="485"
+ y="5"
+ ry="3" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath7052-9"><rect
+ style="fill:#ff0000;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect7054-9"
+ width="6"
+ height="10"
+ x="6"
+ y="14"
+ ry="1" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath66059"><rect
+ style="fill:#ff0000;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect66057"
+ width="6"
+ height="10"
+ x="6"
+ y="14"
+ ry="1" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath66079"><rect
+ style="fill:#ff0000;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect66077"
+ width="6"
+ height="10"
+ x="6"
+ y="14"
+ ry="1" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath51555-6-8-0-1-3"><rect
+ style="fill:#fb9168;fill-opacity:1;stroke-width:0.271456;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect51557-5-1-8-7-7"
+ width="19.999996"
+ height="16"
+ x="178.38519"
+ y="5.9999976"
+ ry="3" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath51465-6-2-8-5-5"><rect
+ style="fill:#dfdfdf;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect51467-3-9-5-9-9"
+ width="10.000002"
+ height="5.0000005"
+ x="183.38519"
+ y="17.999998"
+ ry="0.99999958" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath52515-9-3-0-6-2"><rect
+ style="fill:#d6d2d2;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect52517-4-9-9-2-2"
+ width="6"
+ height="3"
+ x="179.38519"
+ y="13.999998"
+ ry="0.99999958" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath66197"><rect
+ style="fill:#d6d2d2;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect66195"
+ width="6"
+ height="3"
+ x="179.38519"
+ y="13.999998"
+ ry="0.99999958" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath66201"><rect
+ style="fill:#d6d2d2;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect66199"
+ width="6"
+ height="3"
+ x="179.38519"
+ y="13.999998"
+ ry="0.99999958" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath56548-4-6-8-7"><rect
+ style="fill:#bd8e74;fill-opacity:1;stroke-width:0.277182;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect56550-4-2-7-3"
+ width="22"
+ height="22"
+ x="485"
+ y="5"
+ ry="3" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath56548-5-6-7-5-6-8-6"><rect
+ style="fill:#bd8e74;fill-opacity:1;stroke-width:0.277182;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect56550-5-3-5-4-1-9-1"
+ width="22"
+ height="22"
+ x="485"
+ y="5"
+ ry="3" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath70915-4-5-0-2-7-5-3"><path
+ sodipodi:type="star"
+ style="opacity:1;fill:#bd44b3;fill-opacity:1;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="path70917-7-9-2-9-4-0-3"
+ inkscape:flatsided="false"
+ sodipodi:sides="8"
+ sodipodi:cx="560"
+ sodipodi:cy="16"
+ sodipodi:r1="10.946013"
+ sodipodi:r2="12.727922"
+ sodipodi:arg1="0.78539816"
+ sodipodi:arg2="1.1780972"
+ inkscape:rounded="0.29"
+ inkscape:randomized="0.014"
+ d="m 567.75822,23.780557 c -1.02129,1.017197 -1.40469,3.26498 -2.72399,3.814557 -1.3193,0.549578 -3.76804,-0.657585 -5.20836,-0.687167 -1.44032,-0.02958 -3.32578,1.488919 -4.65697,0.936933 -1.33119,-0.551986 -2.06769,-2.91036 -3.08281,-3.927341 -1.01511,-1.016982 -3.30517,-1.550442 -3.83572,-2.877061 -0.53055,-1.326619 0.75095,-3.615262 0.76004,-5.050859 0.009,-1.435596 -1.30602,-3.611418 -0.75806,-4.936294 0.54796,-1.3248769 2.7981,-1.6627753 3.83368,-2.6540083 1.03559,-0.9912328 1.77327,-3.6016077 3.08037,-4.1709394 1.3071,-0.5693318 3.41767,0.6823629 4.85198,0.6871672 1.43432,0.0048 3.67769,-1.1020263 5.01335,-0.5805511 1.33567,0.5214752 1.68844,2.9320874 2.72643,3.9273412 1.03799,0.9952536 3.30533,1.5532379 3.83572,2.8770604 0.53039,1.323824 -0.73478,3.255376 -0.76004,4.694477 -0.0253,1.439101 1.28343,3.594239 0.75806,4.936295 -0.52537,1.342056 -2.8124,1.993192 -3.83368,3.01039 z"
+ transform="matrix(0.60389168,0.3121766,-0.3121766,0.60389168,226.77688,-168.46627)" /></clipPath><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient41693"
+ id="linearGradient2973"
+ gradientUnits="userSpaceOnUse"
+ x1="153"
+ y1="25"
+ x2="135"
+ y2="7" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient41693"><stop
+ style="stop-color:#64d5df;stop-opacity:1;"
+ offset="0"
+ id="stop41689" /><stop
+ style="stop-color:#17c2d6;stop-opacity:1;"
+ offset="0.35665122"
+ id="stop41711" /><stop
+ style="stop-color:#89edf6;stop-opacity:1;"
+ offset="0.71356344"
+ id="stop41709" /><stop
+ style="stop-color:#2bc4d4;stop-opacity:1;"
+ offset="1"
+ id="stop41691" /></linearGradient><radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3000"
+ id="radialGradient3002-5"
+ cx="272"
+ cy="16"
+ fx="272"
+ fy="16"
+ r="12"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient3000"><stop
+ style="stop-color:#62b397;stop-opacity:1;"
+ offset="0.47770822"
+ id="stop2996" /><stop
+ style="stop-color:#3a7a81;stop-opacity:1;"
+ offset="1"
+ id="stop2998" /></linearGradient><radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3405"
+ id="radialGradient3407-4"
+ cx="272"
+ cy="16"
+ fx="272"
+ fy="16"
+ r="5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2,0,0,1.2,-54.4,-3.2)" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient3405"><stop
+ style="stop-color:#27414e;stop-opacity:1;"
+ offset="0.16041158"
+ id="stop3401" /><stop
+ style="stop-color:#27414e;stop-opacity:0.74901961;"
+ offset="0.50162286"
+ id="stop39443" /><stop
+ style="stop-color:#27414e;stop-opacity:0;"
+ offset="1"
+ id="stop3403" /></linearGradient><radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3853"
+ id="radialGradient3855-4"
+ cx="272"
+ cy="16"
+ fx="272"
+ fy="16"
+ r="5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.2,0,0,2,-326.4,-16)" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient3853"><stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="0.39989081"
+ id="stop3851" /><stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop3849" /></linearGradient><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3108"
+ id="linearGradient3110"
+ x1="70.852509"
+ y1="141.75883"
+ x2="70.852509"
+ y2="0.053809531"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient3108"><stop
+ style="stop-color:#1bd96a;stop-opacity:1;"
+ offset="0"
+ id="stop3104" /><stop
+ style="stop-color:#1bd9a1;stop-opacity:1;"
+ offset="1"
+ id="stop3106" /></linearGradient><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1468"
+ id="linearGradient1470"
+ x1="300"
+ y1="26"
+ x2="300"
+ y2="10"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient1468"><stop
+ style="stop-color:#d63954;stop-opacity:1;"
+ offset="0"
+ id="stop1464" /><stop
+ style="stop-color:#e6812b;stop-opacity:1;"
+ offset="1"
+ id="stop1466" /></linearGradient><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6068"
+ id="linearGradient6070"
+ x1="656"
+ y1="27"
+ x2="656"
+ y2="5"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient6068"><stop
+ style="stop-color:#cdcdcd;stop-opacity:1;"
+ offset="0"
+ id="stop6064" /><stop
+ style="stop-color:#eeeeee;stop-opacity:1;"
+ offset="1"
+ id="stop6066" /></linearGradient><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7624"
+ id="linearGradient7626"
+ x1="658"
+ y1="20"
+ x2="658"
+ y2="24"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient7624"><stop
+ style="stop-color:#8e8e86;stop-opacity:1;"
+ offset="0"
+ id="stop7620" /><stop
+ style="stop-color:#8e8e86;stop-opacity:0;"
+ offset="1"
+ id="stop7622" /></linearGradient><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7155"
+ id="linearGradient7165"
+ x1="656"
+ y1="25"
+ x2="656"
+ y2="22"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient7155"><stop
+ style="stop-color:#3e4447;stop-opacity:1;"
+ offset="0"
+ id="stop7151" /><stop
+ style="stop-color:#2e3134;stop-opacity:1;"
+ offset="1"
+ id="stop7153" /></linearGradient><radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6078"
+ id="radialGradient6080"
+ cx="662"
+ cy="18"
+ fx="662"
+ fy="18"
+ r="3"
+ gradientTransform="matrix(0.99999794,-1.7103091e-6,1.7879388e-6,1.0000015,0.0013367,0.00110992)"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient6078"><stop
+ style="stop-color:#006868;stop-opacity:1;"
+ offset="0"
+ id="stop6074" /><stop
+ style="stop-color:#3e4447;stop-opacity:1;"
+ offset="1"
+ id="stop6076" /></linearGradient><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7155"
+ id="linearGradient7157"
+ x1="651"
+ y1="20"
+ x2="651"
+ y2="16"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient36859"
+ id="linearGradient11859-1"
+ x1="111"
+ y1="25"
+ x2="111"
+ y2="7"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(608)" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient36859"><stop
+ style="stop-color:#729657;stop-opacity:1;"
+ offset="0"
+ id="stop36855" /><stop
+ style="stop-color:#a5bf6e;stop-opacity:1;"
+ offset="1"
+ id="stop36857" /></linearGradient><radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient36865"
+ id="radialGradient10457-1"
+ cx="112"
+ cy="17"
+ fx="112"
+ fy="17"
+ r="6"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1666668,-6.8921104e-7,5.6666669e-7,1.1666667,589.33332,-2.8332561)" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient36865"><stop
+ style="stop-color:#63271f;stop-opacity:1;"
+ offset="0"
+ id="stop36861" /><stop
+ style="stop-color:#3d1212;stop-opacity:1;"
+ offset="1"
+ id="stop36863" /></linearGradient><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient11855"
+ id="linearGradient11859"
+ x1="111"
+ y1="25"
+ x2="111"
+ y2="7"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient11855"><stop
+ style="stop-color:#57965f;stop-opacity:1;"
+ offset="0"
+ id="stop11851" /><stop
+ style="stop-color:#78bf6e;stop-opacity:1;"
+ offset="1"
+ id="stop11853" /></linearGradient><radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10455"
+ id="radialGradient10457"
+ cx="112"
+ cy="17"
+ fx="112"
+ fy="17"
+ r="6"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1666668,-6.8921104e-7,5.6666669e-7,1.1666667,-18.666684,-2.8332561)" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient10455"><stop
+ style="stop-color:#1b2719;stop-opacity:1;"
+ offset="0"
+ id="stop10451" /><stop
+ style="stop-color:#0f150e;stop-opacity:1;"
+ offset="1"
+ id="stop10453" /></linearGradient><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5295"
+ id="linearGradient5297"
+ x1="239"
+ y1="5"
+ x2="239"
+ y2="27"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient5295"><stop
+ style="stop-color:#25262d;stop-opacity:1;"
+ offset="0"
+ id="stop5291" /><stop
+ style="stop-color:#141519;stop-opacity:1;"
+ offset="1"
+ id="stop5293" /></linearGradient><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5303"
+ id="linearGradient5316"
+ x1="243"
+ y1="17"
+ x2="243"
+ y2="20"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient5303"><stop
+ style="stop-color:#bd44b3;stop-opacity:1;"
+ offset="0"
+ id="stop5299" /><stop
+ style="stop-color:#d84ecd;stop-opacity:1;"
+ offset="1"
+ id="stop5301" /></linearGradient><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5303"
+ id="linearGradient5305"
+ x1="236"
+ y1="17"
+ x2="236"
+ y2="20"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient84376"
+ id="linearGradient84368"
+ x1="48"
+ y1="26"
+ x2="48"
+ y2="6"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(128,32)" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient84376"><stop
+ style="stop-color:#a63649;stop-opacity:1;"
+ offset="0"
+ id="stop84370" /><stop
+ style="stop-color:#df6277;stop-opacity:1;"
+ offset="1"
+ id="stop84381" /></linearGradient><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient288023"
+ id="linearGradient85182"
+ x1="48"
+ y1="6"
+ x2="48"
+ y2="26"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(128,32)" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient288023"><stop
+ style="stop-color:#c1c1c1;stop-opacity:1;"
+ offset="0"
+ id="stop288019" /><stop
+ style="stop-color:#dfdfdf;stop-opacity:1;"
+ offset="1"
+ id="stop288021" /></linearGradient><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient25803"
+ id="linearGradient25805"
+ x1="785"
+ y1="26"
+ x2="785"
+ y2="6"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient25803"><stop
+ style="stop-color:#8e8e86;stop-opacity:1;"
+ offset="0"
+ id="stop25799" /><stop
+ style="stop-color:#a2a29b;stop-opacity:1;"
+ offset="1"
+ id="stop25801" /></linearGradient><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient27992"
+ id="linearGradient17901"
+ x1="496"
+ y1="26"
+ x2="496"
+ y2="6"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient27992"><stop
+ style="stop-color:#c5c7cf;stop-opacity:1;"
+ offset="0"
+ id="stop27990" /><stop
+ style="stop-color:#d8d9e0;stop-opacity:1;"
+ offset="1"
+ id="stop27988" /></linearGradient><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient56358"
+ id="linearGradient18032"
+ gradientUnits="userSpaceOnUse"
+ x1="503"
+ y1="25"
+ x2="503"
+ y2="23"
+ gradientTransform="translate(0,-4)" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient56358"><stop
+ style="stop-color:#ededed;stop-opacity:1;"
+ offset="0"
+ id="stop56354" /><stop
+ style="stop-color:#f4f4f4;stop-opacity:1;"
+ offset="1"
+ id="stop56356" /></linearGradient><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient56358"
+ id="linearGradient18124"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-8)"
+ x1="503"
+ y1="25"
+ x2="503"
+ y2="23" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18539"
+ id="linearGradient18530"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-6)"
+ x1="503"
+ y1="25"
+ x2="503"
+ y2="23" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient18539"><stop
+ style="stop-color:#27414e;stop-opacity:0;"
+ offset="0"
+ id="stop18537" /><stop
+ style="stop-color:#27414e;stop-opacity:0.74901961;"
+ offset="0.49837714"
+ id="stop18535" /><stop
+ style="stop-color:#27414e;stop-opacity:1;"
+ offset="0.83958842"
+ id="stop18533" /></linearGradient><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18539"
+ id="linearGradient18590"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-10)"
+ x1="503"
+ y1="25"
+ x2="503"
+ y2="23" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18539"
+ id="linearGradient18615"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-14)"
+ x1="503"
+ y1="25"
+ x2="503"
+ y2="23" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18539"
+ id="linearGradient18640"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-2)"
+ x1="503"
+ y1="25"
+ x2="503"
+ y2="23" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient56358"
+ id="linearGradient18124-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-12)"
+ x1="503"
+ y1="25"
+ x2="503"
+ y2="23" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient56358"
+ id="linearGradient18124-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-16)"
+ x1="503"
+ y1="25"
+ x2="503"
+ y2="23" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient48524"
+ id="linearGradient48512"
+ gradientUnits="userSpaceOnUse"
+ x1="153"
+ y1="25"
+ x2="135"
+ y2="7"
+ gradientTransform="translate(256)" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient48524"><stop
+ style="stop-color:#dfcd64;stop-opacity:1;"
+ offset="0"
+ id="stop48516" /><stop
+ style="stop-color:#d6b917;stop-opacity:1;"
+ offset="0.11879402"
+ id="stop48518" /><stop
+ style="stop-color:#f6e689;stop-opacity:1;"
+ offset="0.71356344"
+ id="stop48520" /><stop
+ style="stop-color:#d4bb2b;stop-opacity:1;"
+ offset="1"
+ id="stop48522" /></linearGradient><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18899"
+ id="linearGradient18901"
+ x1="805"
+ y1="16"
+ x2="812"
+ y2="16"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient18899"><stop
+ style="stop-color:#bf454c;stop-opacity:1;"
+ offset="0"
+ id="stop18895" /><stop
+ style="stop-color:#df6277;stop-opacity:1;"
+ offset="0.5"
+ id="stop18972" /><stop
+ style="stop-color:#bf454c;stop-opacity:1;"
+ offset="1"
+ id="stop18897" /></linearGradient><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18899"
+ id="linearGradient19011"
+ x1="812"
+ y1="16"
+ x2="820"
+ y2="16"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18899"
+ id="linearGradient19015"
+ gradientUnits="userSpaceOnUse"
+ x1="805"
+ y1="16"
+ x2="812"
+ y2="16"
+ gradientTransform="matrix(-1,0,0,1,1632,0)" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient19917"
+ id="linearGradient22848"
+ gradientUnits="userSpaceOnUse"
+ x1="816"
+ y1="27"
+ x2="816"
+ y2="20" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient19917"><stop
+ style="stop-color:#a02722;stop-opacity:1;"
+ offset="0"
+ id="stop19913" /><stop
+ style="stop-color:#a02722;stop-opacity:0;"
+ offset="1"
+ id="stop19915" /></linearGradient><radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient19935"
+ id="radialGradient19929"
+ cx="816"
+ cy="14"
+ fx="816"
+ fy="14"
+ r="11"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1570249,0,0,1,-128.13223,0)" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient19935"><stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop19933" /><stop
+ style="stop-color:#f6cff4;stop-opacity:1;"
+ offset="1"
+ id="stop19931" /></linearGradient><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient53203"
+ id="linearGradient39079"
+ gradientUnits="userSpaceOnUse"
+ x1="785"
+ y1="26"
+ x2="785"
+ y2="6" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient53203"><stop
+ style="stop-color:#77563b;stop-opacity:1;"
+ offset="0"
+ id="stop53199" /><stop
+ style="stop-color:#86674f;stop-opacity:1;"
+ offset="1"
+ id="stop53201" /></linearGradient><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient19391"
+ id="linearGradient19373"
+ x1="690"
+ y1="22"
+ x2="690"
+ y2="21"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient19391"><stop
+ style="stop-color:#cfaf6b;stop-opacity:1;"
+ offset="0"
+ id="stop19387" /><stop
+ style="stop-color:#ddc694;stop-opacity:1;"
+ offset="1"
+ id="stop19389" /></linearGradient><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient19391"
+ id="linearGradient19435"
+ gradientUnits="userSpaceOnUse"
+ x1="690"
+ y1="22"
+ x2="690"
+ y2="21"
+ gradientTransform="translate(0,-5)" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient19391"
+ id="linearGradient19458"
+ gradientUnits="userSpaceOnUse"
+ x1="690"
+ y1="22"
+ x2="690"
+ y2="21"
+ gradientTransform="translate(0,-10)" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient19391"
+ id="linearGradient19481"
+ gradientUnits="userSpaceOnUse"
+ x1="690"
+ y1="22"
+ x2="690"
+ y2="21"
+ gradientTransform="translate(0,-15)" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient53203"
+ id="linearGradient56913"
+ gradientUnits="userSpaceOnUse"
+ x1="785"
+ y1="26"
+ x2="785"
+ y2="6"
+ gradientTransform="translate(-352)" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient56992"
+ id="linearGradient56984"
+ x1="433"
+ y1="11"
+ x2="433"
+ y2="20"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient56992"><stop
+ style="stop-color:#4d3f33;stop-opacity:0.5;"
+ offset="0"
+ id="stop56986" /><stop
+ style="stop-color:#4d3f33;stop-opacity:0;"
+ offset="1"
+ id="stop56990" /></linearGradient><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29505"
+ id="linearGradient29507"
+ x1="428"
+ y1="14"
+ x2="428"
+ y2="4"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(2,2)" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient29505"><stop
+ style="stop-color:#99cd61;stop-opacity:1;"
+ offset="0"
+ id="stop29501" /><stop
+ style="stop-color:#bccd61;stop-opacity:1;"
+ offset="1"
+ id="stop29503" /></linearGradient><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6068"
+ id="linearGradient39389"
+ x1="565"
+ y1="23"
+ x2="567"
+ y2="21"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient38100"
+ id="linearGradient38102"
+ x1="408.70773"
+ y1="-379.00925"
+ x2="408.70773"
+ y2="-389.8125"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient38100"><stop
+ style="stop-color:#956c4a;stop-opacity:1;"
+ offset="0"
+ id="stop38096" /><stop
+ style="stop-color:#bb7c47;stop-opacity:1;"
+ offset="1"
+ id="stop38098" /></linearGradient><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient39375"
+ id="linearGradient39377"
+ x1="401.63666"
+ y1="-379.00925"
+ x2="401.63666"
+ y2="-389.8125"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient39375"><stop
+ style="stop-color:#d15e65;stop-opacity:1;"
+ offset="0"
+ id="stop39371" /><stop
+ style="stop-color:#b2594e;stop-opacity:1;"
+ offset="1"
+ id="stop39373" /></linearGradient><radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient62774"
+ id="radialGradient62776"
+ cx="624"
+ cy="15"
+ fx="624"
+ fy="15"
+ r="12"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient62774"><stop
+ style="stop-color:#f2effd;stop-opacity:1;"
+ offset="0.45171013"
+ id="stop62772" /><stop
+ style="stop-color:#d2cbf3;stop-opacity:1;"
+ offset="1"
+ id="stop62770" /></linearGradient><radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient62766"
+ id="radialGradient62768"
+ cx="624"
+ cy="16"
+ fx="624"
+ fy="16"
+ r="6"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient62766"><stop
+ style="stop-color:#fafbb9;stop-opacity:1;"
+ offset="0"
+ id="stop62762" /><stop
+ style="stop-color:#fafbb9;stop-opacity:0;"
+ offset="1"
+ id="stop62764" /></linearGradient><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient12453"
+ id="linearGradient12455"
+ x1="351"
+ y1="26"
+ x2="351"
+ y2="10"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient12453"><stop
+ style="stop-color:#b11917;stop-opacity:1;"
+ offset="0"
+ id="stop12449" /><stop
+ style="stop-color:#e65014;stop-opacity:1;"
+ offset="1"
+ id="stop12451" /></linearGradient><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient12299"
+ id="linearGradient12301"
+ x1="324"
+ y1="26"
+ x2="324"
+ y2="10"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient12299"><stop
+ style="stop-color:#0787c1;stop-opacity:1;"
+ offset="0"
+ id="stop12295" /><stop
+ style="stop-color:#65adb9;stop-opacity:1;"
+ offset="1"
+ id="stop12297" /></linearGradient><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient12445"
+ id="linearGradient12447"
+ x1="334"
+ y1="26"
+ x2="334"
+ y2="10"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient12445"><stop
+ style="stop-color:#798b2f;stop-opacity:1;"
+ offset="0"
+ id="stop12441" /><stop
+ style="stop-color:#9fc41e;stop-opacity:1;"
+ offset="1"
+ id="stop12443" /></linearGradient><radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient21157"
+ id="radialGradient21159"
+ cx="368"
+ cy="16"
+ fx="368"
+ fy="16"
+ r="7"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient21157"><stop
+ style="stop-color:#e1edf2;stop-opacity:1;"
+ offset="0"
+ id="stop21153" /><stop
+ style="stop-color:#abbdc4;stop-opacity:1;"
+ offset="0.72112602"
+ id="stop21161" /><stop
+ style="stop-color:#95acb6;stop-opacity:1;"
+ offset="1"
+ id="stop21155" /></linearGradient><radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient21167"
+ id="radialGradient21309"
+ gradientUnits="userSpaceOnUse"
+ cx="400"
+ cy="16"
+ fx="400"
+ fy="16"
+ r="11"
+ gradientTransform="matrix(1.3636364,0,0,1.3636364,-177.45455,-5.8181818)" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient21167"><stop
+ style="stop-color:#e5e6e9;stop-opacity:1;"
+ offset="0.13595749"
+ id="stop21163" /><stop
+ style="stop-color:#c5c7cf;stop-opacity:1;"
+ offset="0.86267382"
+ id="stop21165" /></linearGradient><radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16441"
+ id="radialGradient16443"
+ cx="559.9212"
+ cy="16.022875"
+ fx="559.9212"
+ fy="16.022875"
+ r="11.80246"
+ gradientTransform="matrix(1,0,0,1.0119015,0,-0.19069696)"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient16441"><stop
+ style="stop-color:#9f0bff;stop-opacity:1;"
+ offset="0.4400529"
+ id="stop16439" /><stop
+ style="stop-color:#7111f8;stop-opacity:1;"
+ offset="1"
+ id="stop16437" /></linearGradient><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath70915-4-5-0-2-7-5-3-9-4"><path
+ sodipodi:type="star"
+ style="opacity:1;fill:#bd44b3;fill-opacity:1;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="path70917-7-9-2-9-4-0-3-1-9"
+ inkscape:flatsided="false"
+ sodipodi:sides="8"
+ sodipodi:cx="560"
+ sodipodi:cy="16"
+ sodipodi:r1="10.946013"
+ sodipodi:r2="12.727922"
+ sodipodi:arg1="0.78539816"
+ sodipodi:arg2="1.1780972"
+ inkscape:rounded="0.29"
+ inkscape:randomized="0.014"
+ d="m 567.75822,23.780557 c -1.02129,1.017197 -1.40469,3.26498 -2.72399,3.814557 -1.3193,0.549578 -3.76804,-0.657585 -5.20836,-0.687167 -1.44032,-0.02958 -3.32578,1.488919 -4.65697,0.936933 -1.33119,-0.551986 -2.06769,-2.91036 -3.08281,-3.927341 -1.01511,-1.016982 -3.30517,-1.550442 -3.83572,-2.877061 -0.53055,-1.326619 0.75095,-3.615262 0.76004,-5.050859 0.009,-1.435596 -1.30602,-3.611418 -0.75806,-4.936294 0.54796,-1.3248769 2.7981,-1.6627753 3.83368,-2.6540083 1.03559,-0.9912328 1.77327,-3.6016077 3.08037,-4.1709394 1.3071,-0.5693318 3.41767,0.6823629 4.85198,0.6871672 1.43432,0.0048 3.67769,-1.1020263 5.01335,-0.5805511 1.33567,0.5214752 1.68844,2.9320874 2.72643,3.9273412 1.03799,0.9952536 3.30533,1.5532379 3.83572,2.8770604 0.53039,1.323824 -0.73478,3.255376 -0.76004,4.694477 -0.0253,1.439101 1.28343,3.594239 0.75806,4.936295 -0.52537,1.342056 -2.8124,1.993192 -3.83368,3.01039 z"
+ transform="matrix(0.60389168,0.3121766,-0.3121766,0.60389168,226.77688,-168.46627)" /></clipPath><radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14255"
+ id="radialGradient14257"
+ cx="560"
+ cy="16"
+ fx="560"
+ fy="16"
+ r="9"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient14255"><stop
+ style="stop-color:#e570f7;stop-opacity:1;"
+ offset="0"
+ id="stop14251" /><stop
+ style="stop-color:#d829c8;stop-opacity:1;"
+ offset="1"
+ id="stop14253" /></linearGradient><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16452"
+ id="linearGradient16454"
+ x1="560"
+ y1="25"
+ x2="560"
+ y2="11"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient16452"><stop
+ style="stop-color:#f6cff4;stop-opacity:1;"
+ offset="0"
+ id="stop16450" /><stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop16448" /></linearGradient><radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2066"
+ id="radialGradient2757-3"
+ cx="496.06177"
+ cy="17.211182"
+ fx="495.87827"
+ fy="18.730774"
+ r="11"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.5554022,0,0,1.2337313,-771.57556,-4.2669434)" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient2066"><stop
+ style="stop-color:#ceb8aa;stop-opacity:1;"
+ offset="0.23876573"
+ id="stop2062" /><stop
+ style="stop-color:#b39888;stop-opacity:1;"
+ offset="0.51858544"
+ id="stop2064" /></linearGradient><linearGradient
+ inkscape:collect="always"
+ id="linearGradient2085"><stop
+ style="stop-color:#261a0a;stop-opacity:1;"
+ offset="0"
+ id="stop2081" /><stop
+ style="stop-color:#3c2b13;stop-opacity:1;"
+ offset="1"
+ id="stop2083" /></linearGradient><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2564"
+ id="linearGradient2566"
+ x1="466"
+ y1="27"
+ x2="466"
+ y2="22"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient2564"><stop
+ style="stop-color:#45362e;stop-opacity:1;"
+ offset="0"
+ id="stop2560" /><stop
+ style="stop-color:#59463c;stop-opacity:1;"
+ offset="1"
+ id="stop2562" /></linearGradient><radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2739"
+ id="radialGradient2757"
+ cx="496.06177"
+ cy="17.211182"
+ fx="495.87827"
+ fy="18.730774"
+ r="11"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.5554022,0,0,1.2337313,-515.57556,-4.2669434)" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient2739"><stop
+ style="stop-color:#cca997;stop-opacity:1;"
+ offset="0.23748928"
+ id="stop2755" /><stop
+ style="stop-color:#bd8e74;stop-opacity:1;"
+ offset="0.51858547"
+ id="stop2735" /></linearGradient><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1330"
+ id="linearGradient1332"
+ x1="487"
+ y1="15"
+ x2="487"
+ y2="5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(256)" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient1330"><stop
+ style="stop-color:#261a0a;stop-opacity:1;"
+ offset="0"
+ id="stop1326" /><stop
+ style="stop-color:#422e11;stop-opacity:1;"
+ offset="1"
+ id="stop1328" /></linearGradient><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1463"
+ id="linearGradient1465"
+ x1="755"
+ y1="27"
+ x2="755"
+ y2="22"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient1463"><stop
+ style="stop-color:#45220e;stop-opacity:1;"
+ offset="0"
+ id="stop1459" /><stop
+ style="stop-color:#552910;stop-opacity:1;"
+ offset="1"
+ id="stop1461" /></linearGradient><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1503"
+ id="linearGradient1505"
+ x1="748"
+ y1="20"
+ x2="748"
+ y2="17"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient1503"><stop
+ style="stop-color:#5c3874;stop-opacity:1;"
+ offset="0"
+ id="stop1499" /><stop
+ style="stop-color:#3c3874;stop-opacity:1;"
+ offset="1"
+ id="stop1501" /></linearGradient><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1308"
+ id="linearGradient1310"
+ x1="16"
+ y1="27"
+ x2="16"
+ y2="5"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient1308"><stop
+ style="stop-color:#f3db6c;stop-opacity:1;"
+ offset="0"
+ id="stop1304" /><stop
+ style="stop-color:#ffeea9;stop-opacity:1;"
+ offset="1"
+ id="stop1306" /></linearGradient><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath7052-4-6"><rect
+ style="fill:#ff0000;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect7054-2-2"
+ width="6"
+ height="10"
+ x="6"
+ y="14"
+ ry="1" /></clipPath><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1440"
+ id="linearGradient1442"
+ x1="7"
+ y1="24"
+ x2="11"
+ y2="14"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient1440"><stop
+ style="stop-color:#2c251f;stop-opacity:1;"
+ offset="0"
+ id="stop1436" /><stop
+ style="stop-color:#4d3f33;stop-opacity:1;"
+ offset="1"
+ id="stop1438" /></linearGradient><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1460"
+ id="linearGradient1462"
+ x1="10"
+ y1="18"
+ x2="12"
+ y2="14"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient1460"><stop
+ style="stop-color:#4c7aba;stop-opacity:1;"
+ offset="0"
+ id="stop1456" /><stop
+ style="stop-color:#86c3cf;stop-opacity:1;"
+ offset="1"
+ id="stop1458" /></linearGradient><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath87687"><rect
+ style="fill:#ff0000;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect87685"
+ width="6"
+ height="10"
+ x="6"
+ y="14"
+ ry="1" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath87707"><rect
+ style="fill:#ff0000;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect87705"
+ width="6"
+ height="10"
+ x="6"
+ y="14"
+ ry="1" /></clipPath><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient292700"
+ id="linearGradient292686"
+ x1="86.052681"
+ y1="26.999552"
+ x2="86"
+ y2="5"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient292700"><stop
+ style="stop-color:#d0d0d0;stop-opacity:1;"
+ offset="0.23078403"
+ id="stop292702" /><stop
+ style="stop-color:#eeeeee;stop-opacity:1;"
+ offset="0.83153141"
+ id="stop292698" /></linearGradient><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient293074"
+ id="linearGradient293076"
+ x1="80"
+ y1="31"
+ x2="80"
+ y2="21"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient293074"><stop
+ style="stop-color:#a63649;stop-opacity:1;"
+ offset="0"
+ id="stop293070" /><stop
+ style="stop-color:#df6277;stop-opacity:1;"
+ offset="0.52521378"
+ id="stop293078" /><stop
+ style="stop-color:#a63649;stop-opacity:1;"
+ offset="1"
+ id="stop293072" /></linearGradient><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2085"
+ id="linearGradient42830"
+ x1="77"
+ y1="17"
+ x2="77"
+ y2="14"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient292039"
+ id="linearGradient292041"
+ x1="89"
+ y1="25"
+ x2="89"
+ y2="18"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient292039"><stop
+ style="stop-color:#fb9168;stop-opacity:1;"
+ offset="0"
+ id="stop292035" /><stop
+ style="stop-color:#f3db6c;stop-opacity:1;"
+ offset="1"
+ id="stop292037" /></linearGradient><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient288023"
+ id="linearGradient288033"
+ x1="183"
+ y1="11"
+ x2="183"
+ y2="7"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient288023"
+ id="linearGradient288025"
+ x1="171"
+ y1="11"
+ x2="171"
+ y2="7"
+ gradientUnits="userSpaceOnUse" /><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath51555-6-8-0-1-3-1-4"><rect
+ style="fill:#fb9168;fill-opacity:1;stroke-width:0.271456;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect51557-5-1-8-7-7-0-9"
+ width="19.999996"
+ height="16"
+ x="178.38519"
+ y="5.9999976"
+ ry="3" /></clipPath><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient287141"
+ id="linearGradient287143"
+ x1="181.38519"
+ y1="21.999998"
+ x2="181.38519"
+ y2="5.9999976"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient287141"><stop
+ style="stop-color:#fb6a32;stop-opacity:1;"
+ offset="0"
+ id="stop287137" /><stop
+ style="stop-color:#fb9168;stop-opacity:1;"
+ offset="1"
+ id="stop287139" /></linearGradient><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient287169"
+ id="linearGradient287171"
+ x1="178.38519"
+ y1="21.999998"
+ x2="198.38519"
+ y2="21.999998"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient287169"><stop
+ style="stop-color:#d6d2d2;stop-opacity:1;"
+ offset="0"
+ id="stop287165" /><stop
+ style="stop-color:#aca7a7;stop-opacity:1;"
+ offset="0.49945405"
+ id="stop287173" /><stop
+ style="stop-color:#d6d2d2;stop-opacity:1;"
+ offset="0.9989081"
+ id="stop287167" /></linearGradient><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath51465-6-2-8-5-5-4-9"><rect
+ style="fill:#dfdfdf;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect51467-3-9-5-9-9-2-3"
+ width="10.000002"
+ height="5.0000005"
+ x="183.38519"
+ y="17.999998"
+ ry="0.99999958" /></clipPath><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient287187"
+ id="linearGradient287189"
+ x1="192.38519"
+ y1="22.999998"
+ x2="192.38519"
+ y2="17.999998"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient287187"><stop
+ style="stop-color:#dfdfdf;stop-opacity:1;"
+ offset="0"
+ id="stop287183" /><stop
+ style="stop-color:#f3f3f3;stop-opacity:1;"
+ offset="1"
+ id="stop287185" /></linearGradient><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath52515-9-3-0-6-2-2-6"><rect
+ style="fill:#d6d2d2;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect52517-4-9-9-2-2-2-0"
+ width="6"
+ height="3"
+ x="179.38519"
+ y="13.999998"
+ ry="0.99999958" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath87819"><rect
+ style="fill:#d6d2d2;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect87817"
+ width="6"
+ height="3"
+ x="179.38519"
+ y="13.999998"
+ ry="0.99999958" /></clipPath><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath87823"><rect
+ style="fill:#d6d2d2;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect87821"
+ width="6"
+ height="3"
+ x="179.38519"
+ y="13.999998"
+ ry="0.99999958" /></clipPath><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3108"
+ id="linearGradient94737"
+ gradientUnits="userSpaceOnUse"
+ x1="70.852509"
+ y1="141.75883"
+ x2="70.852509"
+ y2="0.053809531" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3108"
+ id="linearGradient94739"
+ gradientUnits="userSpaceOnUse"
+ x1="70.852509"
+ y1="141.75883"
+ x2="70.852509"
+ y2="0.053809531" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2085"
+ id="linearGradient94741"
+ gradientUnits="userSpaceOnUse"
+ x1="504"
+ y1="15"
+ x2="504"
+ y2="5" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1503"
+ id="linearGradient94747"
+ gradientUnits="userSpaceOnUse"
+ x1="748"
+ y1="20"
+ x2="748"
+ y2="17" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1503"
+ id="linearGradient94749"
+ gradientUnits="userSpaceOnUse"
+ x1="748"
+ y1="20"
+ x2="748"
+ y2="17" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2085"
+ id="linearGradient94751"
+ gradientUnits="userSpaceOnUse"
+ x1="77"
+ y1="17"
+ x2="77"
+ y2="14" /></defs><sodipodi:namedview
+ id="namedview170"
+ pagecolor="#ffffff"
+ bordercolor="#000000"
+ borderopacity="0.25"
+ inkscape:showpageshadow="2"
+ inkscape:pageopacity="0.0"
+ inkscape:pagecheckerboard="0"
+ inkscape:deskcolor="#d1d1d1"
+ showgrid="true"
+ inkscape:zoom="16"
+ inkscape:cx="13.3125"
+ inkscape:cy="42.25"
+ inkscape:window-width="1366"
+ inkscape:window-height="699"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="i_steve"
+ showguides="true"><inkscape:grid
+ empspacing="32"
+ type="xygrid"
+ id="grid451"
+ originx="0"
+ originy="0" /><sodipodi:guide
+ position="48,1008"
+ orientation="0,-1"
+ id="guide80876"
+ inkscape:locked="false" /><sodipodi:guide
+ position="688,996"
+ orientation="1,0"
+ id="guide87005"
+ inkscape:locked="false" /></sodipodi:namedview><title
+ id="title132">Prism Launcher Logo</title><metadata
+ id="metadata166"><rdf:RDF><cc:Work
+ rdf:about=""><dc:title>Prism Launcher Logo</dc:title><dc:date>19/10/2022</dc:date><dc:creator><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:creator><dc:contributor><cc:Agent><dc:title>AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke</dc:title></cc:Agent></dc:contributor><dc:source>https://github.com/PrismLauncher/PrismLauncher</dc:source><dc:rights><cc:Agent><dc:title>CC BY-SA 4.0</dc:title></cc:Agent></dc:rights><dc:publisher><cc:Agent><dc:title>Prism Launcher</dc:title></cc:Agent></dc:publisher></cc:Work></rdf:RDF></metadata><g
+ id="g23616"
+ transform="matrix(1,0,0,0.6,0,6.2)" /><g
+ id="i_diamond"><rect
+ style="fill:#1bc3d7;fill-opacity:1;stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect15088-8-0"
+ width="20"
+ height="20"
+ x="134"
+ y="6"
+ ry="3" /><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-88"
+ width="32"
+ height="32"
+ x="128"
+ y="0" /><rect
+ style="fill:url(#linearGradient2973);fill-opacity:1;stroke:none;stroke-width:1;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect40970-3-3"
+ width="18"
+ height="18"
+ x="135"
+ y="7"
+ ry="2" /></g><g
+ id="i_brick"
+ style="opacity:0"
+ transform="translate(32)"><rect
+ style="fill:#df6277;fill-opacity:1;stroke-width:0.277182;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect13011"
+ width="22"
+ height="22"
+ x="37"
+ y="5"
+ ry="3" /><path
+ id="rect13933"
+ style="fill:#dfdfdf;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 47,5 v 5 H 37 v 2 h 4 v 8 h -4 v 2 h 10 v 5 h 2 v -5 h 10 v -2 h -4 v -8 h 4 V 10 H 49 V 5 Z m -4,7 h 10 v 8 H 43 Z" /><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-7"
+ width="32"
+ height="32"
+ x="32"
+ y="0" /></g><g
+ id="i_enderpearl-7"
+ transform="translate(-192)"><circle
+ style="fill:url(#radialGradient3002-5);fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="path78788-8"
+ cx="272"
+ cy="16"
+ r="12" /><path
+ id="circle80343-2-6"
+ style="fill:#62b397;fill-opacity:1;stroke-width:0.220486;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 272,7 c -4.97057,0 -9,4.029438 -9,9 0,4.970562 4.02943,9 9,9 4.97056,0 9,-4.029438 9,-9 0,-4.970562 -4.02944,-9 -9,-9 z"
+ sodipodi:nodetypes="sssss" /><circle
+ style="fill:url(#radialGradient3407-4);fill-opacity:1;stroke-width:0.187412;paint-order:stroke markers fill;stop-color:#000000"
+ id="circle81814-8"
+ cx="272"
+ cy="16"
+ r="6" /><path
+ id="circle80343-8"
+ style="fill:url(#radialGradient3855-4);fill-opacity:1;stroke-width:0.220486;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 272,6 c -5.52284,0 -10,4.477158 -10,10 h 3 c 0,-3.865989 3.13401,-7 7,-7 z" /><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-4-4"
+ width="32"
+ height="32"
+ x="256"
+ y="0" /></g><g
+ id="i_modrinth"
+ transform="translate(-480,32)"><g
+ id="g83832"
+ transform="matrix(0.16936591,0,0,0.16936591,580,3.9908865)"
+ style="fill:url(#linearGradient3110);fill-opacity:1"><path
+ d="M 159.07,89.29 A 70.94,70.94 0 1 0 20,63.52 H 32 A 58.78,58.78 0 0 1 145.23,49.93 l -11.66,3.12 a 46.54,46.54 0 0 0 -29,-26.52 l -2.15,12.13 a 34.31,34.31 0 0 1 2.77,63.26 l 3.19,11.9 a 46.52,46.52 0 0 0 28.33,-49 l 11.62,-3.1 A 57.94,57.94 0 0 1 147.27,85 Z"
+ transform="translate(-19.79)"
+ fill="var(--color-brand)"
+ fill-rule="evenodd"
+ id="path83828"
+ style="fill:url(#linearGradient94737);fill-opacity:1" /><path
+ d="M 108.92,139.3 A 70.93,70.93 0 0 1 19.79,76 h 12 a 59.48,59.48 0 0 0 1.78,9.91 58.73,58.73 0 0 0 3.63,9.91 l 10.68,-6.41 a 46.58,46.58 0 0 1 44.72,-65 L 90.43,36.54 A 34.38,34.38 0 0 0 57.36,79.75 C 57.67,80.88 58,82 58.43,83 L 72.09,74.81 68,63.93 80.9,50.68 97.21,47.17 101.9,53 l -7.52,7.61 -6.55,2.06 -4.69,4.82 2.3,6.38 c 0,0 4.64,4.94 4.65,4.94 l 6.57,-1.74 4.67,-5.13 10.2,-3.24 3,6.84 L 104.05,88.43 86.41,94 78.49,85.19 64.7,93.48 a 34.44,34.44 0 0 0 28.72,11.59 L 96.61,117 A 46.6,46.6 0 0 1 54.13,99.83 l -10.64,6.38 a 58.81,58.81 0 0 0 99.6,-9.77 l 11.8,4.29 a 70.77,70.77 0 0 1 -45.97,38.57 z"
+ fill="var(--color-brand)"
+ id="path83830"
+ style="fill:url(#linearGradient94739);fill-opacity:1"
+ transform="translate(-19.79)" /></g><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-8-5"
+ width="32"
+ height="32"
+ x="576"
+ y="0" /></g><g
+ id="i_flame"
+ transform="translate(-192,64)"><path
+ id="path5010"
+ style="fill:url(#linearGradient1470);fill-opacity:1;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 299,10 a 2,2 0 0 0 -2,2 h -3 -5 c 0,2.761421 2.23858,5 5,5 h 5 v 1 c 0,1.656852 1.34315,3 3,3 v 1 c -1.10457,0 -2,0.895438 -2,2 v 2 h 11 v -2 c 0,-1.104562 -0.89543,-2 -2,-2 v -1 c 1.10457,0 2,-0.895432 2,-2 0,-3.865965 3.13401,-7 7,-7 v -2 z" /><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-7-9"
+ width="32"
+ height="32"
+ x="288"
+ y="0" /><path
+ id="path225757"
+ style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ d="M 306.94922,12 C 305.86851,12.02738 305,12.912691 305,14 v 1 a 1,1 0 0 1 -1,-1 v 2 c 0,0.552284 0.44772,1 1,1 0,0.552284 -0.44772,1 -1,1 -0.55228,0 -1,-0.447716 -1,-1 -0.55228,0 -1,0.447716 -1,1 0,1.104568 0.89543,2 2,2 0.55228,0 1,0.447716 1,1 0,-0.552284 0.44772,-1 1,-1 h 1 c 0.55228,0 1,-0.447716 1,-1 v -1 c 0,0.552284 -0.44772,1 -1,1 -0.55228,0 -1,-0.447716 -1,-1 0.55228,0 1,-0.447716 1,-1 v -1 c 0,-0.552284 -0.44772,-1 -1,-1 v -1 c 0,-1.087309 0.86851,-1.97262 1.94922,-2 H 307 c -0.0173,0 -0.0336,-4.35e-4 -0.0508,0 z" /></g><g
+ id="i_skeleton"
+ transform="translate(-608)"><rect
+ style="fill:url(#linearGradient6070);fill-opacity:1;stroke-width:0.277182;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect543-0"
+ width="22"
+ height="22"
+ x="645"
+ y="5"
+ ry="3" /><rect
+ style="fill:url(#linearGradient7626);fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect61092"
+ width="6"
+ height="3"
+ x="653"
+ y="20"
+ ry="1" /><rect
+ style="fill:url(#linearGradient7165);fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect60969"
+ width="16"
+ height="3"
+ x="648"
+ y="22"
+ ry="1" /><rect
+ style="fill:url(#radialGradient6080);fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect63182"
+ width="6"
+ height="4"
+ x="659"
+ y="16"
+ ry="1" /><rect
+ style="fill:url(#linearGradient7157);fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect63184"
+ width="6"
+ height="4"
+ x="647"
+ y="16"
+ ry="1" /><rect
+ style="fill:#00ffff;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect63186"
+ width="2"
+ height="2"
+ x="661"
+ y="17" /><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-88-4"
+ width="32"
+ height="32"
+ x="640"
+ y="0" /></g><g
+ id="i_squarecreeper"
+ transform="translate(-672,64)"><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-8-3-0"
+ width="32"
+ height="32"
+ x="704"
+ y="0" /><rect
+ style="fill:url(#linearGradient11859-1);fill-opacity:1;stroke-width:0.226785;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect543-0-2-3-9"
+ width="18"
+ height="18"
+ x="711"
+ y="7"
+ ry="2.4545455" /><path
+ id="rect29291-0"
+ style="fill:url(#radialGradient10457-1);fill-opacity:1;stroke-width:0.529166;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 714,12 v 4 h 4 v -4 z m 4,4 v 2 h -2 v 6 h 2 v -2 h 4 v 2 h 2 v -6 h -2 v -2 z m 4,0 h 4 v -4 h -4 z" /><rect
+ style="opacity:1;fill:#ff0000;fill-opacity:1;stroke:none;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect37478"
+ width="2"
+ height="2"
+ x="722"
+ y="14" /><rect
+ style="fill:#ff0000;fill-opacity:1;stroke:none;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect37478-7"
+ width="2"
+ height="2"
+ x="716"
+ y="14" /></g><g
+ id="i_creeper"
+ transform="translate(-64,32)"><rect
+ style="fill:url(#linearGradient11859);fill-opacity:1;stroke-width:0.226785;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect543-0-2-3"
+ width="18"
+ height="18"
+ x="103"
+ y="7"
+ ry="2.4545455" /><path
+ id="rect29291"
+ style="fill:url(#radialGradient10457);fill-opacity:1;stroke-width:0.529166;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 106,12 v 4 h 4 v -4 z m 4,4 v 2 h -2 v 6 h 2 v -2 h 4 v 2 h 2 v -6 h -2 v -2 z m 4,0 h 4 v -4 h -4 z" /><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-7-6"
+ width="32"
+ height="32"
+ x="96"
+ y="0" /></g><g
+ id="i_enderman"
+ transform="translate(-192,96)"><rect
+ style="fill:url(#linearGradient5297);fill-opacity:1;stroke-width:0.277182;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect543-0-2"
+ width="22"
+ height="22"
+ x="229"
+ y="5"
+ ry="3" /><rect
+ style="fill:url(#linearGradient5316);fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect63182-8"
+ width="7"
+ height="3"
+ x="242"
+ y="17"
+ ry="1" /><rect
+ style="fill:url(#linearGradient5305);fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect63184-7"
+ width="7"
+ height="3"
+ x="231"
+ y="17"
+ ry="1" /><rect
+ style="fill:#792aac;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect75119"
+ width="2"
+ height="2"
+ x="234"
+ y="18" /><rect
+ style="fill:#792aac;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect75474"
+ width="2"
+ height="2"
+ x="244"
+ y="18" /><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-7-6-1"
+ width="32"
+ height="32"
+ x="224"
+ y="0" /></g><g
+ id="i_stone"
+ transform="translate(-576,64)"><rect
+ style="fill:url(#linearGradient25805);fill-opacity:1;stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect15088-9"
+ width="20"
+ height="20"
+ x="774"
+ y="6"
+ ry="3" /><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-4-1"
+ width="32"
+ height="32"
+ x="768"
+ y="0" /><path
+ id="path47261"
+ style="opacity:0.5;fill:#bfbfbb;fill-opacity:1;stroke-width:0.999997;stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 777,11 v 1 h 12 v -1 z m 14,2 v 1 h 2 v -1 z m -17,2 v 1 h 8 v -1 z m 16,4 v 1 h 4 v -1 z m -8,2 v 1 h 2 v -1 z m 2,3 v 1 h 5 v -1 z" /><path
+ id="path47259"
+ style="opacity:0.5;fill:#7e7e77;fill-opacity:1;stroke-width:0.999997;stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 774,8 v 1 h 7 V 8 Z m 15,0 v 1 h 5 V 8 Z m -4,8 v 1 h 5 v -1 z m -11,4 v 1 h 6 v -1 z m 3,3 v 1 h 2 v -1 z m 14,0 v 1 h 3 v -1 z" /></g><g
+ id="i_iron"
+ transform="translate(-352,64)"><rect
+ style="fill:url(#linearGradient17901);fill-opacity:1;stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect15088"
+ width="20"
+ height="20"
+ x="486"
+ y="6"
+ ry="3" /><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-7-6-1-2"
+ width="32"
+ height="32"
+ x="480"
+ y="0" /><path
+ id="rect17965"
+ style="fill:#efefef;fill-opacity:1;stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 487,23 c 0,1.107999 0.892,2 2,2 h 14 c 1.108,0 2,-0.892001 2,-2 z" /><rect
+ style="fill:url(#linearGradient18032);fill-opacity:1;stroke-width:0.999996;stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect15357-7-8"
+ width="18"
+ height="2"
+ x="487"
+ y="19" /><rect
+ style="fill:url(#linearGradient18124);fill-opacity:1;stroke-width:0.999996;stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect15357-7-8-4"
+ width="18"
+ height="2"
+ x="487"
+ y="15" /><rect
+ style="opacity:0.1;fill:url(#linearGradient18530);fill-opacity:1;stroke-width:0.999996;stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect15357-7-8-4-7"
+ width="18"
+ height="2"
+ x="487"
+ y="17" /><rect
+ style="opacity:0.1;fill:url(#linearGradient18590);fill-opacity:1;stroke-width:0.999996;stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect15357-7-8-4-7-5"
+ width="18"
+ height="2"
+ x="487"
+ y="13" /><rect
+ style="opacity:0.1;fill:url(#linearGradient18615);fill-opacity:1;stroke-width:0.999996;stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect15357-7-8-4-7-6"
+ width="18"
+ height="2"
+ x="487"
+ y="9" /><rect
+ style="opacity:0.1;fill:url(#linearGradient18640);fill-opacity:1;stroke-width:0.999996;stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect15357-7-8-4-7-56"
+ width="18"
+ height="2"
+ x="487"
+ y="21" /><rect
+ style="fill:url(#linearGradient18124-2);fill-opacity:1;stroke-width:0.999996;stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect15357-7-8-4-1"
+ width="18"
+ height="2"
+ x="487"
+ y="11" /><path
+ id="rect15357-7-8-4-5"
+ style="fill:url(#linearGradient18124-0);fill-opacity:1;stroke-width:0.999996;stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 489,7 c -1.108,0 -2,0.8920011 -2,2 h 18 c 0,-1.1079989 -0.892,-2 -2,-2 z" /></g><g
+ id="i_gold"
+ transform="translate(-256,32)"><rect
+ style="fill:#d7bc21;fill-opacity:1;stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect15088-8"
+ width="20"
+ height="20"
+ x="390"
+ y="6"
+ ry="3" /><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-88-6"
+ width="32"
+ height="32"
+ x="384"
+ y="0" /><rect
+ style="fill:url(#linearGradient48512);fill-opacity:1;stroke:none;stroke-width:1;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect40970-3"
+ width="18"
+ height="18"
+ x="391"
+ y="7"
+ ry="2" /></g><g
+ id="i_tnt"
+ transform="translate(-640,64)"><rect
+ style="fill:#a02722;fill-opacity:1;stroke-width:0.277182;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect13011-7"
+ width="20"
+ height="20"
+ x="806"
+ y="6"
+ ry="3" /><g
+ id="g19020"><path
+ id="rect18703"
+ style="opacity:1;fill:url(#linearGradient18901);fill-opacity:1;stroke:none;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 809,6 c -1.662,0 -3,1.3380017 -3,3 v 14 c 0,1.661998 1.338,3 3,3 h 3 V 6 Z"
+ sodipodi:nodetypes="ssssccs" /><rect
+ style="opacity:1;fill:url(#linearGradient19011);fill-opacity:1;stroke:none;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect19003"
+ width="6"
+ height="20"
+ x="813"
+ y="6" /><path
+ id="path19013"
+ style="opacity:1;fill:url(#linearGradient19015);fill-opacity:1;stroke:none;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 823,6 c 1.662,0 3,1.3380017 3,3 v 14 c 0,1.661998 -1.338,3 -3,3 h -3 V 6 Z"
+ sodipodi:nodetypes="ssssccs" /></g><rect
+ style="opacity:1;fill:url(#linearGradient22848);fill-opacity:1;stroke:none;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect19910"
+ width="20"
+ height="20"
+ x="806"
+ y="6"
+ ry="3" /><rect
+ style="opacity:1;fill:url(#radialGradient19929);fill-opacity:1;stroke:none;stroke-width:0.295813;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect121411"
+ width="20"
+ height="10"
+ x="806"
+ y="11" /><path
+ id="rect122467"
+ style="opacity:1;fill:#4d3f33;fill-opacity:1;stroke:none;stroke-width:0.374177;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 808,13 v 2 h 1 v 4 h 2 v -4 h 1 v -2 z m 5,0 v 6 h 2 v -3.171875 l 2,2 V 19 h 2 v -6 h -2 v 2 l -2,-2 z m 7,0 v 2 h 1 v 4 h 2 v -4 h 1 v -2 z"
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccc" /><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-7-9-7"
+ width="32"
+ height="32"
+ x="800"
+ y="0" /></g><g
+ id="i_stone-2"
+ transform="translate(-576,32)"><rect
+ style="fill:url(#linearGradient39079);fill-opacity:1;stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect15088-9-1"
+ width="20"
+ height="20"
+ x="774"
+ y="6"
+ ry="3" /><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-4-1-0"
+ width="32"
+ height="32"
+ x="768"
+ y="0" /><path
+ id="rect48773"
+ style="opacity:0.268946;fill:#a88356;fill-opacity:1;stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ d="M 776.13672,8 C 776.05936,8.00781 776,8.07286 776,8.15234 V 9.84766 C 776,9.93244 776.06756,10 776.15234,10 h 1.69532 C 777.93244,10 778,9.93244 778,9.84766 V 8.15234 C 778,8.06756 777.93244,8 777.84766,8 h -1.69532 c -0.005,0 -0.0105,-5.2e-4 -0.0156,0 z m 10,2 C 786.05936,10.00781 786,10.07286 786,10.15234 v 1.69532 C 786,11.93244 786.06756,12 786.15234,12 h 1.69532 C 787.93244,12 788,11.93244 788,11.84766 V 10.15234 C 788,10.06756 787.93244,10 787.84766,10 h -1.69532 c -0.005,0 -0.0105,-5.2e-4 -0.0156,0 z m -8,4 C 778.05936,14.00781 778,14.07286 778,14.15234 v 1.69532 C 778,15.93244 778.06756,16 778.15234,16 h 1.69532 C 779.93244,16 780,15.93244 780,15.84766 V 14.15234 C 780,14.06756 779.93244,14 779.84766,14 h -1.69532 c -0.005,0 -0.0105,-5.2e-4 -0.0156,0 z m 13,2 C 791.05936,16.00781 791,16.07286 791,16.15234 v 1.69532 C 791,17.93244 791.06756,18 791.15234,18 h 1.69532 C 792.93244,18 793,17.93244 793,17.84766 V 16.15234 C 793,16.06756 792.93244,16 792.84766,16 h -1.69532 c -0.005,0 -0.0105,-5.2e-4 -0.0156,0 z m -7,2 C 784.05936,18.00781 784,18.07286 784,18.15234 v 1.69532 C 784,19.93244 784.06756,20 784.15234,20 h 1.69532 C 785.93244,20 786,19.93244 786,19.84766 V 18.15234 C 786,18.06756 785.93244,18 785.84766,18 h -1.69532 c -0.005,0 -0.0105,-5.2e-4 -0.0156,0 z m -9,2 C 775.05936,20.00781 775,20.07286 775,20.15234 v 1.69532 C 775,21.93244 775.06756,22 775.15234,22 h 1.69532 C 776.93244,22 777,21.93244 777,21.84766 V 20.15234 C 777,20.06756 776.93244,20 776.84766,20 h -1.69532 c -0.005,0 -0.0105,-5.2e-4 -0.0156,0 z m 15,2 C 790.05936,22.00781 790,22.07286 790,22.15234 v 1.69532 C 790,23.93244 790.06756,24 790.15234,24 h 1.69532 C 791.93244,24 792,23.93244 792,23.84766 V 22.15234 C 792,22.06756 791.93244,22 791.84766,22 h -1.69532 c -0.005,0 -0.0105,-5.2e-4 -0.0156,0 z m -9,2 C 781.05936,24.00781 781,24.07286 781,24.15234 v 1.69532 C 781,25.93244 781.06756,26 781.15234,26 h 1.69532 C 782.93244,26 783,25.93244 783,25.84766 V 24.15234 C 783,24.06756 782.93244,24 782.84766,24 h -1.69532 c -0.005,0 -0.0105,-5.2e-4 -0.0156,0 z" /></g><g
+ id="i_planks"
+ transform="translate(-512)"><rect
+ style="fill:#a88a4a;fill-opacity:1;stroke-width:0.277182;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect56542-7-5-0"
+ width="20"
+ height="20"
+ x="678"
+ y="6"
+ ry="3" /><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-7-4-9"
+ width="32"
+ height="32"
+ x="672"
+ y="0" /><path
+ id="rect15086"
+ style="fill:url(#linearGradient19373);fill-opacity:1;stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 678,21 v 2 c 0,0.771066 0.2909,1.469665 0.76562,2 h 18.46876 C 697.7091,24.469665 698,23.771066 698,23 v -2 z" /><rect
+ style="fill:url(#linearGradient19435);fill-opacity:1;stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect15086-4"
+ width="20"
+ height="4"
+ x="678"
+ y="16"
+ ry="0" /><rect
+ style="fill:url(#linearGradient19458);fill-opacity:1;stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect15086-2"
+ width="20"
+ height="4"
+ x="678"
+ y="11"
+ ry="0" /><path
+ id="rect15086-9"
+ style="fill:url(#linearGradient19481);fill-opacity:1;stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 681,6 c -1.662,0 -3,1.3380017 -3,3 v 1 h 20 V 9 c 0,-1.6619983 -1.338,-3 -3,-3 z" /></g><g
+ id="i_grass"
+ transform="translate(-224)"><path
+ id="rect15088-9-1-7"
+ style="fill:url(#linearGradient56913);stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 425,8 h 14 l 3,1 v 14 c 0,1.662 -1.338,3 -3,3 h -14 c -1.662,0 -3,-1.338 -3,-3 V 9 Z"
+ sodipodi:nodetypes="cccsssscc" /><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-7-4-8"
+ width="32"
+ height="32"
+ x="416"
+ y="0" /><path
+ id="rect48773-2"
+ style="opacity:0.268946;fill:#a88356;fill-opacity:1;stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ d="M 424.13672,8 C 424.05936,8.00781 424,8.07286 424,8.15234 V 9.84766 C 424,9.93244 424.06756,10 424.15234,10 h 1.69532 C 425.93244,10 426,9.93244 426,9.84766 V 8.15234 C 426,8.06756 425.93244,8 425.84766,8 h -1.69532 c -0.005,0 -0.0105,-5.2e-4 -0.0156,0 z m 10,2 C 434.05936,10.00781 434,10.07286 434,10.15234 v 1.69532 C 434,11.93244 434.06756,12 434.15234,12 h 1.69532 C 435.93244,12 436,11.93244 436,11.84766 V 10.15234 C 436,10.06756 435.93244,10 435.84766,10 h -1.69532 c -0.005,0 -0.0105,-5.2e-4 -0.0156,0 z m -8,4 C 426.05936,14.00781 426,14.07286 426,14.15234 v 1.69532 C 426,15.93244 426.06756,16 426.15234,16 h 1.69532 C 427.93244,16 428,15.93244 428,15.84766 V 14.15234 C 428,14.06756 427.93244,14 427.84766,14 h -1.69532 c -0.005,0 -0.0105,-5.2e-4 -0.0156,0 z m 13,2 C 439.05936,16.00781 439,16.07286 439,16.15234 v 1.69532 C 439,17.93244 439.06756,18 439.15234,18 h 1.69532 C 440.93244,18 441,17.93244 441,17.84766 V 16.15234 C 441,16.06756 440.93244,16 440.84766,16 h -1.69532 c -0.005,0 -0.0105,-5.2e-4 -0.0156,0 z m -7,2 C 432.05936,18.00781 432,18.07286 432,18.15234 v 1.69532 C 432,19.93244 432.06756,20 432.15234,20 h 1.69532 C 433.93244,20 434,19.93244 434,19.84766 V 18.15234 C 434,18.06756 433.93244,18 433.84766,18 h -1.69532 c -0.005,0 -0.0105,-5.2e-4 -0.0156,0 z m -9,2 C 423.05936,20.00781 423,20.07286 423,20.15234 v 1.69532 C 423,21.93244 423.06756,22 423.15234,22 h 1.69532 C 424.93244,22 425,21.93244 425,21.84766 V 20.15234 C 425,20.06756 424.93244,20 424.84766,20 h -1.69532 c -0.005,0 -0.0105,-5.2e-4 -0.0156,0 z m 15,2 C 438.05936,22.00781 438,22.07286 438,22.15234 v 1.69532 C 438,23.93244 438.06756,24 438.15234,24 h 1.69532 C 439.93244,24 440,23.93244 440,23.84766 V 22.15234 C 440,22.06756 439.93244,22 439.84766,22 h -1.69532 c -0.005,0 -0.0105,-5.2e-4 -0.0156,0 z m -9,2 C 429.05936,24.00781 429,24.07286 429,24.15234 v 1.69532 C 429,25.93244 429.06756,26 429.15234,26 h 1.69532 C 430.93244,26 431,25.93244 431,25.84766 V 24.15234 C 431,24.06756 430.93244,24 430.84766,24 h -1.69532 c -0.005,0 -0.0105,-5.2e-4 -0.0156,0 z" /><path
+ id="rect56976"
+ style="fill:url(#linearGradient56984);stroke-linecap:square;stroke-linejoin:bevel;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 425,8 h 7 7 l 3,1 v 14 l -3,3 h -14 l -3,-3 V 9 Z"
+ sodipodi:nodetypes="cccccccccc" /><path
+ id="rect24023"
+ style="fill:url(#linearGradient29507);fill-opacity:1;stroke:none;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 425,6 c -1.662,0 -3,1.3380037 -3,3 v 3 2 h 2 v -2 h 2 v 2 h 4 v 2 h 2 v -2 -2 -2 h 2 v 2 2 h 2 v -2 h 2 v 2 2 h 2 v -2 h 2 V 9 c 0,-1.6619983 -1.338,-3 -3,-3 h -7 z" /></g><g
+ id="i_meat"
+ transform="translate(-480,32)"><path
+ id="rect80640"
+ style="opacity:1;fill:url(#linearGradient39389);fill-opacity:1;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 568.48528,21.449747 a 1.5,1.5 0 0 0 -1.70424,-0.290027 l -2.18485,-2.184846 c -0.39173,-0.391738 -1.02247,-0.391737 -1.41421,0 l -0.70711,0.707106 c -0.39173,0.391737 -0.39173,1.022477 0,1.414214 l 2.18485,2.184847 a 1.5,1.5 0 0 0 0.29003,1.70424 1.5,1.5 0 0 0 2.12132,0 1.5,1.5 0 0 0 0.4378,-0.979175 1.5,1.5 0 0 0 0.97641,-0.435038 1.5,1.5 0 0 0 0,-2.121321 z" /><rect
+ style="opacity:1;fill:url(#linearGradient38102);fill-opacity:1;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect74200"
+ width="16"
+ height="11"
+ x="397.64703"
+ y="-389.8125"
+ ry="4"
+ rx="0"
+ transform="rotate(45)" /><rect
+ style="opacity:1;fill:url(#linearGradient39377);fill-opacity:1;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect74196"
+ width="8"
+ height="11"
+ x="396.64703"
+ y="-389.8125"
+ ry="4"
+ rx="3"
+ transform="rotate(45)" /><rect
+ style="opacity:1;fill:#dfdfdf;fill-opacity:1;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect79410"
+ width="2"
+ height="3"
+ x="399.64703"
+ y="-385.8125"
+ ry="1"
+ transform="rotate(45)" /><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-7-61"
+ width="32"
+ height="32"
+ x="544"
+ y="0" /></g><g
+ id="i_netherstar"
+ transform="translate(-544,64)"><path
+ id="path87169-8-4"
+ style="fill:url(#radialGradient62776);fill-opacity:1;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 624,4 c -1,1.999998 -2,3.000001 -3,4 -1,0.999999 0,3.000001 -1,4 -1,0.999999 -3,10e-7 -4,1 -1,0.999999 -2,2.000001 -4,3 2,0.999999 3,2.000001 4,3 1,0.999999 3,1e-6 4,1 1,0.999999 0,3.000001 1,4 1,0.999999 2,2.000002 3,4 1,-1.999998 2,-3.000001 3,-4 1,-0.999999 0,-3.000001 1,-4 1,-0.999999 3,-1e-6 4,-1 1,-0.999999 2,-2.000001 4,-3 -2,-0.999999 -3,-2.000001 -4,-3 -1,-0.999999 -3,-10e-7 -4,-1 -1,-0.999999 0,-3.000001 -1,-4 -1,-0.999999 -2,-2.000002 -3,-4 z" /><path
+ style="fill:url(#radialGradient62768);fill-opacity:1;stroke:none;stroke-width:0.132291;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 624,22 c 1,-3 3,-5 6,-6 -3,-1 -5,-3 -6,-6 -1,3 -3,5 -6,6 3,1 5,3 6,6 z"
+ id="path88076"
+ sodipodi:nodetypes="ccccc" /><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-7-6-9"
+ width="32"
+ height="32"
+ x="608"
+ y="0" /></g><g
+ id="i_ftb_logo"
+ transform="translate(-224)"><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-8-2"
+ width="32"
+ height="32"
+ x="320"
+ y="0" /><path
+ id="path15348-5"
+ style="fill:url(#linearGradient12455);fill-opacity:1;stroke:none;stroke-width:0.869508;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 342,10 v 3 11 a 2,2 0 0 0 2,2 h 7 V 20 A 3,3 0 0 0 349.6543,17.49805 3,3 0 0 0 351,15 v -3 a 2,2 0 0 0 -2,-2 z m 3,3 h 3 v 3 h -3 z m 0,6 h 3 v 1 3 h -3 z" /><path
+ id="path15342-4"
+ style="fill:url(#linearGradient12301);fill-opacity:1;stroke:none;stroke-width:0.869508;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 323,10 a 2,2 0 0 0 -2,2 v 14 h 3 v -7 h 4.5 V 16 H 324 v -3 h 5 v -3 z" /><path
+ style="fill:url(#linearGradient12447);fill-opacity:1;stroke:none;stroke-width:0.869508;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 330,10 v 3 h 4 v 13 h 3 V 13 h 4 v -3 z"
+ id="rect10933-8"
+ sodipodi:nodetypes="ccccccccc" /></g><g
+ id="i_gear"
+ transform="translate(-288,96)"><path
+ id="path26489"
+ style="opacity:1;fill:url(#radialGradient21159);fill-opacity:1;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 368,9 c -3.86599,0 -7,3.134007 -7,7 0,3.865993 3.13401,7 7,7 3.86599,0 7,-3.134007 7,-7 0,-3.865993 -3.13401,-7 -7,-7 z m 0,5 c 1.10456,0 2,0.89543 2,2 0,1.10457 -0.89544,2 -2,2 -1.10456,0 -2,-0.89543 -2,-2 0,-1.10457 0.89544,-2 2,-2 z"
+ sodipodi:nodetypes="ssssssssss" /><path
+ id="path23199"
+ style="fill:url(#radialGradient21309);fill-opacity:1;stroke:none;stroke-width:0.148828;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 366,5 v 2.2265625 c -1.00464,0.2280151 -1.94322,0.6232232 -2.78906,1.15625 l -1.57422,-1.5742187 -2.82813,2.828125 1.57422,1.5742192 C 359.84979,12.056778 359.45458,12.995357 359.22656,14 H 357 v 4 h 2.22656 c 0.22802,1.004643 0.62323,1.943222 1.15625,2.789062 l -1.57422,1.574219 2.82813,2.830078 1.57422,-1.576171 c 0.84584,0.533026 1.78442,0.928234 2.78906,1.15625 V 27 h 4 v -2.226562 c 1.00464,-0.228016 1.94322,-0.623224 2.78906,-1.15625 l 1.57422,1.576171 2.83008,-2.830078 -1.57617,-1.574219 C 376.15021,19.943222 376.54542,19.004643 376.77344,18 H 379 v -4 h -2.22656 c -0.22802,-1.004643 -0.62323,-1.943222 -1.15625,-2.789062 l 1.57617,-1.5742192 -2.83008,-2.828125 -1.57422,1.5742187 C 371.94322,7.8497857 371.00464,7.4545776 370,7.2265625 V 5 Z m 2,5 c 3.31371,0 6,2.686295 6,6 0,3.313705 -2.68629,6 -6,6 -3.31371,0 -6,-2.686295 -6,-6 0,-3.313705 2.68629,-6 6,-6 z" /><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-7-6-0"
+ width="32"
+ height="32"
+ x="352"
+ y="0" /></g><g
+ id="i_magitech"
+ transform="translate(-416,96)"><path
+ sodipodi:type="star"
+ style="opacity:1;fill:url(#radialGradient16443);fill-opacity:1;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="path63885"
+ inkscape:flatsided="false"
+ sodipodi:sides="8"
+ sodipodi:cx="560"
+ sodipodi:cy="16"
+ sodipodi:r1="10.946013"
+ sodipodi:r2="12.727922"
+ sodipodi:arg1="0.78539816"
+ sodipodi:arg2="1.1780972"
+ inkscape:rounded="0.29"
+ inkscape:randomized="0.014"
+ d="m 567.75822,23.780557 c -1.02129,1.017197 -1.40469,3.26498 -2.72399,3.814557 -1.3193,0.549578 -3.76804,-0.657585 -5.20836,-0.687167 -1.44032,-0.02958 -3.32578,1.488919 -4.65697,0.936933 -1.33119,-0.551986 -2.06769,-2.91036 -3.08281,-3.927341 -1.01511,-1.016982 -3.30517,-1.550442 -3.83572,-2.877061 -0.53055,-1.326619 0.75095,-3.615262 0.76004,-5.050859 0.009,-1.435596 -1.30602,-3.611418 -0.75806,-4.936294 0.54796,-1.3248769 2.7981,-1.6627753 3.83368,-2.6540083 1.03559,-0.9912328 1.77327,-3.6016077 3.08037,-4.1709394 1.3071,-0.5693318 3.41767,0.6823629 4.85198,0.6871672 1.43432,0.0048 3.67769,-1.1020263 5.01335,-0.5805511 1.33567,0.5214752 1.68844,2.9320874 2.72643,3.9273412 1.03799,0.9952536 3.30533,1.5532379 3.83572,2.8770604 0.53039,1.323824 -0.73478,3.255376 -0.76004,4.694477 -0.0253,1.439101 1.28343,3.594239 0.75806,4.936295 -0.52537,1.342056 -2.8124,1.993192 -3.83368,3.01039 z"
+ transform="rotate(15,543.92119,-105.50919)" /><g
+ id="g68167"
+ clip-path="url(#clipPath70915-4-5-0-2-7-5-3-9-4)"
+ transform="translate(-32)"><rect
+ style="opacity:1;fill:url(#radialGradient14257);fill-opacity:1;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect68163"
+ width="18"
+ height="18"
+ x="551"
+ y="7" /><path
+ id="rect67092"
+ style="opacity:1;fill:url(#linearGradient16454);fill-opacity:1;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ d="M 562,11.419922 V 15 l -2,1 -2,-1 v -3.576172 c -1.82001,0.794312 -2.99746,2.590388 -3,4.576172 0,2.049737 1.2349,3.810134 3,4.582031 V 25 h 4 v -4.417969 c 1.7651,-0.771897 3,-2.532294 3,-4.582031 -9.9e-4,-1.987202 -1.1787,-3.785197 -3,-4.580078 z" /></g><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-0"
+ width="32"
+ height="32"
+ x="512"
+ y="0" /></g><g
+ id="i_herobrine"
+ transform="translate(-448)"><g
+ id="g56546"
+ clip-path="none"
+ transform="translate(-32)"><rect
+ style="fill:url(#radialGradient2757-3);fill-opacity:1;stroke-width:0.277182;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect56542-7-5"
+ width="22"
+ height="22"
+ x="485"
+ y="5"
+ ry="2.999999" /><path
+ id="rect56552"
+ style="fill:url(#linearGradient94741);fill-opacity:1;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ d="M 488 5 C 486.338 5 485 6.3380017 485 8 L 485 15 L 487 15 C 488.108 15 489 14.107998 489 13 L 489 12 L 503 12 L 503 13 C 503 14.107998 503.892 15 505 15 L 507 15 L 507 8 C 507 6.3380017 505.662 5 504 5 L 503 5 L 489 5 L 488 5 z " /></g><rect
+ style="opacity:1;fill:#8a5d54;fill-opacity:1;stroke:none;stroke-width:0.396874;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect53396"
+ width="6"
+ height="3"
+ x="461"
+ y="22"
+ ry="0" /><rect
+ style="fill:#ffffff;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect63182-8-0"
+ width="7"
+ height="3"
+ x="466"
+ y="17"
+ ry="1" /><rect
+ style="fill:#ffffff;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect63184-7-9"
+ width="7"
+ height="3"
+ x="455"
+ y="17"
+ ry="1" /><rect
+ style="opacity:1;fill:#6a493c;fill-opacity:1;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect50123"
+ width="4"
+ height="2"
+ x="462"
+ y="20"
+ ry="0" /><path
+ id="path195645-9"
+ style="fill:url(#linearGradient2566);fill-opacity:1;stroke:none;stroke-width:0.362295;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 461,22 a 2,2 0 0 0 -2,2 v 3 h 3 4 3 v -3 a 2,2 0 0 0 -2,-2 h -1 v 2 h -4 v -2 z" /><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-8-3-9"
+ width="32"
+ height="32"
+ x="448"
+ y="0" /></g><g
+ id="i_steve"
+ transform="translate(-736,32)"><rect
+ style="fill:url(#radialGradient2757);fill-opacity:1;stroke-width:0.277182;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect56542-7"
+ width="22"
+ height="22"
+ x="741"
+ y="5"
+ ry="3" /><path
+ id="rect56552-6"
+ style="fill:url(#linearGradient1332);fill-opacity:1;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ d="M 744 5 C 742.338 5 741 6.3380017 741 8 L 741 15 L 743 15 C 744.108 15 745 14.107997 745 13 L 745 12 L 759 12 L 759 13 C 759 14.107997 759.892 15 761 15 L 763 15 L 763 8 C 763 6.3380017 761.662 5 760 5 L 759 5 L 745 5 L 744 5 z " /><rect
+ style="fill:#8a4c3d;fill-opacity:1;stroke:none;stroke-width:0.396874;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect53396-9"
+ width="6"
+ height="3"
+ x="749"
+ y="22"
+ ry="0" /><rect
+ style="fill:#ffffff;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect63182-8-0-3"
+ width="7"
+ height="3"
+ x="754"
+ y="17"
+ ry="1" /><rect
+ style="fill:#ffffff;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect63184-7-9-7"
+ width="7"
+ height="3"
+ x="743"
+ y="17"
+ ry="1" /><rect
+ style="fill:#6a4030;fill-opacity:1;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect50123-4"
+ width="4"
+ height="2"
+ x="750"
+ y="20"
+ ry="0" /><path
+ id="path195645"
+ style="fill:url(#linearGradient1465);fill-opacity:1;stroke:none;stroke-width:0.362295;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 749,22 a 2,2 0 0 0 -2,2 v 3 h 3 4 3 v -3 a 2,2 0 0 0 -2,-2 h -1 v 2 h -4 v -2 z" /><g
+ id="g1469"
+ style="fill:url(#linearGradient1505);fill-opacity:1"><rect
+ style="fill:url(#linearGradient94747);fill-opacity:1;stroke-width:0.396874;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect75119-2"
+ width="3"
+ height="3"
+ x="746"
+ y="17" /><rect
+ style="fill:url(#linearGradient94749);fill-opacity:1;stroke-width:0.396874;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect112219"
+ width="3"
+ height="3"
+ x="755"
+ y="17" /></g><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-7-6-1-9"
+ width="32"
+ height="32"
+ x="736"
+ y="0" /></g><g
+ id="i_dirt"
+ transform="translate(-192,64)"><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-8-3"
+ width="32"
+ height="32"
+ x="192"
+ y="0" /></g><g
+ id="i_bee"
+ transform="translate(0,64)"><rect
+ style="fill:url(#linearGradient1310);fill-opacity:1;stroke-width:0.277182;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect543"
+ width="22"
+ height="22"
+ x="5"
+ y="5"
+ ry="3" /><g
+ id="g7050"
+ clip-path="url(#clipPath7052-4-6)"><rect
+ style="fill:url(#linearGradient1442);fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect3612"
+ width="6"
+ height="10"
+ x="6"
+ y="14" /><rect
+ style="fill:url(#linearGradient1462);fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect4739"
+ width="3"
+ height="4"
+ x="9"
+ y="14" /></g><use
+ x="0"
+ y="0"
+ xlink:href="#g7050"
+ id="use7056"
+ transform="matrix(-1,0,0,1,32,0)" /><g
+ id="g10049"
+ transform="translate(-1)"
+ style="fill:#2c251f;fill-opacity:1"><rect
+ style="fill:#2c251f;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect9308"
+ width="3"
+ height="3"
+ x="9"
+ y="10"
+ ry="1" /><rect
+ style="fill:#2c251f;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect9310"
+ width="5"
+ height="3"
+ x="4"
+ y="7"
+ ry="1" /><path
+ id="path9312"
+ style="fill:#2c251f;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 8,9 v 1 c 0.5539988,0 1,0.446001 1,1 h 1 V 10 C 9.4460006,10 9,9.5539994 9,9 Z" /></g><g
+ id="g10057"
+ transform="matrix(-1,0,0,1,33,0)"
+ style="fill:#2c251f;fill-opacity:1"><rect
+ style="fill:#2c251f;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect10051"
+ width="3"
+ height="3"
+ x="9"
+ y="10"
+ ry="1" /><rect
+ style="fill:#2c251f;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect10053"
+ width="5"
+ height="3"
+ x="4"
+ y="7"
+ ry="1" /><path
+ id="path10055"
+ style="fill:#2c251f;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 8,9 v 1 c 0.5539988,0 1,0.446001 1,1 h 1 V 10 C 9.4460006,10 9,9.5539994 9,9 Z" /></g><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412"
+ width="32"
+ height="32"
+ x="0"
+ y="0" /></g><g
+ id="i_chicken"
+ transform="translate(-64,96)"><rect
+ style="fill:url(#linearGradient292686);fill-opacity:1;stroke-width:0.277182;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect18469"
+ width="18"
+ height="22"
+ x="71"
+ y="5"
+ ry="3" /><rect
+ style="fill:url(#linearGradient293076);fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect22620"
+ width="8"
+ height="8"
+ x="76"
+ y="21"
+ ry="1" /><g
+ id="g23887"
+ clip-path="none"
+ style="fill:url(#linearGradient42830);fill-opacity:1"><rect
+ style="fill:url(#linearGradient94751);fill-opacity:1;stroke-width:0.170787;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect3612-5"
+ width="5"
+ height="5"
+ x="72"
+ y="12"
+ ry="1" /><path
+ id="rect42884"
+ style="fill:#ffffff;fill-opacity:1;stroke:none;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 75,12 v 2 h 2 v -1 c 0,-0.553999 -0.446001,-1 -1,-1 z" /></g><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-8"
+ width="32"
+ height="32"
+ x="64"
+ y="0" /><use
+ x="0"
+ y="0"
+ xlink:href="#g23887"
+ id="use42929"
+ transform="translate(11)" /><rect
+ style="fill:url(#linearGradient292041);fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect37390-3"
+ width="20"
+ height="7"
+ x="70"
+ y="16"
+ ry="1" /></g><g
+ id="i_fox"
+ transform="translate(-160,128)"><path
+ id="path51543"
+ style="fill:url(#linearGradient288033);fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 180,7 v 2 1 1 c 0,1.107999 0.892,2 2,2 h 2 c 1.108,0 2,-0.892001 2,-2 V 9 c 0,-1.1079989 -0.892,-2 -2,-2 h -1 -1 z" /><path
+ id="rect51469"
+ style="fill:url(#linearGradient288025);fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 172,7 v 2 1 1 c 0,1.107999 -0.892,2 -2,2 h -2 c -1.108,0 -2,-0.892001 -2,-2 V 9 c 0,-1.1079989 0.892,-2 2,-2 h 1 1 z" /><g
+ id="g51553"
+ clip-path="url(#clipPath51555-6-8-0-1-3-1-4)"
+ transform="translate(-12.385191,4.0000023)"><rect
+ style="fill:url(#linearGradient287143);fill-opacity:1;stroke-width:0.271456;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect50678"
+ width="19.999996"
+ height="16"
+ x="178.38519"
+ y="5.9999981" /><rect
+ style="fill:url(#linearGradient287171);fill-opacity:1;stroke-width:0.258767;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect51545"
+ width="21.999998"
+ height="5"
+ x="177.38519"
+ y="19.999998"
+ ry="2" /></g><g
+ id="g51463"
+ clip-path="url(#clipPath51465-6-2-8-5-5-4-9)"
+ transform="translate(-12.385191,4.0000023)"><rect
+ style="fill:url(#linearGradient287189);fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect51033"
+ width="10.000002"
+ height="5.0000005"
+ x="183.38519"
+ y="17.999998" /><rect
+ style="fill:#4d3f33;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect51319"
+ width="6"
+ height="3"
+ x="185.38519"
+ y="16.999998"
+ ry="0.99999958" /></g><g
+ id="g52513"
+ clip-path="url(#clipPath52515-9-3-0-6-2-2-6)"
+ transform="matrix(-1,0,0,1,352.38519,4.0000023)"><rect
+ style="fill:#e9ecec;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect52365"
+ width="6"
+ height="3"
+ x="179.38519"
+ y="13.999998" /><rect
+ style="fill:#141519;fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect52369"
+ width="6"
+ height="5"
+ x="176.38519"
+ y="12.999998" /></g><use
+ x="0"
+ y="0"
+ xlink:href="#g52513"
+ id="use55252"
+ transform="matrix(-1,0,0,1,352,0)" /><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-7-4"
+ width="32"
+ height="32"
+ x="160"
+ y="0" /></g><rect
+ style="fill:url(#linearGradient84368);fill-opacity:1;stroke-width:0.277182;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect13011-3"
+ width="20"
+ height="20"
+ x="166"
+ y="38"
+ ry="3" /><path
+ id="rect13933-4"
+ style="fill:url(#linearGradient85182);fill-opacity:1;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ d="m 175,38 v 5 h -9 v 2 h 4 v 6 h -4 v 2 h 9 v 5 h 2 v -5 h 9 v -2 h -4 v -6 h 4 v -2 h -9 v -5 z m -3,7 h 8 v 6 h -8 z"
+ sodipodi:nodetypes="cccccccccccccccccccccccccc" /><rect
+ style="fill:#ffffff;fill-opacity:0;stroke:none;stroke-width:0.264583;paint-order:stroke markers fill;stop-color:#000000"
+ id="rect128412-7-0"
+ width="32"
+ height="32"
+ x="160"
+ y="32" /></svg>
diff --git a/program_info/win_install.nsi.in b/program_info/win_install.nsi.in
index 0cd7ea11..42a9e762 100644
--- a/program_info/win_install.nsi.in
+++ b/program_info/win_install.nsi.in
@@ -110,6 +110,142 @@ VIAddVersionKey /LANG=${LANG_ENGLISH} "LegalCopyright" "@Launcher_Copyright@"
VIAddVersionKey /LANG=${LANG_ENGLISH} "FileVersion" "@Launcher_VERSION_NAME4@"
VIAddVersionKey /LANG=${LANG_ENGLISH} "ProductVersion" "@Launcher_VERSION_NAME4@"
+
+;--------------------------------
+; Shell Associate Macros
+
+!macro APP_SETUP DESCRIPTION ICON APP_ID APP_NAME APP_EXE COMMANDTEXT COMMAND ; VERB APP_COMPANY
+ ; setup APP_ID
+ WriteRegStr ShCtx "Software\Classes\${APP_ID}" "" `${DESCRIPTION}`
+ WriteRegStr ShCtx "Software\Classes\${APP_ID}\DefaultIcon" "" `${ICON}`
+ ; default open verb
+ WriteRegStr ShCtx "Software\Classes\${APP_ID}\shell" "" "open"
+ WriteRegStr ShCtx "Software\Classes\${APP_ID}\shell\open" "" `${COMMANDTEXT}`
+ WriteRegStr ShCtx "Software\Classes\${APP_ID}\shell\open\command" "" `${COMMAND}`
+
+ ; if you want the app to use it's own implementation of a verb
+ ;WriteRegStr ShCtx "Software\Classes\${APP_ID}\shell\${VERB}" "" "${DESCRIPTION}"
+ ;WriteRegStr ShCtx "Software\Classes\${APP_ID}\shell\${VERB}\command" "" `${COMMAND}`
+
+ WriteRegStr ShCtx "Software\Classes\Applications\${APP_EXE}\shell\open\command" "" `${COMMAND}`
+ WriteRegStr ShCtx "Software\Classes\Applications\${APP_EXE}" "FriendlyAppName" `${APP_NAME}` ; [Optional]
+ ;WriteRegStr ShCtx "Software\Classes\Applications\${APP_EXE}" "ApplicationCompany" `${APP_COMPANY}` ; [Optional]
+ ;WriteRegNone ShCtx "Software\Classes\Applications\${APP_EXE}\SupportedTypes" ".${EXT}" ; [Optional] Only allow "Open With" with specific extension(s) on WinXP+
+
+ # Register "Default Programs" [Optional]
+ !ifdef REGISTER_DEFAULTPROGRAMS
+ WriteRegStr ShCtx "Software\Classes\Applications\${APP_EXE}\Capabilities" "ApplicationDescription" `${DESCRIPTION}`
+ WriteRegStr ShCtx "Software\RegisteredApplications" `${APP_NAME}` "Software\Classes\Applications\${APP_EXE}\Capabilities"
+ !endif
+
+!macroend
+
+!macro APP_ASSOCIATE EXT APP_ID APP_EXE OVERWIRTE
+ ; Backup the previously associated file class
+ ${If} ${OVERWIRTE} == true
+ ReadRegStr $R0 ShCtx "Software\Classes\${EXT}" ""
+ WriteRegStr ShCtx "Software\Classes\${EXT}" "${APP_ID}_backup" "$R0"
+ WriteRegStr ShCtx "Software\Classes\${EXT}" "" "${APP_ID}"
+ ${EndIf}
+
+ WriteRegNone ShCtx "Software\Classes\${EXT}\OpenWithList" "${APP_EXE}" ; Win2000+
+ WriteRegNone ShCtx "Software\Classes\${EXT}\OpenWithProgids" "${APP_ID}" ; WinXP+
+
+ # Register "Default Programs" [Optional]
+ !ifdef REGISTER_DEFAULTPROGRAMS
+ WriteRegStr ShCtx "Software\Classes\Applications\${APP_EXE}\Capabilities\FileAssociations" "${EXT}" "${APP_ID}"
+ !endif
+
+!macroend
+
+!macro APP_UNASSOCIATE EXT APP_ID
+
+ # Unregister file type
+ ClearErrors
+ ; restore backup
+ ReadRegStr $R1 ShCtx "Software\Classes\${EXT}" ""
+ ${If} $R1 == "${APP_ID}"
+ ReadRegStr $R0 ShCtx "Software\Classes\${EXT}" `${APP_ID}_backup`
+ WriteRegStr ShCtx "Software\Classes\${EXT}" "" "$R0"
+ ${Else}
+ ReadRegStr $R0 ShCtx "Software\Classes\${EXT}" ""
+ ${EndIf}
+
+ DeleteRegKey /IfEmpty ShCtx "Software\Classes\${APP_ID}"
+ ${IfNot} ${Errors}
+ ${AndIf} $R0 == "${APP_ID}"
+ DeleteRegValue ShCtx "Software\Classes\${EXT}" ""
+ DeleteRegKey /IfEmpty ShCtx "Software\Classes\${EXT}"
+ ${EndIf}
+
+ DeleteRegValue ShCtx "Software\Classes\${EXT}\OpenWithList" "${APP_EXE}"
+ DeleteRegKey /IfEmpty ShCtx "Software\Classes\${EXT}\OpenWithList"
+ DeleteRegValue ShCtx "Software\Classes\${EXT}\OpenWithProgids" "${APP_ID}"
+ DeleteRegKey /IfEmpty ShCtx "Software\Classes\${EXT}\OpenWithProgids"
+ DeleteRegKey /IfEmpty ShCtx "Software\Classes\${EXT}"
+
+ # Attempt to clean up junk left behind by the Windows shell
+ DeleteRegValue HKCU "Software\Microsoft\Windows\CurrentVersion\ApplicationAssociationToasts" "${APP_ID}_${EXT}"
+ DeleteRegValue HKCU "Software\Microsoft\Windows\CurrentVersion\ApplicationAssociationToasts" "Applications\${APP_EXE}_${EXT}"
+ DeleteRegValue HKCU "Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\${EXT}\OpenWithProgids" "${APP_ID}"
+ DeleteRegKey /IfEmpty HKCU "Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\${EXT}\OpenWithProgids"
+ DeleteRegKey /IfEmpty HKCU "Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\${EXT}\OpenWithList"
+ DeleteRegKey /IfEmpty HKCU "Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\${EXT}"
+ ;DeleteRegKey HKCU "Software\Microsoft\Windows\Roaming\OpenWith\FileExts\.${EXT}"
+ ;DeleteRegKey HKCU "Software\Microsoft\Windows\CurrentVersion\Explorer\RecentDocs\.${EXT}"
+
+!macroend
+
+!macro APP_TEARDOWN APP_ID APP_NAME APP_EXE
+
+ # Unregister file type
+ ClearErrors
+ DeleteRegKey /IfEmpty ShCtx "Software\Classes\${APP_ID}\shell"
+ ${IfNot} ${Errors}
+ DeleteRegKey ShCtx "Software\Classes\${APP_ID}\DefaultIcon"
+ ${EndIf}
+
+ # Unregister "Open With"
+ DeleteRegKey ShCtx "Software\Classes\Applications\${APP_EXE}"
+
+ # Unregister "Default Programs"
+ !ifdef REGISTER_DEFAULTPROGRAMS
+ DeleteRegValue ShCtx "Software\RegisteredApplications" `${APP_NAME}`
+ DeleteRegKey ShCtx "Software\Classes\Applications\${APP_EXE}\Capabilities"
+ DeleteRegKey /IfEmpty ShCtx "Software\Classes\Applications\${APP_EXE}"
+ !endif
+
+ DeleteRegKey ShCtx `Software\Classes\${APP_ID}`
+ DeleteRegKey ShCtx "Software\Classes\Applications\${APP_EXE}"
+
+ # Attempt to clean up junk left behind by the Windows shell
+ DeleteRegValue HKCU "Software\Microsoft\Windows\CurrentVersion\Search\JumplistData" "$INSTDIR\${APP_EXE}"
+ DeleteRegValue HKCU "Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\MuiCache" "$INSTDIR\${APP_EXE}.FriendlyAppName"
+ DeleteRegValue HKCU "Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\MuiCache" "$INSTDIR\${APP_EXE}.ApplicationCompany"
+ DeleteRegValue HKCU "Software\Microsoft\Windows\ShellNoRoam\MUICache" "$INSTDIR\${APP_EXE}" ; WinXP
+ DeleteRegValue HKCU "Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Compatibility Assistant\Store" "$INSTDIR\${APP_EXE}"
+
+!macroend
+
+; !defines for use with SHChangeNotify
+!ifdef SHCNE_ASSOCCHANGED
+!undef SHCNE_ASSOCCHANGED
+!endif
+!define SHCNE_ASSOCCHANGED 0x08000000
+!ifdef SHCNF_FLUSH
+!undef SHCNF_FLUSH
+!endif
+!define SHCNF_FLUSH 0x1000
+
+
+# ensure this is called at the end of any section that changes shell keys
+!macro NotifyShell_AssocChanged
+; Using the system.dll plugin to call the SHChangeNotify Win32 API function so we
+; can update the shell.
+ System::Call "shell32::SHChangeNotify(i,i,i,i) (${SHCNE_ASSOCCHANGED}, ${SHCNF_FLUSH}, 0, 0)"
+!macroend
+
+
;--------------------------------
; The stuff to install
@@ -171,6 +307,27 @@ Section /o "Desktop Shortcut" DESKTOP_SHORTCUTS
SectionEnd
+
+!define APP_ID "@Launcher_CommonName@.App"
+!define APP_EXE "@Launcher_APP_BINARY_NAME@.exe"
+!define APP_ICON "$INSTDIR\${APP_EXE},0"
+!define APP_DESCRIPTION "@Launcher_DisplayName@"
+!define APP_NAME "@Launcher_DisplayName@"
+!define APP_CMD_TEXT "Minecraft Modpack"
+
+!define REGISTER_DEFAULTPROGRAMS ; value doesn't matter
+
+Section -ShellAssoc
+
+ !insertmacro APP_SETUP `${APP_DESCRIPTION}` `${APP_ICON}` `${APP_ID}` `${APP_CMD_TEXT}` `${APP_EXE}` `${APP_CMD_TEXT}` '$INSTDIR\${APP_EXE} -I "%1"'
+
+ !insertmacro APP_ASSOCIATE ".zip" `${APP_ID}` `${APP_EXE}` false
+ !insertmacro APP_ASSOCIATE ".mrpack" `${APP_ID}` `${APP_EXE}` true
+
+ !insertmacro NotifyShell_AssocChanged
+SectionEnd
+
+
;--------------------------------
; Uninstaller
@@ -202,6 +359,16 @@ Section "Uninstall"
SectionEnd
+Section -un.ShellAssoc
+
+ !insertmacro APP_TEARDOWN `${APP_ID}` `${APP_NAME}` `${APP_EXE}`
+
+ !insertmacro APP_UNASSOCIATE ".zip" `${APP_ID}`
+ !insertmacro APP_UNASSOCIATE ".mrpack" `${APP_ID}`
+
+ !insertmacro NotifyShell_AssocChanged
+SectionEnd
+
;--------------------------------
; Extra command line parameters
diff --git a/tests/FileSystem_test.cpp b/tests/FileSystem_test.cpp
index 21270f6f..3a5c38d0 100644
--- a/tests/FileSystem_test.cpp
+++ b/tests/FileSystem_test.cpp
@@ -126,7 +126,7 @@ slots:
qDebug() << tempDir.path();
qDebug() << target_dir.path();
FS::copy c(folder, target_dir.path());
- c.blacklist(new RegexpMatcher("[.]?mcmeta"));
+ c.matcher(new RegexpMatcher("[.]?mcmeta"));
c();
for(auto entry: target_dir.entryList())
@@ -147,6 +147,41 @@ slots:
f();
}
+ void test_copy_with_whitelist()
+ {
+ QString folder = QFINDTESTDATA("testdata/FileSystem/test_folder");
+ auto f = [&folder]()
+ {
+ QTemporaryDir tempDir;
+ tempDir.setAutoRemove(true);
+ qDebug() << "From:" << folder << "To:" << tempDir.path();
+
+ QDir target_dir(FS::PathCombine(tempDir.path(), "test_folder"));
+ qDebug() << tempDir.path();
+ qDebug() << target_dir.path();
+ FS::copy c(folder, target_dir.path());
+ c.matcher(new RegexpMatcher("[.]?mcmeta"));
+ c.whitelist(true);
+ c();
+
+ for(auto entry: target_dir.entryList())
+ {
+ qDebug() << entry;
+ }
+ QVERIFY(target_dir.entryList().contains("pack.mcmeta"));
+ QVERIFY(!target_dir.entryList().contains("assets"));
+ };
+
+ // first try variant without trailing /
+ QVERIFY(!folder.endsWith('/'));
+ f();
+
+ // then variant with trailing /
+ folder.append('/');
+ QVERIFY(folder.endsWith('/'));
+ f();
+ }
+
void test_copy_with_dot_hidden()
{
QString folder = QFINDTESTDATA("testdata/FileSystem/test_folder");