serive,webclient,cli: Crash fix USB; partial CLI rework; reworked USB gadget deployment

This commit is contained in:
MaMe82 2018-11-20 15:24:40 +01:00
parent 8fbcd7f2b9
commit 8200b5810d
24 changed files with 617 additions and 825 deletions

View File

@ -94,4 +94,6 @@ func init() {
cmdDBBackup.Flags().StringVarP(&tmpDBBackupName, "name", "n", "","Name of backup")
cmdDBRestore.Flags().StringVarP(&tmpDBBackupName, "name", "n", "","Name of backup")
cmdDBList.Flags().BoolVar(&BoolJson, "json", false, "Output results as JSON if applicable")
}

View File

@ -2,6 +2,7 @@ package cli_client
import (
"github.com/spf13/cobra"
"os"
pb "github.com/mame82/P4wnP1_go/proto"
"fmt"
@ -12,35 +13,25 @@ var blink_count uint32
// usbCmd represents the usb command
var ledCmd = &cobra.Command{
Use: "LED",
Use: "led",
Short: "Set or Get LED state of P4wnP1",
}
var ledGetCmd = &cobra.Command{
Use: "get",
Short: "Get LED blink count",
Run: func(cmd *cobra.Command, args []string) {
if ls, err := ClientGetLED(StrRemoteHost, StrRemotePort); err == nil {
fmt.Printf("LED blink count %v\n", ls.BlinkCount)
} else {
log.Println(err)
}
},
}
var ledSetCmd = &cobra.Command{
Use: "set",
Short: "Set LED blink count",
Run: func(cmd *cobra.Command, args []string) {
blink := cmd.Flags().Lookup("blink")
if blink.Changed {
if cmd.Flags().Lookup("blink").Changed {
// blink flag has been set
if err := ClientSetLED(StrRemoteHost, StrRemotePort, pb.LEDSettings{BlinkCount: blink_count}); err == nil {
fmt.Printf("LED blink count set to %v\n", blink.Value)
fmt.Printf("LED blink count set to %v\n", blink_count)
} else {
log.Println(err)
os.Exit(-1)
}
} else {
cmd.Usage()
// blink flag has not been set, retrieve current blink count
if ls, err := ClientGetLED(StrRemoteHost, StrRemotePort); err == nil {
fmt.Printf("LED blink count %v\n", ls.BlinkCount)
} else {
log.Println(err)
os.Exit(-1)
}
}
},
}
@ -48,8 +39,6 @@ var ledSetCmd = &cobra.Command{
func init() {
rootCmd.AddCommand(ledCmd)
ledCmd.AddCommand(ledGetCmd)
ledCmd.AddCommand(ledSetCmd)
ledSetCmd.Flags().Uint32VarP(&blink_count,"blink", "b", 0,"Set blink count (0: Off, 1..254: blink n times, >254: On)")
ledCmd.Flags().Uint32VarP(&blink_count,"blink", "b", 0,"Set blink count (0: Off, 1..254: blink n times, >254: On)")
}

View File

@ -11,6 +11,7 @@ import (
var (
StrRemoteHost string
StrRemotePort string
BoolJson bool
)
@ -45,7 +46,6 @@ func Execute() {
func init() {
rootCmd.PersistentFlags().StringVar(&StrRemoteHost, "host", "localhost", "The host with the listening P4wnP1 RPC server")
rootCmd.PersistentFlags().StringVar(&StrRemotePort, "port", "50051", "The port on which the P4wnP1 RPC server is listening")
rootCmd.PersistentFlags().BoolVar(&BoolJson, "json", false, "Output results as JSON if applicable")
/*
// Cobra also supports local flags, which will only run

51
cli_client/cmd_system.go Normal file
View File

@ -0,0 +1,51 @@
package cli_client
import (
"fmt"
"github.com/spf13/cobra"
"os"
)
func init() {
cmdSystem := &cobra.Command{
Use: "system",
Short: "system commands",
}
cmdSystemReboot := &cobra.Command{
Use: "reboot",
Short: "reboot P4wnP1",
Run: func(cmd *cobra.Command, args []string) {
err := ClientReboot(StrRemoteHost, StrRemotePort, TIMEOUT_LONG)
if err != nil {
fmt.Println(" failed")
fmt.Println(err.Error())
os.Exit(-1)
}
fmt.Println(" success")
},
}
cmdSystemShutdown := &cobra.Command{
Use: "shutdown",
Short: "shutdown P4wnP1",
Run: func(cmd *cobra.Command, args []string) {
err := ClientReboot(StrRemoteHost, StrRemotePort, TIMEOUT_LONG)
if err != nil {
fmt.Println(" failed")
fmt.Println(err.Error())
os.Exit(-1)
}
fmt.Println(" success")
},
}
rootCmd.AddCommand(cmdSystem)
cmdSystem.AddCommand(cmdSystemReboot, cmdSystemShutdown)
}

View File

@ -1,249 +0,0 @@
package cli_client
import (
"fmt"
"github.com/spf13/cobra"
"log"
"github.com/davecgh/go-spew/spew"
"google.golang.org/grpc/status"
)
//Empty settings used to store cobra flags
var (
//tmpGadgetSettings = pb.GadgetSettings{CdcEcmSettings:&pb.GadgetSettingsEthernet{},RndisSettings:&pb.GadgetSettingsEthernet{}}
tmpNoAutoDeploy = false
tmpDisableGadget bool = false
tmpUseHIDKeyboard uint8 = 0
tmpUseHIDMouse uint8 = 0
tmpUseHIDRaw uint8 = 0
tmpUseRNDIS uint8 = 0
tmpUseECM uint8 = 0
tmpUseSerial uint8 = 0
tmpUseUMS uint8 = 0
tmpUMSFile string = ""
tmpUMSCdromMode bool = false
)
func init(){
//Configure spew for struct deep printing (disable using printer interface for gRPC structs)
spew.Config.Indent="\t"
spew.Config.DisableMethods = true
spew.Config.DisablePointerAddresses = true
}
// usbCmd represents the usb command
var usbCmd = &cobra.Command{
Use: "USB",
Short: "Set, get or deploy USB Gadget settings",
}
var usbGetCmd = &cobra.Command{
Use: "get",
Short: "Get USB Gadget settings",
Long: ``,
Run: cobraUsbGet,
}
var usbGetDeployedCmd = &cobra.Command{
Use: "deployed",
Short: "Get deployed USB Gadget settings (the currently running configuration for the kernel module)",
Long: ``,
Run: cobraUsbGetDeployed,
}
var usbSetDeployeCmd = &cobra.Command{
Use: "deploy",
Short: "Deployed the USB Gadget settings (as running configuration for the kernel module)",
Long: ``,
Run: cobraUsbDeploySettings,
}
var usbSetCmd = &cobra.Command{
Use: "set",
Short: "set USB Gadget settings",
Long: ``,
Run: cobraUsbSet,
}
func cobraUsbSet(cmd *cobra.Command, args []string) {
gs, err := ClientGetGadgetSettings(StrRemoteHost, StrRemotePort)
if err != nil {
log.Println(err)
return
}
fmt.Printf("Old USB Gadget Settings:\n%s", spew.Sdump(gs))
if tmpDisableGadget {
fmt.Println("Setting gadget to disabled (won't get bound to UDC after deployment)")
gs.Enabled = false
} else {
fmt.Println("Setting gadget to enabled (will be usable after deployment)")
gs.Enabled = true
}
if (cmd.Flags().Lookup("rndis").Changed) {
if tmpUseRNDIS == 0 {
fmt.Println("Disabeling RNDIS")
gs.Use_RNDIS = false
} else {
fmt.Println("Enabeling RNDIS")
gs.Use_RNDIS = true
}
}
if (cmd.Flags().Lookup("cdc-ecm").Changed) {
if tmpUseECM == 0 {
fmt.Println("Disabeling CDC ECM")
gs.Use_CDC_ECM = false
} else {
fmt.Println("Enabeling CDC ECM")
gs.Use_CDC_ECM = true
}
}
if (cmd.Flags().Lookup("serial").Changed) {
if tmpUseSerial == 0 {
fmt.Println("Disabeling Serial")
gs.Use_SERIAL = false
} else {
fmt.Println("Enabeling Serial")
gs.Use_SERIAL = true
}
}
if (cmd.Flags().Lookup("hid-keyboard").Changed) {
if tmpUseHIDKeyboard == 0 {
fmt.Println("Disabeling HID keyboard")
gs.Use_HID_KEYBOARD = false
} else {
fmt.Println("Enabeling HID keyboard")
gs.Use_HID_KEYBOARD = true
}
}
if (cmd.Flags().Lookup("hid-mouse").Changed) {
if tmpUseHIDMouse == 0 {
fmt.Println("Disabeling HID mouse")
gs.Use_HID_MOUSE = false
} else {
fmt.Println("Enabeling HID mouse")
gs.Use_HID_MOUSE = true
}
}
if (cmd.Flags().Lookup("hid-raw").Changed) {
if tmpUseHIDRaw == 0 {
fmt.Println("Disabeling HID raw device")
gs.Use_HID_RAW = false
} else {
fmt.Println("Enabeling HID raw device")
gs.Use_HID_RAW = true
}
}
if (cmd.Flags().Lookup("ums").Changed) {
if tmpUseUMS == 0 {
fmt.Println("Disabeling USB Mass Storage")
gs.Use_UMS = false
} else {
fmt.Println("Enabeling USB Mass Storage")
gs.Use_UMS = true
gs.UmsSettings.Cdrom = tmpUMSCdromMode
if tmpUMSCdromMode {
fmt.Println("Setting USB Mass Storage to CD-Rom mode")
} else {
fmt.Println("Setting USB Mass Storage to flash drive mode")
}
if cmd.Flags().Lookup("ums-file").Changed {
fmt.Printf("Serving USB Mass Storage from '%s'\n", tmpUMSFile)
gs.UmsSettings.File = tmpUMSFile
}
}
}
//Try to set the change config
err = ClientSetGadgetSettings(StrRemoteHost, StrRemotePort, *gs)
if err != nil {
//ToDo: Adopt parsing of Error Message to other gRPC calls
log.Printf("Error setting new gadget settings: %v\n", status.Convert(err).Message())
return
}
gs, err = ClientGetGadgetSettings(StrRemoteHost, StrRemotePort)
if err != nil {
log.Println(err)
return
}
fmt.Printf("New USB Gadget Settings:\n%s", spew.Sdump(gs))
//if "auto deploy" isn't disabled, we deploy the gadget immediately to ConfigFS
if !tmpNoAutoDeploy {
fmt.Println("Auto-deploy the new settings...")
if gs, err := ClientDeployGadgetSettings(StrRemoteHost, StrRemotePort); err != nil {
fmt.Printf("Error deploying Gadget Settings: %v\nReverted to:\n%s", err, spew.Sdump(gs))
} else {
fmt.Printf("Successfully deployed:\n%s", spew.Sdump(gs))
}
}
return
}
func cobraUsbGet(cmd *cobra.Command, args []string) {
if gs, err := ClientGetGadgetSettings(StrRemoteHost, StrRemotePort); err == nil {
fmt.Printf("USB Gadget Settings:\n%s", spew.Sdump(gs))
} else {
log.Println(err)
}
}
func cobraUsbDeploySettings(cmd *cobra.Command, args []string) {
if gs, err := ClientDeployGadgetSettings(StrRemoteHost, StrRemotePort); err != nil {
fmt.Printf("Error deploying Gadget Settings: %v\nReverted to:\n%s", err, spew.Sdump(gs))
} else {
fmt.Printf("Successfully deployed:\n%s", spew.Sdump(gs))
}
}
func cobraUsbGetDeployed(cmd *cobra.Command, args []string) {
if gs, err := ClientGetDeployedGadgetSettings(StrRemoteHost, StrRemotePort); err == nil {
fmt.Printf("Deployed USB Gadget Settings:\n%s", spew.Sdump(gs))
} else {
log.Println(err)
}
}
func init() {
// rootCmd.AddCommand(usbCmd)
usbCmd.AddCommand(usbGetCmd)
usbCmd.AddCommand(usbSetCmd)
usbGetCmd.AddCommand(usbGetDeployedCmd)
usbSetCmd.AddCommand(usbSetDeployeCmd)
usbSetCmd.Flags().BoolVarP(&tmpNoAutoDeploy, "no-deploy","n", false, "If this flag is set, the gadget isn't deployed automatically (allows further changes before deployment)")
usbSetCmd.Flags().BoolVarP(&tmpDisableGadget, "disabled","d", false, "If this flag is set, the gadget stays inactive after deployment (not bound to UDC)")
usbSetCmd.Flags().Uint8VarP(&tmpUseRNDIS, "rndis", "r",0,"Use the RNDIS gadget function (0: disable, 1..n: enable)")
usbSetCmd.Flags().Uint8VarP(&tmpUseECM, "cdc-ecm", "e",0,"Use the CDC ECM gadget function (0: disable, 1..n: enable)")
usbSetCmd.Flags().Uint8VarP(&tmpUseSerial, "serial", "s",0,"Use the SERIAL gadget function (0: disable, 1..n: enable)")
usbSetCmd.Flags().Uint8VarP(&tmpUseHIDKeyboard, "hid-keyboard", "k",0,"Use the HID KEYBOARD gadget function (0: disable, 1..n: enable)")
usbSetCmd.Flags().Uint8VarP(&tmpUseHIDMouse, "hid-mouse", "m",0,"Use the HID MOUSE gadget function (0: disable, 1..n: enable)")
usbSetCmd.Flags().Uint8VarP(&tmpUseHIDRaw, "hid-raw", "g",0,"Use the HID RAW gadget function (0: disable, 1..n: enable)")
usbSetCmd.Flags().Uint8VarP(&tmpUseUMS, "ums", "u",0,"Use the USB Mass Storage gadget function (0: disable, 1..n: enable)")
usbSetCmd.Flags().BoolVar(&tmpUMSCdromMode, "ums-cdrom", false, "If this flag is set, UMS emulates a CD-Rom instead of a flashdrive (ignored, if UMS disabled)")
usbSetCmd.Flags().StringVar(&tmpUMSFile, "ums-file", "", "Path to the image or block device backing UMS (ignored, if UMS disabled)")
}

View File

@ -3,12 +3,10 @@ package cli_client
import (
"encoding/json"
"fmt"
"github.com/davecgh/go-spew/spew"
pb "github.com/mame82/P4wnP1_go/proto"
"github.com/spf13/cobra"
"google.golang.org/grpc/status"
"log"
"os"
pb "github.com/mame82/P4wnP1_go/proto"
)
type devPath int
@ -37,6 +35,8 @@ var (
tmpUsbPid = "0x1347"
tmpUsbManufacturer = "MaMe82"
tmpUsbProduct = "P4wnP1 by MaMe82"
)
@ -79,85 +79,84 @@ func PrintGadgetSettings(gs *pb.GadgetSettings, useJson bool) {
}
func usbSet(cmd *cobra.Command, args []string) {
gs, err := ClientGetGadgetSettings(StrRemoteHost, StrRemotePort)
newGs, err := ClientGetDeployedGadgetSettings(StrRemoteHost, StrRemotePort)
if err != nil {
log.Println(err)
return
}
gs.Pid = tmpUsbPid
gs.Vid = tmpUsbVid
gs.Product = tmpUsbProduct
gs.Manufacturer = tmpUsbManufacturer
gs.Serial = tmpUsbSerialnumber
gs.Enabled = !tmpUsbDisableGadget
gs.Use_RNDIS = tmpUsbUseRNDIS
gs.Use_CDC_ECM = tmpUsbUseECM
gs.Use_SERIAL = tmpUsbUseSerial
gs.Use_HID_KEYBOARD = tmpUsbUseHIDKeyboard
gs.Use_HID_MOUSE = tmpUsbUseHIDMouse
gs.Use_HID_RAW = tmpUsbUseHIDRaw
gs.Use_UMS = tmpUsbUseUMS
fPid := cmd.Flags().Lookup("pid")
fVid := cmd.Flags().Lookup("vid")
fProduct := cmd.Flags().Lookup("product")
fManufacturer := cmd.Flags().Lookup("manufacturer")
fSerialno := cmd.Flags().Lookup("sn")
if fVid.Changed {
newGs.Vid = tmpUsbVid
}
if fPid.Changed {
newGs.Pid = tmpUsbPid
}
if fManufacturer.Changed {
newGs.Manufacturer = tmpUsbManufacturer
}
if fProduct.Changed {
newGs.Product = tmpUsbProduct
}
if fSerialno.Changed {
newGs.Serial = tmpUsbSerialnumber
}
newGs.Enabled = !tmpUsbDisableGadget
newGs.Use_RNDIS = tmpUsbUseRNDIS
newGs.Use_CDC_ECM = tmpUsbUseECM
newGs.Use_SERIAL = tmpUsbUseSerial
newGs.Use_HID_KEYBOARD = tmpUsbUseHIDKeyboard
newGs.Use_HID_MOUSE = tmpUsbUseHIDMouse
newGs.Use_HID_RAW = tmpUsbUseHIDRaw
newGs.Use_UMS = tmpUsbUseUMS
if tmpUsbUseUMS {
gs.UmsSettings.Cdrom = tmpUsbUMSCdromMode
newGs.UmsSettings.Cdrom = tmpUsbUMSCdromMode
if cmd.Flags().Lookup("ums-file").Changed {
fmt.Printf("Serving USB Mass Storage from '%s'\n", tmpUMSFile)
gs.UmsSettings.File = tmpUMSFile
fmt.Printf("Serving USB Mass Storage from '%s'\n", tmpUsbUMSFile)
newGs.UmsSettings.File = tmpUsbUMSFile
}
}
//Update service settings
err = ClientSetGadgetSettings(StrRemoteHost, StrRemotePort, *gs)
deployedGs,err := ClientDeployGadgetSettings(StrRemoteHost, StrRemotePort, newGs)
if err != nil {
fmt.Printf("Error setting new gadget settings: %v\n", status.Convert(err).Message())
fmt.Printf("Error deploying Gadget Settings: %v\nReverted to:\n%+v", err, deployedGs)
os.Exit(-1)
return
}
//deploy updated settings and fetch result (effectively deployed settings)
if gs, err := ClientDeployGadgetSettings(StrRemoteHost, StrRemotePort); err != nil {
fmt.Printf("Error deploying Gadget Settings: %v\nReverted to:\n%s", err, spew.Sdump(gs))
os.Exit(-1)
}
if BoolJson {
PrintGadgetSettings(gs,true)
PrintGadgetSettings(deployedGs,true)
} else {
fmt.Println("Successfully deployed USB gadget settings")
PrintGadgetSettings(gs,false)
PrintGadgetSettings(deployedGs,false)
}
return
}
func usbMount(cmd *cobra.Command, args []string) {
gs, err := ClientGetGadgetSettings(StrRemoteHost, StrRemotePort)
gs, err := ClientGetDeployedGadgetSettings(StrRemoteHost, StrRemotePort)
if err != nil {
log.Println(err)
return
}
/*
gs.Pid = tmpUsbPid
gs.Vid = tmpUsbVid
gs.Product = tmpUsbProduct
gs.Manufacturer = tmpUsbManufacturer
gs.Serial = tmpUsbSerialnumber
gs.Enabled = !tmpUsbDisableGadget
gs.Use_RNDIS = tmpUsbUseRNDIS
gs.Use_CDC_ECM = tmpUsbUseECM
gs.Use_SERIAL = tmpUsbUseSerial
gs.Use_HID_KEYBOARD = tmpUsbUseHIDKeyboard
gs.Use_HID_MOUSE = tmpUsbUseHIDMouse
gs.Use_HID_RAW = tmpUsbUseHIDRaw
gs.Use_UMS = tmpUsbUseUMS
*/
if gs.Use_UMS {
//gs.UmsSettings.Cdrom = tmpUsbUMSCdromMode
if cmd.Flags().Lookup("ums-file").Changed {
fmt.Printf("Serving USB Mass Storage from '%s'\n", tmpUMSFile)
fmt.Printf("Serving USB Mass Storage from '%s'\n", tmpUsbUMSFile)
//gs.UmsSettings.File = tmpUMSFile
ClientMountUMSImage(StrRemoteHost, StrRemotePort, tmpUsbUMSFile, tmpUsbUMSCdromMode)
}
@ -171,7 +170,7 @@ func usbMount(cmd *cobra.Command, args []string) {
}
func usbGet(cmd *cobra.Command, args []string) {
if gs, err := ClientGetGadgetSettings(StrRemoteHost, StrRemotePort); err == nil {
if gs, err := ClientGetDeployedGadgetSettings(StrRemoteHost, StrRemotePort); err == nil {
if BoolJson {
PrintGadgetSettings(gs,true)
} else {
@ -335,4 +334,6 @@ func init() {
cmdUsbMount.Flags().BoolVar(&tmpUsbUMSCdromMode, "ums-cdrom", false, "If this flag is set, UMS emulates a CD-Rom instead of a flashdrive (ignored, if UMS disabled)")
cmdUsbMount.Flags().StringVar(&tmpUsbUMSFile, "ums-file", "", "Path to the image or block device backing UMS (ignored, if UMS disabled)")
cmdUsb.PersistentFlags().BoolVar(&BoolJson, "json", false, "Output results as JSON if applicable")
}

View File

@ -108,17 +108,6 @@ func clientCreateTempDirOfFile(host string, port string, dir string, prefix stri
return
}
/*
func ClientUploadFileFromSrcPath(host string, port string, srcPath string, destPath string, forceOverwrite bool) (err error) {
//open local file for reading
flag := os.O_RDONLY
f, err := os.OpenFile(srcPath, flag, os.ModePerm)
if err != nil { return err }
defer f.Close()
return ClientUploadFile(host,port,f,destPath,forceOverwrite)
}
*/
func ClientRegisterEvent(host string, port string, evtType int64) (err error) {
// open gRPC Client
@ -205,28 +194,51 @@ func ClientGetLED(host string, port string) (ls *pb.LEDSettings, err error) {
return
}
func ClientGetGadgetSettings(host string, port string) (gs *pb.GadgetSettings, err error) {
conn, client, ctx, cancel, err := ClientConnectServer(host, port)
defer conn.Close()
defer cancel()
if err != nil { return }
func ClientReboot(host string, port string, timeout time.Duration) (err error) {
address := host + ":" + port
connection, err := grpc.Dial(address, grpc.WithInsecure())
if err != nil { log.Fatalf("Could not connect to P4wnP1 RPC server: %v", err) }
defer connection.Close()
gs, err = client.GetGadgetSettings(ctx, &pb.Empty{})
if err != nil {
log.Printf("Error getting USB Gadget Settings: %+v", err)
rpcClient := pb.NewP4WNP1Client(connection)
ctx := context.Background()
if timeout > 0 {
ctxNew,cancel := context.WithTimeout(ctx, timeout)
ctx = ctxNew
defer cancel()
}
_,err = rpcClient.Reboot(ctx, &pb.Empty{})
return
}
func ClientDeployGadgetSettings(host string, port string) (gs *pb.GadgetSettings, err error) {
func ClientShutdown(host string, port string, timeout time.Duration) (err error) {
address := host + ":" + port
connection, err := grpc.Dial(address, grpc.WithInsecure())
if err != nil { log.Fatalf("Could not connect to P4wnP1 RPC server: %v", err) }
defer connection.Close()
rpcClient := pb.NewP4WNP1Client(connection)
ctx := context.Background()
if timeout > 0 {
ctxNew,cancel := context.WithTimeout(ctx, timeout)
ctx = ctxNew
defer cancel()
}
_,err = rpcClient.Shutdown(ctx, &pb.Empty{})
return
}
func ClientDeployGadgetSettings(host string, port string, newGs *pb.GadgetSettings) (gs *pb.GadgetSettings, err error) {
conn, client, ctx, cancel, err := ClientConnectServer(host, port)
defer conn.Close()
defer cancel()
if err != nil { return }
gs, err = client.DeployGadgetSetting(ctx, &pb.Empty{})
gs, err = client.DeployGadgetSetting(ctx, newGs)
if err != nil {
log.Printf("Error deploying current USB Gadget Settings: %+v", err)
//We have an error case, thus gs isn't submitted by the gRPC server (even if the value is provided)
@ -252,23 +264,6 @@ func ClientGetDeployedGadgetSettings(host string, port string) (gs *pb.GadgetSet
return
}
func ClientSetGadgetSettings(host string, port string, gs pb.GadgetSettings) (err error) {
conn, client, ctx, cancel, err := ClientConnectServer(host, port)
defer conn.Close()
defer cancel()
if err != nil { return }
_, err = client.SetGadgetSettings(ctx, &gs)
//Only forward the error
/*
if err != nil {
log.Printf("Error setting GadgetSettings %d: %+v", gs, err)
}
*/
return
}
func ClientSetLED(host string, port string, ls pb.LEDSettings) (err error) {
conn, client, ctx, cancel, err := ClientConnectServer(host, port)
defer conn.Close()

13
dist/scripts/serial-teminal.sh vendored Normal file
View File

@ -0,0 +1,13 @@
#!/bin/bash
echo "$TRIGGER"
if [ "$TRIGGER" = "TRIGGER_USB_GADGET_CONNECTED" ]; then
echo "USB gadget connected, starting terminal for ttyGS0"
# start systemd service unit, which spwans agetty for ttyGS0 if needed
service serial-getty@ttyGS0 start
fi
if [ "$TRIGGER" = "TRIGGER_USB_GADGET_DISCONNECTED" ]; then
echo "USB gadget disconnected, stopping terminal for ttyGS0"
# stop systemd service unit, which spwans agetty for ttyGS0
service serial-getty@ttyGS0 stop
fi

View File

@ -1,7 +1,11 @@
#!/bin/bash
# Enable USB functions RNDIS, CDC ECM (don't disable other functions which already have been enabled)
P4wnP1_cli usb set --rndis 1 --cdc-ecm 1
# fallback script, called in case the configured 'Startup Master Template' fails
# the script uses the CLI client to do basic configuration and make P4wnP1 reachable
# Additionally it serves as example on how to use the CLI client to configure P4wnP1 A.L.O.A.
# Enable USB functions RNDIS, CDC ECM
P4wnP1_cli usb set --vid 0x1d6c --pid 0x1347 --manufacturer "MaMe82" --sn "deadbeef1337" --product "P4wnP1 by MaMe82" --rndis --cdc-ecm
# Configure USB ethernet interface "usbeth" to run a DHCP server
# - use IPv4 172.16.0.1 for interface with netmask 255.255.255.252
@ -22,4 +26,4 @@ P4wnP1_cli WIFI set ap -r US -c 6 -s "💥🖥💥 Ⓟ➃ⓌⓃ🅟❶" -k "MaMe
# - add a DHCP range from 172.24.0.10 to 172.24.0.20 with a lease time of 5 minutes
P4wnP1_cli NET set server -i wlan0 -a 172.24.0.1 -m 255.255.255.0 -o "3:" -o "6:" -r "172.24.0.10|172.24.0.20|5m"
P4wnP1_cli LED set -b 5
P4wnP1_cli led -b 2

3
dist/scripts/startup.sh vendored Normal file
View File

@ -0,0 +1,3 @@
#!/bin/bash
P4wnP1_cli led -b 1

57
dist/scripts/trigger-aware.sh vendored Executable file
View File

@ -0,0 +1,57 @@
#!/bin/bash
if [ "$TRIGGER" = "" ]; then
echo "Script not called from TriggerAction"
exit
fi
if [ "$TRIGGER" = "TRIGGER_SERVICE_STARTED" ]; then
echo "Script called from service started"
fi
if [ "$TRIGGER" = "TRIGGER_USB_GADGET_CONNECTED" ]; then
echo "Script called from Trigger USB gadget connected"
fi
if [ "$TRIGGER" = "TRIGGER_USB_GADGET_DISCONNECTED" ]; then
echo "Script called from Trigger USB gadget disconnected"
fi
if [ "$TRIGGER" = "TRIGGER_WIFI_AP_STARTED" ]; then
echo "Script called from Trigger WiFi Access Point started"
fi
if [ "$TRIGGER" = "TRIGGER_WIFI_CONNECTED_AS_STA" ]; then
echo "Script called from Trigger Connected to existing WiFi"
fi
if [ "$TRIGGER" = "TRIGGER_SSH_LOGIN" ]; then
echo "Script called from Trigger SSH login for user: $SSH_LOGIN_USER"
fi
if [ "$TRIGGER" = "TRIGGER_DHCP_LEASE_GRANTED" ]; then
echo "Script called from Trigger DHCP lease granted"
echo "\tInterface: $DHCP_LEASE_IFACE"
echo "\tMac: $DHCP_LEASE_MAC"
echo "\tIP: $DHCP_LEASE_IP"
echo "\tHost: $DHCP_LEASE_HOST"
fi
if [ "$TRIGGER" = "TRIGGER_GROUP_RECEIVE" ]; then
echo "Script called from Trigger Received value on group channel"
echo "\tGroup: $GROUP"
echo "\tValue: $VALUE"
fi
if [ "$TRIGGER" = "TRIGGER_GROUP_RECEIVE_MULTI" ]; then
echo "Script called from Trigger Received multiple values on group channel"
echo "\tGroup: $GROUP"
echo "\tValues: $VALUES"
echo "\tType: $MULTI_TYPE"
fi
if [ "$TRIGGER" = "TRIGGER_GPIO_IN" ]; then
echo "Script called from Trigger GPIO in"
echo "\tGPIO pin: $GPIO_PIN"
echo "\tPin Level: $GPIO_LEVEL"
fi

0
dist/ums/flashdrive/.gitkeep vendored Normal file
View File

View File

@ -61,12 +61,17 @@ type HIDController struct {
ctx context.Context
cancel context.CancelFunc
eventHandler EventHandler
abortLock *sync.Mutex
isAborted bool
}
func NewHIDController(ctx context.Context, keyboardDevicePath string, keyboardMapPath string, mouseDevicePath string) (ctl *HIDController, err error) {
//ToDo: check if hidcontroller could work with a context with cancellation, which then could be cancelled on reuse of the object
if hidControllerReuse == nil {
hidControllerReuse = &HIDController{}
hidControllerReuse.abortLock = &sync.Mutex{}
hidControllerReuse.isAborted = true
hidControllerReuse.initMasterVM()
//clone VM to pool
@ -82,6 +87,11 @@ func NewHIDController(ctx context.Context, keyboardDevicePath string, keyboardMa
}
hidControllerReuse.abortLock.Lock()
defer hidControllerReuse.abortLock.Unlock()
hidControllerReuse.isAborted = false
ctx,cancel := context.WithCancel(ctx)
hidControllerReuse.ctx = ctx
hidControllerReuse.cancel = cancel
@ -125,6 +135,14 @@ func (ctl *HIDController) emitEvent(event Event) {
}
func (ctl *HIDController) Abort() {
ctl.abortLock.Lock()
defer ctl.abortLock.Unlock()
if ctl.isAborted {
return
}
ctl.isAborted = true
// stop the old LED reader if present
// !! Keyboard.Close() has to be called before sending IRQ to VMs (there're JS function which register
// blocking callbacks to the Keyboard's LED reader, which would hinder the VM interrupt in triggering)

View File

@ -151,8 +151,9 @@ func (w *KeyboardLEDStateWatcher) RetrieveNewListener() (l *KeyboardLEDStateList
// of the listener to deal with this interrupt and close the channel after the interrupt is consumed (wrting to the channel
// happens only once)
// - close ledStateFile
func (w *KeyboardLEDStateWatcher) Stop() error {
w.ledStateFile.Close() //produces an error in readLoop which gets translated to an interrupt
func (w *KeyboardLEDStateWatcher) Stop() (err error) {
//ToDo: A crash occurs from time to time, if the underlying file is already gone (gadget destroyed), this has to be called before the file is removed
err = w.ledStateFile.Close() //produces an error in readLoop which gets translated to an interrupt
return nil
}

View File

@ -6479,9 +6479,7 @@ type P4WNP1Client interface {
ListStoredBluetoothSettings(ctx context.Context, in *Empty, opts ...grpcweb.CallOption) (*StringMessageArray, error)
// USB gadget
GetDeployedGadgetSetting(ctx context.Context, in *Empty, opts ...grpcweb.CallOption) (*GadgetSettings, error)
DeployGadgetSetting(ctx context.Context, in *Empty, opts ...grpcweb.CallOption) (*GadgetSettings, error)
GetGadgetSettings(ctx context.Context, in *Empty, opts ...grpcweb.CallOption) (*GadgetSettings, error)
SetGadgetSettings(ctx context.Context, in *GadgetSettings, opts ...grpcweb.CallOption) (*GadgetSettings, error)
DeployGadgetSetting(ctx context.Context, in *GadgetSettings, opts ...grpcweb.CallOption) (*GadgetSettings, error)
GetLEDSettings(ctx context.Context, in *Empty, opts ...grpcweb.CallOption) (*LEDSettings, error)
SetLEDSettings(ctx context.Context, in *LEDSettings, opts ...grpcweb.CallOption) (*Empty, error)
MountUMSFile(ctx context.Context, in *GadgetSettingsUMS, opts ...grpcweb.CallOption) (*Empty, error)
@ -6694,7 +6692,7 @@ func (c *p4WNP1Client) GetDeployedGadgetSetting(ctx context.Context, in *Empty,
return new(GadgetSettings).Unmarshal(resp)
}
func (c *p4WNP1Client) DeployGadgetSetting(ctx context.Context, in *Empty, opts ...grpcweb.CallOption) (*GadgetSettings, error) {
func (c *p4WNP1Client) DeployGadgetSetting(ctx context.Context, in *GadgetSettings, opts ...grpcweb.CallOption) (*GadgetSettings, error) {
resp, err := c.client.RPCCall(ctx, "DeployGadgetSetting", in.Marshal(), opts...)
if err != nil {
return nil, err
@ -6703,24 +6701,6 @@ func (c *p4WNP1Client) DeployGadgetSetting(ctx context.Context, in *Empty, opts
return new(GadgetSettings).Unmarshal(resp)
}
func (c *p4WNP1Client) GetGadgetSettings(ctx context.Context, in *Empty, opts ...grpcweb.CallOption) (*GadgetSettings, error) {
resp, err := c.client.RPCCall(ctx, "GetGadgetSettings", in.Marshal(), opts...)
if err != nil {
return nil, err
}
return new(GadgetSettings).Unmarshal(resp)
}
func (c *p4WNP1Client) SetGadgetSettings(ctx context.Context, in *GadgetSettings, opts ...grpcweb.CallOption) (*GadgetSettings, error) {
resp, err := c.client.RPCCall(ctx, "SetGadgetSettings", in.Marshal(), opts...)
if err != nil {
return nil, err
}
return new(GadgetSettings).Unmarshal(resp)
}
func (c *p4WNP1Client) GetLEDSettings(ctx context.Context, in *Empty, opts ...grpcweb.CallOption) (*LEDSettings, error) {
resp, err := c.client.RPCCall(ctx, "GetLEDSettings", in.Marshal(), opts...)
if err != nil {

View File

@ -3051,9 +3051,7 @@ type P4WNP1Client interface {
ListStoredBluetoothSettings(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*StringMessageArray, error)
// USB gadget
GetDeployedGadgetSetting(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*GadgetSettings, error)
DeployGadgetSetting(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*GadgetSettings, error)
GetGadgetSettings(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*GadgetSettings, error)
SetGadgetSettings(ctx context.Context, in *GadgetSettings, opts ...grpc.CallOption) (*GadgetSettings, error)
DeployGadgetSetting(ctx context.Context, in *GadgetSettings, opts ...grpc.CallOption) (*GadgetSettings, error)
GetLEDSettings(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*LEDSettings, error)
SetLEDSettings(ctx context.Context, in *LEDSettings, opts ...grpc.CallOption) (*Empty, error)
MountUMSFile(ctx context.Context, in *GadgetSettingsUMS, opts ...grpc.CallOption) (*Empty, error)
@ -3263,7 +3261,7 @@ func (c *p4WNP1Client) GetDeployedGadgetSetting(ctx context.Context, in *Empty,
return out, nil
}
func (c *p4WNP1Client) DeployGadgetSetting(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*GadgetSettings, error) {
func (c *p4WNP1Client) DeployGadgetSetting(ctx context.Context, in *GadgetSettings, opts ...grpc.CallOption) (*GadgetSettings, error) {
out := new(GadgetSettings)
err := grpc.Invoke(ctx, "/P4wnP1_grpc.P4WNP1/DeployGadgetSetting", in, out, c.cc, opts...)
if err != nil {
@ -3272,24 +3270,6 @@ func (c *p4WNP1Client) DeployGadgetSetting(ctx context.Context, in *Empty, opts
return out, nil
}
func (c *p4WNP1Client) GetGadgetSettings(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*GadgetSettings, error) {
out := new(GadgetSettings)
err := grpc.Invoke(ctx, "/P4wnP1_grpc.P4WNP1/GetGadgetSettings", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *p4WNP1Client) SetGadgetSettings(ctx context.Context, in *GadgetSettings, opts ...grpc.CallOption) (*GadgetSettings, error) {
out := new(GadgetSettings)
err := grpc.Invoke(ctx, "/P4wnP1_grpc.P4WNP1/SetGadgetSettings", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *p4WNP1Client) GetLEDSettings(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*LEDSettings, error) {
out := new(LEDSettings)
err := grpc.Invoke(ctx, "/P4wnP1_grpc.P4WNP1/GetLEDSettings", in, out, c.cc, opts...)
@ -3952,9 +3932,7 @@ type P4WNP1Server interface {
ListStoredBluetoothSettings(context.Context, *Empty) (*StringMessageArray, error)
// USB gadget
GetDeployedGadgetSetting(context.Context, *Empty) (*GadgetSettings, error)
DeployGadgetSetting(context.Context, *Empty) (*GadgetSettings, error)
GetGadgetSettings(context.Context, *Empty) (*GadgetSettings, error)
SetGadgetSettings(context.Context, *GadgetSettings) (*GadgetSettings, error)
DeployGadgetSetting(context.Context, *GadgetSettings) (*GadgetSettings, error)
GetLEDSettings(context.Context, *Empty) (*LEDSettings, error)
SetLEDSettings(context.Context, *LEDSettings) (*Empty, error)
MountUMSFile(context.Context, *GadgetSettingsUMS) (*Empty, error)
@ -4278,7 +4256,7 @@ func _P4WNP1_GetDeployedGadgetSetting_Handler(srv interface{}, ctx context.Conte
}
func _P4WNP1_DeployGadgetSetting_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(Empty)
in := new(GadgetSettings)
if err := dec(in); err != nil {
return nil, err
}
@ -4290,43 +4268,7 @@ func _P4WNP1_DeployGadgetSetting_Handler(srv interface{}, ctx context.Context, d
FullMethod: "/P4wnP1_grpc.P4WNP1/DeployGadgetSetting",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(P4WNP1Server).DeployGadgetSetting(ctx, req.(*Empty))
}
return interceptor(ctx, in, info, handler)
}
func _P4WNP1_GetGadgetSettings_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(Empty)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(P4WNP1Server).GetGadgetSettings(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/P4wnP1_grpc.P4WNP1/GetGadgetSettings",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(P4WNP1Server).GetGadgetSettings(ctx, req.(*Empty))
}
return interceptor(ctx, in, info, handler)
}
func _P4WNP1_SetGadgetSettings_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GadgetSettings)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(P4WNP1Server).SetGadgetSettings(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/P4wnP1_grpc.P4WNP1/SetGadgetSettings",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(P4WNP1Server).SetGadgetSettings(ctx, req.(*GadgetSettings))
return srv.(P4WNP1Server).DeployGadgetSetting(ctx, req.(*GadgetSettings))
}
return interceptor(ctx, in, info, handler)
}
@ -5636,14 +5578,6 @@ var _P4WNP1_serviceDesc = grpc.ServiceDesc{
MethodName: "DeployGadgetSetting",
Handler: _P4WNP1_DeployGadgetSetting_Handler,
},
{
MethodName: "GetGadgetSettings",
Handler: _P4WNP1_GetGadgetSettings_Handler,
},
{
MethodName: "SetGadgetSettings",
Handler: _P4WNP1_SetGadgetSettings_Handler,
},
{
MethodName: "GetLEDSettings",
Handler: _P4WNP1_GetLEDSettings_Handler,
@ -5930,317 +5864,316 @@ var _P4WNP1_serviceDesc = grpc.ServiceDesc{
func init() { proto.RegisterFile("grpc.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 4980 bytes of a gzipped FileDescriptorProto
// 4963 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x5c, 0x4b, 0x73, 0x23, 0x47,
0x72, 0x06, 0x08, 0xbe, 0x90, 0x20, 0xc8, 0x66, 0xcd, 0x90, 0xc4, 0x70, 0xde, 0xbd, 0x23, 0x69,
0x96, 0x92, 0xa8, 0x15, 0x77, 0x76, 0xa4, 0xd5, 0x4a, 0xd6, 0xe2, 0x45, 0x00, 0x33, 0x20, 0x00,
0x75, 0x03, 0x43, 0xed, 0xcb, 0xbd, 0x8d, 0xee, 0x22, 0xd8, 0x9a, 0x46, 0x37, 0xdc, 0x0f, 0x52,
0xb4, 0x23, 0x36, 0xc2, 0x1b, 0xe1, 0x88, 0x3d, 0xf8, 0xee, 0x83, 0x7f, 0x83, 0x7d, 0xb2, 0x7f,
0x86, 0x7f, 0x88, 0x2f, 0x7b, 0xf3, 0xc5, 0x17, 0x3b, 0xaa, 0xaa, 0xdf, 0xe8, 0xe6, 0x6b, 0xa4,
0x5b, 0x57, 0x56, 0xe6, 0x57, 0x55, 0x59, 0x99, 0x59, 0x59, 0x59, 0x20, 0x01, 0x26, 0xd6, 0x4c,
0xd9, 0x9f, 0x59, 0xa6, 0x63, 0xa2, 0xd2, 0xe0, 0xc5, 0xb9, 0x31, 0xf8, 0x54, 0x22, 0x24, 0xfe,
0x5f, 0x17, 0x60, 0xfd, 0x48, 0xb6, 0x1d, 0x6c, 0x0d, 0xf1, 0x74, 0xa6, 0xcb, 0x0e, 0x46, 0x2f,
0x61, 0xc7, 0xf1, 0xbe, 0x25, 0x43, 0x9e, 0x62, 0x69, 0xac, 0xbb, 0xd8, 0x31, 0x4d, 0xe7, 0xb4,
0x92, 0x7f, 0x92, 0x7f, 0x5e, 0x14, 0xb6, 0xfc, 0xee, 0x9e, 0x3c, 0xc5, 0x35, 0xbf, 0x13, 0xed,
0xc1, 0x66, 0x5c, 0xce, 0xb5, 0xc7, 0x95, 0x05, 0x2a, 0xb1, 0x11, 0x95, 0x18, 0xd9, 0x63, 0xf4,
0x11, 0xa0, 0x38, 0xef, 0xb9, 0x76, 0xa2, 0x55, 0x0a, 0x94, 0x99, 0x8b, 0x32, 0x1f, 0x6b, 0x27,
0x1a, 0xaa, 0xc2, 0xc3, 0x38, 0xb7, 0x63, 0x69, 0x93, 0x09, 0xb6, 0x24, 0x59, 0x71, 0x34, 0xd3,
0xb0, 0x2b, 0x8b, 0x54, 0x70, 0x37, 0x2a, 0x38, 0x64, 0x2c, 0x55, 0xc6, 0x81, 0x5e, 0xc0, 0x76,
0x0c, 0xc2, 0x96, 0x0c, 0xec, 0x9c, 0x9b, 0xd6, 0xdb, 0xca, 0xd2, 0x93, 0xc2, 0xf3, 0xa2, 0x70,
0x37, 0x2a, 0x6b, 0xf7, 0x58, 0x1f, 0xff, 0x0f, 0xf0, 0x40, 0xc0, 0x7f, 0xe7, 0x62, 0xdb, 0x89,
0xeb, 0x48, 0x74, 0x4c, 0x4b, 0x9e, 0x60, 0xc4, 0xc3, 0xda, 0x30, 0x22, 0xe7, 0xe9, 0x27, 0x46,
0x43, 0x9f, 0xc1, 0xaa, 0x8f, 0x4d, 0xb5, 0x51, 0x3a, 0xb8, 0xbf, 0x1f, 0xd9, 0x81, 0xfd, 0x38,
0xb2, 0x10, 0x30, 0xf3, 0xff, 0x98, 0x87, 0xc7, 0x81, 0x76, 0xbd, 0x69, 0x88, 0xd8, 0x71, 0x34,
0x63, 0x62, 0xdf, 0x64, 0x02, 0x5f, 0xc0, 0xaa, 0xed, 0x89, 0x79, 0x13, 0x78, 0x14, 0x9b, 0x40,
0x30, 0x86, 0x0f, 0x2e, 0x04, 0xfc, 0xfc, 0x3f, 0xe5, 0x61, 0x73, 0xae, 0x1f, 0xfd, 0x0a, 0x16,
0x14, 0x8d, 0x8e, 0x55, 0x3a, 0xf8, 0x30, 0x1d, 0xab, 0x6e, 0x1a, 0x8e, 0x65, 0xea, 0x3a, 0xb6,
0x3a, 0xc6, 0x89, 0x69, 0x4d, 0x65, 0xb2, 0x0d, 0xc2, 0x82, 0xa2, 0xa1, 0x9f, 0xc3, 0x82, 0xec,
0x4f, 0xe4, 0x27, 0xe9, 0xc2, 0xd5, 0x09, 0x36, 0x82, 0xa5, 0x0a, 0x0b, 0xb2, 0xcd, 0xef, 0xc1,
0x76, 0x7a, 0x2f, 0xe2, 0xa0, 0x30, 0xd3, 0x0c, 0x6f, 0xe1, 0xe4, 0x93, 0xff, 0xdf, 0x3c, 0xec,
0x04, 0xcc, 0xde, 0x4e, 0x8a, 0xd8, 0x3a, 0xd3, 0x14, 0x4c, 0xcc, 0xc0, 0xc2, 0x13, 0x8d, 0x68,
0x5c, 0x32, 0x2d, 0xc9, 0x35, 0xfc, 0x16, 0x05, 0x58, 0x15, 0xee, 0xfa, 0xed, 0xbe, 0x35, 0x0a,
0xfa, 0x88, 0x65, 0xdb, 0xd8, 0x3a, 0x63, 0x32, 0x8a, 0x69, 0x18, 0x58, 0x71, 0xe8, 0x0a, 0x56,
0x85, 0x0d, 0xd6, 0xd1, 0xb7, 0xea, 0x8c, 0x8c, 0xbe, 0x84, 0x45, 0xe7, 0x62, 0x86, 0xa9, 0x2d,
0xaf, 0x1f, 0x3c, 0x4f, 0x5f, 0x60, 0x7c, 0x56, 0xc3, 0x8b, 0x19, 0x16, 0xa8, 0x14, 0x7a, 0x04,
0xa5, 0xa9, 0xac, 0x90, 0x61, 0x88, 0x91, 0x7a, 0x76, 0x5d, 0x9c, 0xca, 0x4a, 0xdf, 0xa2, 0x7b,
0xf9, 0x18, 0x4a, 0x63, 0x4b, 0x53, 0x27, 0xcc, 0x88, 0x2b, 0x4b, 0xb4, 0x1f, 0x18, 0x89, 0x30,
0xf0, 0xff, 0xbd, 0x08, 0xf7, 0x53, 0x36, 0x21, 0x50, 0x57, 0x05, 0x56, 0x66, 0xe6, 0x39, 0xb6,
0xb0, 0xea, 0xad, 0xd8, 0x6f, 0xa2, 0x27, 0x50, 0xf2, 0x96, 0x26, 0x8f, 0x75, 0xec, 0x2d, 0x2f,
0x4a, 0x42, 0x3f, 0x05, 0xee, 0x44, 0xb6, 0x1d, 0x29, 0xca, 0x56, 0x60, 0x5a, 0x20, 0xf4, 0x7a,
0x84, 0x95, 0x87, 0x35, 0x55, 0xb3, 0x15, 0xf3, 0x0c, 0x5b, 0x94, 0x6d, 0x91, 0xb2, 0xc5, 0x68,
0x68, 0x17, 0x56, 0xc7, 0xa6, 0xa1, 0xd2, 0xfe, 0x25, 0xda, 0x1f, 0xb4, 0xd1, 0x3e, 0xdc, 0xd1,
0x35, 0xe3, 0xad, 0xa4, 0xe3, 0x33, 0xac, 0x4b, 0x36, 0x56, 0x5c, 0x4b, 0x73, 0x2e, 0x2a, 0xcb,
0x94, 0x6d, 0x93, 0x74, 0x75, 0x49, 0x8f, 0xe8, 0x75, 0xa0, 0x03, 0xd8, 0xa2, 0x4c, 0x58, 0xb2,
0xb5, 0xe9, 0x4c, 0xc7, 0xd2, 0x4c, 0xd6, 0x2c, 0xcd, 0x98, 0x54, 0x56, 0xa8, 0xc4, 0x1d, 0xd6,
0x29, 0xd2, 0xbe, 0x01, 0xeb, 0x42, 0x5b, 0xb0, 0x3c, 0xb6, 0x24, 0xac, 0x5a, 0x95, 0x55, 0xca,
0xb4, 0x34, 0xb6, 0x9a, 0xaa, 0x85, 0x1e, 0x02, 0x9c, 0x6a, 0x93, 0x53, 0xc9, 0x9e, 0x61, 0xac,
0x56, 0x8a, 0xb4, 0xab, 0x48, 0x28, 0x22, 0x21, 0x90, 0x6e, 0xdd, 0x3c, 0x97, 0xb0, 0x81, 0xad,
0xc9, 0x45, 0x05, 0x58, 0xb7, 0x6e, 0x9e, 0x37, 0x29, 0x81, 0x68, 0x51, 0x56, 0xcf, 0xb0, 0xe5,
0x68, 0x36, 0x19, 0xbe, 0xc4, 0xb4, 0x18, 0x21, 0xa1, 0x8f, 0x01, 0x79, 0x53, 0xf5, 0xf4, 0x48,
0x23, 0xd8, 0x1a, 0x5b, 0x19, 0xeb, 0xa9, 0x87, 0x1d, 0x64, 0x3c, 0x15, 0x8f, 0xdd, 0x89, 0xf4,
0x16, 0x5f, 0xd8, 0x95, 0x32, 0x1b, 0x8f, 0x52, 0x5e, 0xe3, 0x0b, 0xb6, 0x9f, 0x96, 0x76, 0x26,
0x2b, 0x17, 0x95, 0x75, 0x6f, 0x3f, 0x59, 0x13, 0xfd, 0x12, 0x2a, 0x4a, 0xb0, 0xff, 0x64, 0xac,
0x13, 0x6d, 0xe2, 0x5a, 0xd4, 0x0f, 0x2b, 0x1b, 0x94, 0x75, 0x27, 0xec, 0xaf, 0x47, 0xbb, 0xd1,
0x7b, 0xb0, 0x6e, 0x3b, 0xb2, 0xa3, 0x29, 0x92, 0xac, 0xaa, 0x16, 0xb6, 0xed, 0x0a, 0x47, 0x05,
0xca, 0x8c, 0x5a, 0x65, 0x44, 0xfe, 0xaf, 0x8b, 0xf0, 0xe8, 0x72, 0x87, 0x27, 0xd3, 0xf3, 0x21,
0x88, 0xb9, 0xad, 0x09, 0x7e, 0x13, 0x7d, 0x08, 0x9b, 0xc1, 0xb9, 0x22, 0x9d, 0x61, 0xcb, 0x26,
0xf3, 0x22, 0x46, 0x57, 0x16, 0xb8, 0xa0, 0xe3, 0x0d, 0xa3, 0x13, 0x73, 0x9a, 0xca, 0x86, 0x7b,
0x22, 0x2b, 0x8e, 0x6b, 0x61, 0x8b, 0x5a, 0x5d, 0x59, 0x88, 0xd1, 0xd0, 0x31, 0x20, 0xdb, 0x9d,
0xcd, 0x4c, 0xcb, 0xc1, 0xaa, 0x14, 0x04, 0xbc, 0x45, 0x1a, 0x67, 0x9e, 0x5f, 0x15, 0xa4, 0x82,
0x60, 0xb3, 0x19, 0x60, 0x04, 0x2e, 0x23, 0x02, 0xa7, 0xb8, 0x96, 0x85, 0x0d, 0x27, 0x84, 0x5d,
0xba, 0x21, 0xec, 0x86, 0x87, 0x10, 0x80, 0xbe, 0x0f, 0x1b, 0x8a, 0x2e, 0xdb, 0xb6, 0x64, 0x9e,
0x48, 0x2a, 0x26, 0x51, 0x80, 0x1a, 0xf7, 0x9a, 0x50, 0xa6, 0xe4, 0xfe, 0x49, 0x83, 0x12, 0x11,
0x82, 0x45, 0xea, 0xe9, 0x2b, 0xd4, 0xd3, 0xe9, 0x37, 0x31, 0x09, 0xfb, 0xd4, 0xb4, 0x1c, 0x16,
0x03, 0x56, 0x59, 0x8c, 0xa0, 0x14, 0x1a, 0x23, 0x9e, 0xc2, 0x9a, 0x66, 0x4b, 0xf2, 0x99, 0xac,
0xe9, 0xd4, 0xb7, 0x98, 0x09, 0x97, 0x34, 0xbb, 0xea, 0x93, 0xd0, 0xaf, 0x60, 0xd7, 0x66, 0xb1,
0xc7, 0x3f, 0x06, 0x25, 0x2f, 0xc0, 0x19, 0xf2, 0xcc, 0x33, 0xea, 0x1d, 0x8f, 0x23, 0x12, 0xab,
0xb0, 0xd5, 0x93, 0x67, 0xe8, 0x2b, 0xb8, 0x9f, 0x21, 0x3c, 0x93, 0x0d, 0xd7, 0x33, 0xf9, 0x4a,
0x9a, 0xf4, 0x40, 0x36, 0x5c, 0xf4, 0x4b, 0xb8, 0x97, 0x21, 0x3e, 0x31, 0x3c, 0x37, 0xd8, 0x4e,
0x13, 0x6e, 0x19, 0xfc, 0x77, 0xc0, 0xc5, 0x8e, 0x75, 0x11, 0x3b, 0xa8, 0x06, 0xeb, 0xf1, 0xa3,
0xbe, 0x92, 0x7f, 0x52, 0x78, 0x5e, 0x3a, 0xd8, 0x8d, 0xed, 0x4d, 0x8c, 0x45, 0x48, 0x48, 0x10,
0x25, 0xd3, 0xd3, 0x93, 0x25, 0x2b, 0xf4, 0x9b, 0xff, 0x37, 0x80, 0x72, 0x8c, 0x0d, 0xad, 0xc3,
0x82, 0xc6, 0xa2, 0x66, 0x59, 0x58, 0xd0, 0x54, 0x62, 0xdb, 0xa6, 0x81, 0xc5, 0x53, 0xd3, 0x3f,
0x0b, 0xfc, 0x26, 0x89, 0x6c, 0x9a, 0x4d, 0xa4, 0xce, 0xfc, 0x00, 0x19, 0xb4, 0xd1, 0x03, 0x28,
0x6a, 0xd3, 0xa9, 0xeb, 0x44, 0xc2, 0x62, 0x48, 0x40, 0x5d, 0x58, 0xf7, 0xd6, 0x2e, 0x3a, 0x32,
0xb1, 0x42, 0xcf, 0xd2, 0xf8, 0xb4, 0xd5, 0x88, 0x31, 0xce, 0x76, 0x4e, 0x48, 0xc8, 0xa2, 0x6f,
0x01, 0xb9, 0xf6, 0xb8, 0x25, 0xab, 0x13, 0xec, 0x47, 0x67, 0xac, 0x52, 0x3b, 0x2b, 0x1d, 0xbc,
0x9f, 0x86, 0x38, 0x12, 0x6b, 0x09, 0xee, 0x76, 0x4e, 0x48, 0xc1, 0x40, 0x32, 0x6c, 0x05, 0xd4,
0x06, 0x09, 0xea, 0x3e, 0xf8, 0x0a, 0x05, 0xff, 0xe9, 0xa5, 0xe0, 0x51, 0x81, 0x76, 0x4e, 0x48,
0x47, 0x42, 0x1d, 0x28, 0x93, 0xa4, 0xb0, 0x3a, 0xf0, 0x35, 0xb1, 0x4a, 0xa1, 0x9f, 0xa6, 0x41,
0x1f, 0x47, 0x19, 0xdb, 0x39, 0x21, 0x2e, 0x49, 0xf4, 0x40, 0x08, 0xc1, 0xf4, 0xab, 0xb6, 0xe8,
0xc8, 0xd4, 0x2f, 0x32, 0xf4, 0x70, 0x3c, 0xc7, 0x4d, 0xf4, 0x30, 0x8f, 0x41, 0x73, 0x2b, 0xfb,
0xb4, 0x6b, 0x4e, 0x34, 0x83, 0xba, 0x4d, 0xe9, 0xe0, 0x41, 0xea, 0x4e, 0x89, 0x6d, 0xca, 0xd3,
0xce, 0x09, 0x01, 0x3f, 0x12, 0x80, 0x53, 0x4f, 0x95, 0x59, 0x17, 0xcb, 0x36, 0x6e, 0x59, 0xb2,
0x41, 0xd6, 0x58, 0xa2, 0x18, 0xcf, 0xd2, 0x30, 0x1a, 0xed, 0xfa, 0x20, 0xca, 0xdb, 0xce, 0x09,
0x73, 0xf2, 0xe8, 0x10, 0xd6, 0x26, 0x96, 0xe9, 0xce, 0x04, 0xac, 0x60, 0x62, 0x7d, 0x6b, 0x14,
0xef, 0x49, 0x1a, 0x5e, 0x2b, 0xc2, 0xd7, 0xce, 0x09, 0x31, 0x39, 0x34, 0x82, 0xcd, 0x68, 0xfb,
0xc8, 0xd5, 0x1d, 0x8d, 0x1e, 0x3e, 0xa5, 0x83, 0xf7, 0xae, 0x02, 0xa3, 0xcc, 0xed, 0x9c, 0x30,
0x8f, 0x80, 0x5e, 0xc0, 0xf2, 0x64, 0xa6, 0x99, 0x1d, 0x83, 0x1e, 0x56, 0x19, 0x4e, 0xda, 0x1a,
0x74, 0xfa, 0x1d, 0xa2, 0x2a, 0x8f, 0x17, 0x35, 0x00, 0xc6, 0xb2, 0x7d, 0x2a, 0x2a, 0x96, 0x36,
0x73, 0xe8, 0xd9, 0x95, 0x74, 0x08, 0x2f, 0x1c, 0x90, 0xed, 0xae, 0x05, 0x9c, 0xed, 0xbc, 0x10,
0x91, 0x43, 0x55, 0x28, 0x9e, 0x6a, 0xaa, 0x07, 0xc2, 0xa5, 0xd8, 0x52, 0x04, 0xa4, 0xdd, 0x69,
0x04, 0x18, 0xa1, 0x14, 0x52, 0x60, 0x5b, 0xc5, 0x33, 0xdd, 0xbc, 0xf0, 0xc3, 0xb8, 0x9f, 0x67,
0x57, 0x36, 0x53, 0xcc, 0x9e, 0xe1, 0x35, 0x52, 0x05, 0xda, 0x79, 0x21, 0x03, 0x0a, 0xed, 0x41,
0x41, 0x37, 0x27, 0x15, 0x44, 0x11, 0xb7, 0x53, 0x10, 0xbb, 0xe6, 0xa4, 0x9d, 0x17, 0x08, 0x13,
0x7a, 0x09, 0x2b, 0x44, 0x47, 0x7d, 0xd7, 0xa9, 0xdc, 0x49, 0x51, 0x28, 0xe3, 0x27, 0xfa, 0xec,
0xbb, 0x64, 0x29, 0x3e, 0x33, 0xfa, 0x12, 0x8a, 0x74, 0x73, 0x44, 0x6c, 0xa8, 0x95, 0xbb, 0x29,
0x76, 0xeb, 0x49, 0xfa, 0x3c, 0x44, 0x0d, 0x81, 0x40, 0xad, 0x08, 0x2b, 0xde, 0x56, 0xd5, 0x56,
0x61, 0x99, 0xb1, 0xf2, 0x3b, 0xb0, 0x95, 0x1a, 0x96, 0xf8, 0xfb, 0x70, 0x2f, 0x33, 0xba, 0xf0,
0x8f, 0xe0, 0xc1, 0x65, 0xd1, 0x81, 0xdf, 0x86, 0xbb, 0x69, 0x2e, 0x1e, 0x01, 0x9d, 0x77, 0x55,
0xfe, 0x13, 0xd8, 0x48, 0xf8, 0x1d, 0x89, 0xba, 0x3a, 0xf9, 0x18, 0xd9, 0x5e, 0xaa, 0x5f, 0x14,
0x42, 0x02, 0x7f, 0x0f, 0x76, 0x32, 0x9c, 0x8c, 0xef, 0xc0, 0x9d, 0x14, 0x13, 0x27, 0x78, 0x54,
0x1f, 0x91, 0x4b, 0x57, 0x48, 0x40, 0x77, 0x61, 0xe9, 0x4c, 0xd6, 0x5d, 0x76, 0xa0, 0x2c, 0x09,
0xac, 0xc1, 0xff, 0x25, 0x0f, 0x95, 0x2c, 0x77, 0xb9, 0x02, 0x70, 0x1b, 0x96, 0x29, 0x86, 0x5d,
0x29, 0x3c, 0x29, 0x3c, 0x5f, 0x12, 0xbc, 0x16, 0x7a, 0xe9, 0x5d, 0x36, 0x16, 0xe9, 0x65, 0x23,
0xee, 0x13, 0x73, 0x63, 0x84, 0xd7, 0x0c, 0xfe, 0xbf, 0xf2, 0xc1, 0xe1, 0xc6, 0xbc, 0x0d, 0xdd,
0x87, 0x22, 0x31, 0x0e, 0x96, 0x52, 0xb0, 0xf1, 0x57, 0x09, 0x81, 0x0e, 0xff, 0x15, 0xc0, 0xcc,
0xd5, 0xf5, 0xd1, 0xac, 0x61, 0x9e, 0xb3, 0x24, 0x6d, 0xfd, 0xe0, 0x61, 0x7c, 0x30, 0x8a, 0x32,
0x08, 0x98, 0x84, 0x88, 0x00, 0xfa, 0x0c, 0x80, 0x79, 0x72, 0x53, 0x9d, 0xf8, 0x17, 0xa3, 0x9d,
0x14, 0x71, 0xd2, 0x2d, 0x44, 0x58, 0xd1, 0x07, 0xb0, 0xa1, 0xe2, 0xb1, 0xe9, 0x1a, 0x0a, 0x96,
0xa6, 0x9a, 0xae, 0x6b, 0x2c, 0x9f, 0x2b, 0x08, 0xeb, 0x3e, 0xf9, 0x88, 0x52, 0xf9, 0xcf, 0x60,
0x2b, 0x35, 0x04, 0xa0, 0x47, 0x00, 0x36, 0xfd, 0x8a, 0xe8, 0x35, 0x42, 0xe1, 0x5f, 0xc2, 0xdd,
0x34, 0xb7, 0xbf, 0x52, 0xee, 0x7f, 0xf2, 0xf0, 0xe0, 0x32, 0xff, 0x26, 0x19, 0xab, 0x93, 0x72,
0x31, 0x8f, 0xd2, 0xd0, 0x2b, 0x6f, 0xf7, 0x98, 0x42, 0x5f, 0x5e, 0x3b, 0x78, 0xec, 0xfb, 0x1f,
0x91, 0x1d, 0xc5, 0x61, 0x21, 0x80, 0x50, 0xd1, 0x26, 0x94, 0x0f, 0x47, 0xdd, 0xae, 0x24, 0x36,
0x87, 0xc3, 0x4e, 0xaf, 0x25, 0x72, 0x39, 0x54, 0x82, 0x95, 0x5e, 0x73, 0x78, 0xdc, 0x17, 0x5e,
0x73, 0x79, 0xb4, 0x0a, 0x8b, 0xc7, 0x9d, 0xc3, 0x0e, 0xb7, 0x80, 0x56, 0xa0, 0x30, 0x12, 0x6b,
0x5c, 0x01, 0x95, 0xa1, 0x58, 0xeb, 0x8e, 0x9a, 0xc3, 0x7e, 0x7f, 0xd8, 0xe6, 0x16, 0xd1, 0x1d,
0xd8, 0x18, 0x0a, 0x9d, 0x56, 0xab, 0x29, 0x48, 0xd5, 0xfa, 0xb0, 0xd3, 0xef, 0x89, 0xdc, 0x12,
0x5f, 0x82, 0x62, 0x10, 0x84, 0xf8, 0x3f, 0x40, 0x39, 0x16, 0x61, 0x2e, 0x37, 0xa2, 0x4f, 0xa2,
0x4e, 0xb1, 0x7e, 0x70, 0x6f, 0xce, 0x00, 0xfa, 0xae, 0xf3, 0x86, 0x30, 0xf8, 0xfe, 0xd2, 0x84,
0x8d, 0x44, 0x18, 0xba, 0x95, 0xdb, 0x9d, 0xc3, 0x2e, 0x89, 0x11, 0xef, 0x50, 0x40, 0xf9, 0xc5,
0x5c, 0x01, 0x25, 0x3e, 0xf9, 0x63, 0xed, 0x50, 0x4b, 0xa9, 0x9d, 0xfc, 0x4b, 0x01, 0xd6, 0xa2,
0x5d, 0x41, 0x2e, 0x9f, 0x8f, 0xe4, 0xf2, 0xbb, 0xb0, 0xaa, 0x6a, 0x36, 0xc9, 0xfd, 0x54, 0x2f,
0x8b, 0x0c, 0xda, 0xc4, 0x08, 0x2d, 0x3c, 0x71, 0x75, 0xd9, 0x31, 0xad, 0x0b, 0xaf, 0x38, 0x16,
0xa1, 0xa0, 0xaf, 0x61, 0x8d, 0xa4, 0xc7, 0x9a, 0x31, 0x91, 0xa6, 0xa6, 0xea, 0x47, 0x81, 0x07,
0x73, 0x73, 0x3b, 0x66, 0x4c, 0x47, 0xa6, 0x8a, 0x85, 0xd2, 0x79, 0xd8, 0x40, 0x2f, 0xa1, 0x28,
0xbb, 0xce, 0x29, 0x93, 0x5e, 0x4a, 0xd9, 0x16, 0x22, 0x5d, 0x75, 0x9d, 0x53, 0x2a, 0xba, 0x2a,
0x7b, 0x5f, 0x24, 0xf3, 0x55, 0x4e, 0x65, 0xc3, 0xc0, 0x3a, 0x4d, 0x26, 0xcb, 0x82, 0xdf, 0x44,
0xfb, 0xb0, 0x2c, 0xcf, 0xa4, 0x9a, 0x28, 0x7a, 0x89, 0xe0, 0xce, 0x1c, 0x5c, 0x4d, 0x14, 0xeb,
0x27, 0x13, 0x61, 0x49, 0x9e, 0xd5, 0x44, 0x11, 0x7d, 0x4d, 0xae, 0x41, 0x1a, 0xb9, 0x5a, 0xd5,
0x44, 0x51, 0xd2, 0x35, 0xdb, 0xa9, 0xac, 0xd2, 0xf4, 0x3d, 0x53, 0xb0, 0xcc, 0xf8, 0x6b, 0xa2,
0xd8, 0xd5, 0x6c, 0x6a, 0x72, 0xa7, 0x9a, 0x8a, 0x25, 0xdb, 0xd6, 0xfc, 0xcb, 0xfa, 0x2a, 0x21,
0x88, 0xb6, 0xa6, 0x92, 0xb0, 0x69, 0xe0, 0xef, 0xa7, 0xa6, 0xe1, 0xdd, 0x9b, 0xbd, 0x16, 0xff,
0xef, 0x79, 0x28, 0xd2, 0x9d, 0x71, 0x88, 0xab, 0xee, 0xc3, 0x22, 0x55, 0x40, 0x9e, 0x2a, 0x60,
0x77, 0x7e, 0x6b, 0x09, 0x17, 0xd5, 0x00, 0xe5, 0x8b, 0xae, 0x7e, 0x21, 0xbe, 0x7a, 0x04, 0x8b,
0x74, 0x1e, 0x6c, 0xab, 0xe8, 0x37, 0xaa, 0x43, 0xf2, 0xee, 0xe7, 0xdd, 0x49, 0x2f, 0xb1, 0xa1,
0xa4, 0x04, 0x7f, 0x00, 0x10, 0xaa, 0x80, 0x0c, 0x23, 0x8a, 0x9d, 0x86, 0x6f, 0x47, 0xe4, 0x1b,
0x71, 0x50, 0x18, 0x88, 0xaf, 0xbd, 0x1b, 0x0c, 0xf9, 0xe4, 0x9f, 0x42, 0x59, 0x74, 0x2c, 0xb2,
0xd5, 0xd8, 0xb6, 0x89, 0xa9, 0x73, 0x50, 0x98, 0xda, 0x13, 0xbf, 0x52, 0x36, 0xb5, 0x27, 0xfc,
0xcf, 0x00, 0xc5, 0x58, 0xaa, 0x96, 0x25, 0x5f, 0x10, 0x93, 0x9c, 0xda, 0x13, 0xfa, 0x4d, 0xef,
0x52, 0x45, 0x21, 0x68, 0xf3, 0xfb, 0xb0, 0xd6, 0x3c, 0xc3, 0x86, 0xe3, 0x79, 0x13, 0x31, 0x51,
0xb2, 0x69, 0xd8, 0x20, 0x41, 0x87, 0x42, 0x17, 0x84, 0x08, 0x85, 0x97, 0x01, 0x28, 0x3f, 0x75,
0x6c, 0xb4, 0x0b, 0x2b, 0x8e, 0x4d, 0x07, 0x64, 0xb3, 0x68, 0xe7, 0x04, 0x9f, 0x80, 0xb6, 0x61,
0xc9, 0x19, 0x9b, 0x26, 0xd3, 0xe9, 0x6a, 0x3b, 0x27, 0xb0, 0x26, 0xaa, 0xc0, 0xb2, 0xa3, 0x19,
0xce, 0xcb, 0x17, 0x54, 0xab, 0x05, 0x92, 0x16, 0xb2, 0x76, 0x6d, 0x09, 0x0a, 0x67, 0xb2, 0xce,
0x77, 0x61, 0x89, 0x0e, 0x41, 0xd4, 0xe2, 0x84, 0xb3, 0x60, 0xf5, 0xb4, 0x4f, 0x82, 0x83, 0x73,
0x21, 0xc5, 0xac, 0xc2, 0xa9, 0xf9, 0x27, 0x2a, 0xff, 0x47, 0xb8, 0x4b, 0x7c, 0xbf, 0xa1, 0x59,
0x7d, 0xeb, 0x50, 0xd3, 0xb1, 0xbf, 0x50, 0x0e, 0x0a, 0xaa, 0xe6, 0xa7, 0x0e, 0xe4, 0x93, 0x18,
0xd7, 0xcc, 0xc2, 0x27, 0xda, 0xf7, 0x9e, 0xd2, 0xbd, 0x16, 0x51, 0x89, 0x69, 0xe8, 0x17, 0x87,
0xa6, 0xae, 0x7a, 0x95, 0x8a, 0x55, 0x21, 0x42, 0x21, 0x67, 0x55, 0x62, 0x04, 0x7b, 0x66, 0x1a,
0x36, 0x66, 0xee, 0x6e, 0xbb, 0xba, 0x33, 0x90, 0x83, 0x52, 0x7b, 0x84, 0xc2, 0xff, 0x73, 0x1e,
0x36, 0x04, 0x2c, 0xab, 0xd1, 0x69, 0xfd, 0x02, 0x96, 0x4f, 0xd8, 0x40, 0xf9, 0x94, 0x53, 0xb9,
0xaa, 0x28, 0xd8, 0xb6, 0xb5, 0xb1, 0x8e, 0xd9, 0xd8, 0x82, 0xc7, 0x4c, 0xb6, 0xf8, 0x44, 0xd3,
0xb1, 0x11, 0x5e, 0x7a, 0x83, 0x36, 0x89, 0xa2, 0x36, 0x39, 0x0c, 0x99, 0xbe, 0x05, 0xd6, 0x20,
0xeb, 0xd7, 0xb1, 0xe1, 0x1d, 0xbf, 0xe4, 0x93, 0x6f, 0x00, 0x17, 0xce, 0xc6, 0x5b, 0xc2, 0x03,
0x28, 0x5a, 0x58, 0x56, 0xeb, 0xa6, 0x6b, 0x38, 0xde, 0x3e, 0x84, 0x04, 0xb2, 0x41, 0xaa, 0xec,
0xc8, 0x74, 0xc4, 0x35, 0x81, 0x7e, 0xf3, 0xff, 0x99, 0x07, 0xee, 0xd8, 0xd2, 0x1c, 0xfc, 0x23,
0xaf, 0x6a, 0x9b, 0x04, 0xa6, 0x19, 0x49, 0x77, 0xd9, 0x8e, 0x78, 0x2d, 0x5a, 0x59, 0x72, 0x6d,
0xa7, 0x67, 0x3a, 0xcd, 0xef, 0x49, 0xf4, 0xf1, 0x0a, 0x95, 0x51, 0x5a, 0x30, 0xef, 0xa5, 0xc8,
0xbc, 0xdf, 0x83, 0x0d, 0x32, 0xe3, 0x8e, 0x71, 0x62, 0xfa, 0xb3, 0x46, 0xb0, 0x38, 0x0b, 0x77,
0x8e, 0x7e, 0xf3, 0x7f, 0x02, 0x2e, 0x64, 0xf3, 0x94, 0x94, 0x76, 0x0c, 0x90, 0xc8, 0xa1, 0xfd,
0x3d, 0x9b, 0x76, 0x41, 0xa0, 0xdf, 0x84, 0x46, 0xe3, 0x12, 0x2b, 0x76, 0x05, 0xb1, 0x67, 0x6a,
0xaa, 0x43, 0xcd, 0xab, 0x0d, 0x17, 0x04, 0xbf, 0x49, 0xb6, 0x4d, 0xb3, 0x1b, 0x9a, 0xe5, 0x95,
0x52, 0x59, 0x83, 0xff, 0x2d, 0x70, 0x41, 0x52, 0x13, 0xf1, 0x59, 0x96, 0xc9, 0x44, 0xed, 0x2c,
0xa4, 0xa0, 0xf7, 0x61, 0xdd, 0xd1, 0xa6, 0xd8, 0x74, 0x1d, 0x11, 0x2b, 0xa6, 0xa1, 0xda, 0x5e,
0x98, 0x4b, 0x50, 0xf9, 0x47, 0xb0, 0x16, 0x60, 0xbf, 0x32, 0xc7, 0xc9, 0xfa, 0x08, 0xff, 0x2c,
0x32, 0xf6, 0x2b, 0x73, 0x4c, 0xc3, 0x35, 0x07, 0x05, 0x4d, 0x65, 0x25, 0x9a, 0xb2, 0x40, 0x3e,
0xf9, 0x37, 0x50, 0x69, 0x77, 0x1a, 0x82, 0x6b, 0x18, 0x9a, 0x31, 0x79, 0x65, 0x8e, 0x69, 0xb4,
0x15, 0xa8, 0xd5, 0x47, 0x10, 0x0b, 0xb4, 0xe2, 0x82, 0x60, 0xf1, 0x6c, 0xda, 0x51, 0x7d, 0x2d,
0x91, 0x6f, 0xb2, 0xb1, 0xb6, 0xe9, 0x5a, 0x0a, 0xf6, 0xa2, 0xae, 0xd7, 0xe2, 0xff, 0x04, 0x1b,
0x91, 0x95, 0x53, 0xb8, 0x0f, 0xa1, 0xf0, 0x9d, 0x39, 0xf6, 0xde, 0x2d, 0xe2, 0xe1, 0x37, 0x3a,
0x51, 0x81, 0x70, 0x11, 0x2d, 0x69, 0xf6, 0xa1, 0x66, 0x68, 0xf6, 0x69, 0x70, 0x34, 0x47, 0x28,
0xa1, 0xb7, 0xbe, 0xb2, 0x4d, 0x23, 0x3c, 0x9c, 0x7d, 0x0a, 0xbf, 0x0f, 0xa5, 0x6e, 0xb3, 0x11,
0x9c, 0xfd, 0x8f, 0xa1, 0x34, 0xa6, 0x15, 0x6d, 0x25, 0xf0, 0x8d, 0xb2, 0x00, 0x94, 0x44, 0x9d,
0x83, 0xff, 0x1e, 0xee, 0x8d, 0xc4, 0xda, 0x3b, 0x64, 0x29, 0x9f, 0xcd, 0x65, 0x29, 0xf1, 0x77,
0x26, 0x76, 0xbb, 0x4a, 0xc9, 0x53, 0xfe, 0xba, 0x04, 0xeb, 0xf1, 0x4e, 0x62, 0x66, 0xd8, 0x60,
0x49, 0x89, 0xf7, 0x4a, 0xe0, 0x35, 0xc9, 0x06, 0x9e, 0x69, 0xaa, 0x7f, 0xce, 0x9c, 0x69, 0x2a,
0x7b, 0x80, 0xf1, 0xcf, 0x3c, 0xf2, 0x39, 0x57, 0xad, 0x65, 0xaf, 0x18, 0xf1, 0x6a, 0x2d, 0xad,
0x5b, 0x9b, 0xaa, 0xab, 0x38, 0xde, 0x23, 0x86, 0xdf, 0xa4, 0x1b, 0x8a, 0x2d, 0x4d, 0x66, 0xb9,
0x05, 0xd9, 0x50, 0xda, 0x42, 0x8f, 0xa0, 0xe4, 0xda, 0x58, 0xaa, 0x37, 0xea, 0x52, 0xb3, 0x7e,
0xe4, 0x15, 0xf6, 0x8b, 0xae, 0x8d, 0xeb, 0x8d, 0x7a, 0xb3, 0x7e, 0x44, 0x32, 0x01, 0xd2, 0x2f,
0xf4, 0x1a, 0x1d, 0xd1, 0xab, 0xe8, 0xaf, 0xba, 0x36, 0xa6, 0x6d, 0xf4, 0x1c, 0x38, 0xd2, 0xd9,
0xee, 0x34, 0xa4, 0xd7, 0xcd, 0xdf, 0xd4, 0xfa, 0x55, 0xa1, 0xe1, 0x65, 0x0b, 0xeb, 0xae, 0x8d,
0xdb, 0x9d, 0x86, 0x4f, 0x45, 0x3c, 0x94, 0x7d, 0xce, 0xa3, 0xfe, 0x48, 0x6c, 0x7a, 0xd5, 0xd0,
0x12, 0x63, 0xa3, 0x24, 0x7f, 0x2a, 0x84, 0x47, 0xa8, 0x1e, 0x7b, 0x15, 0xcf, 0x22, 0xe3, 0x10,
0xaa, 0xc7, 0x68, 0x07, 0x56, 0x48, 0xff, 0xe8, 0x48, 0xf4, 0x0a, 0x9a, 0xcb, 0xae, 0x8d, 0x47,
0x47, 0x22, 0x7a, 0x08, 0x40, 0x3a, 0xc4, 0xa6, 0xd0, 0xa9, 0x76, 0xfd, 0x62, 0xbe, 0x6b, 0x63,
0x46, 0x40, 0xaf, 0x60, 0xdd, 0x32, 0x54, 0xcd, 0x0e, 0xeb, 0xcc, 0xeb, 0x29, 0xcf, 0x64, 0xf1,
0xbd, 0x6a, 0x3a, 0xa7, 0xd8, 0x32, 0xb0, 0x23, 0x94, 0xa9, 0x68, 0xb0, 0x85, 0x47, 0xc0, 0x29,
0xaa, 0x22, 0x61, 0x65, 0x1a, 0xa2, 0x6d, 0x5c, 0x1f, 0x6d, 0x5d, 0x51, 0x95, 0xa6, 0x32, 0x0d,
0xe0, 0xaa, 0xb0, 0xe6, 0x4e, 0x23, 0x13, 0xe3, 0x52, 0x1e, 0x12, 0xe3, 0x50, 0xa3, 0x23, 0x51,
0x28, 0xb9, 0xd3, 0x70, 0x46, 0x9f, 0xc2, 0x96, 0x8a, 0xcf, 0x24, 0x12, 0x17, 0xa5, 0x53, 0x4d,
0x95, 0xde, 0xe2, 0x8b, 0xb1, 0x29, 0x5b, 0x2a, 0x2d, 0x75, 0x14, 0x05, 0xa4, 0xe2, 0x33, 0x12,
0x7f, 0xda, 0x9a, 0xfa, 0xda, 0xeb, 0x41, 0x1f, 0x02, 0x8a, 0x89, 0x4c, 0x4d, 0xd7, 0xc6, 0xb4,
0xd4, 0x51, 0x14, 0x36, 0x42, 0xfe, 0x23, 0x42, 0x46, 0x1f, 0x00, 0x17, 0x63, 0xb6, 0xe4, 0x73,
0x5a, 0xdb, 0x28, 0x0a, 0xe5, 0x90, 0x55, 0x90, 0xcf, 0xf9, 0x01, 0x6c, 0xa7, 0xaf, 0x9a, 0x66,
0x93, 0xa6, 0xed, 0xd0, 0x67, 0x0f, 0xff, 0x02, 0x43, 0x08, 0x55, 0x55, 0xb5, 0xd0, 0x3d, 0x58,
0x25, 0xf8, 0xb4, 0x8f, 0xd9, 0xff, 0x8a, 0x8a, 0xcf, 0x48, 0x17, 0xff, 0x15, 0x6c, 0xce, 0x2d,
0x9e, 0x44, 0x64, 0x45, 0xb5, 0xcc, 0xa9, 0xe7, 0x42, 0xac, 0x41, 0x62, 0x18, 0x39, 0x94, 0xfc,
0x5a, 0x33, 0xf9, 0xe6, 0xff, 0x92, 0x87, 0x47, 0x81, 0xe6, 0x6f, 0x1f, 0x01, 0x6a, 0x73, 0x11,
0x20, 0x5e, 0xdc, 0xf4, 0x87, 0xe8, 0x18, 0x0e, 0xb6, 0x4e, 0x64, 0x05, 0xa7, 0x04, 0x03, 0x09,
0x9e, 0xb2, 0x4b, 0x27, 0x56, 0x33, 0xd9, 0xd1, 0x17, 0xb0, 0x48, 0x53, 0x75, 0x56, 0x69, 0xbf,
0xee, 0x20, 0x54, 0x86, 0xff, 0x73, 0x01, 0xee, 0x65, 0x23, 0xa7, 0x9d, 0x8d, 0x5f, 0x7b, 0xe7,
0x20, 0xbb, 0x37, 0x7e, 0x78, 0xbd, 0xd1, 0xf6, 0x23, 0x09, 0x3b, 0x09, 0xe5, 0x33, 0xef, 0xd1,
0xea, 0x85, 0x1f, 0xaa, 0x43, 0x0a, 0xc9, 0x1b, 0x0c, 0xec, 0x4c, 0x65, 0xfb, 0xed, 0x0b, 0x2f,
0x56, 0x05, 0xed, 0x68, 0x24, 0x5c, 0x8a, 0x47, 0xc2, 0x3e, 0x20, 0xf5, 0x54, 0x99, 0xb1, 0xc7,
0x89, 0x20, 0xb7, 0x67, 0xc5, 0xf5, 0xc7, 0xb1, 0x49, 0x36, 0xda, 0xf5, 0x41, 0x9c, 0x4d, 0x48,
0x11, 0x45, 0xcf, 0xa0, 0xec, 0x6f, 0x43, 0xc7, 0x18, 0xd9, 0xd8, 0x0b, 0x71, 0x71, 0x22, 0x5f,
0x87, 0x45, 0x7a, 0x07, 0x03, 0x58, 0x3e, 0xaa, 0xf6, 0x46, 0xd5, 0x2e, 0x97, 0x43, 0x1b, 0x50,
0x22, 0x63, 0x48, 0xf5, 0x6e, 0xa7, 0xd9, 0x1b, 0x72, 0xf9, 0x80, 0x20, 0x36, 0x85, 0x37, 0x4d,
0x81, 0x5b, 0x20, 0x77, 0xfb, 0x51, 0xef, 0xa8, 0xda, 0xab, 0xb6, 0x9a, 0x0d, 0xae, 0xc0, 0xff,
0x5f, 0x01, 0xd0, 0xfc, 0xac, 0xc2, 0x6c, 0x7e, 0x60, 0x5a, 0xc1, 0x19, 0x15, 0x52, 0xd0, 0x73,
0xd8, 0x60, 0xad, 0x40, 0xdd, 0xfe, 0xef, 0x3b, 0x12, 0x64, 0x5a, 0x6f, 0xc3, 0xb2, 0x4d, 0xb3,
0x3a, 0x4f, 0xe3, 0x21, 0x01, 0xed, 0x01, 0x67, 0x98, 0x0e, 0xb9, 0x58, 0x9a, 0x96, 0xe6, 0xc8,
0xf4, 0x9d, 0x84, 0x25, 0x5e, 0x73, 0x74, 0xb4, 0x0f, 0x48, 0x35, 0x7b, 0xa6, 0x53, 0xd3, 0x0c,
0x35, 0x1c, 0x96, 0xed, 0x45, 0x4a, 0x0f, 0xc9, 0x5e, 0x14, 0x59, 0xd7, 0xc7, 0xb2, 0xf2, 0xd6,
0xab, 0xf5, 0xb2, 0x63, 0x24, 0x41, 0x45, 0x2f, 0x60, 0xd9, 0x92, 0x8d, 0x09, 0xb6, 0x2b, 0x2b,
0xd4, 0x8a, 0x1f, 0x64, 0x6c, 0x99, 0x40, 0x98, 0x04, 0x8f, 0x17, 0x1d, 0xc2, 0x8a, 0x39, 0x63,
0xcf, 0x4c, 0xec, 0x9e, 0xfa, 0xd1, 0x15, 0x3b, 0xbd, 0xdf, 0x67, 0xec, 0x4d, 0xc3, 0xb1, 0x2e,
0x04, 0x5f, 0x18, 0xd5, 0xa1, 0xc4, 0xde, 0x52, 0xdb, 0xa6, 0xed, 0xd8, 0x95, 0x22, 0xc5, 0x7a,
0x9a, 0x85, 0x15, 0x70, 0x0a, 0x51, 0xa9, 0xdd, 0x2f, 0x60, 0x2d, 0x8a, 0x4e, 0x4e, 0xe2, 0xb7,
0xf8, 0xc2, 0xdb, 0x37, 0xf2, 0x19, 0xaf, 0x88, 0x14, 0xbd, 0x8a, 0xc8, 0x17, 0x0b, 0x9f, 0xe7,
0x79, 0x13, 0x36, 0x12, 0x6b, 0xa4, 0x19, 0x0d, 0xf9, 0xe8, 0x9a, 0xe7, 0x41, 0x91, 0x34, 0x42,
0x09, 0xfa, 0x47, 0xb3, 0x19, 0xf6, 0x23, 0x60, 0x84, 0x12, 0xec, 0x39, 0xcd, 0x4e, 0xa3, 0x7b,
0x4e, 0x08, 0xfc, 0xe7, 0x70, 0x37, 0x6d, 0x45, 0xf4, 0x56, 0x2a, 0x2b, 0xc1, 0xad, 0x54, 0x56,
0x68, 0xd6, 0x37, 0xf3, 0xf0, 0x17, 0xb4, 0x19, 0xbf, 0x02, 0x4b, 0xcd, 0xe9, 0xcc, 0xb9, 0xd8,
0xfb, 0x3c, 0xf2, 0xd3, 0x86, 0xf9, 0x5f, 0x50, 0xa0, 0x15, 0x28, 0xf4, 0xaa, 0x03, 0x2e, 0x87,
0x56, 0x61, 0x71, 0x50, 0xed, 0x8d, 0xb8, 0x3c, 0x5a, 0x86, 0x85, 0x56, 0x8f, 0x5b, 0xd8, 0x7b,
0x05, 0x5b, 0xa9, 0xe5, 0x50, 0xb4, 0x06, 0xab, 0x62, 0xf3, 0x9b, 0x51, 0xb3, 0x57, 0x6f, 0x72,
0x39, 0x82, 0x50, 0xed, 0x35, 0x98, 0x5c, 0x9f, 0xb8, 0x0d, 0x82, 0xf5, 0xe6, 0xb7, 0xd5, 0xfa,
0x50, 0x0a, 0x98, 0x0a, 0x7b, 0x1f, 0x03, 0x97, 0xac, 0x76, 0x12, 0xfe, 0x91, 0x37, 0x72, 0xa3,
0x7f, 0xdc, 0xe3, 0xf2, 0x04, 0xaa, 0x7f, 0x78, 0xc8, 0x2d, 0xec, 0x7d, 0x02, 0x10, 0x56, 0x37,
0x89, 0xd7, 0x0a, 0x1d, 0xb1, 0xd3, 0x6b, 0xb1, 0x7a, 0xdc, 0x61, 0xb5, 0xdb, 0x25, 0x0d, 0x5a,
0x8f, 0xab, 0xf5, 0x87, 0x6d, 0x6e, 0x61, 0xef, 0x63, 0x58, 0x8b, 0x56, 0xc3, 0x08, 0x52, 0xb7,
0x7f, 0xcc, 0xc0, 0xdb, 0x9d, 0x56, 0x9b, 0xcb, 0x13, 0x94, 0x61, 0xbf, 0xd5, 0xea, 0x36, 0xb9,
0x85, 0xbd, 0x06, 0x6c, 0x24, 0x6a, 0x3c, 0x04, 0x78, 0xd4, 0x7b, 0xdd, 0x23, 0x13, 0xc9, 0x91,
0xa9, 0x55, 0x07, 0x6c, 0x42, 0xe2, 0xb0, 0xca, 0x2d, 0xa0, 0x3b, 0xb0, 0x21, 0x0e, 0xab, 0xd2,
0x61, 0xb5, 0xd3, 0xed, 0xbf, 0x69, 0x0a, 0x52, 0x75, 0xc0, 0x15, 0xf6, 0x1a, 0x50, 0x8e, 0x95,
0x3a, 0xd0, 0x16, 0x6c, 0x12, 0xae, 0x5e, 0x7f, 0x28, 0xd5, 0xfb, 0xbd, 0x5e, 0xb3, 0x3e, 0x6c,
0x36, 0xb8, 0x1c, 0x2a, 0xc2, 0x52, 0x75, 0x20, 0x8d, 0x08, 0xe0, 0x26, 0x94, 0x09, 0x47, 0xd8,
0xbb, 0xb0, 0xf7, 0x3e, 0x2b, 0x78, 0xf9, 0x15, 0x23, 0xa2, 0xdd, 0xe3, 0x41, 0xf5, 0x40, 0x1a,
0x88, 0xaf, 0xd9, 0xfc, 0xfb, 0x83, 0x66, 0x8f, 0xcb, 0xef, 0xfd, 0x0d, 0x70, 0xc9, 0x4b, 0x1c,
0x99, 0xdf, 0xf0, 0x88, 0xe8, 0x90, 0x83, 0xb5, 0x5a, 0x55, 0x6c, 0x4b, 0x62, 0x5d, 0xe8, 0x0c,
0x86, 0x22, 0x8b, 0x66, 0x24, 0xd5, 0xf2, 0x09, 0x0b, 0x07, 0xff, 0xf1, 0x19, 0x2c, 0x0f, 0x5e,
0x1c, 0xf7, 0x06, 0x9f, 0xa2, 0x13, 0x78, 0xda, 0xc2, 0xce, 0x15, 0xbf, 0x42, 0x40, 0xf1, 0x33,
0x83, 0x18, 0xd3, 0xee, 0x4d, 0x7e, 0xb7, 0xc4, 0xe7, 0xd0, 0x9f, 0xf3, 0xf0, 0x8c, 0x1d, 0x8c,
0x57, 0x8c, 0x75, 0x13, 0xdc, 0x9b, 0x4e, 0xe2, 0x0d, 0xdc, 0x8b, 0x2e, 0x36, 0xfe, 0x43, 0xa8,
0xb4, 0x45, 0x5e, 0xe7, 0xf7, 0x55, 0x7c, 0x0e, 0x7d, 0x07, 0x0f, 0x12, 0x6b, 0x8b, 0x43, 0x5f,
0x07, 0xe6, 0xba, 0x63, 0x7d, 0x0b, 0xbb, 0x62, 0x64, 0x0d, 0x89, 0xdf, 0x67, 0x3d, 0xbb, 0xce,
0xef, 0xa5, 0x76, 0x53, 0x96, 0xca, 0xe7, 0xd0, 0xef, 0x60, 0x27, 0xb1, 0x8a, 0xf0, 0x60, 0xbb,
0xfc, 0x07, 0x6f, 0xbb, 0x57, 0xf4, 0xf3, 0x39, 0xf4, 0x7b, 0xd8, 0x26, 0xa9, 0x18, 0x9e, 0xc7,
0xfe, 0x28, 0x5d, 0x36, 0x3d, 0x8f, 0xcb, 0x98, 0xfa, 0x6f, 0x61, 0xb7, 0x85, 0x1d, 0x3a, 0x80,
0x3a, 0x3f, 0x42, 0xbc, 0x24, 0x19, 0xab, 0xd8, 0x5d, 0x63, 0xe6, 0x7f, 0x80, 0x87, 0xde, 0x33,
0xc2, 0x8f, 0x02, 0xff, 0x0d, 0x81, 0xd7, 0x31, 0xfb, 0x4d, 0xe4, 0x4d, 0xe1, 0xd3, 0xb5, 0x21,
0xc0, 0x23, 0x0a, 0xe6, 0x27, 0xa2, 0x3f, 0x04, 0xe6, 0x10, 0xee, 0x77, 0x35, 0x3b, 0x53, 0xc5,
0x69, 0xce, 0xf3, 0x38, 0x7b, 0x10, 0x56, 0x0c, 0xcd, 0xa1, 0x23, 0xa8, 0xb4, 0xb0, 0xe3, 0xcf,
0x33, 0x76, 0x05, 0x48, 0x85, 0xbc, 0xec, 0x46, 0xce, 0xe7, 0x50, 0x1b, 0xee, 0x30, 0xac, 0x77,
0x46, 0x3a, 0x84, 0xcd, 0x16, 0x76, 0x12, 0xb7, 0xfa, 0x5b, 0xe0, 0xf4, 0x61, 0x53, 0x9c, 0xc3,
0xb9, 0x4c, 0xe6, 0x2a, 0xc0, 0x5f, 0xc3, 0x7a, 0x0b, 0x3b, 0xd1, 0xca, 0x48, 0xda, 0xac, 0x2a,
0x31, 0x5a, 0x84, 0x9b, 0x21, 0x88, 0x71, 0x84, 0x4c, 0xee, 0x0c, 0x5b, 0x68, 0xc0, 0xda, 0x91,
0xe9, 0x1a, 0xce, 0xe8, 0x48, 0xa4, 0xe9, 0xe8, 0x15, 0xb7, 0xd8, 0x0c, 0x94, 0x01, 0x70, 0xd4,
0x9a, 0x46, 0x62, 0x2d, 0xfc, 0x55, 0x57, 0x8c, 0x33, 0xb3, 0x9e, 0x93, 0x81, 0xf8, 0x0d, 0xdc,
0x0d, 0xa2, 0x40, 0x14, 0xf5, 0x32, 0x6b, 0xbf, 0x42, 0xdd, 0x43, 0x3f, 0x26, 0xfe, 0xa0, 0xa8,
0xaf, 0x09, 0x6a, 0xe8, 0xf3, 0xd7, 0x45, 0x4d, 0x5f, 0x75, 0x17, 0x2a, 0x31, 0x6f, 0x7f, 0x37,
0xb4, 0x1e, 0x6c, 0x85, 0x7e, 0x1e, 0x85, 0xba, 0xa5, 0x87, 0xbf, 0x82, 0x4d, 0x82, 0x37, 0x9a,
0xda, 0x9d, 0xa9, 0x3c, 0xc1, 0x75, 0x76, 0x87, 0xbf, 0x1d, 0x56, 0x1f, 0xb6, 0xa3, 0x58, 0x87,
0xba, 0x6c, 0x9f, 0xaa, 0x16, 0xb9, 0xe4, 0xdc, 0x3a, 0xfc, 0xac, 0xb1, 0xda, 0xa9, 0x77, 0xa7,
0x79, 0x98, 0x5e, 0xd3, 0xf4, 0x8c, 0x70, 0xf7, 0x41, 0x56, 0xb7, 0xed, 0xea, 0x0e, 0x85, 0xdb,
0x88, 0xc2, 0xbd, 0x32, 0xc7, 0x57, 0x21, 0x66, 0x17, 0x51, 0x69, 0x18, 0xdf, 0x6a, 0x77, 0x1a,
0xc4, 0xa2, 0x83, 0xca, 0x2a, 0xab, 0xc3, 0x66, 0x4b, 0x5d, 0x39, 0xc5, 0x26, 0xa0, 0x76, 0xa7,
0x51, 0x97, 0x0d, 0x05, 0xeb, 0xe1, 0x2c, 0x2f, 0x01, 0xcc, 0xb2, 0x92, 0x1d, 0x36, 0x35, 0xaf,
0xee, 0x1c, 0xf0, 0xa7, 0xdb, 0xc9, 0xc3, 0x4c, 0x7c, 0xb2, 0x9f, 0x7c, 0x0e, 0xd5, 0x60, 0x3b,
0x98, 0x56, 0x55, 0xd7, 0xaf, 0x80, 0xcb, 0x4a, 0x5f, 0xb6, 0x62, 0x73, 0xf2, 0x6b, 0xe1, 0x97,
0xad, 0xee, 0xbd, 0x64, 0x57, 0x6a, 0x1d, 0x9d, 0x4e, 0xb0, 0x74, 0x28, 0x06, 0xef, 0x2c, 0x89,
0x6d, 0x4d, 0xbe, 0xbf, 0x64, 0x4c, 0xf0, 0x35, 0xc0, 0xa1, 0xe8, 0x3f, 0xf9, 0xa0, 0xf8, 0x4e,
0x25, 0xde, 0xa5, 0x12, 0x1a, 0x4b, 0xbe, 0x13, 0xd1, 0x1d, 0x28, 0x1f, 0x8a, 0x2d, 0xec, 0xf8,
0xaf, 0x23, 0x09, 0xbc, 0xc4, 0xdb, 0x4a, 0x02, 0x2f, 0xf9, 0xa4, 0xc2, 0xe7, 0xd0, 0x1f, 0x61,
0xeb, 0x50, 0xac, 0x5b, 0x58, 0x76, 0x70, 0xec, 0x75, 0x0d, 0x25, 0x7e, 0x2f, 0x98, 0xf2, 0xb6,
0xb7, 0xcb, 0x5f, 0xc6, 0x12, 0x8c, 0xf0, 0x6b, 0x28, 0xd1, 0xf7, 0xc2, 0x2e, 0x2d, 0x75, 0x24,
0x76, 0x25, 0xfa, 0x28, 0x9a, 0x54, 0x1f, 0xe9, 0xe2, 0x73, 0x3f, 0xcb, 0xa3, 0x16, 0x94, 0x9a,
0xca, 0x69, 0xf0, 0x5e, 0x74, 0x59, 0x70, 0xbb, 0xa4, 0x8f, 0xcf, 0xa1, 0x0e, 0x20, 0x16, 0x2d,
0x63, 0x3f, 0x2f, 0xc8, 0x7e, 0x50, 0xde, 0xdd, 0x4e, 0x7f, 0xd4, 0xe6, 0x73, 0xe8, 0x4b, 0x58,
0x6b, 0x61, 0x27, 0x7c, 0x0c, 0x4f, 0xb3, 0xd7, 0x6c, 0xe9, 0x43, 0x16, 0xd1, 0xb0, 0x11, 0x10,
0xeb, 0xa7, 0xac, 0x50, 0x72, 0x33, 0x1c, 0x01, 0x36, 0x69, 0xc4, 0x3e, 0xd6, 0x4e, 0xc2, 0xf5,
0x7c, 0x90, 0x60, 0xcf, 0xfa, 0x0d, 0x47, 0xe6, 0xf9, 0xbc, 0x15, 0x9c, 0xa6, 0x31, 0xdc, 0xcb,
0xf4, 0x9e, 0xad, 0x43, 0x8a, 0x58, 0x89, 0x1e, 0xa6, 0xd7, 0x06, 0xcd, 0x5e, 0x77, 0x97, 0x20,
0x86, 0x07, 0xe9, 0xb5, 0x11, 0xd3, 0x57, 0x7c, 0x04, 0xf7, 0x62, 0x27, 0xe9, 0x3b, 0xc2, 0x79,
0xc7, 0x55, 0xca, 0xd4, 0x6e, 0x79, 0x5c, 0x49, 0xf0, 0x98, 0x4d, 0x2d, 0xbb, 0xfe, 0x7b, 0xcd,
0x5a, 0x72, 0xc6, 0x8c, 0x4d, 0xf8, 0xa0, 0x85, 0x9d, 0xaa, 0xae, 0x5f, 0x5d, 0xc2, 0x4e, 0x5b,
0xc2, 0x7e, 0xbc, 0xfe, 0x76, 0x15, 0x06, 0x9f, 0x43, 0x3a, 0x3c, 0x8b, 0xe4, 0xff, 0xd9, 0xa3,
0x5d, 0xa6, 0xfc, 0x6b, 0x2e, 0x99, 0xcf, 0x21, 0xc5, 0xbb, 0x17, 0x65, 0x8f, 0x93, 0x5e, 0x1c,
0xbf, 0x91, 0xdb, 0x7c, 0x07, 0x7c, 0xe0, 0x36, 0x3f, 0xf6, 0x82, 0x7e, 0x03, 0xef, 0x45, 0x1d,
0xea, 0x76, 0xc3, 0xa5, 0x2f, 0x83, 0x42, 0x87, 0x9e, 0xf5, 0x43, 0x42, 0xff, 0x1e, 0x7e, 0x12,
0xfa, 0xc5, 0xcd, 0x2c, 0xec, 0x1a, 0x4e, 0x22, 0xc0, 0xfd, 0x88, 0x49, 0xcd, 0xfd, 0xb9, 0xc3,
0xd5, 0xe9, 0x49, 0x52, 0x84, 0x3a, 0x9e, 0x57, 0x02, 0x48, 0xf6, 0x09, 0x78, 0xa6, 0xcb, 0x4a,
0x32, 0x1f, 0x48, 0x72, 0x5d, 0x3d, 0xc0, 0xef, 0xe0, 0x5e, 0xfa, 0x00, 0x55, 0x55, 0x7d, 0x67,
0xf0, 0xbf, 0xf5, 0xab, 0x53, 0xf3, 0xb3, 0x9f, 0x9a, 0x67, 0xf8, 0xc7, 0xc3, 0x1f, 0xcd, 0x54,
0x72, 0x24, 0xbe, 0x2b, 0x7e, 0xac, 0xf4, 0x90, 0xec, 0xbf, 0xb5, 0x9d, 0x74, 0x61, 0x8b, 0x22,
0xce, 0x59, 0xc8, 0x15, 0xd3, 0x4d, 0xb7, 0xe9, 0x31, 0xfc, 0x24, 0xea, 0x89, 0x59, 0x76, 0x72,
0x99, 0xb3, 0x5c, 0x43, 0xcf, 0x8f, 0x2f, 0x1b, 0x83, 0x98, 0xca, 0x3b, 0xe1, 0x0f, 0xc8, 0x3e,
0x86, 0x2e, 0x3f, 0xa7, 0x98, 0x9b, 0x7b, 0xfa, 0x37, 0xb0, 0x73, 0x2c, 0x6b, 0x4e, 0xda, 0x0f,
0xc0, 0xaf, 0xfc, 0x93, 0x8a, 0x0c, 0xc8, 0x0e, 0xdc, 0x39, 0xd4, 0x2c, 0x3c, 0xf7, 0xc3, 0xd6,
0xcb, 0x7e, 0x7d, 0x9f, 0x09, 0x75, 0x97, 0xe9, 0x33, 0xf1, 0xf7, 0xdb, 0x97, 0xfd, 0x79, 0x71,
0x06, 0xd4, 0x1b, 0xb8, 0x43, 0x95, 0x96, 0x40, 0xfa, 0x69, 0x22, 0x8b, 0xcf, 0xfe, 0x4b, 0xe8,
0xcc, 0xaa, 0xdb, 0x4e, 0x70, 0x98, 0x24, 0xb0, 0xaf, 0x5f, 0x7e, 0x88, 0x0b, 0xf2, 0x39, 0x74,
0x0c, 0xbb, 0x51, 0x43, 0xfa, 0xe1, 0x80, 0x7b, 0x04, 0x38, 0xb4, 0xa0, 0x1b, 0x00, 0x67, 0xd9,
0x4f, 0x25, 0xf4, 0xfc, 0x04, 0xda, 0xad, 0xdd, 0xbe, 0x42, 0x35, 0x2a, 0x5b, 0x8e, 0x3b, 0xbb,
0x06, 0xe4, 0xe5, 0x17, 0x89, 0x2e, 0x54, 0xc4, 0x2c, 0xb4, 0x9b, 0x2f, 0xf7, 0x4b, 0x58, 0x6d,
0xd4, 0x6a, 0xb2, 0xf2, 0xd6, 0x9d, 0xdd, 0x42, 0xfa, 0x2b, 0x28, 0x36, 0x6a, 0x02, 0xb6, 0x89,
0xb2, 0x6e, 0x95, 0xfc, 0xde, 0x0d, 0x75, 0x1d, 0x5c, 0x92, 0x6f, 0x1d, 0x5e, 0x63, 0x75, 0xa4,
0xf0, 0x0f, 0x0a, 0xde, 0x21, 0x5c, 0xdf, 0x09, 0xf1, 0x7c, 0x2d, 0xbd, 0x4b, 0x55, 0x8a, 0x24,
0xba, 0xfe, 0xdf, 0x73, 0xb6, 0x66, 0x9a, 0x79, 0x6b, 0xac, 0x17, 0xb0, 0x2a, 0x9e, 0xba, 0x8e,
0x6a, 0x9e, 0x1b, 0x37, 0xa8, 0x56, 0x1c, 0xc0, 0xb2, 0x80, 0xc7, 0xa6, 0xe9, 0x5c, 0x5f, 0x66,
0xbc, 0x4c, 0xff, 0xff, 0xc4, 0xcf, 0xff, 0x3f, 0x00, 0x00, 0xff, 0xff, 0x24, 0xd9, 0x58, 0xc6,
0x8d, 0x42, 0x00, 0x00,
0x72, 0x06, 0x08, 0x3e, 0x80, 0x04, 0x41, 0x36, 0x6b, 0x86, 0x24, 0x86, 0xf3, 0xee, 0x1d, 0x49,
0xb3, 0x94, 0x44, 0xad, 0xb8, 0xb3, 0x23, 0xad, 0x56, 0xb2, 0x16, 0x2f, 0x02, 0x98, 0x01, 0x01,
0xa8, 0x1b, 0x18, 0x6a, 0x5f, 0xee, 0x6d, 0x74, 0x17, 0xc1, 0xd6, 0x34, 0xba, 0xe1, 0x7e, 0x90,
0xa2, 0x1d, 0xb1, 0x11, 0xde, 0x08, 0x47, 0xec, 0xc1, 0x77, 0x1f, 0x7c, 0xf5, 0xd5, 0xbe, 0xf9,
0x67, 0xf8, 0x87, 0xf8, 0xb2, 0x37, 0x5f, 0x7c, 0xb1, 0xa3, 0xaa, 0xfa, 0x09, 0x74, 0x83, 0x8f,
0x91, 0x6e, 0x5d, 0x59, 0x99, 0x5f, 0x55, 0x65, 0x65, 0x66, 0x65, 0x65, 0x81, 0x04, 0x18, 0x5b,
0x53, 0xe5, 0x60, 0x6a, 0x99, 0x8e, 0x89, 0x8a, 0xfd, 0x17, 0x17, 0x46, 0xff, 0x53, 0x89, 0x90,
0xf8, 0x7f, 0x5d, 0x82, 0x8d, 0x63, 0xd9, 0x76, 0xb0, 0x35, 0xc0, 0x93, 0xa9, 0x2e, 0x3b, 0x18,
0xbd, 0x84, 0x5d, 0xc7, 0xfb, 0x96, 0x0c, 0x79, 0x82, 0xa5, 0x91, 0xee, 0x62, 0xc7, 0x34, 0x9d,
0xb3, 0x72, 0xf6, 0x49, 0xf6, 0x79, 0x41, 0xd8, 0xf6, 0xbb, 0xbb, 0xf2, 0x04, 0x57, 0xfd, 0x4e,
0xb4, 0x0f, 0x5b, 0x71, 0x39, 0xd7, 0x1e, 0x95, 0x97, 0xa8, 0xc4, 0x66, 0x54, 0x62, 0x68, 0x8f,
0xd0, 0x47, 0x80, 0xe2, 0xbc, 0x17, 0xda, 0xa9, 0x56, 0xce, 0x51, 0x66, 0x2e, 0xca, 0x7c, 0xa2,
0x9d, 0x6a, 0xa8, 0x02, 0x0f, 0xe3, 0xdc, 0x8e, 0xa5, 0x8d, 0xc7, 0xd8, 0x92, 0x64, 0xc5, 0xd1,
0x4c, 0xc3, 0x2e, 0x2f, 0x53, 0xc1, 0xbd, 0xa8, 0xe0, 0x80, 0xb1, 0x54, 0x18, 0x07, 0x7a, 0x01,
0x3b, 0x31, 0x08, 0x5b, 0x32, 0xb0, 0x73, 0x61, 0x5a, 0x6f, 0xcb, 0x2b, 0x4f, 0x72, 0xcf, 0x0b,
0xc2, 0xdd, 0xa8, 0xac, 0xdd, 0x65, 0x7d, 0xfc, 0x3f, 0xc0, 0x03, 0x01, 0xff, 0x9d, 0x8b, 0x6d,
0x27, 0xae, 0x23, 0xd1, 0x31, 0x2d, 0x79, 0x8c, 0x11, 0x0f, 0xeb, 0x83, 0x88, 0x9c, 0xa7, 0x9f,
0x18, 0x0d, 0x7d, 0x06, 0x79, 0x1f, 0x9b, 0x6a, 0xa3, 0x78, 0x78, 0xff, 0x20, 0xb2, 0x03, 0x07,
0x71, 0x64, 0x21, 0x60, 0xe6, 0xff, 0x31, 0x0b, 0x8f, 0x03, 0xed, 0x7a, 0xd3, 0x10, 0xb1, 0xe3,
0x68, 0xc6, 0xd8, 0xbe, 0xc9, 0x04, 0xbe, 0x80, 0xbc, 0xed, 0x89, 0x79, 0x13, 0x78, 0x14, 0x9b,
0x40, 0x30, 0x86, 0x0f, 0x2e, 0x04, 0xfc, 0xfc, 0x3f, 0x65, 0x61, 0x6b, 0xae, 0x1f, 0xfd, 0x0a,
0x96, 0x14, 0x8d, 0x8e, 0x55, 0x3c, 0xfc, 0x30, 0x19, 0xab, 0x66, 0x1a, 0x8e, 0x65, 0xea, 0x3a,
0xb6, 0xda, 0xc6, 0xa9, 0x69, 0x4d, 0x64, 0xb2, 0x0d, 0xc2, 0x92, 0xa2, 0xa1, 0x9f, 0xc3, 0x92,
0xec, 0x4f, 0xe4, 0x27, 0xc9, 0xc2, 0x95, 0x31, 0x36, 0x82, 0xa5, 0x0a, 0x4b, 0xb2, 0xcd, 0xef,
0xc3, 0x4e, 0x72, 0x2f, 0xe2, 0x20, 0x37, 0xd5, 0x0c, 0x6f, 0xe1, 0xe4, 0x93, 0xff, 0xdf, 0x2c,
0xec, 0x06, 0xcc, 0xde, 0x4e, 0x8a, 0xd8, 0x3a, 0xd7, 0x14, 0x4c, 0xcc, 0xc0, 0xc2, 0x63, 0x8d,
0x68, 0x5c, 0x32, 0x2d, 0xc9, 0x35, 0xfc, 0x16, 0x05, 0xc8, 0x0b, 0x77, 0xfd, 0x76, 0xcf, 0x1a,
0x06, 0x7d, 0xc4, 0xb2, 0x6d, 0x6c, 0x9d, 0x33, 0x19, 0xc5, 0x34, 0x0c, 0xac, 0x38, 0x74, 0x05,
0x79, 0x61, 0x93, 0x75, 0xf4, 0xac, 0x1a, 0x23, 0xa3, 0x2f, 0x61, 0xd9, 0xb9, 0x9c, 0x62, 0x6a,
0xcb, 0x1b, 0x87, 0xcf, 0x93, 0x17, 0x18, 0x9f, 0xd5, 0xe0, 0x72, 0x8a, 0x05, 0x2a, 0x85, 0x1e,
0x41, 0x71, 0x22, 0x2b, 0x64, 0x18, 0x62, 0xa4, 0x9e, 0x5d, 0x17, 0x26, 0xb2, 0xd2, 0xb3, 0xe8,
0x5e, 0x3e, 0x86, 0xe2, 0xc8, 0xd2, 0xd4, 0x31, 0x33, 0xe2, 0xf2, 0x0a, 0xed, 0x07, 0x46, 0x22,
0x0c, 0xfc, 0x7f, 0x2f, 0xc3, 0xfd, 0x84, 0x4d, 0x08, 0xd4, 0x55, 0x86, 0xb5, 0xa9, 0x79, 0x81,
0x2d, 0xac, 0x7a, 0x2b, 0xf6, 0x9b, 0xe8, 0x09, 0x14, 0xbd, 0xa5, 0xc9, 0x23, 0x1d, 0x7b, 0xcb,
0x8b, 0x92, 0xd0, 0x4f, 0x81, 0x3b, 0x95, 0x6d, 0x47, 0x8a, 0xb2, 0xe5, 0x98, 0x16, 0x08, 0xbd,
0x16, 0x61, 0xe5, 0x61, 0x5d, 0xd5, 0x6c, 0xc5, 0x3c, 0xc7, 0x16, 0x65, 0x5b, 0xa6, 0x6c, 0x31,
0x1a, 0xda, 0x83, 0xfc, 0xc8, 0x34, 0x54, 0xda, 0xbf, 0x42, 0xfb, 0x83, 0x36, 0x3a, 0x80, 0x3b,
0xba, 0x66, 0xbc, 0x95, 0x74, 0x7c, 0x8e, 0x75, 0xc9, 0xc6, 0x8a, 0x6b, 0x69, 0xce, 0x65, 0x79,
0x95, 0xb2, 0x6d, 0x91, 0xae, 0x0e, 0xe9, 0x11, 0xbd, 0x0e, 0x74, 0x08, 0xdb, 0x94, 0x09, 0x4b,
0xb6, 0x36, 0x99, 0xea, 0x58, 0x9a, 0xca, 0x9a, 0xa5, 0x19, 0xe3, 0xf2, 0x1a, 0x95, 0xb8, 0xc3,
0x3a, 0x45, 0xda, 0xd7, 0x67, 0x5d, 0x68, 0x1b, 0x56, 0x47, 0x96, 0x84, 0x55, 0xab, 0x9c, 0xa7,
0x4c, 0x2b, 0x23, 0xab, 0xa1, 0x5a, 0xe8, 0x21, 0xc0, 0x99, 0x36, 0x3e, 0x93, 0xec, 0x29, 0xc6,
0x6a, 0xb9, 0x40, 0xbb, 0x0a, 0x84, 0x22, 0x12, 0x02, 0xe9, 0xd6, 0xcd, 0x0b, 0x09, 0x1b, 0xd8,
0x1a, 0x5f, 0x96, 0x81, 0x75, 0xeb, 0xe6, 0x45, 0x83, 0x12, 0x88, 0x16, 0x65, 0xf5, 0x1c, 0x5b,
0x8e, 0x66, 0x93, 0xe1, 0x8b, 0x4c, 0x8b, 0x11, 0x12, 0xfa, 0x18, 0x90, 0x37, 0x55, 0x4f, 0x8f,
0x34, 0x82, 0xad, 0xb3, 0x95, 0xb1, 0x9e, 0x5a, 0xd8, 0x41, 0xc6, 0x53, 0xf1, 0xc8, 0x1d, 0x4b,
0x6f, 0xf1, 0xa5, 0x5d, 0x2e, 0xb1, 0xf1, 0x28, 0xe5, 0x35, 0xbe, 0x64, 0xfb, 0x69, 0x69, 0xe7,
0xb2, 0x72, 0x59, 0xde, 0xf0, 0xf6, 0x93, 0x35, 0xd1, 0x2f, 0xa1, 0xac, 0x04, 0xfb, 0x4f, 0xc6,
0x3a, 0xd5, 0xc6, 0xae, 0x45, 0xfd, 0xb0, 0xbc, 0x49, 0x59, 0x77, 0xc3, 0xfe, 0x5a, 0xb4, 0x1b,
0xbd, 0x07, 0x1b, 0xb6, 0x23, 0x3b, 0x9a, 0x22, 0xc9, 0xaa, 0x6a, 0x61, 0xdb, 0x2e, 0x73, 0x54,
0xa0, 0xc4, 0xa8, 0x15, 0x46, 0xe4, 0xff, 0xba, 0x0c, 0x8f, 0x16, 0x3b, 0x3c, 0x99, 0x9e, 0x0f,
0x41, 0xcc, 0x6d, 0x5d, 0xf0, 0x9b, 0xe8, 0x43, 0xd8, 0x0a, 0xce, 0x15, 0xe9, 0x1c, 0x5b, 0x36,
0x99, 0x17, 0x31, 0xba, 0x92, 0xc0, 0x05, 0x1d, 0x6f, 0x18, 0x9d, 0x98, 0xd3, 0x44, 0x36, 0xdc,
0x53, 0x59, 0x71, 0x5c, 0x0b, 0x5b, 0xd4, 0xea, 0x4a, 0x42, 0x8c, 0x86, 0x4e, 0x00, 0xd9, 0xee,
0x74, 0x6a, 0x5a, 0x0e, 0x56, 0xa5, 0x20, 0xe0, 0x2d, 0xd3, 0x38, 0xf3, 0xfc, 0xaa, 0x20, 0x15,
0x04, 0x9b, 0xad, 0x00, 0x23, 0x70, 0x19, 0x11, 0x38, 0xc5, 0xb5, 0x2c, 0x6c, 0x38, 0x21, 0xec,
0xca, 0x0d, 0x61, 0x37, 0x3d, 0x84, 0x00, 0xf4, 0x7d, 0xd8, 0x54, 0x74, 0xd9, 0xb6, 0x25, 0xf3,
0x54, 0x52, 0x31, 0x89, 0x02, 0xd4, 0xb8, 0xd7, 0x85, 0x12, 0x25, 0xf7, 0x4e, 0xeb, 0x94, 0x88,
0x10, 0x2c, 0x53, 0x4f, 0x5f, 0xa3, 0x9e, 0x4e, 0xbf, 0x89, 0x49, 0xd8, 0x67, 0xa6, 0xe5, 0xb0,
0x18, 0x90, 0x67, 0x31, 0x82, 0x52, 0x68, 0x8c, 0x78, 0x0a, 0xeb, 0x9a, 0x2d, 0xc9, 0xe7, 0xb2,
0xa6, 0x53, 0xdf, 0x62, 0x26, 0x5c, 0xd4, 0xec, 0x8a, 0x4f, 0x42, 0xbf, 0x82, 0x3d, 0x9b, 0xc5,
0x1e, 0xff, 0x18, 0x94, 0xbc, 0x00, 0x67, 0xc8, 0x53, 0xcf, 0xa8, 0x77, 0x3d, 0x8e, 0x48, 0xac,
0xc2, 0x56, 0x57, 0x9e, 0xa2, 0xaf, 0xe0, 0x7e, 0x8a, 0xf0, 0x54, 0x36, 0x5c, 0xcf, 0xe4, 0xcb,
0x49, 0xd2, 0x7d, 0xd9, 0x70, 0xd1, 0x2f, 0xe1, 0x5e, 0x8a, 0xf8, 0xd8, 0xf0, 0xdc, 0x60, 0x27,
0x49, 0xb8, 0x69, 0xf0, 0xdf, 0x01, 0x17, 0x3b, 0xd6, 0x45, 0xec, 0xa0, 0x2a, 0x6c, 0xc4, 0x8f,
0xfa, 0x72, 0xf6, 0x49, 0xee, 0x79, 0xf1, 0x70, 0x2f, 0xb6, 0x37, 0x31, 0x16, 0x61, 0x46, 0x82,
0x28, 0x99, 0x9e, 0x9e, 0x2c, 0x59, 0xa1, 0xdf, 0xfc, 0xbf, 0x03, 0x94, 0x62, 0x6c, 0x68, 0x03,
0x96, 0x34, 0x16, 0x35, 0x4b, 0xc2, 0x92, 0xa6, 0x12, 0xdb, 0x36, 0x0d, 0x2c, 0x9e, 0x99, 0xfe,
0x59, 0xe0, 0x37, 0x49, 0x64, 0xd3, 0x6c, 0x22, 0x75, 0xee, 0x07, 0xc8, 0xa0, 0x8d, 0x1e, 0x40,
0x41, 0x9b, 0x4c, 0x5c, 0x27, 0x12, 0x16, 0x43, 0x02, 0xea, 0xc0, 0x86, 0xb7, 0x76, 0xd1, 0x91,
0x89, 0x15, 0x7a, 0x96, 0xc6, 0x27, 0xad, 0x46, 0x8c, 0x71, 0xb6, 0x32, 0xc2, 0x8c, 0x2c, 0xfa,
0x16, 0x90, 0x6b, 0x8f, 0x9a, 0xb2, 0x3a, 0xc6, 0x7e, 0x74, 0xc6, 0x2a, 0xb5, 0xb3, 0xe2, 0xe1,
0xfb, 0x49, 0x88, 0x43, 0xb1, 0x3a, 0xc3, 0xdd, 0xca, 0x08, 0x09, 0x18, 0x48, 0x86, 0xed, 0x80,
0x5a, 0x27, 0x41, 0xdd, 0x07, 0x5f, 0xa3, 0xe0, 0x3f, 0x5d, 0x08, 0x1e, 0x15, 0x68, 0x65, 0x84,
0x64, 0x24, 0xd4, 0x86, 0x12, 0x49, 0x0a, 0x2b, 0x7d, 0x5f, 0x13, 0x79, 0x0a, 0xfd, 0x34, 0x09,
0xfa, 0x24, 0xca, 0xd8, 0xca, 0x08, 0x71, 0x49, 0xa2, 0x07, 0x42, 0x08, 0xa6, 0x5f, 0xb1, 0x45,
0x47, 0xa6, 0x7e, 0x91, 0xa2, 0x87, 0x93, 0x39, 0x6e, 0xa2, 0x87, 0x79, 0x0c, 0x9a, 0x5b, 0xd9,
0x67, 0x1d, 0x73, 0xac, 0x19, 0xd4, 0x6d, 0x8a, 0x87, 0x0f, 0x12, 0x77, 0x4a, 0x6c, 0x51, 0x9e,
0x56, 0x46, 0x08, 0xf8, 0x91, 0x00, 0x9c, 0x7a, 0xa6, 0x4c, 0x3b, 0x58, 0xb6, 0x71, 0xd3, 0x92,
0x0d, 0xb2, 0xc6, 0x22, 0xc5, 0x78, 0x96, 0x84, 0x51, 0x6f, 0xd5, 0xfa, 0x51, 0xde, 0x56, 0x46,
0x98, 0x93, 0x47, 0x47, 0xb0, 0x3e, 0xb6, 0x4c, 0x77, 0x2a, 0x60, 0x05, 0x13, 0xeb, 0x5b, 0xa7,
0x78, 0x4f, 0x92, 0xf0, 0x9a, 0x11, 0xbe, 0x56, 0x46, 0x88, 0xc9, 0xa1, 0x21, 0x6c, 0x45, 0xdb,
0xc7, 0xae, 0xee, 0x68, 0xf4, 0xf0, 0x29, 0x1e, 0xbe, 0x77, 0x15, 0x18, 0x65, 0x6e, 0x65, 0x84,
0x79, 0x04, 0xf4, 0x02, 0x56, 0xc7, 0x53, 0xcd, 0x6c, 0x1b, 0xf4, 0xb0, 0x4a, 0x71, 0xd2, 0x66,
0xbf, 0xdd, 0x6b, 0x13, 0x55, 0x79, 0xbc, 0xa8, 0x0e, 0x30, 0x92, 0xed, 0x33, 0x51, 0xb1, 0xb4,
0xa9, 0x43, 0xcf, 0xae, 0x59, 0x87, 0xf0, 0xc2, 0x01, 0xd9, 0xee, 0x6a, 0xc0, 0xd9, 0xca, 0x0a,
0x11, 0x39, 0x54, 0x81, 0xc2, 0x99, 0xa6, 0x7a, 0x20, 0x5c, 0x82, 0x2d, 0x45, 0x40, 0x5a, 0xed,
0x7a, 0x80, 0x11, 0x4a, 0x21, 0x05, 0x76, 0x54, 0x3c, 0xd5, 0xcd, 0x4b, 0x3f, 0x8c, 0xfb, 0x79,
0x76, 0x79, 0x2b, 0xc1, 0xec, 0x19, 0x5e, 0x3d, 0x51, 0xa0, 0x95, 0x15, 0x52, 0xa0, 0xd0, 0x3e,
0xe4, 0x74, 0x73, 0x5c, 0x46, 0x14, 0x71, 0x27, 0x01, 0xb1, 0x63, 0x8e, 0x5b, 0x59, 0x81, 0x30,
0xa1, 0x97, 0xb0, 0x46, 0x74, 0xd4, 0x73, 0x9d, 0xf2, 0x9d, 0x04, 0x85, 0x32, 0x7e, 0xa2, 0xcf,
0x9e, 0x4b, 0x96, 0xe2, 0x33, 0xa3, 0x2f, 0xa1, 0x40, 0x37, 0x47, 0xc4, 0x86, 0x5a, 0xbe, 0x9b,
0x60, 0xb7, 0x9e, 0xa4, 0xcf, 0x43, 0xd4, 0x10, 0x08, 0x54, 0x0b, 0xb0, 0xe6, 0x6d, 0x55, 0x35,
0x0f, 0xab, 0x8c, 0x95, 0xdf, 0x85, 0xed, 0xc4, 0xb0, 0xc4, 0xdf, 0x87, 0x7b, 0xa9, 0xd1, 0x85,
0x7f, 0x04, 0x0f, 0x16, 0x45, 0x07, 0x7e, 0x07, 0xee, 0x26, 0xb9, 0x78, 0x04, 0x74, 0xde, 0x55,
0xf9, 0x4f, 0x60, 0x73, 0xc6, 0xef, 0x48, 0xd4, 0xd5, 0xc9, 0xc7, 0xd0, 0xf6, 0x52, 0xfd, 0x82,
0x10, 0x12, 0xf8, 0x7b, 0xb0, 0x9b, 0xe2, 0x64, 0x7c, 0x1b, 0xee, 0x24, 0x98, 0x38, 0xc1, 0xa3,
0xfa, 0x88, 0x5c, 0xba, 0x42, 0x02, 0xba, 0x0b, 0x2b, 0xe7, 0xb2, 0xee, 0xb2, 0x03, 0x65, 0x45,
0x60, 0x0d, 0xfe, 0x2f, 0x59, 0x28, 0xa7, 0xb9, 0xcb, 0x15, 0x80, 0x3b, 0xb0, 0x4a, 0x31, 0xec,
0x72, 0xee, 0x49, 0xee, 0xf9, 0x8a, 0xe0, 0xb5, 0xd0, 0x4b, 0xef, 0xb2, 0xb1, 0x4c, 0x2f, 0x1b,
0x71, 0x9f, 0x98, 0x1b, 0x23, 0xbc, 0x66, 0xf0, 0xff, 0x95, 0x0d, 0x0e, 0x37, 0xe6, 0x6d, 0xe8,
0x3e, 0x14, 0x88, 0x71, 0xb0, 0x94, 0x82, 0x8d, 0x9f, 0x27, 0x04, 0x3a, 0xfc, 0x57, 0x00, 0x53,
0x57, 0xd7, 0x87, 0xd3, 0xba, 0x79, 0xc1, 0x92, 0xb4, 0x8d, 0xc3, 0x87, 0xf1, 0xc1, 0x28, 0x4a,
0x3f, 0x60, 0x12, 0x22, 0x02, 0xe8, 0x33, 0x00, 0xe6, 0xc9, 0x0d, 0x75, 0xec, 0x5f, 0x8c, 0x76,
0x13, 0xc4, 0x49, 0xb7, 0x10, 0x61, 0x45, 0x1f, 0xc0, 0xa6, 0x8a, 0x47, 0xa6, 0x6b, 0x28, 0x58,
0x9a, 0x68, 0xba, 0xae, 0xb1, 0x7c, 0x2e, 0x27, 0x6c, 0xf8, 0xe4, 0x63, 0x4a, 0xe5, 0x3f, 0x83,
0xed, 0xc4, 0x10, 0x80, 0x1e, 0x01, 0xd8, 0xf4, 0x2b, 0xa2, 0xd7, 0x08, 0x85, 0x7f, 0x09, 0x77,
0x93, 0xdc, 0xfe, 0x4a, 0xb9, 0xff, 0xc9, 0xc2, 0x83, 0x45, 0xfe, 0x4d, 0x32, 0x56, 0x27, 0xe1,
0x62, 0x1e, 0xa5, 0xa1, 0x57, 0xde, 0xee, 0x31, 0x85, 0xbe, 0xbc, 0x76, 0xf0, 0x38, 0xf0, 0x3f,
0x22, 0x3b, 0x8a, 0xc3, 0x42, 0x00, 0xa1, 0xa2, 0x2d, 0x28, 0x1d, 0x0d, 0x3b, 0x1d, 0x49, 0x6c,
0x0c, 0x06, 0xed, 0x6e, 0x53, 0xe4, 0x32, 0xa8, 0x08, 0x6b, 0xdd, 0xc6, 0xe0, 0xa4, 0x27, 0xbc,
0xe6, 0xb2, 0x28, 0x0f, 0xcb, 0x27, 0xed, 0xa3, 0x36, 0xb7, 0x84, 0xd6, 0x20, 0x37, 0x14, 0xab,
0x5c, 0x0e, 0x95, 0xa0, 0x50, 0xed, 0x0c, 0x1b, 0x83, 0x5e, 0x6f, 0xd0, 0xe2, 0x96, 0xd1, 0x1d,
0xd8, 0x1c, 0x08, 0xed, 0x66, 0xb3, 0x21, 0x48, 0x95, 0xda, 0xa0, 0xdd, 0xeb, 0x8a, 0xdc, 0x0a,
0x5f, 0x84, 0x42, 0x10, 0x84, 0xf8, 0x3f, 0x40, 0x29, 0x16, 0x61, 0x16, 0x1b, 0xd1, 0x27, 0x51,
0xa7, 0xd8, 0x38, 0xbc, 0x37, 0x67, 0x00, 0x3d, 0xd7, 0x79, 0x43, 0x18, 0x7c, 0x7f, 0x69, 0xc0,
0xe6, 0x4c, 0x18, 0xba, 0x95, 0xdb, 0x5d, 0xc0, 0x1e, 0x89, 0x11, 0xef, 0x50, 0x40, 0xf9, 0xc5,
0x5c, 0x01, 0x25, 0x3e, 0xf9, 0x13, 0xed, 0x48, 0x4b, 0xa8, 0x9d, 0xfc, 0x4b, 0x0e, 0xd6, 0xa3,
0x5d, 0x41, 0x2e, 0x9f, 0x8d, 0xe4, 0xf2, 0x7b, 0x90, 0x57, 0x35, 0x9b, 0xe4, 0x7e, 0xaa, 0x97,
0x45, 0x06, 0x6d, 0x62, 0x84, 0x16, 0x1e, 0xbb, 0xba, 0xec, 0x98, 0xd6, 0xa5, 0x57, 0x1c, 0x8b,
0x50, 0xd0, 0xd7, 0xb0, 0x4e, 0xd2, 0x63, 0xcd, 0x18, 0x4b, 0x13, 0x53, 0xf5, 0xa3, 0xc0, 0x83,
0xb9, 0xb9, 0x9d, 0x30, 0xa6, 0x63, 0x53, 0xc5, 0x42, 0xf1, 0x22, 0x6c, 0xa0, 0x97, 0x50, 0x90,
0x5d, 0xe7, 0x8c, 0x49, 0xaf, 0x24, 0x6c, 0x0b, 0x91, 0xae, 0xb8, 0xce, 0x19, 0x15, 0xcd, 0xcb,
0xde, 0x17, 0xc9, 0x7c, 0x95, 0x33, 0xd9, 0x30, 0xb0, 0x4e, 0x93, 0xc9, 0x92, 0xe0, 0x37, 0xd1,
0x01, 0xac, 0xca, 0x53, 0xa9, 0x2a, 0x8a, 0x5e, 0x22, 0xb8, 0x3b, 0x07, 0x57, 0x15, 0xc5, 0xda,
0xe9, 0x58, 0x58, 0x91, 0xa7, 0x55, 0x51, 0x44, 0x5f, 0x93, 0x6b, 0x90, 0x46, 0xae, 0x56, 0x55,
0x51, 0x94, 0x74, 0xcd, 0x76, 0xca, 0x79, 0x9a, 0xbe, 0xa7, 0x0a, 0x96, 0x18, 0x7f, 0x55, 0x14,
0x3b, 0x9a, 0x4d, 0x4d, 0xee, 0x4c, 0x53, 0xb1, 0x64, 0xdb, 0x9a, 0x7f, 0x59, 0xcf, 0x13, 0x82,
0x68, 0x6b, 0x2a, 0x09, 0x9b, 0x06, 0xfe, 0x7e, 0x62, 0x1a, 0xde, 0xbd, 0xd9, 0x6b, 0xf1, 0xff,
0x91, 0x85, 0x02, 0xdd, 0x19, 0x87, 0xb8, 0xea, 0x01, 0x2c, 0x53, 0x05, 0x64, 0xa9, 0x02, 0xf6,
0xe6, 0xb7, 0x96, 0x70, 0x51, 0x0d, 0x50, 0xbe, 0xe8, 0xea, 0x97, 0xe2, 0xab, 0x47, 0xb0, 0x4c,
0xe7, 0xc1, 0xb6, 0x8a, 0x7e, 0xa3, 0x1a, 0xcc, 0xde, 0xfd, 0xbc, 0x3b, 0xe9, 0x02, 0x1b, 0x9a,
0x95, 0xe0, 0x0f, 0x01, 0x42, 0x15, 0x90, 0x61, 0x44, 0xb1, 0x5d, 0xf7, 0xed, 0x88, 0x7c, 0x23,
0x0e, 0x72, 0x7d, 0xf1, 0xb5, 0x77, 0x83, 0x21, 0x9f, 0xfc, 0x53, 0x28, 0x89, 0x8e, 0x45, 0xb6,
0x1a, 0xdb, 0x36, 0x31, 0x75, 0x0e, 0x72, 0x13, 0x7b, 0xec, 0x57, 0xca, 0x26, 0xf6, 0x98, 0xff,
0x19, 0xa0, 0x18, 0x4b, 0xc5, 0xb2, 0xe4, 0x4b, 0x62, 0x92, 0x13, 0x7b, 0x4c, 0xbf, 0xe9, 0x5d,
0xaa, 0x20, 0x04, 0x6d, 0xfe, 0x00, 0xd6, 0x1b, 0xe7, 0xd8, 0x70, 0x3c, 0x6f, 0x22, 0x26, 0x4a,
0x36, 0x0d, 0x1b, 0x24, 0xe8, 0x50, 0xe8, 0x9c, 0x10, 0xa1, 0xf0, 0x32, 0x00, 0xe5, 0xa7, 0x8e,
0x8d, 0xf6, 0x60, 0xcd, 0xb1, 0xe9, 0x80, 0x6c, 0x16, 0xad, 0x8c, 0xe0, 0x13, 0xd0, 0x0e, 0xac,
0x38, 0x23, 0xd3, 0x64, 0x3a, 0xcd, 0xb7, 0x32, 0x02, 0x6b, 0xa2, 0x32, 0xac, 0x3a, 0x9a, 0xe1,
0xbc, 0x7c, 0x41, 0xb5, 0x9a, 0x23, 0x69, 0x21, 0x6b, 0x57, 0x57, 0x20, 0x77, 0x2e, 0xeb, 0x7c,
0x07, 0x56, 0xe8, 0x10, 0x44, 0x2d, 0x4e, 0x38, 0x0b, 0x56, 0x4f, 0xfb, 0x24, 0x38, 0x38, 0x97,
0x12, 0xcc, 0x2a, 0x9c, 0x9a, 0x7f, 0xa2, 0xf2, 0x7f, 0x84, 0xbb, 0xc4, 0xf7, 0xeb, 0x9a, 0xd5,
0xb3, 0x8e, 0x34, 0x1d, 0xfb, 0x0b, 0xe5, 0x20, 0xa7, 0x6a, 0x7e, 0xea, 0x40, 0x3e, 0x89, 0x71,
0x4d, 0x2d, 0x7c, 0xaa, 0x7d, 0xef, 0x29, 0xdd, 0x6b, 0x11, 0x95, 0x98, 0x86, 0x7e, 0x79, 0x64,
0xea, 0xaa, 0x57, 0xa9, 0xc8, 0x0b, 0x11, 0x0a, 0x39, 0xab, 0x66, 0x46, 0xb0, 0xa7, 0xa6, 0x61,
0x63, 0xe6, 0xee, 0xb6, 0xab, 0x3b, 0x7d, 0x39, 0x28, 0xb5, 0x47, 0x28, 0xfc, 0x3f, 0x67, 0x61,
0x53, 0xc0, 0xb2, 0x1a, 0x9d, 0xd6, 0x2f, 0x60, 0xf5, 0x94, 0x0d, 0x94, 0x4d, 0x38, 0x95, 0x2b,
0x8a, 0x82, 0x6d, 0x5b, 0x1b, 0xe9, 0x98, 0x8d, 0x2d, 0x78, 0xcc, 0x64, 0x8b, 0x4f, 0x35, 0x1d,
0x1b, 0xe1, 0xa5, 0x37, 0x68, 0x93, 0x28, 0x6a, 0x93, 0xc3, 0x90, 0xe9, 0x5b, 0x60, 0x0d, 0xb2,
0x7e, 0x1d, 0x1b, 0xde, 0xf1, 0x4b, 0x3e, 0xf9, 0x3a, 0x70, 0xe1, 0x6c, 0xbc, 0x25, 0x3c, 0x80,
0x82, 0x85, 0x65, 0xb5, 0x66, 0xba, 0x86, 0xe3, 0xed, 0x43, 0x48, 0x20, 0x1b, 0xa4, 0xca, 0x8e,
0x4c, 0x47, 0x5c, 0x17, 0xe8, 0x37, 0xff, 0x9f, 0x59, 0xe0, 0x4e, 0x2c, 0xcd, 0xc1, 0x3f, 0xf2,
0xaa, 0x76, 0x48, 0x60, 0x9a, 0x92, 0x74, 0x97, 0xed, 0x88, 0xd7, 0xa2, 0x95, 0x25, 0xd7, 0x76,
0xba, 0xa6, 0xd3, 0xf8, 0x9e, 0x44, 0x1f, 0xaf, 0x50, 0x19, 0xa5, 0x05, 0xf3, 0x5e, 0x89, 0xcc,
0xfb, 0x3d, 0xd8, 0x24, 0x33, 0x6e, 0x1b, 0xa7, 0xa6, 0x3f, 0x6b, 0x04, 0xcb, 0xd3, 0x70, 0xe7,
0xe8, 0x37, 0xff, 0x27, 0xe0, 0x42, 0x36, 0x4f, 0x49, 0x49, 0xc7, 0x00, 0x89, 0x1c, 0xda, 0xdf,
0xb3, 0x69, 0xe7, 0x04, 0xfa, 0x4d, 0x68, 0x34, 0x2e, 0xb1, 0x62, 0x57, 0x10, 0x7b, 0x26, 0xa6,
0x3a, 0xd0, 0xbc, 0xda, 0x70, 0x4e, 0xf0, 0x9b, 0x64, 0xdb, 0x34, 0xbb, 0xae, 0x59, 0x5e, 0x29,
0x95, 0x35, 0xf8, 0xdf, 0x02, 0x17, 0x24, 0x35, 0x11, 0x9f, 0x65, 0x99, 0x4c, 0xd4, 0xce, 0x42,
0x0a, 0x7a, 0x1f, 0x36, 0x1c, 0x6d, 0x82, 0x4d, 0xd7, 0x11, 0xb1, 0x62, 0x1a, 0xaa, 0xed, 0x85,
0xb9, 0x19, 0x2a, 0xff, 0x08, 0xd6, 0x03, 0xec, 0x57, 0xe6, 0x68, 0xb6, 0x3e, 0xc2, 0x3f, 0x8b,
0x8c, 0xfd, 0xca, 0x1c, 0xd1, 0x70, 0xcd, 0x41, 0x4e, 0x53, 0x59, 0x89, 0xa6, 0x24, 0x90, 0x4f,
0xfe, 0x0d, 0x94, 0x5b, 0xed, 0xba, 0xe0, 0x1a, 0x86, 0x66, 0x8c, 0x5f, 0x99, 0x23, 0x1a, 0x6d,
0x05, 0x6a, 0xf5, 0x11, 0xc4, 0x1c, 0xad, 0xb8, 0x20, 0x58, 0x3e, 0x9f, 0xb4, 0x55, 0x5f, 0x4b,
0xe4, 0x9b, 0x6c, 0xac, 0x6d, 0xba, 0x96, 0x82, 0xbd, 0xa8, 0xeb, 0xb5, 0xf8, 0x3f, 0xc1, 0x66,
0x64, 0xe5, 0x14, 0xee, 0x43, 0xc8, 0x7d, 0x67, 0x8e, 0xbc, 0x77, 0x8b, 0x78, 0xf8, 0x8d, 0x4e,
0x54, 0x20, 0x5c, 0x44, 0x4b, 0x9a, 0x7d, 0xa4, 0x19, 0x9a, 0x7d, 0x16, 0x1c, 0xcd, 0x11, 0x4a,
0xe8, 0xad, 0xaf, 0x6c, 0xd3, 0x08, 0x0f, 0x67, 0x9f, 0xc2, 0x1f, 0x40, 0xb1, 0xd3, 0xa8, 0x07,
0x67, 0xff, 0x63, 0x28, 0x8e, 0x68, 0x45, 0x5b, 0x09, 0x7c, 0xa3, 0x24, 0x00, 0x25, 0x51, 0xe7,
0xe0, 0xbf, 0x87, 0x7b, 0x43, 0xb1, 0xfa, 0x0e, 0x59, 0xca, 0x67, 0x73, 0x59, 0x4a, 0xfc, 0x9d,
0x89, 0xdd, 0xae, 0x12, 0xf2, 0x94, 0xbf, 0xae, 0xc0, 0x46, 0xbc, 0x93, 0x98, 0x19, 0x36, 0x58,
0x52, 0xe2, 0xbd, 0x12, 0x78, 0x4d, 0xb2, 0x81, 0xe7, 0x9a, 0xea, 0x9f, 0x33, 0xe7, 0x9a, 0xca,
0x1e, 0x60, 0xfc, 0x33, 0x8f, 0x7c, 0xce, 0x55, 0x6b, 0xd9, 0x2b, 0x46, 0xbc, 0x5a, 0x4b, 0xeb,
0xd6, 0xa6, 0xea, 0x2a, 0x8e, 0xf7, 0x88, 0xe1, 0x37, 0xe9, 0x86, 0x62, 0x4b, 0x93, 0x59, 0x6e,
0x41, 0x36, 0x94, 0xb6, 0xd0, 0x23, 0x28, 0xba, 0x36, 0x96, 0x6a, 0xf5, 0x9a, 0xd4, 0xa8, 0x1d,
0x7b, 0x85, 0xfd, 0x82, 0x6b, 0xe3, 0x5a, 0xbd, 0xd6, 0xa8, 0x1d, 0x93, 0x4c, 0x80, 0xf4, 0x0b,
0xdd, 0x7a, 0x5b, 0xf4, 0x2a, 0xfa, 0x79, 0xd7, 0xc6, 0xb4, 0x8d, 0x9e, 0x03, 0x47, 0x3a, 0x5b,
0xed, 0xba, 0xf4, 0xba, 0xf1, 0x9b, 0x6a, 0xaf, 0x22, 0xd4, 0xbd, 0x6c, 0x61, 0xc3, 0xb5, 0x71,
0xab, 0x5d, 0xf7, 0xa9, 0x88, 0x87, 0x92, 0xcf, 0x79, 0xdc, 0x1b, 0x8a, 0x0d, 0xaf, 0x1a, 0x5a,
0x64, 0x6c, 0x94, 0xe4, 0x4f, 0x85, 0xf0, 0x08, 0x95, 0x13, 0xaf, 0xe2, 0x59, 0x60, 0x1c, 0x42,
0xe5, 0x04, 0xed, 0xc2, 0x1a, 0xe9, 0x1f, 0x1e, 0x8b, 0x5e, 0x41, 0x73, 0xd5, 0xb5, 0xf1, 0xf0,
0x58, 0x44, 0x0f, 0x01, 0x48, 0x87, 0xd8, 0x10, 0xda, 0x95, 0x8e, 0x5f, 0xcc, 0x77, 0x6d, 0xcc,
0x08, 0xe8, 0x15, 0x6c, 0x58, 0x86, 0xaa, 0xd9, 0x61, 0x9d, 0x79, 0x23, 0xe1, 0x99, 0x2c, 0xbe,
0x57, 0x0d, 0xe7, 0x0c, 0x5b, 0x06, 0x76, 0x84, 0x12, 0x15, 0x0d, 0xb6, 0xf0, 0x18, 0x38, 0x45,
0x55, 0x24, 0xac, 0x4c, 0x42, 0xb4, 0xcd, 0xeb, 0xa3, 0x6d, 0x28, 0xaa, 0xd2, 0x50, 0x26, 0x01,
0x5c, 0x05, 0xd6, 0xdd, 0x49, 0x64, 0x62, 0x5c, 0xc2, 0x43, 0x62, 0x1c, 0x6a, 0x78, 0x2c, 0x0a,
0x45, 0x77, 0x12, 0xce, 0xe8, 0x53, 0xd8, 0x56, 0xf1, 0xb9, 0x44, 0xe2, 0xa2, 0x74, 0xa6, 0xa9,
0xd2, 0x5b, 0x7c, 0x39, 0x32, 0x65, 0x4b, 0xa5, 0xa5, 0x8e, 0x82, 0x80, 0x54, 0x7c, 0x4e, 0xe2,
0x4f, 0x4b, 0x53, 0x5f, 0x7b, 0x3d, 0xe8, 0x43, 0x40, 0x31, 0x91, 0x89, 0xe9, 0xda, 0x98, 0x96,
0x3a, 0x0a, 0xc2, 0x66, 0xc8, 0x7f, 0x4c, 0xc8, 0xe8, 0x03, 0xe0, 0x62, 0xcc, 0x96, 0x7c, 0x41,
0x6b, 0x1b, 0x05, 0xa1, 0x14, 0xb2, 0x0a, 0xf2, 0x05, 0xdf, 0x87, 0x9d, 0xe4, 0x55, 0xd3, 0x6c,
0xd2, 0xb4, 0x1d, 0xfa, 0xec, 0xe1, 0x5f, 0x60, 0x08, 0xa1, 0xa2, 0xaa, 0x16, 0xba, 0x07, 0x79,
0x82, 0x4f, 0xfb, 0x98, 0xfd, 0xaf, 0xa9, 0xf8, 0x9c, 0x74, 0xf1, 0x5f, 0xc1, 0xd6, 0xdc, 0xe2,
0x49, 0x44, 0x56, 0x54, 0xcb, 0x9c, 0x78, 0x2e, 0xc4, 0x1a, 0x24, 0x86, 0x91, 0x43, 0xc9, 0xaf,
0x35, 0x93, 0x6f, 0xfe, 0x2f, 0x59, 0x78, 0x14, 0x68, 0xfe, 0xf6, 0x11, 0xa0, 0x3a, 0x17, 0x01,
0xe2, 0xc5, 0x4d, 0x7f, 0x88, 0xb6, 0xe1, 0x60, 0xeb, 0x54, 0x56, 0x70, 0x42, 0x30, 0x90, 0xe0,
0x29, 0xbb, 0x74, 0x62, 0x35, 0x95, 0x1d, 0x7d, 0x01, 0xcb, 0x34, 0x55, 0x67, 0x95, 0xf6, 0xeb,
0x0e, 0x42, 0x65, 0xf8, 0x3f, 0xe7, 0xe0, 0x5e, 0x3a, 0x72, 0xd2, 0xd9, 0xf8, 0xb5, 0x77, 0x0e,
0xb2, 0x7b, 0xe3, 0x87, 0xd7, 0x1b, 0xed, 0x20, 0x92, 0xb0, 0x93, 0x50, 0x3e, 0xf5, 0x1e, 0xad,
0x5e, 0xf8, 0xa1, 0x3a, 0xa4, 0x90, 0xbc, 0xc1, 0xc0, 0xce, 0x44, 0xb6, 0xdf, 0xbe, 0xf0, 0x62,
0x55, 0xd0, 0x8e, 0x46, 0xc2, 0x95, 0x78, 0x24, 0xec, 0x01, 0x52, 0xcf, 0x94, 0x29, 0x7b, 0x9c,
0x08, 0x72, 0x7b, 0x56, 0x5c, 0x7f, 0x1c, 0x9b, 0x64, 0xbd, 0x55, 0xeb, 0xc7, 0xd9, 0x84, 0x04,
0x51, 0xf4, 0x0c, 0x4a, 0xfe, 0x36, 0xb4, 0x8d, 0xa1, 0x8d, 0xbd, 0x10, 0x17, 0x27, 0xf2, 0x35,
0x58, 0xa6, 0x77, 0x30, 0x80, 0xd5, 0xe3, 0x4a, 0x77, 0x58, 0xe9, 0x70, 0x19, 0xb4, 0x09, 0x45,
0x32, 0x86, 0x54, 0xeb, 0xb4, 0x1b, 0xdd, 0x01, 0x97, 0x0d, 0x08, 0x62, 0x43, 0x78, 0xd3, 0x10,
0xb8, 0x25, 0x72, 0xb7, 0x1f, 0x76, 0x8f, 0x2b, 0xdd, 0x4a, 0xb3, 0x51, 0xe7, 0x72, 0xfc, 0xff,
0xe5, 0x00, 0xcd, 0xcf, 0x2a, 0xcc, 0xe6, 0xfb, 0xa6, 0x15, 0x9c, 0x51, 0x21, 0x05, 0x3d, 0x87,
0x4d, 0xd6, 0x0a, 0xd4, 0xed, 0xff, 0xbe, 0x63, 0x86, 0x4c, 0xeb, 0x6d, 0x58, 0xb6, 0x69, 0x56,
0xe7, 0x69, 0x3c, 0x24, 0xa0, 0x7d, 0xe0, 0x0c, 0xd3, 0x21, 0x17, 0x4b, 0xd3, 0xd2, 0x1c, 0x99,
0xbe, 0x93, 0xb0, 0xc4, 0x6b, 0x8e, 0x8e, 0x0e, 0x00, 0xa9, 0x66, 0xd7, 0x74, 0xaa, 0x9a, 0xa1,
0x86, 0xc3, 0xb2, 0xbd, 0x48, 0xe8, 0x21, 0xd9, 0x8b, 0x22, 0xeb, 0xfa, 0x48, 0x56, 0xde, 0x7a,
0xb5, 0x5e, 0x76, 0x8c, 0xcc, 0x50, 0xd1, 0x0b, 0x58, 0xb5, 0x64, 0x63, 0x8c, 0xed, 0xf2, 0x1a,
0xb5, 0xe2, 0x07, 0x29, 0x5b, 0x26, 0x10, 0x26, 0xc1, 0xe3, 0x45, 0x47, 0xb0, 0x66, 0x4e, 0xd9,
0x33, 0x13, 0xbb, 0xa7, 0x7e, 0x74, 0xc5, 0x4e, 0x1f, 0xf4, 0x18, 0x7b, 0xc3, 0x70, 0xac, 0x4b,
0xc1, 0x17, 0x46, 0x35, 0x28, 0xb2, 0xb7, 0xd4, 0x96, 0x69, 0x3b, 0x76, 0xb9, 0x40, 0xb1, 0x9e,
0xa6, 0x61, 0x05, 0x9c, 0x42, 0x54, 0x6a, 0xef, 0x0b, 0x58, 0x8f, 0xa2, 0x93, 0x93, 0xf8, 0x2d,
0xbe, 0xf4, 0xf6, 0x8d, 0x7c, 0xc6, 0x2b, 0x22, 0x05, 0xaf, 0x22, 0xf2, 0xc5, 0xd2, 0xe7, 0x59,
0xde, 0x84, 0xcd, 0x99, 0x35, 0xd2, 0x8c, 0x86, 0x7c, 0x74, 0xcc, 0x8b, 0xa0, 0x48, 0x1a, 0xa1,
0x04, 0xfd, 0xc3, 0xe9, 0x14, 0xfb, 0x11, 0x30, 0x42, 0x09, 0xf6, 0x9c, 0x66, 0xa7, 0xd1, 0x3d,
0x27, 0x04, 0xfe, 0x73, 0xb8, 0x9b, 0xb4, 0x22, 0x7a, 0x2b, 0x95, 0x95, 0xe0, 0x56, 0x2a, 0x2b,
0x34, 0xeb, 0x9b, 0x7a, 0xf8, 0x4b, 0xda, 0x94, 0x5f, 0x83, 0x95, 0xc6, 0x64, 0xea, 0x5c, 0xee,
0x7f, 0x1e, 0xf9, 0x69, 0xc3, 0xfc, 0x2f, 0x28, 0xd0, 0x1a, 0xe4, 0xba, 0x95, 0x3e, 0x97, 0x41,
0x79, 0x58, 0xee, 0x57, 0xba, 0x43, 0x2e, 0x8b, 0x56, 0x61, 0xa9, 0xd9, 0xe5, 0x96, 0xf6, 0x5f,
0xc1, 0x76, 0x62, 0x39, 0x14, 0xad, 0x43, 0x5e, 0x6c, 0x7c, 0x33, 0x6c, 0x74, 0x6b, 0x0d, 0x2e,
0x43, 0x10, 0x2a, 0xdd, 0x3a, 0x93, 0xeb, 0x11, 0xb7, 0x41, 0xb0, 0xd1, 0xf8, 0xb6, 0x52, 0x1b,
0x48, 0x01, 0x53, 0x6e, 0xff, 0x63, 0xe0, 0x66, 0xab, 0x9d, 0x84, 0x7f, 0xe8, 0x8d, 0x5c, 0xef,
0x9d, 0x74, 0xb9, 0x2c, 0x81, 0xea, 0x1d, 0x1d, 0x71, 0x4b, 0xfb, 0x9f, 0x00, 0x84, 0xd5, 0x4d,
0xe2, 0xb5, 0x42, 0x5b, 0x6c, 0x77, 0x9b, 0xac, 0x1e, 0x77, 0x54, 0xe9, 0x74, 0x48, 0x83, 0xd6,
0xe3, 0xaa, 0xbd, 0x41, 0x8b, 0x5b, 0xda, 0xff, 0x18, 0xd6, 0xa3, 0xd5, 0x30, 0x82, 0xd4, 0xe9,
0x9d, 0x30, 0xf0, 0x56, 0xbb, 0xd9, 0xe2, 0xb2, 0x04, 0x65, 0xd0, 0x6b, 0x36, 0x3b, 0x0d, 0x6e,
0x69, 0xbf, 0x0e, 0x9b, 0x33, 0x35, 0x1e, 0x02, 0x3c, 0xec, 0xbe, 0xee, 0x92, 0x89, 0x64, 0xc8,
0xd4, 0x2a, 0x7d, 0x36, 0x21, 0x71, 0x50, 0xe1, 0x96, 0xd0, 0x1d, 0xd8, 0x14, 0x07, 0x15, 0xe9,
0xa8, 0xd2, 0xee, 0xf4, 0xde, 0x34, 0x04, 0xa9, 0xd2, 0xe7, 0x72, 0xfb, 0x75, 0x28, 0xc5, 0x4a,
0x1d, 0x68, 0x1b, 0xb6, 0x08, 0x57, 0xb7, 0x37, 0x90, 0x6a, 0xbd, 0x6e, 0xb7, 0x51, 0x1b, 0x34,
0xea, 0x5c, 0x06, 0x15, 0x60, 0xa5, 0xd2, 0x97, 0x86, 0x04, 0x70, 0x0b, 0x4a, 0x84, 0x23, 0xec,
0x5d, 0xda, 0x7f, 0x9f, 0x15, 0xbc, 0xfc, 0x8a, 0x11, 0xd1, 0xee, 0x49, 0xbf, 0x72, 0x28, 0xf5,
0xc5, 0xd7, 0x6c, 0xfe, 0xbd, 0x7e, 0xa3, 0xcb, 0x65, 0xf7, 0xff, 0x06, 0xb8, 0xd9, 0x4b, 0x1c,
0x99, 0xdf, 0xe0, 0x98, 0xe8, 0x90, 0x83, 0xf5, 0x6a, 0x45, 0x6c, 0x49, 0x62, 0x4d, 0x68, 0xf7,
0x07, 0x22, 0x8b, 0x66, 0x24, 0xd5, 0xf2, 0x09, 0x4b, 0x87, 0xff, 0xf6, 0x12, 0x56, 0xfb, 0x2f,
0x4e, 0xba, 0xfd, 0x4f, 0xd1, 0x29, 0x3c, 0x6d, 0x62, 0xe7, 0x8a, 0x5f, 0x21, 0xa0, 0xf8, 0x99,
0x41, 0x8c, 0x69, 0xef, 0x26, 0xbf, 0x5b, 0xe2, 0x33, 0xe8, 0xcf, 0x59, 0x78, 0xc6, 0x0e, 0xc6,
0x2b, 0xc6, 0xba, 0x09, 0xee, 0x4d, 0x27, 0xf1, 0x06, 0xee, 0x45, 0x17, 0x1b, 0xff, 0x21, 0x54,
0xd2, 0x22, 0xaf, 0xf3, 0xfb, 0x2a, 0x3e, 0x83, 0xbe, 0x83, 0x07, 0x33, 0x6b, 0x8b, 0x43, 0x5f,
0x07, 0xe6, 0xba, 0x63, 0x7d, 0x0b, 0x7b, 0x62, 0x64, 0x0d, 0x33, 0xbf, 0xcf, 0x7a, 0x76, 0x9d,
0xdf, 0x4b, 0xed, 0x25, 0x2c, 0x95, 0xcf, 0xa0, 0xdf, 0xc1, 0xee, 0xcc, 0x2a, 0xc2, 0x83, 0x6d,
0xf1, 0x0f, 0xde, 0xf6, 0xae, 0xe8, 0xe7, 0x33, 0xe8, 0xf7, 0xb0, 0x43, 0x52, 0x31, 0x3c, 0x8f,
0xfd, 0x51, 0xb2, 0x6c, 0x72, 0x1e, 0x97, 0x32, 0xf5, 0xdf, 0xc2, 0x5e, 0x13, 0x3b, 0x74, 0x00,
0x75, 0x7e, 0x84, 0x78, 0x49, 0x32, 0x56, 0xb1, 0xbb, 0xc6, 0xcc, 0xff, 0x00, 0x0f, 0xbd, 0x67,
0x84, 0x1f, 0x05, 0xfe, 0x1b, 0x02, 0xaf, 0x63, 0xf6, 0x9b, 0xc8, 0x9b, 0xc2, 0x27, 0x6b, 0x43,
0x80, 0x47, 0x14, 0xcc, 0x4f, 0x44, 0x7f, 0x08, 0xcc, 0x01, 0xdc, 0xef, 0x68, 0x76, 0xaa, 0x8a,
0x93, 0x9c, 0xe7, 0x71, 0xfa, 0x20, 0xac, 0x18, 0x9a, 0x41, 0xc7, 0x50, 0x6e, 0x62, 0xc7, 0x9f,
0x67, 0xec, 0x0a, 0x90, 0x08, 0xb9, 0xe8, 0x46, 0x4e, 0x75, 0x79, 0x87, 0x61, 0xc5, 0x91, 0x16,
0x49, 0x5d, 0x05, 0xf9, 0x6b, 0xd8, 0x68, 0x62, 0x27, 0x5a, 0x89, 0x48, 0x9a, 0x57, 0x39, 0x46,
0x8b, 0x70, 0x33, 0x04, 0x31, 0x8e, 0x90, 0xca, 0x9d, 0xa2, 0xfb, 0x3a, 0xac, 0x1f, 0x9b, 0xae,
0xe1, 0x0c, 0x8f, 0x45, 0x9a, 0xfe, 0x5d, 0x71, 0x6b, 0x4c, 0x41, 0xe9, 0x03, 0x47, 0x77, 0x6f,
0x28, 0x56, 0xc3, 0x5f, 0x51, 0xc5, 0x38, 0x53, 0xeb, 0x27, 0x29, 0x88, 0xdf, 0xc0, 0xdd, 0xc0,
0xeb, 0xa2, 0xa8, 0x8b, 0xac, 0xeb, 0x0a, 0x75, 0x0f, 0xfc, 0x18, 0xf4, 0x83, 0xa2, 0xbe, 0x26,
0xa8, 0xa1, 0x8f, 0x5d, 0x17, 0x35, 0x79, 0xd5, 0x1d, 0x28, 0xc7, 0xbc, 0xeb, 0xdd, 0xd0, 0xba,
0xb0, 0x1d, 0xfa, 0x55, 0x14, 0xea, 0x96, 0x1e, 0xf5, 0x0a, 0xb6, 0x08, 0xde, 0x70, 0x62, 0xb7,
0x27, 0xf2, 0x18, 0xd7, 0xd8, 0x9d, 0xf9, 0x76, 0x58, 0x3d, 0xd8, 0x89, 0x62, 0x1d, 0xe9, 0xb2,
0x7d, 0xa6, 0x5a, 0xe4, 0x52, 0x71, 0x6b, 0x77, 0x5f, 0x67, 0xb5, 0x4a, 0xef, 0x0e, 0xf1, 0x30,
0xb9, 0x86, 0xe8, 0x19, 0xe1, 0xde, 0x83, 0xb4, 0x6e, 0xdb, 0xd5, 0x1d, 0x0a, 0xb7, 0x19, 0x85,
0x7b, 0x65, 0x8e, 0xae, 0x42, 0x4c, 0x2f, 0x5a, 0xd2, 0xb0, 0xb9, 0xdd, 0x6a, 0xd7, 0x89, 0x45,
0x07, 0x95, 0x4c, 0x56, 0xf7, 0x4c, 0x97, 0xba, 0x72, 0x8a, 0x0d, 0x40, 0xad, 0x76, 0xbd, 0x26,
0x1b, 0x0a, 0xd6, 0xc3, 0x59, 0x2e, 0x00, 0x4c, 0xb3, 0x92, 0x5d, 0x36, 0x35, 0xaf, 0xce, 0x1b,
0xf0, 0x27, 0xdb, 0xc9, 0xc3, 0x54, 0x7c, 0xb2, 0x9f, 0x7c, 0x06, 0x55, 0x61, 0x27, 0x98, 0x56,
0x45, 0xd7, 0xaf, 0x80, 0x4b, 0x4b, 0x17, 0xb6, 0x63, 0x73, 0xf2, 0x6b, 0xcf, 0x8b, 0x56, 0xf7,
0xde, 0x6c, 0x57, 0x62, 0xdd, 0x9a, 0x4e, 0xb0, 0x78, 0x24, 0x06, 0xef, 0x1a, 0x33, 0xdb, 0x3a,
0xfb, 0xde, 0x91, 0x32, 0xc1, 0xd7, 0x00, 0x47, 0xa2, 0xff, 0xc4, 0x82, 0xe2, 0x3b, 0x35, 0xf3,
0x0e, 0x34, 0xa3, 0xb1, 0xd9, 0x77, 0x19, 0xba, 0x03, 0xa5, 0x23, 0xb1, 0x89, 0x1d, 0xff, 0x35,
0x62, 0x06, 0x6f, 0xe6, 0x2d, 0x63, 0x06, 0x6f, 0xf6, 0x09, 0x83, 0xcf, 0xa0, 0x3f, 0xc2, 0xf6,
0x91, 0x58, 0xb3, 0xb0, 0xec, 0xe0, 0xd8, 0x6b, 0x16, 0x9a, 0xf9, 0x7d, 0x5e, 0xc2, 0x5b, 0xda,
0x1e, 0xbf, 0x88, 0x25, 0x18, 0xe1, 0xd7, 0x50, 0xa4, 0xef, 0x73, 0x1d, 0x5a, 0x5a, 0x98, 0xd9,
0x95, 0xe8, 0x23, 0xe4, 0xac, 0xfa, 0x48, 0x17, 0x9f, 0xf9, 0x59, 0x16, 0x35, 0xa1, 0xd8, 0x50,
0xce, 0x82, 0xf7, 0x99, 0x45, 0xc1, 0x6d, 0x41, 0x1f, 0x9f, 0x41, 0x6d, 0x40, 0x2c, 0x5a, 0xc6,
0x9e, 0xf3, 0xd3, 0x1f, 0x70, 0xf7, 0x76, 0x92, 0x1f, 0x91, 0xf9, 0x0c, 0xfa, 0x12, 0xd6, 0x9b,
0xd8, 0x09, 0x1f, 0x9f, 0x93, 0xec, 0x35, 0x5d, 0xfa, 0x88, 0x45, 0x34, 0x6c, 0x04, 0xc4, 0xda,
0x19, 0x2b, 0x4c, 0xdc, 0x0c, 0x47, 0x80, 0x2d, 0x1a, 0xb1, 0x4f, 0xb4, 0xd3, 0x70, 0x3d, 0x1f,
0xcc, 0xb0, 0xa7, 0xfd, 0x66, 0x22, 0xf5, 0x7c, 0xde, 0x0e, 0x4e, 0xd3, 0x18, 0xee, 0x22, 0xbd,
0xa7, 0xeb, 0x90, 0x22, 0x96, 0xa3, 0x87, 0xe9, 0xb5, 0x41, 0xd3, 0xd7, 0xdd, 0x21, 0x88, 0xe1,
0x41, 0x7a, 0x6d, 0xc4, 0xe4, 0x15, 0x1f, 0xc3, 0xbd, 0xd8, 0x49, 0xfa, 0x8e, 0x70, 0xde, 0x71,
0x95, 0x30, 0xb5, 0x5b, 0x1e, 0x57, 0x12, 0x3c, 0x66, 0x53, 0x4b, 0xaf, 0xb7, 0x5e, 0xb3, 0x76,
0x9b, 0x32, 0x63, 0x13, 0x3e, 0x68, 0x62, 0xa7, 0xa2, 0xeb, 0x57, 0x97, 0x8c, 0x93, 0x96, 0x70,
0x10, 0xaf, 0x77, 0x5d, 0x85, 0xc1, 0x67, 0x90, 0x0e, 0xcf, 0x22, 0xf9, 0x76, 0xfa, 0x68, 0x8b,
0x94, 0x7f, 0xcd, 0x25, 0xf3, 0x19, 0xa4, 0x78, 0xf7, 0x90, 0xf4, 0x71, 0x92, 0x8b, 0xd1, 0x37,
0x72, 0x9b, 0xef, 0x80, 0x0f, 0xdc, 0xe6, 0xc7, 0x5e, 0xd0, 0x6f, 0xe0, 0xbd, 0xa8, 0x43, 0xdd,
0x6e, 0xb8, 0xe4, 0x65, 0x50, 0xe8, 0xd0, 0xb3, 0x7e, 0x48, 0xe8, 0xdf, 0xc3, 0x4f, 0x42, 0xbf,
0xb8, 0x99, 0x85, 0x5d, 0xc3, 0x49, 0x04, 0xb8, 0x1f, 0x31, 0xa9, 0xb9, 0x3f, 0x2f, 0xb8, 0x3a,
0x3d, 0x99, 0x15, 0xa1, 0x8e, 0xe7, 0x5d, 0xb9, 0x67, 0xfb, 0x04, 0x3c, 0xd5, 0x65, 0x65, 0x36,
0x1f, 0x98, 0xe5, 0xba, 0x7a, 0x80, 0xdf, 0xc1, 0xbd, 0xe4, 0x01, 0x2a, 0xaa, 0xfa, 0xce, 0xe0,
0x7f, 0xeb, 0x57, 0x83, 0xe6, 0x67, 0x3f, 0x31, 0xcf, 0xf1, 0x8f, 0x87, 0x3f, 0x9c, 0xaa, 0xe4,
0x48, 0x7c, 0x57, 0xfc, 0xd8, 0x55, 0x7f, 0xb6, 0xff, 0xd6, 0x76, 0xd2, 0x81, 0x6d, 0x8a, 0x38,
0x67, 0x21, 0x57, 0x4c, 0x37, 0xd9, 0xa6, 0x47, 0xf0, 0x93, 0xa8, 0x27, 0xa6, 0xd9, 0xc9, 0x22,
0x67, 0xb9, 0x86, 0x9e, 0x1f, 0x2f, 0x1a, 0x83, 0x98, 0xca, 0x3b, 0xe1, 0xf7, 0xc9, 0x3e, 0x86,
0x2e, 0x3f, 0xa7, 0x98, 0x9b, 0x7b, 0xfa, 0x37, 0xb0, 0x7b, 0x22, 0x6b, 0x4e, 0xd2, 0x0f, 0xae,
0xaf, 0xfc, 0x13, 0x86, 0x14, 0xc8, 0x36, 0xdc, 0x39, 0xd2, 0x2c, 0x3c, 0xf7, 0x43, 0xd2, 0x45,
0xbf, 0x76, 0x4f, 0x85, 0xba, 0xcb, 0xf4, 0x39, 0xf3, 0xf7, 0xd2, 0x8b, 0xfe, 0x9c, 0x37, 0x05,
0xea, 0x0d, 0xdc, 0xa1, 0x4a, 0x9b, 0x41, 0xfa, 0xe9, 0x4c, 0x16, 0x9f, 0xfe, 0x97, 0xc7, 0xa9,
0x55, 0xae, 0xdd, 0xe0, 0x30, 0x99, 0xc1, 0xbe, 0x7e, 0xf9, 0x21, 0x2e, 0xc8, 0x67, 0xd0, 0x09,
0xec, 0x45, 0x0d, 0xe9, 0x87, 0x03, 0xee, 0x12, 0xe0, 0xd0, 0x82, 0x6e, 0x00, 0x9c, 0x66, 0x3f,
0xe5, 0xd0, 0xf3, 0x67, 0xd0, 0x6e, 0xed, 0xf6, 0x65, 0xaa, 0x51, 0xd9, 0x72, 0xdc, 0xe9, 0x35,
0x20, 0x17, 0x5f, 0x24, 0x3a, 0x50, 0x16, 0xd3, 0xd0, 0x6e, 0xbe, 0xdc, 0x2f, 0x21, 0x5f, 0xaf,
0x56, 0x65, 0xe5, 0xad, 0x3b, 0xbd, 0x85, 0xf4, 0x57, 0x50, 0xa8, 0x57, 0x05, 0x6c, 0x13, 0x65,
0xdd, 0x2a, 0xf9, 0xbd, 0x1b, 0xea, 0x3a, 0xb8, 0x24, 0xdf, 0x3a, 0xbc, 0xc6, 0xea, 0x48, 0xe1,
0x0f, 0xf8, 0xdf, 0x21, 0x5c, 0xdf, 0x09, 0xf1, 0x7c, 0x2d, 0xbd, 0x4b, 0x55, 0x8a, 0x24, 0xba,
0xfe, 0xdf, 0x4f, 0x36, 0xa7, 0x9a, 0x79, 0x6b, 0xac, 0x17, 0x90, 0x17, 0xcf, 0x5c, 0x47, 0x35,
0x2f, 0x8c, 0x1b, 0x54, 0x2b, 0x0e, 0x61, 0x55, 0xc0, 0x23, 0xd3, 0x74, 0xae, 0x2f, 0x33, 0x5a,
0xa5, 0xff, 0xef, 0xe1, 0xe7, 0xff, 0x1f, 0x00, 0x00, 0xff, 0xff, 0x37, 0xcf, 0xba, 0xd4, 0xfd,
0x41, 0x00, 0x00,
}

View File

@ -21,9 +21,8 @@ service P4WNP1 {
//USB gadget
rpc GetDeployedGadgetSetting (Empty) returns (GadgetSettings) { }
rpc DeployGadgetSetting (Empty) returns (GadgetSettings) { }
rpc GetGadgetSettings (Empty) returns (GadgetSettings) { }
rpc SetGadgetSettings (GadgetSettings) returns (GadgetSettings) { }
rpc DeployGadgetSetting (GadgetSettings) returns (GadgetSettings) { }
rpc GetLEDSettings (Empty) returns (LEDSettings) { }
rpc SetLEDSettings (LEDSettings) returns (Empty) { }
rpc MountUMSFile (GadgetSettingsUMS) returns (Empty) { }

View File

@ -42,7 +42,7 @@ var triggerTypeString = map[triggerType]string {
triggerTypeSshLogin: "TRIGGER_SSH_LOGIN",
triggerTypeDhcpLeaseGranted: "TRIGGER_DHCP_LEASE_GRANTED",
triggerTypeGroupReceive: "TRIGGER_GROUP_RECEIVE",
triggerTypeGroupReceiveMulti: "TRIGGER_GROUP_RECEIVE_SEQUENCE",
triggerTypeGroupReceiveMulti: "TRIGGER_GROUP_RECEIVE_MULTI",
triggerTypeGpioIn: "TRIGGER_GPIO_IN",
}
@ -495,12 +495,12 @@ func (tam *TriggerActionManager) executeActionBashScript(evt *pb.Event, ta *pb.T
switch tt {
case triggerTypeGpioIn:
gpioPinName := ta.Trigger.(*pb.TriggerAction_GpioIn).GpioIn.GpioName
env = append(env, fmt.Sprintf("GPIO_PIN=%s", gpioPinName))
env = append(env, fmt.Sprintf("GPIO_PIN='%s'", gpioPinName))
_,level,_ := DeconstructEventTriggerGpioIn(evt)
if level {
env = append(env, fmt.Sprintf("GPIO_LEVEL='HIGH'"))
env = append(env, fmt.Sprintf("GPIO_LEVEL=HIGH"))
} else {
env = append(env, fmt.Sprintf("GPIO_LEVEL='LOW'"))
env = append(env, fmt.Sprintf("GPIO_LEVEL=LOW"))
}
case triggerTypeGroupReceiveMulti:
groupName := ta.Trigger.(*pb.TriggerAction_GroupReceiveMulti).GroupReceiveMulti.GroupName
@ -511,15 +511,15 @@ func (tam *TriggerActionManager) executeActionBashScript(evt *pb.Event, ta *pb.T
for _,v := range values { bashArray += fmt.Sprintf("%d ", v)}
bashArray += ")"
env = append(env,
fmt.Sprintf("GROUP='%s'", groupName),
fmt.Sprintf("GROUP=%s", groupName),
fmt.Sprintf("VALUES=%s", bashArray),
fmt.Sprintf("MULTI_TYPE='%s'", pb.GroupReceiveMultiType_name[int32(rtype)]),
fmt.Sprintf("MULTI_TYPE=%s", pb.GroupReceiveMultiType_name[int32(rtype)]),
)
case triggerTypeGroupReceive:
groupName := ta.Trigger.(*pb.TriggerAction_GroupReceive).GroupReceive.GroupName
value := ta.Trigger.(*pb.TriggerAction_GroupReceive).GroupReceive.Value
env = append(env,
fmt.Sprintf("GROUP='%s'", groupName),
fmt.Sprintf("GROUP=%s", groupName),
fmt.Sprintf("VALUE=%d", value),
)
case triggerTypeDhcpLeaseGranted:

View File

@ -84,7 +84,7 @@ var (
)
type UsbManagerState struct {
UndeployedGadgetSettings *pb.GadgetSettings
//UndeployedGadgetSettings *pb.GadgetSettings
DevicePath map[string]string
}
@ -186,8 +186,8 @@ func NewUSBGadgetManager(rooSvc *Service) (newUGM *UsbGadgetManager, err error)
defGS := GetDefaultGadgetSettings()
newUGM.State.UndeployedGadgetSettings = &defGS //preload state with default settings
err = newUGM.DeployGadgetSettings(newUGM.State.UndeployedGadgetSettings)
//newUGM.State.UndeployedGadgetSettings = &defGS //preload state with default settings
err = newUGM.DeployGadgetSettings(&defGS)
if err != nil {
newUGM.Usable = false
return newUGM,nil
@ -197,7 +197,7 @@ func NewUSBGadgetManager(rooSvc *Service) (newUGM *UsbGadgetManager, err error)
func ValidateGadgetSetting(gs pb.GadgetSettings) error {
func ValidateGadgetSetting(gs *pb.GadgetSettings) error {
/* ToDo: validations
- Done: check host_addr/dev_addr of RNDIS + CDC ECM to be valid MAC addresses via regex
- check host_addr/dev_addr of RNDIS + CDC ECM for duplicates
@ -495,6 +495,8 @@ func (gm *UsbGadgetManager) ParseGadgetState(gadgetName string) (result *pb.Gadg
// remove path
result.UmsSettings.File = filepath.Base(result.UmsSettings.File)
}
} else {
result.UmsSettings = &pb.GadgetSettingsUMS{}
}
//check if UDC is set (Gadget enabled)
@ -526,19 +528,34 @@ func MountUMSFile(filename string) error {
return nil
}
func (gm *UsbGadgetManager) DeployGadgetSettings(settings *pb.GadgetSettings) error {
func (gm *UsbGadgetManager) DeployGadgetSettings(settings *pb.GadgetSettings) (err error) {
if !gm.Usable {
return ErrUsbNotUsable
}
fmt.Println("DeployGadgetSettings before lock ...")
//fmt.Println("DeployGadgetSettings before lock ...")
//Lock, only one change at a time
gm.gadgetSettingsLock.Lock()
defer gm.gadgetSettingsLock.Unlock()
fmt.Println("DeployGadgetSettings beyond lock ...")
//defer gm.gadgetSettingsLock.Unlock()
defer func() {
//fmt.Println("UNLOCKING DeployGadgetSettings")
gm.gadgetSettingsLock.Unlock()
}()
//fmt.Println("DeployGadgetSettings beyond lock ...")
err = ValidateGadgetSetting(settings)
if err != nil {
return
}
//Crash fix: abort HID controller before destorying gadget, to avoid crashes by attempting to close filedescriptors of non existent files
if gm.hidCtl != nil {
gm.hidCtl.Abort()
}
fmt.Println("... deconstruct old gadget")
//ToDo: Former gadgets are destroyed without testing if there're changes, this should be aborted if GadgetSettingsState == GetDeployedGadgetSettings()
gm.DestroyGadget(USB_GADGET_NAME)
var usesUSBEthernet bool
@ -746,10 +763,12 @@ func (gm *UsbGadgetManager) DeployGadgetSettings(settings *pb.GadgetSettings) er
}
log.Printf("Enabeling gadget for UDC: %s\n", udcName)
if err = ioutil.WriteFile(USB_GADGET_DIR+"/UDC", []byte(udcName), os.ModePerm); err != nil {
fmt.Println("... error enabling gadget:", err)
return err
}
//update device path'
//update device path
log.Println("Retrieving path to HID devices")
if devPath,errF := enumDevicePath(USB_FUNCTION_HID_KEYBOARD_name); errF == nil { gm.State.DevicePath[USB_FUNCTION_HID_KEYBOARD_name] = devPath }
if devPath,errF := enumDevicePath(USB_FUNCTION_HID_MOUSE_name); errF == nil { gm.State.DevicePath[USB_FUNCTION_HID_MOUSE_name] = devPath }
if devPath,errF := enumDevicePath(USB_FUNCTION_HID_RAW_name); errF == nil { gm.State.DevicePath[USB_FUNCTION_HID_RAW_name] = devPath }
@ -759,6 +778,7 @@ func (gm *UsbGadgetManager) DeployGadgetSettings(settings *pb.GadgetSettings) er
devPathKeyboard := gm.State.DevicePath[USB_FUNCTION_HID_KEYBOARD_name]
devPathMouse := gm.State.DevicePath[USB_FUNCTION_HID_MOUSE_name]
//log.Printf("Starting HID controller (kbd %s, mouse %s)...\n", devPathKeyboard, devPathMouse)
var errH error
gm.hidCtl, errH = hid.NewHIDController(context.Background(), devPathKeyboard, PATH_KEYBOARD_LANGUAGE_MAPS, devPathMouse)
gm.hidCtl.SetEventHandler(gm)

View File

@ -456,11 +456,7 @@ func (s *server) DeployStoredUSBSettings(ctx context.Context, m *pb.StringMessag
defer s.rootSvc.SubSysEvent.Emit(ConstructEventNotifyStateChange(common_web.STATE_CHANGE_EVT_TYPE_USB))
ws,err := s.GetStoredUSBSettings(ctx,m)
if err != nil { return &pb.GadgetSettings{},err }
st,err = s.SetGadgetSettings(ctx, ws)
if err != nil {
return
}
_,err = s.DeployGadgetSetting(ctx, &pb.Empty{})
st,err = s.DeployGadgetSetting(ctx, ws)
return
}
@ -954,15 +950,14 @@ func (s *server) GetDeployedGadgetSetting(ctx context.Context, e *pb.Empty) (gs
return
}
func (s *server) DeployGadgetSetting(context.Context, *pb.Empty) (gs *pb.GadgetSettings, err error) {
func (s *server) DeployGadgetSetting(ctx context.Context, newGs *pb.GadgetSettings) (gs *pb.GadgetSettings, err error) {
log.Printf("Called DeployGadgetSettings\n")
defer s.rootSvc.SubSysEvent.Emit(ConstructEventNotifyStateChange(common_web.STATE_CHANGE_EVT_TYPE_USB))
gs_backup,_ := s.rootSvc.SubSysUSB.ParseGadgetState(USB_GADGET_NAME)
//ToDo: Former gadgets are destroyed without testing if there're changes, this should be aborted if GadgetSettingsState == GetDeployedGadgetSettings()
//s.rootSvc.SubSysUSB.DestroyGadget(USB_GADGET_NAME) //already done by deploy
errg := s.rootSvc.SubSysUSB.DeployGadgetSettings(s.rootSvc.SubSysUSB.State.UndeployedGadgetSettings)
errg := s.rootSvc.SubSysUSB.DeployGadgetSettings(newGs)
err = nil
if errg != nil {
err = errors.New(fmt.Sprintf("Deploying new gadget settings failed, reverted to old ones: %v", errg))
@ -973,22 +968,6 @@ func (s *server) DeployGadgetSetting(context.Context, *pb.Empty) (gs *pb.GadgetS
return
}
func (s *server) GetGadgetSettings(context.Context, *pb.Empty) (*pb.GadgetSettings, error) {
return s.rootSvc.SubSysUSB.State.UndeployedGadgetSettings, nil
}
func (s *server) SetGadgetSettings(ctx context.Context, gs *pb.GadgetSettings) (res *pb.GadgetSettings, err error) {
defer s.rootSvc.SubSysEvent.Emit(ConstructEventNotifyStateChange(common_web.STATE_CHANGE_EVT_TYPE_USB))
if err = ValidateGadgetSetting(*gs); err != nil {
//We return the validation error and the current (unchanged) GadgetSettingsState
res = s.rootSvc.SubSysUSB.State.UndeployedGadgetSettings
return
}
s.rootSvc.SubSysUSB.State.UndeployedGadgetSettings = gs
res = s.rootSvc.SubSysUSB.State.UndeployedGadgetSettings
return
}
func (s *server) GetLEDSettings(context.Context, *pb.Empty) (res *pb.LEDSettings, err error) {
// res, err = ServiceState.Led.GetLed()
state := s.rootSvc.SubSysLed.GetState()

View File

@ -219,7 +219,7 @@ const (
<div class="col-12">
<q-card>
<q-card-title>
USB Gadget Settings ({{ currentGadgetSettings.UmsSettings }})
USB Gadget Settings
</q-card-title>
<q-card-main>

View File

@ -922,7 +922,7 @@ const templateAction = `
<q-item tag="label" v-if="isActionDeploySettingsTemplate">
<q-item-main>
<q-item-tile label>Type</q-item-tile>
<q-item-tile sublabel>Name of the stored settings template to load</q-item-tile>
<q-item-tile sublabel>Select the type of the template to load</q-item-tile>
<q-item-tile>
<q-select v-model="ta.ActionData.Type" :options="templatetypes" color="secondary" @input="ta.ActionData.TemplateName=''" inverted :disable="!ta.IsActive"></q-select>
</q-item-tile>

View File

@ -1504,15 +1504,9 @@ func actionDeployCurrentGadgetSettings(store *mvuex.Store, context *mvuex.Action
//get current GadgetSettings
curGS := state.CurrentGadgetSettings.toGo()
//try to set them via gRPC (the server holds an internal state, setting != deploying)
err := RpcClient.SetRemoteGadgetSettings(curGS, defaultTimeoutShort)
if err != nil {
QuasarNotifyError("Error in pre-check of new USB gadget settings", err.Error(), QUASAR_NOTIFICATION_POSITION_TOP)
return
}
//try to deploy the, now set, remote GadgetSettings via gRPC
_, err = RpcClient.DeployRemoteGadgetSettings(defaultTimeout)
_, err := RpcClient.DeployRemoteGadgetSettings(defaultTimeout, curGS)
if err != nil {
QuasarNotifyError("Error while deploying new USB gadget settings", err.Error(), QUASAR_NOTIFICATION_POSITION_TOP)
return

View File

@ -678,6 +678,7 @@ func (rpc *Rpc) GetDeployedGadgetSettings(timeout time.Duration) (*pb.GadgetSett
}
/*
func (rpc *Rpc) SetRemoteGadgetSettings(targetGS *pb.GadgetSettings, timeout time.Duration) (err error) {
//gs := vue.GetVM(c).Get("gadgetSettings")
println("SetRemoteGadgetSettings called")
@ -696,15 +697,16 @@ func (rpc *Rpc) SetRemoteGadgetSettings(targetGS *pb.GadgetSettings, timeout tim
return nil
}
*/
func (rpc *Rpc) DeployRemoteGadgetSettings(timeout time.Duration) (*pb.GadgetSettings, error) {
func (rpc *Rpc) DeployRemoteGadgetSettings(timeout time.Duration, targetGS *pb.GadgetSettings) (*pb.GadgetSettings, error) {
//gs := vue.GetVM(c).Get("gadgetSettings")
println("DeployRemoteGadgetSettings called")
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
return rpc.Client.DeployGadgetSetting(ctx, &pb.Empty{})
return rpc.Client.DeployGadgetSetting(ctx, targetGS)
}