diff --git a/FloridOS/build.fish b/FloridOS/build.fish new file mode 100644 index 0000000..2e656c0 --- /dev/null +++ b/FloridOS/build.fish @@ -0,0 +1,26 @@ +#!/usr/bin/fish + +# 1. CLEANUP +rm -rf build +mkdir -p build/iso_root/boot/limine + +# 2. COMPILE KERNEL +gcc -ffreestanding -mcmodel=kernel -fno-stack-protector -fno-pic -m64 -Isrc/include -c src/kernel/kernel.c -o build/kernel.o + +# 3. LINK KERNEL +ld -nostdlib -static -m elf_x86_64 -z max-page-size=0x1000 -T src/kernel/linker.ld build/kernel.o -o build/kernel.elf + +# 4. PREP ISO STRUCTURE (The "Fix") +cp build/kernel.elf build/iso_root/boot/ +cp src/assets/terminal.fpf build/iso_root/boot/ # Make sure path to fpf is correct! +cp limine/limine-bios.sys build/iso_root/boot/limine/ +cp limine/limine-bios-cd.bin build/iso_root/boot/limine/ +cp limine/limine.conf build/iso_root/boot/limine/ + +# 5. BUILD ISO +xorriso -as mkisofs -b boot/limine/limine-bios-cd.bin \ + -no-emul-boot -boot-load-size 4 -boot-info-table \ + build/iso_root -o build/florid_os.iso + +# 6. THE BLESSING +./limine-binary/limine bios-install build/florid_os.iso \ No newline at end of file diff --git a/FloridOS/build/florid_os.iso b/FloridOS/build/florid_os.iso new file mode 100644 index 0000000..6e4f992 Binary files /dev/null and b/FloridOS/build/florid_os.iso differ diff --git a/FloridOS/build/iso_root/boot/kernel.elf b/FloridOS/build/iso_root/boot/kernel.elf new file mode 100644 index 0000000..3203c85 Binary files /dev/null and b/FloridOS/build/iso_root/boot/kernel.elf differ diff --git a/FloridOS/build/iso_root/boot/limine/limine-bios-cd.bin b/FloridOS/build/iso_root/boot/limine/limine-bios-cd.bin new file mode 100644 index 0000000..0621f1e Binary files /dev/null and b/FloridOS/build/iso_root/boot/limine/limine-bios-cd.bin differ diff --git a/FloridOS/build/iso_root/boot/limine/limine-bios.sys b/FloridOS/build/iso_root/boot/limine/limine-bios.sys new file mode 100644 index 0000000..067c730 Binary files /dev/null and b/FloridOS/build/iso_root/boot/limine/limine-bios.sys differ diff --git a/FloridOS/build/kernel.elf b/FloridOS/build/kernel.elf new file mode 100644 index 0000000..3203c85 Binary files /dev/null and b/FloridOS/build/kernel.elf differ diff --git a/FloridOS/build/kernel.o b/FloridOS/build/kernel.o new file mode 100644 index 0000000..e329d9a Binary files /dev/null and b/FloridOS/build/kernel.o differ diff --git a/FloridOS/limine-binary/BOOTAA64.EFI b/FloridOS/limine-binary/BOOTAA64.EFI new file mode 100644 index 0000000..78bd960 Binary files /dev/null and b/FloridOS/limine-binary/BOOTAA64.EFI differ diff --git a/FloridOS/limine-binary/BOOTIA32.EFI b/FloridOS/limine-binary/BOOTIA32.EFI new file mode 100644 index 0000000..9c4d6a2 Binary files /dev/null and b/FloridOS/limine-binary/BOOTIA32.EFI differ diff --git a/FloridOS/limine-binary/BOOTRISCV64.EFI b/FloridOS/limine-binary/BOOTRISCV64.EFI new file mode 100644 index 0000000..e54f159 Binary files /dev/null and b/FloridOS/limine-binary/BOOTRISCV64.EFI differ diff --git a/FloridOS/limine-binary/BOOTX64.EFI b/FloridOS/limine-binary/BOOTX64.EFI new file mode 100644 index 0000000..e118efb Binary files /dev/null and b/FloridOS/limine-binary/BOOTX64.EFI differ diff --git a/FloridOS/limine-binary/LICENSE b/FloridOS/limine-binary/LICENSE new file mode 100644 index 0000000..fad56e1 --- /dev/null +++ b/FloridOS/limine-binary/LICENSE @@ -0,0 +1,22 @@ +Copyright (C) 2019-2024 mintsuki and contributors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/FloridOS/limine-binary/Makefile b/FloridOS/limine-binary/Makefile new file mode 100644 index 0000000..5544143 --- /dev/null +++ b/FloridOS/limine-binary/Makefile @@ -0,0 +1,38 @@ +CC ?= cc +STRIP ?= strip +INSTALL ?= ./install-sh + +PREFIX ?= /usr/local + +CFLAGS ?= -g -O2 -pipe + +.PHONY: all +all: limine + +.PHONY: install +install: all + $(INSTALL) -d '$(DESTDIR)$(PREFIX)/share' + $(INSTALL) -d '$(DESTDIR)$(PREFIX)/share/limine' + $(INSTALL) -m 644 limine-bios.sys '$(DESTDIR)$(PREFIX)/share/limine/' + $(INSTALL) -m 644 limine-bios-cd.bin '$(DESTDIR)$(PREFIX)/share/limine/' + $(INSTALL) -m 644 limine-uefi-cd.bin '$(DESTDIR)$(PREFIX)/share/limine/' + $(INSTALL) -m 644 limine-bios-pxe.bin '$(DESTDIR)$(PREFIX)/share/limine/' + $(INSTALL) -m 644 BOOTX64.EFI '$(DESTDIR)$(PREFIX)/share/limine/' + $(INSTALL) -m 644 BOOTIA32.EFI '$(DESTDIR)$(PREFIX)/share/limine/' + $(INSTALL) -m 644 BOOTAA64.EFI '$(DESTDIR)$(PREFIX)/share/limine/' + $(INSTALL) -m 644 BOOTRISCV64.EFI '$(DESTDIR)$(PREFIX)/share/limine/' + $(INSTALL) -d '$(DESTDIR)$(PREFIX)/include' + $(INSTALL) -m 644 limine.h '$(DESTDIR)$(PREFIX)/include/' + $(INSTALL) -d '$(DESTDIR)$(PREFIX)/bin' + $(INSTALL) limine '$(DESTDIR)$(PREFIX)/bin/' + +.PHONY: install-strip +install-strip: install + $(STRIP) '$(DESTDIR)$(PREFIX)/bin/limine' + +.PHONY: clean +clean: + rm -f limine limine.exe + +limine: limine.c + $(CC) $(CFLAGS) -Wall -Wextra $(WERROR_FLAG) $(CPPFLAGS) $(LDFLAGS) -std=c99 limine.c $(LIBS) -o $@ diff --git a/FloridOS/limine-binary/install-sh b/FloridOS/limine-binary/install-sh new file mode 100644 index 0000000..7c56c9c --- /dev/null +++ b/FloridOS/limine-binary/install-sh @@ -0,0 +1,541 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2023-11-23.18; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# 'make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +tab=' ' +nl=' +' +IFS=" $tab$nl" + +# Set DOITPROG to "echo" to test this script. + +doit=${DOITPROG-} +doit_exec=${doit:-exec} + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +# Create dirs (including intermediate dirs) using mode 755. +# This is like GNU 'install' as of coreutils 8.32 (2020). +mkdir_umask=22 + +backupsuffix= +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +is_target_a_directory=possibly + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -p pass -p to $cpprog. + -s $stripprog installed files. + -S SUFFIX attempt to back up existing files, with suffix SUFFIX. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG + +By default, rm is invoked with -f; when overridden with RMPROG, +it's up to you to specify -f if you want it. + +If -S is not specified, no backups are attempted. + +Report bugs to . +GNU Automake home page: . +General help using GNU software: ." + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -p) cpprog="$cpprog -p";; + + -s) stripcmd=$stripprog;; + + -S) backupsuffix="$2" + shift;; + + -t) + is_target_a_directory=always + dst_arg=$2 + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + shift;; + + -T) is_target_a_directory=never;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +# We allow the use of options -d and -T together, by making -d +# take the precedence; this is for compatibility with GNU install. + +if test -n "$dir_arg"; then + if test -n "$dst_arg"; then + echo "$0: target directory not allowed when installing a directory." >&2 + exit 1 + fi +fi + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call 'install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + if test $# -gt 1 || test "$is_target_a_directory" = always; then + if test ! -d "$dst_arg"; then + echo "$0: $dst_arg: Is not a directory." >&2 + exit 1 + fi + fi +fi + +if test -z "$dir_arg"; then + do_exit='(exit $ret); exit $ret' + trap "ret=129; $do_exit" 1 + trap "ret=130; $do_exit" 2 + trap "ret=141; $do_exit" 13 + trap "ret=143; $do_exit" 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names problematic for 'test' and other utilities. + case $src in + -* | [=\(\)!]) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + # Don't chown directories that already exist. + if test $dstdir_status = 0; then + chowncmd="" + fi + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + dst=$dst_arg + + # If destination is a directory, append the input filename. + if test -d "$dst"; then + if test "$is_target_a_directory" = never; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dstbase=`basename "$src"` + case $dst in + */) dst=$dst$dstbase;; + *) dst=$dst/$dstbase;; + esac + dstdir_status=0 + else + dstdir=`dirname "$dst"` + test -d "$dstdir" + dstdir_status=$? + fi + fi + + case $dstdir in + */) dstdirslash=$dstdir;; + *) dstdirslash=$dstdir/;; + esac + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + # The $RANDOM variable is not portable (e.g., dash). Use it + # here however when possible just to lower collision chance. + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + + trap ' + ret=$? + rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null + exit $ret + ' 0 + + # Because "mkdir -p" follows existing symlinks and we likely work + # directly in world-writeable /tmp, make sure that the '$tmpdir' + # directory is successfully created first before we actually test + # 'mkdir -p'. + if (umask $mkdir_umask && + $mkdirprog $mkdir_mode "$tmpdir" && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + test_tmpdir="$tmpdir/a" + ls_ld_tmpdir=`ls -ld "$test_tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null + fi + trap '' 0;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + [-=\(\)!]*) prefix='./';; + *) prefix='';; + esac + + oIFS=$IFS + IFS=/ + set -f + set fnord $dstdir + shift + set +f + IFS=$oIFS + + prefixes= + + for d + do + test X"$d" = X && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=${dstdirslash}_inst.$$_ + rmtmp=${dstdirslash}_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && + { test -z "$stripcmd" || { + # Create $dsttmp read-write so that cp doesn't create it read-only, + # which would cause strip to fail. + if test -z "$doit"; then + : >"$dsttmp" # No need to fork-exec 'touch'. + else + $doit touch "$dsttmp" + fi + } + } && + $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + set +f && + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # If $backupsuffix is set, and the file being installed + # already exists, attempt a backup. Don't worry if it fails, + # e.g., if mv doesn't support -f. + if test -n "$backupsuffix" && test -f "$dst"; then + $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null + fi + + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/FloridOS/limine-binary/limine b/FloridOS/limine-binary/limine new file mode 100644 index 0000000..43a974e Binary files /dev/null and b/FloridOS/limine-binary/limine differ diff --git a/FloridOS/limine-binary/limine-bios-cd.bin b/FloridOS/limine-binary/limine-bios-cd.bin new file mode 100644 index 0000000..0621f1e Binary files /dev/null and b/FloridOS/limine-binary/limine-bios-cd.bin differ diff --git a/FloridOS/limine-binary/limine-bios-hdd.h b/FloridOS/limine-binary/limine-bios-hdd.h new file mode 100644 index 0000000..d93b38f --- /dev/null +++ b/FloridOS/limine-binary/limine-bios-hdd.h @@ -0,0 +1,1341 @@ +const uint8_t binary_limine_hdd_bin_data[] = { + 0xeb, 0x3c, 0x90, 0x4c, 0x49, 0x4d, 0x49, 0x4e, 0x45, 0x20, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x49, 0x4d, 0x49, 0x4e, + 0x45, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, 0xfc, + 0xea, 0x45, 0x7c, 0x00, 0x00, 0x31, 0xf6, 0x8e, 0xde, 0x8e, 0xc6, 0x8e, 0xd6, 0xbc, 0x00, 0x7c, + 0xfb, 0x80, 0xfa, 0x80, 0x0f, 0x82, 0x10, 0x01, 0x80, 0xfa, 0x8f, 0x0f, 0x87, 0x08, 0x01, 0xb4, + 0x41, 0xbb, 0xaa, 0x55, 0xcd, 0x13, 0x0f, 0x82, 0xfc, 0x00, 0x81, 0xfb, 0x55, 0xaa, 0x0f, 0x85, + 0xf3, 0x00, 0x68, 0x00, 0x70, 0x07, 0xbf, 0xa8, 0x7d, 0x66, 0x8b, 0x05, 0x66, 0x8b, 0x6d, 0x04, + 0x31, 0xdb, 0x66, 0x31, 0xc9, 0x8b, 0x4d, 0xfc, 0xe8, 0x55, 0x00, 0x0f, 0x82, 0xd5, 0x00, 0x66, + 0x8b, 0x45, 0x08, 0x66, 0x8b, 0x6d, 0x0c, 0x01, 0xcb, 0x8b, 0x4d, 0xfe, 0xe8, 0x41, 0x00, 0x0f, + 0x82, 0xc0, 0x00, 0x0f, 0x01, 0x16, 0x4d, 0x7d, 0xfa, 0x0f, 0x20, 0xc0, 0x0f, 0xba, 0xe8, 0x00, + 0x0f, 0x22, 0xc0, 0xea, 0x79, 0x7d, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0xbe, 0x00, 0x80, 0xc7, 0x04, 0x10, 0x00, 0xc7, 0x44, 0x02, 0x01, 0x00, 0x89, 0x5c, 0x04, + 0x8c, 0x44, 0x06, 0x52, 0x56, 0x66, 0x50, 0x66, 0x55, 0xb4, 0x48, 0xbe, 0x10, 0x80, 0xc7, 0x04, + 0x1e, 0x00, 0xcd, 0x13, 0x72, 0x45, 0x8b, 0x6c, 0x18, 0x89, 0xc8, 0x66, 0xc1, 0xe9, 0x10, 0x89, + 0xca, 0x31, 0xc9, 0xf7, 0xf5, 0x85, 0xd2, 0x0f, 0x95, 0xc1, 0x01, 0xc1, 0x66, 0x5a, 0x66, 0x58, + 0x5e, 0x66, 0xf7, 0xf5, 0x66, 0x89, 0x44, 0x08, 0x66, 0xc7, 0x44, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x5a, 0xb4, 0x42, 0xf8, 0xcd, 0x13, 0x72, 0x13, 0x01, 0x6c, 0x04, 0x66, 0x31, 0xdb, 0x66, 0xff, + 0x44, 0x08, 0x0f, 0x90, 0xc3, 0x66, 0x01, 0x5c, 0x0c, 0xe2, 0xe6, 0x61, 0xc3, 0x17, 0x00, 0x4b, + 0x7d, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x9b, 0xcf, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, + 0x93, 0xcf, 0x00, 0x46, 0x46, 0x46, 0x46, 0x46, 0x81, 0xc6, 0x30, 0x4f, 0x68, 0x00, 0xb8, 0x07, + 0x26, 0x89, 0x36, 0x00, 0x00, 0xfb, 0xf4, 0xeb, 0xfd, 0xb8, 0x10, 0x00, 0x00, 0x00, 0x8e, 0xd8, + 0x8e, 0xc0, 0x8e, 0xe0, 0x8e, 0xe8, 0x8e, 0xd0, 0x81, 0xe2, 0xff, 0x00, 0x00, 0x00, 0x6a, 0x00, + 0x52, 0x68, 0x08, 0x47, 0x00, 0x00, 0x68, 0xa0, 0x0a, 0x07, 0x00, 0xe8, 0x60, 0x82, 0x06, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xaa, + 0xfc, 0x30, 0xc0, 0xbf, 0x91, 0x0a, 0x07, 0x00, 0xb9, 0x91, 0x0a, 0x07, 0x00, 0x81, 0xe9, 0x91, + 0x0a, 0x07, 0x00, 0xf3, 0xaa, 0xe9, 0x00, 0x00, 0x00, 0x00, 0x57, 0x56, 0x0f, 0xb6, 0x74, 0x24, + 0x14, 0x8b, 0x7c, 0x24, 0x18, 0xff, 0x74, 0x24, 0x10, 0xff, 0x74, 0x24, 0x10, 0x68, 0x00, 0xf0, + 0x00, 0x00, 0xe8, 0x14, 0x00, 0x00, 0x00, 0x83, 0xc4, 0x0c, 0xbc, 0x00, 0xf0, 0x00, 0x00, 0x31, + 0xed, 0x57, 0x56, 0x6a, 0x00, 0x68, 0x00, 0xf0, 0x00, 0x00, 0xc3, 0x55, 0x53, 0x57, 0x56, 0x8b, + 0x54, 0x24, 0x1c, 0xb8, 0xfd, 0xff, 0xff, 0xff, 0x83, 0xfa, 0x12, 0x0f, 0x82, 0xa2, 0x00, 0x00, + 0x00, 0x8b, 0x4c, 0x24, 0x18, 0x80, 0x39, 0x1f, 0x0f, 0x85, 0x95, 0x00, 0x00, 0x00, 0x80, 0x79, + 0x01, 0x8b, 0x0f, 0x85, 0x8b, 0x00, 0x00, 0x00, 0x80, 0x79, 0x02, 0x08, 0x0f, 0x85, 0x81, 0x00, + 0x00, 0x00, 0x0f, 0xb6, 0x59, 0x03, 0x83, 0xfb, 0x1f, 0x77, 0x78, 0x8d, 0x71, 0x0a, 0xf6, 0xc3, + 0x04, 0x74, 0x0e, 0x0f, 0xb7, 0x3e, 0x8d, 0x6a, 0xf4, 0x39, 0xfd, 0x72, 0x66, 0x8d, 0x74, 0x3e, + 0x02, 0xf6, 0xc3, 0x08, 0x75, 0x04, 0x89, 0xf7, 0xeb, 0x13, 0x89, 0xf5, 0x29, 0xcd, 0x39, 0xd5, + 0x73, 0x51, 0x8d, 0x7e, 0x01, 0x45, 0x80, 0x3e, 0x00, 0x89, 0xfe, 0x75, 0xf1, 0x80, 0xfb, 0x10, + 0x73, 0x04, 0x89, 0xfd, 0xeb, 0x13, 0x89, 0xfe, 0x29, 0xce, 0x39, 0xd6, 0x73, 0x35, 0x8d, 0x6f, + 0x01, 0x46, 0x80, 0x3f, 0x00, 0x89, 0xef, 0x75, 0xf1, 0x83, 0xe3, 0x02, 0x01, 0xeb, 0x01, 0xd1, + 0x29, 0xd9, 0x83, 0xf9, 0x08, 0x7c, 0x1c, 0x83, 0xc1, 0xf8, 0x51, 0x53, 0xff, 0x74, 0x24, 0x1c, + 0xe8, 0x13, 0x00, 0x00, 0x00, 0x83, 0xc4, 0x0c, 0x31, 0xc9, 0x85, 0xc0, 0x0f, 0x94, 0xc1, 0x8d, + 0x44, 0x49, 0xfd, 0x5e, 0x5f, 0x5b, 0x5d, 0xc3, 0x55, 0x53, 0x57, 0x56, 0x81, 0xec, 0x44, 0x06, + 0x00, 0x00, 0x8b, 0x84, 0x24, 0x58, 0x06, 0x00, 0x00, 0x8b, 0x8c, 0x24, 0x5c, 0x06, 0x00, 0x00, + 0x8d, 0x54, 0x24, 0x3c, 0x89, 0x4a, 0xe4, 0x03, 0x8c, 0x24, 0x60, 0x06, 0x00, 0x00, 0x89, 0x4a, + 0xe8, 0x31, 0xc9, 0x89, 0x4a, 0xec, 0x89, 0x4a, 0xf0, 0x89, 0x4a, 0xf4, 0x89, 0x42, 0xfc, 0x89, + 0x42, 0xf8, 0x8b, 0x54, 0x24, 0x2c, 0x85, 0xd2, 0x7e, 0x0a, 0x8b, 0x44, 0x24, 0x28, 0x89, 0x44, + 0x24, 0x0c, 0xeb, 0x4c, 0x8b, 0x74, 0x24, 0x20, 0x8b, 0x44, 0x24, 0x24, 0x8b, 0x4c, 0x24, 0x28, + 0x89, 0x4c, 0x24, 0x0c, 0x89, 0xd1, 0x39, 0xc6, 0x74, 0x1e, 0x8d, 0x56, 0x01, 0x89, 0x54, 0x24, + 0x20, 0x0f, 0xb6, 0x36, 0xd3, 0xe6, 0x8b, 0x7c, 0x24, 0x0c, 0x09, 0xf7, 0x89, 0x7c, 0x24, 0x0c, + 0x89, 0x7c, 0x24, 0x28, 0x89, 0xd6, 0xeb, 0x0a, 0xc7, 0x44, 0x24, 0x30, 0x01, 0x00, 0x00, 0x00, + 0x89, 0xc6, 0x8d, 0x51, 0x08, 0x89, 0x54, 0x24, 0x2c, 0x83, 0xf9, 0xf9, 0x89, 0xd1, 0x7c, 0xc6, + 0x8b, 0x74, 0x24, 0x0c, 0xd1, 0xee, 0x89, 0x74, 0x24, 0x28, 0x8d, 0x5a, 0xff, 0x89, 0x5c, 0x24, + 0x2c, 0x83, 0xfb, 0x01, 0x77, 0x45, 0x8b, 0x4c, 0x24, 0x20, 0x8b, 0x7c, 0x24, 0x24, 0x83, 0xc2, + 0xf7, 0x8d, 0x5a, 0x08, 0x39, 0xf9, 0x74, 0x18, 0x8d, 0x41, 0x01, 0x89, 0x44, 0x24, 0x20, 0x0f, + 0xb6, 0x29, 0x89, 0xd9, 0xd3, 0xe5, 0x09, 0xee, 0x89, 0x74, 0x24, 0x28, 0x89, 0xc1, 0xeb, 0x0a, + 0xc7, 0x44, 0x24, 0x30, 0x01, 0x00, 0x00, 0x00, 0x89, 0xf9, 0x83, 0xc2, 0x10, 0x89, 0x54, 0x24, + 0x2c, 0x83, 0xfb, 0xfa, 0x89, 0xda, 0x7c, 0xc9, 0x83, 0xc3, 0x08, 0x89, 0xf1, 0xc1, 0xe9, 0x02, + 0x89, 0x4c, 0x24, 0x04, 0x89, 0x4c, 0x24, 0x28, 0x8d, 0x53, 0xfe, 0x89, 0x54, 0x24, 0x2c, 0xb8, + 0xfd, 0xff, 0xff, 0xff, 0x83, 0xe6, 0x03, 0x0f, 0x84, 0x7a, 0x04, 0x00, 0x00, 0x83, 0xfe, 0x02, + 0x0f, 0x84, 0xe6, 0x00, 0x00, 0x00, 0x83, 0xfe, 0x01, 0x8d, 0xb4, 0x24, 0xa0, 0x02, 0x00, 0x00, + 0x0f, 0x85, 0xdf, 0x04, 0x00, 0x00, 0xb8, 0xe0, 0xff, 0xff, 0xff, 0x66, 0xc7, 0x44, 0x04, 0x5c, + 0x00, 0x00, 0x83, 0xc0, 0x02, 0x75, 0xf4, 0xc7, 0x44, 0x24, 0x4a, 0x18, 0x00, 0x98, 0x00, 0x66, + 0xc7, 0x44, 0x24, 0x4e, 0x70, 0x00, 0xb8, 0xe8, 0xff, 0xff, 0xff, 0x8d, 0x88, 0x18, 0x01, 0x00, + 0x00, 0x66, 0x89, 0x8c, 0x44, 0x8c, 0x00, 0x00, 0x00, 0x40, 0x75, 0xef, 0x31, 0xc0, 0x66, 0x89, + 0x84, 0x44, 0x8c, 0x00, 0x00, 0x00, 0x40, 0x3d, 0x90, 0x00, 0x00, 0x00, 0x75, 0xf0, 0xb8, 0xf8, + 0xff, 0xff, 0xff, 0x8d, 0x88, 0x20, 0x01, 0x00, 0x00, 0x66, 0x89, 0x8c, 0x44, 0xbc, 0x01, 0x00, + 0x00, 0x40, 0x75, 0xef, 0xb8, 0x90, 0xff, 0xff, 0xff, 0x8d, 0x88, 0x00, 0x01, 0x00, 0x00, 0x66, + 0x89, 0x8c, 0x44, 0x9c, 0x02, 0x00, 0x00, 0x40, 0x75, 0xef, 0xc7, 0x84, 0x24, 0x9c, 0x02, 0x00, + 0x00, 0x1d, 0x01, 0x00, 0x00, 0xb8, 0xe0, 0xff, 0xff, 0xff, 0x66, 0xc7, 0x84, 0x04, 0xc0, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x83, 0xc0, 0x02, 0x75, 0xf1, 0x66, 0xc7, 0x84, 0x24, 0xaa, 0x02, 0x00, + 0x00, 0x20, 0x00, 0x31, 0xc0, 0x66, 0x89, 0x84, 0x44, 0xc0, 0x02, 0x00, 0x00, 0x40, 0x83, 0xf8, + 0x20, 0x75, 0xf2, 0xc7, 0x84, 0x24, 0x00, 0x05, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x8d, 0x4c, + 0x24, 0x20, 0x8d, 0x54, 0x24, 0x3c, 0x56, 0xe8, 0x7d, 0x04, 0x00, 0x00, 0x83, 0xc4, 0x04, 0x85, + 0xc0, 0x0f, 0x84, 0xe1, 0x03, 0x00, 0x00, 0xe9, 0x09, 0x04, 0x00, 0x00, 0x83, 0xfa, 0x04, 0x77, + 0x4d, 0x8b, 0x4c, 0x24, 0x20, 0x8b, 0x74, 0x24, 0x24, 0x83, 0xc3, 0xf6, 0x8d, 0x53, 0x08, 0x39, + 0xf1, 0x74, 0x20, 0x8d, 0x79, 0x01, 0x89, 0x7c, 0x24, 0x20, 0x0f, 0xb6, 0x01, 0x89, 0xd1, 0xd3, + 0xe0, 0x8b, 0x4c, 0x24, 0x04, 0x09, 0xc1, 0x89, 0x4c, 0x24, 0x04, 0x89, 0x4c, 0x24, 0x28, 0x89, + 0xf9, 0xeb, 0x0a, 0xc7, 0x44, 0x24, 0x30, 0x01, 0x00, 0x00, 0x00, 0x89, 0xf1, 0x83, 0xc3, 0x10, + 0x89, 0x5c, 0x24, 0x2c, 0x83, 0xfa, 0xfd, 0x89, 0xd3, 0x7c, 0xc1, 0x83, 0xc2, 0x08, 0x8b, 0x74, + 0x24, 0x04, 0x89, 0xf3, 0xc1, 0xeb, 0x05, 0x89, 0x5c, 0x24, 0x28, 0x8d, 0x42, 0xfb, 0x89, 0x44, + 0x24, 0x2c, 0x83, 0xf8, 0x04, 0x77, 0x4d, 0x8b, 0x4c, 0x24, 0x20, 0x8b, 0x74, 0x24, 0x24, 0x83, + 0xc2, 0xf3, 0x8d, 0x42, 0x08, 0x39, 0xf1, 0x74, 0x1c, 0x8d, 0x79, 0x01, 0x89, 0x7c, 0x24, 0x20, + 0x89, 0xdd, 0x0f, 0xb6, 0x19, 0x89, 0xc1, 0xd3, 0xe3, 0x09, 0xdd, 0x89, 0xeb, 0x89, 0x6c, 0x24, + 0x28, 0x89, 0xf9, 0xeb, 0x0a, 0xc7, 0x44, 0x24, 0x30, 0x01, 0x00, 0x00, 0x00, 0x89, 0xf1, 0x83, + 0xc2, 0x10, 0x89, 0x54, 0x24, 0x2c, 0x83, 0xf8, 0xfd, 0x89, 0xc2, 0x7c, 0xc5, 0x83, 0xc0, 0x08, + 0x8b, 0x74, 0x24, 0x04, 0x89, 0xd9, 0xc1, 0xe9, 0x05, 0x89, 0x0c, 0x24, 0x89, 0x4c, 0x24, 0x28, + 0x8d, 0x48, 0xfb, 0x89, 0x4c, 0x24, 0x2c, 0x83, 0xf9, 0x03, 0x77, 0x4d, 0x8b, 0x7c, 0x24, 0x20, + 0x8b, 0x74, 0x24, 0x24, 0x83, 0xc0, 0xf3, 0x8d, 0x48, 0x08, 0x39, 0xf7, 0x74, 0x1c, 0x8d, 0x57, + 0x01, 0x89, 0x54, 0x24, 0x20, 0x0f, 0xb6, 0x3f, 0xd3, 0xe7, 0x8b, 0x2c, 0x24, 0x09, 0xfd, 0x89, + 0x2c, 0x24, 0x89, 0x6c, 0x24, 0x28, 0x89, 0xd7, 0xeb, 0x0a, 0xc7, 0x44, 0x24, 0x30, 0x01, 0x00, + 0x00, 0x00, 0x89, 0xf7, 0x83, 0xc0, 0x10, 0x89, 0x44, 0x24, 0x2c, 0x83, 0xf9, 0xfc, 0x89, 0xc8, + 0x7c, 0xc5, 0x83, 0xc1, 0x08, 0x8b, 0x74, 0x24, 0x04, 0x83, 0xe6, 0x1f, 0x8b, 0x04, 0x24, 0xc1, + 0xe8, 0x04, 0x89, 0x44, 0x24, 0x28, 0x83, 0xc1, 0xfc, 0x89, 0x4c, 0x24, 0x2c, 0x83, 0xfe, 0x1d, + 0x0f, 0x87, 0xc3, 0x02, 0x00, 0x00, 0x83, 0xe3, 0x1f, 0x83, 0xfb, 0x1d, 0x0f, 0x87, 0xb7, 0x02, + 0x00, 0x00, 0xc7, 0x44, 0x24, 0x08, 0xfd, 0xff, 0xff, 0xff, 0x81, 0xc6, 0x01, 0x01, 0x00, 0x00, + 0x89, 0x74, 0x24, 0x04, 0x43, 0x89, 0x5c, 0x24, 0x10, 0x83, 0x24, 0x24, 0x0f, 0xba, 0xed, 0xff, + 0xff, 0xff, 0xc6, 0x84, 0x14, 0x17, 0x05, 0x00, 0x00, 0x00, 0x42, 0x75, 0xf5, 0x83, 0x04, 0x24, + 0x03, 0x8b, 0x54, 0x24, 0x20, 0x8b, 0x74, 0x24, 0x24, 0x31, 0xdb, 0x83, 0xf9, 0x02, 0x7f, 0x36, + 0x89, 0xd7, 0x39, 0xf7, 0x74, 0x16, 0x8d, 0x57, 0x01, 0x89, 0x54, 0x24, 0x20, 0x0f, 0xb6, 0x3f, + 0xd3, 0xe7, 0x09, 0xf8, 0x89, 0x44, 0x24, 0x28, 0x89, 0xd7, 0xeb, 0x0a, 0xc7, 0x44, 0x24, 0x30, + 0x01, 0x00, 0x00, 0x00, 0x89, 0xf7, 0x8d, 0x69, 0x08, 0x89, 0x6c, 0x24, 0x2c, 0x83, 0xf9, 0xfb, + 0x89, 0xe9, 0x7c, 0xce, 0xeb, 0x02, 0x89, 0xcd, 0x89, 0xc1, 0xc1, 0xe9, 0x03, 0x89, 0x4c, 0x24, + 0x28, 0x83, 0xc5, 0xfd, 0x89, 0x6c, 0x24, 0x2c, 0x24, 0x07, 0x0f, 0xb6, 0xbb, 0x7e, 0x0a, 0x07, + 0x00, 0x88, 0x84, 0x3c, 0x04, 0x05, 0x00, 0x00, 0x3b, 0x1c, 0x24, 0x8d, 0x5b, 0x01, 0x89, 0xc8, + 0x89, 0xe9, 0x75, 0x97, 0x8d, 0x4c, 0x24, 0x3c, 0x8d, 0x94, 0x24, 0x04, 0x05, 0x00, 0x00, 0x6a, + 0x13, 0xe8, 0xf8, 0x03, 0x00, 0x00, 0x83, 0xc4, 0x04, 0x85, 0xc0, 0x0f, 0x85, 0xf2, 0x01, 0x00, + 0x00, 0x83, 0xbc, 0x24, 0x9c, 0x02, 0x00, 0x00, 0xff, 0x0f, 0x84, 0xf2, 0x01, 0x00, 0x00, 0x8b, + 0x44, 0x24, 0x04, 0x8b, 0x7c, 0x24, 0x10, 0x8d, 0x1c, 0x07, 0x31, 0xf6, 0x89, 0x5c, 0x24, 0x14, + 0x8d, 0x4c, 0x24, 0x20, 0x8d, 0x54, 0x24, 0x3c, 0xe8, 0x6e, 0x03, 0x00, 0x00, 0x3b, 0x84, 0x24, + 0x9c, 0x02, 0x00, 0x00, 0x0f, 0x8f, 0xc7, 0x01, 0x00, 0x00, 0x66, 0x83, 0xf8, 0x12, 0x74, 0x38, + 0x0f, 0xb7, 0xc8, 0xba, 0x03, 0x00, 0x00, 0x00, 0x83, 0xf9, 0x11, 0x74, 0x24, 0x83, 0xf9, 0x10, + 0x0f, 0x85, 0xc0, 0x00, 0x00, 0x00, 0x85, 0xf6, 0x0f, 0x84, 0xa3, 0x01, 0x00, 0x00, 0x8d, 0x84, + 0x24, 0x04, 0x05, 0x00, 0x00, 0x0f, 0xb6, 0x44, 0x06, 0xff, 0xb9, 0x02, 0x00, 0x00, 0x00, 0xeb, + 0x13, 0xb9, 0x03, 0x00, 0x00, 0x00, 0xeb, 0x0a, 0xba, 0x0b, 0x00, 0x00, 0x00, 0xb9, 0x07, 0x00, + 0x00, 0x00, 0x31, 0xc0, 0x89, 0x44, 0x24, 0x1c, 0x8b, 0x5c, 0x24, 0x2c, 0x89, 0x0c, 0x24, 0x39, + 0xcb, 0x89, 0x54, 0x24, 0x18, 0x7d, 0x46, 0x8b, 0x6c, 0x24, 0x20, 0x8b, 0x44, 0x24, 0x24, 0x8b, + 0x7c, 0x24, 0x28, 0x8b, 0x0c, 0x24, 0x39, 0xc5, 0x74, 0x1c, 0x8d, 0x55, 0x01, 0x89, 0x54, 0x24, + 0x20, 0x0f, 0xb6, 0x6d, 0x00, 0x89, 0xd9, 0xd3, 0xe5, 0x09, 0xef, 0x89, 0x7c, 0x24, 0x28, 0x89, + 0xd5, 0x8b, 0x0c, 0x24, 0xeb, 0x0a, 0xc7, 0x44, 0x24, 0x30, 0x01, 0x00, 0x00, 0x00, 0x89, 0xc5, + 0x83, 0xc3, 0x08, 0x89, 0x5c, 0x24, 0x2c, 0x39, 0xcb, 0x7c, 0xcb, 0xeb, 0x07, 0x8b, 0x7c, 0x24, + 0x28, 0x8b, 0x0c, 0x24, 0x31, 0xed, 0x4d, 0xd3, 0xe5, 0xf7, 0xd5, 0x21, 0xfd, 0x03, 0x6c, 0x24, + 0x18, 0xd3, 0xef, 0x89, 0x7c, 0x24, 0x28, 0x29, 0xcb, 0x89, 0x5c, 0x24, 0x2c, 0x8b, 0x5c, 0x24, + 0x14, 0x89, 0xd8, 0x29, 0xf0, 0x39, 0xc5, 0x8b, 0x7c, 0x24, 0x10, 0x8b, 0x44, 0x24, 0x1c, 0x76, + 0x12, 0xe9, 0xeb, 0x00, 0x00, 0x00, 0x39, 0xf3, 0xbd, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x84, 0xde, + 0x00, 0x00, 0x00, 0x88, 0x84, 0x34, 0x04, 0x05, 0x00, 0x00, 0x46, 0x4d, 0x75, 0xf5, 0x39, 0xde, + 0x0f, 0x82, 0xea, 0xfe, 0xff, 0xff, 0x80, 0xbc, 0x24, 0x04, 0x06, 0x00, 0x00, 0x00, 0x0f, 0x84, + 0xbd, 0x00, 0x00, 0x00, 0x8d, 0x4c, 0x24, 0x3c, 0x8d, 0x94, 0x24, 0x04, 0x05, 0x00, 0x00, 0x8b, + 0x74, 0x24, 0x04, 0x56, 0xe8, 0x95, 0x02, 0x00, 0x00, 0x83, 0xc4, 0x04, 0x85, 0xc0, 0x0f, 0x85, + 0x8f, 0x00, 0x00, 0x00, 0x8d, 0x94, 0x34, 0x04, 0x05, 0x00, 0x00, 0x8d, 0xb4, 0x24, 0xa0, 0x02, + 0x00, 0x00, 0x89, 0xf1, 0x57, 0xe8, 0x74, 0x02, 0x00, 0x00, 0x83, 0xc4, 0x04, 0x85, 0xc0, 0x0f, + 0x84, 0x59, 0xfc, 0xff, 0xff, 0xeb, 0x7e, 0x8b, 0x4c, 0x24, 0x20, 0x8b, 0x54, 0x24, 0x24, 0x29, + 0xca, 0x83, 0xfa, 0x04, 0x7c, 0x6f, 0x0f, 0xb7, 0x19, 0x0f, 0xb7, 0x51, 0x02, 0x66, 0x31, 0xda, + 0x66, 0x83, 0xfa, 0xff, 0x75, 0x5f, 0x83, 0xc1, 0x04, 0x89, 0x4c, 0x24, 0x20, 0x85, 0xdb, 0x74, + 0x1d, 0x8b, 0x4c, 0x24, 0x20, 0x8b, 0x54, 0x24, 0x38, 0x8d, 0x71, 0x01, 0x8d, 0x7a, 0x01, 0x4b, + 0x89, 0x74, 0x24, 0x20, 0x8a, 0x09, 0x89, 0x7c, 0x24, 0x38, 0x88, 0x0a, 0x75, 0xe3, 0x31, 0xc0, + 0x89, 0x44, 0x24, 0x28, 0x89, 0x44, 0x24, 0x2c, 0xf6, 0x44, 0x24, 0x0c, 0x01, 0x0f, 0x84, 0x4f, + 0xfa, 0xff, 0xff, 0x31, 0xc0, 0x83, 0x7c, 0x24, 0x30, 0x00, 0x0f, 0x94, 0xc0, 0x8d, 0x44, 0x40, + 0xfd, 0xeb, 0x12, 0x89, 0x44, 0x24, 0x08, 0xeb, 0x08, 0xc7, 0x44, 0x24, 0x08, 0xfd, 0xff, 0xff, + 0xff, 0x8b, 0x44, 0x24, 0x08, 0x81, 0xc4, 0x44, 0x06, 0x00, 0x00, 0x5e, 0x5f, 0x5b, 0x5d, 0xc3, + 0x55, 0x53, 0x57, 0x56, 0x89, 0xce, 0x8b, 0x59, 0x0c, 0x39, 0xd3, 0x7d, 0x2f, 0x8b, 0x0e, 0x8b, + 0x46, 0x04, 0x39, 0xc1, 0x74, 0x13, 0x8d, 0x79, 0x01, 0x89, 0x3e, 0x0f, 0xb6, 0x29, 0x89, 0xd9, + 0xd3, 0xe5, 0x09, 0x6e, 0x08, 0x89, 0xf9, 0xeb, 0x09, 0xc7, 0x46, 0x10, 0x01, 0x00, 0x00, 0x00, + 0x89, 0xc1, 0x83, 0xc3, 0x08, 0x89, 0x5e, 0x0c, 0x39, 0xd3, 0x7c, 0xd6, 0x8b, 0x7e, 0x08, 0x31, + 0xc0, 0x48, 0x89, 0xd1, 0xd3, 0xe0, 0xf7, 0xd0, 0x21, 0xf8, 0xd3, 0xef, 0x89, 0x7e, 0x08, 0x29, + 0xd3, 0x89, 0x5e, 0x0c, 0x5e, 0x5f, 0x5b, 0x5d, 0xc3, 0x55, 0x53, 0x57, 0x56, 0x83, 0xec, 0x08, + 0x89, 0xd5, 0x89, 0xcf, 0xe8, 0x22, 0x01, 0x00, 0x00, 0xb9, 0xfd, 0xff, 0xff, 0xff, 0x83, 0x7f, + 0x10, 0x00, 0x0f, 0x85, 0x05, 0x01, 0x00, 0x00, 0x8b, 0x74, 0x24, 0x1c, 0x89, 0x2c, 0x24, 0x3d, + 0xff, 0x00, 0x00, 0x00, 0x77, 0x10, 0x8b, 0x4f, 0x18, 0x8d, 0x51, 0x01, 0x89, 0x57, 0x18, 0x88, + 0x01, 0xe9, 0xcf, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x01, 0x00, 0x00, 0x0f, 0x84, 0xe6, 0x00, 0x00, + 0x00, 0x3b, 0x85, 0x60, 0x02, 0x00, 0x00, 0x0f, 0x8f, 0xcb, 0x00, 0x00, 0x00, 0x3d, 0x1d, 0x01, + 0x00, 0x00, 0x0f, 0x87, 0xc0, 0x00, 0x00, 0x00, 0x83, 0xbe, 0x60, 0x02, 0x00, 0x00, 0xff, 0x0f, + 0x84, 0xb3, 0x00, 0x00, 0x00, 0x0f, 0xb7, 0x8c, 0x00, 0xe6, 0x07, 0x07, 0x00, 0x89, 0x4c, 0x24, + 0x04, 0x05, 0xff, 0xfe, 0xff, 0xff, 0x31, 0xf6, 0xb9, 0xff, 0x00, 0x00, 0x10, 0x0f, 0xa3, 0xc1, + 0x72, 0x10, 0x0f, 0xb6, 0x90, 0xca, 0x09, 0x07, 0x00, 0x89, 0xf9, 0xe8, 0x10, 0xff, 0xff, 0xff, + 0x89, 0xc6, 0x89, 0xf9, 0x8b, 0x5c, 0x24, 0x1c, 0x89, 0xda, 0xe8, 0x8c, 0x00, 0x00, 0x00, 0x83, + 0xf8, 0x1d, 0x77, 0x74, 0x89, 0xc1, 0x3b, 0x83, 0x60, 0x02, 0x00, 0x00, 0x7f, 0x6a, 0x0f, 0xb7, + 0xac, 0x09, 0x42, 0x0a, 0x07, 0x00, 0x31, 0xc0, 0x83, 0xf9, 0x04, 0x72, 0x0e, 0x0f, 0xb6, 0x91, + 0x24, 0x0a, 0x07, 0x00, 0x89, 0xf9, 0xe8, 0xd5, 0xfe, 0xff, 0xff, 0x01, 0xe8, 0x8b, 0x4f, 0x18, + 0x89, 0xca, 0x2b, 0x57, 0x14, 0x39, 0xd0, 0x7f, 0x3f, 0x03, 0x74, 0x24, 0x04, 0x85, 0xf6, 0x7e, + 0x18, 0xf7, 0xd8, 0x31, 0xc9, 0x8b, 0x57, 0x18, 0x8d, 0x2c, 0x0a, 0x8a, 0x1c, 0x28, 0x88, 0x1c, + 0x0a, 0x41, 0x39, 0xce, 0x75, 0xef, 0x8b, 0x4f, 0x18, 0x01, 0xf1, 0x89, 0x4f, 0x18, 0x8b, 0x2c, + 0x24, 0x8b, 0x74, 0x24, 0x1c, 0x89, 0xf9, 0x89, 0xea, 0xe8, 0x1d, 0x00, 0x00, 0x00, 0x83, 0x7f, + 0x10, 0x00, 0x0f, 0x84, 0x07, 0xff, 0xff, 0xff, 0xb9, 0xfd, 0xff, 0xff, 0xff, 0x89, 0xc8, 0x83, + 0xc4, 0x08, 0x5e, 0x5f, 0x5b, 0x5d, 0xc3, 0x31, 0xc9, 0xeb, 0xf2, 0x55, 0x53, 0x57, 0x56, 0x50, + 0x89, 0xd5, 0x89, 0xcb, 0x31, 0xd2, 0x42, 0xe8, 0x64, 0xfe, 0xff, 0xff, 0x89, 0xc7, 0x0f, 0xb7, + 0x45, 0x02, 0x31, 0xf6, 0x39, 0xc7, 0x89, 0x2c, 0x24, 0x7c, 0x21, 0x83, 0xc5, 0x04, 0x31, 0xf6, + 0x01, 0xc6, 0x29, 0xc7, 0x89, 0xd9, 0x31, 0xd2, 0x42, 0xe8, 0x42, 0xfe, 0xff, 0xff, 0x8d, 0x3c, + 0x78, 0x0f, 0xb7, 0x45, 0x00, 0x83, 0xc5, 0x02, 0x39, 0xc7, 0x7d, 0xe4, 0x01, 0xfe, 0x8b, 0x04, + 0x24, 0x0f, 0xb7, 0x44, 0x70, 0x20, 0x83, 0xc4, 0x04, 0x5e, 0x5f, 0x5b, 0x5d, 0xc3, 0x55, 0x53, + 0x57, 0x56, 0x83, 0xec, 0x20, 0x8b, 0x7c, 0x24, 0x34, 0xb8, 0xe0, 0xff, 0xff, 0xff, 0x66, 0xc7, + 0x44, 0x01, 0x20, 0x00, 0x00, 0x83, 0xc0, 0x02, 0x75, 0xf4, 0xc7, 0x81, 0x60, 0x02, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x85, 0xff, 0x74, 0x1b, 0x31, 0xc0, 0x80, 0x3c, 0x02, 0x00, 0x74, 0x0e, + 0x89, 0x81, 0x60, 0x02, 0x00, 0x00, 0x0f, 0xb6, 0x34, 0x02, 0x66, 0xff, 0x04, 0x71, 0x40, 0x39, + 0xc7, 0x75, 0xe7, 0x31, 0xff, 0x31, 0xdb, 0x43, 0xbd, 0xe0, 0xff, 0xff, 0xff, 0xb8, 0xfd, 0xff, + 0xff, 0xff, 0x0f, 0xb7, 0x74, 0x29, 0x20, 0x29, 0xf3, 0x72, 0x66, 0x01, 0xdb, 0x66, 0x89, 0x7c, + 0x2c, 0x20, 0x01, 0xf7, 0x83, 0xc5, 0x02, 0x75, 0xe9, 0x83, 0xff, 0x02, 0x72, 0x04, 0x85, 0xdb, + 0x75, 0x4f, 0x83, 0xff, 0x01, 0x75, 0x07, 0x66, 0x83, 0x79, 0x02, 0x01, 0x75, 0x43, 0x8b, 0x5c, + 0x24, 0x34, 0x85, 0xdb, 0x74, 0x23, 0x31, 0xc0, 0x0f, 0xb6, 0x34, 0x02, 0x85, 0xf6, 0x74, 0x14, + 0x0f, 0xb7, 0x1c, 0x74, 0x8d, 0x6b, 0x01, 0x66, 0x89, 0x2c, 0x74, 0x66, 0x89, 0x44, 0x59, 0x20, + 0x8b, 0x5c, 0x24, 0x34, 0x40, 0x39, 0xc3, 0x75, 0xdf, 0x31, 0xc0, 0x83, 0xff, 0x01, 0x75, 0x11, + 0x66, 0xc7, 0x41, 0x02, 0x02, 0x00, 0x8b, 0x91, 0x60, 0x02, 0x00, 0x00, 0x42, 0x66, 0x89, 0x51, + 0x22, 0x83, 0xc4, 0x20, 0x5e, 0x5f, 0x5b, 0x5d, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, + 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x00, 0x7f, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, + 0x07, 0x00, 0x08, 0x00, 0x09, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x0d, 0x00, 0x0f, 0x00, 0x11, 0x00, + 0x13, 0x00, 0x17, 0x00, 0x1b, 0x00, 0x1f, 0x00, 0x23, 0x00, 0x2b, 0x00, 0x33, 0x00, 0x3b, 0x00, + 0x43, 0x00, 0x53, 0x00, 0x63, 0x00, 0x73, 0x00, 0x83, 0x00, 0xa3, 0x00, 0xc3, 0x00, 0xe3, 0x00, + 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, + 0x05, 0x05, 0x06, 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0b, 0x0b, 0x0c, 0x0c, + 0x0d, 0x0d, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x07, 0x00, 0x09, 0x00, + 0x0d, 0x00, 0x11, 0x00, 0x19, 0x00, 0x21, 0x00, 0x31, 0x00, 0x41, 0x00, 0x61, 0x00, 0x81, 0x00, + 0xc1, 0x00, 0x01, 0x01, 0x81, 0x01, 0x01, 0x02, 0x01, 0x03, 0x01, 0x04, 0x01, 0x06, 0x01, 0x08, + 0x01, 0x0c, 0x01, 0x10, 0x01, 0x18, 0x01, 0x20, 0x01, 0x30, 0x01, 0x40, 0x01, 0x60, 0x10, 0x11, + 0x12, 0x00, 0x08, 0x07, 0x09, 0x06, 0x0a, 0x05, 0x0b, 0x04, 0x0c, 0x03, 0x0d, 0x02, 0x0e, 0x01, + 0x0f, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x95, 0xbd, 0x09, 0x58, 0x14, 0x57, + 0xb6, 0x38, 0x5e, 0x05, 0x0d, 0x36, 0xd8, 0x5a, 0x8d, 0x12, 0x03, 0x8a, 0xda, 0x1a, 0x4c, 0x64, + 0xe2, 0x28, 0x1d, 0x8d, 0x11, 0x97, 0x84, 0xad, 0x40, 0x8d, 0xad, 0x0d, 0x6d, 0x37, 0x4e, 0x12, + 0x62, 0x88, 0x80, 0x0d, 0x51, 0x21, 0x74, 0x97, 0x4b, 0x22, 0xa6, 0xb1, 0xe8, 0x84, 0x4b, 0xa5, + 0x9c, 0x4c, 0x96, 0x79, 0x99, 0x79, 0x93, 0x37, 0xc9, 0x8b, 0x99, 0xc9, 0x2c, 0x79, 0x3a, 0x4b, + 0x14, 0x13, 0x97, 0x6e, 0xf0, 0x01, 0x2e, 0xa3, 0xa0, 0x8e, 0xe2, 0xf2, 0x0c, 0x26, 0x4c, 0x52, + 0xa4, 0x79, 0x49, 0x03, 0x0e, 0x20, 0x1a, 0xfa, 0x7f, 0xce, 0xad, 0x6e, 0x81, 0xcc, 0xcc, 0xfb, + 0x7d, 0x7f, 0xbf, 0x14, 0x5d, 0x77, 0x3b, 0xf7, 0xdc, 0xb3, 0xdd, 0x73, 0xee, 0x52, 0xb9, 0x93, + 0xec, 0x39, 0xa6, 0x70, 0x1a, 0xe6, 0xd0, 0xdb, 0x9b, 0x34, 0x4c, 0x55, 0x27, 0xbe, 0xf6, 0xfe, + 0x96, 0x63, 0xef, 0xf9, 0x9d, 0x9f, 0x61, 0xbe, 0xbe, 0x0f, 0xfe, 0xc4, 0x31, 0x75, 0x06, 0x86, + 0x61, 0xf6, 0xb4, 0xed, 0xf1, 0xec, 0x69, 0xdf, 0xa3, 0xec, 0x69, 0xe9, 0x7c, 0x48, 0xcf, 0x30, + 0xa7, 0x43, 0xff, 0xac, 0xe4, 0x6f, 0x36, 0xb1, 0x2b, 0x92, 0x5c, 0x2c, 0x6e, 0xe2, 0xfb, 0x02, + 0xe1, 0x4d, 0xfc, 0x00, 0x54, 0x66, 0x64, 0xbe, 0x8f, 0x9c, 0x1c, 0xbc, 0x73, 0x98, 0xd9, 0xc9, + 0x30, 0xc7, 0xf0, 0xcf, 0x21, 0x26, 0x8c, 0x61, 0x7a, 0xf7, 0x72, 0x6c, 0x5c, 0xa9, 0xd6, 0xbe, + 0x03, 0xc0, 0x9e, 0xaa, 0xd3, 0x8f, 0x80, 0xc9, 0x19, 0x3c, 0x89, 0x43, 0xdc, 0x4c, 0x4f, 0x71, + 0xdd, 0xdb, 0x50, 0x56, 0xca, 0x98, 0x4f, 0x19, 0x3d, 0xc3, 0xa5, 0xb7, 0x4b, 0x19, 0x3b, 0xb3, + 0xf3, 0xd4, 0x23, 0x0c, 0xf3, 0x14, 0x8b, 0xd0, 0x99, 0x00, 0xe3, 0x7a, 0x4e, 0xa3, 0xe2, 0xc0, + 0xb1, 0x53, 0x07, 0x11, 0xd5, 0x33, 0xf0, 0x47, 0xcb, 0x7c, 0x1f, 0x28, 0xf7, 0x89, 0x9f, 0x01, + 0xb0, 0x5f, 0x7f, 0x0d, 0xa5, 0xa3, 0x20, 0xde, 0xf4, 0x7d, 0x17, 0x08, 0x47, 0x50, 0xb5, 0x99, + 0x89, 0x9a, 0xff, 0x14, 0xbb, 0x19, 0x46, 0xca, 0x4c, 0xd4, 0xbe, 0x7f, 0x53, 0x7d, 0xd1, 0xbd, + 0x3f, 0x00, 0x2f, 0x1c, 0x1b, 0x71, 0x87, 0xfe, 0x8c, 0xd3, 0xf4, 0xe0, 0xcf, 0x54, 0x1d, 0xfc, + 0x58, 0x6c, 0x79, 0xd6, 0xaf, 0x97, 0x74, 0xff, 0xb3, 0xce, 0xe8, 0x08, 0xbe, 0xb6, 0x76, 0xd3, + 0xae, 0x5a, 0x16, 0x16, 0x93, 0xfb, 0xfd, 0xdd, 0x0b, 0x8b, 0xa5, 0xfb, 0x07, 0xba, 0xb9, 0xdf, + 0x70, 0xef, 0x8d, 0x99, 0x5e, 0xfc, 0x4e, 0x71, 0x7e, 0xf1, 0xfa, 0xe2, 0xa7, 0x8b, 0x9f, 0x28, + 0xfe, 0x51, 0xf1, 0x93, 0xc5, 0xeb, 0xb0, 0xcc, 0xdf, 0x7d, 0xfb, 0x2f, 0xcc, 0xe0, 0x70, 0xdd, + 0x9b, 0xdd, 0xc5, 0x1b, 0xe5, 0xc2, 0xc4, 0xd9, 0xc5, 0xe6, 0x62, 0x4b, 0x71, 0x4e, 0x71, 0x6e, + 0xb1, 0xad, 0x38, 0xaf, 0xd8, 0x5a, 0xfc, 0x8b, 0x69, 0x91, 0xdc, 0xbb, 0xdc, 0x87, 0x6a, 0x8b, + 0x85, 0xc5, 0x1c, 0x3b, 0xe9, 0x0e, 0xfd, 0x99, 0xa6, 0xe9, 0x81, 0x8e, 0x75, 0x2c, 0x76, 0x7c, + 0xa6, 0x3b, 0x8e, 0x29, 0x06, 0x5e, 0x0d, 0xe3, 0x94, 0xbf, 0xfe, 0xe9, 0x27, 0x1b, 0x5e, 0x1b, + 0xfd, 0x8f, 0xf9, 0x3f, 0xfe, 0xa9, 0x14, 0x09, 0xfd, 0xfb, 0xc5, 0xdc, 0xe2, 0x40, 0xe4, 0x84, + 0x9e, 0x77, 0xe6, 0x06, 0xe6, 0x4e, 0xea, 0x91, 0xee, 0x41, 0x21, 0x20, 0xf7, 0x4c, 0x02, 0x12, + 0x34, 0x45, 0xe0, 0xfb, 0x64, 0x78, 0x93, 0xd6, 0x26, 0x6a, 0x9a, 0x22, 0x26, 0xf4, 0xa8, 0x0d, + 0x80, 0x5e, 0x8b, 0x7a, 0x29, 0xbd, 0x52, 0xe9, 0xcf, 0xd4, 0xe5, 0xbd, 0x41, 0x7a, 0x3d, 0xd7, + 0xf3, 0xaf, 0xe9, 0xe5, 0xee, 0xf9, 0x1e, 0x6b, 0x1a, 0x23, 0x57, 0xf7, 0x32, 0x8d, 0x91, 0xb9, + 0xf8, 0xc7, 0xd6, 0xcb, 0x14, 0xa7, 0x4c, 0x9a, 0xd0, 0xe3, 0x9c, 0x8b, 0xc4, 0xf8, 0x33, 0x9b, + 0xec, 0xf9, 0xcb, 0x24, 0x24, 0x9f, 0xb3, 0xd3, 0x08, 0x6f, 0xff, 0x99, 0xdb, 0x5b, 0x73, 0xbf, + 0xad, 0xb7, 0x8e, 0x09, 0xfb, 0xcb, 0xa4, 0x0f, 0x35, 0xce, 0x68, 0x6c, 0xa9, 0x71, 0x41, 0xcb, + 0x67, 0x06, 0x29, 0x8d, 0x16, 0xf5, 0x52, 0x1a, 0xa5, 0xf6, 0x72, 0x86, 0x06, 0xd7, 0x29, 0x20, + 0x52, 0xc3, 0xd7, 0xbd, 0x3d, 0x40, 0xa4, 0x4f, 0x81, 0x48, 0x57, 0xf7, 0x34, 0xec, 0xf9, 0x62, + 0x8f, 0x6f, 0xcf, 0x79, 0x24, 0x92, 0x44, 0xc7, 0x45, 0xe8, 0x18, 0x5d, 0xcb, 0xa0, 0x53, 0x86, + 0x71, 0x4e, 0x09, 0x3c, 0x0c, 0x78, 0x30, 0x81, 0x87, 0x73, 0xe9, 0x5f, 0xcc, 0x54, 0xb8, 0x64, + 0x96, 0x11, 0x8f, 0xeb, 0x1a, 0x8c, 0x9e, 0x86, 0xff, 0x9b, 0x76, 0xf8, 0x4f, 0xd5, 0x0f, 0x90, + 0x26, 0xcd, 0xfb, 0xcc, 0x4d, 0x86, 0x69, 0x00, 0xf2, 0x68, 0x6e, 0x52, 0xf2, 0xe8, 0xe8, 0xcf, + 0xd4, 0xd8, 0x9b, 0x2a, 0x79, 0xe4, 0x4d, 0x89, 0xb1, 0x5f, 0xef, 0xe9, 0xfd, 0xd7, 0x24, 0xfa, + 0xb0, 0x57, 0x15, 0xa9, 0x50, 0xd1, 0xed, 0xc0, 0x56, 0x4d, 0x60, 0xab, 0x36, 0xb0, 0x95, 0x09, + 0x4c, 0x63, 0x6e, 0x8a, 0xc7, 0x23, 0x07, 0xe7, 0xe2, 0x70, 0x35, 0x37, 0xf1, 0x67, 0x9a, 0xee, + 0xe6, 0xf0, 0x70, 0x3f, 0xef, 0xfd, 0xfe, 0x70, 0x67, 0x05, 0x02, 0x0c, 0x33, 0x42, 0x30, 0xfe, + 0xb5, 0x1c, 0x80, 0x66, 0x5b, 0xf2, 0x6c, 0x62, 0xc7, 0x80, 0xd8, 0x15, 0x27, 0xf1, 0x3a, 0xc9, + 0x14, 0x4b, 0xce, 0x78, 0xbf, 0x99, 0x4e, 0x4e, 0x7a, 0x07, 0xa7, 0x1b, 0x5b, 0xe7, 0x5b, 0xf5, + 0x6c, 0x8f, 0xd8, 0xca, 0x90, 0x46, 0xcc, 0xeb, 0x27, 0xce, 0x44, 0x0d, 0xbc, 0x0e, 0x4d, 0x37, + 0xfa, 0xa5, 0x7c, 0xad, 0xb1, 0x97, 0xbd, 0x2d, 0xb6, 0x30, 0xf2, 0xce, 0x44, 0x6d, 0x5e, 0x4e, + 0xae, 0xd9, 0xa2, 0x2c, 0x06, 0xbd, 0x15, 0x8f, 0xc7, 0xca, 0xa0, 0x63, 0x92, 0x59, 0x63, 0xec, + 0x99, 0x9f, 0x1c, 0x0e, 0x0d, 0xc4, 0x73, 0x0c, 0xf1, 0xcb, 0x45, 0x37, 0x9f, 0x5e, 0xff, 0x64, + 0x7e, 0x43, 0xb0, 0xbb, 0x2e, 0x9d, 0x64, 0x8d, 0xe5, 0x8e, 0x98, 0xf4, 0x75, 0x8f, 0xa1, 0x48, + 0x65, 0x36, 0x8b, 0xdd, 0xd3, 0x45, 0xaf, 0x81, 0x3b, 0x72, 0x45, 0xec, 0x9d, 0xee, 0x3e, 0xc7, + 0x65, 0x5e, 0x86, 0x42, 0xed, 0xdd, 0x7c, 0x40, 0x8c, 0x3b, 0xd2, 0x22, 0xf6, 0x4c, 0x77, 0x7b, + 0xb8, 0xcc, 0x56, 0x72, 0x3d, 0xe9, 0xa2, 0xf1, 0x04, 0xe9, 0x17, 0x87, 0x1e, 0x3b, 0x4a, 0x25, + 0xf2, 0x95, 0x8f, 0xe1, 0xaf, 0xa0, 0x95, 0x4c, 0xda, 0xce, 0xdf, 0xa0, 0xfc, 0x56, 0xfa, 0x25, + 0x93, 0x7f, 0xc8, 0x2b, 0x55, 0x6a, 0xc9, 0x10, 0xf7, 0x51, 0x23, 0xb1, 0x76, 0x91, 0xfa, 0xf3, + 0x5f, 0xf7, 0x01, 0x7c, 0xbe, 0xe7, 0x10, 0x6d, 0xc1, 0xb7, 0x42, 0x0d, 0x57, 0xf7, 0x63, 0xc4, + 0x84, 0x55, 0xb9, 0x0f, 0x06, 0xe0, 0xef, 0xf9, 0xaf, 0xc8, 0xad, 0x3e, 0xde, 0x0f, 0x95, 0x9a, + 0x9a, 0x78, 0x05, 0xab, 0x1d, 0x53, 0xeb, 0x9e, 0xed, 0x3f, 0x1f, 0x9e, 0xdf, 0x45, 0x3e, 0x33, + 0x5e, 0x25, 0x95, 0x5d, 0xdc, 0xde, 0x1e, 0x96, 0xdb, 0xdb, 0x08, 0x4f, 0x33, 0x3b, 0x96, 0x57, + 0xd8, 0x13, 0x51, 0x97, 0x01, 0x08, 0x69, 0xed, 0x6f, 0x25, 0xbd, 0xfd, 0xe7, 0xa5, 0x4a, 0x3d, + 0x7b, 0x5b, 0xaa, 0x8c, 0x8d, 0xb9, 0x45, 0x4e, 0x79, 0x7d, 0xd3, 0xbd, 0xb7, 0xa6, 0x93, 0xb3, + 0xf7, 0x55, 0xc6, 0xde, 0x67, 0xd2, 0x27, 0x9d, 0x81, 0x2e, 0xe2, 0x07, 0xa5, 0xca, 0xae, 0x6c, + 0xa1, 0x0e, 0x1b, 0xcb, 0xba, 0xc7, 0x49, 0x23, 0x69, 0x26, 0x3d, 0x20, 0x6a, 0xa3, 0x48, 0xa3, + 0x95, 0xf8, 0x58, 0x80, 0x23, 0x59, 0x75, 0x40, 0x63, 0x49, 0x88, 0x73, 0x9f, 0x73, 0xfe, 0xc0, + 0x1d, 0x70, 0xa6, 0xba, 0x3d, 0xce, 0xe7, 0xb8, 0x23, 0x1e, 0xd1, 0x3f, 0x9d, 0x3b, 0x72, 0x12, + 0xe8, 0x92, 0xd4, 0x2c, 0x0e, 0x18, 0xb8, 0xdd, 0x1f, 0x02, 0x8e, 0xee, 0x3e, 0x67, 0x1c, 0x99, + 0x46, 0x6c, 0x1a, 0x5f, 0x0c, 0xd4, 0xda, 0x06, 0xc9, 0x28, 0x32, 0xad, 0x29, 0x4b, 0x83, 0xf8, + 0x1b, 0xaf, 0x1a, 0xcf, 0x75, 0x7e, 0x0c, 0x9c, 0x01, 0xda, 0x55, 0xef, 0xc7, 0xca, 0x57, 0xb9, + 0xea, 0xcb, 0x68, 0xbd, 0x97, 0x07, 0xdc, 0xcd, 0x9c, 0xfb, 0x1b, 0xb5, 0xfd, 0x98, 0x19, 0xad, + 0x00, 0x61, 0xb5, 0x86, 0x3b, 0xdc, 0x7c, 0xfe, 0x6b, 0x72, 0xde, 0x77, 0x52, 0x5e, 0x13, 0x70, + 0x9f, 0xe5, 0xdc, 0xa2, 0x5a, 0x3c, 0x76, 0xc6, 0x65, 0x32, 0x3e, 0x08, 0x51, 0x0c, 0xb0, 0x5c, + 0xf5, 0x06, 0x80, 0xc8, 0x1d, 0x3e, 0x4b, 0x2e, 0x9e, 0xff, 0x9a, 0xfb, 0xa8, 0xb7, 0x73, 0x2d, + 0x24, 0x49, 0x9b, 0xf1, 0x5c, 0x7f, 0x3f, 0x69, 0x35, 0x9e, 0x73, 0xf7, 0x91, 0x06, 0xae, 0x3a, + 0x15, 0xf3, 0x42, 0x8d, 0x3a, 0x1f, 0xc2, 0x94, 0x37, 0xb5, 0x89, 0xef, 0xa2, 0x30, 0x06, 0x0c, + 0xce, 0x55, 0xae, 0xee, 0xe9, 0x48, 0xbb, 0xeb, 0x48, 0xfc, 0x2f, 0xc9, 0x25, 0xe2, 0x3d, 0xff, + 0x2d, 0xbe, 0x7e, 0x4e, 0x78, 0x3f, 0xbc, 0xfb, 0xa2, 0xae, 0x74, 0xfe, 0x18, 0x5b, 0xe2, 0x5c, + 0xc3, 0x1d, 0x69, 0x1a, 0x39, 0x70, 0xcf, 0x8c, 0x61, 0x38, 0x9c, 0xfb, 0x06, 0xbc, 0x34, 0x01, + 0xe7, 0x70, 0xb4, 0x01, 0xdf, 0x33, 0xc4, 0x4b, 0x5a, 0x00, 0x93, 0x6e, 0xd2, 0xe0, 0xee, 0xe3, + 0xaa, 0x87, 0x86, 0x02, 0x01, 0xa0, 0x4c, 0x53, 0x24, 0xc5, 0xc2, 0x0f, 0xa9, 0xef, 0x13, 0x71, + 0x3a, 0x27, 0x7e, 0x0a, 0xd9, 0xf2, 0x72, 0x16, 0xb0, 0x59, 0x30, 0x9d, 0x5c, 0x87, 0xce, 0x01, + 0x1d, 0x44, 0xe5, 0x5b, 0x78, 0xfd, 0x1c, 0x5f, 0x00, 0x99, 0x60, 0x8f, 0xa4, 0xd7, 0x78, 0x42, + 0x12, 0xfc, 0x12, 0xdf, 0x45, 0x04, 0x3f, 0xb7, 0xf7, 0x12, 0x48, 0xc2, 0x15, 0x78, 0x1a, 0x58, + 0x92, 0xdf, 0xc5, 0x7a, 0xa2, 0x9a, 0xc9, 0x45, 0x32, 0xd8, 0x7f, 0x8e, 0x74, 0xf7, 0xb7, 0x4a, + 0xf9, 0x7a, 0xf6, 0x32, 0x28, 0x54, 0xcc, 0x49, 0xd2, 0xea, 0xed, 0x9c, 0x0e, 0x0a, 0x45, 0xce, + 0xdf, 0x97, 0x1f, 0x7b, 0x9f, 0x55, 0x9f, 0x74, 0x91, 0xf4, 0x00, 0x8c, 0xf8, 0xcf, 0xa4, 0xfc, + 0xae, 0xd5, 0xc2, 0x41, 0x6c, 0xcd, 0x7a, 0x90, 0xd5, 0x7d, 0xce, 0x08, 0x32, 0x89, 0xec, 0xd2, + 0x88, 0xed, 0x43, 0x51, 0x5e, 0x72, 0x85, 0x9c, 0x22, 0x6d, 0xe2, 0x71, 0x2d, 0x15, 0x0f, 0x4a, + 0x14, 0x47, 0x42, 0xdf, 0x65, 0xe8, 0xe0, 0x0a, 0xd0, 0xa8, 0x1f, 0xc9, 0x05, 0xa4, 0x27, 0x97, + 0xc9, 0x79, 0x72, 0xb2, 0x73, 0x63, 0x00, 0x86, 0xd9, 0x08, 0xa5, 0x6d, 0xe7, 0xdb, 0x09, 0xe0, + 0x06, 0x95, 0x5d, 0xde, 0x76, 0xee, 0xa3, 0xf3, 0x50, 0xed, 0xeb, 0xce, 0xbf, 0xc1, 0xf8, 0x42, + 0xf2, 0xa5, 0xff, 0xff, 0xa7, 0x7a, 0x02, 0xa8, 0xde, 0x90, 0xd8, 0x3f, 0x1d, 0x68, 0x99, 0x79, + 0x8b, 0x5c, 0x4e, 0xba, 0x25, 0xde, 0x7a, 0x6c, 0x6b, 0xb4, 0xc4, 0x6b, 0x49, 0x4f, 0x27, 0xca, + 0x9e, 0xd1, 0x03, 0x19, 0x9f, 0x50, 0x4d, 0xa9, 0x7e, 0x1b, 0xe9, 0x93, 0xef, 0x27, 0xa7, 0x86, + 0xbc, 0xa4, 0x52, 0x41, 0xfd, 0x1b, 0xe0, 0x3e, 0xf2, 0x93, 0x9e, 0xa0, 0xf2, 0xd5, 0x87, 0x94, + 0xcf, 0xd5, 0xfb, 0x18, 0xb9, 0xcc, 0x7d, 0x30, 0x74, 0xfe, 0x2b, 0xa0, 0x6d, 0x5f, 0x03, 0x14, + 0xf5, 0x37, 0xf1, 0x1d, 0x58, 0xf8, 0xa9, 0x5a, 0xe3, 0x36, 0x68, 0x5a, 0x7f, 0x6b, 0xb8, 0x49, + 0x01, 0x9d, 0x03, 0xfd, 0xdc, 0x5b, 0x0f, 0x14, 0xf6, 0xb3, 0x92, 0x09, 0xd4, 0xef, 0x0c, 0x3b, + 0x56, 0xe8, 0x50, 0xd5, 0xae, 0x8b, 0xaa, 0x5d, 0xc3, 0xff, 0xa9, 0x76, 0xcd, 0x54, 0xed, 0xd2, + 0x84, 0x3a, 0xf1, 0xb8, 0x7e, 0x94, 0x9a, 0x2d, 0x92, 0x2a, 0xc1, 0xe0, 0x69, 0xa5, 0xd4, 0x58, + 0x6e, 0x5f, 0xd3, 0x32, 0xd6, 0x05, 0xdd, 0x8a, 0x88, 0x1f, 0x50, 0x47, 0x12, 0xf4, 0xef, 0xa1, + 0x8b, 0xe4, 0xf6, 0x08, 0x93, 0xec, 0x0c, 0x94, 0x90, 0xf3, 0xca, 0x2b, 0xcb, 0xe0, 0xe7, 0x8a, + 0x78, 0x5c, 0xf3, 0x3e, 0x96, 0xc8, 0xf9, 0x1d, 0xc5, 0x4d, 0xe1, 0x7a, 0xa6, 0x98, 0xbc, 0x18, + 0x46, 0xbc, 0xde, 0x4e, 0x4d, 0x31, 0x79, 0x3c, 0x52, 0x6c, 0xe7, 0x8a, 0x49, 0x86, 0x86, 0x38, + 0xb4, 0xc4, 0xa2, 0x93, 0x2b, 0x0f, 0x97, 0x26, 0x96, 0x32, 0x79, 0x4a, 0x96, 0x19, 0x8d, 0xa2, + 0xae, 0x29, 0x3b, 0x91, 0x49, 0x07, 0xe8, 0xd0, 0x23, 0x43, 0xb2, 0xe3, 0x80, 0xaf, 0xed, 0x3a, + 0x92, 0x1d, 0xeb, 0xf5, 0x41, 0xd3, 0xf5, 0x91, 0x79, 0x79, 0xa5, 0x13, 0x95, 0xbc, 0xfe, 0x40, + 0x00, 0x6a, 0x1e, 0x05, 0x1f, 0x8a, 0xe9, 0xcb, 0xd6, 0xb2, 0xc2, 0x7d, 0x60, 0xf7, 0x8c, 0x7d, + 0xa0, 0xd1, 0x93, 0x25, 0x53, 0x9c, 0x64, 0xd5, 0x72, 0xfb, 0x56, 0xc6, 0xe6, 0x04, 0x1e, 0x46, + 0x04, 0xcc, 0xca, 0xe5, 0x35, 0x14, 0x2e, 0xf1, 0x8b, 0xc7, 0x17, 0xd1, 0x81, 0xd9, 0xdf, 0x00, + 0x25, 0x2c, 0x65, 0x14, 0x29, 0x29, 0x64, 0xd5, 0xab, 0xba, 0x18, 0x50, 0x3a, 0x3b, 0x93, 0x00, + 0x93, 0xda, 0x86, 0x4c, 0xac, 0xae, 0x79, 0x7f, 0x6f, 0x8c, 0x86, 0xa9, 0x13, 0x40, 0x25, 0x6b, + 0x19, 0x59, 0x9e, 0x86, 0x42, 0x73, 0xd2, 0xfb, 0xb5, 0x86, 0xbc, 0xb5, 0x1d, 0x5e, 0xc5, 0x1b, + 0xe3, 0x89, 0xec, 0x84, 0x17, 0xd9, 0x74, 0x9a, 0x9c, 0x14, 0x3f, 0xd7, 0x11, 0xab, 0x0b, 0xc6, + 0x46, 0xe4, 0x9d, 0x98, 0x27, 0x2f, 0xa5, 0xb5, 0x69, 0xf6, 0x71, 0xcc, 0x36, 0x35, 0x73, 0x07, + 0x3c, 0x84, 0x7f, 0xdb, 0xe8, 0x49, 0xfd, 0xd4, 0x85, 0x9c, 0xe7, 0xaf, 0x11, 0xbe, 0x3d, 0xc8, + 0x48, 0x1c, 0xbc, 0x7c, 0xa4, 0x0f, 0xe4, 0x2e, 0x4f, 0xc9, 0x50, 0x51, 0x6d, 0x72, 0x4f, 0x06, + 0x08, 0xcc, 0x72, 0xa8, 0xf9, 0xce, 0x78, 0x78, 0x93, 0xdc, 0xd8, 0x69, 0x31, 0x71, 0xdf, 0x19, + 0xc2, 0x04, 0x76, 0x4c, 0xdc, 0xd1, 0x98, 0xd5, 0xe4, 0x46, 0xcc, 0xa6, 0x31, 0x94, 0x2c, 0xa9, + 0x7d, 0x94, 0x2c, 0x7d, 0x6e, 0xd4, 0x64, 0x96, 0x73, 0x37, 0x02, 0x7d, 0xb8, 0x83, 0x6e, 0x03, + 0x22, 0xdc, 0xae, 0x41, 0xea, 0x87, 0x81, 0x28, 0x14, 0x8b, 0x47, 0x68, 0x9b, 0x8a, 0x1f, 0x70, + 0x07, 0xe5, 0xc5, 0xf0, 0xc6, 0x1d, 0x7c, 0x6b, 0x11, 0x42, 0x3c, 0x13, 0x75, 0xd1, 0x39, 0xa9, + 0xea, 0x16, 0x4e, 0x88, 0x9c, 0xfb, 0x17, 0xd0, 0xb6, 0x58, 0x1c, 0x0c, 0x70, 0xee, 0xd7, 0xc3, + 0xd0, 0x58, 0x94, 0x96, 0x2b, 0x2b, 0x33, 0x28, 0x61, 0xc0, 0x16, 0xe7, 0x2b, 0x24, 0x8e, 0x6c, + 0xd7, 0x93, 0xed, 0x0b, 0xc8, 0xf6, 0x64, 0xc9, 0x3d, 0x17, 0x51, 0x94, 0x1f, 0x42, 0x18, 0x59, + 0x8b, 0xc8, 0xea, 0xa5, 0x4d, 0x59, 0x09, 0x01, 0xcc, 0x5a, 0x46, 0x45, 0x23, 0x40, 0x25, 0x55, + 0x88, 0xa5, 0xf2, 0xa1, 0x94, 0x2c, 0x51, 0x81, 0x34, 0x51, 0xe9, 0x68, 0xe2, 0x4f, 0xeb, 0x81, + 0xf2, 0x64, 0xc0, 0xab, 0x00, 0x77, 0xf9, 0x73, 0x64, 0x80, 0x8a, 0x06, 0xdf, 0x42, 0xf2, 0xdb, + 0x48, 0xfe, 0x85, 0xd2, 0x44, 0x8b, 0x9c, 0xff, 0x0b, 0x8b, 0x32, 0x67, 0xb5, 0x4a, 0x16, 0xde, + 0x83, 0x92, 0x01, 0xd6, 0x44, 0x8a, 0x24, 0xfc, 0x9f, 0x25, 0xde, 0x45, 0xf8, 0xfd, 0x92, 0x7b, + 0x27, 0xa5, 0x0d, 0xff, 0x9f, 0xa5, 0xb3, 0x2d, 0xb2, 0x1b, 0x49, 0x6f, 0x56, 0xbe, 0x34, 0xd1, + 0x06, 0x12, 0xdf, 0x46, 0xdc, 0xe5, 0x88, 0x0a, 0x7f, 0x81, 0xb8, 0x37, 0xd1, 0x97, 0xd3, 0x92, + 0xa9, 0x85, 0xc8, 0x76, 0x4a, 0xc2, 0x42, 0xf8, 0x4b, 0xd1, 0x32, 0x7a, 0xcc, 0x79, 0x4a, 0xa3, + 0xda, 0xc8, 0x62, 0x01, 0x52, 0xfe, 0xfd, 0xa6, 0x4a, 0x4a, 0x7e, 0x2f, 0xd0, 0xf1, 0x45, 0x16, + 0x67, 0x38, 0xa8, 0x26, 0x51, 0x89, 0x72, 0xed, 0x7c, 0x34, 0xc0, 0x08, 0x11, 0x6b, 0x84, 0x3e, + 0x20, 0xcb, 0xec, 0x60, 0x97, 0x14, 0xcf, 0xb2, 0x60, 0xb7, 0x14, 0xb0, 0xa4, 0x76, 0xc2, 0x9f, + 0x26, 0xa6, 0x16, 0x89, 0x76, 0x4e, 0xf8, 0x0b, 0x12, 0x45, 0x87, 0xf0, 0x6d, 0xb4, 0x5b, 0x3b, + 0x90, 0x9a, 0xb1, 0x29, 0xa6, 0x11, 0x1d, 0xef, 0x1c, 0xd9, 0x71, 0x18, 0x8b, 0x91, 0x02, 0x54, + 0xa4, 0x4a, 0x26, 0xe5, 0x2b, 0xae, 0x9d, 0xda, 0x40, 0x40, 0x88, 0x58, 0x01, 0x5d, 0x9f, 0x48, + 0x39, 0xcb, 0x65, 0x9f, 0x05, 0xdb, 0x48, 0x56, 0xc7, 0xba, 0x4f, 0xa8, 0x13, 0x55, 0x29, 0x6b, + 0x3c, 0x91, 0x93, 0x63, 0xb6, 0x29, 0x69, 0x77, 0x10, 0x4a, 0x2c, 0x4c, 0x64, 0x6e, 0x2f, 0xe4, + 0x57, 0xed, 0x8a, 0x55, 0xd5, 0xf6, 0xc5, 0xf0, 0xd0, 0x20, 0x60, 0xe2, 0xe9, 0x0f, 0xf1, 0xe4, + 0xaf, 0x29, 0xa3, 0x78, 0x42, 0x07, 0x34, 0x82, 0x2d, 0xee, 0x74, 0x44, 0x59, 0xe5, 0x8c, 0x3b, + 0x15, 0xde, 0x8d, 0x1e, 0xe2, 0x5e, 0x4e, 0x09, 0x98, 0x09, 0x7f, 0x4b, 0x13, 0xcd, 0x32, 0xff, + 0x0b, 0xb3, 0xf2, 0xca, 0x2a, 0x3a, 0x0a, 0x77, 0x1f, 0xb0, 0x89, 0x05, 0x51, 0x01, 0x73, 0x22, + 0xb1, 0x94, 0x4d, 0xc7, 0x91, 0x4d, 0x7c, 0x33, 0xf2, 0xc8, 0x39, 0x2e, 0xf0, 0x7c, 0xac, 0x2d, + 0x4f, 0xe1, 0xd5, 0xca, 0xd8, 0xd0, 0x0c, 0xa3, 0x7e, 0xb9, 0xf7, 0xee, 0xa8, 0x85, 0x4d, 0xc6, + 0x73, 0x52, 0xe5, 0x35, 0x89, 0x6f, 0x97, 0x4c, 0x1d, 0x30, 0x3c, 0x5f, 0x05, 0x8c, 0x3b, 0xa3, + 0xea, 0x36, 0x2a, 0x28, 0xe7, 0x3e, 0x0b, 0x03, 0xeb, 0xfc, 0x2d, 0x48, 0xa4, 0xf7, 0x86, 0x86, + 0x3b, 0xe0, 0x8c, 0x09, 0xf7, 0x7e, 0xa9, 0xad, 0x1a, 0x62, 0xde, 0x0d, 0xb9, 0x20, 0xd5, 0x6b, + 0xbf, 0x03, 0xbc, 0x2e, 0xfe, 0x91, 0x05, 0x57, 0xa6, 0x18, 0x87, 0x9f, 0xfe, 0x1d, 0x0a, 0x78, + 0xa6, 0x31, 0xfa, 0x43, 0x98, 0xfe, 0x1e, 0xfe, 0x0e, 0x35, 0x21, 0xd5, 0xab, 0x80, 0xf8, 0x74, + 0x75, 0x3e, 0x00, 0x29, 0xe8, 0x00, 0x88, 0x03, 0x9e, 0x26, 0xc3, 0xbd, 0x59, 0x7f, 0xb7, 0xdb, + 0x1a, 0x9b, 0xce, 0x55, 0xd9, 0xc5, 0x08, 0xd3, 0xab, 0xcf, 0x09, 0x53, 0x96, 0x98, 0xde, 0x16, + 0x26, 0x94, 0x96, 0x07, 0x04, 0xbf, 0x12, 0x78, 0x0c, 0xb1, 0xd6, 0x76, 0x6e, 0x86, 0x61, 0xa7, + 0x11, 0x53, 0x47, 0xf5, 0x39, 0xd2, 0x08, 0x4e, 0x10, 0x8c, 0x94, 0xa4, 0x69, 0x45, 0x2a, 0xee, + 0x8c, 0x10, 0xa7, 0x1a, 0x42, 0x6b, 0x97, 0x52, 0xb9, 0x08, 0x8d, 0x64, 0x57, 0xc8, 0x14, 0x72, + 0x07, 0xea, 0x5d, 0xe0, 0x12, 0x1d, 0x38, 0xc9, 0x9e, 0x21, 0x42, 0x3b, 0xdb, 0x44, 0x2a, 0xaf, + 0x19, 0xcf, 0x19, 0x4f, 0xa4, 0x19, 0x3d, 0xcb, 0x41, 0xa7, 0xf8, 0x2e, 0x69, 0xe9, 0x5b, 0xc9, + 0xab, 0x58, 0x30, 0x7c, 0xfe, 0xa0, 0xa9, 0x45, 0x38, 0xdc, 0x2b, 0xb7, 0xd1, 0x60, 0x08, 0xaf, + 0x12, 0x6b, 0x0d, 0x31, 0x55, 0x17, 0x87, 0xb8, 0x53, 0x4c, 0x8e, 0x3c, 0x0a, 0x2f, 0x54, 0x30, + 0x82, 0x76, 0x55, 0x4e, 0xa7, 0x8a, 0x7e, 0x97, 0x4b, 0x7d, 0xe4, 0x63, 0xca, 0xa5, 0x8f, 0x91, + 0x4b, 0x9c, 0x91, 0xf0, 0xaf, 0xf5, 0x5f, 0x21, 0xd6, 0x37, 0xa9, 0xbd, 0x41, 0x69, 0xbd, 0xb8, + 0x72, 0xa4, 0x56, 0x61, 0xb7, 0xcc, 0xf7, 0xd9, 0x45, 0x45, 0xb2, 0xb3, 0x7b, 0x98, 0x39, 0xb9, + 0xec, 0x11, 0x84, 0x26, 0xbe, 0x85, 0x90, 0x19, 0x76, 0x48, 0x1c, 0x4a, 0xad, 0xf8, 0x2f, 0xce, + 0x28, 0xe5, 0xbf, 0xd6, 0x7f, 0x55, 0x32, 0xbd, 0x29, 0x5e, 0x66, 0xd8, 0x86, 0x98, 0x56, 0x49, + 0x78, 0x35, 0xa5, 0x97, 0x34, 0xc3, 0xd8, 0xe3, 0x5b, 0xb8, 0xf4, 0x56, 0xa0, 0x05, 0x97, 0xde, + 0x2b, 0x99, 0xaa, 0xb9, 0xf4, 0xb3, 0x92, 0xb5, 0x26, 0x5d, 0x1c, 0x8c, 0x02, 0x9e, 0x72, 0xee, + 0xb1, 0x00, 0xc3, 0x37, 0x9d, 0x3b, 0xc0, 0x7b, 0x81, 0x82, 0x01, 0xa3, 0xd9, 0xfe, 0x47, 0x13, + 0xcb, 0x28, 0xed, 0xf3, 0x28, 0x5a, 0x87, 0xb4, 0x38, 0xc5, 0xe4, 0x2b, 0x54, 0xc2, 0x35, 0x60, + 0xbc, 0x3d, 0x99, 0x36, 0xb3, 0x42, 0xee, 0xa7, 0x1c, 0xa8, 0xf6, 0x38, 0x35, 0x8d, 0x59, 0xa9, + 0xec, 0x7b, 0x1f, 0x82, 0x91, 0x16, 0x07, 0x52, 0xb9, 0x6a, 0x82, 0xb5, 0xc7, 0xa1, 0xcd, 0x96, + 0xcd, 0x2c, 0xb9, 0x07, 0xf3, 0xc9, 0x82, 0x2a, 0xb0, 0x5a, 0x6f, 0x3e, 0x1a, 0x14, 0xee, 0x52, + 0x06, 0xda, 0x9f, 0x9e, 0xad, 0xca, 0xdd, 0xf2, 0x70, 0xf1, 0x56, 0x18, 0xb7, 0x7b, 0xef, 0x77, + 0x48, 0xa7, 0x2c, 0x71, 0x20, 0xe0, 0x9c, 0x19, 0x82, 0xe5, 0x4c, 0xfb, 0x3e, 0x9c, 0xa5, 0x55, + 0x40, 0x9c, 0x40, 0x6a, 0x02, 0x40, 0xcb, 0x0a, 0x41, 0xb3, 0x81, 0x3c, 0x98, 0x95, 0x4a, 0x15, + 0x1c, 0xf1, 0x8a, 0xde, 0xf0, 0x2c, 0x80, 0xe8, 0xf8, 0xb8, 0x33, 0x07, 0x40, 0xda, 0xcb, 0xd7, + 0xc0, 0x40, 0xee, 0xa5, 0x03, 0xd1, 0x54, 0x1d, 0x47, 0xd1, 0x1d, 0x35, 0xf1, 0x4c, 0xb8, 0x2f, + 0x34, 0xf1, 0x28, 0xef, 0x64, 0x33, 0x0c, 0x8c, 0x66, 0x2e, 0x78, 0x0f, 0xca, 0xa3, 0x60, 0xf0, + 0x95, 0x4d, 0x60, 0x20, 0x95, 0x2f, 0xf0, 0xad, 0x00, 0x4c, 0x71, 0x7f, 0x23, 0x80, 0x0b, 0x08, + 0xf1, 0x40, 0x24, 0xad, 0x59, 0xf9, 0xf9, 0x5c, 0x0a, 0xd1, 0x17, 0x6f, 0x5f, 0x06, 0x94, 0xea, + 0x7c, 0x13, 0xdd, 0xba, 0x21, 0x56, 0x88, 0x51, 0x5a, 0x81, 0x81, 0xca, 0x21, 0xf8, 0xf3, 0xfe, + 0x1d, 0x90, 0x07, 0x5f, 0xc4, 0x7b, 0x77, 0xd4, 0x49, 0x79, 0x8c, 0x5d, 0x02, 0x4c, 0x7c, 0x5b, + 0x5c, 0xdb, 0xc7, 0x31, 0xc2, 0x32, 0xd2, 0x28, 0xa5, 0xc6, 0x41, 0x6e, 0xbf, 0xb8, 0x2b, 0x21, + 0xb0, 0xf3, 0x61, 0x63, 0x60, 0x8d, 0xf1, 0x2a, 0x77, 0x20, 0x4b, 0x67, 0x81, 0xe0, 0xc9, 0xac, + 0x7c, 0xf7, 0x43, 0x55, 0x7f, 0x3d, 0x4e, 0x18, 0x8f, 0xb2, 0x82, 0x41, 0xbc, 0x04, 0x7d, 0x76, + 0xc6, 0x92, 0x5d, 0x09, 0xbb, 0x2e, 0xfb, 0xc6, 0x40, 0xde, 0xc3, 0x34, 0x1c, 0x64, 0xf4, 0x28, + 0xe5, 0xe3, 0xec, 0x35, 0x39, 0x30, 0xc6, 0xf9, 0x2a, 0x46, 0xae, 0x65, 0x03, 0x54, 0xf6, 0x75, + 0xf6, 0xb3, 0xab, 0xe9, 0x08, 0x93, 0x67, 0x02, 0x42, 0xae, 0x6b, 0x50, 0xe3, 0xdf, 0x0f, 0x86, + 0xc6, 0x4a, 0xce, 0xd6, 0x4e, 0x65, 0x81, 0x9e, 0x8d, 0x11, 0xf8, 0x97, 0xb5, 0x3f, 0x94, 0xcb, + 0x32, 0x39, 0xca, 0x5f, 0xef, 0xa5, 0x1c, 0x25, 0x8d, 0x80, 0x58, 0xaa, 0xfd, 0x0d, 0xc8, 0xcb, + 0x53, 0xbc, 0x23, 0xf2, 0xe6, 0xd8, 0xbf, 0x5a, 0x8d, 0x79, 0x1f, 0x8d, 0xc8, 0x8b, 0xb3, 0x7f, + 0x47, 0xeb, 0xfd, 0x6c, 0x38, 0x8f, 0xab, 0xae, 0x06, 0xec, 0x6a, 0x82, 0x1d, 0x20, 0x8e, 0xac, + 0x94, 0x95, 0x20, 0xad, 0x36, 0x7c, 0xd2, 0x31, 0x3d, 0x9c, 0x31, 0xd6, 0x47, 0x9d, 0x14, 0xb2, + 0xe5, 0x7b, 0x52, 0x37, 0x31, 0x4c, 0x52, 0x0b, 0x48, 0xe9, 0xb1, 0xd4, 0xa7, 0xa0, 0x73, 0x73, + 0x29, 0x93, 0x0b, 0x3c, 0x98, 0x15, 0x87, 0x60, 0xe2, 0x6c, 0xca, 0x25, 0x0a, 0x4f, 0x53, 0x1a, + 0x6b, 0xdf, 0xfb, 0x55, 0x38, 0x63, 0x8f, 0xb3, 0x01, 0xfe, 0x5d, 0xd9, 0x21, 0xb2, 0x4c, 0xb1, + 0x4f, 0xb6, 0x00, 0x31, 0x23, 0xec, 0xdf, 0x01, 0x42, 0x4a, 0x0a, 0x25, 0x97, 0xc6, 0xe8, 0xa1, + 0x9c, 0x6d, 0x8c, 0x40, 0x02, 0xb0, 0xfb, 0x59, 0x9f, 0x5f, 0xc5, 0xc1, 0xf7, 0xe5, 0x70, 0x00, + 0x97, 0xaf, 0xb5, 0x17, 0x82, 0xc9, 0x52, 0xa2, 0x96, 0x86, 0x26, 0xd0, 0x38, 0xd1, 0xa3, 0x31, + 0x06, 0xf2, 0xec, 0x66, 0x90, 0x8c, 0x3c, 0x3b, 0x03, 0xa4, 0x83, 0xa0, 0xf0, 0xc4, 0x0c, 0x8a, + 0x06, 0x77, 0x30, 0x6b, 0xe9, 0x32, 0xcb, 0xb7, 0x40, 0xcd, 0x6c, 0x71, 0x97, 0x99, 0x71, 0xfe, + 0x50, 0xca, 0x2a, 0xfc, 0x4d, 0x0c, 0x98, 0x02, 0xa7, 0xde, 0x6c, 0xd7, 0x22, 0xd1, 0x8f, 0xce, + 0xa1, 0xc3, 0xf6, 0x3d, 0xc0, 0x7d, 0xd2, 0xae, 0x77, 0x8c, 0xb3, 0x9f, 0x44, 0xb5, 0xf9, 0x0d, + 0xcd, 0xd4, 0x14, 0x8b, 0xbb, 0x1e, 0x0d, 0x17, 0x66, 0xd9, 0x3f, 0x46, 0x09, 0x7c, 0x4b, 0xcd, + 0xa3, 0xbd, 0xc3, 0xa4, 0xb0, 0x44, 0xa5, 0xd6, 0x40, 0x28, 0x8e, 0xaa, 0x5d, 0x9d, 0x50, 0x87, + 0x7d, 0x1b, 0x03, 0xc6, 0x73, 0xdc, 0x07, 0xf5, 0xe7, 0xdb, 0xa9, 0xef, 0xd9, 0x42, 0x7e, 0xfa, + 0x54, 0x18, 0xaa, 0x9e, 0x0e, 0x4c, 0x1b, 0x79, 0x79, 0x1d, 0xbc, 0xcb, 0x7b, 0xd6, 0x61, 0x4c, + 0xd2, 0x53, 0xca, 0x94, 0x86, 0x29, 0x73, 0x69, 0xec, 0xaa, 0xb5, 0x33, 0x7a, 0x18, 0xd2, 0xc2, + 0xe0, 0x74, 0xce, 0xfb, 0x2d, 0xca, 0x8f, 0xa7, 0xd2, 0xf7, 0xe5, 0x6e, 0xcf, 0xae, 0x18, 0xee, + 0x80, 0x2e, 0x7c, 0xb9, 0x78, 0x6b, 0x9e, 0x53, 0xe3, 0x3e, 0x21, 0x7c, 0x93, 0x4a, 0x9a, 0xf2, + 0x2c, 0x68, 0x40, 0x57, 0x67, 0xa9, 0xea, 0x67, 0x52, 0x48, 0x8f, 0x45, 0x41, 0xcf, 0x02, 0x1a, + 0x54, 0x03, 0xf3, 0xfe, 0x4c, 0xe3, 0x85, 0xaa, 0x86, 0x36, 0xec, 0xe7, 0x32, 0xf6, 0x14, 0x10, + 0x14, 0x05, 0x57, 0x15, 0xa0, 0x2b, 0xee, 0x60, 0xf8, 0x2c, 0xc6, 0xcf, 0x30, 0xcb, 0xd0, 0xce, + 0x0b, 0x93, 0xb0, 0x3c, 0x0f, 0xa1, 0xfd, 0x55, 0x13, 0x34, 0x06, 0xc2, 0xff, 0xf8, 0xb6, 0x52, + 0x6b, 0x29, 0x3c, 0x4b, 0xd1, 0xc2, 0x42, 0xcb, 0x62, 0x5a, 0x28, 0xbd, 0x7c, 0x0d, 0x41, 0xbe, + 0x4c, 0xc3, 0xae, 0x6e, 0x72, 0x45, 0x59, 0x1f, 0x81, 0xc9, 0x67, 0xa0, 0xeb, 0xd2, 0x64, 0x65, + 0xdb, 0xe2, 0xa0, 0x3a, 0x93, 0x72, 0x7d, 0x53, 0x6a, 0x6c, 0xca, 0x58, 0x96, 0x69, 0x4a, 0x8d, + 0x7b, 0x0e, 0x7e, 0x24, 0xb5, 0x45, 0x76, 0x82, 0x77, 0x60, 0x3a, 0xc9, 0x36, 0xa0, 0x17, 0x9f, + 0xad, 0xe9, 0xf4, 0x80, 0x63, 0x65, 0xf7, 0x02, 0xd7, 0x94, 0xc5, 0x0f, 0xaa, 0xa4, 0x0d, 0x75, + 0xd7, 0x91, 0xa2, 0x52, 0x45, 0x25, 0xf5, 0x45, 0x35, 0x65, 0x0c, 0x74, 0xee, 0x19, 0x11, 0x4f, + 0x3c, 0x03, 0x34, 0x95, 0x04, 0x2d, 0xf1, 0x47, 0xb5, 0x71, 0xd5, 0x32, 0x80, 0x97, 0xd2, 0xcd, + 0x40, 0x39, 0xb7, 0x87, 0x98, 0x2e, 0x38, 0x93, 0xfa, 0xd2, 0x0b, 0x5d, 0xce, 0xfb, 0xb8, 0x83, + 0xbb, 0x71, 0xd6, 0x87, 0xb9, 0xcb, 0x79, 0x2f, 0xc4, 0x9d, 0xc5, 0x10, 0x78, 0xbe, 0xe9, 0x2d, + 0x16, 0x07, 0x66, 0x70, 0x6f, 0x78, 0x0c, 0xcd, 0x30, 0x4b, 0xf8, 0xc6, 0x84, 0x02, 0xba, 0xc6, + 0x80, 0x78, 0x3e, 0x40, 0xac, 0x8a, 0xf4, 0xc2, 0x1c, 0xf4, 0x5f, 0x2c, 0x36, 0xa5, 0xf9, 0x5b, + 0xb4, 0xd4, 0x7a, 0x62, 0x6d, 0x27, 0xad, 0xdc, 0xbe, 0xb3, 0x84, 0xef, 0xe8, 0xff, 0x8a, 0x3d, + 0x99, 0xd4, 0x48, 0x84, 0x6b, 0xf1, 0xe7, 0xc1, 0xa5, 0x92, 0x78, 0xa5, 0x76, 0x79, 0xc2, 0x31, + 0xca, 0xf3, 0x3e, 0x1a, 0x55, 0xd4, 0xe1, 0xd4, 0x37, 0x92, 0xfb, 0xfd, 0xc1, 0xc8, 0xe3, 0x16, + 0x08, 0x02, 0xc7, 0x7b, 0x8d, 0x57, 0x0f, 0x05, 0xc6, 0x30, 0x4c, 0xca, 0xad, 0xf8, 0x5e, 0x2e, + 0xfd, 0x22, 0x97, 0xde, 0x24, 0x56, 0xfa, 0x19, 0xa7, 0x4e, 0x32, 0x29, 0xdc, 0xc1, 0x1f, 0x3d, + 0x05, 0x11, 0x0c, 0xa2, 0xe3, 0x47, 0x9f, 0x16, 0x27, 0x4c, 0xa7, 0x4d, 0xca, 0xc7, 0xf9, 0x93, + 0xdb, 0x7b, 0x2a, 0xd2, 0x7b, 0x23, 0x92, 0x6d, 0x8e, 0xb9, 0x22, 0x9b, 0xde, 0x04, 0xa9, 0x49, + 0xcd, 0x35, 0xe7, 0x80, 0x2d, 0x0f, 0xcc, 0x57, 0x3a, 0xa6, 0x51, 0x21, 0x97, 0xf9, 0x37, 0xa5, + 0x54, 0x70, 0xd3, 0xfd, 0xfd, 0x5f, 0x11, 0x2f, 0xdb, 0x03, 0x49, 0x6e, 0xdf, 0xf6, 0x44, 0xf6, + 0x92, 0x24, 0xb4, 0x49, 0x56, 0x3f, 0xb7, 0xaf, 0x47, 0xe2, 0xaf, 0xf5, 0x7f, 0xce, 0x5e, 0x04, + 0x10, 0x43, 0xbe, 0x35, 0x77, 0xa1, 0x46, 0x78, 0x6f, 0x44, 0x0c, 0x43, 0x35, 0xdc, 0x85, 0xba, + 0x67, 0x18, 0xea, 0x72, 0x80, 0xda, 0x4d, 0x06, 0xfa, 0x6f, 0x00, 0x53, 0x5b, 0xd9, 0xee, 0x7f, + 0x00, 0x38, 0x10, 0x73, 0xa6, 0x94, 0xb1, 0x23, 0xc6, 0x36, 0x73, 0x40, 0xb8, 0x00, 0x8d, 0x73, + 0xd4, 0xc6, 0xe2, 0xf1, 0x67, 0x46, 0x84, 0x3d, 0x55, 0x5d, 0xef, 0x32, 0x34, 0x08, 0x71, 0x2d, + 0x9a, 0xc7, 0xb9, 0xd7, 0x03, 0x57, 0x21, 0xec, 0x3e, 0x93, 0x4a, 0x78, 0x45, 0xde, 0x8d, 0xca, + 0x20, 0xcb, 0x6b, 0xd1, 0x79, 0x44, 0x38, 0xe6, 0x1c, 0x65, 0x2b, 0x75, 0x8d, 0x75, 0xe0, 0xdf, + 0x83, 0x8f, 0x47, 0x1a, 0x9a, 0xf8, 0x6b, 0x34, 0x00, 0xae, 0x04, 0x37, 0x8f, 0xc5, 0xf5, 0x5b, + 0x3b, 0x0b, 0x06, 0x49, 0x29, 0x52, 0x6b, 0xc9, 0x12, 0xba, 0x7d, 0xe0, 0xe5, 0xf0, 0x0a, 0x77, + 0x40, 0xa3, 0x17, 0x07, 0xe6, 0x39, 0x0d, 0xc0, 0xee, 0x84, 0x9a, 0xdd, 0x58, 0x2b, 0xbd, 0x6a, + 0x10, 0x8b, 0x85, 0x1b, 0x30, 0xb2, 0x5a, 0xcd, 0x44, 0xf6, 0x0a, 0x84, 0x75, 0x3e, 0x24, 0x38, + 0xdb, 0xca, 0x9e, 0xc7, 0x90, 0xf1, 0xa4, 0xf1, 0x04, 0x68, 0xcc, 0x5b, 0x5e, 0x29, 0xff, 0x1a, + 0x77, 0xe0, 0x6a, 0x1d, 0x4b, 0x63, 0x53, 0xf0, 0x96, 0xaf, 0x49, 0xf9, 0x7e, 0xf6, 0x14, 0x7b, + 0x12, 0x24, 0x82, 0xdc, 0x92, 0xdf, 0x42, 0xf4, 0x94, 0x0a, 0xc4, 0x9b, 0x6f, 0x37, 0x9e, 0x83, + 0x86, 0x4b, 0xde, 0x5a, 0x87, 0x7e, 0xc0, 0xeb, 0x10, 0x88, 0x74, 0x71, 0x62, 0xb1, 0xaa, 0x0f, + 0xe7, 0x03, 0x42, 0x7b, 0x9e, 0xec, 0xc6, 0xca, 0x66, 0x10, 0xa2, 0x52, 0x98, 0x07, 0x5c, 0x11, + 0xaa, 0x19, 0x3a, 0x90, 0x15, 0x99, 0x6a, 0x56, 0xac, 0x8f, 0x04, 0x35, 0x44, 0x4d, 0x53, 0x47, + 0xf9, 0x9d, 0x74, 0x75, 0xd6, 0xcb, 0xef, 0x90, 0x2d, 0x5a, 0xcc, 0x27, 0xb7, 0x00, 0x4c, 0x40, + 0x68, 0x93, 0xdf, 0x41, 0x40, 0x16, 0xe3, 0x55, 0x0b, 0x98, 0xb3, 0x45, 0x2a, 0x1c, 0xd7, 0x32, + 0x34, 0x87, 0x4c, 0xdd, 0x04, 0x03, 0xcb, 0x1c, 0xba, 0x36, 0x9d, 0x05, 0x64, 0xbd, 0x79, 0x94, + 0x1e, 0x81, 0x16, 0xb4, 0x46, 0x0d, 0x2a, 0xe0, 0x3c, 0xe5, 0x3f, 0x17, 0xa2, 0xea, 0x43, 0x96, + 0xfb, 0xaa, 0x73, 0x12, 0x18, 0x41, 0x8d, 0x64, 0xed, 0x60, 0xeb, 0x8d, 0x1e, 0xa9, 0xb2, 0x0d, + 0x46, 0xd6, 0x89, 0x11, 0x73, 0x1f, 0x7f, 0x8d, 0x05, 0x6b, 0xca, 0xb9, 0x31, 0x9c, 0x86, 0x50, + 0x46, 0x65, 0x02, 0x54, 0x20, 0x83, 0x60, 0x30, 0x16, 0x2a, 0x6f, 0x50, 0xb7, 0x17, 0xec, 0x05, + 0x1d, 0xd0, 0x08, 0x9b, 0x31, 0x59, 0xad, 0x49, 0x06, 0x81, 0xe3, 0x16, 0xe5, 0x1d, 0x26, 0x64, + 0x37, 0xfe, 0xea, 0x5b, 0xb8, 0x8c, 0x49, 0x85, 0x0a, 0x33, 0x55, 0xc7, 0xdc, 0xdb, 0x1e, 0x06, + 0x42, 0xd1, 0xae, 0x4c, 0x5a, 0x48, 0x6b, 0xd4, 0x85, 0x51, 0x1f, 0xc4, 0x0f, 0xa1, 0x88, 0xef, + 0x1e, 0x7b, 0x1e, 0x9a, 0xd9, 0xf4, 0x07, 0x28, 0x3d, 0xea, 0x54, 0xef, 0xc4, 0x0f, 0x38, 0x42, + 0xac, 0x0d, 0xfe, 0xb7, 0xfb, 0x1d, 0x50, 0x74, 0x71, 0x20, 0x8c, 0xab, 0x8e, 0xa2, 0x2f, 0x5a, + 0x61, 0x4e, 0x50, 0x4f, 0x47, 0x43, 0x3e, 0xfc, 0xb0, 0x6a, 0x96, 0xf8, 0xae, 0x44, 0xb6, 0xea, + 0x38, 0xca, 0x18, 0x15, 0x3a, 0x5f, 0xb7, 0xfd, 0x51, 0x98, 0x5c, 0x4a, 0x59, 0xa5, 0x6f, 0xf2, + 0xdd, 0xa5, 0xc6, 0xae, 0x58, 0x62, 0xf5, 0x8b, 0x3b, 0x34, 0x8b, 0xb9, 0x57, 0x70, 0x5d, 0x92, + 0x9c, 0x05, 0xfb, 0x21, 0xa7, 0xcd, 0x06, 0x19, 0x6c, 0x4c, 0xdb, 0xc0, 0xd4, 0xa1, 0xe9, 0x31, + 0x2b, 0x7f, 0x7e, 0x38, 0x38, 0xa9, 0xc8, 0x19, 0xe0, 0x6d, 0x77, 0x99, 0x95, 0xf7, 0x83, 0x19, + 0x0d, 0x01, 0x41, 0x17, 0x10, 0x80, 0xa1, 0x97, 0x53, 0xd5, 0xf0, 0x02, 0x2c, 0xaa, 0x4d, 0xc9, + 0x88, 0xa7, 0x89, 0x80, 0xd0, 0x65, 0x51, 0x92, 0x55, 0x5c, 0x64, 0x53, 0x3b, 0xa8, 0x88, 0x4d, + 0x09, 0x47, 0xef, 0x18, 0x1b, 0xaa, 0x90, 0x6d, 0x8a, 0x5e, 0x2d, 0xaf, 0xbe, 0xea, 0xbc, 0x8f, + 0xdc, 0x82, 0x2a, 0x68, 0x94, 0xdb, 0x95, 0xb9, 0xb7, 0x29, 0x91, 0x7d, 0x9c, 0x3d, 0x1f, 0x30, + 0x56, 0x8c, 0xf7, 0xab, 0xf3, 0xe0, 0x55, 0x5c, 0x80, 0x89, 0x1d, 0xb5, 0x70, 0xb0, 0xc0, 0xd8, + 0xd7, 0x97, 0x3e, 0x13, 0xd8, 0x75, 0x11, 0x85, 0xed, 0x92, 0x54, 0xb5, 0x8e, 0x8a, 0x63, 0x17, + 0x39, 0x23, 0xfd, 0x8c, 0x4e, 0x31, 0xe9, 0x09, 0x48, 0x16, 0xa5, 0x7b, 0x41, 0x68, 0x12, 0x11, + 0x5f, 0x4a, 0x00, 0x1f, 0x7e, 0x2f, 0x9a, 0x46, 0x10, 0xd2, 0xbd, 0x0d, 0xd3, 0xe4, 0x0c, 0x08, + 0x96, 0x9a, 0xc5, 0xdb, 0x2c, 0x40, 0x6f, 0x81, 0xb6, 0xc7, 0x21, 0xf6, 0x10, 0xa8, 0x4f, 0x58, + 0x79, 0x8d, 0xe4, 0xb7, 0x8b, 0x03, 0x63, 0xb7, 0xe9, 0x89, 0x57, 0xca, 0x7c, 0x65, 0x36, 0xd1, + 0xec, 0x21, 0xcd, 0x9d, 0xf9, 0xa8, 0x9a, 0xcb, 0x6f, 0x92, 0x7a, 0xd2, 0x9c, 0xd4, 0x46, 0xac, + 0x1d, 0x72, 0xec, 0x4f, 0x89, 0xb5, 0xcd, 0xb1, 0x4c, 0xca, 0x5e, 0x87, 0xbe, 0xe4, 0x9f, 0xb0, + 0x5b, 0xb4, 0x3a, 0xef, 0xaf, 0xa3, 0x31, 0x44, 0x18, 0xeb, 0x8d, 0xc1, 0xf5, 0x25, 0x30, 0x26, + 0x9a, 0xdc, 0x1c, 0x90, 0x60, 0x30, 0x07, 0xe9, 0x93, 0xa9, 0xdc, 0xa2, 0xcd, 0xe1, 0x3b, 0x3a, + 0x75, 0x2c, 0xaa, 0x6a, 0x7f, 0x2f, 0xf1, 0xa6, 0xb4, 0x39, 0x7e, 0x20, 0x65, 0x3f, 0x25, 0x55, + 0x2a, 0xd2, 0xc1, 0x10, 0x98, 0x5f, 0x8f, 0x00, 0xa3, 0xc2, 0x90, 0xf9, 0x0b, 0xe6, 0xc0, 0x23, + 0x3e, 0x41, 0x02, 0x2c, 0x31, 0xca, 0x90, 0xb2, 0x9f, 0x91, 0x8e, 0xaa, 0xd5, 0x07, 0xfa, 0x7f, + 0x45, 0x09, 0x60, 0x3d, 0x8d, 0x01, 0x6e, 0x33, 0x85, 0x7a, 0x1e, 0x08, 0x10, 0xce, 0xb7, 0x48, + 0xd6, 0xd3, 0x31, 0x83, 0xe0, 0x10, 0x1c, 0xc2, 0x15, 0xc0, 0x9c, 0x5c, 0x08, 0xa8, 0x3c, 0x20, + 0x2d, 0x5d, 0xca, 0x81, 0x78, 0x15, 0x17, 0xde, 0x23, 0xed, 0x51, 0x81, 0x34, 0xab, 0x40, 0xbc, + 0x5f, 0x84, 0x81, 0xa3, 0x7d, 0x32, 0xaf, 0x0e, 0x1b, 0x98, 0x73, 0x2d, 0xb4, 0xdb, 0x85, 0xca, + 0xcb, 0x6a, 0x7d, 0x63, 0x9f, 0x94, 0x0f, 0x72, 0x79, 0x1c, 0x6c, 0xde, 0x92, 0x75, 0x09, 0x8e, + 0x3c, 0x08, 0x7f, 0x01, 0x6d, 0x50, 0x18, 0xe9, 0xc7, 0x21, 0x28, 0x14, 0x73, 0xd6, 0x1f, 0x73, + 0x52, 0x32, 0xb5, 0xb1, 0xdd, 0x14, 0x77, 0x73, 0x4e, 0xe0, 0x11, 0x25, 0x33, 0x1e, 0x23, 0xb7, + 0x2e, 0xb4, 0x87, 0x8d, 0x9a, 0x8c, 0x15, 0xc2, 0x61, 0x20, 0x42, 0x38, 0xdf, 0x8c, 0xa1, 0x11, + 0x84, 0xdd, 0xf9, 0xed, 0xa9, 0x4b, 0xb2, 0x13, 0xb8, 0xdd, 0xd5, 0x20, 0xe3, 0xbe, 0x70, 0x64, + 0x83, 0x5f, 0x3c, 0xbe, 0x20, 0xc4, 0x74, 0x9b, 0x64, 0xd2, 0x49, 0x56, 0x3d, 0x5d, 0x2b, 0xd2, + 0xcb, 0xfb, 0x71, 0x2e, 0x0f, 0xec, 0xc7, 0x99, 0xd6, 0x0c, 0xde, 0x72, 0x42, 0x40, 0x88, 0x0b, + 0x08, 0xb1, 0xca, 0x0c, 0xea, 0x3e, 0xc4, 0x3d, 0x1d, 0x6c, 0x01, 0x75, 0xcb, 0xf5, 0x12, 0x9d, + 0x8f, 0xc1, 0x06, 0x4e, 0x94, 0xf6, 0xdc, 0x64, 0x29, 0x45, 0x73, 0xcc, 0xca, 0x4f, 0x1e, 0x1a, + 0x39, 0xa5, 0x8a, 0x6a, 0x2a, 0xd8, 0xae, 0xaa, 0x0b, 0x5d, 0x27, 0xa3, 0x47, 0xfe, 0xf8, 0xf7, + 0x80, 0x8a, 0x99, 0x3a, 0x52, 0x66, 0xea, 0x48, 0x41, 0x57, 0x3a, 0x65, 0x57, 0x5c, 0xc8, 0x95, + 0x5a, 0xa4, 0xba, 0x52, 0xf7, 0x4b, 0x26, 0xad, 0xf4, 0x56, 0x2c, 0x5a, 0x8b, 0x8f, 0xe3, 0xd0, + 0x12, 0x3c, 0xaf, 0x21, 0x31, 0xd2, 0x5b, 0x09, 0x34, 0xc3, 0x40, 0x33, 0x74, 0x24, 0x07, 0x2c, + 0x87, 0x87, 0xd6, 0xe7, 0xde, 0xf4, 0x54, 0x1d, 0x47, 0x98, 0x6a, 0x77, 0x79, 0xa1, 0xfe, 0xfa, + 0xe4, 0x23, 0x1f, 0x42, 0x7f, 0x36, 0xda, 0x9f, 0x8d, 0xf6, 0x07, 0x9e, 0x88, 0x56, 0x19, 0x1f, + 0xea, 0x2f, 0x3b, 0xd8, 0xdf, 0x43, 0xe2, 0x91, 0x9b, 0x50, 0x91, 0x71, 0x26, 0xc9, 0x47, 0x10, + 0x7c, 0x9e, 0xf2, 0x7c, 0x2c, 0x15, 0x72, 0x18, 0xe4, 0x24, 0x30, 0xab, 0x43, 0xc6, 0xa0, 0xd6, + 0xe6, 0x99, 0x95, 0xf4, 0x89, 0xaa, 0x5f, 0xe6, 0x0f, 0x76, 0xb9, 0x7e, 0x58, 0x83, 0x96, 0x12, + 0xeb, 0x71, 0x62, 0x02, 0xea, 0xeb, 0xc8, 0xc0, 0x58, 0x5e, 0xcf, 0x55, 0xcf, 0x46, 0xb5, 0x11, + 0x40, 0x20, 0x62, 0x45, 0x0f, 0x18, 0x82, 0xd3, 0xc6, 0x13, 0x60, 0xdb, 0xad, 0x20, 0x4d, 0xe1, + 0x18, 0xb6, 0x75, 0x90, 0x96, 0x89, 0xe0, 0xa8, 0x40, 0x0c, 0xfb, 0x1f, 0x54, 0xd2, 0xf2, 0xbb, + 0xa4, 0x03, 0xc8, 0x70, 0x50, 0x19, 0x9b, 0x05, 0x04, 0xaa, 0x83, 0x9c, 0x51, 0xf6, 0x7e, 0xa5, + 0xfa, 0x08, 0x0d, 0xc4, 0x7a, 0x8d, 0x08, 0x87, 0x93, 0xfa, 0x71, 0x13, 0x40, 0xd0, 0x4f, 0x11, + 0x5a, 0xc0, 0xc6, 0xef, 0x03, 0xe1, 0x36, 0x75, 0xc1, 0xdc, 0xc9, 0xb7, 0xb1, 0x83, 0xc0, 0x73, + 0x6e, 0xdf, 0x2d, 0x98, 0x93, 0xf9, 0x8e, 0x07, 0xf9, 0x36, 0xc9, 0xd4, 0x1e, 0x0f, 0x46, 0xa0, + 0x0b, 0x7a, 0x49, 0xaa, 0xa7, 0xd2, 0xd4, 0x1e, 0x7f, 0x16, 0xe2, 0xb6, 0x94, 0x56, 0xe2, 0x8f, + 0x1f, 0xe0, 0xd2, 0x87, 0x48, 0xe5, 0x05, 0x1a, 0xeb, 0x79, 0x00, 0xb9, 0xbe, 0xd4, 0x99, 0x5a, + 0x21, 0x46, 0xe2, 0x13, 0xa4, 0x84, 0xb7, 0x51, 0x13, 0x20, 0xda, 0xbe, 0x8f, 0x2a, 0x75, 0x1c, + 0xc6, 0x98, 0x75, 0x52, 0x65, 0x57, 0x9e, 0x72, 0x3b, 0x39, 0x44, 0x82, 0x80, 0x70, 0xda, 0xac, + 0xcc, 0xa7, 0xce, 0xb1, 0x8e, 0x3b, 0x18, 0xb9, 0x2c, 0x1a, 0xb7, 0xcb, 0xdc, 0xab, 0xd0, 0x68, + 0xf4, 0x8b, 0x4d, 0x3a, 0x40, 0x90, 0x08, 0x6d, 0xe0, 0xd8, 0x46, 0x32, 0xc0, 0xd0, 0x30, 0x67, + 0x09, 0x7a, 0xfb, 0x0f, 0x20, 0x3b, 0x4e, 0x90, 0xc1, 0x94, 0xc9, 0xdb, 0x74, 0x69, 0x62, 0xbd, + 0x2e, 0xa5, 0x59, 0xb8, 0x49, 0xbc, 0x3e, 0x2d, 0x2e, 0x85, 0x8c, 0x45, 0x23, 0xa0, 0x5b, 0x21, + 0x65, 0xfe, 0x78, 0x20, 0x38, 0x26, 0xa1, 0xab, 0xff, 0x4b, 0x1c, 0x90, 0x9f, 0x3b, 0xb8, 0xea, + 0xc7, 0x77, 0xb8, 0x7d, 0x67, 0xd8, 0x56, 0xb4, 0x86, 0xe0, 0x1c, 0xe4, 0xa0, 0x6c, 0xd6, 0x29, + 0xa6, 0x49, 0x41, 0x06, 0xaa, 0xbd, 0x3b, 0x7f, 0xd2, 0xf9, 0x17, 0x46, 0xdd, 0x08, 0x68, 0x65, + 0xd4, 0x8e, 0x96, 0x4c, 0x06, 0x7a, 0x88, 0x9f, 0x31, 0x15, 0x5c, 0xb0, 0xbb, 0x6f, 0xc0, 0xee, + 0x54, 0xfa, 0x7d, 0x63, 0xdd, 0x27, 0x10, 0x6e, 0x35, 0xee, 0xa7, 0xc8, 0x9a, 0x15, 0xd2, 0xaa, + 0x57, 0x6e, 0x26, 0x9d, 0x92, 0xac, 0xd7, 0xc4, 0x2b, 0x80, 0xed, 0xaa, 0x57, 0x06, 0x52, 0x4e, + 0xe1, 0x9b, 0xf8, 0x13, 0x5a, 0xfc, 0x4a, 0xf8, 0xba, 0x3b, 0x52, 0x65, 0x5c, 0xe0, 0xe0, 0x3a, + 0x2a, 0xd3, 0xfb, 0xe6, 0xa9, 0x93, 0xc1, 0x2b, 0x98, 0x0c, 0x59, 0x95, 0xde, 0xfe, 0x2f, 0xd8, + 0x8b, 0xe1, 0x7c, 0xc7, 0x44, 0x01, 0x9c, 0x9e, 0x66, 0x29, 0xff, 0x30, 0x7b, 0x19, 0x66, 0x2d, + 0xa9, 0xd2, 0x93, 0x67, 0x03, 0x77, 0x87, 0x8f, 0x0b, 0x24, 0x2b, 0xbf, 0xbc, 0x47, 0x9d, 0x2a, + 0xe3, 0x58, 0xe0, 0x48, 0xcb, 0x44, 0x2b, 0x94, 0xea, 0x52, 0x6e, 0x91, 0x16, 0xe0, 0x63, 0x3c, + 0x30, 0x33, 0x8e, 0xdb, 0xad, 0x50, 0x5b, 0xbe, 0x54, 0x8d, 0x3a, 0x17, 0xe6, 0xd0, 0xb0, 0xe5, + 0xf7, 0x66, 0x1a, 0x9a, 0xbd, 0x05, 0x82, 0x68, 0xbf, 0x03, 0xd4, 0xf5, 0xf5, 0xd8, 0x63, 0x20, + 0xcb, 0xe7, 0x03, 0x69, 0x03, 0x63, 0x2d, 0x59, 0x61, 0x26, 0x38, 0xad, 0xe8, 0x71, 0xa6, 0xf1, + 0x1a, 0x3d, 0xe0, 0xb7, 0x87, 0x83, 0xdd, 0x00, 0xf5, 0x1e, 0x76, 0x89, 0x96, 0xa3, 0x2c, 0x9d, + 0x21, 0x31, 0xa0, 0x77, 0xf2, 0xef, 0xbf, 0x43, 0xbd, 0xc3, 0x6d, 0x6c, 0xb3, 0x39, 0x27, 0x57, + 0xd1, 0xdd, 0xa3, 0x7a, 0x60, 0xee, 0xcf, 0x21, 0xbf, 0x34, 0xdc, 0x3e, 0x08, 0x90, 0xcd, 0xca, + 0xd2, 0x98, 0x50, 0xf0, 0xb4, 0x54, 0x76, 0x0f, 0x8d, 0x2c, 0x99, 0x79, 0xb7, 0x64, 0xa6, 0xec, + 0xde, 0x87, 0x25, 0x11, 0xf6, 0x13, 0xab, 0xb1, 0x44, 0x7b, 0xb7, 0x04, 0xfc, 0xe7, 0xec, 0xce, + 0x17, 0x80, 0x99, 0xb5, 0xef, 0x1c, 0xc2, 0x65, 0x9c, 0x03, 0xa7, 0xea, 0x06, 0x70, 0x61, 0x23, + 0x90, 0xbd, 0xf8, 0xed, 0x16, 0x70, 0xcf, 0x9d, 0xda, 0x54, 0xe1, 0xef, 0x9d, 0x3f, 0x42, 0x39, + 0x31, 0x01, 0x67, 0xe5, 0x83, 0x74, 0xad, 0xa7, 0x95, 0x56, 0x2a, 0x5e, 0x52, 0xd3, 0x8c, 0x55, + 0xa2, 0x45, 0x4f, 0x98, 0xd0, 0xd3, 0xb9, 0x80, 0xa5, 0x4b, 0xa1, 0x47, 0xbe, 0xa3, 0x8b, 0x6f, + 0xde, 0xf6, 0x08, 0x39, 0x33, 0x0c, 0xd7, 0xe3, 0xc8, 0xa5, 0x9f, 0x91, 0xca, 0x96, 0x7e, 0x78, + 0xbd, 0x06, 0xc5, 0xc7, 0xa0, 0x18, 0xc2, 0xcb, 0x48, 0xc9, 0x7d, 0x9a, 0x82, 0x3a, 0xf2, 0x09, + 0xfd, 0xb9, 0x84, 0x0b, 0x18, 0x07, 0x8f, 0xd4, 0x63, 0x69, 0x40, 0x7a, 0xab, 0x05, 0x81, 0x54, + 0x76, 0x80, 0x97, 0xcd, 0x65, 0x0e, 0xd6, 0x1e, 0x39, 0x4c, 0x51, 0x83, 0x3a, 0x0a, 0xb7, 0x6f, + 0x30, 0xbc, 0xb2, 0x0b, 0x78, 0xcf, 0x0e, 0x26, 0xe1, 0xbe, 0x8a, 0xe0, 0x5f, 0x76, 0x93, 0x63, + 0x98, 0x6d, 0x51, 0x4d, 0x59, 0x1a, 0x1d, 0x90, 0xd5, 0x37, 0x7e, 0xd9, 0x4d, 0xf0, 0xed, 0xb6, + 0xe9, 0x21, 0xad, 0x57, 0x77, 0x62, 0xd0, 0x41, 0xf0, 0x4d, 0x80, 0x34, 0x6e, 0xc9, 0xec, 0x87, + 0x09, 0xdc, 0x2f, 0xf1, 0xed, 0xa0, 0x62, 0x38, 0xcb, 0x58, 0xbb, 0x8a, 0xc9, 0x6a, 0x5d, 0xcd, + 0xd3, 0xe3, 0x8b, 0x89, 0x4d, 0x5f, 0xb3, 0x6b, 0x82, 0xe4, 0x6e, 0xc6, 0x9e, 0xb3, 0x62, 0xc1, + 0xb8, 0x93, 0xa7, 0xe3, 0x24, 0xb9, 0x0d, 0x93, 0xab, 0x13, 0x89, 0x2d, 0x41, 0xe2, 0xdb, 0x8a, + 0x49, 0xd6, 0x6c, 0x6e, 0xdf, 0x6d, 0xf6, 0x12, 0xd9, 0x35, 0xc7, 0x78, 0x15, 0x38, 0x87, 0x08, + 0xb4, 0xb8, 0xc0, 0x5d, 0x27, 0x59, 0xc9, 0x4e, 0xbd, 0x9c, 0xff, 0xfb, 0x62, 0xf2, 0xf8, 0x64, + 0x6f, 0xa7, 0x1e, 0x7e, 0x62, 0x7d, 0x61, 0x6c, 0x13, 0xd9, 0x65, 0x30, 0x06, 0x64, 0xfe, 0x34, + 0x46, 0x45, 0x60, 0x85, 0x2e, 0xab, 0x61, 0x9d, 0xdb, 0x53, 0x47, 0x97, 0x6b, 0x81, 0xf7, 0xa7, + 0x49, 0x16, 0x04, 0x8b, 0x55, 0xc7, 0x91, 0xeb, 0xa3, 0x3c, 0xe3, 0x6a, 0x54, 0x65, 0x94, 0x96, + 0xb7, 0x15, 0xe4, 0xb6, 0xf1, 0x2a, 0x2e, 0xb4, 0xd5, 0x60, 0xa6, 0x49, 0x67, 0x0c, 0xac, 0x71, + 0xed, 0x4c, 0x61, 0xe7, 0xc9, 0x2f, 0xb1, 0xce, 0x3e, 0x89, 0xff, 0x05, 0x98, 0x27, 0x98, 0xd6, + 0x07, 0x0c, 0x42, 0xac, 0xc4, 0x1f, 0x96, 0xdf, 0x52, 0xd7, 0xb1, 0xd3, 0x27, 0x7b, 0x15, 0xc0, + 0x23, 0x3d, 0x56, 0xd6, 0xa4, 0x18, 0xfb, 0x3e, 0xbd, 0x8d, 0x5b, 0x4d, 0x07, 0x5e, 0x8d, 0x8b, + 0x40, 0x14, 0x20, 0x66, 0x8c, 0x76, 0x9f, 0x70, 0x6e, 0x58, 0x9d, 0x21, 0xf8, 0x7c, 0x3b, 0x49, + 0x77, 0xff, 0xe5, 0x1c, 0xb3, 0xec, 0x76, 0xa0, 0x95, 0xc7, 0x35, 0x35, 0xdd, 0x22, 0x2a, 0x1d, + 0x8d, 0xd5, 0x53, 0x11, 0x14, 0x03, 0x38, 0x00, 0x9d, 0x82, 0xe5, 0x72, 0xfe, 0x69, 0x8b, 0x12, + 0x13, 0x1a, 0x87, 0xba, 0x7c, 0x9a, 0xd4, 0x9f, 0x5d, 0x6a, 0xb0, 0xc8, 0x1f, 0x63, 0x6d, 0x9b, + 0x72, 0xe6, 0x11, 0xd5, 0x73, 0xed, 0x01, 0x4c, 0x7d, 0xbb, 0xfb, 0xaf, 0xdb, 0xee, 0x82, 0xbe, + 0xa8, 0xfc, 0xf1, 0x11, 0x0c, 0x71, 0x47, 0xc3, 0x0e, 0x01, 0xe6, 0xc1, 0x40, 0xd5, 0xa9, 0x5e, + 0xa3, 0x3a, 0xda, 0x9f, 0x33, 0x34, 0x7e, 0x7c, 0x64, 0x4e, 0xd0, 0xd7, 0x2a, 0x5d, 0xae, 0x3c, + 0xa8, 0xbe, 0x43, 0x80, 0x64, 0x90, 0x85, 0xb7, 0x0f, 0x8d, 0x43, 0x3d, 0x6a, 0xea, 0xfd, 0x80, + 0x3b, 0x68, 0xfd, 0x92, 0x98, 0x17, 0x08, 0x13, 0xb9, 0x83, 0xa6, 0x76, 0xef, 0x0d, 0x7d, 0x14, + 0x38, 0xe8, 0x7e, 0xc8, 0x20, 0x4d, 0xbe, 0x08, 0x08, 0x51, 0xac, 0x7e, 0x70, 0xed, 0x65, 0xfe, + 0x6d, 0xee, 0x60, 0xb9, 0x4e, 0xce, 0xc4, 0x48, 0xbc, 0xbf, 0x8f, 0x64, 0x2f, 0x25, 0x6b, 0x16, + 0x41, 0x9c, 0xee, 0xc9, 0xa4, 0xe3, 0xf3, 0x9b, 0x95, 0x1b, 0xe1, 0x6a, 0x47, 0xd9, 0xa9, 0xe4, + 0x45, 0x7d, 0x53, 0x46, 0xec, 0x0f, 0xee, 0x85, 0x48, 0x35, 0x23, 0x6e, 0x0d, 0xfc, 0x48, 0xd9, + 0x8b, 0x48, 0x46, 0x42, 0x53, 0x86, 0x81, 0x51, 0x03, 0x16, 0xdc, 0x58, 0x69, 0xab, 0x3a, 0x5e, + 0x1d, 0x5a, 0x74, 0x32, 0x5e, 0xf5, 0x7d, 0x1b, 0xe2, 0xdc, 0x22, 0xd4, 0x95, 0x8b, 0xe4, 0x14, + 0x77, 0x20, 0x6d, 0x3c, 0x77, 0x70, 0x87, 0x0e, 0x9c, 0x12, 0xd9, 0x7d, 0x18, 0x83, 0xda, 0x08, + 0x1a, 0xa7, 0x98, 0x15, 0xef, 0xc2, 0xe0, 0x2a, 0x2e, 0xa9, 0xec, 0x72, 0x96, 0x72, 0x07, 0x6d, + 0x93, 0xc5, 0x17, 0x35, 0x06, 0x21, 0x0a, 0x2c, 0x6f, 0xac, 0xb7, 0x5d, 0x1f, 0x55, 0x0f, 0x9e, + 0x06, 0xb9, 0x6c, 0x56, 0xcc, 0xe1, 0xc1, 0xe9, 0x8c, 0xab, 0x6e, 0x46, 0xab, 0xd0, 0x24, 0x09, + 0x17, 0x20, 0xcc, 0xe4, 0xf6, 0x09, 0x5d, 0x36, 0xc5, 0xa0, 0x06, 0xc7, 0x10, 0xa8, 0x0f, 0x42, + 0x2c, 0x60, 0xb3, 0x58, 0x40, 0x06, 0xcc, 0xca, 0x64, 0x1a, 0xae, 0x83, 0x1c, 0x5c, 0x93, 0x35, + 0x6e, 0x44, 0x16, 0x9c, 0xfe, 0x8f, 0x7e, 0xa0, 0x2e, 0x65, 0x64, 0x71, 0x07, 0x33, 0x66, 0x53, + 0xb5, 0x1c, 0x13, 0xa0, 0x7b, 0xa3, 0xd0, 0x0b, 0x7f, 0x8d, 0x34, 0x72, 0xfb, 0xfa, 0x6d, 0x4a, + 0x2b, 0xad, 0xa4, 0xe1, 0x0e, 0x5a, 0x00, 0x61, 0xcb, 0x1c, 0xee, 0xe0, 0xe3, 0xb3, 0x21, 0x0e, + 0x04, 0x77, 0x29, 0x27, 0x2f, 0x17, 0x21, 0x83, 0xd3, 0x26, 0xeb, 0xd5, 0x18, 0x6e, 0xc8, 0xe0, + 0x18, 0x6f, 0xec, 0x5b, 0x2d, 0xc1, 0xcc, 0x67, 0xf2, 0x77, 0x4e, 0x0b, 0xa3, 0xcb, 0xd0, 0x72, + 0x0e, 0x2b, 0xef, 0x18, 0x8f, 0x4e, 0x51, 0x17, 0x06, 0x47, 0x42, 0x87, 0xf7, 0xcb, 0x88, 0x5a, + 0x8d, 0x11, 0xd7, 0x1d, 0x6e, 0xe1, 0x54, 0x11, 0x6b, 0x04, 0x1f, 0x51, 0xac, 0xd4, 0x31, 0xb5, + 0xab, 0x8c, 0x63, 0xb9, 0xea, 0xdf, 0x42, 0x9e, 0xeb, 0x16, 0xc7, 0xb9, 0x61, 0x22, 0x67, 0x3e, + 0x4c, 0x75, 0x4e, 0x51, 0x89, 0x63, 0x50, 0x29, 0x65, 0x56, 0xfe, 0xe3, 0xe1, 0xd0, 0xe6, 0x42, + 0x2d, 0x93, 0x38, 0x9d, 0x3b, 0xd0, 0x2c, 0xc7, 0xae, 0x90, 0x33, 0x7f, 0xd2, 0xbb, 0x2c, 0x1c, + 0x8d, 0xcc, 0x2b, 0xbb, 0x90, 0xc6, 0x95, 0xed, 0x40, 0x11, 0xde, 0x2f, 0x67, 0x26, 0x8f, 0x05, + 0x67, 0x4f, 0x8e, 0xfd, 0x09, 0xa9, 0x3c, 0x2d, 0xbf, 0xba, 0x0c, 0x01, 0xc8, 0x6f, 0xde, 0x83, + 0x3f, 0x9f, 0xde, 0xa6, 0xa1, 0x8b, 0x52, 0x9b, 0xb9, 0x3e, 0xba, 0x26, 0x73, 0xf2, 0x40, 0x86, + 0xf0, 0x77, 0x5c, 0xf8, 0x6e, 0xaf, 0xd5, 0xe4, 0xd5, 0x64, 0xc6, 0x44, 0xa4, 0x8b, 0x83, 0x91, + 0x42, 0x2f, 0x38, 0x67, 0xb5, 0x69, 0x09, 0xe0, 0x1d, 0xd6, 0x54, 0xdf, 0xd3, 0x04, 0x8d, 0x6a, + 0xd3, 0xa6, 0xc1, 0x5b, 0x33, 0xbc, 0xb9, 0xcf, 0xc1, 0x68, 0x38, 0x37, 0x4a, 0x7b, 0x1d, 0xf6, + 0xeb, 0x3a, 0x1c, 0x81, 0x50, 0x0d, 0x82, 0x56, 0xf4, 0x04, 0x2a, 0xba, 0x8d, 0x9e, 0xe5, 0xb2, + 0x8c, 0x19, 0x8d, 0x99, 0x5a, 0x96, 0x19, 0x19, 0x83, 0x7d, 0xa2, 0xc6, 0x60, 0xf5, 0xe0, 0x26, + 0xe5, 0xd0, 0x08, 0x0c, 0x59, 0x58, 0x48, 0x27, 0xe7, 0x96, 0x5a, 0x6d, 0x9f, 0x57, 0x2b, 0x59, + 0x61, 0xbe, 0xec, 0xe0, 0xdc, 0xff, 0x01, 0xa3, 0xaf, 0xfb, 0x7b, 0x00, 0x41, 0x44, 0x9c, 0x36, + 0xa4, 0x0a, 0x03, 0x12, 0xaf, 0xab, 0xc5, 0xb5, 0xca, 0xf5, 0xc6, 0xab, 0x7f, 0x60, 0x61, 0xfa, + 0x37, 0xf6, 0x65, 0x2d, 0x9d, 0xeb, 0x7c, 0x48, 0xbc, 0xad, 0xe5, 0xde, 0xf0, 0x8a, 0xb7, 0xa3, + 0xb9, 0x57, 0x30, 0x1a, 0x9e, 0x69, 0x6a, 0x17, 0x5e, 0xe4, 0x8e, 0x7a, 0xcc, 0x4a, 0x76, 0x34, + 0x65, 0x5b, 0x4d, 0xe6, 0x54, 0x6f, 0x06, 0xb6, 0xd5, 0x24, 0x67, 0x41, 0xc8, 0x75, 0xda, 0x37, + 0xbd, 0x8f, 0x6f, 0x67, 0x81, 0x2d, 0xce, 0x17, 0xd4, 0xdc, 0x4f, 0xb5, 0xd4, 0x16, 0xb6, 0x33, + 0xea, 0x92, 0xe3, 0x6f, 0x4b, 0xc7, 0xca, 0xbc, 0xd7, 0x2c, 0xe5, 0xb7, 0x59, 0x94, 0x3b, 0xd1, + 0xc1, 0xb9, 0x20, 0x88, 0x54, 0xf5, 0xaf, 0xa8, 0x8c, 0xa3, 0x6c, 0xa8, 0x2c, 0xf6, 0x25, 0xb8, + 0x6e, 0x69, 0x71, 0xa7, 0x81, 0x96, 0x0b, 0xe3, 0x7d, 0x41, 0xd6, 0xab, 0xe9, 0x2c, 0x90, 0x35, + 0x6e, 0x5f, 0x83, 0x57, 0x89, 0x10, 0xeb, 0x0d, 0x62, 0x93, 0x21, 0xa5, 0x91, 0xdb, 0x3d, 0x08, + 0x16, 0xcb, 0x17, 0x01, 0xb5, 0x7c, 0x57, 0x41, 0x50, 0xb8, 0x7d, 0xf9, 0x17, 0x2c, 0x39, 0xca, + 0xfd, 0xb3, 0x55, 0x31, 0x0c, 0x87, 0x2c, 0xf4, 0xc3, 0x16, 0x85, 0x94, 0xa7, 0x54, 0xa7, 0x58, + 0x66, 0x87, 0x16, 0x90, 0xc7, 0x42, 0x80, 0x60, 0x56, 0x6a, 0xe7, 0x53, 0x9c, 0xea, 0xc6, 0xe2, + 0xa2, 0xc7, 0xce, 0x31, 0x48, 0xf2, 0x46, 0x90, 0x5a, 0x66, 0xb9, 0xd0, 0x8d, 0xda, 0xb7, 0xc8, + 0xd8, 0xd7, 0xe9, 0xc2, 0xf9, 0xcc, 0x60, 0x41, 0xcf, 0xf0, 0x29, 0xb5, 0x36, 0x64, 0xda, 0x71, + 0xbb, 0xa1, 0x12, 0x44, 0xe2, 0x51, 0x43, 0xa9, 0xc1, 0x8c, 0x65, 0xa9, 0x50, 0x46, 0x6e, 0xa9, + 0xa5, 0x8e, 0xc0, 0x88, 0x7d, 0x67, 0xf4, 0xd4, 0x77, 0x68, 0x8c, 0x1e, 0x31, 0xa0, 0x3b, 0xf4, + 0x2d, 0x87, 0xcb, 0x31, 0xcd, 0x62, 0x40, 0x7f, 0xf4, 0x5b, 0xdc, 0x99, 0xe3, 0xfd, 0x51, 0x67, + 0xc4, 0x80, 0xe1, 0xd3, 0x6f, 0xc1, 0x66, 0x72, 0xfc, 0x75, 0x71, 0x30, 0xac, 0x62, 0x73, 0xca, + 0xf9, 0x8a, 0x12, 0x99, 0xf7, 0x13, 0xbd, 0xb1, 0xcf, 0x48, 0x57, 0x84, 0x20, 0x34, 0x46, 0x8d, + 0xfb, 0x90, 0xda, 0x42, 0x08, 0xa4, 0xfd, 0xd9, 0xe0, 0xcd, 0x63, 0x55, 0x4d, 0xca, 0x95, 0xad, + 0x37, 0x6c, 0xca, 0x4b, 0x6a, 0x14, 0x0b, 0x1e, 0x0c, 0xaf, 0xe0, 0x0a, 0x54, 0x40, 0xce, 0xf7, + 0x3b, 0xa7, 0x1b, 0xfb, 0x88, 0xa9, 0x03, 0x2a, 0x93, 0xd8, 0x3f, 0x00, 0x04, 0x8b, 0x52, 0x42, + 0x4d, 0x7a, 0x07, 0x54, 0xcc, 0x4a, 0xe9, 0x17, 0xbe, 0xa4, 0xa3, 0x23, 0xcd, 0x23, 0xb6, 0x87, + 0xd1, 0x7b, 0x5f, 0xae, 0x97, 0x72, 0x52, 0xef, 0xba, 0xf7, 0x01, 0x41, 0x8f, 0xfe, 0xf7, 0x3c, + 0x6a, 0x2b, 0x63, 0x47, 0xf9, 0xf8, 0x59, 0x99, 0x34, 0x06, 0xde, 0x9a, 0xaa, 0xd4, 0xa9, 0x8b, + 0xf8, 0xa5, 0xcb, 0x6d, 0xca, 0x47, 0xf7, 0x8f, 0xf0, 0xea, 0xe9, 0xe0, 0x0d, 0xc4, 0x7a, 0x01, + 0x0f, 0x9b, 0xf0, 0xb1, 0x63, 0xf9, 0x38, 0xae, 0xfa, 0x7f, 0x18, 0xaa, 0xc2, 0xdc, 0xc1, 0x34, + 0x1d, 0x77, 0x60, 0xc5, 0x78, 0x08, 0x5d, 0x88, 0xa9, 0x4d, 0xf5, 0x7a, 0xaf, 0x01, 0xb6, 0xe1, + 0x26, 0x1d, 0x31, 0x29, 0x13, 0xad, 0x7a, 0x98, 0x1b, 0x8c, 0x1e, 0x33, 0x38, 0x74, 0xb6, 0xdc, + 0x1c, 0xc5, 0x73, 0x4d, 0xf5, 0x71, 0x61, 0x2a, 0x3d, 0x2f, 0x55, 0xc6, 0x3e, 0x58, 0x09, 0xc1, + 0x50, 0xdc, 0x14, 0x13, 0xc8, 0xc2, 0x75, 0x98, 0x5e, 0xc1, 0x15, 0xbc, 0x02, 0xc1, 0x60, 0x52, + 0x03, 0xc9, 0x47, 0xcf, 0x34, 0xbe, 0x05, 0xc2, 0xb4, 0xa4, 0xeb, 0x74, 0x97, 0x32, 0xbe, 0x21, + 0xa5, 0x9f, 0x34, 0xc7, 0xb7, 0x71, 0xe9, 0x97, 0xb9, 0xf4, 0x7e, 0x0c, 0x9b, 0x20, 0x36, 0xd6, + 0xd5, 0x88, 0xde, 0x21, 0x5c, 0x44, 0x3a, 0x90, 0x0e, 0xfd, 0x7b, 0x8d, 0x27, 0xc2, 0xd3, 0x0d, + 0xdc, 0xeb, 0x5e, 0xee, 0x60, 0x2e, 0x98, 0xa3, 0x93, 0xfd, 0x9f, 0xb3, 0xad, 0xe1, 0xbc, 0x32, + 0x11, 0x58, 0x66, 0xd5, 0x4a, 0x95, 0x1d, 0xec, 0xa0, 0xc5, 0x96, 0x63, 0xce, 0xc5, 0x1d, 0x83, + 0x64, 0xe8, 0x5b, 0xe9, 0x1d, 0x8b, 0x93, 0xe5, 0x35, 0x4a, 0xc7, 0x38, 0x5c, 0x8f, 0x8a, 0x8b, + 0xb9, 0x82, 0xbe, 0x5a, 0xbc, 0x9f, 0xdb, 0x8d, 0xdb, 0xae, 0xe2, 0x71, 0xc3, 0x88, 0xc9, 0xd5, + 0x2c, 0x55, 0x6a, 0xa5, 0x34, 0x0d, 0x1e, 0xfa, 0xb8, 0x5f, 0x1c, 0xd0, 0x0b, 0x99, 0x10, 0xef, + 0x8e, 0xe1, 0x0e, 0x3e, 0x0f, 0x3d, 0x3d, 0x9f, 0x20, 0xc7, 0xda, 0xcc, 0xa5, 0x61, 0xe6, 0xdc, + 0xbc, 0x80, 0x51, 0xf9, 0xc5, 0x58, 0x24, 0x5c, 0x82, 0xef, 0x79, 0x4a, 0x99, 0x7d, 0x69, 0x09, + 0xb2, 0xe6, 0x35, 0xe3, 0xb9, 0x5c, 0x0c, 0xe3, 0xb0, 0xb8, 0x72, 0xac, 0xba, 0xf8, 0xb2, 0x31, + 0x9c, 0xf3, 0x3d, 0x8e, 0x30, 0x64, 0xa1, 0xa7, 0x18, 0x4f, 0x76, 0x84, 0x60, 0x91, 0x4b, 0xe4, + 0x7c, 0xab, 0x8f, 0x3d, 0xcf, 0xf6, 0x22, 0x48, 0x0b, 0x14, 0xdb, 0xa0, 0x59, 0xd6, 0xd8, 0x90, + 0x1b, 0x4c, 0xf7, 0x94, 0x66, 0x05, 0x40, 0xf8, 0xc8, 0x60, 0x5f, 0x3d, 0xcb, 0xe1, 0x1e, 0x8d, + 0x96, 0xb0, 0x20, 0x0b, 0x21, 0x6c, 0x51, 0x82, 0xeb, 0xff, 0x4e, 0x97, 0x0c, 0xc0, 0x57, 0x0b, + 0xcb, 0x6f, 0xc8, 0xef, 0x6c, 0xed, 0xa1, 0x42, 0x9c, 0xdf, 0xf9, 0xa3, 0x9e, 0x90, 0x34, 0x4b, + 0xf9, 0x3a, 0x8b, 0x22, 0x8c, 0x09, 0xba, 0xfa, 0x62, 0x63, 0x98, 0x4d, 0x09, 0x9b, 0x15, 0x54, + 0x28, 0xd7, 0x92, 0x79, 0x82, 0xc6, 0x92, 0xe7, 0xd3, 0x36, 0x8e, 0x99, 0x47, 0x06, 0x52, 0x2d, + 0x66, 0xe5, 0x91, 0x48, 0xd5, 0x21, 0xce, 0xd7, 0xba, 0x5e, 0x1c, 0xc7, 0x38, 0x63, 0xf2, 0xec, + 0xb2, 0x89, 0x65, 0x2c, 0xca, 0x61, 0x3a, 0x03, 0xe8, 0x7c, 0xc9, 0x79, 0x16, 0x65, 0xaf, 0x42, + 0xd7, 0x1f, 0xc0, 0x4f, 0x4b, 0x80, 0xd4, 0x0f, 0xc3, 0x82, 0xd3, 0xbd, 0x30, 0x1e, 0x52, 0x4f, + 0xf4, 0x07, 0xcb, 0x9c, 0x63, 0xc9, 0x76, 0x2d, 0x29, 0x57, 0xd7, 0xb9, 0x8d, 0x1e, 0x5f, 0x3f, + 0x15, 0x44, 0x41, 0xeb, 0x7a, 0x94, 0x71, 0x4e, 0x72, 0x81, 0x89, 0x16, 0xee, 0x0d, 0x6c, 0x4d, + 0x08, 0x6c, 0xd5, 0x2b, 0x0f, 0x26, 0xaa, 0xaa, 0x3f, 0xc6, 0x16, 0xb0, 0xc5, 0x01, 0x5a, 0x81, + 0xad, 0xba, 0xc0, 0x56, 0xad, 0x12, 0xab, 0x66, 0x97, 0x26, 0xdb, 0x94, 0xa8, 0xc4, 0x11, 0x32, + 0x4a, 0x57, 0x04, 0x19, 0xe7, 0xbd, 0x92, 0x49, 0x1f, 0xbe, 0x1c, 0x64, 0x3d, 0x2e, 0x07, 0xe5, + 0x7d, 0xab, 0xba, 0x67, 0x05, 0x34, 0x08, 0x3c, 0x13, 0x0b, 0xb5, 0x40, 0x14, 0xcd, 0xea, 0xf2, + 0x8b, 0x12, 0x41, 0x55, 0x41, 0x3f, 0xf2, 0x40, 0x17, 0xaf, 0x03, 0x2e, 0x8b, 0x95, 0xb1, 0x0c, + 0xf7, 0x56, 0xc3, 0xcc, 0x7c, 0xbd, 0xeb, 0x31, 0xc6, 0x99, 0xe7, 0x7a, 0x09, 0x66, 0xf2, 0x6d, + 0x7a, 0xc1, 0x68, 0x3c, 0xf1, 0x09, 0x52, 0x3d, 0x3c, 0x2f, 0x41, 0x7a, 0xc9, 0x10, 0x73, 0xb6, + 0xea, 0x73, 0xc6, 0x1f, 0x08, 0xe4, 0xe4, 0x94, 0xb2, 0x39, 0xe6, 0xbc, 0xdc, 0x1c, 0x9b, 0x72, + 0x2f, 0x5d, 0x65, 0x4f, 0x04, 0x3c, 0x1a, 0x53, 0x59, 0x16, 0x14, 0xab, 0xfa, 0x2a, 0x57, 0x3d, + 0x15, 0xe7, 0x9c, 0x87, 0xb5, 0x60, 0xe4, 0x9b, 0x22, 0x74, 0x31, 0xf4, 0x18, 0x11, 0xd3, 0x49, + 0xa7, 0xa3, 0x03, 0xa7, 0x72, 0xe8, 0x1a, 0xb5, 0x39, 0xb0, 0x2d, 0x41, 0x39, 0x74, 0x1f, 0xc5, + 0x85, 0x34, 0x56, 0x5f, 0x75, 0x4e, 0x91, 0x1e, 0x95, 0xb2, 0x34, 0xef, 0x63, 0x6d, 0xb2, 0x0c, + 0x5b, 0x02, 0x09, 0x1f, 0x3a, 0x8a, 0x2f, 0xbe, 0x30, 0xd2, 0x6f, 0xf4, 0x00, 0x0f, 0x02, 0x0e, + 0x43, 0xc0, 0x91, 0x60, 0x36, 0xe7, 0x59, 0x02, 0x96, 0x58, 0x10, 0x0b, 0xf8, 0x41, 0x0a, 0x81, + 0x07, 0x52, 0xdc, 0x14, 0xce, 0xb2, 0x9d, 0xbf, 0x66, 0xf0, 0xcc, 0x04, 0x40, 0x57, 0xe6, 0xdd, + 0x17, 0x5a, 0xc1, 0x41, 0x25, 0x78, 0x22, 0x41, 0x4a, 0x37, 0x90, 0xcb, 0x51, 0x5e, 0xa7, 0x23, + 0x78, 0x3e, 0x8c, 0x2e, 0x85, 0xe9, 0x21, 0x7e, 0x4e, 0xea, 0x85, 0x29, 0x2f, 0x7e, 0xe0, 0x10, + 0xa6, 0x52, 0x4e, 0x71, 0x19, 0x97, 0x61, 0xf6, 0xe1, 0x2f, 0xe7, 0x01, 0x61, 0x02, 0x82, 0x1f, + 0x94, 0x46, 0x1b, 0x30, 0x63, 0x4f, 0xe1, 0x74, 0x2c, 0x64, 0x60, 0x22, 0x1d, 0x0d, 0x6e, 0x1d, + 0x40, 0x98, 0x66, 0x85, 0x12, 0xba, 0xb8, 0xb0, 0x2e, 0x41, 0x4a, 0x35, 0x80, 0xdb, 0x97, 0x72, + 0x25, 0xbe, 0x89, 0x5c, 0xa4, 0xb0, 0xe4, 0xa5, 0xd1, 0x04, 0x5d, 0x6f, 0x6d, 0xc5, 0x3b, 0x14, + 0x23, 0x5c, 0x92, 0xcf, 0x99, 0x49, 0xf9, 0x46, 0xc7, 0x84, 0xeb, 0x14, 0xba, 0x51, 0x4e, 0x6c, + 0x62, 0x14, 0x2e, 0xe0, 0x41, 0x88, 0x21, 0x0b, 0xe7, 0xf2, 0x4a, 0x23, 0xf2, 0xec, 0xb8, 0x43, + 0x6e, 0xb3, 0x28, 0x19, 0x5a, 0xaa, 0x02, 0x8d, 0x59, 0x11, 0x8c, 0x7d, 0x2d, 0x44, 0x49, 0x36, + 0xe5, 0xbf, 0xc3, 0xef, 0x7a, 0x94, 0x1e, 0xdc, 0x36, 0xd0, 0x29, 0xa9, 0x33, 0x43, 0xc3, 0x25, + 0x6d, 0xd2, 0x54, 0x3d, 0x12, 0xef, 0xaa, 0x73, 0x5c, 0x4a, 0x38, 0x57, 0xfd, 0x6f, 0x68, 0xae, + 0x9e, 0xd4, 0xf9, 0xbe, 0x2d, 0xd5, 0x2b, 0x93, 0x83, 0xb5, 0x1a, 0xd0, 0x70, 0x86, 0x1f, 0xa5, + 0xe7, 0x0c, 0x02, 0x79, 0x76, 0x5c, 0x71, 0xcf, 0xb3, 0xc9, 0xf2, 0xf9, 0x3e, 0xe0, 0xab, 0x59, + 0x39, 0x3f, 0x26, 0xb8, 0xdc, 0xea, 0xc6, 0x0c, 0x71, 0x80, 0x75, 0x4e, 0x5a, 0x16, 0xa0, 0x5b, + 0xd9, 0xef, 0x40, 0x67, 0x55, 0x8d, 0x58, 0x1d, 0x00, 0xf8, 0x1a, 0x25, 0xf7, 0x0e, 0x90, 0x6e, + 0x92, 0xa1, 0x35, 0x2b, 0x9e, 0x19, 0x2a, 0xe4, 0x0c, 0x8d, 0x24, 0x3f, 0x0f, 0x99, 0xde, 0x1b, + 0x63, 0x41, 0xf7, 0x03, 0x0e, 0x6d, 0x6e, 0x0e, 0x9d, 0x58, 0x5e, 0x52, 0x61, 0xbe, 0x87, 0x98, + 0x91, 0x0c, 0x1d, 0xa1, 0x28, 0x42, 0x8c, 0x08, 0x46, 0x89, 0xc4, 0xad, 0x01, 0x51, 0xa3, 0xee, + 0x79, 0xbf, 0x04, 0x9e, 0x22, 0xaf, 0x48, 0x19, 0x5a, 0x30, 0x80, 0xb2, 0xfb, 0x3c, 0x78, 0x0b, + 0x4d, 0x7c, 0x1b, 0xb2, 0x2b, 0x9b, 0x3b, 0xb0, 0x26, 0x00, 0x4e, 0x78, 0x34, 0x7a, 0xe3, 0x11, + 0x35, 0xda, 0x54, 0xdf, 0xff, 0x36, 0xd2, 0x65, 0x21, 0x98, 0x56, 0x31, 0xc0, 0xfe, 0x2d, 0x95, + 0xac, 0x87, 0xf0, 0xd0, 0xd8, 0x3e, 0xba, 0x12, 0xdb, 0x2e, 0xaf, 0x9c, 0x01, 0x06, 0x19, 0x2c, + 0xa4, 0x81, 0xd4, 0x8b, 0x9f, 0xb3, 0x49, 0x8d, 0xb2, 0x73, 0xd2, 0x75, 0x71, 0x48, 0xb3, 0x33, + 0x59, 0x4e, 0x60, 0xc5, 0x1e, 0x96, 0xbd, 0xe2, 0x7a, 0x21, 0x9c, 0x75, 0x46, 0xba, 0x5e, 0x08, + 0x0b, 0x13, 0x12, 0x5c, 0x8b, 0x57, 0x0b, 0xd1, 0xae, 0x17, 0x58, 0x13, 0x57, 0x8d, 0x2b, 0xb9, + 0xdc, 0x81, 0x27, 0xc2, 0x92, 0xae, 0xb3, 0x57, 0xc4, 0xa1, 0xf0, 0x97, 0xda, 0x8c, 0xe7, 0x40, + 0x7b, 0x93, 0xb8, 0x03, 0x09, 0x31, 0xe2, 0xed, 0xb9, 0xce, 0x31, 0xe2, 0xed, 0x25, 0x42, 0x94, + 0x2f, 0xde, 0xb5, 0x33, 0x86, 0x5d, 0xe2, 0x9c, 0x20, 0x57, 0xb0, 0x35, 0xbf, 0xb8, 0x07, 0x09, + 0x95, 0xd2, 0x48, 0x7a, 0x84, 0xcb, 0xa4, 0xbe, 0xb1, 0x9a, 0x26, 0x19, 0x15, 0xff, 0xbb, 0x54, + 0xcd, 0x0e, 0x99, 0x05, 0xe7, 0x7c, 0x09, 0xf1, 0x0a, 0x03, 0x43, 0x9e, 0xe4, 0xc5, 0xe5, 0x64, + 0xdf, 0xdc, 0xaa, 0x5b, 0x2c, 0xee, 0xf7, 0xef, 0xc6, 0xd3, 0x37, 0xa4, 0xb9, 0xea, 0x06, 0x03, + 0xf1, 0xe2, 0x2c, 0xdc, 0xe5, 0x60, 0xeb, 0xe9, 0x82, 0xaf, 0x0f, 0xd7, 0xf1, 0xa1, 0x15, 0xc1, + 0xb5, 0xdd, 0x76, 0xe0, 0x08, 0xe7, 0x1e, 0x83, 0x3b, 0xd5, 0x4f, 0x70, 0x07, 0x2a, 0xc2, 0xc4, + 0xc6, 0xdb, 0x5c, 0x35, 0x2e, 0xa4, 0x57, 0x0d, 0xd1, 0x13, 0x09, 0x22, 0x6a, 0x99, 0x58, 0x1f, + 0x61, 0xcb, 0x95, 0x29, 0x03, 0xcd, 0x4a, 0xe9, 0x83, 0xc1, 0x08, 0xe5, 0x61, 0x8a, 0x58, 0xd0, + 0xf7, 0x52, 0xf1, 0xe3, 0xdc, 0x4f, 0x04, 0x46, 0x60, 0xf9, 0x1c, 0xb4, 0xed, 0xb4, 0xe2, 0x24, + 0x50, 0xd9, 0x01, 0x36, 0x40, 0x82, 0xb8, 0x6f, 0x5d, 0x98, 0x54, 0x1e, 0xed, 0x7a, 0x29, 0xc0, + 0x38, 0x0b, 0xfb, 0xf8, 0x36, 0xd6, 0x39, 0x3e, 0x20, 0x74, 0xe1, 0x56, 0x58, 0xf5, 0x74, 0x3a, + 0x20, 0x9b, 0x72, 0x9c, 0xbe, 0x68, 0xbc, 0x5f, 0x8c, 0x35, 0x9e, 0xc8, 0xb1, 0xe5, 0x80, 0x6b, + 0xad, 0x50, 0x9e, 0x4b, 0xea, 0x72, 0x3b, 0xc6, 0x90, 0x6d, 0x44, 0x08, 0xf2, 0xb3, 0xf3, 0x21, + 0xf8, 0x53, 0xaa, 0x43, 0x6d, 0xc8, 0x98, 0x1e, 0xdc, 0x92, 0xc2, 0x90, 0x0e, 0x85, 0x9f, 0x6a, + 0x03, 0x4a, 0xc4, 0x3a, 0x0d, 0x29, 0xd7, 0x92, 0x46, 0x08, 0x67, 0xec, 0xd3, 0x47, 0x6d, 0x87, + 0x3d, 0x36, 0x9d, 0x6e, 0x87, 0x95, 0xc3, 0x8f, 0x04, 0xa1, 0x60, 0x76, 0x42, 0x53, 0xf6, 0xdd, + 0x20, 0x23, 0x5b, 0xe3, 0x3b, 0x60, 0x5f, 0xa2, 0x6e, 0x67, 0x67, 0xc0, 0xf8, 0xec, 0x83, 0xb8, + 0x37, 0xda, 0x83, 0x16, 0xd2, 0x14, 0x8b, 0x4a, 0x6a, 0xd6, 0x4b, 0x61, 0x52, 0xae, 0xc6, 0xfb, + 0xf9, 0xd8, 0x70, 0xab, 0x5e, 0x6c, 0x65, 0x54, 0x17, 0x21, 0x27, 0x17, 0xcd, 0x62, 0xb2, 0xf2, + 0x3f, 0x34, 0x16, 0x88, 0x0b, 0x99, 0x54, 0x40, 0xb1, 0x5c, 0xaf, 0xbc, 0x4b, 0x37, 0x62, 0xb4, + 0xa1, 0x4c, 0xd1, 0x03, 0xc4, 0x5f, 0xcf, 0xbd, 0xee, 0x51, 0x33, 0x4c, 0x5a, 0x39, 0xe7, 0x97, + 0x72, 0x5a, 0xbb, 0x38, 0x38, 0x99, 0xcb, 0xf0, 0x86, 0xf2, 0x48, 0x73, 0x7f, 0x1b, 0xb7, 0x5c, + 0x4d, 0x5a, 0x70, 0xfd, 0x91, 0xd7, 0xd6, 0xc6, 0x1b, 0xcf, 0x81, 0x81, 0x8b, 0xae, 0x49, 0xd0, + 0xd7, 0x3e, 0x15, 0xc3, 0xa6, 0xfb, 0x7a, 0x1a, 0x21, 0xdc, 0x1e, 0xb9, 0x44, 0xa9, 0xad, 0x0d, + 0xab, 0x9d, 0xb1, 0xa8, 0x5d, 0x98, 0x00, 0x2e, 0x2c, 0x38, 0xb4, 0x71, 0xb5, 0x9a, 0x87, 0x6a, + 0x13, 0x8d, 0x59, 0x8b, 0xda, 0x9d, 0xdd, 0xc6, 0x13, 0x8b, 0xda, 0xb9, 0x77, 0xbc, 0x72, 0x66, + 0x54, 0xc0, 0x17, 0x66, 0xf4, 0xdc, 0x75, 0x4c, 0x54, 0xd0, 0xdc, 0x51, 0x46, 0xde, 0x7e, 0x0c, + 0xe6, 0xb1, 0x33, 0x06, 0x31, 0x30, 0x99, 0x3b, 0x1a, 0xc3, 0x65, 0xf8, 0xc9, 0x25, 0xf1, 0xac, + 0x41, 0x5e, 0x79, 0x4c, 0xbc, 0x05, 0x78, 0x0d, 0xa6, 0x0c, 0x09, 0x0b, 0x55, 0xa8, 0x4b, 0x69, + 0x7d, 0x4d, 0x32, 0xb4, 0xe4, 0x8e, 0xc6, 0x1a, 0xe5, 0xe5, 0xc7, 0x48, 0x13, 0xd4, 0xa4, 0xd5, + 0x06, 0xa0, 0x3e, 0x39, 0x2f, 0x9e, 0x52, 0x53, 0x57, 0xb2, 0x52, 0x3e, 0x73, 0xfe, 0x05, 0x7a, + 0x6e, 0x19, 0xd9, 0xf3, 0xb0, 0xb1, 0x82, 0xb9, 0x06, 0x94, 0xd1, 0x80, 0xe7, 0x5c, 0x05, 0xed, + 0x0a, 0x88, 0x11, 0x3d, 0xb5, 0x09, 0x8f, 0x2e, 0x4e, 0x58, 0x2c, 0xc4, 0xc0, 0x30, 0xef, 0x4d, + 0xb9, 0x05, 0xca, 0x2c, 0xfc, 0xaf, 0x6f, 0x3c, 0xc8, 0x76, 0x34, 0xf7, 0x8e, 0x87, 0x3b, 0xe0, + 0x91, 0x33, 0x99, 0x40, 0xa8, 0x3d, 0x44, 0x02, 0x40, 0x26, 0xd7, 0x4e, 0x96, 0x65, 0xe4, 0x54, + 0x56, 0xe8, 0x1b, 0x79, 0x7c, 0x56, 0xd0, 0x1e, 0xbb, 0x83, 0x27, 0x78, 0xa2, 0xd1, 0x5b, 0xb4, + 0x29, 0xbf, 0x62, 0xd4, 0xc0, 0xc6, 0xe4, 0x4f, 0x39, 0xe3, 0x7c, 0xcc, 0x95, 0xc2, 0x70, 0x6f, + 0x36, 0x88, 0x20, 0xb4, 0x6f, 0x35, 0x55, 0x7f, 0x26, 0xcc, 0x3b, 0x8a, 0x56, 0x29, 0xa5, 0x91, + 0x1e, 0x24, 0x8e, 0xbf, 0x58, 0x31, 0x3d, 0xad, 0x26, 0x73, 0x99, 0x3f, 0x9b, 0x9c, 0x11, 0x3c, + 0x32, 0xdf, 0x55, 0xaa, 0xc1, 0xf9, 0x4e, 0xd9, 0x32, 0x3b, 0xb8, 0x0f, 0x06, 0x9e, 0xb4, 0x67, + 0x79, 0xe8, 0x40, 0x26, 0x74, 0x58, 0x0b, 0x22, 0xe3, 0x75, 0xdd, 0xe0, 0x3c, 0x8a, 0x06, 0xf0, + 0x63, 0x3d, 0xb2, 0xc6, 0xc5, 0x34, 0xab, 0x25, 0x26, 0xa0, 0x92, 0x97, 0x9c, 0x74, 0xd5, 0xff, + 0xd2, 0x35, 0x18, 0xb1, 0x2d, 0x42, 0xf4, 0xfc, 0xc6, 0x37, 0x0d, 0x93, 0xc7, 0x82, 0xc9, 0x13, + 0x3e, 0xce, 0xe5, 0x6d, 0x11, 0x3d, 0x2d, 0xc6, 0x73, 0x2b, 0x5d, 0xb7, 0xa2, 0xb9, 0x8c, 0xfa, + 0x11, 0x43, 0x80, 0xa0, 0x8e, 0xd7, 0x03, 0x43, 0x71, 0x97, 0x96, 0xf7, 0x1b, 0x4f, 0x70, 0x47, + 0x27, 0x93, 0x36, 0xcd, 0x2f, 0x97, 0x62, 0xcb, 0x86, 0xdf, 0xf8, 0xe2, 0x20, 0x71, 0x4c, 0x4d, + 0x9c, 0xf0, 0x8d, 0x85, 0x44, 0xcb, 0xd2, 0xa8, 0x6d, 0x73, 0xc5, 0x86, 0x16, 0xf1, 0x76, 0xc0, + 0x79, 0x3f, 0xf1, 0x83, 0xd7, 0x28, 0x55, 0xea, 0xfb, 0xbf, 0xe2, 0xf6, 0x9d, 0x65, 0x5b, 0x21, + 0x76, 0xf5, 0xb3, 0xdd, 0xe4, 0x8a, 0x77, 0x70, 0x3a, 0xdb, 0x16, 0xd3, 0x0a, 0x13, 0x4c, 0x3a, + 0x69, 0xf4, 0x7d, 0x04, 0xd3, 0x35, 0xfa, 0x37, 0x44, 0x0f, 0xd5, 0x4f, 0x8e, 0x18, 0x12, 0x32, + 0xa6, 0x12, 0x39, 0xc2, 0x1d, 0xe0, 0xd0, 0x4e, 0x4e, 0x02, 0x4c, 0xdc, 0x27, 0x84, 0x7b, 0x81, + 0x90, 0xe5, 0x74, 0xf5, 0x4d, 0xdb, 0x39, 0x0b, 0xf4, 0xbb, 0x31, 0x72, 0x9e, 0xfc, 0x34, 0xeb, + 0x33, 0x42, 0xf6, 0x8f, 0xd4, 0x6c, 0x9b, 0x52, 0x34, 0x14, 0xdc, 0x69, 0x61, 0x7b, 0x7d, 0xf1, + 0xd9, 0xb5, 0x63, 0x96, 0xce, 0x73, 0xc6, 0x40, 0x1c, 0x89, 0xa6, 0x15, 0xa3, 0xa0, 0x9a, 0xf0, + 0xec, 0x0c, 0x5f, 0x67, 0xf6, 0xfe, 0x79, 0xae, 0xc7, 0xe6, 0x39, 0xbf, 0x28, 0x0d, 0xb3, 0xb7, + 0xad, 0xc5, 0xd3, 0x0e, 0xdf, 0xd2, 0xe6, 0x3a, 0x8c, 0xd7, 0xf0, 0x14, 0x69, 0x69, 0xb8, 0xfd, + 0x33, 0x9a, 0x7f, 0x69, 0x38, 0xff, 0x3f, 0xd5, 0xfc, 0xab, 0x34, 0xff, 0x58, 0x28, 0xdf, 0xf9, + 0x62, 0xa9, 0xc6, 0xfe, 0x05, 0xcd, 0xfb, 0xdd, 0xdd, 0xbc, 0x8d, 0x50, 0xef, 0x77, 0xf4, 0x14, + 0xc5, 0xbf, 0xdd, 0xcd, 0x5b, 0x00, 0x7d, 0x0d, 0x99, 0x31, 0x4f, 0x1c, 0x86, 0xf9, 0x14, 0x5a, + 0xac, 0x8c, 0x40, 0x8a, 0x9f, 0xab, 0xce, 0x85, 0x57, 0xdc, 0x0f, 0xad, 0x5e, 0x81, 0x61, 0x61, + 0xf8, 0x3c, 0x6a, 0xbb, 0x32, 0x5c, 0x2f, 0x06, 0xe6, 0xc9, 0x4f, 0x06, 0x04, 0x70, 0x1a, 0x52, + 0x7a, 0xb9, 0x37, 0x3d, 0x8d, 0x9a, 0x70, 0x86, 0x6d, 0x10, 0x9b, 0xc2, 0x3a, 0x67, 0xfe, 0xb3, + 0x62, 0xb6, 0x41, 0x85, 0x96, 0xd9, 0x80, 0x25, 0x1c, 0xdf, 0xd0, 0x38, 0xbc, 0xbc, 0x04, 0xfe, + 0xaf, 0xa0, 0x93, 0x79, 0xf0, 0xdc, 0x07, 0x1a, 0x23, 0xfe, 0x03, 0xed, 0xe6, 0xbb, 0x78, 0xae, + 0xa2, 0xda, 0x23, 0x8d, 0x6b, 0x99, 0xa1, 0x61, 0x9c, 0xb1, 0x40, 0x60, 0xbd, 0x32, 0xfb, 0x13, + 0x56, 0xcd, 0x57, 0x73, 0xc5, 0x5b, 0xe1, 0x87, 0xa6, 0xad, 0x81, 0xc8, 0xf6, 0xb7, 0x6b, 0x30, + 0xb2, 0x3d, 0x09, 0x71, 0x7d, 0xe6, 0xc9, 0x1c, 0xe5, 0x6d, 0xea, 0xcb, 0x6a, 0x02, 0xc2, 0x80, + 0x4d, 0xf9, 0x60, 0xac, 0xba, 0x95, 0xc0, 0xe2, 0xf1, 0x89, 0x97, 0xd4, 0x02, 0x30, 0x5c, 0x8b, + 0x27, 0x8c, 0x3c, 0xbd, 0xe2, 0x4c, 0x71, 0x55, 0x6a, 0x19, 0xe7, 0x7c, 0xd7, 0xb2, 0x4d, 0x78, + 0xe2, 0xbf, 0xee, 0xc7, 0x30, 0xfb, 0x1f, 0xea, 0x35, 0x23, 0xcc, 0xe6, 0x1c, 0xfb, 0x25, 0x3c, + 0x50, 0x91, 0xa9, 0xc2, 0x51, 0x5e, 0xfe, 0x8e, 0x61, 0x14, 0xe3, 0x21, 0x6a, 0xfd, 0x3e, 0x59, + 0x1d, 0xc6, 0xd8, 0x33, 0x80, 0x92, 0xca, 0xfd, 0x2a, 0x60, 0x65, 0xfb, 0xe9, 0xe1, 0x58, 0x2e, + 0x39, 0xe8, 0xcb, 0x72, 0xee, 0x7a, 0x1a, 0x4d, 0x81, 0x81, 0x1e, 0x6b, 0x4a, 0xe0, 0xaa, 0x7f, + 0x4f, 0x23, 0xee, 0x58, 0x50, 0x6d, 0xc9, 0x11, 0xcb, 0xed, 0x73, 0x68, 0x70, 0xe9, 0x87, 0x08, + 0x0a, 0x19, 0x62, 0xcf, 0x80, 0x54, 0xc6, 0xd4, 0xd3, 0x13, 0x10, 0xc4, 0xda, 0x96, 0x4b, 0x84, + 0x0b, 0x36, 0xe5, 0x9b, 0xb3, 0x6a, 0x44, 0xe3, 0x25, 0x17, 0xc5, 0x17, 0x0d, 0x2c, 0xa9, 0xf4, + 0x0b, 0x93, 0xa4, 0x8c, 0xd9, 0xc6, 0x66, 0x72, 0x52, 0x7a, 0x7c, 0x8e, 0xb1, 0x3b, 0xca, 0x4b, + 0x5a, 0x55, 0xe1, 0x81, 0xa0, 0x28, 0xb8, 0x16, 0x24, 0xbe, 0x98, 0xc8, 0x48, 0x19, 0xb1, 0x44, + 0x68, 0x17, 0x26, 0x72, 0xfb, 0x32, 0x34, 0x66, 0xa5, 0x26, 0x3e, 0xe8, 0x37, 0x24, 0x42, 0xbe, + 0x64, 0x49, 0x26, 0xd6, 0xd3, 0xd2, 0xe3, 0x0b, 0x88, 0xa9, 0x59, 0xde, 0x1f, 0x50, 0xcf, 0xbd, + 0xaf, 0xf0, 0x7b, 0x87, 0xa2, 0x48, 0xbf, 0x37, 0x30, 0x3d, 0xcf, 0x96, 0x93, 0xab, 0x6c, 0xbb, + 0xdb, 0xad, 0xf5, 0x5a, 0xff, 0x97, 0x84, 0x6f, 0x01, 0x1d, 0xb9, 0xc6, 0x5e, 0x24, 0xa6, 0xe3, + 0xb8, 0x33, 0x30, 0x24, 0x99, 0x4e, 0x3f, 0x68, 0x6a, 0x91, 0xf8, 0xe6, 0x78, 0xbf, 0xb1, 0x2f, + 0xaa, 0x99, 0x73, 0x5f, 0xc0, 0xd9, 0xe1, 0x45, 0x8d, 0xf4, 0xb8, 0x46, 0xca, 0x6f, 0xe7, 0xf6, + 0x5d, 0x86, 0x19, 0xad, 0xff, 0x06, 0x46, 0x5b, 0xda, 0x70, 0xfe, 0xf8, 0x44, 0xeb, 0xb5, 0xbc, + 0x5c, 0x73, 0xc0, 0x91, 0x68, 0x51, 0xde, 0x3b, 0x1f, 0x3c, 0x9f, 0xe8, 0x9c, 0x8c, 0xf3, 0x6b, + 0xf5, 0x2f, 0x10, 0xdd, 0xa6, 0x80, 0x78, 0x11, 0x66, 0xa7, 0x28, 0xbf, 0x70, 0xac, 0x53, 0x42, + 0xa7, 0x31, 0xc3, 0xc0, 0xd2, 0xe8, 0xaf, 0x83, 0x3c, 0x3e, 0x5b, 0x12, 0xda, 0x89, 0x63, 0x0e, + 0xc4, 0xcf, 0x12, 0x1f, 0x47, 0x4e, 0x12, 0x6f, 0xd2, 0x2d, 0xa9, 0x32, 0x61, 0x4a, 0x65, 0x17, + 0x69, 0x81, 0x50, 0xae, 0xff, 0x0b, 0x6e, 0x5f, 0x2f, 0x7b, 0x51, 0xb2, 0x5e, 0x48, 0xaa, 0x97, + 0xf8, 0xb6, 0x78, 0x7f, 0xd2, 0x79, 0xd5, 0x4c, 0x35, 0xa6, 0x5c, 0x26, 0x03, 0x10, 0x69, 0x41, + 0x2c, 0x57, 0x09, 0x7f, 0x01, 0x1f, 0x1d, 0x3b, 0x00, 0xe6, 0x30, 0x3c, 0x27, 0xd1, 0x92, 0x6b, + 0x56, 0x8e, 0xdd, 0x17, 0x3c, 0xa0, 0xa7, 0x63, 0x3f, 0x03, 0x1c, 0x63, 0x7a, 0x96, 0x54, 0xc6, + 0x91, 0x96, 0x29, 0x7c, 0x82, 0xca, 0x19, 0x6e, 0xf7, 0x16, 0x50, 0xd4, 0xfd, 0x2c, 0x9a, 0x63, + 0xf1, 0x78, 0xb2, 0xba, 0x98, 0xfe, 0xc4, 0x2a, 0xca, 0xf5, 0x35, 0xdf, 0x0d, 0xf3, 0xf8, 0x29, + 0xb9, 0xf2, 0xed, 0xd2, 0xa7, 0xf0, 0x08, 0xb3, 0x78, 0x9f, 0x6a, 0xff, 0x4e, 0xfc, 0x89, 0x85, + 0x49, 0x40, 0xd2, 0xc8, 0xb8, 0x4c, 0x0d, 0xa1, 0xd4, 0xad, 0xe9, 0xa5, 0x4c, 0xe9, 0x53, 0xe0, + 0xc1, 0xa3, 0x91, 0xbc, 0x41, 0x75, 0x0b, 0x2f, 0x7e, 0x4d, 0xa3, 0x27, 0x9b, 0xee, 0x1d, 0x0c, + 0xe9, 0x9f, 0xde, 0xe8, 0xe9, 0x6b, 0x60, 0x69, 0x24, 0x4a, 0xba, 0x05, 0x8f, 0x2f, 0xa9, 0xaa, + 0xf2, 0x5d, 0x70, 0x4b, 0x18, 0x61, 0x9a, 0xc4, 0x5f, 0x03, 0x2b, 0x47, 0xd2, 0xe9, 0x91, 0xd6, + 0x74, 0xad, 0xc4, 0xb7, 0x48, 0xa6, 0x0b, 0x64, 0xa5, 0x86, 0x84, 0x85, 0xd0, 0x7b, 0x6a, 0xd4, + 0xd6, 0x6b, 0x26, 0xd8, 0x25, 0xb9, 0x12, 0x42, 0xbe, 0x31, 0x78, 0xaf, 0xc1, 0x52, 0xca, 0x5a, + 0xec, 0x47, 0xf1, 0xac, 0x91, 0x4d, 0xd9, 0xa0, 0xf6, 0xce, 0x1d, 0x18, 0xf3, 0xe1, 0x4b, 0x9c, + 0x7b, 0x1b, 0x64, 0xd2, 0xd2, 0x33, 0x6a, 0x29, 0x1f, 0x2a, 0xe5, 0x7b, 0xb0, 0x18, 0x4f, 0x3a, + 0x04, 0x9b, 0x5f, 0x57, 0x2b, 0x24, 0x8e, 0xae, 0xf0, 0x48, 0xa8, 0xfd, 0x37, 0x6a, 0x71, 0xc4, + 0xe8, 0xe2, 0x38, 0xda, 0x9e, 0x1e, 0xe5, 0x23, 0x7e, 0x59, 0xf8, 0xa3, 0x25, 0xc7, 0x52, 0xaa, + 0xb1, 0x99, 0x95, 0xeb, 0x74, 0xa3, 0x3e, 0x8e, 0xee, 0xa2, 0x9b, 0xed, 0xf7, 0xac, 0x46, 0x37, + 0x5b, 0x9c, 0x19, 0x5c, 0xeb, 0xe1, 0xaa, 0xf1, 0x9a, 0x02, 0xdd, 0xd9, 0xb4, 0x98, 0x2d, 0xa5, + 0xe1, 0x36, 0x74, 0x6f, 0x7e, 0x1f, 0x6c, 0x41, 0xf7, 0x3b, 0xed, 0xe1, 0x39, 0xd8, 0x22, 0x67, + 0xb8, 0xc5, 0x3e, 0x7a, 0x7f, 0xa3, 0x2e, 0x3c, 0xd8, 0x66, 0x21, 0x6d, 0xb3, 0x3d, 0xd8, 0x26, + 0x9c, 0xb6, 0xc1, 0x7d, 0x07, 0x9b, 0x32, 0x35, 0xd4, 0xc6, 0xf9, 0x92, 0x45, 0x2d, 0xb0, 0x94, + 0xe6, 0xd2, 0xda, 0x2b, 0xff, 0x49, 0xed, 0x6f, 0x67, 0x84, 0x6a, 0xe7, 0x00, 0xf4, 0x88, 0x51, + 0x18, 0x4d, 0x0e, 0xd6, 0x8f, 0xa0, 0xf5, 0x4f, 0xd0, 0x31, 0x1c, 0xbb, 0x5b, 0x7f, 0x86, 0xa5, + 0x34, 0xcc, 0x62, 0x5f, 0x14, 0xda, 0x20, 0xfc, 0xdf, 0xdb, 0x2a, 0x5d, 0x0e, 0xf2, 0x3d, 0xea, + 0x06, 0xe3, 0x5b, 0x0d, 0xb8, 0x5f, 0x9e, 0x19, 0x62, 0x9a, 0x1a, 0xf9, 0x1b, 0xfb, 0xf2, 0x94, + 0xc5, 0xea, 0xdc, 0x00, 0x0e, 0xc4, 0x64, 0xa3, 0x47, 0x16, 0x6e, 0x9a, 0x61, 0x6a, 0xb5, 0xe3, + 0x29, 0x0f, 0x5b, 0x9e, 0xf2, 0x6b, 0x15, 0x8a, 0xb4, 0x10, 0xc3, 0x19, 0xcd, 0xf0, 0x46, 0x61, + 0x55, 0x57, 0x2c, 0xae, 0x63, 0xba, 0xdb, 0xd1, 0xdb, 0x7b, 0x0a, 0x97, 0x71, 0x07, 0x0d, 0xc1, + 0x89, 0xf8, 0x4f, 0xac, 0xb4, 0xd4, 0x4d, 0xa5, 0x70, 0xc8, 0x3b, 0x44, 0xa5, 0xd0, 0x96, 0xa7, + 0x56, 0xa4, 0x13, 0xb6, 0xf5, 0xf6, 0x48, 0x59, 0x0c, 0x16, 0x28, 0xee, 0xfe, 0x90, 0x44, 0xc6, + 0x86, 0xe4, 0x91, 0x9e, 0x33, 0x11, 0xfe, 0xd4, 0xb9, 0x19, 0x7e, 0xab, 0x8e, 0x28, 0xb8, 0xb7, + 0x09, 0x82, 0xc9, 0xb9, 0x71, 0xc3, 0x9d, 0xdc, 0xc6, 0xa9, 0x26, 0x00, 0xf3, 0x5f, 0x8a, 0x3b, + 0x19, 0xcf, 0x98, 0xbc, 0xfc, 0x05, 0x8c, 0xfb, 0x90, 0x8b, 0x9e, 0x72, 0x51, 0xcf, 0x47, 0xe7, + 0x80, 0xb6, 0x15, 0x1b, 0x82, 0xa7, 0xa3, 0x67, 0x63, 0x9d, 0x7d, 0x7e, 0x02, 0x3a, 0x07, 0x73, + 0x2f, 0xdb, 0x23, 0xc9, 0x73, 0x68, 0xce, 0x59, 0x72, 0xdd, 0xfb, 0xe5, 0x18, 0xb6, 0x31, 0xa6, + 0x15, 0xe2, 0xe7, 0x3a, 0xf5, 0x68, 0x8d, 0x2d, 0x78, 0xbe, 0x1a, 0xe6, 0x05, 0x9b, 0xf2, 0x6b, + 0xaa, 0x29, 0x71, 0x32, 0x7f, 0xd8, 0x78, 0x82, 0x2c, 0xd7, 0x91, 0xe5, 0x5a, 0xb2, 0x5c, 0x43, + 0xb4, 0xb2, 0xbc, 0x0a, 0xbd, 0x18, 0xbd, 0x39, 0x47, 0x79, 0xd4, 0x70, 0x57, 0x24, 0xc6, 0x03, + 0x0e, 0x52, 0x24, 0x5d, 0xb5, 0x80, 0x40, 0x97, 0xa4, 0x69, 0xd0, 0x87, 0x4d, 0xd3, 0xd6, 0x66, + 0xe9, 0x6a, 0xd2, 0x74, 0x19, 0xe4, 0x47, 0x7a, 0x29, 0x2b, 0x96, 0xa4, 0xc5, 0x4a, 0x32, 0x9d, + 0xe0, 0x7e, 0x49, 0x0d, 0x60, 0x80, 0x5b, 0xf1, 0x19, 0xf9, 0xcc, 0x1b, 0x88, 0xf2, 0xde, 0x9e, + 0x4e, 0xce, 0x80, 0x51, 0x01, 0xf7, 0x12, 0x11, 0xfc, 0xf8, 0x19, 0xdc, 0x22, 0x16, 0xba, 0xb8, + 0x7d, 0xfd, 0x68, 0x66, 0x40, 0x11, 0x93, 0x49, 0xc5, 0x02, 0x72, 0x51, 0x3d, 0xe9, 0x9d, 0xd4, + 0xac, 0x9e, 0xf5, 0x9e, 0x62, 0xea, 0x12, 0x3d, 0x2c, 0xf8, 0xba, 0x30, 0x14, 0x6e, 0x5f, 0x1b, + 0xb4, 0xbc, 0xc2, 0x9e, 0xc4, 0x23, 0xf1, 0x36, 0xf0, 0x05, 0x75, 0x24, 0x0b, 0x10, 0xbf, 0x06, + 0xc2, 0x7f, 0xe5, 0x1b, 0xea, 0x06, 0xe0, 0xf2, 0xf3, 0x0b, 0x78, 0x1e, 0x9b, 0x57, 0x48, 0x96, + 0x19, 0x2c, 0x25, 0xc9, 0x5a, 0x85, 0x6a, 0x6e, 0x6a, 0x27, 0xab, 0x97, 0x93, 0xac, 0xcc, 0xfd, + 0x6c, 0x67, 0x3e, 0x14, 0x1f, 0x1b, 0x42, 0xd2, 0xe2, 0xe8, 0x0d, 0x77, 0x82, 0x92, 0xc1, 0x55, + 0x8b, 0xd8, 0x2e, 0x5f, 0x2f, 0xde, 0xd6, 0x70, 0xaf, 0x6e, 0xc4, 0x03, 0x7a, 0x78, 0xf6, 0xa3, + 0x85, 0xfa, 0xcc, 0x99, 0xe0, 0xff, 0xcb, 0x19, 0x77, 0x08, 0x7f, 0x01, 0x5d, 0x7d, 0x6f, 0xbb, + 0x26, 0xe2, 0x28, 0xdd, 0x2a, 0xcd, 0x29, 0xd5, 0xe7, 0x98, 0x01, 0x01, 0xf0, 0x43, 0x9e, 0xb9, + 0x15, 0x52, 0x52, 0x70, 0xb0, 0x39, 0x67, 0x94, 0x38, 0x10, 0xc1, 0xb9, 0x07, 0x91, 0x91, 0xfc, + 0x69, 0x88, 0xa2, 0xe5, 0x3c, 0x96, 0xee, 0x01, 0x1d, 0x8a, 0xc7, 0x3d, 0xcb, 0x23, 0x78, 0xd2, + 0xb7, 0xf7, 0x77, 0x52, 0x24, 0xa1, 0x8c, 0x40, 0x52, 0xd2, 0xe3, 0xc5, 0x48, 0x4d, 0x7a, 0xfe, + 0x1b, 0x09, 0x4a, 0x8f, 0x83, 0x1b, 0x03, 0x80, 0x0f, 0x79, 0x6b, 0x15, 0x2d, 0x8c, 0x25, 0x6e, + 0x33, 0xd2, 0xec, 0x88, 0x7a, 0xfc, 0xbe, 0x23, 0x74, 0xfc, 0x5e, 0x21, 0x47, 0xb6, 0xd3, 0xa3, + 0xe3, 0xf4, 0x12, 0xc3, 0xc7, 0x78, 0x2a, 0x87, 0x9a, 0x6a, 0xe7, 0xd3, 0xc6, 0x80, 0x94, 0x7f, + 0xc1, 0xd8, 0x47, 0xfc, 0xdc, 0xde, 0x81, 0x28, 0x72, 0xcb, 0x7b, 0x23, 0xaa, 0xea, 0xc4, 0x19, + 0xba, 0x2b, 0x81, 0x9c, 0x0d, 0x8a, 0x66, 0xe8, 0x80, 0xff, 0x3b, 0x03, 0xc1, 0x21, 0xb8, 0x3b, + 0xe8, 0x71, 0x1b, 0xce, 0x19, 0x01, 0xa3, 0x10, 0xb4, 0x12, 0x15, 0x4d, 0x63, 0xdf, 0xf0, 0xb8, + 0x38, 0x00, 0xf1, 0xb8, 0xf0, 0x9b, 0x51, 0x60, 0x8f, 0xfe, 0x2b, 0xb0, 0x59, 0x2a, 0x58, 0xd7, + 0x11, 0x84, 0xca, 0xd4, 0x05, 0xe8, 0x59, 0x7d, 0xbc, 0xc1, 0xc7, 0x55, 0x9f, 0xa1, 0x47, 0x79, + 0xe8, 0xcd, 0x8e, 0x70, 0x89, 0x52, 0x00, 0xc3, 0x6f, 0x4a, 0x01, 0x88, 0xc9, 0x6b, 0x29, 0x05, + 0x6a, 0x32, 0xc0, 0x3e, 0xb7, 0x90, 0x0c, 0xbd, 0xa4, 0x0e, 0x3e, 0x23, 0x36, 0xfc, 0x08, 0x0e, + 0x7b, 0xe2, 0xc7, 0x48, 0x85, 0x70, 0x8a, 0x9b, 0x78, 0x91, 0x21, 0x2f, 0x26, 0x13, 0xc7, 0x02, + 0xc9, 0xdd, 0x85, 0x17, 0xae, 0x32, 0x16, 0x35, 0x65, 0x2c, 0x55, 0xcf, 0x09, 0xd1, 0x23, 0x4a, + 0x19, 0x71, 0x16, 0x90, 0x6f, 0xb3, 0xf2, 0xe7, 0xae, 0xa0, 0x94, 0x38, 0xc1, 0xf8, 0x37, 0x4b, + 0xd6, 0x36, 0x6a, 0xfc, 0x8f, 0x53, 0xe3, 0x7f, 0x58, 0x32, 0x79, 0x46, 0x18, 0xff, 0x9a, 0x8c, + 0x54, 0x8b, 0x52, 0xda, 0x15, 0x5a, 0x8a, 0x1b, 0x1f, 0xdc, 0x57, 0x24, 0x19, 0x9b, 0xa0, 0x3c, + 0x2a, 0x98, 0xc2, 0x6a, 0xf6, 0xc6, 0x8c, 0xb5, 0x0c, 0x3d, 0xb1, 0xf7, 0x9d, 0x2a, 0x54, 0x20, + 0x43, 0x52, 0x65, 0x97, 0xc4, 0x9f, 0x46, 0x52, 0x55, 0x5f, 0xa2, 0xd7, 0xc4, 0x38, 0x75, 0xac, + 0xd9, 0x62, 0x40, 0xc3, 0xb9, 0x71, 0x03, 0x94, 0x2a, 0x77, 0xa7, 0x9e, 0xde, 0x5b, 0x0b, 0xc9, + 0x13, 0xbd, 0xe3, 0xd7, 0x2d, 0x0b, 0xd7, 0x2c, 0xa5, 0x7a, 0x8b, 0xd9, 0x96, 0xa3, 0xe8, 0xfa, + 0x55, 0xca, 0xed, 0xd2, 0x30, 0x5c, 0xf5, 0x1b, 0x74, 0xda, 0xd6, 0x49, 0x2c, 0x9e, 0x76, 0x8c, + 0x94, 0xd2, 0x34, 0x24, 0x4b, 0x23, 0xa5, 0x69, 0x49, 0x96, 0xb6, 0x36, 0x4d, 0x57, 0x93, 0xa5, + 0xcb, 0x26, 0xbb, 0xf4, 0x52, 0x5a, 0x2c, 0x6e, 0x65, 0x82, 0x64, 0x3c, 0xbd, 0x80, 0x64, 0x25, + 0xa3, 0x64, 0x3c, 0xbd, 0x94, 0xde, 0x1f, 0x89, 0x53, 0xb9, 0x01, 0x9a, 0xb2, 0xdf, 0x17, 0xa2, + 0xc1, 0xfd, 0x92, 0x7a, 0xe3, 0x00, 0x14, 0x45, 0x25, 0x39, 0xe8, 0x8a, 0x2a, 0x8f, 0x32, 0x65, + 0x05, 0xd5, 0x98, 0x3f, 0xb1, 0x35, 0x4f, 0xa7, 0x82, 0x78, 0xd3, 0x56, 0xe0, 0x50, 0x01, 0x2d, + 0x62, 0x48, 0x16, 0x12, 0x41, 0x87, 0x3b, 0xf5, 0x39, 0xc6, 0xc0, 0x1a, 0xdf, 0x2a, 0xa0, 0x43, + 0x96, 0xbd, 0x31, 0x0b, 0xe8, 0x90, 0x86, 0xaf, 0x50, 0x3f, 0x79, 0x44, 0xfd, 0x31, 0x6a, 0xfd, + 0xb0, 0x50, 0x2d, 0x56, 0x56, 0xe5, 0x39, 0x4c, 0x02, 0x72, 0x67, 0xad, 0x23, 0xab, 0x9f, 0x92, + 0xd2, 0x61, 0x1c, 0xcf, 0x48, 0xe9, 0xa0, 0xcf, 0x85, 0x18, 0x4a, 0xc7, 0x86, 0xb6, 0x0a, 0xc4, + 0x65, 0x78, 0x58, 0x1c, 0x04, 0x99, 0x9a, 0x73, 0x6a, 0xcd, 0xdf, 0xc3, 0x73, 0xe4, 0x92, 0x6e, + 0xbf, 0x6b, 0x47, 0x2a, 0xe3, 0x9c, 0x22, 0x7a, 0x33, 0x4b, 0xf5, 0x79, 0x39, 0xca, 0xcf, 0xa7, + 0x04, 0x6d, 0x14, 0x2d, 0x76, 0x1a, 0x69, 0x85, 0xb5, 0x8c, 0x33, 0x4e, 0xf4, 0xae, 0xa3, 0x15, + 0x76, 0x8c, 0xae, 0xa0, 0xcf, 0x5a, 0xf2, 0x30, 0x82, 0xae, 0xf8, 0x18, 0xe2, 0xaa, 0x48, 0xa3, + 0xa7, 0x41, 0xd2, 0xec, 0x47, 0xdb, 0x4f, 0x0f, 0xac, 0x03, 0xce, 0xcb, 0x86, 0x3b, 0x54, 0x4f, + 0xae, 0x4b, 0xb1, 0x7f, 0x70, 0xbd, 0x60, 0x87, 0x1e, 0xf3, 0x02, 0x15, 0x9b, 0x94, 0xc8, 0xee, + 0xe0, 0x9a, 0xa8, 0x5a, 0xe8, 0x8c, 0xa1, 0xed, 0xb2, 0x52, 0x1a, 0x2b, 0x2e, 0xdd, 0x85, 0xf7, + 0x07, 0x84, 0x27, 0x8d, 0xa3, 0x00, 0x4f, 0x38, 0xe7, 0x07, 0xa3, 0x1b, 0xab, 0x1e, 0x44, 0xa4, + 0x36, 0x5f, 0x2b, 0x2d, 0xa3, 0x50, 0xc7, 0xa4, 0x94, 0x6b, 0x85, 0xe8, 0x45, 0xeb, 0x74, 0x42, + 0x44, 0x8a, 0x59, 0xef, 0xd4, 0x8a, 0x4d, 0x9a, 0x15, 0x42, 0x67, 0x30, 0x52, 0x45, 0x30, 0xa1, + 0xf6, 0xd3, 0x68, 0xa0, 0x6d, 0xd5, 0x4a, 0x0f, 0xd3, 0x76, 0x91, 0x29, 0x58, 0xb9, 0x11, 0x2a, + 0xdf, 0xa4, 0x01, 0x35, 0x54, 0x85, 0x0a, 0x60, 0xf1, 0xb4, 0x32, 0xae, 0xde, 0xdf, 0xc9, 0x31, + 0x07, 0x17, 0x49, 0x75, 0x23, 0xef, 0x9c, 0xd1, 0x4b, 0x9d, 0xb2, 0xe0, 0x57, 0xaf, 0x23, 0x82, + 0x6d, 0x69, 0x08, 0xe3, 0x0e, 0x64, 0x0c, 0xa1, 0x65, 0xff, 0x1a, 0x17, 0x77, 0x06, 0x66, 0x39, + 0x13, 0xaa, 0x02, 0x43, 0xb8, 0xbf, 0x1e, 0x5d, 0xf3, 0xca, 0xef, 0xa1, 0xa3, 0x6c, 0xf0, 0x8a, + 0x1b, 0xe9, 0x1b, 0x93, 0xe1, 0x3b, 0x0f, 0x95, 0xc1, 0x2e, 0x3c, 0xfb, 0xd2, 0x22, 0x71, 0x20, + 0x77, 0x57, 0x9e, 0x38, 0x60, 0xe1, 0xaa, 0x1f, 0xc3, 0xa5, 0x9a, 0x01, 0x2b, 0x57, 0x7d, 0x2f, + 0x7d, 0x59, 0xc7, 0xb9, 0xab, 0xe8, 0x19, 0x13, 0xb9, 0x42, 0x0b, 0x6e, 0xe4, 0x04, 0x72, 0x2b, + 0x50, 0xae, 0x51, 0x7e, 0x00, 0xb8, 0x74, 0x46, 0xd1, 0x63, 0x64, 0xaf, 0x89, 0xb7, 0xb4, 0xdb, + 0xd2, 0x03, 0x89, 0xb2, 0x82, 0xf3, 0xe7, 0x25, 0x69, 0x02, 0x8c, 0x98, 0x74, 0x83, 0xf3, 0x17, + 0x89, 0x75, 0x3e, 0xa0, 0x40, 0xee, 0x73, 0xae, 0x12, 0x07, 0x32, 0x55, 0x47, 0xe8, 0x7b, 0x90, + 0x9e, 0x06, 0x23, 0xdd, 0x79, 0x8c, 0xea, 0xd4, 0x06, 0xae, 0xda, 0x45, 0xab, 0x17, 0x72, 0xee, + 0x71, 0xea, 0x61, 0x38, 0x0a, 0xac, 0x05, 0xe3, 0xd6, 0x6e, 0xb3, 0x32, 0x1f, 0xab, 0xe2, 0x81, + 0x63, 0x29, 0x4c, 0xac, 0xd7, 0xe0, 0x35, 0x5c, 0x5e, 0x31, 0x2b, 0x8f, 0xfa, 0xd5, 0x30, 0xd1, + 0x2b, 0x7a, 0x71, 0xdc, 0x7b, 0x6c, 0xd8, 0xf2, 0xa4, 0x5c, 0x1e, 0x58, 0x81, 0xfb, 0x34, 0x26, + 0x05, 0x82, 0xfa, 0xc0, 0x7d, 0xe8, 0x1e, 0xfb, 0x85, 0x76, 0x77, 0x9f, 0xf3, 0xa1, 0x3a, 0x5c, + 0x38, 0xae, 0x0a, 0xe0, 0x5f, 0x49, 0x50, 0x9c, 0x53, 0x49, 0x6b, 0xed, 0x24, 0x39, 0x9b, 0xad, + 0xf9, 0x37, 0xa4, 0x89, 0xd8, 0xc9, 0x56, 0x8c, 0xcd, 0x52, 0x29, 0x46, 0x9a, 0x84, 0xbf, 0xe1, + 0xe2, 0x65, 0x13, 0xd0, 0x37, 0x48, 0x31, 0x70, 0x83, 0x3b, 0x6b, 0xff, 0x71, 0x0c, 0xcf, 0x07, + 0xf7, 0x9d, 0x7b, 0xc8, 0x50, 0x27, 0xae, 0x56, 0x49, 0xd1, 0x72, 0x3a, 0x3d, 0x63, 0x83, 0x77, + 0xdc, 0xa5, 0x5c, 0x8d, 0xfb, 0x1c, 0x57, 0xbd, 0x92, 0xce, 0x1c, 0x1d, 0x47, 0x87, 0x7b, 0x77, + 0x26, 0xac, 0xac, 0x65, 0xe5, 0x6d, 0xac, 0xca, 0x17, 0xf1, 0x6b, 0xe8, 0x39, 0x2d, 0xd8, 0x73, + 0x3f, 0xf4, 0x2c, 0xf8, 0xa1, 0x17, 0xbc, 0x18, 0xda, 0xd1, 0x39, 0x1e, 0xdd, 0x09, 0x5a, 0xc2, + 0xbd, 0xd2, 0x09, 0x20, 0x55, 0x6c, 0x1e, 0xcb, 0xee, 0xc4, 0xeb, 0x4c, 0x94, 0x18, 0xc8, 0x70, + 0x5c, 0x98, 0xa8, 0xd5, 0x56, 0x43, 0xb7, 0xff, 0x0d, 0x6f, 0xa9, 0x6a, 0x27, 0xea, 0x1d, 0xdd, + 0x9a, 0x1f, 0x53, 0xd6, 0xd7, 0x6a, 0x53, 0xab, 0x4f, 0x08, 0x5f, 0x76, 0x62, 0x00, 0x3c, 0x92, + 0x53, 0x7f, 0xc0, 0xbd, 0xe9, 0x41, 0x18, 0x41, 0xe7, 0x47, 0x4c, 0xa8, 0xa7, 0x6d, 0xba, 0xda, + 0xb0, 0x61, 0x89, 0x81, 0x2e, 0x7c, 0x15, 0x40, 0xcc, 0x5a, 0x16, 0xcc, 0x4c, 0x45, 0x1a, 0xe2, + 0x65, 0xed, 0x0a, 0x0e, 0x23, 0x37, 0x58, 0xad, 0x96, 0x4d, 0xab, 0xf6, 0x08, 0x5f, 0xfb, 0xb2, + 0xff, 0x38, 0xfb, 0xd0, 0x20, 0xae, 0xfd, 0xa9, 0xc5, 0xab, 0x54, 0xca, 0x66, 0xd7, 0xfe, 0xe4, + 0x97, 0xc0, 0xbb, 0x34, 0x41, 0xf1, 0x3d, 0xf6, 0x87, 0xd9, 0x75, 0x23, 0x2a, 0x4c, 0x08, 0x61, + 0x57, 0x83, 0x15, 0x52, 0xa1, 0x42, 0xc4, 0x31, 0xba, 0xa5, 0x72, 0x57, 0x50, 0x7d, 0xf1, 0x6a, + 0x87, 0xbe, 0x6f, 0xbf, 0x57, 0x40, 0xea, 0xc1, 0x64, 0x75, 0x8e, 0x01, 0xd3, 0xeb, 0x5a, 0x46, + 0x03, 0x61, 0x67, 0x99, 0x3b, 0xe0, 0xdc, 0x60, 0xec, 0x0b, 0x05, 0xab, 0x96, 0x60, 0xbe, 0xb0, + 0xd2, 0xb5, 0xec, 0x97, 0xb4, 0x42, 0x1a, 0x77, 0xe0, 0x65, 0x4a, 0xef, 0x81, 0x29, 0xce, 0x24, + 0x71, 0x20, 0x5a, 0x18, 0x5f, 0x3a, 0x4e, 0x39, 0xfc, 0x3c, 0x65, 0xe0, 0xfe, 0x68, 0xdf, 0x24, + 0xba, 0x29, 0xfb, 0x5e, 0x57, 0xc8, 0xbd, 0x9c, 0x50, 0x4b, 0x6b, 0x73, 0x07, 0x20, 0xf7, 0xa7, + 0x6a, 0x2d, 0xdc, 0xe6, 0xfb, 0x65, 0xe8, 0x96, 0x64, 0xa8, 0xa3, 0xf9, 0xe2, 0xb2, 0xd3, 0x10, + 0x65, 0x03, 0xbd, 0x5f, 0xa4, 0xb7, 0x8a, 0xde, 0x6b, 0x86, 0x54, 0x9e, 0x1d, 0xdb, 0x06, 0x16, + 0xec, 0x57, 0x7c, 0xbf, 0xa2, 0xaa, 0x0b, 0x36, 0x0a, 0x6b, 0x55, 0xdc, 0xa0, 0x6b, 0x02, 0x80, + 0x6a, 0x9d, 0xb1, 0x4f, 0xce, 0x3f, 0x5c, 0x3a, 0xbb, 0x94, 0xb1, 0x28, 0x9b, 0x26, 0xa9, 0x67, + 0xbb, 0x8e, 0x06, 0xf1, 0x8b, 0x16, 0x1e, 0x68, 0xe2, 0xdb, 0xc7, 0x8d, 0x07, 0x77, 0x1a, 0xe6, + 0x0f, 0xa5, 0xe6, 0x08, 0x75, 0x37, 0xf1, 0x62, 0x92, 0x45, 0x49, 0x55, 0xeb, 0xd6, 0x45, 0x43, + 0xa9, 0x2f, 0x62, 0x1c, 0x33, 0x9e, 0x9e, 0x60, 0xa6, 0xf5, 0x9e, 0x51, 0xeb, 0x21, 0x96, 0xbf, + 0xee, 0xec, 0x19, 0x71, 0xb0, 0x3e, 0x01, 0x58, 0x6e, 0xd5, 0x1a, 0x3d, 0x04, 0x77, 0x33, 0x3b, + 0x70, 0xdb, 0x0f, 0x2f, 0x58, 0xb6, 0x41, 0x2c, 0xd9, 0xe2, 0xb4, 0xe2, 0xc5, 0x69, 0xd4, 0x33, + 0x63, 0xbd, 0xb1, 0x29, 0xa9, 0x29, 0xbe, 0xfe, 0xd3, 0x09, 0x0c, 0xbd, 0x9e, 0x05, 0x0e, 0x40, + 0x74, 0x6e, 0x9e, 0xf2, 0xa6, 0x27, 0x18, 0xe2, 0xb2, 0x5e, 0x79, 0x01, 0x21, 0xb7, 0x92, 0xba, + 0x5d, 0x27, 0x92, 0x6b, 0x56, 0x4d, 0x6d, 0x7b, 0xfc, 0x50, 0x14, 0x2e, 0x78, 0xdd, 0xa2, 0x07, + 0xe2, 0xc1, 0xb5, 0x23, 0x4d, 0x15, 0x27, 0xc4, 0x4a, 0x2d, 0xb3, 0x3d, 0x21, 0xc3, 0x37, 0x4d, + 0x62, 0x97, 0x51, 0x51, 0xe2, 0xc9, 0x59, 0xbc, 0x0d, 0xcd, 0x35, 0xba, 0x70, 0x64, 0xc9, 0xbe, + 0xf9, 0x8d, 0x99, 0x53, 0xdb, 0x7e, 0x08, 0xac, 0xab, 0x85, 0x5f, 0x20, 0xf2, 0x7d, 0xb2, 0xa9, + 0x4d, 0x5e, 0x35, 0x96, 0x95, 0xee, 0xad, 0x1a, 0x54, 0x45, 0x42, 0xae, 0x60, 0xc9, 0x23, 0x35, + 0xbb, 0xb1, 0xba, 0x2a, 0x56, 0x1d, 0xd2, 0x18, 0xb5, 0x35, 0xee, 0xe7, 0x8d, 0x0a, 0xe2, 0x0c, + 0xe4, 0x62, 0x70, 0x58, 0x23, 0xc6, 0xc4, 0x5f, 0x68, 0xe4, 0x15, 0x88, 0xa6, 0x60, 0x68, 0x4f, + 0xc1, 0xd0, 0xe4, 0xca, 0xce, 0xd0, 0x58, 0x6c, 0x4a, 0xf3, 0xb1, 0xe1, 0xb1, 0xe8, 0x08, 0xe9, + 0x4d, 0x3a, 0xe5, 0x3a, 0x95, 0x5c, 0xb3, 0x7e, 0x68, 0x8d, 0x3a, 0x94, 0x6e, 0xea, 0x69, 0x4d, + 0x11, 0xba, 0x48, 0x63, 0xc5, 0x49, 0x7a, 0x3d, 0x6f, 0x19, 0xc5, 0x29, 0x09, 0xaf, 0x3a, 0xc5, + 0xd4, 0xbc, 0x4d, 0x71, 0x9a, 0x9e, 0x5d, 0x7d, 0x55, 0xf8, 0x9b, 0xef, 0x9e, 0xd0, 0x08, 0xc7, + 0xd3, 0xc2, 0xe0, 0xf8, 0x24, 0xf6, 0x2e, 0xaa, 0x86, 0x51, 0xa8, 0xe2, 0x7e, 0x22, 0xdd, 0x01, + 0x1d, 0x8d, 0x2d, 0x45, 0x15, 0xb9, 0xb0, 0x41, 0xe6, 0x3b, 0xc9, 0x45, 0x72, 0x5b, 0xfc, 0x82, + 0xab, 0x95, 0x26, 0x83, 0x32, 0xd4, 0x98, 0x7a, 0x6b, 0x96, 0x0f, 0x91, 0x56, 0x6e, 0xef, 0x60, + 0x82, 0xf7, 0x1b, 0xcd, 0xf2, 0x4f, 0x39, 0xc4, 0xf0, 0x36, 0xbd, 0xc5, 0x17, 0x7f, 0x16, 0xa0, + 0xf5, 0x54, 0xb4, 0x1e, 0x4c, 0xfe, 0x84, 0x3a, 0xbf, 0x95, 0x5d, 0xb5, 0xf9, 0xbd, 0xd2, 0x23, + 0x55, 0x43, 0x14, 0xdb, 0x3c, 0x79, 0x35, 0x10, 0xbc, 0xe6, 0x28, 0xc5, 0xf6, 0x13, 0xbc, 0xe7, + 0x92, 0x2e, 0x7c, 0x2e, 0xdd, 0xeb, 0xcb, 0xfc, 0x63, 0x72, 0xdd, 0x77, 0x6a, 0x75, 0xdc, 0xa9, + 0x08, 0x55, 0xcf, 0x95, 0x77, 0xb1, 0x24, 0x05, 0x32, 0x6b, 0x7e, 0x4a, 0x5b, 0xbc, 0x36, 0xd7, + 0x8c, 0xaa, 0xf8, 0xd9, 0x3f, 0x50, 0x9d, 0x6e, 0xbb, 0x35, 0x52, 0xc6, 0x30, 0xd5, 0x57, 0x9d, + 0x9f, 0xdd, 0x65, 0xd9, 0x5f, 0xe5, 0x95, 0xd8, 0xe1, 0xcf, 0x69, 0xf3, 0xb8, 0x54, 0xdf, 0xe7, + 0xd4, 0xce, 0xfa, 0x3c, 0xa1, 0x1d, 0x5b, 0x41, 0xeb, 0xee, 0x13, 0xc2, 0xc8, 0x37, 0x76, 0x84, + 0xac, 0xcc, 0xa0, 0xce, 0xb5, 0xe6, 0xd8, 0x1c, 0x1b, 0xae, 0x9a, 0xa3, 0x3f, 0xb6, 0x51, 0x5a, + 0x18, 0xd4, 0xa5, 0x43, 0x75, 0x5f, 0x85, 0x33, 0x5c, 0xe6, 0x59, 0x29, 0x26, 0xa5, 0xde, 0xf1, + 0x28, 0xd8, 0x41, 0x70, 0xa2, 0x2e, 0x92, 0xcf, 0xd0, 0x58, 0xdd, 0x76, 0x2d, 0x8d, 0x67, 0xe4, + 0x27, 0x59, 0xa1, 0x5f, 0x8a, 0x8d, 0x4f, 0xa9, 0xaf, 0xf8, 0x8a, 0xbd, 0x45, 0xea, 0x93, 0x7a, + 0x72, 0x73, 0xcc, 0xf6, 0x07, 0x81, 0x5c, 0xca, 0x49, 0xea, 0x99, 0xc2, 0x84, 0xec, 0xa7, 0x90, + 0x7d, 0xe3, 0xcd, 0xf6, 0x25, 0xd8, 0xdd, 0x1f, 0x07, 0xd4, 0xd9, 0xbd, 0x4f, 0x78, 0xdd, 0xfe, + 0x01, 0x9e, 0xc7, 0x7e, 0x4f, 0xcd, 0x18, 0xc1, 0x1d, 0xd7, 0x32, 0xff, 0x93, 0xf4, 0xf2, 0xe4, + 0x5f, 0xe9, 0x99, 0x75, 0x6d, 0x55, 0x03, 0xb5, 0xd4, 0x5f, 0xe0, 0xc6, 0xe2, 0x7b, 0x77, 0xa0, + 0x48, 0x7a, 0x78, 0x00, 0xfe, 0x92, 0x6e, 0xf6, 0x32, 0xa9, 0x17, 0xcf, 0xe1, 0x4d, 0x4a, 0x3d, + 0x93, 0x72, 0x96, 0xca, 0x7d, 0x7c, 0x6b, 0xc5, 0xb3, 0x78, 0xa7, 0x34, 0xa7, 0x94, 0xa5, 0xdb, + 0x88, 0x39, 0xe0, 0xec, 0xd9, 0xfd, 0xa0, 0xe8, 0x76, 0x66, 0xa6, 0x86, 0x51, 0x1e, 0x8e, 0x42, + 0xfa, 0xcd, 0x51, 0x01, 0x54, 0x7b, 0xc8, 0x67, 0x42, 0x2a, 0x85, 0x58, 0xd5, 0x88, 0x95, 0xf1, + 0xc4, 0x76, 0x37, 0x8e, 0x03, 0x3f, 0x6c, 0x71, 0x7b, 0x34, 0x58, 0x42, 0x9b, 0xbc, 0x8f, 0x95, + 0x1d, 0xff, 0x61, 0xff, 0xb3, 0x85, 0x2e, 0xaa, 0x0c, 0xfa, 0xf0, 0x34, 0x19, 0xde, 0x64, 0x51, + 0x57, 0xe6, 0x74, 0xec, 0x32, 0xac, 0x25, 0xde, 0x83, 0xd5, 0x98, 0x43, 0xd8, 0xe5, 0x27, 0xd8, + 0xb9, 0x45, 0x31, 0x31, 0xea, 0xbc, 0xe4, 0x57, 0x17, 0x65, 0xf6, 0xe5, 0x02, 0x49, 0x8e, 0xd2, + 0x75, 0x66, 0x43, 0xad, 0x29, 0x91, 0x3b, 0x60, 0x9d, 0xcd, 0x1d, 0x38, 0x01, 0xa6, 0x8d, 0x6e, + 0x88, 0x8d, 0x3a, 0x9b, 0x00, 0xd1, 0xf8, 0x88, 0x01, 0x38, 0xe9, 0x6e, 0xdf, 0x9c, 0x61, 0x41, + 0x7e, 0x8a, 0x58, 0x8f, 0x4b, 0x61, 0xc6, 0x73, 0x2b, 0x89, 0xf5, 0x02, 0x5e, 0xcc, 0xe9, 0xe0, + 0xaa, 0xd7, 0x60, 0x80, 0x95, 0xa3, 0x10, 0x6b, 0x8b, 0x9c, 0xa3, 0x25, 0x56, 0x0f, 0x30, 0x8d, + 0xf7, 0xcb, 0x9a, 0x27, 0xc5, 0x9d, 0x5e, 0x3d, 0xcb, 0xb9, 0xd3, 0xd1, 0x57, 0x58, 0xe0, 0x45, + 0x97, 0xfc, 0x0a, 0x6e, 0xa7, 0xe4, 0x9f, 0x26, 0xc2, 0x61, 0x98, 0xf3, 0xb8, 0xdd, 0xc7, 0xe8, + 0x55, 0xef, 0x3a, 0x62, 0xfd, 0xb3, 0x34, 0x09, 0xe3, 0x26, 0xbe, 0x4b, 0xda, 0xa5, 0x65, 0x2f, + 0x91, 0xca, 0x6b, 0xd2, 0xd3, 0xba, 0x98, 0x06, 0x29, 0x6d, 0x40, 0x32, 0xb2, 0x8d, 0x44, 0xd8, + 0x2f, 0x3d, 0x7f, 0x47, 0xda, 0xa1, 0x89, 0xe9, 0x27, 0xd6, 0xb6, 0x94, 0x16, 0xd2, 0x33, 0xc5, + 0xda, 0xc5, 0xbd, 0xd1, 0x08, 0xc6, 0x6c, 0x09, 0x84, 0x83, 0xfc, 0x7e, 0x22, 0xb4, 0x93, 0xfc, + 0xe6, 0xf8, 0xeb, 0x78, 0xe0, 0xe7, 0xf5, 0x7a, 0x43, 0x8f, 0x6b, 0x90, 0x15, 0xee, 0x5d, 0x02, + 0xa6, 0x60, 0x28, 0xfe, 0x7a, 0xc5, 0x78, 0xa8, 0x43, 0x86, 0xa6, 0x08, 0xcd, 0xdc, 0xee, 0xbf, + 0x03, 0x9e, 0xc1, 0x6c, 0x68, 0x5e, 0x7d, 0x0e, 0xdc, 0x7b, 0xa1, 0x19, 0x1a, 0x4b, 0xc2, 0x35, + 0x22, 0x00, 0x2c, 0x05, 0xeb, 0xb5, 0x03, 0x88, 0xea, 0x8b, 0x42, 0xa4, 0xc4, 0xb7, 0xa1, 0xa2, + 0x08, 0x87, 0xc9, 0x2e, 0x0d, 0xb8, 0xe8, 0x56, 0x05, 0x57, 0xce, 0xda, 0xe3, 0x07, 0x88, 0x0d, + 0xdc, 0x5b, 0x70, 0xbd, 0x4e, 0x4b, 0x80, 0x35, 0x5f, 0x27, 0x7a, 0xe3, 0x96, 0x73, 0xea, 0x05, + 0xef, 0x2c, 0xad, 0xb4, 0x5a, 0x47, 0xea, 0xa3, 0x4e, 0x3a, 0xd7, 0xd1, 0x75, 0xd2, 0x95, 0xcb, + 0x90, 0xc7, 0xe4, 0xa4, 0x78, 0x85, 0xa9, 0xc8, 0x92, 0x26, 0xa1, 0xd3, 0xd2, 0x4f, 0x2e, 0x56, + 0x35, 0x52, 0xf7, 0x23, 0x0f, 0x9c, 0x18, 0x05, 0xd8, 0xfe, 0x29, 0x0a, 0xd9, 0x8c, 0xeb, 0xe1, + 0x7c, 0xd7, 0x44, 0x93, 0x02, 0x50, 0xc9, 0x23, 0x49, 0x7e, 0x92, 0xa7, 0x01, 0xfe, 0xaf, 0xd1, + 0x1d, 0xa2, 0x65, 0xcd, 0x24, 0x5b, 0x8b, 0x37, 0x7d, 0x79, 0xbf, 0x2f, 0x01, 0xcf, 0x6a, 0x69, + 0x56, 0x48, 0xd6, 0x16, 0xf0, 0x0f, 0x16, 0xd4, 0x93, 0xe6, 0x43, 0xe8, 0xfb, 0xf5, 0x7e, 0xb0, + 0xfc, 0x71, 0xa8, 0x90, 0x91, 0xd2, 0xc0, 0xed, 0x16, 0xf1, 0xe4, 0x13, 0x38, 0x04, 0x87, 0x29, + 0x65, 0xfd, 0x46, 0x8f, 0x9c, 0x90, 0x2a, 0xee, 0xbc, 0x8c, 0x6c, 0xc0, 0x0b, 0xa0, 0xf2, 0xd2, + 0xcb, 0xd2, 0xbd, 0xd2, 0x36, 0xcd, 0x21, 0x3a, 0x97, 0x5a, 0x95, 0x94, 0x56, 0x55, 0xda, 0xba, + 0xa5, 0x35, 0x5a, 0x29, 0x4f, 0x07, 0x28, 0x56, 0x64, 0x90, 0x93, 0xe1, 0x26, 0x65, 0xa2, 0xd0, + 0x55, 0x75, 0x8b, 0x45, 0x11, 0xbd, 0xce, 0x54, 0x3c, 0x02, 0xb3, 0x7f, 0xd5, 0x09, 0x44, 0x86, + 0x05, 0xab, 0xd8, 0x21, 0xaf, 0xba, 0xac, 0x45, 0xc3, 0xdb, 0x25, 0x9e, 0x0b, 0x10, 0x23, 0xc9, + 0xd1, 0x34, 0x65, 0xd3, 0x0d, 0xf5, 0xa6, 0x31, 0x74, 0xbc, 0xdd, 0xbe, 0x70, 0x28, 0x8b, 0x6a, + 0x15, 0xe2, 0x24, 0xab, 0x5f, 0xd6, 0xe5, 0x4a, 0x42, 0x8b, 0xbc, 0xe0, 0x4c, 0x10, 0x53, 0x90, + 0x1a, 0xff, 0x72, 0x80, 0x91, 0xba, 0x84, 0xf7, 0x73, 0xbb, 0xd7, 0xd3, 0x88, 0xd7, 0x4f, 0xea, + 0x51, 0x98, 0x84, 0x71, 0xf4, 0x76, 0x90, 0xbf, 0xf3, 0x51, 0x7a, 0x70, 0x1d, 0xdd, 0x2f, 0xd3, + 0x35, 0xd2, 0x6c, 0x3c, 0x01, 0x1e, 0x9d, 0x6e, 0x85, 0xac, 0x69, 0x26, 0x78, 0xc6, 0xda, 0x9f, + 0x72, 0x12, 0x6f, 0x6f, 0xb5, 0x38, 0x52, 0x90, 0x41, 0x7a, 0xa9, 0x5c, 0xa3, 0x5e, 0x4a, 0x26, + 0x0d, 0x28, 0x3d, 0x63, 0x70, 0xbb, 0x76, 0x8d, 0x06, 0x64, 0xa4, 0x39, 0x1e, 0xbf, 0xab, 0xc1, + 0xa5, 0x77, 0xe3, 0xd9, 0x98, 0x74, 0xab, 0xc2, 0xa5, 0x37, 0x64, 0x88, 0x4d, 0x71, 0x29, 0x97, + 0x85, 0x4b, 0xb2, 0x2e, 0x15, 0x3c, 0x2b, 0x39, 0x56, 0xa5, 0x9e, 0x9c, 0xff, 0x36, 0xf9, 0x8c, + 0x5c, 0xec, 0xfd, 0x80, 0xa6, 0x70, 0x9e, 0x6c, 0x1b, 0x91, 0x22, 0xd7, 0x7b, 0x3f, 0x90, 0x4c, + 0xed, 0x69, 0x22, 0x7f, 0x2d, 0x6e, 0x89, 0xe9, 0x02, 0xe7, 0x2e, 0xc3, 0xcd, 0x48, 0x4f, 0x32, + 0xde, 0x19, 0xf2, 0x20, 0x20, 0x6b, 0x87, 0xe4, 0x3c, 0xa9, 0xaf, 0x1a, 0xc2, 0xa1, 0x43, 0x88, + 0x3d, 0xc4, 0x0a, 0x65, 0x52, 0x25, 0x00, 0x3f, 0x9b, 0x52, 0x31, 0x5b, 0x28, 0x94, 0x9c, 0x67, + 0xb5, 0xd2, 0x53, 0x67, 0x75, 0x78, 0xd0, 0x7c, 0x32, 0xc8, 0x18, 0xdb, 0x2b, 0x55, 0x68, 0x80, + 0xb6, 0xf3, 0x2b, 0x12, 0xe6, 0x3f, 0x11, 0x17, 0xd5, 0x2b, 0xa4, 0x83, 0x1f, 0x1a, 0x5e, 0x61, + 0x00, 0xc9, 0x9d, 0xf8, 0x44, 0xa2, 0xbc, 0xf6, 0xac, 0x96, 0x3c, 0xa1, 0x21, 0x0f, 0xc9, 0xe6, + 0x30, 0x29, 0xdf, 0x9f, 0x72, 0xc5, 0x31, 0x35, 0xa9, 0x41, 0x6c, 0x18, 0x92, 0xac, 0xed, 0x72, + 0xec, 0x49, 0xf9, 0x05, 0x45, 0x45, 0x0a, 0xb0, 0x13, 0xeb, 0xe3, 0x1e, 0x17, 0xbe, 0x01, 0x42, + 0x5e, 0x00, 0x62, 0x9b, 0xfc, 0xa9, 0x30, 0xcf, 0x81, 0xcb, 0x7b, 0x21, 0x05, 0x84, 0x7c, 0x23, + 0xa5, 0xe9, 0x71, 0xbc, 0x72, 0xad, 0x0d, 0x2d, 0x7a, 0xda, 0x17, 0xae, 0xa1, 0xe6, 0xe3, 0xd3, + 0xaf, 0xa8, 0x4b, 0x80, 0xe7, 0x3c, 0x86, 0x6d, 0x45, 0x29, 0x1b, 0x5a, 0x38, 0x79, 0x0f, 0x93, + 0x24, 0xb2, 0x31, 0x02, 0xcd, 0x21, 0x5b, 0x87, 0x35, 0x46, 0x9c, 0x3b, 0xd2, 0x89, 0xcb, 0x9c, + 0x16, 0xea, 0xe6, 0xbc, 0x4e, 0xd7, 0x4b, 0xea, 0xb6, 0x43, 0x4a, 0x9a, 0x4a, 0xdb, 0x80, 0x7c, + 0xdc, 0xc6, 0x93, 0xce, 0x5c, 0xf5, 0x35, 0x7a, 0xb4, 0xfc, 0x7f, 0xe8, 0x37, 0xbd, 0xde, 0x5c, + 0x81, 0x20, 0x42, 0x94, 0x6c, 0x04, 0x4a, 0xbe, 0xa0, 0x91, 0xa2, 0xa5, 0x0a, 0x2d, 0xde, 0xef, + 0xf6, 0x4b, 0x15, 0xba, 0x98, 0x21, 0xf1, 0x05, 0x14, 0x4d, 0xdc, 0x06, 0xfa, 0x04, 0x97, 0xa3, + 0x8a, 0xa5, 0x09, 0xdc, 0xb1, 0x73, 0xdc, 0xc1, 0x2b, 0xde, 0x2f, 0x34, 0x55, 0x83, 0xcc, 0xbb, + 0x81, 0xc0, 0x27, 0xf8, 0x95, 0x23, 0xce, 0x74, 0x25, 0xe5, 0x32, 0x1e, 0x2d, 0x5f, 0xaf, 0xf6, + 0x27, 0xc7, 0xd2, 0x0e, 0xa4, 0x57, 0x73, 0xb1, 0x83, 0x63, 0xe8, 0x4b, 0xa6, 0x9c, 0xa5, 0x33, + 0xe3, 0x94, 0xc3, 0xb9, 0x1a, 0xc8, 0xaa, 0x58, 0x58, 0x55, 0xe9, 0x67, 0x81, 0x27, 0xa4, 0x1f, + 0x9a, 0x49, 0x95, 0x0a, 0xb7, 0xfb, 0x14, 0xc5, 0x88, 0x36, 0x00, 0x59, 0x06, 0x61, 0x66, 0x57, + 0x6a, 0xc5, 0x5c, 0x5d, 0xa0, 0x29, 0x5d, 0x15, 0xde, 0x30, 0xb4, 0xbe, 0x87, 0x54, 0x24, 0xa2, + 0xb8, 0x63, 0xad, 0xdc, 0xc1, 0x93, 0xde, 0x1b, 0xa3, 0x91, 0x38, 0xf9, 0x09, 0xd6, 0x01, 0xdf, + 0x25, 0x65, 0x90, 0x7e, 0xa5, 0x24, 0xbe, 0xa7, 0xc2, 0x1e, 0x74, 0x7f, 0xe2, 0xbb, 0x1d, 0xf9, + 0xc3, 0x8d, 0x4f, 0x70, 0x07, 0x5b, 0xbd, 0x9f, 0x6b, 0xaa, 0x6e, 0x61, 0xe3, 0x43, 0x6a, 0xe3, + 0xd6, 0x20, 0xea, 0x2a, 0x6d, 0xd0, 0x17, 0x38, 0xbc, 0x42, 0x0b, 0xc8, 0x3c, 0x88, 0x9f, 0x18, + 0xea, 0x92, 0x5e, 0x5d, 0xa1, 0x83, 0x44, 0x7c, 0x37, 0x7b, 0x09, 0xaf, 0x10, 0x1c, 0xce, 0xc5, + 0x22, 0xfc, 0x5a, 0xd2, 0xab, 0xb9, 0x98, 0xef, 0x8b, 0x54, 0x5b, 0x67, 0x10, 0xfa, 0x03, 0x03, + 0xca, 0x16, 0x3d, 0x71, 0x4b, 0x28, 0x43, 0xc8, 0x2d, 0x6e, 0xf7, 0x8b, 0x74, 0x4d, 0x67, 0x98, + 0xa7, 0x36, 0xc5, 0x44, 0x57, 0x02, 0x35, 0xd4, 0x84, 0xd4, 0xfd, 0xdb, 0x4e, 0x0d, 0x33, 0xa3, + 0x99, 0x6d, 0x3e, 0x84, 0x52, 0x6a, 0xb3, 0x95, 0xb2, 0xb6, 0x1c, 0x9b, 0xd9, 0x96, 0x33, 0xc2, + 0xcc, 0xcb, 0xf4, 0x38, 0xc0, 0x9c, 0x91, 0x10, 0xc6, 0xaa, 0x10, 0x54, 0x69, 0x60, 0x42, 0xa7, + 0x43, 0xec, 0x6f, 0xaa, 0xcb, 0xfb, 0xe5, 0x7f, 0xa3, 0xa2, 0x84, 0x1b, 0xd9, 0xe3, 0x28, 0x16, + 0x5a, 0x2a, 0x0f, 0x54, 0x5c, 0x82, 0xf3, 0xa9, 0x60, 0x94, 0x78, 0x5d, 0x04, 0x5a, 0x9a, 0x59, + 0x88, 0x05, 0x5e, 0xe4, 0x3f, 0x97, 0x93, 0x9b, 0x9b, 0x9b, 0x93, 0x6b, 0xce, 0x1d, 0x3d, 0xc9, + 0x70, 0x61, 0xc1, 0x49, 0x86, 0xce, 0x53, 0x78, 0xff, 0x5b, 0x85, 0x4e, 0xef, 0x59, 0x95, 0x32, + 0x66, 0xba, 0x7f, 0x3f, 0x75, 0xc4, 0x39, 0x21, 0xdc, 0xfb, 0xd1, 0xff, 0xab, 0xf3, 0x43, 0x71, + 0xb8, 0x67, 0x04, 0xb1, 0x73, 0xa6, 0x16, 0xd7, 0xa6, 0xf0, 0xf3, 0x3d, 0x77, 0x27, 0xf8, 0x21, + 0x7a, 0x09, 0x9e, 0x8a, 0x6c, 0xf3, 0xf2, 0xed, 0x2f, 0x24, 0x59, 0xd1, 0x9c, 0xca, 0x0b, 0xfe, + 0x7b, 0x00, 0x77, 0xc9, 0x1e, 0x65, 0x85, 0x67, 0xa4, 0x2c, 0xbf, 0x64, 0xbb, 0x29, 0xed, 0x1a, + 0x00, 0xf7, 0x8c, 0x6d, 0x92, 0x9e, 0xbe, 0x13, 0x73, 0xde, 0x7d, 0x75, 0x57, 0x8c, 0xab, 0x32, + 0x96, 0x11, 0xc6, 0x1a, 0x03, 0xee, 0x73, 0x9f, 0xe2, 0x32, 0xef, 0x4b, 0x8b, 0xf0, 0x0b, 0x1f, + 0x95, 0x1d, 0xc0, 0x3b, 0xf1, 0x2a, 0x43, 0x91, 0xb1, 0xe4, 0x11, 0x53, 0x3b, 0x9e, 0xbf, 0xee, + 0xfb, 0x33, 0xe8, 0x9f, 0xa9, 0x1d, 0x30, 0x02, 0x5f, 0xfa, 0x3c, 0xd8, 0x87, 0x25, 0x95, 0xd7, + 0x48, 0xdb, 0x14, 0x30, 0x4e, 0xbc, 0x52, 0x19, 0xbb, 0x42, 0x6c, 0x54, 0xdc, 0x27, 0x5e, 0x7a, + 0xc3, 0x9e, 0xa1, 0xde, 0x35, 0x48, 0xea, 0x08, 0x04, 0x92, 0x06, 0xe3, 0xdb, 0x48, 0xa3, 0xd1, + 0x03, 0x04, 0x32, 0x9b, 0x73, 0xf0, 0xb8, 0x94, 0x2d, 0xd7, 0x92, 0x37, 0x82, 0x3c, 0x7e, 0x3a, + 0xc2, 0x39, 0x88, 0x84, 0x73, 0x22, 0x59, 0x86, 0xc8, 0x92, 0xa9, 0x77, 0xe0, 0xef, 0x31, 0x7c, + 0xf5, 0x8d, 0x0f, 0xe0, 0xfd, 0xac, 0x3c, 0xe5, 0x01, 0xf5, 0x2c, 0xe8, 0x08, 0xcd, 0x66, 0x82, + 0xeb, 0x75, 0x1a, 0xbc, 0xd2, 0x1c, 0x37, 0xc2, 0x13, 0x70, 0x8f, 0xf8, 0x42, 0x94, 0x16, 0x0f, + 0xa5, 0x9f, 0x23, 0x66, 0x0d, 0xc1, 0x4d, 0xf4, 0x17, 0x25, 0xab, 0x5e, 0xac, 0xd7, 0x07, 0xd7, + 0xc4, 0x42, 0x37, 0x69, 0x17, 0xb3, 0x82, 0x59, 0x4a, 0xf7, 0x4b, 0x2f, 0xdc, 0x3c, 0x4a, 0x95, + 0x2d, 0xb8, 0xc9, 0x3d, 0x24, 0x3d, 0x31, 0x50, 0x31, 0x8f, 0x5c, 0x67, 0x1b, 0x27, 0xbe, 0x70, + 0xa7, 0x6a, 0x08, 0x15, 0x0e, 0xb5, 0x74, 0x26, 0x38, 0x61, 0x49, 0x8d, 0xe3, 0x50, 0xc9, 0xc0, + 0xcf, 0x41, 0x2d, 0x14, 0xfc, 0xe1, 0xf9, 0x5d, 0x6c, 0x03, 0x98, 0x41, 0x9f, 0x96, 0x85, 0x3f, + 0xe1, 0x6c, 0x3e, 0xc4, 0x95, 0x71, 0x2b, 0x84, 0x0f, 0x68, 0xff, 0x7e, 0xb2, 0x5c, 0x83, 0x62, + 0xaf, 0x0f, 0xfa, 0x65, 0xf5, 0x1a, 0x66, 0xf8, 0x13, 0x43, 0x42, 0x02, 0x7e, 0xb2, 0x86, 0xd7, + 0x49, 0x7a, 0x3c, 0x17, 0xde, 0x1c, 0xe5, 0xe7, 0xaa, 0xff, 0x17, 0xc3, 0x5d, 0x7e, 0xce, 0x4c, + 0x3e, 0x59, 0xfd, 0x62, 0x53, 0xb8, 0x49, 0x8f, 0x87, 0x1c, 0x85, 0x58, 0x22, 0x74, 0xe1, 0xb9, + 0x5f, 0xad, 0xf3, 0x19, 0x89, 0x4f, 0x94, 0x1d, 0x7a, 0x70, 0x2e, 0x35, 0x29, 0x91, 0xc2, 0x2a, + 0x3c, 0xa9, 0xb2, 0xcb, 0x2f, 0x3d, 0x7d, 0x53, 0xca, 0x1a, 0x60, 0x07, 0xa4, 0xd5, 0x77, 0x62, + 0x2e, 0xc3, 0x38, 0x53, 0x06, 0x25, 0x6b, 0x2c, 0xb9, 0x14, 0xff, 0x19, 0xf7, 0x7a, 0x43, 0x0a, + 0xaf, 0x8f, 0x3f, 0xc9, 0xbd, 0xd1, 0x04, 0x5e, 0x00, 0x84, 0x32, 0xdc, 0xeb, 0x1e, 0x6d, 0x9b, + 0x76, 0x40, 0x88, 0x74, 0x55, 0xce, 0x81, 0x89, 0xbc, 0x1a, 0x0f, 0x7b, 0xa1, 0xa9, 0xe7, 0x13, + 0x9d, 0x4e, 0xb1, 0x31, 0x6e, 0xa5, 0xf0, 0x2b, 0x57, 0xe5, 0x6c, 0xc6, 0x09, 0xc5, 0xc9, 0x8c, + 0x73, 0x13, 0xfe, 0x95, 0x04, 0x9d, 0x73, 0x9a, 0x0c, 0x08, 0x5e, 0x0e, 0x08, 0x86, 0x91, 0x1e, + 0x95, 0x62, 0x53, 0x8f, 0x7a, 0xfa, 0xee, 0x37, 0x7a, 0x7c, 0x29, 0x50, 0x03, 0x40, 0xfd, 0x63, + 0x25, 0xa3, 0x5a, 0x09, 0x37, 0x77, 0x2b, 0xfd, 0x78, 0x2c, 0x1c, 0x78, 0x57, 0x4b, 0xbf, 0x56, + 0xa3, 0x81, 0x49, 0x2d, 0x72, 0x3f, 0x1b, 0x3a, 0x54, 0x6a, 0xcf, 0xce, 0xa1, 0x82, 0xe3, 0xbf, + 0x31, 0x1c, 0xdd, 0x2d, 0x92, 0x78, 0x7d, 0x38, 0x5e, 0x6b, 0x52, 0x24, 0x3e, 0x76, 0x22, 0xaf, + 0xc3, 0x99, 0x70, 0x32, 0x7e, 0x9b, 0xeb, 0xa7, 0xb8, 0xf0, 0x60, 0xf5, 0xc8, 0x69, 0x10, 0xf5, + 0x1d, 0x36, 0xa2, 0xb3, 0x86, 0x9f, 0x8d, 0xe1, 0xdb, 0x65, 0x0d, 0x4c, 0xb4, 0xc7, 0xe5, 0xa5, + 0x5e, 0x69, 0x8c, 0xb4, 0x4d, 0x4b, 0x84, 0xd3, 0x6c, 0x23, 0xcc, 0x9a, 0xd4, 0x01, 0x68, 0x8e, + 0x39, 0xb9, 0x04, 0x40, 0x9d, 0x9a, 0x92, 0xaf, 0xab, 0xf8, 0x41, 0x8a, 0x00, 0x2e, 0x49, 0x57, + 0xfc, 0x79, 0x9c, 0xa0, 0xda, 0xc0, 0xa1, 0x93, 0x4c, 0x87, 0xc1, 0x91, 0x0b, 0x4e, 0xe5, 0x8f, + 0xc3, 0xac, 0x8b, 0x53, 0x79, 0xe7, 0x3b, 0x34, 0x5c, 0x04, 0x17, 0xaa, 0x25, 0xd4, 0x92, 0x7b, + 0x83, 0xef, 0x45, 0x77, 0x0a, 0xde, 0xbb, 0xf0, 0xa2, 0x9d, 0xf5, 0xb8, 0xbc, 0xf6, 0x3c, 0x78, + 0x86, 0x17, 0x1c, 0xf3, 0x5d, 0x95, 0xbd, 0x78, 0x63, 0x5f, 0x68, 0x51, 0x61, 0x4f, 0xc9, 0xbf, + 0xe6, 0x98, 0x0e, 0x73, 0x20, 0x79, 0x04, 0xcf, 0x9e, 0xaf, 0xd7, 0x24, 0xf9, 0xe3, 0x2f, 0x87, + 0xf3, 0xa7, 0x27, 0x9a, 0x9a, 0x25, 0xeb, 0x05, 0x12, 0x46, 0x56, 0x6a, 0x7c, 0x8b, 0xc0, 0xdd, + 0x49, 0xc1, 0x93, 0xa3, 0xe0, 0xad, 0x5d, 0x8b, 0xef, 0xe7, 0xde, 0x68, 0xd0, 0xe6, 0xf7, 0x0a, + 0x0b, 0x53, 0xac, 0x0a, 0xf8, 0x67, 0xf1, 0xfd, 0x15, 0x73, 0x24, 0xd3, 0xe9, 0x70, 0x13, 0x08, + 0x72, 0x33, 0x0c, 0x3d, 0xa9, 0x15, 0xe6, 0x7d, 0x68, 0x19, 0x4d, 0xd2, 0x35, 0xe8, 0x34, 0xe1, + 0x95, 0xee, 0xf6, 0xd4, 0x94, 0x36, 0x6e, 0x77, 0x18, 0x9e, 0x50, 0x7a, 0x1e, 0x30, 0x9c, 0x62, + 0x02, 0xef, 0xad, 0xcd, 0x51, 0x40, 0xba, 0x83, 0x58, 0xf0, 0x5d, 0xf1, 0xcd, 0x50, 0xd7, 0xf1, + 0x57, 0xa9, 0xf2, 0x82, 0x64, 0x3d, 0x1d, 0x6e, 0x0d, 0xc1, 0xea, 0x21, 0xf7, 0x4e, 0x01, 0xe7, + 0x31, 0x5b, 0xa3, 0x4e, 0x6e, 0x8e, 0x47, 0x91, 0x04, 0xe0, 0xfd, 0xee, 0x6c, 0xd5, 0x13, 0x70, + 0x6d, 0x33, 0x50, 0x64, 0xd7, 0x7a, 0x35, 0x78, 0xd7, 0x6b, 0xa9, 0x37, 0x09, 0xa6, 0xe9, 0x6b, + 0x53, 0x68, 0x8e, 0x8e, 0x38, 0xbd, 0x5a, 0xdf, 0xcb, 0x00, 0xd3, 0x57, 0x55, 0x75, 0x3b, 0x40, + 0x2f, 0x83, 0x78, 0xb6, 0x8e, 0x0f, 0x99, 0xce, 0x87, 0xdb, 0xd1, 0x89, 0x97, 0xf8, 0x38, 0x79, + 0xc1, 0x93, 0x24, 0xb3, 0x5b, 0x8f, 0x5b, 0x1f, 0x99, 0xdd, 0x1a, 0x3c, 0x34, 0xa4, 0xe9, 0x06, + 0x0e, 0x42, 0x42, 0x07, 0x1c, 0x85, 0x1f, 0x6d, 0x06, 0x99, 0x1c, 0x5a, 0x6d, 0x40, 0xab, 0x57, + 0xae, 0x7c, 0x15, 0x34, 0xca, 0xa9, 0xe3, 0x58, 0xf5, 0x3c, 0x80, 0xd8, 0x35, 0x5b, 0x16, 0x2e, + 0xe0, 0xca, 0x80, 0x4d, 0xb9, 0x3f, 0x52, 0xfd, 0x5e, 0x49, 0x56, 0xa2, 0xd9, 0x46, 0xed, 0xfc, + 0x64, 0x65, 0xf5, 0x47, 0x74, 0x45, 0x80, 0x3b, 0x98, 0x95, 0xb8, 0x6c, 0x35, 0x64, 0x0a, 0x02, + 0x77, 0x10, 0xaf, 0xf7, 0x68, 0xb8, 0x83, 0xc2, 0x4d, 0xb6, 0xb1, 0x34, 0xd2, 0xfe, 0x5b, 0x7a, + 0x84, 0xef, 0x81, 0xc8, 0xe0, 0x8a, 0xaa, 0xf0, 0x24, 0xd4, 0x8d, 0x5c, 0x86, 0xe3, 0xdd, 0x9a, + 0x27, 0x65, 0xcd, 0xe6, 0x0e, 0xfa, 0xbd, 0x8a, 0x4e, 0x6c, 0xf7, 0x43, 0x65, 0x8d, 0xfd, 0x59, + 0xba, 0xad, 0x38, 0x18, 0x11, 0xaa, 0xbc, 0x14, 0x0f, 0x88, 0xae, 0xdc, 0x47, 0x71, 0x72, 0x2d, + 0x7b, 0x87, 0xae, 0xb2, 0x8c, 0xb3, 0xf3, 0xf8, 0xf9, 0x87, 0xc5, 0xea, 0xa2, 0xb1, 0x78, 0x7c, + 0x36, 0xf8, 0x10, 0xf6, 0x07, 0x20, 0xcb, 0x37, 0xd1, 0x8e, 0xd7, 0x02, 0x7d, 0x3a, 0xbb, 0xb2, + 0x8a, 0xde, 0xb7, 0x2a, 0x50, 0x4f, 0x47, 0xcd, 0xfa, 0x2c, 0x24, 0xca, 0x55, 0x5d, 0xdb, 0x91, + 0x58, 0x82, 0xce, 0xdd, 0xe7, 0xfc, 0xa1, 0x4d, 0x59, 0x7f, 0x2d, 0xb4, 0x62, 0x6f, 0x08, 0xee, + 0x3f, 0xd8, 0x94, 0x67, 0xae, 0x05, 0x17, 0x6b, 0x39, 0xf7, 0x7d, 0xb8, 0xc7, 0xf3, 0x0e, 0xe6, + 0xfb, 0xec, 0x78, 0xd1, 0x91, 0x6e, 0x3d, 0x44, 0xe2, 0x9d, 0x9c, 0x2c, 0x4d, 0x71, 0x53, 0x56, + 0x58, 0x38, 0x43, 0x00, 0x77, 0x0d, 0xe9, 0x16, 0x6f, 0xe8, 0x8e, 0xe1, 0x76, 0xdc, 0x8c, 0x81, + 0x1c, 0x73, 0xe9, 0xf3, 0xca, 0xde, 0xff, 0xa2, 0x34, 0x91, 0xb6, 0x46, 0x92, 0xe0, 0xd8, 0x66, + 0x0c, 0x41, 0xd8, 0xbe, 0xac, 0x1c, 0xbd, 0x1b, 0x61, 0xb2, 0x7d, 0x36, 0xbd, 0xba, 0xb8, 0x3c, + 0x17, 0x2c, 0xef, 0x31, 0x8d, 0x7a, 0x54, 0x2d, 0x02, 0xcb, 0x58, 0xe9, 0xe9, 0x58, 0xf9, 0x63, + 0xfc, 0xaa, 0x54, 0xe9, 0x43, 0x48, 0xee, 0x83, 0x9a, 0xe0, 0x67, 0xb3, 0xa0, 0x13, 0xf1, 0xcb, + 0xf1, 0xdc, 0x41, 0x8f, 0xcd, 0x5c, 0xaa, 0x53, 0x78, 0x15, 0x3c, 0xae, 0x96, 0x73, 0xee, 0x62, + 0xf5, 0x0b, 0x53, 0x7a, 0xba, 0x4f, 0xd2, 0xa5, 0xe2, 0x68, 0xdf, 0x83, 0x87, 0x50, 0x00, 0xc0, + 0xd6, 0x20, 0x80, 0xa7, 0xc3, 0x64, 0x77, 0x16, 0x6e, 0xa5, 0x08, 0x7a, 0xb3, 0x62, 0xbd, 0x42, + 0x07, 0x18, 0x84, 0xca, 0xa9, 0x50, 0x67, 0x29, 0xdf, 0x7e, 0x34, 0x02, 0xaa, 0x1e, 0xe7, 0x4b, + 0xbe, 0xab, 0xa5, 0x34, 0x59, 0xb9, 0x18, 0x34, 0xf0, 0x8d, 0x12, 0xdf, 0x68, 0x0c, 0x90, 0x5d, + 0x06, 0x92, 0x95, 0xb0, 0x9f, 0xad, 0x89, 0xac, 0xc9, 0x4a, 0x24, 0x4f, 0xcf, 0x06, 0x32, 0xcc, + 0xe1, 0x19, 0x10, 0x26, 0xb3, 0x32, 0xe1, 0xaa, 0x5a, 0x11, 0xd4, 0x32, 0xdf, 0x2f, 0xaf, 0x0b, + 0xb3, 0x28, 0xff, 0x1e, 0x6c, 0x9a, 0xa5, 0x6d, 0x64, 0xe6, 0x41, 0xf4, 0x92, 0x1a, 0x10, 0x14, + 0x8a, 0xc2, 0x89, 0xf0, 0x20, 0x5e, 0xba, 0xba, 0x5a, 0xf4, 0x9a, 0xde, 0xd9, 0x89, 0x5b, 0x40, + 0x79, 0x96, 0xe0, 0x41, 0x4f, 0x7a, 0x4a, 0x32, 0x23, 0xac, 0xb8, 0x49, 0xc4, 0x52, 0x86, 0x07, + 0x05, 0x2a, 0x26, 0xe2, 0xab, 0x58, 0xd3, 0xfd, 0xf2, 0x50, 0x70, 0x18, 0x7b, 0x2e, 0xab, 0xc3, + 0x68, 0xc3, 0x61, 0x7c, 0x81, 0xc4, 0xb1, 0x98, 0x4b, 0x0d, 0xca, 0xec, 0x8f, 0x42, 0x1b, 0xa7, + 0xb3, 0x80, 0x2c, 0x14, 0xae, 0xfd, 0x2f, 0x78, 0x34, 0x64, 0x6c, 0x27, 0xad, 0x8f, 0xc7, 0x89, + 0x3f, 0x51, 0xcf, 0x28, 0x77, 0xfe, 0x40, 0xbd, 0x92, 0xa6, 0xa5, 0xb4, 0x53, 0xcc, 0xca, 0x9a, + 0xe0, 0x6a, 0x2f, 0xef, 0x0f, 0x6c, 0x4d, 0x50, 0xfe, 0xa7, 0x3f, 0x88, 0xbd, 0x5e, 0xca, 0x4a, + 0x18, 0x9b, 0x65, 0xe0, 0xaa, 0x9b, 0xe8, 0xc9, 0x3b, 0x3f, 0xf1, 0x8a, 0x37, 0x38, 0x62, 0x3a, + 0x8d, 0xac, 0xe7, 0x5b, 0x64, 0xfe, 0x3a, 0x3d, 0xa9, 0x2d, 0xb6, 0x8f, 0x0f, 0x4e, 0x66, 0x80, + 0x0a, 0xe1, 0x2f, 0x70, 0x07, 0xbd, 0x10, 0x4f, 0x18, 0x03, 0x4d, 0xfc, 0x75, 0xcc, 0x2c, 0x6e, + 0xe2, 0x3f, 0xc7, 0xd6, 0xa7, 0x8b, 0xf1, 0x6e, 0x19, 0xdf, 0x02, 0x3f, 0x5f, 0xe2, 0xc7, 0x0f, + 0x84, 0xb6, 0xd2, 0x99, 0x8a, 0xe3, 0xf7, 0xa1, 0xb3, 0x3e, 0xee, 0xf7, 0xb1, 0x8f, 0x2c, 0x3d, + 0x3b, 0xc0, 0x1d, 0x34, 0x7d, 0x9e, 0x43, 0x3f, 0x71, 0xf3, 0xef, 0x61, 0xc1, 0x7b, 0x99, 0xd6, + 0xcf, 0xd9, 0x4b, 0xc5, 0x4b, 0xc0, 0x2c, 0xd1, 0xcf, 0xaa, 0x38, 0xe6, 0x80, 0x45, 0x73, 0x7d, + 0xc1, 0x0a, 0x89, 0x29, 0x4d, 0xea, 0xd1, 0xf9, 0x53, 0x8e, 0xf8, 0x5c, 0x7b, 0x21, 0xea, 0xc6, + 0x34, 0xf5, 0x84, 0xb6, 0x5a, 0x91, 0x7e, 0x8a, 0x29, 0xa5, 0x89, 0xee, 0x28, 0xc6, 0x83, 0x03, + 0x5f, 0x8a, 0xbb, 0xad, 0xfc, 0xf5, 0xe2, 0x26, 0x7a, 0xcf, 0x50, 0x45, 0x9d, 0x3b, 0x78, 0xc2, + 0x9c, 0x53, 0x3a, 0x43, 0xe9, 0xfc, 0x5d, 0x10, 0x13, 0x61, 0x21, 0x65, 0x96, 0x5f, 0x91, 0xfb, + 0x54, 0x3a, 0xf7, 0xe3, 0x56, 0xcb, 0xf6, 0xbb, 0xdf, 0xd1, 0x79, 0x41, 0x55, 0xad, 0x93, 0x57, + 0xf1, 0x2e, 0x2e, 0xae, 0xad, 0x82, 0x97, 0x7f, 0x04, 0x12, 0xf6, 0x9b, 0xf8, 0xb9, 0x9b, 0xbf, + 0xa1, 0xe5, 0xa8, 0x1b, 0xaa, 0x44, 0x77, 0x55, 0x0b, 0x1d, 0x2d, 0x98, 0x50, 0x2c, 0xe9, 0x21, + 0xad, 0x87, 0x74, 0xf2, 0x7e, 0xb6, 0x38, 0xa5, 0x47, 0x98, 0x16, 0x2c, 0xd6, 0xf7, 0x9f, 0x2b, + 0x26, 0xfa, 0x62, 0x89, 0xf9, 0x44, 0x2d, 0x9e, 0x50, 0x9c, 0xd2, 0xc2, 0xbd, 0xe5, 0xf9, 0x84, + 0x96, 0x92, 0xe8, 0x60, 0x7c, 0x80, 0x66, 0xe8, 0x4f, 0xac, 0xf2, 0x01, 0xa0, 0x5e, 0x0d, 0x54, + 0x92, 0x51, 0x16, 0x84, 0x16, 0xd5, 0x2a, 0xbd, 0xc6, 0x86, 0xac, 0x12, 0x9b, 0x48, 0xad, 0xd2, + 0x3d, 0x4a, 0xdd, 0x87, 0x74, 0x18, 0x8a, 0x40, 0xeb, 0x0b, 0x05, 0x1d, 0x85, 0x1f, 0x86, 0x09, + 0x83, 0xfb, 0x3f, 0xfa, 0xb2, 0x30, 0xf8, 0xd6, 0x42, 0xdf, 0x58, 0xe7, 0x60, 0xc7, 0x33, 0xc4, + 0x1b, 0xcc, 0x6b, 0x0d, 0x95, 0xba, 0x4e, 0x84, 0x91, 0xe6, 0x2f, 0x9f, 0x09, 0x66, 0xff, 0x57, + 0x28, 0x5b, 0x79, 0x40, 0x85, 0x36, 0xb1, 0xe3, 0x75, 0x48, 0x46, 0x26, 0xde, 0xd1, 0x85, 0x7d, + 0xf9, 0xba, 0x32, 0x01, 0xa5, 0x87, 0x1e, 0x25, 0x98, 0xfd, 0xf4, 0x88, 0xe5, 0xb8, 0x54, 0x99, + 0x3f, 0x8d, 0xe8, 0x99, 0x95, 0x6e, 0x26, 0x78, 0xff, 0xe4, 0x18, 0x03, 0x5c, 0x91, 0xf3, 0xff, + 0x8c, 0x9f, 0x7f, 0x54, 0xd0, 0xf5, 0x51, 0xe2, 0xa8, 0x07, 0xd4, 0x61, 0x4e, 0x33, 0x59, 0x48, + 0xfe, 0x35, 0xbc, 0xe3, 0x66, 0x06, 0xe4, 0x6f, 0xff, 0x3a, 0xf8, 0xb5, 0xa7, 0x0b, 0xac, 0xf0, + 0x10, 0xf1, 0x93, 0x41, 0xf9, 0xd8, 0xf6, 0xe7, 0x42, 0x61, 0x0e, 0x84, 0x8b, 0x22, 0x7e, 0xe7, + 0x63, 0x12, 0x69, 0xcc, 0x02, 0x07, 0x87, 0x5c, 0x12, 0xf6, 0xdb, 0xef, 0x37, 0x51, 0x5e, 0x3c, + 0x7a, 0x05, 0x3f, 0xab, 0x98, 0x45, 0x1e, 0x46, 0x77, 0x59, 0x3c, 0x9e, 0x3a, 0xe2, 0x8e, 0x08, + 0xf5, 0x64, 0x63, 0x03, 0x0b, 0xdc, 0x3a, 0x2b, 0xcb, 0xd8, 0xff, 0xa0, 0x4e, 0x13, 0xe3, 0xa1, + 0x7e, 0x9d, 0x0b, 0xa3, 0xb9, 0x1a, 0xad, 0x8d, 0x05, 0x62, 0xbf, 0xca, 0xb8, 0x36, 0x69, 0x98, + 0xa6, 0x6a, 0x66, 0x37, 0xfc, 0x00, 0x6e, 0x7b, 0xe8, 0x5d, 0xc5, 0x57, 0x99, 0x97, 0x21, 0x29, + 0x7a, 0x34, 0xc2, 0x25, 0x00, 0xc6, 0xb1, 0x53, 0x3f, 0x06, 0xcf, 0x2d, 0xbf, 0xe1, 0xee, 0xf7, + 0x96, 0x6d, 0x79, 0xf8, 0x7d, 0x62, 0xd2, 0x24, 0x39, 0x13, 0xf5, 0xd2, 0xaa, 0xc4, 0xd8, 0xde, + 0xbd, 0xeb, 0x9f, 0x6e, 0xc8, 0x93, 0xd6, 0x26, 0x6a, 0x21, 0xd6, 0x85, 0x12, 0xc8, 0xd3, 0xf7, + 0xfe, 0x96, 0xb4, 0xac, 0x6f, 0xf8, 0x7e, 0xcd, 0x94, 0xfe, 0x6d, 0x9a, 0xde, 0xbd, 0x3e, 0x9d, + 0xbc, 0x93, 0x0b, 0xc8, 0xce, 0xf1, 0x81, 0xef, 0x7a, 0xf7, 0xde, 0x81, 0xb6, 0x50, 0x6d, 0x27, + 0x34, 0x0b, 0x81, 0xfb, 0x95, 0x73, 0x6c, 0x6d, 0x76, 0xe0, 0x07, 0x59, 0x01, 0xee, 0xa8, 0x07, + 0xb7, 0x05, 0xa1, 0xc6, 0xe9, 0x91, 0xff, 0xee, 0x18, 0x71, 0x1d, 0xd0, 0x0c, 0x03, 0x42, 0x23, + 0xf8, 0xda, 0x6b, 0xa1, 0x34, 0xab, 0x30, 0xa3, 0xd2, 0x61, 0x0a, 0x7e, 0x50, 0x73, 0x38, 0x1d, + 0xae, 0xb4, 0x8f, 0x4a, 0x6b, 0x94, 0x96, 0x51, 0xe9, 0x08, 0xc5, 0x33, 0x2a, 0x1d, 0xa9, 0xec, + 0x1f, 0x95, 0x1e, 0xa3, 0xbc, 0xab, 0xa6, 0xd7, 0xd1, 0xa4, 0x56, 0xf9, 0x09, 0x4d, 0xde, 0x2d, + 0x8f, 0x52, 0x5c, 0x23, 0xcb, 0xa3, 0x95, 0xe7, 0x83, 0xe5, 0x6a, 0x7a, 0xac, 0x52, 0x30, 0x2a, + 0xad, 0x53, 0x72, 0x46, 0xa5, 0xc7, 0x29, 0x69, 0xa3, 0xd2, 0xe3, 0x15, 0xe3, 0x68, 0xf8, 0x9c, + 0x62, 0x18, 0x85, 0x8f, 0x5e, 0xd1, 0x8f, 0xec, 0x2f, 0x46, 0x61, 0x47, 0xd7, 0x9f, 0xa0, 0xe0, + 0x9e, 0xf3, 0x70, 0x7a, 0xa2, 0xd2, 0x3e, 0x2a, 0x1d, 0xab, 0xb4, 0x8c, 0x4a, 0xdf, 0xa3, 0x78, + 0x46, 0xa5, 0x27, 0x29, 0xfb, 0x47, 0xa5, 0xef, 0x55, 0xde, 0x1d, 0x95, 0x8e, 0x53, 0x5e, 0x1b, + 0x95, 0x8e, 0x57, 0x5c, 0xa3, 0xd2, 0x93, 0xe9, 0xa1, 0xcc, 0xe1, 0xf4, 0x14, 0xe5, 0x99, 0x51, + 0xe9, 0x04, 0xc5, 0x3c, 0x2a, 0x3d, 0x55, 0x49, 0xfd, 0x6e, 0xc4, 0x78, 0xa6, 0x29, 0xc6, 0xef, + 0x46, 0x8d, 0x67, 0xba, 0x62, 0xf8, 0x4e, 0x3d, 0x03, 0xc3, 0xa0, 0x33, 0x81, 0x5f, 0x02, 0xc0, + 0x93, 0xfa, 0x18, 0xd1, 0xa1, 0xf0, 0x32, 0x78, 0x02, 0x2f, 0x19, 0x37, 0xab, 0xe0, 0xc9, 0xc8, + 0x4c, 0x4e, 0x36, 0x32, 0x69, 0x4e, 0x67, 0xd1, 0xe6, 0x72, 0x67, 0x51, 0xa1, 0x61, 0x6b, 0xd9, + 0x26, 0x61, 0x73, 0xd1, 0xfa, 0x8a, 0xa2, 0x82, 0xc2, 0xd9, 0x49, 0x86, 0xb2, 0x2d, 0x86, 0xf2, + 0xed, 0x45, 0xcc, 0x6a, 0xd3, 0x0a, 0xc6, 0x52, 0xb4, 0x41, 0xa8, 0x28, 0x71, 0xee, 0x60, 0xd6, + 0x6c, 0x2d, 0xaa, 0x28, 0xde, 0x54, 0xb6, 0x8d, 0xd9, 0x5c, 0xb4, 0x45, 0x60, 0x4c, 0x45, 0x9b, + 0xcb, 0x2a, 0x76, 0x18, 0x36, 0x17, 0x94, 0x1b, 0x8a, 0xb6, 0xdb, 0x0b, 0x04, 0x07, 0x00, 0x99, + 0xcb, 0x98, 0xd7, 0xf1, 0xab, 0x6d, 0x0f, 0x32, 0xb3, 0x1c, 0x90, 0xb9, 0xa1, 0xa8, 0xdc, 0x59, + 0x02, 0x80, 0x0a, 0x9c, 0x86, 0x59, 0xdb, 0xe7, 0x1a, 0xf8, 0x8a, 0x8a, 0xb2, 0x0a, 0xc3, 0x86, + 0xb2, 0xc2, 0xa2, 0xc5, 0x90, 0x06, 0xb0, 0x1b, 0x01, 0x8e, 0xd3, 0xb0, 0xa5, 0xcc, 0x69, 0x28, + 0xaf, 0x28, 0x72, 0xc0, 0x3b, 0x03, 0x5d, 0x1a, 0xa0, 0x13, 0x07, 0xb6, 0x72, 0x96, 0x95, 0x19, + 0xca, 0x36, 0x15, 0x32, 0x45, 0xdb, 0x9d, 0x58, 0xad, 0x18, 0xda, 0x3e, 0xbb, 0xa9, 0x6c, 0xc3, + 0x73, 0xb4, 0x41, 0x71, 0x99, 0xb0, 0xa5, 0x90, 0x59, 0xb1, 0x65, 0x6b, 0xc1, 0xa6, 0x92, 0x42, + 0x43, 0x59, 0x39, 0x42, 0x65, 0xd6, 0x42, 0x8b, 0xcd, 0x05, 0x5b, 0x76, 0x18, 0xf8, 0x45, 0x0f, + 0x25, 0x1b, 0xa0, 0x51, 0x45, 0x49, 0x91, 0x63, 0x06, 0x93, 0x51, 0x26, 0x6c, 0x2a, 0xa4, 0xad, + 0x8a, 0xb6, 0x14, 0x3c, 0xbb, 0xa9, 0xc8, 0x90, 0x06, 0xa5, 0x9b, 0x4a, 0xb6, 0x14, 0x21, 0xe8, + 0x87, 0x16, 0x1b, 0xcc, 0x05, 0x15, 0x4e, 0x43, 0x59, 0xb1, 0xa1, 0xbc, 0xc0, 0x69, 0x37, 0x94, + 0x38, 0x68, 0xcd, 0xc2, 0x92, 0x8a, 0xa2, 0x0d, 0x4e, 0x1c, 0xdf, 0x16, 0xe8, 0xd7, 0xb1, 0x63, + 0x33, 0xd4, 0x7f, 0x2e, 0x9a, 0xb1, 0xac, 0x30, 0x65, 0x32, 0x4c, 0x3a, 0xd0, 0xe8, 0xb9, 0xf2, + 0xb2, 0x12, 0x40, 0x38, 0xbb, 0x68, 0x4b, 0x51, 0x45, 0xc1, 0x26, 0x18, 0x40, 0x99, 0x13, 0x1a, + 0x20, 0xde, 0xc5, 0x05, 0xc2, 0x26, 0x27, 0x93, 0x59, 0xe2, 0x78, 0xce, 0x50, 0x44, 0x47, 0x8c, + 0x63, 0xcf, 0xac, 0x28, 0xd9, 0x5a, 0x84, 0xa3, 0x56, 0xbb, 0xcc, 0x4b, 0xcb, 0x5d, 0xbd, 0x62, + 0x75, 0xf6, 0x62, 0x43, 0x56, 0x09, 0xe0, 0xe3, 0xd8, 0x01, 0xb4, 0xdb, 0x6c, 0xb0, 0x17, 0x00, + 0xd1, 0xb6, 0x6c, 0xa8, 0xd8, 0xa1, 0x52, 0xad, 0xb8, 0xa8, 0xc0, 0x29, 0x54, 0x14, 0x01, 0x27, + 0xe6, 0x18, 0x1c, 0x4e, 0xa1, 0xb8, 0x18, 0xc6, 0x06, 0xe4, 0x2e, 0x71, 0x3c, 0x5b, 0x64, 0x2f, + 0xd8, 0x5a, 0x14, 0xcd, 0xac, 0xe7, 0x33, 0x96, 0xaf, 0xcf, 0xb2, 0xac, 0x67, 0xf8, 0xac, 0x15, + 0x06, 0x73, 0x5a, 0xee, 0x5a, 0x24, 0xbe, 0xa1, 0x64, 0x8b, 0xc3, 0x59, 0xb0, 0x69, 0x53, 0x01, + 0x85, 0xb1, 0xc1, 0x5e, 0x04, 0x04, 0x2b, 0x2e, 0x80, 0x5e, 0x0a, 0x91, 0xb8, 0x8b, 0x0d, 0x16, + 0x61, 0xc3, 0x86, 0x22, 0x87, 0xa3, 0x58, 0xd8, 0xb4, 0x69, 0x07, 0xd4, 0x2d, 0x71, 0x96, 0x00, + 0x05, 0x5f, 0x28, 0x2a, 0x8c, 0x66, 0x9c, 0xc5, 0xce, 0x72, 0x28, 0x2f, 0xaa, 0x00, 0x06, 0x20, + 0x19, 0x80, 0x21, 0x85, 0x25, 0x5b, 0x36, 0x1a, 0x9c, 0xf6, 0x22, 0x43, 0x31, 0xa2, 0x59, 0xb2, + 0xc5, 0xe0, 0xd8, 0x0c, 0xa0, 0xa1, 0xb8, 0xbc, 0x60, 0xc3, 0x73, 0x45, 0x4e, 0x87, 0x61, 0x76, + 0x89, 0x13, 0xeb, 0x01, 0x7f, 0x0b, 0x0d, 0xcf, 0xee, 0x70, 0x16, 0x39, 0x92, 0xe6, 0x18, 0x0a, + 0xcb, 0xb6, 0x6d, 0xd9, 0x54, 0x56, 0x50, 0x08, 0xa8, 0x6e, 0xb4, 0x3b, 0x0d, 0xce, 0x82, 0xe7, + 0x8a, 0x0c, 0x9b, 0xca, 0xb6, 0x6c, 0x2c, 0xaa, 0x98, 0x1b, 0xcd, 0x64, 0xa5, 0xad, 0x9d, 0xff, + 0x10, 0x93, 0x45, 0x11, 0x02, 0x0e, 0x1b, 0x68, 0x45, 0x40, 0x78, 0x63, 0x91, 0x61, 0xfe, 0x5c, + 0x66, 0xde, 0xb3, 0x65, 0x65, 0xce, 0x79, 0x9b, 0x4a, 0x36, 0x03, 0x73, 0x7e, 0xf8, 0x6c, 0x49, + 0x99, 0x63, 0x2e, 0x90, 0x86, 0xf9, 0x5e, 0xda, 0xe0, 0x00, 0x7c, 0x01, 0x99, 0x0d, 0x65, 0x15, + 0xc8, 0x23, 0x00, 0x3a, 0xe5, 0xc9, 0xf9, 0xc6, 0xcd, 0xe6, 0xb4, 0xd5, 0x2b, 0x32, 0xe0, 0xed, + 0x91, 0x25, 0xc6, 0xcd, 0x53, 0x9e, 0x4c, 0xde, 0xbc, 0xd8, 0xc0, 0xa4, 0x01, 0xf3, 0xb6, 0xfc, + 0x50, 0x70, 0x50, 0xa6, 0x6f, 0x1e, 0x21, 0xae, 0x20, 0x19, 0x3b, 0x70, 0x88, 0x40, 0xab, 0x92, + 0xc2, 0x22, 0x43, 0x81, 0x21, 0x58, 0xc7, 0xa1, 0xb2, 0x70, 0x2e, 0x73, 0x97, 0x3f, 0x6b, 0xd7, + 0xac, 0x31, 0x98, 0xd2, 0x56, 0xff, 0xc8, 0x60, 0x5b, 0xb3, 0xca, 0x6a, 0xe2, 0x2d, 0x23, 0xa5, + 0xa9, 0xb0, 0xc8, 0x59, 0x54, 0x81, 0xa8, 0x19, 0x10, 0x6d, 0x43, 0x21, 0xb2, 0x98, 0xa1, 0x68, + 0x40, 0xdf, 0xc9, 0x21, 0x56, 0x0b, 0x5b, 0x00, 0xcb, 0x32, 0xa0, 0x29, 0xed, 0x81, 0x4a, 0x84, + 0x43, 0x15, 0xdf, 0x68, 0xc6, 0x0c, 0x62, 0xef, 0x80, 0xee, 0x9f, 0x2b, 0xda, 0x81, 0xc4, 0xa8, + 0x28, 0x02, 0x86, 0xa3, 0xe0, 0x1b, 0x66, 0x39, 0xe6, 0x06, 0xf9, 0x91, 0xb1, 0xa9, 0xcc, 0x51, + 0x44, 0x39, 0x08, 0xb2, 0x00, 0x52, 0xb5, 0xb5, 0x04, 0x95, 0x83, 0x51, 0x35, 0x41, 0x25, 0x2b, + 0x70, 0xa8, 0x60, 0x8b, 0x41, 0x55, 0x13, 0xe8, 0x37, 0x99, 0xb1, 0x38, 0x81, 0x3d, 0xce, 0x8a, + 0x82, 0x0d, 0x45, 0x8b, 0xa3, 0x19, 0x83, 0xe1, 0xc9, 0x59, 0xe5, 0xf9, 0xd1, 0xcc, 0x72, 0xe0, + 0x46, 0x88, 0x08, 0xc0, 0xc4, 0xb2, 0x0d, 0x05, 0x20, 0xde, 0x8b, 0x0d, 0x6b, 0x04, 0x2a, 0xfb, + 0x6a, 0x81, 0xaa, 0xbd, 0xc0, 0x8f, 0x0a, 0x61, 0x03, 0x95, 0x3d, 0x47, 0xc9, 0xc6, 0x2d, 0xaa, + 0x14, 0x22, 0xb5, 0x05, 0xb4, 0x13, 0x4c, 0x3a, 0xe2, 0x6e, 0xa8, 0x28, 0x80, 0xae, 0xa9, 0x8e, + 0x17, 0x15, 0x42, 0xa6, 0x19, 0x39, 0xa8, 0x4a, 0x7e, 0x49, 0x50, 0x29, 0x83, 0x7a, 0xbb, 0xb9, + 0x60, 0x63, 0xc9, 0x86, 0x20, 0x2d, 0xf8, 0x2d, 0x4e, 0xb0, 0x23, 0x21, 0x1d, 0xab, 0x28, 0xda, + 0x28, 0x6c, 0x2a, 0xa8, 0x50, 0x85, 0x6b, 0x94, 0x9a, 0x3d, 0xf6, 0xd8, 0x63, 0x4c, 0x51, 0x61, + 0x09, 0x20, 0x88, 0x02, 0xc3, 0xcc, 0x9d, 0xc7, 0x44, 0x33, 0xab, 0xd7, 0x66, 0x59, 0x82, 0x60, + 0xb0, 0xc1, 0x08, 0x9d, 0x11, 0xb6, 0x38, 0x84, 0xf2, 0xf2, 0xb2, 0x0a, 0x34, 0x62, 0x41, 0xa5, + 0x71, 0x80, 0xaa, 0x45, 0x87, 0x2c, 0xc7, 0xb0, 0xbd, 0x30, 0x8d, 0x1a, 0xbe, 0xaa, 0xac, 0x94, + 0xb0, 0x73, 0x99, 0x19, 0x30, 0x74, 0x26, 0xb3, 0x68, 0x6b, 0xc9, 0x86, 0x22, 0xda, 0xa0, 0x60, + 0x2b, 0x94, 0x20, 0xcb, 0xee, 0x1a, 0x99, 0xb5, 0x16, 0x0b, 0x13, 0x3d, 0x63, 0x86, 0xc1, 0xa2, + 0x4a, 0x6b, 0x08, 0xed, 0x20, 0xec, 0x19, 0x58, 0xb4, 0x1c, 0xf4, 0xd2, 0xb0, 0xa3, 0x4c, 0x00, + 0x6a, 0x95, 0x97, 0x00, 0x36, 0xdf, 0x97, 0x5c, 0xe0, 0x2c, 0x6a, 0x53, 0x05, 0x88, 0xcb, 0x1c, + 0x03, 0x15, 0x76, 0xf8, 0x51, 0x2b, 0xcd, 0x31, 0x00, 0x01, 0x46, 0xca, 0x3f, 0xc2, 0x0b, 0x59, + 0x21, 0x30, 0x63, 0xc8, 0xa4, 0x32, 0x10, 0x35, 0xf8, 0x41, 0x10, 0xe5, 0x60, 0xb3, 0x4a, 0x70, + 0x04, 0x0e, 0xb4, 0xd4, 0x98, 0xa3, 0xca, 0x20, 0x1d, 0xc0, 0x63, 0xd1, 0xd1, 0xcc, 0x3f, 0x68, + 0x91, 0x2a, 0x6b, 0x19, 0x6b, 0x73, 0x57, 0x3d, 0x98, 0xb6, 0x6a, 0xed, 0x83, 0x99, 0xfc, 0x2a, + 0x55, 0xe4, 0xb0, 0xdd, 0x5c, 0x55, 0x64, 0x7e, 0xe8, 0x08, 0x9a, 0x64, 0x95, 0x91, 0x69, 0x9b, + 0x80, 0xfb, 0x34, 0x4d, 0xcd, 0x08, 0x63, 0x2a, 0xd8, 0x60, 0x47, 0x69, 0x57, 0x53, 0xc1, 0x0e, + 0xfe, 0xa1, 0x9f, 0xb9, 0xc0, 0xad, 0x7f, 0xa0, 0xb3, 0x03, 0x86, 0xe2, 0xc0, 0xe4, 0x36, 0x90, + 0x15, 0x55, 0xb0, 0x87, 0x6d, 0x40, 0x59, 0x79, 0xd1, 0x16, 0x95, 0x9a, 0xb3, 0xb6, 0x23, 0x15, + 0x9e, 0x05, 0x93, 0xa0, 0x1a, 0x18, 0xaa, 0xea, 0xa3, 0xac, 0xc2, 0xff, 0xd3, 0x38, 0x3c, 0x2b, + 0x94, 0x80, 0x7a, 0xae, 0xc8, 0x44, 0x43, 0xb9, 0xb9, 0xc0, 0xb9, 0xc1, 0x3e, 0x37, 0xfa, 0xae, + 0x99, 0x07, 0xf3, 0x5e, 0x58, 0x56, 0xa4, 0x0a, 0x1f, 0xd8, 0x1c, 0xb0, 0xfa, 0x60, 0xd2, 0xe6, + 0x05, 0x8b, 0x2d, 0xaa, 0xf0, 0x39, 0x0c, 0xdb, 0x4a, 0xb0, 0x5e, 0x91, 0xc3, 0x59, 0xb2, 0x45, + 0x95, 0x11, 0x9c, 0x17, 0x1c, 0xa3, 0x74, 0x6d, 0x61, 0x32, 0x10, 0xa1, 0xa0, 0x62, 0x94, 0xe8, + 0x45, 0x33, 0x3c, 0xa8, 0x05, 0xb2, 0x07, 0x15, 0x6f, 0xae, 0x01, 0x0c, 0xc5, 0x96, 0xad, 0x40, + 0x3c, 0x80, 0x00, 0xf3, 0xc3, 0xe6, 0x7f, 0x2a, 0x79, 0x40, 0x8c, 0xcc, 0x32, 0x01, 0xed, 0x82, + 0x4a, 0xf1, 0xed, 0x8b, 0x1e, 0x61, 0x6c, 0x25, 0x15, 0x4e, 0x01, 0x04, 0xce, 0x41, 0xab, 0x31, + 0x25, 0x8e, 0xb2, 0x94, 0x85, 0x0b, 0x93, 0xd5, 0x99, 0x62, 0x4b, 0xc1, 0xe6, 0x22, 0xd5, 0xfc, + 0xdd, 0x55, 0xbc, 0x64, 0xe3, 0x43, 0xf3, 0x17, 0x3c, 0xbc, 0xf0, 0x91, 0x45, 0x29, 0x05, 0xcf, + 0x6e, 0x28, 0x2c, 0x2a, 0x0e, 0xea, 0xbb, 0x61, 0xe9, 0x2c, 0xc7, 0x83, 0xb3, 0xca, 0x1f, 0x8d, + 0x66, 0x56, 0x58, 0xd6, 0xa8, 0x00, 0xb6, 0x94, 0xc1, 0x2c, 0x55, 0xb2, 0xb9, 0x00, 0xd0, 0x50, + 0xa7, 0x7a, 0x1c, 0xe4, 0x86, 0x8a, 0x92, 0x72, 0x54, 0xb3, 0x19, 0x38, 0xf3, 0xfe, 0x33, 0x6d, + 0x57, 0x99, 0x95, 0x0b, 0x4e, 0xc1, 0xb0, 0x11, 0x2a, 0x7a, 0x56, 0xd8, 0xc8, 0xac, 0xcb, 0xe2, + 0x73, 0x99, 0xd9, 0x5b, 0x60, 0x1e, 0x49, 0x0a, 0x56, 0x0a, 0x29, 0xca, 0x0a, 0xf3, 0xd6, 0x05, + 0x86, 0x82, 0xc2, 0x42, 0x14, 0xb8, 0xc5, 0x86, 0x99, 0xb3, 0x1c, 0x33, 0xd1, 0x19, 0xd1, 0x80, + 0x23, 0xa2, 0x67, 0xc3, 0x34, 0x5a, 0xbd, 0x21, 0xd5, 0x45, 0x9d, 0x13, 0x70, 0x4a, 0xe6, 0xc2, + 0x7f, 0xf8, 0xcc, 0x63, 0xa8, 0xdc, 0x30, 0xf1, 0xc9, 0x2c, 0xe3, 0x30, 0xaa, 0xcf, 0xab, 0xc1, + 0xdf, 0x06, 0xe3, 0x70, 0x1e, 0x96, 0x6b, 0xcd, 0x2c, 0x23, 0x43, 0x70, 0xb5, 0x03, 0x3c, 0xf6, + 0x3d, 0xe0, 0xe5, 0xbf, 0x0c, 0xbf, 0xaf, 0x42, 0xde, 0xbd, 0xf0, 0xbe, 0x31, 0x87, 0x65, 0xae, + 0x58, 0x58, 0xe6, 0x5b, 0x48, 0xef, 0x84, 0xf7, 0x0b, 0x50, 0x56, 0x00, 0x91, 0xee, 0xcf, 0xa0, + 0xec, 0x3d, 0xb3, 0x9a, 0xff, 0x15, 0x94, 0x0b, 0x90, 0xe7, 0xce, 0xc5, 0xfd, 0x7e, 0x08, 0xcc, + 0x82, 0xf5, 0xff, 0x5f, 0x4f, 0x25, 0xc0, 0x4a, 0x5e, 0xc9, 0x32, 0xa9, 0xf0, 0x98, 0xe1, 0x79, + 0x06, 0x9e, 0x72, 0x78, 0x5c, 0xf0, 0xbc, 0x06, 0xcf, 0xbb, 0xf0, 0xec, 0x87, 0xc7, 0x03, 0x4f, + 0x0b, 0x3c, 0xed, 0xf0, 0xf8, 0xf1, 0x14, 0xd2, 0xe3, 0x2c, 0xa3, 0x87, 0xc7, 0x00, 0x4f, 0x32, + 0x3c, 0xa9, 0xf0, 0x98, 0xe1, 0x79, 0x06, 0x9e, 0x72, 0x78, 0x5c, 0xf0, 0xbc, 0x06, 0xcf, 0xbb, + 0xf0, 0xec, 0x87, 0xc7, 0x03, 0x4f, 0x0b, 0x3c, 0xed, 0xf0, 0xf8, 0xe1, 0x61, 0xa0, 0x5f, 0x3d, + 0x3c, 0x06, 0x78, 0xd0, 0x9f, 0x8b, 0xc5, 0xb5, 0x57, 0x3c, 0x0a, 0xb9, 0xda, 0xca, 0xe4, 0xbf, + 0x37, 0x79, 0xab, 0xa3, 0xc9, 0xf5, 0xb3, 0xb5, 0xaf, 0x14, 0x64, 0xaf, 0x4e, 0x88, 0xaf, 0x5e, + 0xb2, 0xf4, 0x50, 0x52, 0x2a, 0x84, 0x22, 0x8e, 0xf2, 0x92, 0x2d, 0x42, 0x39, 0x33, 0xf9, 0x26, + 0xc3, 0xac, 0x5f, 0xbf, 0xb9, 0xac, 0xb0, 0xb0, 0x64, 0x3e, 0x43, 0x68, 0x42, 0x28, 0x2c, 0xd9, + 0x8a, 0xa9, 0xbd, 0x7f, 0x0f, 0xa5, 0x68, 0xf1, 0x02, 0x46, 0x33, 0x40, 0x33, 0x82, 0x95, 0xc7, + 0xde, 0x62, 0x18, 0x50, 0xd9, 0xe7, 0xa8, 0x3b, 0xb8, 0xde, 0x41, 0xad, 0x90, 0x83, 0xf1, 0x87, + 0x72, 0x37, 0x40, 0xb6, 0xb3, 0x68, 0x7d, 0xc9, 0x96, 0xc2, 0xa2, 0xed, 0x4c, 0x09, 0xb8, 0x9b, + 0x74, 0x4a, 0x65, 0xac, 0x2c, 0xb0, 0x09, 0xcd, 0xe3, 0xfc, 0xf5, 0xe8, 0x5a, 0x30, 0x2b, 0xc3, + 0x58, 0xaa, 0x5d, 0xeb, 0x51, 0xc5, 0x99, 0xb5, 0x9a, 0x60, 0x6a, 0x63, 0x91, 0x13, 0xca, 0xd1, + 0x63, 0x0b, 0x8b, 0x0c, 0x66, 0x81, 0x3d, 0x73, 0x14, 0xad, 0x47, 0x7b, 0x07, 0x73, 0x98, 0x5b, + 0x0b, 0x60, 0x54, 0x75, 0x5c, 0xef, 0x2c, 0x0b, 0x56, 0xcd, 0x8c, 0x62, 0x99, 0x60, 0xb7, 0x54, + 0x8b, 0xd6, 0xc3, 0x4c, 0xce, 0xe0, 0xa7, 0x31, 0x69, 0x7b, 0x44, 0x93, 0x79, 0x2e, 0x94, 0xda, + 0x80, 0x93, 0x26, 0xf3, 0xfe, 0xd8, 0x11, 0xfd, 0x6d, 0x14, 0x4a, 0x0a, 0x99, 0x09, 0xba, 0x11, + 0x39, 0x60, 0xdd, 0x8b, 0x36, 0x31, 0x2f, 0x43, 0x16, 0xed, 0x40, 0x05, 0x71, 0x73, 0x3c, 0x04, + 0x7d, 0x05, 0xce, 0xf9, 0x23, 0xab, 0xdc, 0xc3, 0x85, 0xf2, 0x70, 0x50, 0xeb, 0x37, 0x94, 0x6d, + 0x71, 0x02, 0x10, 0x26, 0x21, 0x26, 0x94, 0x4d, 0x47, 0x77, 0x71, 0xc2, 0xc8, 0x24, 0x54, 0x65, + 0x76, 0x4e, 0x02, 0x8c, 0xc1, 0x66, 0x16, 0x01, 0x3e, 0xe8, 0x1d, 0x57, 0xac, 0x07, 0xa3, 0x01, + 0xf9, 0xf8, 0x95, 0x14, 0xb5, 0x26, 0xed, 0x72, 0xcd, 0xdd, 0xa4, 0x8a, 0xf6, 0x0e, 0x48, 0x53, + 0xaa, 0x8f, 0x6e, 0xb5, 0x23, 0xee, 0x7b, 0xd9, 0xc5, 0x15, 0x65, 0x9b, 0x29, 0x11, 0x1e, 0x88, + 0x07, 0x00, 0x8e, 0x11, 0x08, 0xa7, 0x0d, 0x67, 0xd0, 0x61, 0xaf, 0xc4, 0x34, 0x45, 0xb2, 0x0d, + 0xdf, 0xd4, 0x6e, 0xa6, 0x4e, 0x86, 0x57, 0x8a, 0x40, 0x46, 0xe8, 0x0d, 0xe8, 0xca, 0x3c, 0x31, + 0x22, 0x81, 0x92, 0x53, 0xc4, 0xdc, 0x98, 0xc2, 0x86, 0xac, 0x90, 0x3a, 0x52, 0xbc, 0x80, 0x19, + 0xca, 0xa0, 0x00, 0xca, 0x47, 0x64, 0xa8, 0xc0, 0xdd, 0x34, 0x07, 0xcc, 0x0d, 0x70, 0xf3, 0xa7, + 0xf0, 0xee, 0x2c, 0x03, 0x33, 0x59, 0x54, 0xc1, 0xfc, 0x16, 0xde, 0x0b, 0x9e, 0x75, 0x30, 0x87, + 0xa6, 0xa3, 0xa0, 0x54, 0x6c, 0x28, 0xdf, 0xc1, 0x5c, 0x0b, 0xbe, 0x6e, 0x2e, 0x67, 0xf0, 0x43, + 0x20, 0xf8, 0x5a, 0x00, 0xf2, 0x06, 0xc9, 0x3d, 0x6a, 0x72, 0x0b, 0xbe, 0x9f, 0x51, 0xdf, 0xc1, + 0x04, 0x32, 0x5f, 0x18, 0x90, 0x63, 0x30, 0x36, 0x30, 0x5c, 0x20, 0x54, 0x33, 0x58, 0x06, 0x0c, + 0x9f, 0x2a, 0x27, 0x4e, 0x66, 0x0b, 0x24, 0x0b, 0x4b, 0x36, 0x02, 0x9b, 0x82, 0x19, 0xbf, 0x9a, + 0x41, 0x1b, 0x02, 0x02, 0x25, 0xcc, 0x03, 0x33, 0xc1, 0x42, 0x40, 0x43, 0xc0, 0x00, 0x0c, 0x20, + 0x08, 0x12, 0x5a, 0x76, 0xe6, 0xc5, 0xfb, 0x40, 0x0f, 0x0b, 0xb6, 0x80, 0x93, 0xb2, 0x3c, 0x91, + 0x65, 0x46, 0x44, 0x41, 0xcc, 0x9c, 0xfb, 0xa1, 0x7e, 0xb9, 0x73, 0x98, 0x90, 0xc7, 0xee, 0xc7, + 0x61, 0xad, 0xa7, 0x66, 0x6e, 0xfd, 0xe6, 0x67, 0x2b, 0x18, 0xe7, 0x6c, 0x96, 0x81, 0x5f, 0x55, + 0xa2, 0x0b, 0x99, 0x7d, 0xb3, 0x11, 0x54, 0x05, 0x6d, 0xc1, 0x2c, 0x9e, 0x7b, 0x17, 0x1a, 0x16, + 0x3f, 0xbb, 0x43, 0x85, 0xf1, 0xbb, 0x7f, 0xc8, 0x2e, 0x76, 0xa8, 0x6c, 0xbb, 0xfd, 0x0f, 0x25, + 0x1b, 0xca, 0xca, 0x2a, 0x0a, 0x99, 0x25, 0xf3, 0xbe, 0x9f, 0x8f, 0xb3, 0xdd, 0x7a, 0xd5, 0xdf, + 0x2c, 0x86, 0x42, 0x95, 0xce, 0x2f, 0x61, 0x35, 0xf5, 0xf5, 0xa3, 0xf9, 0x98, 0x09, 0x42, 0xc8, + 0x54, 0x2f, 0x50, 0xdf, 0x60, 0xf4, 0xf3, 0x1e, 0x56, 0x5f, 0xb7, 0x33, 0x0f, 0x2e, 0x0c, 0xb6, + 0x59, 0xef, 0xb8, 0xeb, 0x29, 0x32, 0x7f, 0x81, 0x4c, 0x10, 0xed, 0xad, 0xeb, 0x61, 0xaa, 0x52, + 0x35, 0x8c, 0x39, 0xfc, 0x08, 0x8c, 0xae, 0x68, 0x33, 0xc8, 0x58, 0x50, 0xe5, 0xa8, 0xd3, 0xc7, + 0x0c, 0x40, 0xb6, 0xa3, 0x00, 0x43, 0x07, 0x50, 0xd9, 0x60, 0x94, 0xc5, 0x78, 0x96, 0xa8, 0xb4, + 0x55, 0xeb, 0x33, 0xdd, 0x4b, 0x90, 0x49, 0x25, 0x77, 0xd3, 0x63, 0x1f, 0x55, 0x8b, 0x2b, 0x0a, + 0xb6, 0x85, 0xb2, 0x0c, 0x90, 0x55, 0xbe, 0x79, 0x33, 0xc8, 0x71, 0x51, 0x11, 0x53, 0xf2, 0x28, + 0xd5, 0xcc, 0x11, 0x9d, 0xef, 0xfe, 0x7e, 0xce, 0x7a, 0xe7, 0x8e, 0x72, 0xd4, 0x7d, 0x98, 0xa4, + 0x60, 0x5e, 0xfa, 0xf9, 0xff, 0x59, 0xac, 0x4a, 0x6e, 0xe3, 0x63, 0x80, 0x3f, 0x62, 0xaf, 0x1a, + 0x9c, 0xe2, 0x32, 0x66, 0x63, 0xea, 0x3f, 0x1b, 0x11, 0x2a, 0xab, 0x94, 0xa6, 0x62, 0xb3, 0xa5, + 0x68, 0xdb, 0x7a, 0xd5, 0x98, 0x6d, 0xcf, 0x60, 0x31, 0x64, 0x02, 0x62, 0x6f, 0x29, 0x5c, 0xaf, + 0xd2, 0x9f, 0x91, 0x82, 0x79, 0xd4, 0xba, 0xd9, 0x32, 0x59, 0x3a, 0xf3, 0xa9, 0x5a, 0xf1, 0xdf, + 0xd9, 0x20, 0xda, 0x0f, 0x81, 0x02, 0x50, 0xef, 0x28, 0x66, 0xb9, 0x9a, 0x52, 0x23, 0x4e, 0xe6, + 0xe8, 0xf2, 0x20, 0x39, 0x8a, 0x20, 0x32, 0x65, 0x56, 0xaf, 0x40, 0xdc, 0x31, 0x3a, 0x66, 0x36, + 0xaf, 0x08, 0x16, 0x94, 0x14, 0x3a, 0x71, 0x69, 0x26, 0xa0, 0xfe, 0xbf, 0x7d, 0xd8, 0xd0, 0xff, + 0xe4, 0x47, 0xff, 0xbd, 0xff, 0xe7, 0x0f, 0x96, 0xff, 0x7b, 0xf0, 0xf7, 0x8d, 0x50, 0xfa, 0x6c, + 0x30, 0x7d, 0x56, 0xad, 0xf4, 0xef, 0x06, 0xf5, 0xf7, 0x8d, 0xe1, 0xff, 0x8b, 0xd4, 0xff, 0x07, + 0x6e, 0xe1, 0x51, 0x7d, 0x40, 0x6c, 0x00, 0x00, +}; diff --git a/FloridOS/limine-binary/limine-bios-pxe.bin b/FloridOS/limine-binary/limine-bios-pxe.bin new file mode 100644 index 0000000..9f7968b Binary files /dev/null and b/FloridOS/limine-binary/limine-bios-pxe.bin differ diff --git a/FloridOS/limine-binary/limine-bios.sys b/FloridOS/limine-binary/limine-bios.sys new file mode 100644 index 0000000..067c730 Binary files /dev/null and b/FloridOS/limine-binary/limine-bios.sys differ diff --git a/FloridOS/limine-binary/limine-uefi-cd.bin b/FloridOS/limine-binary/limine-uefi-cd.bin new file mode 100644 index 0000000..af0f804 Binary files /dev/null and b/FloridOS/limine-binary/limine-uefi-cd.bin differ diff --git a/FloridOS/limine-binary/limine.c b/FloridOS/limine-binary/limine.c new file mode 100644 index 0000000..5b4b63b --- /dev/null +++ b/FloridOS/limine-binary/limine.c @@ -0,0 +1,1290 @@ +#undef IS_WINDOWS +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__) +#define IS_WINDOWS 1 +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef LIMINE_NO_BIOS +#include "limine-bios-hdd.h" +#endif + +static char *program_name = NULL; + +static void perror_wrap(const char *fmt, ...) { + int old_errno = errno; + + fprintf(stderr, "%s: ", program_name); + + va_list args; + va_start(args, fmt); + + vfprintf(stderr, fmt, args); + + va_end(args); + + fprintf(stderr, ": %s\n", strerror(old_errno)); +} + +static void remove_arg(int *argc, char *argv[], int index) { + for (int i = index; i < *argc - 1; i++) { + argv[i] = argv[i + 1]; + } + + (*argc)--; + + argv[*argc] = NULL; +} + +#ifndef LIMINE_NO_BIOS + +static bool quiet = false; + +static int set_pos(FILE *stream, uint64_t pos) { + if (sizeof(long) >= 8) { + return fseek(stream, (long)pos, SEEK_SET); + } + + long jump_size = (LONG_MAX / 2) + 1; + long last_jump = pos % jump_size; + uint64_t jumps = pos / jump_size; + + rewind(stream); + + for (uint64_t i = 0; i < jumps; i++) { + if (fseek(stream, jump_size, SEEK_CUR) != 0) { + return -1; + } + } + if (fseek(stream, last_jump, SEEK_CUR) != 0) { + return -1; + } + + return 0; +} + +#define DIV_ROUNDUP(a, b) (((a) + ((b) - 1)) / (b)) + +struct gpt_table_header { + // the head + char signature[8]; + uint32_t revision; + uint32_t header_size; + uint32_t crc32; + uint32_t _reserved0; + + // the partitioning info + uint64_t my_lba; + uint64_t alternate_lba; + uint64_t first_usable_lba; + uint64_t last_usable_lba; + + // the guid + uint64_t disk_guid[2]; + + // entries related + uint64_t partition_entry_lba; + uint32_t number_of_partition_entries; + uint32_t size_of_partition_entry; + uint32_t partition_entry_array_crc32; +}; + +struct gpt_entry { + uint64_t partition_type_guid[2]; + + uint64_t unique_partition_guid[2]; + + uint64_t starting_lba; + uint64_t ending_lba; + + uint64_t attributes; + + uint16_t partition_name[36]; +}; + +// This table from https://web.mit.edu/freebsd/head/sys/libkern/crc32.c +static const uint32_t crc32_table[] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, + 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, + 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, + 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, + 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, + 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, + 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, + 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, + 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, + 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, + 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, + 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, + 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, + 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, + 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, + 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, + 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, + 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d +}; + +static uint32_t crc32(void *_stream, size_t len) { + uint8_t *stream = _stream; + uint32_t ret = 0xffffffff; + + for (size_t i = 0; i < len; i++) { + ret = (ret >> 8) ^ crc32_table[(ret ^ stream[i]) & 0xff]; + } + + ret ^= 0xffffffff; + return ret; +} + +static uint16_t endswap16(uint16_t value) { + uint16_t ret = 0; + ret |= (value >> 8) & 0x00ff; + ret |= (value << 8) & 0xff00; + return ret; +} + +static uint32_t endswap32(uint32_t value) { + uint32_t ret = 0; + ret |= (value >> 24) & 0x000000ff; + ret |= (value >> 8) & 0x0000ff00; + ret |= (value << 8) & 0x00ff0000; + ret |= (value << 24) & 0xff000000; + return ret; +} + +static uint64_t endswap64(uint64_t value) { + uint64_t ret = 0; + ret |= (value >> 56) & 0x00000000000000ff; + ret |= (value >> 40) & 0x000000000000ff00; + ret |= (value >> 24) & 0x0000000000ff0000; + ret |= (value >> 8) & 0x00000000ff000000; + ret |= (value << 8) & 0x000000ff00000000; + ret |= (value << 24) & 0x0000ff0000000000; + ret |= (value << 40) & 0x00ff000000000000; + ret |= (value << 56) & 0xff00000000000000; + return ret; +} + +#ifdef __BYTE_ORDER__ + +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +#define bigendian true +#else +#define bigendian false +#endif + +#else /* !__BYTE_ORDER__ */ + +static bool bigendian = false; + +#endif /* !__BYTE_ORDER__ */ + +#define ENDSWAP(VALUE) (bigendian ? ( \ + sizeof(VALUE) == 1 ? (VALUE) : \ + sizeof(VALUE) == 2 ? endswap16(VALUE) : \ + sizeof(VALUE) == 4 ? endswap32(VALUE) : \ + sizeof(VALUE) == 8 ? endswap64(VALUE) : (abort(), 1) \ +) : (VALUE)) + +static enum { + CACHE_CLEAN, + CACHE_DIRTY +} cache_state; +static uint64_t cached_block; +static uint8_t *cache = NULL; +static FILE *device = NULL; +static size_t block_size; + +static bool device_init(void) { + size_t guesses[] = { 512, 2048, 4096 }; + + for (size_t i = 0; i < sizeof(guesses) / sizeof(size_t); i++) { + void *tmp = realloc(cache, guesses[i]); + if (tmp == NULL) { + perror_wrap("error: device_init(): realloc()"); + return false; + } + cache = tmp; + + rewind(device); + + size_t ret = fread(cache, guesses[i], 1, device); + if (ret != 1) { + continue; + } + + block_size = guesses[i]; + + if (!quiet) { + fprintf(stderr, "Physical block size of %zu bytes.\n", block_size); + } + + cache_state = CACHE_CLEAN; + cached_block = 0; + return true; + } + + fprintf(stderr, "%s: error: device_init(): Couldn't determine block size of device.\n", program_name); + return false; +} + +static bool device_flush_cache(void) { + if (cache_state == CACHE_CLEAN) + return true; + + if (set_pos(device, cached_block * block_size) != 0) { + perror_wrap("error: device_flush_cache(): set_pos()"); + return false; + } + + size_t ret = fwrite(cache, block_size, 1, device); + if (ret != 1) { + if (ferror(device)) { + perror_wrap("error: device_flush_cache(): fwrite()"); + } + return false; + } + + cache_state = CACHE_CLEAN; + return true; +} + +static bool device_cache_block(uint64_t block) { + if (cached_block == block) + return true; + + if (cache_state == CACHE_DIRTY) { + if (!device_flush_cache()) + return false; + } + + if (set_pos(device, block * block_size) != 0) { + perror_wrap("error: device_cache_block(): set_pos()"); + return false; + } + + size_t ret = fread(cache, block_size, 1, device); + if (ret != 1) { + if (ferror(device)) { + perror_wrap("error: device_cache_block(): fread()"); + } + return false; + } + + cached_block = block; + + return true; +} + +struct uninstall_data { + void *data; + uint64_t loc; + uint64_t count; +}; + +#define UNINSTALL_DATA_MAX 256 + +static bool uninstalling = false; +static struct uninstall_data uninstall_data[UNINSTALL_DATA_MAX]; +static struct uninstall_data uninstall_data_rev[UNINSTALL_DATA_MAX]; +static uint64_t uninstall_data_i = 0; +static const char *uninstall_file = NULL; + +static void reverse_uninstall_data(void) { + for (size_t i = 0, j = uninstall_data_i - 1; i < uninstall_data_i; i++, j--) { + uninstall_data_rev[j] = uninstall_data[i]; + } + + memcpy(uninstall_data, uninstall_data_rev, uninstall_data_i * sizeof(struct uninstall_data)); +} + +static void free_uninstall_data(void) { + for (size_t i = 0; i < uninstall_data_i; i++) { + free(uninstall_data[i].data); + } +} + +static bool store_uninstall_data(const char *filename) { + if (!quiet) { + fprintf(stderr, "Storing uninstall data to file: `%s`...\n", filename); + } + + FILE *udfile = fopen(filename, "wb"); + if (udfile == NULL) { + perror_wrap("error: `%s`", filename); + goto error; + } + + if (fwrite(&uninstall_data_i, sizeof(uint64_t), 1, udfile) != 1) { + goto fwrite_error; + } + + for (size_t i = 0; i < uninstall_data_i; i++) { + if (fwrite(&uninstall_data[i].loc, sizeof(uint64_t), 1, udfile) != 1) { + goto fwrite_error; + } + if (fwrite(&uninstall_data[i].count, sizeof(uint64_t), 1, udfile) != 1) { + goto fwrite_error; + } + if (fwrite(uninstall_data[i].data, uninstall_data[i].count, 1, udfile) != 1) { + goto fwrite_error; + } + } + + fclose(udfile); + return true; + +fwrite_error: + perror_wrap("error: store_uninstall_data(): fwrite()"); + +error: + if (udfile != NULL) { + fclose(udfile); + } + return false; +} + +static bool load_uninstall_data(const char *filename) { + if (!quiet) { + fprintf(stderr, "Loading uninstall data from file: `%s`...\n", filename); + } + + FILE *udfile = fopen(filename, "rb"); + if (udfile == NULL) { + perror_wrap("error: `%s`", filename); + goto error; + } + + if (fread(&uninstall_data_i, sizeof(uint64_t), 1, udfile) != 1) { + goto fread_error; + } + + for (size_t i = 0; i < uninstall_data_i; i++) { + if (fread(&uninstall_data[i].loc, sizeof(uint64_t), 1, udfile) != 1) { + goto fread_error; + } + if (fread(&uninstall_data[i].count, sizeof(uint64_t), 1, udfile) != 1) { + goto fread_error; + } + uninstall_data[i].data = malloc(uninstall_data[i].count); + if (uninstall_data[i].data == NULL) { + perror_wrap("error: load_uninstall_data(): malloc()"); + goto error; + } + if (fread(uninstall_data[i].data, uninstall_data[i].count, 1, udfile) != 1) { + goto fread_error; + } + } + + fclose(udfile); + return true; + +fread_error: + perror_wrap("error: load_uninstall_data(): fread()"); + +error: + if (udfile != NULL) { + fclose(udfile); + } + return false; +} + +static bool _device_read(void *_buffer, uint64_t loc, size_t count) { + uint8_t *buffer = _buffer; + uint64_t progress = 0; + while (progress < count) { + uint64_t block = (loc + progress) / block_size; + + if (!device_cache_block(block)) { + return false; + } + + uint64_t chunk = count - progress; + uint64_t offset = (loc + progress) % block_size; + if (chunk > block_size - offset) + chunk = block_size - offset; + + memcpy(buffer + progress, &cache[offset], chunk); + progress += chunk; + } + + return true; +} + +static bool _device_write(const void *_buffer, uint64_t loc, size_t count) { + if (uninstalling) { + goto skip_save; + } + + if (uninstall_data_i >= UNINSTALL_DATA_MAX) { + fprintf(stderr, "%s: error: Too many uninstall data entries! Please report this bug upstream.\n", program_name); + return false; + } + + struct uninstall_data *ud = &uninstall_data[uninstall_data_i]; + + ud->data = malloc(count); + if (ud->data == NULL) { + perror_wrap("error: _device_write(): malloc()"); + return false; + } + + if (!_device_read(ud->data, loc, count)) { + return false; + } + + ud->loc = loc; + ud->count = count; + +skip_save:; + const uint8_t *buffer = _buffer; + uint64_t progress = 0; + while (progress < count) { + uint64_t block = (loc + progress) / block_size; + + if (!device_cache_block(block)) { + return false; + } + + uint64_t chunk = count - progress; + uint64_t offset = (loc + progress) % block_size; + if (chunk > block_size - offset) + chunk = block_size - offset; + + memcpy(&cache[offset], buffer + progress, chunk); + cache_state = CACHE_DIRTY; + progress += chunk; + } + + if (!uninstalling) { + uninstall_data_i++; + } + return true; +} + +static bool uninstall(bool quiet_arg) { + bool print_cache_flush_fail = false; + bool print_write_fail = false; + bool ret = true; + + uninstalling = true; + + cache_state = CACHE_CLEAN; + cached_block = (uint64_t)-1; + + for (size_t i = 0; i < uninstall_data_i; i++) { + struct uninstall_data *ud = &uninstall_data[i]; + bool retry = false; + while (!_device_write(ud->data, ud->loc, ud->count)) { + if (retry) { + fprintf(stderr, "%s: warning: Retry failed.\n", program_name); + print_write_fail = true; + break; + } + if (!quiet) { + fprintf(stderr, "%s: warning: Uninstall data index %zu failed to write, retrying...\n", program_name, i); + } + if (!device_flush_cache()) { + print_cache_flush_fail = true; + } + cache_state = CACHE_CLEAN; + cached_block = (uint64_t)-1; + retry = true; + } + } + + if (!device_flush_cache()) { + print_cache_flush_fail = true; + } + + if (print_write_fail) { + fprintf(stderr, "%s: error: Some data failed to be uninstalled correctly.\n", program_name); + ret = false; + } + + if (print_cache_flush_fail) { + fprintf(stderr, "%s: error: Device cache flush failure. Uninstall may be incomplete.\n", program_name); + ret = false; + } + + if (ret == true && !quiet && !quiet_arg) { + fprintf(stderr, "Uninstall data restored successfully.\n"); + } + + return ret; +} + +#define device_read(BUFFER, LOC, COUNT) \ + do { \ + if (!_device_read(BUFFER, LOC, COUNT)) \ + goto cleanup; \ + } while (0) + +#define device_write(BUFFER, LOC, COUNT) \ + do { \ + if (!_device_write(BUFFER, LOC, COUNT)) \ + goto cleanup; \ + } while (0) + +static void bios_install_usage(void) { + printf("usage: %s bios-install [GPT partition index]\n", program_name); + printf("\n"); + printf(" --force-mbr Force MBR detection to work even if the\n"); + printf(" safety checks fail (DANGEROUS!)\n"); + printf("\n"); + printf(" --uninstall Reverse the entire install procedure\n"); + printf("\n"); + printf(" --uninstall-data-file=\n"); + printf(" Set the input (for --uninstall) or output file\n"); + printf(" name of the file which contains uninstall data\n"); + printf("\n"); + printf(" --quiet Do not print verbose diagnostic messages\n"); + printf("\n"); + printf(" --help | -h Display this help message\n"); + printf("\n"); +} + +static int bios_install(int argc, char *argv[]) { + int ok = EXIT_FAILURE; + int force_mbr = 0; + bool uninstall_mode = false; + const uint8_t *bootloader_img = binary_limine_hdd_bin_data; + size_t bootloader_file_size = sizeof(binary_limine_hdd_bin_data); + uint8_t orig_mbr[70], timestamp[6]; + const char *part_ndx = NULL; + +#ifndef __BYTE_ORDER__ + uint32_t endcheck = 0x12345678; + uint8_t endbyte = *((uint8_t *)&endcheck); + bigendian = endbyte == 0x12; +#endif + + if (argc < 2) { + bios_install_usage(); +#ifdef IS_WINDOWS + system("pause"); +#endif + return EXIT_FAILURE; + } + + for (int i = 1; i < argc; i++) { + if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) { + bios_install_usage(); + return EXIT_SUCCESS; + } else if (strcmp(argv[i], "--quiet") == 0) { + quiet = true; + } else if (strcmp(argv[i], "--force-mbr") == 0) { + if (force_mbr && !quiet) { + fprintf(stderr, "%s: warning: --force-mbr already set.\n", program_name); + } + force_mbr = 1; + } else if (strcmp(argv[i], "--uninstall") == 0) { + if (uninstall_mode && !quiet) { + fprintf(stderr, "%s: warning: --uninstall already set.\n", program_name); + } + uninstall_mode = true; + } else if (memcmp(argv[i], "--uninstall-data-file=", 21) == 0) { + if (uninstall_file != NULL && !quiet) { + fprintf(stderr, "%s: warning: --uninstall-data-file already set. Overriding...\n", program_name); + } + uninstall_file = argv[i] + 21; + if (strlen(uninstall_file) == 0) { + fprintf(stderr, "%s: error: Uninstall data file has a zero-length name!\n", program_name); + return EXIT_FAILURE; + } + } else { + if (device != NULL) { // [GPT partition index] + part_ndx = argv[i]; // TODO: Make this non-positional? + } else if ((device = fopen(argv[i], "r+b")) == NULL) { // + perror_wrap("error: `%s`", argv[i]); + return EXIT_FAILURE; + } + } + } + + if (device == NULL) { + fprintf(stderr, "%s: error: No device specified\n", program_name); + bios_install_usage(); + return EXIT_FAILURE; + } + + if (!device_init()) { + goto uninstall_mode_cleanup; + } + + if (uninstall_mode) { + if (uninstall_file == NULL) { + fprintf(stderr, "%s: error: Uninstall mode set but no --uninstall-data-file=... passed.\n", program_name); + goto uninstall_mode_cleanup; + } + + if (!load_uninstall_data(uninstall_file)) { + goto uninstall_mode_cleanup; + } + + if (uninstall(false) == false) { + ok = EXIT_FAILURE; + } else { + ok = EXIT_SUCCESS; + } + goto uninstall_mode_cleanup; + } + + // Probe for GPT and logical block size + int gpt = 0; + struct gpt_table_header gpt_header; + uint64_t lb_guesses[] = { 512, 4096 }; + uint64_t lb_size = 0; + for (size_t i = 0; i < sizeof(lb_guesses) / sizeof(uint64_t); i++) { + device_read(&gpt_header, lb_guesses[i], sizeof(struct gpt_table_header)); + if (!strncmp(gpt_header.signature, "EFI PART", 8)) { + lb_size = lb_guesses[i]; + if (!force_mbr) { + gpt = 1; + if (!quiet) { + fprintf(stderr, "Installing to GPT. Logical block size of %" PRIu64 " bytes.\n", + lb_guesses[i]); + } + } else { + fprintf(stderr, "%s: error: Device has a valid GPT, refusing to force MBR.\n", program_name); + goto cleanup; + } + break; + } + } + + struct gpt_table_header secondary_gpt_header; + if (gpt) { + if (!quiet) { + fprintf(stderr, "Secondary header at LBA 0x%" PRIx64 ".\n", + ENDSWAP(gpt_header.alternate_lba)); + } + device_read(&secondary_gpt_header, lb_size * ENDSWAP(gpt_header.alternate_lba), + sizeof(struct gpt_table_header)); + if (!strncmp(secondary_gpt_header.signature, "EFI PART", 8)) { + if (!quiet) { + fprintf(stderr, "Secondary header valid.\n"); + } + } else { + fprintf(stderr, "%s: error: Secondary header not valid, aborting.\n", program_name); + goto cleanup; + } + } + + int mbr = 0; + if (gpt == 0) { + // Do all sanity checks on MBR + mbr = 1; + + uint8_t hint8 = 0; + uint16_t hint16 = 0; + uint32_t hint32 = 0; + + bool any_active = false; + + device_read(&hint8, 446, sizeof(uint8_t)); + if (hint8 != 0x00 && hint8 != 0x80) { + if (!force_mbr) { + mbr = 0; + } else { + hint8 &= 0x80; + device_write(&hint8, 446, sizeof(uint8_t)); + } + } + any_active = any_active || (hint8 & 0x80) != 0; + device_read(&hint8, 446 + 4, sizeof(uint8_t)); + if (hint8 != 0x00) { + device_read(&hint32, 446 + 8, sizeof(uint32_t)); + hint32 = ENDSWAP(hint32); + if (hint32 < 63) { + goto part_too_low; + } + } + device_read(&hint8, 462, sizeof(uint8_t)); + if (hint8 != 0x00 && hint8 != 0x80) { + if (!force_mbr) { + mbr = 0; + } else { + hint8 &= 0x80; + device_write(&hint8, 462, sizeof(uint8_t)); + } + } + any_active = any_active || (hint8 & 0x80) != 0; + device_read(&hint8, 462 + 4, sizeof(uint8_t)); + if (hint8 != 0x00) { + device_read(&hint32, 462 + 8, sizeof(uint32_t)); + hint32 = ENDSWAP(hint32); + if (hint32 < 63) { + goto part_too_low; + } + } + device_read(&hint8, 478, sizeof(uint8_t)); + if (hint8 != 0x00 && hint8 != 0x80) { + if (!force_mbr) { + mbr = 0; + } else { + hint8 &= 0x80; + device_write(&hint8, 478, sizeof(uint8_t)); + } + } + any_active = any_active || (hint8 & 0x80) != 0; + device_read(&hint8, 478 + 4, sizeof(uint8_t)); + if (hint8 != 0x00) { + device_read(&hint32, 478 + 8, sizeof(uint32_t)); + hint32 = ENDSWAP(hint32); + if (hint32 < 63) { + goto part_too_low; + } + } + device_read(&hint8, 494, sizeof(uint8_t)); + if (hint8 != 0x00 && hint8 != 0x80) { + if (!force_mbr) { + mbr = 0; + } else { + hint8 &= 0x80; + device_write(&hint8, 494, sizeof(uint8_t)); + } + } + any_active = any_active || (hint8 & 0x80) != 0; + device_read(&hint8, 494 + 4, sizeof(uint8_t)); + if (hint8 != 0x00) { + device_read(&hint32, 494 + 8, sizeof(uint32_t)); + hint32 = ENDSWAP(hint32); + if (hint32 < 63) { + goto part_too_low; + } + } + + if (0) { +part_too_low: + fprintf(stderr, "%s: error: A partition's start sector is less than 63, aborting.\n", program_name); + goto cleanup; + } + + char hintc[64]; + device_read(hintc, 4, 8); + if (memcmp(hintc, "_ECH_FS_", 8) == 0) { + if (!force_mbr) { + mbr = 0; + } else { + memset(hintc, 0, 8); + device_write(hintc, 4, 8); + } + } + device_read(hintc, 3, 4); + if (memcmp(hintc, "NTFS", 4) == 0) { + if (!force_mbr) { + mbr = 0; + } else { + memset(hintc, 0, 4); + device_write(hintc, 3, 4); + } + } + device_read(hintc, 54, 3); + if (memcmp(hintc, "FAT", 3) == 0) { + if (!force_mbr) { + mbr = 0; + } else { + memset(hintc, 0, 5); + device_write(hintc, 54, 5); + } + } + device_read(hintc, 82, 3); + if (memcmp(hintc, "FAT", 3) == 0) { + if (!force_mbr) { + mbr = 0; + } else { + memset(hintc, 0, 5); + device_write(hintc, 82, 5); + } + } + device_read(hintc, 3, 5); + if (memcmp(hintc, "FAT32", 5) == 0) { + if (!force_mbr) { + mbr = 0; + } else { + memset(hintc, 0, 5); + device_write(hintc, 3, 5); + } + } + device_read(&hint16, 1080, sizeof(uint16_t)); + hint16 = ENDSWAP(hint16); + if (hint16 == 0xef53) { + if (!force_mbr) { + mbr = 0; + } else { + hint16 = 0; + hint16 = ENDSWAP(hint16); + device_write(&hint16, 1080, sizeof(uint16_t)); + } + } + + if (mbr && !any_active) { + if (!quiet) { + fprintf(stderr, "No active partition found, some systems may not boot.\n"); + fprintf(stderr, "Setting partition 1 as active to work around the issue...\n"); + } + hint8 = 0x80; + device_write(&hint8, 446, sizeof(uint8_t)); + } + } + + if (gpt == 0 && mbr == 0) { + fprintf(stderr, "error: Could not determine if the device has a valid partition table.\n"); + fprintf(stderr, " Please ensure the device has a valid MBR or GPT.\n"); + fprintf(stderr, " Alternatively, pass `--force-mbr` to override these checks.\n"); + fprintf(stderr, " **ONLY DO THIS AT YOUR OWN RISK, DATA LOSS MAY OCCUR!**\n"); + goto cleanup; + } + + size_t stage2_size = bootloader_file_size - 512; + + size_t stage2_sects = DIV_ROUNDUP(stage2_size, 512); + + uint16_t stage2_size_a = (stage2_sects / 2) * 512 + (stage2_sects % 2 ? 512 : 0); + uint16_t stage2_size_b = (stage2_sects / 2) * 512; + + // Default split of stage2 for MBR (consecutive in post MBR gap) + uint64_t stage2_loc_a = 512; + uint64_t stage2_loc_b = stage2_loc_a + stage2_size_a; + + if (gpt) { + if (part_ndx != NULL) { + uint32_t partition_num; + sscanf(part_ndx, "%" SCNu32, &partition_num); + partition_num--; + if (partition_num > ENDSWAP(gpt_header.number_of_partition_entries)) { + fprintf(stderr, "%s: error: Partition number is too large.\n", program_name); + goto cleanup; + } + + struct gpt_entry gpt_entry; + device_read(&gpt_entry, + (ENDSWAP(gpt_header.partition_entry_lba) * lb_size) + + (partition_num * ENDSWAP(gpt_header.size_of_partition_entry)), + sizeof(struct gpt_entry)); + + if (gpt_entry.unique_partition_guid[0] == 0 && + gpt_entry.unique_partition_guid[1] == 0) { + fprintf(stderr, "%s: error: No such partition: `%s`.\n", program_name, part_ndx); + goto cleanup; + } + + if (!quiet) { + fprintf(stderr, "GPT partition specified. Installing there instead of embedding.\n"); + } + + stage2_loc_a = ENDSWAP(gpt_entry.starting_lba) * lb_size; + stage2_loc_b = stage2_loc_a + stage2_size_a; + if (stage2_loc_b & (lb_size - 1)) + stage2_loc_b = (stage2_loc_b + lb_size) & ~(lb_size - 1); + } else { + if (!quiet) { + fprintf(stderr, "GPT partition NOT specified. Attempting GPT embedding.\n"); + } + + int64_t max_partition_entry_used = -1; + for (int64_t i = 0; i < (int64_t)ENDSWAP(gpt_header.number_of_partition_entries); i++) { + struct gpt_entry gpt_entry; + device_read(&gpt_entry, + (ENDSWAP(gpt_header.partition_entry_lba) * lb_size) + + (i * ENDSWAP(gpt_header.size_of_partition_entry)), + sizeof(struct gpt_entry)); + + if (gpt_entry.unique_partition_guid[0] != 0 || + gpt_entry.unique_partition_guid[1] != 0) { + if (i > max_partition_entry_used) + max_partition_entry_used = i; + } + } + + stage2_loc_a = (ENDSWAP(gpt_header.partition_entry_lba) + 32) * lb_size; + stage2_loc_a -= stage2_size_a; + stage2_loc_a &= ~(lb_size - 1); + stage2_loc_b = (ENDSWAP(secondary_gpt_header.partition_entry_lba) + 32) * lb_size; + stage2_loc_b -= stage2_size_b; + stage2_loc_b &= ~(lb_size - 1); + + size_t partition_entries_per_lb = + lb_size / ENDSWAP(gpt_header.size_of_partition_entry); + size_t new_partition_array_lba_size = + stage2_loc_a / lb_size - ENDSWAP(gpt_header.partition_entry_lba); + size_t new_partition_entry_count = + new_partition_array_lba_size * partition_entries_per_lb; + + if ((int64_t)new_partition_entry_count <= max_partition_entry_used) { + fprintf(stderr, "%s: error: Cannot embed because there are too many used partition entries.\n", program_name); + goto cleanup; + } + + if (!quiet) { + fprintf(stderr, "New maximum count of partition entries: %zu.\n", new_partition_entry_count); + } + + // Zero out unused partitions + void *empty = calloc(1, ENDSWAP(gpt_header.size_of_partition_entry)); + for (size_t i = max_partition_entry_used + 1; i < new_partition_entry_count; i++) { + device_write(empty, + ENDSWAP(gpt_header.partition_entry_lba) * lb_size + i * ENDSWAP(gpt_header.size_of_partition_entry), + ENDSWAP(gpt_header.size_of_partition_entry)); + } + for (size_t i = max_partition_entry_used + 1; i < new_partition_entry_count; i++) { + device_write(empty, + ENDSWAP(secondary_gpt_header.partition_entry_lba) * lb_size + i * ENDSWAP(secondary_gpt_header.size_of_partition_entry), + ENDSWAP(secondary_gpt_header.size_of_partition_entry)); + } + free(empty); + + uint8_t *partition_array = + malloc(new_partition_entry_count * ENDSWAP(gpt_header.size_of_partition_entry)); + if (partition_array == NULL) { + perror_wrap("error: bios_install(): malloc()"); + goto cleanup; + } + + device_read(partition_array, + ENDSWAP(gpt_header.partition_entry_lba) * lb_size, + new_partition_entry_count * ENDSWAP(gpt_header.size_of_partition_entry)); + + uint32_t crc32_partition_array = + crc32(partition_array, + new_partition_entry_count * ENDSWAP(gpt_header.size_of_partition_entry)); + + free(partition_array); + + gpt_header.partition_entry_array_crc32 = ENDSWAP(crc32_partition_array); + gpt_header.number_of_partition_entries = ENDSWAP(new_partition_entry_count); + gpt_header.crc32 = 0; + gpt_header.crc32 = crc32(&gpt_header, 92); + gpt_header.crc32 = ENDSWAP(gpt_header.crc32); + device_write(&gpt_header, + lb_size, + sizeof(struct gpt_table_header)); + + secondary_gpt_header.partition_entry_array_crc32 = ENDSWAP(crc32_partition_array); + secondary_gpt_header.number_of_partition_entries = + ENDSWAP(new_partition_entry_count); + secondary_gpt_header.crc32 = 0; + secondary_gpt_header.crc32 = crc32(&secondary_gpt_header, 92); + secondary_gpt_header.crc32 = ENDSWAP(secondary_gpt_header.crc32); + device_write(&secondary_gpt_header, + lb_size * ENDSWAP(gpt_header.alternate_lba), + sizeof(struct gpt_table_header)); + } + } else { + if (!quiet) { + fprintf(stderr, "Installing to MBR.\n"); + } + } + + if (!quiet) { + fprintf(stderr, "Stage 2 to be located at 0x%" PRIx64 " and 0x%" PRIx64 ".\n", + stage2_loc_a, stage2_loc_b); + } + + // Save original timestamp + device_read(timestamp, 218, 6); + + // Save the original partition table of the device + device_read(orig_mbr, 440, 70); + + // Write the bootsector from the bootloader to the device + device_write(&bootloader_img[0], 0, 512); + + // Write the rest of stage 2 to the device + device_write(&bootloader_img[512], stage2_loc_a, stage2_size_a); + device_write(&bootloader_img[512 + stage2_size_a], + stage2_loc_b, stage2_size - stage2_size_a); + + // Hardcode in the bootsector the location of stage 2 halves + stage2_size_a = ENDSWAP(stage2_size_a); + device_write(&stage2_size_a, 0x1a4 + 0, sizeof(uint16_t)); + stage2_size_b = ENDSWAP(stage2_size_b); + device_write(&stage2_size_b, 0x1a4 + 2, sizeof(uint16_t)); + stage2_loc_a = ENDSWAP(stage2_loc_a); + device_write(&stage2_loc_a, 0x1a4 + 4, sizeof(uint64_t)); + stage2_loc_b = ENDSWAP(stage2_loc_b); + device_write(&stage2_loc_b, 0x1a4 + 12, sizeof(uint64_t)); + + // Write back timestamp + device_write(timestamp, 218, 6); + + // Write back the saved partition table to the device + device_write(orig_mbr, 440, 70); + + if (!device_flush_cache()) + goto cleanup; + + if (!quiet) { + fprintf(stderr, "Reminder: Remember to copy the limine-bios.sys file in either\n" + " the root, /boot, /limine, or /boot/limine directories of\n" + " one of the partitions on the device, or boot will fail!\n"); + + fprintf(stderr, "Limine BIOS stages installed successfully!\n"); + } + + ok = EXIT_SUCCESS; + +cleanup: + reverse_uninstall_data(); + if (ok != EXIT_SUCCESS) { + // If we failed, attempt to reverse install process + fprintf(stderr, "%s: Install failed, undoing work...\n", program_name); + uninstall(true); + } else if (uninstall_file != NULL) { + store_uninstall_data(uninstall_file); + } +uninstall_mode_cleanup: + free_uninstall_data(); + if (cache) + free(cache); + if (device != NULL) + fclose(device); + + return ok; +} +#endif + +#define CONFIG_B2SUM_SIGNATURE "++CONFIG_B2SUM_SIGNATURE++" + +static void enroll_config_usage(void) { + printf("usage: %s enroll-config \n", program_name); + printf("\n"); + printf(" --reset Remove enrolled BLAKE2B, will not check config integrity\n"); + printf("\n"); + printf(" --quiet Do not print verbose diagnostic messages\n"); + printf("\n"); + printf(" --help | -h Display this help message\n"); + printf("\n"); +} + +static int enroll_config(int argc, char *argv[]) { + int ret = EXIT_FAILURE; + + char *bootloader = NULL; + FILE *bootloader_file = NULL; + bool quiet = false; + bool reset = false; + + for (int i = 1; i < argc; i++) { + if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) { + enroll_config_usage(); + return EXIT_SUCCESS; + } else if (strcmp(argv[i], "--quiet") == 0) { + remove_arg(&argc, argv, i); + quiet = true; + } else if (strcmp(argv[i], "--reset") == 0) { + remove_arg(&argc, argv, i); + reset = true; + } + } + + if (argc <= (reset ? 1 : 2)) { + enroll_config_usage(); +#ifdef IS_WINDOWS + system("pause"); +#endif + return EXIT_FAILURE; + } + + if (!reset && strlen(argv[2]) != 128) { + fprintf(stderr, "%s: error: BLAKE2B specified is not 128 characters long.\n", program_name); + goto cleanup; + } + + bootloader_file = fopen(argv[1], "r+b"); + if (bootloader_file == NULL) { + perror_wrap("error: `%s`", argv[1]); + goto cleanup; + } + + if (fseek(bootloader_file, 0, SEEK_END) != 0) { + perror_wrap("error: enroll_config(): fseek()"); + goto cleanup; + } + size_t bootloader_size = ftell(bootloader_file); + rewind(bootloader_file); + + bootloader = malloc(bootloader_size); + if (bootloader == NULL) { + perror_wrap("error: enroll_config(): malloc()"); + goto cleanup; + } + + if (fread(bootloader, bootloader_size, 1, bootloader_file) != 1) { + perror_wrap("error: enroll_config(): fread()"); + goto cleanup; + } + + char *checksum_loc = NULL; + size_t checked_count = 0; + const char *config_b2sum_sign = CONFIG_B2SUM_SIGNATURE; + for (size_t i = 0; i < bootloader_size - ((sizeof(CONFIG_B2SUM_SIGNATURE) - 1) + 128) + 1; i++) { + if (bootloader[i] != config_b2sum_sign[checked_count]) { + checked_count = 0; + continue; + } + + checked_count++; + + if (checked_count == sizeof(CONFIG_B2SUM_SIGNATURE) - 1) { + checksum_loc = &bootloader[i + 1]; + break; + } + } + + if (checksum_loc == NULL) { + fprintf(stderr, "%s: error: Checksum location not found in provided executable.\n", program_name); + goto cleanup; + } + + if (!reset) { + memcpy(checksum_loc, argv[2], 128); + } else { + memset(checksum_loc, '0', 128); + } + + if (fseek(bootloader_file, 0, SEEK_SET) != 0) { + perror_wrap("error: enroll_config(): fseek()"); + goto cleanup; + } + if (fwrite(bootloader, bootloader_size, 1, bootloader_file) != 1) { + perror_wrap("error: enroll_config(): fwrite()"); + goto cleanup; + } + + if (!quiet) { + fprintf(stderr, "Config file BLAKE2B successfully %s!\n", reset ? "reset" : "enrolled"); + } + ret = EXIT_SUCCESS; + +cleanup: + if (bootloader != NULL) { + free(bootloader); + } + if (bootloader_file != NULL) { + fclose(bootloader_file); + } + return ret; +} + +#define LIMINE_VERSION "7.13.3" +#define LIMINE_COPYRIGHT "Copyright (C) 2019-2024 mintsuki and contributors." + +static void version_usage(void) { + printf("usage: %s version [options...]\n", program_name); + printf("\n"); + printf(" --version-only Only print the version number without licensing info\n"); + printf(" and other distractions\n"); + printf("\n"); + printf(" --help | -h Display this help message\n"); + printf("\n"); +} + +static int version(int argc, char *argv[]) { + if (argc >= 2) { + if (strcmp(argv[1], "--help") == 0) { + version_usage(); + return EXIT_SUCCESS; + } else if (strcmp(argv[1], "--version-only") == 0) { + puts(LIMINE_VERSION); + return EXIT_SUCCESS; + } + } + + puts("Limine " LIMINE_VERSION); + puts(LIMINE_COPYRIGHT); + puts("Limine is distributed under the terms of the BSD-2-Clause license."); + puts("There is ABSOLUTELY NO WARRANTY, to the extent permitted by law."); + return EXIT_SUCCESS; +} + +static void general_usage(void) { + printf("usage: %s \n", program_name); + printf("\n"); + printf(" --print-datadir Print the directory containing the bootloader files\n"); + printf("\n"); + printf(" --version Print the Limine version (like the `version` command)\n"); + printf("\n"); + printf(" --help | -h Display this help message\n"); + printf("\n"); + printf("Commands: `help`, `version`, `bios-install`, `enroll-config`\n"); + printf("Use `--help` after specifying the command for command-specific help.\n"); +} + +static int print_datadir(void) { +#ifdef LIMINE_DATADIR + puts(LIMINE_DATADIR); + return EXIT_SUCCESS; +#else + fprintf(stderr, "%s: error: Cannot print datadir for `limine` built out-of-tree.\n", program_name); + return EXIT_FAILURE; +#endif +} + +int main(int argc, char *argv[]) { + program_name = argv[0]; + + if (argc <= 1) { + general_usage(); + return EXIT_FAILURE; + } + + if (strcmp(argv[1], "help") == 0 + || strcmp(argv[1], "--help") == 0 + || strcmp(argv[1], "-h") == 0) { + general_usage(); + return EXIT_SUCCESS; + } else if (strcmp(argv[1], "bios-install") == 0) { +#ifndef LIMINE_NO_BIOS + return bios_install(argc - 1, &argv[1]); +#else + fprintf(stderr, "%s: error: Limine has been compiled without BIOS support.\n", program_name); + return EXIT_FAILURE; +#endif + } else if (strcmp(argv[1], "enroll-config") == 0) { + return enroll_config(argc - 1, &argv[1]); + } else if (strcmp(argv[1], "--print-datadir") == 0) { + return print_datadir(); + } else if (strcmp(argv[1], "version") == 0 + || strcmp(argv[1], "--version") == 0) { + return version(argc - 1, &argv[1]); + } + + general_usage(); + return EXIT_FAILURE; +} diff --git a/FloridOS/limine-binary/limine.exe b/FloridOS/limine-binary/limine.exe new file mode 100644 index 0000000..ccdd89a Binary files /dev/null and b/FloridOS/limine-binary/limine.exe differ diff --git a/FloridOS/limine-binary/limine.h b/FloridOS/limine-binary/limine.h new file mode 100644 index 0000000..63e8422 --- /dev/null +++ b/FloridOS/limine-binary/limine.h @@ -0,0 +1,609 @@ +/* BSD Zero Clause License */ + +/* Copyright (C) 2022-2024 mintsuki and contributors. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef LIMINE_H +#define LIMINE_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* Misc */ + +#ifdef LIMINE_NO_POINTERS +# define LIMINE_PTR(TYPE) uint64_t +#else +# define LIMINE_PTR(TYPE) TYPE +#endif + +#ifdef __GNUC__ +# define LIMINE_DEPRECATED __attribute__((__deprecated__)) +# define LIMINE_DEPRECATED_IGNORE_START \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") +# define LIMINE_DEPRECATED_IGNORE_END \ + _Pragma("GCC diagnostic pop") +#else +# define LIMINE_DEPRECATED +# define LIMINE_DEPRECATED_IGNORE_START +# define LIMINE_DEPRECATED_IGNORE_END +#endif + +#define LIMINE_REQUESTS_START_MARKER \ + uint64_t limine_requests_start_marker[4] = { 0xf6b8f4b39de7d1ae, 0xfab91a6940fcb9cf, \ + 0x785c6ed015d3e316, 0x181e920a7852b9d9 }; +#define LIMINE_REQUESTS_END_MARKER \ + uint64_t limine_requests_end_marker[2] = { 0xadc0e0531bb10d03, 0x9572709f31764c62 }; + +#define LIMINE_REQUESTS_DELIMITER LIMINE_REQUESTS_END_MARKER + +#define LIMINE_BASE_REVISION(N) \ + uint64_t limine_base_revision[3] = { 0xf9562b2d5c95a6c8, 0x6a7b384944536bdc, (N) }; + +#define LIMINE_BASE_REVISION_SUPPORTED (limine_base_revision[2] == 0) + +#define LIMINE_COMMON_MAGIC 0xc7b1dd30df4c8b88, 0x0a82e883a194f07b + +struct limine_uuid { + uint32_t a; + uint16_t b; + uint16_t c; + uint8_t d[8]; +}; + +#define LIMINE_MEDIA_TYPE_GENERIC 0 +#define LIMINE_MEDIA_TYPE_OPTICAL 1 +#define LIMINE_MEDIA_TYPE_TFTP 2 + +struct limine_file { + uint64_t revision; + LIMINE_PTR(void *) address; + uint64_t size; + LIMINE_PTR(char *) path; + LIMINE_PTR(char *) cmdline; + uint32_t media_type; + uint32_t unused; + uint32_t tftp_ip; + uint32_t tftp_port; + uint32_t partition_index; + uint32_t mbr_disk_id; + struct limine_uuid gpt_disk_uuid; + struct limine_uuid gpt_part_uuid; + struct limine_uuid part_uuid; +}; + +/* Boot info */ + +#define LIMINE_BOOTLOADER_INFO_REQUEST { LIMINE_COMMON_MAGIC, 0xf55038d8e2a1202f, 0x279426fcf5f59740 } + +struct limine_bootloader_info_response { + uint64_t revision; + LIMINE_PTR(char *) name; + LIMINE_PTR(char *) version; +}; + +struct limine_bootloader_info_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_bootloader_info_response *) response; +}; + +/* Firmware type */ + +#define LIMINE_FIRMWARE_TYPE_REQUEST { LIMINE_COMMON_MAGIC, 0x8c2f75d90bef28a8, 0x7045a4688eac00c3 } + +#define LIMINE_FIRMWARE_TYPE_X86BIOS 0 +#define LIMINE_FIRMWARE_TYPE_UEFI32 1 +#define LIMINE_FIRMWARE_TYPE_UEFI64 2 + +struct limine_firmware_type_response { + uint64_t revision; + uint64_t firmware_type; +}; + +struct limine_firmware_type_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_firmware_type_response *) response; +}; + +/* Stack size */ + +#define LIMINE_STACK_SIZE_REQUEST { LIMINE_COMMON_MAGIC, 0x224ef0460a8e8926, 0xe1cb0fc25f46ea3d } + +struct limine_stack_size_response { + uint64_t revision; +}; + +struct limine_stack_size_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_stack_size_response *) response; + uint64_t stack_size; +}; + +/* HHDM */ + +#define LIMINE_HHDM_REQUEST { LIMINE_COMMON_MAGIC, 0x48dcf1cb8ad2b852, 0x63984e959a98244b } + +struct limine_hhdm_response { + uint64_t revision; + uint64_t offset; +}; + +struct limine_hhdm_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_hhdm_response *) response; +}; + +/* Framebuffer */ + +#define LIMINE_FRAMEBUFFER_REQUEST { LIMINE_COMMON_MAGIC, 0x9d5827dcd881dd75, 0xa3148604f6fab11b } + +#define LIMINE_FRAMEBUFFER_RGB 1 + +struct limine_video_mode { + uint64_t pitch; + uint64_t width; + uint64_t height; + uint16_t bpp; + uint8_t memory_model; + uint8_t red_mask_size; + uint8_t red_mask_shift; + uint8_t green_mask_size; + uint8_t green_mask_shift; + uint8_t blue_mask_size; + uint8_t blue_mask_shift; +}; + +struct limine_framebuffer { + LIMINE_PTR(void *) address; + uint64_t width; + uint64_t height; + uint64_t pitch; + uint16_t bpp; + uint8_t memory_model; + uint8_t red_mask_size; + uint8_t red_mask_shift; + uint8_t green_mask_size; + uint8_t green_mask_shift; + uint8_t blue_mask_size; + uint8_t blue_mask_shift; + uint8_t unused[7]; + uint64_t edid_size; + LIMINE_PTR(void *) edid; + /* Response revision 1 */ + uint64_t mode_count; + LIMINE_PTR(struct limine_video_mode **) modes; +}; + +struct limine_framebuffer_response { + uint64_t revision; + uint64_t framebuffer_count; + LIMINE_PTR(struct limine_framebuffer **) framebuffers; +}; + +struct limine_framebuffer_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_framebuffer_response *) response; +}; + +/* Terminal */ + +#define LIMINE_TERMINAL_REQUEST { LIMINE_COMMON_MAGIC, 0xc8ac59310c2b0844, 0xa68d0c7265d38878 } + +#define LIMINE_TERMINAL_CB_DEC 10 +#define LIMINE_TERMINAL_CB_BELL 20 +#define LIMINE_TERMINAL_CB_PRIVATE_ID 30 +#define LIMINE_TERMINAL_CB_STATUS_REPORT 40 +#define LIMINE_TERMINAL_CB_POS_REPORT 50 +#define LIMINE_TERMINAL_CB_KBD_LEDS 60 +#define LIMINE_TERMINAL_CB_MODE 70 +#define LIMINE_TERMINAL_CB_LINUX 80 + +#define LIMINE_TERMINAL_CTX_SIZE ((uint64_t)(-1)) +#define LIMINE_TERMINAL_CTX_SAVE ((uint64_t)(-2)) +#define LIMINE_TERMINAL_CTX_RESTORE ((uint64_t)(-3)) +#define LIMINE_TERMINAL_FULL_REFRESH ((uint64_t)(-4)) + +/* Response revision 1 */ +#define LIMINE_TERMINAL_OOB_OUTPUT_GET ((uint64_t)(-10)) +#define LIMINE_TERMINAL_OOB_OUTPUT_SET ((uint64_t)(-11)) + +#define LIMINE_TERMINAL_OOB_OUTPUT_OCRNL (1 << 0) +#define LIMINE_TERMINAL_OOB_OUTPUT_OFDEL (1 << 1) +#define LIMINE_TERMINAL_OOB_OUTPUT_OFILL (1 << 2) +#define LIMINE_TERMINAL_OOB_OUTPUT_OLCUC (1 << 3) +#define LIMINE_TERMINAL_OOB_OUTPUT_ONLCR (1 << 4) +#define LIMINE_TERMINAL_OOB_OUTPUT_ONLRET (1 << 5) +#define LIMINE_TERMINAL_OOB_OUTPUT_ONOCR (1 << 6) +#define LIMINE_TERMINAL_OOB_OUTPUT_OPOST (1 << 7) + +LIMINE_DEPRECATED_IGNORE_START + +struct LIMINE_DEPRECATED limine_terminal; + +typedef void (*limine_terminal_write)(struct limine_terminal *, const char *, uint64_t); +typedef void (*limine_terminal_callback)(struct limine_terminal *, uint64_t, uint64_t, uint64_t, uint64_t); + +struct LIMINE_DEPRECATED limine_terminal { + uint64_t columns; + uint64_t rows; + LIMINE_PTR(struct limine_framebuffer *) framebuffer; +}; + +struct LIMINE_DEPRECATED limine_terminal_response { + uint64_t revision; + uint64_t terminal_count; + LIMINE_PTR(struct limine_terminal **) terminals; + LIMINE_PTR(limine_terminal_write) write; +}; + +struct LIMINE_DEPRECATED limine_terminal_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_terminal_response *) response; + LIMINE_PTR(limine_terminal_callback) callback; +}; + +LIMINE_DEPRECATED_IGNORE_END + +/* Paging mode */ + +#define LIMINE_PAGING_MODE_REQUEST { LIMINE_COMMON_MAGIC, 0x95c1a0edab0944cb, 0xa4e5cb3842f7488a } + +#if defined (__x86_64__) || defined (__i386__) +#define LIMINE_PAGING_MODE_X86_64_4LVL 0 +#define LIMINE_PAGING_MODE_X86_64_5LVL 1 +#define LIMINE_PAGING_MODE_MAX LIMINE_PAGING_MODE_X86_64_5LVL +#define LIMINE_PAGING_MODE_MIN LIMINE_PAGING_MODE_X86_64_4LVL +#define LIMINE_PAGING_MODE_DEFAULT LIMINE_PAGING_MODE_X86_64_4LVL +#elif defined (__aarch64__) +#define LIMINE_PAGING_MODE_AARCH64_4LVL 0 +#define LIMINE_PAGING_MODE_AARCH64_5LVL 1 +#define LIMINE_PAGING_MODE_MAX LIMINE_PAGING_MODE_AARCH64_5LVL +#define LIMINE_PAGING_MODE_MIN LIMINE_PAGING_MODE_AARCH64_4LVL +#define LIMINE_PAGING_MODE_DEFAULT LIMINE_PAGING_MODE_AARCH64_4LVL +#elif defined (__riscv) && (__riscv_xlen == 64) +#define LIMINE_PAGING_MODE_RISCV_SV39 0 +#define LIMINE_PAGING_MODE_RISCV_SV48 1 +#define LIMINE_PAGING_MODE_RISCV_SV57 2 +#define LIMINE_PAGING_MODE_MAX LIMINE_PAGING_MODE_RISCV_SV57 +#define LIMINE_PAGING_MODE_MIN LIMINE_PAGING_MODE_RISCV_SV39 +#define LIMINE_PAGING_MODE_DEFAULT LIMINE_PAGING_MODE_RISCV_SV48 +#else +#error Unknown architecture +#endif + +struct limine_paging_mode_response { + uint64_t revision; + uint64_t mode; +}; + +struct limine_paging_mode_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_paging_mode_response *) response; + uint64_t mode; + uint64_t max_mode; + uint64_t min_mode; +}; + +/* 5-level paging */ + +#define LIMINE_5_LEVEL_PAGING_REQUEST { LIMINE_COMMON_MAGIC, 0x94469551da9b3192, 0xebe5e86db7382888 } + +LIMINE_DEPRECATED_IGNORE_START + +struct LIMINE_DEPRECATED limine_5_level_paging_response { + uint64_t revision; +}; + +struct LIMINE_DEPRECATED limine_5_level_paging_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_5_level_paging_response *) response; +}; + +LIMINE_DEPRECATED_IGNORE_END + +/* SMP */ + +#define LIMINE_SMP_REQUEST { LIMINE_COMMON_MAGIC, 0x95a67b819a1b857e, 0xa0b61b723b6a73e0 } + +struct limine_smp_info; + +typedef void (*limine_goto_address)(struct limine_smp_info *); + +#if defined (__x86_64__) || defined (__i386__) + +#define LIMINE_SMP_X2APIC (1 << 0) + +struct limine_smp_info { + uint32_t processor_id; + uint32_t lapic_id; + uint64_t reserved; + LIMINE_PTR(limine_goto_address) goto_address; + uint64_t extra_argument; +}; + +struct limine_smp_response { + uint64_t revision; + uint32_t flags; + uint32_t bsp_lapic_id; + uint64_t cpu_count; + LIMINE_PTR(struct limine_smp_info **) cpus; +}; + +#elif defined (__aarch64__) + +struct limine_smp_info { + uint32_t processor_id; + uint32_t reserved1; + uint64_t mpidr; + uint64_t reserved; + LIMINE_PTR(limine_goto_address) goto_address; + uint64_t extra_argument; +}; + +struct limine_smp_response { + uint64_t revision; + uint64_t flags; + uint64_t bsp_mpidr; + uint64_t cpu_count; + LIMINE_PTR(struct limine_smp_info **) cpus; +}; + +#elif defined (__riscv) && (__riscv_xlen == 64) + +struct limine_smp_info { + uint64_t processor_id; + uint64_t hartid; + uint64_t reserved; + LIMINE_PTR(limine_goto_address) goto_address; + uint64_t extra_argument; +}; + +struct limine_smp_response { + uint64_t revision; + uint64_t flags; + uint64_t bsp_hartid; + uint64_t cpu_count; + LIMINE_PTR(struct limine_smp_info **) cpus; +}; + +#else +#error Unknown architecture +#endif + +struct limine_smp_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_smp_response *) response; + uint64_t flags; +}; + +/* Memory map */ + +#define LIMINE_MEMMAP_REQUEST { LIMINE_COMMON_MAGIC, 0x67cf3d9d378a806f, 0xe304acdfc50c3c62 } + +#define LIMINE_MEMMAP_USABLE 0 +#define LIMINE_MEMMAP_RESERVED 1 +#define LIMINE_MEMMAP_ACPI_RECLAIMABLE 2 +#define LIMINE_MEMMAP_ACPI_NVS 3 +#define LIMINE_MEMMAP_BAD_MEMORY 4 +#define LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE 5 +#define LIMINE_MEMMAP_KERNEL_AND_MODULES 6 +#define LIMINE_MEMMAP_FRAMEBUFFER 7 + +struct limine_memmap_entry { + uint64_t base; + uint64_t length; + uint64_t type; +}; + +struct limine_memmap_response { + uint64_t revision; + uint64_t entry_count; + LIMINE_PTR(struct limine_memmap_entry **) entries; +}; + +struct limine_memmap_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_memmap_response *) response; +}; + +/* Entry point */ + +#define LIMINE_ENTRY_POINT_REQUEST { LIMINE_COMMON_MAGIC, 0x13d86c035a1cd3e1, 0x2b0caa89d8f3026a } + +typedef void (*limine_entry_point)(void); + +struct limine_entry_point_response { + uint64_t revision; +}; + +struct limine_entry_point_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_entry_point_response *) response; + LIMINE_PTR(limine_entry_point) entry; +}; + +/* Kernel File */ + +#define LIMINE_KERNEL_FILE_REQUEST { LIMINE_COMMON_MAGIC, 0xad97e90e83f1ed67, 0x31eb5d1c5ff23b69 } + +struct limine_kernel_file_response { + uint64_t revision; + LIMINE_PTR(struct limine_file *) kernel_file; +}; + +struct limine_kernel_file_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_kernel_file_response *) response; +}; + +/* Module */ + +#define LIMINE_MODULE_REQUEST { LIMINE_COMMON_MAGIC, 0x3e7e279702be32af, 0xca1c4f3bd1280cee } + +#define LIMINE_INTERNAL_MODULE_REQUIRED (1 << 0) +#define LIMINE_INTERNAL_MODULE_COMPRESSED (1 << 1) + +struct limine_internal_module { + LIMINE_PTR(const char *) path; + LIMINE_PTR(const char *) cmdline; + uint64_t flags; +}; + +struct limine_module_response { + uint64_t revision; + uint64_t module_count; + LIMINE_PTR(struct limine_file **) modules; +}; + +struct limine_module_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_module_response *) response; + + /* Request revision 1 */ + uint64_t internal_module_count; + LIMINE_PTR(struct limine_internal_module **) internal_modules; +}; + +/* RSDP */ + +#define LIMINE_RSDP_REQUEST { LIMINE_COMMON_MAGIC, 0xc5e77b6b397e7b43, 0x27637845accdcf3c } + +struct limine_rsdp_response { + uint64_t revision; + LIMINE_PTR(void *) address; +}; + +struct limine_rsdp_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_rsdp_response *) response; +}; + +/* SMBIOS */ + +#define LIMINE_SMBIOS_REQUEST { LIMINE_COMMON_MAGIC, 0x9e9046f11e095391, 0xaa4a520fefbde5ee } + +struct limine_smbios_response { + uint64_t revision; + LIMINE_PTR(void *) entry_32; + LIMINE_PTR(void *) entry_64; +}; + +struct limine_smbios_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_smbios_response *) response; +}; + +/* EFI system table */ + +#define LIMINE_EFI_SYSTEM_TABLE_REQUEST { LIMINE_COMMON_MAGIC, 0x5ceba5163eaaf6d6, 0x0a6981610cf65fcc } + +struct limine_efi_system_table_response { + uint64_t revision; + LIMINE_PTR(void *) address; +}; + +struct limine_efi_system_table_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_efi_system_table_response *) response; +}; + +/* EFI memory map */ + +#define LIMINE_EFI_MEMMAP_REQUEST { LIMINE_COMMON_MAGIC, 0x7df62a431d6872d5, 0xa4fcdfb3e57306c8 } + +struct limine_efi_memmap_response { + uint64_t revision; + LIMINE_PTR(void *) memmap; + uint64_t memmap_size; + uint64_t desc_size; + uint64_t desc_version; +}; + +struct limine_efi_memmap_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_efi_memmap_response *) response; +}; + +/* Boot time */ + +#define LIMINE_BOOT_TIME_REQUEST { LIMINE_COMMON_MAGIC, 0x502746e184c088aa, 0xfbc5ec83e6327893 } + +struct limine_boot_time_response { + uint64_t revision; + int64_t boot_time; +}; + +struct limine_boot_time_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_boot_time_response *) response; +}; + +/* Kernel address */ + +#define LIMINE_KERNEL_ADDRESS_REQUEST { LIMINE_COMMON_MAGIC, 0x71ba76863cc55f63, 0xb2644a48c516a487 } + +struct limine_kernel_address_response { + uint64_t revision; + uint64_t physical_base; + uint64_t virtual_base; +}; + +struct limine_kernel_address_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_kernel_address_response *) response; +}; + +/* Device Tree Blob */ + +#define LIMINE_DTB_REQUEST { LIMINE_COMMON_MAGIC, 0xb40ddb48fb54bac7, 0x545081493f81ffb7 } + +struct limine_dtb_response { + uint64_t revision; + LIMINE_PTR(void *) dtb_ptr; +}; + +struct limine_dtb_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_dtb_response *) response; +}; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/FloridOS/limine/limine-bios-cd.bin b/FloridOS/limine/limine-bios-cd.bin new file mode 100644 index 0000000..0621f1e Binary files /dev/null and b/FloridOS/limine/limine-bios-cd.bin differ diff --git a/FloridOS/limine/limine-bios.sys b/FloridOS/limine/limine-bios.sys new file mode 100644 index 0000000..067c730 Binary files /dev/null and b/FloridOS/limine/limine-bios.sys differ diff --git a/FloridOS/limine/limine.conf b/FloridOS/limine/limine.conf new file mode 100644 index 0000000..d39ab09 --- /dev/null +++ b/FloridOS/limine/limine.conf @@ -0,0 +1,3 @@ +/Florid OS + protocol: limine + kernel_path: boot():/kernel.elf \ No newline at end of file diff --git a/FloridOS/limine/limine.h b/FloridOS/limine/limine.h new file mode 100644 index 0000000..63e8422 --- /dev/null +++ b/FloridOS/limine/limine.h @@ -0,0 +1,609 @@ +/* BSD Zero Clause License */ + +/* Copyright (C) 2022-2024 mintsuki and contributors. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef LIMINE_H +#define LIMINE_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* Misc */ + +#ifdef LIMINE_NO_POINTERS +# define LIMINE_PTR(TYPE) uint64_t +#else +# define LIMINE_PTR(TYPE) TYPE +#endif + +#ifdef __GNUC__ +# define LIMINE_DEPRECATED __attribute__((__deprecated__)) +# define LIMINE_DEPRECATED_IGNORE_START \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") +# define LIMINE_DEPRECATED_IGNORE_END \ + _Pragma("GCC diagnostic pop") +#else +# define LIMINE_DEPRECATED +# define LIMINE_DEPRECATED_IGNORE_START +# define LIMINE_DEPRECATED_IGNORE_END +#endif + +#define LIMINE_REQUESTS_START_MARKER \ + uint64_t limine_requests_start_marker[4] = { 0xf6b8f4b39de7d1ae, 0xfab91a6940fcb9cf, \ + 0x785c6ed015d3e316, 0x181e920a7852b9d9 }; +#define LIMINE_REQUESTS_END_MARKER \ + uint64_t limine_requests_end_marker[2] = { 0xadc0e0531bb10d03, 0x9572709f31764c62 }; + +#define LIMINE_REQUESTS_DELIMITER LIMINE_REQUESTS_END_MARKER + +#define LIMINE_BASE_REVISION(N) \ + uint64_t limine_base_revision[3] = { 0xf9562b2d5c95a6c8, 0x6a7b384944536bdc, (N) }; + +#define LIMINE_BASE_REVISION_SUPPORTED (limine_base_revision[2] == 0) + +#define LIMINE_COMMON_MAGIC 0xc7b1dd30df4c8b88, 0x0a82e883a194f07b + +struct limine_uuid { + uint32_t a; + uint16_t b; + uint16_t c; + uint8_t d[8]; +}; + +#define LIMINE_MEDIA_TYPE_GENERIC 0 +#define LIMINE_MEDIA_TYPE_OPTICAL 1 +#define LIMINE_MEDIA_TYPE_TFTP 2 + +struct limine_file { + uint64_t revision; + LIMINE_PTR(void *) address; + uint64_t size; + LIMINE_PTR(char *) path; + LIMINE_PTR(char *) cmdline; + uint32_t media_type; + uint32_t unused; + uint32_t tftp_ip; + uint32_t tftp_port; + uint32_t partition_index; + uint32_t mbr_disk_id; + struct limine_uuid gpt_disk_uuid; + struct limine_uuid gpt_part_uuid; + struct limine_uuid part_uuid; +}; + +/* Boot info */ + +#define LIMINE_BOOTLOADER_INFO_REQUEST { LIMINE_COMMON_MAGIC, 0xf55038d8e2a1202f, 0x279426fcf5f59740 } + +struct limine_bootloader_info_response { + uint64_t revision; + LIMINE_PTR(char *) name; + LIMINE_PTR(char *) version; +}; + +struct limine_bootloader_info_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_bootloader_info_response *) response; +}; + +/* Firmware type */ + +#define LIMINE_FIRMWARE_TYPE_REQUEST { LIMINE_COMMON_MAGIC, 0x8c2f75d90bef28a8, 0x7045a4688eac00c3 } + +#define LIMINE_FIRMWARE_TYPE_X86BIOS 0 +#define LIMINE_FIRMWARE_TYPE_UEFI32 1 +#define LIMINE_FIRMWARE_TYPE_UEFI64 2 + +struct limine_firmware_type_response { + uint64_t revision; + uint64_t firmware_type; +}; + +struct limine_firmware_type_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_firmware_type_response *) response; +}; + +/* Stack size */ + +#define LIMINE_STACK_SIZE_REQUEST { LIMINE_COMMON_MAGIC, 0x224ef0460a8e8926, 0xe1cb0fc25f46ea3d } + +struct limine_stack_size_response { + uint64_t revision; +}; + +struct limine_stack_size_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_stack_size_response *) response; + uint64_t stack_size; +}; + +/* HHDM */ + +#define LIMINE_HHDM_REQUEST { LIMINE_COMMON_MAGIC, 0x48dcf1cb8ad2b852, 0x63984e959a98244b } + +struct limine_hhdm_response { + uint64_t revision; + uint64_t offset; +}; + +struct limine_hhdm_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_hhdm_response *) response; +}; + +/* Framebuffer */ + +#define LIMINE_FRAMEBUFFER_REQUEST { LIMINE_COMMON_MAGIC, 0x9d5827dcd881dd75, 0xa3148604f6fab11b } + +#define LIMINE_FRAMEBUFFER_RGB 1 + +struct limine_video_mode { + uint64_t pitch; + uint64_t width; + uint64_t height; + uint16_t bpp; + uint8_t memory_model; + uint8_t red_mask_size; + uint8_t red_mask_shift; + uint8_t green_mask_size; + uint8_t green_mask_shift; + uint8_t blue_mask_size; + uint8_t blue_mask_shift; +}; + +struct limine_framebuffer { + LIMINE_PTR(void *) address; + uint64_t width; + uint64_t height; + uint64_t pitch; + uint16_t bpp; + uint8_t memory_model; + uint8_t red_mask_size; + uint8_t red_mask_shift; + uint8_t green_mask_size; + uint8_t green_mask_shift; + uint8_t blue_mask_size; + uint8_t blue_mask_shift; + uint8_t unused[7]; + uint64_t edid_size; + LIMINE_PTR(void *) edid; + /* Response revision 1 */ + uint64_t mode_count; + LIMINE_PTR(struct limine_video_mode **) modes; +}; + +struct limine_framebuffer_response { + uint64_t revision; + uint64_t framebuffer_count; + LIMINE_PTR(struct limine_framebuffer **) framebuffers; +}; + +struct limine_framebuffer_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_framebuffer_response *) response; +}; + +/* Terminal */ + +#define LIMINE_TERMINAL_REQUEST { LIMINE_COMMON_MAGIC, 0xc8ac59310c2b0844, 0xa68d0c7265d38878 } + +#define LIMINE_TERMINAL_CB_DEC 10 +#define LIMINE_TERMINAL_CB_BELL 20 +#define LIMINE_TERMINAL_CB_PRIVATE_ID 30 +#define LIMINE_TERMINAL_CB_STATUS_REPORT 40 +#define LIMINE_TERMINAL_CB_POS_REPORT 50 +#define LIMINE_TERMINAL_CB_KBD_LEDS 60 +#define LIMINE_TERMINAL_CB_MODE 70 +#define LIMINE_TERMINAL_CB_LINUX 80 + +#define LIMINE_TERMINAL_CTX_SIZE ((uint64_t)(-1)) +#define LIMINE_TERMINAL_CTX_SAVE ((uint64_t)(-2)) +#define LIMINE_TERMINAL_CTX_RESTORE ((uint64_t)(-3)) +#define LIMINE_TERMINAL_FULL_REFRESH ((uint64_t)(-4)) + +/* Response revision 1 */ +#define LIMINE_TERMINAL_OOB_OUTPUT_GET ((uint64_t)(-10)) +#define LIMINE_TERMINAL_OOB_OUTPUT_SET ((uint64_t)(-11)) + +#define LIMINE_TERMINAL_OOB_OUTPUT_OCRNL (1 << 0) +#define LIMINE_TERMINAL_OOB_OUTPUT_OFDEL (1 << 1) +#define LIMINE_TERMINAL_OOB_OUTPUT_OFILL (1 << 2) +#define LIMINE_TERMINAL_OOB_OUTPUT_OLCUC (1 << 3) +#define LIMINE_TERMINAL_OOB_OUTPUT_ONLCR (1 << 4) +#define LIMINE_TERMINAL_OOB_OUTPUT_ONLRET (1 << 5) +#define LIMINE_TERMINAL_OOB_OUTPUT_ONOCR (1 << 6) +#define LIMINE_TERMINAL_OOB_OUTPUT_OPOST (1 << 7) + +LIMINE_DEPRECATED_IGNORE_START + +struct LIMINE_DEPRECATED limine_terminal; + +typedef void (*limine_terminal_write)(struct limine_terminal *, const char *, uint64_t); +typedef void (*limine_terminal_callback)(struct limine_terminal *, uint64_t, uint64_t, uint64_t, uint64_t); + +struct LIMINE_DEPRECATED limine_terminal { + uint64_t columns; + uint64_t rows; + LIMINE_PTR(struct limine_framebuffer *) framebuffer; +}; + +struct LIMINE_DEPRECATED limine_terminal_response { + uint64_t revision; + uint64_t terminal_count; + LIMINE_PTR(struct limine_terminal **) terminals; + LIMINE_PTR(limine_terminal_write) write; +}; + +struct LIMINE_DEPRECATED limine_terminal_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_terminal_response *) response; + LIMINE_PTR(limine_terminal_callback) callback; +}; + +LIMINE_DEPRECATED_IGNORE_END + +/* Paging mode */ + +#define LIMINE_PAGING_MODE_REQUEST { LIMINE_COMMON_MAGIC, 0x95c1a0edab0944cb, 0xa4e5cb3842f7488a } + +#if defined (__x86_64__) || defined (__i386__) +#define LIMINE_PAGING_MODE_X86_64_4LVL 0 +#define LIMINE_PAGING_MODE_X86_64_5LVL 1 +#define LIMINE_PAGING_MODE_MAX LIMINE_PAGING_MODE_X86_64_5LVL +#define LIMINE_PAGING_MODE_MIN LIMINE_PAGING_MODE_X86_64_4LVL +#define LIMINE_PAGING_MODE_DEFAULT LIMINE_PAGING_MODE_X86_64_4LVL +#elif defined (__aarch64__) +#define LIMINE_PAGING_MODE_AARCH64_4LVL 0 +#define LIMINE_PAGING_MODE_AARCH64_5LVL 1 +#define LIMINE_PAGING_MODE_MAX LIMINE_PAGING_MODE_AARCH64_5LVL +#define LIMINE_PAGING_MODE_MIN LIMINE_PAGING_MODE_AARCH64_4LVL +#define LIMINE_PAGING_MODE_DEFAULT LIMINE_PAGING_MODE_AARCH64_4LVL +#elif defined (__riscv) && (__riscv_xlen == 64) +#define LIMINE_PAGING_MODE_RISCV_SV39 0 +#define LIMINE_PAGING_MODE_RISCV_SV48 1 +#define LIMINE_PAGING_MODE_RISCV_SV57 2 +#define LIMINE_PAGING_MODE_MAX LIMINE_PAGING_MODE_RISCV_SV57 +#define LIMINE_PAGING_MODE_MIN LIMINE_PAGING_MODE_RISCV_SV39 +#define LIMINE_PAGING_MODE_DEFAULT LIMINE_PAGING_MODE_RISCV_SV48 +#else +#error Unknown architecture +#endif + +struct limine_paging_mode_response { + uint64_t revision; + uint64_t mode; +}; + +struct limine_paging_mode_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_paging_mode_response *) response; + uint64_t mode; + uint64_t max_mode; + uint64_t min_mode; +}; + +/* 5-level paging */ + +#define LIMINE_5_LEVEL_PAGING_REQUEST { LIMINE_COMMON_MAGIC, 0x94469551da9b3192, 0xebe5e86db7382888 } + +LIMINE_DEPRECATED_IGNORE_START + +struct LIMINE_DEPRECATED limine_5_level_paging_response { + uint64_t revision; +}; + +struct LIMINE_DEPRECATED limine_5_level_paging_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_5_level_paging_response *) response; +}; + +LIMINE_DEPRECATED_IGNORE_END + +/* SMP */ + +#define LIMINE_SMP_REQUEST { LIMINE_COMMON_MAGIC, 0x95a67b819a1b857e, 0xa0b61b723b6a73e0 } + +struct limine_smp_info; + +typedef void (*limine_goto_address)(struct limine_smp_info *); + +#if defined (__x86_64__) || defined (__i386__) + +#define LIMINE_SMP_X2APIC (1 << 0) + +struct limine_smp_info { + uint32_t processor_id; + uint32_t lapic_id; + uint64_t reserved; + LIMINE_PTR(limine_goto_address) goto_address; + uint64_t extra_argument; +}; + +struct limine_smp_response { + uint64_t revision; + uint32_t flags; + uint32_t bsp_lapic_id; + uint64_t cpu_count; + LIMINE_PTR(struct limine_smp_info **) cpus; +}; + +#elif defined (__aarch64__) + +struct limine_smp_info { + uint32_t processor_id; + uint32_t reserved1; + uint64_t mpidr; + uint64_t reserved; + LIMINE_PTR(limine_goto_address) goto_address; + uint64_t extra_argument; +}; + +struct limine_smp_response { + uint64_t revision; + uint64_t flags; + uint64_t bsp_mpidr; + uint64_t cpu_count; + LIMINE_PTR(struct limine_smp_info **) cpus; +}; + +#elif defined (__riscv) && (__riscv_xlen == 64) + +struct limine_smp_info { + uint64_t processor_id; + uint64_t hartid; + uint64_t reserved; + LIMINE_PTR(limine_goto_address) goto_address; + uint64_t extra_argument; +}; + +struct limine_smp_response { + uint64_t revision; + uint64_t flags; + uint64_t bsp_hartid; + uint64_t cpu_count; + LIMINE_PTR(struct limine_smp_info **) cpus; +}; + +#else +#error Unknown architecture +#endif + +struct limine_smp_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_smp_response *) response; + uint64_t flags; +}; + +/* Memory map */ + +#define LIMINE_MEMMAP_REQUEST { LIMINE_COMMON_MAGIC, 0x67cf3d9d378a806f, 0xe304acdfc50c3c62 } + +#define LIMINE_MEMMAP_USABLE 0 +#define LIMINE_MEMMAP_RESERVED 1 +#define LIMINE_MEMMAP_ACPI_RECLAIMABLE 2 +#define LIMINE_MEMMAP_ACPI_NVS 3 +#define LIMINE_MEMMAP_BAD_MEMORY 4 +#define LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE 5 +#define LIMINE_MEMMAP_KERNEL_AND_MODULES 6 +#define LIMINE_MEMMAP_FRAMEBUFFER 7 + +struct limine_memmap_entry { + uint64_t base; + uint64_t length; + uint64_t type; +}; + +struct limine_memmap_response { + uint64_t revision; + uint64_t entry_count; + LIMINE_PTR(struct limine_memmap_entry **) entries; +}; + +struct limine_memmap_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_memmap_response *) response; +}; + +/* Entry point */ + +#define LIMINE_ENTRY_POINT_REQUEST { LIMINE_COMMON_MAGIC, 0x13d86c035a1cd3e1, 0x2b0caa89d8f3026a } + +typedef void (*limine_entry_point)(void); + +struct limine_entry_point_response { + uint64_t revision; +}; + +struct limine_entry_point_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_entry_point_response *) response; + LIMINE_PTR(limine_entry_point) entry; +}; + +/* Kernel File */ + +#define LIMINE_KERNEL_FILE_REQUEST { LIMINE_COMMON_MAGIC, 0xad97e90e83f1ed67, 0x31eb5d1c5ff23b69 } + +struct limine_kernel_file_response { + uint64_t revision; + LIMINE_PTR(struct limine_file *) kernel_file; +}; + +struct limine_kernel_file_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_kernel_file_response *) response; +}; + +/* Module */ + +#define LIMINE_MODULE_REQUEST { LIMINE_COMMON_MAGIC, 0x3e7e279702be32af, 0xca1c4f3bd1280cee } + +#define LIMINE_INTERNAL_MODULE_REQUIRED (1 << 0) +#define LIMINE_INTERNAL_MODULE_COMPRESSED (1 << 1) + +struct limine_internal_module { + LIMINE_PTR(const char *) path; + LIMINE_PTR(const char *) cmdline; + uint64_t flags; +}; + +struct limine_module_response { + uint64_t revision; + uint64_t module_count; + LIMINE_PTR(struct limine_file **) modules; +}; + +struct limine_module_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_module_response *) response; + + /* Request revision 1 */ + uint64_t internal_module_count; + LIMINE_PTR(struct limine_internal_module **) internal_modules; +}; + +/* RSDP */ + +#define LIMINE_RSDP_REQUEST { LIMINE_COMMON_MAGIC, 0xc5e77b6b397e7b43, 0x27637845accdcf3c } + +struct limine_rsdp_response { + uint64_t revision; + LIMINE_PTR(void *) address; +}; + +struct limine_rsdp_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_rsdp_response *) response; +}; + +/* SMBIOS */ + +#define LIMINE_SMBIOS_REQUEST { LIMINE_COMMON_MAGIC, 0x9e9046f11e095391, 0xaa4a520fefbde5ee } + +struct limine_smbios_response { + uint64_t revision; + LIMINE_PTR(void *) entry_32; + LIMINE_PTR(void *) entry_64; +}; + +struct limine_smbios_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_smbios_response *) response; +}; + +/* EFI system table */ + +#define LIMINE_EFI_SYSTEM_TABLE_REQUEST { LIMINE_COMMON_MAGIC, 0x5ceba5163eaaf6d6, 0x0a6981610cf65fcc } + +struct limine_efi_system_table_response { + uint64_t revision; + LIMINE_PTR(void *) address; +}; + +struct limine_efi_system_table_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_efi_system_table_response *) response; +}; + +/* EFI memory map */ + +#define LIMINE_EFI_MEMMAP_REQUEST { LIMINE_COMMON_MAGIC, 0x7df62a431d6872d5, 0xa4fcdfb3e57306c8 } + +struct limine_efi_memmap_response { + uint64_t revision; + LIMINE_PTR(void *) memmap; + uint64_t memmap_size; + uint64_t desc_size; + uint64_t desc_version; +}; + +struct limine_efi_memmap_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_efi_memmap_response *) response; +}; + +/* Boot time */ + +#define LIMINE_BOOT_TIME_REQUEST { LIMINE_COMMON_MAGIC, 0x502746e184c088aa, 0xfbc5ec83e6327893 } + +struct limine_boot_time_response { + uint64_t revision; + int64_t boot_time; +}; + +struct limine_boot_time_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_boot_time_response *) response; +}; + +/* Kernel address */ + +#define LIMINE_KERNEL_ADDRESS_REQUEST { LIMINE_COMMON_MAGIC, 0x71ba76863cc55f63, 0xb2644a48c516a487 } + +struct limine_kernel_address_response { + uint64_t revision; + uint64_t physical_base; + uint64_t virtual_base; +}; + +struct limine_kernel_address_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_kernel_address_response *) response; +}; + +/* Device Tree Blob */ + +#define LIMINE_DTB_REQUEST { LIMINE_COMMON_MAGIC, 0xb40ddb48fb54bac7, 0x545081493f81ffb7 } + +struct limine_dtb_response { + uint64_t revision; + LIMINE_PTR(void *) dtb_ptr; +}; + +struct limine_dtb_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_dtb_response *) response; +}; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/FloridOS/src/include/limine.h b/FloridOS/src/include/limine.h new file mode 100644 index 0000000..63e8422 --- /dev/null +++ b/FloridOS/src/include/limine.h @@ -0,0 +1,609 @@ +/* BSD Zero Clause License */ + +/* Copyright (C) 2022-2024 mintsuki and contributors. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef LIMINE_H +#define LIMINE_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* Misc */ + +#ifdef LIMINE_NO_POINTERS +# define LIMINE_PTR(TYPE) uint64_t +#else +# define LIMINE_PTR(TYPE) TYPE +#endif + +#ifdef __GNUC__ +# define LIMINE_DEPRECATED __attribute__((__deprecated__)) +# define LIMINE_DEPRECATED_IGNORE_START \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") +# define LIMINE_DEPRECATED_IGNORE_END \ + _Pragma("GCC diagnostic pop") +#else +# define LIMINE_DEPRECATED +# define LIMINE_DEPRECATED_IGNORE_START +# define LIMINE_DEPRECATED_IGNORE_END +#endif + +#define LIMINE_REQUESTS_START_MARKER \ + uint64_t limine_requests_start_marker[4] = { 0xf6b8f4b39de7d1ae, 0xfab91a6940fcb9cf, \ + 0x785c6ed015d3e316, 0x181e920a7852b9d9 }; +#define LIMINE_REQUESTS_END_MARKER \ + uint64_t limine_requests_end_marker[2] = { 0xadc0e0531bb10d03, 0x9572709f31764c62 }; + +#define LIMINE_REQUESTS_DELIMITER LIMINE_REQUESTS_END_MARKER + +#define LIMINE_BASE_REVISION(N) \ + uint64_t limine_base_revision[3] = { 0xf9562b2d5c95a6c8, 0x6a7b384944536bdc, (N) }; + +#define LIMINE_BASE_REVISION_SUPPORTED (limine_base_revision[2] == 0) + +#define LIMINE_COMMON_MAGIC 0xc7b1dd30df4c8b88, 0x0a82e883a194f07b + +struct limine_uuid { + uint32_t a; + uint16_t b; + uint16_t c; + uint8_t d[8]; +}; + +#define LIMINE_MEDIA_TYPE_GENERIC 0 +#define LIMINE_MEDIA_TYPE_OPTICAL 1 +#define LIMINE_MEDIA_TYPE_TFTP 2 + +struct limine_file { + uint64_t revision; + LIMINE_PTR(void *) address; + uint64_t size; + LIMINE_PTR(char *) path; + LIMINE_PTR(char *) cmdline; + uint32_t media_type; + uint32_t unused; + uint32_t tftp_ip; + uint32_t tftp_port; + uint32_t partition_index; + uint32_t mbr_disk_id; + struct limine_uuid gpt_disk_uuid; + struct limine_uuid gpt_part_uuid; + struct limine_uuid part_uuid; +}; + +/* Boot info */ + +#define LIMINE_BOOTLOADER_INFO_REQUEST { LIMINE_COMMON_MAGIC, 0xf55038d8e2a1202f, 0x279426fcf5f59740 } + +struct limine_bootloader_info_response { + uint64_t revision; + LIMINE_PTR(char *) name; + LIMINE_PTR(char *) version; +}; + +struct limine_bootloader_info_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_bootloader_info_response *) response; +}; + +/* Firmware type */ + +#define LIMINE_FIRMWARE_TYPE_REQUEST { LIMINE_COMMON_MAGIC, 0x8c2f75d90bef28a8, 0x7045a4688eac00c3 } + +#define LIMINE_FIRMWARE_TYPE_X86BIOS 0 +#define LIMINE_FIRMWARE_TYPE_UEFI32 1 +#define LIMINE_FIRMWARE_TYPE_UEFI64 2 + +struct limine_firmware_type_response { + uint64_t revision; + uint64_t firmware_type; +}; + +struct limine_firmware_type_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_firmware_type_response *) response; +}; + +/* Stack size */ + +#define LIMINE_STACK_SIZE_REQUEST { LIMINE_COMMON_MAGIC, 0x224ef0460a8e8926, 0xe1cb0fc25f46ea3d } + +struct limine_stack_size_response { + uint64_t revision; +}; + +struct limine_stack_size_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_stack_size_response *) response; + uint64_t stack_size; +}; + +/* HHDM */ + +#define LIMINE_HHDM_REQUEST { LIMINE_COMMON_MAGIC, 0x48dcf1cb8ad2b852, 0x63984e959a98244b } + +struct limine_hhdm_response { + uint64_t revision; + uint64_t offset; +}; + +struct limine_hhdm_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_hhdm_response *) response; +}; + +/* Framebuffer */ + +#define LIMINE_FRAMEBUFFER_REQUEST { LIMINE_COMMON_MAGIC, 0x9d5827dcd881dd75, 0xa3148604f6fab11b } + +#define LIMINE_FRAMEBUFFER_RGB 1 + +struct limine_video_mode { + uint64_t pitch; + uint64_t width; + uint64_t height; + uint16_t bpp; + uint8_t memory_model; + uint8_t red_mask_size; + uint8_t red_mask_shift; + uint8_t green_mask_size; + uint8_t green_mask_shift; + uint8_t blue_mask_size; + uint8_t blue_mask_shift; +}; + +struct limine_framebuffer { + LIMINE_PTR(void *) address; + uint64_t width; + uint64_t height; + uint64_t pitch; + uint16_t bpp; + uint8_t memory_model; + uint8_t red_mask_size; + uint8_t red_mask_shift; + uint8_t green_mask_size; + uint8_t green_mask_shift; + uint8_t blue_mask_size; + uint8_t blue_mask_shift; + uint8_t unused[7]; + uint64_t edid_size; + LIMINE_PTR(void *) edid; + /* Response revision 1 */ + uint64_t mode_count; + LIMINE_PTR(struct limine_video_mode **) modes; +}; + +struct limine_framebuffer_response { + uint64_t revision; + uint64_t framebuffer_count; + LIMINE_PTR(struct limine_framebuffer **) framebuffers; +}; + +struct limine_framebuffer_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_framebuffer_response *) response; +}; + +/* Terminal */ + +#define LIMINE_TERMINAL_REQUEST { LIMINE_COMMON_MAGIC, 0xc8ac59310c2b0844, 0xa68d0c7265d38878 } + +#define LIMINE_TERMINAL_CB_DEC 10 +#define LIMINE_TERMINAL_CB_BELL 20 +#define LIMINE_TERMINAL_CB_PRIVATE_ID 30 +#define LIMINE_TERMINAL_CB_STATUS_REPORT 40 +#define LIMINE_TERMINAL_CB_POS_REPORT 50 +#define LIMINE_TERMINAL_CB_KBD_LEDS 60 +#define LIMINE_TERMINAL_CB_MODE 70 +#define LIMINE_TERMINAL_CB_LINUX 80 + +#define LIMINE_TERMINAL_CTX_SIZE ((uint64_t)(-1)) +#define LIMINE_TERMINAL_CTX_SAVE ((uint64_t)(-2)) +#define LIMINE_TERMINAL_CTX_RESTORE ((uint64_t)(-3)) +#define LIMINE_TERMINAL_FULL_REFRESH ((uint64_t)(-4)) + +/* Response revision 1 */ +#define LIMINE_TERMINAL_OOB_OUTPUT_GET ((uint64_t)(-10)) +#define LIMINE_TERMINAL_OOB_OUTPUT_SET ((uint64_t)(-11)) + +#define LIMINE_TERMINAL_OOB_OUTPUT_OCRNL (1 << 0) +#define LIMINE_TERMINAL_OOB_OUTPUT_OFDEL (1 << 1) +#define LIMINE_TERMINAL_OOB_OUTPUT_OFILL (1 << 2) +#define LIMINE_TERMINAL_OOB_OUTPUT_OLCUC (1 << 3) +#define LIMINE_TERMINAL_OOB_OUTPUT_ONLCR (1 << 4) +#define LIMINE_TERMINAL_OOB_OUTPUT_ONLRET (1 << 5) +#define LIMINE_TERMINAL_OOB_OUTPUT_ONOCR (1 << 6) +#define LIMINE_TERMINAL_OOB_OUTPUT_OPOST (1 << 7) + +LIMINE_DEPRECATED_IGNORE_START + +struct LIMINE_DEPRECATED limine_terminal; + +typedef void (*limine_terminal_write)(struct limine_terminal *, const char *, uint64_t); +typedef void (*limine_terminal_callback)(struct limine_terminal *, uint64_t, uint64_t, uint64_t, uint64_t); + +struct LIMINE_DEPRECATED limine_terminal { + uint64_t columns; + uint64_t rows; + LIMINE_PTR(struct limine_framebuffer *) framebuffer; +}; + +struct LIMINE_DEPRECATED limine_terminal_response { + uint64_t revision; + uint64_t terminal_count; + LIMINE_PTR(struct limine_terminal **) terminals; + LIMINE_PTR(limine_terminal_write) write; +}; + +struct LIMINE_DEPRECATED limine_terminal_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_terminal_response *) response; + LIMINE_PTR(limine_terminal_callback) callback; +}; + +LIMINE_DEPRECATED_IGNORE_END + +/* Paging mode */ + +#define LIMINE_PAGING_MODE_REQUEST { LIMINE_COMMON_MAGIC, 0x95c1a0edab0944cb, 0xa4e5cb3842f7488a } + +#if defined (__x86_64__) || defined (__i386__) +#define LIMINE_PAGING_MODE_X86_64_4LVL 0 +#define LIMINE_PAGING_MODE_X86_64_5LVL 1 +#define LIMINE_PAGING_MODE_MAX LIMINE_PAGING_MODE_X86_64_5LVL +#define LIMINE_PAGING_MODE_MIN LIMINE_PAGING_MODE_X86_64_4LVL +#define LIMINE_PAGING_MODE_DEFAULT LIMINE_PAGING_MODE_X86_64_4LVL +#elif defined (__aarch64__) +#define LIMINE_PAGING_MODE_AARCH64_4LVL 0 +#define LIMINE_PAGING_MODE_AARCH64_5LVL 1 +#define LIMINE_PAGING_MODE_MAX LIMINE_PAGING_MODE_AARCH64_5LVL +#define LIMINE_PAGING_MODE_MIN LIMINE_PAGING_MODE_AARCH64_4LVL +#define LIMINE_PAGING_MODE_DEFAULT LIMINE_PAGING_MODE_AARCH64_4LVL +#elif defined (__riscv) && (__riscv_xlen == 64) +#define LIMINE_PAGING_MODE_RISCV_SV39 0 +#define LIMINE_PAGING_MODE_RISCV_SV48 1 +#define LIMINE_PAGING_MODE_RISCV_SV57 2 +#define LIMINE_PAGING_MODE_MAX LIMINE_PAGING_MODE_RISCV_SV57 +#define LIMINE_PAGING_MODE_MIN LIMINE_PAGING_MODE_RISCV_SV39 +#define LIMINE_PAGING_MODE_DEFAULT LIMINE_PAGING_MODE_RISCV_SV48 +#else +#error Unknown architecture +#endif + +struct limine_paging_mode_response { + uint64_t revision; + uint64_t mode; +}; + +struct limine_paging_mode_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_paging_mode_response *) response; + uint64_t mode; + uint64_t max_mode; + uint64_t min_mode; +}; + +/* 5-level paging */ + +#define LIMINE_5_LEVEL_PAGING_REQUEST { LIMINE_COMMON_MAGIC, 0x94469551da9b3192, 0xebe5e86db7382888 } + +LIMINE_DEPRECATED_IGNORE_START + +struct LIMINE_DEPRECATED limine_5_level_paging_response { + uint64_t revision; +}; + +struct LIMINE_DEPRECATED limine_5_level_paging_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_5_level_paging_response *) response; +}; + +LIMINE_DEPRECATED_IGNORE_END + +/* SMP */ + +#define LIMINE_SMP_REQUEST { LIMINE_COMMON_MAGIC, 0x95a67b819a1b857e, 0xa0b61b723b6a73e0 } + +struct limine_smp_info; + +typedef void (*limine_goto_address)(struct limine_smp_info *); + +#if defined (__x86_64__) || defined (__i386__) + +#define LIMINE_SMP_X2APIC (1 << 0) + +struct limine_smp_info { + uint32_t processor_id; + uint32_t lapic_id; + uint64_t reserved; + LIMINE_PTR(limine_goto_address) goto_address; + uint64_t extra_argument; +}; + +struct limine_smp_response { + uint64_t revision; + uint32_t flags; + uint32_t bsp_lapic_id; + uint64_t cpu_count; + LIMINE_PTR(struct limine_smp_info **) cpus; +}; + +#elif defined (__aarch64__) + +struct limine_smp_info { + uint32_t processor_id; + uint32_t reserved1; + uint64_t mpidr; + uint64_t reserved; + LIMINE_PTR(limine_goto_address) goto_address; + uint64_t extra_argument; +}; + +struct limine_smp_response { + uint64_t revision; + uint64_t flags; + uint64_t bsp_mpidr; + uint64_t cpu_count; + LIMINE_PTR(struct limine_smp_info **) cpus; +}; + +#elif defined (__riscv) && (__riscv_xlen == 64) + +struct limine_smp_info { + uint64_t processor_id; + uint64_t hartid; + uint64_t reserved; + LIMINE_PTR(limine_goto_address) goto_address; + uint64_t extra_argument; +}; + +struct limine_smp_response { + uint64_t revision; + uint64_t flags; + uint64_t bsp_hartid; + uint64_t cpu_count; + LIMINE_PTR(struct limine_smp_info **) cpus; +}; + +#else +#error Unknown architecture +#endif + +struct limine_smp_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_smp_response *) response; + uint64_t flags; +}; + +/* Memory map */ + +#define LIMINE_MEMMAP_REQUEST { LIMINE_COMMON_MAGIC, 0x67cf3d9d378a806f, 0xe304acdfc50c3c62 } + +#define LIMINE_MEMMAP_USABLE 0 +#define LIMINE_MEMMAP_RESERVED 1 +#define LIMINE_MEMMAP_ACPI_RECLAIMABLE 2 +#define LIMINE_MEMMAP_ACPI_NVS 3 +#define LIMINE_MEMMAP_BAD_MEMORY 4 +#define LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE 5 +#define LIMINE_MEMMAP_KERNEL_AND_MODULES 6 +#define LIMINE_MEMMAP_FRAMEBUFFER 7 + +struct limine_memmap_entry { + uint64_t base; + uint64_t length; + uint64_t type; +}; + +struct limine_memmap_response { + uint64_t revision; + uint64_t entry_count; + LIMINE_PTR(struct limine_memmap_entry **) entries; +}; + +struct limine_memmap_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_memmap_response *) response; +}; + +/* Entry point */ + +#define LIMINE_ENTRY_POINT_REQUEST { LIMINE_COMMON_MAGIC, 0x13d86c035a1cd3e1, 0x2b0caa89d8f3026a } + +typedef void (*limine_entry_point)(void); + +struct limine_entry_point_response { + uint64_t revision; +}; + +struct limine_entry_point_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_entry_point_response *) response; + LIMINE_PTR(limine_entry_point) entry; +}; + +/* Kernel File */ + +#define LIMINE_KERNEL_FILE_REQUEST { LIMINE_COMMON_MAGIC, 0xad97e90e83f1ed67, 0x31eb5d1c5ff23b69 } + +struct limine_kernel_file_response { + uint64_t revision; + LIMINE_PTR(struct limine_file *) kernel_file; +}; + +struct limine_kernel_file_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_kernel_file_response *) response; +}; + +/* Module */ + +#define LIMINE_MODULE_REQUEST { LIMINE_COMMON_MAGIC, 0x3e7e279702be32af, 0xca1c4f3bd1280cee } + +#define LIMINE_INTERNAL_MODULE_REQUIRED (1 << 0) +#define LIMINE_INTERNAL_MODULE_COMPRESSED (1 << 1) + +struct limine_internal_module { + LIMINE_PTR(const char *) path; + LIMINE_PTR(const char *) cmdline; + uint64_t flags; +}; + +struct limine_module_response { + uint64_t revision; + uint64_t module_count; + LIMINE_PTR(struct limine_file **) modules; +}; + +struct limine_module_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_module_response *) response; + + /* Request revision 1 */ + uint64_t internal_module_count; + LIMINE_PTR(struct limine_internal_module **) internal_modules; +}; + +/* RSDP */ + +#define LIMINE_RSDP_REQUEST { LIMINE_COMMON_MAGIC, 0xc5e77b6b397e7b43, 0x27637845accdcf3c } + +struct limine_rsdp_response { + uint64_t revision; + LIMINE_PTR(void *) address; +}; + +struct limine_rsdp_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_rsdp_response *) response; +}; + +/* SMBIOS */ + +#define LIMINE_SMBIOS_REQUEST { LIMINE_COMMON_MAGIC, 0x9e9046f11e095391, 0xaa4a520fefbde5ee } + +struct limine_smbios_response { + uint64_t revision; + LIMINE_PTR(void *) entry_32; + LIMINE_PTR(void *) entry_64; +}; + +struct limine_smbios_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_smbios_response *) response; +}; + +/* EFI system table */ + +#define LIMINE_EFI_SYSTEM_TABLE_REQUEST { LIMINE_COMMON_MAGIC, 0x5ceba5163eaaf6d6, 0x0a6981610cf65fcc } + +struct limine_efi_system_table_response { + uint64_t revision; + LIMINE_PTR(void *) address; +}; + +struct limine_efi_system_table_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_efi_system_table_response *) response; +}; + +/* EFI memory map */ + +#define LIMINE_EFI_MEMMAP_REQUEST { LIMINE_COMMON_MAGIC, 0x7df62a431d6872d5, 0xa4fcdfb3e57306c8 } + +struct limine_efi_memmap_response { + uint64_t revision; + LIMINE_PTR(void *) memmap; + uint64_t memmap_size; + uint64_t desc_size; + uint64_t desc_version; +}; + +struct limine_efi_memmap_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_efi_memmap_response *) response; +}; + +/* Boot time */ + +#define LIMINE_BOOT_TIME_REQUEST { LIMINE_COMMON_MAGIC, 0x502746e184c088aa, 0xfbc5ec83e6327893 } + +struct limine_boot_time_response { + uint64_t revision; + int64_t boot_time; +}; + +struct limine_boot_time_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_boot_time_response *) response; +}; + +/* Kernel address */ + +#define LIMINE_KERNEL_ADDRESS_REQUEST { LIMINE_COMMON_MAGIC, 0x71ba76863cc55f63, 0xb2644a48c516a487 } + +struct limine_kernel_address_response { + uint64_t revision; + uint64_t physical_base; + uint64_t virtual_base; +}; + +struct limine_kernel_address_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_kernel_address_response *) response; +}; + +/* Device Tree Blob */ + +#define LIMINE_DTB_REQUEST { LIMINE_COMMON_MAGIC, 0xb40ddb48fb54bac7, 0x545081493f81ffb7 } + +struct limine_dtb_response { + uint64_t revision; + LIMINE_PTR(void *) dtb_ptr; +}; + +struct limine_dtb_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_dtb_response *) response; +}; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/FloridOS/src/kernel/cpu/interrupts.c b/FloridOS/src/kernel/cpu/interrupts.c new file mode 100644 index 0000000..edd6962 --- /dev/null +++ b/FloridOS/src/kernel/cpu/interrupts.c @@ -0,0 +1,17 @@ +#include +#include "../../include/limine.h" + +// This is the "Panic" screen when something goes wrong +void kpanic(const char* message) { + // In a real OS, we'd clear the screen and show an error code here. + // For now, we'll just stop the computer. + while(1) { __asm__("cli; hlt"); } +} + +void exception_handler(uint64_t vec) { + switch(vec) { + case 0: kpanic("DIVISION BY ZERO"); break; + case 14: kpanic("PAGE FAULT"); break; + default: kpanic("UNKNOWN EXCEPTION"); break; + } +} \ No newline at end of file diff --git a/FloridOS/src/kernel/kernel.c b/FloridOS/src/kernel/kernel.c new file mode 100644 index 0000000..c204ccb --- /dev/null +++ b/FloridOS/src/kernel/kernel.c @@ -0,0 +1,250 @@ +/* + * FFFFFFFFFFFFFFFFFFFFFFlllllll iiii dddddddd + * F::::::::::::::::::::Fl:::::l i::::i d::::::d + * F::::::::::::::::::::Fl:::::l iiii d::::::d + * FF::::::FFFFFFFFF::::Fl:::::l d::::::d + * F:::::F FFFFFF l::::l ooooooooooo rrrr rrrrrrr iiiiiii d:::::d + * F:::::F l::::l oo:::::::::::oo r::::rr:::::ri::::i d:::::d + * F::::::FFFFFFFFFF l::::l o:::::::::::::::or::::r r::::ri::::i d:::::d + * F:::::::::::::::F l::::l o:::::ooooo:::::or::::r rrrrri::::i d:::::d + * F:::::::::::::::F l::::l o::::o o::::or::::r i::::i d:::::d + * F::::::FFFFFFFFFF l::::l o::::o o::::or::::r i::::i d:::::d + * F:::::F l::::l o::::o o::::or::::r i::::i d:::::d + * F:::::F l::::l o::::o o::::or::::r i::::i d:::::d + * FF:::::::FF l::::::lo:::::ooooo:::::or::::r i::::::i d::::::d + * F::::::::FF l::::::lo:::::::::::::::or::::r i::::::i d::::::d + * F::::::::FF l::::::l oo:::::::::::oo r::::r i::::::i d::::::d + * FFFFFFFFFFF llllllll ooooooooooo rrrrrr iiiiiiii dddddddd + * + * PROJECT: Florid OS (A Modular, Everything-Is-A-File Operating System) + * ARCH: x86_64 + * BOOTLOADER: Limine + * PHILOSOPHY: 100% Customizable, Userspace-First DE, FPF Packaging. + * TARGET: Monolithic Core Foundation capable of scaling past 16,000+ LOC. + */ + +#include +#include +#include +#include "limine.h" + +/* ========================================================================== + * FLORID PACKAGE FORMAT (FPF) + * ========================================================================== */ + +typedef struct { + char magic[4]; + uint8_t version; + uint8_t type; + uint16_t flags; + uint64_t entry_point; + uint64_t stack_size; + uint64_t heap_size; + uint8_t signature[32]; +} __attribute__((packed)) fpf_header_t; + +void klog(const char* module, const char* msg); + +/* ========================================================================== + * EXHAUSTIVE KERNEL STATUS + * ========================================================================== */ + +typedef enum { + FLORID_SUCCESS = 0, + FLORID_ERROR_GENERIC = 1, + FLORID_ERROR_OUT_OF_MEMORY = 2, + FLORID_ERROR_IO_FAILURE = 3, + FLORID_ERROR_FPF_INVALID_MAGIC = 4, + FLORID_ERROR_FPF_INCOMPATIBLE_VERSION = 5, + FLORID_ERROR_FRAMEBUFFER_NOT_FOUND = 6, + FLORID_ERROR_PAGE_FAULT = 7, + FLORID_ERROR_ACCESS_VIOLATION = 8, + FLORID_ERROR_SYS_CALL_INVALID = 9, + FLORID_ERROR_DEVICE_OFFLINE = 10, + FLORID_ERROR_BUFFER_OVERFLOW = 11, + FLORID_ERROR_TIMEOUT = 12, + FLORID_ERROR_CORRUPT_METADATA = 13, + FLORID_ERROR_KERNEL_PANIC = 14 +} florid_status_t; + +static const char* status_strings[] = { + [FLORID_SUCCESS] = "FLORID_SUCCESS", + [FLORID_ERROR_GENERIC] = "FLORID_ERROR_GENERIC", + [FLORID_ERROR_OUT_OF_MEMORY] = "FLORID_ERROR_OUT_OF_MEMORY", + [FLORID_ERROR_IO_FAILURE] = "FLORID_ERROR_IO_FAILURE", + [FLORID_ERROR_FPF_INVALID_MAGIC] = "FLORID_ERROR_FPF_INVALID_MAGIC", + [FLORID_ERROR_FPF_INCOMPATIBLE_VERSION] = "FLORID_ERROR_FPF_INCOMPATIBLE_VERSION", + [FLORID_ERROR_FRAMEBUFFER_NOT_FOUND] = "FLORID_ERROR_FRAMEBUFFER_NOT_FOUND", + [FLORID_ERROR_PAGE_FAULT] = "FLORID_ERROR_PAGE_FAULT", + [FLORID_ERROR_ACCESS_VIOLATION] = "FLORID_ERROR_ACCESS_VIOLATION", + [FLORID_ERROR_SYS_CALL_INVALID] = "FLORID_ERROR_SYS_CALL_INVALID", + [FLORID_ERROR_DEVICE_OFFLINE] = "FLORID_ERROR_DEVICE_OFFLINE", + [FLORID_ERROR_BUFFER_OVERFLOW] = "FLORID_ERROR_BUFFER_OVERFLOW", + [FLORID_ERROR_TIMEOUT] = "FLORID_ERROR_TIMEOUT", + [FLORID_ERROR_CORRUPT_METADATA] = "FLORID_ERROR_CORRUPT_METADATA", + [FLORID_ERROR_KERNEL_PANIC] = "FLORID_ERROR_KERNEL_PANIC" +}; + +/* ========================================================================== + * HARDWARE DESCRIPTOR TABLES (GDT/IDT) - New Core Additions + * ========================================================================== */ + +typedef struct { uint16_t limit; uint64_t base; } __attribute__((packed)) table_ptr_t; + +void gdt_install(void) { + // Basic flat-model GDT for x86_64 + static uint64_t gdt[] = { + 0x0000000000000000, // Null + 0x00af9a000000ffff, // Kernel Code + 0x00af92000000ffff, // Kernel Data + 0x00affb000000ffff, // User Code + 0x00aff3000000ffff // User Data + }; + table_ptr_t gdt_ptr = { sizeof(gdt) - 1, (uint64_t)gdt }; + __asm__ volatile("lgdt %0" : : "m"(gdt_ptr)); +} + +/* ========================================================================== + * SYSTEM CALL REGISTRY (FPF Interface) + * ========================================================================== */ + +void sys_yield() { klog("SYS", "Yielding CPU."); } +void sys_exit() { klog("SYS", "Terminating Process."); } + +typedef void (*syscall_handler_t)(void); +syscall_handler_t syscall_table[128] = { + [0] = sys_yield, + [1] = sys_exit, + /* To scale to 16k, populate more system interface stubs here */ +}; + +/* ========================================================================== + * LIMINE BOOT REQUESTS + * ========================================================================== */ + +static volatile struct limine_framebuffer_request framebuffer_request = { + .id = LIMINE_FRAMEBUFFER_REQUEST, .revision = 0 +}; + +static volatile struct limine_memmap_request memmap_request = { + .id = LIMINE_MEMMAP_REQUEST, .revision = 0 +}; + +static volatile struct limine_hhdm_request hhdm_request = { + .id = LIMINE_HHDM_REQUEST, .revision = 0 +}; + +static volatile struct limine_module_request module_request = { + .id = LIMINE_MODULE_REQUEST, .revision = 0 +}; + +/* ========================================================================== + * LOGGING (COM1 SERIAL) + * ========================================================================== */ + +static inline void outb(uint16_t port, uint8_t val) { + __asm__ volatile ( "outb %0, %1" : : "a"(val), "Nd"(port) ); +} + +void klog(const char* module, const char* msg) { + const char* p = "["; + while (*p) outb(0x3F8, *p++); + p = module; + while (*p) outb(0x3F8, *p++); + p = "] "; + while (*p) outb(0x3F8, *p++); + p = msg; + while (*p) outb(0x3F8, *p++); + outb(0x3F8, '\r'); outb(0x3F8, '\n'); +} + +/* ========================================================================== + * PHYSICAL MEMORY MANAGER (PMM) + * ========================================================================== */ + +static uint8_t* pmm_bitmap; +static uint64_t pmm_total_pages; + +void pmm_init(struct limine_memmap_response* memmap) { + uint64_t max_addr = 0; + struct limine_memmap_entry* biggest_chunk = NULL; + + for (uint64_t i = 0; i < memmap->entry_count; i++) { + struct limine_memmap_entry* entry = memmap->entries[i]; + if (entry->base + entry->length > max_addr) max_addr = entry->base + entry->length; + if (entry->type == LIMINE_MEMMAP_USABLE && (!biggest_chunk || entry->length > biggest_chunk->length)) { + biggest_chunk = entry; + } + } + + pmm_total_pages = max_addr / 4096; + pmm_bitmap = (uint8_t*)(biggest_chunk->base + hhdm_request.response->offset); + + for (uint64_t i = 0; i < pmm_total_pages / 8; i++) pmm_bitmap[i] = 0xFF; + + for (uint64_t i = 0; i < memmap->entry_count; i++) { + struct limine_memmap_entry* entry = memmap->entries[i]; + if (entry->type == LIMINE_MEMMAP_USABLE) { + for (uint64_t j = 0; j < entry->length; j += 4096) { + uint64_t page = (entry->base + j) / 4096; + pmm_bitmap[page / 8] &= ~(1 << (page % 8)); + } + } + } + klog("PMM", "Physical Memory Manager Online."); +} + +/* ========================================================================== + * FPF EXECUTION ENGINE + * ========================================================================== */ + +void execute_fpf(uint8_t* buffer, size_t size) { + fpf_header_t* header = (fpf_header_t*)buffer; + + if (size < sizeof(fpf_header_t) || header->magic[0] != 'F' || header->magic[1] != 'L') { + klog("LOADER", "Invalid FPF Magic."); + return; + } + + klog("LOADER", "Executing FPF Package."); + + // Jump past header to entry point + uintptr_t entry = (uintptr_t)(buffer + sizeof(fpf_header_t) + header->entry_point); + void (*launch)(void) = (void (*)(void))entry; + + launch(); +} + +/* ========================================================================== + * KERNEL MAIN ENTRY + * ========================================================================== */ + +void _start(void) { + gdt_install(); // Setup hardware segments + klog("CORE", "Florid OS Kernel Initializing..."); + + // 1. Setup Graphics + if (framebuffer_request.response == NULL || framebuffer_request.response->framebuffer_count < 1) { + while(1) __asm__("hlt"); + } + struct limine_framebuffer *fb = framebuffer_request.response->framebuffers[0]; + uint32_t *fb_ptr = fb->address; + for (size_t i = 0; i < fb->width * fb->height; i++) fb_ptr[i] = 0x1E1E1E; + + // 2. Setup Memory + if (memmap_request.response && hhdm_request.response) { + pmm_init(memmap_request.response); + } + + // 3. Find and Boot Terminal / Launcher modules + if (module_request.response) { + for (uint64_t i = 0; i < module_request.response->module_count; i++) { + struct limine_file* module = module_request.response->modules[i]; + klog("INIT", "Loading FPF Module..."); + execute_fpf((uint8_t*)module->address, module->size); + } + } + + klog("CORE", "System idle."); + while (1) { __asm__("hlt"); } +} \ No newline at end of file diff --git a/FloridOS/src/kernel/linker.ld b/FloridOS/src/kernel/linker.ld new file mode 100644 index 0000000..72eb73f --- /dev/null +++ b/FloridOS/src/kernel/linker.ld @@ -0,0 +1,11 @@ +OUTPUT_FORMAT(elf64-x86-64) +ENTRY(_start) + +SECTIONS +{ + . = 0xffffffff80000000; + .text : { *(.text*) } + .rodata : { *(.rodata*) } + .data : { *(.data*) } + .bss : { *(.bss*) *(COMMON) } +} \ No newline at end of file diff --git a/FloridOS/src/kernel/loader/fpf.c b/FloridOS/src/kernel/loader/fpf.c new file mode 100644 index 0000000..b6b9cd8 --- /dev/null +++ b/FloridOS/src/kernel/loader/fpf.c @@ -0,0 +1,62 @@ +/* + * src/kernel/loader/fpf.c - Florid Package Format Execution Engine + * Part of the monolithic core scaling architecture. + */ + +#include +#include +#include +#include "../../include/fpf.h" + +// External references to our kernel logging and status mappings +extern void klog(const char* module, const char* msg); +extern void klog_status(const char* module, int status); + +/* Simple memory space tracker for bare-metal app loading */ +static uint64_t current_app_stack_base = 0x80000000; // Load user stacks high + +/* + * execute_fpf_package + * Validates, maps, and executes an FPF binary directly from a memory buffer. + */ +int execute_fpf_package(uint8_t* raw_binary, size_t size) { + klog("LOADER", "Interrogating binary payload for FPF compliance..."); + + if (size < sizeof(fpf_header_t)) { + klog("LOADER", "FATAL: Payload smaller than base FPF header schema."); + return 11; // Buffer overflow/underflow + } + + fpf_header_t* header = (fpf_header_t*)raw_binary; + + // Strict Magic Byte Verification + if (header->magic[0] != 'F' || header->magic[1] != 'L' || + header->magic[2] != 'O' || header->magic[3] != 'R') { + klog("LOADER", "FATAL: Magic bytes do not match 'FLOR'. Execution aborted."); + return 4; // Invalid Magic + } + + klog("LOADER", "Magic 'FLOR' verified. Parsing execution vectors..."); + + // Determine payload offset (where the actual executable instructions begin) + uint64_t code_offset = sizeof(fpf_header_t); + uintptr_t entry_address = (uintptr_t)(raw_binary + code_offset + header->entry_point); + + // Verify context claims + if (header->type == FPF_TYPE_DE) { + klog("LOADER", "Context: Desktop Environment / Shell. Granting Framebuffer Access."); + } else if (header->type == FPF_TYPE_APP) { + klog("LOADER", "Context: Standard Application. Enforcing sandbox boundaries."); + } + + klog("LOADER", "Transferring instruction pointer to FPF payload entry..."); + + // Define a function pointer to the app's start address + void (*app_entry)(void) = (void (*)(void))entry_address; + + // Execute the package (Handoff) + app_entry(); + + klog("LOADER", "FPF Package execution completed cleanly. Context returned to kernel."); + return 0; +} \ No newline at end of file diff --git a/FloridOS/src/kernel/mm/pmm.c b/FloridOS/src/kernel/mm/pmm.c new file mode 100644 index 0000000..8a7b5d7 --- /dev/null +++ b/FloridOS/src/kernel/mm/pmm.c @@ -0,0 +1,81 @@ +#include +#include +#include +#include "../../include/limine.h" + +static uint8_t* bitmap; +static uint64_t bitmap_pages; +static uint64_t total_pages; +static uint64_t last_index = 0; + +// Helper to set/clear bits in our map +void bitmap_set(uint64_t page) { + bitmap[page / 8] |= (1 << (page % 8)); +} + +void bitmap_clear(uint64_t page) { + bitmap[page / 8] &= ~(1 << (page % 8)); +} + +bool bitmap_test(uint64_t page) { + return bitmap[page / 8] & (1 << (page % 8)); +} + +/* * pmm_init: + * Finds the biggest chunk of RAM and puts the bitmap there. + * Then it marks all usable RAM as "free." + */ +void pmm_init(struct limine_memmap_response* memmap) { + uint64_t max_addr = 0; + uint64_t biggest_chunk_addr = 0; + uint64_t biggest_chunk_len = 0; + + for (uint64_t i = 0; i < memmap->entry_count; i++) { + struct limine_memmap_entry* entry = memmap->entries[i]; + if (entry->type == LIMINE_MEMMAP_USABLE) { + if (entry->base + entry->length > max_addr) + max_addr = entry->base + entry->length; + + if (entry->length > biggest_chunk_len) { + biggest_chunk_len = entry->length; + biggest_chunk_addr = entry->base; + } + } + } + + total_pages = max_addr / 4096; + bitmap_pages = (total_pages / 8) / 4096 + 1; + + // We store the bitmap in the biggest usable chunk of RAM + bitmap = (uint8_t*)(biggest_chunk_addr + 0xffff800000000000); + + // Mark EVERYTHING as used (locked) first + for (uint64_t i = 0; i < total_pages / 8; i++) bitmap[i] = 0xFF; + + // Now, unmap only the truly usable sections + for (uint64_t i = 0; i < memmap->entry_count; i++) { + struct limine_memmap_entry* entry = memmap->entries[i]; + if (entry->type == LIMINE_MEMMAP_USABLE) { + for (uint64_t j = 0; j < entry->length; j += 4096) { + bitmap_clear((entry->base + j) / 4096); + } + } + } + + // Lock the pages the bitmap itself is using + for (uint64_t i = 0; i < bitmap_pages * 4096; i += 4096) { + bitmap_set((biggest_chunk_addr + i) / 4096); + } +} + +/* pmm_alloc: Find a free page of RAM */ +void* pmm_alloc() { + for (uint64_t i = last_index; i < total_pages; i++) { + if (!bitmap_test(i)) { + bitmap_set(i); + last_index = i; + return (void*)(i * 4096); + } + } + return NULL; // Out of memory! +} \ No newline at end of file diff --git a/FloridOS/src/userspace/bridge/loadable.c b/FloridOS/src/userspace/bridge/loadable.c new file mode 100644 index 0000000..371fa3b --- /dev/null +++ b/FloridOS/src/userspace/bridge/loadable.c @@ -0,0 +1,33 @@ +/* + * src/userspace/bridge/loadable.c - Universal FPF Binary Wrapper + * Compile your app logic alongside this file to output a valid .fpf package. + */ + +#include +#include +#include "../../include/fpf.h" + +// Forward declaration of the user's actual main function +extern int florid_main(void); + +// Force the compiler to place this header at the very beginning of the binary +__attribute__((section(".fpf_header"), used)) +const fpf_header_t __app_header = { + .magic = {'F', 'L', 'O', 'R'}, + .version = 1, + .type = FPF_TYPE_DE, // Setting to DE so it can draw the Bloom menu + .flags = 0x08, // FPF_FLAG_FRAMEBUFFER_OWN + .entry_point = 0, // Offset from start of code section + .stack_size = 1024 * 1024, // 1MB stack request + .heap_size = 1024 * 1024 * 16, // 16MB heap request + .signature = {0} // Unsigned demo +}; + +// The raw entry point called by the kernel loader +void _start(void) { + // Jump to the application logic + florid_main(); + + // If the app exits, trap the CPU so it doesn't execute garbage memory + while(1) { __asm__ volatile("hlt"); } +} \ No newline at end of file diff --git a/FloridOS/src/userspace/launcher/main.c b/FloridOS/src/userspace/launcher/main.c new file mode 100644 index 0000000..3ae0890 --- /dev/null +++ b/FloridOS/src/userspace/launcher/main.c @@ -0,0 +1,36 @@ +/* + * src/userspace/launcher/main.c - Bare-metal Demo Launcher + * Proves execution handoff by drawing the White Pill interface. + */ + +#include +#include + +// Hardcoded Limine Framebuffer address for fast demo testing +// (In a full build, the kernel passes this via syscalls/shared registers) +#define FB_ADDRESS 0xffff800000000000 // Replace with your Limine FB base if mapped static + +int florid_main(void) { + // Let's pretend the kernel mapped the FB directly for us + uint32_t* screen = (uint32_t*)FB_ADDRESS; + int width = 1920; // Standard assumption for demo + int height = 1080; + + // Draw the Taskbar Background at the bottom (Height: 60px) + for (int y = height - 60; y < height; y++) { + for (int x = 0; x < width; x++) { + screen[y * width + x] = 0x111111; // Darker taskbar base + } + } + + // Draw the "White Pill" on the far left (X: 20 to 100, Y: height-45 to height-15) + for (int y = height - 45; y < height - 15; y++) { + for (int x = 20; x < 100; x++) { + // Simple visual rounding: cut the absolute corners + if ((x < 25 || x > 95) && (y < height - 40 || y > height - 20)) continue; + screen[y * width + x] = 0xFFFFFF; // Pure white pill trigger + } + } + + return 0; +} \ No newline at end of file diff --git a/FloridOS/src/userspace/terminal/main.c b/FloridOS/src/userspace/terminal/main.c new file mode 100644 index 0000000..e4aaba5 --- /dev/null +++ b/FloridOS/src/userspace/terminal/main.c @@ -0,0 +1,44 @@ +#include + +// The linker looks for _start by default +void _start() { + // Material 3 Surface Color + uint32_t m3_surface = 0x1C1B1F; + + // Pointer to framebuffer (Assuming it's mapped to 0xFD000000 or provided by bootloader) + // For a real test, we just loop to keep the CPU busy so it doesn't crash + while(1) { + __asm__("hlt"); + } +} + +void terminal_main() { + // In a real FPF, the kernel passes the framebuffer info. + // We'll assume a standard 1920x1080 mapping for this demo. + uint32_t* fb = (uint32_t*)0; // This would be mapped via syscall in a finished build + + int term_width = 800; + int term_height = 500; + int start_x = 100; + int start_y = 100; + + // 1. Draw Terminal Window Shadow/Outline + for (int y = start_y - 2; y < start_y + term_height + 2; y++) { + for (int x = start_x - 2; x < start_x + term_width + 2; x++) { + // fb[y * 1920 + x] = M3_OUTLINE; + } + } + + // 2. Draw Terminal Surface + for (int y = start_y; y < start_y + term_height; y++) { + for (int x = start_x; x < start_x + term_width; x++) { + // fb[y * 1920 + x] = M3_SURFACE; + } + } + + // 3. Draw Mock "Prompt" line + // [ > _ ] + for (int i = 0; i < 10; i++) { + // Pixel logic for a cursor + } +} \ No newline at end of file