Add geode

This commit is contained in:
Lncvrt committed 2025-01-05 13:56:22 -07:00
1 parent ceba3130ab
commit 9c61b0a7fd
421 files changed
+30990

No files matched your search

@@ -0,0 +1 @@
{"spritesheets":{"07e6a532ef015bf196db16c6e3dfc1863babd39fd2550b3a57f8ea44df06dcde":"resources\\geode.custom-keybinds\\KB_ControllerSheet.png"},"fonts":{}}
@@ -0,0 +1,11 @@
# Custom Keybinds
Adds support for customizing keybinds in the editor and while playing.
## Usage
Open the settings menu to edit the keybinds. You can edit vanilla keybinds but also ones added by other mods.
## For developers
See the [README](https://github.com/geode-sdk/CustomKeybinds/blob/main/README.md) for instructions on using this mod as a dependency.
@@ -0,0 +1,166 @@
# Changelog
## v1.10.1
- Fixed an issue where all keybinds could get unset on a fresh installation
## v1.10.0
- Updated for GD 2.2074
## v1.9.0
- Unseparate jump/move/checkpoint keybinds for different level modes (1P/2P, Classic/Platformer)
- Fix outdated controller defaults
## v1.8.0
- Separate jump/move/checkpoint keybinds for different level modes (1P/2P, Classic/Platformer)
- Offset binds in inner categories to improve readability
- Enable controller support on Android
- Bump to Geode `v3.6.0`
## v1.7.1
- Fix modifiers not working with mouse buttons. This most likely breaks existing mouse button bindings
- Restart keybind no longer requires "Quick Keys" option enabled, as it ended up confusing users
- Internal fixes
## v1.7.0
- Allow assigning mouse side buttons as keybinds
- Add Android support
## v1.6.4
- Fix spacebar in PlayLayer popups
## v1.6.3
- Fix various issues in PlayLayer
- Restart keybind now requires "Quick Keys" option enabled (like in the vanilla game)
## v1.6.2
- Re-enable `Pan editor`
- Bump to Geode `v3.1.0`
## v1.6.1
- Remove `Pan editor` keybind temporarily
- Bump to Geode `v3.0.0`
## v1.6.0
- Bump to Geode v3.0.0-beta.1
## v1.5.10
- Fix "Key + Modifier" combos behaving weird when repeating
## v1.5.9
- Bump to Geode v2.0.0-beta.26
- Fix 'shift' not being passed in CCKeyboardDispatcher::dispatchKeyboardMSG
## v1.5.8
- Bump to Geode v2.0.0-beta.25
- Fix Alt getting stuck when alt-tabbing out of the game
## v1.5.7
- Fix some other PlayLayer binds from stopping PauseLayer binds
## v1.5.6
- Fix jump-p2 using the wrong PlayLayer function
## v1.5.5
- Fix player jump breaking the space key in EndLevelLayer and RetryLevelLayer
## v1.5.4
- Fix repeating binds entering a repeat loop on press
- Fix Pause Menu not having vanilla functionality with Confirm Exit
- Fix Player not jumping when holding on death
- Bump to Geode v2.0.0-beta.24
## v1.5.3
- Add custom setting that opens the keybind menu
- Fix modifiers not being properly handled on release
- Fix "unpause" sometimes not working
- Fix the "Confirm Exit" popup being able to be spawned multiple times through keybinds
- Simplify the keybind repeat logic, fixing some bugs in the process
- Allow multiple key combinations to trigger the same non-repeating bind at once
## v1.5.2
- Fix unpausing with space also causing the player to jump
- Add missing "Pan editor while swiping" editor keybind
- Add missing "Transform" editor keybind
## v1.5.1
- Fix not being able to hold from respawn in PlayLayer
## v1.5.0
- Add editor save & load position keybinds
- Fix a lot of the internal implementations of keybinds to just use GD's implementations, potentially fixing a bunch of inconsistencies in the editor
## v1.4.0
- Fix being able to reset levels during level end animation
- Remove editor half-move and big-move keybinds, since those are not in the vanilla game and as such should be implemented through mods instead
## v1.3.3
- Fix editor keybinds
- Add F-Keys to editor keybinds
- Add half moves and big moves to editor keybinds
## v1.3.2
- Add DPad Up as default for P1 Jump
- Make keybind info popup wider
## v1.3.1
- Changed the name of the default platformer binds (move left right)
- Made platformer move binds unrepeatable
- Added "W" for Jump P1 as a default
- Fixed non-repeatable binds repeating (a lot)
- Fixed default platformer move binds for P2
## v1.3.0
- Fix controller support
- Add sprites for missing controller buttons (RB, RT, LB, LT)
- Improve controller sprite display in the keybind picker
- Add platformer keybinds
- Add reset, full reset, and toggle hitboxes (this one is experimental)
## v1.2.4
- Add 2.204 support
## v1.2.3
- Fix issues caused by the impostor PlayLayer bug
## v1.2.2
- Fix jump key not working after a level restart
## v1.2.1
- Fix issues with MegaHack
- Add EditorUI controller keybinds
- Improve controller compatibility in UILayer
## v1.1.2
- Fix crashes on exit for Windows
## v1.1.1
- Fix issues on MacOS
- Make repeatable binds false by default
@@ -0,0 +1,384 @@
#pragma once
#include <Geode/DefaultInclude.hpp>
#include <Geode/utils/cocos.hpp>
#include <Geode/loader/Mod.hpp>
#include <Geode/loader/Event.hpp>
#include <cocos2d.h>
#include <unordered_map>
#include <unordered_set>
#ifdef GEODE_IS_WINDOWS
#ifdef HJFOD_CUSTOM_KEYBINDS_EXPORTING
#define CUSTOM_KEYBINDS_DLL __declspec(dllexport)
#else
#define CUSTOM_KEYBINDS_DLL __declspec(dllimport)
#endif
#else
#define CUSTOM_KEYBINDS_DLL __attribute__((visibility("default")))
#endif
struct BindSaveData;
namespace keybinds {
class Bind;
class BindManager;
using DeviceID = std::string;
/**
* Base class for implementing bindings for different input devices
*/
class CUSTOM_KEYBINDS_DLL Bind : public cocos2d::CCObject {
protected:
friend class BindManager;
public:
/**
* Get the hash for this bind
*/
virtual size_t getHash() const = 0;
/**
* Check if this bind is equal to another. By default compares hashes
*/
virtual bool isEqual(Bind* other) const;
/**
* Get the bind's representation as a human-readable string
*/
virtual std::string toString() const = 0;
virtual cocos2d::CCNode* createLabel() const;
virtual DeviceID getDeviceID() const = 0;
virtual matjson::Value save() const = 0;
virtual ~Bind() = default;
cocos2d::CCNodeRGBA* createBindSprite() const;
};
enum class Modifier : unsigned int {
None = 0b0000,
Control = 0b0001,
Shift = 0b0010,
Alt = 0b0100,
Command = 0b1000,
#ifdef GEODE_IS_MACOS
PlatformControl = Command,
#else
PlatformControl = Control,
#endif
};
CUSTOM_KEYBINDS_DLL Modifier operator|(Modifier const& a, Modifier const& b);
CUSTOM_KEYBINDS_DLL Modifier operator|=(Modifier& a, Modifier const& b);
CUSTOM_KEYBINDS_DLL bool operator&(Modifier const& a, Modifier const& b);
CUSTOM_KEYBINDS_DLL std::string keyToString(cocos2d::enumKeyCodes key);
CUSTOM_KEYBINDS_DLL bool keyIsModifier(cocos2d::enumKeyCodes key);
CUSTOM_KEYBINDS_DLL bool keyIsController(cocos2d::enumKeyCodes key);
enum class MouseButton {
Button4 = 0,
Button5 = 1,
};
CUSTOM_KEYBINDS_DLL std::string mouseToString(MouseButton button);
class CUSTOM_KEYBINDS_DLL Keybind final : public Bind {
protected:
cocos2d::enumKeyCodes m_key;
Modifier m_modifiers;
public:
static Keybind* create(cocos2d::enumKeyCodes key, Modifier modifiers = Modifier::None);
static Keybind* parse(matjson::Value const&);
cocos2d::enumKeyCodes getKey() const;
Modifier getModifiers() const;
size_t getHash() const override;
bool isEqual(Bind* other) const override;
std::string toString() const override;
DeviceID getDeviceID() const override;
matjson::Value save() const override;
};
class CUSTOM_KEYBINDS_DLL MouseBind final : public Bind {
protected:
MouseButton m_button;
Modifier m_modifiers;
public:
static MouseBind* create(MouseButton button, Modifier modifiers = Modifier::None);
static MouseBind* parse(matjson::Value const&);
MouseButton getButton() const;
Modifier getModifiers() const;
size_t getHash() const override;
bool isEqual(Bind* other) const override;
std::string toString() const override;
DeviceID getDeviceID() const override;
matjson::Value save() const override;
};
class CUSTOM_KEYBINDS_DLL ControllerBind final : public Bind {
protected:
cocos2d::enumKeyCodes m_button;
public:
static ControllerBind* create(cocos2d::enumKeyCodes button);
static ControllerBind* parse(matjson::Value const&);
cocos2d::enumKeyCodes getButton() const;
size_t getHash() const override;
bool isEqual(Bind* other) const override;
std::string toString() const override;
cocos2d::CCNode* createLabel() const override;
DeviceID getDeviceID() const override;
matjson::Value save() const override;
};
struct CUSTOM_KEYBINDS_DLL BindHash {
geode::Ref<Bind> bind;
BindHash(Bind* bind);
bool operator==(BindHash const& other) const;
};
}
namespace std {
template <>
struct hash<keybinds::BindHash> {
CUSTOM_KEYBINDS_DLL std::size_t operator()(keybinds::BindHash const&) const;
};
}
namespace keybinds {
class BindManager;
class InvokeBindFilter;
using ActionID = std::string;
class CUSTOM_KEYBINDS_DLL Category final {
std::string m_value;
public:
Category() = default;
Category(const char* path);
Category(std::string const& path);
std::vector<std::string> getPath() const;
std::optional<Category> getParent() const;
bool hasParent(Category const& parent) const;
std::string toString() const;
bool operator==(Category const&) const;
static constexpr auto PLAY { "Play" };
static constexpr auto PLAY_PAUSE { "Play/Pause" };
static constexpr auto EDITOR { "Editor" };
static constexpr auto GLOBAL { "Global" };
static constexpr auto EDITOR_UI { "Editor/UI" };
static constexpr auto EDITOR_MODIFY { "Editor/Modify" };
static constexpr auto EDITOR_MOVE { "Editor/Move" };
};
class CUSTOM_KEYBINDS_DLL BindableAction {
protected:
ActionID m_id;
std::string m_name;
std::string m_description;
geode::Mod* m_owner;
std::vector<geode::Ref<Bind>> m_defaults;
Category m_category;
bool m_repeatable;
public:
ActionID getID() const;
std::string getName() const;
std::string getDescription() const;
geode::Mod* getMod() const;
std::vector<geode::Ref<Bind>> getDefaults() const;
Category getCategory() const;
bool isRepeatable() const;
BindableAction() = default;
BindableAction(
ActionID const& id,
std::string const& name,
std::string const& description = "",
std::vector<geode::Ref<Bind>> const& defaults = {},
Category const& category = Category(),
bool repeatable = true,
geode::Mod* owner = geode::Mod::get()
);
};
class CUSTOM_KEYBINDS_DLL InvokeBindEvent : public geode::Event {
protected:
ActionID m_id;
bool m_down;
friend class BindManager;
friend class InvokeBindFilter;
public:
InvokeBindEvent(ActionID const& id, bool down);
ActionID getID() const;
bool isDown() const;
};
class CUSTOM_KEYBINDS_DLL InvokeBindFilter : public geode::EventFilter<InvokeBindEvent> {
protected:
cocos2d::CCNode* m_target;
ActionID m_id;
public:
using Callback = geode::ListenerResult(InvokeBindEvent*);
geode::ListenerResult handle(std::function<Callback> fn, InvokeBindEvent* event);
InvokeBindFilter(cocos2d::CCNode* target, ActionID const& id);
};
class CUSTOM_KEYBINDS_DLL PressBindEvent : public geode::Event {
protected:
Bind* m_bind;
bool m_down;
public:
PressBindEvent(Bind* bind, bool down);
Bind* getBind() const;
bool isDown() const;
};
class CUSTOM_KEYBINDS_DLL PressBindFilter : public geode::EventFilter<PressBindEvent> {
public:
using Callback = geode::ListenerResult(PressBindEvent*);
geode::ListenerResult handle(std::function<Callback> fn, PressBindEvent* event);
PressBindFilter();
};
class CUSTOM_KEYBINDS_DLL DeviceEvent : public geode::Event {
protected:
DeviceID m_id;
bool m_attached;
public:
DeviceEvent(DeviceID const& id, bool attached);
DeviceID getID() const;
bool wasAttached() const;
bool wasDetached() const;
};
class CUSTOM_KEYBINDS_DLL DeviceFilter : public geode::EventFilter<DeviceEvent> {
protected:
std::optional<DeviceID> m_id;
public:
using Callback = void(DeviceEvent*);
geode::ListenerResult handle(std::function<Callback> fn, DeviceEvent* event);
DeviceFilter(std::optional<DeviceID> id = std::nullopt);
};
struct CUSTOM_KEYBINDS_DLL RepeatOptions {
bool enabled = true;
size_t rate = 50;
size_t delay = 500;
};
using BindParser = std::function<Bind*(matjson::Value const&)>;
class CUSTOM_KEYBINDS_DLL BindManager : public cocos2d::CCObject {
// has to inherit from CCObject for scheduler
public:
using DevicelessActions = std::unordered_map<ActionID, std::set<matjson::Value>>;
protected:
struct ActionData {
BindableAction definition;
RepeatOptions repeat;
};
std::unordered_map<BindHash, std::vector<ActionID>> m_binds;
std::unordered_map<DeviceID, DevicelessActions> m_devicelessBinds;
std::unordered_map<DeviceID, BindParser> m_devices;
std::vector<std::pair<ActionID, ActionData>> m_actions;
std::vector<Category> m_categories;
geode::EventListener<PressBindFilter> m_listener =
geode::EventListener<PressBindFilter>(this, &BindManager::onDispatch);
std::unordered_map<ActionID, float> m_repeating;
std::unordered_map<ActionID, std::unordered_set<size_t>> m_downActionBinds;
BindManager();
geode::ListenerResult onDispatch(PressBindEvent* event);
void onRepeat(float dt);
void repeat(ActionID const& action);
void unrepeat(ActionID const& action);
bool loadActionBinds(ActionID const& action);
void saveActionBinds(ActionID const& action);
void fixEmptyBindsBug();
/// Checks if a specific Bind + Action combo is being held.
/// @param action the action ID we are checking
/// @param bind the bind we are checking
/// @returns true if the action bind is being held, false otherwise
bool isActionBindHeld(ActionID const& action, Bind* bind);
/// Marks a bind that belongs to an action as held. No changes will be made if the action doesn't use the bind.
/// @param action the action ID
/// @param bind the bind we are marking as held, has to belong to the action
void markActionBindHeld(ActionID const& action, Bind* bind);
/// Marks a bind that belongs to an action as released. No changes will be made if the action doesn't use the bind.
/// @param action the action ID
/// @param bind the bind we are marking as released, has to belong to the action
void unmarkActionBindHeld(ActionID const& action, Bind* bind);
friend class InvokeBindFilter;
friend struct matjson::Serialize<BindSaveData>;
public:
static BindManager* get();
void save();
void attachDevice(DeviceID const& device, BindParser parser);
void detachDevice(DeviceID const& device);
matjson::Value saveBind(Bind* bind) const;
Bind* loadBind(matjson::Value const& json) const;
bool registerBindable(BindableAction const& action, ActionID const& after = "");
void removeBindable(ActionID const& action);
std::optional<BindableAction> getBindable(ActionID const& action) const;
std::vector<BindableAction> getAllBindables() const;
std::vector<BindableAction> getBindablesIn(Category const& category, bool sub = false) const;
std::vector<BindableAction> getBindablesFor(Bind* bind) const;
std::vector<Category> getAllCategories() const;
/**
* Add a new bindable category. If the category is a subcategory (its
* ID has a slash, like "Editor/Modify"), then all its parent
* categories are inserted aswell, and the subcategory is added after
* its parent's last subcategory
* @param category The category to add. Specify a subcategory by
* including a slash in the name (like "Editor/Modify")
*/
void addCategory(Category const& category);
/**
* @note Also removes all the bindables in this category
*/
void removeCategory(Category const& category);
void addBindTo(ActionID const& action, Bind* bind);
void removeBindFrom(ActionID const& action, Bind* bind);
void removeAllBindsFrom(ActionID const& action);
void resetBindsToDefault(ActionID const& action);
bool hasDefaultBinds(ActionID const& action) const;
std::vector<geode::Ref<Bind>> getBindsFor(ActionID const& action) const;
std::optional<RepeatOptions> getRepeatOptionsFor(ActionID const& action);
void setRepeatOptionsFor(ActionID const& action, RepeatOptions const& options);
void stopAllRepeats();
};
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

@@ -0,0 +1,37 @@
{
"geode": "4.0.1",
"gd": {
"win": "2.2074",
"android": "2.2074"
},
"version": "v1.10.1",
"id": "geode.custom-keybinds",
"name": "Custom Keybinds",
"developer": "Geode Team",
"description": "Custom keybind support for Geode",
"links": {
"source": "https://github.com/geode-sdk/CustomKeybinds"
},
"resources": {
"spritesheets": {
"KB_ControllerSheet": [
"resources/controller/*.png"
]
},
"sprites": [
"resources/*.png"
]
},
"api": {
"include": [
"include/*.hpp"
]
},
"dependencies": [],
"incompatibilities": [],
"settings": {
"open-menu": {
"type": "custom:open-menu"
}
}
}
@@ -0,0 +1 @@
13380582522262
@@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>frames</key>
<dict>
<key>geode.custom-keybinds/controllerBtn_LB_001.png</key>
<dict>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{59,42}</string>
<key>spriteSourceSize</key>
<string>{59,42}</string>
<key>textureRect</key>
<string>{{0,0},{59,42}}</string>
<key>textureRotated</key>
<false/>
</dict>
<key>geode.custom-keybinds/controllerBtn_LT_001.png</key>
<dict>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{59,42}</string>
<key>spriteSourceSize</key>
<string>{59,42}</string>
<key>textureRect</key>
<string>{{0,44},{59,42}}</string>
<key>textureRotated</key>
<false/>
</dict>
<key>geode.custom-keybinds/controllerBtn_RB_001.png</key>
<dict>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{59,42}</string>
<key>spriteSourceSize</key>
<string>{59,42}</string>
<key>textureRect</key>
<string>{{0,88},{59,42}}</string>
<key>textureRotated</key>
<false/>
</dict>
<key>geode.custom-keybinds/controllerBtn_RT_001.png</key>
<dict>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{59,42}</string>
<key>spriteSourceSize</key>
<string>{59,42}</string>
<key>textureRect</key>
<string>{{0,132},{59,42}}</string>
<key>textureRotated</key>
<false/>
</dict>
</dict>
<key>metadata</key>
<dict>
<key>format</key>
<integer>3</integer>
<key>realTextureFileName</key>
<string>geode.custom-keybinds/KB_ControllerSheet-hd.png</string>
<key>size</key>
<string>{59,174}</string>
<key>textureFileName</key>
<string>geode.custom-keybinds/KB_ControllerSheet-hd.png</string>
</dict>
</dict>
</plist>
@@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>frames</key>
<dict>
<key>geode.custom-keybinds/controllerBtn_LB_001.png</key>
<dict>
<key>spriteOffset</key>
<string>{1,0}</string>
<key>spriteSize</key>
<string>{116,83}</string>
<key>spriteSourceSize</key>
<string>{118,84}</string>
<key>textureRect</key>
<string>{{0,0},{116,83}}</string>
<key>textureRotated</key>
<false/>
</dict>
<key>geode.custom-keybinds/controllerBtn_LT_001.png</key>
<dict>
<key>spriteOffset</key>
<string>{1,0}</string>
<key>spriteSize</key>
<string>{116,83}</string>
<key>spriteSourceSize</key>
<string>{118,84}</string>
<key>textureRect</key>
<string>{{0,85},{116,83}}</string>
<key>textureRotated</key>
<false/>
</dict>
<key>geode.custom-keybinds/controllerBtn_RB_001.png</key>
<dict>
<key>spriteOffset</key>
<string>{1,0}</string>
<key>spriteSize</key>
<string>{116,83}</string>
<key>spriteSourceSize</key>
<string>{118,84}</string>
<key>textureRect</key>
<string>{{0,170},{116,83}}</string>
<key>textureRotated</key>
<false/>
</dict>
<key>geode.custom-keybinds/controllerBtn_RT_001.png</key>
<dict>
<key>spriteOffset</key>
<string>{1,0}</string>
<key>spriteSize</key>
<string>{116,83}</string>
<key>spriteSourceSize</key>
<string>{118,84}</string>
<key>textureRect</key>
<string>{{0,255},{116,83}}</string>
<key>textureRotated</key>
<false/>
</dict>
</dict>
<key>metadata</key>
<dict>
<key>format</key>
<integer>3</integer>
<key>realTextureFileName</key>
<string>geode.custom-keybinds/KB_ControllerSheet-uhd.png</string>
<key>size</key>
<string>{116,338}</string>
<key>textureFileName</key>
<string>geode.custom-keybinds/KB_ControllerSheet-uhd.png</string>
</dict>
</dict>
</plist>
@@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>frames</key>
<dict>
<key>geode.custom-keybinds/controllerBtn_LB_001.png</key>
<dict>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{29,21}</string>
<key>spriteSourceSize</key>
<string>{29,21}</string>
<key>textureRect</key>
<string>{{0,0},{29,21}}</string>
<key>textureRotated</key>
<false/>
</dict>
<key>geode.custom-keybinds/controllerBtn_LT_001.png</key>
<dict>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{29,21}</string>
<key>spriteSourceSize</key>
<string>{29,21}</string>
<key>textureRect</key>
<string>{{0,23},{29,21}}</string>
<key>textureRotated</key>
<false/>
</dict>
<key>geode.custom-keybinds/controllerBtn_RB_001.png</key>
<dict>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{29,21}</string>
<key>spriteSourceSize</key>
<string>{29,21}</string>
<key>textureRect</key>
<string>{{0,46},{29,21}}</string>
<key>textureRotated</key>
<false/>
</dict>
<key>geode.custom-keybinds/controllerBtn_RT_001.png</key>
<dict>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{29,21}</string>
<key>spriteSourceSize</key>
<string>{29,21}</string>
<key>textureRect</key>
<string>{{0,69},{29,21}}</string>
<key>textureRotated</key>
<false/>
</dict>
</dict>
<key>metadata</key>
<dict>
<key>format</key>
<integer>3</integer>
<key>realTextureFileName</key>
<string>geode.custom-keybinds/KB_ControllerSheet.png</string>
<key>size</key>
<string>{29,90}</string>
<key>textureFileName</key>
<string>geode.custom-keybinds/KB_ControllerSheet.png</string>
</dict>
</dict>
</plist>
Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 598 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB