From 8efebb8e262ffae6016bdcd07afc3309555acf2b Mon Sep 17 00:00:00 2001 From: Frank DeMarco Date: Mon, 25 Dec 2017 01:41:20 -0500 Subject: [PATCH] skip --- NS.py | 413 +++++++++++++++++----- resource/Introduction_slime_bag_board.png | Bin 0 -> 22372 bytes resource/{Koolaid.png => Kool_man.png} | Bin resource/Kool_man_avatar.png | Bin 0 -> 2084 bytes resource/Skip_0.png | Bin 0 -> 1008 bytes resource/Skip_1.png | Bin 0 -> 994 bytes resource/Skip_2.png | Bin 0 -> 950 bytes 7 files changed, 318 insertions(+), 95 deletions(-) create mode 100644 resource/Introduction_slime_bag_board.png rename resource/{Koolaid.png => Kool_man.png} (100%) create mode 100644 resource/Kool_man_avatar.png create mode 100644 resource/Skip_0.png create mode 100644 resource/Skip_1.png create mode 100644 resource/Skip_2.png diff --git a/NS.py b/NS.py index f3b1ac6..6886582 100644 --- a/NS.py +++ b/NS.py @@ -8,13 +8,14 @@ from pygame.image import load from pygame.transform import rotate from pygame.time import get_ticks from pygame.font import Font +from pygame.gfxdraw import aapolygon from pygame.locals import * from lib.pgfw.pgfw.Game import Game from lib.pgfw.pgfw.GameChild import GameChild from lib.pgfw.pgfw.Sprite import Sprite, RainbowSprite from lib.pgfw.pgfw.Animation import Animation -from lib.pgfw.pgfw.extension import get_step_relative, get_delta, reflect_angle +from lib.pgfw.pgfw.extension import get_step, get_step_relative, get_delta, reflect_angle from lib.pgfw.pgfw.gfx_extension import aa_filled_polygon class SoundEffect(GameChild, Sound): @@ -43,7 +44,7 @@ class SoundEffect(GameChild, Sound): class NS(Game, Animation): - NW, NE, SE, SW = range(4) + LNW, LNE, LSE, LSW = range(4) N, E, S, W, NE, NW = range(6) FRONT_WIDTH = 230 BACK_WIDTH = 500 @@ -96,15 +97,15 @@ class NS(Game, Animation): pressed = True if event.type == KEYDOWN else False lights = self.platform.lights if event.key in (K_UP, K_o): - lights[0].pressed = pressed + lights[NS.LNW].pressed = pressed if self.game_over and not self.suppress_restart: self.reset() elif event.key in (K_RIGHT, K_p): - lights[1].pressed = pressed + lights[NS.LNE].pressed = pressed elif event.key in (K_DOWN, K_SEMICOLON): - lights[2].pressed = pressed + lights[NS.LSE].pressed = pressed elif event.key in (K_LEFT, K_l): - lights[3].pressed = pressed + lights[NS.LSW].pressed = pressed self.last_press = get_ticks() else: if self.get_delegate().compare(event, "reset-game"): @@ -140,8 +141,10 @@ class NS(Game, Animation): self.title.update() self.introduction.update() self.boss.update() - self.platform.update() + if not self.introduction.active: + self.platform.update() self.chemtrails.update() + self.boss.update_dialogue() if self.game_over: self.message.update() if not self.suppress_restart: @@ -321,32 +324,40 @@ class Introduction(Animation): TEXT = "Hey, you lizard slime bag. It's me Giant Tony. " + \ "Do you think you\ncan skate like me? Prove it!", \ "I'll even give you my board for this adventure. And ink my name\n" + \ - "on it. Now the power of Giant Tony pulses through you." + "on it. Now the power of Giant Tony pulses through you.", \ + "Before you go, show me you can scrape! Use your board to touch\n" + \ + "the glowing pads on the platform!", \ + "Great job, lizard scum! Maybe now you're ready to take on Kool\n" + \ + "Man and his friends. Don't let me down!" + SKATEBOARD_START = -30, -20 + TUTORIAL_MOVES = NS.S, NS.NE, NS.N, NS.E, NS.NW, NS.W, NS.E, NS.W def __init__(self, parent): Animation.__init__(self, parent) self.tony = load(self.get_resource("Big_Tony.png")).convert() self.skateboard = Sprite(self) self.skateboard.load_from_path(self.get_resource("Introduction_skateboard.png"), True) - self.skateboard.hide() self.slime_bag = Sprite(self) self.slime_bag.load_from_path(self.get_resource("Introduction_slime_bag.png"), True) + self.slime_bag.load_from_path(self.get_resource("Introduction_slime_bag_board.png"), True) + self.slime_bag.add_frameset([0], name="standing", switch=True) + self.slime_bag.add_frameset([1], name="board") self.slime_bag.location.center = self.get_display_surface().get_rect().center self.tony_avatar = load(self.get_resource("Introduction_tony_avatar.png")).convert() - self.advance_prompt = Sprite(self) - self.advance_prompt.load_from_path(self.get_resource("Dialogue_buttons_full.png"), True, - False, (255, 255, 255)) - self.advance_prompt.load_from_path(self.get_resource("Dialogue_buttons_half.png"), True, - False, (255, 255, 255)) - self.advance_prompt.add_frameset([0], name="full", switch=True) - self.advance_prompt.add_frameset([1], name="half") - dsr = self.get_display_surface().get_rect() - self.advance_prompt.location.bottomright = dsr.right - 3, dsr.bottom - 3 - self.register(self.start) + self.advance_prompt = AdvancePrompt(self) + self.skip_prompt = SkipPrompt(self, self.start_wipe) + self.register(self.start, self.move_board, self.take_board) def reset(self): self.deactivate() - self.cancel_first_press() + self.slime_bag.set_frameset("standing") + self.slime_bag.unhide() + self.halt() + self.skateboard.hide() + self.text_index = 0 + self.tutorial_index = 0 + self.advance_prompt.reset() + self.skip_prompt.reset() def deactivate(self): self.active = False @@ -356,7 +367,7 @@ class Introduction(Animation): self.play(self.start, delay=3000, play_once=True) def start(self): - self.cancel_first_press() + self.advance_prompt.cancel_first_press() dialogue = self.get_game().dialogue dialogue.activate() dialogue.set_avatar(self.tony_avatar) @@ -364,37 +375,152 @@ class Introduction(Animation): dialogue.show_text(self.TEXT[0]) self.text_index = 0 - def cancel_first_press(self): - self.first_pressed = False - self.first_pressed_elapsed = 0 - self.advance_prompt.set_frameset("full") + def give_board(self): + self.skateboard.location.center = self.SKATEBOARD_START + self.skateboard_step = get_step(self.skateboard.location.center, self.slime_bag.location.center, 2) + self.skateboard.unhide() + self.play(self.move_board) + def move_board(self): + self.skateboard.move(*self.skateboard_step) + if self.skateboard.location.colliderect(self.slime_bag.location.inflate(-30, -30)): + self.halt(self.move_board) + self.play(self.take_board, delay=2000, play_once=True) + + def take_board(self): + self.skateboard.hide() + self.slime_bag.set_frameset("board") + + def activate_boss(self): + self.deactivate() + self.get_game().boss.start_level() + + def start_wipe(self): + self.get_game().wipe.start(self.activate_boss) + def update(self): if self.active: Animation.update(self) dialogue = self.get_game().dialogue - if not self.first_pressed and self.get_game().platform.get_edge_pressed() == NS.N: - self.first_pressed = True - self.advance_prompt.set_frameset("half") - elif self.first_pressed and self.get_game().platform.get_edge_pressed() == NS.NW: - if dialogue.is_playing(): - dialogue.show_all() - else: - self.text_index += 1 - if self.text_index == 1: - dialogue.set_name("Tony") - dialogue.show_text(self.TEXT[self.text_index]) - self.get_game().platform.unpress() - self.cancel_first_press() - elif self.first_pressed: - self.first_pressed_elapsed += self.get_game().time_filter.get_last_frame_duration() - if self.first_pressed_elapsed > 4000: - self.cancel_first_press() + wipe = self.get_game().wipe + if not wipe.is_playing() and not self.is_playing(self.start) and not self.text_index == 2: + if self.advance_prompt.check_first_press(): + self.advance_prompt.press_first() + elif self.advance_prompt.check_second_press(): + if dialogue.is_playing(): + dialogue.show_all() + else: + if self.text_index < len(self.TEXT) - 1: + self.text_index += 1 + if self.text_index == 1: + dialogue.set_name("Tony") + self.give_board() + elif self.text_index == 2: + self.slime_bag.hide() + self.halt(self.move_board) + self.take_board() + platform = self.get_game().platform + platform.activate() + platform.set_glowing(platform.get_buttons_from_edges( + [self.TUTORIAL_MOVES[self.tutorial_index]])) + self.get_game().chemtrails.activate() + dialogue.show_text(self.TEXT[self.text_index]) + else: + self.start_wipe() + self.get_game().platform.unpress() + self.advance_prompt.cancel_first_press() + elif self.text_index == 2: + platform = self.get_game().platform + if platform.get_edge_pressed() == self.TUTORIAL_MOVES[self.tutorial_index]: + self.tutorial_index += 1 + if self.tutorial_index == len(self.TUTORIAL_MOVES): + self.text_index += 1 + self.advance_prompt.cancel_first_press() + platform.set_glowing([]) + dialogue.show_text(self.TEXT[self.text_index]) + else: + platform.set_glowing(platform.get_buttons_from_edges( + [self.TUTORIAL_MOVES[self.tutorial_index]])) self.get_display_surface().blit(self.tony, (0, 0)) self.slime_bag.update() + self.skateboard.update() + self.get_game().platform.update() self.get_game().dialogue.update() - if not self.is_playing(self.start) and not dialogue.is_playing(): + if not wipe.is_playing() and not self.is_playing(self.start) and \ + not self.text_index == 2: self.advance_prompt.update() + if not self.text_index == 2: + self.skip_prompt.update() + + +class SkipPrompt(Sprite): + + def __init__(self, parent, callback): + Sprite.__init__(self, parent) + self.callback = callback + for ii in xrange(3): + self.load_from_path(self.get_resource("Skip_%i.png" % ii), True) + self.add_frameset([ii]) + + def reset(self): + self.press_index = 0 + self.press_elapsed = 0 + self.set_frameset(1) + + def update(self): + platform = self.get_game().platform + if self.press_index == 0 and platform.get_edge_pressed() == NS.S: + self.press_index += 1 + self.set_frameset(2) + elif self.press_index == 1 and platform.get_edge_pressed() == NS.NE: + self.press_index += 1 + self.set_frameset(3) + elif self.press_index == 2 and platform.get_edge_pressed() == NS.W: + self.callback() + elif self.press_index > 0: + self.press_elapsed += self.get_game().time_filter.get_last_frame_duration() + if self.press_elapsed > 4000: + self.reset() + Sprite.update(self) + + +class AdvancePrompt(Sprite): + + def __init__(self, parent): + Sprite.__init__(self, parent) + self.load_from_path(self.get_resource("Dialogue_buttons_full.png"), True, + False, (255, 255, 255)) + self.load_from_path(self.get_resource("Dialogue_buttons_half.png"), True, + False, (255, 255, 255)) + self.add_frameset([0], name="full", switch=True) + self.add_frameset([1], name="half") + dsr = self.get_display_surface().get_rect() + self.location.bottomright = dsr.right - 3, dsr.bottom - 3 + + def reset(self): + self.cancel_first_press() + + def cancel_first_press(self): + self.first_pressed = False + self.first_pressed_elapsed = 0 + self.set_frameset("full") + + def check_first_press(self): + return not self.first_pressed and self.get_game().platform.get_edge_pressed() == NS.N + + def press_first(self): + self.first_pressed = True + self.set_frameset("half") + + def check_second_press(self): + return self.first_pressed and self.get_game().platform.get_edge_pressed() == NS.NW + + def update(self): + if self.first_pressed: + self.first_pressed_elapsed += self.get_game().time_filter.get_last_frame_duration() + if self.first_pressed_elapsed > 4000: + self.cancel_first_press() + Sprite.update(self) class Wipe(Animation): @@ -459,14 +585,17 @@ class Platform(GameChild): def __init__(self, parent): GameChild.__init__(self, parent) self.lights = [ - Light(self, "cyan", NS.NW), - Light(self, "magenta", NS.NE), - Light(self, "yellow", NS.SE), - Light(self, "white", NS.SW) + Light(self, "cyan", NS.LNW), + Light(self, "magenta", NS.LNE), + Light(self, "yellow", NS.LSE), + Light(self, "white", NS.LSW) ] def reset(self): self.deactivate() + self.reset_lights() + + def reset_lights(self): for light in self.lights: light.reset() @@ -485,19 +614,43 @@ class Platform(GameChild): def get_edge_pressed(self): pressed = self.get_pressed() - if NS.NW in pressed and NS.NE in pressed: + if NS.LNW in pressed and NS.LNE in pressed: return NS.N - elif NS.NE in pressed and NS.SW in pressed: + elif NS.LNE in pressed and NS.LSW in pressed: return NS.NE - elif NS.NE in pressed and NS.SE in pressed: + elif NS.LNE in pressed and NS.LSE in pressed: return NS.E - elif NS.NW in pressed and NS.SE in pressed: + elif NS.LNW in pressed and NS.LSE in pressed: return NS.NW - elif NS.SE in pressed and NS.SW in pressed: + elif NS.LSE in pressed and NS.LSW in pressed: return NS.S - elif NS.SW in pressed and NS.NW in pressed: + elif NS.LSW in pressed and NS.LNW in pressed: return NS.W + def get_buttons_from_edges(self, edges): + buttons = set() + for edge in edges: + if edge == NS.N: + buttons = buttons.union((NS.LNW, NS.LNE)) + elif edge == NS.NE: + buttons = buttons.union((NS.LNE, NS.LSW)) + elif edge == NS.E: + buttons = buttons.union((NS.LNE, NS.LSE)) + elif edge == NS.NW: + buttons = buttons.union((NS.LNW, NS.LSE)) + elif edge == NS.S: + buttons = buttons.union((NS.LSE, NS.LSW)) + elif edge == NS.W: + buttons = buttons.union((NS.LSW, NS.LNW)) + return list(buttons) + + def set_glowing(self, selected): + for ii, light in enumerate(self.lights): + light.glow_index = 0 + light.halt(light.glow) + if ii in selected: + light.play(light.glow) + def update(self): if self.active: for light in self.lights: @@ -507,9 +660,13 @@ class Platform(GameChild): class Light(Animation): + MAX_GLOW_INDEX = 16 + INTRODUCTION_OFFSET = 80 + def __init__(self, parent, color, position): Animation.__init__(self, parent) self.color = Color(color) + self.color.a = 225 self.position = position self.pressed = False ds = self.get_display_surface() @@ -524,45 +681,67 @@ class Light(Animation): backright = ds.get_width() / 2 + NS.BACK_WIDTH / 2, NS.FRONT + NS.LENGTH right_step = get_step_relative(frontright, backright, NS.STEP) midright = frontright[0] + right_step[0], frontright[1] + right_step[1] - if self.position == NS.NW: + if self.position == NS.LNW: self.points = frontleft, frontmid, mid, midleft - elif self.position == NS.NE: + elif self.position == NS.LNE: self.points = frontmid, frontright, midright, mid - elif self.position == NS.SE: + elif self.position == NS.LSE: self.points = mid, midright, backright, backmid - elif self.position == NS.SW: + elif self.position == NS.LSW: self.points = midleft, mid, backmid, backleft self.register(self.blink, interval=300) + self.register(self.glow) def reset(self): self.hidden = False self.halt(self.blink) + self.halt(self.glow) self.reset_timer() + self.glow_index = 0 def blink(self): self.hidden = not self.hidden + def glow(self): + self.glow_index += 1 + if self.glow_index > self.MAX_GLOW_INDEX: + self.glow_index = 0 + def update(self): Animation.update(self) - boss = self.get_game().boss - chemtrails = self.get_game().chemtrails - if boss.queue and boss.brandish_complete and not self.is_playing(self.blink) \ - and self.in_orientation(boss.queue[chemtrails.queue_index]): - self.play(self.blink) - elif self.is_playing(self.blink) and (not boss.queue or - not self.in_orientation(boss.queue[chemtrails.queue_index])): - self.reset() + if not self.get_game().introduction.active: + boss = self.get_game().boss + chemtrails = self.get_game().chemtrails + if boss.queue and boss.brandish_complete and not self.is_playing(self.blink) \ + and self.in_orientation(boss.queue[chemtrails.queue_index]): + self.play(self.blink) + elif self.is_playing(self.blink) and (not boss.queue or + not self.in_orientation(boss.queue[chemtrails.queue_index])): + self.reset() + points = self.points + else: + points = [] + for point in self.points: + points.append((point[0], point[1] - self.INTRODUCTION_OFFSET)) if not self.hidden: - aa_filled_polygon(self.get_display_surface(), self.points, self.color) + ds = self.get_display_surface() + aa_filled_polygon(ds, points, self.color) + for ii in reversed(xrange(self.glow_index)): + shifted = [] + for point in points: + shifted.append((point[0], point[1] - 1 * (ii + 1))) + alpha = (1 - float(ii + 1) / (self.MAX_GLOW_INDEX + 1)) * 255 + color = Color(self.color.r, self.color.g, self.color.b, int(alpha)) + aapolygon(ds, shifted, color) def in_orientation(self, orientation): - if self.position == NS.NW: + if self.position == NS.LNW: return orientation in (NS.N, NS.NW, NS.W) - elif self.position == NS.NE: + elif self.position == NS.LNE: return orientation in (NS.N, NS.NE, NS.E) - elif self.position == NS.SE: + elif self.position == NS.LSE: return orientation in (NS.NW, NS.E, NS.S) - elif self.position == NS.SW: + elif self.position == NS.LSW: return orientation in (NS.S, NS.NE, NS.W) @@ -594,21 +773,22 @@ class Chemtrails(GameChild): def update(self): if self.active: self.orient() - if self.get_game().boss.queue: - self.timer_remaining -= self.get_game().time_filter.get_last_frame_duration() - self.attack() - if self.timer_remaining < 0: - self.life.decrease() - if not self.get_game().game_over: - self.timer_remaining = self.TIME_LIMIT - self.get_game().boss.combo() - font = Font(self.get_resource("rounded-mplus-1m-bold.ttf"), 24) - text = font.render("%.2f" % max(0, self.timer_remaining / 1000.0), True, Color("white")) - rect = text.get_rect() - ds = self.get_display_surface() - rect.topright = ds.get_rect().topright - ds.blit(text, rect) - self.life.update() + if not self.get_game().introduction.active: + if self.get_game().boss.queue: + self.timer_remaining -= self.get_game().time_filter.get_last_frame_duration() + self.attack() + if self.timer_remaining < 0: + self.life.decrease() + if not self.get_game().game_over: + self.timer_remaining = self.TIME_LIMIT + self.get_game().boss.combo() + font = Font(self.get_resource("rounded-mplus-1m-bold.ttf"), 24) + text = font.render("%.2f" % max(0, self.timer_remaining / 1000.0), True, Color("white")) + rect = text.get_rect() + ds = self.get_display_surface() + rect.topright = ds.get_rect().topright + ds.blit(text, rect) + self.life.update() def attack(self): boss = self.get_game().boss @@ -620,43 +800,49 @@ class Chemtrails(GameChild): if self.queue_index == len(queue): self.timer_remaining = self.TIME_LIMIT self.get_game().boss.combo() - self.get_game().platform.reset() + self.get_game().platform.reset_lights() def orient(self): ds = self.get_display_surface() edge = self.get_game().platform.get_edge_pressed() + dy = -Light.INTRODUCTION_OFFSET if self.get_game().introduction.active else 0 if edge == NS.N: rect = self.image.get_rect() - rect.center = ds.get_width() / 2, NS.FRONT - 30 + rect.center = ds.get_width() / 2, NS.FRONT - 30 + dy ds.blit(self.image, rect.topleft) self.orientation = NS.N elif edge == NS.E: image = rotate(self.image, 270) rect = image.get_rect() - rect.center = ds.get_width() / 2 + NS.FRONT_WIDTH / 2, NS.FRONT + NS.LENGTH * NS.STEP + 10 + rect.center = ds.get_width() / 2 + NS.FRONT_WIDTH / 2, \ + NS.FRONT + NS.LENGTH * NS.STEP + 10 + dy ds.blit(image, rect.topleft) self.orientation = NS.E elif edge == NS.S: rect = self.image.get_rect() - rect.center = ds.get_width() / 2, NS.FRONT + NS.LENGTH - NS.LENGTH * NS.STEP - 20 + rect.center = ds.get_width() / 2, \ + NS.FRONT + NS.LENGTH - NS.LENGTH * NS.STEP - 20 + dy ds.blit(self.image, rect.topleft) self.orientation = NS.S elif edge == NS.W: image = rotate(self.image, 270) rect = image.get_rect() - rect.center = ds.get_width() / 2 - NS.FRONT_WIDTH / 2 + 70, NS.FRONT + NS.LENGTH * NS.STEP + 10 + rect.center = ds.get_width() / 2 - NS.FRONT_WIDTH / 2 + 70, \ + NS.FRONT + NS.LENGTH * NS.STEP + 10 + dy ds.blit(image, rect.topleft) self.orientation = NS.W elif edge == NS.NW: image = rotate(self.image, 315) rect = image.get_rect() - rect.center = ds.get_width() / 2 + 45, NS.FRONT + NS.LENGTH * NS.STEP - 40 + rect.center = ds.get_width() / 2 + 45, \ + NS.FRONT + NS.LENGTH * NS.STEP - 40 + dy ds.blit(image, rect.topleft) self.orientation = NS.NW elif edge == NS.NE: image = rotate(self.image, 45) rect = image.get_rect() - rect.center = ds.get_width() / 2 - 30, NS.FRONT + NS.LENGTH * NS.STEP - 50 + rect.center = ds.get_width() / 2 - 30, \ + NS.FRONT + NS.LENGTH * NS.STEP - 50 + dy ds.blit(image, rect.topleft) self.orientation = NS.NE else: @@ -695,15 +881,33 @@ class Life(GameChild): class Boss(RainbowSprite): def __init__(self, parent): - RainbowSprite.__init__(self, parent, load("resource/Koolaid.png").convert_alpha(), 30) + RainbowSprite.__init__(self, parent, load("resource/Kool_man.png").convert_alpha(), 30) self.health = Health(self) self.sword = Sword(self) - self.register(self.brandish, self.cancel_flash) + self.register(self.brandish, self.cancel_flash, self.show_dialogue) self.add_frameset([0], name="normal") + self.kool_man_avatar = load(self.get_resource("resource/Kool_man_avatar.png")).convert() + self.advance_prompt = AdvancePrompt(self) def cancel_flash(self): self.set_frameset("normal") + def start_level(self): + self.activate() + dialogue = self.get_game().dialogue + dialogue.deactivate() + dialogue.set_avatar(self.kool_man_avatar) + dialogue.set_name("Kool Man") + self.play(self.show_dialogue, delay=3000, play_once=True) + self.get_game().platform.activate() + self.get_game().chemtrails.activate() + + def show_dialogue(self): + dialogue = self.get_game().dialogue + dialogue.activate() + dialogue.show_text("You'll never be able to block my sword, you lizard slime!" + + " See if you\ncan keep up with these moves!") + def reset(self): self.deactivate() self.unhide() @@ -712,7 +916,8 @@ class Boss(RainbowSprite): self.health.reset() self.halt(self.brandish) self.sword.reset() - self.combo() + self.advance_prompt.reset() + # self.combo() self.queue = None self.brandish_complete = True @@ -750,11 +955,29 @@ class Boss(RainbowSprite): def update(self): if self.active: + self.get_display_surface().fill((0, 0, 0)) + dialogue = self.get_game().dialogue + if dialogue.active: + if self.advance_prompt.check_first_press(): + self.advance_prompt.press_first() + elif self.advance_prompt.check_second_press(): + if dialogue.is_playing(): + dialogue.show_all() + else: + self.get_game().dialogue.deactivate() + self.combo() RainbowSprite.update(self) # self.get_display_surface().blit(self.image, (0, 0)) self.sword.update() self.health.update() + def update_dialogue(self): + if self.active: + dialogue = self.get_game().dialogue + if dialogue.active: + self.get_game().dialogue.update() + self.advance_prompt.update() + class Sword(Sprite): diff --git a/resource/Introduction_slime_bag_board.png b/resource/Introduction_slime_bag_board.png new file mode 100644 index 0000000000000000000000000000000000000000..f084956a74fc21e4d19ab5364b683f5bc514e164 GIT binary patch literal 22372 zcmV)MK)An&P)6PCgz3stbTc2`qli_q%tm$vc1@_}`xjz$h0e zNJQW&4r7pr?`Irn2O8z?5nv7QVfjD*032Jy3{`<$u`J7z`RP}(k z>~HD?1Q5pulo&AW`bfsaanC_=<&YHE$0I#q0KYFb4@L(|2IqRe<7 zX4})0^a5y2q#`REXU3W-mn&1YZ6Ac=hoCwDyeN;M<~t7C_c#(@mM}(9E+mGz5Shhe zhFainel|$}S)c>B10lN6v`d5dd~+V-2(l-9;pqm%a3CM+w)$jC`DnJr|qIi*;f zVE_Ifvu)e;WV4rm5bPQHXI6Gxq$XP~N+`Ojzl^xYHI3kGR&t$D!rX|X8tp#F+u*| zcj)N3Qm*N9(ggwAoNv7VpcnXEh-?(1BiY{mLDAK96?X<7>FHgPVIn>dhv_o45Hotg*#8TSRf76R4A=sE03w$Oak19key8Z` zy8}&ANvTP?6Wg%$BDy|EBC!ofqU)nrmO1Z3EXzdK3-a#*OSjMm9wAALo}Lc@HbX=A z($)1owA?z>9qZKQ?c3Lj=Jc-sR|6>-amD043N*-zQpkH`iTci)U^&Ok5|LWT??U7q za8V+ax&aR;Pe1(?1S-Oav1ec}An5J=dB9*`;7jOwVIKSIdSUkOLS)bqH-hd^(GA+# zuBNy5cTv?C$z&Fxs%WZ8Z_AAhsZ@I>4Gq5}kEKzD>VBYjUu9z%Y)Jv|@;Xr%-hjZQD&TRa?;ktOJ_larxP0Da^9$ffKnv08-CiX$5{g zlFGDcJ=+zL$^l(imMU2TG%bg!nlflXt{0#R&@>RzZA&JhYZD|AfP$(DG%W)p&~+C; zprGpohKBB;>(Vt7uvZ!;@OS^Av7%=o4R1BYKN&%aJX8|1{q9hVo z3{%HSc4BimhQ1dKm6qnUF;$JX1DcOnq9J}umgw$c4x*kqd}T!b0Wy9215D=1m9p z94oeA%%WghpqCLAWYEYUBq$Wz=Yr*L2B`PNg(@dwWPGljypRCEsIC zkFmjufqoR#b*5ESZA{DX*$w#BkKo8I?{h7N+rPfA3iTOa{0i_|tZ@Hi%qsRpYlCWA8WiE2* zkqda{=i82{=xbA0arLy)5t6YpzfQx@ur+Nl?{Ue@2K{REl#+AG`QjM!irY zBXt=ABBSsZ38G#EFMME;L=NPXK?7N4B9`y*l3V?&Op~kNhDU{IJO4P^|*jSHu{KEB*v1Hk^&m+!1h=@EXANxo5%Oa{ zhD0arncES(K(RQCUKu0VwhAExs$r6A+eTN{9rXAAIU^%Kwrtxx4vYhN;CsMJz!Yx5 zR7L(YC3r06D((DrFZe+8CbOJ@8H(Z-G`$tr0bC;Wj8^H%0!M-UK!rpiNmo}FFTC(F zwyj|pDvF{2NrboxO_L&P0_=@C#tR2&>wX_y>NO1ZAHX(_bJbP1p{nb#_Ej-D+St~% z9V$2Q@W4Z~X$kszu0xZ$jSz0msITwifTEVmhga8X)fKv4SY=seUQ(4;^P+~ZOC-Q5 z%Z^>t3jieE;|5?oaHV9HHu<;6Ttt(hyZcT6UVeEexm-J)omW#Tbul#b4Z6BMfTnH2 zvP{V=9jLJcMf*5|;~HCI*O1L-5nF!*LqlXT?7uT1CgTK#%5B@%eF^&*XhKF||GFimi-w~murHT3_3l~g8 z6j{cs;y=bXZawXK*AywyR4S+R^xQ=%l>@bbRQo2ncYFf7`>ohbjdXW^1Wj9mt`~Ut z;mS`-y1w${h-!yr# z@Era9U!Ytr%xW*TUB$Mm?)zioXqtjh)sPT6EMF7}tcmg_SkBxGwE}k%iL|0=5mbQ? zF*2FAkWP1^X0nLBcc87?;$F?M##uGiwrz@~LrhHEN2zoO%d!AxPFV8*gAJ5rws{Sx z(Rp=rD9-FrC8ZsVStj~afmlqVtLwcak}K!?q?Qfk$q3d=JS2P;ESx8LQx%3Dng`5Y44;`F&G@&H7l%DD&q_d-9yEgn0=*f z+35NdmSwxu-?oV%>s}PVwk@V~9c-Jl5Tr91)N~rtHpmwSshaw%Nla+17?p8q15a3# z%ahFQDH4k?%CZ&Z#4-g-P^oo*D2c>2)~?mib!PM`2J2X}W&?*tA4eJ0S>Jvg$DLyo zpLvAh=<}pfml26TG#cf|kpWCIL0j8uPMtc!=;&TLJ8vZ3m|^nN7%vr{M1SsCCdVSg z;||56dufj*89DF`6sN}F!@JP+GDnZv%*-5N-MTACt;tYqo1rz{L0rjl{P=TZvzriN z6*RT+Om)9=;`txxwUd+mz=#a>t-#&CZN%a9EwIbRBq_@fEdEM3kE)}F$r(prvGN@IGuNGzVhoYslQH4I~1=7y4}szoxHrED1J))Yxv zaqLT}7>~Inm*NI&5|r)3mOb@@SD2ajSKw8tvlzfhd9O$Sosv;f)d!$j066DeZ&}U? zZV)`v*p^P&wy`#<7<(uW-pioaiD4Tk20Xm;hu~OLrj8(lN+vTzEC!&XX&rQTUqz`@ z;{N*|AYrTQaJtEoMMvjRrYR&XdU`IUt7{XnSZu)qEEY@LfB*fI4vk?@B%7#Ev5FLn zV-gn)Gf(=G?;uk+jXJ;phq9BBzS~dCVSHDV3jj}1XiC^pcH9E8oY;4}8zl+Zge4erV5$?F- zz2tJP9~6tl$mMdUf#>Maqv(2>sgllR+GX6)^*+8l_$6K`zJfz(MoRqyQo%jN*>`eS zHsaicqTqtNiR<5}RXflN>wy(+WZ@vG`y@C`{_hlvMd|E(3-Ndy(=>VFi6_`QxR*`Z zCO&c9C)k?XN?eTtpk*{Z%!m1thyR2>{nJ041xGHI(%De^V^n3$>~WZDicgp zCOC5H2u~SL@%X{V$&ckZe*8Gcj~{1rbd=%YVLCfIX=`i4wrzIr-p!{!{b>&GKg^9S zH!_|X=Nr%d3&+%9%u^OM8w)s&+nHfnf_X;XtG;~DOo)#X%ndoqZGo0sBoy%h#S^rm zxOE8E0DlmPvTYS$ew@MWxqkyWRzPh6jPtn!$cu-$Mt9*@tO5Ysf77@OdV>=pd# z)?ek`gZENU3vP++7$nUkZC0DpulL(UyD0p}6pzQb_S$Rt^rt^frBdPZpZz=s_a0=! z$_?DH^$z}F|36TO9bnr>XBfH%@`KduD#w6FCA;VnJX4ZsPD($&#%cq{PR2sWp;620-$u;Ma!@i8LJCtIT**z*3!3A>0$r_?9{dJ-)Ip}-bCgrRG(jal!Q`o9j2s`eO{!CCQfnF-8XF>2t4gg_ z!?rC>o-`;*Rtk+zmk%AnCPX`@Cf z?q>aI=6bwTLqg}pIxW1Zv($+Of@Y`@=m!29g13r`iMPEUW$VqLYH+9om3^vmv9X>H zUhzTNs%@N7PjON5B5q6E#*S6*;=^zMZMrkv95{G@AIBb{`2#vP{;I=OS3%d?p}nWZ z(L<(^Jh{5zL)ZMKSktveDd{D|NkO8PL^V~8A3jd)1QAm+uaL8+Fqd z*ZonA)t7^ogUl76r-+DCB;rk^s}U}8OggEdNp_hGn4ln7!b0ZrzSUJ(rY1=7F-j9| z3EankE7euRb00>z;n$%3V)r!W_rtC~RLMNIl|SzLB-!Xnl1)v-M3k5vXX4~Ird{Qs zy$^A(_y*G-7~!f9T5P-+VnUYb7NK|m_WXH_WMLy)ueyq)kwo1u&}yyXN9g&aMdljN;_d<47U(6githUkJOsu2sOdvgY?DL4w*fB;ZAjMf z*SE~n(Ob@|DH6+!Rf0Z?id(nxCqTCvBc8h&<%W+!`$l)aSR?|?8E9Tt}=lJ?d|H8AYcj4SI#^(1}jK-lg=_YDM55b-v!KzkRbG6Oz zvnM#bx5%m!t*qFzlI{&}V?)PA+S_v^o0`a<%=1tG@%I>=2kH4E3oe15Ou?!~Xq3m) zn1tjCNVUPb&Cq^1%H(09QwAAnp2npgQw;$`J#d^?c2SlYtN4M^Aj9MBz$Z}2WwxT+ z@)xk~I`Hk-z_ua(D(w0ul)j@deK1B_EJsYluvHUXE0E|g>G_yLdJEX6;OT#ZZFjh4 z?6L2_!M}snx4@474#rXF|CB&~T0>-FXww?1E%ytk3RcR5b$NR3Hc58EgI@>zX}Ix2 zknIGm9n|RjFKU~RAA-le4f(G!V~_I!ZZEs%B*UDl5?X;4p4sc014@(vZFd((6F=njU0f?uSjBI#MHF(^ zK;PZ&A`CnPr3YN**?S*|QP5hU*DZr_zp>_mA(;fzgk%EJ>jOSUaG$)C#`GfeKLleB zLE9R*;coZy)fi+tL9BxP`(bMzXsM9*EP-9Z!NS08k7{yyiDfY1XfKBxk-Cgn#RHA! z*v7rT3DrIEer7NxVCXxbW})vBu|S@l4FPR8!40=Tu4~TO7IA3b;vPdX2|~;P#0#VQ zAHXR;z%*q>B!gOn7eYl?W;MC$GGLQn*gPYn1It@Dd)hTM>9@H4glC4fei+0Mq_@od zJ-y0hpiC!NrfV7ocDX+pl;Zjx(D%TuuY#e&A-S-j%mRqC%Sx&MaSi0wLEp{pPqiUn zWmFd^dJ(LW)LC|dz7xlu#L`QY?c?OJcvvP!ojOTH-UQ3ifKS()q{aAuoPDiTCr0#T?FCJIQmfSq);<7=*iwoWh|NUj3a zgwjjluhn%IAms<4Hi@lIQnpS|WrhhCsvMS4&r_ zrhFX7D&jDM4tRZXPf6B1>C;ubN;!Yk+^Hq#EpNEivRuIu2etyA2dLW5CX}5-;VGbqGn@0728zs; zDtI6;17JDj1CU>wvz7~3mTU2o4HSTXlOSpX1Qv=tjwp@OBu{Kaig+{fr!{A2;Ka)` zo_HB0+KB0Z?Km{9=p?fJi>_%}(xqa9GDXck$%Jk&go9z~)Fc?ZzWv@JS~yHHHxGypAPYxxK@N1cn}>QkkuKEoRdMk-$QFi(Aik@Ju9}{xQlTre`sroEL#kU52dUA0Zc{@fn}esRX`9 zjqvtc-oB#-ATk?<<0caZB+5b^WZ=?aH*%8iO#V#ac2Sl2O$aKtjZ2 zM3iv5Y>QZocsx$ASVYq_CMG5@O%nkmO)&Cco7g^vi19jO_9&%TdLLSyakHkHjs;j zu+nx=x`2Oz#-Jo)!ioZ{G+m$UTexk!Z69+6%Pf@uyTBVfuV^{xEJ}b`61aWvHOVYF z;Dd2!%R#IHi5YhwmFn3DFHh*jw5s%sP2Xqcayjn4`)+!AdPpP^XqrYWz${~9V;nzz zTy|V=d({mM4e^(M`IqGL`PoTWY1}>_cgceb`a2nkP~S1k-U_aWDv-vp)LdasKAO1?(^)N#wtG~g@1 z0jY{vz{JD^_uhLiot>R@babF73bk5|N~J<97Nb(BFf}#B-o1NgJ1*$D&ZCb$N^yLA zcJSiOE_0Br!z}(U*BSC$r~4Y^Q_wUBmzZuj#zY-`#R+k)-*9$OmH}A&{)#tJw@<)t zWMESVB>F&U2i^usRw{JUfl#C#vmC_j{h^7N96ZBu+aCT9a0Z{zrXC3f6 zF}QIPth*f=ZuVWd+F2})B|%b>KX-f4kD_1*!E>61;maM^whiSn+bjz$;DcN%L6SL# zlsp9dGT1|IH_I-GBQjmGx*YC!1!l4;jL3(J&+kvm=g>5ENkX;8Z~hDSNzwTBJzegx#}APkcC_YAt2uDZrXcY zSiuXOt@%zRu_XXyH}Dw=7|RzKeN*Z!w;_AthP=KgL3V>=kVQ_AZ|38IeR3BXH{%4( zxpN^i%V|IXVp&k$#axo-T(iP`Qk3(UAqU)z+nOP^2v9yHeTwP8^Aor&sQQ6V)OoLx z6a-fQy^A~T$^uLh)_pq|EI12XsLq83maxz{3anfK4L5~^wXX#v1>AJ*7nm>iBmWL= zGNxX2rOe%g0>u;i#(^g!pzfCM)$Rk0B}KQtSmd+hYI>4TbP>~2Z=jX4063KSAGJKe zqAcRG2;8kVipFc-rSF-X0}>>|xUC|Ci#;u$8!U6N7|(zBe4PcfB~bnd_&a%NPA_r>Z0W<;OZ<|utc48{ zu*7RNTHjoS@GY+kZG%RRLI4vq zIZK@f>x<3=?(PLO4V3Wb7_W@vv|H;Ra`sK*5w(Z5Usg z(nq;Zg2oAeBqJBLOM*?83v)Z}mdDHjEV4EMJomkw2tvUcyQBSk3Z1 zeg!xMNyp6({RFp#SeOa&x?-gyux4;eG^aVe;M-rb>jXmUS{*Y~SEo^5BXy=ttN;KY z07*naR7jLX{E~XUN(8qOZhZurwb!899tHj$H>nb2lnn48;1{JZ_9OW}ODQ#Im(Hp! z0TB1GL=2XDgB>LA0w&0liMr-_lGfP&cV?b81pyfmnG?qOH<X3vW-}Fll#wdXslP3;B}x2>z1GbtD+lNyY5c5U9*E#fU^6C)TX95 z3j7Bu?-N-rNhVlp=tS)ztFigd!2g!l$s}`)1nhu&SM&W`5HRW)sILCm%D2l%^(XRt zHjp4Cn(0h5aZx2o%09x^DbEf%utFSMfXPEJ`sc7>0^-x)D1wMcL$aM(^m>$;X*l_> zDCvo_^T4HG<{Sj2C>Ob&a=R3z_VY`S?w6!U`OVARBH{BTz}+0Tk_7Ke<=E2QM>`IY z{%=D5n^f%yK;^c`#iVn;Omg!zL2Ws&poQEDpD92H7&U}HU+`T#WBnU^c*I&vc%+@nZF_`i)JuV&G z*OH!a92{wG4BvvOK0iVQE<>&iQM~8uKOU0 zUBe-UiJ%}Y`xf9bnaiBQEef9wXo+FF1Dr5+i7X=6DL%hY?#AFod0}2D^JgCcE*7t1 zsV{LNlSaMvauV9jbdcuVz<h`C%fhs zXzsZT#Xg2J`2ff55x$GX01>R_bwu8FD>%(KgWqLF{~-sN;@dza5+l*Pj+LU7EkxNM z&wto3@-WeEK?OIg+qJi-o~PXgI3kLY?j)A(WUboB1|iTIqnxVhy!_$|oQlOzvbP{I zTWC=mSu3v`&o+DY8jd_Uui|dsd>p6<6GwdsUV4VesZ%Hs1w~QLz7t=fNb(F{8&*3bGNA21QCFe(e7|4|j~H3jx7<$iwZ8~X8EfD^s^t+1RC$&L#ziM~ z=G{0V2fN3p6@I|D^&-z=5>w-BX}^Z#+y9(M`d3JD5m|ZoexUg4W)_`TA6evT^x9lZ z%Jj>>6XCDYos8}H61?kgh-9uNVaG{ETQIlW&Qo2Rc_lH$^o{Fb`yU}%E+6cx;e3L$Fw&=n%2bfRw_r&PpI>#F;RQ12IPqop;=BnyC~Bb@qz( zYaw2fqIOQOqV_0iu@ff0OT>PK87z!w2b=XiS^#Vrc1kdcjtCCtAg5$ z!83=3cyjQEOo?V9sqL&(SI~<)yrET|Z`J4hD}au}psu423_@AwoZN&@s*mGtp1*q$ zc8Ez;wpCs&Z8D#9xAgMQ;mzM2${(3bOUa>{%)-_?p=}$eZA8^h*0kJ0Cb9;x`v^+m zdnooW%{X+64svZDLf!f?cbj(q=cyHTam+f(6I3bH$yP6U$AG#(hBzY4#=)l5T(R}H zXc?J6JNgZTHO4d61QYqMGt;lo(Dy!?dj60rj~|7K%J+>jqn5#oCm*J}>2|cfTZ!8J ztS*$f+&abM(g&IjB)%-5XxYr@x;qVw5H(ag!_~-0QOJ9byCq;^i})Fzk@+TFzV7;f z^6RgM5sUahbs4WlT{CDA&EqJr4Z=utop{l@8LW zJ5esb35Fhl(s!Xe#7TRaz0B2ui8@(q7Go8tzt7zJ=PBUH$^_dB50kp;w}|ZD&)Pzn z+pP)@+pm(#e~n891nPCaOw&t8**rQ;IerySx29P=`65wc6mr|3?+;KP$kTM`TQ2iE_R)|6kTSVM`Va`{Swm% zfm;-3mT7}#pbR`ZHO87fUn9HYb8ySANziLhEP+fZ&ZI;kIHi5an&u_r7_DvViKqU6=mWn)?!=44u-Ijf&{+Hq?bU6FOWQ~t zK1{ED5uNGFXgsoqm4p94WV_^UMVWQ5qJdP99V!dK?EX&uIT*~l8{5-oXoj+cZ^iIe z;1OUQm4yq)EeVvbG1r6j6ZKfj0owuHfwTi+t_zJq0}afC*3~uutDGcJx6 z3lYHz9Nr0xVDYg29OXS<24Nsljif7&a>-Brj`m80nA3$)F2cZshiA%%Fb2MiV@!aSqd~-3BUSH1_B0d4VQkxkYk!AG`&Jr~EvW5V zQTlF^Q!)xz*7WQkY=!VWyh|570=KFR*Irp5dmWZl9%QZu`peSVEv2V&nYjWcN4|cr z9^f3X3ZQ=p?7|%7IT{KgwDhqFh0UpUR`q=hk?V4oH$MpXf5g4#cY{@d^7GLDS;+6A zW=}AQ#ZM$qj{4MKf2*;u@xb+FFwXlHOVPM$K-rpRv@}f4Hi>nA1d6ZFQhJ%|f$su) z^*pQg{4MDnUxZu#7g$xdKYnvNl!if3nMC17IOxpnyz|HS5&XMBozv}Qm?&43iKk&% zSi};YSTCz=`Yt0+U+E;gwO5c?f(75E1l)`ASTla7cUpeH^gPm!;8w=@qe6H8kVCJc zqG>tz|MO46V}FKK7@+Jx)S4!_^-d!Dza}Tto1BoTgQtDv4qk(1uPy9M2w;}n{(Y%} z=n>$b^gJDdU#5NQohYew2wkVcE^-SNKe0`0z2G{g^QMB$uk!S_8}-*zIFgXB7ZFlg zGm20bkB0m{hqp(_`?$YZ!h)YAiOs8_4chEH@Tb7910M+bS5Am?=*(jlZ=mQ_5o1*< z=VGm}8y@>KGlfB3v8MSk(3XFaD@(7Em^y}2GntYJ-TgAp=>f$*RARBFhKo*jRTuD8 z{4cBmhb)uBhX+}0S;RVi1B%@===ZXo5msQK;RKTJJ}=X0q6NWrEG*`>4tp`bCl)oN zQYgLG%pVcs6^u6fY?ZhD<1@0>#DBr&eZQYcE-83fDRqD{A|s&^;RWO`FClmns{0*F zDp+$qTLaKWoVRIjL+k#SJG6mIR15n#Rv0UW+kr z(nzq!uDyW&!kIFQ|HY%gS868lBQJ8fK1_poJ!pccaSyAMDHN?^wy0>i^5S#? z3-32M{!uli4=@Y0ORZbFpc1}oEx4=AtLSbXM;4PTrL;fb2#STqR#p$QJ@vUdTj-b-ECmM2$SEZVikD`hbQFQ z)_kI!e_?}Q@tYm9jwxDbcEFODC2a4B2bc=*5*Gi#2r1`2(#b1{^z=Y#4N7K}`>}=H zuGNt`ogT*Vp!k-#TY(#0v0;Kyw7EHr!Z*dml*n&Xw zw#I%(0(4{vA-oj=7>`-zjj(ZM8$u_EbB)+UHgyXT;~4D!0**e!Br`lIomMNbPPGuA z1evAE!foCcb8hR_;QCpn7LpOQr3twg8>WVM+an*NC3_k1o4!cQu~7=U;jvG_*wZlb zn0poV$#J&nEs*&|gnp8&J;Elcj4@Z7ES3Tm9k+NoUuVHg=E~aJ<>gwBMLK<7IwjKr zTLM7y_h{MA{B8{1wv#k-)3i)qq0W$7OH)@H6)|XDL$df1*IO30*hF*t=TNuiVE?yp z@&~Bc(~RI1hRrt@VS_M&VDW=yhWhgW7G;&i99+eBV4mvjjd6Ps_=aVYKk*WqBMq#Z ze3dojS84q5pQGdlnX;!b%`$2^Pm67$-tb8`8P@lHs5z*Ge`MuMezxh+L`VV7lCM}l zknRB%EBaXGxu` z;-qdv>DlC-UHt(}yT}j@kND*JS_nA&rpI0&T=qX-BYb!SONoZU{FdO|_C+wKa4X!V za2P6&@V1?Qz@?T+NBIy9_B8$S`IK#PTYiu=k9~^B4WESUR@ibG@e?Xn&bXr9xC|}; z;djH9sc^Emo*6q%u4ifaj9bQ1;ws}3l_D)556 zb(aK`g?ttz;H%g^Ex;S0V#;$}s~T9x_A?HYa9AbJ@rZOI_S+`$!-K4N>{CRx-U<8v zg-GQH8g6ys3cQ&;5prcvAKVRU#Z}qtgRn9WzvsBU*DCUg&iZVZ7GefGMfD>Akagg0 z=jf0Jf3HMpc>&GEspAOyJ1R6t7W*6dnpgm&-ie(&f%C*e?rkj<1Nj7m2b421Lxea|{t<2wd2rLS^ypBLzvtw6_EPQ# zfm+Svn!|&vD2@;@ZO}SE2qKn6LNBqwE<+@Ts@;sD#$1DM7hQ+2)yFIixZMxDsK^`e z;5P%NPc$74e3=R0|CNhek_o^=b^ITvj<4g@#H^Qok>U&6>+N6ih^013W%51}rRxyd zweDc^S?Bi&nED>3eS#Npc!s$FSk(|8Bur!rMmUSf`t^XasLm4BX3DGD3NlQvJ(Yhv z-3z|*gR1lkM3KF?~W7LxpKM%3>n1MSgOKbpu}@nO^6H z(00|8^ZP%Gqd$j^#h}#orUMtL6%rE9aQaAJdjS@4Sa`hNl0)Y(!1xi!0=iYr2bc!m z-IRa(9<_wWcrD}3Y}SDzMKELG2OTUQ@XWv`LjV)> zYl>%~!3b%(ehGKKQRCSqyQ{!x%_LiVnM7$AC7Fe>XWR%fKS0$s8IuHfDiGb&3yHno z>zSN|M$s%8DAXzLQkL*IEZOMPNrih~!T?U-aMYRNBKml0-%~@z{f=Fb} zX{a86!hN8X+?{P%7VossD$T>NEFG{pH@B6*Zvc1VmRX)j7bIC_!Gxz%fv8qUmk*&v zRCw~QAwS5BZ89Q*Ij`S}-!Cyk#I>0^itJ+g$r*uUA+RigO+!nSf@k~__7s*+p|*=g%s8 zMNa;4D9-~E_9@0EU*>kbz(ps9Nj1a}wuw{DQ?*ShEUoj_X}7p9lpSW_o^)X#@!E^s zES23&oYP4qb9K(XqC#;?hN zJy)WfQpc%{__UW`KFNE|zp-f{!DvS2Kw`}8^p6J2-dW$`GUUzS_6u2vSbSv_H{sqN4u`Qy&;*5vZwnP&pEICv2Ir(+&5OT1rXBd3zX&<#&(xEjgHcrVTz^?_ zUgFt$^RI>Bn5%}Pj?h-mcd0HhWBj^KVm*@!Xrb2LVg8L0Vw%E$;e=#Cy}S8(eChKw z`8;smgUal=tU-C*4w}~hn0lGYu#|v5br2Rs)k6M04b)6uj%O(g?a{s$wq^s5V=TQm zd#Pq7E8oA~`}ww*c!!r?05A)QZA+;^SvJF|oI2|kY*^=Km>Q>NvTJn!;_p#X1)Ku# z`z*csEeG5sAKxoA8vkQ2)9JOvW8bZvHQb)+EXM1N5!ZDLch7H4=BA94Km?~Oweo;5L1H5%zcgMptH-oA& zf!mrC+h#)7dCani34y6;6jXIy@l(>aF?1aTXqK;^lC$fYWdq$QPER}z+iN8-bOPmFb42x4#wR zvArlZH1}*Lb0kCW=K0%20E)#TJ9q9x2a4Obqh>Nhk(p&($LQ}zFBA}(hPHh>&6y0% zzL5FSVv)g}I|0}(Uq7G&L(tm=R>ESZuA>9Znuh9|G;d0f_(SocuCueh9}*@#@6R#R znIZp`?>qKH$zDM43`?EVmLRw-JD=sXuuU*}s<-XHW1tN1{+5)I-L_p*_726MnqYfJ zmh8q%D6_bXFVKMPnGBiiT-;O4WY`H5@4p{Sh|``Ia=~M<7>PuJY&MIQ$&itiR?SH$ zm5apo?IV{=(%09ArfH$-?`-eeOolX|zc7fVR_J+W0{vdqE>3VVa4wWZQYcP{Z1IK- z|MqUL*Qnllq1-}Ojo)TFK$D1x)^vx~kjbiujE3mxC6m_3XyHKdmP(+`R?~U+j1UM- zLyg5qYZ_T0<~^Un&E6$7jo#i~G);30vIV5Q&$De3)hb&rx`inF&tDH9OoNtn%|dNdy@?(w3pf4?1IHWY(7sV%S1c`f{(di7 zPIHS~H2Jgc&GQ}Wcb-cm5_ENSkxb4nr7q*{CO1^o1xlUIsTc-B&pwM`7>j=K*(Twp zgFgxJpE>xCi#4x>FN0;*!A`=2XB^Tq3b%fZJ*J%x2J9Nf{tZcIF2K5 zYmZkle}JaSnGgGZ!_3heIepbxz?boZCW70^`<*qr)}j}5_WbQ0C{*aZs(zcWa@l5J zpoFg5q|+e{#bjB1Tvb`Sb}jLEJoI_nG|_dPbUHncUA(G%7bAA)|4=7vM$^!b7Wlzk z4}#*rmL%q zL}I?*lT1Qam-{moi__lTPAs;#OqfK_g+{_PixDEkX(mEsHfI^^fK{*U=u&4={?vd) zN?e?j>SS=ctS&XKW}v|~T{|BWF*a`8h;7?gmKDM(Ho9(O+m|9lBGeB~rUYHR8d^Go zru8C3(4d*XVT7BjEzyWtWZD421>R~AzxyDf02srqEoC8 zk@UOMq%Th^YD|sG04nM;Jxl3RdtQJe&I3UGa(-~MYy!AE5{ul}($S(dW*QaCu$ZaN zFg`xc=;-LIw$aegKqL~uwjrONbitva(?}NB?9~G3e#hUx&E4s ztX|zbR~!yhDljxu1xj>vtv@YV0*FSVw6wHv;=~EY#>N;qae}c-hW4f=8hvkO+cx=f znTN;5*#Gz=6vv*YvC+Y@W=LI>V#j~q!TRggQ`lWlPnAw3aO-ZTn7C1Nf#g2ycz3Ul!W{hYpiUOQCae|SN5%T#w>2#XL#zsa*bsl?c zg0Zn7nwyiXT-nDZmt<*djGX4lM=KSMz49{cYgUqO(TMmKxKh!1Zs-XVDs**S77CU~ zBtmm@Gnq_=$;nBkPoBg)c8pd{bG_4s2Ao=re4)T&4?oP2p&_C(Cabd=-Q8C+J$(v0 z1{;3qDw#J&F(SZ|Pd>re*z>ftY20|@^=#gpL(|lGtl?3Z zZJO*K9_HxiC~Mo>X>4rtf#oCz5ALU_DZ$2#8|OV22AFm0*3rIZ4deMd&kqf8=DWubB8FdLB>+h$a z>pb}I!=#c)OjRYfV+VcdG&!IDqiGuG2Kvqcxak(OoTe0`k+khP^#$qA1&iG4%>r7| zc-@~Cuml;V3An5!EgHLjPD3{g`uhhkbvHa!Rn=V}T<{cyV4%OBbUIC6-x7f0<&8AW zou};6Ny@g(fUZ-K3%aOw;(NdL_I7T#^;Y_eMHm4c7vks|qNk;;j&}e67XC>@K~$>? zEuD6gm8v@L1PdY15()Hj1#Fw{YXrqL&1z|)v;xbDGk?U6-_Z?%rglCUMm>)J@!uPP zb|R6K$Y>E%!N6{t!qE!pWMbZU5CNoxKx=O&bL*{uTTZZ)1y12+gdfy(`uqD4LeQ4W zQPOovd-k|CS)7?=7DCXTPIIfKK{iWsGKpH}JyNL@y}i9WxMz?(kLdKgH%I2yYn7=& zIc6O_u@ZMr_^AN1_(5aWQFni;be4t2{zh=?hkiSZJhAa9{p~rL)vym>96SB`q3yZ_>~-1M~qj40HLFL5~^y{QakQU;c+Dbno8Ngt%NV#Mptc_?SUw6Aa%P!JyN@_`ZZ|X(MXbmW| z%JU%tIijFYr*LM;#tQ~4i%p)-0Uu7~QWy2!)vKTi2EH-`M^$>edl!vN&X!&J`ub?o zG%9=dq8Q_7S{@;$U-y&YF&hdD>>j|V7-%UC5fK^=*WqTP{qqYO768f{YKqR68S=Lu zZvxhcn22gQ4H8KzD>~4!ZD-_m*|i&Q(rm&NhEhqkv#hS8K+T~tqR$OuJP9NqD zIULR|Nr}6(9S^Wra%XpD?!Eu}KOgs=b1d)$NE;Mb84FPqSi_bByhrzoop@P0EsD$m z0Hl`{v={i)*yLED{7@OPP(fHl&1wWpz?^s^FZv&V@>2OY`dVrlIg)JJ0gk(>1RpK1Q$3kwr^~t{DrcK>r#2l z!}A5=SRPC4v~#(i%mN}G`eWo1v#5r|DhR~=Wy31uT*9oWqi;1)WcC>#y+qKhz$Z=H z9M4W$$uxGt3M6O4^pCdSGRIxEGDwsy)v zH)zv2E`shvr=O5>lFFA);hmc&pLNM6)>Qg^MEh$8DUouP#Y{erXj#mDZ5D4{A_`y@ z0t=hb9?m(F^t#ONNHG-oR{p@un0rJ~7yzyL7JHm5Gdf6YkVmr#l}ZShfiVj(nafc= zGL5P!8m}}U3#0dqX6$i$KcVYC!}?X|q!`+2G{9R9EJhEogv?^GcdRs)nf~Kx09?mq z=2$sg((gNys3@F60WGCasrzyVVY27*c%DV&YqQXTdq4gwrr1|3Ff?=zt2HC-ggEN8 zZJ}?X$Q%%(#Q%1HaVu{PZ_H3il8{b5N=~!2DNM$i^29KZ{Mnu zE=T!T7>G7|QNk`4>v-8Fmn&$?aU*}rK&+xcx%;DrWPm(lV?)iu)0}!rG5>-bs0dnl zFvIW&Q>iWjohXKRCp@|>F*e`2qEx1kIFL@yaJ3qaLlo99lL|jo9pbP zC^EMZAl(2HmF+3#in-j(pOh&cbg^0z)L;iCiab=SK#4*`mw>rWr`eXWf>JvPVhg{W zMb5QwvvBWy!pP-K2LsVX$sO3Xg??H?(Sv4z!@z{?*p?^?Y-eZoA4GZMnxShyp4nU1 zc2p8%XQ%uvS{Q*0chT9cFwcx>1(6tc6C%j&VM1@aC>n$qx*hnOnK5^Ti3HbeRPMWu z(r7fO)oRpgH5&Cgs?%8}tkiow2AU@DKT4^^o$|Lt%z`gaHIT1`3@2_EuI&DWa;2~)T)ksebNy`mgA-NIXMD2U$f1Ea+M z7QhDx!y630?Nk3royLDO@asNJnw&ayYUKjeYL!x{w9b^4Ql_4ZfB;Y`m8e#$>zry` z205cm`E#+3^?`b))A1uFiUThWx*I-pdRE)EaeW^z1$-fv6}~UIaHc`?izgv~s~4}j zgrV9U;7M)44aNK~QJRjpq8s!8&6WXUY$LP8*MOqns1oqkz`d4ZIbt##=*0_*_zK8o zvD)nr0Io}`R>O6iRrauLa9vchi6`Y+X0dIQ>mqd`!K~|s%%VHriqhuBNGeJ@=C}O@ z@Cad{?G~#QIP$=Qrez+?6~=8lmkTov`hEyH&%<}!wSoF+_fgmX$#Wln>s;MU(<-UlB2LH};EFG&LZq)wSld$UCDY26+Zfy~AqLWoerskT~S+aL%`Z9Wg{^&-XEDrcJkOH?Fm%Yf+@v#k6*GGcJ|-H=t1 z$N!;%oRf%9ng<6P|9lCbb{Lfl9xshsYvSc;;cbfQG{;VN>j`*#k1u8gYr;Hzue z61v9v8r4y$y({=?m#Wo=>Ms$N?Cy1Rd3FTINlE1&!*(MCluD@Qt9bL0*IdZw1?Bt8 zP=d<0t1uac!uY%DVG8&ElbrnG$?!I>%V7cz0q3<>+|$-kLw}Ym0-hZBPV9ZlfHAfS z7;$G%q})yde`;pTPu+3s4pI7aiPL|3n)=K2Ft&Fx;hgJ|JbxpT)p9J{2^X*Cg|o2R zcXkUr4^&n!js}=XQyLZEU!7)h+SA1!`C!=VQ#`x{i_SPlc<06u69Tb4VaMMX5AMygKUF)gkagqbM}=S*AJtI4sVS)0{! z-_ZiY2W2SgzN8_2e1FA#KTJFu=i2$=>nmOczOMn(VztcSUf}bfab^q`Ud%TN9!9x!nqgV`0qq#ZB!w*+E zaiX;HS=^d>^ij#9kDjJr!(W~_#{LJwzHl6eJ$v@x`)wRY;d$`ND|No~rIYHp=Ne6= zxC}fCd`Gv%V{M_%G{B_kIKd!vmgsmB_&YslW5D73*vS2#{N(i5@#BIhHU9j($2Y(E zJm=0`#P@v%+&#v~U75mh!NmSNhHZxl%Ohv1tMKU>q=SHZMTU#G8x-h>pTm=9(k98pwscZ zmhZZ*4Va6Ii!0)@R`dA!*Jsx;%cV=tgv^p~%+>3PR;$IZfM;8?oPSocECMM@oIP9R z=ux=uzB1V?OidZq%P&)CHW}0X4e)I}aasug#ClP5jkX%-ik zI=-(~kZ%|rLn%qKsXNA7SpY zaq!>-4?Hl<`SW$Y`qk6S&B-BcWn=&h18aDABwHxl#q2En{O4y^mK>A{^ZmPSmU~K5 zd?=gc%%aTr%gcq%)vN8ju$&2ksGiU+z)6c^+bFip_rvv~_1ZKnEkUi;NV|@y?|BS( zLO+9IeGTnooyOost)XBO-|6P+kJ!c0V&Rv7ztFqd)#J9CdqYsW?J)oT{aGAGt z>jbgYW2?(-4`PEG73cIdi(CU<2mTd!gY^l3;ydbEYmjdks+%IeF|({*q?@ji)LY`4 ziX(P8s23DJ04!xPrn7tZ$nxUi@=N36*}F2PIjR;F&E>0sGKM=NBSYrW)gZ|DL2&un zwd>x}(pD{zXmBErY?k#!Et1}mpJ}9|rzc|Nk-F?x*!cAf~rD zdbX;B^DChD*2j1?vreqt-3q4*;G^1Oeg*hX;G%w>i`vqQ78sXe%<@K;@$Jei#wMAf z8)$kdxpqv^6}prE5V$QiYudVz!-Qd)roKfG1T5>uMPVduJ+PVB0$|*45

jf9Gfh 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 O0000 literal 0 HcmV?d00001 diff --git a/resource/Skip_0.png b/resource/Skip_0.png new file mode 100644 index 0000000000000000000000000000000000000000..8f87771ca6f609792c6d0a2bfd42b44491eb1d27 GIT binary patch literal 1008 zcmVz9|i+}vjNvS zBzX@xaSE6%-fZB9#tjp1e-@kfNnRm`^vj>?o{Ney7o@u^QaK#aGpqe6V4|6np6F8{ zuXhkwto~Er5%3F`XCl#HMZ+4kdx0cy3wW(@4M2;r-4op)x=N83;63nI{ZYUwquqN^mIYVLJ~c&iO>N}kuL0DkJ6dS5zMqy7-1cRjGs z&`SbzTAMBWdH~iK-h3CK9Eyb&?M=Rm{w}&j^mMhKfRpN<&>qXm|AwUYG5~iC|0D1u z%Q;)rJ^{|>DE{QLm>e_x(axb9N`*0M8_mRR6CGx9elbObjb=ZT4b#kiXO~GoJE8*W zb#{mH0#YdNFKLytGamFa5ei>qvGRPdUF`(zcj|#bS;j6?+XNi%fcsc(`cGYiawrv& zCMsF{HhZIdaRAt?w6X`VmUJn5a=_T`#*u#%VE;CyjE6%0rn3B#;e}|EGp1JU4(Kd2+eA%eEcd?)Ch}L zq^ob+L{Bo4K7-T12lY1K_9Mw6LLrIX?Z;Uf(Sd#W1bqm>#TsQsdfXH}6 z{kZ`SmoFXzS4jU5or>du{c8^Ozobu{InA@Up|%(4GIkQE1A6-8`Ct#QKsw5RrAF46 zWzUt;bKc;SRhqOjN$}@WC4>9)sB3lfOpC0YVp(i%Dl+Pg(Y1*uP0(_+7lBn_78zhG=}&>mNmmCw z;Ed7J3_JwB(*E^Bo%UQkm39Jr3s^ur@w4fPHFa@+i|CqmhQ&aw{!OM>5oG}%p)~C! eMXtD&0)GJb?S?aK>zE?|0000W2Fu)vmxS3EZ2wfEj& zC+SLrSdi8$kq{v)ycU9m5Ozf35s5aXh)0FAXwcHmwV3~;CpUMdGk0{x)b~$rzVDp# zednG#^PTUU@7x=qaNyz}!Fi+zq15bSNC*o&<;lQPUdmWd&L{1z77K*nJ z=+L+^;vGq1bFJh9U)!6QdZWLXv$P4fZs8@dia2Y6dfBnA~p;F2UBtj(? z-&o+GbUYMYF8OTptn0+vXn3>Iyw3pOm*&*@(zz=2M;X0af#rr?6`<4FY~j}fu*vY2 zx(MaaTWHnUMA?MTPC=Jd_M`%z5X4Nk2oEZ2}z8IaIz=&VW?U>mmIs zbPP2S3SVTg@^r9Q?KGWt>VOeR#;#G@44nB3&#~6@UpR+y$QPm}Dp_=zvr)P@3hY!` zSpsY(Udo;sFt)#Oq^ zCueXG${`VHx{^ek^}sbP&|^MWd$$cm{l@`|F3@I&%$F z+6nL@U<2{QPo^iQsY}5`s63{3ebLTLQK8+x*%T|nY~bURroEw;D{lF~A8M*jP(c?b Q?*IS*07*qoM6N<$g2o})T>t<8 literal 0 HcmV?d00001 diff --git a/resource/Skip_2.png b/resource/Skip_2.png new file mode 100644 index 0000000000000000000000000000000000000000..de0c96f282ec832e85f3e70613d15bf808246496 GIT binary patch literal 950 zcmV;n14;aeP)(d0ufD5zG0`I-oX0-vPV{bZs&)40sLP z&12#i1=Q>Q=em5<0)2rtqZ;1e^(Z)Kql}~`Py(E7!nM{tF`WQzjhf-mz%4RcglajL;oE>Iqx6$l} zqA=a;cXpd(L(XZN5F$E4ITRfOOoSp3S*$%1>`*yLd#EO0NJQIZD%*f#f8cj4H}z+Z zP!6R++(addZnHPa6bFE$-;_uH_W|?tjCw;CB+-qtp1gY@(E}TPNK)$)AD# z((NMrbjQwK{1go?LOJ-6CK(ZNRs!cWK+9F02UcY>$pG6)AN?sOogMUm)5cFb@BsKi z&*_H-?YXM8>;(84GJ$x~NBJol+>!qRM5q!yx6uFPV9ow*CRvfo1U^#Bv{w{3<5mj% Y0AFT^XJZmPkN^Mx07*qoM6N<$f~iQfwg3PC literal 0 HcmV?d00001