From adfcc3ba9ec9f931597af8fc949199bd6777681c Mon Sep 17 00:00:00 2001 From: HaxSam Date: Fri, 1 Mar 2024 09:38:03 +0100 Subject: [PATCH 01/35] fixing always updating rainbow mode --- lib/drivers/rgb_backlight.c | 80 +++++++++++++++++++++++++------------ lib/drivers/rgb_backlight.h | 10 ++++- targets/f7/api_symbols.csv | 1 + 3 files changed, 64 insertions(+), 27 deletions(-) diff --git a/lib/drivers/rgb_backlight.c b/lib/drivers/rgb_backlight.c index 097fa30de3..1e24997cb7 100644 --- a/lib/drivers/rgb_backlight.c +++ b/lib/drivers/rgb_backlight.c @@ -18,6 +18,8 @@ */ #include "rgb_backlight.h" +#include "colors.h" +#include "core/timer.h" #include #include #include @@ -205,7 +207,7 @@ uint8_t rgb_backlight_get_rainbow_saturation() { static void rainbow_timer(void* ctx) { UNUSED(ctx); - rgb_backlight_update(rgb_state.last_brightness, true); + rgb_backlight_rainbow_mode(); } void rgb_backlight_reconfigure(bool enabled) { @@ -226,7 +228,50 @@ void rgb_backlight_reconfigure(bool enabled) { rgb_state.rainbow_timer = NULL; } rgb_state.rainbow_hsv.s = rgb_settings.rainbow_saturation; - rgb_backlight_update(rgb_state.last_brightness, false); + rgb_backlight_update(rgb_state.last_brightness, true); + + furi_check(furi_mutex_release(rgb_state.mutex) == FuriStatusOk); +} + +void rgb_backlight_rainbow_mode() { + if(!rgb_state.settings_loaded) return; + furi_check(furi_mutex_acquire(rgb_state.mutex, FuriWaitForever) == FuriStatusOk); + + if(!rgb_state.enabled || rgb_settings.rainbow_mode == RGBBacklightRainbowModeOff || + !rgb_state.last_brightness) { + furi_check(furi_mutex_release(rgb_state.mutex) == FuriStatusOk); + return; + } + + rgb_state.rainbow_hsv.h += rgb_settings.rainbow_speed; + + RgbColor rgb; + hsv2rgb(&rgb_state.rainbow_hsv, &rgb); + + switch(rgb_settings.rainbow_mode) { + case RGBBacklightRainbowModeWave: { + HsvColor hsv = rgb_state.rainbow_hsv; + for(uint8_t i = 0; i < SK6805_get_led_count(); i++) { + if(i) { + hsv.h += (50 * i); + hsv2rgb(&hsv, &rgb); + } + SK6805_set_led_color(i, rgb.r, rgb.g, rgb.b); + } + break; + } + + case RGBBacklightRainbowModeSolid: + for(uint8_t i = 0; i < SK6805_get_led_count(); i++) { + SK6805_set_led_color(i, rgb.r, rgb.g, rgb.b); + } + break; + + default: + break; + } + + SK6805_update(); if(rgb_state.enabled && rgb_settings.rainbow_mode == RGBBacklightRainbowModeOff) SK6805_update(); @@ -234,11 +279,11 @@ void rgb_backlight_reconfigure(bool enabled) { furi_check(furi_mutex_release(rgb_state.mutex) == FuriStatusOk); } -void rgb_backlight_update(uint8_t brightness, bool tick) { +void rgb_backlight_update(uint8_t brightness, bool forced) { if(!rgb_state.settings_loaded) return; furi_check(furi_mutex_acquire(rgb_state.mutex, FuriWaitForever) == FuriStatusOk); - if(!rgb_state.enabled) { + if(!rgb_state.enabled || (brightness == rgb_state.last_brightness && !forced)) { furi_check(furi_mutex_release(rgb_state.mutex) == FuriStatusOk); return; } @@ -258,29 +303,14 @@ void rgb_backlight_update(uint8_t brightness, bool tick) { case RGBBacklightRainbowModeWave: case RGBBacklightRainbowModeSolid: { - if(tick && brightness) { - rgb_state.rainbow_hsv.h += rgb_settings.rainbow_speed; - } else { - rgb_state.rainbow_hsv.v = brightness; - } - - RgbColor rgb; - hsv2rgb(&rgb_state.rainbow_hsv, &rgb); - - if(rgb_settings.rainbow_mode == RGBBacklightRainbowModeWave) { - HsvColor hsv = rgb_state.rainbow_hsv; - for(uint8_t i = 0; i < SK6805_get_led_count(); i++) { - if(i) { - hsv.h += (50 * i); - hsv2rgb(&hsv, &rgb); - } - SK6805_set_led_color(i, rgb.r, rgb.g, rgb.b); - } - } else { + if(!brightness) { + furi_timer_stop(rgb_state.rainbow_timer); for(uint8_t i = 0; i < SK6805_get_led_count(); i++) { - SK6805_set_led_color(i, rgb.r, rgb.g, rgb.b); + SK6805_set_led_color(i, 0, 0, 0); } - } + } else if(!rgb_state.last_brightness) + furi_timer_start(rgb_state.rainbow_timer, rgb_settings.rainbow_interval); + rgb_state.rainbow_hsv.v = brightness; break; } diff --git a/lib/drivers/rgb_backlight.h b/lib/drivers/rgb_backlight.h index a30b5e2688..31de7c4889 100644 --- a/lib/drivers/rgb_backlight.h +++ b/lib/drivers/rgb_backlight.h @@ -97,13 +97,19 @@ uint8_t rgb_backlight_get_rainbow_saturation(); */ void rgb_backlight_reconfigure(bool enabled); +/** + * @brief Run the RGB rainbowmode + * + */ +void rgb_backlight_rainbow_mode(); + /** * @brief Apply current RGB lighting settings * * @param brightness Backlight intensity (0-255) - * @param tick Whether this update was a tick (for rainbow) + * @param forced force a update even brightness doesnt changed */ -void rgb_backlight_update(uint8_t brightness, bool tick); +void rgb_backlight_update(uint8_t brightness, bool forced); #ifdef __cplusplus } diff --git a/targets/f7/api_symbols.csv b/targets/f7/api_symbols.csv index 0f538b0dd5..f387122d8b 100644 --- a/targets/f7/api_symbols.csv +++ b/targets/f7/api_symbols.csv @@ -2963,6 +2963,7 @@ Function,+,rgb_backlight_get_rainbow_mode,RGBBacklightRainbowMode, Function,+,rgb_backlight_get_rainbow_saturation,uint8_t, Function,+,rgb_backlight_get_rainbow_speed,uint8_t, Function,-,rgb_backlight_load_settings,void,_Bool +Function,-,rgb_backlight_rainbow_mode,void, Function,+,rgb_backlight_reconfigure,void,_Bool Function,+,rgb_backlight_save_settings,void, Function,+,rgb_backlight_set_color,void,"uint8_t, const RgbColor*" From 4b7ca736d6ed4c3905dbc22433872cfb19787eaa Mon Sep 17 00:00:00 2001 From: Sergei Gavrilov Date: Fri, 1 Mar 2024 21:58:15 +1000 Subject: [PATCH 02/35] WiFi board: fixed update script on Windows (unfortunately also Mac and Linux) (#3485) * WiFi board update: windows fix * Scripts: add python\Scripts to the path * Windows: another way to call esptool * Aaaaaand once more! * logz * wifi board scripts: udev rule, dev channel * fbt: added ARGS variable for passing extra options to certain scripts; removed `devboard_flash_dev` in favor of `devboard_flash ARGS="-c dev"` * fbt: fully removed `devboard_flash_dev * scripts: wifi_board.py: cleanup * ufbt: ported ARGS for supported targets to ufbt * docs: updated for ARGS=... --------- Co-authored-by: hedger Co-authored-by: hedger --- SConstruct | 61 ++++++++++++-- documentation/fbt.md | 8 +- scripts/fbt_tools/fbt_dist.py | 3 + scripts/ufbt/SConstruct | 41 +++++++-- scripts/ufbt/site_tools/ufbt_help.py | 3 +- scripts/wifi_board.py | 120 +++++++++++++++------------ site_scons/commandline.scons | 5 ++ 7 files changed, 170 insertions(+), 71 deletions(-) diff --git a/SConstruct b/SConstruct index 6d24da920a..2bc0128ccc 100644 --- a/SConstruct +++ b/SConstruct @@ -66,6 +66,7 @@ if GetOption("fullenv") or any( # Target for self-update package dist_basic_arguments = [ + "${ARGS}", "--bundlever", "${UPDATE_VERSION_STRING}", ] @@ -182,6 +183,7 @@ fap_deploy = distenv.PhonyTarget( "send", "${SOURCE}", "/ext/apps", + "${ARGS}", ] ] ), @@ -208,7 +210,7 @@ distenv.Alias("jflash", firmware_jflash) distenv.PhonyTarget( "gdb_trace_all", - "$GDB $GDBOPTS $SOURCES $GDBFLASH", + [["${GDB}", "${GDBOPTS}", "${SOURCES}", "${GDBFLASH}"]], source=firmware_env["FW_ELF"], GDBOPTS="${GDBOPTS_BASE}", GDBREMOTE="${OPENOCD_GDB_PIPE}", @@ -272,19 +274,35 @@ distenv.PhonyTarget( # Just start OpenOCD distenv.PhonyTarget( "openocd", - "${OPENOCDCOM}", + [["${OPENOCDCOM}", "${ARGS}"]], ) # Linter distenv.PhonyTarget( "lint", - [["${PYTHON3}", "${FBT_SCRIPT_DIR}/lint.py", "check", "${LINT_SOURCES}"]], + [ + [ + "${PYTHON3}", + "${FBT_SCRIPT_DIR}/lint.py", + "check", + "${LINT_SOURCES}", + "${ARGS}", + ] + ], LINT_SOURCES=[n.srcnode() for n in firmware_env["LINT_SOURCES"]], ) distenv.PhonyTarget( "format", - [["${PYTHON3}", "${FBT_SCRIPT_DIR}/lint.py", "format", "${LINT_SOURCES}"]], + [ + [ + "${PYTHON3}", + "${FBT_SCRIPT_DIR}/lint.py", + "format", + "${LINT_SOURCES}", + "${ARGS}", + ] + ], LINT_SOURCES=[n.srcnode() for n in firmware_env["LINT_SOURCES"]], ) @@ -307,7 +325,16 @@ firmware_env.Append( ) -black_commandline = "@${PYTHON3} -m black ${PY_BLACK_ARGS} ${PY_LINT_SOURCES}" +black_commandline = [ + [ + "@${PYTHON3}", + "-m", + "black", + "${PY_BLACK_ARGS}", + "${PY_LINT_SOURCES}", + "${ARGS}", + ] +] black_base_args = [ "--include", '"(\\.scons|\\.py|SConscript|SConstruct|\\.fam)$"', @@ -333,12 +360,28 @@ distenv.PhonyTarget( # Start Flipper CLI via PySerial's miniterm distenv.PhonyTarget( - "cli", [["${PYTHON3}", "${FBT_SCRIPT_DIR}/serial_cli.py", "-p", "${FLIP_PORT}"]] + "cli", + [ + [ + "${PYTHON3}", + "${FBT_SCRIPT_DIR}/serial_cli.py", + "-p", + "${FLIP_PORT}", + "${ARGS}", + ] + ], ) -# Update WiFi devboard firmware +# Update WiFi devboard firmware with release channel distenv.PhonyTarget( - "devboard_flash", [["${PYTHON3}", "${FBT_SCRIPT_DIR}/wifi_board.py"]] + "devboard_flash", + [ + [ + "${PYTHON3}", + "${FBT_SCRIPT_DIR}/wifi_board.py", + "${ARGS}", + ] + ], ) @@ -353,7 +396,7 @@ distenv.PhonyTarget( distenv.PhonyTarget( "get_stlink", distenv.Action( - lambda **kw: distenv.GetDevices(), + lambda **_: distenv.GetDevices(), None, ), ) diff --git a/documentation/fbt.md b/documentation/fbt.md index 02de2949fa..0220178a2d 100644 --- a/documentation/fbt.md +++ b/documentation/fbt.md @@ -71,13 +71,13 @@ To use language servers other than the default VS Code C/C++ language server, us - `debug` - build and flash firmware, then attach with gdb with firmware's .elf loaded. - `debug_other`, `debug_other_blackmagic` - attach GDB without loading any `.elf`. It will allow you to manually add external `.elf` files with `add-symbol-file` in GDB. - `updater_debug` - attach GDB with the updater's `.elf` loaded. -- `devboard_flash` - update WiFi dev board with the latest firmware. +- `devboard_flash` - Update WiFi dev board. Supports `ARGS="..."` to pass extra arguments to the update script, e.g. `ARGS="-c dev"`. - `blackmagic` - debug firmware with Blackmagic probe (WiFi dev board). -- `openocd` - just start OpenOCD. +- `openocd` - just start OpenOCD. You can pass extra arguments with `ARGS="..."`. - `get_blackmagic` - output the blackmagic address in the GDB remote format. Useful for IDE integration. - `get_stlink` - output serial numbers for attached STLink probes. Used for specifying an adapter with `SWD_TRANSPORT_SERIAL=...`. -- `lint`, `format` - run clang-format on the C source code to check and reformat it according to the `.clang-format` specs. -- `lint_py`, `format_py` - run [black](https://black.readthedocs.io/en/stable/index.html) on the Python source code, build system files & application manifests. +- `lint`, `format` - run clang-format on the C source code to check and reformat it according to the `.clang-format` specs. Supports `ARGS="..."` to pass extra arguments to clang-format. +- `lint_py`, `format_py` - run [black](https://black.readthedocs.io/en/stable/index.html) on the Python source code, build system files & application manifests. Supports `ARGS="..."` to pass extra arguments to black. - `firmware_pvs` - generate a PVS Studio report for the firmware. Requires PVS Studio to be available on your system's `PATH`. - `cli` - start a Flipper CLI session over USB. diff --git a/scripts/fbt_tools/fbt_dist.py b/scripts/fbt_tools/fbt_dist.py index bf586b8fbb..324a2281f5 100644 --- a/scripts/fbt_tools/fbt_dist.py +++ b/scripts/fbt_tools/fbt_dist.py @@ -150,6 +150,7 @@ def generate(env): "--interface=${SWD_TRANSPORT}", "--serial=${SWD_TRANSPORT_SERIAL}", "${SOURCE}", + "${ARGS}", ], Touch("${TARGET}"), ] @@ -162,6 +163,7 @@ def generate(env): "-p", "${FLIP_PORT}", "${UPDATE_BUNDLE_DIR}/update.fuf", + "${ARGS}", ], Touch("${TARGET}"), ] @@ -180,6 +182,7 @@ def generate(env): "--stack_type=${COPRO_STACK_TYPE}", "--stack_file=${COPRO_STACK_BIN}", "--stack_addr=${COPRO_STACK_ADDR}", + "${ARGS}", ] ], "${COPROCOMSTR}", diff --git a/scripts/ufbt/SConstruct b/scripts/ufbt/SConstruct index a26c2e404a..8178a83da4 100644 --- a/scripts/ufbt/SConstruct +++ b/scripts/ufbt/SConstruct @@ -315,26 +315,56 @@ else: appenv.PhonyTarget( "cli", - [["${PYTHON3}", "${FBT_SCRIPT_DIR}/serial_cli.py", "-p", "${FLIP_PORT}"]], + [ + [ + "${PYTHON3}", + "${FBT_SCRIPT_DIR}/serial_cli.py", + "-p", + "${FLIP_PORT}", + "${ARGS}", + ] + ], ) # Update WiFi devboard firmware dist_env.PhonyTarget( - "devboard_flash", [["${PYTHON3}", "${FBT_SCRIPT_DIR}/wifi_board.py"]] + "devboard_flash", + [ + [ + "${PYTHON3}", + "${FBT_SCRIPT_DIR}/wifi_board.py", + "${ARGS}", + ] + ], ) # Linter - dist_env.PhonyTarget( "lint", - [["${PYTHON3}", "${FBT_SCRIPT_DIR}/lint.py", "check", "${LINT_SOURCES}"]], + [ + [ + "${PYTHON3}", + "${FBT_SCRIPT_DIR}/lint.py", + "check", + "${LINT_SOURCES}", + "${ARGS}", + ] + ], source=original_app_dir.File(".clang-format"), LINT_SOURCES=[original_app_dir], ) dist_env.PhonyTarget( "format", - [["${PYTHON3}", "${FBT_SCRIPT_DIR}/lint.py", "format", "${LINT_SOURCES}"]], + [ + [ + "${PYTHON3}", + "${FBT_SCRIPT_DIR}/lint.py", + "format", + "${LINT_SOURCES}", + "${ARGS}", + ] + ], source=original_app_dir.File(".clang-format"), LINT_SOURCES=[original_app_dir], ) @@ -456,6 +486,7 @@ if dolphin_src_dir.exists(): "send", "${SOURCE}", "/ext/dolphin", + "${ARGS}", ] ], source=ufbt_build_dir.Dir("dolphin"), diff --git a/scripts/ufbt/site_tools/ufbt_help.py b/scripts/ufbt/site_tools/ufbt_help.py index 4873b385c6..632fd98b2d 100644 --- a/scripts/ufbt/site_tools/ufbt_help.py +++ b/scripts/ufbt/site_tools/ufbt_help.py @@ -29,7 +29,8 @@ debug, debug_other, blackmagic: Start GDB devboard_flash: - Update WiFi dev board with the latest firmware + Update WiFi dev board. + Supports ARGS="..." to pass extra arguments to the update script, e.g. ARGS="-c dev" Other: cli: diff --git a/scripts/wifi_board.py b/scripts/wifi_board.py index 3f89ebdc65..b01b6225dd 100755 --- a/scripts/wifi_board.py +++ b/scripts/wifi_board.py @@ -1,16 +1,16 @@ #!/usr/bin/env python3 -from flipper.app import App -from serial.tools.list_ports_common import ListPortInfo - +import json import logging import os -import tempfile import subprocess -import serial.tools.list_ports as list_ports -import json -import requests import tarfile +import tempfile + +import requests +import serial.tools.list_ports as list_ports +from flipper.app import App +from serial.tools.list_ports_common import ListPortInfo class UpdateDownloader: @@ -29,15 +29,15 @@ class UpdateDownloader: def __init__(self): self.logger = logging.getLogger() - def download(self, channel_id: str, dir: str) -> bool: + def download(self, channel_id: str, target_dir: str) -> bool: # Aliases if channel_id in self.CHANNEL_ID_ALIAS: channel_id = self.CHANNEL_ID_ALIAS[channel_id] # Make directory - if not os.path.exists(dir): - self.logger.info(f"Creating directory {dir}") - os.makedirs(dir) + if not os.path.exists(target_dir): + self.logger.info(f"Creating directory {target_dir}") + os.makedirs(target_dir) # Download json index self.logger.info(f"Downloading {self.UPDATE_INDEX}") @@ -79,19 +79,14 @@ def download(self, channel_id: str, dir: str) -> bool: self.logger.info(f"Using version '{version['version']}'") # Get changelog - changelog = None - try: - changelog = version["changelog"] - except Exception as e: - self.logger.error(f"Failed to get changelog: {e}") - - # print changelog - if changelog is not None: + if changelog := version.get("changelog"): self.logger.info(f"Changelog:") for line in changelog.split("\n"): if line.strip() == "": continue self.logger.info(f" {line}") + else: + self.logger.warning(f"Changelog not found") # Find file file_url = None @@ -106,7 +101,7 @@ def download(self, channel_id: str, dir: str) -> bool: # Make file path file_name = file_url.split("/")[-1] - file_path = os.path.join(dir, file_name) + file_path = os.path.join(target_dir, file_name) # Download file self.logger.info(f"Downloading {file_url} to {file_path}") @@ -117,7 +112,7 @@ def download(self, channel_id: str, dir: str) -> bool: # Unzip tgz self.logger.info(f"Unzipping {file_path}") with tarfile.open(file_path, "r") as tar: - tar.extractall(dir) + tar.extractall(target_dir) return True @@ -133,16 +128,24 @@ def init(self): # logging self.logger = logging.getLogger() - def find_wifi_board(self) -> bool: + @staticmethod + def _grep_ports(regexp: str) -> list[ListPortInfo]: # idk why, but python thinks that list_ports.grep returns tuple[str, str, str] - blackmagics: list[ListPortInfo] = list(list_ports.grep("blackmagic")) # type: ignore - daps: list[ListPortInfo] = list(list_ports.grep("CMSIS-DAP")) # type: ignore + return list(list_ports.grep(regexp)) # type: ignore + + def is_wifi_board_connected(self) -> bool: + return ( + len(self._grep_ports("ESP32-S2")) > 0 + or len(self._grep_ports("CMSIS-DAP")) > 0 + ) - return len(blackmagics) > 0 or len(daps) > 0 + @staticmethod + def is_windows() -> bool: + return os.name == "nt" - def find_wifi_board_bootloader(self): - # idk why, but python thinks that list_ports.grep returns tuple[str, str, str] - ports: list[ListPortInfo] = list(list_ports.grep("ESP32-S2")) # type: ignore + @classmethod + def find_port(cls, regexp: str) -> str: + ports: list[ListPortInfo] = cls._grep_ports(regexp) if len(ports) == 0: # Blackmagic probe serial port not found, will be handled later @@ -151,27 +154,28 @@ def find_wifi_board_bootloader(self): raise Exception("More than one WiFi board found") else: port = ports[0] - if os.name == "nt": - port.device = f"\\\\.\\{port.device}" - return port.device + return f"\\\\.\\{port.device}" if cls.is_windows() else port.device + + def find_wifi_board_bootloader_port(self): + return self.find_port("ESP32-S2") + + def find_wifi_board_bootloader_port_damn_windows(self): + self.logger.info("Trying to find WiFi board using VID:PID") + return self.find_port("VID:PID=303A:0002") def update(self): try: - port = self.find_wifi_board_bootloader() + port = self.find_wifi_board_bootloader_port() + + # Damn windows fix + if port is None and self.is_windows(): + port = self.find_wifi_board_bootloader_port_damn_windows() except Exception as e: self.logger.error(f"{e}") return 1 - if self.args.port != "auto": - port = self.args.port - - available_ports = [p[0] for p in list(list_ports.comports())] - if port not in available_ports: - self.logger.error(f"Port {port} not found") - return 1 - if port is None: - if self.find_wifi_board(): + if self.is_wifi_board_connected(): self.logger.error("WiFi board found, but not in bootloader mode.") self.logger.info("Please hold down BOOT button and press RESET button") else: @@ -179,6 +183,13 @@ def update(self): self.logger.info( "Please connect WiFi board to your computer, hold down BOOT button and press RESET button" ) + if not self.is_windows(): + self.logger.info( + "If you are using Linux, you may need to add udev rules to access the device" + ) + self.logger.info( + "Check out 41-flipper.rules & README in scripts/debug folder" + ) return 1 # get temporary dir @@ -197,24 +208,29 @@ def update(self): with open(os.path.join(temp_dir, "flash.command"), "r") as f: flash_command = f.read() - flash_command = flash_command.replace("\n", "").replace("\r", "") - flash_command = flash_command.replace("(PORT)", port) - - # We can't reset the board after flashing via usb - flash_command = flash_command.replace( - "--after hard_reset", "--after no_reset_stub" + replacements = ( + ("\n", ""), + ("\r", ""), + ("(PORT)", port), + # We can't reset the board after flashing via usb + ("--after hard_reset", "--after no_reset_stub"), ) - args = flash_command.split(" ")[0:] - args = list(filter(None, args)) + # hellish toolchain fix + if self.is_windows(): + replacements += (("esptool.py", "python -m esptool"),) + else: + replacements += (("esptool.py", "python3 -m esptool"),) + + for old, new in replacements: + flash_command = flash_command.replace(old, new) - esptool_params = [] - esptool_params.extend(args) + args = list(filter(None, flash_command.split())) self.logger.info(f'Running command: "{" ".join(args)}" in "{temp_dir}"') process = subprocess.Popen( - esptool_params, + args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=temp_dir, diff --git a/site_scons/commandline.scons b/site_scons/commandline.scons index 2d2abd5c67..3ea5dcd6b7 100644 --- a/site_scons/commandline.scons +++ b/site_scons/commandline.scons @@ -274,6 +274,11 @@ vars.AddVariables( help="Enable strict import check for .faps", default=True, ), + ( + "ARGS", + "Extra arguments to pass to certain scripts supporting it", + "", + ), ) Return("vars") From ab39ac944ad97b47ba71f4b5ee6da985ea6a4580 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Fri, 1 Mar 2024 12:42:15 +0000 Subject: [PATCH 03/35] Update apps --- applications/external | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/external b/applications/external index dae7906c1a..af7feff6ae 160000 --- a/applications/external +++ b/applications/external @@ -1 +1 @@ -Subproject commit dae7906c1abb4fd6d4198669a84d92dd1902032b +Subproject commit af7feff6ae10cce3c98d4e2021feaf2d337333f3 From 72fdb751e235b28b7ae14c604d2f12667af1739b Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Fri, 1 Mar 2024 12:42:27 +0000 Subject: [PATCH 04/35] Fix some wording --- .github/workflow_data/release.md | 2 +- ReadMe.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflow_data/release.md b/.github/workflow_data/release.md index f556bfb57f..05602a952f 100644 --- a/.github/workflow_data/release.md +++ b/.github/workflow_data/release.md @@ -8,7 +8,7 @@ **Check the [install guide](https://github.com/Next-Flip/Momentum-Firmware#install) if you're not sure, or [join our Discord](https://discord.gg/momentum) if you have questions or encounter issues!** ## ❤️ Support -If you enjoy the firmware, please consider donating to the team, or sharing it with others! :D +If you enjoy the firmware, please consider donating to the team, or spreading the word! :D > **[Ko-fi](https://ko-fi.com/willyjl)**: One-off or Recurring, No signup required diff --git a/ReadMe.md b/ReadMe.md index 6d64ebf9bd..8a274d04d6 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -7,7 +7,7 @@ Install | Features | Discord | Donate -This custom firmware is based on the [Official Firmware](https://github.com/flipperdevices/flipperzero-firmware), and features most of the awesome features from [Unleashed](https://github.com/DarkFlippers/unleashed-firmware). It is a direct continuation of the Xtreme firmware, built by the same (and only) developers who made that project special, until being unfairly thrown out. +This custom firmware is based on the [Official Firmware](https://github.com/flipperdevices/flipperzero-firmware), and includes most of the awesome features from [Unleashed](https://github.com/DarkFlippers/unleashed-firmware). It is a direct continuation of the Xtreme firmware, built by the same (and only) developers who made that project special, until being unfairly thrown out. -----
@@ -192,7 +192,7 @@ $ ./fbt launch APPSRC=your_appid ## ❤️ Support -If you enjoy the firmware, please consider donating to the team, or sharing it with others! :D +If you enjoy the firmware, please consider donating to the team, or spreading the word! :D > **[Ko-fi](https://ko-fi.com/willyjl)**: One-off or Recurring, No signup required From 5f11c7b197c9329bb4bb2cb76c3b292a026eb12a Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Fri, 1 Mar 2024 12:42:50 +0000 Subject: [PATCH 05/35] Disable devbuild until setup --- .github/workflows/build.yml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 329dfdc0d0..d054252155 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -54,14 +54,14 @@ jobs: - name: "Make tgz, zip and sdk" run: bash .github/workflow_data/package.sh - - name: Send devbuild webhook - if: "github.event_name == 'push' && github.ref_name == 'dev' && !contains(github.event.head_commit.message, '--nobuild')" - env: - NC_HOST: "https://cloud.cynthialabs.net/" - NC_USERAGENT: "${{ secrets.NC_USERAGENT }}" - NC_USER: "${{ secrets.NC_USER }}" - NC_PASS: "${{ secrets.NC_PASS }}" - BUILD_WEBHOOK: ${{ secrets.BUILD_WEBHOOK }} - run: | - python -m pip install pyncclient - python .github/workflow_data/devbuild.py + # - name: Send devbuild webhook + # if: "github.event_name == 'push' && github.ref_name == 'dev' && !contains(github.event.head_commit.message, '--nobuild')" + # env: + # NC_HOST: "https://cloud.cynthialabs.net/" + # NC_USERAGENT: "${{ secrets.NC_USERAGENT }}" + # NC_USER: "${{ secrets.NC_USER }}" + # NC_PASS: "${{ secrets.NC_PASS }}" + # BUILD_WEBHOOK: ${{ secrets.BUILD_WEBHOOK }} + # run: | + # python -m pip install pyncclient + # python .github/workflow_data/devbuild.py From 5795ce18cdce671cb5f34da32f19206a3dafc0a3 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Fri, 1 Mar 2024 12:50:12 +0000 Subject: [PATCH 06/35] Add icon asset --- .github/assets/icon.png | Bin 0 -> 25704 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 .github/assets/icon.png diff --git a/.github/assets/icon.png b/.github/assets/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..e6b46af58a7c8f1cf57c61898c24309d4728c04e GIT binary patch literal 25704 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 literal 0 HcmV?d00001 From accf9bb8c914bd767fa5060db843a3b6f30181a5 Mon Sep 17 00:00:00 2001 From: "Mr. Proxy" Date: Fri, 1 Mar 2024 14:47:03 +0100 Subject: [PATCH 07/35] =?UTF-8?q?Fixed=20some=20mistakes=20=F0=9F=98=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- documentation/file_formats/AssetPacks.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/file_formats/AssetPacks.md b/documentation/file_formats/AssetPacks.md index 602d9c50ff..c2827d49db 100644 --- a/documentation/file_formats/AssetPacks.md +++ b/documentation/file_formats/AssetPacks.md @@ -1,6 +1,6 @@ ## Intro -Asset Packs are an exclusive feature of Xtreme Firmware that allows you to load custom Animation and Icon sets without recompiling the firmware or messing with manifest.txt files (as a user). Here you can find info on how to install Asset Packs and also how to make your own. +Asset Packs are an exclusive feature of Momentum Firmware that allows you to load custom Animation and Icon sets without recompiling the firmware or messing with manifest.txt files (as a user). Here you can find info on how to install Asset Packs and also how to make your own.
@@ -14,7 +14,7 @@ Installing Asset Packs is quite easy and straightforward. First, make sure you'r If you did this correctly, you should see `SD/asset_packs/PackName/Anims` and/or `SD/asset_packs/PackName/Icons`. -- Now simply open the Xtreme Settings app (from the home screen press `Arrow UP` and then `Xtreme Settings`) and select the asset pack you want. When you back out, Flipper will restart and your animations and icons will use the ones from the selected pack! +- Now simply open the Momentum Settings app (from the home screen press `Arrow UP` and then `Momentum Settings`) and select the asset pack you want. When you back out, Flipper will restart and your animations and icons will use the ones from the selected pack!
From 445eab1d637015f02910fcbab6b95b395260150a Mon Sep 17 00:00:00 2001 From: "Mr. Proxy" Date: Fri, 1 Mar 2024 14:48:02 +0100 Subject: [PATCH 08/35] Fixed something --- ReadMe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ReadMe.md b/ReadMe.md index 8a274d04d6..f33b67e9f0 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -7,7 +7,7 @@
Install | Features | Discord | Donate -This custom firmware is based on the [Official Firmware](https://github.com/flipperdevices/flipperzero-firmware), and includes most of the awesome features from [Unleashed](https://github.com/DarkFlippers/unleashed-firmware). It is a direct continuation of the Xtreme firmware, built by the same (and only) developers who made that project special, until being unfairly thrown out. +This custom firmware is based on the [Official Firmware](https://github.com/flipperdevices/flipperzero-firmware), and includes most of the awesome features from [Unleashed](https://github.com/DarkFlippers/unleashed-firmware). It is a direct continuation of the Momentum firmware, built by the same (and only) developers who made that project special, until being unfairly thrown out. -----
From 3eabdadee967ba99cb4dfaeea437d829cbedb63f Mon Sep 17 00:00:00 2001 From: "Mr. Proxy" Date: Fri, 1 Mar 2024 14:52:18 +0100 Subject: [PATCH 09/35] Fixed link --- .../main/nfc/resources/nfc/assets/mf_classic_dict.nfc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/applications/main/nfc/resources/nfc/assets/mf_classic_dict.nfc b/applications/main/nfc/resources/nfc/assets/mf_classic_dict.nfc index fe49f180c1..ef310ccefa 100644 --- a/applications/main/nfc/resources/nfc/assets/mf_classic_dict.nfc +++ b/applications/main/nfc/resources/nfc/assets/mf_classic_dict.nfc @@ -4244,7 +4244,7 @@ FE98F38F3EE2 78DF1176C8FD ADC169F922CB # +------------------------------------------------------------------------------------------------------------------------+ -# | https://github.com/Flipper-XFW/Xtreme-Firmware/blob/dev/applications/main/nfc/resources/nfc/assets/mf_classic_dict.nfc | +# | https://github.com/Next-Flip/Momentum-Firmware/blob/dev/applications/main/nfc/resources/nfc/assets/mf_classic_dict.nfc | # +------------------------------------------------------------------------------------------------------------------------+ ############################################## # STB - keys from Bucharest Public Transport @@ -4389,4 +4389,4 @@ EB9D9C1B03F6 5A4920FD6F87 544954CBB2C4 4752533E1965 -17C06D19E92F \ No newline at end of file +17C06D19E92F From 5e0eba721f15ba76527954103b52a45c706f74b8 Mon Sep 17 00:00:00 2001 From: "Mr. Proxy" Date: Fri, 1 Mar 2024 14:53:20 +0100 Subject: [PATCH 10/35] oops xd --- ReadMe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ReadMe.md b/ReadMe.md index f33b67e9f0..8a274d04d6 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -7,7 +7,7 @@ Install | Features | Discord | Donate -This custom firmware is based on the [Official Firmware](https://github.com/flipperdevices/flipperzero-firmware), and includes most of the awesome features from [Unleashed](https://github.com/DarkFlippers/unleashed-firmware). It is a direct continuation of the Momentum firmware, built by the same (and only) developers who made that project special, until being unfairly thrown out. +This custom firmware is based on the [Official Firmware](https://github.com/flipperdevices/flipperzero-firmware), and includes most of the awesome features from [Unleashed](https://github.com/DarkFlippers/unleashed-firmware). It is a direct continuation of the Xtreme firmware, built by the same (and only) developers who made that project special, until being unfairly thrown out. -----
From 62126152f9387d34b243abb24d17078b1cc610f1 Mon Sep 17 00:00:00 2001 From: "Mr. Proxy" Date: Fri, 1 Mar 2024 15:03:11 +0100 Subject: [PATCH 11/35] Ight didnt know --- applications/main/nfc/resources/nfc/assets/mf_classic_dict.nfc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/main/nfc/resources/nfc/assets/mf_classic_dict.nfc b/applications/main/nfc/resources/nfc/assets/mf_classic_dict.nfc index ef310ccefa..8763d7461c 100644 --- a/applications/main/nfc/resources/nfc/assets/mf_classic_dict.nfc +++ b/applications/main/nfc/resources/nfc/assets/mf_classic_dict.nfc @@ -4244,7 +4244,7 @@ FE98F38F3EE2 78DF1176C8FD ADC169F922CB # +------------------------------------------------------------------------------------------------------------------------+ -# | https://github.com/Next-Flip/Momentum-Firmware/blob/dev/applications/main/nfc/resources/nfc/assets/mf_classic_dict.nfc | +# | https://github.com/Flipper-XFW/Xtreme-Firmware/blob/dev/applications/main/nfc/resources/nfc/assets/mf_classic_dict.nfc | # +------------------------------------------------------------------------------------------------------------------------+ ############################################## # STB - keys from Bucharest Public Transport From 34e8a798d9ec5f840961a6733f8836ecc30a5974 Mon Sep 17 00:00:00 2001 From: HaxSam Date: Fri, 1 Mar 2024 15:36:45 +0100 Subject: [PATCH 12/35] removed unnecessary wrapper for rainbow mode --- lib/drivers/rgb_backlight.c | 56 +++++++++++++++++-------------------- lib/drivers/rgb_backlight.h | 6 ---- targets/f7/api_symbols.csv | 1 - 3 files changed, 25 insertions(+), 38 deletions(-) diff --git a/lib/drivers/rgb_backlight.c b/lib/drivers/rgb_backlight.c index 1e24997cb7..959c759228 100644 --- a/lib/drivers/rgb_backlight.c +++ b/lib/drivers/rgb_backlight.c @@ -18,8 +18,6 @@ */ #include "rgb_backlight.h" -#include "colors.h" -#include "core/timer.h" #include #include #include @@ -205,35 +203,7 @@ uint8_t rgb_backlight_get_rainbow_saturation() { return rainbow_saturation; } -static void rainbow_timer(void* ctx) { - UNUSED(ctx); - rgb_backlight_rainbow_mode(); -} - -void rgb_backlight_reconfigure(bool enabled) { - if(!rgb_state.settings_loaded) return; - furi_check(furi_mutex_acquire(rgb_state.mutex, FuriWaitForever) == FuriStatusOk); - - rgb_state.enabled = enabled; - if(rgb_state.enabled && rgb_settings.rainbow_mode != RGBBacklightRainbowModeOff) { - if(rgb_state.rainbow_timer == NULL) { - rgb_state.rainbow_timer = furi_timer_alloc(rainbow_timer, FuriTimerTypePeriodic, NULL); - } else { - furi_timer_stop(rgb_state.rainbow_timer); - } - furi_timer_start(rgb_state.rainbow_timer, rgb_settings.rainbow_interval); - } else if(rgb_state.rainbow_timer != NULL) { - furi_timer_stop(rgb_state.rainbow_timer); - furi_timer_free(rgb_state.rainbow_timer); - rgb_state.rainbow_timer = NULL; - } - rgb_state.rainbow_hsv.s = rgb_settings.rainbow_saturation; - rgb_backlight_update(rgb_state.last_brightness, true); - - furi_check(furi_mutex_release(rgb_state.mutex) == FuriStatusOk); -} - -void rgb_backlight_rainbow_mode() { +void rainbow_timer(void* ctx) { if(!rgb_state.settings_loaded) return; furi_check(furi_mutex_acquire(rgb_state.mutex, FuriWaitForever) == FuriStatusOk); @@ -276,6 +246,30 @@ void rgb_backlight_rainbow_mode() { if(rgb_state.enabled && rgb_settings.rainbow_mode == RGBBacklightRainbowModeOff) SK6805_update(); + furi_check(furi_mutex_release(rgb_state.mutex) == FuriStatusOk); + UNUSED(ctx); +} + +void rgb_backlight_reconfigure(bool enabled) { + if(!rgb_state.settings_loaded) return; + furi_check(furi_mutex_acquire(rgb_state.mutex, FuriWaitForever) == FuriStatusOk); + + rgb_state.enabled = enabled; + if(rgb_state.enabled && rgb_settings.rainbow_mode != RGBBacklightRainbowModeOff) { + if(rgb_state.rainbow_timer == NULL) { + rgb_state.rainbow_timer = furi_timer_alloc(rainbow_timer, FuriTimerTypePeriodic, NULL); + } else { + furi_timer_stop(rgb_state.rainbow_timer); + } + furi_timer_start(rgb_state.rainbow_timer, rgb_settings.rainbow_interval); + } else if(rgb_state.rainbow_timer != NULL) { + furi_timer_stop(rgb_state.rainbow_timer); + furi_timer_free(rgb_state.rainbow_timer); + rgb_state.rainbow_timer = NULL; + } + rgb_state.rainbow_hsv.s = rgb_settings.rainbow_saturation; + rgb_backlight_update(rgb_state.last_brightness, true); + furi_check(furi_mutex_release(rgb_state.mutex) == FuriStatusOk); } diff --git a/lib/drivers/rgb_backlight.h b/lib/drivers/rgb_backlight.h index 31de7c4889..e82c25c466 100644 --- a/lib/drivers/rgb_backlight.h +++ b/lib/drivers/rgb_backlight.h @@ -97,12 +97,6 @@ uint8_t rgb_backlight_get_rainbow_saturation(); */ void rgb_backlight_reconfigure(bool enabled); -/** - * @brief Run the RGB rainbowmode - * - */ -void rgb_backlight_rainbow_mode(); - /** * @brief Apply current RGB lighting settings * diff --git a/targets/f7/api_symbols.csv b/targets/f7/api_symbols.csv index f387122d8b..0f538b0dd5 100644 --- a/targets/f7/api_symbols.csv +++ b/targets/f7/api_symbols.csv @@ -2963,7 +2963,6 @@ Function,+,rgb_backlight_get_rainbow_mode,RGBBacklightRainbowMode, Function,+,rgb_backlight_get_rainbow_saturation,uint8_t, Function,+,rgb_backlight_get_rainbow_speed,uint8_t, Function,-,rgb_backlight_load_settings,void,_Bool -Function,-,rgb_backlight_rainbow_mode,void, Function,+,rgb_backlight_reconfigure,void,_Bool Function,+,rgb_backlight_save_settings,void, Function,+,rgb_backlight_set_color,void,"uint8_t, const RgbColor*" From bb2b3a937a1fd4db4d223bfe5cc43e519c7839f0 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Sat, 2 Mar 2024 00:44:50 +0000 Subject: [PATCH 13/35] BLE Spam improvements/fixes + remove orgasmotron --- applications/external | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/external b/applications/external index af7feff6ae..caf103e898 160000 --- a/applications/external +++ b/applications/external @@ -1 +1 @@ -Subproject commit af7feff6ae10cce3c98d4e2021feaf2d337333f3 +Subproject commit caf103e89808a682d24b38d5b0b764d62df76cd5 From 8b11f0c1cd04e815d25030c4706403608196cbc2 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Sat, 2 Mar 2024 21:35:11 +0000 Subject: [PATCH 14/35] Don't need drama in the front page --- ReadMe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ReadMe.md b/ReadMe.md index 8a274d04d6..1a5c0226c6 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -7,7 +7,7 @@ Install | Features | Discord | Donate -This custom firmware is based on the [Official Firmware](https://github.com/flipperdevices/flipperzero-firmware), and includes most of the awesome features from [Unleashed](https://github.com/DarkFlippers/unleashed-firmware). It is a direct continuation of the Xtreme firmware, built by the same (and only) developers who made that project special, until being unfairly thrown out. +This custom firmware is based on the [Official Firmware](https://github.com/flipperdevices/flipperzero-firmware), and includes most of the awesome features from [Unleashed](https://github.com/DarkFlippers/unleashed-firmware). It is a direct continuation of the Xtreme firmware, built by the same (and only) developers who made that project special. -----
From 15341d88f7855012a28e0345b1eaed024b7e58b7 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Sat, 2 Mar 2024 21:35:29 +0000 Subject: [PATCH 15/35] Redo support links --- .github/FUNDING.yml | 2 +- .github/workflow_data/release.md | 12 +----------- ReadMe.md | 14 ++------------ 3 files changed, 4 insertions(+), 24 deletions(-) diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index a9c2e81cc2..6c0847dce7 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,2 +1,2 @@ ko_fi: willyjl -custom: ["https://bunq.me/WillyJL", "https://paypal.me/willyjl1"] +custom: ["https://paypal.me/willyjl1"] diff --git a/.github/workflow_data/release.md b/.github/workflow_data/release.md index 05602a952f..8402dd1083 100644 --- a/.github/workflow_data/release.md +++ b/.github/workflow_data/release.md @@ -8,24 +8,14 @@ **Check the [install guide](https://github.com/Next-Flip/Momentum-Firmware#install) if you're not sure, or [join our Discord](https://discord.gg/momentum) if you have questions or encounter issues!** ## ❤️ Support -If you enjoy the firmware, please consider donating to the team, or spreading the word! :D +If you enjoy the firmware please __**spread the word!**__ And if you really love it, maybe consider donating to the team? :D > **[Ko-fi](https://ko-fi.com/willyjl)**: One-off or Recurring, No signup required -> **[Bank transfer](https://bunq.me/WillyJL)**: One-off, No signup required - > **[PayPal](https://paypal.me/willyjl1)**: One-off, Signup required -> **BCH**: `1EnCi1HF8Jw6m2dWSUwHLbCRbVBCQSyDKm` - -> **ETH**: `0x90b8284c3eba44108427e3148ff8efa0ae7a61a8` - > **BTC**: `1EnCi1HF8Jw6m2dWSUwHLbCRbVBCQSyDKm` -> **SHIB**: `0x90b8284c3eba44108427e3148ff8efa0ae7a61a8` - -> **DOGE**: `DNUdUqtmWaAiJ6yoV6hRNEh6Nn1Tg4Aorr` - **Thank you <3** ## 🚀 Changelog diff --git a/ReadMe.md b/ReadMe.md index 1a5c0226c6..81098f41f4 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -83,7 +83,7 @@ In USB mode it also enables additional functionality to spoof the manufacturer a There are too many to name them all, this is a **non-comprehensive** list of the **most notable from an end-user perspective**. For a more detailed list, you can read through the [**changelogs**](https://github.com/Next-Flip/Momentum-Firmware/releases) and commits/code. Also, you can find a **feature comparison with other firmwares** on [our website](https://momentum-fw.dev/#features). -Note that this repo is always updated with the great work from our friends at [Unleashed](https://github.com/DarkFlippers/unleashed-firmware) and the latest changes from [OFW](https://github.com/flipperdevices/flipperzero-firmware). Below are mentioned only **our** changes that we can actually be credited for, so make sure to check their fantastic additions aswell. And a huge thank you to both teams! +Note that this repo is always updated with the great work from our friends at [Unleashed](https://github.com/DarkFlippers/unleashed-firmware) and the latest changes from [OFW](https://github.com/flipperdevices/flipperzero-firmware). Below are mentioned only **our** changes that we can actually be credited for, so make sure to check their fantastic additions aswell. And a huge thank you to both teams! ```txt [Added] @@ -192,22 +192,12 @@ $ ./fbt launch APPSRC=your_appid ## ❤️ Support -If you enjoy the firmware, please consider donating to the team, or spreading the word! :D +If you enjoy the firmware please __**spread the word!**__ And if you really love it, maybe consider donating to the team? :D > **[Ko-fi](https://ko-fi.com/willyjl)**: One-off or Recurring, No signup required -> **[Bank transfer](https://bunq.me/WillyJL)**: One-off, No signup required - > **[PayPal](https://paypal.me/willyjl1)**: One-off, Signup required -> **BCH**: `1EnCi1HF8Jw6m2dWSUwHLbCRbVBCQSyDKm` - -> **ETH**: `0x90b8284c3eba44108427e3148ff8efa0ae7a61a8` - > **BTC**: `1EnCi1HF8Jw6m2dWSUwHLbCRbVBCQSyDKm` -> **SHIB**: `0x90b8284c3eba44108427e3148ff8efa0ae7a61a8` - -> **DOGE**: `DNUdUqtmWaAiJ6yoV6hRNEh6Nn1Tg4Aorr` - **Thank you <3** From 270d271258d6563394bd09bfb06e1e21bfac632d Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Sun, 3 Mar 2024 03:10:10 +0000 Subject: [PATCH 16/35] Rename passport_DB to passport_128x64 --- applications/settings/dolphin_passport/passport.c | 2 +- .../{passport_DB.png => passport_128x64.png} | Bin documentation/file_formats/AssetPacks.md | 3 +-- targets/f7/api_symbols.csv | 2 +- 4 files changed, 3 insertions(+), 4 deletions(-) rename assets/icons/Passport/{passport_DB.png => passport_128x64.png} (100%) diff --git a/applications/settings/dolphin_passport/passport.c b/applications/settings/dolphin_passport/passport.c index abcc12fa5c..a38b718cdf 100644 --- a/applications/settings/dolphin_passport/passport.c +++ b/applications/settings/dolphin_passport/passport.c @@ -66,7 +66,7 @@ static void render_callback(Canvas* canvas, void* _ctx) { } // multipass - canvas_draw_icon(canvas, 0, 0, &I_passport_DB); + canvas_draw_icon(canvas, 0, 0, &I_passport_128x64); // portrait furi_assert((stats->level > 0) && (stats->level <= DOLPHIN_LEVEL_COUNT + 1)); diff --git a/assets/icons/Passport/passport_DB.png b/assets/icons/Passport/passport_128x64.png similarity index 100% rename from assets/icons/Passport/passport_DB.png rename to assets/icons/Passport/passport_128x64.png diff --git a/documentation/file_formats/AssetPacks.md b/documentation/file_formats/AssetPacks.md index c2827d49db..c4b50133e8 100644 --- a/documentation/file_formats/AssetPacks.md +++ b/documentation/file_formats/AssetPacks.md @@ -93,7 +93,7 @@ SD/ |... |-Passport/ |-passport_happy_46x49.bmx - |-passport_DB.bmx + |-passport_128x64.bmx |... |-RFID/ |-RFIDDolphinReceive_97x61.bmx @@ -107,7 +107,6 @@ Which is the same you can find in the firmware source code, in `assets/icons`. T - The pixel numbers in the filename are ignored, they are there purely because of the original Flipper icon names and for a hint as to how you should size your icons, but they are not enforced. - We kept the original naming scheme and file structure for compatibility, but the original setup is quite bad, so bear with us. Some icons in subfolders (like `SubGhz/Scanning_123x52`) are used in other unrelated apps/places. - Some icons in the official firmware have different versions with different numbers to indicate the flipper level they target. Since our system has so many levels, we decided to keep it simple and remove the level progression from icons. For example `Passport/passport_happy1_46x49` becomes `Passport/passport_happy_46x49` and `Animations/Levelup1_128x64` becomes `Animations/Levelup_128x64`. -- The `Passport/passport_DB` is the background for the passport page, it doesn't mention a pixel size because it should be the same as the Flipper screen size (128x64). This system supports **all** internal assets! diff --git a/targets/f7/api_symbols.csv b/targets/f7/api_symbols.csv index 0f538b0dd5..e4fbdda671 100644 --- a/targets/f7/api_symbols.csv +++ b/targets/f7/api_symbols.csv @@ -3907,7 +3907,7 @@ Variable,+,I_next_text_19x6,Icon, Variable,+,I_off_19x20,Icon, Variable,+,I_off_hover_19x20,Icon, Variable,+,I_off_text_12x5,Icon, -Variable,+,I_passport_DB,Icon, +Variable,+,I_passport_128x64,Icon, Variable,+,I_passport_bad_46x49,Icon, Variable,+,I_passport_happy_46x49,Icon, Variable,+,I_passport_okay_46x49,Icon, From 5d38d888e368e4a119b32b0e8eb4ed6335d0ab65 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Sun, 3 Mar 2024 03:24:34 +0000 Subject: [PATCH 17/35] Passport hide Lvl/Tot text, Tot = 0 to 30, Lvl30 = 9999xp --- .../services/dolphin/helpers/dolphin_state.c | 2 +- .../settings/dolphin_passport/passport.c | 38 +++++++++---------- 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/applications/services/dolphin/helpers/dolphin_state.c b/applications/services/dolphin/helpers/dolphin_state.c index 7dba831296..5010263b79 100644 --- a/applications/services/dolphin/helpers/dolphin_state.c +++ b/applications/services/dolphin/helpers/dolphin_state.c @@ -15,7 +15,7 @@ const uint32_t DOLPHIN_LEVELS[] = {100, 200, 300, 450, 600, 750, 950, 1150, 1350, 1600, 1850, 2100, 2400, 2700, 3000, 3350, 3700, 4050, 4450, 4850, - 5250, 5700, 6150, 6600, 7100, 7600, 8100, 8650, 9200}; + 5250, 5700, 6150, 6600, 7100, 7600, 8100, 8650, 9999}; const size_t DOLPHIN_LEVEL_COUNT = COUNT_OF(DOLPHIN_LEVELS); DolphinState* dolphin_state_alloc() { diff --git a/applications/settings/dolphin_passport/passport.c b/applications/settings/dolphin_passport/passport.c index a38b718cdf..116ae0c003 100644 --- a/applications/settings/dolphin_passport/passport.c +++ b/applications/settings/dolphin_passport/passport.c @@ -33,7 +33,7 @@ static void render_callback(Canvas* canvas, void* _ctx) { PassportContext* ctx = _ctx; DolphinStats* stats = ctx->stats; - char level_str[20]; + char level_str[12]; char xp_str[12]; const char* mood_str = NULL; const Icon* portrait = NULL; @@ -48,21 +48,25 @@ static void render_callback(Canvas* canvas, void* _ctx) { portrait = &I_passport_bad_46x49; mood_str = "Mood: Angry"; } + uint32_t xp_progress = 0; - uint32_t xp_need = dolphin_state_xp_to_levelup(stats->icounter); + uint32_t xp_to_levelup = dolphin_state_xp_to_levelup(stats->icounter); uint32_t xp_above_last_levelup = dolphin_state_xp_above_last_levelup(stats->icounter); - uint32_t xp_levelup = 0; + + uint32_t xp_have = 0; + uint32_t xp_target = 0; if(ctx->progress_total) { - xp_levelup = xp_need + stats->icounter; + xp_have = stats->icounter; + xp_target = DOLPHIN_LEVELS[DOLPHIN_LEVEL_COUNT - 1]; } else { - xp_levelup = xp_need + xp_above_last_levelup; + xp_have = xp_above_last_levelup; + xp_target = xp_to_levelup + xp_above_last_levelup; } - uint32_t xp_have = xp_levelup - xp_need; if(stats->level == DOLPHIN_LEVEL_COUNT + 1) { xp_progress = 0; } else { - xp_progress = xp_need * 64 / xp_levelup; + xp_progress = xp_to_levelup * 64 / xp_target; } // multipass @@ -73,18 +77,16 @@ static void render_callback(Canvas* canvas, void* _ctx) { canvas_draw_icon(canvas, 11, 2, portrait); const char* my_name = furi_hal_version_get_name_ptr(); - snprintf(level_str, 12, "Level: %hu", stats->level); - if(stats->level == DOLPHIN_LEVEL_COUNT + 1) { - snprintf(xp_str, 12, "Max Level!"); - } else { - snprintf(xp_str, 12, "%lu/%lu", xp_have, xp_levelup); - } - canvas_set_font(canvas, FontSecondary); + snprintf(level_str, sizeof(level_str), "Level: %hu", stats->level); canvas_draw_str(canvas, 58, 10, my_name ? my_name : "Unknown"); canvas_draw_str(canvas, 58, 22, mood_str); - canvas_set_color(canvas, ColorBlack); - canvas_draw_str(canvas, 58, 34, level_str); + + if(stats->level == DOLPHIN_LEVEL_COUNT + 1) { + snprintf(xp_str, sizeof(xp_str), "Max Level!"); + } else { + snprintf(xp_str, sizeof(xp_str), "%lu/%lu", xp_have, xp_target); + } canvas_set_font(canvas, FontBatteryPercent); canvas_draw_str(canvas, 58, 42, xp_str); canvas_set_font(canvas, FontSecondary); @@ -92,10 +94,6 @@ static void render_callback(Canvas* canvas, void* _ctx) { canvas_set_color(canvas, ColorWhite); canvas_draw_box(canvas, 123 - xp_progress, 45, xp_progress + (xp_progress > 0), 5); canvas_set_color(canvas, ColorBlack); - - canvas_draw_icon(canvas, 52, 51, &I_Ok_btn_9x9); - canvas_draw_str( - canvas, ctx->progress_total ? 37 : 36, 59, ctx->progress_total ? "Lvl" : "Tot"); } int32_t passport_app(void* p) { From 08afaa6f4a0a07779a7a40f7048c86de8012a93a Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Sun, 3 Mar 2024 03:37:34 +0000 Subject: [PATCH 18/35] New Momentum Asset Pack + Passport by @Kuronons --- assets/icons/Passport/passport_128x64.png | Bin 750 -> 4529 bytes .../Kuronons_CFW_Momentum1_128x64/frame_0.png | Bin 0 -> 3379 bytes .../Kuronons_CFW_Momentum1_128x64/frame_1.png | Bin 0 -> 3406 bytes .../Kuronons_CFW_Momentum1_128x64/frame_10.png | Bin 0 -> 3487 bytes .../Kuronons_CFW_Momentum1_128x64/frame_11.png | Bin 0 -> 3473 bytes .../Kuronons_CFW_Momentum1_128x64/frame_12.png | Bin 0 -> 3452 bytes .../Kuronons_CFW_Momentum1_128x64/frame_13.png | Bin 0 -> 3431 bytes .../Kuronons_CFW_Momentum1_128x64/frame_14.png | Bin 0 -> 3422 bytes .../Kuronons_CFW_Momentum1_128x64/frame_15.png | Bin 0 -> 3406 bytes .../Kuronons_CFW_Momentum1_128x64/frame_16.png | Bin 0 -> 3547 bytes .../Kuronons_CFW_Momentum1_128x64/frame_17.png | Bin 0 -> 3539 bytes .../Kuronons_CFW_Momentum1_128x64/frame_18.png | Bin 0 -> 3513 bytes .../Kuronons_CFW_Momentum1_128x64/frame_19.png | Bin 0 -> 3505 bytes .../Kuronons_CFW_Momentum1_128x64/frame_2.png | Bin 0 -> 3434 bytes .../Kuronons_CFW_Momentum1_128x64/frame_20.png | Bin 0 -> 3470 bytes .../Kuronons_CFW_Momentum1_128x64/frame_21.png | Bin 0 -> 3513 bytes .../Kuronons_CFW_Momentum1_128x64/frame_22.png | Bin 0 -> 3549 bytes .../Kuronons_CFW_Momentum1_128x64/frame_23.png | Bin 0 -> 3559 bytes .../Kuronons_CFW_Momentum1_128x64/frame_24.png | Bin 0 -> 3555 bytes .../Kuronons_CFW_Momentum1_128x64/frame_25.png | Bin 0 -> 3528 bytes .../Kuronons_CFW_Momentum1_128x64/frame_26.png | Bin 0 -> 3557 bytes .../Kuronons_CFW_Momentum1_128x64/frame_27.png | Bin 0 -> 3565 bytes .../Kuronons_CFW_Momentum1_128x64/frame_28.png | Bin 0 -> 3540 bytes .../Kuronons_CFW_Momentum1_128x64/frame_29.png | Bin 0 -> 3506 bytes .../Kuronons_CFW_Momentum1_128x64/frame_3.png | Bin 0 -> 3452 bytes .../Kuronons_CFW_Momentum1_128x64/frame_30.png | Bin 0 -> 3498 bytes .../Kuronons_CFW_Momentum1_128x64/frame_31.png | Bin 0 -> 3505 bytes .../Kuronons_CFW_Momentum1_128x64/frame_32.png | Bin 0 -> 3546 bytes .../Kuronons_CFW_Momentum1_128x64/frame_33.png | Bin 0 -> 3537 bytes .../Kuronons_CFW_Momentum1_128x64/frame_34.png | Bin 0 -> 3507 bytes .../Kuronons_CFW_Momentum1_128x64/frame_35.png | Bin 0 -> 3500 bytes .../Kuronons_CFW_Momentum1_128x64/frame_36.png | Bin 0 -> 3485 bytes .../Kuronons_CFW_Momentum1_128x64/frame_37.png | Bin 0 -> 3466 bytes .../Kuronons_CFW_Momentum1_128x64/frame_38.png | Bin 0 -> 3446 bytes .../Kuronons_CFW_Momentum1_128x64/frame_39.png | Bin 0 -> 3434 bytes .../Kuronons_CFW_Momentum1_128x64/frame_4.png | Bin 0 -> 3460 bytes .../Kuronons_CFW_Momentum1_128x64/frame_40.png | Bin 0 -> 3419 bytes .../Kuronons_CFW_Momentum1_128x64/frame_41.png | Bin 0 -> 3397 bytes .../Kuronons_CFW_Momentum1_128x64/frame_42.png | Bin 0 -> 3325 bytes .../Kuronons_CFW_Momentum1_128x64/frame_5.png | Bin 0 -> 3475 bytes .../Kuronons_CFW_Momentum1_128x64/frame_6.png | Bin 0 -> 3483 bytes .../Kuronons_CFW_Momentum1_128x64/frame_7.png | Bin 0 -> 3496 bytes .../Kuronons_CFW_Momentum1_128x64/frame_8.png | Bin 0 -> 3518 bytes .../Kuronons_CFW_Momentum1_128x64/frame_9.png | Bin 0 -> 3485 bytes .../Kuronons_CFW_Momentum1_128x64/meta.txt | 14 ++++++++++++++ .../Kuronons_CFW_Momentum2_128x64/frame_0.png | Bin 0 -> 3379 bytes .../Kuronons_CFW_Momentum2_128x64/frame_1.png | Bin 0 -> 3406 bytes .../Kuronons_CFW_Momentum2_128x64/frame_10.png | Bin 0 -> 3487 bytes .../Kuronons_CFW_Momentum2_128x64/frame_11.png | Bin 0 -> 3473 bytes .../Kuronons_CFW_Momentum2_128x64/frame_12.png | Bin 0 -> 3452 bytes .../Kuronons_CFW_Momentum2_128x64/frame_13.png | Bin 0 -> 3431 bytes .../Kuronons_CFW_Momentum2_128x64/frame_14.png | Bin 0 -> 3422 bytes .../Kuronons_CFW_Momentum2_128x64/frame_15.png | Bin 0 -> 3406 bytes .../Kuronons_CFW_Momentum2_128x64/frame_16.png | Bin 0 -> 3551 bytes .../Kuronons_CFW_Momentum2_128x64/frame_17.png | Bin 0 -> 3546 bytes .../Kuronons_CFW_Momentum2_128x64/frame_18.png | Bin 0 -> 3552 bytes .../Kuronons_CFW_Momentum2_128x64/frame_19.png | Bin 0 -> 3513 bytes .../Kuronons_CFW_Momentum2_128x64/frame_2.png | Bin 0 -> 3434 bytes .../Kuronons_CFW_Momentum2_128x64/frame_20.png | Bin 0 -> 3546 bytes .../Kuronons_CFW_Momentum2_128x64/frame_21.png | Bin 0 -> 3545 bytes .../Kuronons_CFW_Momentum2_128x64/frame_22.png | Bin 0 -> 3555 bytes .../Kuronons_CFW_Momentum2_128x64/frame_23.png | Bin 0 -> 3536 bytes .../Kuronons_CFW_Momentum2_128x64/frame_24.png | Bin 0 -> 3563 bytes .../Kuronons_CFW_Momentum2_128x64/frame_25.png | Bin 0 -> 3547 bytes .../Kuronons_CFW_Momentum2_128x64/frame_26.png | Bin 0 -> 3567 bytes .../Kuronons_CFW_Momentum2_128x64/frame_27.png | Bin 0 -> 3531 bytes .../Kuronons_CFW_Momentum2_128x64/frame_28.png | Bin 0 -> 3552 bytes .../Kuronons_CFW_Momentum2_128x64/frame_29.png | Bin 0 -> 3547 bytes .../Kuronons_CFW_Momentum2_128x64/frame_3.png | Bin 0 -> 3452 bytes .../Kuronons_CFW_Momentum2_128x64/frame_30.png | Bin 0 -> 3567 bytes .../Kuronons_CFW_Momentum2_128x64/frame_31.png | Bin 0 -> 3409 bytes .../Kuronons_CFW_Momentum2_128x64/frame_32.png | Bin 0 -> 3247 bytes .../Kuronons_CFW_Momentum2_128x64/frame_33.png | Bin 0 -> 3345 bytes .../Kuronons_CFW_Momentum2_128x64/frame_34.png | Bin 0 -> 3397 bytes .../Kuronons_CFW_Momentum2_128x64/frame_4.png | Bin 0 -> 3460 bytes .../Kuronons_CFW_Momentum2_128x64/frame_5.png | Bin 0 -> 3475 bytes .../Kuronons_CFW_Momentum2_128x64/frame_6.png | Bin 0 -> 3483 bytes .../Kuronons_CFW_Momentum2_128x64/frame_7.png | Bin 0 -> 3496 bytes .../Kuronons_CFW_Momentum2_128x64/frame_8.png | Bin 0 -> 3518 bytes .../Kuronons_CFW_Momentum2_128x64/frame_9.png | Bin 0 -> 3485 bytes .../Kuronons_CFW_Momentum2_128x64/meta.txt | 15 +++++++++++++++ assets/packs/Momentum/Anims/manifest.txt | 16 ++++++++++++++++ assets/packs/ReadMe.md | 15 +++++++++++---- 83 files changed, 56 insertions(+), 4 deletions(-) create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_0.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_1.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_10.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_11.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_12.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_13.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_14.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_15.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_16.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_17.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_18.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_19.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_2.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_20.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_21.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_22.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_23.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_24.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_25.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_26.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_27.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_28.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_29.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_3.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_30.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_31.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_32.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_33.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_34.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_35.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_36.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_37.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_38.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_39.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_4.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_40.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_41.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_42.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_5.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_6.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_7.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_8.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_9.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/meta.txt create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_0.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_1.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_10.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_11.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_12.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_13.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_14.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_15.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_16.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_17.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_18.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_19.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_2.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_20.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_21.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_22.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_23.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_24.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_25.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_26.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_27.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_28.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_29.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_3.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_30.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_31.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_32.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_33.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_34.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_4.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_5.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_6.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_7.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_8.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_9.png create mode 100644 assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/meta.txt create mode 100644 assets/packs/Momentum/Anims/manifest.txt diff --git a/assets/icons/Passport/passport_128x64.png b/assets/icons/Passport/passport_128x64.png index 69b2ac9ad4568b6f1cdc9d38f2bedb6e5d71de6d..16a3f557ec690ed751b765008617173a01076ab0 100644 GIT binary patch literal 4529 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 literal 0 HcmV?d00001 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_1.png b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_1.png new file mode 100644 index 0000000000000000000000000000000000000000..8a9791cae1a25996929be157ae465fc94c3f5e7b GIT binary patch literal 3406 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 Vzjn{cF8?o7eeK-n)>+N>{srXki=hAj literal 0 HcmV?d00001 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_11.png b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_11.png new file mode 100644 index 0000000000000000000000000000000000000000..00f572b44a1384c7936d7c276b4cfaec815dedf7 GIT binary patch literal 3473 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 literal 0 HcmV?d00001 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_13.png b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_13.png new file mode 100644 index 0000000000000000000000000000000000000000..11773d46e85810b7cfaf3fb26a61f6fa2cf8722c GIT binary patch literal 3431 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 literal 0 HcmV?d00001 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_16.png b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_16.png new file mode 100644 index 0000000000000000000000000000000000000000..3513072a0525cadebb26a351b97783465e0cf2de GIT binary patch literal 3547 zcmcgvdu$ZP8DC?CQXU~`DKSYKZ`PFpG;=%qe&E9xAH?V692Yyns6k?OckaC6Zg<&T z+s7lRW2K4uP=zA;4-ia*N~=V)w57sTN@B$kYEeW>m8fYzH8e^apeR%!;MlZu_U?Qf zt&OepvAW%zo%zl8n&0=$+&9}=A6_u`-nkS-El4&e){%D~xmV4ZMV=dve6W9p<*pre-k>E9v^YP6Xs|i0FJS>jZi}&J^V8q#bp$ z3|)YPo8wGlq>%1Rwb4zkk7+pufeE2ND_V?`MTu7)qIt+emLoq2aEdOfy1>(=iy_*4 zE3L0ftS#vxUvZ`@3_YD?dwY9hy+X|OGc2cR8Vh-r=K(>0V5<|NJaB@#2?+@tn7-|W zw(HQ5L}a+#VVohB7G21BWwB0B3KIz!n@1kY#bD%80ce?JoY(DV3(75%#aW!gP8bj@ zSH_YkrBY@1q+)ZqGCBy?^bm_mzDy4eZtv`yGX^L&h> zm#()R%k2%8MUIyy-~Ma5^V^1#&usMQDmp(?TJt1PcIi9X!-I zUWf86VArzKTc?Furk-~F93l&6=THW-o|7qPOQrOr6NJbyaWWBSh^aB#wsaxQ$rwr^ z;7m>hXLI71!0J0(? zfGi0C3}xO*TbydB!i2QPe4C^=%2rB^tg?ti5o6ipECYy&N<{FY1&~5Mp@tPhLxKpg z#?UwQHn~~XPq`L}IguZ&wob$oQ&E&(afT~(c1Bdqb{9Jp9+HbBI=M>Y8>Sh*IsCX| zlMwR^9q~mk=x-;bix?nFk|34(+w45fb|!2RwV-GSuT~Cis2GyPs5BH(RByHeLb|P` zV$+Vdlv-JvE@Y*S%%TrwL{DrnrEYtY6`olvi(-4bFp1V}Xj_B@ZaVBmK5opA5Ko&H z>{P}FsOR>ks}gT%szK_3?K=LnwGS*s9Jc!^-9wVNyLe|04tK{)0kcg ztJ#H|3?{n}%Y1rg3=Ja96cvCai3gfQoI%hqfQBrn!idun;l{tO!=x4Af9#CuIz8C0 zAeM)GM0Qf_2XQ9tyEz(pUe-1X>BaUqR%wGOXCxiE^v(J+Wza0_+Z7zB)KWHq{x9mA zmT@yHhyV9QVxtp6u?(>PS|N(xiDD$zMr%{pdG*O^!Av_NGebi zg$JS`5;AL~g$+Y91Ql_TTwru0&HYcSeZ-+Mz4VDqqmgW9QK<|{HD)!+l&j6k$@eHx z<28|#4`2$K1!Pl{fT5})z!r}s)fA8-nDvE#XYFZaA-+Vye5*%vKlA8ECt&CC zSARplGJoHb&pmzWo;}A-{CYnW-kke`*FSlTs#$XQ_4dx>o97l%<0mt-4}NUiV~xGq zayRux@V&YNZ(YAoTQ&MMojf;i;@O`(^~8ZAkBlxn_1jt1&u>z$rBnwd-^ecdsG4egXZMOV zE$BV^Z{sWO`W7Bfo;`YJ-wJAHl{IwjJ5`s4sUSEv6%C7b7 z8!e-`Eeu_rl}L)r%JO(2_-0m+#09 z4w&A?rooZnp&JA9&Wzx;`_kL@Y%<drZw@S)tmbN32DW&00000 literal 0 HcmV?d00001 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_17.png b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_17.png new file mode 100644 index 0000000000000000000000000000000000000000..ecb5d775ae9feb83aab747cee63dbeb07b74a6b3 GIT binary patch literal 3539 zcmcgv4U81k9iKY{PdF=uYG@ncFd{|d?RS~Y?dTASA6ik37Q3pP<2!5p+rYCo(^%~=&J{m*`}w0GRa zeoS^}XWsk0|JVEffB(04bZuCB_3Y2grYP#_&W=Pk{1)N6s;Lp~{fFLK3O`rnIyMCq zHD`YGZJ-`_Z~;6#?)3D9eaZEP&a_4f>Aqwa-RAj(R$?5oI8LNhJ;p1NEU3$AffG2EhmVYS)sQqp6zIyufHvPw z8QqEYiY|DIGXr6mGgvmC&&Tp&%=6PMuj@L?39KL>K%ijQ4RHav!3|Xj2@+VolM5Zs zr6Y;h^ajH?1D2Lu$mVKd-JlXC2pC(yIhK!ckxM0@ZPjqOK|fPcZd)wLkSuY-0I+-w z3sFiYYw!uhX0tVP5Uv>liz>cNhz@#&bA;_Cfj8(|WX%w0yrF7X5O$M`p_#^VfY%o1 z2E5P<2E0jvP@BFa6rq!vL}4^@36vC^Nube84Vp9Be1b#I@A14$HFvtIw$XwRnH~A+86Dh~s+%&fq0O zkS+mxwv!s35^7sU%JZ`rHqOc7G+}dYx}+_cG&{2-oj#4+82BWN*rhErAAiSAW3n9SE_& z&{4h^CH)(Ly1)QMmPNTT-sKcXrZ3?@)Pk}hf>uAZscuSyi}OSK50!uh^H(Ib~57w zJal=}HCeEA&EycLY6{{cNrU9%O(ct|mXh_9q}inEdcEnTB7zDMIfGNGMf7n@uY}ba zz;2pA7h;)@?~Ev!k}L~65@b<9x+19vY9)n4RW@zi#HL_Dn*RGfOvniTV`nVS9U^{R zV&$-pp_39nh%+hQ%hEWP%Q#l4yx1Yvt~97xMbe>1U*w-jgJu)osmp+nQOQ#VBo^RfbLSGLCcPuV`op;~$w)uz!3?JT0opu#b$ak|DfD<|$zk}l{H z&&brKLNRxP5;Wb|2 zi7;JRimB?Vsagn#jYkAWomdi8q?t0-Qwj%G+jX)^7M9&*FCUi@vhKJEPL+n>3>!Vx z4$tsXJAM-v*v^N;^=N}TLQxH`b|zYT3U9pq;HkTha?Oc%FSNY5qwPs$>-JBx%k_7Q z`7hnP{TKDY&U+e;eD>&jkDmKmL$Hl3SZU^N9%1*sw@m%o5AWyWXNUg!!6&J2Hus(Fd}{IDv)2?qV0Q_RFW>jr$bs%FsQ%#E zvJPFHWYulus6y5V#ae}L|8iYnEdRMr{9xYGOIn{< zvhMx#vKPMf-LYnR?dsQ-Hn)Exu{NOI-}TCl8O2u*-u&==3^(_=<0Jd}Sa1E?51mY> zzf#=2@QLx~_aA%yp{-B-`REI;Z#sTe`=Tc5^RxC+*L>7M{r$<`KJvt((C{02|mA}=U>`K9leXNFs^Pd1K?wcVONw&<>% b)R|x1d;W_zJ+LJD+ts;dL*nVxn{WLm=#{2v literal 0 HcmV?d00001 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_18.png b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_18.png new file mode 100644 index 0000000000000000000000000000000000000000..f6f4d1ec8874f61fbb9d0d6204327f956dec0ac6 GIT binary patch literal 3513 zcmcIndu$xV8Q*h)3B;jE5XC$iHk+j7HMg_xM|}<#U%&<~u^eL@@tobA^DVi%U3S;L zbJ9>JAW#626a;BpNCN_if*?UW0+`r{@`!i`2}Gf&w6ugaYVuE;#7c`hd#_xm9a}tB zzPs6(-+Zt6zTY?A(7x=FStp-)GDT6d+FBDGZENp9;(pQ2`- z8h#?w;Qftc@TlF{9dsuz*G(rIMV4dWXd&woG(|NnF1W~Cg#+5aJ$5d}92gp5XxoZ0 zS4v5kbX#!RZe8u+6|0wZnyXitn#C+`rke^n5s<|Jq6^tf&esburYKh@<8Yc~=prOo z6=UL|Lb^NIPPaH7rsXIECWHd5Xi-iUC0@CZ<{=MRj{Hf0Q*=?)1)eTH4AJIUDZL|c zaak96i!tdSaCMf==kw9L5OusBmeVwig*?mifFOY1p9@d{HDwaek znXJOc6`Rdg(SESBk62XpZCte9+3#Yu1N%;|XX2%OMB{>rVSdnokA`Ln+X=k7*-blv z2#PCKQ34nm}Q=atss~>`ypmZqI;;6@~Q`W4Q8UcbKY~-qNJPL-LS9Cr^2ON~#as>EBGYCr%LRR&NLRbUvL0VF|DQ<9bvRSQ>KuQk0`M4YG#P=|7*h`x>K<*=G* zln=>+ou#HYKEi& zMN#-LqYa>GWP}YvGXxcJl1$jHWR3G(**?snYI^CFrV%IYETl@m%rQ$)PnB(&$L~?1 z#%m&>4`2$K1!Pl{fT5})z@*hlswp5vFq?`2&)Ad7LYRYC;D7>2_axy+0ZoD`P({+} zIF*w*%uiL8Y$%#yC?+7p#sQ2-&m$b60M(F?mXaZ{+NzONw6NqZd;GW*ku}#%;#6^p z++o9E_3}(!s@HFvBW&l9%QfD3Ll;FwcD5zrorO>SdH-8;U!fb8j*k8IqX)id-Tj;A zPT3nh`-#(DUsJcJ@#pnRX3W23cK9{#@y&}a{AAynFSb1T*P$~GZ%XfI7U%qJaLE}X z&3k__@4x57Z%xi`y@`78;ElgLoof8o;f@G3?VUM$KUlPO*5Um#KHa>3=XLP4`_PU% z*FF#zXKh`3+d6pq9Z$cxG5+Q5*~<@W>d5o~Sl3mUyXDohzos^gjK00??u#}IZ@+a0 z)%U~|P5T}{HS*O}%C2GcPxLR_MF&o=1Yaq=>u~qZuHU%K4brU-LuV4 zjr!B4EpP0);U_^uL*4KHa__1=g^j~AsdolPUl`kV&U<@SYoMm1nF|}m=a*m8p4qj1;m&st{_f71@cou&uRZI<$3`Df^9_fb zO&k7^#y>lSx~zUHweiOfe}2>7^*?+#Xa6Di{+Pe+$WYh5(IaS>f6eyD$DiK3Zs?J#Z(n!hgxKKp;Xk#kU-SBd^L9nt^r8Ou1_u_0|6H{#U6y!q I$@T012e0^=XaE2J literal 0 HcmV?d00001 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_19.png b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_19.png new file mode 100644 index 0000000000000000000000000000000000000000..b40979730065be3886d3a2e0ad2f160283171e8c GIT binary patch literal 3505 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 E2TeSG)Bpeg literal 0 HcmV?d00001 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_20.png b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_20.png new file mode 100644 index 0000000000000000000000000000000000000000..c90df5a9cb7edcd7aff756534d1ea2e126d25e21 GIT binary patch literal 3470 zcmcgv4U81k9iN4^IpDa8wHB~xh5;LDc{|@bAKr2vw+DC8y}Q6x@1z#q%)Ggq-0sXc zGk3d31rJ5>G--_=DYXQ&2@R`8Y}(e7Gq(+!n#HuOrCUon2q=&U)1^Y*4fRr*Da+O2IUZ&i zx(tbi(@cA;knYd+(H&ku=v0zJCdY}iq9ys1Bn!$KTHpkZ<>4bEUeP607X`X{F`zB5 zY<**9eN`8{rJ129@^zLi7K_QEnDl}{me(|m=L+;C-0LWYE9;P{c_ zxpXWM8{SBiX28;l3kAO})(xv+f`G9l?6Z85i(M)MEwhgEM}mA=xn;5>PYT41LcsEM zEJP`rt;44kTPW1gVbnPa7FB(l79Hlse8O%dp*Iqkq;nKBuB;grMjOec(9B^u!0U_s zAusa6A#a8t)Tb{CMda8sD2!(=gOZXn12mqgLw&s?AUN`Zoag0hxzks(jTVF?Pp`hs zaV@VHek*pox`1SGMA8f-l7u(`2}({7b&=P3@!K4)b6f?Qh19fggd4#k;`kh|>7sfW z(z6_U?8-RH)NL;)VAwLJfCmZdyMtvt*{t5}h7op6(w#{&U}Vy9EL{{O( zrb;rx5-%ZBHZ)FF)D$tq+WL%Vj>PE{udh^=<(VL(z7INYs4}l9Jd#b(L?A~+SS2YW z@R&0sQPeEOu1V_+94Ky_ZW3!V0`{8c_@lixNjPhQ6e? z!^?X?*0UhmU~Rn5I*12Taa>txhOZ9x$4QzWsSGLt2N#q$T-Eu3S>`WIf5&wo!~#Rd znWC5VZvxT+15&aq%GL2cr$qAo83&>kRtyo;#;JjZsgx9xLb*8gE+>R^8>`aHCUR%> zDeutbdepI5@xhD}lUPi3*qLUB=N8L~*y0d@Xk8&;E3nYBqaqGS`yhmP)`DPXGCstk zS2kUh1xr&64sno(h?5|l41+h2EGnukYqq3Xq~>~~>6P-4bdl4!RIP$Oi|N&{nnTzf zB+!3Y=CeB^tD>wLkjbV5e1M@GkZQ>U*@_`bDa{f^8Pe&~`|xQl_&cGL6#`&C$qkkFOeKu#@D6cak(glYlso z35^J)Oz3rns!E7h0+Cfy#ENLPmII!5W|f5r&k>PF3dg|>OE%JEPDQH3TPa@UQ#=vo zDl26unqnv>0!rf%!N3u~4hm8Y8EbZm1FNkDS!D|=?y^^oOBva4#000xLvU`5AL|EZ zc&Q(`i3>azz=8Us^KafoQHed>nf6@iu72ZC z@9AYHsF(iD6;D(C*}VIYuaCdTFD>1E?CGVY@BQi3Rg>EnFW9$ixAAUb$2$|p@8J$l Q#s8SPJ9{#R)@{A#Ki?#W;{X5v literal 0 HcmV?d00001 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_21.png b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_21.png new file mode 100644 index 0000000000000000000000000000000000000000..b933c04c3765ceacf16c799096e21ecc7ca140ca GIT binary patch literal 3513 zcmcIn4Q$-x8Fsp=>wu=v!IEwbb6sGd;`9G+b4}7*)1>9nEWNI&N?AVJpA(Zi+q0eA zrIV_tY=U-ZKiV|$C#8UdD*je!z`Av9fdUn5Y>XkM4cHjnSQUveAX?i>J~BseL>hR=anscM2aiys zW2LDrQkKp7op{*k-VxwUJ9=~GjuBI{sJ7K)Ye@$I1sox=RLHxbUP@DmTpga{VTK|T zNHmhBI%0+7K(>$U^a4!EDV8=_Rv;BE#mSsrn%d-pzABpA^T~u{}Co2~P+5*eg z`!ih?UGSEshNH;W8Kzh)riwz!3x*g@(=>+V8J?#BL5JgRgi5plKXN>m zj3pw&8;#NwSXy?W;Mc^uVI@ouFs6ijhD))rO9{|2YdC*2$S2Azlfijhz-|-*maAbQ zO4)1;KCRe7p@t5lwPRpW#kXnEVQ$>VOg|32(ZIxO$3WwXs$pT&kI#o@4$A>vTkH>e zkrxhoGX$YFeL*N9$DTo9JaYjQmz)`(@k|Zs>zx5ckr(7VFJH}_zN&2`&!;%@`Yn!Y zdByOC*zw8&oIw#zQ;5pqr3lSxxxYRYjeT`?5JM%bnmWGS>Q ziZ*Q+l1j^>D%+|mh&Inv*JnI)G)}5`eYw6Y&jcB@-Ox>eRV~4gX~DJy8Y!YmBMn)! zim_qHyozm3txDS%I8fp!UoSPb$^wZZ#E*p3>sb(Ufg z;crx)@(!6)rH;(94`!U6*rF=K&NMqbw^)|N7KbrJ>mq4ehJ~IT6;XgYh9JbVmIX7D z@gW+!xaq3ITbgRHG^?mG&5DpthQS%MBq*vaX|||ZxaxYn=}8fBqAsvHD_4u?lbBu! zt2vC^Aq-uJp+31Yf}t3)A;w88o3v$$60K=)V--%)SXPo`b!KNi&Itc!XH3r>!$DnQ z`6xipNpTRSDLe2AB=Y^dV%i@^u)VDyQHz^} zq9{Bq#<{I&@C0118G?#9Na?sdV`<+1%Jy*%)zV9^HjNHwXE9ZV6^>bhhH7lHdiowE zYP==_ebA<$S+pG2p`ofGjV&Haswp5vFk6#==bc$)AoR~ zr*blf`MJuH4Ml_WGie|;j>ZUjo*@bftr`;2Y?%eCtvXqWg=Ke{i^nBF)*Uy&sbmPw zu<>K<@C+}t<2QDJ?E*MlFK^8;1kv!bo=ius^r!dk`(5L0}UGdZ@cp7 z&lhiaH}_7Od}8d!yDnd|aQV03c7I{>x@RAF^6*zq?p||v@v7C=EO~VD7gwC^{dVil z?H}DddAjqJryshZdyLrhk7MUH6NBGBzF|IbnYixG4NYg3o%+k=PZi(VILSUQ9NqiI znb8G5MW@~>HZMG5eDL_I&Em49?=-&r!be+(g)8>ne(Z{#HxITEe_MG(xMP0b1MeSN zK5t_4$W_1ka4JLWn7Zx{O=ja&#HB6c2Q-2hY+E%*Oni?R706zaAM9`LBH9lGhaP!hr1P71Q+vYiq|YAT z_ua28=^#$<`y>CD+5P63-~MpxqQCBJ{LHzwrUOTAee&vtzAwDCeX@CJhIo7DJ*!;e zKwH5*xoqN))?C{5(u2*VufOv8HK)$CEcvC-`1cc^J-xE4<(b~!d>H?^>RH>Hd3?>_ GuKxhrD3O%_ literal 0 HcmV?d00001 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_22.png b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_22.png new file mode 100644 index 0000000000000000000000000000000000000000..5668abc9af72d8d58fd776b10677a5d3092e4500 GIT binary patch literal 3549 zcmcIn4U81k9UnM84m|?YHZ3Jh#=#GazMbz+Sn#+7IpV_g*z=ACt8eDLy`8W-GtA80 z?p?Lv0HGL5DkZ6$RI3KPmIPW$fARa&s|=TocC%Igg+zYTkl^2d&jOq)pszJ8|axfma#Y zMscQ9PI5`F0cY$b-9BE?y)0#QueNl=ESOKvD;PvT4u_B~Gwqz6C;QE+WVjQqIPNY>m#w(I6sCUr@pxTup@RQ7FHbdc)uFx!j+x5KyaqE4c5_K;yg*o?1+W(?B_yfWF# zxS<KP3_hN0`HTsJ$EJ558j(Si`;={c>o zgWP;@N91^U0#3jX#~G4H65s?Ns3}1-MBd=VJ2~FqxDqr;QWL=tR)a;r@hO2|ctcRG z0lUafcZ~`~mXUV-93%^8=U_W#J*T~>EtxbLogjpcg&PxbhL{?&ZDd%YW@@UX0gN>S zOi2=ft}1DeMm*+3#F3JKL-P}^)e$9CG{00|$hC-!%4!(Ml69y`JP^b*4>Tk}UMOKB59G$d`gZ<7*-*=nhgRftHGFjg!cnLtuC2%sP#09EqJ=~y*&C`ugG8TzW; z1~=>aNf(iriwqsDwn4-bQ(;tJafUBTru=lMo9G z9p#Hr)W3pI7coGQWl=8oH`xW8ZA;iBYC*{mL8~5GSv90c5j7M`)L3E%BC_OQWX{p;DW`)NV%hLRO29s!ACv8ixz)gpF=;Qi!65>(If*r~D z0CryAbWIkJu9+O*R80Y#Bx%4jc@xN@s-rxW{CiRD2b zlARR$L7YkZZjOeYm$j{8d9j@iDsNDgiljrAzREu%1`T1~uF8RGEfo{!uTbBp88)DQb|H6~cBUYux{p?V}v3q?a+YY1EVLETYPw%rOgLdxdT055GrA zx}Zy>@_;4k2q=~$15?u^fRTV@%@Uz1TJwql&)TEPf|%#9$ODz*$PG$qpv#;FG>JzF zuki|xg|W&~OjTD+)dGarcz_|<^Gr!pfo953Pb(a;8db?ET3B+Iy?$JZ$g1NeajMuw z&ahFla(E^$mE$*d2;2GOa6RY5ZHp*s+eG|E(BE5cAOE8j>h~Vls;8)Ic>2S?lCP7&cgNLG4^3HnCV1lbPiIoweqhd?d-`7+ z>YF~zv16LaQn3G&ClO-@wulau1SCJ>F+*YKYP-iOV5eZdnSI3 zI(uUI?wUhyTwL|17Y9zAe(7BAp9dBmd#i7YvigU=Y zEj9SF6OAnmFYSTTuY5FqFn{($E46CYncd4DtGkanb@15F6>5Nea@YMeziwUMvv23T tM|%b*zS2A4;FW1p-k-Tix;*ip@BZZYr9V6yi$1^_7cEQdUijd;{{RSUx;Fp- literal 0 HcmV?d00001 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_23.png b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_23.png new file mode 100644 index 0000000000000000000000000000000000000000..bee87ec12f7271246b19cc7413edd8b230b70301 GIT binary patch literal 3559 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 literal 0 HcmV?d00001 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_25.png b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_25.png new file mode 100644 index 0000000000000000000000000000000000000000..9eaa9277aa9a21869b11f47f7679191c4be60ccf GIT binary patch literal 3528 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 Ad;kCd literal 0 HcmV?d00001 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_27.png b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_27.png new file mode 100644 index 0000000000000000000000000000000000000000..0c8eff3133471bf9a872e68cb612b6d69275da41 GIT binary patch literal 3565 zcmcImdvFz38Q(C%1Sm}js2%!RHp3LE=kEJiZXx7ClMWYX5+$*%_UxW>Z+7lux4WC% zn@}-C>)5d^?F>|kDA2K{j!Z{u{i9ZFa4L!qs!2+{Qi6Ziy-eeRU{;^Z+W&G*iN1f zB|_8b4dM*3wB$n0t%}Y2ze2fcSih#(f;@n;@8!1N?i?cX~^MOyWd=*Qg zluTCPlZwsds%Sr0+ea)a`!*@s@9cLm+m3yw*R$~2KBBRyVwfManICBLQ7wsva;Y=0k8Z91%f#Y>LPPURen<}=^f)L~B<(ut1 zati*6(DCvDoPYt2GbE8DzzIN5I|b1Yd4m@}!|?{km7qzIng|B47Ayje?-U3|F?jU~ zu!HPW|FlqK87arhL9%gn4yG~d=F^e3WYTEM`vJ^bxGfQ9h^aB#Muw_uye6tDP&mm1 z8j=)XB2fV;0b^4$H3&7WvOeKhyr3^89E-@P?uMa?DIH280=g<`z(VAvajFPX zqHKzmu9}=ARHSY6Y*OMdTProR3K5AC#)`!w6G*BC0Td(zph`YD9jm4eMTx^YLtob0 z;$$5!=^zqwk)gxgHi&p)Dh%r@&hX{It}s=zy`@1_;K)S^om}Pl?rG*PPk%0NlMoYU z!hA6z{T+n5hyjW$i*k8Bwu7pjZ=9df+NHn7*(NuTMlp=-H5S6IWYWpPV`paa~ zfgdQpWoYEB1oNF#P=Fq8PLmK%TNdn8 z#{01E>ZWV5fOO5|0HnTY?xZ--P=}{5!k|A=Wjw(g;QA{s~ z)#`!yG$vh$Wj?wyij{&X33DK&su*aBqyiI4I?yDw0oU6TW~TB;_{AEUl$ zGj3*d_}|4cDQ$mzo5Y4Egc1#~A7+TsccK)@b>ZGbo!6L*3uc;wq!k;4+oxgsluGi~ zlr^BLssJRDG!R`UZ`d?-Q`8_YD}?Pz);Rww+lM(+O)sO;G@3~}3#rmCbIcl;uCmP? zllLe|7j%ix2e3pP0mYJJU}~BKFcPq=St3+LYh@JhtUawPhKy3CQL zC-F$(HD2MdFjHBIsgee%T7VE64=^M>&y++JXr>JHl)@3KQH`v~!jik})#DN&YmS@5 zsc49tVZ+zz;hB6?kKZ^?*v=z|>w|{}k5E+IKid+`oy8OH>^bz(4tY7xsh9+P(|For*&Sj!ge0VE@=RUdbZ1<`8TZX`?Z+(4xs?7siO zdt;a0o|yG1>6yf_*{zQ@jBlJfI7j~ZX#L=vg-zyJ^L*XJtwR@9jK6im85c>rPHa8U ztSmU!f9F@Xu{RIwyrKDbJNZ#JGdhtNJT!0D5eqdQ9BUeR|HzgFeT~m9J^zzsL)6A! z-FDZ5y-!o`{waC#*T=thPv+0{7>ID2?cMdH)xqTpU``^&ZZ!{c@-}0Tiue+z` zVd}!@@SfGnkEYM8A3FSpzb@SO`%B$*k5Lbud3Bzf{m~!E$A-nyOD}XQho9U!u=sm_ zubZ>t#}{vHXifiebK?&_@$J{@j}CqD#rh?~`&WIMK5nf&)v;x6LC8Jz%G;_*tXzHW zok!lfeM$Y}TTkECzJuHQ+a1Hj{juK^gn>)3YuDg=7rom5$nz)n`S%u*59Bl6yW8)+ zDSlw=nKfVDzwP=rhwoYhzmnN|V0Zn6jP#8+UL5@Q@YDagsqXoX>vsKRJ~fUa@={ob+12c7%>9ByOV+6{^4*4#hz E9}T>@QUCw| literal 0 HcmV?d00001 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_28.png b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_28.png new file mode 100644 index 0000000000000000000000000000000000000000..0528366e00fd6b410f6574390ebd0e02323b71cc GIT binary patch literal 3540 zcmcIn4R9P)9pAJDLTXEf`jNH{uG^6h>$`pX{n1=%nrqDo*JP4l6NX~m?!LXOy}Lbj zH@R!D%^4X10cD_Cbr7h|Xcg?V11OQHNu^Of9H+tn4#YWUWJa)GIu+vRr1;UvTR4c zPf;sYhu=EtyAL#zhXYP;U(lDhUN_xz1X-?uBl&ceped?lQ$CB#oj9NkoOCi#=FC$Q z4DDD^X1kPtiEKL_bUH>n+%vMR*BsetY8JDpm2S!FL_it`h|Z@|8DGywnUY+cJcq+9 zLzf`I&M4CsDx~`oU39zaVOowrU_vO+iWcEyQR0&xM%aM-+I7Js#UEt};#Sm?t zW$WFstrcD5Ey@fAK~`tkTrL;M2@%&zvYe)AEaX|92Lu89U6}yoLB?M{Cn1J?({r+c z<7VhkA~M{eAj%L+%Pyp|Rk0br5+)KbHjlC_7lENmC7@+iaoHg+RZ?!5EKcDx&ICTe za#bveQX)}>&nq^auA=>5%P_I1;@iAvzjs#_v)$NthddK+873On&l%wnRdYXZ!$VOdO9z8DeV0aV*_XAmju= z0H!FIKrloes2r96!h&UM3NlPloLe7r&7m-!lp~HO9OZs~VbrAz(NfL;YrSUE&k5hdyheXXU8^Wu#Q~fnlvKUfBsYLY-$0td* zt3ozC_?F63%AreDsUx%OgBhkLwwTJWGtUk$EtX}mxj{^#b&<3!!+h5ca>&DNNfP2k z%Yt3VcpnX4+;mmqElo8bfQl*uD2ggD49)H^fEJXb{T z#q>&8%|Vn&V$y|J=Dj;ZQs07>VF4LQ5b&y~0S#M-)VnHRi`;B!VQ1dW2>)kiOgA%( zy_&?zA`g*HiakHd*q)oFQ8t@$%u;!=!x^j6psE!~2QGb{e-;dyg*~Sx2WqucO`zXL zeT!z?(&+HNi)CKge*ZR!4NnMV8eree5ast+Ig(q$y(x8GeLgN&Y7UZCtP^fugzaqw ziJBp)Kv5JPh=ynYO(Rd(Ff>C@5huxn?aJ1;|0~;vIaEzAeXeP=k#-hRrC;Hg%_v!A zo7VYzl&JBVNazEYf<}tbBt6PdRS{r|$C7FaND<7IQovKrqOuU?AQm_fc2PjWVFOKq zDo{nvk~x)=Im|CrmTV}RVkjmc#Kr-PNY67wK>?~EAP4%AHQPd%eO~j z<30QD{=zG*ul(qprpFIm`+;XKr-MDy#d_+J=r4Pz$w}|ncn~ixZ@u(a!!OOgz3zv3 zyZL}$w3`xNNfr@((_K@KJh!jy`DdDP|9n*)tuHjyt$i?d71udRJu~qoyDR>1toTGz z-Q>Y1zLwlQ#86KKFP^yTv9C53?)mz3%f~3{Z!H@Kj{j-u`KzhD)E&=mzwymmzH@H< z?BtG(_tFj5KYj4No9;N;MxBg*ac^*pf7<)O=Lhw}tv~4>*#7p^U+)?H^WAOhX5VPM z?Z~+wFYoxq9=#BmiT?f4!bYm8?#r5b>!&{QkMG^EhZ#7s>N4E|L<;p z@uO>~hVj1Zn5|b$_pJEbUgkjkH^&D0U*ErWWJ6(M-G?rD^76u_dMF25@;7n=$4{=< z-L}R*HLdQeJHF=U0|T8ejkpJ1K6{;iy7}~PChj~vc=#{-R=rifeDwP#I*(>2f`?A7 zZJ4>W`48`mPtNXmgeQa-I=M$e~(?6 lSXLZuAItrE|CLATexcm^Lgds2IsD%h-?A-saPz>}e*n}at_A=A literal 0 HcmV?d00001 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_29.png b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_29.png new file mode 100644 index 0000000000000000000000000000000000000000..df704a449c5c4c4c986f42cb13b3c23a50464db9 GIT binary patch literal 3506 zcmcIn4U80L8J?rI0`(|Ob8@1T>C|Y6&d&dDZ-L{M$YsS{9Y^$Xtg5(!gma7pE>BIYyC= z6{jAOl58^HhWnh30S~VnSdlUZ)|r|`Em}ynlyne~#Q`Eq*-XyYOK~catHX0R%ur+m z3D(7_)=(kYlk6hfTo03SjHOMM6-Y&kak41!%GXJrh~la-4CZJuT8 z-HG;!E_jPmeL;}d8Kzh)#)?AB_0kNdX&S@w4A0Ymp#2TG0F~&Re{WSn0{f=t>h zpBuP-pF2SiYSTA_B5>>p6oxZ5Kyk^L02nGb0jdWJG|Q!Uz^FPa z-T-zj$KEh0)G~G3^|A;y&dH)QX7agoq%E1$J9B=3awhIf#3?W}<~WwFVnr4$WYMBz ztF(bcxM5MC1w|80nMbP1Yt{7$*X$3IDqLT#FUvJSMr}8ATQ)e=RutNlY@Rj+k*8Hf zv}i$9C51zn$C_G|_JHR=iK9%t)X*vmB#IczCTAJ6sHliWJcvLFys{cr3=Ih)i@~bv zdfVKL>m^+aVlGf*xZ6622UAg4UvY}74EBVnn&~eODm)7p6gpg$`QAz9uTQVaIS^u= zBEx*qBmFCZy1)Qgk_4$T-sO~VrYGS*)cmp`Joq0iiKcq%rerashNwjK4#$V2+fX5! zm3V#SDdUh)RqDtr`(TFYi7l!!?2NO+Q;TI;Y_ShRv~H5NWti{UK@oYlH4P!2v@Dp3 zjQ3ID=BBF>Z)vK*(yXG&G%JS5X>bND35se?KI52Cc`=2YRcTPQiX;P4aCOL7(vf7L|_WlkdS7}ELd&T$%-s2yUW}>E)lZsxCu^0 zLvV%-A8Utac&Qz~aSqtdgTwVj^7!)v(Qv3U(V8m#?yq~!%{oC&Zy&t2Yiw-jscBo* zKKjQGW8XjcXYtC82lpTR={?_`y<~cLd;hTB{_>NDkIvbb~L4$$L5;A@=`k{i97p^XbdqZ6I!W?auek;DN@=7pMPz)uq?wEPoC+ zA283`vm3W=JdenC9zS{HS0{(xJvIA*m%jADv1yBUH_Y9;z2nLGSBWQ{{aN~n8N-S5 zhZjuSv}$A18&@A*Miegm_{^O2tR~|2c_SnD6T}||3&#m!e#4<(Z~Mtd__8qL%@cpy z_IT&oH9s2N_4y;CO&1225yn?y-y52B_FzbN*AqM0o$Sc);8z${(R>&+F3m-oIjbm5nO?|S|0cOL!$^_c&s+VN zjbebmw^Qd;j(R|NCEW zZd)|}=t$=NwNcHk zk0~h*fdL^;$!eUH1d)@^qd3Sxh9!R@U}a5EG@heM7frPJrll=TUQp6Sz7lkI7-E2@FIbK?TlPJUq znk13{AO|?PgX1-x)mXj(vKoX%Xo{q!i9%Ej<^g0oSViMRja3c-yQXce7!zt5n&tW# zL^jUOpf1dKPFF!&Dy6kLL5Lg!woOUIZ$IDLs@lMs{8MERl>^tTi0A_hpJ z$cv@%HamyYok^QSEhrko5&sKI3R6p~rX(SvhC+#I3+#X--HH;~wBxHvZ)uwiOa56n_es;LF1tYrE(Gd6Vpp!HM)`0g-I7;=zs1E z)J2x$1_xw;<$;O?8K{uBg$)TqLANksrO}=F3nTo`&KR!Ki~Xv^@{o^6C&hk{pe^6c zP{{MrwoxcArq?k`4XRR+ROnI%`DfIinb^0ha-dpE#RTd<)Hi0vjgJohUMwTh_J6lY zOmsph(g5>UhA4g~i;=t_+M7b>)kfli@#Y|D#Tw!EG1%Uck)Z0L0%Td{fS?OHP*w7V zbzRkY1+k(;*sf@e`)}Dk%ArbnY2~KTMA}(Il|hMP=Ao_%+cb{cqXd;x1wtRd;8hby zh9Cl6Q3QZZ4vUJxBbhg57XqHP$CQOI3o*|E8A5VHq;aYuRDdF|ro<|&#A0r|vLszr zWnDG^AvP9Z6m?>Omw}>-NVOzLtTwA;6)Y^e%N#x~1!UE6lQ>lvB4^m>wQ_hSAC==b zb_m<~Z047?>>IQ)LTEhZ*b;OSGm$P3(sDEmqzazSas7!&u-hdp~3PuX%p^qr<;GJwPuz{`dDTsjc0~|F~uCb@{2+ zKKjresy+YU`P{x6YihTz>)%k&xCQQ_i|28b!?wzsnKySMyF0_o z+}$3e?G-sfF{LEx9~e@oi3Zc;!XKE_mK^A{h@q4iqCwOIY_ue$y;hCqahUp@-MwY0 zcig4g$?ojTd!P6H^}gTF_wBRo8`j_6_=QG>VQz10&33@=AbcO0pMv`n$F8h^p9Mkd z=7?cFvn2U8Fh4xl1P@2N&aSvC_Z8Fj3u)r`7EPB50iYRXlrOC|^?(3r5LLcSQ8r3_b=Yr=Cf z%yVoR5^v3L&51&`E7#7p_#tK0G)6YY5~~?$L6sFzdzclmh ztWd*3lybQmd|I)ELJb|oYx}^Ws&CVxqt1bV@*OntdqbP9?E{SuOc@r%9rQ+M=CB;# zwZ%b?ANx^{KSK~|(>H}8_S_j1CNnodX~~-bn#|Oof!PvL68mAN@8_p-r+vycRut0$ zyJC}9bo~D4i;3ga1vE=yn&BXkWQ0W|YMr8FN`fg!U&4ZkaRr)#)O1Kp>cJAiLZ^sL z0kTfM3G6$bJ1{HMu}#+x3j{XKE0Au=2gUBPwp`9^D@HLX+O#d3;lR|i=Q*aKJC5zj zDpFj-L53nLNXMFj6w7u+*Oo0s7pK-|eY-bFs$_koz8v2M8MWOoUB$JrLNIb%SwNN{ zi%8d98@ZCI+M=Mkl0m1WeKqu;#7VwhYGRcG5@kwNTW~BSYdS$hlpRDgc*O?QEQ3fg zrUu8}(A(nY{V?Y{5OaxRlifB!JeW$7`pR%Zb+9W*)qHPdP!lm+Q0Q<~=QqzXe`EU5 zq6Z;{&?Na{mi2E0>H-5)MUj;1c)M4k`L3)7QHv^uhheEV&k+v0BY`u!+^FBKkO{ zS7qBhq}WZN3-R2?cg7O2EDDB>bj3E1t;hsfScRH%u?=pDuHk=y6cyO6VvYa5vVD?6we&Klnnp9UvxF+6D#xrL-8HsZHGPkg z4bhN+K9DUz$5USUEIthmeHIxb~o-Ek9~Di6UK zHhHWap5di-{H8@G7`NocI@BVaSr5ll)U{84K7D@2Nq_x?;a3igkiBU1k)@OBcdjTe zk1w6~%Wph9{LpjFqX(9Ky{B>Vd1kRYxV!t$5B_G+)6D6o2hMHzOKSPG;oKd}Rr96N zo13)M(H8CJBf5Qrxp3w5=${%G=I!4%+{RpAF!)W7wtG9r^sXHkB{GNF6m<0pZoE;$Fze(FElboMwkESTi?7s zwEJ}}wdcKtcdSL1?tCpXxP#G%)%>Zq_Uukw>SKmJ+ym;)(T7U=CY+yK{oBy-!}ml# zd;DV0q;u-iO&3~vGg{}FiRH$orWgCNr~N0t7C!as_WSYs3*Ud1x%a(uW8d4n^zu`m zy=_vv`{fhw92-d;&YymDX@pqZV9>Nko*{-8p;fyWM4X z?K>MXMXcNe)B!%9va-TdDV)J6%50y8tBh#h2JUoe53US_}=;a2c7Vv}5y!V^s$2{J%`jbemIGps(wMdAuTIOj$Q2k*&Qr&=xv* zb8DurrVF0Z+(;Y;CeN2jrBq2u`Qb1x7>2=Pkrzb-2oz0tF)1T2y0tDLLnAwMgV^;w zHjzjye=JUOU}@EbV$cxlMKzj$FuqIzUP$4@r3%oo8@OOBEL4;`Hctz*NWC}$tkA#$ zOWAA#KBw4Xv4M`_P2*ru&9^zxQEnoj{8k$IW1&qqjf2Kp>xM<~R(h41MQjInV{8&qG3E`5G!>H$RWUWaSztExYqTla&TEFndEvVn59JexV*agLT_jQA`PJ=XTd~ z{8Ds#;&^QX&5)R;IS3>fVG)U1PLxbZFa_xjESMNqp;-t`hs2~AEFmo9L~IJGDQnk& zeaFpDEC_XMGw+8*0te?7$uQ*uZ@8i@n>7c#C?=jw2Qq06Oij72V+xLrMM2V$sOuCd znrtJY!3bl)QHd=PUD50NGrm2R1XZ%XnqQ7@gN(*$m_*UArYkBE44g+)m33qgY$HX{ zEK!6tLX5h!Z-p+TI4LwsO{{W2qD-l33yy_kO(%$mvIADZBQ~gJ8AOsX1vyvs_WA`s z%=!*+E^%yf+9rqxQ%RCvX-=q34ke*l7^_ZdB8C?vI=pJ@I~G{Kx_po40>vW7Ch=lc z^lyXG1qP^!A}O``LAOi`Lm3xXi>ii*z-DDjWobv#k}4;qp^~CzzZ*f&P1K6bHoB`e zD!6PVD@|foeXx`8qz+e`cIP#jGOUP&TBHYIFgwVp(u#`GGk_6YHY zDRd#8`}EFeqC_Z`DWak%K{(3>GBleaTeL;Zp@!s$+PuzuvLgJSow0pyoQ6$-6_AiX zC#7MO=JKImWJwSdT)UE9{J7`T8dM`A+1O{V)}MJvb7<%`#Xz%`h6(IvsBgiDTUk9FFHr6C8j%f4(UGQU zB9blHLWTh&YFUOQ=|oUesCHFr{QtGuCo$9rFSFh>dZ3*pr8273n2lt(QEj^C?oqNK z8Zwj*WJ`vFR9jY%rRy@Hjz|?9I-VxkT@}I$?t-!i6)=?qq(Q$#Kt~=K3f7S>L-!PP zK^3UDSXrv28JeX*vo!Joq6B)LB}*F8Erl3)6@%4IldOt`Rd@O8^HM=JT{pq0$`ssT zlVRiX3=fU#H}#;}g>bpvxSC(XFfG3r$n@mOf4Fey?CKe|t#9JvA3algr2S_feeTe? zJzwg3W8I~%Gb58{hi}qTXX4r z_g}yF!rmLRg|O$BOM<6wxw5@ws^=iz&fvG#3Es|`(dp9Wce>-(_WWwiTW#Mz_s*I2 z@`?A~Ev;=mV_iCW8IPFK$t5=*oZZZ{N)J4E+f4%>ow$X$%zxPK+|YUI%BeLi(?^d# zO!tm)OnPkF`A38UE2j4Upz!zA3{yV*Wz0+;W-h*aVAt8FTBdfdzuyp+|M3KV;>q6$ zc=pyuR%UnawwbqHZf{-rWY?18CFXC;blb(2BXqhg_~CC( zy;<;`r6)^0-~9Z0r(aKXesNiDzkRYLGxO(t{l9)})s54?XF5tJ;V;p5A7AlAvHS7c zkL`Ij)%oh#+`jw%^v~xWjquwCzVoUY=l*fmE^qY3Lv-amo9}ptW!l<@mcDfU$Yt0DQeNR;Wt8kXa7?2aLDfL4!VudQqQ;@5X z=Wv*1=mI3z8fTh9g>-jv9o_7Bn2tp`U~rs3%W9O5i4v4=r6C77mM0$x@UkWUteFePl!5Rise;RWjV+~2nYiB{n-HJLDs)%NL&3KIz!n@29oN4e0Y0?;(dIJehJ7nGX@i_KokluVZ4(~8Yx%4k1Wl_M6Fe47^SclNuOZO6XT>lt`ej%d7T$}m4@$CpDh zhvfubUhMWbf#df$GX$YLeMKk&+nPaPICBLQ=j|Dw;Y=CoYRw)-f#Y>LPI`(v>!xg@ zA&m0$&0TiZbo%^TLdQ!BZ~_H5&JZGrfP(lEx`lfF0Ae`e%ijhGscl29b@kGbn{wH=8PGOD46}tRJAPfm;)ChL{?)ZBr91 zU5}Z(03_Am056FU=n`iD1wqp=p=rvBHMKtB7`-8>!u7@cG981+DDQ?QaHeP(Pyr(5 zA+Q8d0g5G=fVVi)w2%Ukh^M5j^=y*jC|xNvw8{*v!Z>E|rVd0|K>$I~1V|>YoQh># zMS{p-m7y=|ZFbU*mvl@LbAh45-PVYBVk!#rE6(tx!S0Z%>E7a?3^{U5ie#0#D zm#5cfZ4zS0&>>&6g8mLtx`+WWNfM;e_&Pg})7=T1M9nW60+q_C4HZ){F)R&*6xCX6 zpOCJ{0U5I5qx-&fFd0mo4KzMBci5Cr^i-G_|)sjU8Dv(#vjLv+xB7Drw z7)~~ay$WKv$U~%)V$Y8=mgi(>`Y?q(mp0Wjnn*hfOQm0`F)LB3 zTy0iN-=jnosv;>Lzz|du#0*gax}t~xn-EKiAs|^WmKOq^wr7=vFwbFu2QtTz8xk#` zN*rl=B5%fcg^%$V&Q(@SmsMGpNoi0m9$-Xz9;pv9P;?2YR*WN7n-#JO78c!QuO62I zvf{W&oGJ{FGi>-+K0K3`^6?vINwxFH;kqM-4^vcRqBYUfnLlxM{~tcNlUrQ%)&~vA z$sY|*?0urK`log4cegXSGb4*e8y9?jSN%$I8=L%lckS-;@15%Y)cxBx*Q{7}!=rUl z;z-BCdp1wP$+aJB9((==^~)Lt$KJhT;CgE5+wZhTs89TQNoxEHchtAm_acaSH2cG`hzh6>^77pIKchjany%1UUHG>-4^74`;i%(FWlOpu? zA8wrd$=+XXU{4S1|0Da`_g^)3cL{fYbAb8ui$_PQZXY~eV`qo?$8QwBMGw7xno5ti zO^%)W2CR%{zGg zU(ep-d}ZEftcNInN-vr=yIN&w=up+UJk_r4eYbDFKg=b)N`6UUF3H=`EICNMDBP0@Xa;kXQ|uK z?^D!At_i;p>hV3R$ip*sPhZfNyj?e)OcYs;fus41OVAY6)RK3RxfKVrfd}ktjJa^= z#|&*-F{W2a!lc`V2knk+9`4?@smI*5)zmDerI~KZ>qI~X2Z+vR(pg{6$C!d#ojixb zEJGI{!PXcP4;9jV$<1_|<6&BkLSRBD(25r2WKrUk^)wH8$a3T(0Z!3HRTp@=bTLGm zXQlM6#Kw{?@)lzTgTU2UHkZpqb3)Yd23SthG#2tK&jW%0{zx`Jd64yQE=x#Y-}G!Z zu$?R&N<@Y;6vP-}Y0-s@TM?V}OJO1bWAn&mxhM=>DgZ6Bf^&zwbV0dgvN(-1I2-r` z%T=%>O37peKC9SFrh@i^_F-aC$+ub2e$R-D*)HrmL!OD-hl$3U%ZB+u7rqpl1uQ4< z%3^oW2^@dWnIj05>B~Y9*r_=bhBKEzao(N-8qQRpuHNQh6gXawEv$<>=&GS)? zUejx5Ehp!%4IM8nzzG!K7()_C1ds>3(!&e7!0DW@4stq#MQDaqnHOrAddl%Kh-{plK?9g|vjYWf$)w(y^#hbOac3gN5L2VJZRrw(DT5aU zAVNz677`7hVx$5CV}Xooh!@QA`h;T+g-I2zFV>gkm_$ZpH*}e|Fwbiu;7rK?k|mk| zsg?pP%o)6_X$YEfS=t?*O-dZ4tEGlkSwy0Uv21dd0YpVb0P&&)kV0Oeh806Yf(Wt3 z(3kYKIcdjBIu?n!z|i4t>qI;;6@~Q`W4O{_Uzn=tq2i#zLvoQqCs%2{f1deE)1S}U zB*Z*Jhxwux^mh~LA_mBkBuJ(4&2}EA`w}*ZnqM@8SF5M`tEOZzq=rI?>K(REl5V6# zHr@FC(o@=|3stEjv*?2vrYE+T(y%?t4lgX0MX|X-Ormv#v@ODXCl%z7hvNez#PgN~ zJD2f38osjWs>EBGYCr%LRR&NLNnRQpNi0E8Q<9bvRSTD0uQt6A;~c@z0z=v#@7ZVzi$#7o)C&O!2T;k6yFoYNNx=GrqFry*|=b#IY?TuPPly@wofTY)C@@l zilXp9G)V8zH1dQELo);wagt2fu4s+(pR#?JLzVQ>%S|Ir+F3}Ieu-mR(LjZ5nrH7( zqDC4Np$}jRngwK2lz^eCBES}pCDjy=BA88ufT!(wWg*N#EO0=9klc`%0-6L>po*L& zb1Elum|v(Y*-$jaP)tCGjRP2wo@a=H0#rjnT1tk*YO6|C!NQ`u?3LqEKvo?$iBp9k za)u2bD~D(DQaOI(EMYs39In50b$k~^MPBYq#C!6;Key*|`(L7$x1apr>334U>Hh1P zO|ObmD{i^&*xplLezD>40}ZWppL{61{q2C>gpNIbWaWtjICFaU%AJw7x@+z{*Y(WV z-#&ZvEn()GH-7i%=(S58KG=MItd_b;I1*436JFzE2Opi<{y{xD^p}}`Jhb+n)mPnj z=0~foZ@zfw0&MuHaevQ<@bg{EzxR{7UZ1&+YF#{-U$$=N3-8rzIP%UD@qx&v-rfI| zI_jg(-*(@M9dGpBv3QGfddJZ2uYZ50d3U@q^WA>d=#Z9dKQPsLLuB%{X#{Kb9)7cS z!@FN-pZ>uUFHB6XrOqBo)lQ!tYgoMRJllGF+0xNdi=W*!dA9lP!*JD2lzVXBc=xqy zKe4Cr!7nXgjQ*Cow@*YaE~OIG)$W+K<$>$zMPC0a`G$vUZ;+b4NIh3`%evQ3-nru& z7jb;U^i6e(xS^#VJO2J%uN`YzInLFbS~5`|S^xeo2mk)$1C76$vc7unw?}Rq_2WBV zJ8|^*!N#}0=JH4XJh`#=+*rMIR&&7^5myGZl8)w&OG*6OpTApx#1NPe^|ZzF!WL7Qu@PCObqsinpCMR{(%w!Tfeirw=DIJ zyVN?_oqaz(@B8b0zn}N^;qLWcZkfMyKEp6Ao$FFP@H+zEyXMY@_x;cOWd;1qE3VrZ zGRzH&;_ocxhmYM1jeTCGFX~Hw)wKP5f;hfK6Xkpn&yn)M1v?)=Zk zIM#ELT(6SG>0$@%_ttF*=!PxpGxnCvw&8HASFtP0CJ4yWh_K~+t`M5#Bv+AZLOUMj zIkp0cHYd6ESRvb&?q)mufU;@=BO7Ch)r^Fo%8IDn$%goq=X-2dBHFY9*evvB0!*Us1T7dDul}?B&29)2VODq z`~n+GB$huAB{{IP>O#I)7h4ExVS<41Wm4pY1dd&*03ExID-Hy?igL&1X^!S;AqoL2 z)Ugnybh-|oRBS$9M~BhcL9nRi+ob3)GgPE}4-Nf+z@}>lLF4iX!@{VCUJcC*mIJ)L zxY+MUe%S9%5rq2mHKB++cM65^%r#J2_NIWwGj(Xu>|G@rXaOp!Nj- z16i(2kcCx@RL2#lD!RZx6&t6|b+>m*d+YqrMxatSF+Q3KFtpA|Q*%7+x+x zs_wYN)@0qF+Jv;Oz=IMexkjn6RSrm$DOGL3v5>6k1QAho5YeEEVZCJ#NyZecx~jLs z&-p>xcOd2x$Hu#Df_N~M#PyZrgxX+VoT|Bj>YyfKc%abXsm*VkX8!8*eFYCfEOKm| zFJ?vm2B0o5Kvfh;sf~AgWt!_tc@VX*YKW*ePHk+MQstN$DkW;J^Fm0vp&Hq2px>&s zavoc$N|V@CAM7|isl(NVy-9X>X0fb_E%j4~)^*ah3JZNVDv^M;XCcJXmIXhR@gW(! zzUjImI)-jxgf(47SeA8US%QTiX?0gITv>PMgzJr_SBglGO$nR0UPK?o^jcW$ep1L% zIE8rbqdQ~SSkqidMT)3eNS9<6Y6B}sQYDSLie*D@N@qUI2>)kiY`-u_gNDQ^l7PTT zN`o-Txq+W&NwJvo>`Hm@g9WE{K-DXfjePbh|4bP)hX!6l4m4`1o4|gI`lijenbF~Y z7t5ry{qb!QAKwtFG{AqDA*%gUHIjG7ds8`i&B?f6ra1^lu?gHh4cogKkqt}Hk)~-P zk}cUnh5;>VS%xL)L{L;9XLcf-a~6 z6=y0-wKPMsG#df235XIn^DJ4?kZ!>d?5Y^7b{b?=EUdcAUq3DtWW#k6oT?1L9X4*( zFVE1aU%zPq*e-y}_1W8(4Kd8DpLV9&Gv(jE``FQi<7{*4Umxr_^VISMj~smUx#wRv zk-7O|YwPL$&2yJ+U$7>A9p1mGjof?S{CL~FZ3BxI&VJ`7>P=_1J@NX#zy9*h%lObX z9`7=HdJk_s)!cM)*x2^gi+I9Abo9+lSN{6`j-#UV;Nq<<|Kw-k<0DIU zr%t@_&}!z`p69a%!;z(zR^9U%CiB`CcV9Y}Vvc1WJ^%feviq17(Vu^PGP&p%`yaj7 zJo~N%JAe7xR;_F{G2d7^vbTH5>wPqN1t2r;6mo}?eBc|!`EB)2Z|!(@|J$SFW&XBvH_X}1>^$@1 zLu1c&J^9)3;g+V$+TugsyzjtyrvH<}zq@^R^C0u)kryAAnX@_Tt4 vk8iuRWzG{9xz>4GKe%z;`_iYq3v*gZCm-H>^2r17->S~F>r+p!d0_NEj2f0e literal 0 HcmV?d00001 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_35.png b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_35.png new file mode 100644 index 0000000000000000000000000000000000000000..38cb63465b9a00c176ace4f1bee33905840158ca GIT binary patch literal 3500 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 Xa#{DGB{#m4IMKOgLuTLVd$;`ubAgkh literal 0 HcmV?d00001 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_37.png b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_37.png new file mode 100644 index 0000000000000000000000000000000000000000..c3589d31fa266a36031f070425307f34614324d8 GIT binary patch literal 3466 zcmcInd2Afj86P_ka@b%}P>vQlOcZPv-p+kCo5b;k#E6Y8$0&|SA#Y~htVh|Mna+&8 z>r{w9fFuHmMwL+7#u6&x6of+&3THw%q!NMDA_0X|B=83-tO*OzqWPWl6e$Gwf3yb^uzCV_^z7M4ELWM_)7=;%njCUiYRLS z50Y;a^_zW*;NeksU@#uc-e6dMA%$(D^W-fX8Y)FKP0r0;*iC0BCYBvUXf%$y_Oa@fn$02$cR@BNi#%&u3iji3vI{f z&sSDd9>Lzd)Tfza$r?|wVGSIf_xL`QUmzCQVOY)>Zyf^|ZU&n%% zve`O(Qn7_X9UaAMMu1V(wn@>^z-U0&eiHe^p+(k=fX1aYVo}^r&bnp>%K=_r91Quf z9}W3aIH5lMEmy>@Gljxr=37uwa;JbMGj(WSbcY1TemLO!`C9Ds)wt1ukmBi%jjm_= z#i%neyt;s7a7@w+1d@a}0SW4WAQ~cX@ZvQbZ*W`%nuXA`af}B*!Spqg@B+t6)6k%nw#A!B14&53wty5Y@|aUh z(bCPDwBFE#6vz2SsR=6^Bua!R7H^wKQZ+JtKg{|z z_*`V@WVa0v4^(lIUulM~4h|-vnjfwVssaZWBsyHx`AyTzpPjzZbHT*|LnrZKl=W|b z(gg$*Sr+B$c%NG$`N50}UW+P31g&vuQ^S-ZC8eR9qQ*Kmf}k6%7Ml&^=hdgYOP90K zz*fZuD+y0xGu2^tk{zCzFDqh;Lj=5ap0KUJBHxLNI3!&;aPhQh!A?a!!XxLWuE~O} zYbJ*{RZ|crNg6Uu2rOAtHAmJRNwZ1K^hWCCB;qAQRtk`>-TCMR)_X_|yY2Xk1IWlgZuDUCU|BK)6?v3zfYgbjfe;1EM6C1I3i zoX{`OI0*8tRZcH<#Ivgns-BT_?9*rK&y-HHN$57jK%qihy(xEIW3pN>(-?$SY(Q0QIjCDuhfVJHqtIV)sE_;5zl#va`O)#oF1ZUXfv3_`l zm-_LWcu?&^I9y*ax`(Hzrd>Umu7T2rU+n8za3|ez!Nk8GDL!@oyt(*}j`Z5=AKH6y zTN}FYsyo|O&q;1aKhMp*C%kpx&AYFE{I|bs8$9&kgHK=CGI8qAR}%*>*`a>fyyNku z@AfZTbl}*|S6_SPV~5^6`}8}di&nkfOf7$D!Ty(@ljh%e&-kBzdi(ejvrhbYcjj{H$SvZ$Wp~|n zV(i}EAMQNX+cdua^H-<`f}ecy!AOCjp(w!gtLtp& z@3_7F@Wcvw&#T5Js%3L`>(cx7cAb_!nos>}?X8QOwtwARJVFJx{OXO1sPU)fEW3OE yk1jj8mOpUlYLPws=H>-oo@tqTX7Ntxt64>7>@l(Z*H0&ud)BPa>|ed*j{gAIfp{JO literal 0 HcmV?d00001 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_38.png b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_38.png new file mode 100644 index 0000000000000000000000000000000000000000..964e25aa5c45824f8939e6be2ba3acbfb776b5e4 GIT binary patch literal 3446 zcmcgvd2AF_7@w`>suiJ_Xf*0L#0bjUxlg-PU<)O2v6dQ&M(vxKH`@ujJHyPhU1~H{ zhz74#Pnoe$_DC)SS9oa7U9ft3DQybuZ>65$Xz|SKCwIPKdBrrgJ(Hx%MIX=<)!J6}v9*dsv`O-ADZ}i0VKYO!c7|CY=eV4|i1fJ~ zLjhSnw5;12T4m`r(>9-OEgK-9NFq#^i-l5Xlru~s*MR4Em}Te$60OQG3u1+IPp*?* zm%`1{DsPkxn6F8QKkBoTLkTgRS=<3CQw!n6buI%EfE_ll@eNp5a zEIT+jm>v|+lH&+=(5b}0ecRt@L(2ZcnrZLy?4ilh{UfaPmgh*BLQ0jGlAs*uPyfbyvPgtyfK1Mn?52G zk?V}1FrGOAO3LmS(0HZ>^^HXV!I2kqdtPBAcRELGqXi+&({on1CEFVe=f;j#7mzHD zNQQw#k`N~#LG2bqL*xx!Jcr{Aj;la(keW7*a6MQ=9N#SfMluBD2(V|n&YE$dwq-b8 zP{gotZV~4R>zDG0wp`9wS_&gvvdGeGh5=L4u4@~%s92U@D@ee)h%_Q82s^Td6xrki z9%~LqW?;@|@1v$@#n2QV@ z@3sNr!BiaASBBxMgFSJo7WylLs=&bog$`GBe&smxho>(pxe#K3q2qip68+18y1)QM zmPH6zGT!NyNuej}Le#>FA%a#vwX$wXkz#5{O4R6ZLrA(cRkB%5R#%@2E}c}Rfvt)U zR-B&1W~#&PC_6l{SXRUi_7RBIQPQ>o3q2zc_S zPSq5|Ns@+4lQ)qps+uF~j-=U;PJcB$DI#7nM9$!9Mf7(}ugbRia4Aoq3$e`KcSh!Q z>?lM)B8Mg9I8Ym!BUwl^WtnqiLAGqj-7%c`Gb8-R&RAY)fCP1k<>LTDCnZ6cVVuA# z(%AP4u9cJ*J5aK#4XRd=bmY;8`De_a*(7l5a-d#I%>?>i)HiO%O^goz_f2Bs6GDXs z*grEwWfKa?C=Uud&Vi(R-An3%UgKfhrX;FJGi9th3I|r(b+Qr*EAFyKk4u8AJ8ptg$q<}j?`Ky&wQ=^f)2{oWwd?vKW_e z+mnx8h46)s?%Oi^!lwRNEe(5C>}lHb@{E0lw*R(ke)GWoNt4@`T>C(pd-%EI*KT|K z@;p6n?FD)N)ZgF#t!3?luTO7YB9ZjdXgA$N&3I)On){90x+z87KKbpa?UFg~o$~1i zXZ|Yhd@HxX*xK1Jd>5U$W9Y`)PNcS^y1#GV)<_Ni*p%JfnEdykZr0D!Qq)VgPMWs$ zbn3KYDek$J^ovgylt-@L|E|}t^Rg*hcFbCTHnnc^mvc`z;n4a)AvbyP&a0*lznK1M z61D!)nLB!i58i{@p3x5clFxr~!z~}Q&FuC1=22G&Tlems**q`x=1-}so40Rk0GxQz z=ZBuZEwy*wchmRY@Wg?yKfNZkXBWSJ^L?8-K0ipe{3=d&f0)vH@%(9TIA0FM<}Gbs LmVInt?=^n_h$wkv literal 0 HcmV?d00001 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_39.png b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_39.png new file mode 100644 index 0000000000000000000000000000000000000000..4decc6b976a9126864b9e3baac7e4f4656f9be9d GIT binary patch literal 3434 zcmcgvdu$X%7{5}H@`@<`ps~6xpeWAmYxY?VXnSaDJ%n<^5@Td`XRf#D-R`ox*B+qc zwBR!lHO2%3##e+yLzG~IVB`-IjV3C_KQzWflxUhLK2W1l3eMhLk3(D9_}cXLG4q@6 zHQ)F9rVp%IdE@LEm(7U9VzWCtlHK%KqQB)$Q|SHn{X>iBW4hO|E{Mfu&W(Nzu_t%V zqc3~xbWhlmy4kSYd>modB=KV2qv%*{$+Dt{tUeMlCh4`E1pED=!z^Rt1beHT;!|Eb z$=V&8e6nWK%Cxnq&(blwY$>y(Xix!p5+bIU&pClnOt59S27Ql)IhH9y!oCFC8YyIY zQmdGD*C&h;=YhrZ5~J#IL4mTUUeAcU$a4bylYyWbP%|Wvsa`DA=HrafoxGu{i+&~8 zY#4e5#|;b�R9f>-TbkuIn5xa-s+*0t6eK5EX$F%paAIB!T7IUTC`x6G=p-TL=>@ zwY1_w-m8gqf@+v(z_=pvI3dnQE|r1Us^PqXpDQcJ7DsXk_AnGG*tnL zAS#$wWul01bbZpb3QnrtzU5m=7?S^4W63(a^0mKp{07XcEE@Bbrm|(@iN=6dN zsI*&ro0d4r)k}@6!c-z8M6m>H0;p;TAQ57KRQk#5L^X9JL7wO=b5?J=n{)k?i)qXy zmWg)TpyH{iD5|dnD^v%2qEyWlDub%X(~A~5y{hx;CYV1vz1Fd5h((r(^2I3YUqh*j z8lcFsBv;2**+r7;N!m1OLB$YJtDjm|H>JRc8pOgMmi(%MTyJYiXI;~5{I{_~rz$s*P@ zlLx%2DS(Gi1EwjMK$cW3BkLKcVVX{VHN9L!0yHGv;FZxL`a7mqWm{R~^b*>IIQH*5 zLwF6V7AAl`B!C4d0%T&HR+@s53^NF7G@ZtA=Fg1qA3I~YPCxPM63atAqMelZL4wWr zZk|D&m$R*Md2#&?t~RJzMKYnwoaLW!gNBK3*X2OHmYNC7zo>7*jGG)C{_mT_MJI#` z4RC*Eh{|`e63H8)y(xEIV=OM1Y!1>^Y*22WfbBCXg1RYdKvh){K$G?kU8irvG<8$b zkRU6R?JCx||CH^c9IB<4G1@d*X*-LkGN^J)8|tmG&C;=Z6x2l>Qu+Xvq+_61PzI)^ zK|rubWX+P0Dp^a)0ngbJ%0fioi6j7(=jjc>4A5m>0~!>tB4~ml5OK1y6jRkzQ?&pk zHUSVsd!7j;6=wcV&-gj}!|ubsoPK8eVDo{aOc(z2$kb^IPijqj zNA@*-0e=gp{rc14k3P`%bboim+dueP>Au0G`_4GCMqV0xbb5ODqKgWTEII!6uHMU2 z$9`%V+I{FN`?+1mE>GXm(}hob@y4}`{$(zgEIob2m4nYd`qoFy%zC?F?a6l@Xgm1I z@PWq7%{4)42H$*Zg7>B~mgIeQCFpW1xg>V>5fAAh!O=ewU5uUS(#GH>Wm z(oSDP{4oFPrD}wZAzPK1K@r4>cY;)38|k literal 0 HcmV?d00001 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_4.png b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_4.png new file mode 100644 index 0000000000000000000000000000000000000000..27804f2506f014fa229ab5a45d2b5e47523f4cb9 GIT binary patch literal 3460 zcmcInYitx%6rQ%q%R&^55E9KephD#Cymub5w7>$baj`%R#Yp7N%-weE?#wVVZMTSu z2nM74P($J?1jP72(L{)7Fo1~4D-kiqXpDf0K@(7k#99SCv%6guY-xiy*`1xa_q*qH z&-u>XM;m6%96oH!Fp8pv*ViTI!0%G{)()wJ`-08K#>3B0uWo)oQCD0YeJiMEpC1hm zuh@-EVN>dM-E^}tY`F%B<+2{2DQZ$p&ckLa32B2g+fIV{dFytDwygv+Pfl?uZyIT_ z>lXWD?&4XE=HgaUvzVI6^rV~)0t@^W=}j)qx=&O^f11T!U4NH?V# z=xMG`=y;4nCdY}iqQ&^QBn!$!THpkZ<>4bEUeP607X`X_F`&)2()yg_jG``hOE4{A z=;5M!?2%<`J1v7EpP0s;gII-L;bkQ0pUk&q;T>DyjtyAB;m#D?1zCK#}^ z;6m0biFJZvm>^(m4tp#g<06;xK+7!Qyf#0RS8kas$&f5@!T_**2@6q5rAqK##b&c5 zbP!H&2aAfn^@4@1 zClsNb?n7ZTa}Jc`>^`8;ObP1g(|m$M*Kc&)Oi%7K^w>rVLX4-!&$AuN?Fc4Bju#h@ zBo0Y}fkcuJCm=y-6hvL*bzZ!M<8_WJKvR&K77lSaSVSD($g8>_>w^tbDHzoQYpRO2}10cq&}Hoz|@#+Te_esan2$t5;ZA}I3lUYFa&~l zjwghdB+*oip7lxBY>SdAT3@Iy%QZnpX*YD4q~oe26C}mKZPAbnr16G|G(}WYB66}} z6?_M4?(l6Wahxfa8d+t5M2V2N$y)}J6cr;ZNEX5hymA^*3=NACM>K{$t9P24as8BQ zLCi&lj&?f|52oU%z7h;y9BhhGHPcoYR0Iw#D0H}r^YiWSWvTL@g*7BBwE$IwZMA0(Kx z?`CQ2c^TWxmlxaaSj7fasz^F?>9hRPXV5I-+hsXWuBBuGeF^pTn{fl9!+#e`ue5#X zHi?Z+2n8Bo&u56jd$JJ88PVS4JFngw7YsB9p%v@E?ftNQTEUVAnTr%f5s;K;dkvn5 z0XZ$In3vZ&E(#Dl%xro1oVMSQL|9o zlw@S6s)UFo5Lq=vtcd2Me84kyzp^mlIU@2%;W)TqXrY?SsYsQ0E6%HYoF~FSWyK9e zQw+sKKx{lB7hu{nwJ(dp7@KQQ{ z69?GNhr{)n7Y6whRk5r-Ii)f8)$!-Q98q~g_4GgguG#30+gp8LMdgvN2VcEM{ph~C z#_t=y?8>P_ZdeYtb=gxt4t?y0?(1_m`hR>gd`aD9O>h3RGP7mswcGc~N8A1y`-=J0 zu!Ab~`RPRuUQ3PM)%9%!^)NMazghck^`KXO?P_A*-*IeN`-#^oJA9=KHqy6UA5t0`x(tY>e z`Qiuk$ffIU9eMPT3To%hLr-0{h5F^U8h3)QMj7`|?5|eps~Jx&oJp(-pN$sYD!%fr~ytKNZYGtZ&!`f5S(}P#OJnAI1@TT{2qj#KM zU0>T(b=Vr@ezcl|6=feEXqamQW|$*_Gd(xoyxp+b^&B`kq6hj-0uz!+UV^rpZU&Ubv%s*TEZ) oZ`yt0rfoMrak%EYhR3(9U(vmG?dp{iqyI_u(`O~$n7VM;KUBqu#sB~S literal 0 HcmV?d00001 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_40.png b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_40.png new file mode 100644 index 0000000000000000000000000000000000000000..1a8d8b1d96459806e6abe6958b781009cf49b92c GIT binary patch literal 3419 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 VmZv^kIvG3I)76{#e8bMS{{aZ2K&k)$ literal 0 HcmV?d00001 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_5.png b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_5.png new file mode 100644 index 0000000000000000000000000000000000000000..7799b20aa2412bab14f861647a82944e91d6259b GIT binary patch literal 3475 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 literal 0 HcmV?d00001 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_8.png b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_8.png new file mode 100644 index 0000000000000000000000000000000000000000..926ff0911518cfa96860fdc73557bfc04ebf6537 GIT binary patch literal 3518 zcmcIndyEy;8K0|oWi41rC4i4~7)Xo7bLY(a5iZNJ7uaokVS%+SD#DpLXLd*Ky)(|t z?!6F+n?m}~c74Q@LU?S_60vPe8?}|z&0>s+;-mB*r4J>R6g9Ce;$w*}-JZEGE_RpQ zSUb6Q?#wyA^S#dZ{l0U5(6MIq%&V@wieZ?U?QNO$^tYdWmruWp-Zwq*_G0?e{7e}=P z*fG~lN5oBC@>RD9uqzD=y^yy4XTk4HFF*UqU`Fq+sk)8HnvV&hHI!W#!oBNsi=6Aqpv0 zsAFlAve`O(T(S9l9UVq1`=~`#-^N9Uo!flEuP33`8`xxJAJw?9W>^@lCl^99h2<1p zU+njIkr(!O69l0?eNiYP*O@?JJaZA0l-voR@k|}+o2>yskr#A&Uapoq9W~onQA`Q! z;#=GT_KM++vE$VRB!eQ7=4c|x0E$4=Iz`Ep1XGZfK*5Bt0?pFY#3(|IUQ_xLO zH6`UDu!mh|+oVuzn~oRc5#2a9kGcu(7rM*ZvRSje5JsqAllDxSqo$@@7n_>uC@ORi zaAe{DEXgXc9B2RmVo0!VX|^NR)@MAsH%_W}eWkvzXHyyV-7p%(g3LGDuA-A1IrR-V5&JtTd_&GeKNM!kZf3r z4m3>@fo#bZFbw)cEX%MY9SMp`*{))Z_rJ1zoI~~WGHXqvg|@SpD#I$rtU%p$wpliQ zkCF}1kSTotTQV?EZCL@9uFHU6ktn(?Ax*NEmII!1CzXYW0Er|34MKWDaZM{w2f8d^ zRnP@hAmUVIsg`DFwBG_sYyu#N_B>0LXaltrWH>6MR^tX)WeY3r@|TWF8QE~$q)wHG z=ovPCtRJ4~Oa1sw3Y6^vdbsZY?vo0`B%W^1v~-sK{EvNq8Q2MDWZoZZ&YtYJV&K>N zo96!grDwl!2&{YS#K7enZ*85vVAre_^mcsflbf3EJNakEcn&3o4V)(Wv+UNeJ=5{SMLAhapvgqQ!h?u=9LDf-M0Je^=F!A{igW(?zKNT zy$2ot(T;;Hee>`B=!WDfp#I|6GlSr(!-@3pwEhPZL&a0#4cf`)&Zla~u?018IHMb<0R}=5NxaaH4FL&M7KDamOkG-&n9Zj4e z$)VFjeZD(#-N>$!UmVPynDeDS-J7^Pz4O^e{o$2=dvO0=Q}pd0g3YJne^~7+*JK`B IvE@7e0U=bJO#lD@ literal 0 HcmV?d00001 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_9.png b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/frame_9.png new file mode 100644 index 0000000000000000000000000000000000000000..4f992440f2ad58f25b8e906392d358f25c546632 GIT binary patch literal 3485 zcmcIne~cVe9iO{aDCH>i8beW_)9Fb{xVQ8BXSzMMw@2@Qt<80@SFz#Vy!ZBQ?C#7k zGk3dp#&XzVHPRRbNh&4uA4F?gFriXuRH#29;R09O*~|qo^SS7w{q9J zAWn8?XWsj~@2~g$e!g$Nv2nxtD;9rxF~cxd^!29u>F)&n-n6Kd-nTw^Vm1A_%^e(>orJP2(G~XnY$oG1s-0T~o5CfC7miTPoz;&?+Ulid>66$HP3w zRv^)~B$tX6vICioY_}H>R!ax~34+Y(W7Jvg2YP_pa>9-xe+V@H(XVhkR~At96xeA zmyIPt+Z&0J9JRFSLcwo{b;DYiXu$Xq^m#EM#4c5U7&UPINRY26$A~9+QXp;=Qmoj( z(kNvz4fu>=3xx(cjCw|?MK#}MM2FcipYZ)8^hN?idPb?nRdvI{sGpn<%{-P_uKU?9CE{#`FcDh@9Lk3gejzprqu?0*z-HP~Ykf2#mZS>v{Ql?rf~v#!6B`WLIx? zTl5DX2i9 zxerWH$pKlEMF|sC&0(p&KJB5AIGy74)yl#iqB0u$U}4oJx{eG$L_-2ORgr*+MIB(G zD6$|65|re+w9f?&EpC`^mKs}ysYHbk4T;zWif%vvB?SYh(^tVHx@|&P5s1mL=k<1b zc`wL#m`0n*kN4T4;;E@HuB;>{)&>XSB+ZXh2X#rH7cFsm)#kU%F@JvgcGsaHrlE;5 z#j5DvL`jPppsA{?*2XtFC6XUVJ2Yxx)ey;Op4!qhr71BfREpE;bwZkMV>O!DMDD6R zmmtTg@s-&D#C!IhG>ZAEC_x!<3l)l zanlV|!lq#hK+p{h2#R6=+ZJu0%DRzL&75LjQg^-C^lJGimMmC;RTlV$fwwD~)KT401ZnY1^iyqS~5`i6q+^LbE&5%mx2vPmt%1lAtN8d>BC5 zKuHiLxm@5CSm^tC2UTi|A9Zo9FEz@MjXd@|`OF$IOaiAV0h+ZmOkh7oeRHPU{J8ML zmGWV>{`hu?k52_v0^t9f8>;W=Y8Y>hH>T2Ut(jP0zS&3HuSHpX4xZ2HP%&-Q0J^SA zK(Q4Ym?nK9wr$$70Yz1#JXf{G`(JrJPM}6^S@m|2qKzyj$*{&Q>)=p>XV%W#ofK0t z6-pcc$tDIGqP@;G3I>&73Ast8tU8iiK5o`HRP;f^0fsQl~0I^xPUh zHV(}6rE%mYF6Fs^9;lP~@na0r@>pLwl`Xyc&faI+cd%{ge@{Q+K7MV+ZvD)Ue)*?6 z4j((h-?Q&Y#O_?WZqZ75JMrTWzIfR;$G>vb_GP<2udiJB#5pGelgmH&%iSa8BUkRw z-)~*;%C~=h{H>RyHg4*zw#f(K>%ZAPx$o(=wdExXQ0KXkzoPe^yCHGYiz`|N@kCMM ze}C7R&QnL*-aer3DjPk_(%r9o;gam5S4|xl>6&i)6!XXa$9A+Z{ogI8pSzOTU4FE8 z*FEje{L25^*4BwX96Yph`j+;St%Kz3Kl?i#(K}M$?2F9)OZ!^O*WZ8Z%hxlhcgwAd z4w!dOuISACuDm2Q_WaBDv!||QiVVBpw-Zy7EvKD{wjbP{I^D5v@&1DgEar(NtGiyv zwhVrD&7Ot(9cF5J&%&Ku%xja+-1yqxm$>hod;Q_}&a~Y3wXL7rb8xxvl58mVmRBwN z*2(*hK9ss<|3ALmz2m8e&>g?#k9~iA$C>ZEaq?(x*VE4qj@w^fG5yB&2UB;hKk_(S zI{kL*)aI)@&`%fcd-W6d{_r~H)boGdbIC-Rgoi`sUtba)xb7+VvjcwH@&^v}+|vI3 jxfShahpst(;_~Bfp8m<^b4e3Mc2EY0r8r7C( literal 0 HcmV?d00001 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/meta.txt b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/meta.txt new file mode 100644 index 0000000000..5b0d0a4664 --- /dev/null +++ b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum1_128x64/meta.txt @@ -0,0 +1,14 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 16 +Active frames: 83 +Frames order: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 8 8 8 8 8 8 16 17 18 19 20 21 22 23 24 25 25 26 27 28 29 20 30 31 32 33 8 8 16 17 18 19 20 21 22 23 24 25 25 26 27 28 29 20 30 31 32 33 8 8 16 17 18 19 20 21 22 23 24 25 25 25 25 25 25 34 35 36 37 38 39 40 41 42 42 +Active cycles: 1 +Frame rate: 6 +Duration: 3600 +Active cooldown: 3 + +Bubble slots: 0 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_0.png b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_0.png new file mode 100644 index 0000000000000000000000000000000000000000..055618575ba442e601fb47363902d6a61ba6c3d9 GIT binary patch literal 3379 zcmcIne~1)S9N(3b{E<*fB%(Er1(v>@H@|=A>Yc872kv=z8=jfvn>TOv26uPHnYr6l zQrE7i{;G(G#4xA}A@C3F55@2oVMc*O78qu~)yUFBQVg*-yL;k~#vK!70>8C6g4iX;o_Y({_r?^sFzw)^KDRckXi2$ZaE3u9v_oMy;S3j0mFiDIk^#<5p1XM`ev`&4c(yI9U=(z z<(ongI`$9>qm`SWq~r_%jaKSV&sgXa6uN%Kb#nu`(=lKhBM1qenYqF#SZ*~uWK|M?hOq@? zhs~Q4=t=Y&@Y=jhP zK-x0jp(T!TjZ!14EGkhVM8Uje0x8;!1jzzOrLRyYs;MJUf<$MT8+sSIIoD6S7LB>c zGSO)pR6I2mMfH_r`PyVxl&ZO&>ZB?_`p`nBPi=kWFzYv#pC~vq!~)Ai`C?S`cT(!2 z1}L&D%C-3pr$lmHDThWas2U<@jY}&VmS|)mDvL_gXmtXbbn9zm(@ECVMmdM6RHcD% z)dw7$V)0fgcpHLn+_Chh49L4oVkS&{%2>fTj(WzLt=TzN3@d?KS;8+@8%ig zc{vAH%8TnQShWUKuSh0znH&5wWY8?)I}JI|sHJWKa~Jgun{gwf!+#gcptODW4vC9y z2vr*3Ze@t-d#W1A#nIVRI17NwjTYL@BB~5(9J2sr>ufV`@E#@Uf-X_|09e#5pkPS` zrlv`NSOSqXEFx9Jb1MPQIm61L6%2{U0~JF0g(Ms3GSq-3@s`4CyuuSY19TdE~f`sVkOpG`c>+`AZ^y57I;%;ITVnmW&2K5sp~HE88%+-RX!H?v^x6?lV z`nyjKw`}@z=--d%8dB2H-GADN{xO`jmMkrYd*NE zdk81C|(A)RRp;ceHn`^cm{*N;A*J<`_x(7D}DbK6g>>W}`dXLpXJ8`$ literal 0 HcmV?d00001 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_1.png b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_1.png new file mode 100644 index 0000000000000000000000000000000000000000..8a9791cae1a25996929be157ae465fc94c3f5e7b GIT binary patch literal 3406 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 Vzjn{cF8?o7eeK-n)>+N>{srXki=hAj literal 0 HcmV?d00001 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_11.png b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_11.png new file mode 100644 index 0000000000000000000000000000000000000000..00f572b44a1384c7936d7c276b4cfaec815dedf7 GIT binary patch literal 3473 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 literal 0 HcmV?d00001 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_13.png b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_13.png new file mode 100644 index 0000000000000000000000000000000000000000..11773d46e85810b7cfaf3fb26a61f6fa2cf8722c GIT binary patch literal 3431 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 literal 0 HcmV?d00001 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_16.png b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_16.png new file mode 100644 index 0000000000000000000000000000000000000000..609da5c6e8722a373599f9f89284f035029eab7a GIT binary patch literal 3551 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 A2><{9 literal 0 HcmV?d00001 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_19.png b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_19.png new file mode 100644 index 0000000000000000000000000000000000000000..f2f4d2aa755b50288c412c6470aee036127721a0 GIT binary patch literal 3513 zcmcgv3v3j}8D5|{0k+$SDwJA9Y?cs_HhVk!e!v07M{2j6Zs6N-EO4WoRYRv`rJy3Y?Hqq&`H1NTj4Cs38@7kVI*c76nBA-8-L; z*2Y%Tc6GP6JM+!|n*aa)x%)ahzSy+5c`-#%P3>*zE%3Vwz8eF7I;`tIIk@UYM6>J57{n+?m&C$a6CBw5aTfTpOm>&qUthDb=8WWXt;n0J15 zn4ujz#q`J-l<`{0pwl+$ldYp2UDoK3rQ6KN}Z6wgq#H8yFaJ;VT91=J|U;)7fBZUx`*+Q^#QbL*pmhX6> z;}+;hA~xM(m}0=viVJzKCbke%!vq22%Gl%hB#K;$fwon{c||`LE4M9<aR z9;aZtrQn9h@#+GS#vw^DkVq1X1XfVH1kn(AgBQPmcmtsdGy|z=;}F+_MHca0f?&vs zAq$s*UE9fy%nG$FBkTHk3>)X<@c`kx!a%GolQG&0L5K?$X-}sZFg58owqdGBMzT&= zWQi6_cu8fk4GF7@ifn2`;{{EgT%UHWVw6Xu=3GDH+7NS*p`+b4Ks=a=qxwoQe08ulO4VGkGN=j&E+}-ks`J}snV*{eO2L5; z3k)6QixKPJ3e*J#D6%X<$l~!%r%ZCaX$PVfR16Wc`l)SoQ;HN(LtLUpn-f6Nja12I zE4jV;lym5~Dh+H^e6XVQBsNnWcBa|kxy7;~wlqi}T31Nh3M_E5VF~-BWdK4vYguqJ z86V)`E1Ry#f~{*NVv(vTERrORHBH`RWl`0#vYwSRn@qZ1Z+curykv;TK+0qh{U@eZ z!)guU!T^CT#4#Vk87Zqk%4w{GG@G?-NoI8dH781fYFeVM@&wZ9-}hl!M))5)W4VQ4 z;@2gXhkXp4l=wl4$@*@d#-5jRthl_m;euUlP_>GrLzkZ7pBaN@6W^)JfqE@96X^e< zzF9MFZglv6-y|+NAyjC9`&Wjjyr(OXyeZn7xbqs*ae+3+9E4VE0JqP=_7ZOs-Xs=l z5u&lO3FWDqL}7Jal|±$ncMbg}l%l1(Y)zZtDY#J@l&LXM|svNTs57gLZ-Sj<5 z(gj@t`e32vY*w+L4oyvi9%Tze)+`aLqO~>-c+Qzs7A8C*BG0M_!3|5$IAtht4ML;v z8m~Z2&sCOUs=8{b77N72vjjuWGbK@FHB-iVRzYC3T_-EHu;MOv<+#Miy5lA|6%WA~ zHhQcbp5di-{3ZopJ0A|$k5NUQqUJr-Qg_8`Bprt$+AX_o~DL&z$Jq zJJMUcW&3yZKQ7(;>#H{|y!P(s_Wq9#cE9-eZErL@oxb%Dw_wGRt6ur?@>|{>?>zeS z14B#tS`K6uwcQ@z&Nn-nsm50hy)wG1^u0;cbO==|IWYcpq_v1AlIFEE%oZbPu+E< zsqf_c4T*{DwbbyDOCJV5zdAwvqm^2*XZNL}4XYC4ROh{Y%`d$A;^76u)@sZFy_=u5I7?=_d#0PZ%4l z{?e^~{?*2YGw;49F((%O;cL|0V?8U|DEh*4)V{{EV+WVL^n;0uqtss)t^dSC^N*Oe zrtNP8eYYLIAU(8v-@W3S*Eb&P2(7X4HO-H#d+6K69lzY+A7dUoxALjCPOV$Ks`cXa zXHKU7cKU;(pKbcn`N8}(dmE20OE*4y^26WWvGbmD=l8eGr%rtDOMS!C>78F+<516Y z55CSP`rW3)sXgzlPMrG8`zNk@_u`uC$^)PK{>u$}Msc@?kHvqk+BbEi4{Yqe^Pe9Q Blz;#L literal 0 HcmV?d00001 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_2.png b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_2.png new file mode 100644 index 0000000000000000000000000000000000000000..befa38a399043c949f4c3c549f54c3b09b3a1179 GIT binary patch literal 3434 zcmcgvdu$X%7{4}61hK{lJ|ITdZE7Gox9_Jtyt7xlMy}SjhJrzu-JR`idbhjX-L}We zo?;aI!x$4E5D|$+6eEd=22m8mL=rKI#3(9+h(ysuMaB4n>g>HZw55%&P48}Y<~QGK zzVG)<*LHT?(0J~wb0d*RV|yyug?|h96Q5F#zZbu7Y&QOx>ZTU@k;t^^;ioRL{?SYE z;AyL;H|R~zS9K>Bg@&V{Xg=p+bR^PpUEYOyKMDv9^;vd|{PvZdBw-mba)FSh({3xu zSgGY6>R#T_qc88*6@$EPF42-#v49*3Ad$~yZC}mD$f8^okHcw-B#MxrKSm}(g+y<< zlW283M2Jxu=rqj{k`iS^USOqb2$p7Piot&ZU?i27RgNXf4~eyThN*TX=aqHgw-}iT z0#~J|;o;%vFc)>aK8jHkg`!!CWdTM2f0-S?Jh1(yii9Ncbh1LRpkUcHmq{HVL6p!REE2nW>lIkLDM)j4H&>$Fb8O+hmlp5S2^hnuwz)}vI(Jv zu9}XQgZSXA9PC4sYxfnkrPFG=?FZ1-QF}5*VpF4*WvG&@8Jez$z?4i4a3)U!jZ+{n zO-6u*&O%AhD*Ka;J{TrdxW80ihNEK{)zeUshFA`A3XmCH1Ome=KofWo$OxI7q?-z> zvlVGKc@{2ln5~r>T4i8~JVK(*7#iRu83M@i27nTNr4=M;3gmbiDI{@PZ>y7aytHHB zm~$i%p0Zn{q*uJwuM8CoeA?rE$Z*a z)P)TY1%VUF^PN^6WqXqrj+$RGgq3TT7S=3@d`Jz&5>-={kCSd$nQXezKzWq4h+=%GX(4)KI#L5*j;4~Ncfx-77U zB5O3DC0PVC&&xp57!3%VB%6X_^0I*{uGgAgDk5A#v`UMWBKkX~m&2-OpxuXX7oy0& z?+ha_ri74=i;NWkGH_WakYRzLiHfd3g%JguhJQVWF&W`Mc1CyXA>`F0mJ2VBm##x%|GJ?%|M=2lLNI{swNQsqP__;ZgO<^zaJ76 z-VjPOK>e8^O7F>1BzDTVgOO+ z1)#|?k1LWzf~<2;;`Ekcz_ZqbvLIq;#4$jkY5WCw6DR^L1DR(Gk&zjZLF{B@iJGKH znxq3vYz#mU_dJc~Bp_=7R7{b^RvR_4iWZjKrOqCgBC_VXiJdA=;X7h&;>Ks={KG4>^vol-e{_6ZDt^VRHNT$U9NTf9x~KoQ8;;g@r@CG#?ECJ$ zjm?GCmqnZE*^XV zh{v}TzS|qAgLT_C6e9Jvy?Eg}7cFhx@iSW(eXHZ~U#1^7&)Iy@%hR?!wdCOR+g~dj zd1lSVfx_s%4zCg7 E2TeSG)Bpeg literal 0 HcmV?d00001 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_20.png b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_20.png new file mode 100644 index 0000000000000000000000000000000000000000..9ef9790f7eedfdfe7412674307894b66eb0e8c61 GIT binary patch literal 3546 zcmcIn4U81k9iP>TpdbPo8wqh7s-Dre^Zh9ccibLu)`b)H%7V7~X6DV^c)K&h%-r1` zmdkl)BZX>%wr86&K#S| zJ3I5<@BP2t|Nr~HUDvdD;glP0zkwi#DUFMgOYv_H{?<;s2H(H?#y@KC&m?crihv+) zoDqFv#LxS`i636I)0r@ndPp8htUKvXI|ceMjHxA9ktj_f;zivfFf-( zK`j?kOv6hbne%Q}IUPf!K98h(z3X^JdB z!nOoe7bzq&sV1`C^${t>8DKCBPs(bXl?0KK?$lLXs;V@@(HsXb0t8)72=l-RW|t)-QDFGC7uv2v zMiQa!wucD{TUvA>=T*cyK`Bf)V00dOG#h6kmkL1BsNlSIKU+|48Z^qH9CE?{W7!H8 zM=6!6z(*9D%T>@p*wBG3D)}}dI!JeUh+c{Ux7{~TLkHG4yKGnxE=89^GmhmLURmt5 zx}h7ix}yZ4GJQoTLfaZeVKj3E6y@zvpwUbP>S^^pf}!iDT{m0Kou;yFB*(>BvSzvM zm~LlqZ{&Ds0ZPIUB`BOo0$@16$!U()cvfTi`xsVZm?AWVQ`3YYtOoOdVbdI^iL%BD zSAbp9wz|fInucb%eh%V|vvaTo(Vo*%(3VPRjZP3k$3TtA1cgnF+qS9cx(*dtRj`>B z3v?tHKvh%$7%VGDyv173w94y~uF)PPRkXfXU#4qd8I|48I8NsgR0LpIoC*X<;DE|o zDlm9US4C5TmMoT~E%9w!;xJn+HL}XY5(R`LgEe&^$O;6I6HEYQ{K}|E)>X(03{olb zvfg?(>-s6z#4+b7GTLnoi^rzIsJ;>uTN=znshVvs4$2&ZFI?#OD$TDLWB&4Vvt#2B za}*ini&oIT3{w|2KoUhBJ6RZSvhygLN!mDSLD3LSsh(OAFf} zvka{&J!NgOP?Z`qiar=odLol54cjB^@c3d`6x-Q~aI~(HwnbRrT45*jQC$lT@t9>n zk7j%TJFafJB66mx=nP1Jzn8CXipF zzA-aye02EV#WEsoe|?)oM<;|L4bWd^h~j&)7|8|E-V{2oHWC+%HwSSm)-bn^!S(`c zB34HRFc89dtmE=jbtK`mmIWS@AmW7rGey$e|CQ~d9IB+3R&E+~xSd5*8I(9?K5VJ5 z&D@cDl%R5|fawD_CDjCyA&5X%aLYm_heXBTq0Ad|3IWgBW6FYvWf0E-nPKn^3KmdB zMga;Ajl?Rf#3F9IvLszrWnDG^CN>rzhf%qpwJFFjl`)pm4{=kI!6YqTb=ID0mJMTT1Iehxb<1g2o-8KD-AJ=T3`{J{H z{gw@nO``!W`=!@80gx3@yR9kAN-3atUYC% zKKSvYpU-%v`P2tL>pQbBR&&<{Wx~#%bnjoYst^Ac={d1G^Fr*v^h*z>eo(jk;`+u( z#GkhQedF_)TZwZkFY=RC4$gb{g_!r*tUql0@Wf$r{pTx)TecoLe)gWbh({0o^p)$# zzVA<;DHDf@%+V=5fH?HTw3X9hkMEeE4E&IIHTHV*0pERd=N)rzdE2_J<~Os9JDQHH z+dAv~`ENaY#2g&xp8oU`-0@@A)V{Wt$UhZ3Gw=GI1>tSPN9pAGp`q^D{=wRzzGsA4 zpM@8G|LNYh`oHMkz;BwfN=olrd}(LfO(*xy)N>b|wxwj9|uNL<))r1wzow80I>ADQeE-oU<>1!8FGOOM>x<2I!AzqQ@_ynb%i sfi_@% literal 0 HcmV?d00001 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_21.png b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_21.png new file mode 100644 index 0000000000000000000000000000000000000000..abc131243192364150d28d8eceefd45c6c18e34b GIT binary patch literal 3545 zcmcIn4R9P)9p98%E-?|YsIj818(_-7yZ!z&*Cx%SCT*_`X=qcN&hU2k?PcxV?sj*R zyF_ba(s9hlQ~}4CN(vMhJ~{}@$aHi7Tc+Z4=+LPZDO52q&S?E0;$TgOe#EzXm+KXi zCWE+>+mH8t@Bj7w|KI;*tZV&O8|s$T5d_iD*^%zX&td#)Ni4$mti)et`(Z^SQ;+daKuZ)TllxcMYBT^%Khc@LurqIqS}gT^)#k~+%TPKx@+a|bEX zHdEAQF~elMHq>W#4Ebo|(E1)@Xq%y$)XEiPb5X+r@+gF4F`sh+t(c->xf*_thG~k7 zA>pK%EXwS*U+Aje^zDv~ zL(EZRlrLJWe#zfybc1EG z*@(86-*Pq?SEUAxk`G3dp2(!i!}csYys%i7#1{Gxj@A{@wgd}YD=a`CwPtaM=Pe6* zF5?3@aAngKkuz0AX8$kUFKwo2wBmLaQDso(m{l-aVVf1R z_b5T-Q~}cmZgHv!Bm;LmT~P#pOb&^P!9$rhn&W`y?0IED#4?CyapPq04GI=eMMeP% z4voYrti&R2p|T`hR%Kl_046pTAc%XOF7Pr?bP=kS#9*t-TYIN=Dn;R6_x|Rk9gT~L-B(fWg=-JrU9<0W?N^F#ynnPk@#u^BZ@jsI zdp*%|>g1EJG@l3$?rvRiK;Hc3H(?FY(DHgC(KNYs*CQ`G*N!e5KL2X?{o9FzBfhcs zx1YP&eCA^<`_8Q#d-_n_(KFpkE=)eK=ZSk7HeL0Dq4!_N-1Hsmsb>yc!2^X~E<3)a^+%0s>h_K=b8OY8ta_I{a{m6Yxn58Y$b}Db}b!UO#ChX;%$o#y*F}kB>mWp iU%&gUJ=>2wOi%U0P0!Yhe=YjwtFwK5`l(fSj{FA@FswoV literal 0 HcmV?d00001 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_22.png b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_22.png new file mode 100644 index 0000000000000000000000000000000000000000..baac41dc79a7c8b838e827e4fcf5fd9826f456a2 GIT binary patch literal 3555 zcmcgve{dAl9p8W=KZ1oq73fgc)oD?Dx4(ZT7f5oXq|<{mIWe&Xef##^Wrw@lb9XOy zq@od{9qQQVw9}a?N^t75;}piWj?iE!(4ierJEe}ag&F+Ch<~(bhZ5;zBz?R0gQHDI z#{Ss3+uMEb^S-~{_xt(2+upJ6%k$?hn@dsD{Pwl6PVzfIzN=@?Aoq8xiIqf98*AkV=t z%g`aj-yCI{1BG;Vyn}9aTudtw4j_&bX;qK#iX;o_9kjp+9LtlB40zR$G(!~V^2HEs zu9Y-8V{K(!nta*f&d5tcw4eQEP||eOGQEqd&sqO zzU^e`Kq54qydPzVr6m_KxvJQ#R}K>i7+ZunmXC0OOCiugRa`FbrbFcxVsRR0aMt$- zmak$-l;ZI!d_u9AOcm|vB ztBZ5Jj_-KA&LlyoPG1oU-%d`VFqpXlii`Fn&|szt%^9sOhQ8w_94B4LosNoav>-%y zdc|FK)^ZBoZGq$E1vmzM9A!u%Nq`f8pe6*-5P5?aS8}|;aV2P+q^1RZSPK>b$0r2A zkX7=z0_<3Ja?6xZ3mHkr%|Nnob_S*}o6Dv`ZSlC#p7nf~MYuf{Wr(Q}+qMi&5g-x; z4wx24bYm$AbWxH3M97kn#32dtmGv#KG?c_D1PDP5Sdt_I z6UqueIu<3BOmezek+$BoNr}UBt<=COi%66(RuFHQKvFdbpdeWQs^pc^v1;m2lsK$2 z^ku!RPTFzfjzwZFGIX%p1`$t8g+YBq8R9}X*d3&5I$s)81&&;#(8*Pv@0nu$^7Nfq zn}k?k=pbK=P=6PpE@FTp%c5K!@34zF-5s+@)Vz`*f>t}#Q!}MV0X2jrYOJ+Al5|_j zWYdN3D?g=eI;=_qqLL3NNKb4r5Y6{>aNduTwB?HOEcjR5(P= zu)$;X@JwE+$8Ve^Z0C~0^Q7|+%wz!?Iveo zXL9KI#Ibc|!_er+f|l7g4+git?;R-|elE3DJ-xl{fYZ=)YyFA6GoBn>@xzN3?i>2( z#>FRZUH!t-^JWe;2-K3|{Y!5c=4LNncr3oV@sZ~D4@6;PXZ^!3et5QiE-x9vNHFx%}Ah&j!4PM9+r9pKSfw znPu0#R{xdx=i2`9PE#Fqk{bEjTx$Io?@@ z{^L-RE{s1v_VxWsuX$Wp^_k_T9y_utcjVNZ>*{)soa;Zad-&ReX1g$_x#h&`I~VPK z<=Lhg->1&}^FQCUaOU-AH*J5fWy7CF`>DbDmw)=) zl5^jEU$5|cEi%Tj?s%-k5g|SczyZl1rL1tkf&4Mj4ru& w_p$Z-;*_;#@#AgBXT9}cY@73&n};_2^4Y!PH!_C?g1=$yYu3f~wA{PxpAVF<3IG5A literal 0 HcmV?d00001 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_23.png b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_23.png new file mode 100644 index 0000000000000000000000000000000000000000..524c78534dcdfdc3ecced8f82c9acac8f4f78ec2 GIT binary patch literal 3536 zcmcgve{dAl9luMXMly78l7Wm?-7bGftMB&rPq>7Ti%F(jNRw*~qZZ!odzWmv+g)}y z$tA5cMX_bH(vDitsz66X$AZd;I_i{wIL=h3#$nX9#!A~^42(Z;V9Joz(zo}EqfJQ0 z{@A(O+kNlzzQ5l0`}w}x+|}7Of8LezB9X}aj`l=1`5h(Sgd7$E{Rv(3@PTn@%B(kh2=R$KG4k!cnS$3TM^rZtd zWuZ8IlayqWZVT?W+DAOxGt!wdN7k7dqMI72WjUP)$l?G}xopPv^<13J%hkzqILy#g z9ulmJ)6JnmsyEq1wKyK8)nYPi@L~LobC?-S7(@^p`qB25OcgfhSM~SVR?q<0YLzN*bZP0*#6>@gar0Y&vFCH zv8hlZG@OATP7_NDE@a)ZSlcg#i3E(vL6_lTZ0J%Rh|Dt19q=-F<;Y}k24}Gy_yo(9 zu_Q{#WEnoK*lf0p_Jh_zVo}kzY0-Xa*u_jY_MHLG#I1uwWvHvSco+tbmvWp;DR;U`woyDE0J3~-z#i6jD+2fUKv1zq5DPPm@sbe1hZlO#0}3}7W#Aovu^>b#`0 z$^~EtS?S?fp~%$Jj+cdGLB2E)iW0r+05^-A=d7zq{ z3Pedwi<%~y5XmKJt2~R8ILuT^4Xr{%qKL6xLpqCx<95do->S60J{p+P}pu|`wp z^|m+}$4feh#9W}MaJO|Lo|p>5`ij$Baj-W`)yzO)P~ll}kwPa|aennI^XI3(Wm_b~ zJWYl9qUZJZ5b7cZ$dV+Gkmbj_tQ^ktCM*&)zhDTjR!*(1n3Bbi8uBHow_83*y5S<( z^x*Zyr;J7At5Sz%!3Q%;PmJi|urB_3(2!2(uMWx$G}3JilYfFvktTGG;@ig3yGO4CUZaVbvJ1y*O}QW1R- z(~Ds>`=Q;3Nf%=1FYXK$SX0o1G!WBijuRRk zjy;IIio|lE2T3Qzo*$>vo|C1Z>t-x7UtY|hjfxGbT#;1ZQ0Mt)#-JhWSrs`@sikZJ z^AjHN23`x&3MADO0LxNgbW{K6PLRQ|wg1gMcWK{@v>&$ra5&mVd7&HAZt%)jka+w!~4Uizh$WXnWP z_5}6GcWyZSm*)=bkKn(3baK<%4@@1pe)6uRtu@=8dgM2CKd7GAwf(!tRd?Q!pzX7& zhG=r)#51+q8W&B~MGszjd#_U8y!Y&xs(p)Io%&tp=nLrc2S+!YGM7ewxb3aZpLthA zH%m`%{Aj}!hgY?YDb-!k)Y!SZqkn~?^V(}qE{q--pAdshk%h+bk5_JueEZP-uRguL zVe}vOwk|)_HrBMXA^FF3i=KaMO|0tm-`7+>&b+*_@w%RCTzB}%_m98!RCd|b^;=Hd zT-*Qt@x#}=^Kkd%f%gsxKfSqj!MQs(oC;1K`_+AQCw`=Uni3Dcv}$~n+IyOseDcfn z_buKxzUGr1)X~#5qaReI>LRyY_3*yPycRh*BBI?pcbr-I74x#Gq0L9CC$@73 f&)vQFk(VP+^isR3sQupy|8sS;b|&_&SiA9`x~j05 literal 0 HcmV?d00001 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_24.png b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_24.png new file mode 100644 index 0000000000000000000000000000000000000000..cd2ce13b087d3286878baf59f9b6440a3682d847 GIT binary patch literal 3563 zcmcgvdu$ZP8DEnYVke}j(ojRCvR#O56wlr4`ytLR&R`P`Biks4sua)e&fTrJyFKr& z?ZZv68}mqz9NMTr5)nb7zVaf9z%2-2(zp-QsG+T>qC#j~P$jobO#VqJp@Gici=(x% zl|EK?d%H8g`CjvVzi;k|4eQq|tXfh;9U|YxJLi%6BS$A|$xmgbb(2d` zcircIE2w7=RFj7vT3t~u8d;|qb}E2OTgQQHDnrl|wXz|bLB=@4`I#3_ch z%nY!$F45 zLA)&?rpZ@GM>axln}j|f;<6BLc-=)%PiZH^h! zI>M_9y2x9INqAmH3kLi9`vd)az;@z6R#nv?lnDDk7!(0G|crn@XgT7VL5@9 z7H1N+XS)e|h9H!tZwZBG#b!|G&)fpVS!)KUKU0Ecv{ep9p6ztmcCwf|8;Z8k92a2e z+J~*QY4^J;e8&q5a2RSo;3bKb z0jVVp@QNS;Rp(W}ih?Ofyur#kS6m;qjb1;g{Pp?zGHrv%DD8$O>AWb2iV0*%X8|$< z2vCg2ASTF|S1_q7PAp1mcPvukC|NGmx5^|E1&k$wHFY4!3Id1|On_wa3RNuYD&hr* zRffK)ca@#AorrCcnDY$n@3uz76H}32Um=Dq3`YG_P4?yoWe$>y6gs&I^P6Uwzd5}z zZIKX@(D?bH<@9$F>LLb6qR0~`bK@JVEKWwl7KxghH-uBlr#6*MNrF!exf0b{Ete$S z)&kjd;-11&(xP)!sUaipgW;zqHkrb(HO&ssEtYw){RvE>b(^%!!(2P&^& zqEBObA*@CMrQ?`%p&;|=onf(}sG_I7>|kLrl!EQ#8tCl9rJxuV7!=EHtQ6Mbe&4-{hYegJxpKD$9X# zEhQ7^|DwLxGj2|F_21$%mqAY%_<9F7GjI1+Gb`)9Q@7%oOOuOagWi5`^POKIx5?KBTHbu&mF?tq6c?3 z@92Df_vZJW9K61B(Qs35!~Od`>f@_DgUhJupN>8LljWbCc&es*;`qT{{xk4bzk|?d zwy#c}eF(y3d(Jf4!6SB<)S-FRKd)Ot4Z2I`@1YJsYRG$W zVDie>AFmtkq|WX;wKsd@?qikb_6@2v2kV)SYX1J$sr{d;=&pV1YW?Py7cU&rM{F<{ zs%c;F0`)EKrAuRfSboRE-jR>chZS$MSG;np{hreg{PD!`9p@k8ywR$^RMiXPC+7bK zOz|VN(s;CA`cIL}#i<1K^on=( zyt8BN!S@z?ck$6v14Elne_`?2b4Nd{f8!hCB5~fKsdpzIs-mWTe7y769huFeqo3R} z@yO?&tFFSe`}*czN#3=y@7vLJrxT;!yZBsBVxzrlN&osE{POJw{l8;vE$hRFo4X(T EClY$L>i_@% literal 0 HcmV?d00001 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_25.png b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_25.png new file mode 100644 index 0000000000000000000000000000000000000000..c91f67b9b74dfb193cf1d4222e8b471ee25d2e89 GIT binary patch literal 3547 zcmcIneQ*@z8Q-9Uue+(W9|E?+x;Qk|?(O&IYs)B;rqAA8j-w_d zW9`n}-tPPU-skImp5OD{eVyyq#uqMKNDxH4qdnCHzjwp;w)u15-gEffCiq$4wQmUs zV$tWKZv*kz5s8uV;=8_Hq3OGb$sgQR9y_BTNa&>r)h8c=1 zL&9xIswGlLcBebZR@cX*oM35_Wd%~v5}Yhbyz(`YXL*+4;3LtTqKm37@MQI(K$~x6 z^{!M~RTsP^slG7ubcQJwi;1F;aQz&^X`05cJj3%eAn0Jw2~ml5g5{GEQaCVu+Y4>i zAtQ;%aQnj~1(sG^D0nroPEZXK1dJ&mkKqz*6ll zd0B6(n|J-RYeCEfii~z!2k~Gkis~y#an-@@C{^?Ql|hAP;etYkt2)1BhWX3WUw3Q> zF;9_EzUXEB8-cpO09ld*sXE?imvFv2Wkb}0iXpsOKeeT9N){t(D3_?-ZU>NbgH^KG zh__dt@-|tnN*$RMAIvB{G3-!f*q&mCXBW%L`eGl3Xk8_3E3m-LhDGG#mK=n5#U{SM)*HFW4g`& z_UjVMLq38|iv1u-Wqr3mBG1d)X1TnW0mrH~s9Hsmp-W!opJ{_;Vc)LHfqE@96Ua|d z-;5bIJ39P$u}n$ZpWY@h(FvhK1I&LjMCCnIiDX-}H|5T&PsIhZ%|U3zI&k|8Y%g*a z<_rwY0%Mhy3@A^{z%s3IiYNdHVnHl3QzXs(U)es&p;~(BlTD)q+F3-EL6u`xqg;(` zR!-fcM2*)(pby#eu^QKAi16=`hoSW-;^DT3Kt4tU<4Q5M1+iv^BWSQc(b%+i{~ zLNkTX$ehZ_9Oh>$OEwfuF`)GVv2ip;(DMvYfOc$1&^~1rthVZ8l`X8e%UnG!Wn|rP z6Pzj!!5KDstR0@=rFQ(r4zQgMhwG6Ohu~!2@Onq8B~vV0bqId75uGos-?3)}8_S332uc%S{jAKES+ zdE`fY-{u$E8Z)`y&pZ9{(M?UnZ4GdRDXV6MO%1J@L@m;qE25@#9;F?yXM_ zFW$F;SdU)YIlg=8Ey-sVKlbZy#eX@ztT1-&-+!F*{*j*T&csiCcJk+^=($3J5??b(0ev%?p@lzG|U-bl9& zj;}f$A5Psu9B!CzHxc>R+b5S?94Ce@EG3T4dvIRI{&j=QHDj4g-l0?HzWI9Z!#nxJ z6FtpOwCKmRN8=ByU3TWDXWQQS@aapxJAch2Zuf%Cq{34V_(CccD-^ZL%jHfKfg-;_&~RQ`?6bO q@4Z8PWx-t&u>~(KxwrYFhLd-YPrc1Fo{Ii{b*x#RdU|#5cm4yq>Z$1f literal 0 HcmV?d00001 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_26.png b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_26.png new file mode 100644 index 0000000000000000000000000000000000000000..e952f09fea306c44a749e00a6378b00ee3bc33de GIT binary patch literal 3567 zcmcIn4{#LK8DA1=z$7yTW~>z~>srSUeYgMr%0U8$5X*&_9Fj1i?!J9{S-87hb~m|8 zq&3yhVr?TcPCDW+U>&QaN(M(;TH+9d4zx42IvpwK?FbbDeS3E~j+&5+ ztvh#nyYKzp_wW6_?|b)nOY`#D>uwRxtc zwZ`r)>cVePsxt^&ji$5NY$VG^94|?;s;bfqM{^v&2;lc*0zC&Z{;gvYV#tS{?FP1! zAw!9};dBL23R_xmA?=pLX8dB9aKPxC?$T_830=wqO<2OYU0y1$+=Mhrp)|?_KE|>o zERIqE0A#gxZ z7zyx(1w}zMEyWPVq^ZBYm?wB~{JVl1Ptzq%lR6WeED8&{B+e50Rx(b6b$KVSmI=+hY9h1yonO>c- zafmsJ4Edtv^|#^Dg$)!qK`0Z3{5pv4X7bp~fT*@uX=% zPh`BWcVF9dMdVCXF&MzeiUb%TB&Wd|K;&h`5>-o3Oia$tnvRo*O|XK-Gi6Eic}y?L zhMjsQiEtO9sn73>t|G-`AP+>7QGq223{XW&22e4fYC+6&XiVVDXDh-N>N@ z2`Y!XoFxLtt0s`3AOb^C1b|Eqi3;R(nTHGW0Z-YJ%F+?bAf5#>!{D1PSU9H{1t>T) z605Khi@2%Ek_=gu4H*Jl*jRvc-17{9mw{r4x@t)bw%RO{mAA0qE`9B|>{xgZ?!4<~z?-RNj|-@8RZO zUS7Al{^6r1Z&cHw<%^Y-ME~&mvD&P?y? zI7j^BXxlCAk8WRC(Xi|E`p4eBpBQ-1J68KnFV}DaJyq3m`0aVb?$cj;X-+kZZoB`l z`(Ey!d&8l@p>Leun_m8vnX@jfCI+iGqSJD>cWk^&^}YX_oili1UPkHqbL_60r}v$S zRv-D+N6A-}r+@b5Ganp0&@mdX+9SO<=fvnet9wp7n0yKT;17S__U1lcd-rwj_M>m{ zXj8+-RrSZ$9NsZB^6dG#n*QkU$+H_5-}}UCzkTjgZtISD^$Uhi9UeVhV-mmEDebK$ z&VKLIugLHJsD15C^EWTpa_&o`Tc+>7Ts!lFuYR}pUll9g&o+N2^}CVqFIm&F=Gf4Z HhaUY8B44}L literal 0 HcmV?d00001 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_27.png b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_27.png new file mode 100644 index 0000000000000000000000000000000000000000..ac093214b701ee7526c6d68a4375c0626b8e9869 GIT binary patch literal 3531 zcmcIn4R91!9p4-^h45huIzw@)%c7FDyxX_mA8<`Vj+!_eq~s`x)_QMu-zF<}yW8DO zazTMss4dfh&eV@lORbJpn2JKh5rJYU=!}XEGAOAIHSI9gevB4{P8pbrZ|{r4CL~kq z&fVVbd%ySpdjJ3L|87gyicidJn%6{8)XdI~^eXauANjUUO_2L%e)38)`I+W-^oA5Q zeNOyspuV|%E_vALWP75X%yQlI3Q1&n22K_WK0#B|l9r;6%(Xb84czCrDdvrX&oZ=Q zrI}3N>^XEgK{jReT#09cG7p%&x+rHxQV3*&xxlplVnct-@DAGl}H{UR&(< zdyyCRd*cM5HhonnBF7#_VLWpc6c?Rwpz%x%>g(+RMv)g}JuhF)ovx~FG|wkFx_OP` zTHa82OYC@M0ZyX`rx=n*B7i*Ll`Jpl0;hArZIII;EJHISH7yjOdayw7SqSwQuU-ZA zEXN+65Nesa?F9uyHqI%aKFs=VUrAdgqj$Ptgj^GMrc(?tHR(8(&O_DUk!b+S3B+Ha#8EVz_Y0n&plPX?ct}n|oiHzEA=$b4`&{i?28wmr^7CC?n4gt%S zELDJpAgg>;+RDHoC64m-Qe&$uB2mOxHaW`xqM{;zc+mn#A+J!wilHGvgqT=$MQ^*8 z_kxUPk(dh%9q+bI#1m6dTwf`Ms|@zUshS@s4=Ow)7b$ddRpxsqn7=Z;+I2{Xi8FD& z=q3H#gt~|UvLp#oWxUHN;(SlqAyEs8^#@OM>#j-4Rs2`JPT_bJFu+X!kAr#=YJ`&;y%Yq%x_z(?V z+jLdpElo8bfQl*uD2ggD49)oTv*>hjO)u-i_&%u$ukI z?Zc!CvCO-7hBFk7w@nk61{8s9#UODrD+ zh;&jMgek@jyaJ7UKkt~O@?r;FtJ0uq6-h@PeT9F<4Vr}mr!EKTwbV?Y-$Q*9X58fH z@SVjnCT+iWo5aQ^gfb1V|IHBP_jEaucf@;B>b&|`Trk-jB&}E{+&%%@i=2fy1Cxx# zSOtp)gEL`;3n}^Om(fr0i{_OlabL*R%K9+od-;la_ z&7#IluWewGufBZb+lL=NKjXf(t!>k&ecid-{?P-ChjSxuKiV{_aoeSl(JpS+$Z>e~ zg^lYjp7_91AKGU7=Pv#xH}9|Qvo{^zPu;!oA=Azj_|>_yo#wB(Pd?H#G@TAKUfe*kHDqd@=w literal 0 HcmV?d00001 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_28.png b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_28.png new file mode 100644 index 0000000000000000000000000000000000000000..d3cd31e51c468d1a5d8b7c43b87509d64b930f96 GIT binary patch literal 3552 zcmcIn4R9P~8Queo*ffA;z_c>3Zd*m@-u~bIkZVnH#RhX}NDfKIpZ43`?=EZac9-2v z?pkH+XlJyow(5)}0>z;+P+%-!EM=H#!L&nX6jY`eT4ScAV#k}QjYu6ETcEysf4xf5 zWDs}m_IAJT`QE?peV_NcP2F9eZ<@1U4nYu29V-$&@Vf!NpS$`BxPN6&@mBcxn7d+? zPY{jQhu;YC;KR-Eu**vI1%1g*&2Vy2WI8&I7IH4238H0L!9~Ve9FRKBSazKH`@R<` z(lX=Jy;71*y6w2%TCv{4z3aPD#`?8}YEsLVk}U-d1mtjl$U-h_`&uDRmE>yh91b%S zS%L&><5X*?knBr#lkJX&$yk)74VD#1S&ecrQR3w#B+v3J!@)+Ap(Xxm>{m5{)`;aP5A zIW`$eM7lE`_}>_X11iM9Pom>^(G0l5qpWkZ)rK+~w<+yO6JQf?Xy&f*-l10S$l z4GU39CTs91#pZG~v>z-V1dA%ZO^NnX>s-wAVBZ<=47_|0G%l-NPtwyp-c)tGUx%wTL;plD1@0>#+R**#_=N#3?W}YFVbnBSDfCU7-~$ zur$J=Nh>-l(xRandQ40UhNM>4CmdrSOsa5wxxP%t02#I2&|(~GsA?M1iel=tsERzT zN?4#JQ^aB{&0;ksRi&-;EGTi5t(O{FWr9Qz8hzF~X46m$;WnD#r2$CrB zqTY5V>v&1WgqRBy8Sb_Q;=xoD)>oY3DuaDts%8hugEG&;1%(b*Wq#ER^B1S@u`LKO zPmy81XeIrzpMVL{aVvLU=uKeeiEDkg^1P%2Svh2=xit*ekt zFTStxl(ooGRcgp6`(T9WiA}09Y)!Glvx{X}Y`z~uv@VmjWti`zgFNzZYX(9*V_7iM z8SkUP%bTu9ys1Ju(yXk+XjT*zTGu(9mIPTzOKMtFOk8!n-gGD;F2#wOz-nx)T0|ej z^h#Kbeq?7bbRmZN;Lez7RW}ggXfcfy+Js&MRU(_Tl*WQ$nvyKA@-)u8pAr7g&KQn8 zh`qYRa*>CilVZ=0Q)$o1k;rwkmQgA%X3#b(4XRd=WZ;k&`Dfaonb@=Ha-d#I%>?p8 z)Hh?s&5jP=Uo2D7_J_AgOn5>l(*X0|3{iehlp}d(xHqNFt4+lPv&}(h#Tsz?3~VoQ zCgyZ(&<2K#mUJjjRmU+}JeCwgK(b)8lmec$W|W06$6|q_WtN2-64TJ{ zSZJmYni!{WF%I*yl@-%vRn}#L24drAjG*V~q98*%mXMl`v0$}XC#z&(*OM(}CuzKeh3?w(xfDOZTTocK&L=eDkKw`yYDt+D#3odROgo zZ%h5-=^Mw^xVhU#PaHe*=6lEZ#&6%VdQMaEWOMVzi6_Q8Z$Qn9#+@ZYSKKgnvYkB0O#BWyL-8}K{gDdZ%dSAF7#{Tr`5 zMQk`S^3!X7z5Oj_^e@Gohazu%=9#v)KQ7HDZaG}^CQm)~*fZXZ8xA#RJC+iKrk6%- zVoBt>+mEJ)uUzw7L-DU)zJ}QBjun6SP4h$*Y*(#Z4DkDKS>Z9&;D)ONA@2)df)Ez+n(Ps zHvjoQFWqSmPcRdI;`3^J>B0L{PXnItzZ1=A0NGW`#AUY?+)b#62Cif$AU9^ zpExyd^w_z1mbvR+`LWgLe9I@25oNVSo!RsKLt6;<#aDOm#Q4ggKQ(SRzPWg?yTAR} uJwLzyd(D#`Wv6{xX=rYE6q_KT(7aTjYR zyR$Rz{oeoU{r|uJ+x4vr@0@)753i>vYH~|+yp8=29Hc2JUt;G3MOCLk#U$ zF=nxpfQf7)?s1w|c({GV!lb!ksi|4aoY{1JUMB+5I6!nhoyz!nKE@Q}>f|{bW*NEw z36{o~hEO5hk!YnGT@TZ86ao`MfmXCACyNrV+)ne5hb%`v65teFRCR%;OBX}5d6uoW z#pjoFk+&Gr69ieEWplY)G$%w|ubbsGO=BU?@;o32;4jYvC=W9J^sp29BGd zLy5?6dxIE5EG@c_&Q`=`{8E@mz}P&>vRo8~E){^5S;1v{y;MQDWwJPh(>N3O1j|*h zBua@y1wO3Ubh?7}gQh-WQOUPq(SCAy7PD>GcY8e(H}w&X)60hWK^wjtnlUUV@XF$B zj~lptk2^vTD$`elB5>>x6oxZbKyls~0UFL!pjo}q!zggQr0b^2xzk#8NuzGeW;5LdZHa{5lJNtSF>y;g#t>7Zj$`QvDM%Ec0C+=D zfuV`yrkDsw*tR8(*92KG%Io8<*&8NRxV~6lmTM9jmEF(xh@t+I$j5o6ipECYy&iU8t83m}EOLJcbhkuO55G4y4< zjc&^I60SvJE--Ys+d2_XOhsXR#Tc$M*b$~`s<$|(@Q_@j(8*Pr?;K_R^7OqKhlH4C z=rCXOg8p_wUBm!ck_4$V-sf$)uxjo;*y-G3s8r0xrn}r>7}rm zJt)(SNf%<7Z|)3d%9hfys#wsJ1MT?!y}h^T<$zk(~KDBmAG8G2Kib_No#q zi#$X+DfavrV|#9zM%ir2F$?9z_GPS6gQ`>{9k}#m{uwc77WSN~9H`b(F@gRT^^KZw zW23{b7t64;{q1cM8=eq~G{F8hLlocR#YoN%_omQ!_2IZ+tT{+pu}-*s6t)*R3v&iG zfr+sSB!iTvW?&g;oFWQ@1hF6%m?@Oz{;zBw=1?WQ^m5Z^Anh!qO25Q0^H6t%ZDtSO zqeP7-UCt(jCukOsO;G}ds)_(xJeE{bK#E}27XqGgMwNvy2eH5b1wwK|q75_&sz4>7 zkvWxpLp#sMMd6gi8mzke>$_}jT?@@n(<#=nlo8hOZT2S zzhfLe-#;bU^!bccPdmrvPWtiMDf7tf#PQGeO#S|uf4-le@!Zhvnx8h;?po9|aOBz6 zqtEA#EqVU#4ZquVVCy4y>(s@s1`ka*{5PsLIA%u<-}z*JgIIq?yMOaeG-bcL;MWbW zj$gBW=nwTL{`|o?7j2t=^PWrh8H0~3hJ!V;+o_GO7!#-MFh6zQ`}YSk#A`RLUir`v zv*yM~-5cFMI=JuSOUr70zx_9>PTjQOKI-X6-O<_9S7)D@v|T^AruH4`^uVlzpHsCT zwk@jPvhRB>oyL)i`ycpXOP%uiL;UIQuD+!W&pf%FYMb7*hmAHKJ-#T?`obq4J)os2 z`oP+!sJcx9Uu@*Bd3)=-D<)7c+H?2SOz8I~zH{oa*CJii;{&Ugtb6<6Ki=_I`v-T; z{E4&f7r5^1;#(iwS%d%Oj^CDyQ&4FB)xe-`H|D;qyL@bH`azr3Yo=;uq$PHk;JyZ6D*9@huAMpwQv zXYG(S@y+>>3kUZ!=eFK)@423hhlH2jdi1H2uWzfNE}Z=20QL7>lV+})M(uj}rpIPc r_3Y^zram$Ko(+VN zjbebmw^Qd;j(R|NCEW zZd)|}=t$=NwNcHk zk0~h*fdL^;$!eUH1d)@^qd3Sxh9!R@U}a5EG@heM7frPJrll=TUQp6Sz7lkI7-E2@FIbK?TlPJUq znk13{AO|?PgX1-x)mXj(vKoX%Xo{q!i9%Ej<^g0oSViMRja3c-yQXce7!zt5n&tW# zL^jUOpf1dKPFF!&Dy6kLL5Lg!woOUIZ$IDLs@lMs{8MERl>^tTi0A_hpJ z$cv@%HamyYok^QSEhrko5&sKI3R6p~rX(SvhC+#I3+#X--HH;~wBxHvZ)uwiOa56n_es;LF1tYrE(Gd6Vpp!HM)`0g-I7;=zs1E z)J2x$1_xw;<$;O?8K{uBg$)TqLANksrO}=F3nTo`&KR!Ki~Xv^@{o^6C&hk{pe^6c zP{{MrwoxcArq?k`4XRR+ROnI%`DfIinb^0ha-dpE#RTd<)Hi0vjgJohUMwTh_J6lY zOmsph(g5>UhA4g~i;=t_+M7b>)kfli@#Y|D#Tw!EG1%Uck)Z0L0%Td{fS?OHP*w7V zbzRkY1+k(;*sf@e`)}Dk%ArbnY2~KTMA}(Il|hMP=Ao_%+cb{cqXd;x1wtRd;8hby zh9Cl6Q3QZZ4vUJxBbhg57XqHP$CQOI3o*|E8A5VHq;aYuRDdF|ro<|&#A0r|vLszr zWnDG^AvP9Z6m?>Omw}>-NVOzLtTwA;6)Y^e%N#x~1!UE6lQ>lvB4^m>wQ_hSAC==b zb_m<~Z047?>>IQ)LTEhZ*b;OSGm$P3(sDEmqzazSas7!&u-hdp~3PuX%p^qr<;GJwPuz{`dDTsjc0~|F~uCb@{2+ zKKjresy+YU`P{x6YihTz>)%kqj+)qBnkI)NGPHTS`!3nZ-R`ox z_am8MKvJQlGtnaGSP|4e0uGfHsn}YT6sEO;wxvTWTCfb*nK~6Z9Z{?S^zGf{2sR;^ z`eWyAZ}+{=`~G_0@8|pOk+#;)*Ui0oE%>b zA}upYtq>DT!fismR`Y;|ItE&k#z3E;n$*%IWJ5v20x~FoWFeEbeXS6sigGpl91hbI zS%d_AQ7RTHBs&vrWRv3|Qi?FZU>Kg1)d(vIA}8NTatz1NEdGdql{G=pc#bSz6xQaM zDXl$zcUc#Hi&DKo;A%9T&*vj~KH_*iG^?sA&2Tiw0gM2Cza78=u>D)dB*c+#c$OPj zj!lLVq3&dZD1|L8xsY)yVr{=1CLA!j09~4mFriCDplMWaZq`c|m74~Q(kO%Mz{gm& zg2hovBr5O;#bz=Uv>zPm07e3Nd{}`K#&y(ASajr%J`L0k*uqb7Z{{c z%k$O zvMlJyjQ3&g+NLWaXR39~m4Br9k{893w>{+TprCi1LtIWS&J z#RT%dsBg-Qn;sqh-#3X4PY5L%p#PmAO7HPfB<~LQrr3G4iMU|8Ifz@ahPizTwij3v zu{ttHBMCPUS>Q1VB3>vmQz*^(PuV`qp-OsbV@)H5+gV7Jewkw$VNZo^ zmQ38EaDP$-Odr7DRTD^tAOc-c1b|EqiHgBPnKv4W0Z&^~%7Tbx5YGacVekzKDWHms z0u&q?iB(vMMci~{NxH1cx@-VUY%D+!_dH$TWuWLHR8taztv1KWDq2`_m%esfipX)t zP3%;02%llY$I9Uuzf_Lj$i{5v;lp*cd-#5Ws5;vck0lGgKfCS7yg{b6`h$P&7+z8R z$i4?YnOwAQ=aRP1Z=5BGEyVG2 z?>@A@rtMpo|6#xW&hO419NB(3=G^hr$_GFFX4Oj@hTh(Ix}6v~xc&=oEPr)I_p6(0 z8^88g_RMOV-tNe&s$wf%e(9&NKUUqPUsrwm@Q)5M)m7x)SN86+e|F=Zw`QCY8rx9Q zkHvMT_eZy87j4+R)n$*h&5>_BwDpN2=bgS;{r7zNPj8+0>h5EGL~r-0OXT3_cZl{? z(%bodLaE*I#F1ZZxn<@VbJI7aTz+lgO=sJ0zBIJf)!tVx{QT=nHyya8{lTYiOYL3w zmHLORS$7ld1J7T|a(_RymV4&O{mt2x*_vl|ygUmK$McVW@ZC=l=YI06 zL5!?<{f!*au=x8o4DPLa;kDQPc9a&hI=Pm#1%z4-4TUQ@v{v7@# NYgyJB-_zK={$EuJxt{<4 literal 0 HcmV?d00001 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_31.png b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_31.png new file mode 100644 index 0000000000000000000000000000000000000000..75229f9c482a1904f267905305cf77aa47da8b64 GIT binary patch literal 3409 zcmcInTWlQF86F!-li&zKc?bc)XiVAwIXh?WmwIuGH^dg*VB&4 zQ99b4ojK<_|Ly$$_n+N6vUSVqRqIx99JhLSD7OuMYw+E)q8sjaJb!!x{HzRzw#OWI z;SbVp7x&oXYvJK(zc8MR=YL|mK`BFM;IK@!6at##`ueLOad)tUci5y~&I%`Ac}?Jb znia;hJkE!MY|0a9j--%{_FX^stp24EFpZgR4m7KH7nHR+VGqXivnMV zBs;RgK&p@*&yVnfLBx1HgOQ7|!W&jb(p611Hu5r-u_(buLy}>urme_)^AbQ?L_K?3 z?#8Arc*_b?NfO$kSgBMp6(tiylcHow%Bsq3=;%QtddZaGB|aq4y0}y7fwgTx^n7@tjJ2NoWy{Y+E|EE zKHr8fD7I8;qvK@r3|Q3kZ9#Ngm<^e@jm5!q>?6TopRsd5ozE5q-(wU@U1Iex{Ba5gi zB8E(n!W1eQvg&xc)>@wn-03u_()Eq{qJaxC+Ph)P%yAS3`OYY%NYYdXIU3fGu1m6} zSya)f-ja56D$CR$7)KD)`d&rL=>1LZ`Gs=F^d@A~U zy((?uHhgf?^kh_M4*Lu2@bY5W5L=mI5Uq2hZ37kuUQ!_u8<>O;FIg7iV#dd0=G>;6 znoKRz!3Z0sjK&9J&tq&&%> z3yH$FcScdErJA0Fu;yW8GSxsPl@ugn#)xDQ&(oYmocSgr{GXk1gYpcEIua`+5rIz1 zqBtvfQBdMZ7#4lEUS8r%nKm0#yCV4{;Lq^SqCul9@;h>%Q%lC} z3)1#?w@G4pLTJ!{_;rS8yyqH`yfNLIdgrwl;)3PoAhco|xP1w>S0&0Mhq=gQ%tV?4 z71lG8fW zkgHe}>8`3F$23)FSu)d1S0RSt_SFMk^p})Hn1q=kAp>K$5!FMMhD~HbXmrVxbcxB! zm8Cm|WjKb5fY>C&2=qKhRe&TMjaZ(J!D`wet8QV#UGdy;sUtg%o8VM^2+pwSWBc$7 zFYV(uD+Aj_aJYW^}Tj%#2`nkMe zcJ8j%l%AOv4ovKt?^$*Dz{Z1XpE`Wi3x9ll-^6eJeaQQ;GJo&_h5O5%wYB2>`VVir zU`_4M58+zrgz_uyz2utiO;=2Odh3<7W1n5P#on#e_8mQbaE!aB>;C=yeJk%;!N;dx z>YLkjcPI)EARgdgB zel2(1(KmnB_4m7Hws!BoYTpB^-~ap%FW)l%?(mWRqr1ApvDe2go9bV2QSWDizxI^{F0f;PTSq?QftWM&wIao z|K9igzBjK=9(Zc=#?g(HN@epzqdo=qCHOtL;cmDdJ^R~sxZM{wj--{!rib$1U6oVs zY=MUlgVuC5-F({NQK!nh$Q9LYCkAw-vTIK_X8gFwBv;G?VNL$?%dcc9@M`j5y@{Lg zxR?zZClYb+#DNw+ah%(pyl1zxtLuP(j>wqQ?X<(x>DJ^zt^?2cup&zZBs*S{$8v?z zbaPS~j}jpnRg5^snq=BlVo+T*cSw=^8HL!ktzcDARRjo>E`}NFqA=YykWd#XPl7lLqEN~uGB=vbYBE^b zbDMSZF$CCen4{AllT39r}|rfV~eVqweDvflBi9VN}kgP4Q0`D!~L9!zC< zebr>rADqrpwLRAxG*t`-6gnLJ`6Fx0FHau|0|>DyOL@LHh5my;U0{Hr>zdvlpA5R9 zJzWnVYH809)f%2UGBjn-oEnM}bs9kmNw?T1n}g!T{!=@UimG%N@A<&<^c0@l9}ZSn z;q}F`Cw5_0K(ua=wmn!H`Pl+X#Mlgkc+Ij_j^S3tL(pAs4T#T@383HV?Qt}-_j|P+*8KU=I??rNd zzBWbYbynhn_2wY7Vh6Z=4YsGm6T}r9aUm?EyHK9CD-2{4lWIVMLZbyU<nb)%I&uZf$b95T%Y;%(aW$g|74;**6RNB z$HmVdT*42GjQw-z?2cC+JGb?vL*H~hNWbqL?aNnwe*A@VZ@%@zyWgJvYs>yK-{JRn zzjpqH^VE@9QS!-m#(rvzV6}Pf%FaZS`60Tgx7Xzc5;wy3u_8bihJXe8)11Y{O zQpojWy191Or<{_6z=BZXR6U6lEQ{)LPJ|*95c|jgsRq^zN#tr5&$Rh=&e)V*Thqnf zQha|HdWImBN~L5;O1gfZfOK6KpeTqUUX&0SQe#BCWcQa zwor)CLD(_GEUNi7Av(wodsNs&19#B3XvYxKxM^}C@P^t+P; zA)dY>6rq!wL}4^@1(cSZNube84E2n5pOVn^v#y&T&ze~K(lod z*f~lu%E_V*#qsrN*BXqHDq3HyFWa@4jCeN;(X=#-FaZj&Fpw3Dfv&3I#o@bNElL`=Pv7Qck`~FacvfJ ziRYr-Hkf#3Dv9bV#iQC_Pn4?p!RnwYLUyr2XIE{0+Z6Mcr?(Ux7Gf5fC|`_<{>_ZK zm;s6`OLA?z+bPq0PugKo3#x{QTK&|vx+w)m)KDo=qtgjk(hb+hW;1=f_LO(HN>v)f zs`_9>=}B$AHtbBW!_$jpRcxuBvS?i+ZL6@r&4nf6)3!bq;wj5Qn9TTq3|-rFO%`ok zGa-PgrT~bs222x~K$cW3C+j(^*>v3Xded1Ep)A6N1PvG$(e;>K3#-*nihY!IA%VYs zXLP6%6(b$kqJ@BHVIAlMu_}Q`gR)4Vl*5xab2TIU&(2tGafteLiRBTWuue+-AjRi= zx4;q4%R5%3yo8~mU29NrMRK9bUFM%jgJx6Tsmp1rg`Mtf7~yv9UaFx?zvt=M4PJ_XxjWK(2P3s{tDKsH%<>Lyiy zj#Ml$5~LEYFjFMW{jY2va{m>Pe;f3-|sFTI{VwI*2d18vaM$>bgwzI;?y5|dV2<1U;lgE%*As@&%3+Zau=F@ z{jzV~$xEN&XWoDK!Uxa4(9*K}=&{kWV}&Eiiw)ZTJq=o+_1oeq zi`!^-cIKS#{I~P}-+%Vr(UF^aSN~*nE|=>a9x85w-#Pf+ctJPZZ-4&Z8{lVEI5ZyT zazFfW`t8a+x_>P^Jmr(vm@x!lJ7dPwLLOE{ZNcz%KZ_)o9$ zoaYqy9cl@e!a+9a4eg59_FW@ox@(G>4&UF$ZLC`$pvn@$)vFahw(12wlWW0qIxO&9 z21%w0{6MOZ8!L@+gF(bNEsqh!SmtyyFKUV^>DO}-marhgM@6D;DTXCWT=U{VTjaRb zw&IqiE_f^OlSvX5i~@-;ahL=%E&nx=pyL6Q(4P(14=q>lV}eM>@-#WeE5#0z{b zl}PMhIw|mAX~TtT*cR)@%`id0ggOZYF^^N1GN41-xNthEWXc^XunMa(KZyY=wy_YU zQmGAJRBW}{M#stK8L+77+oI^WJR34$8;gVKh_cNypmBZ6usGSq&V*(K%K_eA98LyF z5Kjh61fe~BRwxqBT|!|xa~71QKuKqAG!n^QvTm386ocX)BeiVLwiYPuXy>z=NrI&vPu3+RSt_8)Xw|qJoj_ z$OK_i(sW&RU1n>o^~Hcrr%9ErZ`79)P>|8y4a+tSTXi)TsWx*FwG|iHqOKt#I+zlT zIgV+xq}>vEP~xQ0DK)jq0f`D@8WkNIDY`)rkrW3J9bU1?blW7df|<#4XY>vRl^`kw z4#ZsMxpcQJ5D%u3w7v?w*c=>7Q?)YP7}O;U7Zf^N&H3?V=Fd$3%=aL~63?aiVrBZb z19gD`nySibb9~gRv&vY}gQ&#~LnQD&TarzUcT8zYN)1_wT0>q8NjKXho9*nb=2OMv zvZ}NQZTLXb^kfd-9QGF3;g!X*A+|QjAX?{0+XgHS+@wY#HZTDpUbZZRrHqfs%(+cB zR0$Hs#t7?%hOnX-$hJirsj_aks_80*!&5^!huXUU*BEb=;Xpi@iR1nyhZw`|6(j1Ir| zO%l=*LW2f`|7D2Ad$AG8E$QB5o!4573s#zg(26bK_GQ>!5gjJlj3UYyq_qv@Y1&Lf zrl>12kRX$ljG0nt!8c|5G>6*hWwn~d0JO7|D&r={Y$6kFw&`2EM=7RcDnK8ILeU|O zDk`!KLqSlBOf{%XbeV3<0$%Z!l|`6{nJgk5W4ICMcczLBWI$*%(GWF}Nh_75*}AFQ zIz>QiB4Pyi!B%7)K}RK~t6{L(>5!FK*l<@kcU&@L$8i&!%7)+!n?AM=&+yVdels7~ zE`r1L-`{xnvs|ugaJV>7uD|oqzmEFz_`)skzqD|3P2 zNT-jlasROJ;3s?Ux#@;q-tqY*Z@)c%R2aYU@SfA7KlrmgwX;0%#C&DL!Qx21c2(D& zKK9z>t4=@P|7BnFyNAx})-E~mqt~C9z4o6k-nQdZ{|R!@{-a;Kb^h9(o=W~u^}xWP zM_%aazJQyXJ2rp(o$B1&=AQBSxm@?m&Q-5Iw(sZf?RrJqa^=>S?;pFYXKG)v@Wue% zIdtllhgUzj_K`hLuj`rLeeWE4{oR2>&tCVzm1~YHoc!ZQ_x-1aKkThudeKj(YRSR* z_ZPZ$gwIajzUIisSMS|@&7~)AIDX)c7eD!hiF%LxW9r1q2Oi&gZ1=BMy?5Vl_TPQp Y6~5lxb$I)m=^vfp%_GHUHr=`RD|}LEY5)KL literal 0 HcmV?d00001 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_4.png b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_4.png new file mode 100644 index 0000000000000000000000000000000000000000..27804f2506f014fa229ab5a45d2b5e47523f4cb9 GIT binary patch literal 3460 zcmcInYitx%6rQ%q%R&^55E9KephD#Cymub5w7>$baj`%R#Yp7N%-weE?#wVVZMTSu z2nM74P($J?1jP72(L{)7Fo1~4D-kiqXpDf0K@(7k#99SCv%6guY-xiy*`1xa_q*qH z&-u>XM;m6%96oH!Fp8pv*ViTI!0%G{)()wJ`-08K#>3B0uWo)oQCD0YeJiMEpC1hm zuh@-EVN>dM-E^}tY`F%B<+2{2DQZ$p&ckLa32B2g+fIV{dFytDwygv+Pfl?uZyIT_ z>lXWD?&4XE=HgaUvzVI6^rV~)0t@^W=}j)qx=&O^f11T!U4NH?V# z=xMG`=y;4nCdY}iqQ&^QBn!$!THpkZ<>4bEUeP607X`X_F`&)2()yg_jG``hOE4{A z=;5M!?2%<`J1v7EpP0s;gII-L;bkQ0pUk&q;T>DyjtyAB;m#D?1zCK#}^ z;6m0biFJZvm>^(m4tp#g<06;xK+7!Qyf#0RS8kas$&f5@!T_**2@6q5rAqK##b&c5 zbP!H&2aAfn^@4@1 zClsNb?n7ZTa}Jc`>^`8;ObP1g(|m$M*Kc&)Oi%7K^w>rVLX4-!&$AuN?Fc4Bju#h@ zBo0Y}fkcuJCm=y-6hvL*bzZ!M<8_WJKvR&K77lSaSVSD($g8>_>w^tbDHzoQYpRO2}10cq&}Hoz|@#+Te_esan2$t5;ZA}I3lUYFa&~l zjwghdB+*oip7lxBY>SdAT3@Iy%QZnpX*YD4q~oe26C}mKZPAbnr16G|G(}WYB66}} z6?_M4?(l6Wahxfa8d+t5M2V2N$y)}J6cr;ZNEX5hymA^*3=NACM>K{$t9P24as8BQ zLCi&lj&?f|52oU%z7h;y9BhhGHPcoYR0Iw#D0H}r^YiWSWvTL@g*7BBwE$IwZMA0(Kx z?`CQ2c^TWxmlxaaSj7fasz^F?>9hRPXV5I-+hsXWuBBuGeF^pTn{fl9!+#e`ue5#X zHi?Z+2n8Bo&u56jd$JJ88PVS4JFngw7YsB9p%v@E?ftNQTEUVAnTr%f5s;K;dkvn5 z0XZ$In3vZ&E(#Dl%xro1oVMSQL|9o zlw@S6s)UFo5Lq=vtcd2Me84kyzp^mlIU@2%;W)TqXrY?SsYsQ0E6%HYoF~FSWyK9e zQw+sKKx{lB7hu{nwJ(dp7@KQQ{ z69?GNhr{)n7Y6whRk5r-Ii)f8)$!-Q98q~g_4GgguG#30+gp8LMdgvN2VcEM{ph~C z#_t=y?8>P_ZdeYtb=gxt4t?y0?(1_m`hR>gd`aD9O>h3RGP7mswcGc~N8A1y`-=J0 zu!Ab~`RPRuUQ3PM)%9%!^)NMazghck^`KXO?P_A*-*IeN`-#^oJA9=KHqy6UA5t0`x(tY>e z`Qiuk$ffIU9eMPT3To%hLr-0{h5F^U8h3)QMj7`|?5|eps~Jx&oJp(-pN$sYD!%fr~ytKNZYGtZ&!`f5S(}P#OJnAI1@TT{2qj#KM zU0>T(b=Vr@ezcl|6=feEXqamQW|$*_Gd(xoyxp+b^&B`kq6hj-0uz!+UV^rpZU&Ubv%s*TEZ) oZ`yt0rfoMrak%EYhR3(9U(vmG?dp{iqyI_u(`O~$n7VM;KUBqu#sB~S literal 0 HcmV?d00001 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_5.png b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_5.png new file mode 100644 index 0000000000000000000000000000000000000000..7799b20aa2412bab14f861647a82944e91d6259b GIT binary patch literal 3475 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 literal 0 HcmV?d00001 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_8.png b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_8.png new file mode 100644 index 0000000000000000000000000000000000000000..926ff0911518cfa96860fdc73557bfc04ebf6537 GIT binary patch literal 3518 zcmcIndyEy;8K0|oWi41rC4i4~7)Xo7bLY(a5iZNJ7uaokVS%+SD#DpLXLd*Ky)(|t z?!6F+n?m}~c74Q@LU?S_60vPe8?}|z&0>s+;-mB*r4J>R6g9Ce;$w*}-JZEGE_RpQ zSUb6Q?#wyA^S#dZ{l0U5(6MIq%&V@wieZ?U?QNO$^tYdWmruWp-Zwq*_G0?e{7e}=P z*fG~lN5oBC@>RD9uqzD=y^yy4XTk4HFF*UqU`Fq+sk)8HnvV&hHI!W#!oBNsi=6Aqpv0 zsAFlAve`O(T(S9l9UVq1`=~`#-^N9Uo!flEuP33`8`xxJAJw?9W>^@lCl^99h2<1p zU+njIkr(!O69l0?eNiYP*O@?JJaZA0l-voR@k|}+o2>yskr#A&Uapoq9W~onQA`Q! z;#=GT_KM++vE$VRB!eQ7=4c|x0E$4=Iz`Ep1XGZfK*5Bt0?pFY#3(|IUQ_xLO zH6`UDu!mh|+oVuzn~oRc5#2a9kGcu(7rM*ZvRSje5JsqAllDxSqo$@@7n_>uC@ORi zaAe{DEXgXc9B2RmVo0!VX|^NR)@MAsH%_W}eWkvzXHyyV-7p%(g3LGDuA-A1IrR-V5&JtTd_&GeKNM!kZf3r z4m3>@fo#bZFbw)cEX%MY9SMp`*{))Z_rJ1zoI~~WGHXqvg|@SpD#I$rtU%p$wpliQ zkCF}1kSTotTQV?EZCL@9uFHU6ktn(?Ax*NEmII!1CzXYW0Er|34MKWDaZM{w2f8d^ zRnP@hAmUVIsg`DFwBG_sYyu#N_B>0LXaltrWH>6MR^tX)WeY3r@|TWF8QE~$q)wHG z=ovPCtRJ4~Oa1sw3Y6^vdbsZY?vo0`B%W^1v~-sK{EvNq8Q2MDWZoZZ&YtYJV&K>N zo96!grDwl!2&{YS#K7enZ*85vVAre_^mcsflbf3EJNakEcn&3o4V)(Wv+UNeJ=5{SMLAhapvgqQ!h?u=9LDf-M0Je^=F!A{igW(?zKNT zy$2ot(T;;Hee>`B=!WDfp#I|6GlSr(!-@3pwEhPZL&a0#4cf`)&Zla~u?018IHMb<0R}=5NxaaH4FL&M7KDamOkG-&n9Zj4e z$)VFjeZD(#-N>$!UmVPynDeDS-J7^Pz4O^e{o$2=dvO0=Q}pd0g3YJne^~7+*JK`B IvE@7e0U=bJO#lD@ literal 0 HcmV?d00001 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_9.png b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/frame_9.png new file mode 100644 index 0000000000000000000000000000000000000000..4f992440f2ad58f25b8e906392d358f25c546632 GIT binary patch literal 3485 zcmcIne~cVe9iO{aDCH>i8beW_)9Fb{xVQ8BXSzMMw@2@Qt<80@SFz#Vy!ZBQ?C#7k zGk3dp#&XzVHPRRbNh&4uA4F?gFriXuRH#29;R09O*~|qo^SS7w{q9J zAWn8?XWsj~@2~g$e!g$Nv2nxtD;9rxF~cxd^!29u>F)&n-n6Kd-nTw^Vm1A_%^e(>orJP2(G~XnY$oG1s-0T~o5CfC7miTPoz;&?+Ulid>66$HP3w zRv^)~B$tX6vICioY_}H>R!ax~34+Y(W7Jvg2YP_pa>9-xe+V@H(XVhkR~At96xeA zmyIPt+Z&0J9JRFSLcwo{b;DYiXu$Xq^m#EM#4c5U7&UPINRY26$A~9+QXp;=Qmoj( z(kNvz4fu>=3xx(cjCw|?MK#}MM2FcipYZ)8^hN?idPb?nRdvI{sGpn<%{-P_uKU?9CE{#`FcDh@9Lk3gejzprqu?0*z-HP~Ykf2#mZS>v{Ql?rf~v#!6B`WLIx? zTl5DX2i9 zxerWH$pKlEMF|sC&0(p&KJB5AIGy74)yl#iqB0u$U}4oJx{eG$L_-2ORgr*+MIB(G zD6$|65|re+w9f?&EpC`^mKs}ysYHbk4T;zWif%vvB?SYh(^tVHx@|&P5s1mL=k<1b zc`wL#m`0n*kN4T4;;E@HuB;>{)&>XSB+ZXh2X#rH7cFsm)#kU%F@JvgcGsaHrlE;5 z#j5DvL`jPppsA{?*2XtFC6XUVJ2Yxx)ey;Op4!qhr71BfREpE;bwZkMV>O!DMDD6R zmmtTg@s-&D#C!IhG>ZAEC_x!<3l)l zanlV|!lq#hK+p{h2#R6=+ZJu0%DRzL&75LjQg^-C^lJGimMmC;RTlV$fwwD~)KT401ZnY1^iyqS~5`i6q+^LbE&5%mx2vPmt%1lAtN8d>BC5 zKuHiLxm@5CSm^tC2UTi|A9Zo9FEz@MjXd@|`OF$IOaiAV0h+ZmOkh7oeRHPU{J8ML zmGWV>{`hu?k52_v0^t9f8>;W=Y8Y>hH>T2Ut(jP0zS&3HuSHpX4xZ2HP%&-Q0J^SA zK(Q4Ym?nK9wr$$70Yz1#JXf{G`(JrJPM}6^S@m|2qKzyj$*{&Q>)=p>XV%W#ofK0t z6-pcc$tDIGqP@;G3I>&73Ast8tU8iiK5o`HRP;f^0fsQl~0I^xPUh zHV(}6rE%mYF6Fs^9;lP~@na0r@>pLwl`Xyc&faI+cd%{ge@{Q+K7MV+ZvD)Ue)*?6 z4j((h-?Q&Y#O_?WZqZ75JMrTWzIfR;$G>vb_GP<2udiJB#5pGelgmH&%iSa8BUkRw z-)~*;%C~=h{H>RyHg4*zw#f(K>%ZAPx$o(=wdExXQ0KXkzoPe^yCHGYiz`|N@kCMM ze}C7R&QnL*-aer3DjPk_(%r9o;gam5S4|xl>6&i)6!XXa$9A+Z{ogI8pSzOTU4FE8 z*FEje{L25^*4BwX96Yph`j+;St%Kz3Kl?i#(K}M$?2F9)OZ!^O*WZ8Z%hxlhcgwAd z4w!dOuISACuDm2Q_WaBDv!||QiVVBpw-Zy7EvKD{wjbP{I^D5v@&1DgEar(NtGiyv zwhVrD&7Ot(9cF5J&%&Ku%xja+-1yqxm$>hod;Q_}&a~Y3wXL7rb8xxvl58mVmRBwN z*2(*hK9ss<|3ALmz2m8e&>g?#k9~iA$C>ZEaq?(x*VE4qj@w^fG5yB&2UB;hKk_(S zI{kL*)aI)@&`%fcd-W6d{_r~H)boGdbIC-Rgoi`sUtba)xb7+VvjcwH@&^v}+|vI3 jxfShahpst(;_~Bfp8m<^b4e3Mc2EY0r8r7C( literal 0 HcmV?d00001 diff --git a/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/meta.txt b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/meta.txt new file mode 100644 index 0000000000..165bf758ed --- /dev/null +++ b/assets/packs/Momentum/Anims/Kuronons_CFW_Momentum2_128x64/meta.txt @@ -0,0 +1,15 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 32 +Active frames: 132 +Frames order: 0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 11 11 12 12 13 13 14 14 15 15 0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 8 8 8 8 16 16 16 17 17 17 18 18 18 19 19 19 20 20 21 21 22 22 8 8 16 17 18 19 20 21 22 8 16 17 18 19 20 21 22 16 18 20 22 8 17 19 21 16 18 20 22 8 17 19 21 24 27 30 25 28 23 26 29 24 27 30 25 28 23 26 29 24 27 30 25 28 23 27 24 28 25 29 26 30 27 23 28 24 29 25 30 26 23 31 32 32 33 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 +Active cycles: 1 +Frame rate: 12 +Duration: 3600 +Active cooldown: 3 + +Bubble slots: 0 + diff --git a/assets/packs/Momentum/Anims/manifest.txt b/assets/packs/Momentum/Anims/manifest.txt new file mode 100644 index 0000000000..70b59e0157 --- /dev/null +++ b/assets/packs/Momentum/Anims/manifest.txt @@ -0,0 +1,16 @@ +Filetype: Flipper Animation Manifest +Version: 1 + +Name: Kuronons_CFW_Momentum1_128x64 +Min butthurt: 0 +Max butthurt: 18 +Min level: 1 +Max level: 30 +Weight: 3 + +Name: Kuronons_CFW_Momentum2_128x64 +Min butthurt: 0 +Max butthurt: 18 +Min level: 1 +Max level: 30 +Weight: 3 \ No newline at end of file diff --git a/assets/packs/ReadMe.md b/assets/packs/ReadMe.md index 7dd7f80fb8..cb4ca1ec43 100644 --- a/assets/packs/ReadMe.md +++ b/assets/packs/ReadMe.md @@ -1,6 +1,13 @@ # Pre-included Asset Packs -Includes a WatchDogs asset pack by default. Credits: -- [WrenchAtHome](https://github.com/wrenchathome) for some [desktop anims](https://github.com/wrenchathome/flip0anims) -- [u/Cheroon](https://www.reddit.com/user/Cheroon/) for the [passport portait](https://www.reddit.com/r/watch_dogs/comments/50n046/pixel_art_wrench_mask_gif/) -- [WillyJL](https://github.com/Willy-JL) for other assets, icons and animations +- **`Momentum`** - Credits: + - [Kuronons](https://github.com/Kuronons) for the [desktop animations](https://github.com/Kuronons/FZ_graphics/tree/main/Animations/Custom_Firmwares) + - [Kuronons](https://github.com/Kuronons) for the [passport background](https://github.com/Kuronons/FZ_graphics/tree/main/Passport%20background) (not in asset pack, it's in base firmware) + +- **`WatchDogs`** - Credits: + - [WrenchAtHome](https://github.com/wrenchathome) for some [desktop animations](https://github.com/wrenchathome/flip0anims) + - [u/Cheroon](https://www.reddit.com/user/Cheroon/) for the [passport portait](https://www.reddit.com/r/watch_dogs/comments/50n046/pixel_art_wrench_mask_gif/) + - [David Libeau](https://davidlibeau.fr/) for the [primary font (hacked)](http://bit.ly/WatchDogsFont) + - [Gissio](https://github.com/Gissio) for the [secondary font (tiny5)](https://github.com/Gissio/font_tiny5) + - Ife Mena for the [keyboard font (3x5im)](https://www.pentacom.jp/pentacom/bitfontmaker2/gallery/?id=7785) + - [WillyJL](https://github.com/Willy-JL) for other assets, icons and animations (mostly converted from game assets) From 384c3f14d8b19e030403f34864fa274f57c3a8cb Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Sun, 3 Mar 2024 04:14:38 +0000 Subject: [PATCH 19/35] BadKB allow overriding mode+options with ID/BT_ID cmd (the right way) --- .../main/bad_kb/helpers/ducky_script.c | 1 + .../main/bad_kb/scenes/bad_kb_scene_config.c | 38 +++++++------------ .../scenes/bad_kb_scene_config_bt_mac.c | 13 ++++++- .../scenes/bad_kb_scene_config_bt_name.c | 13 ++++++- .../scenes/bad_kb_scene_config_usb_name.c | 28 ++++++++++++-- .../scenes/bad_kb_scene_config_usb_vidpid.c | 15 +++++++- 6 files changed, 77 insertions(+), 31 deletions(-) diff --git a/applications/main/bad_kb/helpers/ducky_script.c b/applications/main/bad_kb/helpers/ducky_script.c index b94ab73b3d..e7f41b3ed3 100644 --- a/applications/main/bad_kb/helpers/ducky_script.c +++ b/applications/main/bad_kb/helpers/ducky_script.c @@ -382,6 +382,7 @@ static void ducky_script_preload(BadKbScript* bad_kb, File* script_file) { app->has_usb_id = strncmp(line_tmp, ducky_cmd_id, strlen(ducky_cmd_id)) == 0; app->has_bt_id = strncmp(line_tmp, ducky_cmd_bt_id, strlen(ducky_cmd_bt_id)) == 0; + // Auto-switch to mode chosen with ID/BT_ID, can override manually in config screen if(app->has_usb_id) { app->is_bt = false; app->set_usb_id = ducky_set_usb_id(bad_kb, &line_tmp[strlen(ducky_cmd_id) + 1]); diff --git a/applications/main/bad_kb/scenes/bad_kb_scene_config.c b/applications/main/bad_kb/scenes/bad_kb_scene_config.c index ca5ec64000..3083e86960 100644 --- a/applications/main/bad_kb/scenes/bad_kb_scene_config.c +++ b/applications/main/bad_kb/scenes/bad_kb_scene_config.c @@ -52,11 +52,6 @@ void bad_kb_scene_config_on_enter(void* context) { var_item_list, "Connection", 2, bad_kb_scene_config_connection_callback, bad_kb); variable_item_set_current_value_index(item, bad_kb->is_bt); variable_item_set_current_value_text(item, bad_kb->is_bt ? "BT" : "USB"); - if(bad_kb->has_usb_id) { - variable_item_set_locked(item, true, "Script has\nID cmd!\nLocked to\nUSB Mode!"); - } else if(bad_kb->has_bt_id) { - variable_item_set_locked(item, true, "Script has\nBT_ID cmd!\nLocked to\nBT Mode!"); - } if(bad_kb->is_bt) { item = variable_item_list_add( @@ -65,43 +60,24 @@ void bad_kb_scene_config_on_enter(void* context) { variable_item_set_current_value_text(item, bad_kb->bt_remember ? "ON" : "OFF"); item = variable_item_list_add(var_item_list, "BT Device Name", 0, NULL, bad_kb); - if(bad_kb->set_bt_id) { - variable_item_set_locked(item, true, "Script has\nBT_ID cmd!\nLocked to\nset Name!"); - } item = variable_item_list_add(var_item_list, "BT MAC Address", 0, NULL, bad_kb); if(bad_kb->bt_remember) { variable_item_set_locked(item, true, "Remember\nmust be Off!"); - } else if(bad_kb->set_bt_id) { - variable_item_set_locked(item, true, "Script has\nBT_ID cmd!\nLocked to\nset MAC!"); } item = variable_item_list_add(var_item_list, "Randomize BT MAC", 0, NULL, bad_kb); if(bad_kb->bt_remember) { variable_item_set_locked(item, true, "Remember\nmust be Off!"); - } else if(bad_kb->set_bt_id) { - variable_item_set_locked(item, true, "Script has\nBT_ID cmd!\nLocked to\nset MAC!"); } } else { item = variable_item_list_add(var_item_list, "USB Manufacturer", 0, NULL, bad_kb); - if(bad_kb->set_usb_id) { - variable_item_set_locked(item, true, "Script has\nID cmd!\nLocked to\nset Mname!"); - } item = variable_item_list_add(var_item_list, "USB Product Name", 0, NULL, bad_kb); - if(bad_kb->set_usb_id) { - variable_item_set_locked(item, true, "Script has\nID cmd!\nLocked to\nset Pname!"); - } item = variable_item_list_add(var_item_list, "USB VID and PID", 0, NULL, bad_kb); - if(bad_kb->set_usb_id) { - variable_item_set_locked(item, true, "Script has\nID cmd!\nLocked to\nset IDs!"); - } item = variable_item_list_add(var_item_list, "Randomize USB VID:PID", 0, NULL, bad_kb); - if(bad_kb->set_usb_id) { - variable_item_set_locked(item, true, "Script has\nID cmd!\nLocked to\nset IDs!"); - } } variable_item_list_set_enter_callback( @@ -142,7 +118,15 @@ bool bad_kb_scene_config_on_event(void* context, SceneManagerEvent event) { scene_manager_next_scene(bad_kb->scene_manager, BadKbSceneConfigBtMac); break; case VarItemListIndexBtRandomizeMac: + // Set user config and remember furi_hal_random_fill_buf(bad_kb->config.ble.mac, sizeof(bad_kb->config.ble.mac)); + // Apply to ID config so its temporarily overridden + if(bad_kb->set_bt_id) { + memcpy( + bad_kb->id_config.ble.mac, + bad_kb->config.ble.mac, + sizeof(bad_kb->id_config.ble.mac)); + } bad_kb_config_refresh(bad_kb); break; default: @@ -166,8 +150,14 @@ bool bad_kb_scene_config_on_event(void* context, SceneManagerEvent event) { case VarItemListIndexUsbRandomizeVidPid: furi_hal_random_fill_buf( (void*)bad_kb->usb_vidpid_buf, sizeof(bad_kb->usb_vidpid_buf)); + // Set user config and remember bad_kb->config.usb.vid = bad_kb->usb_vidpid_buf[0]; bad_kb->config.usb.pid = bad_kb->usb_vidpid_buf[1]; + // Apply to ID config so its temporarily overridden + if(bad_kb->set_usb_id) { + bad_kb->id_config.usb.vid = bad_kb->config.usb.vid; + bad_kb->id_config.usb.pid = bad_kb->config.usb.pid; + } bad_kb_config_refresh(bad_kb); break; default: diff --git a/applications/main/bad_kb/scenes/bad_kb_scene_config_bt_mac.c b/applications/main/bad_kb/scenes/bad_kb_scene_config_bt_mac.c index 5439c0bc4c..ea9849448e 100644 --- a/applications/main/bad_kb/scenes/bad_kb_scene_config_bt_mac.c +++ b/applications/main/bad_kb/scenes/bad_kb_scene_config_bt_mac.c @@ -10,7 +10,10 @@ void bad_kb_scene_config_bt_mac_on_enter(void* context) { BadKbApp* bad_kb = context; ByteInput* byte_input = bad_kb->byte_input; - memcpy(bad_kb->bt_mac_buf, bad_kb->config.ble.mac, sizeof(bad_kb->bt_mac_buf)); + memcpy( + bad_kb->bt_mac_buf, + bad_kb->set_bt_id ? bad_kb->id_config.ble.mac : bad_kb->config.ble.mac, + sizeof(bad_kb->bt_mac_buf)); furi_hal_bt_reverse_mac_addr(bad_kb->bt_mac_buf); byte_input_set_header_text(byte_input, "Set BT MAC address"); @@ -33,7 +36,15 @@ bool bad_kb_scene_config_bt_mac_on_event(void* context, SceneManagerEvent event) consumed = true; if(event.event == BadKbAppCustomEventByteInputDone) { furi_hal_bt_reverse_mac_addr(bad_kb->bt_mac_buf); + // Set user config and remember memcpy(bad_kb->config.ble.mac, bad_kb->bt_mac_buf, sizeof(bad_kb->config.ble.mac)); + // Apply to ID config so its temporarily overridden + if(bad_kb->set_bt_id) { + memcpy( + bad_kb->id_config.ble.mac, + bad_kb->bt_mac_buf, + sizeof(bad_kb->id_config.ble.mac)); + } bad_kb_config_refresh(bad_kb); } scene_manager_previous_scene(bad_kb->scene_manager); diff --git a/applications/main/bad_kb/scenes/bad_kb_scene_config_bt_name.c b/applications/main/bad_kb/scenes/bad_kb_scene_config_bt_name.c index 04a02aed40..67a92c6bf1 100644 --- a/applications/main/bad_kb/scenes/bad_kb_scene_config_bt_name.c +++ b/applications/main/bad_kb/scenes/bad_kb_scene_config_bt_name.c @@ -10,7 +10,10 @@ void bad_kb_scene_config_bt_name_on_enter(void* context) { BadKbApp* bad_kb = context; TextInput* text_input = bad_kb->text_input; - strlcpy(bad_kb->bt_name_buf, bad_kb->config.ble.name, sizeof(bad_kb->bt_name_buf)); + strlcpy( + bad_kb->bt_name_buf, + bad_kb->set_bt_id ? bad_kb->id_config.ble.name : bad_kb->config.ble.name, + sizeof(bad_kb->bt_name_buf)); text_input_set_header_text(text_input, "Set BT device name"); text_input_set_result_callback( @@ -31,7 +34,15 @@ bool bad_kb_scene_config_bt_name_on_event(void* context, SceneManagerEvent event if(event.type == SceneManagerEventTypeCustom) { consumed = true; if(event.event == BadKbAppCustomEventTextInputDone) { + // Set user config and remember strlcpy(bad_kb->config.ble.name, bad_kb->bt_name_buf, sizeof(bad_kb->config.ble.name)); + // Apply to ID config so its temporarily overridden + if(bad_kb->set_bt_id) { + strlcpy( + bad_kb->id_config.ble.name, + bad_kb->bt_name_buf, + sizeof(bad_kb->id_config.ble.name)); + } bad_kb_config_refresh(bad_kb); } scene_manager_previous_scene(bad_kb->scene_manager); diff --git a/applications/main/bad_kb/scenes/bad_kb_scene_config_usb_name.c b/applications/main/bad_kb/scenes/bad_kb_scene_config_usb_name.c index c7dd7a2fa3..0cd9da1c86 100644 --- a/applications/main/bad_kb/scenes/bad_kb_scene_config_usb_name.c +++ b/applications/main/bad_kb/scenes/bad_kb_scene_config_usb_name.c @@ -11,10 +11,16 @@ void bad_kb_scene_config_usb_name_on_enter(void* context) { TextInput* text_input = bad_kb->text_input; if(scene_manager_get_scene_state(bad_kb->scene_manager, BadKbSceneConfigUsbName)) { - strlcpy(bad_kb->usb_name_buf, bad_kb->config.usb.manuf, sizeof(bad_kb->usb_name_buf)); + strlcpy( + bad_kb->usb_name_buf, + bad_kb->set_usb_id ? bad_kb->id_config.usb.manuf : bad_kb->config.usb.manuf, + sizeof(bad_kb->usb_name_buf)); text_input_set_header_text(text_input, "Set USB manufacturer name"); } else { - strlcpy(bad_kb->usb_name_buf, bad_kb->config.usb.product, sizeof(bad_kb->usb_name_buf)); + strlcpy( + bad_kb->usb_name_buf, + bad_kb->set_usb_id ? bad_kb->id_config.usb.product : bad_kb->config.usb.product, + sizeof(bad_kb->usb_name_buf)); text_input_set_header_text(text_input, "Set USB product name"); } @@ -37,15 +43,31 @@ bool bad_kb_scene_config_usb_name_on_event(void* context, SceneManagerEvent even consumed = true; if(event.event == BadKbAppCustomEventTextInputDone) { if(scene_manager_get_scene_state(bad_kb->scene_manager, BadKbSceneConfigUsbName)) { + // Set user config and remember strlcpy( bad_kb->config.usb.manuf, bad_kb->usb_name_buf, - sizeof(bad_kb->config.usb.product)); + sizeof(bad_kb->config.usb.manuf)); + // Apply to ID config so its temporarily overridden + if(bad_kb->set_usb_id) { + strlcpy( + bad_kb->id_config.usb.manuf, + bad_kb->usb_name_buf, + sizeof(bad_kb->id_config.usb.manuf)); + } } else { + // Set user config and remember strlcpy( bad_kb->config.usb.product, bad_kb->usb_name_buf, sizeof(bad_kb->config.usb.product)); + // Apply to ID config so its temporarily overridden + if(bad_kb->set_usb_id) { + strlcpy( + bad_kb->id_config.usb.product, + bad_kb->usb_name_buf, + sizeof(bad_kb->id_config.usb.product)); + } } bad_kb_config_refresh(bad_kb); } diff --git a/applications/main/bad_kb/scenes/bad_kb_scene_config_usb_vidpid.c b/applications/main/bad_kb/scenes/bad_kb_scene_config_usb_vidpid.c index 33f899f410..43b1314655 100644 --- a/applications/main/bad_kb/scenes/bad_kb_scene_config_usb_vidpid.c +++ b/applications/main/bad_kb/scenes/bad_kb_scene_config_usb_vidpid.c @@ -10,8 +10,13 @@ void bad_kb_scene_config_usb_vidpid_on_enter(void* context) { BadKbApp* bad_kb = context; ByteInput* byte_input = bad_kb->byte_input; - bad_kb->usb_vidpid_buf[0] = __REVSH(bad_kb->config.usb.vid); - bad_kb->usb_vidpid_buf[1] = __REVSH(bad_kb->config.usb.pid); + if(bad_kb->set_usb_id) { + bad_kb->usb_vidpid_buf[0] = __REVSH(bad_kb->id_config.usb.vid); + bad_kb->usb_vidpid_buf[1] = __REVSH(bad_kb->id_config.usb.pid); + } else { + bad_kb->usb_vidpid_buf[0] = __REVSH(bad_kb->config.usb.vid); + bad_kb->usb_vidpid_buf[1] = __REVSH(bad_kb->config.usb.pid); + } byte_input_set_header_text(byte_input, "Set USB VID:PID"); byte_input_set_result_callback( @@ -32,8 +37,14 @@ bool bad_kb_scene_config_usb_vidpid_on_event(void* context, SceneManagerEvent ev if(event.type == SceneManagerEventTypeCustom) { consumed = true; if(event.event == BadKbAppCustomEventByteInputDone) { + // Set user config and remember bad_kb->config.usb.vid = __REVSH(bad_kb->usb_vidpid_buf[0]); bad_kb->config.usb.pid = __REVSH(bad_kb->usb_vidpid_buf[1]); + // Apply to ID config so its temporarily overridden + if(bad_kb->set_usb_id) { + bad_kb->id_config.usb.vid = bad_kb->config.usb.vid; + bad_kb->id_config.usb.pid = bad_kb->config.usb.pid; + } bad_kb_config_refresh(bad_kb); } scene_manager_previous_scene(bad_kb->scene_manager); From 4b9e516a51ae0640016f9c73cd014eb33d809f87 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Sun, 3 Mar 2024 05:20:46 +0000 Subject: [PATCH 20/35] Fix battery info alignment --- .../settings/power_settings_app/views/battery_info.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/applications/settings/power_settings_app/views/battery_info.c b/applications/settings/power_settings_app/views/battery_info.c index 209a6ddc4b..ea7f932507 100644 --- a/applications/settings/power_settings_app/views/battery_info.c +++ b/applications/settings/power_settings_app/views/battery_info.c @@ -83,16 +83,16 @@ static void draw_battery(Canvas* canvas, BatteryInfoModel* data, int x, int y) { } if(data->alt) { - if(!strcmp(value, "")) { + if(!value[0]) { canvas_draw_str_aligned(canvas, x + 92, y + 14, AlignCenter, AlignCenter, header); - } else if(!strcmp(header, "")) { + } else if(!header[0]) { canvas_draw_str_aligned(canvas, x + 92, y + 14, AlignCenter, AlignCenter, value); } else { canvas_draw_str_aligned(canvas, x + 92, y + 9, AlignCenter, AlignCenter, header); canvas_draw_str_aligned(canvas, x + 92, y + 19, AlignCenter, AlignCenter, value); } } else { - if(!strcmp(emote, "")) { + if(!emote[0] && header[0] && value[0]) { canvas_draw_str_aligned(canvas, x + 92, y + 9, AlignCenter, AlignCenter, header); canvas_draw_str_aligned(canvas, x + 92, y + 21, AlignCenter, AlignCenter, value); } else { From 0860a064f545f4f8bdce9a28c2017da00723ee6f Mon Sep 17 00:00:00 2001 From: Kuronons <110337784+Kuronons@users.noreply.github.com> Date: Sun, 3 Mar 2024 11:56:37 +0100 Subject: [PATCH 21/35] Update passport.c Moving NAME, MOOD, LVL & XP/XP 1 pixel on the right for better display. --- applications/settings/dolphin_passport/passport.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/applications/settings/dolphin_passport/passport.c b/applications/settings/dolphin_passport/passport.c index 116ae0c003..94dc8f4228 100644 --- a/applications/settings/dolphin_passport/passport.c +++ b/applications/settings/dolphin_passport/passport.c @@ -78,9 +78,9 @@ static void render_callback(Canvas* canvas, void* _ctx) { const char* my_name = furi_hal_version_get_name_ptr(); snprintf(level_str, sizeof(level_str), "Level: %hu", stats->level); - canvas_draw_str(canvas, 58, 10, my_name ? my_name : "Unknown"); - canvas_draw_str(canvas, 58, 22, mood_str); - canvas_draw_str(canvas, 58, 34, level_str); + canvas_draw_str(canvas, 59, 10, my_name ? my_name : "Unknown"); + canvas_draw_str(canvas, 59, 22, mood_str); + canvas_draw_str(canvas, 59, 34, level_str); if(stats->level == DOLPHIN_LEVEL_COUNT + 1) { snprintf(xp_str, sizeof(xp_str), "Max Level!"); @@ -88,7 +88,7 @@ static void render_callback(Canvas* canvas, void* _ctx) { snprintf(xp_str, sizeof(xp_str), "%lu/%lu", xp_have, xp_target); } canvas_set_font(canvas, FontBatteryPercent); - canvas_draw_str(canvas, 58, 42, xp_str); + canvas_draw_str(canvas, 59, 42, xp_str); canvas_set_font(canvas, FontSecondary); canvas_set_color(canvas, ColorWhite); From 21d3eb096d7696450ac0b3580ad1d39d5fc62bc6 Mon Sep 17 00:00:00 2001 From: Kuronons <110337784+Kuronons@users.noreply.github.com> Date: Sun, 3 Mar 2024 20:20:55 +0100 Subject: [PATCH 22/35] Update AssetPacks.md minor fixes --- documentation/file_formats/AssetPacks.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/file_formats/AssetPacks.md b/documentation/file_formats/AssetPacks.md index c4b50133e8..1a319c7a6f 100644 --- a/documentation/file_formats/AssetPacks.md +++ b/documentation/file_formats/AssetPacks.md @@ -66,7 +66,7 @@ With icons there are quite a few differences and issues we had to solve. In part #### Static icons -The `.bm` format does not include image width and height, with animations that is stored in `meta.txt`, so for static icons we made a special format: `.bmx`, which is `[ int32 width ] + [ int32 height ] + [ standard .bm pixel data ]`, but this is handled by the packer (see below) so don't worry abou it. +The `.bm` format does not include image width and height, with animations that is stored in `meta.txt`, so for static icons we made a special format: `.bmx`, which is `[ int32 width ] + [ int32 height ] + [ standard .bm pixel data ]`, but this is handled by the packer (see below) so don't worry about it. #### Animated icons @@ -149,7 +149,7 @@ All the .bm and .bmx struggles are dealt with by the packer system, which is in - Now upload the packed packs from that folder onto your flipper in `SD/asset_packs`. -- Done! Just select it from the Xtreme Settings app now. And if you're generous share your (packed) asset pack in #asset-packs on discord. +- Done! Just select it from the Momentum Settings app now. And if you're generous share your (packed) asset pack in #asset-packs on discord. #### Building with Firmware From 6ad42cccc04cf547194b53f77cd443c99702b62f Mon Sep 17 00:00:00 2001 From: Kuronons <110337784+Kuronons@users.noreply.github.com> Date: Sun, 3 Mar 2024 22:36:18 +0100 Subject: [PATCH 23/35] Delete assets/icons/Passport/passport_128x64.png --- assets/icons/Passport/passport_128x64.png | Bin 4529 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 assets/icons/Passport/passport_128x64.png diff --git a/assets/icons/Passport/passport_128x64.png b/assets/icons/Passport/passport_128x64.png deleted file mode 100644 index 16a3f557ec690ed751b765008617173a01076ab0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4529 zcmcIo4~!I78J`0p6oDqOA6KY?arI`=FK0ua{KR&lPU4X*3=zH%+xt|%>E z8%ol9=SOFY^tGK=Nz#>res^!BH+Q4u1cf+v16#zag%U_h($Zzs5_dL=ifoI1zt|f4 z+x`PF*>_uGJz7r5mC|CsU%t64R&QR}?QGuYm~L#@4f4{e1poz6;c~T*FNRjNHCDs5 z;5lke#N?VtWn*hB87Y)|b6s*eC<~dz733%ik##eU8P!z%dRbLeC4u3mA*@@}u!t&; z9x>2Xc0FrVrhQZwytT##DwUFzNDL1T$A?KgDEB9@X_^T|O{gjY2^4NBR(KT^!$o5V z84)^Vzf|#qq8uS|I~c6A#=z406bhvVY%v^l6F4kU<)s9UE76o{g09n$D-D+OHRZ08 z5P4A$#YzaWxFHK(%HjWZ!P!HKQb&%r_M^hZdW!xDXp9!47h*Z(|dVINo0~n3f zuo%-kY%&!Q&KMFHfDGz5h_dq2{6y5qDi;tHT~ZyHhK(;|` z#5L7GF0mQcb?jo#i^=19(?LEc=K>dePA0Z@rqf;J!1MFa5w7Y;$(`9W0|Oa?m5a#{ zEiAAD=ES2wY>kaI_C}n}57rxXRe=LC0vw}*)?TK6yn9X2hqX{+azrevX6S0jabOVW zsGZiH$~>{>gai_s{5)Z*A$?uWq4O`{oUwfOYtQ{IwbZOHaQxm3&O$Z#5 z0o|yAI1>&KhIon)9#<(JoBCv?6JlxFSXjOj(?{Lv4De#VfKru+z4OTkRpq*1E@D`5 z5q7AFZ0b>D*f!BT&M7osG?}T=#=ATjCnyey@&sa)c$q`F73Hus=9Pnj%uA)b@6>L*C{1|IVQ#X8`U8ib)CL!X^k~gSkv+7!&1U?UQ4vwlEc;+lblU4{+Juuz-Ea!t%tW+2GG3epH= z$n-ctjB-!Y9o-|mY2P;!6V2MiY~9pt-9eh^VI(+pp<)mnDu%{Qk3mtSZnIcAp~4lm zikJ{CG6{vKH8@bjhH7Lurt?Ixp-8L8#rp?V}v0Msd zR1Ag~5dt|dBLuV45G4!)Q*F&qC*jwBvzffulCjZxhN$hJhZ?CQ#@RH`ygfsbdRimx z*>*K`*^yckBWpRPo|Y1q&R;dj3Ez&8mTFD#K^i?azJ%eW@hvTiuq!FUm-4Q8BR5M@ z%g;MA$?od$Q!oB>$5wgH7XH%tZ$H1{$`7XQesIIVhtvK0$zQL3t1UJyd&i1hGrnS- zSo6lV_pM#G_2l+Db}WA4tI5|p&Odj)>TKPy^q;@|$ho1J-~YpsN6(GC=kq@~{G+#~ zJ-*-@k15iMmgBRh*FNYkxIBLK7G>e>AKJ2Bm!5g(KtXD|^^HHCUHN2BS~|HqaqO{K zKiDB1%=R50OddM)G3lAzebc}Dj~N@{ZU0&!N!2+|sso#6$VWGvdwJoOuC1>xZk2YEbvI{U^q*e*)MuqN+n#92hqoSF)bre_iaQe^ zPPE*AV}JI??{7P@^TEI0CUu6l9sbK6`OuL+LEl+DckjRRzw3xk8+dd6-d~@&YXR=* z8}3-rH}}|mFMR35wujdbpC-?nJ<{f1{=R$BzS1s|TzB})XHI|l>-i-!+P-*HiJ!UV z)VA-u{OZwV#l*mq_kYrwPxf!$$6lTL?4R$v`=MjgfAv!M$eYrg-fIh{?_6}x?YHRO znje02y7x%iP3F~uzxihH+RUfs{Hz$BeBoOiSA6RHfxcVPhxWYkg?*jd_mqb=KKtlM v|H8iWEz*IJQstVxXTjikqPNq_<)lx*^DH={ Date: Sun, 3 Mar 2024 22:42:00 +0100 Subject: [PATCH 24/35] Replace asset --- assets/icons/Passport/passport_128x64.png | Bin 0 -> 4656 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 assets/icons/Passport/passport_128x64.png diff --git a/assets/icons/Passport/passport_128x64.png b/assets/icons/Passport/passport_128x64.png new file mode 100644 index 0000000000000000000000000000000000000000..10287aa68e174305832b927a5db4c0abf3c18a70 GIT binary patch literal 4656 zcmc&&3yd6P9iPJ#`;Y=c4JDxCHZfKE-Ol%zZyxQ^?z25*+e>@cYt+CuGvC}zy1TR8 z+4lBMqO}lAfz&`u4U|B6D4`f3B9-_ESBNis)bR4r`ao$44FzK)rX@}N&%W-U*WQX4 zC$sbTzW?`seZT)>cIV*Q)fddae7>S67YwY)t%v(|_^q0I9$Y{F-B*^vZC-WFrbtm1 zToV8KlsoUbOi?b%1Vh91;o{Y{8K;hA$MZ4Yk7&4SE(x+HZUm5x=YG!EbSzLEE)J^MuqIXBuOU~{sA^dKm@}Oi%T%HfEs5dO5jJdQ+LWm6BLUKC zo^P+u722}kEtMFp*Q<6iIW{)dKSuk*+DH;xmX*{pQSMFUl$B^?eq8M(Ef zS`WgC8gmp*xV4^2fTk@I%GEC0O4N1}I4s!^)gtz&ft+_J44J0nGV%%PH6N zupG#{i>sqyJ&Z=fvpAtU{We$B1OF@ne7ut#S6!xkH?0$7s#Bb%Txk@M3818Vhmx^hLh1xYQ)yG7HJWn>501N5;LSx zIEM(av2JTXjHif0FYw1_CG}j}4{K!s8yA$th)h;1BTZ?=qCHTF>Z0Pxfm|v9s`dwg zXG_;|OiC=|X_iEmU>*|E@euPd^>wNf-PJqmbD_I6235Si6<=QH0*~%)*qrM=wm3ml zaE>HqE;5B$}yRPgicK4QHKk| zz#jJfggPZR8hKy8MuE!>v=Zj52+CECNm3^3@; z;VrgfqY^xI4s5r`qR_98iJDB0fO}_+o#fe+kHofftL|F5vpj2$ut!3 zIPXX8gqaZ|-PCy%%Vcy@X;@&(j!tgT`COf_RLF2 ztVxQYC(_^|V(jVAT$&7f9GjS9NqXkxSy&KmA}A*s(kbJ}@&!el312r{!>6KW-}e#| zz3Rms!!jJhMY`oVbp-~rwhyHP~n-^D=&jG=}CtmE~SSo${=b@0TA(o&neTT zW{F;T2`n5JLo+X-@kE9WJ%-~D1Mp=yCg;*}gw-oAj{z7plOs;0L@ro_z&af<$}u3- z(M>V~zW$TW_)JYYtBo8b1(3tcOd8{S7GPe;(X^4(X(3-AnORrrJ*;fzm{wX!o;!av zDW`o1Lt1JM!Pj;C*!`@Bm+l_}vH~qu4L(qoVBFpe$Q|J=m+bKZ;=U;6w(IXJlT z>j&@^uYK;zWoPimPc6IFO)Ec}e}}U4=H{Oft;=ubD#|20en2^`th#L1ug}|l_~)-* zc*C+czj5~^H>H1g^4V|QygmKs$!8x~up|AzNu=yMs3^yait?B7`7gfUMh~8NeD|f( z*eS~1kHG8Uh03v?((68G-qCjm-@f?Kf#j3-$!l^Sdmn%Gj~7n<>anLb@4BV&@-t5u zSN^`Qy?XMw-4AYooiMt1n|LCiW zR%|&wvFFg2o;ZK|k%gaLTfgt6p_AI5H>RH6biCBJ_Y?XH^6&%UE4L~S-~0XR54`%f z59_Bc-s?sSSAX_9yIy+ew<`;i$Ce-c$K1bf{K=mtCdL;YXv}%&{(X=9vTx(=RqGa? zx~EWgt{7hQ% Date: Mon, 4 Mar 2024 05:31:03 +0000 Subject: [PATCH 25/35] Sync apps Changes: - maintenance of subtree remotes - update scripts for better reliability --- applications/external | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/external b/applications/external index caf103e898..4783492f5b 160000 --- a/applications/external +++ b/applications/external @@ -1 +1 @@ -Subproject commit caf103e89808a682d24b38d5b0b764d62df76cd5 +Subproject commit 4783492f5b2532c14ed4d3e3236a60203bd9d66a From 900d51129be82f2c086a5f8a033959f97df91533 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Mon, 4 Mar 2024 06:19:45 +0000 Subject: [PATCH 26/35] Add Air Labyrinth by @jamisonderek + fix Air Arkanoid build --- applications/external | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/external b/applications/external index 4783492f5b..8874281a1e 160000 --- a/applications/external +++ b/applications/external @@ -1 +1 @@ -Subproject commit 4783492f5b2532c14ed4d3e3236a60203bd9d66a +Subproject commit 8874281a1e6b65c6417ae2e510bf9c472366556d From 2709b2041d9c8e0224dcf3b03032cd352557f22b Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Mon, 4 Mar 2024 06:55:03 +0000 Subject: [PATCH 27/35] AirLabyrinth: Fix build on gcc12 --- applications/external | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/external b/applications/external index 8874281a1e..415316f7e9 160000 --- a/applications/external +++ b/applications/external @@ -1 +1 @@ -Subproject commit 8874281a1e6b65c6417ae2e510bf9c472366556d +Subproject commit 415316f7e9c42a41ee46a56a6a691d485969b014 From 1070064f8954b17047ff64c5f892f787d5b2e731 Mon Sep 17 00:00:00 2001 From: Rodrigo Basoalto Date: Mon, 4 Mar 2024 06:50:28 -0300 Subject: [PATCH 28/35] Parser for Santiago, Chile BIP transit card (#3456) * Parser for Santiago, Chile BIP transit card It's used for all public transportation in the city of Santiago, Chile (bus, subway). We've reverse-engineered most of the non-zero bits of data found, and checked them across dozens of cards. * Update to use bit_lib instead of nfc_util * PR feedback Co-authored-by: Rodrigo Basoalto Co-authored-by: gornekich --- applications/main/nfc/application.fam | 9 + .../main/nfc/plugins/supported_cards/bip.c | 368 ++++++++++++++++++ 2 files changed, 377 insertions(+) create mode 100644 applications/main/nfc/plugins/supported_cards/bip.c diff --git a/applications/main/nfc/application.fam b/applications/main/nfc/application.fam index 4bcc798237..b6a0f09d37 100644 --- a/applications/main/nfc/application.fam +++ b/applications/main/nfc/application.fam @@ -128,6 +128,15 @@ App( sources=["plugins/supported_cards/aime.c"], ) +App( + appid="bip_parser", + apptype=FlipperAppType.PLUGIN, + entry_point="bip_plugin_ep", + targets=["f7"], + requires=["nfc"], + sources=["plugins/supported_cards/bip.c"], +) + App( appid="umarsh_parser", apptype=FlipperAppType.PLUGIN, diff --git a/applications/main/nfc/plugins/supported_cards/bip.c b/applications/main/nfc/plugins/supported_cards/bip.c new file mode 100644 index 0000000000..211c27cb56 --- /dev/null +++ b/applications/main/nfc/plugins/supported_cards/bip.c @@ -0,0 +1,368 @@ +#include "nfc_supported_card_plugin.h" + +#include +#include +#include +#include + +#define TAG "Bip" + +#define SECTOR_BLOCK_OFFSET(sector, block) (((sector) * 4) + (block)) + +static const uint64_t bip_keys_a[] = { + 0x3a42f33af429, + 0x6338a371c0ed, + 0xf124c2578ad0, + 0x32ac3b90ac13, + 0x4ad1e273eaf1, + 0xe2c42591368a, + 0x2a3c347a1200, + 0x16f3d5ab1139, + 0x937a4fff3011, + 0x35c3d2caee88, + 0x693143f10368, + 0xa3f97428dd01, + 0x63f17a449af0, + 0xc4652c54261c, + 0xd49e2826664f, + 0x3df14c8000a1, +}; + +static const uint64_t bip_keys_b[] = { + 0x1fc235ac1309, + 0x243f160918d1, + 0x9afc42372af1, + 0x682d401abb09, + 0x067db45454a9, + 0x15fc4c7613fe, + 0x68d30288910a, + 0xf59a36a2546d, + 0x64e3c10394c2, + 0xb736412614af, + 0x324f5df65310, + 0x643fb6de2217, + 0x82f435dedf01, + 0x0263de1278f3, + 0x51284c3686a6, + 0x6a470d54127c, +}; + +bool bip_verify(Nfc* nfc) { + bool verified = true; + + const uint8_t verify_sector = 0; + uint8_t block_num = mf_classic_get_first_block_num_of_sector(verify_sector); + FURI_LOG_D(TAG, "Verifying sector %u", verify_sector); + + MfClassicKey key_a_0 = {}; + bit_lib_num_to_bytes_be(bip_keys_a[0], COUNT_OF(key_a_0.data), key_a_0.data); + + MfClassicAuthContext auth_ctx = {}; + MfClassicError error = + mf_classic_poller_sync_auth(nfc, block_num, &key_a_0, MfClassicKeyTypeA, &auth_ctx); + + if(error == MfClassicErrorNotPresent) { + FURI_LOG_D(TAG, "Failed to read block %u: %d", block_num, error); + verified = false; + } + + return verified; +} + +static bool bip_read(Nfc* nfc, NfcDevice* device) { + furi_assert(nfc); + furi_assert(device); + + bool is_read = false; + + MfClassicData* data = mf_classic_alloc(); + nfc_device_copy_data(device, NfcProtocolMfClassic, data); + + do { + MfClassicType type = MfClassicType1k; + MfClassicError error = mf_classic_poller_sync_detect_type(nfc, &type); + if(error == MfClassicErrorNotPresent) { + FURI_LOG_W(TAG, "Card not MIFARE Classic 1k"); + break; + } + + data->type = type; + MfClassicDeviceKeys keys = {}; + for(size_t i = 0; i < mf_classic_get_total_sectors_num(data->type); i++) { + bit_lib_num_to_bytes_be(bip_keys_a[i], sizeof(MfClassicKey), keys.key_a[i].data); + FURI_BIT_SET(keys.key_a_mask, i); + bit_lib_num_to_bytes_be(bip_keys_b[i], sizeof(MfClassicKey), keys.key_b[i].data); + FURI_BIT_SET(keys.key_b_mask, i); + } + + error = mf_classic_poller_sync_read(nfc, &keys, data); + if(error == MfClassicErrorNotPresent) { + FURI_LOG_W(TAG, "Failed to read data. Bad keys?"); + break; + } + + nfc_device_set_data(device, NfcProtocolMfClassic, data); + + is_read = true; + } while(false); + + mf_classic_free(data); + + return is_read; +} + +typedef struct { + uint16_t year; + uint8_t month; + uint8_t day; + uint8_t hour; + uint8_t minute; + uint8_t second; +} BipTimestamp; + +static void parse_bip_timestamp(const MfClassicBlock* block, BipTimestamp* timestamp) { + furi_assert(block); + furi_assert(timestamp); + + timestamp->day = (((block->data[1] << 8) + block->data[0]) >> 6) & 0x1f; + timestamp->month = (((block->data[1] << 8) + block->data[0]) >> 11) & 0xf; + timestamp->year = 2000 + ((((block->data[2] << 8) + block->data[1]) >> 7) & 0x1f); + timestamp->hour = (((block->data[3] << 8) + block->data[2]) >> 4) & 0x1f; + timestamp->minute = (((block->data[3] << 8) + block->data[2]) >> 9) & 0x3f; + timestamp->second = (((block->data[4] << 8) + block->data[3]) >> 7) & 0x3f; +} + +static int compare_bip_timestamp(const BipTimestamp* t1, const BipTimestamp* t2) { + furi_assert(t1); + furi_assert(t2); + if(t1->year != t2->year) { + return t1->year - t2->year; + } + if(t1->month != t2->month) { + return t1->month - t2->month; + } + if(t1->day != t2->day) { + return t1->day - t2->day; + } + if(t1->hour != t2->hour) { + return t1->hour - t2->hour; + } + if(t1->minute != t2->minute) { + return t1->minute - t2->minute; + } + if(t1->second != t2->second) { + return t1->second - t2->second; + } + return 0; +} + +static void print_bip_timestamp(const BipTimestamp* timestamp, FuriString* str) { + furi_assert(timestamp); + furi_assert(str); + furi_string_cat_printf( + str, + "%04u-%02u-%02u %02u:%02u:%02u", + timestamp->year, + timestamp->month, + timestamp->day, + timestamp->hour, + timestamp->minute, + timestamp->second); +} + +static bool is_bip_block_empty(const MfClassicBlock* block) { + furi_assert(block); + // check if all but last byte are zero (last is checksum) + for(size_t i = 0; i < sizeof(block->data) - 1; i++) { + if(block->data[i] != 0) { + return false; + } + } + return true; +} + +static void parse_uint16_le(const uint8_t* data, uint16_t* value) { + furi_assert(data); + furi_assert(value); + + *value = (data[0]) | (data[1] << 8); +} + +static void parse_uint32_le(const uint8_t* data, uint32_t* value) { + furi_assert(data); + furi_assert(value); + + *value = (data[0]) | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); +} + +static void parse_uint16_txn_amount(const uint8_t* data, uint16_t* value) { + furi_assert(data); + furi_assert(value); + + parse_uint16_le(data, value); + *value = *value >> 2; +} + +typedef struct { + BipTimestamp timestamp; + uint16_t amount; +} BipTransaction; + +static bool bip_parse(const NfcDevice* device, FuriString* parsed_data) { + furi_assert(device); + furi_assert(parsed_data); + + bool parsed = true; + + struct { + uint32_t card_id; + uint16_t balance; + uint16_t flags; + BipTimestamp trip_time_window; + BipTransaction top_ups[3]; + BipTransaction charges[3]; + } bip_data = { + .card_id = 0, + .balance = 0, + .flags = 0, + .trip_time_window = {0, 0, 0, 0, 0, 0}, + .top_ups = + { + {{0, 0, 0, 0, 0, 0}, 0}, + {{0, 0, 0, 0, 0, 0}, 0}, + {{0, 0, 0, 0, 0, 0}, 0}, + }, + .charges = + { + {{0, 0, 0, 0, 0, 0}, 0}, + {{0, 0, 0, 0, 0, 0}, 0}, + {{0, 0, 0, 0, 0, 0}, 0}, + }, + }; + + const MfClassicData* data = nfc_device_get_data(device, NfcProtocolMfClassic); + + do { + // verify first sector keys + MfClassicSectorTrailer* sec_tr = mf_classic_get_sector_trailer_by_sector(data, 0); + uint64_t key = bit_lib_bytes_to_num_be(sec_tr->key_a.data, 6); + if(key != bip_keys_a[0]) { + parsed = false; + break; + } + key = bit_lib_bytes_to_num_be(sec_tr->key_b.data, 6); + if(key != bip_keys_b[0]) { + parsed = false; + break; + } + + // Get Card ID, little-endian 4 bytes at sector 0 block 1, bytes 4-7 + parse_uint32_le(&data->block[SECTOR_BLOCK_OFFSET(0, 1)].data[4], &bip_data.card_id); + + // Get balance, little-endian 2 bytes at sector 8 block 1, bytes 0-1 + parse_uint16_le(&data->block[SECTOR_BLOCK_OFFSET(8, 1)].data[0], &bip_data.balance); + + // Get balance flags (negative balance, etc.), little-endian 2 bytes at sector 8 block 1, bytes 2-3 + parse_uint16_le(&data->block[SECTOR_BLOCK_OFFSET(8, 1)].data[2], &bip_data.flags); + + // Get trip time window, proprietary format, at sector 5 block 1, bytes 0-7 + parse_bip_timestamp(&data->block[SECTOR_BLOCK_OFFSET(5, 1)], &bip_data.trip_time_window); + + // Last 3 top-ups: sector 10, ring-buffer of 3 blocks, timestamp in bytes 0-7, amount in bytes 9-10 + for(size_t i = 0; i < 3; i++) { + if(is_bip_block_empty(&data->block[SECTOR_BLOCK_OFFSET(10, i)])) { + continue; + } + BipTransaction* top_up = &bip_data.top_ups[i]; + parse_bip_timestamp(&data->block[SECTOR_BLOCK_OFFSET(10, i)], &top_up->timestamp); + parse_uint16_txn_amount( + &data->block[SECTOR_BLOCK_OFFSET(10, i)].data[9], &top_up->amount); + } + + // Last 3 charges (i.e. trips), sector 11, ring-buffer of 3 blocks, timestamp in bytes 0-7, amount in bytes 10-11 + for(size_t i = 0; i < 3; i++) { + if(is_bip_block_empty(&data->block[SECTOR_BLOCK_OFFSET(11, i)])) { + continue; + } + BipTransaction* charge = &bip_data.charges[i]; + parse_bip_timestamp(&data->block[SECTOR_BLOCK_OFFSET(11, i)], &charge->timestamp); + parse_uint16_txn_amount( + &data->block[SECTOR_BLOCK_OFFSET(11, i)].data[10], &charge->amount); + } + + // All data is now parsed and stored in bip_data, now print it + + // Print basic info + furi_string_printf( + parsed_data, + "\e#Tarjeta Bip!\n" + "Card Number: %ld\n" + "Balance: $%d (flags %x)\n" + "Current Trip Window Ends:\n @", + bip_data.card_id, + bip_data.balance, + bip_data.flags); + + print_bip_timestamp(&bip_data.trip_time_window, parsed_data); + + // Find newest top-up + size_t newest_top_up = 0; + for(size_t i = 1; i < 3; i++) { + const BipTimestamp* newest = &bip_data.top_ups[newest_top_up].timestamp; + const BipTimestamp* current = &bip_data.top_ups[i].timestamp; + if(compare_bip_timestamp(current, newest) > 0) { + newest_top_up = i; + } + } + + // Print top-ups, newest first + furi_string_cat_printf(parsed_data, "\n\e#Last Top-ups"); + for(size_t i = 0; i < 3; i++) { + const BipTransaction* top_up = &bip_data.top_ups[(3u + newest_top_up - i) % 3]; + furi_string_cat_printf(parsed_data, "\n+$%d\n @", top_up->amount); + print_bip_timestamp(&top_up->timestamp, parsed_data); + } + + // Find newest charge + size_t newest_charge = 0; + for(size_t i = 1; i < 3; i++) { + const BipTimestamp* newest = &bip_data.charges[newest_charge].timestamp; + const BipTimestamp* current = &bip_data.charges[i].timestamp; + if(compare_bip_timestamp(current, newest) > 0) { + newest_charge = i; + } + } + + // Print charges + furi_string_cat_printf(parsed_data, "\n\e#Last Charges (Trips)"); + for(size_t i = 0; i < 3; i++) { + const BipTransaction* charge = &bip_data.charges[(3u + newest_charge - i) % 3]; + furi_string_cat_printf(parsed_data, "\n-$%d\n @", charge->amount); + print_bip_timestamp(&charge->timestamp, parsed_data); + } + + parsed = true; + } while(false); + + return parsed; +} + +/* Actual implementation of app<>plugin interface */ +static const NfcSupportedCardsPlugin bip_plugin = { + .protocol = NfcProtocolMfClassic, + .verify = bip_verify, + .read = bip_read, + .parse = bip_parse, +}; + +/* Plugin descriptor to comply with basic plugin specification */ +static const FlipperAppPluginDescriptor bip_plugin_descriptor = { + .appid = NFC_SUPPORTED_CARD_PLUGIN_APP_ID, + .ep_api_version = NFC_SUPPORTED_CARD_PLUGIN_API_VERSION, + .entry_point = &bip_plugin, +}; + +/* Plugin entry point - must return a pointer to const descriptor */ +const FlipperAppPluginDescriptor* bip_plugin_ep() { + return &bip_plugin_descriptor; +} From eb4f1bdbf89e10a391c19f500f0fb4ce19fc437a Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Mon, 4 Mar 2024 14:43:34 +0000 Subject: [PATCH 29/35] MassStorage: Fix image creation error message --- .../system/mass_storage/scenes/mass_storage_scene_create_image.c | 1 + 1 file changed, 1 insertion(+) diff --git a/applications/system/mass_storage/scenes/mass_storage_scene_create_image.c b/applications/system/mass_storage/scenes/mass_storage_scene_create_image.c index 4a732374b0..c1b6ca46af 100644 --- a/applications/system/mass_storage/scenes/mass_storage_scene_create_image.c +++ b/applications/system/mass_storage/scenes/mass_storage_scene_create_image.c @@ -147,6 +147,7 @@ bool mass_storage_scene_create_image_on_event(void* context, SceneManagerEvent e } if(storage_virtual_format(app->fs_api) == FSE_OK) { success = true; + error = NULL; } storage_virtual_quit(app->fs_api); } while(false); From 80d097bda780404e921799f9dcd80fd2a38aa265 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Mon, 4 Mar 2024 14:57:53 +0000 Subject: [PATCH 30/35] Passport: Fix progressbar --- applications/settings/dolphin_passport/passport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/settings/dolphin_passport/passport.c b/applications/settings/dolphin_passport/passport.c index 94dc8f4228..09a884d62f 100644 --- a/applications/settings/dolphin_passport/passport.c +++ b/applications/settings/dolphin_passport/passport.c @@ -66,7 +66,7 @@ static void render_callback(Canvas* canvas, void* _ctx) { if(stats->level == DOLPHIN_LEVEL_COUNT + 1) { xp_progress = 0; } else { - xp_progress = xp_to_levelup * 64 / xp_target; + xp_progress = (xp_target - xp_have) * 64 / xp_target; } // multipass From d71cf85cecc3aa938d2c56174eb1ae0e8751a0de Mon Sep 17 00:00:00 2001 From: Sil333033 <94360907+Sil333033@users.noreply.github.com> Date: Mon, 4 Mar 2024 16:42:47 +0100 Subject: [PATCH 31/35] Remove general uart channel setting This was needed bacc in the days for UART Terminal but just noticed it has an setup option inside the app --- .../momentum_app_scene_protocols_gpio.c | 24 ------------------- lib/momentum/momentum.h | 1 - lib/momentum/settings.c | 2 -- 3 files changed, 27 deletions(-) diff --git a/applications/main/momentum_app/scenes/momentum_app_scene_protocols_gpio.c b/applications/main/momentum_app/scenes/momentum_app_scene_protocols_gpio.c index 061a2b3641..ae561ae6ed 100644 --- a/applications/main/momentum_app/scenes/momentum_app_scene_protocols_gpio.c +++ b/applications/main/momentum_app/scenes/momentum_app_scene_protocols_gpio.c @@ -58,18 +58,6 @@ static void momentum_app_scene_protocols_gpio_nmea_channel_changed(VariableItem* app->save_settings = true; } -static void momentum_app_scene_protocols_gpio_general_channel_changed(VariableItem* item) { - MomentumApp* app = variable_item_get_context(item); - momentum_settings.uart_general_channel = variable_item_get_current_value_index(item) == 0 ? - FuriHalSerialIdUsart : - FuriHalSerialIdLpuart; - variable_item_set_current_value_text( - item, - momentum_settings.uart_general_channel == FuriHalSerialIdUsart ? UART_DEFAULT : - UART_EXTRA); - app->save_settings = true; -} - void momentum_app_scene_protocols_gpio_on_enter(void* context) { MomentumApp* app = context; VariableItemList* var_item_list = app->var_item_list; @@ -113,18 +101,6 @@ void momentum_app_scene_protocols_gpio_on_enter(void* context) { item, momentum_settings.uart_nmea_channel == FuriHalSerialIdUsart ? UART_DEFAULT : UART_EXTRA); - item = variable_item_list_add( - var_item_list, - "General UART", - 2, - momentum_app_scene_protocols_gpio_general_channel_changed, - app); - variable_item_set_current_value_index(item, momentum_settings.uart_general_channel); - variable_item_set_current_value_text( - item, - momentum_settings.uart_general_channel == FuriHalSerialIdUsart ? UART_DEFAULT : - UART_EXTRA); - variable_item_list_set_enter_callback( var_item_list, momentum_app_scene_protocols_gpio_var_item_list_callback, app); diff --git a/lib/momentum/momentum.h b/lib/momentum/momentum.h index de5c21ae0a..1bbbde2d40 100644 --- a/lib/momentum/momentum.h +++ b/lib/momentum/momentum.h @@ -83,7 +83,6 @@ typedef struct { SpiHandle spi_nrf24_handle; FuriHalSerialId uart_esp_channel; FuriHalSerialId uart_nmea_channel; - FuriHalSerialId uart_general_channel; bool file_naming_prefix_after; } MomentumSettings; diff --git a/lib/momentum/settings.c b/lib/momentum/settings.c index 375bafc5df..f5b1d3de63 100644 --- a/lib/momentum/settings.c +++ b/lib/momentum/settings.c @@ -40,7 +40,6 @@ MomentumSettings momentum_settings = { .spi_nrf24_handle = SpiDefault, // &furi_hal_spi_bus_handle_external .uart_esp_channel = FuriHalSerialIdUsart, // pin 13,14 .uart_nmea_channel = FuriHalSerialIdUsart, // pin 13,14 - .uart_general_channel = FuriHalSerialIdUsart, // pin 13,14 .file_naming_prefix_after = false, // Before }; @@ -110,7 +109,6 @@ static const struct { {setting_enum(spi_nrf24_handle, SpiCount)}, {setting_enum(uart_esp_channel, FuriHalSerialIdMax)}, {setting_enum(uart_nmea_channel, FuriHalSerialIdMax)}, - {setting_enum(uart_general_channel, FuriHalSerialIdMax)}, {setting_bool(file_naming_prefix_after)}, }; From 7fa364d28e0d77f879584bbfadae374cdd12dac9 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Tue, 5 Mar 2024 02:13:18 +0000 Subject: [PATCH 32/35] Fix windows build --- applications/external | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/external b/applications/external index 415316f7e9..762688f712 160000 --- a/applications/external +++ b/applications/external @@ -1 +1 @@ -Subproject commit 415316f7e9c42a41ee46a56a6a691d485969b014 +Subproject commit 762688f7127324da6ef38a0d22c04a05c44fae71 From 7b26dc5ebfaa9d137e9d1764f95ee3738ee75a01 Mon Sep 17 00:00:00 2001 From: philicious Date: Tue, 5 Mar 2024 03:42:39 +0100 Subject: [PATCH 33/35] NFC: Fix washcity plugin verify function being to greedy (#3467) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * NFC: Fix washcity plugin verify function being to greedy It verifies only a single sector and that one using one of the commonly used key 0xA0A1A2A3A4A5 This leads to false-positives and the dicts not being used at all * nfc app: washcity plugin: fix verify function Co-authored-by: gornekich Co-authored-by: あく --- .../main/nfc/plugins/supported_cards/washcity.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/applications/main/nfc/plugins/supported_cards/washcity.c b/applications/main/nfc/plugins/supported_cards/washcity.c index 2c0ec094c1..179b569d7e 100644 --- a/applications/main/nfc/plugins/supported_cards/washcity.c +++ b/applications/main/nfc/plugins/supported_cards/washcity.c @@ -57,20 +57,20 @@ static bool washcity_verify(Nfc* nfc) { bool verified = false; do { - const uint8_t ticket_sector_number = 0; - const uint8_t ticket_block_number = - mf_classic_get_first_block_num_of_sector(ticket_sector_number) + 1; - FURI_LOG_D(TAG, "Verifying sector %u", ticket_sector_number); + const uint8_t verify_sector_number = 1; + const uint8_t verify_block_number = + mf_classic_get_first_block_num_of_sector(verify_sector_number); + FURI_LOG_D(TAG, "Verifying sector %u", verify_sector_number); MfClassicKey key = {0}; bit_lib_num_to_bytes_be( - washcity_1k_keys[ticket_sector_number].a, COUNT_OF(key.data), key.data); + washcity_1k_keys[verify_sector_number].a, COUNT_OF(key.data), key.data); MfClassicAuthContext auth_context; MfClassicError error = mf_classic_poller_sync_auth( - nfc, ticket_block_number, &key, MfClassicKeyTypeA, &auth_context); + nfc, verify_block_number, &key, MfClassicKeyTypeA, &auth_context); if(error != MfClassicErrorNone) { - FURI_LOG_D(TAG, "Failed to read block %u: %d", ticket_block_number, error); + FURI_LOG_D(TAG, "Failed to read block %u: %d", verify_block_number, error); break; } From a6c5a1ba6972131d08adef3a3d81a5d3eb776610 Mon Sep 17 00:00:00 2001 From: assasinfil Date: Tue, 5 Mar 2024 05:56:35 +0300 Subject: [PATCH 34/35] Troyka parser improvements (#3390) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Updated troyka layout (full version) * Changed to furi func * Small refactor * Bitlib refactor * Moved to API * Rollback troyka parser * Fix functions * Parser func refactor start * Layout E3 refactored * Layout E4 refactored * Layout 6 refactored * Layout E5 refactored * Layout 2 refactored * Layout E5 fix * Layout E6 refactored, valid_date need fix * Layout E6 fix * Layout FCB refactored * Layout F0B refactored * Layout 8 refactored * Layout A refactored * Layout C refactored * Layout D refactored * Layout E1 refactored * Layout E2 refactored * Fixes * Old code cleanup * Memory cleanup * Unused imports cleanup * Keys struct refactor * Layout E1 fix * Added debug info for layout and department * Fix PVS warnings * Fix more PVS warnings Co-authored-by: gornekich Co-authored-by: あく --- .../nfc/api/mosgortrans/mosgortrans_util.c | 1308 +++++++++++++++++ .../nfc/api/mosgortrans/mosgortrans_util.h | 17 + .../main/nfc/api/nfc_app_api_table_i.h | 7 +- .../main/nfc/plugins/supported_cards/bip.c | 4 +- .../main/nfc/plugins/supported_cards/troika.c | 247 +--- 5 files changed, 1398 insertions(+), 185 deletions(-) create mode 100644 applications/main/nfc/api/mosgortrans/mosgortrans_util.c create mode 100644 applications/main/nfc/api/mosgortrans/mosgortrans_util.h diff --git a/applications/main/nfc/api/mosgortrans/mosgortrans_util.c b/applications/main/nfc/api/mosgortrans/mosgortrans_util.c new file mode 100644 index 0000000000..f2484a2af5 --- /dev/null +++ b/applications/main/nfc/api/mosgortrans/mosgortrans_util.c @@ -0,0 +1,1308 @@ +#include "mosgortrans_util.h" + +#define TAG "Mosgortrans" + +void from_days_to_datetime(uint32_t days, DateTime* datetime, uint16_t start_year) { + uint32_t timestamp = days * 24 * 60 * 60; + DateTime start_datetime = {0}; + start_datetime.year = start_year - 1; + start_datetime.month = 12; + start_datetime.day = 31; + timestamp += datetime_datetime_to_timestamp(&start_datetime); + datetime_timestamp_to_datetime(timestamp, datetime); +} + +void from_minutes_to_datetime(uint32_t minutes, DateTime* datetime, uint16_t start_year) { + uint32_t timestamp = minutes * 60; + DateTime start_datetime = {0}; + start_datetime.year = start_year - 1; + start_datetime.month = 12; + start_datetime.day = 31; + timestamp += datetime_datetime_to_timestamp(&start_datetime); + datetime_timestamp_to_datetime(timestamp, datetime); +} + +void from_seconds_to_datetime(uint32_t seconds, DateTime* datetime, uint16_t start_year) { + uint32_t timestamp = seconds; + DateTime start_datetime = {0}; + start_datetime.year = start_year - 1; + start_datetime.month = 12; + start_datetime.day = 31; + timestamp += datetime_datetime_to_timestamp(&start_datetime); + datetime_timestamp_to_datetime(timestamp, datetime); +} + +typedef struct { + uint16_t view; //101 + uint16_t type; //102 + uint8_t layout; //111 + uint8_t layout2; //112 + uint16_t blank_type; //121 + uint16_t type_of_extended; //122 + uint8_t extended; //123 + uint8_t benefit_code; //124 + uint32_t number; //201 + uint16_t use_before_date; //202 + uint16_t use_before_date2; //202.2 + uint16_t use_with_date; //205 + uint8_t requires_activation; //301 + uint16_t activate_during; //302 + uint16_t extension_counter; //304 + uint8_t blocked; //303 + uint32_t valid_from_date; //311 + uint16_t valid_to_date; //312 + uint8_t valid_for_days; //313 + uint32_t valid_for_minutes; //314 + uint16_t valid_for_time; //316 + uint16_t valid_for_time2; //316.2 + uint32_t valid_to_time; //317 + uint16_t remaining_trips; //321 + uint8_t remaining_trips1; //321.1 + uint32_t remaining_funds; //322 + uint16_t total_trips; //331 + uint16_t start_trip_date; //402 + uint16_t start_trip_time; //403 + uint32_t start_trip_neg_minutes; //404 + uint32_t start_trip_minutes; //405 + uint8_t start_trip_seconds; //406 + uint8_t minutes_pass; //412 + uint8_t passage_5_minutes; //413 + uint8_t metro_ride_with; //414 + uint8_t transport_type; //421 + uint8_t transport_type_flag; //421.0 + uint8_t transport_type1; //421.1 + uint8_t transport_type2; //421.2 + uint8_t transport_type3; //421.3 + uint8_t transport_type4; //421.4 + uint16_t validator; //422 + uint8_t validator1; //422.1 + uint16_t validator2; //422.2 + uint16_t route; //424 + uint8_t passage_in_metro; //431 + uint8_t transfer_in_metro; //432 + uint8_t passages_ground_transport; //433 + uint8_t fare_trip; //441 + uint16_t crc16; //501.1 + uint16_t crc16_2; //501.2 + uint32_t hash; //502 + uint16_t hash1; //502.1 + uint32_t hash2; //502.2 + uint8_t geozone_a; //GeoZoneA + uint8_t geozone_b; //GeoZoneB + uint8_t company; //Company + uint8_t units; //Units + uint64_t rfu1; //rfu1 + uint16_t rfu2; //rfu2 + uint32_t rfu3; //rfu3 + uint8_t rfu4; //rfu4 + uint8_t rfu5; //rfu5 + uint8_t write_enabled; //write_enabled + uint32_t tech_code; //TechCode + uint8_t interval; //Interval + uint16_t app_code1; //AppCode1 + uint16_t app_code2; //AppCode2 + uint16_t app_code3; //AppCode3 + uint16_t app_code4; //AppCode4 + uint16_t type1; //Type1 + uint16_t type2; //Type2 + uint16_t type3; //Type3 + uint16_t type4; //Type4 + uint8_t zoo; //zoo +} BlockData; + +void parse_layout_2(BlockData* data_block, const MfClassicBlock* block) { + data_block->view = bit_lib_get_bits_16(block->data, 0x00, 10); //101 + data_block->type = bit_lib_get_bits_16(block->data, 0x0A, 10); //102 + data_block->number = bit_lib_get_bits_32(block->data, 0x14, 32); //201 + data_block->layout = bit_lib_get_bits(block->data, 0x34, 4); //111 + data_block->use_before_date = bit_lib_get_bits_16(block->data, 0x38, 16); //202 + data_block->benefit_code = bit_lib_get_bits(block->data, 0x48, 8); //124 + data_block->rfu1 = bit_lib_get_bits_32(block->data, 0x50, 32); //rfu1 + data_block->crc16 = bit_lib_get_bits_16(block->data, 0x70, 16); //501.1 + data_block->blocked = bit_lib_get_bits(block->data, 0x80, 1); //303 + data_block->start_trip_time = bit_lib_get_bits_16(block->data, 0x81, 12); //403 + data_block->start_trip_date = bit_lib_get_bits_16(block->data, 0x8D, 16); //402 + data_block->valid_from_date = bit_lib_get_bits_16(block->data, 0x9D, 16); //311 + data_block->valid_to_date = bit_lib_get_bits_16(block->data, 0xAD, 16); //312 + data_block->start_trip_seconds = bit_lib_get_bits(block->data, 0xDB, 6); //406 + data_block->transport_type1 = bit_lib_get_bits(block->data, 0xC3, 2); //421.1 + data_block->transport_type2 = bit_lib_get_bits(block->data, 0xC5, 2); //421.2 + data_block->transport_type3 = bit_lib_get_bits(block->data, 0xC7, 2); //421.3 + data_block->transport_type4 = bit_lib_get_bits(block->data, 0xC9, 2); //421.4 + data_block->use_with_date = bit_lib_get_bits_16(block->data, 0xBD, 16); //205 + data_block->route = bit_lib_get_bits(block->data, 0xCD, 1); //424 + data_block->validator1 = bit_lib_get_bits_16(block->data, 0xCE, 15); //422.1 + data_block->validator = bit_lib_get_bits_16(block->data, 0xCD, 16); + data_block->total_trips = bit_lib_get_bits_16(block->data, 0xDD, 16); //331 + data_block->write_enabled = bit_lib_get_bits(block->data, 0xED, 1); //write_enabled + data_block->rfu2 = bit_lib_get_bits(block->data, 0xEE, 2); //rfu2 + data_block->crc16_2 = bit_lib_get_bits_16(block->data, 0xF0, 16); //501.2 +} + +void parse_layout_6(BlockData* data_block, const MfClassicBlock* block) { + data_block->view = bit_lib_get_bits_16(block->data, 0x00, 10); //101 + data_block->type = bit_lib_get_bits_16(block->data, 0x0A, 10); //102 + data_block->number = bit_lib_get_bits_32(block->data, 0x14, 32); //201 + data_block->layout = bit_lib_get_bits(block->data, 0x34, 4); //111 + data_block->use_before_date = bit_lib_get_bits_16(block->data, 0x38, 16); //202 + data_block->geozone_a = bit_lib_get_bits(block->data, 0x48, 4); //GeoZoneA + data_block->geozone_b = bit_lib_get_bits(block->data, 0x4C, 4); //GeoZoneB + data_block->blank_type = bit_lib_get_bits_16(block->data, 0x50, 10); //121 + data_block->type_of_extended = bit_lib_get_bits_16(block->data, 0x5A, 10); //122 + data_block->rfu1 = bit_lib_get_bits_16(block->data, 0x64, 12); //rfu1 + data_block->crc16 = bit_lib_get_bits_16(block->data, 0x70, 16); //501.1 + data_block->blocked = bit_lib_get_bits(block->data, 0x80, 1); //303 + data_block->start_trip_time = bit_lib_get_bits_16(block->data, 0x81, 12); //403 + data_block->start_trip_date = bit_lib_get_bits_16(block->data, 0x8D, 16); //402 + data_block->valid_from_date = bit_lib_get_bits_16(block->data, 0x9D, 16); //311 + data_block->valid_to_date = bit_lib_get_bits_16(block->data, 0xAD, 16); //312 + data_block->company = bit_lib_get_bits(block->data, 0xBD, 4); //Company + data_block->validator1 = bit_lib_get_bits(block->data, 0xC1, 4); //422.1 + data_block->remaining_trips = bit_lib_get_bits_16(block->data, 0xC5, 10); //321 + data_block->units = bit_lib_get_bits(block->data, 0xCF, 6); //Units + data_block->validator2 = bit_lib_get_bits_16(block->data, 0xD5, 10); //422.2 + data_block->total_trips = bit_lib_get_bits_16(block->data, 0xDF, 16); //331 + data_block->extended = bit_lib_get_bits(block->data, 0xEF, 1); //123 + data_block->crc16_2 = bit_lib_get_bits_16(block->data, 0xF0, 16); //501.2 +} + +void parse_layout_8(BlockData* data_block, const MfClassicBlock* block) { + data_block->view = bit_lib_get_bits_16(block->data, 0x00, 10); //101 + data_block->type = bit_lib_get_bits_16(block->data, 0x0A, 10); //102 + data_block->number = bit_lib_get_bits_32(block->data, 0x14, 32); //201 + data_block->layout = bit_lib_get_bits(block->data, 0x34, 4); //111 + data_block->use_before_date = bit_lib_get_bits_16(block->data, 0x38, 16); //202 + data_block->rfu1 = bit_lib_get_bits_64(block->data, 0x48, 56); //rfu1 + data_block->valid_from_date = bit_lib_get_bits_16(block->data, 0x80, 16); //311 + data_block->valid_for_days = bit_lib_get_bits(block->data, 0x90, 8); //313 + data_block->requires_activation = bit_lib_get_bits(block->data, 0x98, 1); //301 + data_block->rfu2 = bit_lib_get_bits(block->data, 0x99, 7); //rfu2 + data_block->remaining_trips1 = bit_lib_get_bits(block->data, 0xA0, 8); //321.1 + data_block->remaining_trips = bit_lib_get_bits(block->data, 0xA8, 8); //321 + data_block->validator1 = bit_lib_get_bits(block->data, 0xB0, 2); //422.1 + data_block->validator = bit_lib_get_bits_16(block->data, 0xB1, 15); //422 + data_block->hash = bit_lib_get_bits_32(block->data, 0xC0, 32); //502 + data_block->rfu3 = bit_lib_get_bits_32(block->data, 0xE0, 32); //rfu3 +} + +void parse_layout_A(BlockData* data_block, const MfClassicBlock* block) { + data_block->view = bit_lib_get_bits_16(block->data, 0x00, 10); //101 + data_block->type = bit_lib_get_bits_16(block->data, 0x0A, 10); //102 + data_block->number = bit_lib_get_bits_32(block->data, 0x14, 32); //201 + data_block->layout = bit_lib_get_bits(block->data, 0x34, 4); //111 + data_block->valid_from_date = bit_lib_get_bits_16(block->data, 0x40, 12); //311 + data_block->valid_for_minutes = bit_lib_get_bits_32(block->data, 0x4C, 19); //314 + data_block->requires_activation = bit_lib_get_bits(block->data, 0x5F, 1); //301 + data_block->start_trip_minutes = bit_lib_get_bits_32(block->data, 0x60, 19); //405 + data_block->minutes_pass = bit_lib_get_bits(block->data, 0x77, 7); //412 + data_block->transport_type_flag = bit_lib_get_bits(block->data, 0x7E, 2); //421.0 + data_block->remaining_trips = bit_lib_get_bits(block->data, 0x80, 8); //321 + data_block->validator = bit_lib_get_bits_16(block->data, 0x88, 16); //422 + data_block->transport_type1 = bit_lib_get_bits(block->data, 0x98, 2); //421.1 + data_block->transport_type2 = bit_lib_get_bits(block->data, 0x9A, 2); //421.2 + data_block->transport_type3 = bit_lib_get_bits(block->data, 0x9C, 2); //421.3 + data_block->transport_type4 = bit_lib_get_bits(block->data, 0x9E, 2); //421.4 + data_block->hash = bit_lib_get_bits_32(block->data, 0xC0, 32); //502 +} + +void parse_layout_C(BlockData* data_block, const MfClassicBlock* block) { + data_block->view = bit_lib_get_bits_16(block->data, 0x00, 10); //101 + data_block->type = bit_lib_get_bits_16(block->data, 0x0A, 10); //102 + data_block->number = bit_lib_get_bits_32(block->data, 0x14, 32); //201 + data_block->layout = bit_lib_get_bits(block->data, 0x34, 4); //111 + data_block->use_before_date = bit_lib_get_bits_16(block->data, 0x38, 16); //202 + data_block->rfu1 = bit_lib_get_bits_64(block->data, 0x48, 56); //rfu1 + data_block->valid_from_date = bit_lib_get_bits_16(block->data, 0x80, 16); //311 + data_block->valid_for_days = bit_lib_get_bits(block->data, 0x90, 8); //313 + data_block->requires_activation = bit_lib_get_bits(block->data, 0x98, 1); //301 + data_block->rfu2 = bit_lib_get_bits_16(block->data, 0x99, 13); //rfu2 + data_block->remaining_trips = bit_lib_get_bits_16(block->data, 0xA6, 10); //321 + data_block->validator = bit_lib_get_bits_16(block->data, 0xB0, 16); //422 + data_block->hash = bit_lib_get_bits_32(block->data, 0xC0, 32); //502 + data_block->start_trip_date = bit_lib_get_bits_16(block->data, 0xE0, 16); //402 + data_block->start_trip_time = bit_lib_get_bits_16(block->data, 0xF0, 11); //403 + data_block->transport_type = bit_lib_get_bits(block->data, 0xFB, 2); //421 + data_block->rfu3 = bit_lib_get_bits(block->data, 0xFD, 2); //rfu3 + data_block->transfer_in_metro = bit_lib_get_bits(block->data, 0xFF, 1); //432 +} + +void parse_layout_D(BlockData* data_block, const MfClassicBlock* block) { + data_block->view = bit_lib_get_bits_16(block->data, 0x00, 10); //101 + data_block->type = bit_lib_get_bits_16(block->data, 0x0A, 10); //102 + data_block->number = bit_lib_get_bits_32(block->data, 0x14, 32); //201 + data_block->layout = bit_lib_get_bits(block->data, 0x34, 4); //111 + data_block->rfu1 = bit_lib_get_bits(block->data, 0x38, 8); //rfu1 + data_block->use_before_date = bit_lib_get_bits_16(block->data, 0x40, 16); //202 + data_block->valid_for_time = bit_lib_get_bits_16(block->data, 0x50, 11); //316 + data_block->rfu2 = bit_lib_get_bits(block->data, 0x5B, 5); //rfu2 + data_block->use_before_date2 = bit_lib_get_bits_16(block->data, 0x60, 16); //202.2 + data_block->valid_for_time2 = bit_lib_get_bits_16(block->data, 0x70, 11); //316.2 + data_block->rfu3 = bit_lib_get_bits(block->data, 0x7B, 5); //rfu3 + data_block->valid_from_date = bit_lib_get_bits_16(block->data, 0x80, 16); //311 + data_block->valid_for_days = bit_lib_get_bits(block->data, 0x90, 8); //313 + data_block->requires_activation = bit_lib_get_bits(block->data, 0x98, 1); //301 + data_block->rfu4 = bit_lib_get_bits(block->data, 0x99, 2); //rfu4 + data_block->passage_5_minutes = bit_lib_get_bits(block->data, 0x9B, 5); //413 + data_block->transport_type1 = bit_lib_get_bits(block->data, 0xA0, 2); //421.1 + data_block->passage_in_metro = bit_lib_get_bits(block->data, 0xA2, 1); //431 + data_block->passages_ground_transport = bit_lib_get_bits(block->data, 0xA3, 3); //433 + data_block->remaining_trips = bit_lib_get_bits_16(block->data, 0xA6, 10); //321 + data_block->validator = bit_lib_get_bits_16(block->data, 0xB0, 16); //422 + data_block->hash = bit_lib_get_bits_32(block->data, 0xC0, 32); //502 + data_block->start_trip_date = bit_lib_get_bits_16(block->data, 0xE0, 16); //402 + data_block->start_trip_time = bit_lib_get_bits_16(block->data, 0xF0, 11); //403 + data_block->transport_type2 = bit_lib_get_bits(block->data, 0xFB, 2); //421.2 + data_block->rfu5 = bit_lib_get_bits(block->data, 0xFD, 2); //rfu5 + data_block->transfer_in_metro = bit_lib_get_bits(block->data, 0xFF, 1); //432 +} + +void parse_layout_E1(BlockData* data_block, const MfClassicBlock* block) { + data_block->view = bit_lib_get_bits_16(block->data, 0x00, 10); //101 + data_block->type = bit_lib_get_bits_16(block->data, 0x0A, 10); //102 + data_block->number = bit_lib_get_bits_32(block->data, 0x14, 32); //201 + data_block->layout = bit_lib_get_bits(block->data, 0x34, 4); //111 + data_block->layout2 = bit_lib_get_bits(block->data, 0x38, 5); //112 + data_block->use_before_date = bit_lib_get_bits_16(block->data, 0x3D, 16); //202 + data_block->blank_type = bit_lib_get_bits_16(block->data, 0x4D, 10); //121 + data_block->validator = bit_lib_get_bits_16(block->data, 0x80, 16); //422 + data_block->start_trip_date = bit_lib_get_bits_16(block->data, 0x90, 16); //402 + data_block->start_trip_time = bit_lib_get_bits_16(block->data, 0xA0, 11); //403 + data_block->transport_type1 = bit_lib_get_bits(block->data, 0xAB, 2); //421.1 + data_block->transport_type2 = bit_lib_get_bits(block->data, 0xAD, 2); //421.2 + data_block->transfer_in_metro = bit_lib_get_bits(block->data, 0xB1, 1); //432 + data_block->passage_in_metro = bit_lib_get_bits(block->data, 0xB2, 1); //431 + data_block->passages_ground_transport = bit_lib_get_bits(block->data, 0xB3, 3); //433 + data_block->minutes_pass = bit_lib_get_bits(block->data, 0xB9, 8); //412 + data_block->remaining_funds = bit_lib_get_bits_32(block->data, 0xC4, 19); //322 + data_block->fare_trip = bit_lib_get_bits(block->data, 0xD7, 2); //441 + data_block->blocked = bit_lib_get_bits(block->data, 0x9D, 1); //303 + data_block->zoo = bit_lib_get_bits(block->data, 0xDA, 1); //zoo + data_block->hash = bit_lib_get_bits_32(block->data, 0xE0, 32); //502 +} + +void parse_layout_E2(BlockData* data_block, const MfClassicBlock* block) { + data_block->view = bit_lib_get_bits_16(block->data, 0x00, 10); //101 + data_block->type = bit_lib_get_bits_16(block->data, 0x0A, 10); //102 + data_block->number = bit_lib_get_bits_32(block->data, 0x14, 32); //201 + data_block->layout = bit_lib_get_bits(block->data, 0x34, 4); //111 + data_block->layout2 = bit_lib_get_bits(block->data, 0x38, 5); //112 + data_block->type_of_extended = bit_lib_get_bits_16(block->data, 0x3D, 10); //122 + data_block->use_before_date = bit_lib_get_bits_16(block->data, 0x47, 16); //202 + data_block->blank_type = bit_lib_get_bits_16(block->data, 0x57, 10); //121 + data_block->valid_from_date = bit_lib_get_bits_16(block->data, 0x61, 16); //311 + data_block->activate_during = bit_lib_get_bits_16(block->data, 0x71, 9); //302 + data_block->valid_for_minutes = bit_lib_get_bits_32(block->data, 0x83, 20); //314 + data_block->minutes_pass = bit_lib_get_bits(block->data, 0x9A, 8); //412 + data_block->transport_type = bit_lib_get_bits(block->data, 0xA3, 2); //421 + data_block->passage_in_metro = bit_lib_get_bits(block->data, 0xA5, 1); //431 + data_block->transfer_in_metro = bit_lib_get_bits(block->data, 0xA6, 1); //432 + data_block->remaining_trips = bit_lib_get_bits_16(block->data, 0xA7, 10); //321 + data_block->validator = bit_lib_get_bits_16(block->data, 0xB1, 16); //422 + data_block->start_trip_neg_minutes = bit_lib_get_bits_32(block->data, 0xC4, 20); //404 + data_block->requires_activation = bit_lib_get_bits(block->data, 0xD8, 1); //301 + data_block->blocked = bit_lib_get_bits(block->data, 0xD9, 1); //303 + data_block->extended = bit_lib_get_bits(block->data, 0xDA, 1); //123 + data_block->hash = bit_lib_get_bits_32(block->data, 0xE0, 32); //502 +} + +void parse_layout_E3(BlockData* data_block, const MfClassicBlock* block) { + data_block->view = bit_lib_get_bits_16(block->data, 0x00, 10); //101 + data_block->type = bit_lib_get_bits_16(block->data, 0x0A, 10); //102 + data_block->number = bit_lib_get_bits_32(block->data, 0x14, 32); //201 + data_block->layout = bit_lib_get_bits(block->data, 0x34, 4); //111 + data_block->layout2 = bit_lib_get_bits(block->data, 0x38, 5); //112 + data_block->use_before_date = bit_lib_get_bits_16(block->data, 61, 16); //202 + data_block->blank_type = bit_lib_get_bits_16(block->data, 0x4D, 10); //121 + data_block->remaining_funds = bit_lib_get_bits_32(block->data, 0xBC, 22); //322 + data_block->hash = bit_lib_get_bits_32(block->data, 224, 32); //502 + data_block->validator = bit_lib_get_bits_16(block->data, 0x80, 16); //422 + data_block->start_trip_minutes = bit_lib_get_bits_32(block->data, 0x90, 23); //405 + data_block->fare_trip = bit_lib_get_bits(block->data, 0xD2, 2); //441 + data_block->minutes_pass = bit_lib_get_bits(block->data, 0xAB, 7); //412 + data_block->transport_type_flag = bit_lib_get_bits(block->data, 0xB2, 2); //421.0 + data_block->transport_type1 = bit_lib_get_bits(block->data, 0xB4, 2); //421.1 + data_block->transport_type2 = bit_lib_get_bits(block->data, 0xB6, 2); //421.2 + data_block->transport_type3 = bit_lib_get_bits(block->data, 0xB8, 2); //421.3 + data_block->transport_type4 = bit_lib_get_bits(block->data, 0xBA, 2); //421.4 + data_block->blocked = bit_lib_get_bits(block->data, 0xD4, 1); //303 +} + +void parse_layout_E4(BlockData* data_block, const MfClassicBlock* block) { + data_block->view = bit_lib_get_bits_16(block->data, 0x00, 10); //101 + data_block->type = bit_lib_get_bits_16(block->data, 0x0A, 10); //102 + data_block->number = bit_lib_get_bits_32(block->data, 0x14, 32); //201 + data_block->layout = bit_lib_get_bits(block->data, 0x34, 4); //111 + data_block->layout2 = bit_lib_get_bits(block->data, 0x38, 5); //112 + data_block->type_of_extended = bit_lib_get_bits_16(block->data, 0x3D, 10); //122 + data_block->use_before_date = bit_lib_get_bits_16(block->data, 0x47, 13); //202 + data_block->blank_type = bit_lib_get_bits_16(block->data, 0x54, 10); //121 + data_block->valid_from_date = bit_lib_get_bits_16(block->data, 0x5E, 13); //311 + data_block->activate_during = bit_lib_get_bits_16(block->data, 0x6B, 9); //302 + data_block->extension_counter = bit_lib_get_bits_16(block->data, 0x74, 10); //304 + data_block->valid_for_minutes = bit_lib_get_bits_32(block->data, 0x80, 20); //314 + data_block->minutes_pass = bit_lib_get_bits(block->data, 0x98, 7); //412 + data_block->transport_type_flag = bit_lib_get_bits(block->data, 0x9F, 2); //421.0 + data_block->transport_type1 = bit_lib_get_bits(block->data, 0xA1, 2); //421.1 + data_block->transport_type2 = bit_lib_get_bits(block->data, 0xA3, 2); //421.2 + data_block->transport_type3 = bit_lib_get_bits(block->data, 0xA5, 2); //421.3 + data_block->transport_type4 = bit_lib_get_bits(block->data, 0xA7, 2); //421.4 + data_block->remaining_trips = bit_lib_get_bits_16(block->data, 0xA9, 10); //321 + data_block->validator = bit_lib_get_bits_16(block->data, 0xB3, 16); //422 + data_block->start_trip_neg_minutes = bit_lib_get_bits_32(block->data, 0xC3, 20); //404 + data_block->requires_activation = bit_lib_get_bits(block->data, 0xD7, 1); //301 + data_block->blocked = bit_lib_get_bits(block->data, 0xD8, 1); //303 + data_block->extended = bit_lib_get_bits(block->data, 0xD9, 1); //123 + data_block->hash = bit_lib_get_bits_32(block->data, 0xE0, 32); //502 +} + +void parse_layout_E5(BlockData* data_block, const MfClassicBlock* block) { + data_block->view = bit_lib_get_bits_16(block->data, 0x00, 10); //101 + data_block->type = bit_lib_get_bits_16(block->data, 0x0A, 10); //102 + data_block->number = bit_lib_get_bits_32(block->data, 0x14, 32); //201 + data_block->layout = bit_lib_get_bits(block->data, 0x34, 4); //111 + data_block->layout2 = bit_lib_get_bits(block->data, 0x38, 5); //112 + data_block->use_before_date = bit_lib_get_bits_16(block->data, 0x3D, 13); //202 + data_block->blank_type = bit_lib_get_bits_16(block->data, 0x4A, 10); //121 + data_block->valid_to_time = bit_lib_get_bits_32(block->data, 0x54, 23); //317 + data_block->extension_counter = bit_lib_get_bits_16(block->data, 0x6B, 10); //304 + data_block->start_trip_minutes = bit_lib_get_bits_32(block->data, 0x80, 23); //405 + data_block->metro_ride_with = bit_lib_get_bits(block->data, 0x97, 7); //414 + data_block->minutes_pass = bit_lib_get_bits(block->data, 0x9E, 7); //412 + data_block->remaining_funds = bit_lib_get_bits_32(block->data, 0xA7, 19); //322 + data_block->validator = bit_lib_get_bits_16(block->data, 0xBA, 16); //422 + data_block->blocked = bit_lib_get_bits(block->data, 0xCA, 1); //303 + data_block->route = bit_lib_get_bits_16(block->data, 0xCC, 12); //424 + data_block->passages_ground_transport = bit_lib_get_bits(block->data, 0xD8, 7); //433 + data_block->hash = bit_lib_get_bits_32(block->data, 0xE0, 32); //502 +} + +void parse_layout_E6(BlockData* data_block, const MfClassicBlock* block) { + data_block->view = bit_lib_get_bits_16(block->data, 0x00, 10); //101 + data_block->type = bit_lib_get_bits_16(block->data, 0x0A, 10); //102 + data_block->number = bit_lib_get_bits_32(block->data, 0x14, 32); //201 + data_block->layout = bit_lib_get_bits(block->data, 0x34, 4); //111 + data_block->layout2 = bit_lib_get_bits(block->data, 0x38, 5); //112 + data_block->type_of_extended = bit_lib_get_bits_16(block->data, 0x3D, 10); //122 + data_block->use_before_date = bit_lib_get_bits_16(block->data, 0x47, 13); //202 + data_block->blank_type = bit_lib_get_bits_16(block->data, 0x54, 10); //121 + data_block->valid_from_date = bit_lib_get_bits_32(block->data, 0x5E, 23); //311 + data_block->extension_counter = bit_lib_get_bits_16(block->data, 0x75, 10); //304 + data_block->valid_for_minutes = bit_lib_get_bits_32(block->data, 0x80, 20); //314 + data_block->start_trip_neg_minutes = bit_lib_get_bits_32(block->data, 0x94, 20); //404 + data_block->metro_ride_with = bit_lib_get_bits(block->data, 0xA8, 7); //414 + data_block->minutes_pass = bit_lib_get_bits(block->data, 0xAF, 7); //412 + data_block->remaining_trips = bit_lib_get_bits(block->data, 0xB6, 7); //321 + data_block->validator = bit_lib_get_bits_16(block->data, 0xBD, 16); //422 + data_block->blocked = bit_lib_get_bits(block->data, 0xCD, 1); //303 + data_block->extended = bit_lib_get_bits(block->data, 0xCE, 1); //123 + data_block->route = bit_lib_get_bits_16(block->data, 0xD4, 12); //424 + data_block->hash = bit_lib_get_bits_32(block->data, 0xE0, 32); //502 +} + +void parse_layout_FCB(BlockData* data_block, const MfClassicBlock* block) { + data_block->view = bit_lib_get_bits_16(block->data, 0x00, 10); //101 + data_block->type = bit_lib_get_bits_16(block->data, 0x0A, 10); //102 + data_block->number = bit_lib_get_bits_32(block->data, 0x14, 32); //201 + data_block->layout = bit_lib_get_bits(block->data, 0x34, 4); //111 + data_block->tech_code = bit_lib_get_bits_32(block->data, 0x38, 10); //tech_code + data_block->valid_from_date = bit_lib_get_bits_16(block->data, 0x42, 16); //311 + data_block->valid_to_date = bit_lib_get_bits_16(block->data, 0x52, 16); //312 + data_block->interval = bit_lib_get_bits(block->data, 0x62, 4); //interval + data_block->app_code1 = bit_lib_get_bits_16(block->data, 0x66, 10); //app_code1 + data_block->hash1 = bit_lib_get_bits_16(block->data, 0x70, 16); //502.1 + data_block->type1 = bit_lib_get_bits_16(block->data, 0x80, 10); //type1 + data_block->app_code2 = bit_lib_get_bits_16(block->data, 0x8A, 10); //app_code2 + data_block->type2 = bit_lib_get_bits_16(block->data, 0x94, 10); //type2 + data_block->app_code3 = bit_lib_get_bits_16(block->data, 0x9E, 10); //app_code3 + data_block->type3 = bit_lib_get_bits_16(block->data, 0xA8, 10); //type3 + data_block->app_code4 = bit_lib_get_bits_16(block->data, 0xB2, 10); //app_code4 + data_block->type4 = bit_lib_get_bits_16(block->data, 0xBC, 10); //type4 + data_block->hash2 = bit_lib_get_bits_32(block->data, 0xE0, 32); //502.2 +} + +void parse_layout_F0B(BlockData* data_block, const MfClassicBlock* block) { + data_block->view = bit_lib_get_bits_16(block->data, 0x00, 10); //101 + data_block->type = bit_lib_get_bits_16(block->data, 0x0A, 10); //102 + data_block->number = bit_lib_get_bits_32(block->data, 0x14, 32); //201 + data_block->layout = bit_lib_get_bits(block->data, 0x34, 4); //111 + data_block->tech_code = bit_lib_get_bits_32(block->data, 0x38, 10); //tech_code + data_block->valid_from_date = bit_lib_get_bits_16(block->data, 0x42, 16); //311 + data_block->valid_to_date = bit_lib_get_bits_16(block->data, 0x52, 16); //312 + data_block->hash1 = bit_lib_get_bits_32(block->data, 0x70, 16); //502.1 +} + +void parse_transport_type(BlockData* data_block, FuriString* transport) { + switch(data_block->transport_type_flag) { + case 1: + uint8_t transport_type = + (data_block->transport_type1 || data_block->transport_type2 || + data_block->transport_type3 || data_block->transport_type4); + switch(transport_type) { + case 1: + furi_string_cat(transport, "Metro"); + break; + case 2: + furi_string_cat(transport, "Monorail"); + break; + case 3: + furi_string_cat(transport, "MCC"); + break; + default: + furi_string_cat(transport, "Unknown"); + break; + } + break; + case 2: + furi_string_cat(transport, "Ground"); + break; + default: + furi_string_cat(transport, ""); + break; + } +} + +bool mosgortrans_parse_transport_block(const MfClassicBlock* block, FuriString* result) { + BlockData data_block = {}; + const uint16_t valid_departments[] = {0x106, 0x108, 0x10A, 0x10E, 0x110, 0x117}; + uint16_t transport_departament = bit_lib_get_bits_16(block->data, 0, 10); + if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { + furi_string_cat_printf(result, "Transport departament: %x\n", transport_departament); + } + bool departament_valid = false; + for(uint8_t i = 0; i < 6; i++) { + if(transport_departament == valid_departments[i]) { + departament_valid = true; + break; + } + } + if(!departament_valid) { + return false; + } + FURI_LOG_D(TAG, "Transport departament: %x", transport_departament); + uint16_t layout_type = bit_lib_get_bits_16(block->data, 52, 4); + if(layout_type == 0xE) { + layout_type = bit_lib_get_bits_16(block->data, 52, 9); + } else if(layout_type == 0xF) { + layout_type = bit_lib_get_bits_16(block->data, 52, 14); + } + if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { + furi_string_cat_printf(result, "Layout: %x\n", layout_type); + } + FURI_LOG_D(TAG, "Layout type %x", layout_type); + switch(layout_type) { + case 0x02: { + parse_layout_2(&data_block, block); + //number + furi_string_cat_printf(result, "Number: %010lu\n", data_block.number); + //use_before_date + DateTime card_use_before_date_s = {0}; + from_days_to_datetime(data_block.use_before_date, &card_use_before_date_s, 1992); + furi_string_cat_printf( + result, + "Use before: %02d.%02d.%04d\n", + card_use_before_date_s.day, + card_use_before_date_s.month, + card_use_before_date_s.year); + + if(data_block.valid_from_date == 0 || data_block.valid_to_date == 0) { + furi_string_cat(result, "\e#No ticket\n"); + return true; + } + //remaining_trips + furi_string_cat_printf(result, "Trips: %d\n", data_block.total_trips); + //valid_from_date + DateTime card_valid_from_date_s = {0}; + from_days_to_datetime(data_block.valid_from_date, &card_valid_from_date_s, 1992); + furi_string_cat_printf( + result, + "Valid from: %02d.%02d.%04d\n", + card_valid_from_date_s.day, + card_valid_from_date_s.month, + card_valid_from_date_s.year); + //valid_to_date + DateTime card_valid_to_date_s = {0}; + from_days_to_datetime(data_block.valid_to_date, &card_valid_to_date_s, 1992); + furi_string_cat_printf( + result, + "Valid to: %02d.%02d.%04d\n", + card_valid_to_date_s.day, + card_valid_to_date_s.month, + card_valid_to_date_s.year); + //trip_number + furi_string_cat_printf(result, "Trips: %d\n", data_block.total_trips); + //trip_from + DateTime card_start_trip_minutes_s = {0}; + from_seconds_to_datetime( + data_block.start_trip_date * 24 * 60 * 60 + data_block.start_trip_time * 60 + + data_block.start_trip_seconds, + &card_start_trip_minutes_s, + 1992); + furi_string_cat_printf( + result, + "Trip from: %02d.%02d.%04d %02d:%02d", + card_start_trip_minutes_s.day, + card_start_trip_minutes_s.month, + card_start_trip_minutes_s.year, + card_start_trip_minutes_s.hour, + card_start_trip_minutes_s.minute); + break; + } + case 0x06: { + parse_layout_6(&data_block, block); + //number + furi_string_cat_printf(result, "Number: %010lu\n", data_block.number); + //use_before_date + DateTime card_use_before_date_s = {0}; + from_days_to_datetime(data_block.use_before_date, &card_use_before_date_s, 1992); + furi_string_cat_printf( + result, + "Use before: %02d.%02d.%04d\n", + card_use_before_date_s.day, + card_use_before_date_s.month, + card_use_before_date_s.year); + //remaining_trips + furi_string_cat_printf(result, "Trips left: %d\n", data_block.remaining_trips); + //valid_from_date + DateTime card_valid_from_date_s = {0}; + from_days_to_datetime(data_block.valid_from_date, &card_valid_from_date_s, 1992); + furi_string_cat_printf( + result, + "Valid from: %02d.%02d.%04d\n", + card_valid_from_date_s.day, + card_valid_from_date_s.month, + card_valid_from_date_s.year); + //valid_to_date + DateTime card_valid_to_date_s = {0}; + from_days_to_datetime(data_block.valid_to_date, &card_valid_to_date_s, 1992); + furi_string_cat_printf( + result, + "Valid to: %02d.%02d.%04d\n", + card_valid_to_date_s.day, + card_valid_to_date_s.month, + card_valid_to_date_s.year); + //trip_number + furi_string_cat_printf(result, "Trips: %d\n", data_block.total_trips); + //trip_from + DateTime card_start_trip_minutes_s = {0}; + from_minutes_to_datetime( + (data_block.start_trip_date) * 24 * 60 + data_block.start_trip_time, + &card_start_trip_minutes_s, + 1992); + furi_string_cat_printf( + result, + "Trip from: %02d.%02d.%04d %02d:%02d\n", + card_start_trip_minutes_s.day, + card_start_trip_minutes_s.month, + card_start_trip_minutes_s.year, + card_start_trip_minutes_s.hour, + card_start_trip_minutes_s.minute); + //validator + furi_string_cat_printf( + result, "Validator: %05d", data_block.validator1 * 1024 + data_block.validator2); + break; + } + case 0x08: { + parse_layout_8(&data_block, block); + //number + furi_string_cat_printf(result, "Number: %010lu\n", data_block.number); + //use_before_date + DateTime card_use_before_date_s = {0}; + from_days_to_datetime(data_block.use_before_date, &card_use_before_date_s, 1992); + //remaining_trips + furi_string_cat_printf(result, "Trips left: %d\n", data_block.remaining_trips); + //valid_from_date + DateTime card_valid_from_date_s = {0}; + from_days_to_datetime(data_block.valid_from_date, &card_valid_from_date_s, 1992); + furi_string_cat_printf( + result, + "Valid from: %02d.%02d.%04d\n", + card_valid_from_date_s.day, + card_valid_from_date_s.month, + card_valid_from_date_s.year); + //valid_to_date + DateTime card_valid_to_date_s = {0}; + from_days_to_datetime( + data_block.valid_from_date + data_block.valid_for_days, &card_valid_to_date_s, 1992); + furi_string_cat_printf( + result, + "Valid to: %02d.%02d.%04d\n", + card_valid_to_date_s.day, + card_valid_to_date_s.month, + card_valid_to_date_s.year); + break; + } + case 0x0A: { + parse_layout_A(&data_block, block); + //number + furi_string_cat_printf(result, "Number: %010lu\n", data_block.number); + //use_before_date + DateTime card_use_before_date_s = {0}; + from_days_to_datetime(data_block.use_before_date, &card_use_before_date_s, 2016); + furi_string_cat_printf( + result, + "Use before: %02d.%02d.%04d\n", + card_use_before_date_s.day, + card_use_before_date_s.month, + card_use_before_date_s.year); + //remaining_trips + furi_string_cat_printf(result, "Trips left: %d\n", data_block.remaining_trips); + //valid_from_date + DateTime card_valid_from_date_s = {0}; + from_days_to_datetime(data_block.valid_from_date, &card_valid_from_date_s, 2016); + furi_string_cat_printf( + result, + "Valid from: %02d.%02d.%04d\n", + card_valid_from_date_s.day, + card_valid_from_date_s.month, + card_valid_from_date_s.year); + //valid_to_date + DateTime card_valid_to_date_s = {0}; + from_minutes_to_datetime( + data_block.valid_from_date * 24 * 60 + data_block.valid_for_minutes - 1, + &card_valid_to_date_s, + 2016); + furi_string_cat_printf( + result, + "Valid to: %02d.%02d.%04d\n", + card_valid_to_date_s.day, + card_valid_to_date_s.month, + card_valid_to_date_s.year); + //trip_from + if(data_block.start_trip_minutes) { + DateTime card_start_trip_minutes_s = {0}; + from_minutes_to_datetime( + data_block.valid_from_date * 24 * 60 + data_block.start_trip_minutes, + &card_start_trip_minutes_s, + 2016); + furi_string_cat_printf( + result, + "Trip from: %02d.%02d.%04d %02d:%02d\n", + card_start_trip_minutes_s.day, + card_start_trip_minutes_s.month, + card_start_trip_minutes_s.year, + card_start_trip_minutes_s.hour, + card_start_trip_minutes_s.minute); + } + //trip_switch + if(data_block.minutes_pass) { + DateTime card_start_switch_trip_minutes_s = {0}; + from_minutes_to_datetime( + data_block.valid_from_date * 24 * 60 + data_block.start_trip_minutes + + data_block.minutes_pass, + &card_start_switch_trip_minutes_s, + 2016); + furi_string_cat_printf( + result, + "Trip switch: %02d.%02d.%04d %02d:%02d\n", + card_start_switch_trip_minutes_s.day, + card_start_switch_trip_minutes_s.month, + card_start_switch_trip_minutes_s.year, + card_start_switch_trip_minutes_s.hour, + card_start_switch_trip_minutes_s.minute); + } + //transport + FuriString* transport = furi_string_alloc(); + parse_transport_type(&data_block, transport); + furi_string_cat_printf(result, "Transport: %s\n", furi_string_get_cstr(transport)); + //validator + if(data_block.validator) { + furi_string_cat_printf(result, "Validator: %05d\n", data_block.validator); + } + furi_string_free(transport); + break; + } + case 0x0C: { + parse_layout_C(&data_block, block); + //number + furi_string_cat_printf(result, "Number: %010lu\n", data_block.number); + //use_before_date + DateTime card_use_before_date_s = {0}; + from_days_to_datetime(data_block.use_before_date, &card_use_before_date_s, 1992); + //remaining_trips + furi_string_cat_printf(result, "Trips left: %d\n", data_block.remaining_trips); + //valid_from_date + DateTime card_valid_from_date_s = {0}; + from_days_to_datetime(data_block.valid_from_date, &card_valid_from_date_s, 1992); + furi_string_cat_printf( + result, + "Valid from: %02d.%02d.%04d\n", + card_valid_from_date_s.day, + card_valid_from_date_s.month, + card_valid_from_date_s.year); + //valid_to_date + DateTime card_valid_to_date_s = {0}; + from_days_to_datetime( + data_block.valid_from_date + data_block.valid_for_days, &card_valid_to_date_s, 1992); + furi_string_cat_printf( + result, + "Valid to: %02d.%02d.%04d\n", + card_valid_to_date_s.day, + card_valid_to_date_s.month, + card_valid_to_date_s.year); + //remaining_trips + furi_string_cat_printf(result, "Trips left: %d\n", data_block.remaining_trips); + //trip_from + if(data_block.start_trip_date) { + DateTime card_start_trip_minutes_s = {0}; + from_minutes_to_datetime( + data_block.start_trip_date * 24 * 60 + data_block.start_trip_time, + &card_start_trip_minutes_s, + 1992); + } + //validator + if(data_block.validator) { + furi_string_cat_printf(result, "Validator: %05d", data_block.validator); + } + break; + } + case 0x0D: { + parse_layout_D(&data_block, block); + //number + furi_string_cat_printf(result, "Number: %010lu\n", data_block.number); + //use_before_date + DateTime card_use_before_date_s = {0}; + from_days_to_datetime(data_block.use_before_date, &card_use_before_date_s, 1992); + furi_string_cat_printf( + result, + "Use before: %02d.%02d.%04d\n", + card_use_before_date_s.day, + card_use_before_date_s.month, + card_use_before_date_s.year); + //remaining_trips + furi_string_cat_printf(result, "Trips left: %d\n", data_block.remaining_trips); + //valid_from_date + DateTime card_valid_from_date_s = {0}; + from_days_to_datetime(data_block.valid_from_date, &card_valid_from_date_s, 1992); + furi_string_cat_printf( + result, + "Valid from: %02d.%02d.%04d\n", + card_valid_from_date_s.day, + card_valid_from_date_s.month, + card_valid_from_date_s.year); + //valid_to_date + DateTime card_valid_to_date_s = {0}; + from_days_to_datetime( + data_block.valid_from_date + data_block.valid_for_days, &card_valid_to_date_s, 1992); + furi_string_cat_printf( + result, + "Valid to: %02d.%02d.%04d\n", + card_valid_to_date_s.day, + card_valid_to_date_s.month, + card_valid_to_date_s.year); + //trip_from + if(data_block.start_trip_date) { + DateTime card_start_trip_minutes_s = {0}; + from_minutes_to_datetime( + data_block.start_trip_date * 24 * 60 + data_block.start_trip_time, + &card_start_trip_minutes_s, + 1992); + } + //trip_switch + if(data_block.passage_5_minutes) { + DateTime card_start_switch_trip_minutes_s = {0}; + from_minutes_to_datetime( + data_block.start_trip_date * 24 * 60 + data_block.start_trip_time + + data_block.passage_5_minutes, + &card_start_switch_trip_minutes_s, + 1992); + } + //validator + if(data_block.validator) { + furi_string_cat_printf(result, "Validator: %05d", data_block.validator); + } + break; + } + case 0xE1: + case 0x1C1: { + parse_layout_E1(&data_block, block); + //number + furi_string_cat_printf(result, "Number: %010lu\n", data_block.number); + //use_before_date + DateTime card_use_before_date_s = {0}; + from_days_to_datetime(data_block.use_before_date, &card_use_before_date_s, 1992); + furi_string_cat_printf( + result, + "Use before: %02d.%02d.%04d\n", + card_use_before_date_s.day, + card_use_before_date_s.month, + card_use_before_date_s.year); + //remaining_funds + furi_string_cat_printf(result, "Balance: %ld rub\n", data_block.remaining_funds / 100); + //trip_from + if(data_block.start_trip_date) { + DateTime card_start_trip_minutes_s = {0}; + from_minutes_to_datetime( + data_block.start_trip_date * 24 * 60 + data_block.start_trip_time, + &card_start_trip_minutes_s, + 1992); + furi_string_cat_printf( + result, + "Trip from: %02d.%02d.%04d %02d:%02d\n", + card_start_trip_minutes_s.day, + card_start_trip_minutes_s.month, + card_start_trip_minutes_s.year, + card_start_trip_minutes_s.hour, + card_start_trip_minutes_s.minute); + } + //transport + FuriString* transport = furi_string_alloc(); + switch(data_block.transport_type1) { + case 1: + switch(data_block.transport_type2) { + case 1: + furi_string_cat(transport, "Metro"); + break; + case 2: + furi_string_cat(transport, "Monorail"); + break; + default: + furi_string_cat(transport, "Unknown"); + break; + } + break; + case 2: + furi_string_cat(transport, "Ground"); + break; + case 3: + furi_string_cat(transport, "MCC"); + break; + default: + furi_string_cat(transport, ""); + break; + } + furi_string_cat_printf(result, "Transport: %s\n", furi_string_get_cstr(transport)); + //validator + if(data_block.validator) { + furi_string_cat_printf(result, "Validator: %05d", data_block.validator); + } + furi_string_free(transport); + break; + } + case 0xE2: + case 0x1C2: { + parse_layout_E2(&data_block, block); + //number + furi_string_cat_printf(result, "Number: %010lu\n", data_block.number); + //use_before_date + DateTime card_use_before_date_s = {0}; + from_days_to_datetime(data_block.use_before_date, &card_use_before_date_s, 1992); + furi_string_cat_printf( + result, + "Use before: %02d.%02d.%04d\n", + card_use_before_date_s.day, + card_use_before_date_s.month, + card_use_before_date_s.year); + //remaining_trips + furi_string_cat_printf(result, "Trips left: %d\n", data_block.remaining_trips); + //valid_from_date + DateTime card_valid_from_date_s = {0}; + from_days_to_datetime(data_block.valid_from_date, &card_valid_from_date_s, 1992); + furi_string_cat_printf( + result, + "Valid from: %02d.%02d.%04d\n", + card_valid_from_date_s.day, + card_valid_from_date_s.month, + card_valid_from_date_s.year); + //valid_to_date + if(data_block.activate_during) { + DateTime card_valid_to_date_s = {0}; + from_days_to_datetime( + data_block.valid_from_date + data_block.activate_during, + &card_valid_to_date_s, + 1992); + furi_string_cat_printf( + result, + "Valid to: %02d.%02d.%04d\n", + card_valid_to_date_s.day, + card_valid_to_date_s.month, + card_valid_to_date_s.year); + } else { + DateTime card_valid_to_date_s = {0}; + from_minutes_to_datetime( + data_block.valid_from_date * 24 * 60 + data_block.valid_for_minutes - 1, + &card_valid_to_date_s, + 1992); + furi_string_cat_printf( + result, + "Valid to: %02d.%02d.%04d\n", + card_valid_to_date_s.day, + card_valid_to_date_s.month, + card_valid_to_date_s.year); + } + //trip_from + if(data_block.start_trip_neg_minutes) { + DateTime card_start_trip_minutes_s = {0}; + from_minutes_to_datetime( + data_block.valid_to_date * 24 * 60 + data_block.valid_for_minutes - + data_block.start_trip_neg_minutes, + &card_start_trip_minutes_s, + 1992); //-time + furi_string_cat_printf( + result, + "Trip from: %02d.%02d.%04d %02d:%02d\n", + card_start_trip_minutes_s.day, + card_start_trip_minutes_s.month, + card_start_trip_minutes_s.year, + card_start_trip_minutes_s.hour, + card_start_trip_minutes_s.minute); + } + //trip_switch + if(data_block.minutes_pass) { + DateTime card_start_switch_trip_minutes_s = {0}; + from_minutes_to_datetime( + data_block.valid_from_date * 24 * 60 + data_block.valid_for_minutes - + data_block.start_trip_neg_minutes + data_block.minutes_pass, + &card_start_switch_trip_minutes_s, + 1992); + furi_string_cat_printf( + result, + "Trip switch: %02d.%02d.%04d %02d:%02d\n", + card_start_switch_trip_minutes_s.day, + card_start_switch_trip_minutes_s.month, + card_start_switch_trip_minutes_s.year, + card_start_switch_trip_minutes_s.hour, + card_start_switch_trip_minutes_s.minute); + } + //transport + FuriString* transport = furi_string_alloc(); + switch(data_block.transport_type) { + case 1: + furi_string_cat(transport, "Metro"); + break; + case 2: + furi_string_cat(transport, "Monorail"); + break; + case 3: + furi_string_cat(transport, "Ground"); + break; + default: + furi_string_cat(transport, "Unknown"); + break; + } + //validator + if(data_block.validator) { + furi_string_cat_printf(result, "Validator: %05d", data_block.validator); + } + furi_string_free(transport); + break; + } + case 0xE3: + case 0x1C3: { + parse_layout_E3(&data_block, block); + // number + furi_string_cat_printf(result, "Number: %010lu\n", data_block.number); + // use_before_date + DateTime card_use_before_date_s = {0}; + from_days_to_datetime(data_block.use_before_date, &card_use_before_date_s, 1992); + furi_string_cat_printf( + result, + "Use before: %02d.%02d.%04d\n", + card_use_before_date_s.day, + card_use_before_date_s.month, + card_use_before_date_s.year); + // remaining_funds + furi_string_cat_printf(result, "Balance: %lu rub\n", data_block.remaining_funds); + // start_trip_minutes + DateTime card_start_trip_minutes_s = {0}; + from_minutes_to_datetime(data_block.start_trip_minutes, &card_start_trip_minutes_s, 2016); + furi_string_cat_printf( + result, + "Trip from: %02d.%02d.%04d %02d:%02d\n", + card_start_trip_minutes_s.day, + card_start_trip_minutes_s.month, + card_start_trip_minutes_s.year, + card_start_trip_minutes_s.hour, + card_start_trip_minutes_s.minute); + // transport + FuriString* transport = furi_string_alloc(); + parse_transport_type(&data_block, transport); + furi_string_cat_printf(result, "Transport: %s\n", furi_string_get_cstr(transport)); + // validator + furi_string_cat_printf(result, "Validator: %05d\n", data_block.validator); + // fare + FuriString* fare = furi_string_alloc(); + switch(data_block.fare_trip) { + case 0: + furi_string_cat(fare, ""); + break; + case 1: + furi_string_cat(fare, "Single"); + break; + case 2: + furi_string_cat(fare, "90 minutes"); + break; + default: + furi_string_cat(fare, "Unknown"); + break; + } + furi_string_cat_printf(result, "Fare: %s", furi_string_get_cstr(fare)); + furi_string_free(fare); + furi_string_free(transport); + break; + } + case 0xE4: + case 0x1C4: { + parse_layout_E4(&data_block, block); + + // number + furi_string_cat_printf(result, "Number: %010lu\n", data_block.number); + // use_before_date + DateTime card_use_before_date_s = {0}; + from_days_to_datetime(data_block.use_before_date, &card_use_before_date_s, 2016); + furi_string_cat_printf( + result, + "Use before: %02d.%02d.%04d\n", + card_use_before_date_s.day, + card_use_before_date_s.month, + card_use_before_date_s.year); + // remaining_funds + furi_string_cat_printf(result, "Balance: %lu rub\n", data_block.remaining_funds); + // valid_from_date + DateTime card_use_from_date_s = {0}; + from_days_to_datetime(data_block.valid_from_date, &card_use_from_date_s, 2016); + furi_string_cat_printf( + result, + "Valid from: %02d.%02d.%04d\n", + card_use_from_date_s.day, + card_use_from_date_s.month, + card_use_from_date_s.year); + // valid_to_date + DateTime card_use_to_date_s = {0}; + if(data_block.requires_activation) { + from_days_to_datetime( + data_block.valid_from_date + data_block.activate_during, + &card_use_to_date_s, + 2016); + } else { + from_minutes_to_datetime( + data_block.valid_from_date * 24 * 60 + data_block.valid_for_minutes - 1, + &card_use_to_date_s, + 2016); + } + + furi_string_cat_printf( + result, + "Valid to: %02d.%02d.%04d\n", + card_use_to_date_s.day, + card_use_to_date_s.month, + card_use_to_date_s.year); + // trip_number + // furi_string_cat_printf(result, "Trips left: %d", data_block.remaining_trips); + // trip_from + DateTime card_start_trip_minutes_s = {0}; + from_minutes_to_datetime( + data_block.valid_from_date * 24 * 60 + data_block.valid_for_minutes - + data_block.start_trip_neg_minutes, + &card_start_trip_minutes_s, + 2016); + //transport + FuriString* transport = furi_string_alloc(); + parse_transport_type(&data_block, transport); + furi_string_cat_printf(result, "Transport: %s\n", furi_string_get_cstr(transport)); + // validator + if(data_block.validator) { + furi_string_cat_printf(result, "Validator: %05d", data_block.validator); + } + furi_string_free(transport); + break; + } + case 0xE5: + case 0x1C5: { + parse_layout_E5(&data_block, block); + //number + furi_string_cat_printf(result, "Number: %010lu\n", data_block.number); + //use_before_date + DateTime card_use_before_date_s = {0}; + from_days_to_datetime(data_block.use_before_date, &card_use_before_date_s, 2019); + furi_string_cat_printf( + result, + "Use before: %02d.%02d.%04d\n", + card_use_before_date_s.day, + card_use_before_date_s.month, + card_use_before_date_s.year); + //remaining_funds + furi_string_cat_printf(result, "Balance: %ld rub\n", data_block.remaining_funds / 100); + //start_trip_minutes + if(data_block.start_trip_minutes) { + DateTime card_start_trip_minutes_s = {0}; + from_minutes_to_datetime( + data_block.start_trip_minutes, &card_start_trip_minutes_s, 2019); + furi_string_cat_printf( + result, + "Trip from: %02d.%02d.%04d %02d:%02d\n", + card_start_trip_minutes_s.day, + card_start_trip_minutes_s.month, + card_start_trip_minutes_s.year, + card_start_trip_minutes_s.hour, + card_start_trip_minutes_s.minute); + } + //start_m_trip_minutes + if(data_block.metro_ride_with) { + DateTime card_start_m_trip_minutes_s = {0}; + from_minutes_to_datetime( + data_block.start_trip_minutes + data_block.metro_ride_with, + &card_start_m_trip_minutes_s, + 2019); + furi_string_cat_printf( + result, + "(M) from: %02d.%02d.%04d %02d:%02d\n", + card_start_m_trip_minutes_s.day, + card_start_m_trip_minutes_s.month, + card_start_m_trip_minutes_s.year, + card_start_m_trip_minutes_s.hour, + card_start_m_trip_minutes_s.minute); + } + if(data_block.minutes_pass) { + DateTime card_start_change_trip_minutes_s = {0}; + from_minutes_to_datetime( + data_block.start_trip_minutes + data_block.minutes_pass, + &card_start_change_trip_minutes_s, + 2019); + furi_string_cat_printf( + result, + "Trip edit: %02d.%02d.%04d %02d:%02d\n", + card_start_change_trip_minutes_s.day, + card_start_change_trip_minutes_s.month, + card_start_change_trip_minutes_s.year, + card_start_change_trip_minutes_s.hour, + card_start_change_trip_minutes_s.minute); + } + //transport + //validator + if(data_block.validator) { + furi_string_cat_printf(result, "Validator: %05d", data_block.validator); + } + break; + } + case 0xE6: + case 0x1C6: { + parse_layout_E6(&data_block, block); + //number + furi_string_cat_printf(result, "Number: %010lu\n", data_block.number); + //use_before_date + DateTime card_use_before_date_s = {0}; + from_days_to_datetime(data_block.use_before_date, &card_use_before_date_s, 2019); + furi_string_cat_printf( + result, + "Use before: %02d.%02d.%04d\n", + card_use_before_date_s.day, + card_use_before_date_s.month, + card_use_before_date_s.year); + //remaining_trips + furi_string_cat_printf(result, "Trips left: %d\n", data_block.remaining_trips); + //valid_from_date + DateTime card_use_from_date_s = {0}; + from_minutes_to_datetime(data_block.valid_from_date, &card_use_from_date_s, 2019); + furi_string_cat_printf( + result, + "Valid from: %02d.%02d.%04d\n", + card_use_from_date_s.day, + card_use_from_date_s.month, + card_use_from_date_s.year); + //valid_to_date + DateTime card_use_to_date_s = {0}; + from_minutes_to_datetime( + data_block.valid_from_date + data_block.valid_for_minutes - 1, + &card_use_to_date_s, + 2019); + furi_string_cat_printf( + result, + "Valid to: %02d.%02d.%04d\n", + card_use_to_date_s.day, + card_use_to_date_s.month, + card_use_to_date_s.year); + //start_trip_minutes + if(data_block.start_trip_neg_minutes) { + DateTime card_start_trip_minutes_s = {0}; + from_minutes_to_datetime( + data_block.valid_from_date + data_block.valid_for_minutes - + data_block.start_trip_neg_minutes, + &card_start_trip_minutes_s, + 2019); //-time + furi_string_cat_printf( + result, + "Trip from: %02d.%02d.%04d %02d:%02d\n", + card_start_trip_minutes_s.day, + card_start_trip_minutes_s.month, + card_start_trip_minutes_s.year, + card_start_trip_minutes_s.hour, + card_start_trip_minutes_s.minute); + } + //start_trip_m_minutes + if(data_block.metro_ride_with) { + DateTime card_start_trip_m_minutes_s = {0}; + from_minutes_to_datetime( + data_block.valid_from_date + data_block.valid_for_minutes - + data_block.start_trip_neg_minutes + data_block.metro_ride_with, + &card_start_trip_m_minutes_s, + 2019); + furi_string_cat_printf( + result, + "(M) from: %02d.%02d.%04d %02d:%02d\n", + card_start_trip_m_minutes_s.day, + card_start_trip_m_minutes_s.month, + card_start_trip_m_minutes_s.year, + card_start_trip_m_minutes_s.hour, + card_start_trip_m_minutes_s.minute); + } + //transport + //validator + if(data_block.validator) { + furi_string_cat_printf(result, "Validator: %05d", data_block.validator); + } + break; + } + case 0x3CCB: { + parse_layout_FCB(&data_block, block); + //number + furi_string_cat_printf(result, "Number: %010lu\n", data_block.number); + //valid_from_date + DateTime card_use_from_date_s = {0}; + from_days_to_datetime(data_block.valid_from_date, &card_use_from_date_s, 1992); + furi_string_cat_printf( + result, + "Valid from: %02d.%02d.%04d\n", + card_use_from_date_s.day, + card_use_from_date_s.month, + card_use_from_date_s.year); + //valid_to_date + DateTime card_use_to_date_s = {0}; + from_days_to_datetime(data_block.valid_to_date, &card_use_to_date_s, 1992); + furi_string_cat_printf( + result, + "Valid to: %02d.%02d.%04d", + card_use_to_date_s.day, + card_use_to_date_s.month, + card_use_to_date_s.year); + break; + } + case 0x3C0B: { + //number + furi_string_cat_printf(result, "Number: %010lu\n", data_block.number); + //valid_from_date + DateTime card_use_from_date_s = {0}; + from_days_to_datetime(data_block.valid_from_date, &card_use_from_date_s, 1992); + furi_string_cat_printf( + result, + "Valid from: %02d.%02d.%04d\n", + card_use_from_date_s.day, + card_use_from_date_s.month, + card_use_from_date_s.year); + //valid_to_date + DateTime card_use_to_date_s = {0}; + from_days_to_datetime(data_block.valid_to_date, &card_use_to_date_s, 1992); + furi_string_cat_printf( + result, + "Valid to: %02d.%02d.%04d", + card_use_to_date_s.day, + card_use_to_date_s.month, + card_use_to_date_s.year); + break; + } + default: + result = NULL; + return false; + } + + return true; +} diff --git a/applications/main/nfc/api/mosgortrans/mosgortrans_util.h b/applications/main/nfc/api/mosgortrans/mosgortrans_util.h new file mode 100644 index 0000000000..e5da8ddeb4 --- /dev/null +++ b/applications/main/nfc/api/mosgortrans/mosgortrans_util.h @@ -0,0 +1,17 @@ +#pragma once + +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +bool mosgortrans_parse_transport_block(const MfClassicBlock* block, FuriString* result); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/applications/main/nfc/api/nfc_app_api_table_i.h b/applications/main/nfc/api/nfc_app_api_table_i.h index 08bff072ea..bf0e926ee6 100644 --- a/applications/main/nfc/api/nfc_app_api_table_i.h +++ b/applications/main/nfc/api/nfc_app_api_table_i.h @@ -1,4 +1,5 @@ #include "gallagher/gallagher_util.h" +#include "mosgortrans/mosgortrans_util.h" /* * A list of app's private functions and objects to expose for plugins. @@ -10,4 +11,8 @@ static constexpr auto nfc_app_api_table = sort(create_array_t( gallagher_deobfuscate_and_parse_credential, void, (GallagherCredential * credential, const uint8_t* cardholder_data_obfuscated)), - API_VARIABLE(GALLAGHER_CARDAX_ASCII, const uint8_t*))); + API_VARIABLE(GALLAGHER_CARDAX_ASCII, const uint8_t*), + API_METHOD( + mosgortrans_parse_transport_block, + bool, + (const MfClassicBlock* block, FuriString* result)))); diff --git a/applications/main/nfc/plugins/supported_cards/bip.c b/applications/main/nfc/plugins/supported_cards/bip.c index 211c27cb56..f6fed6774b 100644 --- a/applications/main/nfc/plugins/supported_cards/bip.c +++ b/applications/main/nfc/plugins/supported_cards/bip.c @@ -296,8 +296,8 @@ static bool bip_parse(const NfcDevice* device, FuriString* parsed_data) { furi_string_printf( parsed_data, "\e#Tarjeta Bip!\n" - "Card Number: %ld\n" - "Balance: $%d (flags %x)\n" + "Card Number: %lu\n" + "Balance: $%hu (flags %hu)\n" "Current Trip Window Ends:\n @", bip_data.card_id, bip_data.balance, diff --git a/applications/main/nfc/plugins/supported_cards/troika.c b/applications/main/nfc/plugins/supported_cards/troika.c index ba7c3bf5e3..50806e137d 100644 --- a/applications/main/nfc/plugins/supported_cards/troika.c +++ b/applications/main/nfc/plugins/supported_cards/troika.c @@ -1,10 +1,12 @@ #include "nfc_supported_card_plugin.h" +#include #include #include #include #include +#include "../../api/mosgortrans/mosgortrans_util.h" #include "furi_hal_rtc.h" #define TAG "Troika" @@ -19,19 +21,6 @@ typedef struct { uint32_t data_sector; } TroikaCardConfig; -typedef enum { - TroikaLayoutUnknown = 0x0, - TroikaLayout2 = 0x2, - TroikaLayoutE = 0xE, -} TroikaLayout; - -typedef enum { - TroikaSublayoutUnknown = 0x0, - TroikaSublayout3 = 0x3, - TroikaSublayout5 = 0x5, - TroikaSublayout6 = 0x6, -} TroikaSubLayout; - static const MfClassicKeyPair troika_1k_keys[] = { {.a = 0xa0a1a2a3a4a5, .b = 0xfbf225dc5d58}, {.a = 0xa82607b01c0d, .b = 0x2910989b6880}, @@ -52,33 +41,53 @@ static const MfClassicKeyPair troika_1k_keys[] = { }; static const MfClassicKeyPair troika_4k_keys[] = { - {.a = 0xa0a1a2a3a4a5, .b = 0xfbf225dc5d58}, {.a = 0xa82607b01c0d, .b = 0x2910989b6880}, - {.a = 0x2aa05ed1856f, .b = 0xeaac88e5dc99}, {.a = 0x2aa05ed1856f, .b = 0xeaac88e5dc99}, - {.a = 0x73068f118c13, .b = 0x2b7f3253fac5}, {.a = 0xfbc2793d540b, .b = 0xd3a297dc2698}, - {.a = 0x2aa05ed1856f, .b = 0xeaac88e5dc99}, {.a = 0xae3d65a3dad4, .b = 0x0f1c63013dbb}, - {.a = 0xa73f5dc1d333, .b = 0xe35173494a81}, {.a = 0x69a32f1c2f19, .b = 0x6b8bd9860763}, - {.a = 0x9becdf3d9273, .b = 0xf8493407799d}, {.a = 0x08b386463229, .b = 0x5efbaecef46b}, - {.a = 0xcd4c61c26e3d, .b = 0x31c7610de3b0}, {.a = 0xa82607b01c0d, .b = 0x2910989b6880}, - {.a = 0x0e8f64340ba4, .b = 0x4acec1205d75}, {.a = 0x2aa05ed1856f, .b = 0xeaac88e5dc99}, - {.a = 0x6b02733bb6ec, .b = 0x7038cd25c408}, {.a = 0x403d706ba880, .b = 0xb39d19a280df}, - {.a = 0xc11f4597efb5, .b = 0x70d901648cb9}, {.a = 0x0db520c78c1c, .b = 0x73e5b9d9d3a4}, - {.a = 0x3ebce0925b2f, .b = 0x372cc880f216}, {.a = 0x16a27af45407, .b = 0x9868925175ba}, - {.a = 0xaba208516740, .b = 0xce26ecb95252}, {.a = 0xcd64e567abcd, .b = 0x8f79c4fd8a01}, - {.a = 0x764cd061f1e6, .b = 0xa74332f74994}, {.a = 0x1cc219e9fec1, .b = 0xb90de525ceb6}, - {.a = 0x2fe3cb83ea43, .b = 0xfba88f109b32}, {.a = 0x07894ffec1d6, .b = 0xefcb0e689db3}, - {.a = 0x04c297b91308, .b = 0xc8454c154cb5}, {.a = 0x7a38e3511a38, .b = 0xab16584c972a}, - {.a = 0x7545df809202, .b = 0xecf751084a80}, {.a = 0x5125974cd391, .b = 0xd3eafb5df46d}, - {.a = 0x7a86aa203788, .b = 0xe41242278ca2}, {.a = 0xafcef64c9913, .b = 0x9db96dca4324}, - {.a = 0x04eaa462f70b, .b = 0xac17b93e2fae}, {.a = 0xe734c210f27e, .b = 0x29ba8c3e9fda}, - {.a = 0xd5524f591eed, .b = 0x5daf42861b4d}, {.a = 0xe4821a377b75, .b = 0xe8709e486465}, - {.a = 0x518dc6eea089, .b = 0x97c64ac98ca4}, {.a = 0xbb52f8cce07f, .b = 0x6b6119752c70}, + {.a = 0xEC29806D9738, .b = 0xFBF225DC5D58}, //1 + {.a = 0xA0A1A2A3A4A5, .b = 0x7DE02A7F6025}, //2 + {.a = 0x2AA05ED1856F, .b = 0xEAAC88E5DC99}, //3 + {.a = 0x2AA05ED1856F, .b = 0xEAAC88E5DC99}, //4 + {.a = 0x73068F118C13, .b = 0x2B7F3253FAC5}, //5 + {.a = 0xFBC2793D540B, .b = 0xD3A297DC2698}, //6 + {.a = 0x2AA05ED1856F, .b = 0xEAAC88E5DC99}, //7 + {.a = 0xAE3D65A3DAD4, .b = 0x0F1C63013DBA}, //8 + {.a = 0xA73F5DC1D333, .b = 0xE35173494A81}, //9 + {.a = 0x69A32F1C2F19, .b = 0x6B8BD9860763}, //10 + {.a = 0x9BECDF3D9273, .b = 0xF8493407799D}, //11 + {.a = 0x08B386463229, .b = 0x5EFBAECEF46B}, //12 + {.a = 0xCD4C61C26E3D, .b = 0x31C7610DE3B0}, //13 + {.a = 0xA82607B01C0D, .b = 0x2910989B6880}, //14 + {.a = 0x0E8F64340BA4, .b = 0x4ACEC1205D75}, //15 + {.a = 0x2AA05ED1856F, .b = 0xEAAC88E5DC99}, //16 + {.a = 0x6B02733BB6EC, .b = 0x7038CD25C408}, //17 + {.a = 0x403D706BA880, .b = 0xB39D19A280DF}, //18 + {.a = 0xC11F4597EFB5, .b = 0x70D901648CB9}, //19 + {.a = 0x0DB520C78C1C, .b = 0x73E5B9D9D3A4}, //20 + {.a = 0x3EBCE0925B2F, .b = 0x372CC880F216}, //21 + {.a = 0x16A27AF45407, .b = 0x9868925175BA}, //22 + {.a = 0xABA208516740, .b = 0xCE26ECB95252}, //23 + {.a = 0xCD64E567ABCD, .b = 0x8F79C4FD8A01}, //24 + {.a = 0x764CD061F1E6, .b = 0xA74332F74994}, //25 + {.a = 0x1CC219E9FEC1, .b = 0xB90DE525CEB6}, //26 + {.a = 0x2FE3CB83EA43, .b = 0xFBA88F109B32}, //27 + {.a = 0x07894FFEC1D6, .b = 0xEFCB0E689DB3}, //28 + {.a = 0x04C297B91308, .b = 0xC8454C154CB5}, //29 + {.a = 0x7A38E3511A38, .b = 0xAB16584C972A}, //30 + {.a = 0x7545DF809202, .b = 0xECF751084A80}, //31 + {.a = 0x5125974CD391, .b = 0xD3EAFB5DF46D}, //32 + {.a = 0xFFFFFFFFFFFF, .b = 0xFFFFFFFFFFFF}, //33 + {.a = 0xFFFFFFFFFFFF, .b = 0xFFFFFFFFFFFF}, //34 + {.a = 0xFFFFFFFFFFFF, .b = 0xFFFFFFFFFFFF}, //35 + {.a = 0xFFFFFFFFFFFF, .b = 0xFFFFFFFFFFFF}, //36 + {.a = 0xFFFFFFFFFFFF, .b = 0xFFFFFFFFFFFF}, //37 + {.a = 0xFFFFFFFFFFFF, .b = 0xFFFFFFFFFFFF}, //38 + {.a = 0xFFFFFFFFFFFF, .b = 0xFFFFFFFFFFFF}, //39 + {.a = 0xFFFFFFFFFFFF, .b = 0xFFFFFFFFFFFF}, //40 }; static bool troika_get_card_config(TroikaCardConfig* config, MfClassicType type) { bool success = true; if(type == MfClassicType1k) { - config->data_sector = 8; + config->data_sector = 11; config->keys = troika_1k_keys; } else if(type == MfClassicType4k) { config->data_sector = 8; // Further testing needed @@ -90,126 +99,6 @@ static bool troika_get_card_config(TroikaCardConfig* config, MfClassicType type) return success; } -static TroikaLayout troika_get_layout(const MfClassicData* data, uint8_t start_block_num) { - furi_assert(data); - - // Layout is stored in byte 6 of block, length 4 bits (bits 52 - 55), second nibble. - const uint8_t* layout_ptr = &data->block[start_block_num].data[6]; - const uint8_t layout = (*layout_ptr & 0x0F); - - TroikaLayout result = TroikaLayoutUnknown; - switch(layout) { - case TroikaLayout2: - case TroikaLayoutE: - result = layout; - break; - default: - // If debug is enabled - pass the actual layout value for the debug text - if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { - return layout; - } else { - return TroikaLayoutUnknown; - } - } - - return result; -} - -static TroikaSubLayout troika_get_sub_layout(const MfClassicData* data, uint8_t start_block_num) { - furi_assert(data); - - // Sublayout is stored in byte 7 (bits 56 - 60) of block, length 5 bits (first nibble and one bit from second nibble) - const uint8_t* sub_layout_ptr = &data->block[start_block_num].data[7]; - const uint8_t sub_layout = (*sub_layout_ptr & 0x3F) >> 3; - - TroikaSubLayout result = TroikaSublayoutUnknown; - switch(sub_layout) { - case TroikaSublayout3: - case TroikaSublayout5: - case TroikaSublayout6: - result = sub_layout; - break; - default: - // If debug is enabled - pass the actual sublayout value for the debug text - if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { - return sub_layout; - } else { - return TroikaSublayoutUnknown; - } - } - - return result; -} - -static bool troika_has_balance(TroikaLayout layout, TroikaSubLayout sub_layout) { - UNUSED(sub_layout); - // Layout 0x2 has no balance - - if(layout == TroikaLayout2) { - return false; - } - - return true; -} - -static uint16_t troika_get_balance( - const MfClassicData* data, - uint8_t start_block_num, - TroikaLayout layout, - TroikaSubLayout sub_layout) { - furi_assert(data); - - // In layout 0x3 balance in bits 188:209 ( from sector start, length 22). - // In layout 0x5 balance in bits 165:185 ( from sector start, length 20). - - uint32_t balance = 0; - uint8_t balance_data_offset = 0; - bool supported_layout = false; - - if(layout == TroikaLayoutE && sub_layout == TroikaSublayout3) { - balance_data_offset = 7; - supported_layout = true; - } else if(layout == TroikaLayoutE && sub_layout == TroikaSublayout5) { - balance_data_offset = 4; - supported_layout = true; - } - - if(supported_layout) { - const uint8_t* temp_ptr = &data->block[start_block_num + 1].data[balance_data_offset]; - balance |= (temp_ptr[0] & 0x3) << 18; - balance |= temp_ptr[1] << 10; - balance |= temp_ptr[2] << 2; - balance |= (temp_ptr[3] & 0xC0) >> 6; - } - - return balance / 100; -} - -static uint32_t troika_get_number( - const MfClassicData* data, - uint8_t start_block_num, - TroikaLayout layout, - TroikaSubLayout sub_layout) { - furi_assert(data); - UNUSED(sub_layout); - - if(layout == TroikaLayoutE || layout == TroikaLayout2) { - const uint8_t* temp_ptr = &data->block[start_block_num].data[2]; - - uint32_t number = 0; - for(size_t i = 1; i < 5; i++) { - number <<= 8; - number |= temp_ptr[i]; - } - number >>= 4; - number |= (temp_ptr[0] & 0xf) << 28; - - return number; - } else { - return 0; - } -} - static bool troika_verify_type(Nfc* nfc, MfClassicType type) { bool verified = false; @@ -230,7 +119,7 @@ static bool troika_verify_type(Nfc* nfc, MfClassicType type) { FURI_LOG_D(TAG, "Failed to read block %u: %d", block_num, error); break; } - + FURI_LOG_D(TAG, "Verify success!"); verified = true; } while(false); @@ -306,40 +195,34 @@ static bool troika_parse(const NfcDevice* device, FuriString* parsed_data) { bit_lib_bytes_to_num_be(sec_tr->key_a.data, COUNT_OF(sec_tr->key_a.data)); if(key != cfg.keys[cfg.data_sector].a) break; - // Get the block number of the block that contains the data - const uint8_t start_block_num = mf_classic_get_first_block_num_of_sector(cfg.data_sector); + FuriString* metro_result = furi_string_alloc(); + FuriString* ground_result = furi_string_alloc(); + FuriString* tat_result = furi_string_alloc(); - // Get layout, sublayout, balance and number - TroikaLayout layout = troika_get_layout(data, start_block_num); - TroikaSubLayout sub_layout = troika_get_sub_layout(data, start_block_num); + bool result1 = mosgortrans_parse_transport_block(&data->block[32], metro_result); + bool result2 = mosgortrans_parse_transport_block(&data->block[28], ground_result); + bool result3 = mosgortrans_parse_transport_block(&data->block[16], tat_result); - if(!furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { - // If debug is enabled - proceed even if layout or sublayout is unknown, that will make collecting data easier - if(layout == TroikaLayoutUnknown || sub_layout == TroikaSublayoutUnknown) break; + furi_string_cat_printf(parsed_data, "\e#Troyka card\n"); + if(result1) { + furi_string_cat_printf( + parsed_data, "\e#Metro\n%s\n", furi_string_get_cstr(metro_result)); } - uint32_t number = troika_get_number(data, start_block_num, layout, sub_layout); - - furi_string_printf(parsed_data, "\e#Troika\nNum: %lu", number); - - if(troika_has_balance(layout, sub_layout) || - furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { - uint16_t balance = troika_get_balance(data, start_block_num, layout, sub_layout); - furi_string_cat_printf(parsed_data, "\nBalance: %u RUR", balance); - } else { - furi_string_cat_printf(parsed_data, "\nBalance: Not available"); + if(result2) { + furi_string_cat_printf( + parsed_data, "\e#Ediniy\n%s\n", furi_string_get_cstr(ground_result)); } - if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { - furi_string_cat_printf( - parsed_data, - "\nLayout: %02x\nSublayout: %02x\nData Block: %u", - layout, - sub_layout, - start_block_num); + if(result3) { + furi_string_cat_printf(parsed_data, "\e#TAT\n%s\n", furi_string_get_cstr(tat_result)); } - parsed = true; + furi_string_free(tat_result); + furi_string_free(ground_result); + furi_string_free(metro_result); + + parsed = result1 || result2 || result3; } while(false); return parsed; @@ -363,4 +246,4 @@ static const FlipperAppPluginDescriptor troika_plugin_descriptor = { /* Plugin entry point - must return a pointer to const descriptor */ const FlipperAppPluginDescriptor* troika_plugin_ep() { return &troika_plugin_descriptor; -} +} \ No newline at end of file From 5e47048369477e6569f62a05d196eca520492402 Mon Sep 17 00:00:00 2001 From: Silent Date: Tue, 5 Mar 2024 04:03:46 +0100 Subject: [PATCH 35/35] Archive: Fix item focus after aborting the Delete operation (#3475) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: hedger Co-authored-by: あく --- applications/main/archive/scenes/archive_scene_browser.c | 1 + applications/main/archive/scenes/archive_scene_delete.c | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/applications/main/archive/scenes/archive_scene_browser.c b/applications/main/archive/scenes/archive_scene_browser.c index d156d171d5..284e534aba 100644 --- a/applications/main/archive/scenes/archive_scene_browser.c +++ b/applications/main/archive/scenes/archive_scene_browser.c @@ -157,6 +157,7 @@ bool archive_scene_browser_on_event(void* context, SceneManagerEvent event) { break; case ArchiveBrowserEventFileMenuDelete: if(archive_get_tab(browser) != ArchiveTabFavorites) { + archive_show_file_menu(browser, false); scene_manager_set_scene_state( archive->scene_manager, ArchiveAppSceneBrowser, SCENE_STATE_NEED_REFRESH); scene_manager_next_scene(archive->scene_manager, ArchiveAppSceneDelete); diff --git a/applications/main/archive/scenes/archive_scene_delete.c b/applications/main/archive/scenes/archive_scene_delete.c index d3964d0feb..45d5b47cc9 100644 --- a/applications/main/archive/scenes/archive_scene_delete.c +++ b/applications/main/archive/scenes/archive_scene_delete.c @@ -29,6 +29,12 @@ void archive_scene_delete_on_enter(void* context) { filename = furi_string_alloc(); ArchiveFile_t* current = archive_get_current_file(app->browser); + + FuriString* filename_no_ext = furi_string_alloc(); + path_extract_filename(current->path, filename_no_ext, true); + strlcpy(app->text_store, furi_string_get_cstr(filename_no_ext), MAX_NAME_LEN); + furi_string_free(filename_no_ext); + path_extract_filename(current->path, filename, false); char delete_str[64];