diff --git a/apps/airbnbcalendar/airbnb_calendar.star b/apps/airbnbcalendar/airbnb_calendar.star index 974483475..9da926088 100644 --- a/apps/airbnbcalendar/airbnb_calendar.star +++ b/apps/airbnbcalendar/airbnb_calendar.star @@ -74,7 +74,7 @@ def listing(url, height): dtstart_list = re.match(r"DTSTART;VALUE=DATE:(.{4})(.{2})(.{2})", ical) dtend_list = re.match(r"DTEND;VALUE=DATE:(.{4})(.{2})(.{2})", ical) - summary_list = re.match(r"SUMMARY:(.+)", ical) + summary_list = re.match(r"SUMMARY:([^\r\n]+)", ical) event_list = zip(dtstart_list, dtend_list, summary_list) now = time.now() diff --git a/apps/apitext/api_text.star b/apps/apitext/api_text.star index c1e159765..fe823a56f 100644 --- a/apps/apitext/api_text.star +++ b/apps/apitext/api_text.star @@ -6,6 +6,7 @@ Author: Michael Yagi """ load("cache.star", "cache") +load("encoding/base64.star", "base64") load("encoding/json.star", "json") load("http.star", "http") load("random.star", "random") @@ -13,6 +14,9 @@ load("render.star", "render") load("schema.star", "schema") load("time.star", "time") +BG_IMAGE = "/9j/4AAQSkZJRgABAQEBLAEsAAD/4QDARXhpZgAATU0AKgAAAAgABgEaAAUAAAABAAAAVgEbAAUAAAABAAAAXgEoAAMAAAABAAIAAAExAAIAAAARAAAAZgEyAAIAAAAUAAAAeIdpAAQAAAABAAAAjAAAAAAAAAEsAAAAAQAAASwAAAABcGFpbnQubmV0IDUuMC4xMwAAMjAwOTowMzoyMCAxNjozNzo0OAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAFAKADAAQAAAABAAADIAAAAAAAAP/hB+xodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+DQo8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA0LjEtYzAzNiA0Ni4yNzY3MjAsIE1vbiBGZWIgMTkgMjAwNyAyMjo0MDowOCAgICAgICAgIj4NCiAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4NCiAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iIHhtbG5zOnhhcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1sbnM6eGFwTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iIHhtbG5zOnBob3Rvc2hvcD0iaHR0cDovL25zLmFkb2JlLmNvbS9waG90b3Nob3AvMS4wLyIgZGM6Zm9ybWF0PSJpbWFnZS9qcGVnIiB4YXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDUzMgV2luZG93cyIgeGFwOkNyZWF0ZURhdGU9IjIwMDktMDMtMjBUMTY6Mzc6NDgtMDQ6MDAiIHhhcDpNb2RpZnlEYXRlPSIyMDA5LTAzLTIwVDE2OjM3OjQ4LTA0OjAwIiB4YXA6TWV0YWRhdGFEYXRlPSIyMDA5LTAzLTIwVDE2OjM3OjQ4LTA0OjAwIiB4YXBNTTpEb2N1bWVudElEPSJ1dWlkOjY5RDEwQ0NDOEUxNURFMTFBQTM3RDcxMzFBMUIxNDBDIiB4YXBNTTpJbnN0YW5jZUlEPSJ1dWlkOjZBRDEwQ0NDOEUxNURFMTFBQTM3RDcxMzFBMUIxNDBDIiB0aWZmOk9yaWVudGF0aW9uPSIxIiB0aWZmOlhSZXNvbHV0aW9uPSIzMDAwMDAwLzEwMDAwIiB0aWZmOllSZXNvbHV0aW9uPSIzMDAwMDAwLzEwMDAwIiB0aWZmOlJlc29sdXRpb25Vbml0PSIyIiB0aWZmOk5hdGl2ZURpZ2VzdD0iMjU2LDI1NywyNTgsMjU5LDI2MiwyNzQsMjc3LDI4NCw1MzAsNTMxLDI4MiwyODMsMjk2LDMwMSwzMTgsMzE5LDUyOSw1MzIsMzA2LDI3MCwyNzEsMjcyLDMwNSwzMTUsMzM0MzI7NzAzMjBEMDYyQjUzNDhCODhDOTY5RDA1MzY3MzkyQjAiIGV4aWY6UGl4ZWxYRGltZW5zaW9uPSIxMjgwIiBleGlmOlBpeGVsWURpbWVuc2lvbj0iODAwIiBleGlmOkNvbG9yU3BhY2U9IjEiIGV4aWY6TmF0aXZlRGlnZXN0PSIzNjg2NCw0MDk2MCw0MDk2MSwzNzEyMSwzNzEyMiw0MDk2Miw0MDk2MywzNzUxMCw0MDk2NCwzNjg2NywzNjg2OCwzMzQzNCwzMzQzNywzNDg1MCwzNDg1MiwzNDg1NSwzNDg1NiwzNzM3NywzNzM3OCwzNzM3OSwzNzM4MCwzNzM4MSwzNzM4MiwzNzM4MywzNzM4NCwzNzM4NSwzNzM4NiwzNzM5Niw0MTQ4Myw0MTQ4NCw0MTQ4Niw0MTQ4Nyw0MTQ4OCw0MTQ5Miw0MTQ5Myw0MTQ5NSw0MTcyOCw0MTcyOSw0MTczMCw0MTk4NSw0MTk4Niw0MTk4Nyw0MTk4OCw0MTk4OSw0MTk5MCw0MTk5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" +MAX_TEXT_LENGTH = 1000 + def main(config): random.seed(time.now().unix // 10) @@ -52,6 +56,49 @@ def main(config): def get_text(api_url, base_url, heading_response_path, body_response_path, image_response_path, request_headers, debug_output, ttl_seconds, heading_font_color, body_font_color, image_placement): message = "" + row = render.Row(children = []) + + if debug_output == False: + message = "API TEXT" + + row = render.Stack([ + render.Image(src = base64.decode(BG_IMAGE)), + render.Box( + render.Row( + main_align = "space_evenly", + cross_align = "center", + children = [ + render.Box( + width = 44, + height = 12, + color = "#FFFFFF", + ), + ], + ), + ), + render.Box( + render.Row( + main_align = "space_evenly", + cross_align = "center", + children = [ + render.Box( + width = 42, + height = 10, + color = "#000000", + ), + ], + ), + ), + render.Box( + render.Row( + main_align = "space_evenly", + cross_align = "center", + children = [ + render.Text(content = message, font = "tom-thumb", color = body_font_color), + ], + ), + ), + ]) if api_url == "": message = "API URL must not be blank" @@ -74,6 +121,7 @@ def get_text(api_url, base_url, heading_response_path, body_response_path, image output_map = get_data(api_url, debug_output, headerMap, ttl_seconds) output_content = output_map["data"] output_type = output_map["type"] + children = [] if output_content != None and (output_type == "text" or (output_type == "json" and (len(heading_response_path) > 0 or len(body_response_path) > 0 or len(image_response_path) > 0))): # api_url_array = api_url.split("/") @@ -94,9 +142,9 @@ def get_text(api_url, base_url, heading_response_path, body_response_path, image outputStr = outputStr[0:outputLen] if outputLen >= 200: outputStr = outputStr + "..." - print("Decoded JSON truncated: " + outputStr) + print("Decoded response JSON truncated: " + outputStr) else: - print("Decoded JSON: " + outputStr) + print("Decoded response JSON: " + outputStr) # Parse response path for JSON response_path_data_body = parse_response_path(output, body_response_path, debug_output, ttl_seconds) @@ -105,6 +153,19 @@ def get_text(api_url, base_url, heading_response_path, body_response_path, image body_parse_message = response_path_data_body["message"] if debug_output: print("Getting text body. Pass: " + str(body_parse_failure == False)) + if body_parse_failure: + children.append(render.WrappedText(content = body_parse_message, font = "tom-thumb", color = "#FF0000")) + else: + bodyoutputStr = output_body + if bodyoutputStr != None: + if len(bodyoutputStr) >= 200: + print("Body text: " + bodyoutputStr[0:200] + "...") + else: + print("Body text: " + bodyoutputStr) + + if len(output_body) >= MAX_TEXT_LENGTH: + output_body = output_body[0:MAX_TEXT_LENGTH] + "..." + print("Body text truncated") # Get heading response_path_data_heading = parse_response_path(output, heading_response_path, debug_output, ttl_seconds) @@ -113,6 +174,19 @@ def get_text(api_url, base_url, heading_response_path, body_response_path, image heading_parse_message = response_path_data_heading["message"] if debug_output: print("Getting text heading. Pass: " + str(heading_parse_failure == False)) + if heading_parse_failure: + children.append(render.WrappedText(content = heading_parse_message, font = "tom-thumb", color = "#FF0000")) + else: + headingoutputStr = output_heading + if headingoutputStr != None: + if len(headingoutputStr) >= 200: + print("Header text: " + headingoutputStr[0:200] + "...") + else: + print("Header text: " + headingoutputStr) + + if len(output_heading) >= MAX_TEXT_LENGTH: + output_heading = output_heading[0:MAX_TEXT_LENGTH] + "..." + print("Heading text truncated") # Get image response_path_data_image = parse_response_path(output, image_response_path, debug_output, ttl_seconds) @@ -121,6 +195,8 @@ def get_text(api_url, base_url, heading_response_path, body_response_path, image image_parse_message = response_path_data_image["message"] if debug_output: print("Getting image. Pass: " + str(image_parse_failure == False)) + if image_parse_failure: + children.append(render.WrappedText(content = image_parse_message, font = "tom-thumb", color = "#FF0000")) if (body_parse_failure == False and output_body != None) or (heading_parse_failure == False and output_heading != None) or (image_parse_failure == False and output_image != None): if type(output_body) == "string": @@ -128,16 +204,16 @@ def get_text(api_url, base_url, heading_response_path, body_response_path, image if type(output_heading) == "string": output_heading = output_heading.replace("\n", "").replace("\\", "") - children = [] img = None image_endpoint = "" # Process image data if output_image != None and type(output_image) == "string": if output_image.startswith("http") == False and (base_url == "" or base_url.startswith("http") == False): - message = "Base URL required" + message = "Base URL required for image" if debug_output: - print("Invalid URL. Requires a base_url") + children.append(render.WrappedText(content = message, font = "tom-thumb", color = "#FF0000")) + print(message) else: if output_image.startswith("http") == False: if output_image.startswith("/"): @@ -149,7 +225,9 @@ def get_text(api_url, base_url, heading_response_path, body_response_path, image img = output_image_map["data"] if img == None and debug_output: - print("Could not retrieve image") + message = "Could not retrieve image" + print(message) + children.append(render.WrappedText(content = message, font = "tom-thumb", color = "#FF0000")) # Insert image according to placement if image on left rendered_image = None @@ -176,10 +254,10 @@ def get_text(api_url, base_url, heading_response_path, body_response_path, image if output_heading != None and type(output_heading) == "string": if rendered_image != None: output_heading = wrap(output_heading, 9) - heading_lines = calculate_lines(output_heading, 10) + heading_lines = calculate_lines(output_heading, True, 10) children.append(render.WrappedText(content = output_heading, font = "tom-thumb", color = heading_font_color, width = 41)) else: - heading_lines = calculate_lines(output_heading, 17) + heading_lines = calculate_lines(output_heading, False, 17) children.append(render.Padding( pad = (0, 1, 0, 0), child = render.Column( @@ -196,10 +274,10 @@ def get_text(api_url, base_url, heading_response_path, body_response_path, image if output_body != None and type(output_body) == "string": if rendered_image != None: output_body = wrap(output_body, 9) - body_lines = calculate_lines(output_body, 10) + body_lines = calculate_lines(output_body, True, 10) children.append(render.WrappedText(content = output_body, font = "tom-thumb", color = body_font_color, width = 41)) else: - body_lines = calculate_lines(output_body, 17) + body_lines = calculate_lines(output_body, False, 17) children.append(render.Padding( pad = (0, 1, 0, 0), child = render.Column( @@ -231,10 +309,15 @@ def get_text(api_url, base_url, heading_response_path, body_response_path, image elif len(image_response_path) > 0 and output_image == None and debug_output: if len(image_endpoint) > 0: print("Image URL found but failed to render URL " + image_endpoint) + children.append(render.WrappedText(content = "Image URL found but failed to render URL " + image_endpoint, font = "tom-thumb", color = "#FF0000")) else: print("No image URL found") + children.append(render.WrappedText(content = "No image URL found", font = "tom-thumb", color = "#FF0000")) - height = 32 + ((heading_lines + body_lines) - ((heading_lines + body_lines) * 0.52)) + percent = 0.52 + if image_placement == 4: + percent = 0.62 + height = 32 + ((heading_lines + body_lines) - ((heading_lines + body_lines) * percent)) if debug_output: print("heading_lines: " + str(heading_lines)) @@ -277,7 +360,7 @@ def get_text(api_url, base_url, heading_response_path, body_response_path, image ] return render.Root( - delay = 100, + delay = 90, show_full_animation = True, child = render.Row( children = children_content, @@ -288,7 +371,7 @@ def get_text(api_url, base_url, heading_response_path, body_response_path, image else: return render.Root( - delay = 100, + delay = 90, show_full_animation = True, child = render.Marquee( offset_start = 32, @@ -301,39 +384,52 @@ def get_text(api_url, base_url, heading_response_path, body_response_path, image ) else: - message = "Oops! Check URL and header values. URL must return JSON or text." + message = "Oops! Check URL and header values. URL " + api_url + " must return JSON or text." if debug_output: print(message) if message == "": message = "Could not get text" - row = render.Row(children = []) + message = "API Text - " + message + if debug_output == True: - row = render.Row( - main_align = "space_evenly", - cross_align = "center", - children = [ - render.WrappedText(content = message, font = "tom-thumb"), - ], + row = render.Marquee( + offset_start = 32, + offset_end = 32, + height = 32, + scroll_direction = "vertical", + width = 64, + child = render.WrappedText(content = message, font = "tom-thumb", color = "#FF0000"), ) return render.Root( + delay = 90, + show_full_animation = True, child = render.Box( row, ), ) -def calculate_lines(text, length): +def calculate_lines(text, wrapped, length): words = text.split(" ") currentlength = 0 breaks = 0 - for word in words: - if len(word) + currentlength >= length: + for subwords in words: + if wrapped: + subwords = text.split("\n") + + if (len(subwords) > 0) and wrapped: + if len(subwords) == 0: + breaks = breaks + 1 + else: + breaks = len(subwords) + currentlength = 0 + elif len(subwords) + currentlength >= length: breaks = breaks + 1 currentlength = 0 - currentlength = currentlength + len(word) + 1 + currentlength = currentlength + len(subwords) + 1 return breaks + 1 @@ -357,10 +453,11 @@ def wrap_line(line, line_length): cur_line_length = 0 str_builder = "" + index = 0 for word in words: # If adding the new word to the current line would be too long, # then put it on a new line (and split it up if it's too long). - if (cur_line_length + len(word)) > line_length: + if (index == 0 or (cur_line_length + len(word)) > line_length): # Only move down to a new line if we have text on the current line. # Avoids situation where # wrapped whitespace causes emptylines in text. @@ -393,6 +490,8 @@ def wrap_line(line, line_length): cur_line_length = cur_line_length + len(word) + index = index + 1 + return str_builder def parse_response_path(output, responsePathStr, debug_output, ttl_seconds): diff --git a/apps/aquarium/aquarium.star b/apps/aquarium/aquarium.star new file mode 100644 index 000000000..8db947af9 --- /dev/null +++ b/apps/aquarium/aquarium.star @@ -0,0 +1,215 @@ +""" +Applet: Aquarium +Summary: Digital Aquarium +Description: A digital aquarium. +Author: Robert Ison +""" + +load("encoding/base64.star", "base64") +load("random.star", "random") +load("render.star", "render") +load("schema.star", "schema") + +SCREEN_WIDTH = 64 +SCREEN_HEIGHT = 32 + +sealife = [ + { + "direction": "left", + "name": "Clownfish", + "height": 15, + "width": 27, + "image": "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", + }, + { + "direction": "right", + "name": "Blue Tang", + "height": 14, + "width": 25, + "image": "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", + }, + { + "direction": "right", + "name": "Lionfish", + "height": 14, + "width": 25, + "image": "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", + }, + { + "direction": "left", + "name": "Shark", + "height": 11, + "width": 29, + "image": "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", + }, + { + "direction": "right", + "name": "Blowfish", + "height": 16, + "width": 25, + "image": "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", + }, + { + "direction": "right", + "name": "Cuttlefish", + "height": 14, + "width": 30, + "image": "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", + }, +] + +coral = [ + { + "name": "Brain", + "height": 12, + "width": 20, + "image": "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", + }, + { + "name": "Finger", + "height": 15, + "width": 17, + "image": "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", + }, + { + "name": "Tubes", + "height": 18, + "width": 17, + "image": "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", + }, + { + "name": "Fan", + "height": 17, + "width": 15, + "image": "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", + }, +] + +water = [ + { + "name": "Aqua", + "html": "#54cee3", + }, + { + "name": "Deep Sky Blue", + "html": "#00BFFF", + }, + { + "name": "Aquamarine", + "html": "#7fffd4", + }, + { + "name": "Light Blue", + "html": "#ADD8E6", + }, + { + "name": "Very Dark Blue", + "html": "#08056d", + }, + { + "name": "Dark Turquoise", + "html": "#00ced1", + }, + { + "name": "Turquoise", + "html": "#40E0D0", + }, +] + +def main(config): + water_color = config.str("color", "") + + return render.Root( + get_frames(water_color), + show_full_animation = True, + delay = 120, + ) + +def get_frames(water_color): + random_sealife = sorted(sealife, key = lambda x: random.number(0, 10)) + random_coral = sorted(coral, key = lambda x: random.number(0, 10)) + + if water_color == "Random" or water_color == "": + water_color = water[random.number(0, len(water) - 1)]["html"] + + number_of_fish_to_display = min(3, len(random_sealife)) + widest_fish_length = max(random_sealife, key = lambda x: x["width"])["width"] + + first_offset = random.number(0, 32 - random_coral[0]["width"]) + second_offset = random.number(32, 64 - random_coral[1]["width"]) + third_offset = random.number(0, 64 - random_coral[2]["width"]) + + # store each frame of the animation in this list of frame + frames = [] + + for i in range(SCREEN_WIDTH + (widest_fish_length * 2)): + children = [] + children.append(render.Box(color = water_color, width = SCREEN_WIDTH, height = SCREEN_HEIGHT)) + children.append(add_padding_to_child_element(render.Image(src = base64.decode(random_coral[1]["image"])), second_offset, SCREEN_HEIGHT - random_coral[1]["height"])) + + for f in range(number_of_fish_to_display): + children.append(get_fish_frame(random_sealife[f], i, f)) + + children.append(add_padding_to_child_element(render.Image(src = base64.decode(random_coral[0]["image"])), first_offset, SCREEN_HEIGHT - random_coral[0]["height"])) + children.append(add_padding_to_child_element(render.Image(src = base64.decode(random_coral[2]["image"])), third_offset, SCREEN_HEIGHT - random_coral[2]["height"])) + + frame = render.Stack( + children = children, + ) + + frames.append(frame) + + return render.Animation( + children = [frame for frame in frames], + ) + +def get_fish_frame(fish, frame, fish_number): + increment = 1 if fish_number == 1 else 2 + left_offset = -fish["width"] - (10 * fish_number) * fish_number + (frame * increment) if fish["direction"] == "right" else SCREEN_WIDTH - (frame * increment) + top_offset = fish_number * 9 - 2 + return add_padding_to_child_element(render.Image(src = base64.decode(fish["image"]), width = fish["width"] + random.number(0, 1), height = fish["height"]), left_offset, top_offset) + +def add_padding_to_child_element(element, left = 0, top = 0, right = 0, bottom = 0): + padded_element = render.Padding( + pad = (left, top, right, bottom), + child = element, + ) + + return padded_element + +def get_color_options(colors): + colors = sorted(colors, key = lambda x: x["name"]) + + color_options = [ + schema.Option( + display = color["name"], + value = color["html"], + ) + for color in colors + ] + + color_options.append( + schema.Option( + display = "Random", + value = "Random", + ), + ) + + return color_options + +def get_schema(): + color_options = get_color_options(water) + + return schema.Schema( + version = "1", + fields = [ + schema.Dropdown( + id = "color", + name = "Water Color", + desc = "What Water Color do you prefer?", + icon = "water", #"palette","paintbrush" + options = color_options, + default = color_options[len(color_options) - 1].value, + ), + ], + ) diff --git a/apps/aquarium/aquarium.webp b/apps/aquarium/aquarium.webp new file mode 100644 index 000000000..90cb22168 Binary files /dev/null and b/apps/aquarium/aquarium.webp differ diff --git a/apps/aquarium/manifest.yaml b/apps/aquarium/manifest.yaml new file mode 100644 index 000000000..cfa219212 --- /dev/null +++ b/apps/aquarium/manifest.yaml @@ -0,0 +1,6 @@ +--- +id: aquarium +name: Aquarium +summary: Digital Aquarium +desc: A digital aquarium. +author: Robert Ison diff --git a/apps/aquarium/readme.md b/apps/aquarium/readme.md new file mode 100644 index 000000000..5c7f520b3 --- /dev/null +++ b/apps/aquarium/readme.md @@ -0,0 +1,7 @@ +# Aquarium for Tidbyt + +Created by: Robert Ison + +Displays an aquarium scene that changes each time with different fish and color. + +![Aquarium for Tidbyt](aquarium.webp) diff --git a/apps/breakingbad/breakingbad.star b/apps/breakingbad/breakingbad.star new file mode 100644 index 000000000..f38ae5528 --- /dev/null +++ b/apps/breakingbad/breakingbad.star @@ -0,0 +1,224 @@ +""" +Applet: BreakingBad +Summary: Breaking Bad TV Credit +Description: Display credit in Breaking Bad TV show format. +Author: Robert Ison +""" + +load("encoding/base64.star", "base64") +load("render.star", "render") +load("schema.star", "schema") + +SMOKE = base64.decode(""" +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 +""") + +FONT = "6x10" +ELEMENT_GREEN = "#094b3f" +WHITE = "#FFF" + +elements = { + "H": "Hydrogen", + "He": "Helium", + "Li": "Lithium", + "Be": "Beryllium", + "B": "Boron", + "C": "Carbon", + "N": "Nitrogen", + "O": "Oxygen", + "F": "Fluorine", + "Ne": "Neon", + "Na": "Sodium", + "Mg": "Magnesium", + "Al": "Aluminum", + "Si": "Silicon", + "P": "Phosphorus", + "S": "Sulfur", + "Cl": "Chlorine", + "Ar": "Argon", + "K": "Potassium", + "Ca": "Calcium", + "Sc": "Scandium", + "Ti": "Titanium", + "V": "Vanadium", + "Cr": "Chromium", + "Mn": "Manganese", + "Fe": "Iron", + "Co": "Cobalt", + "Ni": "Nickel", + "Cu": "Copper", + "Zn": "Zinc", + "Ga": "Gallium", + "Ge": "Germanium", + "As": "Arsenic", + "Se": "Selenium", + "Br": "Bromine", + "Kr": "Krypton", + "Rb": "Rubidium", + "Sr": "Strontium", + "Y": "Yttrium", + "Zr": "Zirconium", + "Nb": "Niobium", + "Mo": "Molybdenum", + "Tc": "Technetium", + "Ru": "Ruthenium", + "Rh": "Rhodium", + "Pd": "Palladium", + "Ag": "Silver", + "Cd": "Cadmium", + "In": "Indium", + "Sn": "Tin", + "Sb": "Antimony", + "Te": "Tellurium", + "I": "Iodine", + "Xe": "Xenon", + "Cs": "Cesium", + "Ba": "Barium", + "La": "Lanthanum", + "Ce": "Cerium", + "Pr": "Praseodymium", + "Nd": "Neodymium", + "Pm": "Promethium", + "Sm": "Samarium", + "Eu": "Europium", + "Gd": "Gadolinium", + "Tb": "Terbium", + "Dy": "Dysprosium", + "Ho": "Holmium", + "Er": "Erbium", + "Tm": "Thulium", + "Yb": "Ytterbium", + "Lu": "Lutetium", + "Hf": "Hafnium", + "Ta": "Tantalum", + "W": "Tungsten", + "Re": "Rhenium", + "Os": "Osmium", + "Ir": "Iridium", + "Pt": "Platinum", + "Au": "Gold", + "Hg": "Mercury", + "Tl": "Thallium", + "Pb": "Lead", + "Bi": "Bismuth", + "Po": "Polonium", + "At": "Astatine", + "Rn": "Radon", + "Fr": "Francium", + "Ra": "Radium", + "Ac": "Actinium", + "Th": "Thorium", + "Pa": "Protactinium", + "U": "Uranium", + "Np": "Neptunium", + "Pu": "Plutonium", + "Am": "Americium", + "Cm": "Curium", + "Bk": "Berkelium", + "Cf": "Californium", + "Es": "Einsteinium", + "Fm": "Fermium", + "Md": "Mendelevium", + "No": "Nobelium", + "Lr": "Lawrencium", + "Rf": "Rutherfordium", + "Db": "Dubnium", + "Sg": "Seaborgium", + "Bh": "Bohrium", + "Hs": "Hassium", + "Mt": "Meitnerium", + "Ds": "Darmstadtium", + "Rg": "Roentgentium", + "Cn": "Copernicum", + "Nh": "Nihonium", + "Fl": "Flerovium", + "Mc": "Moscovium", + "Lv": "Livermorium", + "Ts": "Tennessine", + "Og": "Oganesson", +} + +def main(config): + line1 = config.str("line1", "") + line2 = config.str("line2", "") + show_smoke = config.bool("show_image", True) + + return render.Root( + child = render.Stack( + children = [ + render.Image(src = SMOKE) if show_smoke else None, + get_display_children_for_given_breakdown(1, find_element_symbol(line1)), + get_display_children_for_given_breakdown(2, find_element_symbol(line2)), + ], + ), + delay = 1, + ) + +def get_display_children_for_given_breakdown(row, breakdown): + items = [] + + height_offset = 1 + 15 * (int(row) - 1) + left_offset = 1 + 3 * (int(row) - 1) + text_height_difference = 2 + + prefix = breakdown[0] + element = breakdown[1] + suffix = breakdown[2] + + if (len(prefix) > 0): + items.insert(len(items), add_padding_to_child_element(render.Text(prefix.strip(), font = FONT), left_offset, height_offset + text_height_difference)) + + left_offset = left_offset + 6 * len(prefix) + + if (len(element) > 0): + items.insert(len(items), add_padding_to_child_element(get_element_box_children(element), left_offset, height_offset)) + left_offset = left_offset + 14 + + if (len(suffix) > 0): + items.insert(len(items), add_padding_to_child_element(render.Text(suffix.strip(), font = FONT), left_offset, height_offset + text_height_difference)) + + return render.Stack(items) + +def get_element_box_children(element): + return render.Box(width = 13, height = 14, color = WHITE, child = render.Box(width = 11, height = 12, color = ELEMENT_GREEN, child = add_padding_to_child_element(render.Text(element), 1))) + +def find_element_symbol(name): + for length in (2, 1): # Check 2-letter symbols first, then 1-letter + for i in range(len(name) - (length - 1)): + if name[i:i + length].capitalize() in elements: + return name[:i], name[i:i + length].capitalize(), name[i + length:] + + return name, "", "" + +def add_padding_to_child_element(element, left = 0, top = 0, right = 0, bottom = 0): + padded_element = render.Padding( + pad = (left, top, right, bottom), + child = element, + ) + + return padded_element + +def get_schema(): + return schema.Schema( + version = "1", + fields = [ + schema.Text( + id = "line1", + name = "Line 1", + desc = "First Name", + icon = "pencil", + ), + schema.Text( + id = "line2", + name = "Line 2", + desc = "Last Name", + icon = "pencil", + ), + schema.Toggle( + id = "show_image", + name = "Show background image?", + desc = "Display the smoking background?", + icon = "fireFlameCurved", + ), + ], + ) diff --git a/apps/breakingbad/breakingbad.webp b/apps/breakingbad/breakingbad.webp new file mode 100644 index 000000000..29d03b038 Binary files /dev/null and b/apps/breakingbad/breakingbad.webp differ diff --git a/apps/breakingbad/manifest.yaml b/apps/breakingbad/manifest.yaml new file mode 100644 index 000000000..ed9a3f3d4 --- /dev/null +++ b/apps/breakingbad/manifest.yaml @@ -0,0 +1,6 @@ +--- +id: breakingbad +name: BreakingBad +summary: Breaking Bad title display +desc: Display text in Breaking Bad TV show format. +author: Robert Ison diff --git a/apps/breakingbad/readme.md b/apps/breakingbad/readme.md new file mode 100644 index 000000000..ff9d80a17 --- /dev/null +++ b/apps/breakingbad/readme.md @@ -0,0 +1,5 @@ +Breaking Bad for Tidbyt + +Create your own Credit in the Breaking Bad format. + +![Breaking Bad for Tidbyt](breakingbad.webp) diff --git a/apps/compactstocks/README.md b/apps/compactstocks/README.md index e8b335415..cc17a856c 100644 --- a/apps/compactstocks/README.md +++ b/apps/compactstocks/README.md @@ -10,4 +10,4 @@ Check out the official [Tidbyt documentation](https://tidbyt.dev/docs/) for inst ## Update frequency -The app fetches new data once an hour. This interval is chosen because the free tier of APIStocks allows 5000 requests per month. Considering that we are showing 5 stocks, that's 1000 requests per stock per month, which is about once an hour. If you have a paid subscription and can afford more frequent updates, you can change the interval by modifying the `ttl_seconds` variable. +The app fetches new data once an hour. This interval is chosen because the free tier of APIStocks allows 5000 requests per month. Considering that we are showing 5 stocks, that's 1000 requests per stock per month, which is about once an hour. If you have a paid subscription and can afford more frequent updates, you can change the interval by modifying the `TTL_SECONDS` variable. diff --git a/apps/compactstocks/demo.jpg b/apps/compactstocks/demo.jpg index e3415f9f6..0b4d75827 100644 Binary files a/apps/compactstocks/demo.jpg and b/apps/compactstocks/demo.jpg differ diff --git a/apps/compactstocks/stocks.star b/apps/compactstocks/stocks.star index 1c3998801..ba1ce5eb7 100644 --- a/apps/compactstocks/stocks.star +++ b/apps/compactstocks/stocks.star @@ -12,6 +12,8 @@ load("schema.star", "schema") APISTOCKS_HOST = "apistocks.p.rapidapi.com" APISTOCKS_URL = "https://apistocks.p.rapidapi.com/intraday" +TTL_SECONDS = 3600 + def fetch_data(symbol, api_key): rep = http.get(APISTOCKS_URL, headers = { "x-rapidapi-host": APISTOCKS_HOST, @@ -20,7 +22,7 @@ def fetch_data(symbol, api_key): "symbol": symbol, "interval": "5min", "maxreturn": "144", # Get last 12 hours of data - }, ttl_seconds = 3600) + }, ttl_seconds = TTL_SECONDS) if rep.status_code != 200: print("Stock API request failed with status %d" % rep.status_code) return None @@ -51,17 +53,93 @@ def calculate_last_day_percentage(data): return move_percentage -def render_entry(symbol, color, close_price, percentage): +# Format the price to 2 decimal places and pad to 7 characters. +def format_price(close_price): + price_value = int(close_price * 100 + 0.5) / 100.0 + price_parts = str(price_value).split(".") + if len(price_parts) == 1: + price_str = price_parts[0] + ".00" # If there's no decimal part, add ".00" + elif len(price_parts[1]) == 1: + price_str = price_parts[0] + "." + price_parts[1] + "0" # If there's only 1 decimal digit, add a 0 + else: + price_str = price_parts[0] + "." + price_parts[1][:2] # Limit to two decimal places + + # Pad the price to 7 characters for alignment + if len(price_str) < 7: + price_str = " " * (7 - len(price_str)) + price_str + return price_str + +# Format the percentage +def format_percentage(percentage): percentage_abs = abs(percentage) - return render.Marquee( - width = 64, - child = render.Row( - children = [ - render.Text("%s " % (symbol), font = "tom-thumb", color = color), - render.Text("%s " % (int(close_price * 100) / 100), font = "tom-thumb"), - render.Text("%s%%" % (int(percentage_abs * 10) / 10), font = "tom-thumb", color = "#f00" if percentage < 0 else "#0f0"), - ], - ), + percentage_value = int(percentage_abs * 10 + 0.5) / 10.0 + if percentage_value >= 100: + # Remove decimal for values >= 100 + percentage_str = str(int(percentage_value)) + "%" + else: + percentage_str = str(percentage_value) + "%" + if len(percentage_str) < 5: + percentage_str = " " * (5 - len(percentage_str)) + percentage_str + return percentage_str + +# Pad or truncate the symbol to a fixed width of 4 characters. +def pad_symbol(symbol): + if len(symbol) < 4: + return symbol + " " * (4 - len(symbol)) + return symbol[:4] + +# Format the symbol, price, and percentage +def render_entry(symbol, color, close_price, percentage): + symbol_padded = pad_symbol(symbol) + price_str = format_price(close_price) + percentage_str = format_percentage(percentage) + percentage_color = "#f00" if percentage < 0 else "#0f0" + + # Create the symbol column + symbol_column = render.Column( + cross_align = "start", + children = [ + render.Text( + symbol_padded, + font = "tom-thumb", + color = color, + ), + ], + ) + + # Create the price column + price_column = render.Column( + cross_align = "end", + children = [ + render.Text( + price_str, + font = "tom-thumb", + color = "#fff", + ), + ], + ) + + # Create the percentage column + percentage_column = render.Column( + cross_align = "end", + children = [ + render.Text( + percentage_str, + font = "tom-thumb", + color = percentage_color, + ), + ], + ) + + # Create the main row with space between the columns + return render.Row( + main_align = "space_between", + expanded = True, + children = [ + symbol_column, + price_column, + percentage_column, + ], ) def main(config): @@ -95,14 +173,19 @@ def main(config): symbol = data["Metadata"]["Symbol"] latest = data["Results"][-1] close_price = latest["Close"] - render_children.append(render_entry(symbol, color, close_price, calculate_last_day_percentage(data))) + percentage_change = calculate_last_day_percentage(data) + render_children.append( + render_entry(symbol, color, close_price, percentage_change), + ) else: # Example data - render_children.append(render_entry("XMPL1", "#8ff", 114.5, 1.4) if symbol == "_EX1" else render_entry("XMPL2", "#f8f", 233.8, -6.6)) + render_children.append(render_entry("XMP1", "#8ff", 114.5, 1.4) if symbol == "_EX1" else render_entry("XM2", "#f8f", 33.8, -6.6)) return render.Root( - render.Box( - child = render.Column(children = render_children), + render.Column( + children = render_children, + main_align = "center", + expanded = True, ), ) diff --git a/apps/congresswatch/congress_watch.star b/apps/congresswatch/congress_watch.star index 1c0025b49..bdf39e01d 100644 --- a/apps/congresswatch/congress_watch.star +++ b/apps/congresswatch/congress_watch.star @@ -14,14 +14,15 @@ load("schema.star", "schema") #Keep Track of Settings load("secret.star", "secret") #Encrypt the API Key load("time.star", "time") #Ensure Timely display of congressional actions -API_KEY = "IwiU6rcUFvTMiiVCz1HXblunVhKixvY5L3mDTHsU" +API_KEY = "" #Remove before committing API_KEY_ENCRYPTED = "AV6+xWcEONGMeP4KdGqCO9aQ5vhdBFz4VLyxinpFW+SIsoiYmqcCR33CU6kNEc01NR/ywxYUNJl0CeNkNTZ/lT8rDEjKlENdTMU8/A8YsYjnrUhnq6QLIeO6BRVtGRTwcILtm0fPZrEWId8Ta4cETXU09Ib6LO8AYeHorr0mvi2wNiNn776WxcF+UIkBXg==" # CONGRESS_API_URL = "https://api.congress.gov/v3/" CONGRESS_SESSION_LENGTH_IN_DAYS = 720 #730, but we'll shorten it some to make sure we don't miss CONGRESS_BILL_TTL = 12 * 60 * 60 #12 hours * 60 mins/hour * 60 seconds/min MAX_ITEMS = 50 - -senate_icon = base64.decode("""iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAw3pUWHRSYXcgcHJvZmlsZSB0eXBlIGV4aWYAAHjabVBbDsMgDPvPKXaEvArhOHTtpN1gx1+AtCpVLeE6ceRCYP99P/BqYFLQJVsqKaFDixauLgwHamdC7RwFHmLqw2mwt8S/MkpLMX/0Cackqq6WS5C9w1hno2jk2y0ofiTtRuxii6ASQcLDoAio41mYiuXrE9YdZ9g40Ehyzz5D7rVm3962eFOYdyFBZ5E0LiDtKEh1kTubD5KYa3GrxiiNhTzt6QD8Ad0yWR/a/LVjAAABhGlDQ1BJQ0MgcHJvZmlsZQAAeJx9kT1Iw0AcxV9TpUUqDhYREcxQXbSLijjWKhShQqgVWnUwufQLmjQkLS6OgmvBwY/FqoOLs64OroIg+AHi7OCk6CIl/i8ptIjx4Lgf7+497t4BQqPMNKsrBmh61Uwl4mImuyoGXhFAEAMYwbjMLGNOkpLwHF/38PH1LsqzvM/9OXrVnMUAn0gcY4ZZJd4gntmsGpz3icOsKKvE58QTJl2Q+JHristvnAsOCzwzbKZT88RhYrHQwUoHs6KpEU8TR1RNp3wh47LKeYuzVq6x1j35C0M5fWWZ6zSHkcAiliBBhIIaSiijiiitOikWUrQf9/APOX6JXAq5SmDkWEAFGmTHD/4Hv7u18lOTblIoDnS/2PbHKBDYBZp12/4+tu3mCeB/Bq70tr/SAGY/Sa+3tcgR0LcNXFy3NWUPuNwBBp8M2ZQdyU9TyOeB9zP6pizQfwv0rLm9tfZx+gCkqavkDXBwCIwVKHvd493Bzt7+PdPq7wey3HLAo6VLtgAADXppVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+Cjx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDQuNC4wLUV4aXYyIj4KIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIgogICAgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIKICAgIHhtbG5zOkdJTVA9Imh0dHA6Ly93d3cuZ2ltcC5vcmcveG1wLyIKICAgIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIKICAgIHhtbG5zOnRpZmY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vdGlmZi8xLjAvIgogICAgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIgogICB4bXBNTTpEb2N1bWVudElEPSJnaW1wOmRvY2lkOmdpbXA6YjdkNmM1YmItMDllNC00NjZjLWJmODgtNTMzYWU2N2NhYjNmIgogICB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjQwNzg2NmRlLTU4NTktNGY0ZC05ZWVmLTgyMmFjZDEwNWMxMCIKICAgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOmM5Y2NiOWUyLTA3OGQtNGNiZi1hMDhjLTZkOWIyMTFlNmI3OSIKICAgR0lNUDpBUEk9IjIuMCIKICAgR0lNUDpQbGF0Zm9ybT0iTWFjIE9TIgogICBHSU1QOlRpbWVTdGFtcD0iMTcyMDQ3Nzk1ODYxNjM0NyIKICAgR0lNUDpWZXJzaW9uPSIyLjEwLjM2IgogICBkYzpGb3JtYXQ9ImltYWdlL3BuZyIKICAgdGlmZjpPcmllbnRhdGlvbj0iMSIKICAgeG1wOkNyZWF0b3JUb29sPSJHSU1QIDIuMTAiCiAgIHhtcDpNZXRhZGF0YURhdGU9IjIwMjQ6MDc6MDhUMTg6MzI6MzYtMDQ6MDAiCiAgIHhtcDpNb2RpZnlEYXRlPSIyMDI0OjA3OjA4VDE4OjMyOjM2LTA0OjAwIj4KICAgPHhtcE1NOkhpc3Rvcnk+CiAgICA8cmRmOlNlcT4KICAgICA8cmRmOmxpCiAgICAgIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiCiAgICAgIHN0RXZ0OmNoYW5nZWQ9Ii8iCiAgICAgIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6ZGYzYjJhMGItNzg4NC00ODMzLTk0NzEtOTI1MjYwODliN2I4IgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJHaW1wIDIuMTAgKE1hYyBPUykiCiAgICAgIHN0RXZ0OndoZW49IjIwMjQtMDctMDhUMTg6MzI6MzgtMDQ6MDAiLz4KICAgIDwvcmRmOlNlcT4KICAgPC94bXBNTTpIaXN0b3J5PgogIDwvcmRmOkRlc2NyaXB0aW9uPgogPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIAo8P3hwYWNrZXQgZW5kPSJ3Ij8+OdIajgAAAAZiS0dEAOAApAAro1pwXAAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB+gHCBYgJh51uS0AAABISURBVDjLY2CgEDDikvj///9/FIWMjIxEGYCuEUMDmkGMxGrEZRAjOZqRDWGiNBCpYwBywKCz8clRzwWjBlAhM1GSEil1AAMANBoUMIVLXC0AAAAASUVORK5CYII=""") +SAMPLE_CONGRESS_BODY = """{"congress": {"endYear": "2024", "name": "118th Congress", "number": 118, "sessions": [{"chamber": "House of Representatives", "endDate": "2024-01-03", "number": 1, "startDate": "2023-01-03", "type": "R"}, {"chamber": "Senate", "endDate": "2024-01-03", "number": 1, "startDate": "2023-01-03", "type": "R"}, {"chamber": "Senate", "number": 2, "startDate": "2024-01-03", "type": "R"}, {"chamber": "House of Representatives", "number": 2, "startDate": "2024-01-03", "type": "R"}], "startYear": "2023", "updateDate": "2023-01-03T17:43:32Z", "url": "https://api.congress.gov/v3/congress/118?format=json"}, "request": {"contentType": "application/json", "format": "json"}}""" +SAMPLE_CONGRESS_DATA = """{"bills":[{"congress":118,"latestAction":{"actionDate":"2024-09-10","text":"TEST DATA: Referred to the House Committee on Ways and Means."},"number":"9518","originChamber":"House","originChamberCode":"H","title":"TEST DATA: BRAVE Act of 2024","type":"HR","updateDate":"2024-11-05","updateDateIncludingText":"2024-11-05","url":"https://api.congress.gov/v3/bill/118/hr/9518?format=json"},{"congress":118,"latestAction":{"actionDate":"2024-09-10","text":"TEST DATA: Referred to the House Committee on Ways and Means."},"number":"9522","originChamber":"House","originChamberCode":"H","title":"TEST DATA: To amend the Internal Revenue Code of 1986 to modify the railroad track maintenance credit.","type":"HR","updateDate":"2024-11-05","updateDateIncludingText":"2024-11-05","url":"https://api.congress.gov/v3/bill/118/hr/9522?format=json"}],"pagination":{"count":88,"next":"https://api.congress.gov/v3/bill/118?sort=updateDate desc&fromDateTime=2024-11-04T00:00:00Z&offset=50&limit=50&format=json"},"request":{"congress":"118","contentType":"application/json","format":"json"}}""" +CONGRESS_ICON = base64.decode("""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""") period_options = [ schema.Option( @@ -75,47 +76,60 @@ scroll_speed_options = [ def main(config): api_key = secret.decrypt(API_KEY_ENCRYPTED) or API_KEY - #Get the current congress - congress_session_url = "%scongress/current?API_KEY=%s&format=json" % (CONGRESS_API_URL, api_key) - congress_session_body = cache.get(congress_session_url) + #initialize + senate_start = None + house_start = None + congress_number = "" - if congress_session_body == None: - print("Cache Expired, getting new session info") - congress_session_body = http.get(url = congress_session_url).body() + if api_key == "": + #test environment or app preview + congress_session_body = json.decode(SAMPLE_CONGRESS_BODY) + congress_data = json.decode(SAMPLE_CONGRESS_DATA) - congress_session_body = json.decode(congress_session_body) + #Congress Session Info + congress_number = congress_session_body["congress"]["number"] + else: + #Get the current congress + congress_session_url = "%scongress/current?API_KEY=%s&format=json" % (CONGRESS_API_URL, api_key) + congress_session_body = cache.get(congress_session_url) - if congress_session_body == None: - #Error getting data - fail("Error: Failed to get data from cache or http get calling") + if congress_session_body == None: + congress_session_body = http.get(url = congress_session_url).body() - #Congress Session INfo - congress_number = congress_session_body["congress"]["number"] - senate_start = None - house_start = None + congress_session_body = json.decode(congress_session_body) + + if congress_session_body == None: + #Error getting data + fail("Error: Failed to get data from cache or http get calling") + + #Congress Session Info + congress_number = congress_session_body["congress"]["number"] - for i in range(0, len(congress_session_body["congress"]["sessions"])): - current_start_date = time.parse_time(congress_session_body["congress"]["sessions"][i]["startDate"], format = "2006-01-02") + for i in range(0, len(congress_session_body["congress"]["sessions"])): + current_start_date = time.parse_time(congress_session_body["congress"]["sessions"][i]["startDate"], format = "2006-01-02") - if congress_session_body["congress"]["sessions"][i]["chamber"] == "House of Representatives": - if house_start == None or house_start < current_start_date: - house_start = current_start_date - elif congress_session_body["congress"]["sessions"][i]["chamber"] == "Senate": - if senate_start == None or senate_start < current_start_date: - senate_start = current_start_date + if congress_session_body["congress"]["sessions"][i]["chamber"] == "House of Representatives": + if house_start == None or house_start < current_start_date: + house_start = current_start_date + elif congress_session_body["congress"]["sessions"][i]["chamber"] == "Senate": + if senate_start == None or senate_start < current_start_date: + senate_start = current_start_date - session_duration_days = (time.now() - senate_start).hours / 24 + session_duration_days = (time.now() - senate_start).hours / 24 - cache_ttl = int((CONGRESS_SESSION_LENGTH_IN_DAYS - session_duration_days) * 60 * 60 * 24) + cache_ttl = int((CONGRESS_SESSION_LENGTH_IN_DAYS - session_duration_days) * 60 * 60 * 24) - #let's cache this for what should be the rest of the session - cache.set(congress_session_url, json.encode(congress_session_body), ttl_seconds = cache_ttl) + #let's cache this for what should be the rest of the session + cache.set(congress_session_url, json.encode(congress_session_body), ttl_seconds = cache_ttl) - #Get Bill Data for past X days where X = the most days we search based on period options - bill_data_from_date = (time.now() - time.parse_duration("%sh" % config.get("period", period_options[-1].value) * 24)) - congress_bill_url = "%sbill/%s?limit=%s&sort=updateDate+desc&api_key=%s&format=json&fromDateTime=%sT00:00:00Z" % (CONGRESS_API_URL, congress_number, MAX_ITEMS, api_key, bill_data_from_date.format("2006-01-02")) + #Get Bill Data for past X days where X = the most days we search based on period options + bill_data_from_date = (time.now() - time.parse_duration("%sh" % config.get("period", period_options[-1].value) * 24)) + congress_bill_url = "%sbill/%s?limit=%s&sort=updateDate+desc&api_key=%s&format=json&fromDateTime=%sT00:00:00Z" % (CONGRESS_API_URL, congress_number, MAX_ITEMS, api_key, bill_data_from_date.format("2006-01-02")) + + congress_data = json.decode(get_cachable_data(congress_bill_url, CONGRESS_BILL_TTL)) + + #We have either live or test data, now display it. - congress_data = json.decode(get_cachable_data(congress_bill_url, CONGRESS_BILL_TTL)) filtered_congress_data = filter_bills(congress_data, config.get("period", period_options[0].value), config.get("source", source[-1].value)) number_filtered_items = len(filtered_congress_data) @@ -124,10 +138,13 @@ def main(config): #let's diplay a random bill from the filtered list random_number = randomize(0, number_filtered_items) + row1 = filtered_congress_data[random_number]["originChamber"] row2 = "%s%s %s" % (filtered_congress_data[random_number]["type"], filtered_congress_data[random_number]["number"], filtered_congress_data[random_number]["title"]) row3 = (filtered_congress_data[random_number]["latestAction"]["text"]) + #Fonts: 10x20 5x8 6x10-rounded 6x10 6x13 CG-pixel-3x5-mono CG-pixel-4x5-mono Dina_r400 tb-8 tom-thumb + return render.Root( render.Column( children = [ @@ -136,9 +153,9 @@ def main(config): render.Marquee( width = 47, height = 8, - child = render.Text(row1, font = "6x13", color = "#fff"), + child = add_padding_to_child_element(render.Text(row1, font = "6x10", color = "#fff"), 1), ), - render.Image(senate_icon), + render.Image(CONGRESS_ICON), render.Box(width = 1, height = 16, color = "#000"), ], ), @@ -176,6 +193,13 @@ def filter_bills(data, period, source): return filtered_data +def add_padding_to_child_element(element, left = 0, top = 0, right = 0, bottom = 0): + padded_element = render.Padding( + pad = (left, top, right, bottom), + child = element, + ) + return padded_element + def randomize(min, max): now = time.now() rand = int(str(now.nanosecond)[-6:-3]) / 1000 diff --git a/apps/customquotes/custom_quotes.star b/apps/customquotes/custom_quotes.star index 3a9541d2a..06249508e 100644 --- a/apps/customquotes/custom_quotes.star +++ b/apps/customquotes/custom_quotes.star @@ -1,7 +1,7 @@ """ Applet: Custom Quotes Summary: Display custom quotes -Description: Display quotes from a Gsheet like this https://docs.google.com/spreadsheets/d/1zDiMWjzZQqB6QRMhde0dOoptTjwdv6GalNHHYkUytAI/edit?usp=sharing +Description: Display quotes from a Google sheet with a quote and author column Author: vipulchhajer """ diff --git a/apps/fireflies/fireflies.star b/apps/fireflies/fireflies.star index 6cda8d26d..f7b168c13 100644 --- a/apps/fireflies/fireflies.star +++ b/apps/fireflies/fireflies.star @@ -11,59 +11,35 @@ load("schema.star", "schema") load("time.star", "time") # Tidbyt Constants -WIDTH = 64 -HEIGHT = 32 -HEIGHT_CLOCK = 26 +WIDTH, HEIGHT, HEIGHT_CLOCK = 64, 32, 26 # Colors -YELLOW = "#ffff00" -GREEN = "#ADFF2F" -ORANGE_RED = "#FF4500" -BLUE = "#0000FF" +YELLOW, GREEN, ORANGE_RED, BLUE = "#FFFF00", "#ADFF2F", "#FF4500", "#0000FF" # Firefly Properties -N_FIREFLIES = 10 -MAX_FIREFLIES = 50 -DELTA_LIGHTNESS = 14 -LIGHT_UP = 14 -MAX_LIGHTNESS = 70 +N_FIREFLIES, MAX_FIREFLIES, DELTA_LIGHTNESS, LIGHT_UP, MAX_LIGHTNESS = 10, 50, 14, 14, 70 # Animation Properties -DELAY = 250 -N_FRAMES = int(15 * 1000 / DELAY) +DELAY = 250 # Delay between frames in milliseconds +DURATION_SECONDS = 15 # Total animation duration in seconds +N_FRAMES = DURATION_SECONDS * 1000 // DELAY # Number of frames in the animation # Time Settings -DEFAULT_LOCATION = { - "lat": 38.8951, - "lng": -77.0364, - "locality": "Washington, D.C.", - "timezone": "America/New_York", -} - -# Indeces for Lists -FIREFLY_X = 0 # Firefly x-position -FIREFLY_Y = 1 # Firefly y-position -FIREFLY_HUE = 2 # Firefly hue -FIREFLY_LIGHTNESS = 3 # Firefly lightness -DATA_X_OFFSET = 0 # Offset for x location -DATA_Y_OFFSET = 1 # Offset for y location -DATA_PERIOD = 2 # Period of the sinusoidal formulas represting the x and y coordinates -DATA_A = 3 # Semi-major axis value -DATA_B = 4 # Semi-minor axis value -DATA_TIME_OFFSET = 5 # Time offset within the elliptical period -DATA_ROTATE = 6 # Ellipse rotation angle in degrees -DATA_LIGHTNESS_OFFSET = 7 # Index offset for the lightness -DATA_I0 = 8 # Index for lightness graph where y-values begin to increase from 0 -DATA_HUE = 9 # Hue value 0 <= hue < 360 in dgrees -DATA_LIGHTNESS_ON_OFF = 10 # Determines if firefly ever turns off or not +DEFAULT_LOCATION = {"lat": 38.8951, "lng": -77.0364, "locality": "Washington, D.C.", "timezone": "America/New_York"} + +# Firefly Indices +# 0: x-position, 1: y-position, 2: hue, 3: lightness +FIREFLY_X, FIREFLY_Y, FIREFLY_HUE, FIREFLY_LIGHTNESS = range(4) + +# Data Indices For Each Firefly +# 0: Offset for x location, 1: Offset for y location, 2: Period of the sinusoidal formulas representing the x and y coordinates +# 3: Semi-major axis value, 4: Semi-minor axis value, 5: Time offset within the elliptical period, 6: Ellipse rotation angle in degrees +# 7: Index offset for the lightness, 8: Index for lightness graph where y-values begin to increase from 0 +# 9: Hue value (0 <= hue < 360 in degrees), 10: Determines if firefly ever turns off or not +DATA_X_OFFSET, DATA_Y_OFFSET, DATA_PERIOD, DATA_A, DATA_B, DATA_TIME_OFFSET, DATA_ROTATE, DATA_LIGHTNESS_OFFSET, DATA_I0, DATA_HUE, DATA_LIGHTNESS_ON_OFF = range(11) # Display Text Properties -TEXT_FONT = "CG-pixel-3x5-mono" # Text font name -FONT_HEIGHT = 5 # Font height -RIGHT_ALIGN = "right" # Align type -LEFT_ALIGN = "left" -CENTER_ALIGN = "center" -TIME_COLOR = "#405678" # Color of time text +TEXT_FONT, FONT_HEIGHT, RIGHT_ALIGN, LEFT_ALIGN, CENTER_ALIGN, TIME_COLOR = "CG-pixel-3x5-mono", 5, "right", "left", "center", "#405678" def main(config): show_clock = config.bool("show_clock", False) @@ -80,7 +56,7 @@ def main(config): fireflies = [[0, 0, 0, 0] for _ in range(MAX_FIREFLIES)] now = time.now().in_location(timezone) - tm = seconds_since_midnight(now, DELAY / 1000) + sec_since_midnight = seconds_since_midnight(now) if delta_lightness == 2: N_lightness = 70 elif delta_lightness == 7: @@ -91,17 +67,17 @@ def main(config): frames = [] for t in range(N_FRAMES): - update_fireflies(fireflies, firefly_data, n_fireflies, now, tm, t, hue, rnd_color, delta_lightness, N_lightness, show_clock, speed) + update_fireflies(fireflies, firefly_data, n_fireflies, sec_since_midnight, t, hue, rnd_color, delta_lightness, N_lightness, show_clock, speed) frames.append(render_frame(generate_screen(fireflies), show_clock, timezone)) return render_animation(frames) -def update_fireflies(fireflies, firefly_data, n_fireflies, now, tm, t, hue, rnd_color, delta_lightness, N_lightness, show_clock, speed): +def update_fireflies(fireflies, firefly_data, n_fireflies, sec_since_midnight, t, hue, rnd_color, delta_lightness, N_lightness, show_clock, speed): for f in range(n_fireflies): - tt = tm + t * DELAY / 1000 + firefly_data[f][DATA_TIME_OFFSET] + tt = sec_since_midnight + t * DELAY / 1000 + firefly_data[f][DATA_TIME_OFFSET] theta = 2 * 3.141592653589793 * tt / firefly_data[f][DATA_PERIOD] / speed x, y = calculate_position(firefly_data[f], theta) - lightness = get_lightness(now, t, firefly_data[f][DATA_LIGHTNESS_OFFSET], LIGHT_UP, delta_lightness, firefly_data[f][DATA_I0], N_lightness, firefly_data[f][DATA_LIGHTNESS_ON_OFF]) + lightness = get_lightness(sec_since_midnight, t, firefly_data[f][DATA_LIGHTNESS_OFFSET], LIGHT_UP, delta_lightness, firefly_data[f][DATA_I0], N_lightness, firefly_data[f][DATA_LIGHTNESS_ON_OFF]) fireflies[f][FIREFLY_X] = x fireflies[f][FIREFLY_Y] = y @@ -127,12 +103,12 @@ def calculate_position(data, theta): return x % WIDTH, y % HEIGHT -def get_firefly_data(set): - # 0 1 2 3 4 5 6 7 8 9 10 - # [DATA_X_OFFSET, DATA_Y_OFFSET, DATA_PERIOD, DATA_A, DATA_B, DATA_TIME_OFFSET, DATA_ROTATE, DATA_LIGHTNESS_OFFSET, DATA_I0, DATA_HUE, DATA_LIGHTNESS_ON_OFF] - - if set == 1: - return [ +def get_firefly_data(set_number): + """Retrieve firefly data based on the selected set. + 0 1 2 3 4 5 6 7 8 9 10 + [DATA_X_OFFSET, DATA_Y_OFFSET, DATA_PERIOD, DATA_A, DATA_B, DATA_TIME_OFFSET, DATA_ROTATE, DATA_LIGHTNESS_OFFSET, DATA_I0, DATA_HUE, DATA_LIGHTNESS_ON_OFF]""" + firefly_sets = { + 1: [ [12, 29, 226.0, 27, 1, 2, 2.0, 5, 8, 28, 1], [10, 3, 210.0, 25, 1, 2, 45.0, 2, 7, 193, 1], [17, 16, 273.0, 19, 1, 3, 2.0, 2, 3, 26, 0], @@ -183,9 +159,8 @@ def get_firefly_data(set): [33, 3, 216.0, 27, 3, 3, 6.0, 9, 17, 140, 0], [44, 11, 171.0, 21, 4, 6, 42.0, 13, 21, 246, 0], [1, 13, 105.0, 24, 1, 4, 11.0, 9, 0, 169, 1], - ] - elif set == 2: - return [ + ], + 2: [ [0, 7, 100.0, 27, 2, 4, 37.0, 12, 10, 74, 0], [36, 15, 142.0, 18, 3, 7, 15.0, 12, 15, 257, 1], [10, 7, 139.0, 26, 2, 1, 19.0, 2, 26, 279, 0], @@ -236,9 +211,8 @@ def get_firefly_data(set): [39, 17, 65.0, 12, 1, 2, 23.0, 1, 21, 143, 0], [19, 15, 104.0, 14, 4, 7, 28.0, 6, 3, 282, 0], [8, 5, 64.0, 16, 2, 6, 17.0, 14, 1, 281, 1], - ] - elif set == 3: - return [ + ], + 3: [ [13, 21, 53.0, 22, 3, 1, 16.0, 14, 21, 19, 0], [0, 19, 132.0, 29, 4, 7, 43.0, 2, 26, 76, 1], [26, 9, 110.0, 26, 3, 6, 8.0, 14, 23, 317, 1], @@ -288,9 +262,8 @@ def get_firefly_data(set): [15, 10, 52.0, 24, 3, 1, 35.0, 13, 11, 279, 1], [39, 13, 135.0, 26, 4, 2, 30.0, 13, 2, 107, 0], [28, 17, 72.0, 15, 3, 7, 0.0, 1, 3, 349, 1], - ] - elif set == 4: - return [ + ], + 4: [ [41, 14, 134.0, 10, 2, 6, 5.0, 9, 17, 200, 0], [33, 26, 90.0, 29, 2, 5, 8.0, 0, 0, 310, 1], [51, 17, 70.0, 19, 3, 2, 24.0, 5, 11, 52, 1], @@ -341,81 +314,27 @@ def get_firefly_data(set): [25, 20, 100.0, 16, 2, 2, 7.0, 8, 0, 263, 1], [33, 16, 66.0, 22, 3, 4, 17.0, 12, 28, 139, 0], [12, 22, 86.0, 25, 2, 1, 8.0, 5, 7, 36, 1], - ] - else: - return [ - [12, 29, 226.0, 27, 1, 2, 2.0, 5, 8, 28, 1], - [10, 3, 210.0, 25, 1, 2, 45.0, 2, 7, 193, 1], - [17, 16, 273.0, 19, 1, 3, 2.0, 2, 3, 26, 0], - [63, 5, 129.0, 15, 1, 3, 27.0, 12, 18, 187, 1], - [24, 14, 229.0, 26, 2, 4, 15.0, 14, 16, 131, 1], - [20, 30, 200.0, 14, 2, 0, 17.0, 13, 17, 346, 1], - [55, 10, 216.0, 20, 4, 4, 29.0, 11, 29, 145, 1], - [18, 21, 262.0, 29, 4, 2, 35.0, 10, 26, 127, 1], - [40, 30, 144.0, 17, 1, 7, 36.0, 8, 11, 299, 1], - [14, 26, 114.0, 19, 3, 5, 43.0, 11, 10, 176, 0], - [11, 16, 160.0, 14, 4, 2, 9.0, 2, 18, 84, 0], - [23, 4, 108.0, 12, 1, 7, 42.0, 7, 12, 207, 1], - [59, 26, 114.0, 13, 4, 6, 18.0, 12, 29, 100, 0], - [63, 17, 179.0, 23, 2, 3, 13.0, 3, 10, 155, 0], - [25, 4, 165.0, 26, 3, 5, 3.0, 8, 30, 271, 1], - [47, 31, 252.0, 25, 3, 4, 35.0, 12, 12, 290, 1], - [56, 13, 246.0, 16, 4, 5, 24.0, 6, 24, 321, 1], - [30, 20, 250.0, 20, 4, 2, 3.0, 7, 7, 171, 0], - [15, 5, 102.0, 29, 3, 0, 2.0, 4, 12, 121, 1], - [48, 10, 246.0, 16, 3, 2, 0.0, 3, 3, 293, 1], - [51, 11, 191.0, 24, 1, 5, 42.0, 7, 10, 192, 1], - [37, 12, 178.0, 21, 1, 4, 23.0, 11, 19, 324, 0], - [38, 20, 284.0, 28, 2, 0, 30.0, 2, 17, 129, 1], - [48, 16, 287.0, 12, 4, 5, 30.0, 7, 10, 234, 1], - [20, 2, 128.0, 23, 4, 1, 18.0, 11, 30, 344, 1], - [10, 28, 170.0, 23, 1, 5, 8.0, 6, 13, 157, 0], - [15, 13, 240.0, 23, 3, 1, 24.0, 14, 25, 229, 1], - [13, 5, 207.0, 18, 2, 3, 31.0, 0, 20, 24, 0], - [60, 20, 149.0, 19, 2, 7, 21.0, 7, 14, 145, 0], - [7, 6, 147.0, 26, 2, 4, 1.0, 12, 4, 67, 1], - [36, 15, 196.0, 28, 4, 1, 22.0, 9, 8, 170, 0], - [3, 14, 121.0, 14, 3, 5, 12.0, 6, 1, 284, 1], - [56, 0, 263.0, 13, 1, 3, 33.0, 2, 20, 263, 0], - [27, 3, 281.0, 28, 3, 4, 11.0, 4, 19, 235, 0], - [27, 14, 185.0, 12, 4, 0, 22.0, 7, 7, 151, 1], - [29, 26, 229.0, 19, 3, 1, 26.0, 2, 10, 133, 1], - [15, 31, 177.0, 19, 4, 7, 43.0, 7, 10, 327, 1], - [46, 16, 117.0, 19, 2, 5, 0.0, 0, 15, 91, 1], - [6, 23, 128.0, 14, 1, 3, 41.0, 13, 13, 23, 1], - [63, 1, 186.0, 12, 3, 3, 4.0, 13, 7, 76, 1], - [60, 8, 195.0, 17, 1, 6, 9.0, 12, 0, 262, 0], - [7, 12, 191.0, 29, 4, 3, 8.0, 1, 28, 219, 1], - [31, 8, 114.0, 23, 2, 6, 34.0, 14, 10, 76, 1], - [47, 28, 210.0, 16, 3, 2, 7.0, 8, 19, 174, 1], - [37, 9, 183.0, 21, 4, 6, 4.0, 4, 5, 276, 1], - [26, 27, 295.0, 10, 4, 3, 20.0, 14, 20, 294, 1], - [28, 7, 149.0, 27, 2, 7, 38.0, 4, 5, 285, 1], - [33, 3, 216.0, 27, 3, 3, 6.0, 9, 17, 140, 0], - [44, 11, 171.0, 21, 4, 6, 42.0, 13, 21, 246, 0], - [1, 13, 105.0, 24, 1, 4, 11.0, 9, 0, 169, 1], - ] + ], + } -def seconds_since_midnight(current_time, resolution): - seconds = current_time.hour * 3600 + current_time.minute * 60 + current_time.second + (current_time.nanosecond / 1000000000) - return step_round(seconds / resolution) * resolution + # Return the requested set or default to set 1 if the set number is invalid. + return firefly_sets.get(set_number, firefly_sets[1]) -def calculate_index(now, delta_lightness): - seconds_since_midnight = (now.hour * 3600) + (now.minute * 60) + now.second + (now.nanosecond / 1000000000) - return int(seconds_since_midnight / 0.25) % delta_lightness +def seconds_since_midnight(current_time): + seconds = current_time.hour * 3600 + current_time.minute * 60 + current_time.second + t_mod = (seconds + 14) // 15 * 15 + return t_mod -def step_round(number): - int_part = int(number) - fractional_part = number - int_part - return int_part if fractional_part <= 0.5 else int_part + 1 +def calculate_index(sec_since_midnight, delta_lightness): + return int(sec_since_midnight * 1000 / DELAY) % delta_lightness -def get_lightness(now, t, idx_offset, delta_lightness_1, delta_lightness_2, i0, N_lightness, darkness): +def get_lightness(sec_since_midnight, t, idx_offset, delta_lightness_1, delta_lightness_2, i0, N_lightness, darkness): # Calculate the total lightness steps total_lightness_steps = MAX_LIGHTNESS * (1 / delta_lightness_1 + 1 / delta_lightness_2) N_lightness = i0 + int(total_lightness_steps) # Calculate the index - idx = (calculate_index(now, N_lightness) + t + idx_offset) % N_lightness + idx = (calculate_index(sec_since_midnight, N_lightness) + t + idx_offset) % N_lightness # Define thresholds im = i0 + MAX_LIGHTNESS / delta_lightness_1 @@ -606,14 +525,14 @@ def get_schema(): schema.Toggle( id = "rnd_color", name = "Random Colors", - desc = "Enable random colors.", + desc = "Enable random colors for fireflies.", icon = "sliders", default = False, ), schema.Toggle( id = "show_clock", name = "Show Clock", - desc = "Enable displaying time.", + desc = "Enable displaying current time.", icon = "sliders", default = False, ), diff --git a/apps/halloweencountdn/halloween_countdn.star b/apps/halloweencountdn/halloween_countdn.star index 4246ee61b..b0f22af1f 100644 --- a/apps/halloweencountdn/halloween_countdn.star +++ b/apps/halloweencountdn/halloween_countdn.star @@ -14,7 +14,7 @@ def main(config): ghost_gif = base64.decode("R0lGODdhmQClANUAAAAAAAwMDBMTExwcHCMiIigmJiwrKzAvLzMyMjg2Njw8PEE+PkNDQ0lGRkxLS1JPT1RTU1lWVl1cXGBcXGNiYmlmZmxqanFubnRycnp2dnx8fIJ+foOCgoqGho2MjJGNjZSSkpuWlp2cnKOenqSjo6mjo6urq7GurrS0tLm3t7y8vMLCwszMzNPT09zb2+Df3+Li4ujn5+zs7PDv7/Ly8vj39////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAVkADcALAAAAACZAKUAAAb/QIBwSCwaj8ikcslsOp/QqHRKrVqv2Kx2y+16v+CweEwum8/otHrNbrvf8Lh8Tq/b7/i8fs/vUwUQIDaDhIMiEgJ+iksSI4WPkIMWiYuLDJGYmReVewEhmaCZIZx3oaagCKRyDqetmBiqbx+utJAjsWsCtbuQCrhnELzCj79kGcPIhJvFXxbJz4OUzFqX0NAg01rW2zYB2Vbc3BzfU+HmBuRPs+bhsOlLGOzsGe9JCvLyD/VH+PgN+0T69RsAEEA1gfIKIuz3Yd9Cgd7SsXrY7x1FgQS/ObpYMZsujv2kFQMpcBQzBCQFTkspUKSqj7tMGAggIACBFs9MWNBwbSQv/w1HBsDgRYMBkQBDk/0KwIuCEhS7CBxBIAOZy0obXcm4asQFLV9JJvK6FasWDa5GDpoat8TAsFj3aKFrwrSVExHCJKgiQcsDlFZ66b4lVQstErtPBnOitSLKKRJQaAhbQNiVOycwQTmAUvUnpwFfoajNJDWxYkXrWpW+e8owv9N+aq1uItlURCfIKhGoBbbJ7lMZmwSDzQcvLaBO+J6C8KSzsN59dslwItYUCyd1h0VQNFo1Ewq1jDJ5Fjg6r+tJAnjdlUpJZmGX+QwTgQTlMAtKWDzz26f6LhbtCYAABvols9kRwyVDlnwsgXLbEG5Bs+AeDYIiQ3AAxAVNQ3zYV/9hJihggAFO2zjFxycfctQehSlyhGEeLXLkmhwRxvjQg3hccJEMEihgHEszxiHjEOulFCQcFzE3RIIkHfnGQ/wV4YyRexSwEHpHeJASjnYcg1B5RxR5EYMILeHhmCwKRN8StaGpx0JcGqElR3ucKU9jTHRXph48YdSEnQul2VGeIAkqD35NTOkmHgjFeQRUdL6pEm6F5gFaPyY4cWmkeDQgEHRK9MnpHRy0RGmljE7KxG+olqLqEmIuaseebbEk6aBKtNlqHe+xsyISipKUxwEIYXlEjSnlESw+Lw6xqa14KCeQsUP0KmyqC7E1BKsVwkgRCwwMgIAgLXprI0drunr/7kUcqrvuQ+3O+i5FE9Yxr6x03EuRufq+Skd2/eJKB7cBJ3SHngVzg8cGCQs8R8MOywExPthOHE7FFm+DccbQbMwxMiV4/DF8Io/M3h0LmAyNo0+q/EzJLrtyB6Ax13JHPDWTLG/OvDQrJM+8wAx0JndYO3Qod/h3dCja0tHB0q4c4C7USE9NNdFWXx2J0FrbwLXWX/OiTwAl8FLavll3PATCmUDHy1zPgrJB2DZkJIEpFRRxt8xH0WKEd2k/os8QND/CJd9FIB7QKXk8DYp425ryGuNGAAzKEWwTUu/AoED2NyhzFcFkJqEnbsqvi19+69ZHZAUJNodJHnvVRxD8nMjcqz/StOmsI6EjKGAWwTAosM/eO7/EJDG6DekmQXtQobAMQNyEFJ9HBZDEi4SGNpSuRCaof47J5kakVkhshYDaRSS7HxEB1uM9oiQfDxAivRalEjL/EqIW4iQAv7PB/goyhQXMxgkPAMEIOKA+AjrwgRCMoAQnSMEKWvCCGMygBjfIwQ568IMgDKEIR0jCEprwhChMoQpXmIYgAAAh+QQFZAA3ACwVAAIAawCPAAAG/8CbcEgsGo/IZHEDszmfNhjIoaxar9hsViKCer9OmkVLLpuvAbB6bcuc33CsAESjse/QOkgQ7/sVdXiCXzQDfodmgIOLXjQehoiRSgwjdoyXTycEkpxFGpaYoTY0Gp2dGqKpYaSmhxAtqrFOLA+tcBKwsjZIizQttmcusWR4MG7AWbmYfXcwyFcroZFsLmPPSMqDrWsyztdFGTWMwGwwFN9CEzLjyGwyF+hN2uhrMwHX8oLoRGowkLb58Owr0u+fqUUDj4DxZypAQDYJeX15xMnhvIgSn9BQUPEixoxOYHBENCCawI9WoIz0E6CDR5RJnrBAcGjAupMwUzpZCaekvv+cWJyA4HlmwE+gQWVgiIPAJESkWmyUgqPgKBEZJCQ42CrBhZ8VIETQ8IMiwRsELHASgaGBQAAAcAMggCDjDA0MDAwMGMBgRZ+7b6reObLCggC4iBErUGEGwuHEBiSwGPuGQ9Eug4nQIIHgcWLIXrOIefsZQIDIjM+oIIoFgbCnRFQwKE3bgxYUA2gjFiD5TIwKidTeMOFAd2kClK3QmG08LobQZUBs0mIAFWwhLRiQbo44eRUS3BFXP9PCshYLr9UY0eA5PADvSWgYcA+XwRu/WqyvKQKDOf330PwHAGtZ4JeFfmAYYQIBAgYA3xFKCQjIGSwYkN91QhgmoAF2VAH/AwISviGDbVgQQMJ+RmgXHhEWgJKEP80RAReBBWZBwUNQHKHAdroVoYIXSMDA42dHMLDLGSsAgAUHGArhwJBEEhHATTkaAUN7iR0hAAVOIKmkFXOgaAQFWGZZhCJAWjlfaUgogNmRZCR5RVdiFkECg7QZIQAKCRohgwVsIvFJlVok+aUSTNZ5lX9mEjEABqAQWgQLQyJhYpqFHlYFAm9+oQR7gQ6hgAeKDjEaYkkkKikWLkRwKBJO9RmkY43eIIADOK6qmQS5vUrEpZ5qUQ1cSsQabBIrYICnkgEMgIAFwhmxh69CBIABlbp6uAGxSKDVpJ8kQMAAAxBYIEJ633pC/20AFPx4bBYxeMAtYZkFdckV2knpQDbZetjBvEYYi6m97FQhgwR6OUunemTAgAHAv6ZVahX3XjGLCCC0EOm7WGQH8RAiYMuxTghZXHCBtQ6R6xNlnExxyXGmLMTKXbZslcnRYmHoxxYxbPMdMsjwoBI3o4xqERjMMDHBCboggQLPRVVvzEevlS7TOcqwJgAgeIP1wFR/TDMnNMAAwXZuDh2TrGbsTO3YknAApQEkSA12GW4X0TPbfqgA5YypZdFvoSlnsPHgZ0DQHAW/JJS31T4fQgN3W0b0uMpLvwFCeBMOdPnMmZ/x92cmOp4y3Ieo4J4AS3le66B8x1HIiuzC+f/N54ezjAgMK9qKge3X4B46GTRIEOMQA4BQ8+215r78X6P7aoBT6AgfeRwyHD+EkYhLsnMRzkcignFF8HZ3K98P4eD1cGxEPhEMnHh+J+kLgeD8ZtAQvSexm1L/Dc4DXvveN4Qwjcx/VQPg8LQwuR6xSGTPs8X/woeIBoZKCAY8IP0SSEHJOXAI9+seIibIvvZtrVYQ4FMJNwiwDqbuggSQWP8QOK8KuNAPs2uUAAQmwhFWLQQLLIPqzLTDqQGjfgHsBAeyRACaRfCIVbthJFjAAAIggA45Q18UVyi5QBStFTHQwBZnOI0vtgIGgJqXFDnxEmCgcYwaLKMRkRGDDMD/EX+IyCIwhnioNbIxiCzsIxflGEdkIJGMf8QjMGgwPjUiMpFPRIcMxOjIQkJFEm/k1gVyd8lruEBx3FLaIzt5iBYo4Gjo6iEp48CCZQkBgpFcZSRWsB0hAFKWqjHTLXFJhhZQklu75GUWTMAoWw5SmGfwQHuMOUpkkmGJujymM59JpDQ0c5pZgCaqrGlJbIrmYVnipiK9iQUWFCdLApAmOa0wrSxJQJ3rTILT2ESqa8bzCCQ4IbG4ZM97FkGbWeJnN/2pIEahCgLwJOgQJFAmJSGgnwq9gUG5ZQCIEnQF+qSoRf35iDzdwCgDjagQMNDQaoVUpDewwN9MOk6U3kAG/xM9lDhjqQURaEADJoCOFlRwUxEg404eZabuqAKXyPh0p8whwFEbxoGmkigJoLzgyGDQVA6kwAoYhYyBrvBLABDgqdDgAAUQYxAjtABEQb3Bu1QgVsRQoQoU4BG7siACg5ZVCbL5zF1Z1NBXydB2eU3MXs9UGhrpqDQCAOunEGueI2QUYg5wkRCGpdcqeGBZiPnqFUSAWbJuNqb3OMIJ+mqE9IDslHqtCxJi0KvSDJawtHktEVBbmgBsdQjnTKsQPHATIcSAtokJgGKJsIHRDeAFHkKra72GBBkA9zOhjU1fqXUDD8Bit63V621vEIMVZBe61kgCSXUTAOAoAQTfDevuVt1HwCI4QAUwWIFyaWNbIqxAA9GDi09gNd/aCnAIzuWOQ0A2XepiMK7hse0KFpxfbtlWgDAi34ORIIL0mskaV+KOEgQkBPqobwXMLcz+qtWEgPU3gUJYgQvAqb0jeHgILx4CBRbM4BbfYMYgjkF8vftBGZ1NwxvuHYyFLKMYy+gCGRirjTvsnioQechLvsF/kGDkIkfZCFcGsoufbOUrS1nLQe5xEdqLZS5D2ctfFnMSyDxm3W6ZzV2G85kvGOYo1fljVJbznOn8Zjtfgc+RUHOZBd1nFDtZZpwAdKERnWdDdxLPh3Z0H4IAADs=") jack_gif = base64.decode("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") - timezone = config.get("timezone") or "America/New_York" + timezone = config.get("$tz", "America/New_York") now = time.now().in_location(timezone) halloween_year = now.year diff --git a/apps/partyparrot/.gitignore b/apps/partyparrot/.gitignore new file mode 100644 index 000000000..2badf7e04 --- /dev/null +++ b/apps/partyparrot/.gitignore @@ -0,0 +1 @@ +!demo.gif diff --git a/apps/partyparrot/demo.gif b/apps/partyparrot/demo.gif new file mode 100644 index 000000000..69ac7ad09 Binary files /dev/null and b/apps/partyparrot/demo.gif differ diff --git a/apps/partyparrot/manifest.yaml b/apps/partyparrot/manifest.yaml new file mode 100644 index 000000000..a297afe41 --- /dev/null +++ b/apps/partyparrot/manifest.yaml @@ -0,0 +1,8 @@ +--- +id: party-parrot +name: Party Parrot +summary: Animated party parrot +desc: 12 different party parrots to choose from. +author: tobyxdd +fileName: parrot.star +packageName: partyparrot diff --git a/apps/partyparrot/parrot.star b/apps/partyparrot/parrot.star new file mode 100644 index 000000000..9e9f04951 --- /dev/null +++ b/apps/partyparrot/parrot.star @@ -0,0 +1,122 @@ +""" +Applet: Party Parrot +Summary: Animated party parrot +Description: 12 different party parrots to choose from. +Author: tobyxdd +""" + +load("encoding/base64.star", "base64") +load("render.star", "render") +load("schema.star", "schema") + +GIFs = { + "normal": base64.decode(""" +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 +"""), + "fast": base64.decode(""" +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 +"""), + "stoked": base64.decode(""" +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 +"""), + "sassy": base64.decode(""" +R0lGODlhKwAgAOf/AAABAAgBAAAECAMGAggFCwcKBg4IBgQLDhIHDxIMCxILFhcLDA0QDAgRExwMEhsMGRAQGCENChATCBoOHhgSCg4VGx8QHB8RFBMVEiQQIygQGxwVDg0aDg0ZGSUTER8TIxUaEi4TEhYaJTAULiwYFw8gICMZLSMcExMhExofFzQWJDcUMjgXFysZLjIdHCkhFRsjMhUmJiAlHRUpFjsaO0MbHUAbLzQeNjMgPT0hIz0gOyIpOkcdRE0fHxotLDEoGicrIk0fN0EjP0gnJj4nR04iTjkvHy0yJVYmJVkkPx45Hx43NSczR1gkU0IrT1AsK18oKE0qTTA4KkkwVVkvMGIpYGssK2grSVkvVUU6JjY/MS4+WGsrZSZGJm8wL1kyXCRGR1I2YmE2N3UxUXozMk5BKjREXj1HOGY4ZXkydS1SLYE1WIY3NzdKaXE+PGE+cixSU0ZNOVdJMIY3YitYMnE9cjBWWDFbL5M9Pog6hj5Sc0tUP35FRZA9aW9IhYFFgaFDQWZWN0Faf09cRpg/kzZmODRjY6BDc45NT6FCnG1dPVVjTHxRlUpiiaVFn7NLS5dTUFpoUbFKfpRRk0B1QLBJq6FXVj9ycWBsUHlnQlNqmMNQUIpapZxXoMFPh2ZyVr9PuEWARK9gYKlcqEZ+fdVYWc1Vj111pZhjtW16XctUxop2TEuJS2x/YbxoaeRfXt1bm9VZzbhkuWN+sk2LiHGEZt1b2Kdtx+5iZOVgn1GWUcxvbpuBVHaKa+tiqfRmaOJg3cZrw2mIwXuMaFGWlv9paO1i5LN11s9v0PhmsVWhWtt3d2+Pylafof5st6uOXdZ21/pp8/9o912pWnSY1+Z/gMWA6+N74PGChVqsrbiZZHqg4WK1Y8+H+PmIhfGD8YGm6NeM//+Ni4Cr8/qI+GjCaGe+vsupbYaw+f+M/27LcIu1/mrGxnPTcdq3eHLPznjbeHzlfOrEf3jd24HtgX7l4/XPiIT1h4fv7P7WiYz6h4zz8Yj/iYD5+4f//////yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJBAD/ACwAAAAAKwAgAAAI/gD/CRxIsKDBgwgTKlzIsKHDhxAjAgjAYggJAAAiShwiqpq3j8sgsciokaEBS97EqVwpDhsikiURLnDFUpy3XbuqqbQEMybBALtq7hoyYIABPh/d9PQJwFLLIYhU1thTq9anFK7EXFhaEgAflbsweqsGINWws1qUAljgUyCAIdhUVqsRdRmAVmeH7RFDxc3LtgCCrkwpzm6tvHvcpHTF9SGAqDVVGs4bBzJZnwN0Rm4J4FPeM6JWPmnMEACkzSs9RMoLhKZKUaQXAliGWiWfOGdrGdAsLqzGtXFru0pxNhIJwoVjJwQQobZKbyEGDTvidKXd3wuC196FYVAE3r2Vlx/0GoG2c3Evv7KEHdHAMj6QnWMbYn7lEPEFHxdeINg5eHGXOfZEcKJE0N95K/nmEABP1CeOJQOIghyC7DUEgBvaJfhEDq5UkyFqFSrE4IE1eSOKGAmE4OBmIY7nAUoItrTMhJtdlxALK8Z4njceJASUjkC+RpoYQQa5TADjuYHTkkw26eSTTobAFUZUVmnllVhmiRFBAQEAIfkECQQA/wAsAAAAACsAIAAACP4A/wkcSLAgQQAIExpcyLBhQQBZeJ1z5+4cLyMAHGrUaICXvXwgQ9p7ZmCjyYM/zoVcGfIchZMmAbxwx9JexXMf850bAJOjSns55cnBAAREFppCezYEsApkpizy8vGS0mpYrTiZeP3IlFGpwR9R8yUAoFLOomFoMf34wbSA14e8Qq6S87HMWbSfAFx0J6fr238UwrLMEgntsLxA87kr+ReAIpYhCRv+ZGAlL79KAWiDDFLRHsNqWQbCDBMATc7PpBge1HSlO7deE3AGeS5FLbRSnkHm6vXH7HzyfnyyOuD0Sm2kTfr+zQtIrUFlOJ9LvrFATs72yuyRsRnyM+oayZ7+Vmxgw/WVq8A7BJBpvFTdnMv8HaDytz3BLF96lVnmvPuVWewnhzuBZOLff/l81xNESBnhEYIryVOGeg+VYZw7WQTizoHjTReTIvgBt8oJL2QS4njphWfgbPJow8uJv7lDIQCBcAjhbH019AKMN86GHEMAwNcjgu7wtNAAPA4JmTwbMLTBOVBGKeWUVFYppTZNLpTQllx26eWXCBUUEAAh+QQJBAD/ACwAAAAAKwAgAAAI/gD/CRxIsKDBgwgTKiQIAMDChxAFAuBAiRUrShwcRtw4EICSaff4ieR3j5sajRwfAqBEb6RLkqxQpkQIgFXIkffK6VKmTmQomTMZhrp3ryfJQiC0SGGgi1+5GUENemypDEA5pxJqDRv2iUPVAUCDWhVJCYAyftOObB1Wi8Edj2FTArgzEh6lePyUaVk7TIayUO2UxN049iU/XXH4yjDKbXBEBi0NK5OythaIdiLvlY0KoKlhpyAqM8ArMt4MxwoLG1YHQCtXJTdFlkOdcABpw/dmYNo6qNDLe11oH+Rw27CuM1tlcDPceCaKyJ/hMcD0aQb0ke2EGyxQ3PC0FFJYnH1mPRMA5s+ZKdn+PLu8Z/T84lFCv7n8efjXXdLhrOQ+/M8/iVVIAcv9F91pMw1ATzkoFOKfgaXpgoJ2EokXny4cqFFOdwbSo0xwEKFQXDzTFMLBVRC6dI8yGaVWoGHx5JciP/C8lVAXsc2YomZxATCNjkCSFGBBABgV5Iz3FAKUj+o06eSTUEYpZZTcFCBTQ1hmqeWWXHaZ5T8BAQAh+QQJBAD/ACwAAAAAKwAgAAAI/gD/CRxIsKDBgwgTKlzIsKHDhxAjSlwIoAMcQ2AaAJj4EAAYc/j6+euHLxuYjRwVDiAm0p/Ll/2yFUiJEIC5ly7nsZv30twAmgVt4sR3CYBRQ/VcEkMJFAAxf6QM4fNHTEqqYam0EGsG5l0JoAKXTDX6zt+SRcPSLoJTwqYdsEL9XYIzdUmktMM+NaC1pF4zphzBtBzp0gcmvJ8AEK7ngyaAZjhf+ribFlMHnNkARxzAM7I/OGjTRloSuWjgwTiJncG7h1bkeksmAiDl2aU5IHiPZPOcWaLT2v7qlfg0rBWAzkMP+N4NnJaWYYPgoH75NuJj4MGXDJJxszYc366xnZsDUGJq7a8Sl0yPTIu553maHQJwXxufec/v4jcE4CMp9v/EHKCfQgDEQNd//9VDzBIDHmSTIYashyBO/ZhjiFEMAVAPPnYgNeF//bxzYYP/HOcPPqQskY2EH7oUIhwNAsCOi+z4sAQt5rD4YUwd6Dcfhe80swRyLXpWDy0YEgSAIe806eSTUEYpJZTskDKAZkZlqeWWXHbppZb/BAQAIfkECQQA/wAsAAAAACsAIAAACP4A/wkcSLCgwYMIEypcyLChw4cQI0pMCACAiC1mdggAMPEhgDbMxqFbh26bJhgcO1KsIGzkupcwxzVKqbKgRWowc8JEp4lmTYEicOrcdkrTLHAkmfhUCUDYy21I1wlrcCROih1Qe/78B0DPSHAimKBDt2PQsLNaNCldOvHAtpfUKo4bV+HT2WGDzFTcwRYiAEE5NZ1aBw6C3bORmBRl1tcjM50vwR1IdTfxS3SCGjdkAjly3buD2sRk0hFAo84vYUS6u+c0TGYCJgKYhXrdFrNnj9DOmVkigMeoZx05W2uAUJjCNFME3nlbA8qRILiMqRzh79rrBGnpJWWwTnTVD5jOxg5uxxkAb3XG9Q0YO7MBrnXOCi/+OOpG9mHOl71lemf/OY2jR0URAcBEIwBip54gDdAnkFs7IKggeafw1RAM62zDRBvpTYjaOJqIUJ0IL40jiAiabJOgh0+1odwBOVHTxgFbNHJKfiyic0ps1uW3jTCntKEJi50x06B4mjCj5JJMNunkk0yeQqBNFVVp5ZVYZqnllAIFBAAh+QQJBAD/ACwAAAAAKwAgAAAI/gD/CRxIsKDBgwgTKlzIsKHDhxAjSpxIUSIAABUjXvxAhAgOBBgzLgQQ5pi1cOG6WUP1IaTIggAI3OqGsibKboxcvvwH4MMxm0BR5twpkMBPoMc4cUJ1stsUnRUB3EJp7WS4WwS07JHi0xonqBMBvKFpDQEOmmEGDVt7xg+Riy8BHD0Ws1s3HJ/WDltEZAKAFmAjEqEplFPKFqn0YiLCidGtARkBGA7a7UPitZic1PQT2CECq0C7tci7dlGYmt2cdGY4hXDQMJH0DvJj8xjkiW+C1nyjdu2RyTWHSmSkGyWqFGtrSUW6WiHt4tYm5MX0Iai15glPFw/H6EgtLcSBfl6fOOCo7tRaBoCuOd5i7u3HCDwXjx3hhwlTt3MyD/RNfZh+oGLCeqFtZw0O/w20nB848Leddf49NAFNOLXAiWsPhsYJAQ454dotLTDmYIYofdXQYDZ1c8tTOIRH4mb1mXDLjDTOyIkfb9So444zonKbQhcFKeSQRBY5ZEIBAQAh+QQJBAD/ACwAAAAAKwAgAAAI/gD/CRxIsKDBgwgTKlzIsKHDhxAjSpxIsaLFixgjAtiIAAGBjRkRbowi69q3b9egdUIAICRBAA+CkUtHs2a6b5NaugSA5ZrNnzRH6cQIIMo3oOSQyUJ2NN2foRYzQKNJrum3LwyOpFAAjVwwAkRH1fxDwKcsILWGDdsTRegAjFhm0hQCIJjTOGqHfRqABoACqBIByLI5CstRNHvytgIwiaSCikXl1pSLZZBiAF3T5aQIQCxQml8sq00FwOfNEZxNfx51Ji8mAJKFBsbyuaYsKXkHobH57UFgz7WhYUg77AzwdOSwBLZbG7mORWoxIPuJJvDU5ulkpai1aERTqkKsdGNHjubMkcE2rwFuCGD6+GsjCHwPun4hAAKdxtOUlZ+6RpIIuDfefDf59lBRPo2SwSiS6UcTMvWJZFRNwbQQRSfINIhdMBEepIBqNH0TDBofTXBccB0WVBQyLLbYIn+TjOLijC0Gg4BDG+Wo44489pjjQgEBACH5BAkEAP8ALAAAAAArACAAAAj+AP8JHEiwoMGDCBMqXMiwocOHECNKnEixosWLGDNq3MjxH4CPBBQE+Aig40AACPKoMiZNWjRboPIQKMkRABdbLXPqtJWHZkYAeaLpHJqz0oCfaYQSjVXJESiW0gj5pAigClRptqA6YqDlzBEexmzZ4mERwIirthBUEZoB07BhvWQ4GjGiZ0UEqnTGAkAjmjEAqd4OO1NlZKKpEAEkGhotDyhpwAALXtSEkCNjBCgWUUoUK4BWk7nkTIO4oeLOOf8GfrsnTdHSCz/mRd3ywSfBWha33BvxIzDaLZsselsrxWzPEUcQwAmc0Jm3qR5c5f0QAKEVj4HvBb1obU5VsBF78jXmyDtwLmdqYaiks1J4gwCK4DRGgxBwrBmk9NXZxCHQ6RkQwllnoFin13snrXBcTrEU0QQoA+rU2FVRIehREb91Rl4GPORRSSzGDBihXQqBdZ8xqiSywkcp0UaaQkCpIuOMNNaoSiWJEFKJjTO+mBBJQAYp5JBEIhQQACH5BAkEAP8ALAAAAAArACAAAAj+AP8JHEiwoMGDCBMqXMiwocOHECNKnEixosWLGDECAIDAxpgrKgxszGhw4xpYyZypdObLVBAAJAcCCGJqpc2VkmCSBHDF101nyWDlwqnzIs+UNyUt2JhkqLM1RSkCSOLTmacgPk1JWNQq1RmaNnJanFnV2RUAkpxJOjOsbaqpAOY4iAoRgA2nKvsAqCkpTtu2A85K0ktxAaybyaoe8vuXgamhpug6RPvT5uK/wwYcZrlAIgDNlXGybVsLwGZnSSQvBHABaWhPQP5iGuBa7EOOKkKvhFWgVts9Y2xGhjhgTW7dQDUsaivFk01YqhFO9eTAdWhJQHqlMnDaGfSHBkyKJdNQE3myIHHOBLfpKXpBABqcO5szxnplWA4CdH/qXuaV076EhZxKhyRhnS8OrOZAWjeZosEh9iG2X3sKzbTfbjbQFKFuLyUU14YrJSOJCiqMIYkn4un2nXQQDqhSUIcEoYED8t0XHQCHuBgaiCr5oppdpgQp5JBEFmkkkQmWtNGSTDbp5JNQ0hUQACH5BAkEAP8ALAAAAAArACAAAAj+AP8JHEiwoMGDCBMqXMiwocOHECNKnEixIkMAGDFabAjAQA88jx7hqWEAwEaEHQG9Ksay5Ss8AUyeHAiAzMqWOFmWiiDzJAA2v3IW2wQIj8pir0L0rPgzaLFSNwEViDNICotXrwAF2FjTaSkAUIrhCoFpmFkpbAZEUMoUitOhAEIgNdDK7LA9NTriWQoRABJcOfFsmlvL7iAygB59nQjgqlCXBQqbHcSG5S8WjB89dknXMJ6WbPheBAB4s9gQn+zGAdRyk+iFcU237BHJLobBLHG9TghgAQvZLAFJMfuJdMtfIfrCfLv5VYJUwwYhyVnjIYAauCLglk1GSy0Zmo+PY3YIYDAeMsCRspASoXTurQ5ZBE0aXrZr1jgf7TYYoVTrANuZxsZNLUHhUAT1sfSIAQmm99R+NLHgn1CbhGCTgyyFBtuFzZERARub4MKcUL9UxxuCDpbCBgsRsIDeZtnx1gOBDv7ySikTPjYWSla4hyGGPSC0wCObFGnkkUgmqeSRSIiW0ZNQRinllE8OFBAAIfkECQQA/wAsAAAAACsAIAAACP4A/wkcSLCgwYMIEypcyLChw4cQI0qcSLGixYsYMQIAgMDGmCsqDGzMaHDjGljJnKl05stUEAAkBwIIYmqlzZWSYJIEcMXXTWfJYOXCqfMiz5Q3JS3YmGSoszVFKQJI4tOZpyA+TUlY1CrVGZo2clqcWdXZFQCSnEk6M6xtqqkA5jiIChGADacq+wCoKSlO27YDzkrSS3EBrJvJqh7y+5eBqaGm6DpE+9Pm4r/DBhxmuUAiAM2VcbJtWwvAZmdJJC8EcAFpaE9A/mIa4FrsQ44qQq+EVaBW2z1jbEaGOGBNbt1ANSxqK8WTTViqEU715MB1aElAeqUycNoZ9IcGTIol01ATebIgcc4Et+kpekEAGpw7mzPGemVYDgJ0f+pe5pXTvoSFnEqHJGGdLw6s5kBaN5miwSH2IbZfewrNtN9uNtAUoW4vJRTXhislI4kKKowhiSfi6faddBAOqFJQhwShgQPy3RcdAIe4GBqIKvmiml2mBCnkkEQWaSSRCZa00ZJMNunkk1DSFRAAIfkECQQA/wAsAAAAACsAIAAACP4A/wkcSLCgwYMIEypcyLChw4cQI0qcSLGixYsYM2rcyPEfgI8EFAT4CKDjQAAI8qgyJk1aNFug8hAoyREAF1stc+q0lYdmRgB5oukcmrPSgJ9phBKNVckRKJbSCPmkCKAKVGm2oDpioOXMER7GbNniYRHAiKu2EFQRmgHTsGG9ZDgaMaJnRQSqdMYCQCOaMQCp3g47U2VkoqkQASQaGi0PKGnAAAte1ISQI2MEKBZRShQrgFaTueRMg7ih4s45/wZ+uydN0dILP+ZF3fLBJ8FaFrfcG/EjMNotmyx6WyvFbM8RRxDACZzQmbepHlzl/RAAoRWPge8FvWhtTlWwEXvyNebIO3AuZ2phqKSzUniDAIrgNEaDEHCsGaT01dnEIdDpGRDCWWegWKfXeyetcFxOsRTRBCgD6tTYVVEh6FERv3VGXgY85FFJLMYMGKFdCoF1nzGqJLLCRynRRppCQKki44w01qhKJYkQUomNM76YEElABinkkEQiFBAAIfkECQQA/wAsAAAAACsAIAAACP4A/wkcSLCgwYMIEypcyLChw4cQI0qcSLGixYsYIwLYiAABgY0ZEW6MIuvat2/XoHVCACAkQQAPgpFLR7Nmum+TWroEgOWazZ80R+nECCDKN6DkkMlCdjTdn6EWM0CjSa7pty8MjqRQAI1cMAJER9X8Q8CnLCC1hg3bE0XoAIxYZtIUAiCY0zhqh30agAaAAqgSAciyOQrLUTR78rYCMImkgopF5daUi2WQYgBd0+WkCEAsUJpfLKtNBcDnzRGcTX8edSYvJgCShQbG8rmmLCl5B6Gx+e1BYM+1oWFIO+wM8HTksAS2Wxu5jkVqMSD7iSbw1ObpZKWotWhEU6pCrHRjR47mzJHBNq8Bbghg+vhrIwh8D7p+IQACncbTlJWfukaSCLg33nw3+fZQUT6NksEokulHEzL1iWRUTcG0EEUnyDSIXTARHqSAajR9EwwaH01wXHAdFlQUMiy22CJ/k4zi4owtBoOAQxvlqOOOPPaY40IBAQAh+QQJBAD/ACwAAAAAKwAgAAAI/gD/CRxIsKDBgwgTKlzIsKHDhxAjSpxIUSIAABUjXvxAhAgOBBgzLgQQ5pi1cOG6WUP1IaTIggAI3OqGsibKboxcvvwH4MMxm0BR5twpkMBPoMc4cUJ1stsUnRUB3EJp7WS4WwS07JHi0xonqBMBvKFpDQEOmmEGDVt7xg+Riy8BHD0Ws1s3HJ/WDltEZAKAFmAjEqEplFPKFqn0YiLCidGtARkBGA7a7UPitZic1PQT2CECq0C7tci7dlGYmt2cdGY4hXDQMJH0DvJj8xjkiW+C1nyjdu2RyTWHSmSkGyWqFGtrSUW6WiHt4tYm5MX0Iai15glPFw/H6EgtLcSBfl6fOOCo7tRaBoCuOd5i7u3HCDwXjx3hhwlTt3MyD/RNfZh+oGLCeqFtZw0O/w20nB848Leddf49NAFNOLXAiWsPhsYJAQ454dotLTDmYIYofdXQYDZ1c8tTOIRH4mb1mXDLjDTOyIkfb9So444zonKbQhcFKeSQRBY5ZEIBAQAh+QQJBAD/ACwAAAAAKwAgAAAI/gD/CRxIsKDBgwgTKlzIsKHDhxAjSkwIAICILWZ2CAAw8SGANszGoVuHbpsmGBw7UqwgbOS6lzDHNUqpsqBFajBzwkSniWZNgSJw6tx2StMscCSZ+FQJQNjLbUjXCWtwJE6KHVB7/vwHQM9IcCKYoEO3Y9Cws1o0KV068cC2l9QqjhtX4dPZYYPMVNzBFiIAQTk1nVoHDoLds5GYFGXW1yMznS/BHUh1N/FLdIIaN2QCOXLdu4PaxGTSEUCjzi9hRLq75zRMZgImApiFet0Ws2eP0M6ZWSKAx6hnHTlba4BQmMI0UwTeeVsDypEguIypHOHv2usEaeklZbBOdNUPmM7GDm7HGQBvdcb1DRg7swGudc4KL/446kb2Yc6XvWV6Z/85jaNHRREBwEQjAGKnniAN0CeQWzsgqCB5p/DVEAzrbMNEG+lNiNo4mohQnQgvjSOICJpsk6CHT7Wh3AE5UdPGAVs0ckp+LKJzSmzW5beNMKe0oQmLnTHToHiaMKPkkkw26eSTTJ5CoE0VVWnllVhmqeWUAgUEACH5BAkEAP8ALAAAAAArACAAAAj+AP8JHEiwoMGDCBMqXMiwocOHECNKXAigAxxDYBoAmPgQABhz+Pr564cvG5iNHBUOICbSn8uX/bIVSIkQgLmXLuexm/fS3ACaBW3ixHcJgFFD9VwSQwkUADF/pAzh80dMSqphqbQQawbmXQmgApdMNfrO35JFw9IuglPCph2wQv1dgjN1SaS0wz41oLWkXjOmHMG0HOnSBya8nwAQrueDJoBmOF/6uJsWUwec2QBHHMAzsj84aNNGWhK5aODBOImdwbuHVuR6SyYCIOXZpTkgeI9k85xZotPa/uqV+DSsFYDOQw/43g2clpZhg+Cgfvk24mPgwZcMknGzNhzfrrGdmwNQYmrtrxKXTI9Mi7nneZodAnBfG595z+/iNwTgIyn2/8QcoJ9CAMRA13//1UPMEgMeZJMhhqyHIE79mGOIUQwBUA8+diA14X/9vHNhg/8c5w8+pCyRjYQfuhQiHA0CwI6L7PiwBC3msPhhTB3oNx+F7zSzBHItelYPLRgSBIAh7zTp5JNQRikllOyQMoBmRmWp5ZZcdumllv8EBAAh+QQJBAD/ACwAAAAAKwAgAAAI/gD/CRxIsKDBgwgTKiQIAMDChxAFAuBAiRUrShwcRtw4EICSaff4ieR3j5sajRwfAqBEb6RLkqxQpkQIgFXIkffK6VKmTmQomTMZhrp3ryfJQiC0SGGgi1+5GUENemypDEA5pxJqDRv2iUPVAUCDWhVJCYAyftOObB1Wi8Edj2FTArgzEh6lePyUaVk7TIayUO2UxN049iU/XXH4yjDKbXBEBi0NK5OythaIdiLvlY0KoKlhpyAqM8ArMt4MxwoLG1YHQCtXJTdFlkOdcABpw/dmYNo6qNDLe11oH+Rw27CuM1tlcDPceCaKyJ/hMcD0aQb0ke2EGyxQ3PC0FFJYnH1mPRMA5s+ZKdn+PLu8Z/T84lFCv7n8efjXXdLhrOQ+/M8/iVVIAcv9F91pMw1ATzkoFOKfgaXpgoJ2EokXny4cqFFOdwbSo0xwEKFQXDzTFMLBVRC6dI8yGaVWoGHx5JciP/C8lVAXsc2YomZxATCNjkCSFGBBABgV5Iz3FAKUj+o06eSTUEYpZZTcFCBTQ1hmqeWWXHaZ5T8BAQAh+QQBBAD/ACwAAAAAKwAgAAAI/gD/CRxIsCBBAAgTGlzIsGFBAFl4nXPn7hwvIwAcatRogJe9fCBD2ntmYKPJgz/OhVwZ8hyFkyYBvHDH0l7Fcx/znRsAk6NKeznlycEABEQWmkJ7NgSwCmSmLPLy8ZLSalitOJl4/ciUUanBH1HzJQCgUs6iYWgx/fjBtIDXh7xCrpLzscxZtJ8AXHQnp+vbfxTCsswSCe2wvEDzuSv5F4AiliEJG/5kYCUvv0oBaIMMUtEew2pZBsIMEwBNzs+kGB7UdKU7t14TcAZ5LkUttFKeQebq9cfsfPJ+fLI64PRKbaRN+v7NC0itQWU4n0u+sUBOzvbK7JGxGfIz6hrJnv5WbGDD9ZWrwDsEkGm8VN2cy/wdoPK3PcEsX3qVWea8+5VZ7CeHO4Fk4t9/+XzXE0RIGeERgivJU4Z6D5VhnDtZBOLOgeNNF5Mi+AG3ygkvZBLieOmFZ+Bs8mjDy4m/uUMhAIFwCOFsfTX0Aow3zoYcQwDA1yOC7vC00AA8DgmZPBswtME5UEYp5ZRUVimlNk0ulNCWXHbp5ZcIFRQQADs= +"""), + "meld": base64.decode(""" +R0lGODlhLAAgAOf/AAACAAgBAAEEAAAECAQHAggFCwYKBQULDhIHDhIKCRQMFw0QDAoRExAPGBsNFBoNGQwTBxISCRkPHhgSCiEPDyAPHA8VGxMVEyQQIycRGw4ZGRsWDw4aECETIxUaEi0TEBgaJSQXKzETLiEZLBAgHxEhEiMcExkfFzMWIysYLTgXFzsXORgjMhYmJTAdNCkiFRQpFR8lHTYdNj0cMEIcHjEgPDcgPj8fOyQoOTAoGhwtLCUrI0kdRU0fH04fOEMjPz8nRRo2HzYuHy0yJCUzSFYnJh83NT8rTlokQFkjVB86Hk4pTTszH18oJi44KWQnYEgxVVouVWkrSkQ7J20pZjU/MFswXC0/WGwvLiVHJ1A1YSNGSFg2ZHUwUjJEXmY1ZE1DKT1HOGk3ZnsxdoE3NipTLTZLaV8/coU1Xy5SU0ROOSdYMVVKMFlJMHM8czJVV2dDfi1cLz1Sci1ZWok5hpI9QEtUP5A8aXxEfG5JhENYeUxcRYJGhWhVN5c/kUJbgDZlN6FDQzdjY3lMi6BEdHtRlaNEn0liiFNkTWtePY1Pj7JLSUJvO7NIf4RVnFhpUZhRlkB1QK9KrT9ycV5sUFVql8ROUXpnQolapjx7Q8JOicFMt55ZomNyVZJfrkWBQ19zoUl+fahdqc9TkddXV112qZhjuc5Sx2t6XYt1S02JSml/YOZcWmV9sbZkt95am9VZzbxju06KiG+FZt1a2alsxVGQje1jZupgqFOXUJqBUXSLa2uHwMVrxPVkauNg3q1y0WWKw3iNZ1GXmf9mZe1i5Ld01vlls89w0HOOyVWhWFKhof9ruP9m9vpo9KyNXdd32V6oWW+Y2HiX18Z+6eJ631SsrFatrc2E8nih4biYYmG1Y/CC8H+n59mK/2G4t36r8v2G+PiJ+GjCaP+K/ISx98uobGrBwIm2/W/Lb2vNy3HTb27Qztq2eHjadnfjfHrc2nzmeOrFf3jl4YHtf/XPiYL1hoPv6/7Wior7hIfz74T/hnz5+YD9/YL//////yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJBgD/ACwAAAAALAAgAAAI/gD/CRxIsKDBgwgTKlzIsKHDhxAjSpxIsaLFhSoEALj4EIAAFb5IYdnIcSEALKR8EVu5KEDJhAEWrSRWRyYxSy5fFgxgiWUdOyew3Bypc+DJnlhO2BG2CkAdACoSFBWYQIVTAKuEaV3QA0CPJiR1NunaY4FWrTvq1CEVKGxJAIFIqd1xVlgMm6TccgRAimWMuhds+lJRFCTLC2dnCei5kozeigDIzLQkYJZWVAlUsnxMEYBNYr4SoNKKSOhkzhMBMF6JBZHWKnVmEsv7kq/sOlWEoRLASrYl1BJVy2YlAJUTybIXAY/oWTYxMk6Ey8ZS1PRp5DNZ5XwZoLds7DPbNhaF67y8rx5T//XQXH4lq+Wdvbe/CT/16va/00ufTzw9b+eWBCggBelRIKCAACSoYH3MLahgQAAh+QQJBgD/ACwAAAAALAAgAAAI/gD/CRxIsKDBgwgTKlzIsKHDhxAjSpxIsaLFixgLAgDwz8HGjAsBBEAhpcuxV3cCcASpcYYmXMxiynyFZCXLfwAIHZMZ89VOZrh82MyYUyYun8wAICDUM8FNKTFxSdmIoNGsRwY0obkzFWROH6O6VOm06pEHYcKqICGA4M5Qi0sB+EDRCa0wO2gRIZnh45UAkF1GBeiSYJVdvMIQdcF17JgPokxx4TIw63BeNDLdYgTwKmphy8L2YI456u3EGUYdGEarBu2ORjKPBbgI4E5sH5TsOhG2SkBnmTNow5aJJgzaWRCEdcrAk1kX0xABaOKp6QTaRxmEhRktUwrt6UYzZtR1QuiR7+YoaDPleaeKnRm4BEDl+Qp69PkzCwAYxcxlc820/SZTF+sJGNMxwW22nkyj/NQcM5rYJxEKDj7Y3HNe8Wfhg955Bd6G7EkYEWcbjmLiiQBihMCJLJq40YsvEgXjjAAEBAAh+QQJBgD/ACwAAAAALAAgAAAI/gD/CRxIsKDBgwgTKlzIsKHDhxAjSpxIsaLFixgzatwoEQCAAgoEeATA8d9IBQhEnirWrJkzWpuoeMTokYchWCxdwmrJkycsmRYBrNjkrKfRoy7pkJwIIMkvpEadnZIk6VRRZ0AlKqDVEtYmQ5tyNmPpjI6HKmFOUHHmdSlEADedbVqAdogIsnSa0SqASpiwWQv8EKDDw61DAEr9VEDkV5gTSc1OUWkGy0NjYUOSNJVkuCEGQ00B9PUbxlAzSTtPnbhcesypU50XAvBTbIwhAZfV5M15KgZryGNjKwRwqiUtAJftjOkJa3VjJ5t4jhGOEEDOXwBWNVbjpyctA7MawZ8o3pLz4Qc8iwno1LhK9PQK2AtbBeBpy03UDQLg0fPJnsY7kMdTEv8Jg4gIPeH3EII8bVKFX6gUYF+DvglThWk8gfaQAEV1dUF4djxxVDEr7LHKAlwN+FaKLvGwByoXCNjTKQ44ISJP2L313n0x7JAXVH4Q15N5DzXV4Vgi8CDWiGv1tEJ+1e2UoZTpHelST85AWZ2MVjqTpQIYjqjlQQDsaBQtIghgiB9VveammwV0ZMibdPoR5Eh45tlRnnwCEBAAIfkECQYA/wAsAAAAACwAIAAACP4A/wkcSLCgwYMIEypcyLChw4cQI0qcSLGixYsYEwIAUAABAgEbMwrc2PHjRgScoFXjxq1aLB4AMAJAiWxly1hLuJHbyZOcuF4KYlIEoEhnz53ijh6FpmAoJ6VQd1brFavazlhCIQLAs5MbVWRJeVYLRy4cJwI7dhB4Wm1JVocAYoljemLIAitGuQEQRa6agk7ChHUSIErAgLcNBQjgFEVN4Fk7XPUlAIAPOWQnZgUW5iEKgKBag1ohQGmzGstYl8Qi12vHZmFV+CwRdUOrqCWKAKzabMdN3yhhew15XcVV0l6INXIVV0335j1WkPJs/XrH6rJfkh9EYJWcXsCB9+qIUVrtgubAHpDxhEaAIYCnSAWUDhyG79FqCM6jAtC97BKGBfRHjhh7bObEdT2J88MjgSFyw1GQaEeQDEbt5EoVjy0ADVScOEEffDyJIuFAN4S1EzIcaIbIDyb2VA0GnawCgXo9ucEQBhX6JMMes8QgWVSieBBGdD1xI4N7G/YUyw5hfNHiUeKIAUAvSwngHohdVZCCgFC1lSM5row4IVk9cfJjVDx9SQ5MDQV4FDdkohkVN001NKWceN5XAFwIyrnEk0pxUwFcNMoJCSTIJKrooorKIOZAArjC6KTIiLjRpZhm+ug/mnZ6aUAAIfkECQYA/wAsAAAAACwAIAAACP4A/wkcSLCgwYMIEypcyLChw4cQI0qcSLGiRYMAAAwEICAEECA1Cmi8SJCjxyMhAZwxhs2bS2qYFIy0CGAAHJYusVFz5LJnT2pwZk4EYMOYz6NIe+YRChFADWpJkRrDhMlUS2wpmDoEUMtlLaq1Wr50acpAGDs7UlCjNkgrQ6fAvOXhoEaNhzNXgXjDFgKRsL9OHEkQ4HYhRwCDBKD6u+qCUUwFdCpY/FeNFo41CicE4ALAEQ9//+7oOsiTN2oFVoXeo8VRVc0HAWgBBsfRkNDCnHQ1errArNB2zuS8/LAA71o7cFcx5ZMaAsrC1Az6KWErc68ncA/p6rMDpdBhTOX3NAVbIAAuPo0ZwM2Bd88jfv/G4P6eoXGf2AR0+jurAFSfnlTxFyoA/DcebABAgRQUe/yFSApSNbDYHi5IhSBPR5nixF9DYJIUHFXMssN16V2IlHOoPBKCgc2lUIUEYvkETHl5JJXHEB6QiFQtAmB4lDEIFpKUMQXAEZVSLPaEDRAK3ZcUXkfmdGQtEriF2JExRhmlMVAIBUAIOmopZlTYLGXeEe6N6RImSYqJTVBOtaklNqYc4Zl4amLTZVxqegMMFwgo8NUZcABj6KGIJmooHLMp6uihmLRWS0aUVmrppZhmqmlAACH5BAkGAP8ALAAAAAAsACAAAAj+AP8JHEiwoMGDCBMqXMiwocOHECMqBCBxIIABOLxcAQGAYsKOIK54wTHAo0MAFiplK4euHLhkZg6YtHjATDJwLMtlq2Rh5scr2dAJHSpUGouZAFhII0o02xWfBgHoAceUaTYWBFkErToUnB6oFuWwJFouWKVKyYTy8giAl9BkZ4ONHVpODth/OLq9zSlnQZgqBg6hS0ZEIJG0hwxUCbNAbMu06LrhONhWaCsArQYvWCVMWKcDlQAI6Di60oFOnVctSHs5M7q1Br2MDV3p9Y7OwmZ5eIqjY+8rHmbh3uGWttByXgpWFprtzzR0rZzgFjak0h9pILxI+1NpyHQnmaf+/dn6eiYOrtCrTN8RDN20A0vRBbuNu4rrqpMFAqjNNfr0GMmUY0YpQyUTw3f3MRWafu1xJQ0HuM2yQDalmDFXNgsI1xkH8VUVjEcCUMXVNAJo2AkL3ShFFDgsoJabAM9xBY4AAlmAXksgINLZHl7wQkRVXuzRGSIgzFWVBQKdd2Mp0lHXyiEEMtWKd8I4ESV6+YFwIzrZCPBIJxZ0o8eVQ3VjQSePCEAeVyAIFOKWrZxQxR+vmcHVH1WckGBVM+q3J1Pl6DHAc9IMYKRQ0wygx6FSsiXblt04lowAjNal143ImbTflui8RAQIbnHFqIIzsXBAg3yWwgARpYjIKVeFwRyAlX6HtGIBqsfxwoIZcr16YzAWPMmWYK2AAMpY2RBx2Ki+tgQKCJkdMmxRRFzRSisMlMKsr+C0cgUR8UlLa1eXqdjsik/KYQELrbgqrmFDZeOFHJeeO9Q0V9Q6zaGFDTRAMMkEgwMOACdj8MEIJ6zwwgYHMwBBHUUs8cQUV2zxxAIFBAAh+QQJBgD/ACwAAAAALAAgAAAI/gD/CRxIsKDBgwgTKlzIsKHDhxAjSnwIAIARQXOMVERY0cgcQRoBSARAIBQ7fv368YMni4TIgQBIyIKHUiW7UAReNgTQQl0/f0CD+ps35yWAOfOEBu2nroVOhRaTBuWnTh0/oPwEVRR01R9Vq0LnaVwYVei5kCSs/Zx34EDSftZcWjwXdmzCA+zmbbnm796BPbNmUWJwbssyW8OWbTnHgFLgPQfu+bu2ZR67AwkByOr3zaI/dgSEiRa2I01MAOpcptkxWhgBdv40fusn6ynBFknn6Vj2eUHrKrKMpIk8zIisKq0XwF6mI3eLgwBsTQXK7sLvb/xCDcP6DfnoC7C9/ga1ZfsfAXhKP3to7eSbtS2SgX5z0tpDeKHwCBic81MpPAGzjDaELRrc5885Q4w2iwDoKdXPHAUBsF169wDQiWizLMAAb/gtEKAwnQAQn1LDPAUAXen5s8UeooXYwohA3aPDhcLssUWKB5pooFDX0CeMHQBwqJQgdojmBF8psmMijGEJ4NgJqKV4zgmCCSAVhSY2mOI1J9iYhjop8rPiCUimCI+JKIY5iQDLTPINjssIMElXUpooC45AiXXPN5PgeI8RV6ZYW0EkBJoePLQJgqeWKc5DgkEATNIfhd9ssQWjeKbXzyTlGdDCMpMCBc8yDAiCXaZ49rNMCwYYZAQ7czpc0x88obQgCzuhourgNTqwY4RBgjD1Ka0k2GKorkrxs6pPguz3k5IHyHIsskvBAxJsD7rKzzlzpIEotUkOIwgDtsTHz68FETCJBqeCm+IkbgY6j34EVdSCNVXlq+++/PbL7zIbCVTRwAQXbPDBCB/8T0AAIfkECQYA/wAsAAAAACwAIAAACP4A/wkcSLCgwYMIEyosCKChwYYAFkp8CKCMqotlBDQUYBGjw4kLATBat69kyVwQPrkzWXIdo4ggDwLgsI1lSWVK0tlkuY0DzJgCAZQYZ/MdSpLxtqmK9s7muBI/Ywog+q7pvqcAPsVzpyRGmCFDS1a9KgDoPwC59tELEsTevjhDAAjIkiuMsLt74uyzx5bevlxRJZbw+65hPHtZhihpGGfPXWGUstiL17ApvRIxAdS8qUzt4m25omV59LiTEr/KOpfcFjjh4J30YATxu68M6buoYNBmeXki2p373JXQWRIQotJK3O4ELFEASZv2lKQ1qcrx3Ud6ga8ru1D3znWSef46eWwnEnC1MEKW2cl3s8nts+7GcL+zTGuCIne+K6HcpL0SpHXi3XkvLfSJftnZpEwVswyhynklfSIRIPqV0Z9J7xBQRRa7AQdISMkVxcGF1AlA3HnR3UcQAc/5V0KLLK0zHYTrECARAHF0uA8MRAFHok30xKEiflntRg8EMEII5CdDFqREHHG8Q884WSl53jtQLnZjLvQAQkBF9FlZEj3KEPAJPcwtZMA64xgASI9ijpmOKhAAQtw6BqgHSBYnxrlXEEqo0uc+kTQJgAFc+lnUj/vEE0RCAEAQpqJWKqOiAXBSGmeGMkWjKaUpMpTFOOmUauqpqKaqKqrjKGHATwwQxSrrrLTWaus/AQEAIfkECQYA/wAsAAAAACwAIAAACP4A/wkcSLDgQAAIEyI0yLChQ4IABFx6Zq5dO22XCCx8yNEhgDbm8Ikcic9cm40dUwoEkKgeyZf1LqFUyRGMS3zyzJmTBzMVAJodAWhzqWtCjBgmtI10We8k0IcmUuXQFqGTMGGPIPDU9aIdvnYJnjYEcOkFADAnrl4VEJKJUJE+xRoU+oxJKidqhRkIqS0HT5wG5EJMJLKetiF5F4TEdxPuT8H/THgVqW1H4sUvzT2W+3akubRXVwGYDDPCZqAsX8qDsOpqJwGNXyaaqRIA5sJTrApD1OYlSV0bTtf+S/KSnatOnvke+UymWAHLzUGY9WgDcd/PdAkQC+B6YTZ2TqkoXS5S12zut5mTje2bifOnnWEK8Z4ZgC7hKQEoX07/ZZ82z+AX1H7kFfhMDhIJyJEA/RUokjl7aaegR7o4SJ45Quzn04RztcGehfI8k0CFhW2oElsWkqTNFAn0kR4+zxCQX28pjqSNNqT5RhVHCL1Yo4PayDgWGBM0+CN57xlkQCpgHOlkO4Ex1AZGTjrZBkMA9GGeTlx26eWXYHrZB5YKlWnmmWiaSVBAACH5BAkGAP8ALAAAAAAsACAAAAj+AP8JHEiw4EAACBMCMMiwocOCAARcemauXTttlwQsfMjxIYA25vCJHInPXJuNHVMeTFSPpMt6l1Cq7AimJT555szJexlzZkcA2lrqmhAjhgltI1vWO+nzoYlUObRF6CRM2CMDO3W9aIevXYKmDQFcegEAzImqVQGEZAJUZCqZYAUCfcYklRO0wgyE1JZj500DcQkCSCSynrYheBeExGfTLdymJriK1LYj8WKX5h7PbDvS3NmqqwBIfgkh8GCX7SCsqtpJQGOXiUxfLjyFqjBEbVyS1KX5p1+Sl+xUdfJM98hnvTkCMG4OwqxHG37rRh4XgPTCbOycQGpcJO/qs4+Ni32tm4lp7i+FXMecXHlx4+td9mnv8X33+89yCAgsIP59kebo9V1TAOjyX3fmCPHeWz59RN6B8jyTgH31MKiSAOH9p80UCfSR4TMEpPTRgS5po81oukn1U4YkHqhNiA9N4F+L9/XkEBg05ihSO4A5dImOOrbh0GA5FWnkkUgmeaSQYSnk5JNQRqkQQQEBACH5BAkGAP8ALAAAAAAsACAAAAj+AP8JHEiwoMGDCBMqXDgQgEOGECECEFBGlcUyDyNqbAjhk7t9IEGuYwRgo0YAStKFXAlyG4eSJhdCWLcv3jZV0d6xHFcCZsyDAD7Fc6ckRpghJcaBfBdv3zgBPxFOzJIrjLCre+LssxckCL19uXxGFYjSYZw9V4VRymKPnkOd9EqMJQhgW65oWR6l7aTkqzJlIbeJ/QnAK8gyeq+igvGVZdy5/wyoBAkI0V4l9liCDDsWQK6VqtBefaRV8751gzeyXbnNSVo7kUzvowcjal2W6wTMuhpjm+x9GH+WyLzSXgm9nWA0lU3yZ2mWyqrMGqLq975PUcsQX/lOQJUsjWWfA4rKYfvKTwJo/ranJLVE9bg/W19HwLZS0+Y104vj/r112fR80h9DQf1n2jtxxBHEgFKV4ZuBK9GjDAGf0MNZRAIAch+Es6WjCgSATEafRGVMxuFWSiihiokgRcJgZLmEd+I+7uQHUjxBKATBgzNCqEx/BmzYo4Hv1GcQANEMeSJ7R2YxTjpQRinllFRWOeU4ShTk0JZcdunll2BySVBAACH5BAkGAP8ALAAAAAAsACAAAAj+AP8JHEiwoMGDCBMqXMiwocOHECNKnMgQAAAjcwQZsUjRIQASsuDxG8mPXSgCADoqBDBnXr+XMPvxU9cipUqDAATde3lPnTp+MedtvFnwgMt+y0hYNHIu6FCi/wAMW7blHANKs2btMdrv2pZ57A5AjapOaZodwtIKI8Cu38Zv/WTZvHng3jAjsqqoFbag7TId8PrNa0FU6kt+3/SqvdBWJkxbcycC+Arzm5O9HhrHhEdApQDN/c4NUTsLAOjDczoCWBazH7wFs9J2AnC09bDIEFvsjHlPR6e0e7a0hnkOt0fWwwXZSevk2vCX7Iw3BKDu+bkTsyjRfi5YesWmw/mdbdlzwjn36JLhPl8GYBJQ7sUlT+IutPZzuZIFcXe9XzAJiRZtEVh/3PEziXcIAUCAIN+8R2B4y7TQ2XQtyHLag61d0wI7RlREgi32YdgaPxH+JMhKB8gSoogw8QOPRm3xk1qCaVzIYj/sDCMIA7bsxk+HOGnQ4I3PTTLJN/bNM+FAFrVgjU9QRinllFROyR5BFmWp5ZZcdunllgMFBAAh+QQJBgD/ACwAAAAALAAgAAAI/gD/CRxIsKDBgwgTKlzIsKHDhxAjKgQgsaJAAABAXPGCYwBFiw0BHDCTDFw5dOWyVbLwESRCACykoZtJc2a2Ky1dFmSRraZPdOD05NT5DwCvmckqVQp2smY5OUNdEkmG7pCBKmEWyDlZjiq6bjiIXhQAoBKDTsKErVpAtRWAVjN5Ra0IAAeAKx5mpRW242ilsjPLeSEKwIu0P5WG7BXmBO60Pz3jzoV4QCa6YDsWV4H7E11YkABK0UwWY3Hjzuj+WizcFF22BXrTerD8M9hkhgBoA2WBVtgsAdNQg7s9kchPL3vSImLR+qcFuqJ9tlLMODrqzxFD/+xmodMjApFRnIOga6bznyonOAsXYHFA85nTBuh5L524QgH0n3ZDHdiL/YMZHdUZfT6p9hBGRJQCDn8MosPLASw8JIAZTDXIYDAWtHLIfwBMRaCFgYECAlwbTsRAKR+CCE4rVxBhWYkvxQTiTyseIocFLLSy4EwwGgSAHPvN6NM0VxzSyjTvEfESDsEk4+STUEYp5ZRPBjMAgBhlqeWWXHbp5UcBAQAh+QQJBgD/ACwAAAAALAAgAAAI/gD/CRxIsKDBgwgTKlzIsKHDhxAjSpxIsWJEAAAsXhQQAsiRGgUyalQIYMAZY9i8ecNGzVHIkQcB2DCmsmZNalpEwhQIoAY1m0BX5tEJE0AtlbUwYaqV0iY2OEQt9gTmLQ8HNWo8wEmJjaY3ail2AhAAYJAAVMKErbpAExMAUypNRaUIIAWAIx7Spt1xtBAATCqx2RgJQAswOI6G6BXm5KgxOD9VOpobsYDXWjsWV4EblJoCqZy9ATuxeMjRoN7OVATAxaYxA4s9eA3qlqJlpwA6pZ1VIHLQWpQZAoASFMqetIhcoFZpLPhCAI6CmnKSdgjg5cCckyzUGQGqRyF8gQf1pD0hADio8zjxEBo1FLrcgxorgH65N7m2ZwM90xS1YBflxRSfffbBwQVwEAEQgicE2ofNIED8BMRDd+nXoGtQQBHZUA0B4IJ4F65kyhkKONLfZB1SFaJKwHCBgAKYgOiXcIYBY+ONOOYIDCZaOFKLjsCcESBGRBZp5JFIGilQQAAh+QQJBgD/ACwAAAAALAAgAAAI/gD/CRxIsKDBgwgTKlzIsKHDhxAjSpxIsaLFixgzCgQAgAACBAU4akTI0Uqvaty4VUMGiQCAkQQByEAWjpzNm+SquXkJE8CPajiDkhMHiadGBNBsQot1Uii5ohoBuOEWjg+BHTEAxLIpjtvNnRkBDEghygAqYcIQYRBHjg8GoDldZAQJwMoOtMJWAagm7gaAXjdFGaUoVdEXN2rwzgKAjBwnK15tcktxEelQPonRLm48NKjgigAU3YRURTFjpzkHR1QQmZyrGHhRAWgtVIxqh6FxIjMwC22nFKhtxrrdEIAonOIwdEK7B0/w1BO1BnWzR9isE66ecyPOEACnoK44gMza84Pt8xTcFUoNKu6HHQKAn5Nbkl5hAdqOc8sPhz76VpzcLIGfU9CEFJ1oQQ0oFDdWKAKVRFHIR6AVYnBDFAESySAhOeGEA40rbjygSGThPPiQGBJWc0NILogC103ifAGRVMjUaOONNfYCCSSi4HijIvUVxNGQRBZp5JEiCRQQACH5BAkGAP8ALAAAAAAsACAAAAj+AP8JHEiwoMGDCBMqXMiwocOHECNKnEixosWLGDMCAFAAAQICGzMmBEAAErJq3LhV62UlpEiCANxUI0ezJrlwyGQAeCkQACRxNoOSq/Zjp0ifQof2igWNJjQER93U5AaUXCwAMXYQ4BOOmxujF13MHIqBDzlxGBAJE4bKgKgUA8BWBCCqZi8AN8RVA7BqrbAdLTtiTMFtqhVO5JABmOVXjZsvir5apBu0qmLGa9XwAfp08lihl/1WgVRTkVyIAMQkpckNACq/MVxNVUARQKzVNFN0WjvLADKbpicC+JwUz561nTBUpSnqtEMAhXG7OsF4j1SbVyemwE1T3I89szh+yLbJyTlDAEu40+xFwM6P5TQlRwSQIpx6cqYR2+RWQHiBpupxs0R0NWU3HySKWEEgbgvSFBxEJYnDjRhWAHifTVEcaB853CjygBuuQBPOhurJENEX8A0ligscyUDcamKgpggyNNZYoyiQQNKLjTzWKF9DGwUp5JBEFumSQgEBACH5BAkGAP8ALAAAAAAsACAAAAj+AP8JHEiwoMGDCBMqXMiwocOHECNKnEixIkEAFiMCKFDjCJAQAjBmVLjRETVs3rxhM3ZmgMiRBQFooZayZk1jNl7C/AcgD0qbQKnV0JkRAJyfNbHVwoSpVspaRC2moOnNGEpscDyoUcMhjzdgQ2ECMJXSFABMVS+sEiYMlYBBAELCtPETE4BC3mrtYMvWwxEAKaJKBOCoJjU4xvI64StsiCM4wLQIhqiAKlBTVRjvcFq1QMYzQGvWGsL4BLCaZiueDZ3SmAfGBhLX5DKZIQDOoakVmMW2EwCknSkCkM3aBSK2e6CEhiL8NGtvmEgLc0IWqKPaJD0990YtxCNUCCyD1yyEXaHy7aY8OPEaGk75hGO3e4NTgLhN8hMBuKC7HRto1sZ4NlgtXMAhn3z4RQQEd0AMAtyBNnkSwnsD9ZQSNVBAYR+EN/3lEGFJOaLAGaY8CCE1LlB4V1CYKIAAF85x+JWKZwBj443A1OKIFpjg6OOPNkpmGwBEFmnkkUgmWaRCAQEAIfkECQYA/wAsAAAAACwAIAAACP4A/wkcSLCgwYMIEypcyLChw4cQI0p0CGAADi9XQAAAMPEhAAuVspVDVw5cMjMHOHZUCOBKNnQwY8KUxkLlSoMA9ICTyRNdNhY3ccoZKbNcsEqVksHkZTPoPxzdYCYbWU7OgjBVDBxCl4yIU4EAeMFsBaAV1wWrhAnrxKASAAFNV3oh6rYSOl471Aqb5eEKABxxJ4aNme3PNHStnOgVNqTSH2leAkfE0XNslcU7gs08cBOA3cqJF8dQCrOUZIqaK0vzoHfWgpcwy0XuCGBn5WkCZqntxML2zNMMLVSOzQKR2j1eehIBrpDycHSlFDM2y9P0RBDPfRJ41MlC1OrME5cK8A36RJU/lc3Qpj68nJ4Bh3mWG0B7bvZuQ3uWE7DSc3aSw/Gi0UQsHCDWf8OBU8py4REEwCGtWJAagpUZZQZ/DT2IGAigEEWhfl01qCE60hBxRSvkfRhTOaUwwNyI6IDTCgsWyAFhih/SxBwR8k3TyiFXxKdiTPgBN0AwySSp5JJMNumkksEAhtBGVFZp5ZVYZrlRQQEBACH5BAkGAP8ALAAAAAAsACAAAAj+AP8JHEiwoMGDCBMqXMiwocOHECNKfAgAgBFBc4xUnEiRQCh2/ELygyeLBACOCwG0UMevn8uX/ebNOYnyoMV5MPmpU3fP5T1BNGsOvAnznEYAJJa5nHdAKMED7OZtuRbzwJ5ZsygxOLdl2bCgNQHI6vfNYj92BISpFbYjDVJ1YFG2wAlPh1J2C9YKqyLLyLB7TYUCsPWy5dkLeqt8M/xVKAF4MF2y86DXybeXUuNGnGMYJjsAs9YOOedZAEoAwyIvBdBJ7awFkGEu0+wQAGnV/bbsUdtJR0+Y91pwBMAOd79rTtTaEYR79kQAOHHPA0Bp1onbkeE+L2782ok9WzqYF6XN0LbxfvwmAVCKu+zzsefnGYmuehJKEvRxx8YNdPgk8eepBs8WG0VEQAvLABhgTt8IQgB5CBnBTgtULRggO7K0AGFBguiEoIIWwjSPLSYxxNlZF8EDYohLyXLAhkYYdo8tDAgyDHcsqsaOWwkRkN8830wySY7G8fONBrStt9OSTDbp5JNOWqNhXBVVaeWVWGap5ZX/BAQAIfkECQYA/wAsAAAAACwAIAAACP4A/wkcSLCgwYMIEyosCKDhwocQBTYso6piGQEAImpkyGjdvo8f3X2CkHEjRAActoFc+TGdkpImEwIoMY7lu2iqtsXbtw5CTIUCasZ793FciSFhYihxF+8TzJ8EAeTaRy9IEHv74uwRxjVMriwYoRosQW/fu4b07GWhxFXYnjgNlYiNqvKjMmVUlXRq+yhLtFzbnkIly5IqDFR8y3ysKtik1ML77OltiwgQyHQG5gLwCDnOo7Z7VK3M1VgjjLKQI9lp66TuR7VQASiGvG9bDK6zBHAGGfgnAEa098WDsfdRCawr7ZWA+in4PlVDZlXBWzgOVMvB6WWpIoAoS3tlfJorQU57nYDmhe1xgEpgN+1c7kGuK30yDmra5FmOo/+w4af7zrE0n1hBxBGHdwGy5JRvudDzCQHKAJhgbWXwh1B7LQECgSrpSBjgOIAIEBEAkbCUjipKjDfhSulU+FAQO6WH4IqL5ZKZTNTRuOI2Pl04o44JjnOjQSoCSWM0pSkxTjpMNunkk1BG+eQ4WQjW0JVYZqnlllxm+U9AACH5BAkGAP8ALAAAAAAsACAAAAj+AP8JHEiw4EAACBMiNMiwoUOCAARcemauXTttlwgsfMjRIYA25vCJHInPXJuNHVMKBJCoHsmX9S6hVMkRjEt88syZkwczFQCaHQFoc6lrQowYJrSNdFnvJNCHJlLl0BahkzBhjyDw1PWiHb52CZ42BHDpBQAwJ65eFRCSiVCRPsUaFPqMSSonaoUZCKktB0+cBuRCTCSynrYheReExHcT7k/B/0x4FaltR+LFL809lvt2pLm0V1cBmAwzwmagLF/Kg7DqaicBjV8mmqkSAObCU6wKQ9TmJUldG07X/kvykp2rTp75HvlMplgBy81BmPVoA3Hfz3QJEAvgemE2dk6pKF0uUtds7reZk43tm4nzp51hCvGeGYAu4SkBKF9O/2WfNs/gF9R+5BX4TA4SCciRAP0VKJI5e2mnoEe6OEieOULs59OEc7XBnoXyPJNAhYVtqBJbFpKkzRQJ9JEePs8QkF9vKY6kjTak+UYVRwi9WKOD2sg4FhgTNPgjee8ZZEAqYBzpZDuBMdQGRk462QZDAPRhnk5cdunll2B62QeWCpVp5plomklQQAAh+QQJBgD/ACwAAAAALAAgAAAI/gD/CRxIsKDBgwgTKiwIoKHBhgAWSnwIoIyqi2UENBRgEaPDiQsBMFq3r2TJXBA+uTNZch2jiCAPAuCwjWVJZUrS2WS5jQPMmAIBlBhn8x1KkvG2qYr2zua4Ej9jCiD6rum+pwA+xXOnJEaYIUNLVr0qAOg/ALn20QsSxN6+OEMACMiSK4ywu3vi7LPHlt6+XFEllvD7rmE8e1mGKGkYZ89dYZSy2IvXsCm9EjEB1LypTO3ibbmiZXn0uJMSv8o6l9wWOOHgnfRgBPG7rwzpu6hg0GZ5eSLanfvcldBZEhCi0krc7gQsUQBJm/aUpDWpyvHdR3qBryu7UPfOdZJ5/jp5bCcScLUwQpbZyXezye2z7sZwv7NMa4Iid74rodykvRKkdeLdeS8t9Il+2dmkTBWzDKHKeSV9IhEg+pXRn0nvEFBFFrsBB0hIyRXFwYXUCUDcedHdRxABz/lXQossrTMdhOsQIBEAcXS4DwxEAUeiTfTEoSJ+We1GDwQwQgjkJ0MWpEQccbxDzzhZKXneO1AudmMu9ABCQEX0WVkSPcoQ8Ak9zC1kwDrjGABIj2KOmY4qEABC3DoGqAdIFifGuVcQSqjS5z6RNAmAAVz6WdSP+8QTREIAQBCmolYqo6IBcFIaZ4YyRaMppSkylMU46ZRq6qmopqoqquMoYcBPDBDFKuustNZq6z8BAQAh+QQJBgD/ACwAAAAALAAgAAAI/gD/CRxIsKDBgwgTKlzIsKHDhxAjSnwIAIARQXOMVERY0cgcQRoBSARAIBQ7fv368YMni4TIgQBIyIKHUiW7UAReNgTQQl0/f0CD+ps35yWAOfOEBu2nroVOhRaTBuWnTh0/oPwEVRR01R9Vq0LnaVwYVei5kCSs/Zx34EDSftZcWjwXdmzCA+zmbbnm796BPbNmUWJwbssyW8OWbTnHgFLgPQfu+bu2ZR67AwkByOr3zaI/dgSEiRa2I01MAOpcptkxWhgBdv40fusn6ynBFknn6Vj2eUHrKrKMpIk8zIisKq0XwF6mI3eLgwBsTQXK7sLvb/xCDcP6DfnoC7C9/ga1ZfsfAXhKP3to7eSbtS2SgX5z0tpDeKHwCBic81MpPAGzjDaELRrc5885Q4w2iwDoKdXPHAUBsF169wDQiWizLMAAb/gtEKAwnQAQn1LDPAUAXen5s8UeooXYwohA3aPDhcLssUWKB5pooFDX0CeMHQBwqJQgdojmBF8psmMijGEJ4NgJqKV4zgmCCSAVhSY2mOI1J9iYhjop8rPiCUimCI+JKIY5iQDLTPINjssIMElXUpooC45AiXXPN5PgeI8RV6ZYW0EkBJoePLQJgqeWKc5DgkEATNIfhd9ssQWjeKbXzyTlGdDCMpMCBc8yDAiCXaZ49rNMCwYYZAQ7czpc0x88obQgCzuhourgNTqwY4RBgjD1Ka0k2GKorkrxs6pPguz3k5IHyHIsskvBAxJsD7rKzzlzpIEotUkOIwgDtsTHz68FETCJBqeCm+IkbgY6j34EVdSCNVXlq+++/PbL7zIbCVTRwAQXbPDBCB/8T0AAIfkECQYA/wAsAAAAACwAIAAACP4A/wkcSLCgwYMIEypcyLChw4cQIyoEIHEggAE4vFwBAYBiwo4grnjBMcCjQwAWKmUrh64cuGRmDpi0eMBMMnAsy2WrZGHmxyvZ0AkdKlQai5kAWEgjSjTbFZ8GAegBx5RpNhYEWQStOhScHqgW5bAkWi5YpUrJhPLyCICX0GRng40dWk4O2H84ur3NKWdBmCoGDqFLRkQgkbSHDFQJs0Bsy7TouuE42FZoKwCtBi9YJUxYpwOVAAjoOLrSgU6dVy1IezkzurUGvYwNXen1js7CZnl4iqNj7yseZuHe4Za20HJeClYWmu3PNHStnOAWNqTSH2kgvEj7U2nIdCeZp/792fp6Jg6u0KtM3xEM3bQDS9EFu427iuuqkwUCqM01+vQYyZRjRilDJRPDd/cxFZp+7XElDQe4zbJANqWYMVc2CwjXGQfxVRWMRwJQxdU0AmjYCQvdKEUUOCyglpsAz3EFjgACWYBeSyAg0tkeXvBCRFVe7NEZIiDMVZUFAp13YynSUdfKIQQy1Yp3wjgRJXr5gXAjOtkI8EgnFnSjx5VDdWNBJ48IQB5XIAgU4patnFDFH6+ZwdUfVZyQYFUz6rcnU+XoMcBz0gxgpFDTDKDHoVKyJduW3TiWjACM1qXXjciZtN+W6LxEBAhuccWogjOxcECDfJbCABGliMgpV4XBHICVfoe0YgGqx/HCghlyvXpjMBY8yZZgrYAAyljZEHHYqL62BAoImR0ybFFEXNFKKwyUwqyv4LRyBRHxSUtrV5ep2OyKT8phAQutuCquYUNl44Ucl5471DRX1DrNoYUNNEAwyQSDAw4AJ2PwwQgnrPDCBgczAEEdRSzxxBRXbPHEAgUEACH5BAkGAP8ALAAAAAAsACAAAAj+AP8JHEiwoMGDCBMqXMiwocOHECNKnEixokWDAAAMBCAgBBAgNQpovEiQo8cjIQGcMYbNm0tqmBSMtAhgAByWLrFRc+SyZ09qcGZOBGDDmM+jSHvmEQoRQA1qSZEaw4TJVEtsKZg6BFDLZS2qtVq+dGnKQBg7O1JQozZIK0OnwLzl4aBGjYczV4F4wxYCkbC/ThxJEOB2IUcAgwSg+rvqglFMBXQqWPxXjRaONQonBOACwBEPf//u6DrIkzdqBVaF3qPFUVXNBwFoAQbH0ZDQwpx0NXq6wKzQds7kvPywAO9aO3BXMeWTGgLKwtQM+ilhK3OvJ3AP6eqzA6XQYUzl9zQFWyAALj6NGcDNgXfPI37/xuD+nqFxn9gEdPo7qwBUn55U8RcqAPw3HmwAQIEUFHv8hUgKUjWw2B4uSIUgT0eZ4sRfQ2CSFBxVzLLDdeldiJRzqDwSgoHNpVCFBGL5BEx5eSSVxxAekIhULQJgeJQxCBaSlDEFwBGVUiz2hA0QCt2XFF5H5nRkLRK4hdiRMUYZpTFQCAVACDpqKWZU2Cxl3hHujekSJkmKiU1QTrWpJTamHOGZeGpi02VcanoDDBcIKPDVGXAAY+ihiCZqKByzKerooZi0VktGlFZq6aWYZqppQAAh+QQJBgD/ACwAAAAALAAgAAAI/gD/CRxIsKDBgwgTKlzIsKHDhxAjSpxIsaLFixgTAgBQAAECARszCtzY8eNGBJygVePGrVosHgAwAkCJbGXLWEu4kdvJk5y4XgpiUgSgSGfPneKOHoWmYCgnpVB3VusVq9rOWEIhAsCzkxtVZEl5VgtHLhwnAjt2EHhabUlWhwBiiWN6YsgCK0a5ARBFrpqCTsKEdRIgSsCAtw0FCOAURU3gWTtc9SUAgA85ZCdmBRbmIQqAoFqDWiFAabMay1iXxCLXa8dmYVX4LBF1Q6uoJYoArNpsx03fKGF7DXldxVXSXog1chVXTffmPVaQ8mz9esfqsl+SH0RglZxewIH36ohRWu2C5sAekPGERoAhgKdIBZQOHIbv0WoIzqMC0L3sEoYF9EeOGHts5sR1PYnzwyOBIXLDUZBoR5AMRu3kShWPLQANVJw4QR98PIki4UA3hLUTMhxohsgPJvZUDQadrAKBej25wRAGFfokwx6zxCBZVKJ4EEZ0PXEjg3sb9hTLDmF80eJR4ogBQC9LCeAeiF1VkIKAULWVIzmujDghWT1x8mNUPH1JDkwNBXgUN2SiGRU3TTU0pZx43lcAXAjKucSTSnFTAVw0ygkJJMgkquiiisog5kACuMLopMiIuNGlmGb66D+adnppQAAh+QQJBgD/ACwAAAAALAAgAAAI/gD/CRxIsKDBgwgTKlzIsKHDhxAjSpxIsaLFixgzatwoEQCAAgoEeATA8d9IBQhEnirWrJkzWpuoeMTokYchWCxdwmrJkycsmRYBrNjkrKfRoy7pkJwIIMkvpEadnZIk6VRRZ0AlKqDVEtYmQ5tyNmPpjI6HKmFOUHHmdSlEADedbVqAdogIsnSa0SqASpiwWQv8EKDDw61DAEr9VEDkV5gTSc1OUWkGy0NjYUOSNJVkuCEGQ00B9PUbxlAzSTtPnbhcesypU50XAvBTbIwhAZfV5M15KgZryGNjKwRwqiUtAJftjOkJa3VjJ5t4jhGOEEDOXwBWNVbjpyctA7MawZ8o3pLz4Qc8iwno1LhK9PQK2AtbBeBpy03UDQLg0fPJnsY7kMdTEv8Jg4gIPeH3EII8bVKFX6gUYF+DvglThWk8gfaQAEV1dUF4djxxVDEr7LHKAlwN+FaKLvGwByoXCNjTKQ44ISJP2L313n0x7JAXVH4Q15N5DzXV4Vgi8CDWiGv1tEJ+1e2UoZTpHelST85AWZ2MVjqTpQIYjqjlQQDsaBQtIghgiB9VveammwV0ZMibdPoR5Eh45tlRnnwCEBAAIfkECQYA/wAsAAAAACwAIAAACP4A/wkcSLCgwYMIEypcyLChw4cQI0qcSLGixYsYCwIA8M/BxowLAQRAIaXLsVd3AnAEqXGGJlzMYsp8hWQly38ACB2TGfPVTma4fNjMmFMmLp/MACAg1DPBTSkxcUnZiKDRrEcGNKG5MxVkTh+julTptOqRB2HCqiAhgODOUItLAfhA0QmtMDtoESGZ4eOVAJBdRgXokmCVXbzCEHXBdeyYD6JMceEyMOtwXjQy3WIE8CpqYcvC9mCOOertxBlGHRhGqwbtjkYyjwW4COBObB+U7DoRtkpAZ5kzaMOWiSYM2lkQhHXKwJNZF9MQAWjiqekE2kcZhIUZLVMK7elGM2bUdULoke/mKGgz5Xmnip0ZuARA5fkKevT5MwsAGMXMZXPNtP0mUxfrCRjTMcFttp5Mo/zUHDOa2CcRCg4+2NxzXvFn4YPeeQXehuxJGBFnG45i4okAYoTAiSyauNGLLxIF44wABAQAIfkEAQYA/wAsAAAAACwAIAAACP4A/wkcSLCgwYMIEypcyLChw4cQI0qcSLGixYUqBAC4+BCAABW+SGHZyHEhACykfBFbuShAyYQBFq0kVkcmMUsuXxYMYIllHTsnsNwcqXPgyZ5YTtgRtgpAHQAqEhQVmECFUwCrhGld0ANAjyYkdTbp2mOBVq076tQhFShsSQCBSKndcVZYDJuk3HIEQIpljLoXbPpSURQkywtnZwnouZKM3ooAyMy0JGCWVlQJVLJ8TBGATWK+EqDSikjoZM4TATBeiQWR1ip1ZhLL+5Kv7DpVhKESwEq2JdQSVctmJQCVE8myFwGP6Fk2MTJOhMvGUtT0aeQzWeV8GaC3bOwz2zYWheu8vK8eU//10Fx+Javlnb23vwk/9er2v9NLn088PW/nlgQoIAXpUSCggAAkqGB9zC2oYEAAOw== +"""), + "thug": base64.decode(""" +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 +"""), + "conga": base64.decode(""" +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 +"""), + "moonwalk": base64.decode(""" +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 +"""), + "pair": base64.decode(""" +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 +"""), + "usa": base64.decode(""" +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 +"""), + "cloud": base64.decode(""" +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 +"""), + "blob": base64.decode(""" +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 +"""), +} + +def main(config): + gif = GIFs[config.str("type", "normal")] + return render.Root( + render.Box( + child = render.Image(src = gif), + ), + ) + +def get_schema(): + options = [ + schema.Option( + display = "Normal", + value = "normal", + ), + schema.Option( + display = "Fast", + value = "fast", + ), + schema.Option( + display = "Stoked", + value = "stoked", + ), + schema.Option( + display = "Sassy", + value = "sassy", + ), + schema.Option( + display = "Meld", + value = "meld", + ), + schema.Option( + display = "Thug life", + value = "thug", + ), + schema.Option( + display = "Conga line", + value = "conga", + ), + schema.Option( + display = "Moonwalk", + value = "moonwalk", + ), + schema.Option( + display = "Pair", + value = "pair", + ), + schema.Option( + display = "USA", + value = "usa", + ), + schema.Option( + display = "Cloud", + value = "cloud", + ), + schema.Option( + display = "Blob", + value = "blob", + ), + ] + return schema.Schema( + version = "1", + fields = [ + schema.Dropdown( + id = "type", + name = "Type", + desc = "Choose your parrot", + icon = "feather", + default = options[0].value, + options = options, + ), + ], + ) diff --git a/apps/plexshowtime/plex_showtime.star b/apps/plexshowtime/plex_showtime.star index ff29a3294..4453c2a65 100644 --- a/apps/plexshowtime/plex_showtime.star +++ b/apps/plexshowtime/plex_showtime.star @@ -15,16 +15,19 @@ load("time.star", "time") PLEX_ICON = "/9j/4AAQSkZJRgABAQEAwADAAAD/4QBoRXhpZgAATU0AKgAAAAgABAEaAAUAAAABAAAAPgEbAAUAAAABAAAARgEoAAMAAAABAAIAAAExAAIAAAARAAAATgAAAAAAAADAAAAAAQAAAMAAAAABcGFpbnQubmV0IDUuMC4xMwAA/9sAQwABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB/9sAQwEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB/8AAEQgACgAKAwESAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQACEQMRAD8A/nv/AGavgD8JPiR+xD+2B8VPi/4T/wCFey/CVtHv/g1+0v8A2x4rk/4Sb4sXFrbNbfsvf8ID/bf/AAi3i/8A4TC1NjqH/CQ6FoFv4k+GH9vf8JT4y1e/8IzaZplt+a9fn/EPB+eZzxdwxxFl/Gub8PZZkUayzHIctjiKlDiL2k3KNHMI4vMq2Rxw8I3p8/8Aq5WzNQqVXRzShUjgp4L3MDmuDwmV5jga+UYXHYjGuLw+NxDpxngOVJOVB08PHFucmuZr69GheMb4eUXWVcor9APDP//Z" PLEX_BANNER = "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" +PLEX_BANNER_PORTRAIT = "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" +MAX_TEXT_LENGTH = 1000 GET_TOP = 15 def main(config): random.seed(time.now().unix) plex_server_url = config.str("plex_server_url", "") - plex_api_key = config.str("plex_api_key", "") + plex_token = config.str("plex_token", "") show_heading = config.bool("show_heading", True) heading_color = config.str("heading_color", "#FFA500") font_color = config.str("font_color", "#FFFFFF") + show_summary = config.bool("show_summary", False) show_recent = config.bool("show_recent", True) show_added = config.bool("show_added", True) show_library = config.bool("show_library", True) @@ -59,10 +62,11 @@ def main(config): if debug_output: print("------------------------------") print("CONFIG - plex_server_url: " + plex_server_url) - print("CONFIG - plex_api_key: " + plex_api_key) + print("CONFIG - plex_token: " + plex_token) print("CONFIG - ttl_seconds: " + str(ttl_seconds)) print("CONFIG - debug_output: " + str(debug_output)) print("CONFIG - endpoint_map: " + str(endpoint_map)) + print("CONFIG - show_summary: " + str(show_summary)) print("CONFIG - show_recent: " + str(show_recent)) print("CONFIG - show_added: " + str(show_added)) print("CONFIG - show_playing: " + str(show_playing)) @@ -74,15 +78,15 @@ def main(config): print("CONFIG - font_color: " + font_color) print("CONFIG - fit_screen: " + str(fit_screen)) - return get_text(plex_server_url, plex_api_key, endpoint_map, debug_output, fit_screen, filter_movie, filter_tv, filter_music, show_heading, heading_color, font_color, ttl_seconds) + return get_text(plex_server_url, plex_token, endpoint_map, debug_output, fit_screen, filter_movie, filter_tv, filter_music, show_heading, show_summary, heading_color, font_color, ttl_seconds) -def get_text(plex_server_url, plex_api_key, endpoint_map, debug_output, fit_screen, filter_movie, filter_tv, filter_music, show_heading, heading_color, font_color, ttl_seconds): +def get_text(plex_server_url, plex_token, endpoint_map, debug_output, fit_screen, filter_movie, filter_tv, filter_music, show_heading, show_summary, heading_color, font_color, ttl_seconds): base_url = plex_server_url if base_url.endswith("/"): base_url = base_url[0:len(base_url) - 1] display_message_string = "" - if plex_server_url == "" or plex_api_key == "": + if plex_server_url == "" or plex_token == "": display_message_string = "Plex API URL and Plex API key must not be blank" elif endpoint_map["id"] == 0: display_message_string = "Select recent, added, library or playing" @@ -91,7 +95,7 @@ def get_text(plex_server_url, plex_api_key, endpoint_map, debug_output, fit_scre else: headerMap = { "Accept": "application/json", - "X-Plex-Token": plex_api_key, + "X-Plex-Token": plex_token, } api_endpoint = plex_server_url @@ -115,13 +119,20 @@ def get_text(plex_server_url, plex_api_key, endpoint_map, debug_output, fit_scre break if valid_parent_map == True: + using_portrait_banner = False + marquee_text_array = [ - {"message": endpoint_map["title"], "color": heading_color}, - {"message": "Not Available", "color": font_color}, + {"type": "heading", "message": endpoint_map["title"], "color": heading_color}, + {"type": "title", "message": "Not Available", "color": font_color}, + {"type": "body", "message": "Not Available", "color": font_color}, ] - img = base64.decode(PLEX_BANNER) + if show_summary: + img = base64.decode(PLEX_BANNER_PORTRAIT) + else: + img = base64.decode(PLEX_BANNER) + # Get media list and filter if output["MediaContainer"]["size"] > 0: # Check if has needed keys valid_media_container_key = False @@ -166,7 +177,7 @@ def get_text(plex_server_url, plex_api_key, endpoint_map, debug_output, fit_scre elif library_type == "show": # Try to find episodes library_type_enum = 4 - media_type = "Show" + media_type = "TV Show" elif library_type == "artist": media_type = "Music" @@ -212,6 +223,7 @@ def get_text(plex_server_url, plex_api_key, endpoint_map, debug_output, fit_scre if endpoint_map["id"] != 4 and len(metadata_list) > GET_TOP: break + # Process text if len(metadata_list) > 0: random_index = random.number(0, len(metadata_list) - 1) if library_type == "artist": @@ -234,16 +246,121 @@ def get_text(plex_server_url, plex_api_key, endpoint_map, debug_output, fit_scre is_clip = True break - image_map = find_valid_image(metadata_list[random_index], base_url, debug_output, headerMap, ttl_seconds) + # Relabel + media_type = "Movie" + if is_clip: + media_type = "Clip" + elif metadata_list[random_index]["type"] == "season" or metadata_list[random_index]["type"] == "episode" or metadata_list[random_index]["type"] == "show": + media_type = "TV Show" + elif metadata_list[random_index]["type"] == "album" or metadata_list[random_index]["type"] == "track" or metadata_list[random_index]["type"] == "artist": + media_type = "Music" + elif metadata_list[random_index]["type"] == "movie": + media_type = "Movie" + + # Find title + header_text = "" + if show_heading: + header_text = media_type + " " + endpoint_map["title"] + + header_text = header_text.strip() + + if debug_output: + print("header_text: " + header_text) + + title = "" + parent_title = "" + grandparent_title = "" + for key in metadata_keys: + if key == "title": + title = metadata_list[random_index][key] + elif key == "parentTitle": + parent_title = metadata_list[random_index][key] + elif key == "grandparentTitle": + grandparent_title = metadata_list[random_index][key] + + if len(grandparent_title) > 0: + grandparent_title = grandparent_title + " - " + if len(parent_title) > 0: + parent_title = parent_title + ": " + + # Find summary + title_text = "" + if show_summary: + title_text = grandparent_title + parent_title + title + title_text = title_text.strip() + contains_summary = False + has_key = False + for m_key in metadata_list[random_index].keys(): + if m_key == "summary" and len(metadata_list[random_index][m_key].strip()) > 0: + contains_summary = True + + if m_key == "key": + has_key = True + + # Check if summary exists + if contains_summary == False and has_key: + child_metadata = get_data(base_url + metadata_list[random_index]["key"], debug_output, headerMap, ttl_seconds) + child_metadata_output = json.decode(child_metadata, None) + + if child_metadata_output != None: + valid = False + for m_key in child_metadata_output.keys(): + if m_key == "MediaContainer": + valid = True + break + if valid and child_metadata_output["MediaContainer"]["size"] > 0: + child_metadata_first = child_metadata_output["MediaContainer"]["Metadata"][0] + for m_key in child_metadata_first.keys(): + if m_key == "summary" and len(child_metadata_first[m_key].strip()) > 0: + metadata_list[random_index][m_key] = child_metadata_first[m_key].strip() + contains_summary = True + break + + body_text = "" + if contains_summary: + body_text = metadata_list[random_index]["summary"] + else: + body_text = grandparent_title + parent_title + title + body_text = body_text.strip() + show_summary = False + if debug_output: + print("body_text: " + body_text) + if debug_output: + print("title_text: " + title_text) + + output_str = body_text[0:len(body_text)] + if len(output_str) > 200: + output_str = output_str[0:200] + "..." + + print("body_text: " + output_str) + else: + body_text = grandparent_title + parent_title + title + body_text = body_text.strip() + if debug_output: + print("body_text: " + body_text) + + if len(title_text) >= MAX_TEXT_LENGTH: + title_text = title_text[0:MAX_TEXT_LENGTH] + "..." + print("Title text truncated") + + if len(body_text) >= MAX_TEXT_LENGTH: + body_text = body_text[0:MAX_TEXT_LENGTH] + "..." + print("Body text truncated") + + # Find art + image_map = find_valid_image(metadata_list[random_index], base_url, debug_output, headerMap, show_summary, ttl_seconds) img = image_map["img"] art_type = image_map["art_type"] img_url = image_map["img_url"] validated_image = image_map["validated_image"] - # If art not found, try to look for specific metadata art - if art_type == "thumb" or art_type == "parentThumb" or art_type == "grandparentThumb": + # If art/thumb not found, try to look for specific metadata art/thumb + if (show_summary and (art_type == "art" or art_type == "parentArt" or art_type == "grandparentArt")) or (show_summary == False and (art_type == "thumb" or art_type == "parentThumb" or art_type == "grandparentThumb")): if debug_output: - print("Only thumbnails found, looking further for art") + if show_summary: + print("Only art found, looking further for thumbnails") + else: + print("Only thumbnails found, looking further for art") single_metadata = base_url + metadata_list[random_index]["key"] single_metadata_json = get_data(single_metadata, debug_output, headerMap, ttl_seconds) metadata_output = json.decode(single_metadata_json, None) @@ -254,13 +371,13 @@ def get_text(plex_server_url, plex_api_key, endpoint_map, debug_output, fit_scre if m_key == "MediaContainer": valid = True if valid and metadata_output["MediaContainer"]["size"] > 0: - sub_image_map = find_valid_image(metadata_output["MediaContainer"]["Metadata"][0], base_url, debug_output, headerMap, ttl_seconds) + sub_image_map = find_valid_image(metadata_output["MediaContainer"]["Metadata"][0], base_url, debug_output, headerMap, show_summary, ttl_seconds) sub_img = sub_image_map["img"] sub_art_type = sub_image_map["art_type"] sub_img_url = sub_image_map["img_url"] sub_validated_image = sub_image_map["validated_image"] - if sub_art_type == "art" or sub_art_type == "parentArt" or sub_art_type == "grandparentArt": + if (show_summary == False and (sub_art_type == "art" or sub_art_type == "parentArt" or sub_art_type == "grandparentArt")) or (show_summary and (sub_art_type == "thumb" or sub_art_type == "parentThumb" or sub_art_type == "grandparentThumb")): if debug_output: print("Identified art in metadata") img = sub_img @@ -276,62 +393,41 @@ def get_text(plex_server_url, plex_api_key, endpoint_map, debug_output, fit_scre else: if debug_output: print("Media image not detected, using Plex banner") - img = base64.decode(PLEX_BANNER) + if show_summary: + using_portrait_banner = True + img = base64.decode(PLEX_BANNER_PORTRAIT) + else: + img = base64.decode(PLEX_BANNER) elif debug_output: print("Using image type " + art_type + ": " + img_url) - media_type = "Movie" - if is_clip: - media_type = "Clip" - elif metadata_list[random_index]["type"] == "season" or metadata_list[random_index]["type"] == "episode" or metadata_list[random_index]["type"] == "show": - media_type = "Show" - elif metadata_list[random_index]["type"] == "album" or metadata_list[random_index]["type"] == "track" or metadata_list[random_index]["type"] == "artist": - media_type = "Music" - elif metadata_list[random_index]["type"] == "movie": - media_type = "Movie" - - header_text = "" - if show_heading: - header_text = media_type + " " + endpoint_map["title"] - - header_text = header_text.strip() - - if debug_output: - print("header_text: " + header_text) - - title = "" - parent_title = "" - grandparent_title = "" - for key in metadata_keys: - if key == "title": - title = metadata_list[random_index][key] - elif key == "parentTitle": - parent_title = metadata_list[random_index][key] - elif key == "grandparentTitle": - grandparent_title = metadata_list[random_index][key] - - if len(grandparent_title) > 0: - grandparent_title = grandparent_title + " - " - if len(parent_title) > 0: - parent_title = parent_title + ": " - - body_text = grandparent_title + parent_title + title - body_text = body_text.strip() - if debug_output: - print("body_text: " + body_text) - - marquee_text_array = [ - {"message": header_text, "color": heading_color}, - {"message": body_text, "color": font_color}, - ] + if show_summary: + marquee_text_array = [ + {"type": "heading", "message": header_text, "color": "#FFFFFF"}, + {"type": "title", "message": title_text, "color": heading_color}, + {"type": "body", "message": body_text, "color": font_color}, + ] + else: + marquee_text_array = [ + {"type": "heading", "message": header_text, "color": heading_color}, + {"type": "body", "message": body_text, "color": font_color}, + ] - if debug_output: + if debug_output and show_summary == False: print("Full title: " + header_text + " " + body_text) else: display_message_string = "No results for " + endpoint_map["title"] return display_message(debug_output, [{"message": display_message_string, "color": "#FF0000"}]) - if fit_screen == True: + # img = base64.decode(PLEX_BANNER_PORTRAIT) + # using_portrait_banner = True + + if show_summary: + rendered_image = render.Image( + width = 22, + src = img, + ) + elif fit_screen: rendered_image = render.Image( width = 64, src = img, @@ -342,7 +438,7 @@ def get_text(plex_server_url, plex_api_key, endpoint_map, debug_output, fit_scre src = img, ) - return render_marquee(marquee_text_array, rendered_image, debug_output) + return render_marquee(marquee_text_array, rendered_image, show_summary, debug_output, using_portrait_banner) else: display_message_string = "No valid results for " + endpoint_map["title"] @@ -353,7 +449,7 @@ def get_text(plex_server_url, plex_api_key, endpoint_map, debug_output, fit_scre return display_message(debug_output, [{"message": display_message_string, "color": "#FF0000"}]) -def find_valid_image(metadata, base_url, debug_output, headerMap, ttl_seconds): +def find_valid_image(metadata, base_url, debug_output, headerMap, show_summary, ttl_seconds): img = None art_type = "" img_url = "" @@ -362,58 +458,103 @@ def find_valid_image(metadata, base_url, debug_output, headerMap, ttl_seconds): # thumb if art not available img = None - validated_image = "" - valid_keys = [] + valid_image = { + "art": False, + "parentArt": False, + "grandparentArt": False, + "thumb": False, + "parentThumb": False, + "grandparentThumb": False, + } + for key in metadata_keys: if key == "art" or key == "parentArt" or key == "grandparentArt" or (key == "thumb" and metadata["thumb"].endswith("/-1") == False) or key == "parentThumb" or key == "grandparentThumb": - valid_keys.append(key) + valid_image[key] = True - for valid_key in valid_keys: - if valid_key == "art": - art_type = valid_key - img_url = base_url + metadata[art_type] - img = get_data(img_url, debug_output, headerMap, ttl_seconds) - break - if img == None: - for valid_key in valid_keys: - if valid_key == "parentArt": - art_type = valid_key + # if show_summary is true, prioritize thumbs + if show_summary: + if metadata["type"] == "album" or metadata["type"] == "track" or metadata["type"] == "artist": + if valid_image["thumb"] == True: + art_type = "thumb" img_url = base_url + metadata[art_type] img = get_data(img_url, debug_output, headerMap, ttl_seconds) - break - if img == None: - for valid_key in valid_keys: - if valid_key == "grandparentArt": - art_type = valid_key - img_url = base_url + metadata[art_type] - img = get_data(img_url, debug_output, headerMap, ttl_seconds) - break - if img == None: - for valid_key in valid_keys: - if valid_key == "thumb": - art_type = valid_key + + if valid_image["parentThumb"] == True and img == None: + art_type = "parentThumb" img_url = base_url + metadata[art_type] img = get_data(img_url, debug_output, headerMap, ttl_seconds) - break - if img == None: - for valid_key in valid_keys: - if valid_key == "parentThumb": - art_type = valid_key + else: + if valid_image["parentThumb"] == True: + art_type = "parentThumb" img_url = base_url + metadata[art_type] img = get_data(img_url, debug_output, headerMap, ttl_seconds) - break - if img == None: - for valid_key in valid_keys: - if valid_key == "grandparentThumb": - art_type = valid_key + + if valid_image["thumb"] == True and img == None: + art_type = "thumb" img_url = base_url + metadata[art_type] img = get_data(img_url, debug_output, headerMap, ttl_seconds) - break + + if valid_image["grandparentThumb"] == True and img == None: + art_type = "grandparentThumb" + img_url = base_url + metadata[art_type] + img = get_data(img_url, debug_output, headerMap, ttl_seconds) + + if valid_image["art"] == True and img == None: + art_type = "art" + img_url = base_url + metadata[art_type] + img = get_data(img_url, debug_output, headerMap, ttl_seconds) + + if valid_image["parentArt"] == True and img == None: + art_type = "parentArt" + img_url = base_url + metadata[art_type] + img = get_data(img_url, debug_output, headerMap, ttl_seconds) + + if valid_image["grandparentArt"] == True and img == None: + art_type = "grandparentArt" + img_url = base_url + metadata[art_type] + img = get_data(img_url, debug_output, headerMap, ttl_seconds) + else: + if valid_image["art"] == True: + art_type = "art" + img_url = base_url + metadata[art_type] + img = get_data(img_url, debug_output, headerMap, ttl_seconds) + + if valid_image["parentArt"] == True and img == None: + art_type = "parentArt" + img_url = base_url + metadata[art_type] + img = get_data(img_url, debug_output, headerMap, ttl_seconds) + + if valid_image["grandparentArt"] == True and img == None: + art_type = "grandparentArt" + img_url = base_url + metadata[art_type] + img = get_data(img_url, debug_output, headerMap, ttl_seconds) + + if valid_image["thumb"] == True and img == None: + art_type = "thumb" + img_url = base_url + metadata[art_type] + img = get_data(img_url, debug_output, headerMap, ttl_seconds) + + if valid_image["parentThumb"] == True and img == None: + art_type = "parentThumb" + img_url = base_url + metadata[art_type] + img = get_data(img_url, debug_output, headerMap, ttl_seconds) + + if valid_image["grandparentThumb"] == True and img == None: + art_type = "grandparentThumb" + img_url = base_url + metadata[art_type] + img = get_data(img_url, debug_output, headerMap, ttl_seconds) + + validated_image = "" + if img != None: + validated_image = img return {"img": img, "art_type": art_type, "img_url": img_url, "validated_image": validated_image} -def display_message(debug_output, message_array = []): - img = base64.decode(PLEX_BANNER) +def display_message(debug_output, message_array = [], show_summary = False): + if show_summary: + img = base64.decode(PLEX_BANNER_PORTRAIT) + else: + img = base64.decode(PLEX_BANNER) if debug_output == False: return render.Root( @@ -434,9 +575,9 @@ def display_message(debug_output, message_array = []): width = 64, src = img, ) - return render_marquee(message_array, rendered_image, debug_output) + return render_marquee(message_array, rendered_image, show_summary, debug_output) -def render_marquee(message_array, image, debug_output): +def render_marquee(message_array, image, show_summary, debug_output, using_portrait_banner = False): icon_img = base64.decode(PLEX_ICON) text_array = [] @@ -445,79 +586,235 @@ def render_marquee(message_array, image, debug_output): string_length = 0 full_message = "" for_break = False + heading_lines = 0 + title_lines = 0 + body_lines = 0 for message in message_array: - if index == len(message_array) - 1 or len(message["message"]) > 0: - marquee_message = message["message"] - local_length = len(marquee_message) - if local_length > 0: - local_length = local_length + 1 - - string_length = string_length + local_length - - if index == len(message_array) - 1 and string_length > max_length: - marquee_message = marquee_message[0:local_length - (string_length - max_length + 3)] + "..." - for_break = True - elif index == len(message_array) - 1 and string_length <= max_length: - marquee_message = marquee_message[0:local_length] - for_break = True - elif len(message["message"]) > 0: - # Heading - marquee_message = marquee_message + " " - - full_message = full_message + marquee_message - text_array.append(render.Text(marquee_message, color = message["color"], font = "tom-thumb")) - if for_break: - break + if show_summary == False: + if index == len(message_array) - 1 or len(message["message"]) > 0: + marquee_message = message["message"] + local_length = len(marquee_message) + if local_length > 0: + local_length = local_length + 1 + + string_length = string_length + local_length + + if index == len(message_array) - 1 and string_length > max_length: + # marquee_message = marquee_message[0:local_length-(string_length-max_length+3)] + "..." + for_break = True + elif index == len(message_array) - 1 and string_length <= max_length: + marquee_message = marquee_message[0:local_length] + for_break = True + elif len(message["message"]) > 0: + # Heading + marquee_message = marquee_message + " " + + full_message = full_message + marquee_message + text_array.append(render.Text(marquee_message, color = message["color"], font = "tom-thumb")) + if for_break: + break + elif len(message["message"]) > 0: + output_text = wrap(message["message"], 9) + + if message["type"] == "heading": + heading_lines = calculate_lines(output_text, 10) + if debug_output: + print("heading_lines: " + str(heading_lines)) + elif message["type"] == "title": + title_lines = calculate_lines(output_text, 10) + if debug_output: + print("title_lines: " + str(title_lines)) + elif message["type"] == "body": + body_lines = calculate_lines(output_text, 10) + if debug_output: + print("body_lines: " + str(body_lines)) + + text_array.append(render.WrappedText(content = output_text, font = "tom-thumb", color = message["color"], width = 41)) index = index + 1 - if debug_output: + if show_summary == False and debug_output: print("Marquee text: " + full_message) - return render.Root( - child = render.Column( - children = [ - render.Box( - width = 64, - height = 7, - child = render.Row( - expanded = True, - main_align = "space_evenly", - cross_align = "center", - children = [ - render.Image(src = icon_img, width = 7, height = 7), - render.Padding( - pad = (0, 1, 0, 0), - child = render.Row( - expanded = True, - main_align = "space_evenly", - cross_align = "center", - children = [ - render.Marquee( - scroll_direction = "horizontal", - width = 57, - offset_start = 64, - offset_end = 57, - child = render.Row(text_array), + if show_summary: + marquee_height = 32 + ((heading_lines + title_lines + body_lines) - ((heading_lines + title_lines + body_lines) * 0.62)) + + children = [ + render.Column( + expanded = True, + main_align = "space_evenly", + cross_align = "center", + children = [image], + ), + ] + + if using_portrait_banner == False: + children.append(render.Image(src = icon_img, width = 7, height = 7)) + + return render.Root( + delay = 90, + show_full_animation = True, + child = render.Box( + render.Row( + children = [ + render.Stack( + children = children, + ), + render.Padding( + pad = (1, 0, 0, 0), + child = render.Stack( + children = [ + render.Marquee( + offset_start = 32, + offset_end = 32, + height = int(marquee_height), + scroll_direction = "vertical", + width = 41, + child = render.Column( + children = text_array, ), - ], - ), + ), + # render.Row( + # expanded=True, + # cross_align="end", + # main_align="end", + # children=[render.Image(src = icon_img, width = 7, height = 7)] + # ) + ], ), - ], - ), + ), + ], ), - render.Padding( - pad = (0, 0, 0, 0), - child = render.Row( - expanded = True, - main_align = "space_evenly", - cross_align = "center", - children = [image], + ), + ) + else: + marquee_width = 57 + ((len(full_message)) - ((len(full_message)) * 0.9)) + + return render.Root( + show_full_animation = True, + child = render.Column( + children = [ + render.Box( + width = 64, + height = 7, + child = render.Row( + expanded = True, + main_align = "space_evenly", + cross_align = "center", + children = [ + render.Image(src = icon_img, width = 7, height = 7), + render.Padding( + pad = (0, 1, 0, 0), + child = render.Row( + expanded = True, + main_align = "space_evenly", + cross_align = "center", + children = [ + render.Marquee( + scroll_direction = "horizontal", + width = int(marquee_width), + offset_start = 64, + offset_end = 57, + child = render.Row(text_array), + ), + ], + ), + ), + ], + ), ), - ), - ], - ), - ) + render.Padding( + pad = (0, 0, 0, 0), + child = render.Row( + expanded = True, + main_align = "space_evenly", + cross_align = "center", + children = [image], + ), + ), + ], + ), + ) + +def calculate_lines(text, length): + words = text.split(" ") + currentlength = 0 + breaks = 0 + + for word in words: + subwords = text.split("\n") + if len(subwords) > 0 or len(word) + currentlength >= length: + # subwords = word + # if len(subwords) + currentlength >= length: + if len(subwords) == 0: + breaks = breaks + 1 + else: + breaks = len(subwords) + currentlength = 0 + currentlength = currentlength + len(subwords) + 1 + + return breaks + 1 + +def wrap(string, line_length): + lines = string.split("\n") + + b = "" + for line in lines: + b = b + wrap_line(line, line_length) + + return b + +def wrap_line(line, line_length): + if len(line) == 0: + return "\n" + + if len(line) <= line_length: + return line + "\n" + + words = line.split(" ") + cur_line_length = 0 + str_builder = "" + + index = 0 + for word in words: + # If adding the new word to the current line would be too long, + # then put it on a new line (and split it up if it's too long). + if (index == 0 or (cur_line_length + len(word)) > line_length): + # Only move down to a new line if we have text on the current line. + # Avoids situation where + # wrapped whitespace causes emptylines in text. + if cur_line_length > 0: + str_builder = str_builder + "\n" + cur_line_length = 0 + + # If the current word is too long + # to fit on a line (even on its own), + # then split the word up. + for _ in range(5000): + if len(word) <= line_length: + word = word + " " + break + else: + str_builder = str_builder + word[0:line_length - 1] + if word.strip().rfind("-") == -1 and word.strip().rfind("'") == -1: + str_builder = str_builder + "-" + word = word[line_length - 1:len(word)] + str_builder = str_builder + "\n" + + # Remove leading whitespace from the word, + # so the new line starts flush to the left. + word = word.lstrip(" ") + + if word.rfind(" ") == -1: + str_builder = str_builder + " " + word.strip() + else: + str_builder = str_builder + word.strip() + + cur_line_length = cur_line_length + len(word) + + index = index + 1 + + return str_builder def get_data(url, debug_output, headerMap = {}, ttl_seconds = 20): res = None @@ -546,39 +843,46 @@ def get_schema(): fields = [ schema.Text( id = "plex_server_url", - name = "Plex Server URL (required)", - desc = "Your Plex Server URL.", + name = "Plex server URL (required)", + desc = "Plex server URL.", icon = "globe", default = "", ), schema.Text( - id = "plex_api_key", - name = "Plex API Key (required)", - desc = "Your Plex API key.", + id = "plex_token", + name = "Plex token (required)", + desc = "Plex token.", icon = "key", default = "", ), schema.Toggle( id = "show_heading", name = "Show heading", - desc = "Show the heading with title", + desc = "Display the media and library view type.", icon = "eye", default = True, ), schema.Text( id = "heading_color", name = "Heading color", - desc = "Heading color using Hex color codes. eg, `#FFA500`", + desc = "Heading color using Hex color codes. eg, `#FFA500`. This is the title in summary view, otherwise the media and library view type.", icon = "paintbrush", default = "#FFA500", ), schema.Text( id = "font_color", name = "Font color", - desc = "Main font color using Hex color codes. eg, `#FFFFFF`", + desc = "Main font color using Hex color codes. eg, `#FFFFFF`. This is the summary in summary view, otherwise the title.", icon = "paintbrush", default = "#FFFFFF", ), + schema.Toggle( + id = "show_summary", + name = "Show summary", + desc = "Show summary if available.", + icon = "alignLeft", + default = False, + ), schema.Toggle( id = "fit_screen", name = "Fit screen", @@ -630,8 +934,8 @@ def get_schema(): ), schema.Toggle( id = "filter_tv", - name = "Filter by shows", - desc = "Filter results by shows.", + name = "Filter by TV shows", + desc = "Filter results by TV shows.", icon = "tv", default = True, ), diff --git a/apps/rachio/rachio.star b/apps/rachio/rachio.star index 8381d9f8f..f9f6b7672 100644 --- a/apps/rachio/rachio.star +++ b/apps/rachio/rachio.star @@ -108,10 +108,10 @@ def main(config): current_events = None all_events = get_events(selected_device, api_key, past_start, rounded_time) - recent_events = get_selected_events(all_events, False) - current_events = get_selected_events(all_events, True) + recent_events = get_selected_events(tz, all_events, False) + current_events = get_selected_events(tz, all_events, True) - return render_rachio(config, get_device_name(devices, selected_device), recent_events, current_events, now, delay, skip_when_empty) + return render_rachio(tz, config, get_device_name(devices, selected_device), recent_events, current_events, now, delay, skip_when_empty) def get_device_name(devices, selected_device): for device in devices: @@ -164,7 +164,7 @@ def display_error_screen(time, line_3, line_4 = "", delay = 45): delay = delay, ) -def render_rachio(config, device_name, recent_events, current_events, now, delay, skip_when_empty = True): +def render_rachio(tz, config, device_name, recent_events, current_events, now, delay, skip_when_empty = True): show_device_name = config.bool("title_display", True) line_1 = "Rachio" @@ -199,7 +199,7 @@ def render_rachio(config, device_name, recent_events, current_events, now, delay if show_current_events: preface = "Current" - readable_date = time.from_timestamp(int(int(latest_event["eventDate"]) / 1000.0)) + readable_date = time.from_timestamp(int(int(latest_event["eventDate"]) / 1000.0)).in_location(tz) line_2 = readable_date.format("Mon Jan 2 at 3:04 PM") line_3 = "%s: %s - %s" % (preface, latest_event["summary"], readable_date.format("Mon Jan 2 at 3:04 PM")) @@ -261,7 +261,7 @@ def get_events(deviceId, api_key, start, end): return event_response.json() -def get_selected_events(events, current): +def get_selected_events(tz, events, current): selected_sub_types = [] if current: selected_sub_types = [ZONE_STARTED] @@ -272,7 +272,7 @@ def get_selected_events(events, current): for event in events: if "subType" in event.keys(): if event["subType"] in selected_sub_types: - eventDateSecs = time.from_timestamp(int(event["eventDate"] / 1000)) + eventDateSecs = time.from_timestamp(int(event["eventDate"] / 1000)).in_location(tz) parsedDate = eventDateSecs.format("Monday 03:04PM") newEvent = dict(type = event["subType"], date = parsedDate, summary = event["summary"], eventDate = event["eventDate"]) selected_events.append(newEvent) diff --git a/apps/shipweatherclock/manifest.yaml b/apps/shipweatherclock/manifest.yaml new file mode 100644 index 000000000..4bc77ed5a --- /dev/null +++ b/apps/shipweatherclock/manifest.yaml @@ -0,0 +1,6 @@ +--- +id: shipweatherclock +name: ShipWeatherClock +summary: Ship scene w time/weather +desc: Clock with ship on the ocean scene that changes with weather. +author: Peter Uth diff --git a/apps/shipweatherclock/shipweatherclock.star b/apps/shipweatherclock/shipweatherclock.star new file mode 100644 index 000000000..756de3b24 --- /dev/null +++ b/apps/shipweatherclock/shipweatherclock.star @@ -0,0 +1,583 @@ +""" +Applet: ShipWeatherClock +Summary: Ship scene w time/weather +Description: Clock with ship on the ocean scene that changes with weather. +Author: Peter Uth +""" + +load("encoding/base64.star", "base64") +load("encoding/json.star", "json") +load("http.star", "http") +load("render.star", "render") +load("schema.star", "schema") +load("time.star", "time") + +TTL_SECONDS = 20 * 60 # 20 minutes API pull interval +DEFAULT_LOCATION = { + "lat": "47.60", + "lng": "-122.33", + "locality": "Seattle", + "timezone": "America/Los_Angeles", +} + +# define custom pixel art +SHIP_DAY = base64.decode("iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAABhGlDQ1BJQ0MgcHJvZmlsZQAAKJF9kT1Iw0AcxV9Ti1IqDhYRdchQneyiIuJUq1CECqVWaNXB5NIvaNKQpLg4Cq4FBz8Wqw4uzro6uAqC4AeIs4OToouU+L+k0CLGg+N+vLv3uHsHCI0KU82uGKBqlpFOxMVsblXsfkUQwxhAALMSM/W5VCoJz/F1Dx9f76I8y/vcn6NXyZsM8InEMaYbFvEG8fSmpXPeJw6zkqQQnxOPG3RB4keuyy6/cS46LPDMsJFJzxOHicViB8sdzEqGSjxFHFFUjfKFrMsK5y3OaqXGWvfkLwzltZVlrtMcQQKLWEIKImTUUEYFFqK0aqSYSNN+3MM/5PhT5JLJVQYjxwKqUCE5fvA/+N2tWZiccJNCcSDwYtsfo0D3LtCs2/b3sW03TwD/M3Cltf3VBjDzSXq9rUWOgL5t4OK6rcl7wOUOMPikS4bkSH6aQqEAvJ/RN+WA/lsguOb21trH6QOQoa6SN8DBITBWpOx1j3f3dPb275lWfz/OkXLLpp+1fwAAAAlwSFlzAAAuIwAALiMBeKU/dgAAAAd0SU1FB+gKGxYTBfJFka8AAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAoklEQVQoz52QTRHEIAyFXzq991oPRQAOqgIZVbEyULEOEJB42OsqYA8M3cAA7fSdwiNf/gAlZo610NGMgUQEGiYiyvEEAFfVb3UUkVsgMXPRadu2YRFjTBpXH6I+zuhYEx7qMXjq2BFbcevtLCI5W5o+gI4d8fUG5aS6iQ8gchZxXZLx+ban0f8+pIJzNtbln9CShgCU4/TAGjrB3i56p9r7AUivfni8gP/RAAAAAElFTkSuQmCC") +SHIP_NIGHT = base64.decode("iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAABgmlDQ1BJQ0MgcHJvZmlsZQAAKJF9kTtIA0EURY9RiWjEwhQiIltEK9OoiKVGIQgKISr4K9zdmChk17CbYGMp2AYs/DRGLWystbWwFQTBD4i1hZWijcj6JgkkiHFgmMOduY/37oCvkDYtt2EELDvrxKMRbW5+QfO/0IIP6Mavm25mNBabpOb6vKNOnbdhVav2uz9Xa2LFNaFOEx4xM05WeFl4aCObUbwnHDRX9YTwmXCfIw0KPyjdKPGr4lSRVdMEnZn4mHBQWEtVsVHF5qpjCQ8KhxKWLfV9cyVOKN5UbKVzZrlPNWFgxZ6dVrrsLqJMMEUMDYMca6TJEpbTFsUlLveRGv7Ooj8mLkNca5jiGGcdC73oR/3B72zd5EB/qVIgAo3PnvfeA/4d+M573teR530fQ/0TXNoV/3oBhj9Ez1e00CG0bcH5VUUzduFiGzoeM7qjF6V62b5kEt5O5Zvmof0GmhdLuZXvObmHGclq8hr2D6A3JbWXaszdVJ3bv2/K+f0AGrVyg8UeX9UAAAAJcEhZcwAALiMAAC4jAXilP3YAAAAHdElNRQfoCwIAKB5MSFkcAAAAGXRFWHRDb21tZW50AENyZWF0ZWQgd2l0aCBHSU1QV4EOFwAAAK1JREFUKM+dkCESwjAQRd8yEQh0VXFUVyARvU9OkVP0RkhEPY6qagSiM4soLSEstNOnNn/3708iRHjvNcuyWCKEIBg4/tB1HSEEtZa4l6Dj4FKclbIE8d5rLMRvtJbUdS0Abm4w/ayRDStZbZw4HVCrTs+9omWOSpl/Dl1uUBVwviK9osf9d0jTItIrWhWDcH/Yt9lt3/2mRQCmxLH5i9gEDMWcOTVNxthskZoAnlZrRXVS7ZEKAAAAAElFTkSuQmCC") +STARS = base64.decode("iVBORw0KGgoAAAANSUhEUgAAAEAAAAAgCAIAAAAt/+nTAAABg2lDQ1BJQ0MgcHJvZmlsZQAAKJF9kT1Iw0AcxV9TpWIrDnYQcchQneyiIo61CkWoEGqFVh1MLv2CJg1Jiouj4Fpw8GOx6uDirKuDqyAIfoA4OzgpukiJ/0sKLWI8OO7Hu3uPu3eA0KwyzepJAJpum5lUUszlV8XQK8IQEEIcYZlZxpwkpeE7vu4R4OtdnGf5n/tzDKgFiwEBkTjBDNMm3iCe2bQNzvvEUVaWVeJz4gmTLkj8yHXF4zfOJZcFnhk1s5l54iixWOpipYtZ2dSIp4ljqqZTvpDzWOW8xVmr1ln7nvyFkYK+ssx1mqNIYRFLkCBCQR0VVGFTXxXopFjI0H7Sxz/i+iVyKeSqgJFjATVokF0/+B/87tYqTk16SZEk0PviOB9jQGgXaDUc5/vYcVonQPAZuNI7/loTmP0kvdHRYkfA4DZwcd3RlD3gcgcYfjJkU3alIE2hWATez+ib8sDQLdC/5vXW3sfpA5ClrtI3wMEhMF6i7HWfd/d19/bvmXZ/P1uhcp059wCBAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAB3RJTUUH6AsCCAch5iEd9AAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAAAySURBVFjD7dZBEQBACAJAq1OVJJa4l7cbgXHAmZ8lGTijrbsH4Olo4IEFXSdFKQLAYQu39A8iAmA7lwAAAABJRU5ErkJggg==") +MOON = base64.decode("iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAABg2lDQ1BJQ0MgcHJvZmlsZQAAKJF9kT1Iw0AcxV9TpWIrDnYQcchQneyiIo61CkWoEGqFVh1MLv2CJg1Jiouj4Fpw8GOx6uDirKuDqyAIfoA4OzgpukiJ/0sKLWI8OO7Hu3uPu3eA0KwyzepJAJpum5lUUszlV8XQK8IQEEIcYZlZxpwkpeE7vu4R4OtdnGf5n/tzDKgFiwEBkTjBDNMm3iCe2bQNzvvEUVaWVeJz4gmTLkj8yHXF4zfOJZcFnhk1s5l54iixWOpipYtZ2dSIp4ljqqZTvpDzWOW8xVmr1ln7nvyFkYK+ssx1mqNIYRFLkCBCQR0VVGFTXxXopFjI0H7Sxz/i+iVyKeSqgJFjATVokF0/+B/87tYqTk16SZEk0PviOB9jQGgXaDUc5/vYcVonQPAZuNI7/loTmP0kvdHRYkfA4DZwcd3RlD3gcgcYfjJkU3alIE2hWATez+ib8sDQLdC/5vXW3sfpA5ClrtI3wMEhMF6i7HWfd/d19/bvmXZ/P1uhcp059wCBAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAB3RJTUUH6AsCCAU3IMPKJwAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAAA8SURBVBjThY/JDQAwCMNM9x8GJkw/VK3o5SexRAILStxd42YUJM3QzDZhlSKCpwDQ+PAUji9qyXYtlwM67DslQxOP4PMAAAAASUVORK5CYII=") +MOON_CLOUDS = base64.decode("iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAABhGlDQ1BJQ0MgcHJvZmlsZQAAKJF9kT1Iw0AcxV9bpaIVh1YQcchQO9lFRRxrFYpQIdQKrTqYXPoFTRqSFBdHwbXg4Mdi1cHFWVcHV0EQ/ABxdnBSdJES/5cUWsR4cNyPd/ced+8Af7PKVLMnAaiaZWRSSSGXXxWCrxhAAGEMIyYxU58TxTQ8x9c9fHy9i/Ms73N/jkGlYDLAJxAnmG5YxBvEM5uWznmfOMLKkkJ8Tjxh0AWJH7kuu/zGueSwn2dGjGxmnjhCLJS6WO5iVjZU4mniqKJqlO/Puaxw3uKsVuusfU/+wlBBW1nmOs0xpLCIJYgQIKOOCqqwEKdVI8VEhvaTHv5Rxy+SSyZXBYwcC6hBheT4wf/gd7dmcWrSTQolgd4X2/4YB4K7QKth29/Htt06AQLPwJXW8deawOwn6Y2OFj0ChraBi+uOJu8BlzvAyJMuGZIjBWj6i0Xg/Yy+KQ+Eb4H+Nbe39j5OH4AsdZW+AQ4OgViJstc93t3X3du/Z9r9/QCDd3KtmFmoAgAAAAlwSFlzAAAuIwAALiMBeKU/dgAAAAd0SU1FB+gLAxMXMG6cBKMAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAARElEQVQY04XOsQ3AMAwDwZfHUs+5NJh6rpVUAQIHkb8+EAxedfcFYJuqCoBg60EAkuID9qXFUGbOAJiB7fPJ9XdOUgDcvrYd4Q73XgoAAAAASUVORK5CYII=") +CLOUDS_LIGHT_DAY = base64.decode("iVBORw0KGgoAAAANSUhEUgAAAEAAAAAgCAYAAACinX6EAAABhGlDQ1BJQ0MgcHJvZmlsZQAAKJF9kT1Iw0AcxV9bpaIVKXYQcchQnSyIijjWKhShQqgVWnUwufQLmjQkKS6OgmvBwY/FqoOLs64OroIg+AHi7OCk6CIl/i8ptIjx4Lgf7+497t4B/kaFqWZXHFA1y0gnE0I2tyoEX9GHAMKYQFhipj4niil4jq97+Ph6F+NZ3uf+HP1K3mSATyCOM92wiDeIZzYtnfM+cYSVJIX4nHjcoAsSP3JddvmNc9FhP8+MGJn0PHGEWCh2sNzBrGSoxNPEUUXVKN+fdVnhvMVZrdRY6578haG8trLMdZojSGIRSxAhQEYNZVRgIUarRoqJNO0nPPzDjl8kl0yuMhg5FlCFCsnxg//B727NwtSkmxRKAN0vtv0xCgR3gWbdtr+Pbbt5AgSegSut7a82gNlP0uttLXoEDGwDF9dtTd4DLneAoSddMiRHCtD0FwrA+xl9Uw4YvAV619zeWvs4fQAy1FXqBjg4BMaKlL3u8e6ezt7+PdPq7weNmXKxByfkgQAAAAlwSFlzAAAuIwAALiMBeKU/dgAAAAd0SU1FB+gLAxIWNHEom8wAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAABg0lEQVRo3u3UsYoqMRQG4D/jYiHIFnrFRnAbG1nwBW5rdfE57H2CfYfb37dQsBvFYSwGLMRCrtWMNhaiO0Yyk+RstYuiC2vnwPm65JwEzg8J6IwxhlarFS0WC9Jan5doOp3SvZRS1vO8f3hgzvlCCAEpJQqFAhznooTT6QSt9V2X5/N5UavV2pkIgIigtUYul0McxxBCXDQ2m034vg8iujeEXw8dQJqmMMZgv98jDEOEYfh+OByuGsvlMqrVKsbjMYwxP7qciCClTB85ALiuu1+v12a5XB4/90ajESmlbr5rKSVNJhNSSpG19maPtZaMMRRFESGL+v1+EkURpWl6c0CtNQ0GAwqCgI7H49Xws9mMgiAwWZhVfFcYDoe6Xq/nisUiKpXK16dorcVut4PneXBd96XVav1tNBq/S6WScBwn2Ww2/+fz+Vu32x1kIYCnW5u9Xu+53W4/AYDv+7PtdvsqpXSSJIHWGnEcm06n83n2DxhjjDHGGGOMMcYYY4wxxjLgA2EDX+Re5XcdAAAAAElFTkSuQmCC") +CLOUDS_LIGHT_NIGHT = base64.decode("iVBORw0KGgoAAAANSUhEUgAAAEAAAAAgCAYAAACinX6EAAABhGlDQ1BJQ0MgcHJvZmlsZQAAKJF9kT1Iw0AcxV9bpaIVKXYQcchQnSyIijjWKhShQqgVWnUwufQLmjQkKS6OgmvBwY/FqoOLs64OroIg+AHi7OCk6CIl/i8ptIjx4Lgf7+497t4B/kaFqWZXHFA1y0gnE0I2tyoEX9GHAMKYQFhipj4niil4jq97+Ph6F+NZ3uf+HP1K3mSATyCOM92wiDeIZzYtnfM+cYSVJIX4nHjcoAsSP3JddvmNc9FhP8+MGJn0PHGEWCh2sNzBrGSoxNPEUUXVKN+fdVnhvMVZrdRY6578haG8trLMdZojSGIRSxAhQEYNZVRgIUarRoqJNO0nPPzDjl8kl0yuMhg5FlCFCsnxg//B727NwtSkmxRKAN0vtv0xCgR3gWbdtr+Pbbt5AgSegSut7a82gNlP0uttLXoEDGwDF9dtTd4DLneAoSddMiRHCtD0FwrA+xl9Uw4YvAV619zeWvs4fQAy1FXqBjg4BMaKlL3u8e6ezt7+PdPq7weNmXKxByfkgQAAAAlwSFlzAAAuIwAALiMBeKU/dgAAAAd0SU1FB+gLAxMHKtk874gAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAABiUlEQVRo3u3UsaoaQRQG4H/WTKNLBDV60eqCKfMCPkBeQlIEJG9xQcgLaGlhESz2Tawv2FlYyK4iNps1G2Z3ds5JkxuuVy/Ebi+crzwzDDP/HI4aj8eMv5gZcRyjKAo0m014nve0hCiK0Ov1cAvnHO92ux/z+fwrSsp7WbDWQmsNpdRFnYhuOrxSqah6vf4ZJeY9/30iglIKeZ5fBNButxGGIZj51hA+lDoA5xyICFmWIUkSJElyyrLsYmO1WoXv+9hut//dCcwMa60tdQBhGCZpmlKapr+n06laLBbviQjOuYvNjUYD3W4XURTBOfdqNzAzmBmn0wmTyaRW5gDUteJwOMw7nY72ff9sED4hImw2G9RqNbRaLWitzx5/OBzAzDSbzSoouasXXK1W3/v9/gMAj4jOhiIzwxiDOI6xXq/vjTEfi6K4K4oiN8b8Oh6Pq/1+/y0Igi94A652wGAwqC+Xy58AMBqNHrXWn6y1/+ZFnucuCIJ3EEIIIYQQQgghhBBCCCGEeEP+AB90ynum2FsSAAAAAElFTkSuQmCC") +CLOUDS_HEAVY_DAY = base64.decode("iVBORw0KGgoAAAANSUhEUgAAAEAAAAAgCAYAAACinX6EAAABhGlDQ1BJQ0MgcHJvZmlsZQAAKJF9kT1Iw0AcxV9bpaIVKXYQcchQnSyIijjWKhShQqgVWnUwufQLmjQkKS6OgmvBwY/FqoOLs64OroIg+AHi7OCk6CIl/i8ptIjx4Lgf7+497t4B/kaFqWZXHFA1y0gnE0I2tyoEX9GHAMKYQFhipj4niil4jq97+Ph6F+NZ3uf+HP1K3mSATyCOM92wiDeIZzYtnfM+cYSVJIX4nHjcoAsSP3JddvmNc9FhP8+MGJn0PHGEWCh2sNzBrGSoxNPEUUXVKN+fdVnhvMVZrdRY6578haG8trLMdZojSGIRSxAhQEYNZVRgIUarRoqJNO0nPPzDjl8kl0yuMhg5FlCFCsnxg//B727NwtSkmxRKAN0vtv0xCgR3gWbdtr+Pbbt5AgSegSut7a82gNlP0uttLXoEDGwDF9dtTd4DLneAoSddMiRHCtD0FwrA+xl9Uw4YvAV619zeWvs4fQAy1FXqBjg4BMaKlL3u8e6ezt7+PdPq7weNmXKxByfkgQAAAAlwSFlzAAAuIwAALiMBeKU/dgAAAAd0SU1FB+gLAxIFGswR15EAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAB8UlEQVRo3u3VMavaUBQH8P9NTDWm1kal4CBtJsElL2IXJ6GTDqVDeZt+ibt26ejg4OYn6FRwLHQTBYdWVAQVQTpZH0iQqKjXNKZLfWuftpFS7m+5S845OQfuuQQeopQ+TqVSZrFYfCQIAkRR9KxWt9sFABiGcVacAG+FhsPh19lsBkHwrhRjDIQQ3NzcnB3r9QAAYGDbtqcFTNNEIpEAIeSfG8AaQGe/31/0cw+x3W7R6XQQCAQuivd0AJVKZQPg82g0+uY4zl/Pv9ls0Gg0sFwuwRi7KIfvCldg3u/3bzVNa6bT6cCfLkLXdcEYw3w+R6vVQqlUIr+WoKsoCvx+/1n5RK+7b7fbTrPZ/B6NRr+sVqtXmqaFJEk6q+Hj8QjGGMbjMabTqdvr9X5ks1lfvV5/f/pO1/XnlmU9cxznSTgcfvCLQ3Bl1Wr1g67rbw3DkBRFgSiKcF33vtkT27axXq8xmUzc3W53sG37Lp/Pv/hd/nK5/DGZTL7JZDJiLBaDJEn3++d0noZqWdb1B0ApfQrgNpfLvVNVNe7z+QRCCFmtVjgcDhBFEbIs28Fg8G6xWPQLhcLrS+rUarVPqqq+lGU55DiOKAiCoCgKIpEIIYTANE13MBgc8b+jlMYppXFwHMdxHMdxHMdxHMdxHMdxHH4CyQy8JI6Oae8AAAAASUVORK5CYII=") +CLOUDS_HEAVY_NIGHT = base64.decode("iVBORw0KGgoAAAANSUhEUgAAAEAAAAAgCAYAAACinX6EAAABhGlDQ1BJQ0MgcHJvZmlsZQAAKJF9kT1Iw0AcxV9bpaIVKXYQcchQnSyIijjWKhShQqgVWnUwufQLmjQkKS6OgmvBwY/FqoOLs64OroIg+AHi7OCk6CIl/i8ptIjx4Lgf7+497t4B/kaFqWZXHFA1y0gnE0I2tyoEX9GHAMKYQFhipj4niil4jq97+Ph6F+NZ3uf+HP1K3mSATyCOM92wiDeIZzYtnfM+cYSVJIX4nHjcoAsSP3JddvmNc9FhP8+MGJn0PHGEWCh2sNzBrGSoxNPEUUXVKN+fdVnhvMVZrdRY6578haG8trLMdZojSGIRSxAhQEYNZVRgIUarRoqJNO0nPPzDjl8kl0yuMhg5FlCFCsnxg//B727NwtSkmxRKAN0vtv0xCgR3gWbdtr+Pbbt5AgSegSut7a82gNlP0uttLXoEDGwDF9dtTd4DLneAoSddMiRHCtD0FwrA+xl9Uw4YvAV619zeWvs4fQAy1FXqBjg4BMaKlL3u8e6ezt7+PdPq7weNmXKxByfkgQAAAAlwSFlzAAAuIwAALiMBeKU/dgAAAAd0SU1FB+gLAxMIFwbMv1YAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAABxklEQVRo3u3VvcoaQRQG4PfM7kR3iSKIWdcmXoFdmmmDhSAhRfiuJk0uxM5NFbAM5AJskhQhhXYRBXfRlUWMP7N/k2ohkCJRvrUI89RzzuG8sz+EEgkhnrZarV2v13tCRGCMlTbL930AgOu6V9UxlKu23W6/HA4HEFFpQ9I0BRGh3W5fXVt2AADwPcuyUgecz2fU6/WbQi47gAOAr8UNlSFJEqzXa5imeVN9qQFMp9OfAD6FYfgjz/NH7x/HMRaLBS6XC259yu7xCvhBEDz4vn95jBCUUkjTFFEUYTabwfM8mkwmtN/vkabp1f2MsrdfrVbZcrlc27b9WUr5stFo1AzDuGrhYukwDBFFkQqCIB2NRuZ8Pn9XnHMc57mU8lme5/VKpfLPfxzCnQ0Gg/eO47xxXZdzzsEYg1Lqj3NZliGOY+x2O5UkSZzneTAej7t/69/v9z80m83XnU7HsG0bv4ddfIeKUKWU9w9ACNEA8NDtdt9Wq1WXMcaIiKSUyLIMRATOecI5D47H4zfP817dMmc4HH60LOuFaZo1pZRBRIxzDsuyiIhwOp3UZrPJ8b8TQrhCCBeapmmapmmapmmapmmapmmahl8T0MMoSBWbjQAAAABJRU5ErkJggg==") +RAIN_LIGHT_DAY = base64.decode("iVBORw0KGgoAAAANSUhEUgAAAEAAAAAgCAYAAACinX6EAAABhGlDQ1BJQ0MgcHJvZmlsZQAAKJF9kT1Iw0AcxV9bpaIVh1YQcchQO9lFRRxrFYpQIdQKrTqYXPoFTRqSFBdHwbXg4Mdi1cHFWVcHV0EQ/ABxdnBSdJES/5cUWsR4cNyPd/ced+8Af7PKVLMnAaiaZWRSSSGXXxWCrxhAAGEMIyYxU58TxTQ8x9c9fHy9i/Ms73N/jkGlYDLAJxAnmG5YxBvEM5uWznmfOMLKkkJ8Tjxh0AWJH7kuu/zGueSwn2dGjGxmnjhCLJS6WO5iVjZU4mniqKJqlO/Puaxw3uKsVuusfU/+wlBBW1nmOs0xpLCIJYgQIKOOCqqwEKdVI8VEhvaTHv5Rxy+SSyZXBYwcC6hBheT4wf/gd7dmcWrSTQolgd4X2/4YB4K7QKth29/Htt06AQLPwJXW8deawOwn6Y2OFj0ChraBi+uOJu8BlzvAyJMuGZIjBWj6i0Xg/Yy+KQ+Eb4H+Nbe39j5OH4AsdZW+AQ4OgViJstc93t3X3du/Z9r9/QCDd3KtmFmoAgAAAAlwSFlzAAAuIwAALiMBeKU/dgAAAAd0SU1FB+gLAxQKJxds+/0AAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAYklEQVRo3u3XwQ0AIAxCUfdfWkcwerDSPO5G+NQmjlGqORve9TIUVTapadDzgRLSwOwNp4VoMY2eFFmOQjzzmxQkwqsNDjqjBLoWG5n+LdSNnxbfcgIwhOLJOU0ZeaCotp0FMhpJt5CNKToAAAAASUVORK5CYII=") +RAIN_LIGHT_NIGHT = base64.decode("iVBORw0KGgoAAAANSUhEUgAAAEAAAAAgCAYAAACinX6EAAABhGlDQ1BJQ0MgcHJvZmlsZQAAKJF9kT1Iw0AcxV9bpaIVh1YQcchQO9lFRRxrFYpQIdQKrTqYXPoFTRqSFBdHwbXg4Mdi1cHFWVcHV0EQ/ABxdnBSdJES/5cUWsR4cNyPd/ced+8Af7PKVLMnAaiaZWRSSSGXXxWCrxhAAGEMIyYxU58TxTQ8x9c9fHy9i/Ms73N/jkGlYDLAJxAnmG5YxBvEM5uWznmfOMLKkkJ8Tjxh0AWJH7kuu/zGueSwn2dGjGxmnjhCLJS6WO5iVjZU4mniqKJqlO/Puaxw3uKsVuusfU/+wlBBW1nmOs0xpLCIJYgQIKOOCqqwEKdVI8VEhvaTHv5Rxy+SSyZXBYwcC6hBheT4wf/gd7dmcWrSTQolgd4X2/4YB4K7QKth29/Htt06AQLPwJXW8deawOwn6Y2OFj0ChraBi+uOJu8BlzvAyJMuGZIjBWj6i0Xg/Yy+KQ+Eb4H+Nbe39j5OH4AsdZW+AQ4OgViJstc93t3X3du/Z9r9/QCDd3KtmFmoAgAAAAlwSFlzAAAuIwAALiMBeKU/dgAAAAd0SU1FB+gLAxQrCt4ssmsAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAaUlEQVRo3u3XwQ3AIAxDUXbg0vm6/w50hIoeSB093xH2d4jEGIWa173a3XUyFFU2qWnQ84ES0sC8G04L0WIaPSmyHIU45jcpSIRXGxx0Rgl0LTYy/bdQX/y0+JYTgCEUd85pysgDRdXtPEblOT33lCsJAAAAAElFTkSuQmCC") +RAIN_HEAVY_DAY = base64.decode("iVBORw0KGgoAAAANSUhEUgAAAEAAAAAgCAYAAACinX6EAAABhGlDQ1BJQ0MgcHJvZmlsZQAAKJF9kT1Iw0AcxV9bpaIVh1YQcchQO9lFRRxrFYpQIdQKrTqYXPoFTRqSFBdHwbXg4Mdi1cHFWVcHV0EQ/ABxdnBSdJES/5cUWsR4cNyPd/ced+8Af7PKVLMnAaiaZWRSSSGXXxWCrxhAAGEMIyYxU58TxTQ8x9c9fHy9i/Ms73N/jkGlYDLAJxAnmG5YxBvEM5uWznmfOMLKkkJ8Tjxh0AWJH7kuu/zGueSwn2dGjGxmnjhCLJS6WO5iVjZU4mniqKJqlO/Puaxw3uKsVuusfU/+wlBBW1nmOs0xpLCIJYgQIKOOCqqwEKdVI8VEhvaTHv5Rxy+SSyZXBYwcC6hBheT4wf/gd7dmcWrSTQolgd4X2/4YB4K7QKth29/Htt06AQLPwJXW8deawOwn6Y2OFj0ChraBi+uOJu8BlzvAyJMuGZIjBWj6i0Xg/Yy+KQ+Eb4H+Nbe39j5OH4AsdZW+AQ4OgViJstc93t3X3du/Z9r9/QCDd3KtmFmoAgAAAAlwSFlzAAAuIwAALiMBeKU/dgAAAAd0SU1FB+gLAxQKFzG1y1EAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAhElEQVRo3u2ZUQ7AIAhDvf+l9QImKhHQ8vrpop3YdjO0VhK9rwYOn5uJnXjyK/o5Dyjhe1W5p9lkRuzxMq48hBkg+AA/ScLhiCVQBoir+u78mzym6zYyBqDkF4A8UFYFgauqnPCTf0VqIX0JfFMguVP2kGUjGUXf3sjWeq9XT775EVesAUCGeYembslzAAAAAElFTkSuQmCC") +RAIN_HEAVY_NIGHT = base64.decode("iVBORw0KGgoAAAANSUhEUgAAAEAAAAAgCAYAAACinX6EAAABhGlDQ1BJQ0MgcHJvZmlsZQAAKJF9kT1Iw0AcxV9bpaIVh1YQcchQO9lFRRxrFYpQIdQKrTqYXPoFTRqSFBdHwbXg4Mdi1cHFWVcHV0EQ/ABxdnBSdJES/5cUWsR4cNyPd/ced+8Af7PKVLMnAaiaZWRSSSGXXxWCrxhAAGEMIyYxU58TxTQ8x9c9fHy9i/Ms73N/jkGlYDLAJxAnmG5YxBvEM5uWznmfOMLKkkJ8Tjxh0AWJH7kuu/zGueSwn2dGjGxmnjhCLJS6WO5iVjZU4mniqKJqlO/Puaxw3uKsVuusfU/+wlBBW1nmOs0xpLCIJYgQIKOOCqqwEKdVI8VEhvaTHv5Rxy+SSyZXBYwcC6hBheT4wf/gd7dmcWrSTQolgd4X2/4YB4K7QKth29/Htt06AQLPwJXW8deawOwn6Y2OFj0ChraBi+uOJu8BlzvAyJMuGZIjBWj6i0Xg/Yy+KQ+Eb4H+Nbe39j5OH4AsdZW+AQ4OgViJstc93t3X3du/Z9r9/QCDd3KtmFmoAgAAAAlwSFlzAAAuIwAALiMBeKU/dgAAAAd0SU1FB+gLAxQrF70q3rIAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAiklEQVRo3u2Zyw3AIAxD2aEX5uv+O9AFUItQPtR5PiKBIdgGRGsFcfV7vDd8dbAiduLJr+jPeUAJ36vKPc0mM2KPybjyEGaA4ANckoTDEUugDBBX9dX+ljxbz21kDEDJE4A8UFYFgauqnPCdP0VqIf8S+KZAcqesIctGMoq2XsjSeKdXT/7zI7JYD/ImXl1oA3nQAAAAAElFTkSuQmCC") +SNOW_DAY = base64.decode("iVBORw0KGgoAAAANSUhEUgAAAEAAAAAgCAYAAACinX6EAAABhGlDQ1BJQ0MgcHJvZmlsZQAAKJF9kT1Iw0AcxV9bpaIVh1YQcchQO9lFRRxrFYpQIdQKrTqYXPoFTRqSFBdHwbXg4Mdi1cHFWVcHV0EQ/ABxdnBSdJES/5cUWsR4cNyPd/ced+8Af7PKVLMnAaiaZWRSSSGXXxWCrxhAAGEMIyYxU58TxTQ8x9c9fHy9i/Ms73N/jkGlYDLAJxAnmG5YxBvEM5uWznmfOMLKkkJ8Tjxh0AWJH7kuu/zGueSwn2dGjGxmnjhCLJS6WO5iVjZU4mniqKJqlO/Puaxw3uKsVuusfU/+wlBBW1nmOs0xpLCIJYgQIKOOCqqwEKdVI8VEhvaTHv5Rxy+SSyZXBYwcC6hBheT4wf/gd7dmcWrSTQolgd4X2/4YB4K7QKth29/Htt06AQLPwJXW8deawOwn6Y2OFj0ChraBi+uOJu8BlzvAyJMuGZIjBWj6i0Xg/Yy+KQ+Eb4H+Nbe39j5OH4AsdZW+AQ4OgViJstc93t3X3du/Z9r9/QCDd3KtmFmoAgAAAAlwSFlzAAAuIwAALiMBeKU/dgAAAAd0SU1FB+gLAxQsKqoDBGQAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAZElEQVRo3u3XwQ0AIQwDQfpvOpRwOh4ER+M/wl6HSKzVqKqqcXfdDEWdTWoa9HyghDQw34bTQoyYRk+KLEchrvlNChLh1QYHnVECXYuDTL8W6sTPiG85ARhC8c85TRl5oKi7nQ3XgJNt4HaPtwAAAABJRU5ErkJggg==") +SNOW_NIGHT = base64.decode("iVBORw0KGgoAAAANSUhEUgAAAEAAAAAgCAYAAACinX6EAAABhGlDQ1BJQ0MgcHJvZmlsZQAAKJF9kT1Iw0AcxV9bpaIVh1YQcchQO9lFRRxrFYpQIdQKrTqYXPoFTRqSFBdHwbXg4Mdi1cHFWVcHV0EQ/ABxdnBSdJES/5cUWsR4cNyPd/ced+8Af7PKVLMnAaiaZWRSSSGXXxWCrxhAAGEMIyYxU58TxTQ8x9c9fHy9i/Ms73N/jkGlYDLAJxAnmG5YxBvEM5uWznmfOMLKkkJ8Tjxh0AWJH7kuu/zGueSwn2dGjGxmnjhCLJS6WO5iVjZU4mniqKJqlO/Puaxw3uKsVuusfU/+wlBBW1nmOs0xpLCIJYgQIKOOCqqwEKdVI8VEhvaTHv5Rxy+SSyZXBYwcC6hBheT4wf/gd7dmcWrSTQolgd4X2/4YB4K7QKth29/Htt06AQLPwJXW8deawOwn6Y2OFj0ChraBi+uOJu8BlzvAyJMuGZIjBWj6i0Xg/Yy+KQ+Eb4H+Nbe39j5OH4AsdZW+AQ4OgViJstc93t3X3du/Z9r9/QCDd3KtmFmoAgAAAAlwSFlzAAAuIwAALiMBeKU/dgAAAAd0SU1FB+gLAxQtH+Wr8QYAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAZklEQVRo3u3XwQ3AIAxDUfYfJiu2IyB6IHX0fEfY3yESazWqqp5xd90MRZ1Nahr0fKCENDB7w2khRkyjJ0WWoxDX/CYFifBqg4POKIGuxUGm/xbqi58R33ICMITiyTlNGXmgqLudF2iScE5Btz32AAAAAElFTkSuQmCC") +LIGHTNING = base64.decode("iVBORw0KGgoAAAANSUhEUgAAAEAAAAAgCAYAAACinX6EAAABhGlDQ1BJQ0MgcHJvZmlsZQAAKJF9kT1Iw0AcxV9TpaIVByuIOASpThZBRRxrFYpQIdQKrTqYXPoFTRqSFhdHwbXg4Mdi1cHFWVcHV0EQ/ABxdnBSdJES/5cUWsR4cNyPd/ced+8AoV5imtURBTS9YibjMTGdWRUDr+iBHwOYwIjMLGNOkhLwHF/38PH1LsKzvM/9OXrVrMUAn0gcZYZZId4gntmsGJz3iUOsIKvE58TjJl2Q+JHristvnPMOCzwzZKaS88QhYjHfxkobs4KpEU8Th1VNp3wh7bLKeYuzVqqy5j35C4NZfWWZ6zSHEcciliBBhIIqiiihggitOikWkrQf8/APOX6JXAq5imDkWEAZGmTHD/4Hv7u1clOTblIwBnS+2PbHKBDYBRo12/4+tu3GCeB/Bq70lr9cB2Y/Sa+1tPAR0LcNXFy3NGUPuNwBBp8M2ZQdyU9TyOWA9zP6pgzQfwt0r7m9Nfdx+gCkqKvEDXBwCIzlKXvd491d7b39e6bZ3w+/a3LFYPmf5QAAAAlwSFlzAAAuIwAALiMBeKU/dgAAAAd0SU1FB+gLAxcHNCQ6ejcAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAdklEQVRo3u2YsRHAIAwDbfbfWWlSpEiRJuC7f20g+YWBqsFKkqJql/lVSvTR5q2A6MPNW4FJ08dW4GkcF8KbYUwIuYXcCF96vyOEdcp8d/eEQYxeg1NC8tD7+7aHDwD/DjAE/wPUMQokgE6BBNApwBNgBZRi6wJ5G3elOccUgAAAAABJRU5ErkJggg==") + +def main(config): + # get coordinates and current time + location = config.get("location") + loc = json.decode(location) if location else json.decode(str(DEFAULT_LOCATION)) + timezone = loc["timezone"] + lat = loc["lat"] + lng = loc["lng"] + now = time.now().in_location(timezone) + now_unix = time.now().unix + + # get 24 vs. 12 hour clock selection + clock24_bool = config.bool("24hour", False) + if clock24_bool: + clock_format = "15:04" + else: + clock_format = "3:04 PM" + + # get Celsius vs. Fahrenheait selection + celsius_bool = config.bool("celsius", False) + if celsius_bool: + unit_temp = "C" + else: + unit_temp = "F" + + # wind thresholds for wave animations + wind_medium_threshold_mps = 3 * 0.44704 # [mph] to [m/s] + wind_heavy_threshold_mps = 10 * 0.44704 # [mph] to [m/s] + + # pull weather data from API or cache + weather_url = "https://api.open-meteo.com/v1/forecast?latitude=" + str(lat) + "&longitude=" + str(lng) + "¤t=temperature_2m,weather_code,cloud_cover,wind_speed_10m&daily=temperature_2m_max,temperature_2m_min,sunrise,sunset" + res = http.get(url = weather_url, ttl_seconds = TTL_SECONDS) + if res.status_code != 200: + fail("request to %s failed with status code: %d - %s" % (weather_url, res.status_code, res.body())) + + # DEVELOPMENT: check if result was served from API pull or cache + if res.headers.get("Tidbyt-Cache-Status") == "HIT": + print("Displaying cached data.") + else: + print("Calling Open Meteo API.") + + # get data values of interest from pulled data + sunrise = res.json()["daily"]["sunrise"][0] + sunset = res.json()["daily"]["sunset"][0] + low_temp_C = res.json()["daily"]["temperature_2m_min"][0] + now_temp_C = res.json()["current"]["temperature_2m"] + high_temp_C = res.json()["daily"]["temperature_2m_max"][0] + windspeed_kmph = res.json()["current"]["wind_speed_10m"] + weather_code = res.json()["current"]["weather_code"] + + # convert times to unix and windspeed to m/s + sunrise = time.parse_time(sunrise + ":00Z") + sunrise_unix = sunrise.unix + sunset = time.parse_time(sunset + ":00Z") + sunset_unix = sunset.unix + windspeed_mps = windspeed_kmph * 1000 / 60 / 60 + + # convert temperature units + low_temp = low_temp_C + now_temp = now_temp_C + high_temp = high_temp_C + if unit_temp == "F": + low_temp = low_temp_C * 9 / 5 + 32 + now_temp = now_temp_C * 9 / 5 + 32 + high_temp = high_temp_C * 9 / 5 + 32 + low_temp = int(low_temp) + now_temp = int(now_temp) + high_temp = int(high_temp) + + # set wind animation strength + if windspeed_mps > wind_heavy_threshold_mps: + wind = 2 + elif windspeed_mps > wind_medium_threshold_mps: + wind = 1 + else: + wind = 0 + + # determine day/night and ratios for sun/moon heights + min_height = 22 + max_height = 1 + if sunrise_unix <= now_unix and now_unix <= sunset_unix: + day = True + day_ratio = (now_unix - sunrise_unix) / (sunset_unix - sunrise_unix) + night_ratio = 1 + else: + day = False + day_ratio = 1 + if now_unix > sunset_unix: + # assume next sunrise is the same + sunrise_unix = sunrise_unix + 24 * 60 * 60 + else: + # assume previous sunset is the same + sunset_unix = sunset_unix - 24 * 60 * 60 + night_ratio = (now_unix - sunset_unix) / (sunrise_unix - sunset_unix) + sun_height = int(min_height * abs(0.5 - day_ratio) / 0.5) + max_height + moon_height = int(min_height * abs(0.5 - night_ratio) / 0.5) + max_height + + # determine weather conditions + weather_table = [ + # code, clouds, rain, snow, lightning, # description + [0, 0, 0, 0, 0], # Clear sky + [1, 1, 0, 0, 0], # Mainly clear + [2, 2, 0, 0, 0], # Partly cloudy + [3, 3, 0, 0, 0], # Overcast + [45, 3, 0, 0, 0], # Fog + [48, 3, 0, 0, 0], # Depositing rime fog + [51, 3, 1, 0, 0], # Drizzle: light + [53, 3, 1, 0, 0], # Drizzle: moderate + [55, 3, 2, 0, 0], # Drizzle: dense + [56, 3, 1, 0, 0], # Freezing drizzle: light + [57, 3, 2, 0, 0], # Freezing drizzle: dense + [61, 3, 1, 0, 0], # Rain: slight + [63, 3, 2, 0, 0], # Rain: moderate + [65, 3, 2, 0, 0], # Rain: heavy + [66, 3, 1, 0, 0], # Freezing rain: light + [67, 3, 2, 0, 0], # Freezing rain: heavy + [71, 3, 0, 1, 0], # Snow fall: slight + [73, 3, 0, 1, 0], # Snow fall: moderate + [75, 3, 0, 1, 0], # Snow fall: heavy + [77, 3, 0, 1, 0], # Snow grains + [80, 3, 1, 0, 0], # Rain showers: slight + [81, 3, 2, 0, 0], # Rain showers: moderate + [82, 3, 2, 0, 0], # Rain showers: violent + [85, 3, 0, 1, 0], # Snow showers: slight + [86, 3, 0, 1, 0], # Snow showers: heavy + [95, 3, 2, 0, 1], # Thunderstorm: Slight or moderate + [96, 3, 1, 0, 1], # Thunderstorm with slight hail + [99, 3, 2, 0, 1], # Thunderstorm with heavy hail + ] + + w = [0, 0, 0, 0, 0] + for w in weather_table: + if w[0] == weather_code: + break + cloud_scale = w[1] + rain_scale = w[2] + snow_scale = w[3] + lightning_scale = w[4] + + # animation timing + t_end = 15 + t_delay_ms = int(5000 / 24) # 24 is slowest for seemless repeat + t_delay = t_delay_ms / 1000 + pps = 1 / t_delay # pixels per second + offset = int(t_end * pps) # offset number of pixels for seemless repeat + + # individual render components + sky = draw_sky(day, day_ratio, sun_height, cloud_scale) + sun = draw_sun(sun_height, cloud_scale) + moon = draw_moon(moon_height, cloud_scale) + ship = draw_ship(day, wind) + ocean = draw_ocean(day) + wave1 = draw_wave(day, wind, 0, 64, 20, 0, 21, [1, 1, 0, 0, 0, 0, 0, 0]) + wave2 = draw_wave(day, wind, 0, 64, 28, 0, 22, [1, 1, 1, 1, 0, 0, 1, 1]) + wave3 = draw_wave(day, wind, 50, 32, 22, 21, 21, [0, 0, 0, 0, 1, 1, 0, 0]) + wave4 = draw_wave(day, wind, 42, 32, 22, 22, 22, [0, 0, 1, 1, 1, 1, 1, 1]) + stream1_1 = draw_stream(day, wind, 50, 24, 20, 0) + stream1_2 = draw_stream(day, wind, 50, 24, 20, offset) + stream2_1 = draw_stream(day, wind, 10, 26, 20, 0) + stream2_2 = draw_stream(day, wind, 10, 26, 20, offset) + stream3_1 = draw_stream(day, wind, 35, 28, 20, 0) + stream3_2 = draw_stream(day, wind, 35, 28, 20, offset) + stream4_1 = draw_stream(day, wind, 1, 30, 20, 0) + stream4_2 = draw_stream(day, wind, 1, 30, 20, offset) + text_time = print_time(day, now, clock_format) + text_low_temp = print_temp(day, str(low_temp), 50, 6) + text_high_temp = print_temp(day, str(high_temp), 64, 6) + text_now_temp = print_temp(day, str(now_temp) + unit_temp, 64, 12) + stars = draw_stars(day, cloud_scale) + clouds_heavy = draw_clouds(day, cloud_scale, 1, CLOUDS_HEAVY_DAY, CLOUDS_HEAVY_NIGHT) + clouds_light = draw_clouds(day, cloud_scale, 0, CLOUDS_LIGHT_DAY, CLOUDS_LIGHT_NIGHT) + rain_heavy = draw_rain_heavy(day, rain_scale) + rain_light = draw_rain_light(day, rain_scale) + snow = draw_snow(day, snow_scale) + lightning = draw_lightning(lightning_scale) + + # top-level render + return render.Root(delay = t_delay_ms, child = render.Stack(children = [ + sky, + stars, + sun, + moon, + ship, + snow, + rain_heavy, + rain_light, + lightning, + ocean, + wave1, + wave2, + wave3, + wave4, + stream1_1, + stream1_2, + stream2_1, + stream2_2, + stream3_1, + stream3_2, + stream4_1, + stream4_2, + clouds_heavy, + clouds_light, + text_time, + text_low_temp, + text_high_temp, + text_now_temp, + ])) + +def get_schema(): + return schema.Schema( + version = "1", + fields = [ + schema.Location( + id = "location", + name = "Location", + icon = "locationDot", + desc = "Determines location for time and weather.", + ), + schema.Toggle( + id = "24hour", + name = "24 Hour Time", + icon = "clock", + desc = "Display 12-hour time (off) or 24-hour time (on).", + default = False, + ), + schema.Toggle( + id = "celsius", + name = "Celsius Temperature", + icon = "thermometer", + desc = "Display temperature in Fahrenheit (off) or Celsius (on).", + default = False, + ), + ], + ) + +def draw_sun(sun_height, cloud_scale): + if cloud_scale > 2: + sun_color = "#ffffc5" + else: + sun_color = "#FFFF00" + sun = render.Column(children = [ + render.Box(height = sun_height), + render.Row(children = [ + render.Box(width = 22), + render.Circle(color = sun_color, diameter = 8), + ]), + ]) + return sun + +def draw_moon(moon_height, cloud_scale): + if cloud_scale > 2: + img = MOON_CLOUDS + else: + img = MOON + moon = render.Column(children = [ + render.Box(height = moon_height), + render.Row(children = [ + render.Box(width = 22), + render.Image(src = img), + ]), + ]) + return moon + +def draw_sky(day, day_ratio, sun_height, cloud_scale): + if day: + if cloud_scale > 2: + sky = render.Box(width = 64, height = 32, color = "#aaaaaa") + elif sun_height > 20: + if day_ratio < 0.5: + sky = render.Column(children = [ + render.Box(width = 64, height = 5, color = "#87CEEB"), + render.Box(width = 64, height = 8, color = "#FFFF8c"), + render.Box(width = 64, height = 6, color = "#ff724c"), + render.Box(width = 64, height = 4, color = "#AA336A"), + ]) + else: + sky = render.Column(children = [ + render.Box(width = 64, height = 5, color = "#87CEEB"), + render.Box(width = 64, height = 8, color = "#FFFF00"), + render.Box(width = 64, height = 6, color = "#FFA500"), + render.Box(width = 64, height = 4, color = "#ff0000"), + ]) + else: + sky = render.Box(width = 64, height = 32, color = "#87CEEB") + elif cloud_scale > 2: + sky = render.Box(width = 64, height = 32, color = "#202020") + else: + sky = render.Box(width = 64, height = 32, color = "#000000") + return sky + +def draw_ship(day, wind): + height1 = 8 + height2 = 9 + height3 = 10 + left_space = 4 + if day: + ship = SHIP_DAY + else: + ship = SHIP_NIGHT + if wind == 2: + ship = render.Column(children = [ + render.Animation(children = [ + render.Box(height = height1), + render.Box(height = height1), + render.Box(height = height2), + render.Box(height = height2), + render.Box(height = height3), + render.Box(height = height3), + render.Box(height = height2), + render.Box(height = height2), + ]), + render.Row(children = [ + render.Box(width = left_space), + render.Image(src = ship), + ]), + ]) + else: + ship = render.Column(children = [ + render.Box(height = height3), + render.Row(children = [ + render.Box(width = left_space), + render.Image(src = ship), + ]), + ]) + return ship + +def draw_ocean(day): + if day: + ocean_color = "#0000FF" + else: + ocean_color = "#131862" + ocean = render.Column(children = [ + render.Box(width = 64, height = 23), + render.Box(width = 64, height = 9, color = ocean_color), + ]) + return ocean + +def draw_wave(day, wind, w1, w2, w3, h1, h2, seq): + if day: + ocean_color = "#0000FF" + else: + ocean_color = "#131862" + colors = [] + for s in seq: + if s == 0: + colors.append("") + else: + colors.append(ocean_color) + if wind == 2: + if w1 == 0: + wave = render.Column(children = [ + render.Box(width = w2, height = h2), + render.Animation(children = [ + render.Box(width = w3, height = 1, color = colors[0]), + render.Box(width = w3, height = 1, color = colors[1]), + render.Box(width = w3, height = 1, color = colors[2]), + render.Box(width = w3, height = 1, color = colors[3]), + render.Box(width = w3, height = 1, color = colors[4]), + render.Box(width = w3, height = 1, color = colors[5]), + render.Box(width = w3, height = 1, color = colors[6]), + render.Box(width = w3, height = 1, color = colors[7]), + ]), + ]) + else: + wave = render.Row(children = [ + render.Box(width = w1, height = h1), + render.Column(children = [ + render.Box(width = w2, height = h2), + render.Animation(children = [ + render.Box(width = w3, height = 1, color = colors[0]), + render.Box(width = w3, height = 1, color = colors[1]), + render.Box(width = w3, height = 1, color = colors[2]), + render.Box(width = w3, height = 1, color = colors[3]), + render.Box(width = w3, height = 1, color = colors[4]), + render.Box(width = w3, height = 1, color = colors[5]), + render.Box(width = w3, height = 1, color = colors[6]), + render.Box(width = w3, height = 1, color = colors[7]), + ]), + ]), + ]) + else: + wave = render.Box() + return wave + +def draw_stream(day, wind, start_width, start_height, width, offset): + if day: + stream_color = "#00008B" + else: + stream_color = "#00094b" + if wind > 0: + stream = render.Column(children = [ + render.Box(height = start_height), + render.Marquee( + width = 64, + offset_start = offset, + offset_end = 0, + child = render.Row(children = [ + render.Box(width = start_width, height = 1), + render.Box(width = width, height = 1, color = stream_color), + render.Box(width = 65 - start_width - width, height = 1), + ]), + ), + ]) + else: + stream = render.Box() + return stream + +def print_time(day, now, clock_format): + if day: + text_color = "#000000" + else: + text_color = "#ffffff" + text = render.WrappedText( + align = "right", + width = 64, + color = text_color, + content = now.format(clock_format), + font = "CG-pixel-3x5-mono", + ) + return text + +def print_temp(day, temperature, x, y): + if day: + text_color = "#000000" + else: + text_color = "#ffffff" + text = render.Column(children = [ + render.Box(height = y), + render.WrappedText( + align = "right", + width = x, + color = text_color, + content = temperature, + font = "CG-pixel-3x5-mono", + ), + ]) + return text + +def draw_stars(day, cloud_scale): + if day or cloud_scale > 2: + star = render.Box() + else: + star = render.Image(src = STARS) + return star + +def draw_clouds(day, cloud_scale, threshold, img_day, img_night): + if day: + img = img_day + else: + img = img_night + if cloud_scale > threshold: + clouds = render.Image(src = img) + else: + clouds = render.Box() + return clouds + +def draw_rain_light(day, rain_scale): + if day: + img = RAIN_LIGHT_DAY + else: + img = RAIN_LIGHT_NIGHT + if rain_scale > 0: + rain = render.Column(children = [ + render.Animation(children = [ + render.Box(height = 1), + render.Box(height = 1), + render.Box(height = 1), + render.Box(height = 1), + render.Box(height = 5), + render.Box(height = 5), + render.Box(height = 5), + render.Box(height = 5), + ]), + render.Image(src = img), + ]) + else: + rain = render.Box() + return rain + +def draw_rain_heavy(day, rain_scale): + if day: + img = RAIN_HEAVY_DAY + else: + img = RAIN_HEAVY_NIGHT + if rain_scale > 1: + rain = render.Column(children = [ + render.Animation(children = [ + render.Box(height = 1), + render.Box(height = 1), + render.Box(height = 5), + render.Box(height = 5), + ]), + render.Image(src = img), + ]) + else: + rain = render.Box() + return rain + +def draw_snow(day, snow_scale): + if day: + img = SNOW_DAY + else: + img = SNOW_NIGHT + if snow_scale > 0: + snow = render.Column(children = [ + render.Animation(children = [ + render.Box(height = 1), + render.Box(height = 1), + render.Box(height = 1), + render.Box(height = 1), + render.Box(height = 5), + render.Box(height = 5), + render.Box(height = 5), + render.Box(height = 5), + ]), + render.Image(src = img), + ]) + else: + snow = render.Box() + return snow + +def draw_lightning(lightning_scale): + if lightning_scale > 0: + lightning = render.Animation(children = [ + render.Box(), + render.Box(), + render.Image(src = LIGHTNING), + render.Image(src = LIGHTNING), + render.Box(), + render.Box(), + render.Box(), + render.Box(), + render.Box(), + render.Box(), + render.Box(), + render.Box(), + render.Box(), + render.Box(), + render.Box(), + render.Box(), + ]) + else: + lightning = render.Box() + return lightning diff --git a/apps/skybyt/manifest.yaml b/apps/skybyt/manifest.yaml new file mode 100644 index 000000000..c3349e6bd --- /dev/null +++ b/apps/skybyt/manifest.yaml @@ -0,0 +1,8 @@ +--- +id: skybyt +name: Skybyt +summary: Bluesky follower count +desc: Displays a Bluesky user's follower count. +author: Alex Karp +fileName: skybyt.star +packageName: skybyt diff --git a/apps/skybyt/skybyt.star b/apps/skybyt/skybyt.star new file mode 100644 index 000000000..78f4af72b --- /dev/null +++ b/apps/skybyt/skybyt.star @@ -0,0 +1,99 @@ +""" +Applet: Skybyt +Summary: Bluesky follower count +Description: Displays a Bluesky user's follower count. +Author: Alex Karp +""" + +load("cache.star", "cache") +load("encoding/base64.star", "base64") +load("http.star", "http") +load("humanize.star", "humanize") +load("render.star", "render") +load("schema.star", "schema") + +BLUESKY_ICON = base64.decode(""" +iVBORw0KGgoAAAANSUhEUgAAABAAAAAOCAYAAAAmL5yKAAABgGlDQ1BzUkdCIElFQzYxOTY2LTIuMQAAKJF1kc8rRFEUxz8zaMRMFMnC4qXBBjFKbJSZhJo0jVF+bd68+aVmxuu9J8lW2U5RYuPXgr+ArbJWikjJ2prYoOc8MzWSObd77ud+7zmne88Fdyyr5czqPsjlLSM6HlRm5+YVzzP1uGihC5+qmfpoJBKmor3fSazYTY9Tq3Lcv1afSJoauGqFRzTdsIQnhMOrlu7wtnCzllETwqfC3YZcUPjW0eNFfnY4XeRPh41YNATuRmEl/Yvjv1jLGDlheTn+XHZFK93HeYk3mZ+ZlrVdZhsmUcYJojDJGCEG6WdY/CA9BOiVHRXy+37yp1iWXE28zhoGS6TJYNEt6opUT8qaEj0pI8ua0/+/fTVTA4FidW8Qap5s+7UDPFvwVbDtj0Pb/jqCqke4yJfzlw9g6E30Qlnz70PDBpxdlrX4DpxvQuuDrhrqj1Ql051KwcsJ+Oag6RrqFoo9K51zfA+xdfmqK9jdg06Jb1j8BjmWZ9GqLiRsAAAACXBIWXMAAAsTAAALEwEAmpwYAAABP0lEQVQokX3RPWsUURjF8d9e1i5IBpImL5gtxMrK3sLC0jKpLARJo/gFhjSBgZSCEkEDNiEfwFJIikCaFDba2AkhZgvhohYhYZlY5BkYl5kcuDD3POf/cC4zKKr6NZ7gPXZymX65QUVVz+E51vFpUFT1b9yO+Qke5jL96IFHOMRSWH8SLluZZRwUVb3UAS9jvwXDRcJ4KjuKJfMteD7g0VR2nHDW0fYu3rTub8Ob1tmwo0GjtaKq9zDAak9mPMQxnvYE3vX4jY4TPuCoJ7AQp0tH2BlAUdVDPMY9PMP9HugrPuI7PucyTRLkMk2wgq0bYDHbwp1gNA0WcNoB/I3MTMdsMZfpZ4rLBOcdod040zoP5rpBtHjh+t83Xm495xtm4/sKL3OZtv9bEEsexJJLbOYyHYT/CBu4hVe5TF8a5h+53FrG27G36gAAAABJRU5ErkJggg== +""") + +def main(config): + handle = config.get("handle", "autistic.af") + + if handle.startswith("@"): + handle = handle[len("@"):] + + cache_key = "bsky_follows_%s" % (handle) + + formatted_followers_count = cache.get(cache_key) + message = "@%s" % handle + + if formatted_followers_count == None: + followers_count = get_followers_count(handle) + + if followers_count == None: + formatted_followers_count = "Not Found" + message = "Check your handle. (%s)" % handle + else: + formatted_followers_count = "%s %s" % (humanize.comma(followers_count), humanize.plural_word(followers_count, "follower")) + cache.set(cache_key, formatted_followers_count, ttl_seconds = 240) + + handle_child = render.Text( + color = "#3c3c3c", + content = message, + ) + + if len(message) > 12: + handle_child = render.Marquee( + width = 64, + child = handle_child, + ) + + return render.Root( + child = render.Box( + render.Column( + expanded = True, + main_align = "space_evenly", + cross_align = "center", + children = [ + render.Row( + expanded = True, + main_align = "space_evenly", + cross_align = "center", + children = [ + render.Image(BLUESKY_ICON), + render.WrappedText(formatted_followers_count), + ], + ), + handle_child, + ], + ), + ), + ) + +def get_followers_count(handle): + response = http.get( + "https://public.api.bsky.app/xrpc/app.bsky.actor.getProfile?actor=%s" % (handle), + headers = { + "Content-Type": "application/json", + "Accept": "application/activity+json", + }, + ) + + if response.status_code == 200: + body = response.json() + if body != None and len(body) > 0: + return int(body["followersCount"]) + return None + +def get_schema(): + return schema.Schema( + version = "1", + fields = [ + schema.Text( + id = "handle", + name = "Handle", + desc = "Bluesky handle for which to display follower count.", + icon = "user", + ), + ], + ) diff --git a/apps/thanksgivingday/thanksgiving_day.star b/apps/thanksgivingday/thanksgiving_day.star index a38729168..afd10d312 100644 --- a/apps/thanksgivingday/thanksgiving_day.star +++ b/apps/thanksgivingday/thanksgiving_day.star @@ -22,6 +22,8 @@ def main(config): thanksgiving_year = now.year thanksgiving_day = math.ceil(28 - (5 + now.year + now.year / 4 - now.year / 100 + now.year / 400) % 7) + if thanksgiving_year == 2024: + thanksgiving_day = 28 if 11 == now.month: if 0 > thanksgiving_day - now.day: diff --git a/apps/thingswifesays/things_wife_says.star b/apps/thingswifesays/things_wife_says.star index 4f60647c2..ad9e4325a 100644 --- a/apps/thingswifesays/things_wife_says.star +++ b/apps/thingswifesays/things_wife_says.star @@ -59,8 +59,8 @@ def main(config): render.Box( color = "#333333", #remove color background if picture is used child = render.Image(src = WIFE), - width = 28, - height = 28, + width = 22, + height = 30, ), render.Box( child = render.Marquee( @@ -69,14 +69,14 @@ def main(config): offset_end = 6, child = render.WrappedText( content = phrase, - width = 30, + width = 40, # color="#f44336" ), scroll_direction = "vertical", ), - width = 34, + width = 42, height = 32, - padding = 2, + padding = 1, ), ], ), diff --git a/apps/zmanim/zmanim.star b/apps/zmanim/zmanim.star index 48fda8314..932312bad 100644 --- a/apps/zmanim/zmanim.star +++ b/apps/zmanim/zmanim.star @@ -1,51 +1,97 @@ -""" -Zmanim app for Tidbyt displays Jewish prayer times. -Data provided by Chabad.org's Zmanim API. -""" - load("http.star", "http") load("render.star", "render") load("schema.star", "schema") +load("time.star", "time") DEFAULT_ZIP = "11367" -ZMANIM_MAP = { - "Dawn": "Dawn (Alot", - "Misheyakir": "Earliest Tallit", - "Sunrise": "Sunrise", - "Last Shema": "Latest Shema", - "Last Shach": "Latest Shacharit", - "Midday": "Midday", - "Mincha Ged": "Earliest Mincha", - "Mincha Ket": "Mincha Ketanah", - "Plag": "Plag Hamincha", - "Sunset": "Sunset", - "Nightfall": "Nightfall", - "Midnight": "Midnight", -} +ZMANIM_MAP = dict( + Dawn = "Dawn (Alot", + Misheyakir = "Earliest Tallit", + Sunrise = "Sunrise", + Last_Shema = "Latest Shema", + Last_Shach = "Latest Shacharit", + Midday = "Midday", + Mincha_Ged = "Earliest Mincha", + Mincha_Ket = "Mincha Ketanah", + Plag = "Plag Hamincha", + Sunset = "Sunset", + Nightfall = "Nightfall", + Midnight = "Midnight", + Candle_Lighting = "Candle Lighting", + Shabbat_Ends = "Shabbat Ends", + Candle_Lighting_after = "Candle Lighting after", + Holiday_Ends = "Holiday Ends", +) def get_url(zip_code): - """Creates the URL for the Chabad.org Zmanim API.""" - return "https://www.chabad.org/tools/rss/zmanim.xml?locationid=" + zip_code + "&locationtype=2" + return "https://www.chabad.org/tools/rss/zmanim.xml?locationid=%s&locationtype=2" % zip_code def clean_title(title): - """Extracts and maps the display title from the full title.""" original = title.split(" - ")[0].split(" (")[0] for display_name, match_text in ZMANIM_MAP.items(): if original.startswith(match_text): return display_name return original -def clean_time(time): - """Extracts the time from the full time string.""" - return time.split(" - ")[1].split(" --")[0].strip() +def clean_time(zman_time): + return zman_time.split(" - ")[1].split(" --")[0].strip() + +def format_date(now): + weekday = now.format("Monday") # Get full weekday name + month = now.format("January") # Get full month name + day = now.day + + days = { + "Monday": "Mon", + "Tuesday": "Tue", + "Wednesday": "Wed", + "Thursday": "Thu", + "Friday": "Fri", + "Saturday": "Sat", + "Sunday": "Sun", + } + + months = { + "January": "Jan", + "February": "Feb", + "March": "Mar", + "April": "Apr", + "May": "May", + "June": "Jun", + "July": "Jul", + "August": "Aug", + "September": "Sep", + "October": "Oct", + "November": "Nov", + "December": "Dec", + } + + short_day = days[weekday] + short_month = months[month] + + return "%s %s %d" % (short_day, short_month, day) + +def create_zman_row(title, zman_time, title_font, time_font, first): + row_children = [ + render.Text(content = clean_title(title) + ":", font = title_font), + render.Box(height = 1), + render.Text(content = zman_time, font = time_font, color = "#ff0"), + ] + + if not first: + row_children.insert(0, render.Box(height = 4, width = 1)) + + return render.Column(children = row_children) def main(config): - """Main function to create the Zmanim display.""" font = "tb-8" title_font = "tom-thumb" time_font = "CG-pixel-4x5-mono" zip_code = config.str("zip_code", DEFAULT_ZIP) + now = time.now() + current_date = format_date(now) + rep = http.get( url = get_url(zip_code), ttl_seconds = 14400, @@ -53,6 +99,7 @@ def main(config): "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36", }, ) + if rep.status_code != 200: display_rows = [ render.Text("Error", font = title_font), @@ -60,34 +107,27 @@ def main(config): render.Text("data!", font = title_font), ] else: - body = rep.body() - items = body.split("")[1:] - display_rows = [] + display_rows = [ + render.Box(height = 8), + render.Text(current_date, font = title_font, color = "#ff0"), + render.Box(height = 4), + ] + + items = rep.body().split("")[1:] first = True + for item in items: title_start = item.find("") + 7 title_end = item.find("") + if title_start > 6 and title_end > 0: full_title = item[title_start:title_end].strip() original_title = full_title.split(" - ")[0] + for match_text in ZMANIM_MAP.values(): if original_title.startswith(match_text): - time = clean_time(full_title) - row_children = [ - render.Text( - content = clean_title(full_title) + ":", - font = title_font, - ), - render.Box(height = 1), - render.Text( - content = time, - font = time_font, - color = "#ff0", - ), - ] - if not first: - row_children.insert(0, render.Box(height = 4, width = 1)) - display_rows.append(render.Column(children = row_children)) + zman_time = clean_time(full_title) + display_rows.append(create_zman_row(full_title, zman_time, title_font, time_font, first)) first = False break @@ -119,13 +159,13 @@ def main(config): ) def get_schema(): - """Defines the configuration schema for the app.""" scroll_speed = [ schema.Option(display = "Slower", value = "100"), schema.Option(display = "Slow", value = "70"), schema.Option(display = "Normal", value = "50"), schema.Option(display = "Fast (Default)", value = "30"), ] + return schema.Schema( version = "1", fields = [