diff --git a/Fruit_Jam/Fruit_Jam_Spell_Jam/aws_polly.py b/Fruit_Jam/Fruit_Jam_Spell_Jam/aws_polly.py new file mode 100644 index 000000000..a428713f9 --- /dev/null +++ b/Fruit_Jam/Fruit_Jam_Spell_Jam/aws_polly.py @@ -0,0 +1,295 @@ +# SPDX-FileCopyrightText: 2025 Tim Cocks for Adafruit Industries +# SPDX-License-Identifier: MIT +import hmac +import json + +from adafruit_datetime import datetime +import adafruit_hashlib as hashlib + + +def url_encode(string, safe=""): + """ + Minimal URL encoding function to replace urllib.parse.quote + + Args: + string (str): String to encode + safe (str): Characters that should not be encoded + + Returns: + str: URL encoded string + """ + # Characters that need to be encoded (RFC 3986) + unreserved = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.~" + + # Add safe characters to unreserved set + allowed = unreserved + safe + + encoded = "" + for char in string: + if char in allowed: + encoded += char + else: + # Convert to percent-encoded format + encoded += f"%{ord(char):02X}" + + return encoded + + +def _zero_pad(num, count=2): + padded = str(num) + while len(padded) < count: + padded = "0" + padded + return padded + + +class PollyHTTPClient: + # pylint: disable=no-self-use + def __init__(self, requests_instance, access_key, secret_key, region="us-east-1"): + self._requests = requests_instance + self.access_key = access_key + self.secret_key = secret_key + self.region = region + self.service = "polly" + self.host = f"polly.{region}.amazonaws.com" + self.endpoint = f"https://{self.host}" + + def _sign(self, key, msg): + """Helper function for AWS signature""" + return hmac.new(key, msg.encode("utf-8"), hashlib.sha256).digest() + + def _get_signature_key(self, date_stamp): + """Generate AWS signature key""" + k_date = self._sign(("AWS4" + self.secret_key).encode("utf-8"), date_stamp) + k_region = self._sign(k_date, self.region) + k_service = self._sign(k_region, self.service) + k_signing = self._sign(k_service, "aws4_request") + return k_signing + + def _create_canonical_request(self, method, uri, query_string, headers, payload): + """Create canonical request for AWS Signature V4""" + canonical_uri = url_encode(uri, safe="/") + canonical_querystring = query_string + + # Create canonical headers + canonical_headers = "" + signed_headers = "" + header_names = sorted(headers.keys()) + for name in header_names: + canonical_headers += f"{name.lower()}:{headers[name].strip()}\n" + signed_headers += f"{name.lower()};" + signed_headers = signed_headers[:-1] # Remove trailing semicolon + + # Create payload hash + payload_hash = hashlib.sha256(payload.encode("utf-8")).hexdigest() + + # Create canonical request + canonical_request = (f"{method}\n{canonical_uri}\n{canonical_querystring}\n" + f"{canonical_headers}\n{signed_headers}\n{payload_hash}") + + return canonical_request, signed_headers + + def _create_string_to_sign(self, timestamp, credential_scope, canonical_request): + """Create string to sign for AWS Signature V4""" + algorithm = "AWS4-HMAC-SHA256" + canonical_request_hash = hashlib.sha256( + canonical_request.encode("utf-8") + ).hexdigest() + string_to_sign = ( + f"{algorithm}\n{timestamp}\n{credential_scope}\n{canonical_request_hash}" + ) + return string_to_sign + + def synthesize_speech( # pylint: disable=too-many-locals + self, + text, + voice_id="Joanna", + output_format="mp3", + engine="standard", + text_type="text", + ): + """ + Synthesize speech using Amazon Polly via direct HTTP request + + Args: + text (str): Text to convert to speech + voice_id (str): Voice to use (e.g., 'Joanna', 'Matthew', 'Amy') + output_format (str): Audio format ('mp3', 'ogg_vorbis', 'pcm') + engine (str): Engine type ('standard' or 'neural') + text_type (str): 'text' or 'ssml' + + Returns: + bytes: Audio data if successful, None if failed + """ + + # Prepare request + method = "POST" + uri = "/v1/speech" + + # Create request body + request_body = { + "Text": text, + "OutputFormat": output_format, + "VoiceId": voice_id, + "Engine": engine, + "TextType": text_type, + } + payload = json.dumps(request_body) + + # Get current time + now = datetime.now() + # amzdate = now.strftime('%Y%m%dT%H%M%SZ') + amzdate = (f"{now.year}{_zero_pad(now.month)}{_zero_pad(now.day)}" + f"T{_zero_pad(now.hour)}{_zero_pad(now.minute)}{_zero_pad(now.second)}Z") + # datestamp = now.strftime('%Y%m%d') + datestamp = f"{now.year}{_zero_pad(now.month)}{_zero_pad(now.day)}" + + # Create headers + headers = { + "Content-Type": "application/x-amz-json-1.0", + "Host": self.host, + "X-Amz-Date": amzdate, + "X-Amz-Target": "AWSPollyService.SynthesizeSpeech", + } + + # Create canonical request + canonical_request, signed_headers = self._create_canonical_request( + method, uri, "", headers, payload + ) + + # Create string to sign + credential_scope = f"{datestamp}/{self.region}/{self.service}/aws4_request" + string_to_sign = self._create_string_to_sign( + amzdate, credential_scope, canonical_request + ) + + # Create signature + signing_key = self._get_signature_key(datestamp) + signature = hmac.new( + signing_key, string_to_sign.encode("utf-8"), hashlib.sha256 + ).hexdigest() + + # Add authorization header + authorization_header = ( + f"AWS4-HMAC-SHA256 " + f"Credential={self.access_key}/{credential_scope}, " + f"SignedHeaders={signed_headers}, " + f"Signature={signature}" + ) + headers["Authorization"] = authorization_header + + # Make request + try: + url = f"{self.endpoint}{uri}" + response = self._requests.post(url, headers=headers, data=payload) + + if response.status_code == 200: + return response.content + else: + print(f"Error: HTTP {response.status_code}") + print(f"Response: {response.text}") + return None + + except Exception as e: # pylint: disable=broad-except + print(f"Request failed: {e}") + return None + + +def text_to_speech_polly_http( + requests_instance, + text, + access_key, + secret_key, + output_file="/saves/awspollyoutput.mp3", + voice_id="Joanna", + region="us-east-1", + output_format="mp3", +): + """ + Simple function to convert text to speech using Polly HTTP API + + Args: + text (str): Text to convert + access_key (str): AWS Access Key ID + secret_key (str): AWS Secret Access Key + output_file (str): Output file path + voice_id (str): Polly voice ID + region (str): AWS region + output_format (str): Audio format + + Returns: + bool: True if successful, False otherwise + """ + + # Create Polly client + client = PollyHTTPClient(requests_instance, access_key, secret_key, region) + + # Synthesize speech + audio_data = client.synthesize_speech( + text=text, voice_id=voice_id, output_format=output_format + ) + + if audio_data: + # Save to file + try: + with open(output_file, "wb") as f: + f.write(audio_data) + print(f"Audio saved to: {output_file}") + return True + except Exception as e: # pylint: disable=broad-except + print(f"Failed to save file: {e}") + return False + else: + print("Failed to synthesize speech") + return False + + +def text_to_speech_with_ssml( + requests_instance, + text, + access_key, + secret_key, + speech_rate="medium", + output_file="output.mp3", +): + """ + Example with SSML for speech rate control + """ + # Wrap text in SSML + ssml_text = f'{text}' + + client = PollyHTTPClient(requests_instance, access_key, secret_key) + audio_data = client.synthesize_speech( + text=ssml_text, voice_id="Joanna", text_type="ssml" + ) + + if audio_data: + with open(output_file, "wb") as f: + f.write(audio_data) + print(f"SSML audio saved to: {output_file}") + return True + return False + + +# Example usage +# if __name__ == "__main__": +# # Replace with your actual AWS credentials +# AWS_ACCESS_KEY = os.getenv('AWS_ACCESS_KEY') +# AWS_SECRET_KEY = os.getenv('AWS_SECRET_KEY') +# +# # Basic usage +# success = text_to_speech_polly_http( +# text="Hello from CircuitPython! This is Amazon Polly speaking.", +# access_key=AWS_ACCESS_KEY, +# secret_key=AWS_SECRET_KEY, +# voice_id="Joanna" +# ) + +# SSML example +# if success: +# text_to_speech_with_ssml( +# text="This speech has a custom rate using SSML markup.", +# access_key=AWS_ACCESS_KEY, +# secret_key=AWS_SECRET_KEY, +# speech_rate="slow", +# output_file="ssml_example.mp3" +# ) diff --git a/Fruit_Jam/Fruit_Jam_Spell_Jam/code.py b/Fruit_Jam/Fruit_Jam_Spell_Jam/code.py new file mode 100644 index 000000000..69f629ec4 --- /dev/null +++ b/Fruit_Jam/Fruit_Jam_Spell_Jam/code.py @@ -0,0 +1,131 @@ +# SPDX-FileCopyrightText: 2025 Tim Cocks for Adafruit Industries +# SPDX-License-Identifier: MIT +import os +import sys +import time + +import supervisor +from adafruit_fruitjam import FruitJam +from adafruit_fruitjam.peripherals import request_display_config +import adafruit_connection_manager +import adafruit_requests +from displayio import OnDiskBitmap, TileGrid, Group +from adafruit_bitmap_font import bitmap_font +from adafruit_display_text.bitmap_label import Label + +from aws_polly import text_to_speech_polly_http + +# constants +LETTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + +# local variables +curword = "" +lastword = "" + +# setup display +request_display_config(320, 240) +display = supervisor.runtime.display + +# setup background image +main_group = Group() +background = OnDiskBitmap("spell_jam_assets/background.bmp") +background_tg = TileGrid(background, pixel_shader=background.pixel_shader) +main_group.append(background_tg) + +# setup 14-segment label used to display words +font = bitmap_font.load_font("spell_jam_assets/14segment_16.bdf") +screen_lbl = Label(text="Type a word", font=font, color=0x00FF00) +screen_lbl.anchor_point = (0.5, 0) +screen_lbl.anchored_position = (display.width // 2, 100) +main_group.append(screen_lbl) + +# initialize Fruit Jam built-in hardware +fj = FruitJam() +fj.neopixels.brightness = 0.1 +fj.peripherals.volume = 9 + +# AWS auth requires us to have accurate date/time +now = fj.sync_time() + +# setup adafruit_requests session +# pylint: disable=protected-access +pool = adafruit_connection_manager.get_radio_socketpool(fj.network._wifi.esp) +ssl_context = adafruit_connection_manager.get_radio_ssl_context(fj.network._wifi.esp) +requests = adafruit_requests.Session(pool, ssl_context) + +# read AWS keys from settings.toml +AWS_ACCESS_KEY = os.getenv("AWS_ACCESS_KEY") +AWS_SECRET_KEY = os.getenv("AWS_SECRET_KEY") + + +def fetch_word(word, voice="Joanna"): + """ + Fetch an MP3 saying a word from AWS Polly + :param word: The word to speak + :param voice: The AWS Polly voide ID to use + :return: Boolean, whether the request was successful. + """ + fj.neopixels.fill(0xFFFF00) + success = text_to_speech_polly_http( + requests, + text=word, + access_key=AWS_ACCESS_KEY, + secret_key=AWS_SECRET_KEY, + voice_id=voice, + ) + fj.neopixels.fill(0x00FF00) + return success + + +def say_and_spell_lastword(): + """ + Say the last word, then spell it out one letter at a time, finally say it once more. + """ + fj.play_mp3_file("/saves/awspollyoutput.mp3") + time.sleep(0.2) + for letter in lastword: + fj.play_mp3_file(f"spell_jam_assets/letter_mp3s/{letter.upper()}.mp3") + time.sleep(0.2) + fj.play_mp3_file("/saves/awspollyoutput.mp3") + fj.neopixels.fill(0x000000) + + +display.root_group = main_group +while True: + # check how many bytes are available + available = supervisor.runtime.serial_bytes_available + + # if there are some bytes available + if available: + # read data from the keyboard input + c = sys.stdin.read(available) + # print the data that was read + print(c, end="") + + if c in LETTERS: + curword += c + screen_lbl.text = curword + elif c in {"\x7f", "\x08"}: # backspace + curword = curword[:-1] + screen_lbl.text = curword + elif c == "\n": + if curword: + lastword = curword + fetch_word(lastword) + say_and_spell_lastword() + curword = "" + else: + # repeat last word + say_and_spell_lastword() + elif c.encode("utf-8") == b"\x1b[B": + # down arrow + fj.peripherals.volume = max(1, fj.peripherals.volume - 1) + print(f"Volume: {fj.peripherals.volume}") + elif c.encode("utf-8") == b"\x1b[A": + # up arrow + fj.peripherals.volume = min( + fj.peripherals.safe_volume_limit, fj.peripherals.volume + 1 + ) + print(f"Volume: {fj.peripherals.volume}") + else: + print(f"unused key: {c.encode('utf-8')}") diff --git a/Fruit_Jam/Fruit_Jam_Spell_Jam/hmac.py b/Fruit_Jam/Fruit_Jam_Spell_Jam/hmac.py new file mode 100644 index 000000000..d1516d9a4 --- /dev/null +++ b/Fruit_Jam/Fruit_Jam_Spell_Jam/hmac.py @@ -0,0 +1,93 @@ +# SPDX-FileCopyrightText: 2015 Paul Sokolovsky +# SPDX-License-Identifier: MIT +# https://github.com/micropython/micropython-lib +# https://github.com/micropython/micropython-lib/blob/master/LICENSE + +# Implements the hmac module from the Python standard library. + + +class HMAC: + # pylint: disable=protected-access, import-outside-toplevel + def __init__(self, key, msg=None, digestmod=None): + if not isinstance(key, (bytes, bytearray)): + raise TypeError("key: expected bytes/bytearray") + + import adafruit_hashlib as hashlib + + if digestmod is None: + # TODO: Default hash algorithm is now deprecated. + digestmod = hashlib.md5 + + if callable(digestmod): + # A hashlib constructor returning a new hash object. + make_hash = digestmod # A + elif isinstance(digestmod, str): + # A hash name suitable for hashlib.new(). + make_hash = lambda d=b"": getattr(hashlib, digestmod)(d) + else: + # A module supporting PEP 247. + make_hash = digestmod.new # C + + self._outer = make_hash() + self._inner = make_hash() + + self.digest_size = getattr(self._inner, "digest_size", None) + # If the provided hash doesn't support block_size (e.g. built-in + # hashlib), 64 is the correct default for all built-in hash + # functions (md5, sha1, sha256). + self.block_size = getattr(self._inner, "block_size", 64) + + # Truncate to digest_size if greater than block_size. + if len(key) > self.block_size: + key = make_hash(key).digest() + + # Pad to block size. + key = key + bytes(self.block_size - len(key)) + + self._outer.update(bytes(x ^ 0x5C for x in key)) + self._inner.update(bytes(x ^ 0x36 for x in key)) + + if msg is not None: + self.update(msg) + + @property + def name(self): + return "hmac-" + getattr(self._inner, "name", type(self._inner).__name__) + + def update(self, msg): + self._inner.update(msg) + + def copy(self): + if not hasattr(self._inner, "copy"): + # Not supported for built-in hash functions. + raise NotImplementedError() + # Call __new__ directly to avoid the expensive __init__. + other = self.__class__.__new__(self.__class__) + other.block_size = self.block_size + other.digest_size = self.digest_size + other._inner = self._inner.copy() + other._outer = self._outer.copy() + return other + + def _current(self): + h = self._outer + if hasattr(h, "copy"): + # built-in hash functions don't support this, and as a result, + # digest() will finalise the hmac and further calls to + # update/digest will fail. + h = h.copy() + h.update(self._inner.digest()) + return h + + def digest(self): + h = self._current() + return h.digest() + + def hexdigest(self): + import binascii + + return str(binascii.hexlify(self.digest()), "utf-8") + + +def new(key, msg=None, digestmod=None): + return HMAC(key, msg, digestmod) diff --git a/Fruit_Jam/Fruit_Jam_Spell_Jam/icon.bmp b/Fruit_Jam/Fruit_Jam_Spell_Jam/icon.bmp new file mode 100644 index 000000000..91b42534f Binary files /dev/null and b/Fruit_Jam/Fruit_Jam_Spell_Jam/icon.bmp differ diff --git a/Fruit_Jam/Fruit_Jam_Spell_Jam/metadata.json b/Fruit_Jam/Fruit_Jam_Spell_Jam/metadata.json new file mode 100644 index 000000000..2a14fabb9 --- /dev/null +++ b/Fruit_Jam/Fruit_Jam_Spell_Jam/metadata.json @@ -0,0 +1,4 @@ +{ + "title": "Spell Jam", + "icon": "icon.bmp" +} diff --git a/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/14segment_16.bdf b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/14segment_16.bdf new file mode 100644 index 000000000..e17ac7935 --- /dev/null +++ b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/14segment_16.bdf @@ -0,0 +1,2432 @@ +STARTFONT 2.1 +COMMENT +COMMENT Converted from OpenType font "DSEG14Modern-Regular.ttf" by "otf2bdf 3.0". +COMMENT +FONT -FreeType-DSEG14 Modern-Medium-R-Normal--22-160-100-100-P-120-ISO10646-1 +SIZE 16 100 100 +FONTBOUNDINGBOX 17 22 -1 0 +STARTPROPERTIES 19 +FOUNDRY "FreeType" +FAMILY_NAME "DSEG14 Modern" +WEIGHT_NAME "Medium" +SLANT "R" +SETWIDTH_NAME "Normal" +ADD_STYLE_NAME "" +PIXEL_SIZE 22 +POINT_SIZE 160 +RESOLUTION_X 100 +RESOLUTION_Y 100 +SPACING "P" +AVERAGE_WIDTH 120 +CHARSET_REGISTRY "ISO10646" +CHARSET_ENCODING "1" +FONT_ASCENT 22 +FONT_DESCENT 0 +COPYRIGHT "Created by Keshikan with FontForge 2.0 (http://fontforge.sf.net)" +_OTF_FONTFILE "DSEG14Modern-Regular.ttf" +_OTF_PSNAME "DSEG14Modern-Regular" +ENDPROPERTIES +CHARS 93 +STARTCHAR 0020 +ENCODING 32 +SWIDTH 180 0 +DWIDTH 4 0 +BBX 0 0 0 0 +BITMAP +ENDCHAR +STARTCHAR 0021 +ENCODING 33 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 0 0 0 0 +BITMAP +ENDCHAR +STARTCHAR 0022 +ENCODING 34 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 8 10 2 10 +BITMAP +80 +C3 +C3 +C3 +C3 +C3 +C3 +C0 +C0 +C0 +ENDCHAR +STARTCHAR 0024 +ENCODING 36 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +FFF8 +BFF0 +C300 +C300 +C300 +C300 +C300 +C300 +C000 +C000 +FCF0 +3CFC +000C +000C +030C +030C +030C +030C +030C +030C +3FF4 +7FFC +ENDCHAR +STARTCHAR 0025 +ENCODING 37 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 20 2 1 +BITMAP +8000 +C000 +D020 +D020 +D860 +DCE0 +CCC0 +CCC0 +C480 +FCF0 +3CFC +048C +0CCC +0CCC +1CEC +186C +102C +102C +000C +0004 +ENDCHAR +STARTCHAR 0026 +ENCODING 38 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +FFF8 +3FF0 +0000 +1020 +1020 +1860 +1CE0 +0CC0 +0CC0 +0480 +0000 +000C +048C +0CCC +0CCC +1CEC +186C +102C +102C +000C +3FF4 +7FFC +ENDCHAR +STARTCHAR 0027 +ENCODING 39 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 2 6 8 12 +BITMAP +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR 0028 +ENCODING 40 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 3 16 10 3 +BITMAP +20 +20 +60 +E0 +C0 +C0 +80 +00 +00 +80 +C0 +C0 +E0 +60 +20 +20 +ENDCHAR +STARTCHAR 0029 +ENCODING 41 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 3 16 5 3 +BITMAP +80 +80 +C0 +E0 +60 +60 +20 +00 +00 +20 +60 +60 +E0 +C0 +80 +80 +ENDCHAR +STARTCHAR 002A +ENCODING 42 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 10 18 4 2 +BITMAP +0C00 +4C80 +4C80 +6D80 +7F80 +3F00 +3300 +1200 +F3C0 +F3C0 +1200 +3300 +3F00 +7F80 +6D80 +4C80 +4C80 +0C00 +ENDCHAR +STARTCHAR 002B +ENCODING 43 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 10 18 4 2 +BITMAP +0C00 +0C00 +0C00 +0C00 +0C00 +0C00 +0000 +0000 +F3C0 +F3C0 +0000 +0000 +0C00 +0C00 +0C00 +0C00 +0C00 +0C00 +ENDCHAR +STARTCHAR 002C +ENCODING 44 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 3 7 5 3 +BITMAP +20 +60 +60 +E0 +C0 +80 +80 +ENDCHAR +STARTCHAR 002D +ENCODING 45 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 10 2 4 10 +BITMAP +F3C0 +F3C0 +ENDCHAR +STARTCHAR 002E +ENCODING 46 +SWIDTH 0 0 +DWIDTH 0 0 +BBX 2 3 -1 0 +BITMAP +C0 +C0 +C0 +ENDCHAR +STARTCHAR 002F +ENCODING 47 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 8 16 5 3 +BITMAP +01 +01 +03 +07 +06 +06 +04 +00 +00 +20 +60 +60 +E0 +C0 +80 +80 +ENDCHAR +STARTCHAR 0030 +ENCODING 48 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +FFFC +BFF4 +C00C +C02C +C02C +C06C +C0EC +C0CC +C0CC +C08C +C000 +000C +C40C +CC0C +CC0C +DC0C +D80C +D00C +D00C +C00C +BFF4 +FFFC +ENDCHAR +STARTCHAR 0031 +ENCODING 49 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 2 21 14 1 +BITMAP +40 +40 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +00 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +40 +ENDCHAR +STARTCHAR 0032 +ENCODING 50 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +FFFC +3FF4 +000C +000C +000C +000C +000C +000C +000C +000C +3CF0 +3CF0 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +BFF0 +FFFC +ENDCHAR +STARTCHAR 0033 +ENCODING 51 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +FFFC +3FF4 +000C +000C +000C +000C +000C +000C +000C +000C +3CF0 +3CFC +000C +000C +000C +000C +000C +000C +000C +000C +3FF4 +7FFC +ENDCHAR +STARTCHAR 0034 +ENCODING 52 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 21 2 1 +BITMAP +0004 +8004 +C00C +C00C +C00C +C00C +C00C +C00C +C00C +C00C +FCF0 +3CFC +000C +000C +000C +000C +000C +000C +000C +000C +0004 +ENDCHAR +STARTCHAR 0035 +ENCODING 53 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +FFF8 +BFF0 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +FCF0 +3CFC +000C +000C +000C +000C +000C +000C +000C +000C +3FF4 +7FFC +ENDCHAR +STARTCHAR 0036 +ENCODING 54 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +FFF8 +BFF0 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +FCF0 +3CFC +C00C +C00C +C00C +C00C +C00C +C00C +C00C +C00C +BFF4 +FFFC +ENDCHAR +STARTCHAR 0037 +ENCODING 55 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 21 2 1 +BITMAP +FFFC +BFF4 +C00C +C00C +C00C +C00C +C00C +C00C +C00C +C00C +C000 +000C +000C +000C +000C +000C +000C +000C +000C +000C +0004 +ENDCHAR +STARTCHAR 0038 +ENCODING 56 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +FFFC +BFF4 +C00C +C00C +C00C +C00C +C00C +C00C +C00C +C00C +FCF0 +3CFC +C00C +C00C +C00C +C00C +C00C +C00C +C00C +C00C +BFF4 +FFFC +ENDCHAR +STARTCHAR 0039 +ENCODING 57 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +FFFC +BFF4 +C00C +C00C +C00C +C00C +C00C +C00C +C00C +C00C +FCF0 +3CFC +000C +000C +000C +000C +000C +000C +000C +000C +3FF4 +7FFC +ENDCHAR +STARTCHAR 003A +ENCODING 58 +SWIDTH 180 0 +DWIDTH 4 0 +BBX 3 12 1 5 +BITMAP +40 +E0 +C0 +00 +00 +00 +00 +00 +00 +40 +E0 +C0 +ENDCHAR +STARTCHAR 003C +ENCODING 60 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 13 19 3 1 +BITMAP +0040 +0040 +00C0 +01C0 +0180 +0180 +0100 +0000 +0000 +0800 +1800 +1800 +3800 +3000 +2000 +2000 +0000 +7FE0 +FFF8 +ENDCHAR +STARTCHAR 003D +ENCODING 61 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 13 12 3 0 +BITMAP +79E0 +79E0 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +7FE0 +FFF8 +ENDCHAR +STARTCHAR 003E +ENCODING 62 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 13 19 3 1 +BITMAP +2000 +2000 +3000 +3800 +1800 +1800 +0800 +0000 +0000 +0100 +0180 +0180 +01C0 +00C0 +0040 +0040 +0000 +7FE0 +FFF8 +ENDCHAR +STARTCHAR 003F +ENCODING 63 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 20 2 2 +BITMAP +FFFC +BFF4 +C00C +C00C +C00C +C00C +C00C +C00C +C00C +C00C +C0F0 +00F0 +0000 +0000 +0300 +0300 +0300 +0300 +0300 +0300 +ENDCHAR +STARTCHAR 0040 +ENCODING 64 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +FFFC +BFF4 +C00C +C00C +C00C +C00C +C00C +C00C +C00C +C00C +C0F0 +00FC +C00C +C00C +C30C +C30C +C30C +C30C +C30C +C30C +BFF4 +FFFC +ENDCHAR +STARTCHAR 0041 +ENCODING 65 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +FFFC +BFF4 +C00C +C00C +C00C +C00C +C00C +C00C +C00C +C00C +FCF0 +3CFC +C00C +C00C +C00C +C00C +C00C +C00C +C00C +C00C +8004 +8000 +ENDCHAR +STARTCHAR 0042 +ENCODING 66 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +FFFC +3FF4 +030C +030C +030C +030C +030C +030C +000C +000C +00F0 +00FC +000C +000C +030C +030C +030C +030C +030C +030C +3FF4 +7FFC +ENDCHAR +STARTCHAR 0043 +ENCODING 67 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +FFF8 +BFF0 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +0000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +BFF0 +FFFC +ENDCHAR +STARTCHAR 0044 +ENCODING 68 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +FFFC +3FF4 +030C +030C +030C +030C +030C +030C +000C +000C +0000 +000C +000C +000C +030C +030C +030C +030C +030C +030C +3FF4 +7FFC +ENDCHAR +STARTCHAR 0045 +ENCODING 69 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +FFF8 +BFF0 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +FCF0 +3CF0 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +BFF0 +FFFC +ENDCHAR +STARTCHAR 0046 +ENCODING 70 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 13 22 2 0 +BITMAP +FFF8 +BFF0 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +FCF0 +3CF0 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +8000 +8000 +ENDCHAR +STARTCHAR 0047 +ENCODING 71 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +FFF8 +BFF0 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C0F0 +00FC +C00C +C00C +C00C +C00C +C00C +C00C +C00C +C00C +BFF4 +FFFC +ENDCHAR +STARTCHAR 0048 +ENCODING 72 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +0004 +8004 +C00C +C00C +C00C +C00C +C00C +C00C +C00C +C00C +FCF0 +3CFC +C00C +C00C +C00C +C00C +C00C +C00C +C00C +C00C +8004 +8000 +ENDCHAR +STARTCHAR 0049 +ENCODING 73 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +FFF8 +3FF0 +0300 +0300 +0300 +0300 +0300 +0300 +0000 +0000 +0000 +0000 +0000 +0000 +0300 +0300 +0300 +0300 +0300 +0300 +3FF0 +7FFC +ENDCHAR +STARTCHAR 004A +ENCODING 74 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +0004 +0004 +000C +000C +000C +000C +000C +000C +000C +000C +0000 +000C +C00C +C00C +C00C +C00C +C00C +C00C +C00C +C00C +BFF4 +FFFC +ENDCHAR +STARTCHAR 004B +ENCODING 75 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 11 21 2 0 +BITMAP +8000 +C000 +C020 +C020 +C060 +C0E0 +C0C0 +C0C0 +C080 +FC00 +3C00 +C080 +C0C0 +C0C0 +C0E0 +C060 +C020 +C020 +C000 +8000 +8000 +ENDCHAR +STARTCHAR 004C +ENCODING 76 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 21 2 0 +BITMAP +8000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +0000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +BFF0 +FFFC +ENDCHAR +STARTCHAR 004D +ENCODING 77 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +0004 +8004 +C00C +D02C +D02C +D86C +DCEC +CCCC +CCCC +C48C +C000 +000C +C00C +C00C +C30C +C30C +C30C +C30C +C30C +C30C +8004 +8000 +ENDCHAR +STARTCHAR 004E +ENCODING 78 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +0004 +8004 +C00C +D00C +D00C +D80C +DC0C +CC0C +CC0C +C40C +C000 +000C +C08C +C0CC +C0CC +C0EC +C06C +C02C +C02C +C00C +8004 +8000 +ENDCHAR +STARTCHAR 004F +ENCODING 79 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +FFFC +BFF4 +C00C +C00C +C00C +C00C +C00C +C00C +C00C +C00C +C000 +000C +C00C +C00C +C00C +C00C +C00C +C00C +C00C +C00C +BFF4 +FFFC +ENDCHAR +STARTCHAR 0050 +ENCODING 80 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +FFFC +BFF4 +C00C +C00C +C00C +C00C +C00C +C00C +C00C +C00C +FCF0 +3CF0 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +8000 +8000 +ENDCHAR +STARTCHAR 0051 +ENCODING 81 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +FFFC +BFF4 +C00C +C00C +C00C +C00C +C00C +C00C +C00C +C00C +C000 +000C +C08C +C0CC +C0CC +C0EC +C06C +C02C +C02C +C00C +BFF4 +FFFC +ENDCHAR +STARTCHAR 0052 +ENCODING 82 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +FFFC +BFF4 +C00C +C00C +C00C +C00C +C00C +C00C +C00C +C00C +FCF0 +3CF0 +C080 +C0C0 +C0C0 +C0E0 +C060 +C020 +C020 +C000 +8000 +8000 +ENDCHAR +STARTCHAR 0053 +ENCODING 83 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +FFF8 +BFF0 +C000 +D000 +D000 +D800 +DC00 +CC00 +CC00 +C400 +FCF0 +3CFC +008C +00CC +00CC +00EC +006C +002C +002C +000C +3FF4 +7FFC +ENDCHAR +STARTCHAR 0054 +ENCODING 84 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 13 20 2 2 +BITMAP +FFF8 +3FF0 +0300 +0300 +0300 +0300 +0300 +0300 +0000 +0000 +0000 +0000 +0000 +0000 +0300 +0300 +0300 +0300 +0300 +0300 +ENDCHAR +STARTCHAR 0055 +ENCODING 85 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +0004 +8004 +C00C +C00C +C00C +C00C +C00C +C00C +C00C +C00C +C000 +000C +C00C +C00C +C00C +C00C +C00C +C00C +C00C +C00C +BFF4 +FFFC +ENDCHAR +STARTCHAR 0056 +ENCODING 86 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 11 21 2 0 +BITMAP +8000 +C000 +C020 +C020 +C060 +C0E0 +C0C0 +C0C0 +C080 +C000 +0000 +C400 +CC00 +CC00 +DC00 +D800 +D000 +D000 +C000 +8000 +8000 +ENDCHAR +STARTCHAR 0057 +ENCODING 87 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +0004 +8004 +C30C +C30C +C30C +C30C +C30C +C30C +C00C +C00C +C000 +000C +C48C +CCCC +CCCC +DCEC +D86C +D02C +D02C +C00C +8004 +8000 +ENDCHAR +STARTCHAR 0058 +ENCODING 88 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 8 16 5 3 +BITMAP +81 +81 +C3 +E7 +66 +66 +24 +00 +00 +24 +66 +66 +E7 +C3 +81 +81 +ENDCHAR +STARTCHAR 0059 +ENCODING 89 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 8 17 5 3 +BITMAP +81 +81 +C3 +E7 +66 +66 +24 +00 +00 +00 +00 +18 +18 +18 +18 +18 +18 +ENDCHAR +STARTCHAR 005A +ENCODING 90 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +FFF8 +3FF0 +0000 +0020 +0020 +0060 +00E0 +00C0 +00C0 +0080 +0000 +0000 +0400 +0C00 +0C00 +1C00 +1800 +1000 +1000 +0000 +3FF0 +7FFC +ENDCHAR +STARTCHAR 005C +ENCODING 92 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 8 16 5 3 +BITMAP +80 +80 +C0 +E0 +60 +60 +20 +00 +00 +04 +06 +06 +07 +03 +01 +01 +ENDCHAR +STARTCHAR 005E +ENCODING 94 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 6 10 2 10 +BITMAP +80 +C0 +D0 +D0 +D8 +DC +CC +CC +C4 +C0 +ENDCHAR +STARTCHAR 005F +ENCODING 95 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 13 2 3 0 +BITMAP +7FE0 +FFF8 +ENDCHAR +STARTCHAR 0060 +ENCODING 96 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 3 7 5 12 +BITMAP +80 +80 +C0 +E0 +60 +60 +20 +ENDCHAR +STARTCHAR 0061 +ENCODING 97 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +FFFC +BFF4 +C00C +C00C +C00C +C00C +C00C +C00C +C00C +C00C +FCF0 +3CFC +C00C +C00C +C00C +C00C +C00C +C00C +C00C +C00C +8004 +8000 +ENDCHAR +STARTCHAR 0062 +ENCODING 98 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +FFFC +3FF4 +030C +030C +030C +030C +030C +030C +000C +000C +00F0 +00FC +000C +000C +030C +030C +030C +030C +030C +030C +3FF4 +7FFC +ENDCHAR +STARTCHAR 0063 +ENCODING 99 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +FFF8 +BFF0 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +0000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +BFF0 +FFFC +ENDCHAR +STARTCHAR 0064 +ENCODING 100 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +FFFC +3FF4 +030C +030C +030C +030C +030C +030C +000C +000C +0000 +000C +000C +000C +030C +030C +030C +030C +030C +030C +3FF4 +7FFC +ENDCHAR +STARTCHAR 0065 +ENCODING 101 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +FFF8 +BFF0 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +FCF0 +3CF0 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +BFF0 +FFFC +ENDCHAR +STARTCHAR 0066 +ENCODING 102 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 13 22 2 0 +BITMAP +FFF8 +BFF0 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +FCF0 +3CF0 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +8000 +8000 +ENDCHAR +STARTCHAR 0067 +ENCODING 103 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +FFF8 +BFF0 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C0F0 +00FC +C00C +C00C +C00C +C00C +C00C +C00C +C00C +C00C +BFF4 +FFFC +ENDCHAR +STARTCHAR 0068 +ENCODING 104 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +0004 +8004 +C00C +C00C +C00C +C00C +C00C +C00C +C00C +C00C +FCF0 +3CFC +C00C +C00C +C00C +C00C +C00C +C00C +C00C +C00C +8004 +8000 +ENDCHAR +STARTCHAR 0069 +ENCODING 105 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +FFF8 +3FF0 +0300 +0300 +0300 +0300 +0300 +0300 +0000 +0000 +0000 +0000 +0000 +0000 +0300 +0300 +0300 +0300 +0300 +0300 +3FF0 +7FFC +ENDCHAR +STARTCHAR 006A +ENCODING 106 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +0004 +0004 +000C +000C +000C +000C +000C +000C +000C +000C +0000 +000C +C00C +C00C +C00C +C00C +C00C +C00C +C00C +C00C +BFF4 +FFFC +ENDCHAR +STARTCHAR 006B +ENCODING 107 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 11 21 2 0 +BITMAP +8000 +C000 +C020 +C020 +C060 +C0E0 +C0C0 +C0C0 +C080 +FC00 +3C00 +C080 +C0C0 +C0C0 +C0E0 +C060 +C020 +C020 +C000 +8000 +8000 +ENDCHAR +STARTCHAR 006C +ENCODING 108 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 21 2 0 +BITMAP +8000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +0000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +BFF0 +FFFC +ENDCHAR +STARTCHAR 006D +ENCODING 109 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +0004 +8004 +C00C +D02C +D02C +D86C +DCEC +CCCC +CCCC +C48C +C000 +000C +C00C +C00C +C30C +C30C +C30C +C30C +C30C +C30C +8004 +8000 +ENDCHAR +STARTCHAR 006E +ENCODING 110 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +0004 +8004 +C00C +D00C +D00C +D80C +DC0C +CC0C +CC0C +C40C +C000 +000C +C08C +C0CC +C0CC +C0EC +C06C +C02C +C02C +C00C +8004 +8000 +ENDCHAR +STARTCHAR 006F +ENCODING 111 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +FFFC +BFF4 +C00C +C00C +C00C +C00C +C00C +C00C +C00C +C00C +C000 +000C +C00C +C00C +C00C +C00C +C00C +C00C +C00C +C00C +BFF4 +FFFC +ENDCHAR +STARTCHAR 0070 +ENCODING 112 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +FFFC +BFF4 +C00C +C00C +C00C +C00C +C00C +C00C +C00C +C00C +FCF0 +3CF0 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +8000 +8000 +ENDCHAR +STARTCHAR 0071 +ENCODING 113 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +FFFC +BFF4 +C00C +C00C +C00C +C00C +C00C +C00C +C00C +C00C +C000 +000C +C08C +C0CC +C0CC +C0EC +C06C +C02C +C02C +C00C +BFF4 +FFFC +ENDCHAR +STARTCHAR 0072 +ENCODING 114 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +FFFC +BFF4 +C00C +C00C +C00C +C00C +C00C +C00C +C00C +C00C +FCF0 +3CF0 +C080 +C0C0 +C0C0 +C0E0 +C060 +C020 +C020 +C000 +8000 +8000 +ENDCHAR +STARTCHAR 0073 +ENCODING 115 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +FFF8 +BFF0 +C000 +D000 +D000 +D800 +DC00 +CC00 +CC00 +C400 +FCF0 +3CFC +008C +00CC +00CC +00EC +006C +002C +002C +000C +3FF4 +7FFC +ENDCHAR +STARTCHAR 0074 +ENCODING 116 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 13 20 2 2 +BITMAP +FFF8 +3FF0 +0300 +0300 +0300 +0300 +0300 +0300 +0000 +0000 +0000 +0000 +0000 +0000 +0300 +0300 +0300 +0300 +0300 +0300 +ENDCHAR +STARTCHAR 0075 +ENCODING 117 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +0004 +8004 +C00C +C00C +C00C +C00C +C00C +C00C +C00C +C00C +C000 +000C +C00C +C00C +C00C +C00C +C00C +C00C +C00C +C00C +BFF4 +FFFC +ENDCHAR +STARTCHAR 0076 +ENCODING 118 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 11 21 2 0 +BITMAP +8000 +C000 +C020 +C020 +C060 +C0E0 +C0C0 +C0C0 +C080 +C000 +0000 +C400 +CC00 +CC00 +DC00 +D800 +D000 +D000 +C000 +8000 +8000 +ENDCHAR +STARTCHAR 0077 +ENCODING 119 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +0004 +8004 +C30C +C30C +C30C +C30C +C30C +C30C +C00C +C00C +C000 +000C +C48C +CCCC +CCCC +DCEC +D86C +D02C +D02C +C00C +8004 +8000 +ENDCHAR +STARTCHAR 0078 +ENCODING 120 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 8 16 5 3 +BITMAP +81 +81 +C3 +E7 +66 +66 +24 +00 +00 +24 +66 +66 +E7 +C3 +81 +81 +ENDCHAR +STARTCHAR 0079 +ENCODING 121 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 8 17 5 3 +BITMAP +81 +81 +C3 +E7 +66 +66 +24 +00 +00 +00 +00 +18 +18 +18 +18 +18 +18 +ENDCHAR +STARTCHAR 007A +ENCODING 122 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +FFF8 +3FF0 +0000 +0020 +0020 +0060 +00E0 +00C0 +00C0 +0080 +0000 +0000 +0400 +0C00 +0C00 +1C00 +1800 +1000 +1000 +0000 +3FF0 +7FFC +ENDCHAR +STARTCHAR 007C +ENCODING 124 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 2 18 8 2 +BITMAP +C0 +C0 +C0 +C0 +C0 +C0 +00 +00 +00 +00 +00 +00 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR 007E +ENCODING 126 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 22 2 0 +BITMAP +FFFC +BFF4 +C30C +D32C +D32C +DB6C +DFEC +CFCC +CCCC +C48C +FCF0 +3CFC +C48C +CCCC +CFCC +DFEC +DB6C +D32C +D32C +C30C +BFF4 +FFFC +ENDCHAR +STARTCHAR 00A5 +ENCODING 165 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 10 17 4 3 +BITMAP +4080 +4080 +6180 +7380 +3300 +3300 +1200 +F3C0 +F3C0 +0000 +0000 +0C00 +0C00 +0C00 +0C00 +0C00 +0C00 +ENDCHAR +STARTCHAR 00A6 +ENCODING 166 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 2 18 8 2 +BITMAP +C0 +C0 +C0 +C0 +C0 +C0 +00 +00 +00 +00 +00 +00 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR 00B0 +ENCODING 176 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 14 12 2 10 +BITMAP +FFFC +BFF4 +C00C +C00C +C00C +C00C +C00C +C00C +C00C +C00C +FCF0 +3CF0 +ENDCHAR +STARTCHAR 00B1 +ENCODING 177 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 13 20 3 0 +BITMAP +0600 +0600 +0600 +0600 +0600 +0600 +0000 +0000 +79E0 +79E0 +0000 +0000 +0600 +0600 +0600 +0600 +0600 +0600 +7FE0 +FFF8 +ENDCHAR +ENDFONT diff --git a/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/14segment_16.bdf.license b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/14segment_16.bdf.license new file mode 100644 index 000000000..9232f592f --- /dev/null +++ b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/14segment_16.bdf.license @@ -0,0 +1,8 @@ +# SPDX-FileCopyrightText: Copyright (c) 2020, keshikan (https://www.keshikan.net), with Reserved Font Name "DSEG". + +# SPDX-License-Identifier: OFL-1.1-RFN + +# This Font Software is licensed under the SIL Open Font License, Version 1.1. +# This license is copied below, and is also available with a FAQ at: +# http://scripts.sil.org/OFL + diff --git a/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/background.bmp b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/background.bmp new file mode 100644 index 000000000..6151b7c45 Binary files /dev/null and b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/background.bmp differ diff --git a/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/background.bmp.license b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/background.bmp.license new file mode 100644 index 000000000..39cb00c04 --- /dev/null +++ b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/background.bmp.license @@ -0,0 +1,3 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025, Tim Cocks for Adafruit Industries + +# SPDX-License-Identifier: MIT \ No newline at end of file diff --git a/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/A.mp3 b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/A.mp3 new file mode 100644 index 000000000..f281ab896 Binary files /dev/null and b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/A.mp3 differ diff --git a/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/B.mp3 b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/B.mp3 new file mode 100644 index 000000000..30d3d593a Binary files /dev/null and b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/B.mp3 differ diff --git a/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/C.mp3 b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/C.mp3 new file mode 100644 index 000000000..ce7b23a8a Binary files /dev/null and b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/C.mp3 differ diff --git a/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/D.mp3 b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/D.mp3 new file mode 100644 index 000000000..2397eabc3 Binary files /dev/null and b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/D.mp3 differ diff --git a/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/E.mp3 b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/E.mp3 new file mode 100644 index 000000000..1b70a9dee Binary files /dev/null and b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/E.mp3 differ diff --git a/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/F.mp3 b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/F.mp3 new file mode 100644 index 000000000..5ac0905b9 Binary files /dev/null and b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/F.mp3 differ diff --git a/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/G.mp3 b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/G.mp3 new file mode 100644 index 000000000..c687fca09 Binary files /dev/null and b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/G.mp3 differ diff --git a/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/H.mp3 b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/H.mp3 new file mode 100644 index 000000000..44ad2dba7 Binary files /dev/null and b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/H.mp3 differ diff --git a/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/I.mp3 b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/I.mp3 new file mode 100644 index 000000000..ef568e288 Binary files /dev/null and b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/I.mp3 differ diff --git a/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/J.mp3 b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/J.mp3 new file mode 100644 index 000000000..08b708145 Binary files /dev/null and b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/J.mp3 differ diff --git a/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/K.mp3 b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/K.mp3 new file mode 100644 index 000000000..69ae3e3b6 Binary files /dev/null and b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/K.mp3 differ diff --git a/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/L.mp3 b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/L.mp3 new file mode 100644 index 000000000..5fb69a7ce Binary files /dev/null and b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/L.mp3 differ diff --git a/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/M.mp3 b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/M.mp3 new file mode 100644 index 000000000..521e6d272 Binary files /dev/null and b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/M.mp3 differ diff --git a/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/N.mp3 b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/N.mp3 new file mode 100644 index 000000000..b10d92f92 Binary files /dev/null and b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/N.mp3 differ diff --git a/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/O.mp3 b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/O.mp3 new file mode 100644 index 000000000..edf62590c Binary files /dev/null and b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/O.mp3 differ diff --git a/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/P.mp3 b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/P.mp3 new file mode 100644 index 000000000..635952f6c Binary files /dev/null and b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/P.mp3 differ diff --git a/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/Q.mp3 b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/Q.mp3 new file mode 100644 index 000000000..9c6b6c725 Binary files /dev/null and b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/Q.mp3 differ diff --git a/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/R.mp3 b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/R.mp3 new file mode 100644 index 000000000..b5386fabe Binary files /dev/null and b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/R.mp3 differ diff --git a/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/S.mp3 b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/S.mp3 new file mode 100644 index 000000000..10c399dc9 Binary files /dev/null and b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/S.mp3 differ diff --git a/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/T.mp3 b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/T.mp3 new file mode 100644 index 000000000..e01ac6947 Binary files /dev/null and b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/T.mp3 differ diff --git a/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/U.mp3 b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/U.mp3 new file mode 100644 index 000000000..2521c9650 Binary files /dev/null and b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/U.mp3 differ diff --git a/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/V.mp3 b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/V.mp3 new file mode 100644 index 000000000..922738aea Binary files /dev/null and b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/V.mp3 differ diff --git a/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/W.mp3 b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/W.mp3 new file mode 100644 index 000000000..d210b316e Binary files /dev/null and b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/W.mp3 differ diff --git a/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/X.mp3 b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/X.mp3 new file mode 100644 index 000000000..576910ea3 Binary files /dev/null and b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/X.mp3 differ diff --git a/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/Y.mp3 b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/Y.mp3 new file mode 100644 index 000000000..ef11d65a6 Binary files /dev/null and b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/Y.mp3 differ diff --git a/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/Z.mp3 b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/Z.mp3 new file mode 100644 index 000000000..e3e95aa7f Binary files /dev/null and b/Fruit_Jam/Fruit_Jam_Spell_Jam/spell_jam_assets/letter_mp3s/Z.mp3 differ