From 2657be9878339ea966fd9b4632f8319facee72f1 Mon Sep 17 00:00:00 2001 From: LmeSzinc <37934724+LmeSzinc@users.noreply.github.com> Date: Sat, 10 Aug 2024 22:36:33 +0800 Subject: [PATCH 01/11] Fix: Clear stuck record before and after combat --- tasks/combat/combat.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tasks/combat/combat.py b/tasks/combat/combat.py index 538aff780..9c14ae0c2 100644 --- a/tasks/combat/combat.py +++ b/tasks/combat/combat.py @@ -163,6 +163,8 @@ class Combat(CombatInteract, CombatPrepare, CombatState, CombatTeam, CombatSuppo skip_first_screenshot = True is_executing = True self.combat_state_reset() + self.device.stuck_record_clear() + self.device.click_record_clear() self.device.screenshot_interval_set('combat') while 1: if skip_first_screenshot: @@ -196,6 +198,8 @@ class Combat(CombatInteract, CombatPrepare, CombatState, CombatTeam, CombatSuppo if self.handle_battle_pass_notification(): continue + self.device.stuck_record_clear() + self.device.click_record_clear() self.device.screenshot_interval_set() def _combat_can_again(self) -> bool: From 2de76057cd7082aa005b8804ea50ef234940925c Mon Sep 17 00:00:00 2001 From: LmeSzinc <37934724+LmeSzinc@users.noreply.github.com> Date: Sat, 10 Aug 2024 22:49:36 +0800 Subject: [PATCH 02/11] Fix: Clear click record after list dragging --- tasks/combat/support.py | 4 ++++ tasks/dungeon/ui.py | 2 ++ 2 files changed, 6 insertions(+) diff --git a/tasks/combat/support.py b/tasks/combat/support.py index 867f353c4..fe86baa69 100644 --- a/tasks/combat/support.py +++ b/tasks/combat/support.py @@ -203,6 +203,7 @@ class CombatSupport(UI): scroll.set_bottom(main=self) scroll.drag_threshold = backup scroll.set_top(main=self) + self.device.click_record_clear() logger.info("Searching support") skip_first_screenshot = True @@ -216,9 +217,11 @@ class CombatSupport(UI): if character: logger.info("Support found") if self._select_support(character): + self.device.click_record_clear() return True else: logger.warning("Support not selected") + self.device.click_record_clear() return False if not scroll.at_bottom(main=self): @@ -226,6 +229,7 @@ class CombatSupport(UI): continue else: logger.info("Support not found") + self.device.click_record_clear() return False def _select_support(self, character: SupportCharacter): diff --git a/tasks/dungeon/ui.py b/tasks/dungeon/ui.py index 45e09b102..e558d038d 100644 --- a/tasks/dungeon/ui.py +++ b/tasks/dungeon/ui.py @@ -578,6 +578,7 @@ class DungeonUI(DungeonState): DUNGEON_LIST.use_plane = bool(dungeon.is_Calyx_Crimson) # Insight dungeon DUNGEON_LIST.insight_row(dungeon, main=self) + self.device.click_record_clear() # Check if dungeon unlocked for entrance in DUNGEON_LIST.navigates: entrance: OcrResultButton = entrance @@ -596,6 +597,7 @@ class DungeonUI(DungeonState): DUNGEON_LIST.drag_vector = (0.2, 0.4) DUNGEON_LIST.limit_entrance = True DUNGEON_LIST.insight_row(dungeon, main=self) + self.device.click_record_clear() DUNGEON_LIST.drag_vector = DraggableList.drag_vector DUNGEON_LIST.limit_entrance = False DUNGEON_LIST.load_rows(main=self) From db96109d038bb415fcccb75f504eaf2064eac4b5 Mon Sep 17 00:00:00 2001 From: LmeSzinc <37934724+LmeSzinc@users.noreply.github.com> Date: Fri, 2 Aug 2024 02:44:11 +0800 Subject: [PATCH 03/11] Fix: [ALAS] Catch Permission Denial on am start (cherry picked from commit 342f444164605994c0efa40257b8c4187713fe2d) --- module/device/method/adb.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/module/device/method/adb.py b/module/device/method/adb.py index 8bfa20b8c..be4faf720 100644 --- a/module/device/method/adb.py +++ b/module/device/method/adb.py @@ -320,6 +320,24 @@ class Adb(Connection): if 'Warning: Activity not started' in ret: logger.info('App activity is already started') return True + # Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.YoStarEN.AzurLane/com.manjuu.azurlane.MainActivity } + # java.lang.SecurityException: Permission Denial: starting Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.YoStarEN.AzurLane/com.manjuu.azurlane.MainActivity } from null (pid=5140, uid=2000) not exported from uid 10064 + # at android.os.Parcel.readException(Parcel.java:1692) + # at android.os.Parcel.readException(Parcel.java:1645) + # at android.app.ActivityManagerProxy.startActivityAsUser(ActivityManagerNative.java:3152) + # at com.android.commands.am.Am.runStart(Am.java:643) + # at com.android.commands.am.Am.onRun(Am.java:394) + # at com.android.internal.os.BaseCommand.run(BaseCommand.java:51) + # at com.android.commands.am.Am.main(Am.java:124) + # at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method) + # at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:290) + if 'Permission Denial' in ret: + if allow_failure: + return False + else: + logger.error(ret) + logger.error('Permission Denial while starting app, probably because activity invalid') + return False # Success # Starting: Intent... return True From 7b29800961fa501eebe5ef90c9fe83087761b9dd Mon Sep 17 00:00:00 2001 From: LmeSzinc <37934724+LmeSzinc@users.noreply.github.com> Date: Sat, 10 Aug 2024 22:16:58 +0800 Subject: [PATCH 04/11] Refactor: [ALAS] app_start_uiautomator2 to be the same as adb (cherry picked from commit 360bfa0474dd5ce4a7f312cb7120759ddbc85077) --- module/device/method/uiautomator_2.py | 130 ++++++++++++++++++++++++-- 1 file changed, 123 insertions(+), 7 deletions(-) diff --git a/module/device/method/uiautomator_2.py b/module/device/method/uiautomator_2.py index 04a55883f..880655e8b 100644 --- a/module/device/method/uiautomator_2.py +++ b/module/device/method/uiautomator_2.py @@ -224,28 +224,144 @@ class Uiautomator2(Connection): return result['package'] @retry - def app_start_uiautomator2(self, package_name=None, activity_name=None): + def _app_start_u2_monkey(self, package_name=None, allow_failure=False): + """ + Args: + package_name (str): + allow_failure (bool): + + Returns: + bool: If success to start + + Raises: + PackageNotInstalled: + """ + if not package_name: + package_name = self.package + result = self.u2.shell([ + 'monkey', '-p', package_name, '-c', + 'android.intent.category.LAUNCHER', '--pct-syskeys', '0', '1' + ]) + if 'No activities found' in result.output: + # ** No activities found to run, monkey aborted. + if allow_failure: + return False + else: + logger.error(result) + raise PackageNotInstalled(package_name) + elif 'inaccessible' in result: + # /system/bin/sh: monkey: inaccessible or not found + return False + else: + # Events injected: 1 + # ## Network stats: elapsed time=4ms (0ms mobile, 0ms wifi, 4ms not connected) + return True + + @retry + def _app_start_u2_am(self, package_name=None, activity_name=None, allow_failure=False): + """ + Args: + package_name (str): + activity_name (str): + allow_failure (bool): + + Returns: + bool: If success to start + + Raises: + PackageNotInstalled: + """ + if not package_name: + package_name = self.package + if not activity_name: + try: + info = self.u2.app_info(package_name) + except u2.BaseError as e: + if allow_failure: + return False + # BaseError('package "111" not found') + elif 'not found' in str(e): + logger.error(e) + raise PackageNotInstalled(package_name) + # Unknown error + else: + raise + activity_name = info['mainActivity'] + + ret = self.u2.shell(['am', 'start', '-a', 'android.intent.action.MAIN', '-c', + 'android.intent.category.LAUNCHER', '-n', f'{package_name}/{activity_name}']) + # Invalid activity + # Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=... } + # Error type 3 + # Error: Activity class {.../...} does not exist. + if 'Error: Activity class' in ret.output: + if allow_failure: + return False + else: + logger.error(ret) + return False + # Already running + # Warning: Activity not started, intent has been delivered to currently running top-most instance. + if 'Warning: Activity not started' in ret.output: + logger.info('App activity is already started') + return True + # Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.YoStarEN.AzurLane/com.manjuu.azurlane.MainActivity } + # java.lang.SecurityException: Permission Denial: starting Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.YoStarEN.AzurLane/com.manjuu.azurlane.MainActivity } from null (pid=5140, uid=2000) not exported from uid 10064 + # at android.os.Parcel.readException(Parcel.java:1692) + # at android.os.Parcel.readException(Parcel.java:1645) + # at android.app.ActivityManagerProxy.startActivityAsUser(ActivityManagerNative.java:3152) + # at com.android.commands.am.Am.runStart(Am.java:643) + # at com.android.commands.am.Am.onRun(Am.java:394) + # at com.android.internal.os.BaseCommand.run(BaseCommand.java:51) + # at com.android.commands.am.Am.main(Am.java:124) + # at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method) + # at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:290) + if 'Permission Denial' in ret.output: + if allow_failure: + return False + else: + logger.error(ret) + logger.error('Permission Denial while starting app, probably because activity invalid') + return False + # Success + # Starting: Intent... + return True + + # No @retry decorator since _app_start_adb_am and _app_start_adb_monkey have @retry already + # @retry + def app_start_uiautomator2(self, package_name=None, activity_name=None, allow_failure=False): """ Args: package_name (str): If None, to get from config activity_name (str): If None, to get from DICT_PACKAGE_TO_ACTIVITY + If still None, launch from monkey + If monkey failed, fetch activity name and launch from am + allow_failure (bool): + True for no PackageNotInstalled raising, just return False Returns: + bool: If success to start + Raises: + PackageNotInstalled: """ if not package_name: package_name = self.package if not activity_name: activity_name = DICT_PACKAGE_TO_ACTIVITY.get(package_name) - try: - self.u2.app_start(package_name, activity_name) - except u2.exceptions.BaseError as e: - # BaseError: package "com.bilibili.azurlane" not found - logger.error(e) - raise PackageNotInstalled(package_name) + if activity_name: + if self._app_start_u2_am(package_name, activity_name, allow_failure): + return True + if self._app_start_u2_monkey(package_name, allow_failure): + return True + if self._app_start_u2_am(package_name, activity_name, allow_failure): + return True + + logger.error('app_start_uiautomator2: All trials failed') + return False @retry def app_stop_uiautomator2(self, package_name=None): From 1f98932bc828209e37e40091577914b7ffcb561c Mon Sep 17 00:00:00 2001 From: LmeSzinc <37934724+LmeSzinc@users.noreply.github.com> Date: Sat, 10 Aug 2024 23:56:15 +0800 Subject: [PATCH 05/11] Fix: [ALAS] Handle empty getprop on mumu12 >= 4.0 (cherry picked from commit 9c7f2fcb7d917a4724752d85b763b542342f006f) --- module/device/connection.py | 26 +++++++++++++++++++++++--- module/device/method/nemu_ipc.py | 3 +++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/module/device/connection.py b/module/device/connection.py index 5779e9760..11c9aadaf 100644 --- a/module/device/connection.py +++ b/module/device/connection.py @@ -271,6 +271,7 @@ class Connection(ConnectionAttr): return self.adb_shell(['getprop', name]).strip() @cached_property + @retry def cpu_abi(self) -> str: """ Returns: @@ -282,6 +283,7 @@ class Connection(ConnectionAttr): return abi @cached_property + @retry def sdk_ver(self) -> int: """ Android SDK/API levels, see https://apilevels.com/ @@ -295,6 +297,7 @@ class Connection(ConnectionAttr): return 0 @cached_property + @retry def is_avd(self): if get_serial_pair(self.serial)[0] is None: return False @@ -305,12 +308,28 @@ class Connection(ConnectionAttr): return False @cached_property + @retry def nemud_app_keep_alive(self) -> str: res = self.adb_getprop('nemud.app_keep_alive') logger.attr('nemud.app_keep_alive', res) return res + @cached_property @retry + def nemud_player_version(self) -> str: + # [nemud.player_product_version]: [3.8.27.2950] + res = self.adb_getprop('nemud.player_version') + logger.attr('nemud.player_version', res) + return res + + @cached_property + @retry + def nemud_player_engine(self) -> str: + # NEMUX or MACPRO + res = self.adb_getprop('nemud.player_engine') + logger.attr('nemud.player_engine', res) + return res + def check_mumu_app_keep_alive(self): if not self.is_mumu_family: return False @@ -340,12 +359,13 @@ class Connection(ConnectionAttr): """ if not self.is_mumu_family: return False + # >= 4.0 has no info in getprop + if self.nemud_player_version == '': + return True if self.nemud_app_keep_alive != '': return True if IS_MACINTOSH: - res = self.adb_getprop('nemud.player_engine') - logger.attr('nemud.player_engine', res) - if 'MACPRO' in res: + if 'MACPRO' in self.nemud_player_engine: return True return False diff --git a/module/device/method/nemu_ipc.py b/module/device/method/nemu_ipc.py index 315c1897e..55973719f 100644 --- a/module/device/method/nemu_ipc.py +++ b/module/device/method/nemu_ipc.py @@ -486,6 +486,9 @@ class NemuIpc(Platform): def nemu_ipc_available(self) -> bool: if not self.is_mumu_family: return False + # >= 4.0 has no info in getprop + if self.nemud_player_version == '': + return True if self.nemud_app_keep_alive == '': return False try: From e89c8e70134b3433196348dfb8b67d44873d23ad Mon Sep 17 00:00:00 2001 From: LmeSzinc <37934724+LmeSzinc@users.noreply.github.com> Date: Sun, 11 Aug 2024 00:15:39 +0800 Subject: [PATCH 06/11] Fix: [ALAS] Launch parameters on waydroid (cherry picked from commit 886736de45ceac0f23250c9aa27d1cb516f0311b) --- module/device/connection.py | 7 +++++++ module/device/connection_attr.py | 4 ++++ module/device/method/adb.py | 7 +++++-- module/device/method/uiautomator_2.py | 7 +++++-- 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/module/device/connection.py b/module/device/connection.py index 11c9aadaf..74ef2fa3d 100644 --- a/module/device/connection.py +++ b/module/device/connection.py @@ -307,6 +307,13 @@ class Connection(ConnectionAttr): return True return False + @cached_property + @retry + def is_waydroid(self): + res = self.adb_getprop('ro.product.brand') + logger.attr('ro.product.brand', res) + return 'waydroid' in res.lower() + @cached_property @retry def nemud_app_keep_alive(self) -> str: diff --git a/module/device/connection_attr.py b/module/device/connection_attr.py index 2cb44ff5b..57fdd8468 100644 --- a/module/device/connection_attr.py +++ b/module/device/connection_attr.py @@ -163,6 +163,10 @@ class ConnectionAttr: def is_network_device(self): return bool(re.match(r'\d+\.\d+\.\d+\.\d+:\d+', self.serial)) + @cached_property + def is_local_network_device(self): + return bool(re.match(r'192\.168\.\d+\.\d+:\d+', self.serial)) + @cached_property def is_over_http(self): return bool(re.match(r"^https?://", self.serial)) diff --git a/module/device/method/adb.py b/module/device/method/adb.py index be4faf720..f699b7309 100644 --- a/module/device/method/adb.py +++ b/module/device/method/adb.py @@ -303,8 +303,11 @@ class Adb(Connection): logger.error(result) raise PackageNotInstalled(package_name) - ret = self.adb_shell(['am', 'start', '-a', 'android.intent.action.MAIN', '-c', - 'android.intent.category.LAUNCHER', '-n', f'{package_name}/{activity_name}']) + cmd = ['am', 'start', '-a', 'android.intent.action.MAIN', '-c', + 'android.intent.category.LAUNCHER', '-n', f'{package_name}/{activity_name}'] + if self.is_local_network_device and self.is_waydroid: + cmd += ['--windowingMode', '4'] + ret = self.adb_shell(cmd) # Invalid activity # Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=... } # Error type 3 diff --git a/module/device/method/uiautomator_2.py b/module/device/method/uiautomator_2.py index 880655e8b..9dec3f5a8 100644 --- a/module/device/method/uiautomator_2.py +++ b/module/device/method/uiautomator_2.py @@ -288,8 +288,11 @@ class Uiautomator2(Connection): raise activity_name = info['mainActivity'] - ret = self.u2.shell(['am', 'start', '-a', 'android.intent.action.MAIN', '-c', - 'android.intent.category.LAUNCHER', '-n', f'{package_name}/{activity_name}']) + cmd = ['am', 'start', '-a', 'android.intent.action.MAIN', '-c', + 'android.intent.category.LAUNCHER', '-n', f'{package_name}/{activity_name}'] + if self.is_local_network_device and self.is_waydroid: + cmd += ['--windowingMode', '4'] + ret = self.u2.shell(cmd) # Invalid activity # Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=... } # Error type 3 From 58da4a71443807b3e7b2f7b3454b15760bcb4200 Mon Sep 17 00:00:00 2001 From: LmeSzinc <37934724+LmeSzinc@users.noreply.github.com> Date: Sun, 11 Aug 2024 00:44:23 +0800 Subject: [PATCH 07/11] Pref: [ALAS] Connect all possible serial at once (cherry picked from commit 14a3f57d789fba50297c1371934da82474d5690b) --- module/device/connection.py | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/module/device/connection.py b/module/device/connection.py index 74ef2fa3d..557e8e07e 100644 --- a/module/device/connection.py +++ b/module/device/connection.py @@ -692,13 +692,9 @@ class Connection(ConnectionAttr): # Brute force connect nearby ports to handle serial switches if self.is_mumu12_family: before = self.serial - for port_offset in [1, -1, 2, -2]: - port = self.port + port_offset - serial = self.serial.replace(str(self.port), str(port)) - msg = self.adb_client.connect(serial) - logger.info(msg) - if 'connected' in msg: - break + serial_list = [self.serial.replace(str(self.port), str(self.port + offset)) + for offset in [1, -1, 2, -2]] + self.adb_brute_force_connect(serial_list) self.detect_device() if self.serial != before: return True @@ -711,6 +707,25 @@ class Connection(ConnectionAttr): self.detect_device() return False + def adb_brute_force_connect(self, serial_list): + """ + Args: + serial_list (list[str]): + """ + import asyncio + ev = asyncio.new_event_loop() + + def _connect(serial): + msg = self.adb_client.connect(serial) + logger.info(msg) + return msg + + async def connect(): + tasks = [ev.run_in_executor(None, _connect, serial) for serial in serial_list] + await asyncio.gather(*tasks) + + ev.run_until_complete(connect()) + @Config.when(DEVICE_OVER_HTTP=True) def adb_connect(self): # No adb connect if over http From 1ba1caabcdb69e371c095c8d6685b76cbfdc8590 Mon Sep 17 00:00:00 2001 From: LmeSzinc <37934724+LmeSzinc@users.noreply.github.com> Date: Sun, 11 Aug 2024 01:06:51 +0800 Subject: [PATCH 08/11] Add: Store reserved trailblaze power --- config/template.json | 1 + module/config/argument/args.json | 6 ++++++ module/config/argument/argument.yaml | 2 ++ module/config/argument/stored.json | 13 +++++++++++++ module/config/config_generated.py | 1 + module/config/i18n/en-US.json | 4 ++++ module/config/i18n/es-ES.json | 4 ++++ module/config/i18n/ja-JP.json | 4 ++++ module/config/i18n/zh-CN.json | 4 ++++ module/config/i18n/zh-TW.json | 4 ++++ module/config/stored/classes.py | 4 ++++ module/config/stored/stored_generated.py | 2 ++ 12 files changed, 49 insertions(+) diff --git a/config/template.json b/config/template.json index da1b72da5..5c0c8fa09 100644 --- a/config/template.json +++ b/config/template.json @@ -107,6 +107,7 @@ }, "DungeonStorage": { "TrailblazePower": {}, + "Reserved": {}, "Immersifier": {}, "DungeonDouble": {}, "EchoOfWar": {}, diff --git a/module/config/argument/args.json b/module/config/argument/args.json index 6f256c5af..94b4738f0 100644 --- a/module/config/argument/args.json +++ b/module/config/argument/args.json @@ -715,6 +715,12 @@ "order": 1, "color": "#eb8efe" }, + "Reserved": { + "type": "stored", + "value": {}, + "display": "hide", + "stored": "StoredResersed" + }, "Immersifier": { "type": "stored", "value": {}, diff --git a/module/config/argument/argument.yaml b/module/config/argument/argument.yaml index 518883531..89e52636a 100644 --- a/module/config/argument/argument.yaml +++ b/module/config/argument/argument.yaml @@ -120,6 +120,8 @@ DungeonStorage: stored: StoredTrailblazePower order: 1 color: "#eb8efe" + Reserved: + stored: StoredResersed Immersifier: stored: StoredImmersifier DungeonDouble: diff --git a/module/config/argument/stored.json b/module/config/argument/stored.json index 857b38430..0beb4eb59 100644 --- a/module/config/argument/stored.json +++ b/module/config/argument/stored.json @@ -662,6 +662,19 @@ "order": 0, "color": "#777777" }, + "Reserved": { + "name": "Reserved", + "path": "Dungeon.DungeonStorage.Reserved", + "i18n": "DungeonStorage.Reserved.name", + "stored": "StoredResersed", + "attrs": { + "time": "2020-01-01 00:00:00", + "total": 8, + "value": 0 + }, + "order": 0, + "color": "#777777" + }, "Immersifier": { "name": "Immersifier", "path": "Dungeon.DungeonStorage.Immersifier", diff --git a/module/config/config_generated.py b/module/config/config_generated.py index d20cd1636..469b09d08 100644 --- a/module/config/config_generated.py +++ b/module/config/config_generated.py @@ -57,6 +57,7 @@ class GeneratedConfig: # Group `DungeonStorage` DungeonStorage_TrailblazePower = {} + DungeonStorage_Reserved = {} DungeonStorage_Immersifier = {} DungeonStorage_DungeonDouble = {} DungeonStorage_EchoOfWar = {} diff --git a/module/config/i18n/en-US.json b/module/config/i18n/en-US.json index 3e65f33b5..e5592fc3e 100644 --- a/module/config/i18n/en-US.json +++ b/module/config/i18n/en-US.json @@ -445,6 +445,10 @@ "name": "Power", "help": "" }, + "Reserved": { + "name": "Reserved Trailblaze Power", + "help": "" + }, "Immersifier": { "name": "Immersifier", "help": "" diff --git a/module/config/i18n/es-ES.json b/module/config/i18n/es-ES.json index 288420308..171636fa3 100644 --- a/module/config/i18n/es-ES.json +++ b/module/config/i18n/es-ES.json @@ -445,6 +445,10 @@ "name": "Poder", "help": "" }, + "Reserved": { + "name": "Trailblaze Poder Reservada", + "help": "" + }, "Immersifier": { "name": "Inmersor", "help": "" diff --git a/module/config/i18n/ja-JP.json b/module/config/i18n/ja-JP.json index 5608de57a..a6176ccac 100644 --- a/module/config/i18n/ja-JP.json +++ b/module/config/i18n/ja-JP.json @@ -445,6 +445,10 @@ "name": "DungeonStorage.TrailblazePower.name", "help": "DungeonStorage.TrailblazePower.help" }, + "Reserved": { + "name": "DungeonStorage.Reserved.name", + "help": "DungeonStorage.Reserved.help" + }, "Immersifier": { "name": "DungeonStorage.Immersifier.name", "help": "DungeonStorage.Immersifier.help" diff --git a/module/config/i18n/zh-CN.json b/module/config/i18n/zh-CN.json index c3a497b1e..dd9b23529 100644 --- a/module/config/i18n/zh-CN.json +++ b/module/config/i18n/zh-CN.json @@ -445,6 +445,10 @@ "name": "开拓力", "help": "" }, + "Reserved": { + "name": "后备开拓力", + "help": "" + }, "Immersifier": { "name": "沉浸器", "help": "" diff --git a/module/config/i18n/zh-TW.json b/module/config/i18n/zh-TW.json index 1addf4201..f07928363 100644 --- a/module/config/i18n/zh-TW.json +++ b/module/config/i18n/zh-TW.json @@ -445,6 +445,10 @@ "name": "開拓力", "help": "" }, + "Reserved": { + "name": "后备開拓力", + "help": "" + }, "Immersifier": { "name": "沉浸器", "help": "" diff --git a/module/config/stored/classes.py b/module/config/stored/classes.py index 8d5073e61..cbffb5382 100644 --- a/module/config/stored/classes.py +++ b/module/config/stored/classes.py @@ -206,6 +206,10 @@ class StoredTrailblazePower(StoredCounter): return value +class StoredResersed(StoredCounter): + FIXED_TOTAL = 2400 + + class StoredImmersifier(StoredCounter): FIXED_TOTAL = 8 diff --git a/module/config/stored/stored_generated.py b/module/config/stored/stored_generated.py index 25489d7b0..7a4c52f93 100644 --- a/module/config/stored/stored_generated.py +++ b/module/config/stored/stored_generated.py @@ -22,6 +22,7 @@ from module.config.stored.classes import ( StoredInt, StoredPlanner, StoredPlannerOverall, + StoredResersed, StoredSimulatedUniverse, StoredSimulatedUniverseElite, StoredTrailblazePower, @@ -85,6 +86,7 @@ class StoredGenerated: Item_Dream_Making_Engine = StoredPlanner("Dungeon.Planner.Item_Dream_Making_Engine") Item_Shards_of_Desires = StoredPlanner("Dungeon.Planner.Item_Shards_of_Desires") TrailblazePower = StoredTrailblazePower("Dungeon.DungeonStorage.TrailblazePower") + Reserved = StoredResersed("Dungeon.DungeonStorage.Reserved") Immersifier = StoredImmersifier("Dungeon.DungeonStorage.Immersifier") DungeonDouble = StoredDungeonDouble("Dungeon.DungeonStorage.DungeonDouble") EchoOfWar = StoredEchoOfWar("Dungeon.DungeonStorage.EchoOfWar") From 20ec5d0316fd1fff96629c7087298b2e33ddbc7a Mon Sep 17 00:00:00 2001 From: LmeSzinc <37934724+LmeSzinc@users.noreply.github.com> Date: Sun, 11 Aug 2024 02:12:54 +0800 Subject: [PATCH 09/11] Fix: SURVIVAL_INDEX_OE_LOADED when oe is locked --- .../ui_rogue/SURVIVAL_INDEX_OE_LOADED.2.png | Bin 0 -> 7329 bytes .../SURVIVAL_INDEX_OE_LOADED.SEARCH.png | Bin 7242 -> 11428 bytes .../ui_rogue/SURVIVAL_INDEX_OE_LOADED.png | Bin 11428 -> 7242 bytes .../dungeon/assets/assets_dungeon_ui_rogue.py | 23 ++++++++++++------ 4 files changed, 16 insertions(+), 7 deletions(-) create mode 100644 assets/share/dungeon/ui_rogue/SURVIVAL_INDEX_OE_LOADED.2.png diff --git a/assets/share/dungeon/ui_rogue/SURVIVAL_INDEX_OE_LOADED.2.png b/assets/share/dungeon/ui_rogue/SURVIVAL_INDEX_OE_LOADED.2.png new file mode 100644 index 0000000000000000000000000000000000000000..6db8ecab6c3a3777987853d4a761bc9b95db10a6 GIT binary patch literal 7329 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 literal 0 HcmV?d00001 diff --git a/assets/share/dungeon/ui_rogue/SURVIVAL_INDEX_OE_LOADED.SEARCH.png b/assets/share/dungeon/ui_rogue/SURVIVAL_INDEX_OE_LOADED.SEARCH.png index 257eff5aa060720e11fbb628aaa3c994eaa6c7c4..59583979ea0922a608665027bf1b74f8a26cbe13 100644 GIT binary patch delta 6552 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

{fh{BpCG^OykLoPA`hS$E-m zsWpCg{a+fY#Bt_5)l&&$`0~=}^4(_nYD#-pF7OAd`_~0()t5e_Ybz}9Q?Wmy-G6LQ zuM5%*&xSQ^V`$x+ABwvDdR>^jKJVuZ!(e(|(FXSZLjUpe#6)SPwPRU!wzigN zYUaIr_ssHZ@h!=9pl9^(^rX`$<-nE?utnB$I@BC8pv>k^7ccCbS8S)pNr3P)$@K%x zx-fhUG{GEVRFF4rEk&L@#goRuZ!fkH^PA#DXL&I)Nwrwan%b!v1h(ccQ%$Tn>=%b>PNHE)jIw-qOF0LYi+ri<*l-pJG z6g9kjKOnLL6uJw*e1qmWpjbp3G;%Vqx8#qB+{#Hi`|S~?zh$%OD@aG3CohIg7w4FQ zln~Z^*T)Dt#0{&9*wQbhsWuV=NLlaIe$>q;5s1+X|)pla~8XmS10 z;>ask$u2)6tgD4`SM)a!WqzZjJBQlB(bd56wJd>fq@N%*>(Lwf-KM80fA`Z)olJ!J62%U z2&P9C55*C2yLX1?3|n^lJRSPItgCBzDpfyJjaJEMexUOMI!$7}goKhH^^LaIFc>UW zGo7K7Py>-k<(JJu=D6Anx5e1v1xmfSh#R#qwCRt@oUaWJ8&iXR9R5LO3H)cRGxkTWX_;!GF`sbqI~i4hf2hq z@~UBv>JIfn2^`qlOyCC`c+vYH9E(pRVn>2|%>~;2I3(#E(xx}zZ}f)D+oeqb*$X@VLq69dz#8Rhn>{Z2re6o ziwqilk>6M!K^N2M>+vFsxQKJ1W~TLa2ua+o$3AXMP# z`+kl|vQ=qv9?iLO{qpC;5g{?N=wU67p2N;zYvTUlbf`9;UhR0ol$?JNvGNr;(p%%A zrCd~|v|Bh&jF19X!dn%^pXp{`NC&R8zyF7cnw*KaLxPz+TBs5zDk|a-TUhNUro8L!dqQBj2NuriEp3nV}BIWf(v=E%_3>S zbzs;DbnEeo&Hd@Uy}HeI0L!1w2ruA$d#C|xpuHwR5||QhthZXsW(W7-+l>35CiW6! z6G&e*>;l{n*GnSM8GBX7l=r@{h`1T^e@Y<|BwrjSdC^f+=sN{t6%Z-2$ue+MRaUJl zLHI{2hdbrf_OSq+m%4loB#Wh^TQ#CrLlJj6#`tU>%z`Pa;MrhOE(~YZ=+`3R26m6z zePD^eH^&OJV)Ka0ci5*1|7~jvA37o`iMe!tu)IMELmFjqSPZ7Qf8eeRWS{tu0)K@- zr@Lsnu8}`v*c|t-;goTNldYTX} z{X-=VH!pk=2QKZP|9Kp_K&6mT1_w=3d6GqhptXi3mR83AzOJ@~r}{hxNwyJ@k@=1J z$!|aYr&gvr2HCKa{N~~V(x;tJuO?iiH#QQ}4$H>rKJ_t!0?xhM?iz8HPZ|cR+%=Kq&kGv0h@~J2F@~( zh0jt%@9Q4I{ELtl4^JH)=HT~(X|o@G(?iv*>ziuQTIMdth9-EJvv%iwXYcy6@MLIw zh!hxT1lm@P3Po2Cb@E3F(Vt*YT;bHrxvn_xJbQetJ$Jq-5>_P3V2B$>Ow}tR&A%Su z@RjQK!4l2cEWi7M(Mq}v788gat+^Y50)gVoDm?*kF*qG+{c&HuuxS zFh$b`t%HyMWr**u8|mZrZjB`a4OfCd{p%o~MORSNzvu$;cvhitX91L z_nGx9Vh=j$x#>~SQauU$Gh7n=O8aj8LrCWz3I`yNgBwE*DhTlFF>n~@lK+1f|6jiV z|AX<{*#Txxz*~W(F9g!r@x#@RAPL-y&Jake5miNk%X#nPM`O-E)w|8MYU{rSVfrJeivLTsVLI2I zHEWY}6c~W8x2cABzFgI$su7J4B1*lo*#CCWfqv-JIVk$2C?e|}3!57h;e|%SpB+WE zJyO-3X|cb3EZrVVPlSaiP3s|`^`lQDwpwAU_Kygg%2@ssM>&y!9*?sM;6Whu{owPW zZ?mv@?9HjKUOV@K;VREwJ&n(|5B#XP$W`wfnEHRa H{kQ)DlrT1J delta 1973 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

{fh{BpCG^OykLoPA`hS$E-m zsWpCg{a+fY#Bt_5)l&&$`0~=}^4(_nYD#-pF7OAd`_~0()t5e_Ybz}9Q?Wmy-G6LQ zuM5%*&xSQ^V`$x+ABwvDdR>^jKJVuZ!(e(|(FXSZLjUpe#6)SPwPRU!wzigN zYUaIr_ssHZ@h!=9pl9^(^rX`$<-nE?utnB$I@BC8pv>k^7ccCbS8S)pNr3P)$@K%x zx-fhUG{GEVRFF4rEk&L@#goRuZ!fkH^PA#DXL&I)Nwrwan%b!v1h(ccQ%$Tn>=%b>PNHE)jIw-qOF0LYi+ri<*l-pJG z6g9kjKOnLL6uJw*e1qmWpjbp3G;%Vqx8#qB+{#Hi`|S~?zh$%OD@aG3CohIg7w4FQ zln~Z^*T)Dt#0{&9*wQbhsWuV=NLlaIe$>q;5s1+X|)pla~8XmS10 z;>ask$u2)6tgD4`SM)a!WqzZjJBQlB(bd56wJd>fq@N%*>(Lwf-KM80fA`Z)olJ!J62%U z2&P9C55*C2yLX1?3|n^lJRSPItgCBzDpfyJjaJEMexUOMI!$7}goKhH^^LaIFc>UW zGo7K7Py>-k<(JJu=D6Anx5e1v1xmfSh#R#qwCRt@oUaWJ8&iXR9R5LO3H)cRGxkTWX_;!GF`sbqI~i4hf2hq z@~UBv>JIfn2^`qlOyCC`c+vYH9E(pRVn>2|%>~;2I3(#E(xx}zZ}f)D+oeqb*$X@VLq69dz#8Rhn>{Z2re6o ziwqilk>6M!K^N2M>+vFsxQKJ1W~TLa2ua+o$3AXMP# z`+kl|vQ=qv9?iLO{qpC;5g{?N=wU67p2N;zYvTUlbf`9;UhR0ol$?JNvGNr;(p%%A zrCd~|v|Bh&jF19X!dn%^pXp{`NC&R8zyF7cnw*KaLxPz+TBs5zDk|a-TUhNUro8L!dqQBj2NuriEp3nV}BIWf(v=E%_3>S zbzs;DbnEeo&Hd@Uy}HeI0L!1w2ruA$d#C|xpuHwR5||QhthZXsW(W7-+l>35CiW6! z6G&e*>;l{n*GnSM8GBX7l=r@{h`1T^e@Y<|BwrjSdC^f+=sN{t6%Z-2$ue+MRaUJl zLHI{2hdbrf_OSq+m%4loB#Wh^TQ#CrLlJj6#`tU>%z`Pa;MrhOE(~YZ=+`3R26m6z zePD^eH^&OJV)Ka0ci5*1|7~jvA37o`iMe!tu)IMELmFjqSPZ7Qf8eeRWS{tu0)K@- zr@Lsnu8}`v*c|t-;goTNldYTX} z{X-=VH!pk=2QKZP|9Kp_K&6mT1_w=3d6GqhptXi3mR83AzOJ@~r}{hxNwyJ@k@=1J z$!|aYr&gvr2HCKa{N~~V(x;tJuO?iiH#QQ}4$H>rKJ_t!0?xhM?iz8HPZ|cR+%=Kq&kGv0h@~J2F@~( zh0jt%@9Q4I{ELtl4^JH)=HT~(X|o@G(?iv*>ziuQTIMdth9-EJvv%iwXYcy6@MLIw zh!hxT1lm@P3Po2Cb@E3F(Vt*YT;bHrxvn_xJbQetJ$Jq-5>_P3V2B$>Ow}tR&A%Su z@RjQK!4l2cEWi7M(Mq}v788gat+^Y50)gVoDm?*kF*qG+{c&HuuxS zFh$b`t%HyMWr**u8|mZrZjB`a4OfCd{p%o~MORSNzvu$;cvhitX91L z_nGx9Vh=j$x#>~SQauU$Gh7n=O8aj8LrCWz3I`yNgBwE*DhTlFF>n~@lK+1f|6jiV z|AX<{*#Txxz*~W(F9g!r@x#@RAPL-y&Jake5miNk%X#nPM`O-E)w|8MYU{rSVfrJeivLTsVLI2I zHEWY}6c~W8x2cABzFgI$su7J4B1*lo*#CCWfqv-JIVk$2C?e|}3!57h;e|%SpB+WE zJyO-3X|cb3EZrVVPlSaiP3s|`^`lQDwpwAU_Kygg%2@ssM>&y!9*?sM;6Whu{owPW zZ?mv@?9HjKUOV@K;VREwJ&n(|5B#XP$W`wfnEHRa H{kQ)DlrT1J diff --git a/tasks/dungeon/assets/assets_dungeon_ui_rogue.py b/tasks/dungeon/assets/assets_dungeon_ui_rogue.py index c64300e06..d2e5e6db9 100644 --- a/tasks/dungeon/assets/assets_dungeon_ui_rogue.py +++ b/tasks/dungeon/assets/assets_dungeon_ui_rogue.py @@ -45,13 +45,22 @@ SIMULATED_UNIVERSE_LOADED_CLASSIC = ButtonWrapper( ) SURVIVAL_INDEX_OE_LOADED = ButtonWrapper( name='SURVIVAL_INDEX_OE_LOADED', - share=Button( - file='./assets/share/dungeon/ui_rogue/SURVIVAL_INDEX_OE_LOADED.png', - area=(455, 208, 485, 338), - search=(460, 238, 480, 268), - color=(130, 116, 91), - button=(455, 208, 485, 338), - ), + share=[ + Button( + file='./assets/share/dungeon/ui_rogue/SURVIVAL_INDEX_OE_LOADED.png', + area=(460, 238, 480, 268), + search=(455, 208, 485, 338), + color=(221, 192, 131), + button=(460, 238, 480, 268), + ), + Button( + file='./assets/share/dungeon/ui_rogue/SURVIVAL_INDEX_OE_LOADED.2.png', + area=(460, 238, 480, 268), + search=(455, 208, 485, 338), + color=(198, 161, 100), + button=(460, 238, 480, 268), + ), + ], ) SURVIVAL_INDEX_SU_LOADED = ButtonWrapper( name='SURVIVAL_INDEX_SU_LOADED', From 216a1bac2f640d9e47ac77ce8abff169239a92ea Mon Sep 17 00:00:00 2001 From: LmeSzinc <37934724+LmeSzinc@users.noreply.github.com> Date: Sun, 11 Aug 2024 02:27:40 +0800 Subject: [PATCH 10/11] Refactor: Abstract StaminaStatus class to handle various states --- .../combat/prepare/OCR_TRAILBLAZE_POWER.png | Bin 10207 -> 0 bytes .../combat/{ => stamina}/fuel/FUEL.SEARCH.png | Bin .../share/combat/{ => stamina}/fuel/FUEL.png | Bin .../combat/{ => stamina}/fuel/FUEL_MINUS.png | Bin .../combat/{ => stamina}/fuel/FUEL_PLUS.png | Bin .../fuel/FUEL_SELECTED.SEARCH.png | Bin .../{ => stamina}/fuel/FUEL_SELECTED.png | Bin .../combat/{ => stamina}/fuel/FUEL_SLIDER.png | Bin .../combat/{ => stamina}/fuel/OCR_FUEL.png | Bin .../{ => stamina}/fuel/OCR_FUEL_COUNT.png | Bin .../combat/{ => stamina}/fuel/USING_FUEL.png | Bin .../EXTRACT_RESERVED_TRAILBLAZE_POWER.png | Bin ...XTRACT_RESERVED_TRAILBLAZE_POWER_COUNT.png | Bin .../reserved}/RESERVED_MINUS.png | Bin .../reserved}/RESERVED_PLUS.png | Bin .../reserved}/RESERVED_SLIDER.png | Bin .../combat/stamina/status/ICON_SEARCH.png | Bin 0 -> 45234 bytes .../stamina/status/IMMERSIFIER_ICON.png} | Bin .../stamina/status/IMMERSIFIER_OCR.png} | Bin .../status/RESERVED_ICON.png} | Bin 7016 -> 7005 bytes .../status/RESERVED_OCR.png} | Bin 7485 -> 9026 bytes .../status/STAMINA_ICON.png} | Bin 6980 -> 6988 bytes .../combat/stamina/status/STAMINA_OCR.png | Bin 0 -> 12042 bytes tasks/combat/assets/assets_combat_fuel.py | 165 ------------------ tasks/combat/assets/assets_combat_prepare.py | 10 -- .../assets/assets_combat_stamina_fuel.py | 85 +++++++++ .../assets/assets_combat_stamina_reserved.py | 55 ++++++ .../assets/assets_combat_stamina_status.py | 75 ++++++++ tasks/combat/combat.py | 25 ++- tasks/combat/fuel.py | 66 +++++-- tasks/combat/prepare.py | 41 ++--- tasks/combat/stamina_status.py | 161 +++++++++++++++++ .../dungeon/assets/assets_dungeon_stamina.py | 10 -- tasks/dungeon/stamina.py | 8 +- tasks/dungeon/state.py | 72 +------- tasks/ornament/combat.py | 2 +- tasks/rogue/entry/entry.py | 2 +- tasks/rogue/event/reward.py | 2 +- 38 files changed, 464 insertions(+), 315 deletions(-) delete mode 100644 assets/share/combat/prepare/OCR_TRAILBLAZE_POWER.png rename assets/share/combat/{ => stamina}/fuel/FUEL.SEARCH.png (100%) rename assets/share/combat/{ => stamina}/fuel/FUEL.png (100%) rename assets/share/combat/{ => stamina}/fuel/FUEL_MINUS.png (100%) rename assets/share/combat/{ => stamina}/fuel/FUEL_PLUS.png (100%) rename assets/share/combat/{ => stamina}/fuel/FUEL_SELECTED.SEARCH.png (100%) rename assets/share/combat/{ => stamina}/fuel/FUEL_SELECTED.png (100%) rename assets/share/combat/{ => stamina}/fuel/FUEL_SLIDER.png (100%) rename assets/share/combat/{ => stamina}/fuel/OCR_FUEL.png (100%) rename assets/share/combat/{ => stamina}/fuel/OCR_FUEL_COUNT.png (100%) rename assets/share/combat/{ => stamina}/fuel/USING_FUEL.png (100%) rename assets/share/combat/{fuel => stamina/reserved}/EXTRACT_RESERVED_TRAILBLAZE_POWER.png (100%) rename assets/share/combat/{fuel => stamina/reserved}/OCR_EXTRACT_RESERVED_TRAILBLAZE_POWER_COUNT.png (100%) rename assets/share/combat/{fuel => stamina/reserved}/RESERVED_MINUS.png (100%) rename assets/share/combat/{fuel => stamina/reserved}/RESERVED_PLUS.png (100%) rename assets/share/combat/{fuel => stamina/reserved}/RESERVED_SLIDER.png (100%) create mode 100644 assets/share/combat/stamina/status/ICON_SEARCH.png rename assets/share/{dungeon/stamina/ENTER_IMMERSIFIER.png => combat/stamina/status/IMMERSIFIER_ICON.png} (100%) rename assets/share/{dungeon/stamina/ENTER_IMMERSIFIER.BUTTON.png => combat/stamina/status/IMMERSIFIER_OCR.png} (100%) rename assets/share/combat/{fuel/RESERVED_TRAILBLAZE_POWER_ENTRANCE.png => stamina/status/RESERVED_ICON.png} (73%) rename assets/share/combat/{fuel/OCR_RESERVED_TRAILBLAZE_POWER.png => stamina/status/RESERVED_OCR.png} (57%) rename assets/share/combat/{fuel/FUEL_ENTRANCE.png => stamina/status/STAMINA_ICON.png} (74%) create mode 100644 assets/share/combat/stamina/status/STAMINA_OCR.png delete mode 100644 tasks/combat/assets/assets_combat_fuel.py create mode 100644 tasks/combat/assets/assets_combat_stamina_fuel.py create mode 100644 tasks/combat/assets/assets_combat_stamina_reserved.py create mode 100644 tasks/combat/assets/assets_combat_stamina_status.py create mode 100644 tasks/combat/stamina_status.py diff --git a/assets/share/combat/prepare/OCR_TRAILBLAZE_POWER.png b/assets/share/combat/prepare/OCR_TRAILBLAZE_POWER.png deleted file mode 100644 index 8fe06b9b76b95459ffbeb20606f92b1877e26ddb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10207 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 KQmORn{r>|43Zz>A diff --git a/assets/share/combat/fuel/FUEL.SEARCH.png b/assets/share/combat/stamina/fuel/FUEL.SEARCH.png similarity index 100% rename from assets/share/combat/fuel/FUEL.SEARCH.png rename to assets/share/combat/stamina/fuel/FUEL.SEARCH.png diff --git a/assets/share/combat/fuel/FUEL.png b/assets/share/combat/stamina/fuel/FUEL.png similarity index 100% rename from assets/share/combat/fuel/FUEL.png rename to assets/share/combat/stamina/fuel/FUEL.png diff --git a/assets/share/combat/fuel/FUEL_MINUS.png b/assets/share/combat/stamina/fuel/FUEL_MINUS.png similarity index 100% rename from assets/share/combat/fuel/FUEL_MINUS.png rename to assets/share/combat/stamina/fuel/FUEL_MINUS.png diff --git a/assets/share/combat/fuel/FUEL_PLUS.png b/assets/share/combat/stamina/fuel/FUEL_PLUS.png similarity index 100% rename from assets/share/combat/fuel/FUEL_PLUS.png rename to assets/share/combat/stamina/fuel/FUEL_PLUS.png diff --git a/assets/share/combat/fuel/FUEL_SELECTED.SEARCH.png b/assets/share/combat/stamina/fuel/FUEL_SELECTED.SEARCH.png similarity index 100% rename from assets/share/combat/fuel/FUEL_SELECTED.SEARCH.png rename to assets/share/combat/stamina/fuel/FUEL_SELECTED.SEARCH.png diff --git a/assets/share/combat/fuel/FUEL_SELECTED.png b/assets/share/combat/stamina/fuel/FUEL_SELECTED.png similarity index 100% rename from assets/share/combat/fuel/FUEL_SELECTED.png rename to assets/share/combat/stamina/fuel/FUEL_SELECTED.png diff --git a/assets/share/combat/fuel/FUEL_SLIDER.png b/assets/share/combat/stamina/fuel/FUEL_SLIDER.png similarity index 100% rename from assets/share/combat/fuel/FUEL_SLIDER.png rename to assets/share/combat/stamina/fuel/FUEL_SLIDER.png diff --git a/assets/share/combat/fuel/OCR_FUEL.png b/assets/share/combat/stamina/fuel/OCR_FUEL.png similarity index 100% rename from assets/share/combat/fuel/OCR_FUEL.png rename to assets/share/combat/stamina/fuel/OCR_FUEL.png diff --git a/assets/share/combat/fuel/OCR_FUEL_COUNT.png b/assets/share/combat/stamina/fuel/OCR_FUEL_COUNT.png similarity index 100% rename from assets/share/combat/fuel/OCR_FUEL_COUNT.png rename to assets/share/combat/stamina/fuel/OCR_FUEL_COUNT.png diff --git a/assets/share/combat/fuel/USING_FUEL.png b/assets/share/combat/stamina/fuel/USING_FUEL.png similarity index 100% rename from assets/share/combat/fuel/USING_FUEL.png rename to assets/share/combat/stamina/fuel/USING_FUEL.png diff --git a/assets/share/combat/fuel/EXTRACT_RESERVED_TRAILBLAZE_POWER.png b/assets/share/combat/stamina/reserved/EXTRACT_RESERVED_TRAILBLAZE_POWER.png similarity index 100% rename from assets/share/combat/fuel/EXTRACT_RESERVED_TRAILBLAZE_POWER.png rename to assets/share/combat/stamina/reserved/EXTRACT_RESERVED_TRAILBLAZE_POWER.png diff --git a/assets/share/combat/fuel/OCR_EXTRACT_RESERVED_TRAILBLAZE_POWER_COUNT.png b/assets/share/combat/stamina/reserved/OCR_EXTRACT_RESERVED_TRAILBLAZE_POWER_COUNT.png similarity index 100% rename from assets/share/combat/fuel/OCR_EXTRACT_RESERVED_TRAILBLAZE_POWER_COUNT.png rename to assets/share/combat/stamina/reserved/OCR_EXTRACT_RESERVED_TRAILBLAZE_POWER_COUNT.png diff --git a/assets/share/combat/fuel/RESERVED_MINUS.png b/assets/share/combat/stamina/reserved/RESERVED_MINUS.png similarity index 100% rename from assets/share/combat/fuel/RESERVED_MINUS.png rename to assets/share/combat/stamina/reserved/RESERVED_MINUS.png diff --git a/assets/share/combat/fuel/RESERVED_PLUS.png b/assets/share/combat/stamina/reserved/RESERVED_PLUS.png similarity index 100% rename from assets/share/combat/fuel/RESERVED_PLUS.png rename to assets/share/combat/stamina/reserved/RESERVED_PLUS.png diff --git a/assets/share/combat/fuel/RESERVED_SLIDER.png b/assets/share/combat/stamina/reserved/RESERVED_SLIDER.png similarity index 100% rename from assets/share/combat/fuel/RESERVED_SLIDER.png rename to assets/share/combat/stamina/reserved/RESERVED_SLIDER.png diff --git a/assets/share/combat/stamina/status/ICON_SEARCH.png b/assets/share/combat/stamina/status/ICON_SEARCH.png new file mode 100644 index 0000000000000000000000000000000000000000..38240df1ac658811c7b894f1bf19fec997f87f04 GIT binary patch literal 45234 zcmc$^1ydbSvjsZ1yE_~R!QEXB4uRk#5ZocSySoN=C%8*+cXtUM+}+{vefQq?e!`oo zQ+w)6)l^UK-QBBKuP~)AQYeUohyVbf$Vh{g0RZOX7IF$6@?#MplZE(L5NxHj8~^|b z>pwpTAT0wQ01y?-#l@AB%xoNO9L#KN$z{aF$!+azOw6r}0l;-7Q^iH|*FCP##=S9` zy4cc1O|q3A0HQ31A41p4Lyrga1JN->`h!9d)v<9fGNje|{O1v+Gefs?Xqrt$!$ZGC zsA=<@k^L=h@Nz#tJ$+t$Zrjh;f0=NbMDxYKq>kImvjBLNg9P}N$YK8@`y{|fhY(dl}3sRQlu5o zQ}a`1fb8l4a>_+OOwe7G5WZTCY*LWE?J$6Iv}P=th#ugZD#kDdkn=zS;-pyPP~`GZ zIV>}sn7uT01!S-cfaun$L{a_+uAePw>rP+&wI1HumK5CTyDIzMM6RY=wBw!S9EuG7ocnh zA*!7^Ela)wE9!vR#-k4VDniaT#3}d32sfS=5z?$&r6BCS3CWm&Xvm1`=iietUvGfDc=Tzd|snzr?)w3v>9;1 zFEzuOl|TxEZhw^Hz!bxY+n9$wY?ow7uL!?fP=NAa#jY=na1EnYUEXI9kP)bwGtPjB z_cdcAAyOQGZpy*tb`Jo*Iv-<1=plgdTPz;0UCC~&sUTQQnNMD*G-nW4KFckYMsDH@50J22P zB2Gt|@`}+On>R{Z|FHNmg;E7TmMlgOXnWQ5@ZIS$i~9B4YeNqLsj zg!QC?zKwas({cw+j(}Hqw4v`bE2>H4vc7g?h=g94CL#48uHmjGr+N&hA&DlpGY(N# zmi{?B6=Z}j)(QNNK=d9f|JYb5O?gf6-=9t>>oHs4H4p*BnbOEZtwyRH(!8|Gpqne2Qh0L6WhQUX^AnP$>|aK{wBkr#_Cg z9$xv&1l z9DHdgU-mZ{>l|k#W|fcXdd$5aw{p=1WM_T1&VpCzM^3 zW0WSp>gIRozWP5IqSOWlN#+Dg=c^hv4G=_8;0~}EUuudi*sDVwGgzi57<{jNJdt;X zc_wmZ_K;T*cPKR}H;FUJ+_M{pKpm*ryx?8Vke#5IK$-AhgkltCtXZ(AFsbma;9hZG z=~yv1wLir@JzhC?vdt99WXQbbv*x>ZLTKS?`PvfHvg$N>Bs6Py>~@H7J93M9xHc_y zYkiY{i+6Osa6V1O&B6iC6-!{n%42vj7HfE5nPT2NeG$0z8)MY0C9cmbe_AI0b2If> zi0KZeE1r-^xec*FImf#3UrPaf19P_3g1&m(41dd)%7;&) zdFL}Mv-CTb+g4wqf(j)v`eh@yA_kLIk~~LYk`$8e%Tv^a)ZNr?)fdZU7POBUj;$9o ztdxi}(vj2o(nlMASEN_;Ij381U~gl`(9Y1_s{CAGJ$X4nJV`r&J>|XAzx#A&eK$!m zMvO_a!0*WKY47MX=4@r#c3iN<(Oc42(tD_3N@SYrka^9CS0ooZika-3jHhB<9A5l0 z+kG@~m+-7*reXFrKfN{mZ^g3p+}fC6zgO9_0#iECuuiYwx#-Qsz2>&v*iL3~dU4Nn z>^}1k=O0=>p4&+k>oTab7Feu@R{OqhwvT$~@d*hUKTRA$2@MEAX1iyHbQE=fHUv8; zy%)Swz2RQ6p820fUt=CRx7@C9FTcR(L3BgxLbUr4`qe>MLXknILKnhu!bHKe!ZITZ z;fNt4plFfV|FY@AyCQltWdCc*kT#7o0-uTVjp&JGj9Q*_0V6ti5`F{S+otGI{&1`j zK6F#cDzur*oFEnN(F>cFj;)mG=xe=-qn+bD!$SE#t!LBr=*yUr$Upq67LE4KrsWn^ z%2tLa>CL{)rOke>ArBIl$(W8#BA~^o73;|pl!BRDE4&*(E~dncuee+MQ-K8QDlk1rQKBO+D(`DeQ?sl<{9dMd z;vLT#znA!vS+Js{(*QeyqB6Z(96|ga%4-F6@WOief zO_QPtJ^e3~e{Or$BSgPKM(+PnJ~~{l;#dXAPv_SwS1O_6$}|6_cm0n4-L+Y|UHaP` z`-aKe(IX|2KdxtcY_(Ezb=^|4tJdWvs8ga9moh>H&xMIqN4dqw)%;?{Yt(GCHtAJq zTT@x>%EImMRkU)zOktroy}t%WVoAdA=+DZVZ+{GN^b?KL&MlJXzpMMu;U(&p+m`>X ze5jUe-rLsrqC4+->t?;OvM$>+a(XO%TyXre{9dcGO19lXbbc!M0;PiJGHRDd*IIVn zG1uMVHhR2%d}JJoQ=jwn`&eW7>QydR{+)ZKkItz2YeiX8$1?TGLg$)`$2DpI2@e1I zdBRCs1HG$;WxIse?a!Gr|FsxG1EQABJ@2(_!not?D^ z*2-K_q|$u0yXn3*E9s|cE)BNd=umq^ce_7t6nT2=C>`WZ^#1J~-$?aox`jWMcB7x+ z>vSq-%(u=F%xynEh|JF<`9UJp(e&u~BhW<`-eX zxzxXI_wp~PmO5W`+D*kLvxM;+&*YnQ?}x9~_hWP}+H7w?_Xewil_s=BV6 zw7XLPr3>T5c((+I8`L&1vo5(IQ|V(%JH?v&evn zJ*B20stS$$2}Rn(B*kwy*R;rkZ;)GU&B5E}ulq*jnRjb(NKX0p$zpT&^``ZvpKC4m z3vOq;`@8@K2poz|Ar=V#|LaYv?^nG4u|tFHXY;NQ7#ffW35|Gxk!Y4-zitY~ElR31ZsL`AhX2!ip>cGN=;MENaNm45Vs4DnWbOb`!5+1%R!3Luw(ptsmWC>xN0nKC>ZcOKpksv>l>ylUn8>< z^$t7?__7KSU3eKPVzlACP=I=Z|11GqT_7PM3<^CiWPq5%ZRS%TQ-!0S>e1sA`0T2g!2WWTaf#F#xDakDXUi7?7x zL1JvL4+N48-MlwAlR|1zQfTcQlx+WVQXc9k<==}mN!cA@dee$IA~;P%!G$4DH~T-s zUMGxh*+v;)acR>=y!V|EwyGL5`~pL2Y^co`lLVVjSVKeRu~>N4>&@DNP7S-=V5t_U*^A170Ue)IN>9Zobpr7ZN|eUL*VB^|QRY z2xPt|lpRNeM9Y``_v~Jb_>2TwV;@JSFL&{<%@WIuxXX?b{9u2S?8984J!QBLcha>z z!2Z+;B5lM<*|$)ume*Dcy}6P{5f@7xE0oX_bvwVrSoMbl>9t}JNQXjz@nNuY^n-`f zVTNFrV$tENor(cUB5ZO92x@(F0~1UL2wZBt0D)6j)-I~&NDL}RMVL1b0$n0mS;%Ej z#{+v${dw{5{kFto+K+{fG_iVW#TQC##psO31f9|Fbobmkq%m(e)0S{bZR=tkX8Yx1 zzQ2FWk~ptn9Ct=XR*PLo^85*2x}Mt{(P!tj~)xi{^ZX377#e#0C7n-?^iW&k#e z1hdokFkl}9O;;=nJAo7O9WO9~ny?9mvVRZ$SYo@CHSA>Gz3YBo2vf=Hkm!7k6WG?e zQ2dhe|5=Ef0>CRlR#C$(H}*hs1hr0=qaA8>kj1+0MQZV$+$(ZJo7%xd07L-!D55Ew zZw!^FT`3CQ9Wd!g1%mwYAdLaQ$a*7-r8y!nPXvgDN+QQs+i0dhgCn5{CW_jwp;P;_ zQx{|pRGDYQJ{s0kRX-{I6gAMEnM>b2x#Q}2bSl-fZf=N3bvAa!PvL^JqC%yFl zB-jht-OjpEcm-z)(l{s1Pce3~&VTEDW^S%aMR3asqBw?&5Xxv2EV;a_J}J6+-pmd6GiXs{moW6IziQe@*$-0<(@%p8t%A(7r; zJm>Xiy>$JCyL|4bNkoh8w{EcCk_#Z-(MU++;CTKU!EIN(ER-}v<8&Z+njUy625Iao z1zXnPJNQUf1k=x;klxhM)h9nV5wjj05tV4T>Iy!8!8fHJ1c^)M3}4;)yV%nv3P1aV zo07l7Q&^k!b&-kAstM{UE5i84vP7VV!W+uyXyFF}VAuZX?$T?pD8=c9jz&A+4P{y~2uDry(n?RZ&k*JrNTNRJk9aNTdx>AJ&lAT`Kscpk- zrzk+~?ngambhuYCv0mNA9yj~u9k3IWDrDGeYB=RIBcaE=(ar?q|0{CjMq?7 ztiAS5{$~wOVFuMf{-GN0gga|JH6-)I*mzRc{?k8NU8jPAo;$QSx>xzbn$#2=3QSCj z@qYHmUE63cNP19g3zsu6=@c#Z$FevxKhA^D(;1`qa!FZgrke4mm44uO{s& z*QDykhS8w{UH>ibTZsx@P!qhrPz>5T9EPCjP58D{CmG3=?LPlVmL5lH3>TX`q-MJ!h{7-AB%)o{-ywQ_`=CU4~X}JXrRd> zgE0azM77kc#0T)mWO&TzLNBl@P7LY@rnAyzK8O((W!lUoF75C|QlrLYzt13YzdlEF zX1xe?P-tj_UvV=Vy68z}T5GqCfU1K169k#$X-3S++Mnl4u%aha+Eigl*jGA4(PbMf zDvUc(tX#GqH9jdp=olx(C+HA(0QM8slk=~MT}A7P_As-e)p6{9HOcZ8Srw)ME~d(k z{9-0d96|3>8I4gz9+0PcY3hE&8B?Xk$>lkXyb2Y62q!9$HFAQqq=u|Uzok|*5!i#R zvBMysfqrFo2|Q>F6bK@W3J4MG2zXXea+eV2M|~p^?14X3O@YukS}7vkMz3wPWE6cO zTY3{)IN0!ulivuwyKWCCq-k;V;(HiNigambr5o!uvFpVzHn~a^$Qqi1(EiS7KpJ6) zWTiy>q6=BQEHAp9?>q3k>^Keur2Y%z-Z3~*{1ASdv0bZn;~<9>&HOcrGF9_N6^kg| zN9ZhHG@Ja+RZSqK{6qAGJ-1r3i4iGe1@~gTBx~J1Q|aod_TsOKPw!bi<*!4KSX|!z z8;d);A6a5-dl(~va$j(Of7ckuz_Zt?PyUKF=ov9C!JnKdO{Nb$PGl2{8qBWsrXj`= zU~2tOpZOhL8L`+~2}kisHn~8IO3cUzL-n`p<$nLr2fL??2rO~`fztoe?OQh80zmuczM_s^pGmJ zU;q{FHe;jaCa?`uBRKaZC`-z-WO~5@pjsJ}PXt@Nl2VFuP-qI__S}TU=dw%Z!g<&M zN}-%%wW*wPqs4+@=s)y-ZsB3U>pWR$dSXy_hK2?Qq29OAFg50;yQY}#M%+S4LH}>M z%p|JyR%JwyH zdekpD1-4`wg>W(TAoM9949|1gEr8x__;mkb__#h+Nu@|rF!-?})U|IYn7E&u#=w)( z0Dxhzqc)B-RWyynz~I7~F@Rh+3>3(H(+O{7a*jxZ#j}jj*J59Cj_K)oVkT$~^#p&1 z+AWxo4lLduQsCO&--Zj;ib=KGODx>~^_$S$naCdk+iY>V!!_%i6_Vl`<-%_UfF>V8 z#19tmW59kD3*oK0WgG>2!cjP+p8PB$V5&0;3?3Sbm=w(n+7kKQykfL05UiZz?fMTp zA7O5eR0P)q-uMs-F-+b>NkFblQ;e15mw**B=bFXex_ zjUHV{tLhA=APSmM?5_-N26ER{G6hq!^)Hooj-_15kzmVd%#u`Mq`F!c+VoHSvu>k& z-n&6mT*(xLv++13CmXZBpiZ0GQ?@feb?^qsb~WLlDLM4oi?@-?W1wv!D3J4N4}Jh5 zMAySWb*^5OZ=l!4eX+Fd>PlxpLbVclz@wOZgM8f|d2Oc7obzn`40#ev0WFFb9P$jg z&`|#YmH?VUgzjrW1M*fU3Wgr=(NJkXu&lHAkev2{Y*y==R&J}ORr-V6`T~wU z_@s*apt23a@8|Z@0?)X3J|d$Z10wprU8K(=bc$92C|!^5)A^S!se;4jg{>BT6?qyr zt-xBA6AVVd-2kqn=f-$mdUk1=aa(F866iwYc>^Z(rFikLyW`sR6YC`%qCFzPgcvj@ zJh;aJ=|}mS!x|hIdB|LoSVldR+?12qLy$1AdeG|Rku)Hf#mW6^uXR@!mwUe~@nx$b zj{|h_1?tkBOIO2|#@gCiSh@tLFY3@#P;~IU?2!v~qden6CS6?(`G7)=YvJ0Ltzp_O zrAX-N+koN%8qzEV5_6q#%FB0o{_|1oPVRrXh(Aei0HCXhU!{lb-(bD-)MaWvD*z7` zqhVDLv9FlJ%C&)U))ZKyGTiMXEYEu6*otkJ-tnya#1a{<`Qh=5=e*c3iVC7 zkgnc>f|Lfc?bc}$2l_pDnv>H4IWqTOAbc_C+3*O-KScq1pdd-GvDejZW!C2u+pc@F zpQCHUk1Q0B=66vxuGkp+lfq{&*OS7J35#*cKcdmUdKT7G&#$enw!X#jlX~4upNV?_ z5Nez`AOkSu9ZuZjuKDAQo+gp3P8xInI6pFTama3c9hq++jY_~#gxyMDD4PQ1lk^fZ z1|*1J&z^ojjw2$*NHBG?%i$Rtv@)I%@3A-{1}`@yx_gIcnpww8t^Nu0zi@&%7O0b^ zl^HXE#A}Ff1!39naWhS?*@l19LX8YmA2bXWP)x(@k`Fb8qOHjwbBbQ%!MpPSpOB2k zLZ?|xE9}`b06D5|GjH~Ke1@zY`X+{vHZS{4f=yn7(HRl9x3^)gZ8bGDUbo6pmh36x zMgxOz19#^eHo;dF6&2SO-{Ql-wCdXCyBjwZH3ZfJE?O@j9E~5z$c+v#_k%xLol}Nhvr|mbyX!L zhZ%K~e>VM*oKHOODqGK1+G=LqCsR=nF{;&9s%e{Sx3rlo44Q6?%Rsny(u#-I%MOjj z)4F0{!!}{#zH?%YojxH(QaQQ2#C<^i<`iv z(OIZj4Reh2fyD3;1AEOM&1ZiwhcQOL*V>X>eiDVv4ArNM97ARplf*}Ql8j_E zNQq*VB-+4Z>9C2sWKTV*JZ9?@3Czxv#ruzWyfQbBy-GJO>N>L4CE|haqAgY9asT}d((8%s5uI_Rp$*_{z>CJwstuPOaGZe&odCgQ}Y0dEELoCD} z)JtNV#(TC(Kix)zLTkUT*Q+G-r@K`K#JA8|_e!tcEevy0jw)||g!jqdjefEE_wUZb!GPD34 zqXAW$hU+*MU8Wlh&%uVF1!>jZ%{k9mas3TJhMy2vx>(XQaddRl)9b>g^dB1&kt%2? z3zcnbh;l$KRYp{*$-oR^+%$)FRreN}XF!#aR6yT6>`v9MsqA`@5L~08t6@71(lbft zq6hs#=|GpEk@AJ|s7Wy;qVD>XTS5z+f>J$n0`2PPc+(9>hEBFn&bwFc^Ku-7geP>- zmp>`=d}7NK5Zd7iD481UXS%Fkj%xJn#NxT$Ew{(KZRPTxzbM?Zhp1O-FR!mp43J|G z8K$IadFq>NArvl)n5I*Jmrq9_?9#sYRv=g!H|c+Cxk9$mucRy;`yu&z5@s~J2mWaQ z&NnVD&hO2S*0abgCU|fiiK;7E=b^? z{hthbh#Zl1q95;1hS56eS_pc2gV8kst4(X}$7p2D`!3ej)=u*%AdsxM(rZW*W4e*? zS{E%2H`__biXtFlRCJ?w>1{U*{h8ClnSRoCapbr?S#w#{9aq&iRcR<)Vm{+{f}?E; zxe-@nSGcs<5iFvp(smgYeV6E*5YWv9PitBoinqEe-dwv9hvqb&L#6SZ_6(&NIzEs;sK| zT!M?SplDg4k)ec7O#CpgSOw)fqKd-~^$g@Rpl8FOKc1ppJhzatA%M=!&S$~% zj^|2`|6{e@?zb&BS_U!oKp-&?q#oG7K33^hOsFhApdAk7o9}K=v*Zs$a=kZ>G)CL{ zUC|8;Z6{F>yC0wf*Cf;g1!$%LU3g?baB)0zPhB>+HQM5Ltz=|KR2Bs3agVb+y4p>&!)oZ)I932;3$ zCHZy#h9<`%HIa`%VI~)CQaDc32&Nua*O-u7=~ zbhP&^|HjLqqEAcn-ESOvb&)UFv_rZ2OtBh>8x4WkQ7G=8iQ?!5!kTPZqik#6VgaS) zuET0L9icSAd~GMBhStAGv_*j9Y4j%2yundIEcp4cZMFF^?@kq2D`%Ru#`l z4}t2M(2lr+1)AakRAU%~wgR!<&N6Lm%zqyK=ybc!TBBaXis%oHf3%`z$1kIhSltOK zluPb7RVdRcsGv>!(n{LBwDeHH{eD%Z`)Z+<*HY97J5{qo06=Pez6p|B6+i?$e=$dW z=Z}{d;}E7$pg7&yi6~e@W0hb1tRnN3Hh8vnYAS-m8bhg&{foLyR@kcrKyF(U=PUxI z*cgCRoVR7epKxSE;X_%RoRNfyM$EdizE35j&ok7J_MH9~K(l*uM)8 zrD!v}$io*yhB~<+C8r@$->?$w9<>E}4q8UAoqqLzhF*HoL#bnhF~pC2=%|6_vB3tB z9(dmUC*Llg^PZ#Fxb9pfetx@i=_Cs)P94u7rN}eVejFepBocN!nCiHM05!NHS2k~l z&o`i;`lIOqSAg)_uyyw1(0;>AVokVMt_Vy;=#^%5$4{X8hd#Wgl&bxH(uoxYD<)!j zrcqf*E$r|1GxPhn-rU4rG1=W%M1hy$S}mU>PA%#9s;s=I#FW4Bu4uJbnU6(5bag{P ziHnP8?Jvur_F##XTscs56`Fj9EQegHwgY%9FLiZ4ypNZmeZL{>X8%JdYjU3iU+r6} zWU&&>3GsfGxZvvcpATr=yz*ER<7Krw;|^R{wbh}mHo0_O=5gQN-ak4w4NnZ_d=ip} zH#pS8MTa@9(Vyg@RZWZ)i5<0O2?}GC(>D;B*xYBJcl_M5+cySj#{oiYWE5L2{?wz6 zIEB*qB?Shn@_?ztoUf%AD|HPh+x zS%MOhB#Zpny8k5sidtWxV$S5pYIsO(?L``NJVwEa@}%a4YH9iwbCU(nIAcGlCBE@S z;4;ZlVS$gj{Ghzr+q-+%q5u`%m{)DyiwLGt4t_XE>{FiP&i$*h$`(3YD3ga9we0r8 z0itVOcCXirvq7fd*?g>kQRdE<6-!}pXmRmWX79_0jn^|5WOhOvjLrWUV0GfXUq-d6 zPCrJ_gi2F^saE_92CBq6)cJ6C45Niw{;V@fGzTf@qq_NlsYgN_Nr$Y~S}HbaxvZv) zF+|`nNZ?zan-h8pAoBw&@V>^eZA17<7KZk8_ijy%8^Gt0fx6t&h*6<{a7l0>GVsu` z%Mu+*?(wOGC?z-+4lsfFRW}`8%NH1E7Ijtq)eId-K!K&sjV+Q3oB3|Y#6r;P*6HW; zc_9{oy^95c>6KmHw>w8++}OlK1=Q8TA|xR2lE3kOG9$+&)X(g+;^fuzSR>zE&2xASz_b~=Mw zh=!gJF`<#nfZkHIzA_bsLiq(Fixu>51_((e-Qi(;m37Yof?;E~-Y*91N^xw(cul zQ;y#qE#egwjO}GEi}UktQ64J8*q?cDBS_5TxVgAcHJE;v*s0+7mJa=ZxZ<_h5E6QS zxkkHnQb;GkO3jc+Gu7GX&}YZ%;VO}|yCf`5ipRt$Efowi>*mNTt+hLm(Dj=7mVT~e zFSc@ykd!0ykC(WSWF|Z+X@5FSxbV^y9+^+XRNMB<*pD#jUbn3>g zU&hP^>@r;SPmXopR}RZ8TuxV<28_vG`#;Xx4W%M)vI(d75??6wON);zIt%5G-E9HYdC@RZO@b&F04-=ca8)U^&-Y|F)Ht?6$ujSyYIO7 zTJ*f5s~}I_ne^Oa=l<(TNuDVx-=I}L{E+8Ny4v~s!~}Cwp=O0t}Q@B z?6E8q+7}!sjgzPr6;<(k?*awuR>zfMU0c2nJ|U(+kBjnD|DBr>AF{ANEZJv)x@sUo zj_m7)$TeJ(V~8rzR}g<^bO4Ph$2A1cgR#j7m7&Ej@FGx&F%ZY!^T8>Ni8dOzP=jM4z982@);-snQ=svWg9m6JdP~z=G+&`BZ zEPXaavV}8BY|J9@)H-%5>-3g;;7C0UHtwuJ+e*Z;SL|3~+Yl1WCAUeKjWv$H0Laws z?PEw0_6Ou@RZa6WR-LSZ@rSgmEw6M=DU~BGhpCA$|4Goy#)hy^nzfmknU$4*&K?&%S-|I#OT|&sW#dW;^V^ z%)WXD&=9{xk2(X9)NnlV@ll9)+8N)G5!gmmLE&tyrM-1F{szNivgi0ePaVZO9i2fq z@kN6oZ`@O_kcAu=5MR`W#GwmAmF5=~u&-cJ%!+sW?qpH0Zv*v}yGb!{C+}h5VA)gU z6%-W2bsTJLY#x3Xy6V$7uWbcw1j*3$t{=@y>3UA$xa&Ueg!_Cb58aaD^dL~~yTb%v$G+(CCG_K3T z#kb&K_PepMv1a}Q4JhgA#+7(hH2d&anj5+m2nA>OGZ1yOWn} zQY0{ibNWzFZkMg16EIU0B1s~S^$+VHc{q4@`1ro*ZYZgIU)@;LXkqHn(=aaLH2i6t zrduA#MmhjR{5PUF%iY4!@ugm6GIa1T!(rm&@NlEqT!m+*0J}tJ7iVx;OZXxwdHI9!NKdAZ{J-JGOVH-aVh8(gBlBh0Jd`ZRXR?RDcv;uM za;+a5o8)fMG{`i}tKiD_m&vLhZjT;kuWMdaZu6;$IJC#O5&%Hv3$twZveMGx_ZHBh z2q15R^fX0i7>15$QWsb1?dSdDa)maafUwVfPPDkQKjqEw8UkuklnJ#%0L>H;Uk>^p zdUd9Xl8Vv_MNY1H4o;4_dG!V^?vEvu)`*?*Tb#IFN~qam_+9WoTDM;$YdJQQ{aB$9 z-Ptq4HWI#awbdhNa6aF#SDHaDA=rqn!*y6pHDfsP8yaaIL_%pP*jQpDN?ahfOnF#S zo)z0un7gXI=1*a6Zf;R!M`>$d%7#a|%>aR`8|ViGVT|s5wuwc6|6E+WOa^Iu8>X{ zr^M0Am{UVT^O!?&1~@*0?s2-SXK$o4^78$z{i zOZ)0kgr15l7m{^ozCHcz$eVd%=y0{mJ>+9|-vWaIE}?p8FnQKSUzegWV{-z~L(%&N z804QZz&SF)ew?~lfw5Pb0?LqP(8wR!3F)y=UxqGU~uPZPm9%s*|@t1els;(83U%sJ? zjUI=qYItopcs;u?4_($C`M5V$xJ;MbS7^7E*-f)A-#GkqSAcQ_?8tn{Epu8s@29$J zvd$pL(Gb2q`XZl%lINH{B9WuB<>ib}64WC)426nOfg6$2Xo4=AkDC!=MUiuWa4#e! z0EL{NiF%ufmSq4*%)dt9Pt>5{uu-1Uh1h)$oL*rpymCq44mvG1SCa3t0Z(?D=3X|5CKD*5dA_fD?y%4%g|r z8E6=z({BG*Qk=0=)3zWJy?&GV9qG?jbc+K|vUa`lJuxAVtE~@HdJ_>=okR7egfZYL zN@-RvR?!u8Xhf%ef#|%5(uJ4>^DDtu7EkT#*Ere2>qh}!;7JUc)HkK(gGyG++h-Nt6aVbWTk zYYWl;S7&-depT~Jcv;n3T+NO7g#`HXN263j!$* z9+J(0oc`082%@Ove2t!{g9?;Lw3%2NRvcJfDEobnyEAokFU$Ms(C6_$%I43mB)p6r zI*1ZcL_$KsL2k5i4JvR*Vui2ph#598%&-POj*yg;%ljisb8~Vs9hlWE*xKn5gMDFI zT3hZ<1yvDs<*6{g(Qg<*h%8OZ)`Tk0%?4OC=XMme6q&5veF4ZNmaUvW=wrrl#s!D^ zr-OWq%ST53!GQsAV1jJ%4ClNWWv^lCSaSo{-ek6}ni?wyhglTMs-Bp3o2wli!F@ko zT(dp0oQuYNR=WosJ$+f3C1n11HoT&S;A>AP0*+HYcfN4~uw_fY!D0 z_``!~UqXQv?s#w{`7(b*Z( zh_>I_mxF_Y=7YS5wDk0b1w%u_`pTe(fQ66m?xOej z-S(Wa<6N9I-r0V#tCh(^!^7iwUPE_0H&lzNw6xTHpMPU{VF4D%GX0PDp3gkG?mcOO zZI;jvRO#l|*MCMXw>Hf_aG9n9z9=q^ju}30k0jUp($g1H2T*7N7Z<%~$qjoE8M&$n z9?HWtu-9|y??d(o%) zhDJq2C2QNu48Ag+dZ~aJH2dlC1?@& z;iGSfEBWZYDCzQ(xf3f#Fwm9i9hcW|sCU?H{+x^D2&*eAY#e|21vs>|v<}J90l&_V z-5CF#b>}HeT6TjN)bjL%rO2cI-qB7;NjaLtR9W#QCKCB$k^~|EvZI`&A(2kj>%4v( zx4E5;uQplZv4B64$N2Ti3L#(U#)O&3& z4BQ|W{sm(aO$~-c-&S7JB!|F7*TWF^W9N~U{o874bKLVZKghURt$z;p!)3+?iZ~hFW+76MQM{Z*-W0aB5lZj5fG4` z*<=gbn3<7hOfz!ejm`vXn7Tzzt;KawUA<9>JUMDv4@ zNB^DT$CZxUXjSn#%oat_d>W^M3>*o+k$Qh5Mjy)}JD;p7X)LaEI zcFCZl0iy6d#!KNd#vBx9K%jpbkkjt9{#oela%4ny^4imI#nE8CbYA%F(&zO^qcclP zl<`k#Wu?&dSY4y_szs{?m2|4PP4@f8;DC=bhG@qlOW4PIwN#D%W6pctcD>l4&s6jj zVu?x#V-Kgq@TQGik(p#3Lkf@&KmasoK$i?xBu&AbEA=k|G8=RAEcn2r5{bmW%xJwl!JP_UEc0KS%iB&+`SSPyV{mFi`rhQN5cpd@S`6%|&`^uC*y)-<(pKlwG`H(C zlGC<5&MMx^J}f*YO%ds_mjlC?*Sn@pkCU1~vJdsfs!ivq9~{}x{FCMwQ1xFFl(b1)SPYZbI%G+`G^gJ2j5X)g%$XBPcB+r12OJ0q-wr2iCkCD?GlLdRr zu01a_wKHbQ3SV>u5OMwF7-Q%G?Jn5>8xNB?65{p!rjZDT#h{r!FCt+ma# z3F61!dYfT`&pVe74-c9i9GACq5->W5x_t2u!Z7-!0tT-Bq5QSyn!t zsA=fj&St-115BQ$mc_c%0Qxk-=Zqn%4-rJ46<9N{V&^Pgj!CQDY!}ya?h7Iiw(vY*Bob$J#NlndNcDI)EORi3fHZ{*FMZBpg*V&xg-YOy@ULnOR$_AJ?Qn{XJH6mN4i95YOQ~9 zQlwfn2K`-|dd9}P{dl_A5&hopA;OMMBt~2V4}l58Ca_O%+n27?>{(w5ElVwxOA4Gb zl%Rgsds0x);>@ulS$D+cMKE`KFiaMcS?#)SBN{^QeLz4}@8f=Qp1uZw(pB9mXjsJkafrNd}%7xMiCZC9qOCG^~F z<9YpF=&fe*0XB3KNw@hZoW4@Ja7M}g9h0_V+M>DRw2mWb4*>}N`NUTzgKwP zNrLqM`k!Dx3oi)+Oo7M%KetJ#C%=!&`1|uP6yVlq3lI2Gzygp)NuwL@>n=KOL1GMQ zn#Sa`Mbf-QkN~nVPS2IZJk;8<{D8hmHW1cD1BTWIV_(E0C~504k&8(19a<2Rkctn{ zUG+Pp9j!1oU#KoRoxiT-e{>9>3W(Z{VW_7p#R6@ptUlqBEWzGy=H!r~!IAc!Q8mU9$r?piVPIuw9A4BvAV`MO>lK5aVwO6K zv9>$jxm_n%HTf(i5wkh20C@r6ivbRdY?wep9(?58VR z?dQ=iPir^q*qZRqOp?lvfd5BtmGa8ik?-&JtE=WwipFc;DJ7$dKD{aS(DM>XeZ00%(geT`4={MkM5T?_ z^J8iE!*whPL|X?L8`8lowA-|E9zJ8M^SNuAklHP&QwDUO%aGbAO&dYsiX{r0sqS)h)k$*v$=Psd1mYDICkY4?U{mN$V z_gFuAe@#{8d^I;wnWm2Fnw<-4@X>V`jtPgo9JF+v2G(sYy1V_fhh066ea}fcJ9Ct$ z$FB!RtY7;lau^te-?4-o4o~c#EbBi!riVgh`}YbR(}BehJctfLrHw4p*&e7`G44M9 zOyBcFEV0q#%nLeRYrTnEP^qY`HSDw;_7C*RK#roYEK0Q$aKKg(_BIp{yk5VUK@DH% z2frSCUTv16%M=N?yO_!rjQzphy6JY#JSxb?N9p-kfAf4T4(dzcxQAMA2aRK5<>N*L z4GjpegdNLYW8?Gtih$L)L6ZF_ASXXqK!&WJgd-krrk$oHk>ozKH8Qm%*?RmMdFq>R zKZJAKSM)ntBS&*JQ&rGN=#gVvE}`K?rV6-U1a_B@_w@LEg{{t18oX6e(cx)yjdKEG zz8zw$X@9;yQm(rmAJU5khBa2J1Sfr8j^EOIa=+1Pr{^lA6hU#GLTy4D?S{rl(SuB>Oh`)~&c1Tzx| zlA`HT7L6nOZo(&8+OJ-{`ZUsb5QAyb62KzBHcZeAMYaP`&AQqg z9<9WF^byysR+1(apMlMk#a+kyS5O(Z{%dQ$qO{G1tGhH-Ee8B(H{p0tCR~Xp`S|E8 zw(;=fh;obqnDMaYm4U4-8aj_4=>&{T0NfgQi1Gb>KvhRYg-G7MK@ErQL4B>%C{4P; zn>Z4vf&b-UN5|?$r$?|tq^v(W9Kb|%IHcSZu8qgm1eCQ7xtP0m4Jh~~BB4V*{7Vu| z0WZ%_lW{SG$;|s{ENP)Ff;OWGl(vb6Si^0<>0Dm!M~DF}AUTayyIAAELKz<~BGOe; zQ?uK@TV^#bF3!#CIajRH7xnY=;~fzZQ6C7d^YD1LBD2Cfgp6ESvWc%p+6goK9kII8_(4j@pBc`izjWc0U-Ka9+U(@=wY zo}bmT(eBaq01$m~u>rl_?*&bQh9`HQ`D7Vg=SXpC&t>sMYkde01o)x$_STf7q$|y? z`>9RW)Q?-1qXm9Fs$_=>*032X-pruv`eIg=55RWiCmskuOpcA-Q#n`r@ytEW`{Eel4Icvs0NQxsiA%EdSLRnD6R1mv<3x(&pGp83=OD{1YK}%Ef zQv}xJ_Gc?VB(%J7?eshozv*gBl=ywCo!4~V3F~$M{sBN!J_Xq9j;9^HCSP)gz4Y8r z3OP9~oC1dyFr=fRGUKG;31Aw5XR4x9XUE5cU=c204zH-Jw11A$atgf`(~fgrl} z_Q-_1bM7Nf@WnRJmTztm<<7&kQEI8Hzo9>%b1nZZ>n6TtE1td8gz}UxP6W zwE`mFnJ?_&;o*KDSRM)KiTbwh);%qZ@Hw6ThtXjrV~dMR z52vMLscecCAZ#e;km5~F`en}`eS}o+{T<}=JDfNnKAxaJeOgZZJh}H_D-r}n$9s=5 zFweGV_#Qb3_(+L$n`>Em`_!v~GL{Y_=Dbkq@l+SBU1xggAi#1l%mFi-zcW%kAt^wy~JOS zj>p)5Ny#YMA5LMJAsYWMhoyVwH#Y-L@2r4N@t=!tHD#*BVE*KUVf>4IPJlOz=?s#W ztya%Vt*NO2XoETKnG1PRfnysvQzkv!Sod!O!|YYYODq9XpDVb6Xvp#EZCVvbGAOm_ zwl|R;^!4>S)6C|@Z=Y60qUW>GZY)Jx-_3JniJo-{PEwOniSpH%f2PMuLQSfA>CpV% zwzVn3ms)ltpHb8E-1Gc&b@0)KtFgDFg~$}38@qH$tUoX2->V&#F*Ssl7J6q;yv-IA zDcFK&G>(iL@nI-tFi%h@@mrRTsS7V&6sh9DhrT50x*pFb|E{Ng{@0r!C4w35H-jWc z9IL3@mV*#I%=yH7=8HYQyu7@zp=q~xNwIg}84r@&ZqHiHLgH%MD_eXl8^S;(;L0GE z=%_y(n+|C9b@mgThFggT9EdFYS3S(qJ^$nQw}enkIoAFAaTkyLPz>3A4E5y3!<}lf zIA!eK$NjHKvq-Nr`Cx>}d!E;|wp9z4;aXX zOYW2?W_^MdieeZRqjDHRq>4qfl4eK{`l{oWi802!D0-wPnT-v@s8y1@A4r7Kvcy z2tcq4m9-gou+416(I{T|gX(r0kfrb{Y%0)D(FzE$xa6pU4K%dB-bC6Q+ImQw0Jnx$ ziP$24I^K^uJqz~U9=zTEMj0ve=hKQByro6!8ki&6T7~_k7`_~=`=0&%n~`T%Wp8Kg z@Zr_*N>i(CS-1UW`@RtX>;s1Ly2&?o=L)=qiJtPBDr^r>>;ZX5P>c?C*_IiCWE?AY z7^-ZOmhbg(O|_x#W;?M1tVJYm1|ZUEYicUYMi}$FMtqo0$gofe)d7w2%KfT!Bfyt| z7iXIX3qJ~su-;)mior9jb)o=XLv(x%q(ey`b;hBEgWrCpQ$FE1OSHZFkK1&Vl& z&{$o9G-feCvZx0QlWu;(LsCn5I1AhY6!XDgBs9^P-XlRz|G$pn^1Hb(*|Q`7kcf&4 za(AhCKfoK7S|R_d^xMeDyCwG{8{5kHSc2%{MX4bpRgtfCsexDpaT?(IH9f2_|W_1Pf zo!BUk%V@@Lc(KEHSYc&p_~7a$_!O{#3W^I@#t9`fTAru@M703eXPljhRM@W6OKv4g zNL=MA%O$xmoRU)hkGBzo>g?b^7jTQj^EjhsjiP7fm>T!)BW15wY3#Xv494Du%n~n8Jo?h={7gAvuSavx_QYs za7VlM;X~A0uDT=rmm9^vi&|}o%dOB@ZT88;gy+2)G-7rG!dk=G`PIWe7rFb4mFB=j zyixRYu|MN!z-71RIeFtZ(_G}gx~s3K&1^W%!dYTqQyp3{Eud_OI6;n>n1?JPz)<$} zr~@9$(SZjFczN)pbxKpQaAuV~TCC=synzJ<{=G7zK*kJO9wUhze!j1LAp0v5<4u7Q5owd3e+}}^kMY0_&6r-P9!$gQ#a|FXM#)g$pt8dQ2(JzD4Pi2)yTdp%=fyY_=tXfseB7YqNJT9_+jaKW_OMg?S-6~-{ z62B|}q$55YY@9zM^k1jyxxb_ne$)^yxa|DfA(*c7d~79Q+~xIqJdL#$P>A60`j!>} z%l4C&H6LGJu(>?CiQSzCRP>s2jkt{qoJ5#=);0NT4b^J-K>mEf!p_jo-rpeohpAq#e3)}}Bbsll?9^adUgoJR&$PKBQ z^(YYnn0gN15|wr^znO*l^h>E3jg~{j<-=A6YOu^u)+=A>2Nm3juon5 zEl}OZpTjo|Zh*#Cv8;s6v41(VVv+>^>z6@1VKw(dQ&!rksW~N}_)2hKYK(((1=xK2 zL#!0xa_lxMUEUY{!9$Nl3D4Ivfj)rX#^yxu)yOM3d#dM5*>R=L@oaA@Tf+bJNWI(w z$8V$RCaBlZ4OZhHeRzK#&RUT=@9h-vgl$f-%C4w!C|$BG*IjW6?D!L&?6HhXkGB#%cYvJwYE_S; z>$VyxeEsNU52+i?L;U*IT)S%@AaiTn_(_ncD21K2R;X+~f3`7h8X-YKG@>%pwl#D! zL;YpLCz&+DvPHDpMj8|ijZ=1?H37OdfksNM*SsB>uL?=7%l|ghsYi!B1U}EaSOWw> zt0$~B(4P^6+&mP_uK8|gK}EzL$R6b6 zZk9s)A^Q$o{H!;3ZiW~!WkL*!8t!oDx!Yq2%-+BuNWPCD1g$@W;*!GtFynwi11@4JxBa5AM;RMeDJ zR!T`V|A;v07+_-- zCnO|@nR}hpwt35DE+QI;5Qr`n_yT7E&G`@sR4fYm$Pg`i`Y;EpM|Z^r;Yc2J!Y-(` z=xOv-noX&b#^z9wKNp&LABayjXpC(qwzRNPw6$f)JUu?PkQur0pI%&CBonAP!k_#5x2%XCpL9q6iw5hbxK#BO zyAnC`IPQ1SE?IA+lJi$J<}Puqd~K@Zxf6DD3>Pn^MQV9A$_QzJu%JSLI%agUda$6< z3cVm1CFMrFxg5vW`1U%RUln~l^dF_8mgiSfK4{XJxoQxks-Fp^!W9Xwm4()v6jlrB zOy(FVTvkXknAiv@-bD?{3<91EBxPdP$H!+Ie(S{mupD~&`k<{%x!jo19Y%rD7RR;c zM%c^snZ#o%)Yr>6(cQ#rllq@-_mQ#DjX4~7(t0>{1p)4^lHMoIG96{;x# zKGh9FgZg%AeHVp)E}3AI?)-u> ztm9kqCbYYkP#hkjl|B#e4u{ zLih7AM#hwAIV$hsp-jb+B{nfs8ui-*MNY#83+w&Ojl8F0s|#;fM+64^&li=~zm3HMeqcfrxlh-XR0GMc~f7<)hvc?f$f21bI9yp<& z;QKEaO`Ai{?cY}aRJP}TJP5!+%M1=CO2EU8It>1yMn+tpX%icH{q_o|D=lUCI)xCl zQN%at;fg4$FyU9PlNLon-;^x^J)BpBscGv!O!ATkTpbw$$zMQB>A7Ne^q$b)Y_MIb z$q~6;9XvkM`0(~kZWJKM_~RLCSeUiwbM$V)C6x%`$BP(Y?knspk;BP1t6J^L#^&FC-v^9=acT4|qE*nR>LFh$bvZJcEi zQ#@qYO;sZ?!+!Tyqi;Vk8uyz1f53B)i;k8DDW9f*C2fixOhQUpSyMBtT0p!V?KhKh zoove6U4|P54F#or8VwI|?1so9#nP1B_W@J{uzVbx`keyt7jwDbpBASM8(J&#S{G}sR$No#e0zP75 z5KxNQo6*nu@N3_-dqf+`$HTMjeFs>+loQxEIByg5b#=#%aT607g5i@H>LEWsX8r>S z3D(6#6X~P)DM}-XCi_lwo7O4-ELp%q{Hu* zo)vbhz3=xs7REd#)&GZV;7tLi;)q`_s4)!ZgYU+58s}Z|I^Gb$4%<$t$xvLPw5Dc* zBzdrj*Gp(Dv4H=Rg#K5y@+eI|)vf`wL?fhx*mgv`V2AeKtj6L8w*+XBsCmwb0Q;k9 z+*MszFc3?5zMW6%a?BKVTs9LFl2zZw79mF8P*vP!jxyW<0~LZP8UiFPrI_)vWe?Cl zLyec)94LY^beZkZ>L9|vpFA!6z`t^Qd$nXNC@f%i(`#qJ6N}r2xS45{!_C8UzMjqw zB|~oVzzj!Jr`eyd!~4x&>pcZ*#5ttYy{GqQ@t=4Q6FewiYiMdVdz>7?kAJw%NJK`h zqR?v?6lKVsqtFu(OBB85y+cHoUX4bmi(-y}RRrB&hP)ENnApaT0pm*sDHXse&z>c6 z;Rv955Xf`$QcB&e|DlH!!bAp=N6$y;3rlN~2N$Z3U+IF9Ob3nvgp%N6ks<%-UKje8lNm?$K?_s|pnP@k(U*+~wO9GZ+FBng$r z=0?z&-E48#fKP@W)jT)^!ZOg$R_j{}dUn@cXL>H@6(wA+nxP6vq^2~Y59_Xx@80EZ zG_2J8Bby^(K!hIZ%yzi!x0$Hy^bf+pn=+TANn*bdh5f zzD%=-h9W}8oi4IDA4uLKf}ruNC8uq>X9!yZ6VFH>Nl_5j7DN+)E1kzPiSacuZRNdA z*2Y59-oE^M;}M&_PoC;tSvDgjUybhnGpKWoy+%bia-vsI)n>nV)OdG91n5k2{cpnq zDTGZaM2d{wA355C7{Aa)JYsuRaX~BLg=fWs0m~>MlEyG{S~U z>VbB)wy`rSKug8TRu5cBKtn_0TOg|yU`m#zWC&vmh$yEI_9%lud)ehUG1lQ@ekt4T&t9$O>^Cv~orF~ND zW_`yO8x%if6&|(K9FYy??tf||t=0=CsWjVqxC`pa!uyZUtGkR!(rj^XJ6FytOrqF(G(ta*a3{Lm4JdR z)S%nvib&gF`uJsksi(#J!m`BepcIW2Wa{hd>*_l3{PfU?ONrTntt4a_j9_xI%CBwY z{R!ZE17FTw?18x2Z3kk|QunEQy-w8@(I$|l1O=(9>Z)0vJR859=Q8H{&0mPZZt2Zz z=@5d{EeIg*-n|vw&_OLL&NfW{wtPbMFcTcy&qbYkB##F?(aNjJ z<3@Kp28ZUzKxE|PoSnyp7sNkfeoUYI=jw-`0LX%F>*MX!5p@r6^>YC5#G0cQ0HAWX zX&!F%hh__ix%&_J4^>qM_^a6Ay z?#Y3OKHjQ++Km|CLICmKfvu+~ zAu%Nch1_5J-85w?(&cb)05$vi@j6tx{bL$k710}>@adWwj>Ja(=IXRG02SIJ@|zho z6zRlu!x0eR2Ok`+-X2&{z?OKgA1_3Fd>_o~GcrgXYA{%w@S@)FAm$bpo6>DDzX2T! zRhUc30rd1hI2O>R*4)hqY< z49G{&RtE?A)g?v8Lk*0Fms}ajnCmn-Uors|mF&%+B^{#H`?aF}xJRg|4z4$w_yi3H zgXj2TGL^RsE#R1pli4@G1ao=3xd_bvQjO-Y&Fb$QB8%>KmlJ^bA6_@slDsU%iBeYWdHmLx8DJo2Z{HU z;rhy5{zyWof?T4bkV;9?M%RJkL5NDo3(Wr}%!0?TEszwUC_+qppDvcwpa27dAa4y& zN5XDSL77Ct03?be{BZ3V`geOj7R5Yth6OD3F^VwuP27x(Oc8W?{Y{^ptnSxuk6Svw zwp;8)IaCq*bkg6eWiZ}*Y_~`kfwfd;8r^H; zdsf!!#OBqt*TCJF%JW0?C^gy~2wG+j35f!IrZ>h-eP}$_s`_ra`Y&R zzCN*sC$%KKsZN7eI~UdADLaRAPc;xQ71*7B9ldP#Xu<#ik!XTIJl3Fp@vM+{bRecL zs353*t$sa5As0TpEeabKcc$)Hsfv~YvdQBeIZ>FrG(VhNp z->H}EU5Brf0XhXbjEMUtjS+A?yvPk@Oqi6y5taPy{3!+R|dk%|bC z)iRBW#>2?Y&d!`F0$|gWH;MpH*d<-i8#r_`^`0^B_;a__es0z(8SLib&aXhVthQFp z31CV`;=-kWZ}k@#aI{*C;n!}tdw8@oH@`6h79~e&a!Tdz3uw4h6eJ{d3QGc$LUyw{ zpXKu07j*&h<>?72+M){3On{#RohKqv&>zMB_46m2ZbNZRPryRsjOFM#$i(l9(wn7f zeQmYm^T)1c0UI0JrX3yL`ho(fN_t*x?WM2{Ro)V%$Qa%WwzG&%vblFDXlsun86^|x z&)dYk%N_P>0N^+U0U{WH0}m9hr4cpP95I#1ww0Fd4F9d;?c=lPQ4tAzwi95h-d+V{5cQ8?raf81%E_{ zaXOV`_-o2YG`Ku3&UP<9>PYB#-V{)Zc(Ccsdkqt5KVJ4a%V%gY(>`F1bv z;L=X>iGF|RCR7XrL{q(Y$YJO>et%f=9s^%4SKjPXc6-6MHB`h-7$xrDI__7%FZ-f2 zP?UJ~*WU&ml-~B=kpgZ*m)|oNYtTkMq~VxJhX60n`~IMDTKMR{9*fvN=bPo9;xzp9BA+DLb2PJMj;~xa-#!c@np?h7l{A`LDunmlB_CS%`YCB3qx~ ziR8yA&DINz)fdy2*$e+A_xH&=LhjAYz!P7g{0w&aSX4TL|s{n8q*?y74B`G5V21e~ckc-XZl^|11Hb+{KIhJIEyb>J~Kl!A(k1K&`( zlacU{fF%Y!M6z7c$I5E|+J23g+?~d&xuh$$|1sS}@ z^|ZS_eG2il(j)qA0^c6intUl)5y%~9F@CKiAq!BQBAf68+uCkaaL+}KWAEwqQW^_Y zy}a_LUrW8uS46C@1L3iG8VWGKi>XXFTw-^g?0>)@38cv&^r#RTrMNh#d<oFhe;E@WZ|S=E7A z0EKhOz0T3e2}pjcR94%QkW(8qdKkKE`oMa`W*pc2Mh>jF{#=Bso$xU%bll9&Zu*Pp z>+gNhDtFtyTrhTA76kxo^4v|IJzf5bRkFnzLsm%7*}kj#4;g<$q-0c+9bd@1A(GIr ztg@|a1AF^7pv#+^)8+arAZV+e<#Bd6&yo|T4IYx6o#O`6|7<_L?SFchAJZe!)?>uF z8_-Y@KX~ZzSiX5u@_6jJn4a3l$`)|=@V#Pf?R83$X-!p?o1q}nQW%Mch`e)lUWlq& zkeQY}-Zu`Zc}@%vQe$0R6vj8@kT9lgFo~HI^qoddg4lDXvH!n$!IFlH?d_X8_2gW^ zbg1Rd@Y_tK1P6bI-vcN!!x7ixn_`28GJVYXpRO+QasnUORm6Bxyam!~bV)sl`4}Yp zcBp|$fD*ETii*Qp!_^)udCwC&{)l``P-RTL2iHVmT9?0atk_o_``5;42t^0hjYFJX70COm!y*|Idd9sB^1Ku^XA#zkuKmQPSK7{09C`;pbZdVs_nYLFz|+lrl=I z&-AVr)e-`zcK%CQ9m2*!d6bS0_C#R3lGJli0>vS_W+!^-eEy?^4NsGo>5ZHq9GZK! zD3Z^-bcm9|X)Tj2MdraJSqip0G985>D-u5!e!2gMPy)v2xOj3#oX#7HA93+WjV6!8 zp6ku0x4#s>a@+#x(ZG@0dL6bel+VvoFoGX+Bc=@uv&B>5G(q_kADzB)4H2ND^zpI> znfQTb1$t?|B;`5U|fV zB<(gI6VRxA(7~OZxGl}pwfM+2#w2mLxaTss>sTO}r_BGZ%q#v^cXkC3HGbiBiKb5Y z(2kMFA1Zl)ApA^3l8KbVYtAwPm~zN8+0L4Koz{HL8=KS8)+#kuO2 zni2zHeiHc`CzQG{SB*gx2f8iq&0H~GytxiP=Xqisenq2zpDv)y4)?Xc%b)G-r%pFI zJt9cnCp1ND*;&$m0= zt^WadnUk}HvawpVM&0gfTH#|I9m19$7``Oz+>W%aBrYxy#|~4Bj_qH}06&zMJXg2V z(q7r#US+0WqtjDRP!I{k%ZMNSQ8-7QK2?2yhfgT=!y=+2K)L;2CfgTEGL|@OX4Q4* zCMQBJU^l*hVSn+uc)^+w|F@g)uD21hRofqHT!X)|r1;qe!W*CT7WuIEsn$g8v%ywF z#?3yzo^dRf-?pS|OYU(Nn9r$1c!bMO^z zVy)5Zm#4EEYGF5~>6b1GS&Y;7I(BIC+K2|2lpWSlP@J^MgNkes2tX2@n~`^afbU4FDbA@HA##$jGD| zWlnfaJH#2d%PP>hyhpTVPB?shy1{GxiuruL_IY1BjR!DCwXBwJOM81?fRFs2aAG41 z*+w)pv{Qf!0Kj0Cf*vk32~!LOYc4hjP|Nief;gFX@I$jwo7T+JvsHckb$&y(t{kC; zFb~f>&=Onbpv>{LQvN$Gg(w%GzYEt8#GWkI7d14@&*^36?v+}q`@_8+fi$V*pzqD; z`;vv&ea>D$G1+{`oyhgSUh#8?BV^ZWE34_*yy+TA7!jdrXU~)uuYa(H-H--LW1Xdb zDz1vT0!DK2yK z2DDzm5Il~T;hZn$b4x}}{e{D^X@$?v1(8d&fxuj2;(&9fZYi&8;IZ;441HGgi9LI- z%Wv4lbOo63gR;=k`pS2HtE5975PxuiyI+u~ZvnoD-<;17Mc!vxk;rF~Vm0 z+TLd$$oAf92)FDf|Cbem`=Cpoic!BB;mMixczSMxjRQ znDu;bwOav#Ts-*iBoRWRkeMJrr%e`6%jN_$&?OX!&A^&{mr#g-#n1Y?@l|H!i3T~% zaxI!5N6S?saKm_zjL>J{yp!7uT`y=_Tf7~ zj^_E;n6qeVrqxuJS2)^K$sx~+ii+C#$rLN#LrWUoY4wzp^@}CL$v=L`UE$g3i%(j%qk=m_^8cdzF^H(!+|*L@= zS~n>LiXbTy6O+Gkt&i&?p;1vJ49?gj%B!~xRx>>*(ne!(Eh1;P+lW67$iWQyk;Mla07M6 zhw)wqxxI%w_`DPqW#FMBIZJ>D2(eobm&~wPkr95p$3p!u%0r~fT1mbWeJJ*D&5MV~ z?WBgEfcI7aMU(mStXk1vdM=ncJWDbm?&t#Eq&GcNPjL|M%ii z`LsgIzkH|o^BT`FAt8k^SR}7EjwdGp6#M0Bhq_YId1~=};n?^LUwkK|@b&LP21F#} zlBV}~pbR_^k1Cq1u4AQ<17Q>w23|SPviOnb*RKr}>EIwO`1Mqu*LUw|8Jih{xCQUK zn`6Xrg{W2Mny&M475{S$kHvsfAZG^zWTc< z`nGcOcG>z#gRSp>YSU|-5GNrPl?Yg&X`!#v`+7hodz2zAOFtLc>?+?uZQriNKYh>j zvpH(97w4t5sRo$<&`dPcWtG2KptgUNmZH;vj`11DW!j~yatj*<9!%iTAiB4QufJ%ud`!WJm13HKeHJBJyTyGN0Ps;ksaDebkP6V@~@SAiPNxyuO`P!RGjB03TQH8CSW11^wVxw!PKkT3<920OJx*4M5*g*0 z2_?P9VywFS(Cz$-Aqbd$1J{Bm__~r|*Yd&VAGJghj@nqY*lt97YkOa0o6tz*p};x~ zoYMcg6*8-94^B_TcT;!LIl}Wqm%T5!PyP-OM7InqP64rA{(6BDH;qq#x+LCdbMOe| zaUOfa*woxF4|or~wsuW6fU1~j^JRhvc*+L@T_NiQlotRQsQ3-JR9=$EwsjT3JcD+K z2%H>*7anBy8FfAkv85D)c@=}hkc~k!TrH~ZEIZ|#x9?~AWDlP*i&*&Q3^37}A874^ ztQjvaO$Ni8;XS96msH+Wg*vU!{7HRP2(ahlPPFLSGNvii7_{>MH8HrjU!QW@aZuIu zI&sCCo{Oj-0oi7Cu3+x4qJn?4YNg(Mv~9m-+IDKUVIW1GK4lCFDVHtYS5<*z%716Y z3?Jy}_B|nU-|7pV7Lx(axrb=(>?&=ca<+ixkj9O;pQCu5Cxsj``g@(Eq|%Z)9R@Zt zS5}7kPwcN6H9b~tlJSE5c4Cq5QF^#BKdqX}%9p2PP&Z1MfiT~N=+v{42Z)ycye51< z%v=uPO-wI;yBSq1&$tc$G?A_gBk!d^~2dj}_h;fj%!WgSp9DpZ-)0rld}kIE?Eu5wF+Zh__hy)`KX z4p(^&lV?UzU{)`SlGk16FWtpYo@dz?nm#fLbOGvUm?fb{)L3>@S$YOTr^&1g0wZYr z!oono%vy#l%?GGJw&E8WNCS|Qp_QiR1tzlg&hJ1;Vo5U?tc#huZ@+%4#FGiY;sD^? z;&I*M-^sgD71fpy`I^Le#-H39sWy z!>}_&IycnL+6ZX8C{JS@=-~tkR0J{1Mu(eoKC=9^Gl59 zcKCL5bVzrC~Y3RSx)gln@ z45BdwbKALo){K@9f-52mp*xtj)YhTvz~8_#b+O4|f`veRja^3k*H)!I!BWqyEudoI z{`%!MuwKV*a~@^1+VH&c)e&GyvgniV;N8$}O7KL93JVBp1!F+;)ObaOxH58Y4*Qd7 zDOJP(1~S^h9tf9DUv|{^2CQ|tiC&fRa<1GzE|Ps;sYCb~@#?k@LbaNu7XWi*-e>yooB^0FtTW z$~R9{Zm!(_VbkVEte6NaKE(egLf z!GRcxBMt^xEkuRjcTKQCTJl^!xMh8N_5R{LZES@XLDNDVE&Ub=K2iAm#p2ttC}@)G zM`k^<7(0Ar{LIF6+!(Uqg@QO#P(j^|ippCmFy-ibhA+SYkMBFJE!som34zyqWDtvn zAe%_Lr2>WG7t=R@!A4Gf(Wrjf`b!PCtCGITnrIhR8)x=de-M8jN zpw^(X=RD1JMY8`w;_0B$q3zix`~GPF{ofDyn|1wK$p79DoL8*_!^4I{D5Ryt!FXUj zP9kvO=%k2;0}wNc>r4Pj>2;Pz$at0`4~yqBK_;3xov^j>CLWra^ zxr)|$9r2R$(NR{)7(KJCN&UP+n27KmBSA|W3QP6jp$$-co0XM)cz8s1l-;yL6GHA< zY0CoCHc{k+xq!`xgD2XKS-vAfXf8PsSReE|9IZbb(bdZsowZ<&g-3{@a4LpG= z8#h^$pm_z_22%}9!@1S@)%Bn2>+|#L2FAL&??2n(s1Wk;7^oH-ELB%lR+g8efRI1+ zwwIIuZ;L4}DS4BrU|p?7NX|R;Ri6(O&)gnZZ;`a(DXS_8Vl%AoMMks)3dVUR$l5+A zX=-c3E<0hlP6HTkCGw`6N9V9cfWXE%sSC4IxdodVr3(K?{-%$MTACkksFy!43u$6C zX?5P5F6br409)`sczigT1|aN`KL zYj}pu>0HlAP5#Ow$!%NFd~7jsw?>9QqL}cZ^e)gL1}8+HmN>WieuAqSVh)2QuQ?v@ zX5DXHTZ;%iek9`2%#_pAsG(FO&|ku+pAmA@fe&jiqjL4NR<~c@xH!Lr_rN)plr>A- zSu(52qxl6GvdF(oO{LxCr~t3qFtrL^>^PcZV;*R;$^Ob@VmD?+>AA~ld^gS+aHY89 zoIwPEd@iIZL<-ISWM(-e`T9Ln#}By)2~QGFQK{i?stlfGr~2(kWd0A*)Q&PCEpXo^ zEJcO{FFLevT&GYN3Kfd3U3F-B(`ldO%(X5B$UQNcD49`7I^g$x+p4T3X}<(V>XaSD zx=pXi|50VmeJ8nJVAUrJ92br&CfOg1qK#in{fgmUql zHD*?z1^HS;rqMVglZ2yomrcY**VeYO&TggQZPRLMvI8;*IWvu5JXI|iuS}p1d^$Kq z8k{wlrfqar!s$O9Z)&;z-`XDlq#gMq7^6GFS@j~9JEQDYo636w|M6SprYX(qTIGrf z@m*eOsC>1_pawsn1o;K9{V)22{5|)12_3x*FE##sQA$4|=r3J84MvJ%3K~uV*_h_X zB@7#y$mmxPJd8rQ8mV0*pP*cXJm>X`|4VO*XIv15pnjAL!nE7VK^!PVPkoZoM@S(_ z10m+qFiTccRWZ0!krGj0qRZn^(927;6{&ONzc#7+UGiB2;SHBucoHExElXHil#n6VhqoP}M`v(@sSyp2OpxpV%ap}(?rY5MCQYM3a z(m|`E_lFT)0uK-RfnERNcH|<^9wOhZk*zIDU3+(_I++Qhk_F?%p&2Fazaq)0syL<+ zN`+)e)aqi=Z6)S>`>d4cE9if;cjk9;KXU1Z@_tHQQi`i{2#-HRu~3!*nfSyK6YsU= z2-vQtgf4_06N+Gi9KRj%IV74IFTAksQVx!m6o!DJhBqtg1WF4E(G4U?%a?u!CNv2y ztZLcNHDNEzKtV{Ghbr`e=MXu{GYT}U5!-Jymn5+2lF?6};mC+n6rjH8{G zXtnbPka)4f;Z%9}iV?4Ob8iSO67|%11r{gn1_r_%lobr0Rx1Bf0^|8^d$6`4L&+4N zH$gOEO6aTC2#5%HDTp+P#IkgFF%V}A3PO4(bPDOnAoL~(u`C8w0e*vP60+(s09+5} z+wEG^yC@dN_;`oqA3Gw4OVa2RrvbZbhGJNm+6R~#`OlcF*IfuhDDrwr7I8#LR6Y`A<_Z?6qQayx(HDaf}uoOr~y47 zpp*zm4Mk}ILI^#OknqlV*Lt2m;rVp(Dc@$+UiZvB_ukj_yW%LAE@#mg4TG4(K|*43 zQ8+seck(iIbZC{1Yg(da^D4zK&?*9y>HXSL`OU>oWe_{U}eAMm^mQ~{(lN1T$MME3@fZU z56-UwpEf}36}}__&X=N}XzlGL=N&vAqu=&o6JWZ(t~CF&*jRr<43v@ZWvlgBz!J5} z<7x$8(@EhgZdvgABYrj!=f1yd_P*Kl=IpsjXSMSTmU;5GX^Wlvg<#>-_o55tsoobXF7?lg)t7?6>U$EJAg#8=((`V(SpS4iVyj6HDl0f5J z1Co~95g12#l^o!#_pfNn*i-9YWDsv@KR}hIW=bQ6PVH@f{YtvoFrsEIZu1OW z9_KNXqV&sE^73Jel;r29Lu%to{kIHqr0U!H&|$4IMj%kvx57V{@>B87HxKw0&qYUn zxhD~}m%A6p&8U8a`+h#N*GxG2*xn4(<+JAgp|)+bpZiOY?B4WIK8ENKPC6iid?ta( z_iuuOA|&!br&ELLh(scZbyVMJ6ZlB_yr)<6SC(`GfU5{!?Xc6M)&3ztw zp_LSk{l3Y+7kpUc{-?9sdeJwo`&|5*WdVx#VZwkqT@1D`4s=`Xl&1gKl<@-uBrVaP*Z^x=wpPzVf$$F59pmI7@Q zn`+9+EKNpFjj!JK2KMo(Nc32pm5=i#t$J)=aLoMEQX|~~RCo)nP}0#YESw{gCN=FB zshgl+29Z{`Ey(#f-ZmMGPn8A}7Z>&9sol3xvRV&PsAxj)Psk~0%HlXV>#WtqAjI37 z%QnlOGRTwcb)mV3`!iPA#;@*o2D9qNH)e=l#$ zq*PllWrn%Ecm8+c;2VP85sqd{2-+3*aV_7XzXSbYg|NbdIiSV}j)bh3S z>xt*TNUJ`l&6@x5)Q^935~;uMsAO~J>&%2h<~zpmkJg7zg*TUa0gZIo!G@`~$!0n# z{-ZtoVkE)Y*U>^RQ*09X^c9^r6~o2dF;jDC1qO)bG$UF1f_4zc8VRUq@!6qi;B$?S zT~0n~o~GZmz94rN4C4qnW#0K37I$~h;P%i5qKVLwsp_knBF8jy6!GeiV91AW&)LFh z7vKi3@%ZEg+lTuMT3EqBK{ZWHvgc_dsd$x{#@fYGCzIw6T>W_Slj0(gP|99y!T_d$ zHi69-J|@sXiHVlJVE{iTY2;Y*3-@ED9G3Wf>M+Jr4K!`U4~T_jw>jb3L0>#(az(*! z@iivU{pRjIw=rVkpqJJvfq{1p6fhpCCFCx5)G3{D|FTk{?|j}Vb1Ie0uO4L}Cz5h4 zUG%k34`l_Au>M;9vyYo~!?5Por~adkegzua$3@chROJBLJ{8H)1;FY8P6PE+n|{KWyI)-U`Szhr27Q-8#Ncc5ojpeZ*J`+}-Pk_R zoqErjj2TIA?3t0)znqRU5cN#$V|a70)+qXF)l~@nENbhDu8E=>`Z-j->eplSZ=`XG`6j)1a+6Bi)rq*_{u!Y+W<> z)w+a%v!-@-80XqJFJIY#A5>cmbkv%dgH4TVw{Tznrw1FZwbd5R6BfSoO8=AkCGZRg z?Ect}_#(xx(h!`rqJKolQX#K!PW(JcMlj3uNo{G>KG9417xX_~$f-HItXhuDSm4X~ zrYKM!d`VwmYuPL4#=fEBF<)7ds!DM&4H_QZhwQAq`83X<4|hIz28vSwKfWpRP=yZ& zhq(`41V9P~AM_*C?f`Npz(6l@yfk#m;9o4A-N;=#JGiaw%##ZTrneg-ZS$XXMgmr= zZZa1@pUtJU4KRbk=qqJFR|kDACKSfB$kiwI^eNtGE)E=wcm%W!^h9&?&n`dn{jB;V zM#f@3^^zeft~2&TcussBO)C)L;^51_DAdr_>J+`6!~DPUk)SR-91t)VCDWa z)Uz{+cOp@j$J||d=QyZjp3ppZDoE!dI5q6SC20i<@JIhW@sw+Cn*kTu&No)r@-IC> zXEhmc-C}e!{`h5U3HZ$weyMV1@Z(5OX7G#47D*s;)pdN*^YpzULhX;Y){C=!toQ5d zKT%q&{scMtGK$rA+)ZD7|F1jSt^9ierW@W8xf7%8!63iMg-ysF31BSHt|2Krtm*2coF~t`J_Mx z>_25u1G+gT=P_8Jq+`*CF1@?C=`;d8c9ComGn8zS{kre)@}gW*{Op%8URDz5o~<^* ztTO(gU(2y6{d=jsohDz;zmYwddwmsC_qE^3+$Ym`>)we!uV2^sVAircu=Z;}7!of^ zcju8(I=|p%`JU$$LJvVtrD$B)pxuAl3`VlSi~s%y3<3`x6aR;X%TrxR3U5e_PU*cP zEc~QI+WFj*eZr}Gz%!aJo$ig?*>m%gh-q}h2h(i+&<2C4w<$K!x&E2C5l5aD;F-qv zQ~6vSoB9|fa;LxUo6-B=TD{*g=%05-70yP&?<`dbJmj3@6g>I3e+g;qpHvc1NqHUl z(9Kvc;h36BbL*C&etX0Wp>@lt*=4bWJwu6sj;xm7~te+>S1#>`F8XS=0MziNll1oiS zGUY@#DrPv=^xVr!4S@whb8pq|-+Z2Kpcks4rY?0{TqCdJ)aY@-W9jo>=O}j~XrH)} z=l_Bq=Q%UJ%eRApEY2jRzjW1NA)LEm0C?%#d`e8tzE!C&(R29_{=wtPGeAqh;{Dxq zWqOA}I!YrWh*cDfwLOU%AQE}Y3H&X>GB;kWRc%xNNNnBz!_D8;~rdE(^i~r_+X>7Fs^eV zA-cKwjM~)l@XVFq0Ba_3sO;#YlqRZkXIh?bO>k)A!qMebZxn$b`~oJP=hA9#-Os;g zq--Gs697duj+7Q~gLKOv1tkH5RLsT}VRJB;4zT98_3;y-CZEFG!Pfc2@GG)ljXMU zt|I}>0n)@bJ#%g4i|J*E=v(3iSa;-C?tz4?kIX5-IvxSEwQ|o^jM6{jUl69zw%i_P zGx6@B*P0d$r_Sj*La9!3-^CpG3ZVx!vBuxOhrNYsUPI_gh zkh)Zj45I^5`DESgBOyh87)xL|qI)-5^R@g3U_wodWJ&*U9 zx=i7khI5{VhcA}EaWoB@!;}Y}u!*tZFc9CjJM)xvFtRUmqg-FmM``F5W2M*Eo4}`FNU9 zhz7`eDn`VIfUasbIQ?w9tFKbYo>$KI6y`8bGA+sJKp>&A2qFS!+2-IM%^4^N+QI=t zy+DAGfDdQmcegmZ%S%h8Mj@<(Kmhh+&ZA(%NAtn~%PG5+8ou28FHVSy-NgX6N0%g1 z`kvUTPcZiW>C?g}E!!=0Hi6mPcYFTKyvdnJb#!BW$4Zvucpvx*XD*Z#2R#5*@3Dxs zkSt2QHTg2AJFP>JsswTa`>Zx4XU}PG5;2@AtjnDiCAE}A2oC)rwxvLNgS zfucQAup(7h=GxGjY!|M3B>?~vG+J6WZPf!-wVkyoT2o@Q@>2N5>{3^K;KXMKlzzv_ z9$n641qWu7<(D{M_gjSkXj;ZYOpI^;)p_+Af=YBRDIptDFJ9H&1S@^>oE5S3s81QK zyUnWjJC^1oNvutnHazpbhvXbTH}L%pBZiM1I%Q7nCr&7Lh8Ro?B34Vp_7BZQ7Y4ya zp#{;JGP@s~d1m45jvnNHA9ZhbE`__qU|JK+*Sc1M76qB;1o|077P?<&%%~+Lkm_6~ z(|a%OotJwdD|Xb!sjF|)(q1;1#LJI`yS$M{hBU<|8hbHpQ_LIJGmM^)6Q>Hoiv4W* zcUIfXs8M$HqkgS-CA_8&R5(v$bJHA;t%u#6?HR5t>(o?3H^dMMb26<<45aAE8IIaJ zHz?aQ+ys{%&ViG|wiAG9GG}6!_j`nh#Zk!No4YX1FePlDDM(XFzz4RyscQ5ai`lmz znyDpV-eR9~Fi0-QgEqKb$DcRxo*V3*)ZrNTbA$KSa-TwCwccFC;q(CX%uhSz0C|Nk zJT&7X@gs%5k(zDp-MC|0Dw8=u`w2!Gu;MaG%>vs@S>Uux*;735T@M{c}_`QZnRP3u1G@>+?deFn8(QiOtvm zEndjuQ|}micle=?CKh>_Jc7oid}a)>HwYCDcN|soHrivg@~V3ZNV6xc zh5MOH1sc^;&AydUWM&D4JSmh%bp4*ytWIegx3lU-Ih&>SpmOZ86x?HLXVXx`pZS5m zRP3BPGf`bp(Ph)+kADbbk^1Wrbl-G2Ta^UwH2hO2_%Te^#f$8~ev;A9VM4l4w2vuv z!4-zw=K8e4@CQ{grj=S(||Z&I(n-xEV`B; zKtF1en1VEj&n~5&fkD^_T(Z_bm4$O;1WA&=!2=HVZfMRaasI8KHv&J}6cX=lAsW>@ zHjmfc9J9VhDhmsB>loQI#g>LYrM_sU|ES4PL2I`SxO=1@CZ>t@Y;r_~m)~3EsvajYlAQeB=1D@qd{WGFXkBP3-U6pFoW*c{HHU!5s1mrr|pYaQjA<7Mr zUPm)kvTVtl7s@fFJ-+o( zL&<`0-=RWz)Dn3XX6hB^R$a_geegutYdHj^zV^ILI9Ow;*6dh`W4)`YM!htei7BMW zcPYO5uwXSFBwO!Icl4<|R4T!ZsP2OkAG{q2G3eJ(=5)-$m_`X0Q%%>7#mr1me7twZ zViI*bJH5QSp4@1j{_&><7Lr2cC%vZ;m1q1$q*<1TB6Z@q&jb9LQ;V+=-t|xFjRPUD z>eq7Ag_Rj>_sP)NB@rjj&|b+DQfNR?*)bL2j@Yl${TUC;5ER6Oi2%=Io?d1us> ze_=T~B;Am7h0=C1wMwMvr-Qf(+_19Pf$VA(w*Xzxtd6f8+^Y4`AFBsxDXjiZEVMS5 zRv{F$YY`TNEQMJR)KXO8lYTi$Bz^&c#!6)S%@Wp}DbQTQx@zm+Z*khMvvRE3pz-vMDBX0>p5_0NbsE5!2>Vvy(gYN zboC(MFd0$)hSCX4rI z%_Cf}e$l%r+9W_BEq&m6ZB?heJl5Lt@c5PII(r5i#HZuW^+T%v`DnLUgJWsdLPv1| zWEoY}Zj@1`xOGVt;it3ZX24~Nd`jzEPtPk9b19*#W8e1&m%ZVsL&|^ql10xsB`(f& zoy*21Fmb0?IHO2WWS3vOm~2{Eb?6TtsAQ>Cf=O`E9GtlW)iv;dctesK3C_Pr#A;=G zhbKB`LpF?F)Qy-cdgDqTXTj@&9F4cC?R4+fe}2;!&eG}?GYk>CFmr|FkBRA99d$-k zEUl-H4{(MQ{$18r@Af}PBFl$#VN#wYF7#K(VtqBI%P5SDD7R-i?ohjq&v25=Fk*U0 z8c_n#qYNN6;ybpS}{RCE-Vo?VWiu!k!Nm6(;iY?A#Thf_AM~bosK$>ST%vm~^aMB` zdpW|}etKlPbr&xwJQ9V==xFrnD?x{iyI1;2WILdVcvmUaiV;T2%t&+Spdw);8lt8g zXUWW+n4gSqBBkAsc_2hRriWxT+9!xp4R)1n4LTIefiBo>tac&enl@Soaq>ZxD23(#ehYJp3C6 zD~zVSixwotvbpTX2gmN^<@%pmxgSwioP&{n%Y;J{%#xNl((eUx_EF!Km2E;1dXoeP z%o1L(m*$WvyoOl0$oZUa%E;OSXOgQOsAhk-<}nveh{=7sCf~Nymh1RvZ50af7-zz~ z@*a3G0&q6=Qp?-y%d@JTo#SlPh|a!@^>dEx6D@m60FP}k+-0KL(f&mxY3!O~uJijB z=>C4rVqkTj_Ydve$q@(oGk(|i-o02~+9Q(9id9m@y@rw1GV?ML46W$rjfH~!JUpzo z9R%OlI|SM%0mSEgJEmWHmGccl=<0H(zqVZUk6K3QFe%sSJiN&N z?iw_lW?ehL$gFOy#|ql9eEyPO{54uV(DBD__~X^I^Kc@f{G*(>LsjwB&iR^3n-Yhl zeva>@gJTu$FE5I!+?*WnNR+reJXQL1IPB;(_aNp8&9z%6a}3Ld9lMmByYX5tbe3T4 z_E!2jPDL4lnSE9mnF~$1ezAob|CD=LuZd{EtLoykt>|kHpnxDzAfsB+~xMd!kK$k*bD5gfsITw?-{FYPX@+e&K*2EP_=UZ)YBv9NJ<3|{Mu>n zP^J`KyID-y6lI^$xKEcnc-J#r+zlvFD7LN=uMrTinj_MK7H?f=#3M-T9g4 z59ts)o6QHT<|f6rp8Y;DtK3l&q^#naqxi_E{e`~Xh=AC#f3)q20=8Y!_9mC*(-g{` zA<~HsU&evg9YMpZj8=}XHoI!tPrCa-bqOr*M_3RCUM8Am9nhR4LA)R|A-$;mR2Ipo zAaE%!a;zb|RH^T2Kgu?wN7ZgU3?n0ZSb$S8xPwNrW~5!bZRa!@K22dOZel^zV!CB4 z>Ngg!a|BwvU-+Rsh$?cR5?QQ~(jQNo&^!vz|%-yC4gj!0inZx>mZ3mkIv6K=c?!4I3-cJWVti8qgT}S@n++E)X7u)Zq zW~X?m*tvK}4s2IBj^3zn_=Zm&AGy1q{E>YSzr2AWDW59dVSL}Af zg;iW_+O3iNt`ek1-coZ+_-N)8duk)+}V{_gq}{T&i-*#V4k<3 zW|Y4Ue;{K=8;{N?ZwouYt6UO1B{&{0lPM0dt32ri#M)pguqz`X7%f7{49QVTxtU55 zWGE@MW4`TVop^(#=w@SR9zG`9_xUb^LM@=G<*IgBxd?;q9@PQ@jDmTGn7FesF!Dhz zFOh8Ol|wMVO6<30g8iH@Mn8&b&AL+k-0JVz_SiYKKD(kZmOD|i)Ty=lBNORzYduK6 zG7C@Pz2#$VgbZ=(teG7=G9;AYDn5cK%xr^|$aPe$q717R+6XY%4*Q7KKoL=V+yOOn ze0$)5Wh#_FG-@CYf6nnhA}SaC7fXzonW8;` zhZDxGYhf)#wE`X*>N}fRqFR5K%M*Y%KwG&^J;8{$kd$PL86@H5Zp}=hJKN$a5Y3D`M30gZ_2G$lpuL#6bqS$wX`r zg)PH{Cq|b^?^Z@$lY5NN9xGiF^p%%xzhsv^7(e@W+W`;iFue<@S|wcg z+I;YHLJppS+rD*_G*PT_^6Y5wQ5?t6$oL1tw@Zp(MssG7II#ELc^Y8}A2x@7-mZr= zi)RKuu=(*m^>~B!dop_F{uxVh)dB|L;8mOjv$t>a{XDb!0l9E29zCU1PWPbE{QXeD zHStERGi9Of*M6Ltd?nZ&K#mPztq5Gr>8x^gX5}{ow&C3an>Mogl(?;_YBC$jU40~b zqq&({tF;O^59ryzau-)Z)_4E?1hcf`zXUM|cdvdys_Gl5sHF@$y7%3`e@&j3SmMSJ z-my`|!*PBD2ToY3tHQyeMqc(ye-P}PjuE>$pgw@o7+zg}bz%JoW^rQ-)2!*s z3GG2^1eUSx?;WlVEYmk7Q{a4|Bu~utYiC(z`Ry$-;z^?5uMk}%K3h5C?N&)|&X5N? zEZrMcHQ|@(DY47F?sd~=OfxvxSeI9gL zU>hp4asp^R(0{-GD)3(g{;R-$75J|L|5f0>3j9}r|Jw?{WOln`8c0XWwTrQ`c{&a?L#9yAze&DPd-0cD*gAfi_K1J5Kp{zz6N`(_T>OX700kHTfX(M?ckeD&a;Z3*isI$fTq~KoaP|F#r3=>$ z<#+WLQek^vJXLEohoWRCO177yINN=#wjej){~{{_001^jd7yvvg)bgF{qC!saAv8V z?JEu)=wF^*Nw0R=tIhaqtuj?9_m*<0DAVb*2TP^ieE!{5V`VjWM_kO<{|qR=003+j zmEO41NqYMyuFbVWD4(ybEH-oP5I^>*gD+jYd|e}#O{elneRiR?w$>OZ9Z0&}EpdFd zz19i!RJ$WUU_F0qfd&9zgrniGh_P(i{+%7EUtAH*OGxwvY4c1+KB*x^)LYj0ASW*=)#WLh9bV`{O8juerFrI$jL}p>N-I*VmfMOUcSyw|3>7b4LXTtcR2I007uHPn?1jTq<1;Jsmuiboy?g2#w|;D*Qq6}DLRfB1&#%rrb*6o2=ips^ zJ7fraXtt360I+e&o#e(XeSN9$#EYkw>P!1aatnWr+UFks!>=FwQV3zHI=I&EK63c3 zzI-vX!+fXp*DG@`%*@TTqn-WZgFOQR1QcKZ05*r2`K9Tlg`}1K&DZZJM46sUF_%dn zzJKE1H|!c1I`ZRRe(U2$mKx33ZgZkstj6(LI#tLXE}RgR|`=gj^cJ_tW>(tYCn1M^515=-^nh75c&s_={Wa;SKog- zw{W$bkM&HjF_vnc?PR!kX&m95;*24rC0Dz4%R_%#9 z$v~;N+U+bYFW2W!{yY??Ca3D{P;Y;=U!R%1bL-^R-panwuuxyUefLz9$v^$u3$3J+ z&4<@tIVC_q0R{kIbGUPA{Mfk*J4XfzSl{43_9y>lgx6-Us(;xV}GsdZDqJ%8ykF?_XQWq*MF0^&H$*iqhQ>!e~@|K!U(Jc#8%Az{Yv(?Te%R z#WPpu<4V+9EmzCcwN59S>Xx#(TBF`gGU3__&CXiVb0mbYytuMZTZz({?IZn-X6qBf z)g6U`3;_TD0000000000006U{5v&Q5Knn~XfKBJ000030{{sNEAVd4dYKWWw0000< KMNUMnLSTYETyJjx delta 1703 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 b|NjF3VH_P}XeXym00000NkvXXu0mjf*kxKV delta 1678 zcmV;9266e!HpDitz6yVFNkl9mnza@BHhpr{8+++O8X0H#RypU@|}i zAqd$ZUJw;EhG0n4n0SMSL}N_E!-W{HNJzXfB7x`);(>^qWE=!1Y=h06x&u45UHSF2 z?$`F${(j!k3lp!~vOrY4GsBpdVNHCX<#Hw z3=CiZ0AM9J7l)f-A=$kcYZjw-A=8tLy7}02rkbl&K)??*Yk;!Yqw8){hbF&1C7(^bK9>7_YoZWQPDCYQHZhc0_@I4aq&VGo@7{r%#(wnn?(?-`WigSj)_Sv* z>l@3pT5ZoqvavEa0R{j7mQ+_~-}}imneuzBbAL$HCR6wK7R!Hy!zWg^PPWdy*)kTz zd*e*^RI;y|1pok+{Ovcj)LeWRrSV$nOvLE1 z#_7oH=sNr3@1}?LAA9GewurU0NOi6nDi$v6tJ^ium1#;PNAl^#zFOyeW@nd)!Sdw< z7ytlR@@6{9l^B1owOmZJ)FQUWP(xJu+shIC8?M>#;n9zV&lWnn$G5D%u;=oQ>1aAy zjjL0Y;_TwgWb#r*KMY_10APhUI~kedQ$4x!yF2#3f9cxMa~-AL*)=g05fOtMx4oUp zoV@PlOg_JD@!iH+B<3b!v@g{)zgSodaBy-{;94n>^>5A zWEUbia_(Ft)<-H)8y&ml?!j#Ry0JqqChIyg^H&xw;P zti4iAG-rRabuA4Gnd1iqWI1y~9RL7W^88<``%hP2e7W4zlx%HH-QE4#t_S)WI@?AL z9By5|wOXl6pFBCX@13hY|HX7eV=7;W$#PWpOO}bDYwd&mXSn1NixA*0T z$98U7*I(C@5)cCz003ASPNWi-PfzUF_U`9)Pp|IT9gUxfM6z00n2B_KL_`#NdS3b7 zPn$NaIW@B(+t-$8yKy*`tF@=ftr6)30Wp990DzU@y87p@{mNuh<6thkCL*RIJ$1fx z;K_g2@(p#@?;gxF7Eb)-jXQtw!^^|Ni~l%uan-8DbYZp$GoPBy<`N7SbBa?~O-*pEV0~i1RSRu+Ci&LvoiJ53h zC)4x!qf=c2-G@`>{xe+~JvFv<=fYevotxXVZm4DFpPrtqjZJ=X@cjC9dpbAW_RD`q z;`o`QfGlSoPyhg6$;F{$Lm{FiM&@H8ACp(gO?78qKRP}%y>VbygLK* z|4OdeoG7%!WMdq9>&uJP*w`5@h1!MrhGTmV_1@6i*}d@TFEzAX-85cK?t3LJ9EdHq zMns%DJ0~E^na`91002u)pRGN6JhJt%wm-7jxUvvaGchq4u^6l7qB%KvTi05fQ)Agu z?_CiQr5O8X)McZ(Iwmj2j?U4}n>saQ*>VC5001mWy&T)`iIbyIDn(OsG}T8j7d^#j zuEoM)q*Bcv9BA)J9*>A9N1Tf0hM2EJcYD<3qNBA#K(lcXya|&~3ke?hU;hOF0RR63 Y02tLBW22L>SpWb407*qoM6N<$f{les5&!@I diff --git a/assets/share/combat/stamina/status/STAMINA_OCR.png b/assets/share/combat/stamina/status/STAMINA_OCR.png new file mode 100644 index 0000000000000000000000000000000000000000..85631fbdb6bf6a6fc9dc3ba7107ac76be798d269 GIT binary patch literal 12042 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�(T`@pFcJ4Rh{o#cYmCPs_3M9rP#HHE<4rPFK!ED1xk90P5C`2m&nT_!Au zRp*Z*39AKoH2Z}PbpwGoMlO=g2&9iQI+5FY48%?uKKYlC0PgeAdOtE~Aa6r!uN=9) zQ?4aHQO@iVOMsKN@q}g;t@VML5MF6IXl{PKttp%-g4p{URT1=xy6owH6Xz18hTS{(SKIc~Qh~OqM~6-&XtG_7HcW6dFHSV*e$a;8AEuA|#>k7D)4kev@@U`AQpIstAf!y@ zxhh{c)L6msCp_vB?Jh|5)i9v<()B(3p~P{HW7sj#@||ypH3ypzk}$>zadFa`Oc6;JqjKg0(R@!Tyl|_YGTC*FRZDtw-ZDf ziYWBvwM?)eshnM9@6oi;qLgae6vEu4*DZN6IQlIsL1QnPQ+R)+9l1L@7y602mqs}A z0~_!00&z4Q?E=&Cxh_eZtd_>j5i3J!6&)45W;cbc4>zu~zO`Rn#ZC*!u=MXBfUp3`A=r8~n*W*nU!n|9lh0H4ZF(6ll}(kZd2jG$yg(KL`A^mC=>iSUFM?2 zUCF@eA9x}daKSt2x9 z;KssJsG3$&k#4bRexa57a3&-^*_Q||fEWzphX>~?tf1Q6;5)DQfu?FIadwz&<~T~-0a%Ax6u2L>?-gR}V z9ywL#FU1!qA@O|VQf>5x5U_&%i~S6WQXS;PvL;&o&W=7HkRqJ_3nrA$=0m3X;fVeI zNTdj&W^{%7U4C^cAO3abl#4aA>;}jO?j8r35CRvBe{0C!Z=r&q*u);!KJPeweCz)b z@IJ}T+Rsh6j#X9a+jGT3--!^MZd=iJ^^mvbjV#jz#gXhRGPlc#U}9~u>!f1dBDo;h z*8oj&m@FLj%Pf2>E5vP|Vyb7(j0u!wFr+@NvH4V}(Hqf8GW90^9)ge@ te+c}Cz<&t*hroXb{C|eP3_I|M0m#SnkVF)^= cost: return True else: diff --git a/tasks/combat/fuel.py b/tasks/combat/fuel.py index 06fc08df0..461fa1196 100644 --- a/tasks/combat/fuel.py +++ b/tasks/combat/fuel.py @@ -4,14 +4,16 @@ from module.base.utils import area_offset, crop from module.logger import logger from module.ocr.ocr import Digit from tasks.base.assets.assets_base_popup import GET_REWARD, POPUP_CANCEL, POPUP_CONFIRM -from tasks.base.ui import UI from tasks.combat.assets.assets_combat_finish import COMBAT_AGAIN, COMBAT_EXIT -from tasks.combat.assets.assets_combat_fuel import * from tasks.combat.assets.assets_combat_prepare import COMBAT_PREPARE +from tasks.combat.assets.assets_combat_stamina_fuel import * +from tasks.combat.assets.assets_combat_stamina_reserved import * +from tasks.combat.assets.assets_combat_stamina_status import * +from tasks.combat.stamina_status import StaminaStatus from tasks.item.slider import Slider -class Fuel(UI): +class Fuel(StaminaStatus): fuel_trailblaze_power = 60 def _use_fuel_finish(self): @@ -26,7 +28,7 @@ class Fuel(UI): return True if self.appear(COMBAT_PREPARE): if self.image_color_count(COMBAT_PREPARE.button, color=(230, 230, 230), threshold=240, count=400): - logger.info(f'Use fuel finished at COMBAT_AGAIN') + logger.info(f'Use fuel finished at COMBAT_PREPARE') return True return False @@ -87,7 +89,7 @@ class Fuel(UI): timer = self.get_interval_timer(COMBAT_EXIT, interval=5, renew=True) timer.set_current(4.4) - def extract_reserved_trailblaze_power(self, current, skip_first_screenshot=True): + def extract_reserved_trailblaze_power(self, skip_first_screenshot=True): """ Extract reserved trailblaze power from previous combat. @@ -95,11 +97,8 @@ class Fuel(UI): bool: If extracted """ logger.info('Extract reserved trailblaze power') - reserved = Digit(OCR_RESERVED_TRAILBLAZE_POWER).ocr_single_line(self.device.image) - if reserved <= 0: - logger.info('No reserved trailblaze power') - return False + RESERVED_ICON.load_search(ICON_SEARCH.area) self.interval_clear([POPUP_CONFIRM, POPUP_CANCEL, GET_REWARD]) while 1: if skip_first_screenshot: @@ -111,12 +110,14 @@ class Fuel(UI): break if self.appear_then_click(EXTRACT_RESERVED_TRAILBLAZE_POWER): continue - if self.appear_then_click(RESERVED_TRAILBLAZE_POWER_ENTRANCE): + if self.appear_then_click(RESERVED_ICON): continue - count = min(reserved, self.config.stored.TrailblazePower.FIXED_TOTAL - current) - logger.info(f'Having {reserved} reserved, going to use {count}') - self.set_reserved_trailblaze_power(count, total=reserved) + # No need, amount will be set by game client + # count = min(reserved, self.config.stored.TrailblazePower.FIXED_TOTAL - current) + # logger.info(f'Having {reserved} reserved, going to use {count}') + # self.set_reserved_trailblaze_power(count, total=reserved) + self._fuel_confirm() return True @@ -160,6 +161,7 @@ class Fuel(UI): logger.info("Use Fuel") + STAMINA_ICON.load_search(ICON_SEARCH.area) timeout = Timer(1, count=3) has_fuel = False while 1: @@ -182,7 +184,7 @@ class Fuel(UI): if self.appear_then_click(FUEL): has_fuel = True continue - if not self.appear(POPUP_CONFIRM) and self.appear_then_click(FUEL_ENTRANCE): + if not self.appear(POPUP_CONFIRM) and self.appear_then_click(STAMINA_ICON): continue offset = FUEL_SELECTED.button_offset @@ -215,3 +217,39 @@ class Fuel(UI): self.set_fuel_count(use) self._fuel_confirm() return True + + def extract_stamina(self, update=True, use_reserved=True, use_fuel=False): + """ + Args: + update: + use_reserved: + use_fuel: + + Returns: + bool: If used + """ + if not use_reserved and not use_fuel: + return False + + logger.hr('Extract stamina', level=2) + logger.info(f'Extract stamina, reserved={use_reserved}, fuel={use_fuel}') + if update: + self.update_stamina_status() + used = False + + if use_reserved: + if self.config.stored.Reserved.value <= 0: + logger.info('No reserved stamina') + else: + self.extract_reserved_trailblaze_power() + used = True + self.update_stamina_status() + self.get_interval_timer(COMBAT_AGAIN).wait() + + if use_fuel: + self.use_fuel(current=self.config.stored.TrailblazePower.value) + used = True + self.update_stamina_status() + self.get_interval_timer(COMBAT_AGAIN).wait() + + return used diff --git a/tasks/combat/prepare.py b/tasks/combat/prepare.py index 3f76ecd87..37e069731 100644 --- a/tasks/combat/prepare.py +++ b/tasks/combat/prepare.py @@ -1,35 +1,20 @@ -import re - import module.config.server as server from module.base.timer import Timer from module.base.utils import color_similar, get_color from module.logger import logger -from module.ocr.ocr import Digit, DigitCounter -from tasks.base.ui import UI +from module.ocr.ocr import Digit from tasks.combat.assets.assets_combat_prepare import ( - OCR_TRAILBLAZE_POWER, OCR_WAVE_COST, OCR_WAVE_COUNT, WAVE_MINUS, - WAVE_PLUS, WAVE_SLIDER + WAVE_PLUS, + WAVE_SLIDER ) +from tasks.combat.stamina_status import StaminaStatus from tasks.item.slider import Slider -class TrailblazePowerOcr(DigitCounter): - def after_process(self, result): - result = super().after_process(result) - # The trailblaze power icon is recognized as 买 - # OCR_TRAILBLAZE_POWER includes the icon because the length varies by value - result = re.sub(r'[买米装:()]', '', result) - # 61240 -> 6/240 - result = re.sub(r'1240$', '/240', result) - # 0*0/24 -> 0/240 - result = re.sub(r'24$', '240', result) - return result - - -class CombatPrepare(UI): +class CombatPrepare(StaminaStatus): # Current combat waves, combat_waves = 1 # Limit combat runs, 0 means no limit. @@ -78,20 +63,20 @@ class CombatPrepare(UI): else: self.device.screenshot() - current, _, total = TrailblazePowerOcr(OCR_TRAILBLAZE_POWER).ocr_single_line(self.device.image) - # Empty result - if total == 0: + data = self.update_stamina_status(image=self.device.image) + if data.stamina is None: continue # Confirm if it is > 240, sometimes just OCR errors - if current > 240 and timeout.reached(): + # if current > 240 and timeout.reached(): + # break + if expect_reduce and timeout.reached(): break - if expect_reduce and current >= before: + if expect_reduce and data.stamina >= before: continue - if current <= 240: + if data.stamina <= 240: break - self.config.stored.TrailblazePower.value = current - return current + return data.stamina def combat_get_wave_cost(self, skip_first_screenshot=True): """ diff --git a/tasks/combat/stamina_status.py b/tasks/combat/stamina_status.py new file mode 100644 index 000000000..a21ad7050 --- /dev/null +++ b/tasks/combat/stamina_status.py @@ -0,0 +1,161 @@ +import re + +from pydantic import BaseModel + +from module.base.timer import Timer +from module.base.utils import crop +from module.logger import logger +from module.ocr.ocr import Digit, DigitCounter +from tasks.base.ui import UI +from tasks.combat.assets.assets_combat_stamina_status import * + + +class StaminaOcr(DigitCounter): + def after_process(self, result): + result = super().after_process(result) + # The trailblaze power icon is recognized as 买 + # OCR_TRAILBLAZE_POWER includes the icon because the length varies by value + result = re.sub(r'[买米装来:()]', '', result) + # 61240 -> 6/240 + result = re.sub(r'1240$', '/240', result) + # 0*0/24 -> 0/240 + result = re.sub(r'24$', '240', result) + return result + + +class ReservedOcr(Digit): + pass + + +class ImmersifierOcr(DigitCounter): + pass + + +class DataStaminaStatus(BaseModel): + stamina: int | None + reserved: int | None + immersifier: int | None + + +class StaminaStatus(UI): + @staticmethod + def get_stamina_status(image) -> DataStaminaStatus: + """ + Update trailblaze power, stored trailblaze power, immersifier + + Returns: + int: Stamina, or None if stamina not displayed or error on OCR + int: Reserved stamina + int: Immersifier + """ + for button in [STAMINA_ICON, RESERVED_ICON, IMMERSIFIER_ICON]: + button.load_search(ICON_SEARCH.area) + + stamina = None + if STAMINA_ICON.match_template(image): + STAMINA_OCR.load_offset(STAMINA_ICON) + im = crop(image, STAMINA_OCR.button, copy=False) + stamina, _, total = StaminaOcr(STAMINA_OCR).ocr_single_line(im, direct_ocr=True) + if total > 240 or total == 0: + logger.warning(f'Unexpected stamina total: {total}') + stamina = None + + reserved = None + if RESERVED_ICON.match_template(image): + RESERVED_OCR.load_offset(RESERVED_ICON) + im = crop(image, RESERVED_OCR.button, copy=False) + reserved = ReservedOcr(RESERVED_OCR).ocr_single_line(im, direct_ocr=True) + if reserved > 2400: + logger.warning(f'Unexpected reserved value: {reserved}') + reserved = None + + immersifier = None + if IMMERSIFIER_ICON.match_template(image): + IMMERSIFIER_OCR.load_offset(IMMERSIFIER_ICON) + im = crop(image, IMMERSIFIER_OCR.button, copy=False) + immersifier, _, total = StaminaOcr(IMMERSIFIER_OCR).ocr_single_line(im, direct_ocr=True) + if total != 8: + logger.warning(f'Unexpected immersifier total: {total}') + immersifier = None + + return DataStaminaStatus( + stamina=stamina, + reserved=reserved, + immersifier=immersifier, + ) + + def update_stamina_status( + self, + image=None, + skip_first_screenshot=True, + expect_stamina=False, + expect_reserved=False, + expect_immersifier=False, + ) -> DataStaminaStatus: + """ + Update stamina status with retry + + Args: + image: Detect given image only, no new screenshot will be taken + and all expect_* are considered False + skip_first_screenshot: + expect_stamina: + True to expect stamina exists, retry detect if it wasn't + expect_reserved: + expect_immersifier: + + Pages: + in: page_guild, Survival_Index, Simulated_Universe + or page_rogue, LEVEL_CONFIRM + or rogue, REWARD_CLOSE + """ + timeout = Timer(1, count=2).start() + if image is None: + image = self.device.image + use_cached_image = False + else: + skip_first_screenshot = True + use_cached_image = True + + while 1: + if skip_first_screenshot: + skip_first_screenshot = False + else: + self.device.screenshot() + image = self.device.image + + # Timeout + if timeout.reached(): + logger.warning('dungeon_update_stamina() timeout') + return DataStaminaStatus( + stamina=None, + reserved=None, + immersifier=None, + ) + + # Ocr + status = self.get_stamina_status(image) + valid = True + if expect_stamina and status.stamina is None: + valid = False + if expect_reserved and status.reserved is None: + valid = False + if expect_immersifier and status.immersifier is None: + valid = False + if status.stamina is None and status.reserved is None and status.immersifier is None: + logger.warning('update_stamina_status: No icon detected') + valid = False + + # Write config + with self.config.multi_set(): + if status.stamina is not None: + self.config.stored.TrailblazePower.value = status.stamina + if status.reserved is not None: + self.config.stored.Reserved.value = status.reserved + if status.immersifier is not None: + self.config.stored.Immersifier.value = status.reserved + + if use_cached_image or valid: + return status + else: + continue diff --git a/tasks/dungeon/assets/assets_dungeon_stamina.py b/tasks/dungeon/assets/assets_dungeon_stamina.py index 290d0b3f0..78d5b12f1 100644 --- a/tasks/dungeon/assets/assets_dungeon_stamina.py +++ b/tasks/dungeon/assets/assets_dungeon_stamina.py @@ -41,16 +41,6 @@ AMOUNT_PLUS = ButtonWrapper( ), ], ) -ENTER_IMMERSIFIER = ButtonWrapper( - name='ENTER_IMMERSIFIER', - share=Button( - file='./assets/share/dungeon/stamina/ENTER_IMMERSIFIER.png', - area=(1047, 26, 1066, 49), - search=(1027, 6, 1086, 69), - color=(138, 127, 117), - button=(1049, 26, 1151, 48), - ), -) IMMERSIFIER_CHECK = ButtonWrapper( name='IMMERSIFIER_CHECK', share=Button( diff --git a/tasks/dungeon/stamina.py b/tasks/dungeon/stamina.py index 6f28729b3..41fd56354 100644 --- a/tasks/dungeon/stamina.py +++ b/tasks/dungeon/stamina.py @@ -3,6 +3,7 @@ from module.base.timer import Timer from module.logger import logger from module.ocr.ocr import Digit from tasks.base.page import page_guide +from tasks.combat.assets.assets_combat_stamina_status import ICON_SEARCH, IMMERSIFIER_ICON from tasks.dungeon.assets.assets_dungeon_stamina import * from tasks.dungeon.keywords import KEYWORDS_DUNGEON_TAB from tasks.dungeon.ui import DungeonUI @@ -16,6 +17,7 @@ class DungeonStamina(DungeonUI): out: IMMERSIFIER_CHECK """ logger.info('Enter immersifier') + IMMERSIFIER_ICON.load_search(ICON_SEARCH.area) while 1: if skip_first_screenshot: skip_first_screenshot = False @@ -24,7 +26,7 @@ class DungeonStamina(DungeonUI): if self.appear(IMMERSIFIER_CHECK): break - if self.appear_then_click(ENTER_IMMERSIFIER, interval=2): + if self.appear_then_click(IMMERSIFIER_ICON, interval=2): continue def _immersifier_exit(self, skip_first_screenshot=True): @@ -140,7 +142,7 @@ class DungeonStamina(DungeonUI): logger.hr('Immersifier store', level=2) logger.info(f'Max store: {max_store}') self.dungeon_tab_goto(KEYWORDS_DUNGEON_TAB.Survival_Index) - self.dungeon_update_stamina() + self.update_stamina_status() before = self.config.stored.Immersifier.value if self.config.stored.Immersifier.is_full(): @@ -159,7 +161,7 @@ class DungeonStamina(DungeonUI): self._immersifier_enter() self._item_amount_set(amount, ocr_button=OCR_IMMERSIFIER_AMOUNT) self._item_confirm() - self.dungeon_update_stamina() + self.update_stamina_status() diff = self.config.stored.Immersifier.value - before logger.info(f'Stored {diff} immersifiers') return diff diff --git a/tasks/dungeon/state.py b/tasks/dungeon/state.py index 6a1a042ed..814306161 100644 --- a/tasks/dungeon/state.py +++ b/tasks/dungeon/state.py @@ -1,14 +1,13 @@ from datetime import timedelta from module.base.base import ModuleBase -from module.base.timer import Timer from module.base.utils import crop from module.config.stored.classes import now from module.config.utils import DEFAULT_TIME, get_server_next_monday_update, get_server_next_update from module.logger import logger from module.ocr.ocr import DigitCounter -from tasks.base.ui import UI -from tasks.dungeon.assets.assets_dungeon_state import OCR_SIMUNI_POINT, OCR_SIMUNI_POINT_OFFSET, OCR_STAMINA +from tasks.combat.stamina_status import StaminaStatus +from tasks.dungeon.assets.assets_dungeon_state import OCR_SIMUNI_POINT, OCR_SIMUNI_POINT_OFFSET from tasks.dungeon.keywords import DungeonList @@ -19,7 +18,7 @@ class OcrSimUniPoint(DigitCounter): return result -class DungeonState(UI): +class DungeonState(StaminaStatus): def dungeon_get_simuni_point(self, image=None) -> int: """ Page: @@ -48,67 +47,6 @@ class DungeonState(UI): logger.warning(f'Invalid SimulatedUniverse points: {value}/{total}') return 0 - def dungeon_update_stamina(self, image=None, skip_first_screenshot=True): - """ - Returns: - bool: If success - - Pages: - in: page_guild, Survival_Index, Simulated_Universe - or page_rogue, LEVEL_CONFIRM - or rogue, REWARD_CLOSE - """ - ocr = DigitCounter(OCR_STAMINA) - timeout = Timer(1, count=2).start() - if image is None: - image = self.device.image - use_cached_image = False - else: - skip_first_screenshot = True - use_cached_image = True - - while 1: - if skip_first_screenshot: - skip_first_screenshot = False - else: - self.device.screenshot() - image = self.device.image - - stamina = (0, 0, 0) - immersifier = (0, 0, 0) - - if timeout.reached(): - logger.warning('dungeon_update_stamina() timeout') - return False - - for row in ocr.detect_and_ocr(image): - if row.ocr_text.isdigit(): - continue - if row.ocr_text == '+': - continue - if not ocr.is_format_matched(row.ocr_text): - continue - data = ocr.format_result(row.ocr_text) - if data[2] == self.config.stored.TrailblazePower.FIXED_TOTAL: - stamina = data - if data[2] == self.config.stored.Immersifier.FIXED_TOTAL: - immersifier = data - - if stamina[2] > 0 and immersifier[2] > 0: - break - if use_cached_image: - logger.info('dungeon_update_stamina() ended') - return - - stamina = stamina[0] - immersifier = immersifier[0] - logger.attr('TrailblazePower', stamina) - logger.attr('Imersifier', immersifier) - with self.config.multi_set(): - self.config.stored.TrailblazePower.value = stamina - self.config.stored.Immersifier.value = immersifier - return True - def dungeon_update_simuni(self): """ Update rogue weekly points, stamina, immersifier @@ -122,8 +60,8 @@ class DungeonState(UI): def func(image): logger.info('Update thread start') with self.config.multi_set(): - self.dungeon_get_simuni_point(image) - self.dungeon_update_stamina(image) + # self.dungeon_get_simuni_point(image) + self.update_stamina_status(image) ModuleBase.worker.submit(func, self.device.image) diff --git a/tasks/ornament/combat.py b/tasks/ornament/combat.py index 2e6c6b512..638e508e9 100644 --- a/tasks/ornament/combat.py +++ b/tasks/ornament/combat.py @@ -130,7 +130,7 @@ class OrnamentCombat(Dungeon, RouteLoader, DungeonState): after = before for _ in range(3): - self.dungeon_update_stamina() + self.update_stamina_status() after = self.get_equivalent_stamina() if expect_reduce: if before > after: diff --git a/tasks/rogue/entry/entry.py b/tasks/rogue/entry/entry.py index 9286f45e0..6a94b51b9 100644 --- a/tasks/rogue/entry/entry.py +++ b/tasks/rogue/entry/entry.py @@ -261,7 +261,7 @@ class RogueEntry(RouteBase, RogueRewardHandler, RoguePathHandler, DungeonRogueUI if not self.image_color_count(LEVEL_CONFIRM, color=(223, 223, 225), threshold=240, count=50): self.interval_clear(LEVEL_CONFIRM) continue - self.dungeon_update_stamina() + self.update_stamina_status() self.check_stop_condition() self.device.click(LEVEL_CONFIRM) continue diff --git a/tasks/rogue/event/reward.py b/tasks/rogue/event/reward.py index 4d9390922..a280c24ad 100644 --- a/tasks/rogue/event/reward.py +++ b/tasks/rogue/event/reward.py @@ -54,7 +54,7 @@ class RogueReward(RogueUI, CombatInteract, DungeonState): confirm.reset() continue if self.appear(REWARD_CLOSE, interval=2): - self.dungeon_update_stamina() + self.update_stamina_status() if not init: initial_stamina = self.config.stored.TrailblazePower.value initial_immersifier = self.config.stored.Immersifier.value From 47a07b0c522e586cce6935c06438e26cda33a710 Mon Sep 17 00:00:00 2001 From: LmeSzinc <37934724+LmeSzinc@users.noreply.github.com> Date: Sun, 11 Aug 2024 02:39:55 +0800 Subject: [PATCH 11/11] Fix: Leave OE before running --- .../base/main_page/ROGUE_LEAVE_FOR_NOW_OE.png | Bin 0 -> 7536 bytes assets/share/base/page/MAP_EXIT_OE.png | Bin 0 -> 6166 bytes tasks/base/assets/assets_base_main_page.py | 10 ++++++++++ tasks/base/assets/assets_base_page.py | 10 ++++++++++ tasks/base/ui.py | 11 ++++++++--- 5 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 assets/share/base/main_page/ROGUE_LEAVE_FOR_NOW_OE.png create mode 100644 assets/share/base/page/MAP_EXIT_OE.png diff --git a/assets/share/base/main_page/ROGUE_LEAVE_FOR_NOW_OE.png b/assets/share/base/main_page/ROGUE_LEAVE_FOR_NOW_OE.png new file mode 100644 index 0000000000000000000000000000000000000000..71c09441736d14fc7aa0444d86b7d9928d95fe94 GIT binary patch literal 7536 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 literal 0 HcmV?d00001 diff --git a/assets/share/base/page/MAP_EXIT_OE.png b/assets/share/base/page/MAP_EXIT_OE.png new file mode 100644 index 0000000000000000000000000000000000000000..6718bb2d2a352d1d4ef1df947732d54239ec89bf GIT binary patch literal 6166 zcmeH~=T}orxW$Lwq<4@mAkw6YAVq564FaJHNRwWI5K2IbB8VbQnsfvdfq+t!7%5Rf zdKW}`kCYfX(r>)~!Toxdv(~KVtU3ERd**k(%zk2e%YdGihZX=pZwS$a0YE`~BpswC zB^E6KBNAev34quJ0YJz4canhId@cZJjlFbqOiexE2zZbuJV4M;M@KLq5bo~f>jpsB zM1gszP5J?c#_WL`qm}mfW^K0b10XDdqV8m}En#{NoF6fB&|0yvGv`Ar+a8Y6 zLJATViZ7!*Zaz)8ooH#V@>^i4{C#9N0gpfaaomK<$DQ;e2N+|RS;W#-O1!~!SlkWO zae)*QNLyEP3@JNgj$DvwrRR$WMLPhSWXP~6#5>IslDBX`3IaxDF0pjXpT}ZM#jJr~ z8kiGi!O@YV!a%2tMJF5R+jNn3;=wQ_qByVB|X^KHPoO0;}z*soM61?JKunIdR4))z zAq6`8tbJsHP_p8y!>w}_jsbCK2noRUWcFqMH>|*h&K%?k-QJvA5L)=+TdVENDZ%7U zvm~6KohQNy!I44xF95)EIQ02UMKcw*vNXTqj`Jn#wwIjwY{G>#gtlhSnx2u81EyO8 zgbByx@mH0`{>cafHk4lnBR zvia&_qQ<$xJbW%OYM=P_Y%+Wk+{@L>E~r!?uI^Z*rag1z;D>V1zdHtIJC zX(EHoa0t+f+L3<7Lzf1aJQU@T2LPnE9;RqXl7PPKvPA%zesS5q$>4;3qXs~?_`#KT zH>oasWj9jUPF#gwxSHZ=$ZvL1vpNf@CNR4sj|=xxbLJ$I3p+y;pU0F5t|qXV z3Ac9!mXTIyd#5=-M7E^^*{&zqYaOLdb_&WrJ$c$>AeZr=&W!9kX|UGEHv&9QzZC}! zAru)MVzNqnhIktI)nh)Cln?#)D;NPHpC-G;49PLLKl|xy|Ln1z(-RvWu?`N`Wg8`{ z6eU+an`N}5^zW6>&O*OEA+UUFy-4JPD!BAV%#6FVyA}*Z% z#-u?soaL}B%tf^})kYsB_FITws8IBdI0LI=I^+^V*Yl-Yv_hh(@`iMVK9EU>beVaX z#xRptK2&Ty)vs%2iMlQZC77Mon97)H^8C2#>rx||YJ0*0l&0hotSp1YNXboenfz6e zymn4;rCDD^;dkoF1l6M3hJM8%rn2UbD_9kSb4B~|ICOf-q)SH!bGOQve3Rc2HsuF}FX$Wn6@SxIM6Wyx4|$13u*zGc1XVg=22j;hfL zKFd!P$~FD4P*{rTfSF@yi{t6TBUk#m_&ELIcu1**YvVWWBq5G(@@`u;+GBxMWb0Bs zFN|I6>JB%cAr!~FA+ixrbDf|{ca(dYd%?=RJ`#p+wR4--f94zY3-#0YM@W-NYf9IS zc~`qvM^#^&2%l(~aKQ)SIq>Tfgy4VztpcfnJyk!|gJ2qrGR6!OhnWl>SkoABT}Q6c z>~-%ktWFOZ?D_4M?s2XW#t1_K*RCp3E2nb%%Bi?+_NKc2@_FHf9@=~~|Ax886O-2F zSvq7`DvlQW{n%qsDU4IY9RNAuoASBg?BXRqS=Lt8zSJVom*JD^ju~ngLG<=^ zN=>20QC%C!*GKbx3Y}YiHcg%+#l6zYZ#PO*PVC5<$hzM{k!759fO=u2VTH8Xv-*KD z9J61STK5~X_BG|T&byGOn%DE;O?6&%TS%VYEZYKGio~$Qp1J>o+{VcU?MChfCI0%p z^S((IA8yl+QX6^ zlFe!ESN^ozzbL#XbD8HiX88TcUTNN^ys7G+e&45i)!QShj*VsVc)J|FsuOPRZXVby z-0NK|D9ZgXtiqHrSlOtMVU{D9{{J(&-g0C^7i zD=H<5B#KXzvKKViwJ*@n+X@7x!?B#(yoas|Qyx;eL+stu1?;zZkFNHLLHWm+lj8@d zXPKhluMeTCy&tF(<_vrj&;nlEIh==)Y!X-GD`nQq8q5**5C>9Ys3qHDkLKj9l!|8` z)h4|^1crE^ynSK5t{Zvi7<482LD=IzdRy5n2-Zt9_$Nzk<8A6s7K2D}zPSqdOSu+V z2-lkBsgjSJE35rIg`qcWm26Y*tHixv$*$8}juq54mE|&7F84R)W8Hp~7iXf^Qj%0+ zR@;a+y77Faz$$ZJWm+v#=g2eOL_heO0*whw5}C&R{G-T@v6b%F3~J!#y`R$8Gx9U? zOJVe0Sq+jut~Oq7G;x=dOs8K$uK0EHra$gJSQ0r5+L>hcje`!AHo$63891P_ZzRL) zxa`8vkY>p3?+UZ-XKRNdbPqZ1H>bWcMZc>bM~B&N%?Y>aec}*FH0KPJk#m4y?uL17 z4oCKQ_S9vanl9MDEVsRpQ`^a~*x^^NbR-{ID`r+?boKbx?B4$9%I=(b*OK6!J!)qa zeT6gA5fy-XQ}gGYK6+)r`j+G9{XL}L#KeqIV>f;svR=0Ck2a@D5vE`@O#8~Te zXv7XfEFZht3?XBq>Ahr_wNJBN?EgCTwQn{j zx^a(s9fFh`R&5PNNtgN+tG{d}{CZYez;}nwpr!FViXgY>8r-3jVqI8Va9MrpaOq+C zV)@fdvwkO$C{93KZWhh`6*fkI7A#BXS$<3ZQX3@*iCvngO#_`qdSwDG@c z^%`}9sDRUX$Xh%3y4yhy-ugxjV%Ko@nu3F|cQ)s~UKK=ZipEaQCS z@%*qsufeE@zDQC^fq(!nJx}xY-Tw6X^15=?f$k`)bL4tZ6>j!);rPD+o0IWPy2HeQ z)*58RP9UMG;;m|jNQXdEKT>_`^+|RAWF!Giz|3|u3*=lr(K<8T89H+9C?7OA(7@e4 zJCQwjv~w&vT%fW>no7kAHy=8B}Mmcvqh;#n3a(pDExJ)Xv@Db_ELvgLTo)xCK-xAFgG1mJYx*84vWk1wXd zo}%xi;j22Cnct65`7m0r5z)r!N8YioPI`rnMd9SZ~MPhj}P@ah38D(wv z?H)yz@~Kk|gYU}x*%t1t#7Gb$L@~!GAS1l}#d=30K=+xIRSPCmR+P_)*y2AjJE$_l z)i^zU+edmt;#a3N$3^Dr*TltJl|Md7c+AUa`M<%!?vYJ3 zB}7-L@3Ra63OvoHi`BG5c|Zr*=F$$X+@$DL6@E6ZdQQHUo|sxx9hW4X^GVu(##?%-_sPgr5#Bqbq5*70m}p}oplQ$2jwSR%czukYA#)>@Bf zm9@5~1gVdLPwjrl3P0R}vHxui0saxK^#k(9b>E4{X8uV5Au6Zhz!ZC$+JMjzF->h2 z?S?Z3@FGNng<%rRa++%&p+?esuU9>ZLbMp8XLUNvC5D@bX#B=)(McVh+KckIm|oc}uIQeOlc5HoVJQpI(3%q&@{B-TBQKa(d=Zh2O=YXYNN9A6kAA5?R|`kvrwa6`y`7`E z8FBv{Yj7%+z=oTRP?KiN%!<;^Uke9n?DcEQiPNngM+o>pBMzcYhaM{+D~l5u#GeFZ z+eH(<`fvOr@Q=Vh0{;m7Bk+&FKLY;<{GSMLh`~# literal 0 HcmV?d00001 diff --git a/tasks/base/assets/assets_base_main_page.py b/tasks/base/assets/assets_base_main_page.py index 3a50ad9ed..00705ff87 100644 --- a/tasks/base/assets/assets_base_main_page.py +++ b/tasks/base/assets/assets_base_main_page.py @@ -23,3 +23,13 @@ ROGUE_LEAVE_FOR_NOW = ButtonWrapper( button=(729, 475, 765, 519), ), ) +ROGUE_LEAVE_FOR_NOW_OE = ButtonWrapper( + name='ROGUE_LEAVE_FOR_NOW_OE', + share=Button( + file='./assets/share/base/main_page/ROGUE_LEAVE_FOR_NOW_OE.png', + area=(730, 551, 760, 587), + search=(710, 531, 780, 607), + color=(63, 52, 40), + button=(730, 551, 760, 587), + ), +) diff --git a/tasks/base/assets/assets_base_page.py b/tasks/base/assets/assets_base_page.py index 7f8721892..5169979cc 100644 --- a/tasks/base/assets/assets_base_page.py +++ b/tasks/base/assets/assets_base_page.py @@ -297,6 +297,16 @@ MAP_EXIT = ButtonWrapper( ), ], ) +MAP_EXIT_OE = ButtonWrapper( + name='MAP_EXIT_OE', + share=Button( + file='./assets/share/base/page/MAP_EXIT_OE.png', + area=(51, 55, 68, 84), + search=(31, 35, 88, 104), + color=(141, 140, 141), + button=(51, 55, 68, 84), + ), +) MAP_GOTO_WORLD = ButtonWrapper( name='MAP_GOTO_WORLD', share=Button( diff --git a/tasks/base/ui.py b/tasks/base/ui.py index c0614c0d5..b344d5747 100644 --- a/tasks/base/ui.py +++ b/tasks/base/ui.py @@ -4,8 +4,8 @@ from module.base.timer import Timer from module.exception import GameNotRunningError, GamePageUnknownError from module.logger import logger from module.ocr.ocr import Ocr -from tasks.base.assets.assets_base_main_page import ROGUE_LEAVE_FOR_NOW -from tasks.base.assets.assets_base_page import CLOSE, MAIN_GOTO_CHARACTER, MAP_EXIT +from tasks.base.assets.assets_base_main_page import ROGUE_LEAVE_FOR_NOW, ROGUE_LEAVE_FOR_NOW_OE +from tasks.base.assets.assets_base_page import CLOSE, MAIN_GOTO_CHARACTER, MAP_EXIT, MAP_EXIT_OE from tasks.base.main_page import MainPage from tasks.base.page import Page, page_gacha, page_main from tasks.combat.assets.assets_combat_finish import COMBAT_EXIT @@ -344,7 +344,6 @@ class UI(MainPage): return appear - def is_in_map_exit(self, interval=0): self.device.stuck_record_add(MAP_EXIT) @@ -355,6 +354,9 @@ class UI(MainPage): if MAP_EXIT.match_template_luma(self.device.image): if self.image_color_count(MAP_EXIT, color=(235, 235, 235), threshold=221, count=50): appear = True + if MAP_EXIT_OE.match_template_luma(self.device.image): + if self.image_color_count(MAP_EXIT_OE, color=(235, 235, 235), threshold=221, count=50): + appear = True if appear and interval: self.interval_reset(MAP_EXIT, interval=interval) @@ -482,3 +484,6 @@ class UI(MainPage): if self.appear_then_click(ROGUE_LEAVE_FOR_NOW, interval=2): clicked = True continue + if self.appear_then_click(ROGUE_LEAVE_FOR_NOW_OE, interval=2): + clicked = True + continue