Merge remote-tracking branch 'warped-rudi/cubox-stable' into development. Closes #50
authorLars Op den Kamp <lars@opdenkamp.eu>
Mon, 8 Oct 2012 18:24:03 +0000 (20:24 +0200)
committerLars Op den Kamp <lars@opdenkamp.eu>
Mon, 8 Oct 2012 18:24:03 +0000 (20:24 +0200)
145 files changed:
.gitignore
ChangeLog
configure.ac
debian/changelog
debian/control
debian/control.hardy
debian/libcec2.install [moved from debian/libcec1.install with 100% similarity]
include/cec.h
include/cecc.h
include/cecloader.h
include/cectypes.h
project/LibCecSharp.sln
project/LibCecSharp.vcproj
project/cec-config.rc
project/libCEC.nsi
project/libcec.rc
project/libcec.sln
project/libcec.vcxproj
project/testclient.rc
src/CecSharpTester/CecSharpClient.cs
src/CecSharpTester/Properties/AssemblyInfo.cs
src/LibCecSharp/AssemblyInfo.cpp
src/LibCecSharp/CecSharpTypes.h
src/LibCecSharp/LibCecSharp.cpp
src/LibCecTray/.gitignore [new file with mode: 0644]
src/LibCecTray/LibCECTray.csproj [new file with mode: 0644]
src/LibCecTray/Program.cs [new file with mode: 0644]
src/LibCecTray/Properties/AssemblyInfo.cs [moved from src/cec-config-gui/Properties/AssemblyInfo.cs with 81% similarity]
src/LibCecTray/Properties/Resources.Designer.cs [new file with mode: 0644]
src/LibCecTray/Properties/Resources.resx [new file with mode: 0644]
src/LibCecTray/controller/Actions.cs [new file with mode: 0644]
src/LibCecTray/controller/CECController.cs [new file with mode: 0644]
src/LibCecTray/controller/actions/ConnectToDevice.cs [new file with mode: 0644]
src/LibCecTray/controller/actions/GetCurrentPhysicalAddress.cs [new file with mode: 0644]
src/LibCecTray/controller/actions/RescanDevices.cs [new file with mode: 0644]
src/LibCecTray/controller/actions/SendActivateSource.cs [new file with mode: 0644]
src/LibCecTray/controller/actions/SendImageViewOn.cs [new file with mode: 0644]
src/LibCecTray/controller/actions/SendStandby.cs [new file with mode: 0644]
src/LibCecTray/controller/actions/ShowDeviceInfo.cs [new file with mode: 0644]
src/LibCecTray/controller/actions/UpdateConfiguration.cs [new file with mode: 0644]
src/LibCecTray/controller/actions/UpdateConnectedDevice.cs [new file with mode: 0644]
src/LibCecTray/controller/actions/UpdateDeviceInfo.cs [new file with mode: 0644]
src/LibCecTray/controller/actions/UpdateEvent.cs [new file with mode: 0644]
src/LibCecTray/controller/actions/UpdatePhysicalAddress.cs [new file with mode: 0644]
src/LibCecTray/controller/applications/ApplicationController.cs [new file with mode: 0644]
src/LibCecTray/controller/applications/ApplicationControllerUI.Designer.cs [new file with mode: 0644]
src/LibCecTray/controller/applications/ApplicationControllerUI.cs [new file with mode: 0644]
src/LibCecTray/controller/applications/ApplicationControllerUI.resx [new file with mode: 0644]
src/LibCecTray/controller/applications/ApplicationInput.cs [new file with mode: 0644]
src/LibCecTray/controller/applications/Applications.cs [new file with mode: 0644]
src/LibCecTray/controller/applications/CecButtonConfig.cs [new file with mode: 0644]
src/LibCecTray/controller/applications/CecButtonConfigUI.Designer.cs [new file with mode: 0644]
src/LibCecTray/controller/applications/CecButtonConfigUI.cs [new file with mode: 0644]
src/LibCecTray/controller/applications/CecButtonConfigUI.resx [new file with mode: 0644]
src/LibCecTray/controller/applications/ConfigureApplication.Designer.cs [new file with mode: 0644]
src/LibCecTray/controller/applications/ConfigureApplication.cs [new file with mode: 0644]
src/LibCecTray/controller/applications/ConfigureApplication.resx [moved from src/cec-config-gui/Properties/Resources.resx with 91% similarity]
src/LibCecTray/controller/applications/IControllerTabPage.cs [new file with mode: 0644]
src/LibCecTray/controller/applications/KeyInput.cs [new file with mode: 0644]
src/LibCecTray/controller/applications/WindowsAPI.cs [new file with mode: 0644]
src/LibCecTray/controller/applications/internal/WMCController.cs [new file with mode: 0644]
src/LibCecTray/controller/applications/internal/XBMCController.cs [new file with mode: 0644]
src/LibCecTray/controller/applications/internal/XBMCControllerUI.Designer.cs [new file with mode: 0644]
src/LibCecTray/controller/applications/internal/XBMCControllerUI.cs [new file with mode: 0644]
src/LibCecTray/controller/applications/internal/XBMCControllerUI.resx [new file with mode: 0644]
src/LibCecTray/settings/CECSetting.cs [new file with mode: 0644]
src/LibCecTray/settings/CECSettingBool.cs [new file with mode: 0644]
src/LibCecTray/settings/CECSettingByte.cs [new file with mode: 0644]
src/LibCecTray/settings/CECSettingDeviceType.cs [new file with mode: 0644]
src/LibCecTray/settings/CECSettingLogicalAddress.cs [new file with mode: 0644]
src/LibCecTray/settings/CECSettingLogicalAddresses.cs [new file with mode: 0644]
src/LibCecTray/settings/CECSettingNumeric.cs [new file with mode: 0644]
src/LibCecTray/settings/CECSettingString.cs [new file with mode: 0644]
src/LibCecTray/settings/CECSettingUShort.cs [new file with mode: 0644]
src/LibCecTray/settings/CECSettingVendorId.cs [new file with mode: 0644]
src/LibCecTray/settings/CECSettings.cs [new file with mode: 0644]
src/LibCecTray/ui/About.Designer.cs [new file with mode: 0644]
src/LibCecTray/ui/About.cs [new file with mode: 0644]
src/LibCecTray/ui/About.resx [new file with mode: 0644]
src/LibCecTray/ui/AsyncForm.cs [new file with mode: 0644]
src/LibCecTray/ui/CECTray.Designer.cs [moved from src/cec-config-gui/CecConfigGUI.Designer.cs with 64% similarity]
src/LibCecTray/ui/CECTray.cs [new file with mode: 0644]
src/LibCecTray/ui/CECTray.resx [moved from src/cec-config-gui/CecConfigGUI.resx with 50% similarity]
src/LibCecTray/ui/DeviceInformation.Designer.cs [moved from src/cec-config-gui/DeviceInformation.Designer.cs with 98% similarity]
src/LibCecTray/ui/DeviceInformation.cs [new file with mode: 0644]
src/LibCecTray/ui/DeviceInformation.resx [moved from src/cec-config-gui/DeviceInformation.resx with 100% similarity]
src/cec-config-gui/AsyncForm.cs [deleted file]
src/cec-config-gui/CecButtonConfig.cs [deleted file]
src/cec-config-gui/CecConfigGUI.cs [deleted file]
src/cec-config-gui/DeviceInformation.cs [deleted file]
src/cec-config-gui/Program.cs [deleted file]
src/cec-config-gui/Properties/DataSources/CecButtonConfig.datasource [deleted file]
src/cec-config-gui/Properties/Resources.Designer.cs [deleted file]
src/cec-config-gui/Properties/Settings.Designer.cs [deleted file]
src/cec-config-gui/Properties/Settings.settings [deleted file]
src/cec-config-gui/actions/ConnectToDevice.cs [deleted file]
src/cec-config-gui/actions/RescanDevices.cs [deleted file]
src/cec-config-gui/actions/SendActivateSource.cs [deleted file]
src/cec-config-gui/actions/SendImageViewOn.cs [deleted file]
src/cec-config-gui/actions/SendStandby.cs [deleted file]
src/cec-config-gui/actions/ShowDeviceInfo.cs [deleted file]
src/cec-config-gui/actions/UpdateConfiguration.cs [deleted file]
src/cec-config-gui/actions/UpdateConnectedDevice.cs [deleted file]
src/cec-config-gui/actions/UpdateDeviceInfo.cs [deleted file]
src/cec-config-gui/actions/UpdateEvent.cs [deleted file]
src/cec-config-gui/actions/UpdatePhysicalAddress.cs [deleted file]
src/cec-config-gui/cec-config-gui.csproj [deleted file]
src/cec-config/cec-config.cpp
src/lib/CECClient.cpp
src/lib/CECClient.h
src/lib/CECInputBuffer.h
src/lib/CECProcessor.cpp
src/lib/CECProcessor.h
src/lib/CECTypeUtils.h
src/lib/LibCEC.cpp
src/lib/LibCEC.h
src/lib/LibCECC.cpp
src/lib/adapter/AdapterCommunication.h
src/lib/adapter/Pulse-Eight/USBCECAdapterCommands.cpp
src/lib/adapter/Pulse-Eight/USBCECAdapterCommunication.cpp
src/lib/adapter/Pulse-Eight/USBCECAdapterCommunication.h
src/lib/adapter/Pulse-Eight/USBCECAdapterDetection.cpp
src/lib/adapter/Pulse-Eight/USBCECAdapterDetection.h
src/lib/adapter/Pulse-Eight/USBCECAdapterMessage.cpp
src/lib/adapter/Pulse-Eight/USBCECAdapterMessage.h
src/lib/adapter/Pulse-Eight/USBCECAdapterMessageQueue.cpp
src/lib/adapter/Pulse-Eight/USBCECAdapterMessageQueue.h
src/lib/adapter/RPi/RPiCECAdapterCommunication.cpp
src/lib/adapter/RPi/RPiCECAdapterCommunication.h
src/lib/devices/CECAudioSystem.cpp
src/lib/devices/CECBusDevice.cpp
src/lib/devices/CECPlaybackDevice.cpp
src/lib/implementations/CECCommandHandler.cpp
src/lib/implementations/VLCommandHandler.cpp
src/lib/implementations/VLCommandHandler.h
src/lib/platform/posix/os-socket.h
src/lib/platform/posix/serialport.cpp
src/lib/platform/threads/mutex.h
src/lib/platform/threads/threads.h
src/lib/platform/util/StdString.h
src/lib/platform/util/buffer.h
src/lib/platform/windows/os-threads.h
src/lib/platform/windows/os-types.h
src/testclient/main.cpp
support/create-installer.bat

index 420dc5e6b9740ac3e03c8f19926e66bd643f8b96..b912fbb4ec73ba9242c05397c7d8198b6df80a05 100644 (file)
@@ -42,6 +42,16 @@ config.h.in
 config.h.in~
 stamp-h1
 
+/debian/*.log
+/debian/*.substvars
+/debian/*.debhelper
+/debian/files
+/debian/cec-utils
+/debian/libcec-dev
+/debian/libcec
+/debian/libcec2
+/debian/tmp
+
 include/boost
 
 project/bin
index b2e908e16beb5b25974d24fc2442e7b5faca1f91..64eb888e6acfcc5259c04c92c30f953271cc1058 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,37 @@
+libcec (2.0.1-1) unstable; urgency=low
+
+  * changed/added:
+    * added Loewe support
+    * added signal handlers to client applications
+    * Documentation updated
+    * replaced cec-config-gui by libCEC tray
+    * log the exact data for failed transmissions, not the opcode
+    * don't log every frame, unless debugging was enabled in ./configure or
+      visual studio
+    * changed some log levels from NOTICE to DEBUG, so the non-debugging output
+      is less spammy
+  * interface changes:
+    * WARNING: breaking API changes
+    * clean up: deprecated methods and fields removed
+    * callback parameters changed to fix plain C compilation
+    * added GetAdapterProductId()+GetAdapterVendorId()/
+      cec_get_adapter_product_id()+cec_get_adapter_vendor_id()
+  * fixed:
+    * fix plain C compilation
+    * prevent sending directly addressed commands from being sent to broadcast
+    * don't wait for a response when sending a reply, so we don't block message
+      handling
+    * message response signaling and logging
+    * prevent double taps by not sending the same key press twice within 200ms
+    * fall back to the primary client when
+      CCECProcessor::HandleLogicalAddressLost() and no client could be found
+    * no more delay up to 2 seconds when exiting libCEC
+    * rpi: current firmware first sends a change to logical address 'broadcast'
+      and then signals us that the address was lost. libCEC then failed to
+      re-register, because it didn't know any client at this address
+
+ -- Pulse-Eight Packaging <packaging@pulse-eight.com>  Wed, 3 Oct 2012 16:49:00 +0100
+
 libcec (1.9.1-1) unstable; urgency=low
 
   * changed/added:
index 6206ce0574ed51b9973158dc6e476fb1154c5732..967699255c51c1085d056f5f7276cb4f5061b6dc 100644 (file)
@@ -1,10 +1,10 @@
 AC_PREREQ(2.59)
-AC_INIT([libcec], [1:9:0], [http://libcec.pulse-eight.com/])
+AC_INIT([libcec], [2:0:0], [http://libcec.pulse-eight.com/])
 AC_CONFIG_HEADERS([config.h])
 AH_TOP([#pragma once])
 
 AM_INIT_AUTOMAKE([foreign])
-m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES])
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
 
 AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION)
 
@@ -335,10 +335,11 @@ fi
 LIBS_LIBCEC="$LIBS"
 LIBS="$libs_client"
 
-CXXFLAGS="$CXXFLAGS -fPIC -Wall -Wextra -Wno-missing-field-initializers"
+CXXFLAGS="$CXXFLAGS -fPIC -Wall -Wextra -Werror -Wno-missing-field-initializers"
 
 if test "x$use_debug" = "xyes"; then
   CXXFLAGS="$CXXFLAGS -g"
+  AC_DEFINE(CEC_DEBUGGING,"1", "generate libCEC debug output")
 fi
 
 if test "x$optimisation" = "xyes"; then
index b2e908e16beb5b25974d24fc2442e7b5faca1f91..64eb888e6acfcc5259c04c92c30f953271cc1058 100644 (file)
@@ -1,3 +1,37 @@
+libcec (2.0.1-1) unstable; urgency=low
+
+  * changed/added:
+    * added Loewe support
+    * added signal handlers to client applications
+    * Documentation updated
+    * replaced cec-config-gui by libCEC tray
+    * log the exact data for failed transmissions, not the opcode
+    * don't log every frame, unless debugging was enabled in ./configure or
+      visual studio
+    * changed some log levels from NOTICE to DEBUG, so the non-debugging output
+      is less spammy
+  * interface changes:
+    * WARNING: breaking API changes
+    * clean up: deprecated methods and fields removed
+    * callback parameters changed to fix plain C compilation
+    * added GetAdapterProductId()+GetAdapterVendorId()/
+      cec_get_adapter_product_id()+cec_get_adapter_vendor_id()
+  * fixed:
+    * fix plain C compilation
+    * prevent sending directly addressed commands from being sent to broadcast
+    * don't wait for a response when sending a reply, so we don't block message
+      handling
+    * message response signaling and logging
+    * prevent double taps by not sending the same key press twice within 200ms
+    * fall back to the primary client when
+      CCECProcessor::HandleLogicalAddressLost() and no client could be found
+    * no more delay up to 2 seconds when exiting libCEC
+    * rpi: current firmware first sends a change to logical address 'broadcast'
+      and then signals us that the address was lost. libCEC then failed to
+      re-register, because it didn't know any client at this address
+
+ -- Pulse-Eight Packaging <packaging@pulse-eight.com>  Wed, 3 Oct 2012 16:49:00 +0100
+
 libcec (1.9.1-1) unstable; urgency=low
 
   * changed/added:
index 511fb0c227c5e235066491a92870d5c928258b12..232fdf5255b59b303cf209d11dc3bcdd47c650c2 100644 (file)
@@ -14,19 +14,19 @@ Vcs-Browser: http://anonscm.debian.org/gitweb/?p=collab-maint/libcec.git
 Package: libcec-dev
 Architecture: any
 Section: libdevel
-Depends: libcec1 (= ${binary:Version}),
+Depends: libcec2 (= ${binary:Version}),
          ${misc:Depends}
 Description: USB CEC Adaptor communication Library (development files)
  This library provides support for the Pulse-Eight USB-CEC adapter.
  .
  This package provides the necessary files needed for development.
 
-Package: libcec1
+Package: libcec2
 Architecture: any
 Multi-Arch: same
-Provides: libcec
-Replaces: libcec (<< 1.6)
-Conflicts: libcec (<< 1.6)
+Provides: libcec, libcec1
+Replaces: libcec (<< 1.6), libcec1
+Conflicts: libcec (<< 1.6), libcec1
 Pre-Depends: ${misc:Pre-Depends}
 Depends: ${shlibs:Depends}, ${misc:Depends}
 Description: USB CEC Adaptor communication Library (shared library)
@@ -37,7 +37,7 @@ Description: USB CEC Adaptor communication Library (shared library)
 Package: cec-utils
 Architecture: any
 Section: utils
-Depends: libcec1 (= ${binary:Version}),
+Depends: libcec2 (= ${binary:Version}),
          ${shlibs:Depends},
          ${misc:Depends}
 Description: USB CEC Adaptor communication Library (utility programs)
@@ -47,6 +47,6 @@ Description: USB CEC Adaptor communication Library (utility programs)
 
 Package: libcec
 Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}, libcec1 (= ${binary:Version})
-Description: Transitional package libcec.
+Depends: ${shlibs:Depends}, ${misc:Depends}, libcec2 (= ${binary:Version})
+Description: Meta package libcec.
 
index e92e1b2498091f636697f3dca5da9812e379badf..1806cf3ca098a48eda494d77f3a06d86fd1f3799 100644 (file)
@@ -13,17 +13,17 @@ Vcs-Browser: http://anonscm.debian.org/gitweb/?p=collab-maint/libcec.git
 Package: libcec-dev
 Architecture: any
 Section: libdevel
-Depends: libcec1 (= ${binary:Version}),
+Depends: libcec2 (= ${binary:Version}),
          ${misc:Depends}
 Description: USB CEC Adaptor communication Library (development files)
  This library provides support for the Pulse-Eight USB-CEC adapter.
  .
  This package provides the necessary files needed for development.
 
-Package: libcec1
+Package: libcec2
 Architecture: any
 Multi-Arch: same
-Provides: libcec
+Provides: libcec, libcec1
 Replaces: libcec (<< 1.6)
 Conflicts: libcec (<< 1.6)
 Pre-Depends: ${misc:Pre-Depends}
@@ -36,7 +36,7 @@ Description: USB CEC Adaptor communication Library (shared library)
 Package: cec-utils
 Architecture: any
 Section: utils
-Depends: libcec1 (= ${binary:Version}),
+Depends: libcec2 (= ${binary:Version}),
          ${shlibs:Depends},
          ${misc:Depends}
 Description: USB CEC Adaptor communication Library (utility programs)
@@ -46,6 +46,6 @@ Description: USB CEC Adaptor communication Library (utility programs)
 
 Package: libcec
 Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}, libcec1 (= ${binary:Version})
+Depends: ${shlibs:Depends}, ${misc:Depends}, libcec2 (= ${binary:Version})
 Description: Transitional package libcec.
 
index f5e75903149cdc91aa87a5a23aeebeb06bdb3b90..1b0019bea193a912c165fabaccb0a2d1229c3c3c 100644 (file)
 
 #include "cectypes.h"
 
-#define LIBCEC_VERSION_CURRENT CEC_SERVER_VERSION_1_9_0
+#define LIBCEC_VERSION_CURRENT CEC_SERVER_VERSION_2_0_0
 
 namespace CEC
 {
+  /*!
+   * To create a new libCEC instance, call CECInitialise() and pass the
+   * configuration as argument. Then call Open() to open a connection to the
+   * adapter. Close() closes the connection and CECDestroy() cleans up the
+   * libCEC instance.
+   *
+   * libCEC can send commands to other devices on the CEC bus via the methods
+   * on this interface, and all commands that libCEC received are sent back
+   * to the application via callback methods. The callback methods can be
+   * found in cectypes.h, ICECCallbacks.
+   */
   class ICECAdapter
   {
   public:
@@ -60,20 +71,8 @@ namespace CEC
      */
     virtual void Close(void) = 0;
 
-// XXX XBMC Eden for Windows has been built against 1.2.0 and Ubuntu against 1.5.2
-// we accidently broke the abi between these versions, and this will ensure the upgrade will still work
-#if !defined(_WIN32) && !defined(_WIN64)
     /*!
-     * @brief Set and enable the callback methods. If this method is not called, the GetNext...() methods will have to be used.
-     * @param cbParam Parameter to pass to callback methods.
-     * @param callbacks The callbacks to set.
-     * @return True when enabled, false otherwise.
-     */
-    virtual bool EnableCallbacks(void *cbParam, ICECCallbacks *callbacks) = 0;
-#endif
-
-    /*!
-     * @brief Try to find all connected CEC adapters. Only implemented on Linux and Windows at the moment.
+     * @brief Try to find all connected CEC adapters.
      * @param deviceList The vector to store device descriptors in.
      * @param iBufSize The size of the deviceList buffer.
      * @param strDevicePath Optional device path. Only adds device descriptors that match the given device path.
@@ -82,138 +81,72 @@ namespace CEC
     virtual int8_t FindAdapters(cec_adapter *deviceList, uint8_t iBufSize, const char *strDevicePath = NULL) = 0;
 
     /*!
-     * @brief Ping the CEC adapter.
+     * @brief Sends a ping command to the adapter, to check if it's responding.
      * @return True when the ping was succesful, false otherwise.
      */
     virtual bool PingAdapter(void) = 0;
 
     /*!
-     * @brief Start the bootloader of the CEC adapter.
-     * @return True when the command was sent succesfully, false otherwise.
+     * @brief Start the bootloader of the CEC adapter. Closes the connection when successful.
+     * @return True when the command was sent successfully, false otherwise.
      */
     virtual bool StartBootloader(void) = 0;
     //@}
 
     /*!
-     * @deprecated Use libcec_configuration instead
-     * @return Get the minimal version of libcec that this version of libcec can interface with.
-     */
-    virtual int8_t GetMinLibVersion(void) const = 0;
-
-    /*!
-     * @deprecated Use libcec_configuration instead
-     * @return Get the major version of libcec.
-     */
-    virtual int8_t GetLibVersionMajor(void) const = 0;
-
-    /*!
-     * @deprecated Use libcec_configuration instead
-     * @return Get the minor version of libcec.
-     */
-    virtual int8_t GetLibVersionMinor(void) const = 0;
-
-    /*!
-     * @deprecated Use callback methods instead
-     * @brief Get the next log message in the queue, if there is one.
-     * @param message The next message.
-     * @return True if a message was passed, false otherwise.
-     */
-    virtual bool GetNextLogMessage(cec_log_message *message) = 0;
-
-    /*!
-     * @deprecated Use callback methods instead
-     * @brief Get the next keypress in the queue, if there is one.
-     * @param key The next keypress.
-     * @return True if a key was passed, false otherwise.
-     */
-    virtual bool GetNextKeypress(cec_keypress *key) = 0;
-
-    /*!
-     * @deprecated Use callback methods instead
-     * @brief Get the next CEC command that was received by the adapter.
-     * @param command The next command.
-     * @return True when a command was passed, false otherwise.
-     */
-    virtual bool GetNextCommand(cec_command *command) = 0;
-
-    /*!
-     * @brief Transmit a command over the CEC line.
+     * @brief Transmit a raw CEC command over the CEC line.
      * @param data The command to send.
      * @return True when the data was sent and acked, false otherwise.
      */
     virtual bool Transmit(const cec_command &data) = 0;
 
     /*!
-     * @brief Change the logical address of the CEC adapter.
+     * @brief Change the logical address on the CEC bus of the CEC adapter. libCEC automatically assigns a logical address, and this method is only available for debugging purposes.
      * @param iLogicalAddress The CEC adapter's new logical address.
      * @return True when the logical address was set successfully, false otherwise.
      */
     virtual bool SetLogicalAddress(cec_logical_address iLogicalAddress = CECDEVICE_PLAYBACKDEVICE1) = 0;
 
     /*!
-     * @brief Change the physical address (HDMI port) of the CEC adapter.
+     * @brief Change the physical address (HDMI port) of the CEC adapter. libCEC will try to autodetect the physical address when connecting. If it did, it's set in libcec_configuration.
      * @param iPhysicalAddress The CEC adapter's new physical address.
      * @brief True when the physical address was set successfully, false otherwise.
      */
     virtual bool SetPhysicalAddress(uint16_t iPhysicalAddress = CEC_DEFAULT_PHYSICAL_ADDRESS) = 0;
 
-// XXX XBMC Eden for Windows has been built against 1.2.0 and Ubuntu against 1.5.2
-// we accidently broke the abi between these versions, and this will ensure the upgrade will still work
-#if !defined(_WIN32) && !defined(_WIN64)
-    /*!
-     * @deprecated Use libcec_configuration instead.
-     * @brief Enable physical address detection (if the connected adapter supports this).
-     * @return True when physical address detection was enabled, false otherwise.
-     */
-    virtual bool EnablePhysicalAddressDetection(void) = 0;
-
     /*!
-     * @brief Changes the active HDMI port.
-     * @param iBaseDevice The device to which this libcec is connected.
-     * @param iPort The new port number.
-     * @return True when changed, false otherwise.
-     */
-    virtual bool SetHDMIPort(cec_logical_address iBaseDevice, uint8_t iPort) = 0;
-#endif
-
-    /*!
-     * @brief Power on the connected CEC capable devices.
+     * @brief Power on the given CEC capable devices. If CECDEVICE_BROADCAST is used, then wakeDevice in libcec_configuration will be used.
      * @param address The logical address to power on.
      * @return True when the command was sent succesfully, false otherwise.
      */
     virtual bool PowerOnDevices(cec_logical_address address = CECDEVICE_TV) = 0;
 
     /*!
-     * @brief Put connected CEC capable devices in standby mode.
+     * @brief Put the given CEC capable devices in standby mode. If CECDEVICE_BROADCAST is used, then standbyDevices in libcec_configuration will be used.
      * @brief address The logical address of the device to put in standby.
      * @return True when the command was sent succesfully, false otherwise.
      */
     virtual bool StandbyDevices(cec_logical_address address = CECDEVICE_BROADCAST) = 0;
 
     /*!
-     * @brief Change the active source.
+     * @brief Change the active source to a device type handled by libCEC. Use CEC_DEVICE_TYPE_RESERVED to make the default type used by libCEC active.
      * @param type The new active source. Leave empty to use the primary type
      * @return True when the command was sent succesfully, false otherwise.
      */
     virtual bool SetActiveSource(cec_device_type type = CEC_DEVICE_TYPE_RESERVED) = 0;
 
     /*!
-     * @deprecated Use SetActiveSource() instead
-     */
-    virtual bool SetActiveView(void) = 0;
-
-    /*!
-     * @brief Change the deck control mode, if this adapter is registered as playback device.
+     * @brief Change the deck control mode, if this adapter is registered as playback or recording device.
      * @param mode The new control mode.
-     * @param bSendUpdate True to send the status over the CEC line.
+     * @param bSendUpdate True to send the new status over the CEC line.
      * @return True if set, false otherwise.
      */
     virtual bool SetDeckControlMode(cec_deck_control_mode mode, bool bSendUpdate = true) = 0;
 
     /*!
-     * @brief Change the deck info, if this adapter is a playback device.
+     * @brief Change the deck info, if this adapter is a playback or recording device.
      * @param info The new deck info.
-     * @param bSendUpdate True to send the status over the CEC line.
+     * @param bSendUpdate True to send the new status over the CEC line.
      * @return True if set, false otherwise.
      */
     virtual bool SetDeckInfo(cec_deck_info info, bool bSendUpdate = true) = 0;
@@ -225,16 +158,16 @@ namespace CEC
     virtual bool SetInactiveView(void) = 0;
 
     /*!
-     * @brief Change the menu state.
-     * @param state The new true.
-     * @param bSendUpdate True to send the status over the CEC line.
+     * @brief Change the menu state. This value is already changed by libCEC automatically if a device is (de)activated.
+     * @param state The new state.
+     * @param bSendUpdate True to send the new status over the CEC line.
      * @return True if set, false otherwise.
      */
     virtual bool SetMenuState(cec_menu_state state, bool bSendUpdate = true) = 0;
 
     /*!
-     * @brief Display a message on the device with the given logical address.
-     * @param iLogicalAddress The device to display the message on.
+     * @brief Display a message on the device with the given logical address. Not supported by most TVs.
+     * @param iLogicalAddress The logical address of the device to display the message on.
      * @param duration The duration of the message
      * @param strMessage The message to display.
      * @return True when the command was sent, false otherwise.
@@ -242,7 +175,7 @@ namespace CEC
     virtual bool SetOSDString(cec_logical_address iLogicalAddress, cec_display_control duration, const char *strMessage) = 0;
 
     /*!
-     * @brief Enable or disable monitoring mode.
+     * @brief Enable or disable monitoring mode, for debugging purposes. If monitoring mode is enabled, libCEC won't respond to any command, but only log incoming data.
      * @param bEnable True to enable, false to disable.
      * @return True when switched successfully, false otherwise.
      */
@@ -250,14 +183,14 @@ namespace CEC
 
     /*!
      * @brief Get the CEC version of the device with the given logical address
-     * @param iLogicalAddress The device to get the CEC version for.
+     * @param iLogicalAddress The logical address of the device to get the CEC version for.
      * @return The version or CEC_VERSION_UNKNOWN when the version couldn't be fetched.
      */
     virtual cec_version GetDeviceCecVersion(cec_logical_address iLogicalAddress) = 0;
 
     /*!
      * @brief Get the menu language of the device with the given logical address
-     * @param iLogicalAddress The device to get the menu language for.
+     * @param iLogicalAddress The logical address of the device to get the menu language for.
      * @param language The requested menu language.
      * @return True when fetched succesfully, false otherwise.
      */
@@ -265,38 +198,27 @@ namespace CEC
 
     /*!
      * @brief Get the vendor ID of the device with the given logical address.
-     * @param iLogicalAddress The device to get the vendor id for.
+     * @param iLogicalAddress The logical address of the device to get the vendor ID for.
      * @return The vendor ID or 0 if it wasn't found.
      */
     virtual uint64_t GetDeviceVendorId(cec_logical_address iLogicalAddress) = 0;
 
     /*!
      * @brief Get the power status of the device with the given logical address.
-     * @param iLogicalAddress The device to get the power status for.
+     * @param iLogicalAddress The logical address of the device to get the power status for.
      * @return The power status or CEC_POWER_STATUS_UNKNOWN if it wasn't found.
      */
     virtual cec_power_status GetDevicePowerStatus(cec_logical_address iLogicalAddress) = 0;
 
-// XXX XBMC Eden for Windows has been built against 1.2.0 and Ubuntu against 1.5.2
-// we accidently broke the abi between these versions, and this will ensure the upgrade will still work
-#if !defined(_WIN32) && !defined(_WIN64)
     /*!
-     * @brief Get the physical address of the device with the given logical address.
-     * @param iLogicalAddress The device to get the vendor id for.
-     * @return The physical address or 0 if it wasn't found.
-     */
-    virtual uint16_t GetDevicePhysicalAddress(cec_logical_address iLogicalAddress) = 0;
-#endif
-
-    /*!
-     * @brief Sends a POLL message to a device.
+     * @brief Sends a POLL message to a device, to check if it's present and responding.
      * @param iLogicalAddress The device to send the message to.
      * @return True if the POLL was acked, false otherwise.
      */
     virtual bool PollDevice(cec_logical_address iLogicalAddress) = 0;
 
     /*!
-     * @return The devices that are active on the bus and not handled by libcec.
+     * @return The logical addresses of the devices that are active on the bus, including those handled by libCEC.
      */
     virtual cec_logical_addresses GetActiveDevices(void) = 0;
 
@@ -337,7 +259,7 @@ namespace CEC
 
     /*!
      * @brief Send a keypress to a device on the CEC bus.
-     * @param iDestination The address to send the message to.
+     * @param iDestination The logical address of the device to send the message to.
      * @param key The key to send.
      * @param bWait True to wait for a response, false otherwise.
      * @return True when the keypress was acked, false otherwise.
@@ -346,9 +268,9 @@ namespace CEC
 
     /*!
      * @brief Send a key release to a device on the CEC bus.
-     * @param iDestination The address to send the message to.
+     * @param iDestination The logical address of the device to send the message to.
      * @param bWait True to wait for a response, false otherwise.
-     * @return True when the keypress was acked, false otherwise.
+     * @return True when the key release was acked, false otherwise.
      */
     virtual bool SendKeyRelease(cec_logical_address iDestination, bool bWait = false) = 0;
 
@@ -367,7 +289,7 @@ namespace CEC
 
     /*!
      * @brief Check whether a device is currently the active source on the CEC bus.
-     * @param iLogicalAddress The address to check.
+     * @param iLogicalAddress The logical address of the device to check.
      * @return True when it is the active source, false otherwise.
      */
     virtual bool IsActiveSource(cec_logical_address iLogicalAddress) = 0;
@@ -380,30 +302,17 @@ namespace CEC
     virtual bool SetStreamPath(cec_logical_address iLogicalAddress) = 0;
 
     /*!
-     * @brief Sets the stream path to the device on the given logical address.
+     * @brief Sets the stream path to the device on the given physical address.
      * @param iPhysicalAddress The address to activate.
      * @return True when the command was sent, false otherwise.
      */
     virtual bool SetStreamPath(uint16_t iPhysicalAddress) = 0;
 
     /*!
-     * @return The list of addresses that libCEC is controlling
+     * @return The list of logical addresses that libCEC is controlling
      */
     virtual cec_logical_addresses GetLogicalAddresses(void) = 0;
 
-    virtual const char *ToString(const cec_menu_state state) = 0;
-    virtual const char *ToString(const cec_version version) = 0;
-    virtual const char *ToString(const cec_power_status status) = 0;
-    virtual const char *ToString(const cec_logical_address address) = 0;
-    virtual const char *ToString(const cec_deck_control_mode mode) = 0;
-    virtual const char *ToString(const cec_deck_info status) = 0;
-    virtual const char *ToString(const cec_opcode opcode) = 0;
-    virtual const char *ToString(const cec_system_audio_status mode) = 0;
-    virtual const char *ToString(const cec_audio_status status) = 0;
-    virtual const char *ToString(const cec_vendor_id vendor) = 0;
-    virtual const char *ToString(const cec_client_version version) = 0;
-    virtual const char *ToString(const cec_server_version version) = 0;
-
     /*!
      * @brief Get libCEC's current configuration.
      * @param configuration The configuration.
@@ -419,13 +328,13 @@ namespace CEC
     virtual bool SetConfiguration(const libcec_configuration *configuration) = 0;
 
     /*!
-     * @return True when this device can persist the user configuration, false otherwise.
+     * @return True when this CEC adapter can persist the user configuration, false otherwise.
      */
     virtual bool CanPersistConfiguration(void) = 0;
 
     /*!
      * @brief Persist the given configuration in adapter (if supported)
-     * @brief The configuration to store.
+     * @brief configuration The configuration to store.
      * @return True when the configuration was persisted, false otherwise.
      */
     virtual bool PersistConfiguration(libcec_configuration *configuration) = 0;
@@ -441,7 +350,7 @@ namespace CEC
     virtual bool IsLibCECActiveSource(void) = 0;
 
     /*!
-     * @brief Get information about the given device
+     * @brief Get information about the given CEC adapter.
      * @param strPort The port to which the device is connected
      * @param config The device configuration
      * @param iTimeoutMs The timeout in milliseconds
@@ -449,9 +358,6 @@ namespace CEC
      */
     virtual bool GetDeviceInformation(const char *strPort, libcec_configuration *config, uint32_t iTimeoutMs = 10000) = 0;
 
-// XXX XBMC Eden for Windows has been built against 1.2.0 and Ubuntu against 1.5.2
-// we accidently broke the abi between these versions, and this will ensure the upgrade will still work
-#if defined(_WIN32) || defined(_WIN64)
     /*!
      * @brief Set and enable the callback methods. If this method is not called, the GetNext...() methods will have to be used.
      * @param cbParam Parameter to pass to callback methods.
@@ -460,16 +366,9 @@ namespace CEC
      */
     virtual bool EnableCallbacks(void *cbParam, ICECCallbacks *callbacks) = 0;
 
-        /*!
-     * @deprecated Use libcec_configuration instead.
-     * @brief Enable physical address detection (if the connected adapter supports this).
-     * @return True when physical address detection was enabled, false otherwise.
-     */
-    virtual bool EnablePhysicalAddressDetection(void) = 0;
-
     /*!
      * @brief Changes the active HDMI port.
-     * @param iBaseDevice The device to which this libcec is connected.
+     * @param iBaseDevice The device to which this libCEC is connected.
      * @param iPort The new port number.
      * @return True when changed, false otherwise.
      */
@@ -477,19 +376,16 @@ namespace CEC
 
     /*!
      * @brief Get the physical address of the device with the given logical address.
-     * @param iLogicalAddress The device to get the vendor id for.
+     * @param iLogicalAddress The logical address of the device to get the physical address for.
      * @return The physical address or 0 if it wasn't found.
      */
     virtual uint16_t GetDevicePhysicalAddress(cec_logical_address iLogicalAddress) = 0;
-#endif
 
     /*!
      * @return A string with information about how libCEC was compiled.
      */
     virtual const char *GetLibInfo(void) = 0;
 
-    virtual const char *ToString(const cec_user_control_code key) = 0;
-
     /*!
      * @brief Calling this method will initialise the host on which libCEC is running.
      * Calling this method will initialise the host on which libCEC is running. On the RPi, it calls
@@ -501,23 +397,33 @@ namespace CEC
      */
     virtual void InitVideoStandalone(void) = 0;
 
+    /*!
+     * @return The (virtual) USB vendor id
+     */
+    virtual uint16_t GetAdapterVendorId(void) const = 0;
+
+    /*!
+     * @return The (virtual) USB product id
+     */
+    virtual uint16_t GetAdapterProductId(void) const = 0;
+
+    virtual const char *ToString(const cec_menu_state state) = 0;
+    virtual const char *ToString(const cec_version version) = 0;
+    virtual const char *ToString(const cec_power_status status) = 0;
+    virtual const char *ToString(const cec_logical_address address) = 0;
+    virtual const char *ToString(const cec_deck_control_mode mode) = 0;
+    virtual const char *ToString(const cec_deck_info status) = 0;
+    virtual const char *ToString(const cec_opcode opcode) = 0;
+    virtual const char *ToString(const cec_system_audio_status mode) = 0;
+    virtual const char *ToString(const cec_audio_status status) = 0;
+    virtual const char *ToString(const cec_vendor_id vendor) = 0;
+    virtual const char *ToString(const cec_client_version version) = 0;
+    virtual const char *ToString(const cec_server_version version) = 0;
+    virtual const char *ToString(const cec_user_control_code key) = 0;
     virtual const char *ToString(const cec_adapter_type type) = 0;
   };
 };
 
-/*!
- * @brief Load the CEC adapter library.
- * @param strDeviceName How to present this device to other devices.
- * @param deviceTypes The device types to use on the CEC bus.
- * @return An instance of ICECAdapter or NULL on error.
- */
-extern "C" DECLSPEC void * CECInit(const char *strDeviceName, CEC::cec_device_type_list deviceTypes);
-
-/*!
- * @deprecated
- */
-extern "C" DECLSPEC void * CECCreate(const char *strDeviceName, CEC::cec_logical_address iLogicalAddress = CEC::CECDEVICE_PLAYBACKDEVICE1, uint16_t iPhysicalAddress = CEC_DEFAULT_PHYSICAL_ADDRESS);
-
 /*!
  * @brief Unload the CEC adapter library.
  */
index 60b54bdedba6bb25beddd3131a6088261031bd7a..a4892c48b045ab13d276e1e32ee69738503c0b06 100644 (file)
@@ -46,12 +46,6 @@ extern DECLSPEC int cec_initialise(CEC::libcec_configuration *configuration);
 extern DECLSPEC int cec_initialise(libcec_configuration *configuration);
 #endif
 
-#ifdef __cplusplus
-extern DECLSPEC int cec_init_typed(const char *strDeviceName, CEC::cec_device_type_list deviceTypes);
-#else
-extern DECLSPEC int cec_init_typed(const char *strDeviceName, cec_device_type_list deviceTypes);
-#endif
-
 extern DECLSPEC void cec_destroy(void);
 
 extern DECLSPEC int cec_open(const char *strPort, uint32_t iTimeout);
@@ -74,12 +68,6 @@ extern DECLSPEC int cec_ping_adapters(void);
 
 extern DECLSPEC int cec_start_bootloader(void);
 
-extern DECLSPEC int8_t cec_get_min_lib_version(void);
-
-extern DECLSPEC int8_t cec_get_lib_version_major(void);
-
-extern DECLSPEC int8_t cec_get_lib_version_minor(void);
-
 #ifdef __cplusplus
 extern DECLSPEC int cec_power_on_devices(CEC::cec_logical_address address);
 #else
@@ -92,8 +80,6 @@ extern DECLSPEC int cec_standby_devices(CEC::cec_logical_address address);
 extern DECLSPEC int cec_standby_devices(cec_logical_address address);
 #endif
 
-extern DECLSPEC int cec_set_active_view(void);
-
 #ifdef __cplusplus
 extern DECLSPEC int cec_set_active_source(CEC::cec_device_type type);
 #else
@@ -120,24 +106,6 @@ extern DECLSPEC int cec_set_menu_state(CEC::cec_menu_state state, int bSendUpdat
 extern DECLSPEC int cec_set_menu_state(cec_menu_state state, int bSendUpdate);
 #endif
 
-#ifdef __cplusplus
-extern DECLSPEC int cec_get_next_log_message(CEC::cec_log_message *message);
-#else
-extern DECLSPEC int cec_get_next_log_message(cec_log_message *message);
-#endif
-
-#ifdef __cplusplus
-extern DECLSPEC int cec_get_next_keypress(CEC::cec_keypress *key);
-#else
-extern DECLSPEC int cec_get_next_keypress(cec_keypress *key);
-#endif
-
-#ifdef __cplusplus
-extern DECLSPEC int cec_get_next_command(CEC::cec_command *command);
-#else
-extern DECLSPEC int cec_get_next_command(cec_command *command);
-#endif
-
 #ifdef __cplusplus
 extern DECLSPEC int cec_transmit(const CEC::cec_command *data);
 #else
@@ -256,8 +224,6 @@ extern DECLSPEC CEC::cec_osd_name cec_get_device_osd_name(CEC::cec_logical_addre
 extern DECLSPEC cec_osd_name cec_get_device_osd_name(cec_logical_address iAddress);
 #endif
 
-extern DECLSPEC int cec_enable_physical_address_detection(void);
-
 #ifdef __cplusplus
 extern DECLSPEC int cec_set_stream_path_logical(CEC::cec_logical_address iAddress);
 #else
@@ -306,6 +272,10 @@ extern DECLSPEC const char * cec_get_lib_info(void);
 
 extern DECLSPEC void cec_init_video_standalone(void);
 
+extern DECLSPEC uint16_t cec_get_adapter_vendor_id(void);
+
+extern DECLSPEC uint16_t cec_get_adapter_product_id(void);
+
 #ifdef __cplusplus
 };
 #endif
index 7a7dce6cf583d70c340e7f1fc9f5d0bcd5c9a595..de138cc7ea90e070e6a056bb9f60bd21bbc353e4 100644 (file)
 
 HINSTANCE g_libCEC = NULL;
 
-/*!
- * @brief Create a new libCEC instance.
- * @param strDeviceName The name of the primary device to pass to other CEC devices.
- * @param types The list of device types to register on the bus.
- * @param strLib The name of and/or path to libCEC
- * @return An instance of libCEC or NULL when it failed to load.
- */
-CEC::ICECAdapter *LibCecInit(const char *strDeviceName, CEC::cec_device_type_list types, const char *strLib = NULL)
-{
-  if (!g_libCEC)
-#if defined(_WIN64)
-    g_libCEC = LoadLibrary(strLib ? strLib : "libcec.x64.dll");
-#else
-    g_libCEC = LoadLibrary(strLib ? strLib : "libcec.dll");
-#endif
-  if (!g_libCEC)
-    return NULL;
-
-  typedef void* (__cdecl*_LibCecInit)(const char *, CEC::cec_device_type_list);
-  _LibCecInit LibCecInit;
-  LibCecInit = (_LibCecInit) (GetProcAddress(g_libCEC, "CECInit"));
-  if (!LibCecInit)
-    return NULL;
-  return static_cast< CEC::ICECAdapter* > (LibCecInit(strDeviceName, types));
-}
-
 /*!
  * @brief Create a new libCEC instance.
  * @param configuration The configuration to pass to libCEC
@@ -145,40 +119,6 @@ bool LibCecBootloader(const char *strLib = NULL)
 
 void *g_libCEC = NULL;
 
-/*!
- * @brief Create a new libCEC instance.
- * @param strDeviceName The name of the primary device to pass to other CEC devices.
- * @param types The list of device types to register on the bus.
- * @param strLib The name of and/or path to libCEC
- * @return An instance of libCEC or NULL when it failed to load.
- */
-CEC::ICECAdapter *LibCecInit(const char *strDeviceName, CEC::cec_device_type_list types, const char *strLib = NULL)
-{
-  if (!g_libCEC)
-  {
-#if defined(__APPLE__)
-    g_libCEC = dlopen(strLib ? strLib : "libcec.dylib", RTLD_LAZY);
-#else
-    g_libCEC = dlopen(strLib ? strLib : "libcec.so." CEC_LIB_VERSION_MAJOR_STR, RTLD_LAZY);
-#endif
-    if (!g_libCEC)
-    {
-      cout << dlerror() << endl;
-      return NULL;
-    }
-  }
-
-  typedef void* _LibCecInit(const char *, CEC::cec_device_type_list);
-  _LibCecInit* LibCecInit = (_LibCecInit*) dlsym(g_libCEC, "CECInit");
-  if (!LibCecInit)
-  {
-    cout << "cannot find CECInit" << endl;
-    return NULL;
-  }
-
-  return (CEC::ICECAdapter*) LibCecInit(strDeviceName, types);
-}
-
 /*!
  * @brief Create a new libCEC instance.
  * @param configuration The configuration to pass to libCEC
index a44bbeaaf3c3d033aceabe4abb5b79e01d74e4aa..2af86437c726152708000c6cb77b3b8422aa2d11 100644 (file)
@@ -61,77 +61,262 @@ extern "C" {
 namespace CEC {
 #endif
 
-//default physical address 1.0.0.0, HDMI port 1
+/*!
+ * default physical address 1.0.0.0, HDMI port 1
+ */
 #define CEC_DEFAULT_PHYSICAL_ADDRESS 0x1000
+/*!
+ * default HDMI port to which the adapter is connected, port 1
+ */
 #define CEC_DEFAULT_HDMI_PORT        1
+/*!
+ * default logical address of the device to which the adapter is connected, TV
+ */
 #define CEC_DEFAULT_BASE_DEVICE      0
-#define MSGSTART                     0xFF
-#define MSGEND                       0xFE
-#define MSGESC                       0xFD
-#define ESCOFFSET                    3
+
+/*!
+ * timeout in milliseconds to send a key release event after receiving a key press
+ */
 #define CEC_BUTTON_TIMEOUT           500
+
+/*!
+ * don't send the same key twice within this timeout in milliseconds
+ */
+#define CEC_DOUBLE_TAP_TIMEOUT_MS    200
+
+/*!
+ * don't query the power state for the same device within this timeout in milliseconds
+ */
 #define CEC_POWER_STATE_REFRESH_TIME 30000
+
+/*!
+ * unknown firmware version value
+ */
 #define CEC_FW_VERSION_UNKNOWN       0xFFFF
+
+/*!
+ * unknown build date value
+ */
 #define CEC_FW_BUILD_UNKNOWN         0
+
+/*!
+ * maximum number of retries when opening a connection
+ */
 #define CEC_CONNECT_TRIES            3
 
+/*!
+ * physical address of the TV
+ */
 #define CEC_PHYSICAL_ADDRESS_TV      0
+
+/*!
+ * minimum physical address for the adapter
+ */
 #define CEC_MIN_PHYSICAL_ADDRESS     0x1000
+
+/*!
+ * maximum physical address for the adapter
+ */
 #define CEC_MAX_PHYSICAL_ADDRESS     0xFFFE
+
+/*!
+ * invalid physical address value
+ */
 #define CEC_INVALID_PHYSICAL_ADDRESS 0xFFFF
 
+/*!
+ * minimum vendor ID value
+ */
 #define CEC_MIN_VENDORID             1
+
+/*!
+ * maximum vendor ID value
+ */
 #define CEC_MAX_VENDORID             0xFFFFFE
+
+/*!
+ * invalid vendor ID value
+ */
 #define CEC_INVALID_VENDORID         0xFFFFFF
 
+/*!
+ * minimum HDMI port number value
+ */
 #define CEC_MIN_HDMI_PORTNUMBER      1
+
+/*!
+ * maximum HDMI port number value
+ */
 #define CEC_MAX_HDMI_PORTNUMBER      15
+
+/*!
+ * invalid HDMI port number value
+ */
 #define CEC_HDMI_PORTNUMBER_NONE     0
 
+/*!
+ * default value for settings "use tv menu language"
+ */
 #define CEC_DEFAULT_SETTING_USE_TV_MENU_LANGUAGE      1
+
+/*!
+ * default value for settings "activate source"
+ */
 #define CEC_DEFAULT_SETTING_ACTIVATE_SOURCE           1
+
+/*!
+ * default value for settings "power off on shutdown"
+ */
 #define CEC_DEFAULT_SETTING_POWER_OFF_SHUTDOWN        1
+
+/*!
+ * default value for settings "power off when activating the screensaver"
+ */
 #define CEC_DEFAULT_SETTING_POWER_OFF_SCREENSAVER     1
+
+/*!
+ * default value for settings "power off on standby"
+ */
 #define CEC_DEFAULT_SETTING_POWER_OFF_ON_STANDBY      1
+
+/*!
+ * default value for settings "shutdown on standby"
+ */
 #define CEC_DEFAULT_SETTING_SHUTDOWN_ON_STANDBY       0
+
+/*!
+ * default value for settings "send inactive source when stopping"
+ */
 #define CEC_DEFAULT_SETTING_SEND_INACTIVE_SOURCE      1
+
+/*!
+ * default value for settings "power off devices when going to standby"
+ */
 #define CEC_DEFAULT_SETTING_POWER_OFF_DEVICES_STANDBY 1
+
+/*!
+ * default value for settings "device menu language"
+ */
 #define CEC_DEFAULT_DEVICE_LANGUAGE                   "eng"
+
+/*!
+ * default value for settings "autodetect physical address"
+ */
 #define CEC_DEFAULT_SETTING_AUTODETECT_ADDRESS        0
+
+/*!
+ * default value for settings "get settings from ROM"
+ */
 #define CEC_DEFAULT_SETTING_GET_SETTINGS_FROM_ROM     0
+
+/*!
+ * default value for settings "libCEC CEC version"
+ */
 #define CEC_DEFAULT_SETTING_CEC_VERSION               0x05
 
+/*!
+ * wait this amount of milliseconds before retrying to send a failed message
+ */
 #define CEC_DEFAULT_TRANSMIT_RETRY_WAIT 500
+
+/*!
+ * transmission fails when not acked within this amount of milliseconds after sending the initial packet
+ */
 #define CEC_DEFAULT_TRANSMIT_TIMEOUT    1000
+
+/*!
+ * wait this amount of milliseconds for an ack
+ */
 #define CEC_DEFAULT_TRANSMIT_WAIT       1000
+
+/*!
+ * default number of retries
+ */
 #define CEC_DEFAULT_TRANSMIT_RETRIES    1
 
+/*!
+ * default connection timeout in milliseconds
+ */
 #define CEC_DEFAULT_CONNECT_TIMEOUT     10000
+
+/*!
+ * wait this amount of milliseconds before retrying when failing to connect
+ */
 #define CEC_DEFAULT_CONNECT_RETRY_WAIT  1000
+
+/*!
+ * default serial baudrate
+ */
 #define CEC_SERIAL_DEFAULT_BAUDRATE     38400
+
+/*!
+ * maximum time to wait when clearing input
+ */
 #define CEC_CLEAR_INPUT_DEFAULT_WAIT    1000
 
+/*!
+ * wait this amount of milliseconds before retrying when libCEC failed to make itself the active source
+ */
 #define CEC_ACTIVE_SOURCE_SWITCH_RETRY_TIME_MS 5000
+
+/*!
+ * don't forward any power off command to the client application for this amount of milliseconds after sending a power off command
+ */
 #define CEC_FORWARD_STANDBY_MIN_INTERVAL 10000
 
+/*!
+ * the virtual device path to use for the Raspberry Pi's CEC wire
+ */
 #define CEC_RPI_VIRTUAL_PATH           "Raspberry Pi"
+
+/*!
+ * the name of the virtual COM port to use for the Raspberry Pi's CEC wire
+ */
 #define CEC_RPI_VIRTUAL_COM            "RPI"
 
+/*!
+ * the path to use for the TDA995x's CEC wire
+ */
 #define CEC_TDA995x_PATH               "/dev/hdmicec"
+
+/*!
+ * the name of the virtual COM port to use for the TDA995x's CEC wire
+ */
 #define CEC_TDA995x_VIRTUAL_COM                "CuBox"
 
-#define CEC_MIN_LIB_VERSION          1
-#define CEC_LIB_VERSION_MAJOR        1
-#define CEC_LIB_VERSION_MAJOR_STR    "1"
-#define CEC_LIB_VERSION_MINOR        9
+/*!
+ * Mimimum client version
+ */
+#define CEC_MIN_LIB_VERSION          2
+
+/*!
+ * libCEC's major version number
+ */
+#define CEC_LIB_VERSION_MAJOR        2
+
+/*!
+ * libCEC's major version number as string
+ */
+#define CEC_LIB_VERSION_MAJOR_STR    "2"
+
+/*!
+ * libCEC's minor version number
+ */
+#define CEC_LIB_VERSION_MINOR        0
+
+#define MSGSTART                     0xFF
+#define MSGEND                       0xFE
+#define MSGESC                       0xFD
+#define ESCOFFSET                    3
+
 
 typedef enum cec_abort_reason
 {
-  CEC_ABORT_REASON_UNRECOGNIZED_OPCODE            = 0,
-  CEC_ABORT_REASON_NOT_IN_CORRECT_MODE_TO_RESPOND = 1,
-  CEC_ABORT_REASON_CANNOT_PROVIDE_SOURCE          = 2,
-  CEC_ABORT_REASON_INVALID_OPERAND                = 3,
-  CEC_ABORT_REASON_REFUSED                        = 4
+  CEC_ABORT_REASON_UNRECOGNIZED_OPCODE            = 0,//!< CEC_ABORT_REASON_UNRECOGNIZED_OPCODE
+  CEC_ABORT_REASON_NOT_IN_CORRECT_MODE_TO_RESPOND = 1,//!< CEC_ABORT_REASON_NOT_IN_CORRECT_MODE_TO_RESPOND
+  CEC_ABORT_REASON_CANNOT_PROVIDE_SOURCE          = 2,//!< CEC_ABORT_REASON_CANNOT_PROVIDE_SOURCE
+  CEC_ABORT_REASON_INVALID_OPERAND                = 3,//!< CEC_ABORT_REASON_INVALID_OPERAND
+  CEC_ABORT_REASON_REFUSED                        = 4 //!< CEC_ABORT_REASON_REFUSED
 } cec_abort_reason;
 
 typedef enum cec_analogue_broadcast_type
@@ -646,6 +831,7 @@ typedef enum cec_vendor_id
   CEC_VENDOR_SHARP     = 0x08001F,
   CEC_VENDOR_VIZIO     = 0x6B746D,
   CEC_VENDOR_BROADCOM  = 0x18C086,
+  CEC_VENDOR_LOEWE     = 0x000982,
    
   CEC_VENDOR_UNKNOWN   = 0
 } cec_vendor_id;
@@ -773,11 +959,10 @@ typedef struct cec_command
   int32_t             transmit_timeout; /**< the timeout to use in ms */
 
 #ifdef __cplusplus
-  // @todo re-add in v2.0 (breaks ABI)
-  //cec_command(void)
-  //{
-  //  Clear();
-  //}
+  cec_command(void)
+  {
+    Clear();
+  }
 
   cec_command &operator =(const struct cec_command &command)
   {
@@ -899,18 +1084,6 @@ typedef struct cec_device_type_list
   cec_device_type types[5]; /**< the list of device types */
 
 #ifdef __cplusplus
-  /*!
-   * @deprecated Use Clear() instead.
-   * @brief Clear this list.
-   */
-  void clear(void) { Clear(); }
-  /*!
-   * @deprecated Use Add() instead.
-   * @brief Add a type to this list.
-   * @param type The type to add.
-   */
-  void add(const cec_device_type type) { Add(type); }
-
   /*!
    * @brief Clear this list.
    */
@@ -1092,21 +1265,21 @@ typedef enum libcec_parameter_type
   CEC_PARAMETER_TYPE_UNKOWN
 } libcec_parameter_type;
 
-struct libcec_parameter
+typedef struct libcec_parameter
 {
   libcec_parameter_type paramType; /**< the type of this parameter */
   void*                 paramData; /**< the value of this parameter */
-};
+} libcec_parameter;
 
-struct libcec_configuration;
+typedef struct libcec_configuration libcec_configuration;
 
-typedef int (CEC_CDECL* CBCecLogMessageType)(void *param, const cec_log_message &);
-typedef int (CEC_CDECL* CBCecKeyPressType)(void *param, const cec_keypress &);
-typedef int (CEC_CDECL* CBCecCommandType)(void *param, const cec_command &);
-typedef int (CEC_CDECL* CBCecConfigurationChangedType)(void *param, const libcec_configuration &);
-typedef int (CEC_CDECL* CBCecAlertType)(void *param, const libcec_alert, const libcec_parameter &);
-typedef int (CEC_CDECL* CBCecMenuStateChangedType)(void *param, const cec_menu_state);
-typedef void (CEC_CDECL* CBCecSourceActivatedType)(void *param, const cec_logical_address, const uint8_t);
+typedef int (CEC_CDECL* CBCecLogMessageType)(void*, const cec_log_message);
+typedef int (CEC_CDECL* CBCecKeyPressType)(void*, const cec_keypress);
+typedef int (CEC_CDECL* CBCecCommandType)(void*, const cec_command);
+typedef int (CEC_CDECL* CBCecConfigurationChangedType)(void*, const libcec_configuration);
+typedef int (CEC_CDECL* CBCecAlertType)(void*, const libcec_alert, const libcec_parameter);
+typedef int (CEC_CDECL* CBCecMenuStateChangedType)(void*, const cec_menu_state);
+typedef void (CEC_CDECL* CBCecSourceActivatedType)(void*, const cec_logical_address, const uint8_t);
 
 typedef struct ICECCallbacks
 {
@@ -1165,9 +1338,8 @@ typedef struct ICECCallbacks
   CBCecSourceActivatedType CBCecSourceActivated;
 
 #ifdef __cplusplus
-  // @todo re-add in v2.0 (breaks ABI)
-  // ICECCallbacks(void) { Clear(); }
-  //~ICECCallbacks(void) { Clear(); };
+   ICECCallbacks(void) { Clear(); }
+  ~ICECCallbacks(void) { Clear(); };
 
   void Clear(void)
   {
@@ -1199,7 +1371,9 @@ typedef enum cec_client_version
   CEC_CLIENT_VERSION_1_8_0   = 0x1800,
   CEC_CLIENT_VERSION_1_8_1   = 0x1801,
   CEC_CLIENT_VERSION_1_8_2   = 0x1802,
-  CEC_CLIENT_VERSION_1_9_0   = 0x1900
+  CEC_CLIENT_VERSION_1_9_0   = 0x1900,
+  CEC_CLIENT_VERSION_1_99_0  = 0x1990,
+  CEC_CLIENT_VERSION_2_0_0   = 0x2000,
 } cec_client_version;
 
 typedef enum cec_server_version
@@ -1219,21 +1393,23 @@ typedef enum cec_server_version
   CEC_SERVER_VERSION_1_8_0   = 0x1800,
   CEC_SERVER_VERSION_1_8_1   = 0x1801,
   CEC_SERVER_VERSION_1_8_2   = 0x1802,
-  CEC_SERVER_VERSION_1_9_0   = 0x1900
+  CEC_SERVER_VERSION_1_9_0   = 0x1900,
+  CEC_SERVER_VERSION_1_99_0  = 0x1990,
+  CEC_SERVER_VERSION_2_0_0   = 0x2000,
 } cec_server_version;
 
-typedef struct libcec_configuration
+struct libcec_configuration
 {
   uint32_t              clientVersion;        /*!< the version of the client that is connecting */
-  char                  strDeviceName[13];    /*!< how to name the device on the CEC bus */
-  cec_device_type_list  deviceTypes;          /*!< the CEC device types to emulate */
+  char                  strDeviceName[13];    /*!< the device name to use on the CEC bus */
+  cec_device_type_list  deviceTypes;          /*!< the device type(s) to use on the CEC bus for libCEC */
   uint8_t               bAutodetectAddress;   /*!< (read only) set to 1 by libCEC when the physical address was autodetected */
-  uint16_t              iPhysicalAddress;     /*!< the physical address of the CEC adapter. only used when bAutodetectAddress = 0 or when the adapter doesn't support autodetection */
-  cec_logical_address   baseDevice;           /*!< the logical address of the device to which the adapter is connected. only used when iPhysicalAddress = 0 and bAutodetectAddress = 0 or when the adapter doesn't support autodetection */
-  uint8_t               iHDMIPort;            /*!< the HDMI port to which the adapter is connected. only used when iPhysicalAddress = 0 and bAutodetectAddress = 0 or when the adapter doesn't support autodetection */
+  uint16_t              iPhysicalAddress;     /*!< the physical address of the CEC adapter */
+  cec_logical_address   baseDevice;           /*!< the logical address of the device to which the adapter is connected. only used when iPhysicalAddress = 0 or when the adapter doesn't support autodetection */
+  uint8_t               iHDMIPort;            /*!< the HDMI port to which the adapter is connected. only used when iPhysicalAddress = 0 or when the adapter doesn't support autodetection */
   uint64_t              tvVendor;             /*!< override the vendor ID of the TV. leave this untouched to autodetect */
-  cec_logical_addresses wakeDevices;          /*!< wake these CEC devices when initialising libCEC or when calling PowerOnDevices() without any parameter */
-  cec_logical_addresses powerOffDevices;      /*!< power off these devices when calling StandbyDevices() without any parameter */
+  cec_logical_addresses wakeDevices;          /*!< list of devices to wake when initialising libCEC or when calling PowerOnDevices() without any parameter. */
+  cec_logical_addresses powerOffDevices;      /*!< list of devices to power off when calling StandbyDevices() without any parameter. */
 
   uint32_t              serverVersion;        /*!< the version number of the server. read-only */
 
@@ -1257,46 +1433,41 @@ typedef struct libcec_configuration
   uint8_t               bMonitorOnly;         /*!< won't allocate a CCECClient when starting the connection when set (same as monitor mode). added in 1.6.3 */
   cec_version           cecVersion;           /*!< CEC spec version to use by libCEC. defaults to v1.4. added in 1.8.0 */
   cec_adapter_type      adapterType;          /*!< type of the CEC adapter that we're connected to. added in 1.8.2 */
+  uint8_t               iDoubleTapTimeoutMs;  /*!< prevent double taps withing this timeout. defaults to 200ms. added in 2.0.0 */
 
 #ifdef __cplusplus
-  // @todo re-add in v2.0 (breaks ABI)
-  // libcec_configuration(void) { Clear(); }
-  //~libcec_configuration(void) { Clear(); }
+   libcec_configuration(void) { Clear(); }
+  ~libcec_configuration(void) { Clear(); }
 
   bool operator==(const libcec_configuration &other) const
   {
-    return (     clientVersion        == other.clientVersion &&
-        !strncmp(strDeviceName,          other.strDeviceName, 13) &&
-                 deviceTypes          == other.deviceTypes &&
-                 bAutodetectAddress   == other.bAutodetectAddress &&
-                 iPhysicalAddress     == other.iPhysicalAddress &&
-                 baseDevice           == other.baseDevice &&
-                 iHDMIPort            == other.iHDMIPort &&
-                 tvVendor             == other.tvVendor &&
-                 wakeDevices          == other.wakeDevices &&
-                 powerOffDevices      == other.powerOffDevices &&
-                 serverVersion        == other.serverVersion &&
-                 bGetSettingsFromROM  == other.bGetSettingsFromROM &&
-                 bUseTVMenuLanguage   == other.bUseTVMenuLanguage &&
-                 bActivateSource      == other.bActivateSource &&
-                 bPowerOffScreensaver == other.bPowerOffScreensaver &&
-                 bPowerOffOnStandby   == other.bPowerOffOnStandby &&
-                 bSendInactiveSource  == other.bSendInactiveSource &&
-        /* libcec 1.5.3+ */
-        (other.clientVersion < CEC_CLIENT_VERSION_1_5_3 || logicalAddresses == other.logicalAddresses) &&
-        /* libcec 1.6.0+ */
-        (other.clientVersion < CEC_CLIENT_VERSION_1_6_0 || iFirmwareVersion          == other.iFirmwareVersion) &&
-        (other.clientVersion < CEC_CLIENT_VERSION_1_6_0 || bPowerOffDevicesOnStandby == other.bPowerOffDevicesOnStandby) &&
-        (other.clientVersion < CEC_CLIENT_VERSION_1_6_0 || bShutdownOnStandby        == other.bShutdownOnStandby) &&
-        /* libcec 1.6.2+ */
-        (other.clientVersion < CEC_CLIENT_VERSION_1_6_2 || !strncmp(strDeviceLanguage, other.strDeviceLanguage, 3)) &&
-        (other.clientVersion < CEC_CLIENT_VERSION_1_6_2 || iFirmwareBuildDate        == other.iFirmwareBuildDate) &&
-        /* libcec 1.6.3+ */
-        (other.clientVersion < CEC_CLIENT_VERSION_1_6_3 || bMonitorOnly              == other.bMonitorOnly) &&
-        /* libcec 1.8.0+ */
-        (other.clientVersion < CEC_CLIENT_VERSION_1_8_0 || cecVersion                == other.cecVersion) &&
-        /* libcec 1.8.2+ */
-        (other.clientVersion < CEC_CLIENT_VERSION_1_8_2 || adapterType               == other.adapterType));
+    return (     clientVersion             == other.clientVersion &&
+        !strncmp(strDeviceName,               other.strDeviceName, 13) &&
+                  deviceTypes               == other.deviceTypes &&
+                  bAutodetectAddress        == other.bAutodetectAddress &&
+                  iPhysicalAddress          == other.iPhysicalAddress &&
+                  baseDevice                == other.baseDevice &&
+                  iHDMIPort                 == other.iHDMIPort &&
+                  tvVendor                  == other.tvVendor &&
+                  wakeDevices               == other.wakeDevices &&
+                  powerOffDevices           == other.powerOffDevices &&
+                  serverVersion             == other.serverVersion &&
+                  bGetSettingsFromROM       == other.bGetSettingsFromROM &&
+                  bUseTVMenuLanguage        == other.bUseTVMenuLanguage &&
+                  bActivateSource           == other.bActivateSource &&
+                  bPowerOffScreensaver      == other.bPowerOffScreensaver &&
+                  bPowerOffOnStandby        == other.bPowerOffOnStandby &&
+                  bSendInactiveSource       == other.bSendInactiveSource &&
+                  logicalAddresses          == other.logicalAddresses &&
+                  iFirmwareVersion          == other.iFirmwareVersion &&
+                  bPowerOffDevicesOnStandby == other.bPowerOffDevicesOnStandby &&
+                  bShutdownOnStandby        == other.bShutdownOnStandby &&
+        !strncmp(strDeviceLanguage,           other.strDeviceLanguage, 3) &&
+                  iFirmwareBuildDate        == other.iFirmwareBuildDate &&
+                  bMonitorOnly              == other.bMonitorOnly &&
+                  cecVersion                == other.cecVersion &&
+                  adapterType               == other.adapterType &&
+                  iDoubleTapTimeoutMs       == other.iDoubleTapTimeoutMs);
   }
 
   bool operator!=(const libcec_configuration &other) const
@@ -1313,8 +1484,8 @@ typedef struct libcec_configuration
     baseDevice = (cec_logical_address)CEC_DEFAULT_BASE_DEVICE;
     iHDMIPort =                       CEC_DEFAULT_HDMI_PORT;
     tvVendor =              (uint64_t)CEC_VENDOR_UNKNOWN;
-    clientVersion =         (uint32_t)CEC_CLIENT_VERSION_PRE_1_5;
-    serverVersion =         (uint32_t)CEC_SERVER_VERSION_PRE_1_5;
+    clientVersion =         (uint32_t)CEC_CLIENT_VERSION_2_0_0;
+    serverVersion =         (uint32_t)CEC_SERVER_VERSION_2_0_0;
     bAutodetectAddress =              0;
     bGetSettingsFromROM =             CEC_DEFAULT_SETTING_GET_SETTINGS_FROM_ROM;
     bUseTVMenuLanguage =              CEC_DEFAULT_SETTING_USE_TV_MENU_LANGUAGE;
@@ -1330,9 +1501,10 @@ typedef struct libcec_configuration
     bMonitorOnly =                    0;
     cecVersion =         (cec_version)CEC_DEFAULT_SETTING_CEC_VERSION;
     adapterType =                     ADAPTERTYPE_UNKNOWN;
+    iDoubleTapTimeoutMs =             CEC_DOUBLE_TAP_TIMEOUT_MS;
 
     memset(strDeviceName, 0, 13);
-    deviceTypes.clear();
+    deviceTypes.Clear();
     logicalAddresses.Clear();
     wakeDevices.Clear();
     powerOffDevices.Clear();
@@ -1348,7 +1520,7 @@ typedef struct libcec_configuration
     callbacks     = NULL;
   }
 #endif
-} libcec_configuration;
+};
 
 #ifdef __cplusplus
 };
index 81b35c839eb441dcb5bbcb1816cd09a1acd7a728..7b9b1db546ee94ac5f807eacfd16916b0d307433 100644 (file)
@@ -5,7 +5,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CecSharpTester", "..\src\Ce
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibCecSharp", "LibCecSharp.vcproj", "{E54D4581-CD59-4687-BB10-694B8192EABA}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "cec-config-gui", "..\src\cec-config-gui\cec-config-gui.csproj", "{58C106FE-C159-46D3-97E1-73AB83232670}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LibCECTray", "..\src\LibCecTray\LibCECTray.csproj", "{58C106FE-C159-46D3-97E1-73AB83232670}"
 EndProject
 Global
        GlobalSection(SolutionConfigurationPlatforms) = preSolution
index 39f93b53d507cb2aa34dc2b7464483dd8dcf6b05..7bce4c0b697ab5383ce011f10188a289904bc767 100644 (file)
@@ -51,6 +51,7 @@
                                PreprocessorDefinitions="_DEBUG;_CRT_SECURE_NO_WARNINGS"
                                RuntimeLibrary="3"
                                UsePrecompiledHeader="0"
+                               GenerateXMLDocumentationFiles="true"
                                WarningLevel="3"
                                WarnAsError="true"
                                DebugInformationFormat="3"
                                PreprocessorDefinitions="_DEBUG;_CRT_SECURE_NO_WARNINGS"
                                RuntimeLibrary="3"
                                UsePrecompiledHeader="0"
+                               GenerateXMLDocumentationFiles="true"
                                WarningLevel="3"
                                WarnAsError="true"
                                DebugInformationFormat="3"
                                PreprocessorDefinitions="NDEBUG;_CRT_SECURE_NO_WARNINGS"
                                RuntimeLibrary="2"
                                UsePrecompiledHeader="0"
+                               GenerateXMLDocumentationFiles="true"
                                WarningLevel="3"
                                WarnAsError="true"
                                DebugInformationFormat="3"
                                PreprocessorDefinitions="NDEBUG;_CRT_SECURE_NO_WARNINGS"
                                RuntimeLibrary="2"
                                UsePrecompiledHeader="0"
+                               GenerateXMLDocumentationFiles="true"
                                WarningLevel="3"
                                WarnAsError="true"
                                DebugInformationFormat="3"
index 794082517e725c368e0775be77d891de7be39725..8927346fb6504637f061b04a5451ced071ca5c9c 100644 (file)
Binary files a/project/cec-config.rc and b/project/cec-config.rc differ
index f4b2cfb275b454827debaefddd01917d3d7aca4a..514840673440a763c065970fdffd0cfabef1b1ce 100644 (file)
@@ -7,7 +7,7 @@
 !include "LogicLib.nsh"
 !include "x64.nsh"
 
-Name "Pulse-Eight USB-CEC Adapter"
+Name "Pulse-Eight libCEC version 2.0.0"
 OutFile "..\build\libCEC-installer.exe"
 
 XPStyle on
@@ -128,8 +128,10 @@ Section "libCEC" SecLibCec
   File "..\ChangeLog"
   File "..\README"
   File "..\build\*.dll"
+  File "..\build\*.xml"
   SetOutPath "$INSTDIR\x64"
   File /nonfatal "..\build\x64\*.dll"
+  File /nonfatal "..\build\x64\*.xml"
 
   ; Copy to XBMC\system
   ReadRegStr $1 HKCU "Software\XBMC" ""
@@ -149,9 +151,9 @@ Section "CEC debug client" SecCecClient
 
   ; Copy to the installation directory
   SetOutPath "$INSTDIR"
-  File /x p8-usbcec-driver-installer.exe /x cec-config-gui.exe "..\build\*.exe"
+  File /x p8-usbcec-driver-installer.exe /x cec-tray.exe "..\build\*.exe"
   SetOutPath "$INSTDIR\x64"
-  File /nonfatal /x cec-config-gui.exe "..\build\x64\*.exe"
+  File /nonfatal /x cec-tray.exe "..\build\x64\*.exe"
 
   !insertmacro MUI_STARTMENU_WRITE_BEGIN Application
   SetOutPath "$INSTDIR"
@@ -170,28 +172,47 @@ Section "CEC debug client" SecCecClient
     
 SectionEnd
 
-Section "CEC configuration tool" SecCecConfig
+Section "libCEC Tray Application" SecCecTray
   SetShellVarContext current
   SectionIn 1 3
 
+  ; Uninstall previous beta builds of the tray application
+  ReadRegStr $1 HKLM "Software\Pulse-Eight\libCECTray" ""
+  ${If} $1 != ""
+    MessageBox MB_OK \
+         "A previous beta build of the libCEC Tray Application was found. Press OK to uninstall the old version. Do not uninstall the driver when asked to. Thank you for participating in the beta test."
+    ExecWait '"$1\Uninstall.exe" /S _?=$1'
+       Delete "$1\Uninstall.exe"
+  ${EndIf}
+
+  ; Replace cec-config-gui.exe
+  Delete "$INSTDIR\cec-config-gui.exe"
+  ${If} ${RunningX64}
+    Delete "$INSTDIR\x64\cec-config-gui.exe"
+  ${EndIf}
+  Delete "$SMPROGRAMS\$StartMenuFolder\CEC Adapter Configuration.lnk"
+  ${If} ${RunningX64}
+    Delete "$SMPROGRAMS\$StartMenuFolder\CEC Adapter Configuration (x64).lnk"
+  ${EndIf}
+
   ; Copy to the installation directory
   SetOutPath "$INSTDIR"
-  File "..\build\cec-config-gui.exe"
+  File "..\build\cec-tray.exe"
   SetOutPath "$INSTDIR\x64"
-  File /nonfatal "..\build\x64\cec-config-gui.exe"
+  File /nonfatal "..\build\x64\cec-tray.exe"
 
   !insertmacro MUI_STARTMENU_WRITE_BEGIN Application
   SetOutPath "$INSTDIR"
 
   CreateDirectory "$SMPROGRAMS\$StartMenuFolder"
   ${If} ${RunningX64}
-    CreateShortCut "$SMPROGRAMS\$StartMenuFolder\CEC Adapter Configuration (x64).lnk" "$INSTDIR\x64\cec-config-gui.exe" \
-      "" "$INSTDIR\x64\cec-config-gui.exe" 0 SW_SHOWNORMAL \
-      "" "Start the CEC Adapter Configuration tool (x64)."
+    CreateShortCut "$SMPROGRAMS\$StartMenuFolder\libCEC Tray (x64).lnk" "$INSTDIR\x64\cec-tray.exe" \
+      "" "$INSTDIR\x64\cec-tray.exe" 0 SW_SHOWNORMAL \
+      "" "Start the libCEC Tray (x64)."
   ${Else}
-    CreateShortCut "$SMPROGRAMS\$StartMenuFolder\CEC Adapter Configuration.lnk" "$INSTDIR\cec-config-gui.exe" \
-      "" "$INSTDIR\cec-config-gui.exe" 0 SW_SHOWNORMAL \
-      "" "Start the CEC Adapter Configuration tool."
+    CreateShortCut "$SMPROGRAMS\$StartMenuFolder\libCEC Tray.lnk" "$INSTDIR\cec-tray.exe" \
+      "" "$INSTDIR\cec-tray.exe" 0 SW_SHOWNORMAL \
+      "" "Start the libCEC Tray."
   ${EndIf}
   !insertmacro MUI_STARTMENU_WRITE_END  
     
@@ -279,9 +300,11 @@ Section "Uninstall"
   Delete "$INSTDIR\COPYING"
   Delete "$INSTDIR\*.dll"
   Delete "$INSTDIR\*.lib"
+  Delete "$INSTDIR\*.xml"
   Delete "$INSTDIR\x64\*.dll"
   Delete "$INSTDIR\x64\*.lib"
   Delete "$INSTDIR\x64\*.exe"
+  Delete "$INSTDIR\x64\*.xml"
   Delete "$INSTDIR\README"
   Delete "$SYSDIR\libcec.dll"
   ${If} ${RunningX64}
@@ -300,9 +323,9 @@ Section "Uninstall"
   RMDir "$PROGRAMFILES\Pulse-Eight"
   
   !insertmacro MUI_STARTMENU_GETFOLDER Application $StartMenuFolder
-  Delete "$SMPROGRAMS\$StartMenuFolder\CEC Adapter Configuration.lnk"
+  Delete "$SMPROGRAMS\$StartMenuFolder\libCEC Tray.lnk"
   ${If} ${RunningX64}
-    Delete "$SMPROGRAMS\$StartMenuFolder\CEC Adapter Configuration (x64).lnk"
+    Delete "$SMPROGRAMS\$StartMenuFolder\libCEC Tray (x64).lnk"
   ${EndIf}
   Delete "$SMPROGRAMS\$StartMenuFolder\CEC Test client.lnk"
   ${If} ${RunningX64}
index 7b488df50750ddabfc055c8d25f3895293552703..579649fd32745d1e49a76be7227dc27f9c25b76d 100644 (file)
Binary files a/project/libcec.rc and b/project/libcec.rc differ
index dbb86c9fb8e6be5013a36feefac4187a2f3b60da..83d6d89a119dce27f3818cadc30679e0c58e6e05 100644 (file)
@@ -8,11 +8,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testclient", "testclient.vc
                {C04B0FB1-667D-4F1C-BDAE-A07CDFFAAAA0} = {C04B0FB1-667D-4F1C-BDAE-A07CDFFAAAA0}
        EndProjectSection
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cec-config", "cec-config.vcxproj", "{00EE7081-9EEE-485C-B7CE-699A7BCA40C1}"
-       ProjectSection(ProjectDependencies) = postProject
-               {C04B0FB1-667D-4F1C-BDAE-A07CDFFAAAA0} = {C04B0FB1-667D-4F1C-BDAE-A07CDFFAAAA0}
-       EndProjectSection
-EndProject
 Global
        GlobalSection(SolutionConfigurationPlatforms) = preSolution
                Debug|Win32 = Debug|Win32
@@ -37,14 +32,6 @@ Global
                {F01222BF-6B3D-43BD-B254-434031CB9887}.Release|Win32.Build.0 = Release|Win32
                {F01222BF-6B3D-43BD-B254-434031CB9887}.Release|x64.ActiveCfg = Release|x64
                {F01222BF-6B3D-43BD-B254-434031CB9887}.Release|x64.Build.0 = Release|x64
-               {00EE7081-9EEE-485C-B7CE-699A7BCA40C1}.Debug|Win32.ActiveCfg = Debug|Win32
-               {00EE7081-9EEE-485C-B7CE-699A7BCA40C1}.Debug|Win32.Build.0 = Debug|Win32
-               {00EE7081-9EEE-485C-B7CE-699A7BCA40C1}.Debug|x64.ActiveCfg = Debug|x64
-               {00EE7081-9EEE-485C-B7CE-699A7BCA40C1}.Debug|x64.Build.0 = Debug|x64
-               {00EE7081-9EEE-485C-B7CE-699A7BCA40C1}.Release|Win32.ActiveCfg = Release|Win32
-               {00EE7081-9EEE-485C-B7CE-699A7BCA40C1}.Release|Win32.Build.0 = Release|Win32
-               {00EE7081-9EEE-485C-B7CE-699A7BCA40C1}.Release|x64.ActiveCfg = Release|x64
-               {00EE7081-9EEE-485C-B7CE-699A7BCA40C1}.Release|x64.Build.0 = Release|x64
        EndGlobalSection
        GlobalSection(SolutionProperties) = preSolution
                HideSolutionNode = FALSE
index dd529e1b454008fd7d1f9a387eba321f68c503ea..fca963584b394266b155de494885bbc7e1325c47 100644 (file)
     <ClCompile>
       <WarningLevel>Level4</WarningLevel>
       <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>HAVE_P8_USB;_USE_32BIT_TIME_T;_DEBUG;_CRT_SECURE_NO_WARNINGS;_WINSOCKAPI_;__STDC_CONSTANT_MACROS;DLL_EXPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>CEC_DEBUGGING;HAVE_P8_USB;_USE_32BIT_TIME_T;_DEBUG;_CRT_SECURE_NO_WARNINGS;_WINSOCKAPI_;__STDC_CONSTANT_MACROS;DLL_EXPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <AdditionalIncludeDirectories>$(SolutionDir)..\include;$(SolutionDir)..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <DisableSpecificWarnings>
       </DisableSpecificWarnings>
     <ClCompile>
       <WarningLevel>Level4</WarningLevel>
       <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>HAVE_P8_USB;_WIN64;_DEBUG;_CRT_SECURE_NO_WARNINGS;_WINSOCKAPI_;__STDC_CONSTANT_MACROS;DLL_EXPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>CEC_DEBUGGING;HAVE_P8_USB;_WIN64;_DEBUG;_CRT_SECURE_NO_WARNINGS;_WINSOCKAPI_;__STDC_CONSTANT_MACROS;DLL_EXPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <AdditionalIncludeDirectories>$(SolutionDir)..\include;$(SolutionDir)..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <DisableSpecificWarnings>
       </DisableSpecificWarnings>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
\ No newline at end of file
+</Project>
index c227b7ee4dbeb2394564b646f19f930bd3591900..b7f8c08cf5572dde4344636fcda3dcc91567f987 100644 (file)
Binary files a/project/testclient.rc and b/project/testclient.rc differ
index dca7ce0ff8d84b18098453370e3ee913f79304e2..37b04e9cf6c759f58f4b7635de0ea925e541b043 100644 (file)
@@ -43,7 +43,7 @@ namespace CecSharpClient
       Config = new LibCECConfiguration();
       Config.DeviceTypes.Types[0] = CecDeviceType.RecordingDevice;
       Config.DeviceName = "CEC Tester";
-      Config.ClientVersion = CecClientVersion.Version1_9_0;
+      Config.ClientVersion = CecClientVersion.Version2_0_0;
       Config.SetCallbacks(this);
       LogLevel = (int)CecLogLevel.All;
 
index 53d167cea85425497d257c96ce72d1425af3a2bd..2b249ff4d4c91c5822f3b93182bfe2bb83901a31 100644 (file)
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
 // You can specify all the values or you can default the Build and Revision Numbers 
 // by using the '*' as shown below:
 // [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.9.0.0")]
-[assembly: AssemblyFileVersion("1.9.0.0")]
+[assembly: AssemblyVersion("2.0.0.0")]
+[assembly: AssemblyFileVersion("2.0.0.0")]
index 9f633ca2274f6fe0cda6bf2224be4c6fed22935a..ed06b3b3ba74c9aa3b3866cd669024bbe97a0e9f 100644 (file)
@@ -13,7 +13,7 @@ using namespace System::Security::Permissions;
 [assembly:AssemblyTrademarkAttribute("")];
 [assembly:AssemblyCultureAttribute("")];
 
-[assembly:AssemblyVersionAttribute("1.9.0.0")];
+[assembly:AssemblyVersionAttribute("2.0.0.0")];
 
 [assembly:ComVisible(false)];
 [assembly:CLSCompliantAttribute(true)];
index 52c0b2020797bfd702ddbc4aa293395f49947f27..fb14a54dba9cc00c6ac50d1b695fcacb29656507 100644 (file)
@@ -1,35 +1,35 @@
 #pragma once
 /*
- * This file is part of the libCEC(R) library.
- *
- * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
- * libCEC(R) is an original work, containing original code.
- *
- * libCEC(R) is a trademark of Pulse-Eight Limited.
- *
- * This program is dual-licensed; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- *
- * Alternatively, you can license this library under a commercial license,
- * please contact Pulse-Eight Licensing for more information.
- *
- * For more information contact:
- * Pulse-Eight Licensing       <license@pulse-eight.com>
- *     http://www.pulse-eight.com/
- *     http://www.pulse-eight.net/
- */
+* This file is part of the libCEC(R) library.
+*
+* libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
+* libCEC(R) is an original work, containing original code.
+*
+* libCEC(R) is a trademark of Pulse-Eight Limited.
+*
+* This program is dual-licensed; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+*
+* Alternatively, you can license this library under a commercial license,
+* please contact Pulse-Eight Licensing for more information.
+*
+* For more information contact:
+* Pulse-Eight Licensing       <license@pulse-eight.com>
+*     http://www.pulse-eight.com/
+*     http://www.pulse-eight.net/
+*/
 
 #include "../lib/platform/threads/mutex.h"
 #include <vcclr.h>
 
 #using <System.dll>
 
+/// <summary>
+/// LibCecSharp namespace
+/// </summary>
+/// <see cref="LibCecSharp" />
 namespace CecSharp
 {
-       public enum class CecDeviceType
-       {
-               Tv              = 0,
-               RecordingDevice = 1,
-               Reserved        = 2,
-               Tuner           = 3,
-               PlaybackDevice  = 4,
-               AudioSystem     = 5
-       };
-
-       public enum class CecLogLevel
-       {
-               None    = 0,
-               Error   = 1,
-               Warning = 2,
-               Notice  = 4,
-               Traffic = 8,
-               Debug   = 16,
-               All     = 31
-       };
-
-       public enum class CecLogicalAddress
-       {
-               Unknown          = -1, //not a valid logical address
-               Tv               = 0,
-               RecordingDevice1 = 1,
-               RecordingDevice2 = 2,
-               Tuner1           = 3,
-               PlaybackDevice1  = 4,
-               AudioSystem      = 5,
-               Tuner2           = 6,
-               Tuner3           = 7,
-               PlaybackDevice2  = 8,
-               RecordingDevice3 = 9,
-               Tuner4           = 10,
-               PlaybackDevice3  = 11,
-               Reserved1        = 12,
-               Reserved2        = 13,
-               FreeUse          = 14,
-               Unregistered     = 15,
-               Broadcast        = 15
-       };
-
-       public enum class CecAlert
-       {
-               ServiceDevice = 1
-       };
-
-       public enum class CecParameterType
-       {
-               ParameterTypeString = 1
-       };
-
-       public ref class CecParameter
-       {
-       public:
-               CecParameter(CecParameterType type, System::String ^ strData)
-               {
-                       Type = type;
-                       Data = strData;
-               }
-
-               property CecParameterType Type;
-               property System::String ^ Data;
-       };
-
-       public enum class CecPowerStatus
-       {
-               On                      = 0x00,
-               Standby                 = 0x01,
-               InTransitionStandbyToOn = 0x02,
-               InTransitionOnToStandby = 0x03,
-               Unknown                 = 0x99
-       };
-
-       public enum class CecVersion
-       {
-               Unknown = 0x00,
-               V1_2    = 0x01,
-               V1_2A   = 0x02,
-               V1_3    = 0x03,
-               V1_3A   = 0x04,
-               V1_4    = 0x05
-       };
-
-       public enum class CecDisplayControl
-       {
-               DisplayForDefaultTime = 0x00,
-               DisplayUntilCleared   = 0x40,
-               ClearPreviousMessage  = 0x80,
-               ReservedForFutureUse  = 0xC0
-       };
-
-       public enum class CecMenuState
-       {
-               Activated   = 0,
-               Deactivated = 1
-       };
-
-       public enum class CecDeckControlMode
-       {
-               SkipForwardWind   = 1,
-               SkipReverseRewind = 2,
-               Stop              = 3,
-               Eject             = 4
-       };
-
-       public enum class CecDeckInfo
-       {
-               Play               = 0x11,
-               Record             = 0x12,
-               Reverse            = 0x13,
-               Still              = 0x14,
-               Slow               = 0x15,
-               SlowReverse        = 0x16,
-               FastForward        = 0x17,
-               FastReverse        = 0x18,
-               NoMedia            = 0x19,
-               Stop               = 0x1A,
-               SkipForwardWind    = 0x1B,
-               SkipReverseRewind  = 0x1C,
-               IndexSearchForward = 0x1D,
-               IndexSearchReverse = 0x1E,
-               OtherStatus        = 0x1F
-       };
-
-       public enum class CecUserControlCode
-       {
-               Select                      = 0x00,
-               Up                          = 0x01,
-               Down                        = 0x02,
-               Left                        = 0x03,
-               Right                       = 0x04,
-               RightUp                     = 0x05,
-               RightDown                   = 0x06,
-               LeftUp                      = 0x07,
-               LeftDown                    = 0x08,
-               RootMenu                    = 0x09,
-               SetupMenu                   = 0x0A,
-               ContentsMenu                = 0x0B,
-               FavoriteMenu                = 0x0C,
-               Exit                        = 0x0D,
-               Number0                     = 0x20,
-               Number1                     = 0x21,
-               Number2                     = 0x22,
-               Number3                     = 0x23,
-               Number4                     = 0x24,
-               Number5                     = 0x25,
-               Number6                     = 0x26,
-               Number7                     = 0x27,
-               Number8                     = 0x28,
-               Number9                     = 0x29,
-               Dot                         = 0x2A,
-               Enter                       = 0x2B,
-               Clear                       = 0x2C,
-               NextFavorite                = 0x2F,
-               ChannelUp                   = 0x30,
-               ChannelDown                 = 0x31,
-               PreviousChannel             = 0x32,
-               SoundSelect                 = 0x33,
-               InputSelect                 = 0x34,
-               DisplayInformation          = 0x35,
-               Help                        = 0x36,
-               PageUp                      = 0x37,
-               PageDown                    = 0x38,
-               Power                       = 0x40,
-               VolumeUp                    = 0x41,
-               VolumeDown                  = 0x42,
-               Mute                        = 0x43,
-               Play                        = 0x44,
-               Stop                        = 0x45,
-               Pause                       = 0x46,
-               Record                      = 0x47,
-               Rewind                      = 0x48,
-               FastForward                 = 0x49,
-               Eject                       = 0x4A,
-               Forward                     = 0x4B,
-               Backward                    = 0x4C,
-               StopRecord                  = 0x4D,
-               PauseRecord                 = 0x4E,
-               Angle                       = 0x50,
-               SubPicture                  = 0x51,
-               VideoOnDemand               = 0x52,
-               ElectronicProgramGuide      = 0x53,
-               TimerProgramming            = 0x54,
-               InitialConfiguration        = 0x55,
-               PlayFunction                = 0x60,
-               PausePlayFunction           = 0x61,
-               RecordFunction              = 0x62,
-               PauseRecordFunction         = 0x63,
-               StopFunction                = 0x64,
-               MuteFunction                = 0x65,
-               RestoreVolumeFunction       = 0x66,
-               TuneFunction                = 0x67,
-               SelectMediaFunction         = 0x68,
-               SelectAVInputFunction       = 0x69,
-               SelectAudioInputFunction    = 0x6A,
-               PowerToggleFunction         = 0x6B,
-               PowerOffFunction            = 0x6C,
-               PowerOnFunction             = 0x6D,
-               F1Blue                      = 0x71,
-               F2Red                       = 0X72,
-               F3Green                     = 0x73,
-               F4Yellow                    = 0x74,
-               F5                          = 0x75,
-               Data                        = 0x76,
-               Max                         = 0x76,
-               SamsungReturn               = 0x91,
-               Unknown
-       };
-
-       public enum class CecVendorId
-       {
-               Samsung   = 0x0000F0,
-               LG        = 0x00E091,
-               Panasonic = 0x008045,
-               Pioneer   = 0x00E036,
-               Onkyo     = 0x0009B0,
-               Yamaha    = 0x00A0DE,
-               Philips   = 0x00903E,
-               Sony      = 0x080046,
-               Toshiba   = 0x000039,
-               Akai      = 0x0020C7,
-               Benq      = 0x8065E9,
-               Daewoo    = 0x009053,
-               Grundig   = 0x00D0D5,
-               Medion    = 0x000CB8,
-               Sharp     = 0x08001F,
-               Vizio     = 0x6B746D,
-               Unknown   = 0
-       };
-
-       public enum class CecAudioStatus
-       {
-               MuteStatusMask      = 0x80,
-               VolumeStatusMask    = 0x7F,
-               VolumeMin           = 0x00,
-               VolumeMax           = 0x64,
-               VolumeStatusUnknown = 0x7F
-       };
-
-       public enum class CecOpcode
-       {
-               ActiveSource                  = 0x82,
-               ImageViewOn                   = 0x04,
-               TextViewOn                    = 0x0D,
-               InactiveSource                = 0x9D,
-               RequestActiveSource           = 0x85,
-               RoutingChange                 = 0x80,
-               RoutingInformation            = 0x81,
-               SetStreamPath                 = 0x86,
-               Standby                       = 0x36,
-               RecordOff                     = 0x0B,
-               RecordOn                      = 0x09,
-               RecordStatus                  = 0x0A,
-               RecordTvScreen                = 0x0F,
-               ClearAnalogueTimer            = 0x33,
-               ClearDigitalTimer             = 0x99,
-               ClearExternalTimer            = 0xA1,
-               SetAnalogueTimer              = 0x34,
-               SetDigitalTimer               = 0x97,
-               SetExternalTimer              = 0xA2,
-               SetTimerProgramTitle          = 0x67,
-               TimerClearedStatus            = 0x43,
-               TimerStatus                   = 0x35,
-               CecVersion                    = 0x9E,
-               GetCecVersion                 = 0x9F,
-               GivePhysicalAddress           = 0x83,
-               GetMenuLanguage               = 0x91,
-               ReportPhysicalAddress         = 0x84,
-               SetMenuLanguage               = 0x32,
-               DeckControl                   = 0x42,
-               DeckStatus                    = 0x1B,
-               GiveDeckStatus                = 0x1A,
-               Play                          = 0x41,
-               GiveTunerDeviceStatus         = 0x08,
-               SelectAnalogueService         = 0x92,
-               SelectDigtalService           = 0x93,
-               TunerDeviceStatus             = 0x07,
-               TunerStepDecrement            = 0x06,
-               TunerStepIncrement            = 0x05,
-               DeviceVendorId                = 0x87,
-               GiveDeviceVendorId            = 0x8C,
-               VendorCommand                 = 0x89,
-               VendorCommandWithId           = 0xA0,
-               VendorRemoteButtonDown        = 0x8A,
-               VendorRemoteButtonUp          = 0x8B,
-               SetOsdString                  = 0x64,
-               GiveOsdName                   = 0x46,
-               SetOsdName                    = 0x47,
-               MenuRequest                   = 0x8D,
-               MenuStatus                    = 0x8E,
-               UserControlPressed            = 0x44,
-               UserControlRelease            = 0x45,
-               GiveDevicePowerStatus         = 0x8F,
-               ReportPowerStatus             = 0x90,
-               FeatureAbort                  = 0x00,
-               Abort                         = 0xFF,
-               GiveAudioStatus               = 0x71,
-               GiveSystemAudioMode           = 0x7D,
-               ReportAudioStatus             = 0x7A,
-               SetSystemAudioMode            = 0x72,
-               SystemAudioModeRequest        = 0x70,
-               SystemAudioModeStatus         = 0x7E,
-               SetAudioRate                  = 0x9A,
-               /* when this opcode is set, no opcode will be sent to the device. this is one of the reserved numbers */
-               None                          = 0xFD
-       };
-
-       public enum class CecSystemAudioStatus
-       {
-               Off = 0,
-               On  = 1
-       };
-
-       public enum class CecClientVersion
-       {
-               VersionPre1_5 = 0,
-               Version1_5_0  = 0x1500,
-               Version1_5_1  = 0x1501,
-               Version1_5_2  = 0x1502,
-               Version1_5_3  = 0x1503,
-               Version1_6_0  = 0x1600,
-               Version1_6_1  = 0x1601,
-               Version1_6_2  = 0x1602,
-               Version1_6_3  = 0x1603,
-               Version1_7_0  = 0x1700,
-               Version1_7_1  = 0x1701,
-               Version1_7_2  = 0x1702,
-               Version1_8_0  = 0x1800,
-               Version1_8_1  = 0x1801,
-               Version1_8_2  = 0x1802,
-               Version1_9_0  = 0x1900
-       };
-
-       public enum class CecServerVersion
-       {
-               VersionPre1_5 = 0,
-               Version1_5_0  = 0x1500,
-               Version1_5_1  = 0x1501,
-               Version1_5_2  = 0x1502,
-               Version1_5_3  = 0x1503,
-               Version1_6_0  = 0x1600,
-               Version1_6_1  = 0x1601,
-               Version1_6_2  = 0x1602,
-               Version1_6_3  = 0x1603,
-               Version1_7_0  = 0x1700,
-               Version1_7_1  = 0x1701,
-               Version1_7_2  = 0x1702,
-               Version1_8_0  = 0x1800,
-               Version1_8_1  = 0x1801,
-               Version1_8_2  = 0x1802,
-               Version1_9_0  = 0x1900
-       };
-
-       public ref class CecAdapter
-       {
-       public:
-               CecAdapter(System::String ^ strPath, System::String ^ strComPort)
-               {
-                       Path = strPath;
-                       ComPort = strComPort;
-               }
-
-               property System::String ^ Path;
-               property System::String ^ ComPort;
-       };
-
-       public ref class CecDeviceTypeList
-       {
-       public:
-               CecDeviceTypeList(void)
-               {
-                       Types = gcnew array<CecDeviceType>(5);
-                       for (unsigned int iPtr = 0; iPtr < 5; iPtr++)
-                               Types[iPtr] = CecDeviceType::Reserved;
-               }
-
-               property array<CecDeviceType> ^ Types;
-       };
-
-       public ref class CecLogicalAddresses
-       {
-       public:
-               CecLogicalAddresses(void)
-               {
-                       Addresses = gcnew array<CecLogicalAddress>(16);
-                       Clear();
-               }
-
-               void Clear(void)
-               {
-                       Primary = CecLogicalAddress::Unknown;
-                       for (unsigned int iPtr = 0; iPtr < 16; iPtr++)
-                               Addresses[iPtr] = CecLogicalAddress::Unknown;
-               }
-
-               bool IsSet(CecLogicalAddress iAddress)
-               {
-                       return Addresses[(unsigned int)iAddress] != CecLogicalAddress::Unknown;
-               }
-
-         void Set(CecLogicalAddress iAddress)
-               {
-                       Addresses[(unsigned int)iAddress] = iAddress;
-                       if (Primary == CecLogicalAddress::Unknown)
-                               Primary = iAddress;
-               }
-
-               property CecLogicalAddress          Primary;
-               property array<CecLogicalAddress> ^ Addresses;
-       };
-
-       public ref class CecDatapacket
-       {
-       public:
-               CecDatapacket(void)
-               {
-                       Data = gcnew array<uint8_t>(100);
-                       Size = 0;
-               }
-
-               void PushBack(uint8_t data)
-               {
-                       if (Size < 100)
-                       {
-                               Data[Size] = data;
-                               Size++;
-                       }
-               }
-
-               property array<uint8_t> ^ Data;
-               property uint8_t          Size;
-       };
-
-       public ref class CecCommand
-       {
-       public:
-               CecCommand(CecLogicalAddress iInitiator, CecLogicalAddress iDestination, bool bAck, bool bEom, CecOpcode iOpcode, int32_t iTransmitTimeout)
-               {
-                       Initiator       = iInitiator;
-                       Destination     = iDestination;
-                       Ack             = bAck;
-                       Eom             = bEom;
-                       Opcode          = iOpcode;
-                       OpcodeSet       = true;
-                       TransmitTimeout = iTransmitTimeout;
-                       Parameters      = gcnew CecDatapacket;
-                       Empty           = false;
-               }
-
-               CecCommand(void)
-               {
-                       Initiator       = CecLogicalAddress::Unknown;
-                       Destination     = CecLogicalAddress::Unknown;
-                       Ack             = false;
-                       Eom             = false;
-                       Opcode          = CecOpcode::None;
-                       OpcodeSet       = false;
-                       TransmitTimeout = 0;
-                       Parameters      = gcnew CecDatapacket;
-                       Empty           = true;
-               }
-
-               void PushBack(uint8_t data)
-               {
-                       if (Initiator == CecLogicalAddress::Unknown && Destination == CecLogicalAddress::Unknown)
-                       {
-                               Initiator   = (CecLogicalAddress) (data >> 4);
-                               Destination = (CecLogicalAddress) (data & 0xF);
-                       }
-                       else if (!OpcodeSet)
-                       {
-                               OpcodeSet = true;
-                               Opcode    = (CecOpcode)data;
-                       }
-                       else
-                       {
-                               Parameters->PushBack(data);
-                       }
-               }
-
-               property bool               Empty;
-               property CecLogicalAddress  Initiator;
-               property CecLogicalAddress  Destination;
-               property bool               Ack;
-               property bool               Eom;
-               property CecOpcode          Opcode;
-               property CecDatapacket ^    Parameters;
-               property bool               OpcodeSet;
-               property int32_t            TransmitTimeout;
-       };
-
-       public ref class CecKeypress
-       {
-       public:
-               CecKeypress(CecUserControlCode iKeycode, unsigned int iDuration)
-               {
-                       Keycode  = iKeycode;
-                       Duration = iDuration;
-                       Empty    = false;
-               }
-
-               CecKeypress(void)
-               {
-                       Keycode  = CecUserControlCode::Unknown;
-                       Duration = 0;
-                       Empty    = true;
-               }
-
-               property bool               Empty;
-               property CecUserControlCode Keycode;
-               property unsigned int       Duration;
-       };
-
-       public ref class CecLogMessage
-       {
-       public:
-               CecLogMessage(System::String ^ strMessage, CecLogLevel iLevel, int64_t iTime)
-               {
-                       Message = strMessage;
-                       Level   = iLevel;
-                       Time    = iTime;
-                       Empty   = false;
-               }
-
-               CecLogMessage(void)
-               {
-                       Message = "";
-                       Level   = CecLogLevel::None;
-                       Time    = 0;
-                       Empty   = true;
-               }
-
-               property bool            Empty;
-               property System::String ^Message;
-               property CecLogLevel     Level;
-               property int64_t         Time;
-       };
-
-       ref class CecCallbackMethods; //forward
-       public ref class LibCECConfiguration
-       {
-       public:
-               LibCECConfiguration(void)
-               {
-                       DeviceName          = "";
-                       DeviceTypes         = gcnew CecDeviceTypeList();
-                       AutodetectAddress  = true;
-                       PhysicalAddress     = CEC_DEFAULT_PHYSICAL_ADDRESS;
-                       BaseDevice          = (CecLogicalAddress)CEC_DEFAULT_BASE_DEVICE;
-                       HDMIPort            = CEC_DEFAULT_HDMI_PORT;
-                       ClientVersion       = CecClientVersion::VersionPre1_5;
-                       ServerVersion       = CecServerVersion::VersionPre1_5;
-                       TvVendor            = CecVendorId::Unknown;
-
-                       GetSettingsFromROM  = false;
-                       UseTVMenuLanguage   = CEC_DEFAULT_SETTING_USE_TV_MENU_LANGUAGE == 1;
-                       ActivateSource      = CEC_DEFAULT_SETTING_ACTIVATE_SOURCE == 1;
-
-                       WakeDevices         = gcnew CecLogicalAddresses();
-                       if (CEC_DEFAULT_SETTING_ACTIVATE_SOURCE == 1)
-                               WakeDevices->Set(CecLogicalAddress::Tv);
-
-                       PowerOffDevices     = gcnew CecLogicalAddresses();
-                       if (CEC_DEFAULT_SETTING_POWER_OFF_SHUTDOWN == 1)
-                               PowerOffDevices->Set(CecLogicalAddress::Broadcast);
-
-                       PowerOffScreensaver = CEC_DEFAULT_SETTING_POWER_OFF_SCREENSAVER == 1;
-                       PowerOffOnStandby   = CEC_DEFAULT_SETTING_POWER_OFF_ON_STANDBY == 1;
-
-                       SendInactiveSource  = CEC_DEFAULT_SETTING_SEND_INACTIVE_SOURCE == 1;
-                       LogicalAddresses    = gcnew CecLogicalAddresses();
-                       FirmwareVersion     = 1;
-                       PowerOffDevicesOnStandby = CEC_DEFAULT_SETTING_POWER_OFF_DEVICES_STANDBY == 1;
-                       ShutdownOnStandby   = CEC_DEFAULT_SETTING_SHUTDOWN_ON_STANDBY == 1;
-                       DeviceLanguage      = "";
-               }
-
-               void SetCallbacks(CecCallbackMethods ^callbacks)
-               {
-                       Callbacks = callbacks;
-               }
-
-               void Update(const CEC::libcec_configuration &config)
-               {
-                       DeviceName = gcnew System::String(config.strDeviceName);
-
-                       for (unsigned int iPtr = 0; iPtr < 5; iPtr++)
-                               DeviceTypes->Types[iPtr] = (CecDeviceType)config.deviceTypes.types[iPtr];
-
-                       AutodetectAddress  = config.bAutodetectAddress == 1;
-                       PhysicalAddress    = config.iPhysicalAddress;
-                       BaseDevice         = (CecLogicalAddress)config.baseDevice;
-                       HDMIPort           = config.iHDMIPort;
-                       ClientVersion      = (CecClientVersion)config.clientVersion;
-                       ServerVersion      = (CecServerVersion)config.serverVersion;
-                       TvVendor           = (CecVendorId)config.tvVendor;
-
-                       // player specific settings
-                       GetSettingsFromROM = config.bGetSettingsFromROM == 1;
-                       UseTVMenuLanguage = config.bUseTVMenuLanguage == 1;
-                       ActivateSource = config.bActivateSource == 1;
-
-                       WakeDevices->Clear();
-                       for (uint8_t iPtr = 0; iPtr <= 16; iPtr++)
-                               if (config.wakeDevices[iPtr])
-                                       WakeDevices->Set((CecLogicalAddress)iPtr);
-
-                       PowerOffDevices->Clear();
-                       for (uint8_t iPtr = 0; iPtr <= 16; iPtr++)
-                               if (config.powerOffDevices[iPtr])
-                                       PowerOffDevices->Set((CecLogicalAddress)iPtr);
-
-                       PowerOffScreensaver = config.bPowerOffScreensaver == 1;
-                       PowerOffOnStandby = config.bPowerOffOnStandby == 1;
-
-                       if (ServerVersion >= CecServerVersion::Version1_5_1)
-                               SendInactiveSource = config.bSendInactiveSource == 1;
-
-                       if (ServerVersion >= CecServerVersion::Version1_5_3)
-                       {
-                               LogicalAddresses->Clear();
-                               for (uint8_t iPtr = 0; iPtr <= 16; iPtr++)
-                                       if (config.logicalAddresses[iPtr])
-                                               LogicalAddresses->Set((CecLogicalAddress)iPtr);
-                       }
-
-                       if (ServerVersion >= CecServerVersion::Version1_6_0)
-                       {
-                               FirmwareVersion          = config.iFirmwareVersion;
-                               PowerOffDevicesOnStandby = config.bPowerOffDevicesOnStandby == 1;
-                               ShutdownOnStandby        = config.bShutdownOnStandby == 1;
-                       }
-
-                       if (ServerVersion >= CecServerVersion::Version1_6_2)
-                               DeviceLanguage = gcnew System::String(config.strDeviceLanguage);
-
-                       if (ServerVersion >= CecServerVersion::Version1_6_3)
-                         MonitorOnlyClient = config.bMonitorOnly == 1;
-               }
-
-               property System::String ^     DeviceName;
-               property CecDeviceTypeList ^  DeviceTypes;
-               property bool                 AutodetectAddress;
-               property uint16_t             PhysicalAddress;
-               property CecLogicalAddress    BaseDevice;
-               property uint8_t              HDMIPort;
-               property CecClientVersion     ClientVersion;
-               property CecServerVersion     ServerVersion;
-               property CecVendorId          TvVendor;
-
-               // player specific settings
-               property bool                 GetSettingsFromROM;
-               property bool                 UseTVMenuLanguage;
-               property bool                 ActivateSource;
-               property CecLogicalAddresses ^WakeDevices;
-               property CecLogicalAddresses ^PowerOffDevices;
-               property bool                 PowerOffScreensaver;
-               property bool                 PowerOffOnStandby;
-               property bool                 SendInactiveSource;
-               property CecLogicalAddresses ^LogicalAddresses;
-               property uint16_t             FirmwareVersion;
-               property bool                 PowerOffDevicesOnStandby;
-               property bool                 ShutdownOnStandby;
-               property bool                 MonitorOnlyClient;
-               property System::String ^     DeviceLanguage;
-               property CecCallbackMethods ^ Callbacks;
-       };
-
-       // the callback methods are called by unmanaged code, so we need some delegates for this
-       #pragma unmanaged
-       // unmanaged callback methods
-       typedef int (__stdcall *LOGCB)    (const CEC::cec_log_message &message);
-       typedef int (__stdcall *KEYCB)    (const CEC::cec_keypress &key);
-       typedef int (__stdcall *COMMANDCB)(const CEC::cec_command &command);
-       typedef int (__stdcall *CONFIGCB) (const CEC::libcec_configuration &config);
-       typedef int (__stdcall *ALERTCB)  (const CEC::libcec_alert, const CEC::libcec_parameter &data);
-       typedef int (__stdcall *MENUCB)   (const CEC::cec_menu_state newVal);
-       typedef void (__stdcall *ACTICB)  (const CEC::cec_logical_address logicalAddress, const uint8_t bActivated);
-
-       typedef struct
-       {
-               LOGCB     logCB;
-               KEYCB     keyCB;
-               COMMANDCB commandCB;
-               CONFIGCB  configCB;
-               ALERTCB   alertCB;
-               MENUCB    menuCB;
-               ACTICB    sourceActivatedCB;
-       } UnmanagedCecCallbacks;
-
-       static PLATFORM::CMutex                   g_callbackMutex;
-       static std::vector<UnmanagedCecCallbacks> g_unmanagedCallbacks;
+  /// <summary>
+  /// The device type. For client applications, libCEC only supports RecordingDevice, PlaybackDevice or Tuner.
+  /// libCEC uses RecordingDevice by default.
+  /// </summary>
+  public enum class CecDeviceType
+  {
+    /// <summary>
+    /// Television
+    /// </summary>
+    Tv              = 0,
+    /// <summary>
+    /// Recording device
+    /// </summary>
+    RecordingDevice = 1,
+    /// <summary>
+    /// Reserved / do not use
+    /// </summary>
+    Reserved        = 2,
+    /// <summary>
+    /// Tuner
+    /// </summary>
+    Tuner           = 3,
+    /// <summary>
+    /// Playback device
+    /// </summary>
+    PlaybackDevice  = 4,
+    /// <summary>
+    /// Audio system / AVR
+    /// </summary>
+    AudioSystem     = 5
+  };
+
+  /// <summary>
+  /// Log level that can be used by the logging callback method to filter messages from libCEC.
+  /// </summary>
+  public enum class CecLogLevel
+  {
+    /// <summary>
+    /// No logging
+    /// </summary>
+    None    = 0,
+    /// <summary>
+    /// libCEC encountered a serious problem, and couldn't complete an action.
+    /// </summary>
+    Error   = 1,
+    /// <summary>
+    /// libCEC warns that it encountered a problem, but recovered.
+    /// </summary>
+    Warning = 2,
+    /// <summary>
+    /// libCEC informs the client about a CEC state change.
+    /// </summary>
+    Notice  = 4,
+    /// <summary>
+    /// Raw CEC data traffic
+    /// </summary>
+    Traffic = 8,
+    /// <summary>
+    /// Debugging messages
+    /// </summary>
+    Debug   = 16,
+    /// <summary>
+    /// Display all messages
+    /// </summary>
+    All     = 31
+  };
+
+  /// <summary>
+  /// A logical address on the CEC bus
+  /// </summary>
+  public enum class CecLogicalAddress
+  {
+    /// <summary>
+    /// Not a valid logical address
+    /// </summary>
+    Unknown          = -1,
+    /// <summary>
+    /// Television
+    /// </summary>
+    Tv               = 0,
+    /// <summary>
+    /// Recording device 1
+    /// </summary>
+    RecordingDevice1 = 1,
+    /// <summary>
+    /// Recording device 2
+    /// </summary>
+    RecordingDevice2 = 2,
+    /// <summary>
+    /// Tuner 1
+    /// </summary>
+    Tuner1           = 3,
+    /// <summary>
+    /// Playback device 1
+    /// </summary>
+    PlaybackDevice1  = 4,
+    /// <summary>
+    /// Audio system / AVR
+    /// </summary>
+    AudioSystem      = 5,
+    /// <summary>
+    /// Tuner 2
+    /// </summary>
+    Tuner2           = 6,
+    /// <summary>
+    /// Tuner 3
+    /// </summary>
+    Tuner3           = 7,
+    /// <summary>
+    /// Playback device 2
+    /// </summary>
+    PlaybackDevice2  = 8,
+    /// <summary>
+    /// Recording device 3
+    /// </summary>
+    RecordingDevice3 = 9,
+    /// <summary>
+    /// Tuner 4
+    /// </summary>
+    Tuner4           = 10,
+    /// <summary>
+    /// Playback device 3
+    /// </summary>
+    PlaybackDevice3  = 11,
+    /// <summary>
+    /// Reserved address 1
+    /// </summary>
+    Reserved1        = 12,
+    /// <summary>
+    /// Reserved address 2
+    /// </summary>
+    Reserved2        = 13,
+    /// <summary>
+    /// Free to use
+    /// </summary>
+    FreeUse          = 14,
+    /// <summary>
+    /// Unregistered / new device
+    /// </summary>
+    Unregistered     = 15,
+    /// <summary>
+    /// Broadcast address
+    /// </summary>
+    Broadcast        = 15
+  };
+
+  /// <summary>
+  /// The type of alert when libCEC calls the CecAlert callback
+  /// </summary>
+  public enum class CecAlert
+  {
+    /// <summary>
+    /// The device needs servicing. This is set when the firmware can be upgraded, or when a problem with the firmware is detected.
+    /// The latest firmware flash tool can be downloaded from http://packages.pulse-eight.net/
+    /// </summary>
+    ServiceDevice = 1
+  };
+
+  /// <summary>
+  /// The type of parameter that is sent with the CecAlert callback
+  /// </summary>
+  public enum class CecParameterType
+  {
+    /// <summary>
+    /// The parameter is a string
+    /// </summary>
+    ParameterTypeString = 1
+  };
+
+  /// <summary>
+  /// A parameter for the CecAlert callback
+  /// </summary>
+  public ref class CecParameter
+  {
+  public:
+    /// <summary>
+    /// Create a new parameter
+    /// </summary>
+    /// <param name="type">The type of this parameter.</param>
+    /// <param name="data">The value of this parameter.</param>
+    CecParameter(CecParameterType type, System::String ^ data)
+    {
+      Type = type;
+      Data = data;
+    }
+
+    /// <summary>
+    /// The type of this parameter
+    /// </summary>
+    property CecParameterType Type;
+    /// <summary>
+    /// The value of this parameter
+    /// </summary>
+    property System::String ^ Data;
+  };
+
+  /// <summary>
+  /// The power status of a CEC device
+  /// </summary>
+  public enum class CecPowerStatus
+  {
+    /// <summary>
+    /// Powered on
+    /// </summary>
+    On                      = 0x00,
+    /// <summary>
+    /// In standby mode
+    /// </summary>
+    Standby                 = 0x01,
+    /// <summary>
+    /// In transition from standby to on
+    /// </summary>
+    InTransitionStandbyToOn = 0x02,
+    /// <summary>
+    /// In transition from on to standby
+    /// </summary>
+    InTransitionOnToStandby = 0x03,
+    /// <summary>
+    /// Unknown status
+    /// </summary>
+    Unknown                 = 0x99
+  };
+
+  /// <summary>
+  /// The CEC version of a CEC device
+  /// </summary>
+  public enum class CecVersion
+  {
+    /// <summary>
+    /// Unknown version
+    /// </summary>
+    Unknown = 0x00,
+    /// <summary>
+    /// Version 1.2
+    /// </summary>
+    V1_2    = 0x01,
+    /// <summary>
+    /// Version 1.2a
+    /// </summary>
+    V1_2A   = 0x02,
+    /// <summary>
+    /// Version 1.3
+    /// </summary>
+    V1_3    = 0x03,
+    /// <summary>
+    /// Version 1.3a
+    /// </summary>
+    V1_3A   = 0x04,
+    /// <summary>
+    /// Version 1.4
+    /// </summary>
+    V1_4    = 0x05
+  };
+
+  /// <summary>
+  /// Parameter for OSD string display, that controls how to display the string
+  /// </summary>
+  public enum class CecDisplayControl
+  {
+    /// <summary>
+    /// Display for the default time
+    /// </summary>
+    DisplayForDefaultTime = 0x00,
+    /// <summary>
+    /// Display until it is cleared by ClearPreviousMessage
+    /// </summary>
+    DisplayUntilCleared   = 0x40,
+    /// <summary>
+    /// Clear message displayed by DisplayUntilCleared
+    /// </summary>
+    ClearPreviousMessage  = 0x80,
+    /// <summary>
+    /// Reserved / do not use
+    /// </summary>
+    ReservedForFutureUse  = 0xC0
+  };
+
+  /// <summary>
+  /// The menu state of a CEC device
+  /// </summary>
+  public enum class CecMenuState
+  {
+    /// <summary>
+    /// Menu active
+    /// </summary>
+    Activated   = 0,
+    /// <summary>
+    /// Menu not active
+    /// </summary>
+    Deactivated = 1
+  };
+
+  /// <summary>
+  /// Deck control mode for playback and recording devices
+  /// </summary>
+  public enum class CecDeckControlMode
+  {
+    /// <summary>
+    /// Skip forward / wind
+    /// </summary>
+    SkipForwardWind   = 1,
+    /// <summary>
+    /// Skip reverse / rewind
+    /// </summary>
+    SkipReverseRewind = 2,
+    /// <summary>
+    /// Stop
+    /// </summary>
+    Stop              = 3,
+    /// <summary>
+    /// Eject
+    /// </summary>
+    Eject             = 4
+  };
+
+  /// <summary>
+  /// Deck status for playback and recording devices
+  /// </summary>
+  public enum class CecDeckInfo
+  {
+    /// <summary>
+    /// Playing
+    /// </summary>
+    Play               = 0x11,
+    /// <summary>
+    /// Recording
+    /// </summary>
+    Record             = 0x12,
+    /// <summary>
+    /// Reverse
+    /// </summary>
+    Reverse            = 0x13,
+    /// <summary>
+    /// Showing still frame
+    /// </summary>
+    Still              = 0x14,
+    /// <summary>
+    /// Playing slow
+    /// </summary>
+    Slow               = 0x15,
+    /// <summary>
+    /// Playing slow reverse
+    /// </summary>
+    SlowReverse        = 0x16,
+    /// <summary>
+    /// Fast forward
+    /// </summary>
+    FastForward        = 0x17,
+    /// <summary>
+    /// Fast reverse
+    /// </summary>
+    FastReverse        = 0x18,
+    /// <summary>
+    /// No media detected
+    /// </summary>
+    NoMedia            = 0x19,
+    /// <summary>
+    /// Stop / not playing
+    /// </summary>
+    Stop               = 0x1A,
+    /// <summary>
+    /// Skip forward / wind
+    /// </summary>
+    SkipForwardWind    = 0x1B,
+    /// <summary>
+    /// Skip reverse / rewind
+    /// </summary>
+    SkipReverseRewind  = 0x1C,
+    /// <summary>
+    /// Index search forward
+    /// </summary>
+    IndexSearchForward = 0x1D,
+    /// <summary>
+    /// Index search reverse
+    /// </summary>
+    IndexSearchReverse = 0x1E,
+    /// <summary>
+    /// Other / unknown status
+    /// </summary>
+    OtherStatus        = 0x1F
+  };
+
+  /// <summary>
+  /// User control code, the key code when the user presses or releases a button on the remote.
+  /// Used by SendKeypress() and the CecKey callback.
+  /// </summary>
+  public enum class CecUserControlCode
+  {
+    /// <summary>
+    /// Select / OK
+    /// </summary>
+    Select                      = 0x00,
+    /// <summary>
+    /// Direction up
+    /// </summary>
+    Up                          = 0x01,
+    /// <summary>
+    /// Direction down
+    /// </summary>
+    Down                        = 0x02,
+    /// <summary>
+    /// Direction left
+    /// </summary>
+    Left                        = 0x03,
+    /// <summary>
+    /// Direction right
+    /// </summary>
+    Right                       = 0x04,
+    /// <summary>
+    /// Direction right + up
+    /// </summary>
+    RightUp                     = 0x05,
+    /// <summary>
+    /// Direction right + down
+    /// </summary>
+    RightDown                   = 0x06,
+    /// <summary>
+    /// Direction left + up
+    /// </summary>
+    LeftUp                      = 0x07,
+    /// <summary>
+    /// Direction left + down
+    /// </summary>
+    LeftDown                    = 0x08,
+    /// <summary>
+    /// Root menu
+    /// </summary>
+    RootMenu                    = 0x09,
+    /// <summary>
+    /// Setup menu
+    /// </summary>
+    SetupMenu                   = 0x0A,
+    /// <summary>
+    /// Contents menu
+    /// </summary>
+    ContentsMenu                = 0x0B,
+    /// <summary>
+    /// Favourite menu
+    /// </summary>
+    FavoriteMenu                = 0x0C,
+    /// <summary>
+    /// Exit / back
+    /// </summary>
+    Exit                        = 0x0D,
+    /// <summary>
+    /// Number 0
+    /// </summary>
+    Number0                     = 0x20,
+    /// <summary>
+    /// Number 1
+    /// </summary>
+    Number1                     = 0x21,
+    /// <summary>
+    /// Number 2
+    /// </summary>
+    Number2                     = 0x22,
+    /// <summary>
+    /// Number 3
+    /// </summary>
+    Number3                     = 0x23,
+    /// <summary>
+    /// Number 4
+    /// </summary>
+    Number4                     = 0x24,
+    /// <summary>
+    /// Number 5
+    /// </summary>
+    Number5                     = 0x25,
+    /// <summary>
+    /// Number 6
+    /// </summary>
+    Number6                     = 0x26,
+    /// <summary>
+    /// Number 7
+    /// </summary>
+    Number7                     = 0x27,
+    /// <summary>
+    /// Number 8
+    /// </summary>
+    Number8                     = 0x28,
+    /// <summary>
+    /// Number 9
+    /// </summary>
+    Number9                     = 0x29,
+    /// <summary>
+    /// .
+    /// </summary>
+    Dot                         = 0x2A,
+    /// <summary>
+    /// Enter input
+    /// </summary>
+    Enter                       = 0x2B,
+    /// <summary>
+    /// Clear input
+    /// </summary>
+    Clear                       = 0x2C,
+    /// <summary>
+    /// Next favourite
+    /// </summary>
+    NextFavorite                = 0x2F,
+    /// <summary>
+    /// Channel up
+    /// </summary>
+    ChannelUp                   = 0x30,
+    /// <summary>
+    /// Channel down
+    /// </summary>
+    ChannelDown                 = 0x31,
+    /// <summary>
+    /// Previous channel
+    /// </summary>
+    PreviousChannel             = 0x32,
+    /// <summary>
+    /// Select sound track
+    /// </summary>
+    SoundSelect                 = 0x33,
+    /// <summary>
+    /// Select input
+    /// </summary>
+    InputSelect                 = 0x34,
+    /// <summary>
+    /// Display information
+    /// </summary>
+    DisplayInformation          = 0x35,
+    /// <summary>
+    /// Show help
+    /// </summary>
+    Help                        = 0x36,
+    /// <summary>
+    /// Page up
+    /// </summary>
+    PageUp                      = 0x37,
+    /// <summary>
+    /// Page down
+    /// </summary>
+    PageDown                    = 0x38,
+    /// <summary>
+    /// Toggle powered on / standby
+    /// </summary>
+    Power                       = 0x40,
+    /// <summary>
+    /// Volume up
+    /// </summary>
+    VolumeUp                    = 0x41,
+    /// <summary>
+    /// Volume down
+    /// </summary>
+    VolumeDown                  = 0x42,
+    /// <summary>
+    /// Mute audio
+    /// </summary>
+    Mute                        = 0x43,
+    /// <summary>
+    /// Start playback
+    /// </summary>
+    Play                        = 0x44,
+    /// <summary>
+    /// Stop playback
+    /// </summary>
+    Stop                        = 0x45,
+    /// <summary>
+    /// Pause playback
+    /// </summary>
+    Pause                       = 0x46,
+    /// <summary>
+    /// Toggle recording
+    /// </summary>
+    Record                      = 0x47,
+    /// <summary>
+    /// Rewind
+    /// </summary>
+    Rewind                      = 0x48,
+    /// <summary>
+    /// Fast forward
+    /// </summary>
+    FastForward                 = 0x49,
+    /// <summary>
+    /// Eject media
+    /// </summary>
+    Eject                       = 0x4A,
+    /// <summary>
+    /// Forward
+    /// </summary>
+    Forward                     = 0x4B,
+    /// <summary>
+    /// Backward
+    /// </summary>
+    Backward                    = 0x4C,
+    /// <summary>
+    /// Stop recording
+    /// </summary>
+    StopRecord                  = 0x4D,
+    /// <summary>
+    /// Pause recording
+    /// </summary>
+    PauseRecord                 = 0x4E,
+    /// <summary>
+    /// Change angle
+    /// </summary>
+    Angle                       = 0x50,
+    /// <summary>
+    /// Toggle sub picture
+    /// </summary>
+    SubPicture                  = 0x51,
+    /// <summary>
+    /// Toggle video on demand
+    /// </summary>
+    VideoOnDemand               = 0x52,
+    /// <summary>
+    /// Toggle electronic program guide (EPG)
+    /// </summary>
+    ElectronicProgramGuide      = 0x53,
+    /// <summary>
+    /// Toggle timer programming
+    /// </summary>
+    TimerProgramming            = 0x54,
+    /// <summary>
+    /// Set initial configuration
+    /// </summary>
+    InitialConfiguration        = 0x55,
+    /// <summary>
+    /// Start playback function
+    /// </summary>
+    PlayFunction                = 0x60,
+    /// <summary>
+    /// Pause playback function
+    /// </summary>
+    PausePlayFunction           = 0x61,
+    /// <summary>
+    /// Toggle recording function
+    /// </summary>
+    RecordFunction              = 0x62,
+    /// <summary>
+    /// Pause recording function
+    /// </summary>
+    PauseRecordFunction         = 0x63,
+    /// <summary>
+    /// Stop playback function
+    /// </summary>
+    StopFunction                = 0x64,
+    /// <summary>
+    /// Mute audio function
+    /// </summary>
+    MuteFunction                = 0x65,
+    /// <summary>
+    /// Restore volume function
+    /// </summary>
+    RestoreVolumeFunction       = 0x66,
+    /// <summary>
+    /// Tune function
+    /// </summary>
+    TuneFunction                = 0x67,
+    /// <summary>
+    /// Select media function
+    /// </summary>
+    SelectMediaFunction         = 0x68,
+    /// <summary>
+    /// Select AV input function
+    /// </summary>
+    SelectAVInputFunction       = 0x69,
+    /// <summary>
+    /// Select audio input function
+    /// </summary>
+    SelectAudioInputFunction    = 0x6A,
+    /// <summary>
+    /// Toggle powered on / standby function
+    /// </summary>
+    PowerToggleFunction         = 0x6B,
+    /// <summary>
+    /// Power off function
+    /// </summary>
+    PowerOffFunction            = 0x6C,
+    /// <summary>
+    /// Power on function
+    /// </summary>
+    PowerOnFunction             = 0x6D,
+    /// <summary>
+    /// F1 / blue button
+    /// </summary>
+    F1Blue                      = 0x71,
+    /// <summary>
+    /// F2 / red button
+    /// </summary>
+    F2Red                       = 0X72,
+    /// <summary>
+    /// F3 / green button
+    /// </summary>
+    F3Green                     = 0x73,
+    /// <summary>
+    /// F4 / yellow button
+    /// </summary>
+    F4Yellow                    = 0x74,
+    /// <summary>
+    /// F5
+    /// </summary>
+    F5                          = 0x75,
+    /// <summary>
+    /// Data / teletext
+    /// </summary>
+    Data                        = 0x76,
+    /// <summary>
+    /// Max. valid key code for standard buttons
+    /// </summary>
+    Max                         = 0x76,
+    /// <summary>
+    /// Extra return button on Samsung remotes
+    /// </summary>
+    SamsungReturn               = 0x91,
+    /// <summary>
+    /// Unknown / invalid key code
+    /// </summary>
+    Unknown
+  };
+
+  /// <summary>
+  /// Vendor IDs for CEC devices
+  /// </summary>
+  public enum class CecVendorId
+  {
+    Samsung   = 0x0000F0,
+    LG        = 0x00E091,
+    Panasonic = 0x008045,
+    Pioneer   = 0x00E036,
+    Onkyo     = 0x0009B0,
+    Yamaha    = 0x00A0DE,
+    Philips   = 0x00903E,
+    Sony      = 0x080046,
+    Toshiba   = 0x000039,
+    Akai      = 0x0020C7,
+    Benq      = 0x8065E9,
+    Daewoo    = 0x009053,
+    Grundig   = 0x00D0D5,
+    Medion    = 0x000CB8,
+    Sharp     = 0x08001F,
+    Vizio     = 0x6B746D,
+    Unknown   = 0
+  };
+
+  /// <summary>
+  /// Audio status of audio system / AVR devices
+  /// </summary>
+  public enum class CecAudioStatus
+  {
+    /// <summary>
+    /// Muted
+    /// </summary>
+    MuteStatusMask      = 0x80,
+    /// <summary>
+    /// Not muted, volume status mask
+    /// </summary>
+    VolumeStatusMask    = 0x7F,
+    /// <summary>
+    /// Minumum volume
+    /// </summary>
+    VolumeMin           = 0x00,
+    /// <summary>
+    /// Maximum volume
+    /// </summary>
+    VolumeMax           = 0x64,
+    /// <summary>
+    /// Unknown status
+    /// </summary>
+    VolumeStatusUnknown = 0x7F
+  };
+
+  /// <summary>
+  /// CEC opcodes, as described in the HDMI CEC specification
+  /// </summary>
+  public enum class CecOpcode
+  {
+    /// <summary>
+    /// Active source
+    /// </summary>
+    ActiveSource                  = 0x82,
+    /// <summary>
+    /// Image view on: power on display for image display
+    /// </summary>
+    ImageViewOn                   = 0x04,
+    /// <summary>
+    /// Text view on: power on display for text display
+    /// </summary>
+    TextViewOn                    = 0x0D,
+    /// <summary>
+    /// Device no longer is the active source
+    /// </summary>
+    InactiveSource                = 0x9D,
+    /// <summary>
+    /// Request which device has the active source status
+    /// </summary>
+    RequestActiveSource           = 0x85,
+    /// <summary>
+    /// Routing change for HDMI switches
+    /// </summary>
+    RoutingChange                 = 0x80,
+    /// <summary>
+    /// Routing information for HDMI switches
+    /// </summary>
+    RoutingInformation            = 0x81,
+    /// <summary>
+    /// Change the stream path to the given physical address
+    /// </summary>
+    SetStreamPath                 = 0x86,
+    /// <summary>
+    /// Inform that a device went into standby mode
+    /// </summary>
+    Standby                       = 0x36,
+    /// <summary>
+    /// Stop recording
+    /// </summary>
+    RecordOff                     = 0x0B,
+    /// <summary>
+    /// Start recording
+    /// </summary>
+    RecordOn                      = 0x09,
+    /// <summary>
+    /// Recording status information
+    /// </summary>
+    RecordStatus                  = 0x0A,
+    /// <summary>
+    /// Record current display
+    /// </summary>
+    RecordTvScreen                = 0x0F,
+    /// <summary>
+    /// Clear analogue timer
+    /// </summary>
+    ClearAnalogueTimer            = 0x33,
+    /// <summary>
+    /// Clear digital timer
+    /// </summary>
+    ClearDigitalTimer             = 0x99,
+    /// <summary>
+    /// Clear external timer
+    /// </summary>
+    ClearExternalTimer            = 0xA1,
+    /// <summary>
+    /// Set analogue timer
+    /// </summary>
+    SetAnalogueTimer              = 0x34,
+    /// <summary>
+    /// Set digital timer
+    /// </summary>
+    SetDigitalTimer               = 0x97,
+    /// <summary>
+    /// Set external timer
+    /// </summary>
+    SetExternalTimer              = 0xA2,
+    /// <summary>
+    /// Set program title of a timer
+    /// </summary>
+    SetTimerProgramTitle          = 0x67,
+    /// <summary>
+    /// Timer status cleared
+    /// </summary>
+    TimerClearedStatus            = 0x43,
+    /// <summary>
+    /// Timer status information
+    /// </summary>
+    TimerStatus                   = 0x35,
+    /// <summary>
+    /// CEC version used by a device
+    /// </summary>
+    CecVersion                    = 0x9E,
+    /// <summary>
+    /// Request CEC version of a device
+    /// </summary>
+    GetCecVersion                 = 0x9F,
+    /// <summary>
+    /// Request physical address of a device
+    /// </summary>
+    GivePhysicalAddress           = 0x83,
+    /// <summary>
+    /// Request language code of the menu language of a device
+    /// 3 character ISO 639-2 country code. see http://http://www.loc.gov/standards/iso639-2/
+    /// </summary>
+    GetMenuLanguage               = 0x91,
+    /// <summary>
+    /// Report the physical address
+    /// </summary>
+    ReportPhysicalAddress         = 0x84,
+    /// <summary>
+    /// Report the language code of the menu language
+    /// 3 character ISO 639-2 country code. see http://http://www.loc.gov/standards/iso639-2/
+    /// </summary>
+    SetMenuLanguage               = 0x32,
+    /// <summary>
+    /// Deck control for playback and recording devices
+    /// </summary>
+    DeckControl                   = 0x42,
+    /// <summary>
+    /// Deck status for playback and recording devices
+    /// </summary>
+    DeckStatus                    = 0x1B,
+    /// <summary>
+    /// Request deck status from playback and recording devices
+    /// </summary>
+    GiveDeckStatus                = 0x1A,
+    /// <summary>
+    /// Start playback on playback and recording devices
+    /// </summary>
+    Play                          = 0x41,
+    /// <summary>
+    /// Request tuner status
+    /// </summary>
+    GiveTunerDeviceStatus         = 0x08,
+    /// <summary>
+    /// Select analogue service on a tuner
+    /// </summary>
+    SelectAnalogueService         = 0x92,
+    /// <summary>
+    /// Select digital service on a tuner
+    /// </summary>
+    SelectDigtalService           = 0x93,
+    /// <summary>
+    /// Report tuner device status
+    /// </summary>
+    TunerDeviceStatus             = 0x07,
+    /// <summary>
+    /// Tuner step decrement
+    /// </summary>
+    TunerStepDecrement            = 0x06,
+    /// <summary>
+    /// Tuner step increment
+    /// </summary>
+    TunerStepIncrement            = 0x05,
+    /// <summary>
+    /// Report device vendor ID
+    /// </summary>
+    DeviceVendorId                = 0x87,
+    /// <summary>
+    /// Request device vendor ID
+    /// </summary>
+    GiveDeviceVendorId            = 0x8C,
+    /// <summary>
+    /// Vendor specific command
+    /// </summary>
+    VendorCommand                 = 0x89,
+    /// <summary>
+    /// Vendor specific command with vendor ID
+    /// </summary>
+    VendorCommandWithId           = 0xA0,
+    /// <summary>
+    /// Vendor specific remote button pressed
+    /// </summary>
+    VendorRemoteButtonDown        = 0x8A,
+    /// <summary>
+    /// Vendor specific remote button released
+    /// </summary>
+    VendorRemoteButtonUp          = 0x8B,
+    /// <summary>
+    /// Display / clear OSD string
+    /// </summary>
+    SetOsdString                  = 0x64,
+    /// <summary>
+    /// Request device OSD name
+    /// </summary>
+    GiveOsdName                   = 0x46,
+    /// <summary>
+    /// Report device OSD name
+    /// </summary>
+    SetOsdName                    = 0x47,
+    /// <summary>
+    /// Request device menu status
+    /// </summary>
+    MenuRequest                   = 0x8D,
+    /// <summary>
+    /// Report device menu status
+    /// </summary>
+    MenuStatus                    = 0x8E,
+    /// <summary>
+    /// Remote button pressed
+    /// </summary>
+    UserControlPressed            = 0x44,
+    /// <summary>
+    /// Remote button released
+    /// </summary>
+    UserControlRelease            = 0x45,
+    /// <summary>
+    /// Request device power status
+    /// </summary>
+    GiveDevicePowerStatus         = 0x8F,
+    /// <summary>
+    /// Report device power status
+    /// </summary>
+    ReportPowerStatus             = 0x90,
+    /// <summary>
+    /// Feature abort / unsupported command
+    /// </summary>
+    FeatureAbort                  = 0x00,
+    /// <summary>
+    /// Abort command
+    /// </summary>
+    Abort                         = 0xFF,
+    /// <summary>
+    /// Give audio status
+    /// </summary>
+    GiveAudioStatus               = 0x71,
+    /// <summary>
+    /// Give audiosystem mode
+    /// </summary>
+    GiveSystemAudioMode           = 0x7D,
+    /// <summary>
+    /// Report device audio status
+    /// </summary>
+    ReportAudioStatus             = 0x7A,
+    /// <summary>
+    /// Set audiosystem mode
+    /// </summary>
+    SetSystemAudioMode            = 0x72,
+    /// <summary>
+    /// Request audiosystem mode
+    /// </summary>
+    SystemAudioModeRequest        = 0x70,
+    /// <summary>
+    /// Report audiosystem mode
+    /// </summary>
+    SystemAudioModeStatus         = 0x7E,
+    /// <summary>
+    /// Set audio bitrate
+    /// </summary>
+    SetAudioRate                  = 0x9A,
+    /// <summary>
+    /// When this opcode is set, no opcode will be sent to the device / poll message
+    /// This is one of the reserved numbers
+    /// </summary>
+    None                          = 0xFD
+  };
+
+  /// <summary>
+  /// Audiosystem status
+  /// </summary>
+  public enum class CecSystemAudioStatus
+  {
+    /// <summary>
+    /// Turned off
+    /// </summary>
+    Off = 0,
+    /// <summary>
+    /// Turned on
+    /// </summary>
+    On  = 1
+  };
+
+  /// <summary>
+  /// libCEC client application version
+  /// </summary>
+  public enum class CecClientVersion
+  {
+    /// <summary>
+    /// before v1.5.0
+    /// </summary>
+    VersionPre1_5 = 0,
+    /// <summary>
+    /// v1.5.0
+    /// </summary>
+    Version1_5_0  = 0x1500,
+    /// <summary>
+    /// v1.5.1
+    /// </summary>
+    Version1_5_1  = 0x1501,
+    /// <summary>
+    /// v1.5.2
+    /// </summary>
+    Version1_5_2  = 0x1502,
+    /// <summary>
+    /// v1.5.3
+    /// </summary>
+    Version1_5_3  = 0x1503,
+    /// <summary>
+    /// v1.6.0
+    /// </summary>
+    Version1_6_0  = 0x1600,
+    /// <summary>
+    /// v1.6.1
+    /// </summary>
+    Version1_6_1  = 0x1601,
+    /// <summary>
+    /// v1.6.2
+    /// </summary>
+    Version1_6_2  = 0x1602,
+    /// <summary>
+    /// v1.6.3
+    /// </summary>
+    Version1_6_3  = 0x1603,
+    /// <summary>
+    /// v1.7.0
+    /// </summary>
+    Version1_7_0  = 0x1700,
+    /// <summary>
+    /// v1.7.1
+    /// </summary>
+    Version1_7_1  = 0x1701,
+    /// <summary>
+    /// v1.7.2
+    /// </summary>
+    Version1_7_2  = 0x1702,
+    /// <summary>
+    /// v1.8.0
+    /// </summary>
+    Version1_8_0  = 0x1800,
+    /// <summary>
+    /// v1.8.1
+    /// </summary>
+    Version1_8_1  = 0x1801,
+    /// <summary>
+    /// v1.8.2
+    /// </summary>
+    Version1_8_2  = 0x1802,
+    /// <summary>
+    /// v1.9.0
+    /// </summary>
+    Version1_9_0  = 0x1900,
+    /// <summary>
+    /// v2.0.0-pre
+    /// </summary>
+    Version1_99_0  = 0x1990,
+    /// <summary>
+    /// v2.0.0
+    /// </summary>
+    Version2_0_0   = 0x2000
+  };
+
+  /// <summary>
+  /// libCEC version
+  /// </summary>
+  public enum class CecServerVersion
+  {
+    /// <summary>
+    /// before v1.5.0
+    /// </summary>
+    VersionPre1_5 = 0,
+    /// <summary>
+    /// v1.5.0
+    /// </summary>
+    Version1_5_0  = 0x1500,
+    /// <summary>
+    /// v1.5.1
+    /// </summary>
+    Version1_5_1  = 0x1501,
+    /// <summary>
+    /// v1.5.2
+    /// </summary>
+    Version1_5_2  = 0x1502,
+    /// <summary>
+    /// v1.5.3
+    /// </summary>
+    Version1_5_3  = 0x1503,
+    /// <summary>
+    /// v1.6.0
+    /// </summary>
+    Version1_6_0  = 0x1600,
+    /// <summary>
+    /// v1.6.1
+    /// </summary>
+    Version1_6_1  = 0x1601,
+    /// <summary>
+    /// v1.6.2
+    /// </summary>
+    Version1_6_2  = 0x1602,
+    /// <summary>
+    /// v1.6.3
+    /// </summary>
+    Version1_6_3  = 0x1603,
+    /// <summary>
+    /// v1.7.0
+    /// </summary>
+    Version1_7_0  = 0x1700,
+    /// <summary>
+    /// v1.7.1
+    /// </summary>
+    Version1_7_1  = 0x1701,
+    /// <summary>
+    /// v1.7.2
+    /// </summary>
+    Version1_7_2  = 0x1702,
+    /// <summary>
+    /// v1.8.0
+    /// </summary>
+    Version1_8_0  = 0x1800,
+    /// <summary>
+    /// v1.8.1
+    /// </summary>
+    Version1_8_1  = 0x1801,
+    /// <summary>
+    /// v1.8.2
+    /// </summary>
+    Version1_8_2  = 0x1802,
+    /// <summary>
+    /// v1.9.0
+    /// </summary>
+    Version1_9_0  = 0x1900,
+    /// <summary>
+    /// v2.0.0-pre
+    /// </summary>
+    Version1_99_0  = 0x1990,
+    /// <summary>
+    /// v2.0.0
+    /// </summary>
+    Version2_0_0   = 0x2000
+  };
+
+  /// <summary>
+  /// Type of adapter to which libCEC is connected
+  /// </summary>
+  public enum class CecAdapterType
+  {
+    /// <summary>
+    /// Unknown adapter type
+    /// </summary>
+    Unknown                 = 0,
+    /// <summary>
+    /// Pulse-Eight USB-CEC adapter
+    /// </summary>
+    PulseEightExternal      = 0x1,
+    /// <summary>
+    /// Pulse-Eight CEC daughterboard
+    /// </summary>
+    PulseEightDaughterboard = 0x2,
+    /// <summary>
+    /// Raspberry Pi
+    /// </summary>
+    RaspberryPi             = 0x100
+  };
+
+  /// <summary>
+  /// Descriptor of a CEC adapter, returned when scanning for adapters that are connected to the system
+  /// </summary>
+  public ref class CecAdapter
+  {
+  public:
+    /// <summary>
+    /// Create a new CEC adapter descriptor
+    /// </summary>
+    /// <param name="path"> The path descriptor for this CEC adapter</param>
+    /// <param name="comPort">The COM port of this CEC adapter</param>
+    CecAdapter(System::String ^ path, System::String ^ comPort)
+    {
+      Path = path;
+      ComPort = comPort;
+    }
+
+    /// <summary>
+    /// The path descriptor for this CEC adapter
+    /// </summary>
+    property System::String ^ Path;
+
+    /// <summary>
+    /// The COM port of this CEC adapter
+    /// </summary>
+    property System::String ^ ComPort;
+  };
+
+  /// <summary>
+  /// A list of CEC device types
+  /// </summary>
+  public ref class CecDeviceTypeList
+  {
+  public:
+    /// <summary>
+    /// Create a new empty list of CEC device types
+    /// </summary>
+    CecDeviceTypeList(void)
+    {
+      Types = gcnew array<CecDeviceType>(5);
+      for (unsigned int iPtr = 0; iPtr < 5; iPtr++)
+        Types[iPtr] = CecDeviceType::Reserved;
+    }
+
+    /// <summary>
+    /// The array with CecDeviceType instances in this list.
+    /// </summary>
+    property array<CecDeviceType> ^ Types;
+  };
+
+  /// <summary>
+  /// A list of logical addresses
+  /// </summary>
+  public ref class CecLogicalAddresses
+  {
+  public:
+    /// <summary>
+    /// Create a new empty list of logical addresses
+    /// </summary>
+    CecLogicalAddresses(void)
+    {
+      Addresses = gcnew array<CecLogicalAddress>(16);
+      Clear();
+    }
+
+    /// <summary>
+    /// Clears this list
+    /// </summary>
+    void Clear(void)
+    {
+      Primary = CecLogicalAddress::Unknown;
+      for (unsigned int iPtr = 0; iPtr < 16; iPtr++)
+        Addresses[iPtr] = CecLogicalAddress::Unknown;
+    }
+
+    /// <summary>
+    /// Checks whether a logical address is set in this list.
+    /// </summary>
+    /// <param name="address">The address to check.</param>
+    /// <returns>True when set, false otherwise</returns>
+    bool IsSet(CecLogicalAddress address)
+    {
+      return Addresses[(unsigned int)address] != CecLogicalAddress::Unknown;
+    }
+
+    /// <summary>
+    /// Add a logical address to this list (if it's not set already)
+    /// </summary>
+    /// <param name="address">The address to add.</param>
+    void Set(CecLogicalAddress address)
+    {
+      Addresses[(unsigned int)address] = address;
+      if (Primary == CecLogicalAddress::Unknown)
+        Primary = address;
+    }
+
+    /// <summary>
+    /// The primary (first) address in this list
+    /// </summary>
+    property CecLogicalAddress          Primary;
+
+    /// <summary>
+    /// The list of addresses
+    /// </summary>
+    property array<CecLogicalAddress> ^ Addresses;
+  };
+
+
+  /// <summary>
+  /// Byte array used for CEC command parameters
+  /// </summary>
+  public ref class CecDatapacket
+  {
+  public:
+    /// <summary>
+    /// Create a new byte array with maximum size 100
+    /// </summary>
+    CecDatapacket(void)
+    {
+      Data = gcnew array<uint8_t>(100);
+      Size = 0;
+    }
+
+    /// <summary>
+    /// Adds a byte to this byte array
+    /// </summary>
+    /// <param name="data">The byte to add.</param>
+    void PushBack(uint8_t data)
+    {
+      if (Size < 100)
+      {
+        Data[Size] = data;
+        Size++;
+      }
+    }
+
+    /// <summary>
+    /// Array data
+    /// </summary>
+    property array<uint8_t> ^ Data;
+
+    /// <summary>
+    /// Current data size
+    /// </summary>
+    property uint8_t          Size;
+  };
+
+  /// <summary>
+  /// A CEC command that is received or transmitted over the CEC bus
+  /// </summary>
+  public ref class CecCommand
+  {
+  public:
+    /// <summary>
+    /// Create a new CEC command instance
+    /// </summary>
+    /// <param name="initiator">The initiator of the command</param>
+    /// <param name="destination">The receiver of the command</param>
+    /// <param name="ack">True when the ack bit is set, false otherwise</param>
+    /// <param name="eom">True when the eom bit is set, false otherwise</param>
+    /// <param name="opcode">The CEC opcode of this command</param>
+    /// <param name="transmitTimeout">The timeout to use when transmitting a command</param>
+    CecCommand(CecLogicalAddress initiator, CecLogicalAddress destination, bool ack, bool eom, CecOpcode opcode, int32_t transmitTimeout)
+    {
+      Initiator       = initiator;
+      Destination     = destination;
+      Ack             = ack;
+      Eom             = eom;
+      Opcode          = opcode;
+      OpcodeSet       = true;
+      TransmitTimeout = transmitTimeout;
+      Parameters      = gcnew CecDatapacket;
+      Empty           = false;
+    }
+
+    /// <summary>
+    /// Create a new empty CEC command instance
+    /// </summary>
+    CecCommand(void)
+    {
+      Initiator       = CecLogicalAddress::Unknown;
+      Destination     = CecLogicalAddress::Unknown;
+      Ack             = false;
+      Eom             = false;
+      Opcode          = CecOpcode::None;
+      OpcodeSet       = false;
+      TransmitTimeout = 0;
+      Parameters      = gcnew CecDatapacket;
+      Empty           = true;
+    }
+
+    /// <summary>
+    /// Pushes a byte of data to this CEC command
+    /// </summary>
+    /// <param name="data">The byte to add</param>
+    void PushBack(uint8_t data)
+    {
+      if (Initiator == CecLogicalAddress::Unknown && Destination == CecLogicalAddress::Unknown)
+      {
+        Initiator   = (CecLogicalAddress) (data >> 4);
+        Destination = (CecLogicalAddress) (data & 0xF);
+      }
+      else if (!OpcodeSet)
+      {
+        OpcodeSet = true;
+        Opcode    = (CecOpcode)data;
+      }
+      else
+      {
+        Parameters->PushBack(data);
+      }
+    }
+
+    /// <summary>
+    /// True when this command is empty, false otherwise.
+    /// </summary>
+    property bool               Empty;
+    /// <summary>
+    /// The initiator of the command
+    /// </summary>
+    property CecLogicalAddress  Initiator;
+    /// <summary>
+    /// The destination of the command
+    /// </summary>
+    property CecLogicalAddress  Destination;
+    /// <summary>
+    /// True when the ack bit is set, false otherwise
+    /// </summary>
+    property bool               Ack;
+    /// <summary>
+    /// True when the eom bit is set, false otherwise
+    /// </summary>
+    property bool               Eom;
+    /// <summary>
+    /// The CEC opcode of the command
+    /// </summary>
+    property CecOpcode          Opcode;
+    /// <summary>
+    /// The parameters of this command
+    /// </summary>
+    property CecDatapacket ^    Parameters;
+    /// <summary>
+    /// True when an opcode is set, false otherwise (poll message)
+    /// </summary>
+    property bool               OpcodeSet;
+    /// <summary>
+    /// The timeout to use when transmitting a command
+    /// </summary>
+    property int32_t            TransmitTimeout;
+  };
+
+  /// <summary>
+  /// A key press that was received
+  /// </summary>
+  public ref class CecKeypress
+  {
+  public:
+    /// <summary>
+    /// Create a new key press instance
+    /// </summary>
+    /// <param name="keycode">The key code of this key press</param>
+    /// <param name="duration">The duration of this key press in milliseconds</param>
+    CecKeypress(CecUserControlCode keycode, unsigned int duration)
+    {
+      Keycode  = keycode;
+      Duration = duration;
+      Empty    = false;
+    }
+
+    /// <summary>
+    /// Create a new empty key press instance
+    /// </summary>
+    CecKeypress(void)
+    {
+      Keycode  = CecUserControlCode::Unknown;
+      Duration = 0;
+      Empty    = true;
+    }
+
+    /// <summary>
+    /// True when empty, false otherwise
+    /// </summary>
+    property bool               Empty;
+    /// <summary>
+    /// The key code of this key press
+    /// </summary>
+    property CecUserControlCode Keycode;
+    /// <summary>
+    /// The duration of this key press in milliseconds
+    /// </summary>
+    property unsigned int       Duration;
+  };
+
+  /// <summary>
+  /// A log message that libCEC generated
+  /// </summary>
+  public ref class CecLogMessage
+  {
+  public:
+    /// <summary>
+    /// Create a new log message
+    /// </summary>
+    /// <param name="message">The actual message</param>
+    /// <param name="level">The log level, so the application can choose what type information to display</param>
+    /// <param name="time">The timestamp of this message, in milliseconds after connecting</param>
+    CecLogMessage(System::String ^ message, CecLogLevel level, int64_t time)
+    {
+      Message = message;
+      Level   = level;
+      Time    = time;
+      Empty   = false;
+    }
+
+    /// <summary>
+    /// Create a new empty log message
+    /// </summary>
+    CecLogMessage(void)
+    {
+      Message = "";
+      Level   = CecLogLevel::None;
+      Time    = 0;
+      Empty   = true;
+    }
+
+    /// <summary>
+    /// True when empty, false otherwise.
+    /// </summary>
+    property bool            Empty;
+    /// <summary>
+    /// The actual message
+    /// </summary>
+    property System::String ^Message;
+    /// <summary>
+    /// The log level, so the application can choose what type information to display
+    /// </summary>
+    property CecLogLevel     Level;
+    /// <summary>
+    /// The timestamp of this message, in milliseconds after connecting
+    /// </summary>
+    property int64_t         Time;
+  };
+
+  ref class CecCallbackMethods; //forward declaration
+
+  /// <summary>
+  /// The configuration that libCEC uses.
+  /// </summary>
+  public ref class LibCECConfiguration
+  {
+  public:
+    /// <summary>
+    /// Create a new configuration instance with default settings.
+    /// </summary>
+    LibCECConfiguration(void)
+    {
+      DeviceName          = "";
+      DeviceTypes         = gcnew CecDeviceTypeList();
+      AutodetectAddress  = true;
+      PhysicalAddress     = CEC_DEFAULT_PHYSICAL_ADDRESS;
+      BaseDevice          = (CecLogicalAddress)CEC_DEFAULT_BASE_DEVICE;
+      HDMIPort            = CEC_DEFAULT_HDMI_PORT;
+      ClientVersion       = CecClientVersion::VersionPre1_5;
+      ServerVersion       = CecServerVersion::VersionPre1_5;
+      TvVendor            = CecVendorId::Unknown;
+
+      GetSettingsFromROM  = false;
+      UseTVMenuLanguage   = CEC_DEFAULT_SETTING_USE_TV_MENU_LANGUAGE == 1;
+      ActivateSource      = CEC_DEFAULT_SETTING_ACTIVATE_SOURCE == 1;
+
+      WakeDevices         = gcnew CecLogicalAddresses();
+      if (CEC_DEFAULT_SETTING_ACTIVATE_SOURCE == 1)
+        WakeDevices->Set(CecLogicalAddress::Tv);
+
+      PowerOffDevices     = gcnew CecLogicalAddresses();
+      if (CEC_DEFAULT_SETTING_POWER_OFF_SHUTDOWN == 1)
+        PowerOffDevices->Set(CecLogicalAddress::Broadcast);
+
+      PowerOffScreensaver = CEC_DEFAULT_SETTING_POWER_OFF_SCREENSAVER == 1;
+      PowerOffOnStandby   = CEC_DEFAULT_SETTING_POWER_OFF_ON_STANDBY == 1;
+
+      SendInactiveSource  = CEC_DEFAULT_SETTING_SEND_INACTIVE_SOURCE == 1;
+      LogicalAddresses    = gcnew CecLogicalAddresses();
+      FirmwareVersion     = 1;
+      PowerOffDevicesOnStandby = CEC_DEFAULT_SETTING_POWER_OFF_DEVICES_STANDBY == 1;
+      ShutdownOnStandby   = CEC_DEFAULT_SETTING_SHUTDOWN_ON_STANDBY == 1;
+      DeviceLanguage      = "";
+      FirmwareBuildDate   = gcnew System::DateTime(1970,1,1,0,0,0,0);
+      CECVersion          = (CecVersion)CEC_DEFAULT_SETTING_CEC_VERSION;
+      AdapterType         = CecAdapterType::Unknown;
+    }
+
+    /// <summary>
+    /// Change the callback method pointers in this configuration instance.
+    /// </summary>
+    /// <param name="callbacks">The new callbacks</param>
+    void SetCallbacks(CecCallbackMethods ^callbacks)
+    {
+      Callbacks = callbacks;
+    }
+
+    /// <summary>
+    /// Update this configuration with data received from libCEC
+    /// </summary>
+    /// <param name="config">The configuration that was received from libCEC</param>
+    void Update(const CEC::libcec_configuration &config)
+    {
+      DeviceName = gcnew System::String(config.strDeviceName);
+
+      for (unsigned int iPtr = 0; iPtr < 5; iPtr++)
+        DeviceTypes->Types[iPtr] = (CecDeviceType)config.deviceTypes.types[iPtr];
+
+      AutodetectAddress  = config.bAutodetectAddress == 1;
+      PhysicalAddress    = config.iPhysicalAddress;
+      BaseDevice         = (CecLogicalAddress)config.baseDevice;
+      HDMIPort           = config.iHDMIPort;
+      ClientVersion      = (CecClientVersion)config.clientVersion;
+      ServerVersion      = (CecServerVersion)config.serverVersion;
+      TvVendor           = (CecVendorId)config.tvVendor;
+
+      // player specific settings
+      GetSettingsFromROM = config.bGetSettingsFromROM == 1;
+      UseTVMenuLanguage = config.bUseTVMenuLanguage == 1;
+      ActivateSource = config.bActivateSource == 1;
+
+      WakeDevices->Clear();
+      for (uint8_t iPtr = 0; iPtr <= 16; iPtr++)
+        if (config.wakeDevices[iPtr])
+          WakeDevices->Set((CecLogicalAddress)iPtr);
+
+      PowerOffDevices->Clear();
+      for (uint8_t iPtr = 0; iPtr <= 16; iPtr++)
+        if (config.powerOffDevices[iPtr])
+          PowerOffDevices->Set((CecLogicalAddress)iPtr);
+
+      PowerOffScreensaver = config.bPowerOffScreensaver == 1;
+      PowerOffOnStandby = config.bPowerOffOnStandby == 1;
+
+      if (ServerVersion >= CecServerVersion::Version1_5_1)
+        SendInactiveSource = config.bSendInactiveSource == 1;
+
+      if (ServerVersion >= CecServerVersion::Version1_5_3)
+      {
+        LogicalAddresses->Clear();
+        for (uint8_t iPtr = 0; iPtr <= 16; iPtr++)
+          if (config.logicalAddresses[iPtr])
+            LogicalAddresses->Set((CecLogicalAddress)iPtr);
+      }
+
+      if (ServerVersion >= CecServerVersion::Version1_6_0)
+      {
+        FirmwareVersion          = config.iFirmwareVersion;
+        PowerOffDevicesOnStandby = config.bPowerOffDevicesOnStandby == 1;
+        ShutdownOnStandby        = config.bShutdownOnStandby == 1;
+      }
+
+      if (ServerVersion >= CecServerVersion::Version1_6_2)
+      {
+        DeviceLanguage = gcnew System::String(config.strDeviceLanguage);
+        FirmwareBuildDate = gcnew System::DateTime(1970,1,1,0,0,0,0);
+        FirmwareBuildDate = FirmwareBuildDate->AddSeconds(config.iFirmwareBuildDate);
+      }
+
+      if (ServerVersion >= CecServerVersion::Version1_6_3)
+        MonitorOnlyClient = config.bMonitorOnly == 1;
+
+      if (ServerVersion >= CecServerVersion::Version1_8_0)
+        CECVersion = (CecVersion)config.cecVersion;
+
+      if (ServerVersion >= CecServerVersion::Version1_8_2)
+        AdapterType = (CecAdapterType)config.adapterType;
+    }
+
+    /// <summary>
+    /// The device name to use on the CEC bus
+    /// </summary>
+    property System::String ^     DeviceName;
+
+    /// <summary>
+    /// The device type(s) to use on the CEC bus for libCEC
+    /// </summary>
+    property CecDeviceTypeList ^  DeviceTypes;
+
+    /// <summary>
+    /// (read only) set to true by libCEC when the physical address was autodetected
+    /// </summary>
+    property bool                 AutodetectAddress;
+
+    /// <summary>
+    /// The physical address of the CEC adapter
+    /// </summary>
+    property uint16_t             PhysicalAddress;
+
+    /// <summary>
+    /// The logical address of the device to which the adapter is connected. Only used when PhysicalAddress = 0 or when the adapter doesn't support autodetection
+    /// </summary>
+    property CecLogicalAddress    BaseDevice;
+
+    /// <summary>
+    /// The HDMI port to which the adapter is connected. Only used when iPhysicalAddress = 0 or when the adapter doesn't support autodetection
+    /// </summary>
+    property uint8_t              HDMIPort;
+
+    /// <summary>
+    /// The client API version to use
+    /// </summary>
+    property CecClientVersion     ClientVersion;
+
+    /// <summary>
+    /// The version of libCEC
+    /// </summary>
+    property CecServerVersion     ServerVersion;
+
+    /// <summary>
+    /// Override the vendor ID of the TV. Leave this untouched to autodetect
+    /// </summary>
+    property CecVendorId          TvVendor;
+
+    /// <summary>
+    /// True to read the settings from the EEPROM, which possibly override the settings passed here
+    /// </summary>
+    property bool                 GetSettingsFromROM;
+
+    /// <summary>
+    /// Use the language setting of the TV in the client application. Must be implemented by the client application.
+    /// 3 character ISO 639-2 country code. see http://http://www.loc.gov/standards/iso639-2/
+    /// </summary>
+    property bool                 UseTVMenuLanguage;
+
+    /// <summary>
+    /// Make libCEC the active source when starting the client application
+    /// </summary>
+    property bool                 ActivateSource;
+
+    /// <summary>
+    /// List of devices to wake when initialising libCEC or when calling PowerOnDevices() without any parameter.
+    /// </summary>
+    property CecLogicalAddresses ^WakeDevices;
+
+    /// <summary>
+    /// List of devices to power off when calling StandbyDevices() without any parameter.
+    /// </summary>
+    property CecLogicalAddresses ^PowerOffDevices;
+
+    /// <summary>
+    /// Send standby commands when the client application activates the screensaver. Must be implemented by the client application.
+    /// </summary>
+    property bool                 PowerOffScreensaver;
+
+    /// <summary>
+    /// Power off the PC when the TV powers off. Must be implemented by the client application.
+    /// </summary>
+    property bool                 PowerOffOnStandby;
+
+    /// <summary>
+    /// Send an inactive source message when exiting the client application.
+    /// </summary>
+    property bool                 SendInactiveSource;
+
+    /// <summary>
+    /// The list of logical addresses that libCEC is using
+    /// </summary>
+    property CecLogicalAddresses ^LogicalAddresses;
+
+    /// <summary>
+    /// The firmware version of the adapter to which libCEC is connected
+    /// </summary>
+    property uint16_t             FirmwareVersion;
+
+    /// <summary>
+    /// Send standby commands when the client application activates standby mode (S3). Must be implemented by the client application.
+    /// </summary>
+    property bool                 PowerOffDevicesOnStandby;
+
+    /// <summary>
+    /// Shutdown this PC when the TV is switched off. only used when PowerOffOnStandby = false
+    /// </summary>
+    property bool                 ShutdownOnStandby;
+
+    /// <summary>
+    /// True to start a monitor-only client, false to start a standard client.
+    /// </summary>
+    property bool                 MonitorOnlyClient;
+
+    /// <summary>
+    /// The language code of the menu language that libCEC reports to other devices.
+    /// 3 character ISO 639-2 country code. see http://http://www.loc.gov/standards/iso639-2/
+    /// </summary>
+    property System::String ^     DeviceLanguage;
+
+    /// <summary>
+    /// The callback methods to use.
+    /// </summary>
+    property CecCallbackMethods ^ Callbacks;
+
+    /// <summary>
+    /// The build date of the firmware.
+    /// </summary>
+    property System::DateTime ^   FirmwareBuildDate;
+
+    /// <summary>
+    /// The CEC version that libCEC uses.
+    /// </summary>
+    property CecVersion           CECVersion;
+
+    /// <summary>
+    /// The type of adapter that libCEC is connected to.
+    /// </summary>
+    property CecAdapterType       AdapterType;
+  };
+
+  // the callback methods are called by unmanaged code, so we need some delegates for this
+#pragma unmanaged
+  // unmanaged callback methods
+  typedef int (__stdcall *LOGCB)    (const CEC::cec_log_message &message);
+  typedef int (__stdcall *KEYCB)    (const CEC::cec_keypress &key);
+  typedef int (__stdcall *COMMANDCB)(const CEC::cec_command &command);
+  typedef int (__stdcall *CONFIGCB) (const CEC::libcec_configuration &config);
+  typedef int (__stdcall *ALERTCB)  (const CEC::libcec_alert, const CEC::libcec_parameter &data);
+  typedef int (__stdcall *MENUCB)   (const CEC::cec_menu_state newVal);
+  typedef void (__stdcall *ACTICB)  (const CEC::cec_logical_address logicalAddress, const uint8_t bActivated);
+
+  /// <summary>
+  /// libCEC callback methods. Unmanaged code.
+  /// </summary>
+  typedef struct
+  {
+    /// <summary>
+    /// Log message callback
+    /// </summary>
+    LOGCB     logCB;
+    /// <summary>
+    /// Key press/release callback
+    /// </summary>
+    KEYCB     keyCB;
+    /// <summary>
+    /// Raw CEC data callback
+    /// </summary>
+    COMMANDCB commandCB;
+    /// <summary>
+    /// Updated configuration callback
+    /// </summary>
+    CONFIGCB  configCB;
+    /// <summary>
+    /// Alert message callback
+    /// </summary>
+    ALERTCB   alertCB;
+    /// <summary>
+    /// Menu status change callback
+    /// </summary>
+    MENUCB    menuCB;
+    /// <summary>
+    /// Source (de)activated callback
+    /// </summary>
+    ACTICB    sourceActivatedCB;
+  } UnmanagedCecCallbacks;
+
+  static PLATFORM::CMutex                   g_callbackMutex;
+  static std::vector<UnmanagedCecCallbacks> g_unmanagedCallbacks;
   static CEC::ICECCallbacks                 g_cecCallbacks;
 
-       int CecLogMessageCB(void *cbParam, const CEC::cec_log_message &message)
-       {
-               if (cbParam)
-               {
-                       size_t iPtr = (size_t)cbParam;
-                       PLATFORM::CLockObject lock(g_callbackMutex);
-                       if (iPtr >= 0 && iPtr < g_unmanagedCallbacks.size())
-                               return g_unmanagedCallbacks[iPtr].logCB(message);
-               }
-               return 0;
-       }
-
-       int CecKeyPressCB(void *cbParam, const CEC::cec_keypress &key)
-       {
-               if (cbParam)
-               {
-                       size_t iPtr = (size_t)cbParam;
-                       PLATFORM::CLockObject lock(g_callbackMutex);
-                       if (iPtr >= 0 && iPtr < g_unmanagedCallbacks.size())
-                               return g_unmanagedCallbacks[iPtr].keyCB(key);
-               }
-               return 0;
-       }
-
-       int CecCommandCB(void *cbParam, const CEC::cec_command &command)
-       {
-               if (cbParam)
-               {
-                       size_t iPtr = (size_t)cbParam;
-                       PLATFORM::CLockObject lock(g_callbackMutex);
-                       if (iPtr >= 0 && iPtr < g_unmanagedCallbacks.size())
-                               return g_unmanagedCallbacks[iPtr].commandCB(command);
-               }
-               return 0;
-       }
-
-  int CecConfigCB(void *cbParam, const CEC::libcec_configuration &config)
-       {
-               if (cbParam)
-               {
-                       size_t iPtr = (size_t)cbParam;
-                       PLATFORM::CLockObject lock(g_callbackMutex);
-                       if (iPtr >= 0 && iPtr < g_unmanagedCallbacks.size())
-                               return g_unmanagedCallbacks[iPtr].configCB(config);
-               }
-               return 0;
-       }
-
-       int CecAlertCB(void *cbParam, const CEC::libcec_alert alert, const CEC::libcec_parameter &data)
-       {
-               if (cbParam)
-               {
-                       size_t iPtr = (size_t)cbParam;
-                       PLATFORM::CLockObject lock(g_callbackMutex);
-                       if (iPtr >= 0 && iPtr < g_unmanagedCallbacks.size())
-                               return g_unmanagedCallbacks[iPtr].alertCB(alert, data);
-               }
-               return 0;
-       }
-
-       int CecMenuCB(void *cbParam, const CEC::cec_menu_state newVal)
-       {
-               if (cbParam)
-               {
-                       size_t iPtr = (size_t)cbParam;
-                       PLATFORM::CLockObject lock(g_callbackMutex);
-                       if (iPtr >= 0 && iPtr < g_unmanagedCallbacks.size())
-                               return g_unmanagedCallbacks[iPtr].menuCB(newVal);
-               }
-               return 0;
-       }
-
-       void CecSourceActivatedCB(void *cbParam, const CEC::cec_logical_address logicalAddress, const uint8_t bActivated)
-       {
-               if (cbParam)
-               {
-                       size_t iPtr = (size_t)cbParam;
-                       PLATFORM::CLockObject lock(g_callbackMutex);
-                       if (iPtr >= 0 && iPtr < g_unmanagedCallbacks.size())
-                               g_unmanagedCallbacks[iPtr].sourceActivatedCB(logicalAddress, bActivated);
-               }
-       }
-
-       #pragma managed
-       // delegates for the unmanaged callback methods
-       public delegate int  CecLogMessageManagedDelegate(const CEC::cec_log_message &);
-       public delegate int  CecKeyPressManagedDelegate(const CEC::cec_keypress &);
-       public delegate int  CecCommandManagedDelegate(const CEC::cec_command &);
-       public delegate int  CecConfigManagedDelegate(const CEC::libcec_configuration &);
-       public delegate int  CecAlertManagedDelegate(const CEC::libcec_alert, const CEC::libcec_parameter &);
-       public delegate int  CecMenuManagedDelegate(const CEC::cec_menu_state newVal);
-       public delegate void CecSourceActivatedManagedDelegate(const CEC::cec_logical_address logicalAddress, const uint8_t bActivated);
-
-       void AssignCallbacks()
-       {
-               g_cecCallbacks.CBCecLogMessage           = CecLogMessageCB;
-               g_cecCallbacks.CBCecKeyPress             = CecKeyPressCB;
-               g_cecCallbacks.CBCecCommand              = CecCommandCB;
-               g_cecCallbacks.CBCecConfigurationChanged = CecConfigCB;
-               g_cecCallbacks.CBCecAlert                = CecAlertCB;
-               g_cecCallbacks.CBCecMenuStateChanged     = CecMenuCB;
+  /// <summary>
+  /// Called by libCEC to send back a log message to the application
+  /// </summary>
+  /// <param name="cbParam">Pointer to the callback struct</param>
+  /// <param name="message">The log message</param>
+  /// <return>1 when handled, 0 otherwise</return>
+  int CecLogMessageCB(void *cbParam, const CEC::cec_log_message message)
+  {
+    if (cbParam)
+    {
+      size_t iPtr = (size_t)cbParam;
+      PLATFORM::CLockObject lock(g_callbackMutex);
+      if (iPtr >= 0 && iPtr < g_unmanagedCallbacks.size())
+        return g_unmanagedCallbacks[iPtr].logCB(message);
+    }
+    return 0;
+  }
+
+  /// <summary>
+  /// Called by libCEC to send back a key press or release to the application
+  /// </summary>
+  /// <param name="cbParam">Pointer to the callback struct</param>
+  /// <param name="key">The key press command that libCEC received</param>
+  /// <return>1 when handled, 0 otherwise</return>
+  int CecKeyPressCB(void *cbParam, const CEC::cec_keypress key)
+  {
+    if (cbParam)
+    {
+      size_t iPtr = (size_t)cbParam;
+      PLATFORM::CLockObject lock(g_callbackMutex);
+      if (iPtr >= 0 && iPtr < g_unmanagedCallbacks.size())
+        return g_unmanagedCallbacks[iPtr].keyCB(key);
+    }
+    return 0;
+  }
+
+  /// <summary>
+  /// Called by libCEC to send back raw CEC data to the application
+  /// </summary>
+  /// <param name="cbParam">Pointer to the callback struct</param>
+  /// <param name="command">The raw CEC data</param>
+  /// <return>1 when handled, 0 otherwise</return>
+  int CecCommandCB(void *cbParam, const CEC::cec_command command)
+  {
+    if (cbParam)
+    {
+      size_t iPtr = (size_t)cbParam;
+      PLATFORM::CLockObject lock(g_callbackMutex);
+      if (iPtr >= 0 && iPtr < g_unmanagedCallbacks.size())
+        return g_unmanagedCallbacks[iPtr].commandCB(command);
+    }
+    return 0;
+  }
+
+  /// <summary>
+  /// Called by libCEC to send back an updated configuration to the application
+  /// </summary>
+  /// <param name="cbParam">Pointer to the callback struct</param>
+  /// <param name="config">The new configuration</param>
+  /// <return>1 when handled, 0 otherwise</return>
+  int CecConfigCB(void *cbParam, const CEC::libcec_configuration config)
+  {
+    if (cbParam)
+    {
+      size_t iPtr = (size_t)cbParam;
+      PLATFORM::CLockObject lock(g_callbackMutex);
+      if (iPtr >= 0 && iPtr < g_unmanagedCallbacks.size())
+        return g_unmanagedCallbacks[iPtr].configCB(config);
+    }
+    return 0;
+  }
+
+  /// <summary>
+  /// Called by libCEC to send back an alert message to the application
+  /// </summary>
+  /// <param name="cbParam">Pointer to the callback struct</param>
+  /// <param name="data">The alert message</param>
+  /// <return>1 when handled, 0 otherwise</return>
+  int CecAlertCB(void *cbParam, const CEC::libcec_alert alert, const CEC::libcec_parameter data)
+  {
+    if (cbParam)
+    {
+      size_t iPtr = (size_t)cbParam;
+      PLATFORM::CLockObject lock(g_callbackMutex);
+      if (iPtr >= 0 && iPtr < g_unmanagedCallbacks.size())
+        return g_unmanagedCallbacks[iPtr].alertCB(alert, data);
+    }
+    return 0;
+  }
+
+  /// <summary>
+  /// Called by libCEC to send back a menu state change to the application
+  /// </summary>
+  /// <param name="cbParam">Pointer to the callback struct</param>
+  /// <param name="newVal">The new menu state</param>
+  /// <return>1 when handled, 0 otherwise</return>
+  int CecMenuCB(void *cbParam, const CEC::cec_menu_state newVal)
+  {
+    if (cbParam)
+    {
+      size_t iPtr = (size_t)cbParam;
+      PLATFORM::CLockObject lock(g_callbackMutex);
+      if (iPtr >= 0 && iPtr < g_unmanagedCallbacks.size())
+        return g_unmanagedCallbacks[iPtr].menuCB(newVal);
+    }
+    return 0;
+  }
+
+  /// <summary>
+  /// Called by libCEC to notify the application that the source that is handled by libCEC was (de)activated
+  /// </summary>
+  /// <param name="cbParam">Pointer to the callback struct</param>
+  /// <param name="logicalAddress">The logical address that was (de)activated</param>
+  /// <param name="activated">True when activated, false when deactivated</param>
+  void CecSourceActivatedCB(void *cbParam, const CEC::cec_logical_address logicalAddress, const uint8_t activated)
+  {
+    if (cbParam)
+    {
+      size_t iPtr = (size_t)cbParam;
+      PLATFORM::CLockObject lock(g_callbackMutex);
+      if (iPtr >= 0 && iPtr < g_unmanagedCallbacks.size())
+        g_unmanagedCallbacks[iPtr].sourceActivatedCB(logicalAddress, activated);
+    }
+  }
+
+#pragma managed
+  /// <summary>
+  /// Delegate method for the CecLogMessageCB callback in CecCallbackMethods
+  /// </summary>
+  public delegate int  CecLogMessageManagedDelegate(const CEC::cec_log_message &);
+  /// <summary>
+  /// Delegate method for the CecKeyPressCB callback in CecCallbackMethods
+  /// </summary>
+  public delegate int  CecKeyPressManagedDelegate(const CEC::cec_keypress &);
+  /// <summary>
+  /// Delegate method for the CecCommandCB callback in CecCallbackMethods
+  /// </summary>
+  public delegate int  CecCommandManagedDelegate(const CEC::cec_command &);
+  /// <summary>
+  /// Delegate method for the CecConfigCB callback in CecCallbackMethods
+  /// </summary>
+  public delegate int  CecConfigManagedDelegate(const CEC::libcec_configuration &);
+  /// <summary>
+  /// Delegate method for the CecAlertCB callback in CecCallbackMethods
+  /// </summary>
+  public delegate int  CecAlertManagedDelegate(const CEC::libcec_alert, const CEC::libcec_parameter &);
+  /// <summary>
+  /// Delegate method for the CecMenuCB callback in CecCallbackMethods
+  /// </summary>
+  public delegate int  CecMenuManagedDelegate(const CEC::cec_menu_state);
+  /// <summary>
+  /// Delegate method for the CecSourceActivatedCB callback in CecCallbackMethods
+  /// </summary>
+  public delegate void CecSourceActivatedManagedDelegate(const CEC::cec_logical_address, const uint8_t);
+
+  /// <summary>
+  /// Assign the callback methods in the g_cecCallbacks struct
+  /// </summary>
+  void AssignCallbacks()
+  {
+    g_cecCallbacks.CBCecLogMessage           = CecLogMessageCB;
+    g_cecCallbacks.CBCecKeyPress             = CecKeyPressCB;
+    g_cecCallbacks.CBCecCommand              = CecCommandCB;
+    g_cecCallbacks.CBCecConfigurationChanged = CecConfigCB;
+    g_cecCallbacks.CBCecAlert                = CecAlertCB;
+    g_cecCallbacks.CBCecMenuStateChanged     = CecMenuCB;
     g_cecCallbacks.CBCecSourceActivated      = CecSourceActivatedCB;
-       }
-
-       // callback method interface
-       public ref class CecCallbackMethods
-       {
-       public:
+  }
+
+  /// <summary>
+  /// The callback methods that libCEC uses
+  /// </summary>
+  public ref class CecCallbackMethods
+  {
+  public:
     CecCallbackMethods(void)
     {
-                       m_iCallbackPtr = -1;
-                       AssignCallbacks();
+      m_iCallbackPtr = -1;
+      AssignCallbacks();
       m_bHasCallbacks = false;
       m_bDelegatesCreated = false;
     }
 
-         ~CecCallbackMethods(void)
+    ~CecCallbackMethods(void)
     {
       DestroyDelegates();
     }
 
-               size_t GetCallbackPtr(void)
-               {
-                       PLATFORM::CLockObject lock(g_callbackMutex);
-                       return m_iCallbackPtr;
-               }
-
-       protected:
-   !CecCallbackMethods(void)
-   {
-     DestroyDelegates();
-   }
-
-       public:
-               virtual void DisableCallbacks(void)
-               {
-                       DestroyDelegates();
-               }
-
-               virtual bool EnableCallbacks(CecCallbackMethods ^ callbacks)
-               {
+    /// <summary>
+    /// Pointer to the callbacks struct entry
+    /// </summary>
+    size_t GetCallbackPtr(void)
+    {
+      PLATFORM::CLockObject lock(g_callbackMutex);
+      return m_iCallbackPtr;
+    }
+
+  protected:
+    !CecCallbackMethods(void)
+    {
+      DestroyDelegates();
+    }
+
+  public:
+    /// <summary>
+    /// Disable callback methods
+    /// </summary>
+    virtual void DisableCallbacks(void)
+    {
+      DestroyDelegates();
+    }
+
+    /// <summary>
+    /// Enable callback methods
+    /// </summary>
+    /// <param name="callbacks">Callback methods to activate</param>
+    /// <return>true when handled, false otherwise</return>
+    virtual bool EnableCallbacks(CecCallbackMethods ^ callbacks)
+    {
       CreateDelegates();
-                       if (!m_bHasCallbacks)
-                       {
-                               m_bHasCallbacks = true;
-                               m_callbacks = callbacks;
-                               return true;
-                       }
-
-                       return false;
-               }
-
-               virtual int ReceiveLogMessage(CecLogMessage ^ message)
-               {
-                       return 0;
-               }
-
-               virtual int ReceiveKeypress(CecKeypress ^ key)
-               {
-                       return 0;
-               }
-
-               virtual int ReceiveCommand(CecCommand ^ command)
-               {
-                       return 0;
-               }
-
-               virtual int ConfigurationChanged(LibCECConfiguration ^ config)
-               {
-                       return 0;
-               }
-
-               virtual int ReceiveAlert(CecAlert alert, CecParameter ^ data)
-               {
-                       return 0;
-               }
-
-               virtual int ReceiveMenuStateChange(CecMenuState newVal)
-               {
-                       return 0;
-               }
-
-               virtual void SourceActivated(CecLogicalAddress logicalAddress, bool bActivated)
-               {
-               }
-
-       protected:
-               // managed callback methods
-               int CecLogMessageManaged(const CEC::cec_log_message &message)
-               {
-                       int iReturn(0);
-                       if (m_bHasCallbacks)
-                               iReturn = m_callbacks->ReceiveLogMessage(gcnew CecLogMessage(gcnew System::String(message.message), (CecLogLevel)message.level, message.time));
-                       return iReturn;
-               }
-
-               int CecKeyPressManaged(const CEC::cec_keypress &key)
-               {
-                       int iReturn(0);
-                       if (m_bHasCallbacks)
-                               iReturn = m_callbacks->ReceiveKeypress(gcnew CecKeypress((CecUserControlCode)key.keycode, key.duration));
-                       return iReturn;
-               }
-
-               int CecCommandManaged(const CEC::cec_command &command)
-               {
-                       int iReturn(0);
-                       if (m_bHasCallbacks)
-                       {
-                               CecCommand ^ newCommand = gcnew CecCommand((CecLogicalAddress)command.initiator, (CecLogicalAddress)command.destination, command.ack == 1 ? true : false, command.eom == 1 ? true : false, (CecOpcode)command.opcode, command.transmit_timeout);
-                               for (uint8_t iPtr = 0; iPtr < command.parameters.size; iPtr++)
-                                       newCommand->Parameters->PushBack(command.parameters[iPtr]);
-                               iReturn = m_callbacks->ReceiveCommand(newCommand);
-                       }
-                       return iReturn;
-               }
-
-               int CecConfigManaged(const CEC::libcec_configuration &config)
-               {
-                       int iReturn(0);
-                       if (m_bHasCallbacks)
-                       {
-                               LibCECConfiguration ^netConfig = gcnew LibCECConfiguration();
-                               netConfig->Update(config);
-                               iReturn = m_callbacks->ConfigurationChanged(netConfig);
-                       }
-                       return iReturn;
-               }
-
-               int CecAlertManaged(const CEC::libcec_alert alert, const CEC::libcec_parameter &data)
-               {
-                       int iReturn(0);
-                       if (m_bHasCallbacks)
-                       {
-                               CecParameterType newType = (CecParameterType)data.paramType;
-                               if (newType == CecParameterType::ParameterTypeString)
-                               {
-                                       System::String ^ newData = gcnew System::String((const char *)data.paramData, 0, 128);
-                                       CecParameter ^ newParam = gcnew CecParameter(newType, newData);
-                                   iReturn = m_callbacks->ReceiveAlert((CecAlert)alert, newParam);
-                               }
-                       }
-                       return iReturn;
-               }
-
-               int CecMenuManaged(const CEC::cec_menu_state newVal)
-               {
-                       int iReturn(0);
-                       if (m_bHasCallbacks)
-                       {
-                               iReturn = m_callbacks->ReceiveMenuStateChange((CecMenuState)newVal);
-                       }
-                       return iReturn;
-               }
-
-               void CecSourceActivatedManaged(const CEC::cec_logical_address logicalAddress, const uint8_t bActivated)
-               {
-                       if (m_bHasCallbacks)
-                               m_callbacks->SourceActivated((CecLogicalAddress)logicalAddress, bActivated == 1);
-               }
-
-               void DestroyDelegates()
-               {
+      if (!m_bHasCallbacks)
+      {
+        m_bHasCallbacks = true;
+        m_callbacks = callbacks;
+        return true;
+      }
+
+      return false;
+    }
+
+    /// <summary>
+    /// Called by libCEC to send back a log message to the application.
+    /// Override in the application to handle this callback.
+    /// </summary>
+    /// <param name="message">The log message</param>
+    /// <return>1 when handled, 0 otherwise</return>
+    virtual int ReceiveLogMessage(CecLogMessage ^ message)
+    {
+      return 0;
+    }
+
+    /// <summary>
+    /// Called by libCEC to send back a key press or release to the application.
+    /// Override in the application to handle this callback.
+    /// </summary>
+    /// <param name="key">The key press command that libCEC received</param>
+    /// <return>1 when handled, 0 otherwise</return>
+    virtual int ReceiveKeypress(CecKeypress ^ key)
+    {
+      return 0;
+    }
+
+    /// <summary>
+    /// Called by libCEC to send back raw CEC data to the application.
+    /// Override in the application to handle this callback.
+    /// </summary>
+    /// <param name="command">The raw CEC data</param>
+    /// <return>1 when handled, 0 otherwise</return>
+    virtual int ReceiveCommand(CecCommand ^ command)
+    {
+      return 0;
+    }
+
+    /// <summary>
+    /// Called by libCEC to send back an updated configuration to the application.
+    /// Override in the application to handle this callback.
+    /// </summary>
+    /// <param name="config">The new configuration</param>
+    /// <return>1 when handled, 0 otherwise</return>
+    virtual int ConfigurationChanged(LibCECConfiguration ^ config)
+    {
+      return 0;
+    }
+
+    /// <summary>
+    /// Called by libCEC to send back an alert message to the application.
+    /// Override in the application to handle this callback.
+    /// </summary>
+    /// <param name="data">The alert message</param>
+    /// <return>1 when handled, 0 otherwise</return>
+    virtual int ReceiveAlert(CecAlert alert, CecParameter ^ data)
+    {
+      return 0;
+    }
+
+    /// <summary>
+    /// Called by libCEC to send back a menu state change to the application.
+    /// Override in the application to handle this callback.
+    /// </summary>
+    /// <param name="newVal">The new menu state</param>
+    /// <return>1 when handled, 0 otherwise</return>
+    virtual int ReceiveMenuStateChange(CecMenuState newVal)
+    {
+      return 0;
+    }
+
+    /// <summary>
+    /// Called by libCEC to notify the application that the source that is handled by libCEC was (de)activated.
+    /// Override in the application to handle this callback.
+    /// </summary>
+    /// <param name="logicalAddress">The logical address that was (de)activated</param>
+    /// <param name="activated">True when activated, false when deactivated</param>
+    virtual void SourceActivated(CecLogicalAddress logicalAddress, bool activated)
+    {
+    }
+
+  protected:
+    // managed callback methods
+    int CecLogMessageManaged(const CEC::cec_log_message &message)
+    {
+      int iReturn(0);
+      if (m_bHasCallbacks)
+        iReturn = m_callbacks->ReceiveLogMessage(gcnew CecLogMessage(gcnew System::String(message.message), (CecLogLevel)message.level, message.time));
+      return iReturn;
+    }
+
+    int CecKeyPressManaged(const CEC::cec_keypress &key)
+    {
+      int iReturn(0);
+      if (m_bHasCallbacks)
+        iReturn = m_callbacks->ReceiveKeypress(gcnew CecKeypress((CecUserControlCode)key.keycode, key.duration));
+      return iReturn;
+    }
+
+    int CecCommandManaged(const CEC::cec_command &command)
+    {
+      int iReturn(0);
+      if (m_bHasCallbacks)
+      {
+        CecCommand ^ newCommand = gcnew CecCommand((CecLogicalAddress)command.initiator, (CecLogicalAddress)command.destination, command.ack == 1 ? true : false, command.eom == 1 ? true : false, (CecOpcode)command.opcode, command.transmit_timeout);
+        for (uint8_t iPtr = 0; iPtr < command.parameters.size; iPtr++)
+          newCommand->Parameters->PushBack(command.parameters[iPtr]);
+        iReturn = m_callbacks->ReceiveCommand(newCommand);
+      }
+      return iReturn;
+    }
+
+    int CecConfigManaged(const CEC::libcec_configuration &config)
+    {
+      int iReturn(0);
+      if (m_bHasCallbacks)
+      {
+        LibCECConfiguration ^netConfig = gcnew LibCECConfiguration();
+        netConfig->Update(config);
+        iReturn = m_callbacks->ConfigurationChanged(netConfig);
+      }
+      return iReturn;
+    }
+
+    int CecAlertManaged(const CEC::libcec_alert alert, const CEC::libcec_parameter &data)
+    {
+      int iReturn(0);
+      if (m_bHasCallbacks)
+      {
+        CecParameterType newType = (CecParameterType)data.paramType;
+        if (newType == CecParameterType::ParameterTypeString)
+        {
+          System::String ^ newData = gcnew System::String((const char *)data.paramData, 0, 128);
+          CecParameter ^ newParam = gcnew CecParameter(newType, newData);
+          iReturn = m_callbacks->ReceiveAlert((CecAlert)alert, newParam);
+        }
+      }
+      return iReturn;
+    }
+
+    int CecMenuManaged(const CEC::cec_menu_state newVal)
+    {
+      int iReturn(0);
+      if (m_bHasCallbacks)
+      {
+        iReturn = m_callbacks->ReceiveMenuStateChange((CecMenuState)newVal);
+      }
+      return iReturn;
+    }
+
+    void CecSourceActivatedManaged(const CEC::cec_logical_address logicalAddress, const uint8_t bActivated)
+    {
+      if (m_bHasCallbacks)
+        m_callbacks->SourceActivated((CecLogicalAddress)logicalAddress, bActivated == 1);
+    }
+
+    void DestroyDelegates()
+    {
       m_bHasCallbacks = false;
-                       if (m_bDelegatesCreated)
-                       {
+      if (m_bDelegatesCreated)
+      {
         m_bDelegatesCreated = false;
-                               m_logMessageGCHandle.Free();
-                               m_keypressGCHandle.Free();
-                               m_commandGCHandle.Free();
-                               m_alertGCHandle.Free();
-                               m_menuGCHandle.Free();
-                               m_sourceActivatedGCHandle.Free();
-                       }
-               }
+        m_logMessageGCHandle.Free();
+        m_keypressGCHandle.Free();
+        m_commandGCHandle.Free();
+        m_alertGCHandle.Free();
+        m_menuGCHandle.Free();
+        m_sourceActivatedGCHandle.Free();
+      }
+    }
 
     void CreateDelegates()
     {
@@ -1024,87 +2335,87 @@ namespace CecSharp
         // create the delegate method for the log message callback
         m_logMessageDelegate      = gcnew CecLogMessageManagedDelegate(this, &CecCallbackMethods::CecLogMessageManaged);
         m_logMessageGCHandle      = System::Runtime::InteropServices::GCHandle::Alloc(m_logMessageDelegate);
-                               m_logMessageCallback      = static_cast<LOGCB>(System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(m_logMessageDelegate).ToPointer());
+        m_logMessageCallback      = static_cast<LOGCB>(System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(m_logMessageDelegate).ToPointer());
 
         // create the delegate method for the keypress callback
         m_keypressDelegate        = gcnew CecKeyPressManagedDelegate(this, &CecCallbackMethods::CecKeyPressManaged);
         m_keypressGCHandle        = System::Runtime::InteropServices::GCHandle::Alloc(m_keypressDelegate);
-                               m_keypressCallback        = static_cast<KEYCB>(System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(m_keypressDelegate).ToPointer());
+        m_keypressCallback        = static_cast<KEYCB>(System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(m_keypressDelegate).ToPointer());
 
         // create the delegate method for the command callback
         m_commandDelegate         = gcnew CecCommandManagedDelegate(this, &CecCallbackMethods::CecCommandManaged);
         m_commandGCHandle         = System::Runtime::InteropServices::GCHandle::Alloc(m_commandDelegate);
-                               m_commandCallback         = static_cast<COMMANDCB>(System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(m_commandDelegate).ToPointer());
+        m_commandCallback         = static_cast<COMMANDCB>(System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(m_commandDelegate).ToPointer());
 
         // create the delegate method for the configuration change callback
         m_configDelegate          = gcnew CecConfigManagedDelegate(this, &CecCallbackMethods::CecConfigManaged);
         m_configGCHandle          = System::Runtime::InteropServices::GCHandle::Alloc(m_configDelegate);
-                               m_configCallback          = static_cast<CONFIGCB>(System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(m_configDelegate).ToPointer());
+        m_configCallback          = static_cast<CONFIGCB>(System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(m_configDelegate).ToPointer());
 
         // create the delegate method for the alert callback
         m_alertDelegate           = gcnew CecAlertManagedDelegate(this, &CecCallbackMethods::CecAlertManaged);
         m_alertGCHandle           = System::Runtime::InteropServices::GCHandle::Alloc(m_alertDelegate);
-                               m_alertCallback           = static_cast<ALERTCB>(System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(m_alertDelegate).ToPointer());
+        m_alertCallback           = static_cast<ALERTCB>(System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(m_alertDelegate).ToPointer());
 
         // create the delegate method for the menu callback
         m_menuDelegate            = gcnew CecMenuManagedDelegate(this, &CecCallbackMethods::CecMenuManaged);
         m_menuGCHandle            = System::Runtime::InteropServices::GCHandle::Alloc(m_menuDelegate);
-                               m_menuCallback            = static_cast<MENUCB>(System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(m_menuDelegate).ToPointer());
+        m_menuCallback            = static_cast<MENUCB>(System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(m_menuDelegate).ToPointer());
 
-                         // create the delegate method for the source activated callback
+        // create the delegate method for the source activated callback
         m_sourceActivatedDelegate = gcnew CecSourceActivatedManagedDelegate(this, &CecCallbackMethods::CecSourceActivatedManaged);
         m_sourceActivatedGCHandle = System::Runtime::InteropServices::GCHandle::Alloc(m_sourceActivatedDelegate);
-                               m_sourceActivatedCallback = static_cast<ACTICB>(System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(m_sourceActivatedDelegate).ToPointer());
+        m_sourceActivatedCallback = static_cast<ACTICB>(System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(m_sourceActivatedDelegate).ToPointer());
 
         delete context;
 
-                               UnmanagedCecCallbacks unmanagedCallbacks;
-                               unmanagedCallbacks.logCB             = m_logMessageCallback;
-                               unmanagedCallbacks.keyCB             = m_keypressCallback;
-                               unmanagedCallbacks.commandCB         = m_commandCallback;
-                               unmanagedCallbacks.configCB          = m_configCallback;
-                               unmanagedCallbacks.alertCB           = m_alertCallback;
-                               unmanagedCallbacks.menuCB            = m_menuCallback;
-                               unmanagedCallbacks.sourceActivatedCB = m_sourceActivatedCallback;
-
-                               PLATFORM::CLockObject lock(g_callbackMutex);
-                               g_unmanagedCallbacks.push_back(unmanagedCallbacks);
-                               m_iCallbackPtr = g_unmanagedCallbacks.size() - 1;
-                               m_bDelegatesCreated = true;
+        UnmanagedCecCallbacks unmanagedCallbacks;
+        unmanagedCallbacks.logCB             = m_logMessageCallback;
+        unmanagedCallbacks.keyCB             = m_keypressCallback;
+        unmanagedCallbacks.commandCB         = m_commandCallback;
+        unmanagedCallbacks.configCB          = m_configCallback;
+        unmanagedCallbacks.alertCB           = m_alertCallback;
+        unmanagedCallbacks.menuCB            = m_menuCallback;
+        unmanagedCallbacks.sourceActivatedCB = m_sourceActivatedCallback;
+
+        PLATFORM::CLockObject lock(g_callbackMutex);
+        g_unmanagedCallbacks.push_back(unmanagedCallbacks);
+        m_iCallbackPtr = g_unmanagedCallbacks.size() - 1;
+        m_bDelegatesCreated = true;
       }
     }
 
-               CecLogMessageManagedDelegate ^                    m_logMessageDelegate;
-               static System::Runtime::InteropServices::GCHandle m_logMessageGCHandle;
-               LOGCB                                             m_logMessageCallback;
+    CecLogMessageManagedDelegate ^                    m_logMessageDelegate;
+    static System::Runtime::InteropServices::GCHandle m_logMessageGCHandle;
+    LOGCB                                             m_logMessageCallback;
 
-               CecKeyPressManagedDelegate ^                      m_keypressDelegate;
-               static System::Runtime::InteropServices::GCHandle m_keypressGCHandle;
-               KEYCB                                             m_keypressCallback;
+    CecKeyPressManagedDelegate ^                      m_keypressDelegate;
+    static System::Runtime::InteropServices::GCHandle m_keypressGCHandle;
+    KEYCB                                             m_keypressCallback;
 
-               CecCommandManagedDelegate ^                       m_commandDelegate;
-               static System::Runtime::InteropServices::GCHandle m_commandGCHandle;
-               COMMANDCB                                         m_commandCallback;
+    CecCommandManagedDelegate ^                       m_commandDelegate;
+    static System::Runtime::InteropServices::GCHandle m_commandGCHandle;
+    COMMANDCB                                         m_commandCallback;
 
-         CecConfigManagedDelegate ^                        m_configDelegate;
-               static System::Runtime::InteropServices::GCHandle m_configGCHandle;
-               CONFIGCB                                          m_configCallback;
+    CecConfigManagedDelegate ^                        m_configDelegate;
+    static System::Runtime::InteropServices::GCHandle m_configGCHandle;
+    CONFIGCB                                          m_configCallback;
 
-               CecAlertManagedDelegate ^                         m_alertDelegate;
-               static System::Runtime::InteropServices::GCHandle m_alertGCHandle;
-               ALERTCB                                           m_alertCallback;
+    CecAlertManagedDelegate ^                         m_alertDelegate;
+    static System::Runtime::InteropServices::GCHandle m_alertGCHandle;
+    ALERTCB                                           m_alertCallback;
 
-               CecMenuManagedDelegate ^                          m_menuDelegate;
-               static System::Runtime::InteropServices::GCHandle m_menuGCHandle;
-               MENUCB                                            m_menuCallback;
+    CecMenuManagedDelegate ^                          m_menuDelegate;
+    static System::Runtime::InteropServices::GCHandle m_menuGCHandle;
+    MENUCB                                            m_menuCallback;
 
-               CecSourceActivatedManagedDelegate ^               m_sourceActivatedDelegate;
-               static System::Runtime::InteropServices::GCHandle m_sourceActivatedGCHandle;
-               ACTICB                                            m_sourceActivatedCallback;
+    CecSourceActivatedManagedDelegate ^               m_sourceActivatedDelegate;
+    static System::Runtime::InteropServices::GCHandle m_sourceActivatedGCHandle;
+    ACTICB                                            m_sourceActivatedCallback;
 
-               CecCallbackMethods ^ m_callbacks;
-         bool                 m_bHasCallbacks;
+    CecCallbackMethods ^ m_callbacks;
+    bool                 m_bHasCallbacks;
     bool                 m_bDelegatesCreated;
-               size_t               m_iCallbackPtr;
-       };
+    size_t               m_iCallbackPtr;
+  };
 }
index 81c857fb2fed67c2475365eab980289d32aaf21b..ff3c619f487694166c2ec37d23aa37763e446c67 100644 (file)
@@ -1,34 +1,34 @@
 /*
- * This file is part of the libCEC(R) library.
- *
- * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
- * libCEC(R) is an original work, containing original code.
- *
- * libCEC(R) is a trademark of Pulse-Eight Limited.
- *
- * This program is dual-licensed; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- *
- * Alternatively, you can license this library under a commercial license,
- * please contact Pulse-Eight Licensing for more information.
- *
- * For more information contact:
- * Pulse-Eight Licensing       <license@pulse-eight.com>
- *     http://www.pulse-eight.com/
- *     http://www.pulse-eight.net/
- */
+* This file is part of the libCEC(R) library.
+*
+* libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
+* libCEC(R) is an original work, containing original code.
+*
+* libCEC(R) is a trademark of Pulse-Eight Limited.
+*
+* This program is dual-licensed; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+*
+* Alternatively, you can license this library under a commercial license,
+* please contact Pulse-Eight Licensing for more information.
+*
+* For more information contact:
+* Pulse-Eight Licensing       <license@pulse-eight.com>
+*     http://www.pulse-eight.com/
+*     http://www.pulse-eight.net/
+*/
 
 #include "CecSharpTypes.h"
 #using <System.dll>
@@ -40,577 +40,793 @@ using namespace msclr::interop;
 
 namespace CecSharp
 {
-       public ref class LibCecSharp : public CecCallbackMethods
-       {
-       public:
-         LibCecSharp(LibCECConfiguration ^config)
-               {
+  /// <summary>
+  /// Create a LibCecSharp instance and pass the configuration as argument.
+  /// Then call Open() to open a connection to the adapter. Close() closes the
+  /// connection.
+  ///
+  /// libCEC can send commands to other devices on the CEC bus via the methods
+  /// on this interface, and all commands that libCEC received are sent back
+  /// to the application via callback methods. The callback methods can be
+  /// found in CecSharpTypes.h, CecCallbackMethods.
+  /// </summary>
+  public ref class LibCecSharp : public CecCallbackMethods
+  {
+  public:
+    /// <summary>
+    /// Create a new LibCecSharp instance.
+    /// </summary>
+    /// <param name="config">The configuration to pass to libCEC.</param>
+    LibCecSharp(LibCECConfiguration ^config)
+    {
       m_callbacks = config->Callbacks;
-                       CecCallbackMethods::EnableCallbacks(m_callbacks);
-                       if (!InitialiseLibCec(config))
-                               throw gcnew Exception("Could not initialise LibCecSharp");
-               }
-
-               LibCecSharp(String ^ strDeviceName, CecDeviceTypeList ^ deviceTypes)
-               {
-      m_callbacks = gcnew CecCallbackMethods();
-                       LibCECConfiguration ^config = gcnew LibCECConfiguration();
-                       config->SetCallbacks(this);
-                       config->DeviceName  = strDeviceName;
-                       config->DeviceTypes = deviceTypes;
-                       if (!InitialiseLibCec(config))
-                               throw gcnew Exception("Could not initialise LibCecSharp");
-               }
-          
-               ~LibCecSharp(void)
-               {
-                       Close();
-                       m_libCec = NULL;
-               }
-
-       private:
-               !LibCecSharp(void)
-               {
-                       Close();
-                       m_libCec = NULL;
-               }
-
-               bool InitialiseLibCec(LibCECConfiguration ^config)
-               {
-                       marshal_context ^ context = gcnew marshal_context();
-                       libcec_configuration libCecConfig;
-                       ConvertConfiguration(context, config, libCecConfig);
-
-                       m_libCec = (ICECAdapter *) CECInitialise(&libCecConfig);
-                       config->Update(libCecConfig);
-
-                       delete context;
-                       return m_libCec != NULL;
-               }
-
-         void ConvertConfiguration(marshal_context ^context, LibCECConfiguration ^netConfig, CEC::libcec_configuration &config)
-               {
-                       config.Clear();
-
-                       const char *strDeviceName = context->marshal_as<const char*>(netConfig->DeviceName);
-                       memcpy_s(config.strDeviceName, 13, strDeviceName, 13);
-                       for (unsigned int iPtr = 0; iPtr < 5; iPtr++)
-                               config.deviceTypes.types[iPtr] = (cec_device_type)netConfig->DeviceTypes->Types[iPtr];
-
-                       config.bAutodetectAddress   = netConfig->AutodetectAddress ? 1 : 0;
-                       config.iPhysicalAddress     = netConfig->PhysicalAddress;
-                       config.baseDevice           = (cec_logical_address)netConfig->BaseDevice;
-                       config.iHDMIPort            = netConfig->HDMIPort;
-                       config.clientVersion        = (cec_client_version)netConfig->ClientVersion;
-                       config.bGetSettingsFromROM  = netConfig->GetSettingsFromROM ? 1 : 0;
-                       config.bActivateSource      = netConfig->ActivateSource ? 1 : 0;
-                       config.tvVendor             = (cec_vendor_id)netConfig->TvVendor;
-                       config.wakeDevices.Clear();
-                       for (int iPtr = 0; iPtr < 16; iPtr++)
-                       {
-                               if (netConfig->WakeDevices->IsSet((CecLogicalAddress)iPtr))
-                                       config.wakeDevices.Set((cec_logical_address)iPtr);
-                       }
-                       config.powerOffDevices.Clear();
-                       for (int iPtr = 0; iPtr < 16; iPtr++)
-                       {
-                               if (netConfig->PowerOffDevices->IsSet((CecLogicalAddress)iPtr))
-                                       config.powerOffDevices.Set((cec_logical_address)iPtr);
-                       }
-                       config.bPowerOffScreensaver = netConfig->PowerOffScreensaver ? 1 : 0;
-                       config.bPowerOffOnStandby   = netConfig->PowerOffOnStandby ? 1 : 0;
-
-                       if (netConfig->ServerVersion >= CecServerVersion::Version1_5_1)
-                               config.bSendInactiveSource  = netConfig->SendInactiveSource ? 1 : 0;
-
-                       if (netConfig->ServerVersion >= CecServerVersion::Version1_6_0)
-                       {
-                               config.bPowerOffDevicesOnStandby  = netConfig->PowerOffDevicesOnStandby ? 1 : 0;
-                               config.bShutdownOnStandby         = netConfig->ShutdownOnStandby ? 1 : 0;
-                       }
-
-                       if (netConfig->ServerVersion >= CecServerVersion::Version1_6_2)
-                       {
-                               const char *strDeviceLanguage = context->marshal_as<const char*>(netConfig->DeviceLanguage);
-                               memcpy_s(config.strDeviceLanguage, 3, strDeviceLanguage, 3);
-                       }
-
-                       if (netConfig->ServerVersion >= CecServerVersion::Version1_6_3)
-                         config.bMonitorOnly = netConfig->MonitorOnlyClient ? 1 : 0;
-
-                       config.callbacks = &g_cecCallbacks;
-               }
-
-       public:
-               array<CecAdapter ^> ^ FindAdapters(String ^ path)
-               {
-                       cec_adapter *devices = new cec_adapter[10];
-
-                       marshal_context ^ context = gcnew marshal_context();
-                       const char* strPathC = path->Length > 0 ? context->marshal_as<const char*>(path) : NULL;
-
-                       uint8_t iDevicesFound = m_libCec->FindAdapters(devices, 10, NULL);
-
-                       array<CecAdapter ^> ^ adapters = gcnew array<CecAdapter ^>(iDevicesFound);
-                       for (unsigned int iPtr = 0; iPtr < iDevicesFound; iPtr++)
-                               adapters[iPtr] = gcnew CecAdapter(gcnew String(devices[iPtr].path), gcnew String(devices[iPtr].comm));
-
-                       delete devices;
-                       delete context;
-                       return adapters;
-               }
-
-               bool Open(String ^ strPort, int iTimeoutMs)
-               {
+      CecCallbackMethods::EnableCallbacks(m_callbacks);
+      if (!InitialiseLibCec(config))
+        throw gcnew Exception("Could not initialise LibCecSharp");
+    }
+
+    ~LibCecSharp(void)
+    {
+      Close();
+      m_libCec = NULL;
+    }
+
+    /// <summary>
+    /// Try to find all connected CEC adapters.
+    /// </summary>
+    /// <param name="path">The path filter for adapters. Leave empty to return all adapters.</param>
+    /// <returns>The adapters that were found.</returns>
+    array<CecAdapter ^> ^ FindAdapters(String ^ path)
+    {
+      cec_adapter *devices = new cec_adapter[10];
+
+      marshal_context ^ context = gcnew marshal_context();
+      const char* strPathC = path->Length > 0 ? context->marshal_as<const char*>(path) : NULL;
+
+      uint8_t iDevicesFound = m_libCec->FindAdapters(devices, 10, NULL);
+
+      array<CecAdapter ^> ^ adapters = gcnew array<CecAdapter ^>(iDevicesFound);
+      for (unsigned int iPtr = 0; iPtr < iDevicesFound; iPtr++)
+        adapters[iPtr] = gcnew CecAdapter(gcnew String(devices[iPtr].path), gcnew String(devices[iPtr].comm));
+
+      delete devices;
+      delete context;
+      return adapters;
+    }
+
+    /// <summary>
+    /// Open a connection to the CEC adapter.
+    /// </summary>
+    /// <param name="strPort">The COM port of the adapter</param>
+    /// <param name="iTimeoutMs">Connection timeout in milliseconds</param>
+    /// <returns>True when a connection was opened, false otherwise.</returns>
+    bool Open(String ^ strPort, int iTimeoutMs)
+    {
       CecCallbackMethods::EnableCallbacks(m_callbacks);
       EnableCallbacks(m_callbacks);
-                       marshal_context ^ context = gcnew marshal_context();
-                       const char* strPortC = context->marshal_as<const char*>(strPort);
-                       bool bReturn = m_libCec->Open(strPortC, iTimeoutMs);
-                       delete context;
-                       return bReturn;
-               }
-
-               void Close(void)
-               {
-                       DisableCallbacks();
-                       m_libCec->Close();
-               }
-
-               virtual void DisableCallbacks(void) override
-               {
-                       // delete the callbacks, since these might already have been destroyed in .NET
-                       CecCallbackMethods::DisableCallbacks();
-                       if (m_libCec)
-                               m_libCec->EnableCallbacks(NULL, NULL);
-               }
-
-               virtual bool EnableCallbacks(CecCallbackMethods ^ callbacks) override
-               {
-                       if (m_libCec && CecCallbackMethods::EnableCallbacks(callbacks))
-                               return m_libCec->EnableCallbacks((void*)GetCallbackPtr(), &g_cecCallbacks);
-
-                       return false;
-               }
-
-               bool PingAdapter(void)
-               {
-                       return m_libCec->PingAdapter();
-               }
-
-               bool StartBootloader(void)
-               {
-                       return m_libCec->StartBootloader();
-               }
-
-               int GetMinLibVersion(void)
-               {
-                       return m_libCec->GetMinLibVersion();
-               }
-
-               int GetLibVersionMajor(void)
-               {
-                       return m_libCec->GetLibVersionMajor();
-               }
-
-               int GetLibVersionMinor(void)
-               {
-                       return m_libCec->GetLibVersionMinor();
-               }
-
-               CecLogMessage ^ GetNextLogMessage(void)
-               {
-                       cec_log_message msg;
-                       if (m_libCec->GetNextLogMessage(&msg))
-                       {
-                               return gcnew CecLogMessage(gcnew String(msg.message), (CecLogLevel)msg.level, msg.time);
-                       }
-
-                       return gcnew CecLogMessage();
-               }
-
-               CecKeypress ^ GetNextKeypress(void)
-               {
-                       cec_keypress key;
-                       if (m_libCec->GetNextKeypress(&key))
-                       {
-                               return gcnew CecKeypress((CecUserControlCode)key.keycode, key.duration);
-                       }
-
-                       return gcnew CecKeypress();
-               }
-
-               CecCommand ^ GetNextCommand(void)
-               {
-                       cec_command command;
-                       if (m_libCec->GetNextCommand(&command))
-                       {
-                               CecCommand ^ retVal = gcnew CecCommand((CecLogicalAddress)command.initiator, (CecLogicalAddress)command.destination, command.ack == 1 ? true : false, command.eom == 1 ? true : false, (CecOpcode)command.opcode, command.transmit_timeout);
-                               for (uint8_t iPtr = 0; iPtr < command.parameters.size; iPtr++)
-                                       retVal->Parameters->PushBack(command.parameters[iPtr]);
-                               return retVal;
-                       }
-
-                       return gcnew CecCommand();
-               }
-
-               bool Transmit(CecCommand ^ command)
-               {
-                       cec_command ccommand;
-                       cec_command::Format(ccommand, (cec_logical_address)command->Initiator, (cec_logical_address)command->Destination, (cec_opcode)command->Opcode);
-                       ccommand.transmit_timeout = command->TransmitTimeout;
-                       ccommand.eom              = command->Eom;
-                       ccommand.ack              = command->Ack;
-                       for (unsigned int iPtr = 0; iPtr < command->Parameters->Size; iPtr++)
-                               ccommand.parameters.PushBack(command->Parameters->Data[iPtr]);
-
-                       return m_libCec->Transmit(ccommand);
-               }
-
-               bool SetLogicalAddress(CecLogicalAddress logicalAddress)
-               {
-                       return m_libCec->SetLogicalAddress((cec_logical_address) logicalAddress);
-               }
-
-               bool SetPhysicalAddress(uint16_t physicalAddress)
-               {
-                       return m_libCec->SetPhysicalAddress(physicalAddress);
-               }
-
-               bool PowerOnDevices(CecLogicalAddress logicalAddress)
-               {
-                       return m_libCec->PowerOnDevices((cec_logical_address) logicalAddress);
-               }
-
-               bool StandbyDevices(CecLogicalAddress logicalAddress)
-               {
-                       return m_libCec->StandbyDevices((cec_logical_address) logicalAddress);
-               }
-
-               bool PollDevice(CecLogicalAddress logicalAddress)
-               {
-                       return m_libCec->PollDevice((cec_logical_address) logicalAddress);
-               }
-
-               bool SetActiveSource(CecDeviceType type)
-               {
-                       return m_libCec->SetActiveSource((cec_device_type) type);
-               }
-
-               bool SetDeckControlMode(CecDeckControlMode mode, bool sendUpdate)
-               {
-                       return m_libCec->SetDeckControlMode((cec_deck_control_mode) mode, sendUpdate);
-               }
-
-               bool SetDeckInfo(CecDeckInfo info, bool sendUpdate)
-               {
-                       return m_libCec->SetDeckInfo((cec_deck_info) info, sendUpdate);
-               }
-
-               bool SetInactiveView(void)
-               {
-                       return m_libCec->SetInactiveView();
-               }
-
-               bool SetMenuState(CecMenuState state, bool sendUpdate)
-               {
-                       return m_libCec->SetMenuState((cec_menu_state) state, sendUpdate);
-               }
-
-               bool SetOSDString(CecLogicalAddress logicalAddress, CecDisplayControl duration, String ^ message)
-               {
-                       marshal_context ^ context = gcnew marshal_context();
-                       const char* strMessageC = context->marshal_as<const char*>(message);
-
-                       bool bReturn = m_libCec->SetOSDString((cec_logical_address) logicalAddress, (cec_display_control) duration, strMessageC);
-
-                       delete context;
-                       return bReturn;
-               }
-
-               bool SwitchMonitoring(bool enable)
-               {
-                       return m_libCec->SwitchMonitoring(enable);
-               }
-
-               CecVersion GetDeviceCecVersion(CecLogicalAddress logicalAddress)
-               {
-                       return (CecVersion) m_libCec->GetDeviceCecVersion((cec_logical_address) logicalAddress);
-               }
-
-               String ^ GetDeviceMenuLanguage(CecLogicalAddress logicalAddress)
-               {
-                       cec_menu_language lang;
-                       if (m_libCec->GetDeviceMenuLanguage((cec_logical_address) logicalAddress, &lang))
-                       {
-                               return gcnew String(lang.language);
-                       }
-
-                       return gcnew String("");
-               }
-
-               CecVendorId GetDeviceVendorId(CecLogicalAddress logicalAddress)
-               {
-                       return (CecVendorId)m_libCec->GetDeviceVendorId((cec_logical_address) logicalAddress);
-               }
-
-               CecPowerStatus GetDevicePowerStatus(CecLogicalAddress logicalAddress)
-               {
-                       return (CecPowerStatus) m_libCec->GetDevicePowerStatus((cec_logical_address) logicalAddress);
-               }
-
-               void RescanActiveDevices(void)
-               {
-                       m_libCec->RescanActiveDevices();
-               }
-
-               CecLogicalAddresses ^ GetActiveDevices(void)
-               {
-                       CecLogicalAddresses ^ retVal = gcnew CecLogicalAddresses();
-                       unsigned int iDevices = 0;
-
-                       cec_logical_addresses activeDevices = m_libCec->GetActiveDevices();
-
-                       for (uint8_t iPtr = 0; iPtr < 16; iPtr++)
-                               if (activeDevices[iPtr])
-                                       retVal->Addresses[iDevices++] = (CecLogicalAddress)iPtr;
-
-                       return retVal;
-               }
-
-               bool IsActiveDevice(CecLogicalAddress logicalAddress)
-               {
-                       return m_libCec->IsActiveDevice((cec_logical_address)logicalAddress);
-               }
-
-               bool IsActiveDeviceType(CecDeviceType type)
-               {
-                       return m_libCec->IsActiveDeviceType((cec_device_type)type);
-               }
-
-               bool SetHDMIPort(CecLogicalAddress address, uint8_t port)
-               {
-                       return m_libCec->SetHDMIPort((cec_logical_address)address, port);
-               }
-
-               uint8_t VolumeUp(bool wait)
-               {
-                       return m_libCec->VolumeUp(wait);
-               }
-
-               uint8_t VolumeDown(bool wait)
-               {
-                       return m_libCec->VolumeDown(wait);
-               }
-
-               uint8_t MuteAudio(bool wait)
-               {
-                       return m_libCec->MuteAudio(wait);
-               }
-
-               bool SendKeypress(CecLogicalAddress destination, CecUserControlCode key, bool wait)
-               {
-                       return m_libCec->SendKeypress((cec_logical_address)destination, (cec_user_control_code)key, wait);
-               }
-
-               bool SendKeyRelease(CecLogicalAddress destination, bool wait)
-               {
-                       return m_libCec->SendKeyRelease((cec_logical_address)destination, wait);
-               }
-
-               String ^ GetDeviceOSDName(CecLogicalAddress logicalAddress)
-               {
-                       cec_osd_name osd = m_libCec->GetDeviceOSDName((cec_logical_address) logicalAddress);
-                       return gcnew String(osd.name);
-               }
-
-               CecLogicalAddress GetActiveSource()
-               {
-                       return (CecLogicalAddress)m_libCec->GetActiveSource();
-               }
-
-               bool IsActiveSource(CecLogicalAddress logicalAddress)
-               {
-                       return m_libCec->IsActiveSource((cec_logical_address)logicalAddress);
-               }
-
-               uint16_t GetDevicePhysicalAddress(CecLogicalAddress iAddress)
-               {
-                       return m_libCec->GetDevicePhysicalAddress((cec_logical_address)iAddress);
-               }
-
-               bool SetStreamPath(CecLogicalAddress iAddress)
-               {
-                       return m_libCec->SetStreamPath((cec_logical_address)iAddress);
-               }
-
-               bool SetStreamPath(uint16_t iPhysicalAddress)
-               {
-                       return m_libCec->SetStreamPath(iPhysicalAddress);
-               }
-
-               CecLogicalAddresses ^GetLogicalAddresses(void)
-               {
-                       CecLogicalAddresses ^addr = gcnew CecLogicalAddresses();
-                       cec_logical_addresses libAddr = m_libCec->GetLogicalAddresses();
-                       for (unsigned int iPtr = 0; iPtr < 16; iPtr++)
-                               addr->Addresses[iPtr] = (CecLogicalAddress)libAddr.addresses[iPtr];
-                       addr->Primary = (CecLogicalAddress)libAddr.primary;
-                       return addr;
-               }
-
-               bool GetCurrentConfiguration(LibCECConfiguration ^configuration)
-               {
-                       libcec_configuration config;
-                       config.Clear();
-
-                       if (m_libCec->GetCurrentConfiguration(&config))
-                       {
-                               configuration->Update(config);
-                               return true;
-                       }
-                       return false;
-               }
+      marshal_context ^ context = gcnew marshal_context();
+      const char* strPortC = context->marshal_as<const char*>(strPort);
+      bool bReturn = m_libCec->Open(strPortC, iTimeoutMs);
+      delete context;
+      return bReturn;
+    }
+
+    /// <summary>
+    /// Close the connection to the CEC adapter
+    /// </summary>
+    void Close(void)
+    {
+      DisableCallbacks();
+      m_libCec->Close();
+    }
+
+    /// <summary>
+    /// Disable all calls to callback methods.
+    /// </summary>
+    virtual void DisableCallbacks(void) override
+    {
+      // delete the callbacks, since these might already have been destroyed in .NET
+      CecCallbackMethods::DisableCallbacks();
+      if (m_libCec)
+        m_libCec->EnableCallbacks(NULL, NULL);
+    }
+
+    /// <summary>
+    /// Enable or change the callback methods that libCEC uses to send changes to the client application.
+    /// </summary>
+    /// <param name="callbacks">The new callback methods to use.</param>
+    /// <returns>True when the callbacks were changed, false otherwise</returns>
+    virtual bool EnableCallbacks(CecCallbackMethods ^ callbacks) override
+    {
+      if (m_libCec && CecCallbackMethods::EnableCallbacks(callbacks))
+        return m_libCec->EnableCallbacks((void*)GetCallbackPtr(), &g_cecCallbacks);
+
+      return false;
+    }
+
+    /// <summary>
+    /// Sends a ping command to the adapter, to check if it's responding.
+    /// </summary>
+    /// <returns>True when the ping was succesful, false otherwise</returns>
+    bool PingAdapter(void)
+    {
+      return m_libCec->PingAdapter();
+    }
+
+    /// <summary>
+    /// Start the bootloader of the CEC adapter. Closes the connection when successful.
+    /// </summary>
+    /// <returns>True when the command was sent successfully, false otherwise.</returns>
+    bool StartBootloader(void)
+    {
+      return m_libCec->StartBootloader();
+    }
+
+    /// <summary>
+    /// Transmit a raw CEC command over the CEC line.
+    /// </summary>
+    /// <param name="command">The command to transmit</param>
+    /// <returns>True when the data was sent and acked, false otherwise.</returns>
+    bool Transmit(CecCommand ^ command)
+    {
+      cec_command ccommand;
+      cec_command::Format(ccommand, (cec_logical_address)command->Initiator, (cec_logical_address)command->Destination, (cec_opcode)command->Opcode);
+      ccommand.transmit_timeout = command->TransmitTimeout;
+      ccommand.eom              = command->Eom;
+      ccommand.ack              = command->Ack;
+      for (unsigned int iPtr = 0; iPtr < command->Parameters->Size; iPtr++)
+        ccommand.parameters.PushBack(command->Parameters->Data[iPtr]);
+
+      return m_libCec->Transmit(ccommand);
+    }
+
+    /// <summary>
+    /// Change the logical address on the CEC bus of the CEC adapter. libCEC automatically assigns a logical address, and this method is only available for debugging purposes.
+    /// </summary>
+    /// <param name="logicalAddress">The CEC adapter's new logical address.</param>
+    /// <returns>True when the logical address was set successfully, false otherwise.</returns>
+    bool SetLogicalAddress(CecLogicalAddress logicalAddress)
+    {
+      return m_libCec->SetLogicalAddress((cec_logical_address) logicalAddress);
+    }
+
+    /// <summary>
+    /// Change the physical address (HDMI port) of the CEC adapter. libCEC will try to autodetect the physical address when connecting. If it did, it's set in libcec_configuration.
+    /// </summary>
+    /// <param name="physicalAddress">The CEC adapter's new physical address.</param>
+    /// <returns>True when the physical address was set successfully, false otherwise.</returns>
+    bool SetPhysicalAddress(uint16_t physicalAddress)
+    {
+      return m_libCec->SetPhysicalAddress(physicalAddress);
+    }
+
+    /// <summary>
+    /// Power on the given CEC capable devices. If CECDEVICE_BROADCAST is used, then wakeDevice in libcec_configuration will be used.
+    /// </summary>
+    /// <param name="logicalAddress">The logical address to power on.</param>
+    /// <returns>True when the command was sent succesfully, false otherwise.</returns>
+    bool PowerOnDevices(CecLogicalAddress logicalAddress)
+    {
+      return m_libCec->PowerOnDevices((cec_logical_address) logicalAddress);
+    }
+
+    /// <summary>
+    /// Put the given CEC capable devices in standby mode. If CECDEVICE_BROADCAST is used, then standbyDevices in libcec_configuration will be used.
+    /// </summary>
+    /// <param name="logicalAddress">The logical address of the device to put in standby.</param>
+    /// <returns>True when the command was sent succesfully, false otherwise.</returns>
+    bool StandbyDevices(CecLogicalAddress logicalAddress)
+    {
+      return m_libCec->StandbyDevices((cec_logical_address) logicalAddress);
+    }
+
+    /// <summary>
+    /// Sends a POLL message to a device, to check if it's present and responding.
+    /// </summary>
+    /// <param name="logicalAddress">The device to send the message to.</param>
+    /// <returns>True if the POLL was acked, false otherwise.</returns>
+    bool PollDevice(CecLogicalAddress logicalAddress)
+    {
+      return m_libCec->PollDevice((cec_logical_address) logicalAddress);
+    }
+
+    /// <summary>
+    /// Change the active source to a device type handled by libCEC. Use CEC_DEVICE_TYPE_RESERVED to make the default type used by libCEC active.
+    /// </summary>
+    /// <param name="type">The new active source. Use CEC_DEVICE_TYPE_RESERVED to use the primary type</param>
+    /// <returns>True when the command was sent succesfully, false otherwise.</returns>
+    bool SetActiveSource(CecDeviceType type)
+    {
+      return m_libCec->SetActiveSource((cec_device_type) type);
+    }
+
+    /// <summary>
+    /// Change the deck control mode, if this adapter is registered as playback or recording device.
+    /// </summary>
+    /// <param name="mode">The new control mode.</param>
+    /// <param name="sendUpdate">True to send the new status over the CEC line.</param>
+    /// <returns>True if set, false otherwise.</returns>
+    bool SetDeckControlMode(CecDeckControlMode mode, bool sendUpdate)
+    {
+      return m_libCec->SetDeckControlMode((cec_deck_control_mode) mode, sendUpdate);
+    }
+
+    /// <summary>
+    /// Change the deck info, if this adapter is a playback or recording device.
+    /// </summary>
+    /// <param name="info">The new deck info.</param>
+    /// <param name="sendUpdate">True to send the new status over the CEC line.</param>
+    /// <returns>True if set, false otherwise.</returns>
+    bool SetDeckInfo(CecDeckInfo info, bool sendUpdate)
+    {
+      return m_libCec->SetDeckInfo((cec_deck_info) info, sendUpdate);
+    }
+
+    /// <summary>
+    /// Broadcast a message that notifies connected CEC capable devices that this device is no longer the active source.
+    /// </summary>
+    /// <returns>True when the command was sent succesfully, false otherwise.</returns>
+    bool SetInactiveView(void)
+    {
+      return m_libCec->SetInactiveView();
+    }
+
+    /// <summary>
+    /// Change the menu state. This value is already changed by libCEC automatically if a device is (de)activated.
+    /// </summary>
+    /// <param name="state">The new state.</param>
+    /// <param name="sendUpdate">True to send the new status over the CEC line.</param>
+    /// <returns>True if set, false otherwise.</returns>
+    bool SetMenuState(CecMenuState state, bool sendUpdate)
+    {
+      return m_libCec->SetMenuState((cec_menu_state) state, sendUpdate);
+    }
+
+    /// <summary>
+    /// Display a message on the device with the given logical address. Not supported by most TVs.
+    /// </summary>
+    /// <param name="logicalAddress">The logical address of the device to display the message on.</param>
+    /// <param name="duration">The duration of the message</param>
+    /// <param name="message">The message to display.</param>
+    /// <returns>True when the command was sent, false otherwise.</returns>
+    bool SetOSDString(CecLogicalAddress logicalAddress, CecDisplayControl duration, String ^ message)
+    {
+      marshal_context ^ context = gcnew marshal_context();
+      const char* strMessageC = context->marshal_as<const char*>(message);
+
+      bool bReturn = m_libCec->SetOSDString((cec_logical_address) logicalAddress, (cec_display_control) duration, strMessageC);
+
+      delete context;
+      return bReturn;
+    }
+
+    /// <summary>
+    /// Enable or disable monitoring mode, for debugging purposes. If monitoring mode is enabled, libCEC won't respond to any command, but only log incoming data.
+    /// </summary>
+    /// <param name="enable">True to enable, false to disable.</param>
+    /// <returns>True when switched successfully, false otherwise.</returns>
+    bool SwitchMonitoring(bool enable)
+    {
+      return m_libCec->SwitchMonitoring(enable);
+    }
+
+    /// <summary>
+    /// Get the CEC version of the device with the given logical address
+    /// </summary>
+    /// <param name="logicalAddress">The logical address of the device to get the CEC version for.</param>
+    /// <returns>The version or CEC_VERSION_UNKNOWN when the version couldn't be fetched.</returns>
+    CecVersion GetDeviceCecVersion(CecLogicalAddress logicalAddress)
+    {
+      return (CecVersion) m_libCec->GetDeviceCecVersion((cec_logical_address) logicalAddress);
+    }
+
+    /// <summary>
+    /// Get the menu language of the device with the given logical address
+    /// </summary>
+    /// <param name="logicalAddress">The logical address of the device to get the menu language for.</param>
+    /// <returns>The requested menu language.</returns>
+    String ^ GetDeviceMenuLanguage(CecLogicalAddress logicalAddress)
+    {
+      cec_menu_language lang;
+      if (m_libCec->GetDeviceMenuLanguage((cec_logical_address) logicalAddress, &lang))
+      {
+        return gcnew String(lang.language);
+      }
+
+      return gcnew String("");
+    }
+
+    /// <summary>
+    /// Get the vendor ID of the device with the given logical address.
+    /// </summary>
+    /// <param name="logicalAddress">The logical address of the device to get the vendor ID for.</param>
+    /// <returns>The vendor ID or 0 if it wasn't found.</returns>
+    CecVendorId GetDeviceVendorId(CecLogicalAddress logicalAddress)
+    {
+      return (CecVendorId)m_libCec->GetDeviceVendorId((cec_logical_address) logicalAddress);
+    }
+
+    /// <summary>
+    /// Get the power status of the device with the given logical address.
+    /// </summary>
+    /// <param name="logicalAddress">The logical address of the device to get the power status for.</param>
+    /// <returns>The power status or CEC_POWER_STATUS_UNKNOWN if it wasn't found.</returns>
+    CecPowerStatus GetDevicePowerStatus(CecLogicalAddress logicalAddress)
+    {
+      return (CecPowerStatus) m_libCec->GetDevicePowerStatus((cec_logical_address) logicalAddress);
+    }
+
+    /// <summary>
+    /// Tell libCEC to poll for active devices on the bus.
+    /// </summary>
+    void RescanActiveDevices(void)
+    {
+      m_libCec->RescanActiveDevices();
+    }
+
+    /// <summary>
+    /// Get the logical addresses of the devices that are active on the bus, including those handled by libCEC.
+    /// </summary>
+    /// <returns>The logical addresses of the active devices</returns>
+    CecLogicalAddresses ^ GetActiveDevices(void)
+    {
+      CecLogicalAddresses ^ retVal = gcnew CecLogicalAddresses();
+      unsigned int iDevices = 0;
+
+      cec_logical_addresses activeDevices = m_libCec->GetActiveDevices();
+
+      for (uint8_t iPtr = 0; iPtr < 16; iPtr++)
+        if (activeDevices[iPtr])
+          retVal->Addresses[iDevices++] = (CecLogicalAddress)iPtr;
+
+      return retVal;
+    }
+
+    /// <summary>
+    /// Check whether a device is active on the bus.
+    /// </summary>
+    /// <param name="logicalAddress">The address to check.</param>
+    /// <returns>True when active, false otherwise.</returns>
+    bool IsActiveDevice(CecLogicalAddress logicalAddress)
+    {
+      return m_libCec->IsActiveDevice((cec_logical_address)logicalAddress);
+    }
+
+    /// <summary>
+    /// Check whether a device of the given type is active on the bus.
+    /// </summary>
+    /// <param name="type">The type to check.</param>
+    /// <returns>True when active, false otherwise.</returns>
+    bool IsActiveDeviceType(CecDeviceType type)
+    {
+      return m_libCec->IsActiveDeviceType((cec_device_type)type);
+    }
+
+    /// <summary>
+    /// Changes the active HDMI port.
+    /// </summary>
+    /// <param name="address">The device to which this libCEC is connected.</param>
+    /// <param name="port">The new port number.</param>
+    /// <returns>True when changed, false otherwise.</returns>
+    bool SetHDMIPort(CecLogicalAddress address, uint8_t port)
+    {
+      return m_libCec->SetHDMIPort((cec_logical_address)address, port);
+    }
+
+    /// <summary>
+    /// Sends a volume up keypress to an audiosystem if it's present.
+    /// </summary>
+    /// <param name="sendRelease">Send a key release after the keypress.</param>
+    /// <returns>The new audio status.</returns>
+    uint8_t VolumeUp(bool sendRelease)
+    {
+      return m_libCec->VolumeUp(sendRelease);
+    }
+
+    /// <summary>
+    /// Sends a volume down keypress to an audiosystem if it's present.
+    /// </summary>
+    /// <param name="sendRelease">Send a key release after the keypress.</param>
+    /// <returns>The new audio status.</returns>
+    uint8_t VolumeDown(bool sendRelease)
+    {
+      return m_libCec->VolumeDown(sendRelease);
+    }
 
+    /// <summary>
+    /// Sends a mute keypress to an audiosystem if it's present.
+    /// </summary>
+    /// <param name="sendRelease">Send a key release after the keypress.</param>
+    /// <returns>The new audio status.</returns>
+    uint8_t MuteAudio(bool sendRelease)
+    {
+      return m_libCec->MuteAudio(sendRelease);
+    }
+
+    /// <summary>
+    /// Send a keypress to a device on the CEC bus.
+    /// </summary>
+    /// <param name="destination">The logical address of the device to send the message to.</param>
+    /// <param name="key">The key to send.</param>
+    /// <param name="wait">True to wait for a response, false otherwise.</param>
+    /// <returns>True when the keypress was acked, false otherwise.</returns>
+    bool SendKeypress(CecLogicalAddress destination, CecUserControlCode key, bool wait)
+    {
+      return m_libCec->SendKeypress((cec_logical_address)destination, (cec_user_control_code)key, wait);
+    }
+
+    /// <summary>
+    /// Send a key release to a device on the CEC bus.
+    /// </summary>
+    /// <param name="destination">The logical address of the device to send the message to.</param>
+    /// <param name="wait">True to wait for a response, false otherwise.</param>
+    /// <returns>True when the key release was acked, false otherwise.</returns>
+    bool SendKeyRelease(CecLogicalAddress destination, bool wait)
+    {
+      return m_libCec->SendKeyRelease((cec_logical_address)destination, wait);
+    }
+
+    /// <summary>
+    /// Get the OSD name of a device on the CEC bus.
+    /// </summary>
+    /// <param name="logicalAddress">The logical address of the device to get the OSD name for.</param>
+    /// <returns>The OSD name.</returns>
+    String ^ GetDeviceOSDName(CecLogicalAddress logicalAddress)
+    {
+      cec_osd_name osd = m_libCec->GetDeviceOSDName((cec_logical_address) logicalAddress);
+      return gcnew String(osd.name);
+    }
+
+    /// <summary>
+    /// Get the logical address of the device that is currently the active source on the CEC bus.
+    /// </summary>
+    /// <returns>The active source or CECDEVICE_UNKNOWN when unknown.</returns>
+    CecLogicalAddress GetActiveSource()
+    {
+      return (CecLogicalAddress)m_libCec->GetActiveSource();
+    }
+
+    /// <summary>
+    /// Check whether a device is currently the active source on the CEC bus.
+    /// </summary>
+    /// <param name="logicalAddress">The logical address of the device to check.</param>
+    /// <returns>True when it is the active source, false otherwise.</returns>
+    bool IsActiveSource(CecLogicalAddress logicalAddress)
+    {
+      return m_libCec->IsActiveSource((cec_logical_address)logicalAddress);
+    }
+
+    /// <summary>
+    /// Get the physical address of the device with the given logical address.
+    /// </summary>
+    /// <param name="address">The logical address of the device to get the physical address for.</param>
+    /// <returns>The physical address or 0 if it wasn't found.</returns>
+    uint16_t GetDevicePhysicalAddress(CecLogicalAddress address)
+    {
+      return m_libCec->GetDevicePhysicalAddress((cec_logical_address)address);
+    }
+
+    /// <summary>
+    /// Sets the stream path to the device on the given logical address.
+    /// </summary>
+    /// <param name="address">The address to activate.</param>
+    /// <returns>True when the command was sent, false otherwise.</returns>
+    bool SetStreamPath(CecLogicalAddress address)
+    {
+      return m_libCec->SetStreamPath((cec_logical_address)address);
+    }
+
+    /// <summary>
+    /// Sets the stream path to the device on the given physical address.
+    /// </summary>
+    /// <param name="physicalAddress">The address to activate.</param>
+    /// <returns>True when the command was sent, false otherwise.</returns>
+    bool SetStreamPath(uint16_t physicalAddress)
+    {
+      return m_libCec->SetStreamPath(physicalAddress);
+    }
+
+    /// <summary>
+    /// Get the list of logical addresses that libCEC is controlling
+    /// </summary>
+    /// <returns>The list of logical addresses that libCEC is controlling</returns>
+    CecLogicalAddresses ^GetLogicalAddresses(void)
+    {
+      CecLogicalAddresses ^addr = gcnew CecLogicalAddresses();
+      cec_logical_addresses libAddr = m_libCec->GetLogicalAddresses();
+      for (unsigned int iPtr = 0; iPtr < 16; iPtr++)
+        addr->Addresses[iPtr] = (CecLogicalAddress)libAddr.addresses[iPtr];
+      addr->Primary = (CecLogicalAddress)libAddr.primary;
+      return addr;
+    }
+
+    /// <summary>
+    /// Get libCEC's current configuration.
+    /// </summary>
+    /// <param name="configuration">The configuration.</param>
+    /// <returns>True when the configuration was updated, false otherwise.</returns>
+    bool GetCurrentConfiguration(LibCECConfiguration ^configuration)
+    {
+      libcec_configuration config;
+      config.Clear();
+
+      if (m_libCec->GetCurrentConfiguration(&config))
+      {
+        configuration->Update(config);
+        return true;
+      }
+      return false;
+    }
+
+    /// <summary>
+    /// Check whether the CEC adapter can persist a configuration.
+    /// </summary>
+    /// <returns>True when this CEC adapter can persist the user configuration, false otherwise.</returns>
     bool CanPersistConfiguration(void)
-               {
-                       return m_libCec->CanPersistConfiguration();
-               }
+    {
+      return m_libCec->CanPersistConfiguration();
+    }
 
+    /// <summary>
+    /// Persist the given configuration in adapter (if supported)
+    /// </summary>
+    /// <param name="configuration">The configuration to store.</param>
+    /// <returns>True when the configuration was persisted, false otherwise.</returns>
     bool PersistConfiguration(LibCECConfiguration ^configuration)
-               {
-                       marshal_context ^ context = gcnew marshal_context();
-                       libcec_configuration config;
-                       ConvertConfiguration(context, configuration, config);
+    {
+      marshal_context ^ context = gcnew marshal_context();
+      libcec_configuration config;
+      ConvertConfiguration(context, configuration, config);
 
-                       bool bReturn = m_libCec->PersistConfiguration(&config);
+      bool bReturn = m_libCec->PersistConfiguration(&config);
 
-                       delete context;
-                       return bReturn;
-               }
+      delete context;
+      return bReturn;
+    }
 
-               bool SetConfiguration(LibCECConfiguration ^configuration)
-               {
-                       marshal_context ^ context = gcnew marshal_context();
-                       libcec_configuration config;
-                       ConvertConfiguration(context, configuration, config);
+    /// <summary>
+    /// Change libCEC's configuration.
+    /// </summary>
+    /// <param name="configuration">The new configuration.</param>
+    /// <returns>True when the configuration was changed successfully, false otherwise.</returns>
+    bool SetConfiguration(LibCECConfiguration ^configuration)
+    {
+      marshal_context ^ context = gcnew marshal_context();
+      libcec_configuration config;
+      ConvertConfiguration(context, configuration, config);
 
-                       bool bReturn = m_libCec->SetConfiguration(&config);
+      bool bReturn = m_libCec->SetConfiguration(&config);
 
-                       delete context;
-                       return bReturn;
-               }
+      delete context;
+      return bReturn;
+    }
 
+    /// <summary>
+    /// Check whether libCEC is the active source on the bus.
+    /// </summary>
+    /// <returns>True when libCEC is the active source on the bus, false otherwise.</returns>
     bool IsLibCECActiveSource()
     {
       return m_libCec->IsLibCECActiveSource();
     }
 
+    /// <summary>
+    /// Get information about the given CEC adapter.
+    /// </summary>
+    /// <param name="port">The COM port to which the device is connected</param>
+    /// <param name="configuration">The device configuration</param>
+    /// <param name="timeoutMs">The timeout in milliseconds</param>
+    /// <returns>True when the device was found, false otherwise</returns>
     bool GetDeviceInformation(String ^ port, LibCECConfiguration ^configuration, uint32_t timeoutMs)
     {
       bool bReturn(false);
       marshal_context ^ context = gcnew marshal_context();
 
       libcec_configuration config;
-                       config.Clear();
+      config.Clear();
 
       const char* strPortC = port->Length > 0 ? context->marshal_as<const char*>(port) : NULL;
 
       if (m_libCec->GetDeviceInformation(strPortC, &config, timeoutMs))
-                       {
-                               configuration->Update(config);
+      {
+        configuration->Update(config);
         bReturn = true;
-                       }
+      }
 
       delete context;
       return bReturn;
     }
 
-               String ^ ToString(CecLogicalAddress iAddress)
-               {
-                       const char *retVal = m_libCec->ToString((cec_logical_address)iAddress);
-                       return gcnew String(retVal);
-               }
-
-               String ^ ToString(CecVendorId iVendorId)
-               {
-                       const char *retVal = m_libCec->ToString((cec_vendor_id)iVendorId);
-                       return gcnew String(retVal);
-               }
-         
-               String ^ ToString(CecVersion iVersion)
-               {
-                       const char *retVal = m_libCec->ToString((cec_version)iVersion);
-                       return gcnew String(retVal);
-               }
-         
-               String ^ ToString(CecPowerStatus iState)
-               {
-                       const char *retVal = m_libCec->ToString((cec_power_status)iState);
-                       return gcnew String(retVal);
-               }
-
-               String ^ ToString(CecMenuState iState)
-               {
-                       const char *retVal = m_libCec->ToString((cec_menu_state)iState);
-                       return gcnew String(retVal);
-               }
-
-               String ^ ToString(CecDeckControlMode iMode)
-               {
-                       const char *retVal = m_libCec->ToString((cec_deck_control_mode)iMode);
-                       return gcnew String(retVal);
-               }
-
-               String ^ ToString(CecDeckInfo status)
-               {
-                       const char *retVal = m_libCec->ToString((cec_deck_info)status);
-                       return gcnew String(retVal);
-               }
-
-               String ^ ToString(CecOpcode opcode)
-               {
-                       const char *retVal = m_libCec->ToString((cec_opcode)opcode);
-                       return gcnew String(retVal);
-               }
-
-               String ^ ToString(CecSystemAudioStatus mode)
-               {
-                       const char *retVal = m_libCec->ToString((cec_system_audio_status)mode);
-                       return gcnew String(retVal);
-               }
-
-               String ^ ToString(CecAudioStatus status)
-               {
-                       const char *retVal = m_libCec->ToString((cec_audio_status)status);
-                       return gcnew String(retVal);
-               }
-
-               String ^ ToString(CecClientVersion version)
-               {
-                       const char *retVal = m_libCec->ToString((cec_client_version)version);
-                       return gcnew String(retVal);
-               }
-
-               String ^ ToString(CecServerVersion version)
-               {
-                       const char *retVal = m_libCec->ToString((cec_server_version)version);
-                       return gcnew String(retVal);
-               }
-
-               String ^ GetLibInfo()
-               {
-                       const char *retVal = m_libCec->GetLibInfo();
-                       return gcnew String(retVal);
-               }
-
-               void InitVideoStandalone()
-               {
-                       m_libCec->InitVideoStandalone();
-               }
-
-       private:
-               ICECAdapter *        m_libCec;
+    String ^ ToString(CecLogicalAddress iAddress)
+    {
+      const char *retVal = m_libCec->ToString((cec_logical_address)iAddress);
+      return gcnew String(retVal);
+    }
+
+    String ^ ToString(CecVendorId iVendorId)
+    {
+      const char *retVal = m_libCec->ToString((cec_vendor_id)iVendorId);
+      return gcnew String(retVal);
+    }
+
+    String ^ ToString(CecVersion iVersion)
+    {
+      const char *retVal = m_libCec->ToString((cec_version)iVersion);
+      return gcnew String(retVal);
+    }
+
+    String ^ ToString(CecPowerStatus iState)
+    {
+      const char *retVal = m_libCec->ToString((cec_power_status)iState);
+      return gcnew String(retVal);
+    }
+
+    String ^ ToString(CecMenuState iState)
+    {
+      const char *retVal = m_libCec->ToString((cec_menu_state)iState);
+      return gcnew String(retVal);
+    }
+
+    String ^ ToString(CecDeckControlMode iMode)
+    {
+      const char *retVal = m_libCec->ToString((cec_deck_control_mode)iMode);
+      return gcnew String(retVal);
+    }
+
+    String ^ ToString(CecDeckInfo status)
+    {
+      const char *retVal = m_libCec->ToString((cec_deck_info)status);
+      return gcnew String(retVal);
+    }
+
+    String ^ ToString(CecOpcode opcode)
+    {
+      const char *retVal = m_libCec->ToString((cec_opcode)opcode);
+      return gcnew String(retVal);
+    }
+
+    String ^ ToString(CecSystemAudioStatus mode)
+    {
+      const char *retVal = m_libCec->ToString((cec_system_audio_status)mode);
+      return gcnew String(retVal);
+    }
+
+    String ^ ToString(CecAudioStatus status)
+    {
+      const char *retVal = m_libCec->ToString((cec_audio_status)status);
+      return gcnew String(retVal);
+    }
+
+    String ^ ToString(CecClientVersion version)
+    {
+      const char *retVal = m_libCec->ToString((cec_client_version)version);
+      return gcnew String(retVal);
+    }
+
+    String ^ ToString(CecServerVersion version)
+    {
+      const char *retVal = m_libCec->ToString((cec_server_version)version);
+      return gcnew String(retVal);
+    }
+
+    /// <summary>
+    /// Get a string with information about how libCEC was compiled.
+    /// </summary>
+    /// <returns>A string with information about how libCEC was compiled.</returns>
+    String ^ GetLibInfo()
+    {
+      const char *retVal = m_libCec->GetLibInfo();
+      return gcnew String(retVal);
+    }
+
+    /// <summary>
+    /// Calling this method will initialise the host on which libCEC is running.
+    /// On the RPi, it calls bcm_host_init(), which may only be called once per process, and is called by any process using
+    /// the video api on that system. So only call this method if libCEC is used in an application that
+    /// does not already initialise the video api.
+    /// </summary>
+    /// <remarks>Should be called as first call to libCEC, directly after CECInitialise() and before using Open()</remarks>
+    void InitVideoStandalone()
+    {
+      m_libCec->InitVideoStandalone();
+    }
+
+    /// <summary>
+    /// Get the (virtual) USB vendor id
+    /// </summary>
+    /// <returns>The (virtual) USB vendor id</returns>
+    uint16_t GetAdapterVendorId()
+    {
+      return m_libCec->GetAdapterVendorId();
+    }
+
+    /// <summary>
+    /// Get the (virtual) USB product id
+    /// </summary>
+    /// <returns>The (virtual) USB product id</returns>
+    uint16_t GetAdapterProductId()
+    {
+      return m_libCec->GetAdapterProductId();
+    }
+
+  private:
+    !LibCecSharp(void)
+    {
+      Close();
+      m_libCec = NULL;
+    }
+
+    bool InitialiseLibCec(LibCECConfiguration ^config)
+    {
+      marshal_context ^ context = gcnew marshal_context();
+      libcec_configuration libCecConfig;
+      ConvertConfiguration(context, config, libCecConfig);
+
+      m_libCec = (ICECAdapter *) CECInitialise(&libCecConfig);
+      config->Update(libCecConfig);
+
+      delete context;
+      return m_libCec != NULL;
+    }
+
+    void ConvertConfiguration(marshal_context ^context, LibCECConfiguration ^netConfig, CEC::libcec_configuration &config)
+    {
+      config.Clear();
+
+      const char *strDeviceName = context->marshal_as<const char*>(netConfig->DeviceName);
+      memcpy_s(config.strDeviceName, 13, strDeviceName, 13);
+      for (unsigned int iPtr = 0; iPtr < 5; iPtr++)
+        config.deviceTypes.types[iPtr] = (cec_device_type)netConfig->DeviceTypes->Types[iPtr];
+
+      config.bAutodetectAddress   = netConfig->AutodetectAddress ? 1 : 0;
+      config.iPhysicalAddress     = netConfig->PhysicalAddress;
+      config.baseDevice           = (cec_logical_address)netConfig->BaseDevice;
+      config.iHDMIPort            = netConfig->HDMIPort;
+      config.clientVersion        = (cec_client_version)netConfig->ClientVersion;
+      config.bGetSettingsFromROM  = netConfig->GetSettingsFromROM ? 1 : 0;
+      config.bActivateSource      = netConfig->ActivateSource ? 1 : 0;
+      config.tvVendor             = (cec_vendor_id)netConfig->TvVendor;
+      config.wakeDevices.Clear();
+      for (int iPtr = 0; iPtr < 16; iPtr++)
+      {
+        if (netConfig->WakeDevices->IsSet((CecLogicalAddress)iPtr))
+          config.wakeDevices.Set((cec_logical_address)iPtr);
+      }
+      config.powerOffDevices.Clear();
+      for (int iPtr = 0; iPtr < 16; iPtr++)
+      {
+        if (netConfig->PowerOffDevices->IsSet((CecLogicalAddress)iPtr))
+          config.powerOffDevices.Set((cec_logical_address)iPtr);
+      }
+      config.bPowerOffScreensaver = netConfig->PowerOffScreensaver ? 1 : 0;
+      config.bPowerOffOnStandby   = netConfig->PowerOffOnStandby ? 1 : 0;
+
+      if (netConfig->ServerVersion >= CecServerVersion::Version1_5_1)
+        config.bSendInactiveSource  = netConfig->SendInactiveSource ? 1 : 0;
+
+      if (netConfig->ServerVersion >= CecServerVersion::Version1_6_0)
+      {
+        config.bPowerOffDevicesOnStandby  = netConfig->PowerOffDevicesOnStandby ? 1 : 0;
+        config.bShutdownOnStandby         = netConfig->ShutdownOnStandby ? 1 : 0;
+      }
+
+      if (netConfig->ServerVersion >= CecServerVersion::Version1_6_2)
+      {
+        const char *strDeviceLanguage = context->marshal_as<const char*>(netConfig->DeviceLanguage);
+        memcpy_s(config.strDeviceLanguage, 3, strDeviceLanguage, 3);
+      }
+
+      if (netConfig->ServerVersion >= CecServerVersion::Version1_6_3)
+        config.bMonitorOnly = netConfig->MonitorOnlyClient ? 1 : 0;
+
+      if (netConfig->ServerVersion >= CecServerVersion::Version1_8_0)
+        config.cecVersion = (cec_version)netConfig->CECVersion;
+
+      config.callbacks = &g_cecCallbacks;
+    }
+
+
+    ICECAdapter *        m_libCec;
     CecCallbackMethods ^ m_callbacks;
-       };
+  };
 }
diff --git a/src/LibCecTray/.gitignore b/src/LibCecTray/.gitignore
new file mode 100644 (file)
index 0000000..bcfdf01
--- /dev/null
@@ -0,0 +1,6 @@
+/build
+/obj
+/support/private
+/project/_ReSharper.LibCECTray
+
+*.user
\ No newline at end of file
diff --git a/src/LibCecTray/LibCECTray.csproj b/src/LibCecTray/LibCECTray.csproj
new file mode 100644 (file)
index 0000000..430ae9c
--- /dev/null
@@ -0,0 +1,235 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>..\..\build\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
+    <OutputPath>..\..\build\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>..\..\build\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <OutputPath>..\..\build\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <UseVSHostingProcess>false</UseVSHostingProcess>
+  </PropertyGroup>
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.21022</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{58C106FE-C159-46D3-97E1-73AB83232670}</ProjectGuid>
+    <OutputType>WinExe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>LibCECTray</RootNamespace>
+    <AssemblyName>cec-tray</AssemblyName>
+    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <SignAssembly>false</SignAssembly>
+    <PublishUrl>publish\</PublishUrl>
+    <Install>true</Install>
+    <InstallFrom>Disk</InstallFrom>
+    <UpdateEnabled>false</UpdateEnabled>
+    <UpdateMode>Foreground</UpdateMode>
+    <UpdateInterval>7</UpdateInterval>
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+    <UpdatePeriodically>false</UpdatePeriodically>
+    <UpdateRequired>false</UpdateRequired>
+    <MapFileExtensions>true</MapFileExtensions>
+    <ApplicationRevision>0</ApplicationRevision>
+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+    <IsWebBootstrapper>false</IsWebBootstrapper>
+    <UseApplicationTrust>false</UseApplicationTrust>
+    <BootstrapperEnabled>true</BootstrapperEnabled>
+    <ApplicationIcon>..\..\project\favicon.ico</ApplicationIcon>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Deployment" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="controller\Actions.cs" />
+    <Compile Include="controller\actions\GetCurrentPhysicalAddress.cs" />
+    <Compile Include="controller\actions\UpdateConfiguration.cs" />
+    <Compile Include="controller\actions\ConnectToDevice.cs" />
+    <Compile Include="controller\actions\RescanDevices.cs" />
+    <Compile Include="controller\actions\SendActivateSource.cs" />
+    <Compile Include="controller\actions\SendImageViewOn.cs" />
+    <Compile Include="controller\actions\SendStandby.cs" />
+    <Compile Include="controller\actions\ShowDeviceInfo.cs" />
+    <Compile Include="controller\actions\UpdateConnectedDevice.cs" />
+    <Compile Include="controller\actions\UpdateDeviceInfo.cs" />
+    <Compile Include="controller\actions\UpdatePhysicalAddress.cs" />
+    <Compile Include="controller\applications\ApplicationController.cs" />
+    <Compile Include="controller\applications\ApplicationControllerUI.cs">
+      <SubType>Component</SubType>
+    </Compile>
+    <Compile Include="controller\applications\ApplicationControllerUI.Designer.cs">
+      <DependentUpon>ApplicationControllerUI.cs</DependentUpon>
+    </Compile>
+    <Compile Include="controller\applications\ApplicationInput.cs" />
+    <Compile Include="controller\applications\Applications.cs" />
+    <Compile Include="controller\applications\CecButtonConfig.cs" />
+    <Compile Include="controller\applications\CecButtonConfigUI.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="controller\applications\CecButtonConfigUI.Designer.cs">
+      <DependentUpon>CecButtonConfigUI.cs</DependentUpon>
+    </Compile>
+    <Compile Include="controller\applications\ConfigureApplication.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="controller\applications\ConfigureApplication.Designer.cs">
+      <DependentUpon>ConfigureApplication.cs</DependentUpon>
+    </Compile>
+    <Compile Include="controller\applications\IControllerTabPage.cs">
+      <SubType>Component</SubType>
+    </Compile>
+    <Compile Include="controller\applications\internal\XBMCController.cs" />
+    <Compile Include="controller\applications\internal\XBMCControllerUI.cs">
+      <SubType>Component</SubType>
+    </Compile>
+    <Compile Include="controller\applications\internal\XBMCControllerUI.Designer.cs">
+      <DependentUpon>XBMCControllerUI.cs</DependentUpon>
+    </Compile>
+    <Compile Include="controller\CECController.cs" />
+    <Compile Include="settings\CECSettingBool.cs" />
+    <Compile Include="settings\CECSettingByte.cs" />
+    <Compile Include="settings\CECSettingDeviceType.cs" />
+    <Compile Include="settings\CECSettingLogicalAddress.cs" />
+    <Compile Include="settings\CECSettingLogicalAddresses.cs" />
+    <Compile Include="settings\CECSettingNumeric.cs" />
+    <Compile Include="settings\CECSettingString.cs" />
+    <Compile Include="settings\CECSettingUShort.cs" />
+    <Compile Include="settings\CECSettingVendorId.cs" />
+    <Compile Include="ui\About.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="ui\About.Designer.cs">
+      <DependentUpon>About.cs</DependentUpon>
+    </Compile>
+    <Compile Include="ui\AsyncForm.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="settings\CECSetting.cs" />
+    <Compile Include="settings\CECSettings.cs" />
+    <Compile Include="ui\CECTray.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="ui\CECTray.Designer.cs">
+      <DependentUpon>CECTray.cs</DependentUpon>
+    </Compile>
+    <Compile Include="ui\DeviceInformation.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="ui\DeviceInformation.Designer.cs">
+      <DependentUpon>DeviceInformation.cs</DependentUpon>
+    </Compile>
+    <Compile Include="controller\applications\KeyInput.cs" />
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <EmbeddedResource Include="controller\applications\ApplicationControllerUI.resx">
+      <DependentUpon>ApplicationControllerUI.cs</DependentUpon>
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
+    <EmbeddedResource Include="controller\applications\CecButtonConfigUI.resx">
+      <DependentUpon>CecButtonConfigUI.cs</DependentUpon>
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
+    <EmbeddedResource Include="controller\applications\ConfigureApplication.resx">
+      <DependentUpon>ConfigureApplication.cs</DependentUpon>
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
+    <EmbeddedResource Include="controller\applications\internal\XBMCControllerUI.resx">
+      <DependentUpon>XBMCControllerUI.cs</DependentUpon>
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
+    <EmbeddedResource Include="ui\About.resx">
+      <DependentUpon>About.cs</DependentUpon>
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
+    <EmbeddedResource Include="ui\CECTray.resx">
+      <DependentUpon>CECTray.cs</DependentUpon>
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
+    <EmbeddedResource Include="ui\DeviceInformation.resx">
+      <DependentUpon>DeviceInformation.cs</DependentUpon>
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
+    <EmbeddedResource Include="Properties\Resources.resx">
+      <Generator>ResXFileCodeGenerator</Generator>
+      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
+    <Compile Include="Properties\Resources.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DependentUpon>Resources.resx</DependentUpon>
+      <DesignTime>True</DesignTime>
+    </Compile>
+    <Compile Include="controller\actions\UpdateEvent.cs" />
+    <Compile Include="controller\applications\WindowsAPI.cs" />
+    <Compile Include="controller\applications\internal\WMCController.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 2.0 %28x86%29</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.0">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.0 %28x86%29</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="project\favicon.ico" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\project\LibCecSharp.vcproj">
+      <Project>{E54D4581-CD59-4687-BB10-694B8192EABA}</Project>
+      <Name>LibCecSharp</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+  <PropertyGroup>
+    <PostBuildEvent>
+    </PostBuildEvent>
+  </PropertyGroup>
+</Project>
\ No newline at end of file
diff --git a/src/LibCecTray/Program.cs b/src/LibCecTray/Program.cs
new file mode 100644 (file)
index 0000000..c0a6a3a
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing       <license@pulse-eight.com>
+ *     http://www.pulse-eight.com/
+ *     http://www.pulse-eight.net/
+ */
+
+using System;
+using System.Windows.Forms;
+using LibCECTray.controller.applications;
+using LibCECTray.ui;
+
+namespace LibCECTray
+{
+  static class Program
+  {
+    private static CECTray _instance;
+    public static CECTray Instance
+    {
+      get { return _instance ?? (_instance = new CECTray()); }
+    }
+
+    [STAThread]
+    static void Main()
+    {
+      var instance = WindowsAPI.RunningInstance();
+      if (instance == null)
+      {
+        Application.EnableVisualStyles();
+        Application.SetCompatibleTextRenderingDefault(false);
+        Application.Run(Instance);
+      }
+      else
+      {
+        WindowsAPI.ShowWindowAsync(instance.MainWindowHandle, (int)WindowsAPI.ShowType.ShowNormal);
+        WindowsAPI.SetForegroundWindow(instance.MainWindowHandle);
+      }
+    }
+  }
+}
similarity index 81%
rename from src/cec-config-gui/Properties/AssemblyInfo.cs
rename to src/LibCecTray/Properties/AssemblyInfo.cs
index 891de3eaa0f3b242a3797f26ec833fcbf6d20697..8c25663917ba4dd7d6066cb856ef9a6516d05105 100644 (file)
@@ -1,15 +1,14 @@
 ï»¿using System.Reflection;
-using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 
 // General Information about an assembly is controlled through the following 
 // set of attributes. Change these attribute values to modify the information
 // associated with an assembly.
-[assembly: AssemblyTitle("cec-config-gui")]
+[assembly: AssemblyTitle("CECTray")]
 [assembly: AssemblyDescription("")]
 [assembly: AssemblyConfiguration("")]
 [assembly: AssemblyCompany("Pulse-Eight Ltd.")]
-[assembly: AssemblyProduct("cec-config-gui")]
+[assembly: AssemblyProduct("libCEC Tray")]
 [assembly: AssemblyCopyright("Copyright (c) Pulse-Eight Ltd. 2011-2012")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]
@@ -20,7 +19,7 @@ using System.Runtime.InteropServices;
 [assembly: ComVisible(false)]
 
 // The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("acfc1f63-3e6c-45ca-9296-9fbf8541b4ae")]
+[assembly: Guid("F9987167-85D8-4b3b-949A-A4F89EA1C01C")]
 
 // Version information for an assembly consists of the following four values:
 //
@@ -32,5 +31,5 @@ using System.Runtime.InteropServices;
 // You can specify all the values or you can default the Build and Revision Numbers 
 // by using the '*' as shown below:
 // [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.9.0.0")]
-[assembly: AssemblyFileVersion("1.9.0.0")]
+[assembly: AssemblyVersion("1.7.2.0")]
+[assembly: AssemblyFileVersion("1.7.2.0")]
diff --git a/src/LibCecTray/Properties/Resources.Designer.cs b/src/LibCecTray/Properties/Resources.Designer.cs
new file mode 100644 (file)
index 0000000..0285bd3
--- /dev/null
@@ -0,0 +1,1494 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:2.0.50727.5448
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace LibCECTray.Properties {
+    using System;
+    
+    
+    /// <summary>
+    ///   A strongly-typed resource class, for looking up localized strings, etc.
+    /// </summary>
+    // This class was auto-generated by the StronglyTypedResourceBuilder
+    // class via a tool like ResGen or Visual Studio.
+    // To add or remove a member, edit your .ResX file then rerun ResGen
+    // with the /str option, or rebuild your VS project.
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")]
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    internal class Resources {
+        
+        private static global::System.Resources.ResourceManager resourceMan;
+        
+        private static global::System.Globalization.CultureInfo resourceCulture;
+        
+        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal Resources() {
+        }
+        
+        /// <summary>
+        ///   Returns the cached ResourceManager instance used by this class.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Resources.ResourceManager ResourceManager {
+            get {
+                if (object.ReferenceEquals(resourceMan, null)) {
+                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("LibCECTray.Properties.Resources", typeof(Resources).Assembly);
+                    resourceMan = temp;
+                }
+                return resourceMan;
+            }
+        }
+        
+        /// <summary>
+        ///   Overrides the current thread's CurrentUICulture property for all
+        ///   resource lookups using this strongly typed resource class.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Globalization.CultureInfo Culture {
+            get {
+                return resourceCulture;
+            }
+            set {
+                resourceCulture = value;
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to libCEC v{0} - client v{1}.
+        /// </summary>
+        internal static string about_libcec_version {
+            get {
+                return ResourceManager.GetString("about_libcec_version", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Activating the source.
+        /// </summary>
+        internal static string action_activating_source {
+            get {
+                return ResourceManager.GetString("action_activating_source", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Checking if {0} is present.
+        /// </summary>
+        internal static string action_check_device_present {
+            get {
+                return ResourceManager.GetString("action_check_device_present", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Detecting AVR device.
+        /// </summary>
+        internal static string action_detecting_avr {
+            get {
+                return ResourceManager.GetString("action_detecting_avr", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Detecting AVR vendor.
+        /// </summary>
+        internal static string action_detecting_avr_vendor {
+            get {
+                return ResourceManager.GetString("action_detecting_avr_vendor", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Detecting TV vendor.
+        /// </summary>
+        internal static string action_detecting_tv_vendor {
+            get {
+                return ResourceManager.GetString("action_detecting_tv_vendor", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Opening connection.
+        /// </summary>
+        internal static string action_opening_connection {
+            get {
+                return ResourceManager.GetString("action_opening_connection", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Polling active devices.
+        /// </summary>
+        internal static string action_polling_active_devices {
+            get {
+                return ResourceManager.GetString("action_polling_active_devices", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Reading device configuration.
+        /// </summary>
+        internal static string action_reading_device_configuration {
+            get {
+                return ResourceManager.GetString("action_reading_device_configuration", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Refreshing device list.
+        /// </summary>
+        internal static string action_refreshing_device_list {
+            get {
+                return ResourceManager.GetString("action_refreshing_device_list", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Requesting active source state.
+        /// </summary>
+        internal static string action_requesting_active_source_state {
+            get {
+                return ResourceManager.GetString("action_requesting_active_source_state", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Requesting CEC version.
+        /// </summary>
+        internal static string action_requesting_cec_version {
+            get {
+                return ResourceManager.GetString("action_requesting_cec_version", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Requesting menu language.
+        /// </summary>
+        internal static string action_requesting_menu_language {
+            get {
+                return ResourceManager.GetString("action_requesting_menu_language", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Requesting OSD name.
+        /// </summary>
+        internal static string action_requesting_osd_name {
+            get {
+                return ResourceManager.GetString("action_requesting_osd_name", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Requesting physical address.
+        /// </summary>
+        internal static string action_requesting_physical_address {
+            get {
+                return ResourceManager.GetString("action_requesting_physical_address", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Requesting power status.
+        /// </summary>
+        internal static string action_requesting_power_status {
+            get {
+                return ResourceManager.GetString("action_requesting_power_status", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Requesting the vendor ID.
+        /// </summary>
+        internal static string action_requesting_vendor_id {
+            get {
+                return ResourceManager.GetString("action_requesting_vendor_id", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Sending the &apos;{0}&apos; command to {1}.
+        /// </summary>
+        internal static string action_sending_command_to {
+            get {
+                return ResourceManager.GetString("action_sending_command_to", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Sending power on commands.
+        /// </summary>
+        internal static string action_sending_power_on {
+            get {
+                return ResourceManager.GetString("action_sending_power_on", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Setting the new configuration.
+        /// </summary>
+        internal static string action_setting_new_libcec_configuration {
+            get {
+                return ResourceManager.GetString("action_setting_new_libcec_configuration", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Showing device information.
+        /// </summary>
+        internal static string action_showing_device_information {
+            get {
+                return ResourceManager.GetString("action_showing_device_information", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to close CECTray.
+        /// </summary>
+        internal static string action_type_close_controller_application {
+            get {
+                return ResourceManager.GetString("action_type_close_controller_application", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to generic.
+        /// </summary>
+        internal static string action_type_generic {
+            get {
+                return ResourceManager.GetString("action_type_generic", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to send key.
+        /// </summary>
+        internal static string action_type_sendkey {
+            get {
+                return ResourceManager.GetString("action_type_sendkey", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to start application.
+        /// </summary>
+        internal static string action_type_start_application {
+            get {
+                return ResourceManager.GetString("action_type_start_application", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Add new application.
+        /// </summary>
+        internal static string add_new_application {
+            get {
+                return ResourceManager.GetString("add_new_application", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Send &apos;inactive source&apos; when shutting down the application.
+        /// </summary>
+        internal static string app_inactive_source {
+            get {
+                return ResourceManager.GetString("app_inactive_source", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Pulse-Eight USB-CEC Adapter - libCECTray BETA3.
+        /// </summary>
+        internal static string app_name {
+            get {
+                return ResourceManager.GetString("app_name", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Pause playback when switching to another source.
+        /// </summary>
+        internal static string app_pause_playback_on_deactivate {
+            get {
+                return ResourceManager.GetString("app_pause_playback_on_deactivate", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Send inactive source message when stopping the application.
+        /// </summary>
+        internal static string app_send_inactive_source {
+            get {
+                return ResourceManager.GetString("app_send_inactive_source", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Put this PC in standby mode when the TV is switched off.
+        /// </summary>
+        internal static string app_standby_on_tv_standby {
+            get {
+                return ResourceManager.GetString("app_standby_on_tv_standby", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Put devices in standby mode when activating screensaver.
+        /// </summary>
+        internal static string app_standby_screensaver {
+            get {
+                return ResourceManager.GetString("app_standby_screensaver", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Use the TV&apos;s language setting.
+        /// </summary>
+        internal static string app_use_tv_language {
+            get {
+                return ResourceManager.GetString("app_use_tv_language", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Windows Media Center.
+        /// </summary>
+        internal static string application_windows_media_center {
+            get {
+                return ResourceManager.GetString("application_windows_media_center", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to XBMC.
+        /// </summary>
+        internal static string application_xbmc {
+            get {
+                return ResourceManager.GetString("application_xbmc", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to - autodetect -.
+        /// </summary>
+        internal static string autodetect {
+            get {
+                return ResourceManager.GetString("autodetect", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Cannot open file &apos;{0}&apos;.
+        /// </summary>
+        internal static string cannot_open_file {
+            get {
+                return ResourceManager.GetString("cannot_open_file", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Cannot open &apos;{0}&apos; for writing.
+        /// </summary>
+        internal static string cannot_open_for_writing {
+            get {
+                return ResourceManager.GetString("cannot_open_for_writing", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to cec-log.txt.
+        /// </summary>
+        internal static string cec_log_filename {
+            get {
+                return ResourceManager.GetString("cec_log_filename", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to txt files (*.txt)|*.txt|All files (*.*)|*.*.
+        /// </summary>
+        internal static string cec_log_filter {
+            get {
+                return ResourceManager.GetString("cec_log_filter", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The command &apos;{0}&apos; was not acked..
+        /// </summary>
+        internal static string command_not_acked {
+            get {
+                return ResourceManager.GetString("command_not_acked", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Command sent successfully..
+        /// </summary>
+        internal static string command_sent_successfully {
+            get {
+                return ResourceManager.GetString("command_sent_successfully", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Mapped to.
+        /// </summary>
+        internal static string config_button_mapped_to {
+            get {
+                return ResourceManager.GetString("config_button_mapped_to", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to CEC Button.
+        /// </summary>
+        internal static string config_cec_button {
+            get {
+                return ResourceManager.GetString("config_cec_button", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Configure &apos;{0}&apos;.
+        /// </summary>
+        internal static string configure_application {
+            get {
+                return ResourceManager.GetString("configure_application", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Could not detect to any CEC adapter. Please check your configuration. Do you want to try again?.
+        /// </summary>
+        internal static string could_not_connect_try_again {
+            get {
+                return ResourceManager.GetString("could_not_connect_try_again", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Couldn&apos;t create directory &apos;{0}&apos;.
+        /// </summary>
+        internal static string could_not_create_directory {
+            get {
+                return ResourceManager.GetString("could_not_create_directory", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to AVR.
+        /// </summary>
+        internal static string device_audiosystem {
+            get {
+                return ResourceManager.GetString("device_audiosystem", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Broadcast.
+        /// </summary>
+        internal static string device_broadcast {
+            get {
+                return ResourceManager.GetString("device_broadcast", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Free Use.
+        /// </summary>
+        internal static string device_free_use {
+            get {
+                return ResourceManager.GetString("device_free_use", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Player.
+        /// </summary>
+        internal static string device_playbackdevice {
+            get {
+                return ResourceManager.GetString("device_playbackdevice", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Recorder.
+        /// </summary>
+        internal static string device_recorder {
+            get {
+                return ResourceManager.GetString("device_recorder", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Reserved.
+        /// </summary>
+        internal static string device_reserved {
+            get {
+                return ResourceManager.GetString("device_reserved", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Tuner.
+        /// </summary>
+        internal static string device_tuner {
+            get {
+                return ResourceManager.GetString("device_tuner", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to TV.
+        /// </summary>
+        internal static string device_tv {
+            get {
+                return ResourceManager.GetString("device_tv", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to You have changed the device type. Persist the configuration, and restart the application to use the new setting..
+        /// </summary>
+        internal static string device_type_changed {
+            get {
+                return ResourceManager.GetString("device_type_changed", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Error.
+        /// </summary>
+        internal static string error {
+            get {
+                return ResourceManager.GetString("error", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Executables (*.exe)|*.exe|All files (*.*)|*.*.
+        /// </summary>
+        internal static string exe_file_filter {
+            get {
+                return ResourceManager.GetString("exe_file_filter", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Make the media player the active source when starting.
+        /// </summary>
+        internal static string global_activate_source {
+            get {
+                return ResourceManager.GetString("global_activate_source", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Advanced mode.
+        /// </summary>
+        internal static string global_advanced_mode {
+            get {
+                return ResourceManager.GetString("global_advanced_mode", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Connected to HDMI device.
+        /// </summary>
+        internal static string global_connected_to_hdmi_device {
+            get {
+                return ResourceManager.GetString("global_connected_to_hdmi_device", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Device type.
+        /// </summary>
+        internal static string global_device_type {
+            get {
+                return ResourceManager.GetString("global_device_type", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Override physical address.
+        /// </summary>
+        internal static string global_override_physical_address {
+            get {
+                return ResourceManager.GetString("global_override_physical_address", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Override TV vendor.
+        /// </summary>
+        internal static string global_override_tv_vendor {
+            get {
+                return ResourceManager.GetString("global_override_tv_vendor", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Physical address.
+        /// </summary>
+        internal static string global_physical_address {
+            get {
+                return ResourceManager.GetString("global_physical_address", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Standby when stopping.
+        /// </summary>
+        internal static string global_standby_devices {
+            get {
+                return ResourceManager.GetString("global_standby_devices", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Minimise after connecting to the adapter.
+        /// </summary>
+        internal static string global_start_hidden {
+            get {
+                return ResourceManager.GetString("global_start_hidden", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to TV vendor.
+        /// </summary>
+        internal static string global_tv_vendor {
+            get {
+                return ResourceManager.GetString("global_tv_vendor", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Wake on startup.
+        /// </summary>
+        internal static string global_wake_devices {
+            get {
+                return ResourceManager.GetString("global_wake_devices", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Hide.
+        /// </summary>
+        internal static string hide {
+            get {
+                return ResourceManager.GetString("hide", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The log file was stored as &apos;{0}&apos;..
+        /// </summary>
+        internal static string log_stored_as {
+            get {
+                return ResourceManager.GetString("log_stored_as", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to no.
+        /// </summary>
+        internal static string no {
+            get {
+                return ResourceManager.GetString("no", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Ready.
+        /// </summary>
+        internal static string ready {
+            get {
+                return ResourceManager.GetString("ready", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Please select the file to be executed.
+        /// </summary>
+        internal static string select_exe_file {
+            get {
+                return ResourceManager.GetString("select_exe_file", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Settings were stored.
+        /// </summary>
+        internal static string settings_stored {
+            get {
+                return ResourceManager.GetString("settings_stored", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Show.
+        /// </summary>
+        internal static string show {
+            get {
+                return ResourceManager.GetString("show", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Starting XBMC will exit this application, as only one program can be using the adapter at a time. Are you sure you want to proceed?.
+        /// </summary>
+        internal static string start_xbmc_exit_tray {
+            get {
+                return ResourceManager.GetString("start_xbmc_exit_tray", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Where do you want to store the settings file?.
+        /// </summary>
+        internal static string store_settings_where {
+            get {
+                return ResourceManager.GetString("store_settings_where", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Are you sure you want to proceed?.
+        /// </summary>
+        internal static string title_are_you_sure {
+            get {
+                return ResourceManager.GetString("title_are_you_sure", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to unknown.
+        /// </summary>
+        internal static string unknown {
+            get {
+                return ResourceManager.GetString("unknown", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to IME accept.
+        /// </summary>
+        internal static string VK_ACCEPT {
+            get {
+                return ResourceManager.GetString("VK_ACCEPT", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to applications.
+        /// </summary>
+        internal static string VK_APPS {
+            get {
+                return ResourceManager.GetString("VK_APPS", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to backspace.
+        /// </summary>
+        internal static string VK_BACK {
+            get {
+                return ResourceManager.GetString("VK_BACK", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to control+break.
+        /// </summary>
+        internal static string VK_CANCEL {
+            get {
+                return ResourceManager.GetString("VK_CANCEL", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to caps lock.
+        /// </summary>
+        internal static string VK_CAPITAL {
+            get {
+                return ResourceManager.GetString("VK_CAPITAL", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to ctrl.
+        /// </summary>
+        internal static string VK_CONTROL {
+            get {
+                return ResourceManager.GetString("VK_CONTROL", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to IME convert.
+        /// </summary>
+        internal static string VK_CONVERT {
+            get {
+                return ResourceManager.GetString("VK_CONVERT", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to del.
+        /// </summary>
+        internal static string VK_DELETE {
+            get {
+                return ResourceManager.GetString("VK_DELETE", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to down arrow.
+        /// </summary>
+        internal static string VK_DOWN {
+            get {
+                return ResourceManager.GetString("VK_DOWN", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to ESC.
+        /// </summary>
+        internal static string VK_ESCAPE {
+            get {
+                return ResourceManager.GetString("VK_ESCAPE", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to IME final mode.
+        /// </summary>
+        internal static string VK_FINAL {
+            get {
+                return ResourceManager.GetString("VK_FINAL", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to IME Hanguel mode.
+        /// </summary>
+        internal static string VK_HANGUEL {
+            get {
+                return ResourceManager.GetString("VK_HANGUEL", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to IME Hangul mode.
+        /// </summary>
+        internal static string VK_HANGUL {
+            get {
+                return ResourceManager.GetString("VK_HANGUL", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to IME Hanja mode.
+        /// </summary>
+        internal static string VK_HANJA {
+            get {
+                return ResourceManager.GetString("VK_HANJA", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to ins.
+        /// </summary>
+        internal static string VK_INSERT {
+            get {
+                return ResourceManager.GetString("VK_INSERT", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to IME Junja mode.
+        /// </summary>
+        internal static string VK_JUNJA {
+            get {
+                return ResourceManager.GetString("VK_JUNJA", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to IME Kana mode.
+        /// </summary>
+        internal static string VK_KANA {
+            get {
+                return ResourceManager.GetString("VK_KANA", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to IME Kanji mode.
+        /// </summary>
+        internal static string VK_KANJI {
+            get {
+                return ResourceManager.GetString("VK_KANJI", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to start application 1.
+        /// </summary>
+        internal static string VK_LAUNCH_APP1 {
+            get {
+                return ResourceManager.GetString("VK_LAUNCH_APP1", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to start application 2.
+        /// </summary>
+        internal static string VK_LAUNCH_APP2 {
+            get {
+                return ResourceManager.GetString("VK_LAUNCH_APP2", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to start mail.
+        /// </summary>
+        internal static string VK_LAUNCH_MAIL {
+            get {
+                return ResourceManager.GetString("VK_LAUNCH_MAIL", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to select media.
+        /// </summary>
+        internal static string VK_LAUNCH_MEDIA_SELECT {
+            get {
+                return ResourceManager.GetString("VK_LAUNCH_MEDIA_SELECT", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to left mouse button.
+        /// </summary>
+        internal static string VK_LBUTTON {
+            get {
+                return ResourceManager.GetString("VK_LBUTTON", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to left control.
+        /// </summary>
+        internal static string VK_LCONTROL {
+            get {
+                return ResourceManager.GetString("VK_LCONTROL", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to left arrow.
+        /// </summary>
+        internal static string VK_LEFT {
+            get {
+                return ResourceManager.GetString("VK_LEFT", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to left menu.
+        /// </summary>
+        internal static string VK_LMENU {
+            get {
+                return ResourceManager.GetString("VK_LMENU", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to left shift.
+        /// </summary>
+        internal static string VK_LSHIFT {
+            get {
+                return ResourceManager.GetString("VK_LSHIFT", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to left Windows.
+        /// </summary>
+        internal static string VK_LWIN {
+            get {
+                return ResourceManager.GetString("VK_LWIN", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to middle mouse button.
+        /// </summary>
+        internal static string VK_MBUTTON {
+            get {
+                return ResourceManager.GetString("VK_MBUTTON", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to next track.
+        /// </summary>
+        internal static string VK_MEDIA_NEXT_TRACK {
+            get {
+                return ResourceManager.GetString("VK_MEDIA_NEXT_TRACK", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to play/pause media.
+        /// </summary>
+        internal static string VK_MEDIA_PLAY_PAUSE {
+            get {
+                return ResourceManager.GetString("VK_MEDIA_PLAY_PAUSE", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to previous track.
+        /// </summary>
+        internal static string VK_MEDIA_PREV_TRACK {
+            get {
+                return ResourceManager.GetString("VK_MEDIA_PREV_TRACK", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to stop media.
+        /// </summary>
+        internal static string VK_MEDIA_STOP {
+            get {
+                return ResourceManager.GetString("VK_MEDIA_STOP", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to alt.
+        /// </summary>
+        internal static string VK_MENU {
+            get {
+                return ResourceManager.GetString("VK_MENU", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to IME mode change request.
+        /// </summary>
+        internal static string VK_MODECHANGE {
+            get {
+                return ResourceManager.GetString("VK_MODECHANGE", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to page down.
+        /// </summary>
+        internal static string VK_NEXT {
+            get {
+                return ResourceManager.GetString("VK_NEXT", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to IME nonconvert.
+        /// </summary>
+        internal static string VK_NONCONVERT {
+            get {
+                return ResourceManager.GetString("VK_NONCONVERT", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to num lock.
+        /// </summary>
+        internal static string VK_NUMLOCK {
+            get {
+                return ResourceManager.GetString("VK_NUMLOCK", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to numeric keypad 0.
+        /// </summary>
+        internal static string VK_NUMPAD0 {
+            get {
+                return ResourceManager.GetString("VK_NUMPAD0", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to numeric keypad 1.
+        /// </summary>
+        internal static string VK_NUMPAD1 {
+            get {
+                return ResourceManager.GetString("VK_NUMPAD1", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to numeric keypad 2.
+        /// </summary>
+        internal static string VK_NUMPAD2 {
+            get {
+                return ResourceManager.GetString("VK_NUMPAD2", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to numeric keypad 3.
+        /// </summary>
+        internal static string VK_NUMPAD3 {
+            get {
+                return ResourceManager.GetString("VK_NUMPAD3", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to numeric keypad 4.
+        /// </summary>
+        internal static string VK_NUMPAD4 {
+            get {
+                return ResourceManager.GetString("VK_NUMPAD4", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to numeric keypad 5.
+        /// </summary>
+        internal static string VK_NUMPAD5 {
+            get {
+                return ResourceManager.GetString("VK_NUMPAD5", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to numeric keypad 6.
+        /// </summary>
+        internal static string VK_NUMPAD6 {
+            get {
+                return ResourceManager.GetString("VK_NUMPAD6", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to numeric keypad 7.
+        /// </summary>
+        internal static string VK_NUMPAD7 {
+            get {
+                return ResourceManager.GetString("VK_NUMPAD7", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to numeric keypad 8.
+        /// </summary>
+        internal static string VK_NUMPAD8 {
+            get {
+                return ResourceManager.GetString("VK_NUMPAD8", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to numeric keypad 9.
+        /// </summary>
+        internal static string VK_NUMPAD9 {
+            get {
+                return ResourceManager.GetString("VK_NUMPAD9", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to :; key.
+        /// </summary>
+        internal static string VK_OEM_1 {
+            get {
+                return ResourceManager.GetString("VK_OEM_1", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to /? key.
+        /// </summary>
+        internal static string VK_OEM_2 {
+            get {
+                return ResourceManager.GetString("VK_OEM_2", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to `~ key.
+        /// </summary>
+        internal static string VK_OEM_3 {
+            get {
+                return ResourceManager.GetString("VK_OEM_3", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to [{ key.
+        /// </summary>
+        internal static string VK_OEM_4 {
+            get {
+                return ResourceManager.GetString("VK_OEM_4", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to \| key.
+        /// </summary>
+        internal static string VK_OEM_5 {
+            get {
+                return ResourceManager.GetString("VK_OEM_5", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to ]} key.
+        /// </summary>
+        internal static string VK_OEM_6 {
+            get {
+                return ResourceManager.GetString("VK_OEM_6", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to &apos;&quot;&quot; key.
+        /// </summary>
+        internal static string VK_OEM_7 {
+            get {
+                return ResourceManager.GetString("VK_OEM_7", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to clear.
+        /// </summary>
+        internal static string VK_OEM_CLEAR {
+            get {
+                return ResourceManager.GetString("VK_OEM_CLEAR", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to , key.
+        /// </summary>
+        internal static string VK_OEM_COMMA {
+            get {
+                return ResourceManager.GetString("VK_OEM_COMMA", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to - key.
+        /// </summary>
+        internal static string VK_OEM_MINUS {
+            get {
+                return ResourceManager.GetString("VK_OEM_MINUS", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to . key.
+        /// </summary>
+        internal static string VK_OEM_PERIOD {
+            get {
+                return ResourceManager.GetString("VK_OEM_PERIOD", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to + key.
+        /// </summary>
+        internal static string VK_OEM_PLUS {
+            get {
+                return ResourceManager.GetString("VK_OEM_PLUS", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to unicode packet.
+        /// </summary>
+        internal static string VK_PACKET {
+            get {
+                return ResourceManager.GetString("VK_PACKET", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to page up.
+        /// </summary>
+        internal static string VK_PRIOR {
+            get {
+                return ResourceManager.GetString("VK_PRIOR", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to IME PROCESS.
+        /// </summary>
+        internal static string VK_PROCESSKEY {
+            get {
+                return ResourceManager.GetString("VK_PROCESSKEY", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to right mouse button.
+        /// </summary>
+        internal static string VK_RBUTTON {
+            get {
+                return ResourceManager.GetString("VK_RBUTTON", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to right control.
+        /// </summary>
+        internal static string VK_RCONTROL {
+            get {
+                return ResourceManager.GetString("VK_RCONTROL", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to enter.
+        /// </summary>
+        internal static string VK_RETURN {
+            get {
+                return ResourceManager.GetString("VK_RETURN", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to right arrow.
+        /// </summary>
+        internal static string VK_RIGHT {
+            get {
+                return ResourceManager.GetString("VK_RIGHT", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to right menu.
+        /// </summary>
+        internal static string VK_RMENU {
+            get {
+                return ResourceManager.GetString("VK_RMENU", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to right shift.
+        /// </summary>
+        internal static string VK_RSHIFT {
+            get {
+                return ResourceManager.GetString("VK_RSHIFT", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to right Windows.
+        /// </summary>
+        internal static string VK_RWIN {
+            get {
+                return ResourceManager.GetString("VK_RWIN", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to scroll lock.
+        /// </summary>
+        internal static string VK_SCROLL {
+            get {
+                return ResourceManager.GetString("VK_SCROLL", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to print screen.
+        /// </summary>
+        internal static string VK_SNAPSHOT {
+            get {
+                return ResourceManager.GetString("VK_SNAPSHOT", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to spacebar.
+        /// </summary>
+        internal static string VK_SPACE {
+            get {
+                return ResourceManager.GetString("VK_SPACE", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to up arrow.
+        /// </summary>
+        internal static string VK_UP {
+            get {
+                return ResourceManager.GetString("VK_UP", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to X1 mouse button.
+        /// </summary>
+        internal static string VK_XBUTTON1 {
+            get {
+                return ResourceManager.GetString("VK_XBUTTON1", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to X2 mouse button.
+        /// </summary>
+        internal static string VK_XBUTTON2 {
+            get {
+                return ResourceManager.GetString("VK_XBUTTON2", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Where do you want to store the log file?.
+        /// </summary>
+        internal static string where_do_you_want_to_store_the_log {
+            get {
+                return ResourceManager.GetString("where_do_you_want_to_store_the_log", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to xml files (*.xml)|*.xml|All files (*.*)|*.*.
+        /// </summary>
+        internal static string xml_file_filter {
+            get {
+                return ResourceManager.GetString("xml_file_filter", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to yes.
+        /// </summary>
+        internal static string yes {
+            get {
+                return ResourceManager.GetString("yes", resourceCulture);
+            }
+        }
+    }
+}
diff --git a/src/LibCecTray/Properties/Resources.resx b/src/LibCecTray/Properties/Resources.resx
new file mode 100644 (file)
index 0000000..14f481e
--- /dev/null
@@ -0,0 +1,597 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <data name="could_not_connect_try_again" xml:space="preserve">
+    <value>Could not detect to any CEC adapter. Please check your configuration. Do you want to try again?</value>
+  </data>
+  <data name="app_name" xml:space="preserve">
+    <value>Pulse-Eight USB-CEC Adapter - libCECTray BETA3</value>
+  </data>
+  <data name="device_type_changed" xml:space="preserve">
+    <value>You have changed the device type. Persist the configuration, and restart the application to use the new setting.</value>
+  </data>
+  <data name="where_do_you_want_to_store_the_log" xml:space="preserve">
+    <value>Where do you want to store the log file?</value>
+  </data>
+  <data name="show" xml:space="preserve">
+    <value>Show</value>
+  </data>
+  <data name="hide" xml:space="preserve">
+    <value>Hide</value>
+  </data>
+  <data name="action_activating_source" xml:space="preserve">
+    <value>Activating the source</value>
+  </data>
+  <data name="action_check_device_present" xml:space="preserve">
+    <value>Checking if {0} is present</value>
+  </data>
+  <data name="action_detecting_avr" xml:space="preserve">
+    <value>Detecting AVR device</value>
+  </data>
+  <data name="action_detecting_avr_vendor" xml:space="preserve">
+    <value>Detecting AVR vendor</value>
+  </data>
+  <data name="action_detecting_tv_vendor" xml:space="preserve">
+    <value>Detecting TV vendor</value>
+  </data>
+  <data name="action_opening_connection" xml:space="preserve">
+    <value>Opening connection</value>
+  </data>
+  <data name="action_polling_active_devices" xml:space="preserve">
+    <value>Polling active devices</value>
+  </data>
+  <data name="action_reading_device_configuration" xml:space="preserve">
+    <value>Reading device configuration</value>
+  </data>
+  <data name="action_refreshing_device_list" xml:space="preserve">
+    <value>Refreshing device list</value>
+  </data>
+  <data name="action_requesting_active_source_state" xml:space="preserve">
+    <value>Requesting active source state</value>
+  </data>
+  <data name="action_requesting_cec_version" xml:space="preserve">
+    <value>Requesting CEC version</value>
+  </data>
+  <data name="action_requesting_menu_language" xml:space="preserve">
+    <value>Requesting menu language</value>
+  </data>
+  <data name="action_requesting_osd_name" xml:space="preserve">
+    <value>Requesting OSD name</value>
+  </data>
+  <data name="action_requesting_physical_address" xml:space="preserve">
+    <value>Requesting physical address</value>
+  </data>
+  <data name="action_requesting_power_status" xml:space="preserve">
+    <value>Requesting power status</value>
+  </data>
+  <data name="action_requesting_vendor_id" xml:space="preserve">
+    <value>Requesting the vendor ID</value>
+  </data>
+  <data name="action_sending_command_to" xml:space="preserve">
+    <value>Sending the '{0}' command to {1}</value>
+  </data>
+  <data name="action_sending_power_on" xml:space="preserve">
+    <value>Sending power on commands</value>
+  </data>
+  <data name="action_setting_new_libcec_configuration" xml:space="preserve">
+    <value>Setting the new configuration</value>
+  </data>
+  <data name="action_showing_device_information" xml:space="preserve">
+    <value>Showing device information</value>
+  </data>
+  <data name="cannot_open_for_writing" xml:space="preserve">
+    <value>Cannot open '{0}' for writing</value>
+  </data>
+  <data name="command_not_acked" xml:space="preserve">
+    <value>The command '{0}' was not acked.</value>
+  </data>
+  <data name="command_sent_successfully" xml:space="preserve">
+    <value>Command sent successfully.</value>
+  </data>
+  <data name="device_audiosystem" xml:space="preserve">
+    <value>AVR</value>
+  </data>
+  <data name="device_playbackdevice" xml:space="preserve">
+    <value>Player</value>
+  </data>
+  <data name="device_recorder" xml:space="preserve">
+    <value>Recorder</value>
+  </data>
+  <data name="device_tuner" xml:space="preserve">
+    <value>Tuner</value>
+  </data>
+  <data name="device_tv" xml:space="preserve">
+    <value>TV</value>
+  </data>
+  <data name="log_stored_as" xml:space="preserve">
+    <value>The log file was stored as '{0}'.</value>
+  </data>
+  <data name="no" xml:space="preserve">
+    <value>no</value>
+  </data>
+  <data name="ready" xml:space="preserve">
+    <value>Ready</value>
+  </data>
+  <data name="unknown" xml:space="preserve">
+    <value>unknown</value>
+  </data>
+  <data name="yes" xml:space="preserve">
+    <value>yes</value>
+  </data>
+  <data name="application_windows_media_center" xml:space="preserve">
+    <value>Windows Media Center</value>
+  </data>
+  <data name="device_broadcast" xml:space="preserve">
+    <value>Broadcast</value>
+  </data>
+  <data name="device_free_use" xml:space="preserve">
+    <value>Free Use</value>
+  </data>
+  <data name="device_reserved" xml:space="preserve">
+    <value>Reserved</value>
+  </data>
+  <data name="autodetect" xml:space="preserve">
+    <value>- autodetect -</value>
+  </data>
+  <data name="cec_log_filename" xml:space="preserve">
+    <value>cec-log.txt</value>
+  </data>
+  <data name="cec_log_filter" xml:space="preserve">
+    <value>txt files (*.txt)|*.txt|All files (*.*)|*.*</value>
+  </data>
+  <data name="global_activate_source" xml:space="preserve">
+    <value>Make the media player the active source when starting</value>
+  </data>
+  <data name="global_advanced_mode" xml:space="preserve">
+    <value>Advanced mode</value>
+  </data>
+  <data name="global_connected_to_hdmi_device" xml:space="preserve">
+    <value>Connected to HDMI device</value>
+  </data>
+  <data name="global_device_type" xml:space="preserve">
+    <value>Device type</value>
+  </data>
+  <data name="global_override_physical_address" xml:space="preserve">
+    <value>Override physical address</value>
+  </data>
+  <data name="global_override_tv_vendor" xml:space="preserve">
+    <value>Override TV vendor</value>
+  </data>
+  <data name="global_physical_address" xml:space="preserve">
+    <value>Physical address</value>
+  </data>
+  <data name="global_standby_devices" xml:space="preserve">
+    <value>Standby when stopping</value>
+  </data>
+  <data name="global_start_hidden" xml:space="preserve">
+    <value>Minimise after connecting to the adapter</value>
+  </data>
+  <data name="global_tv_vendor" xml:space="preserve">
+    <value>TV vendor</value>
+  </data>
+  <data name="global_wake_devices" xml:space="preserve">
+    <value>Wake on startup</value>
+  </data>
+  <data name="about_libcec_version" xml:space="preserve">
+    <value>libCEC v{0} - client v{1}</value>
+  </data>
+  <data name="config_button_mapped_to" xml:space="preserve">
+    <value>Mapped to</value>
+  </data>
+  <data name="config_cec_button" xml:space="preserve">
+    <value>CEC Button</value>
+  </data>
+  <data name="action_type_close_controller_application" xml:space="preserve">
+    <value>close CECTray</value>
+  </data>
+  <data name="action_type_generic" xml:space="preserve">
+    <value>generic</value>
+  </data>
+  <data name="action_type_sendkey" xml:space="preserve">
+    <value>send key</value>
+  </data>
+  <data name="action_type_start_application" xml:space="preserve">
+    <value>start application</value>
+  </data>
+  <data name="add_new_application" xml:space="preserve">
+    <value>Add new application</value>
+  </data>
+  <data name="configure_application" xml:space="preserve">
+    <value>Configure '{0}'</value>
+  </data>
+  <data name="exe_file_filter" xml:space="preserve">
+    <value>Executables (*.exe)|*.exe|All files (*.*)|*.*</value>
+  </data>
+  <data name="select_exe_file" xml:space="preserve">
+    <value>Please select the file to be executed</value>
+  </data>
+  <data name="VK_ACCEPT" xml:space="preserve">
+    <value>IME accept</value>
+  </data>
+  <data name="VK_APPS" xml:space="preserve">
+    <value>applications</value>
+  </data>
+  <data name="VK_BACK" xml:space="preserve">
+    <value>backspace</value>
+  </data>
+  <data name="VK_CANCEL" xml:space="preserve">
+    <value>control+break</value>
+  </data>
+  <data name="VK_CAPITAL" xml:space="preserve">
+    <value>caps lock</value>
+  </data>
+  <data name="VK_CONTROL" xml:space="preserve">
+    <value>ctrl</value>
+  </data>
+  <data name="VK_CONVERT" xml:space="preserve">
+    <value>IME convert</value>
+  </data>
+  <data name="VK_DELETE" xml:space="preserve">
+    <value>del</value>
+  </data>
+  <data name="VK_DOWN" xml:space="preserve">
+    <value>down arrow</value>
+  </data>
+  <data name="VK_ESCAPE" xml:space="preserve">
+    <value>ESC</value>
+  </data>
+  <data name="VK_FINAL" xml:space="preserve">
+    <value>IME final mode</value>
+  </data>
+  <data name="VK_HANGUEL" xml:space="preserve">
+    <value>IME Hanguel mode</value>
+  </data>
+  <data name="VK_HANGUL" xml:space="preserve">
+    <value>IME Hangul mode</value>
+  </data>
+  <data name="VK_HANJA" xml:space="preserve">
+    <value>IME Hanja mode</value>
+  </data>
+  <data name="VK_INSERT" xml:space="preserve">
+    <value>ins</value>
+  </data>
+  <data name="VK_JUNJA" xml:space="preserve">
+    <value>IME Junja mode</value>
+  </data>
+  <data name="VK_KANA" xml:space="preserve">
+    <value>IME Kana mode</value>
+  </data>
+  <data name="VK_KANJI" xml:space="preserve">
+    <value>IME Kanji mode</value>
+  </data>
+  <data name="VK_LAUNCH_APP1" xml:space="preserve">
+    <value>start application 1</value>
+  </data>
+  <data name="VK_LAUNCH_APP2" xml:space="preserve">
+    <value>start application 2</value>
+  </data>
+  <data name="VK_LAUNCH_MAIL" xml:space="preserve">
+    <value>start mail</value>
+  </data>
+  <data name="VK_LAUNCH_MEDIA_SELECT" xml:space="preserve">
+    <value>select media</value>
+  </data>
+  <data name="VK_LBUTTON" xml:space="preserve">
+    <value>left mouse button</value>
+  </data>
+  <data name="VK_LCONTROL" xml:space="preserve">
+    <value>left control</value>
+  </data>
+  <data name="VK_LEFT" xml:space="preserve">
+    <value>left arrow</value>
+  </data>
+  <data name="VK_LMENU" xml:space="preserve">
+    <value>left menu</value>
+  </data>
+  <data name="VK_LSHIFT" xml:space="preserve">
+    <value>left shift</value>
+  </data>
+  <data name="VK_LWIN" xml:space="preserve">
+    <value>left Windows</value>
+  </data>
+  <data name="VK_MBUTTON" xml:space="preserve">
+    <value>middle mouse button</value>
+  </data>
+  <data name="VK_MEDIA_NEXT_TRACK" xml:space="preserve">
+    <value>next track</value>
+  </data>
+  <data name="VK_MEDIA_PLAY_PAUSE" xml:space="preserve">
+    <value>play/pause media</value>
+  </data>
+  <data name="VK_MEDIA_PREV_TRACK" xml:space="preserve">
+    <value>previous track</value>
+  </data>
+  <data name="VK_MEDIA_STOP" xml:space="preserve">
+    <value>stop media</value>
+  </data>
+  <data name="VK_MENU" xml:space="preserve">
+    <value>alt</value>
+  </data>
+  <data name="VK_MODECHANGE" xml:space="preserve">
+    <value>IME mode change request</value>
+  </data>
+  <data name="VK_NEXT" xml:space="preserve">
+    <value>page down</value>
+  </data>
+  <data name="VK_NONCONVERT" xml:space="preserve">
+    <value>IME nonconvert</value>
+  </data>
+  <data name="VK_NUMLOCK" xml:space="preserve">
+    <value>num lock</value>
+  </data>
+  <data name="VK_NUMPAD0" xml:space="preserve">
+    <value>numeric keypad 0</value>
+  </data>
+  <data name="VK_NUMPAD1" xml:space="preserve">
+    <value>numeric keypad 1</value>
+  </data>
+  <data name="VK_NUMPAD2" xml:space="preserve">
+    <value>numeric keypad 2</value>
+  </data>
+  <data name="VK_NUMPAD3" xml:space="preserve">
+    <value>numeric keypad 3</value>
+  </data>
+  <data name="VK_NUMPAD4" xml:space="preserve">
+    <value>numeric keypad 4</value>
+  </data>
+  <data name="VK_NUMPAD5" xml:space="preserve">
+    <value>numeric keypad 5</value>
+  </data>
+  <data name="VK_NUMPAD6" xml:space="preserve">
+    <value>numeric keypad 6</value>
+  </data>
+  <data name="VK_NUMPAD7" xml:space="preserve">
+    <value>numeric keypad 7</value>
+  </data>
+  <data name="VK_NUMPAD8" xml:space="preserve">
+    <value>numeric keypad 8</value>
+  </data>
+  <data name="VK_NUMPAD9" xml:space="preserve">
+    <value>numeric keypad 9</value>
+  </data>
+  <data name="VK_OEM_1" xml:space="preserve">
+    <value>:; key</value>
+  </data>
+  <data name="VK_OEM_2" xml:space="preserve">
+    <value>/? key</value>
+  </data>
+  <data name="VK_OEM_3" xml:space="preserve">
+    <value>`~ key</value>
+  </data>
+  <data name="VK_OEM_4" xml:space="preserve">
+    <value>[{ key</value>
+  </data>
+  <data name="VK_OEM_5" xml:space="preserve">
+    <value>\| key</value>
+  </data>
+  <data name="VK_OEM_6" xml:space="preserve">
+    <value>]} key</value>
+  </data>
+  <data name="VK_OEM_7" xml:space="preserve">
+    <value>'"" key</value>
+  </data>
+  <data name="VK_OEM_CLEAR" xml:space="preserve">
+    <value>clear</value>
+  </data>
+  <data name="VK_OEM_COMMA" xml:space="preserve">
+    <value>, key</value>
+  </data>
+  <data name="VK_OEM_MINUS" xml:space="preserve">
+    <value>- key</value>
+  </data>
+  <data name="VK_OEM_PERIOD" xml:space="preserve">
+    <value>. key</value>
+  </data>
+  <data name="VK_OEM_PLUS" xml:space="preserve">
+    <value>+ key</value>
+  </data>
+  <data name="VK_PACKET" xml:space="preserve">
+    <value>unicode packet</value>
+  </data>
+  <data name="VK_PRIOR" xml:space="preserve">
+    <value>page up</value>
+  </data>
+  <data name="VK_PROCESSKEY" xml:space="preserve">
+    <value>IME PROCESS</value>
+  </data>
+  <data name="VK_RBUTTON" xml:space="preserve">
+    <value>right mouse button</value>
+  </data>
+  <data name="VK_RCONTROL" xml:space="preserve">
+    <value>right control</value>
+  </data>
+  <data name="VK_RETURN" xml:space="preserve">
+    <value>enter</value>
+  </data>
+  <data name="VK_RIGHT" xml:space="preserve">
+    <value>right arrow</value>
+  </data>
+  <data name="VK_RMENU" xml:space="preserve">
+    <value>right menu</value>
+  </data>
+  <data name="VK_RSHIFT" xml:space="preserve">
+    <value>right shift</value>
+  </data>
+  <data name="VK_RWIN" xml:space="preserve">
+    <value>right Windows</value>
+  </data>
+  <data name="VK_SCROLL" xml:space="preserve">
+    <value>scroll lock</value>
+  </data>
+  <data name="VK_SNAPSHOT" xml:space="preserve">
+    <value>print screen</value>
+  </data>
+  <data name="VK_SPACE" xml:space="preserve">
+    <value>spacebar</value>
+  </data>
+  <data name="VK_UP" xml:space="preserve">
+    <value>up arrow</value>
+  </data>
+  <data name="VK_XBUTTON1" xml:space="preserve">
+    <value>X1 mouse button</value>
+  </data>
+  <data name="VK_XBUTTON2" xml:space="preserve">
+    <value>X2 mouse button</value>
+  </data>
+  <data name="application_xbmc" xml:space="preserve">
+    <value>XBMC</value>
+  </data>
+  <data name="app_inactive_source" xml:space="preserve">
+    <value>Send 'inactive source' when shutting down the application</value>
+  </data>
+  <data name="app_use_tv_language" xml:space="preserve">
+    <value>Use the TV's language setting</value>
+  </data>
+  <data name="cannot_open_file" xml:space="preserve">
+    <value>Cannot open file '{0}'</value>
+  </data>
+  <data name="settings_stored" xml:space="preserve">
+    <value>Settings were stored</value>
+  </data>
+  <data name="start_xbmc_exit_tray" xml:space="preserve">
+    <value>Starting XBMC will exit this application, as only one program can be using the adapter at a time. Are you sure you want to proceed?</value>
+  </data>
+  <data name="store_settings_where" xml:space="preserve">
+    <value>Where do you want to store the settings file?</value>
+  </data>
+  <data name="title_are_you_sure" xml:space="preserve">
+    <value>Are you sure you want to proceed?</value>
+  </data>
+  <data name="xml_file_filter" xml:space="preserve">
+    <value>xml files (*.xml)|*.xml|All files (*.*)|*.*</value>
+  </data>
+  <data name="app_send_inactive_source" xml:space="preserve">
+    <value>Send inactive source message when stopping the application</value>
+  </data>
+  <data name="app_standby_on_tv_standby" xml:space="preserve">
+    <value>Put this PC in standby mode when the TV is switched off</value>
+  </data>
+  <data name="app_standby_screensaver" xml:space="preserve">
+    <value>Put devices in standby mode when activating screensaver</value>
+  </data>
+  <data name="could_not_create_directory" xml:space="preserve">
+    <value>Couldn't create directory '{0}'</value>
+  </data>
+  <data name="error" xml:space="preserve">
+    <value>Error</value>
+  </data>
+  <data name="app_pause_playback_on_deactivate" xml:space="preserve">
+    <value>Pause playback when switching to another source</value>
+  </data>
+</root>
\ No newline at end of file
diff --git a/src/LibCecTray/controller/Actions.cs b/src/LibCecTray/controller/Actions.cs
new file mode 100644 (file)
index 0000000..2d065a9
--- /dev/null
@@ -0,0 +1,295 @@
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing       <license@pulse-eight.com>
+ *     http://www.pulse-eight.com/
+ *     http://www.pulse-eight.net/
+ */
+
+using System.Threading;
+using CecSharp;
+using LibCECTray.controller.actions;
+using LibCECTray.ui;
+using System.Windows.Forms;
+
+namespace LibCECTray.controller
+{
+  /// <summary>
+  /// Actions that can be executed by a background thread
+  /// </summary>
+  internal class Actions
+  {
+    public Actions(CECController controller)
+    {
+      _controller = controller;
+    }
+
+    /// <summary>
+    /// Event handler for processing updates for a background thread
+    /// </summary>
+    /// <param name="src">The source that sent the event</param>
+    /// <param name="updateEvent">The type of event</param>
+    private void ProcessEventHandler(object src, UpdateEvent updateEvent)
+    {
+      switch (updateEvent.Type)
+      {
+        case UpdateEventType.StatusText:
+          _controller.SetStatusText(updateEvent.StringValue);
+          break;
+        case UpdateEventType.ProgressBar:
+          _controller.SetProgressBar(updateEvent.IntValue, true);
+          break;
+        case UpdateEventType.PhysicalAddress:
+          _controller.Settings.PhysicalAddress.Value = (ushort)updateEvent.IntValue;
+          break;
+        case UpdateEventType.TVVendorId:
+          _controller.Settings.SetVendorName(CecLogicalAddress.Tv, (CecVendorId)updateEvent.IntValue, _controller.Lib.ToString((CecVendorId)updateEvent.IntValue));
+          break;
+        case UpdateEventType.BaseDevice:
+          _controller.Settings.ConnectedDevice.Value = (CecLogicalAddress)updateEvent.IntValue;
+          break;
+        case UpdateEventType.HDMIPort:
+          _controller.Settings.HDMIPort.Value = (byte)updateEvent.IntValue;
+          break;
+        case UpdateEventType.HasAVRDevice:
+          CecLogicalAddresses allowedMask = new CecLogicalAddresses();
+          allowedMask.Set(CecLogicalAddress.Tv);
+          if (updateEvent.BoolValue)
+            allowedMask.Set(CecLogicalAddress.AudioSystem);
+          _controller.Settings.ConnectedDevice.AllowedAddressMask = allowedMask;
+          break;
+        case UpdateEventType.AVRVendorId:
+          _controller.Settings.SetVendorName(CecLogicalAddress.AudioSystem, (CecVendorId)updateEvent.IntValue, _controller.Lib.ToString((CecVendorId)updateEvent.IntValue));
+          break;
+        case UpdateEventType.Configuration:
+          SuppressUpdates = true;
+          _controller.ConfigurationChanged(updateEvent.ConfigValue);
+          SuppressUpdates = false;
+          break;
+        case UpdateEventType.PollDevices:
+          _controller.CheckActiveDevices();
+          break;
+        case UpdateEventType.ProcessCompleted:
+          if (!(_activeProcess is GetCurrentPhysicalAddress))
+          {
+            _activeProcess = new GetCurrentPhysicalAddress(_controller.Lib);
+            _activeProcess.EventHandler += ProcessEventHandler;
+            (new Thread(_activeProcess.Run)).Start();
+          }
+          else
+          {
+            _activeProcess = null;
+          }
+
+          if (_updatingInfoPanel != null)
+          {
+            _updatingInfoPanel.SetControlEnabled(_updatingInfoPanel.bUpdate, true);
+            _updatingInfoPanel = null;
+          }
+
+          _controller.SetControlsEnabled(true);
+          _controller.SetProgressBar(100, false);
+
+          if (_controller.Settings.StartHidden.Value)
+          {
+            _controller.SetShowInTaskbar(false);
+            //SetToolStripMenuText(tsMenuShowHide, Resources.show);
+            _controller.Hide(true);
+          }
+
+          break;
+        case UpdateEventType.ExitApplication:
+          _activeProcess = null;
+          Application.Exit();
+          break;
+      }
+    }
+
+    #region Actions
+    /// <summary>
+    /// Updates the contents of a device information window
+    /// </summary>
+    /// <param name="panel">The panel to update</param>
+    public void UpdateInfoPanel(DeviceInformation panel)
+    {
+      if (SuppressUpdates || _activeProcess != null) return;
+
+      _controller.SetControlsEnabled(false);
+      _updatingInfoPanel = panel;
+      panel.SetControlEnabled(panel.bUpdate, false);
+      _activeProcess = new UpdateDeviceInfo(_controller, _controller.Lib, panel);
+      _activeProcess.EventHandler += ProcessEventHandler;
+      (new Thread(_activeProcess.Run)).Start();
+    }
+
+    /// <summary>
+    /// Change the device to which the adapter is connected and/or the HDMI port number
+    /// </summary>
+    /// <param name="address">The new device to which the adapter is connected</param>
+    /// <param name="portnumber">The new HDMI port number</param>
+    public void SetConnectedDevice(CecLogicalAddress address, int portnumber)
+    {
+      if (SuppressUpdates || _activeProcess != null) return;
+
+      _controller.SetControlsEnabled(false);
+      _activeProcess = new UpdateConnectedDevice(_controller.Lib, address, portnumber);
+      _activeProcess.EventHandler += ProcessEventHandler;
+      (new Thread(_activeProcess.Run)).Start();
+    }
+
+    /// <summary>
+    /// Changes the physical address setting of libCEC
+    /// </summary>
+    /// <param name="physicalAddress">The new physical address</param>
+    public void SetPhysicalAddress(ushort physicalAddress)
+    {
+      if (SuppressUpdates || _activeProcess != null || !_controller.Settings.OverridePhysicalAddress.Value) return;
+
+      _controller.SetControlsEnabled(false);
+      _activeProcess = new UpdatePhysicalAddress(_controller.Lib, physicalAddress);
+      _activeProcess.EventHandler += ProcessEventHandler;
+      (new Thread(_activeProcess.Run)).Start();
+    }
+
+    /// <summary>
+    /// Send an updated configuration to libCEC
+    /// </summary>
+    /// <param name="config">The new configuration</param>
+    public void UpdateConfigurationAsync(LibCECConfiguration config)
+    {
+      if (SuppressUpdates || _activeProcess != null) return;
+
+      _controller.SetControlsEnabled(false);
+      _activeProcess = new UpdateConfiguration(_controller.Lib, config);
+      _activeProcess.EventHandler += ProcessEventHandler;
+      (new Thread(_activeProcess.Run)).Start();
+    }
+
+    /// <summary>
+    /// Send an image view on command to the device at the given logical address
+    /// </summary>
+    /// <param name="address">The address to send the image view on command to</param>
+    public void SendImageViewOn(CecLogicalAddress address)
+    {
+      if (SuppressUpdates || _activeProcess != null) return;
+
+      _controller.SetControlsEnabled(false);
+      _activeProcess = new SendImageViewOn(_controller.Lib, address);
+      _activeProcess.EventHandler += ProcessEventHandler;
+      (new Thread(_activeProcess.Run)).Start();
+    }
+
+    /// <summary>
+    /// Activate the source at the given logical address. 
+    /// </summary>
+    /// <param name="address">The logical address of the device to activate</param>
+    public void ActivateSource(CecLogicalAddress address)
+    {
+      if (SuppressUpdates || _activeProcess != null) return;
+
+      _controller.SetControlsEnabled(false);
+      _activeProcess = new SendActivateSource(_controller.Lib, address);
+      _activeProcess.EventHandler += ProcessEventHandler;
+      (new Thread(_activeProcess.Run)).Start();
+    }
+
+    /// <summary>
+    /// Send a standby command to the device at the given logical address
+    /// </summary>
+    /// <param name="address">The logical address of the device to send to standby</param>
+    public void SendStandby(CecLogicalAddress address)
+    {
+      if (SuppressUpdates || _activeProcess != null) return;
+
+      _controller.SetControlsEnabled(false);
+      _activeProcess = new SendStandby(_controller.Lib, address);
+      _activeProcess.EventHandler += ProcessEventHandler;
+      (new Thread(_activeProcess.Run)).Start();
+    }
+
+    /// <summary>
+    /// Fetch device information and show an information dialog for the device at the given logical address
+    /// </summary>
+    /// <param name="address">The logical address of the device to get the info for</param>
+    public void ShowDeviceInfo(CecLogicalAddress address)
+    {
+      if (SuppressUpdates || _activeProcess != null) return;
+
+      _controller.SetControlsEnabled(false);
+      _activeProcess = new ShowDeviceInfo(_controller, _controller.Lib, address);
+      _activeProcess.EventHandler += ProcessEventHandler;
+      (new Thread(_activeProcess.Run)).Start();
+    }
+
+    /// <summary>
+    /// Poll devices to check which ones are active
+    /// </summary>
+    public void RescanDevices()
+    {
+      if (SuppressUpdates || _activeProcess != null) return;
+
+      _controller.SetControlsEnabled(false);
+      _activeProcess = new RescanDevices(_controller.Lib);
+      _activeProcess.EventHandler += ProcessEventHandler;
+      (new Thread(_activeProcess.Run)).Start();
+    }
+
+    /// <summary>
+    /// Update the physical address of libCEC that is displayed in the UI
+    /// </summary>
+    public void UpdatePhysicalAddress()
+    {
+      if (SuppressUpdates || _activeProcess != null) return;
+
+      _controller.SetControlsEnabled(false);
+      _activeProcess = new GetCurrentPhysicalAddress(_controller.Lib);
+      _activeProcess.EventHandler += ProcessEventHandler;
+      (new Thread(_activeProcess.Run)).Start();
+    }
+
+    /// <summary>
+    /// Connect to the adapter with the given configuration
+    /// </summary>
+    /// <param name="config">The client configuration</param>
+    public void ConnectToDevice(LibCECConfiguration config)
+    {
+      if (_activeProcess != null) return;
+
+      _activeProcess = new ConnectToDevice(_controller.Lib, config);
+      _activeProcess.EventHandler += ProcessEventHandler;
+      (new Thread(_activeProcess.Run)).Start();
+    }
+    #endregion
+
+    #region Members
+    private readonly CECController _controller;
+    private DeviceInformation _updatingInfoPanel;
+    public bool SuppressUpdates = true;
+    private UpdateProcess _activeProcess;
+    #endregion
+  }
+}
diff --git a/src/LibCecTray/controller/CECController.cs b/src/LibCecTray/controller/CECController.cs
new file mode 100644 (file)
index 0000000..f81cd94
--- /dev/null
@@ -0,0 +1,525 @@
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing       <license@pulse-eight.com>
+ *     http://www.pulse-eight.com/
+ *     http://www.pulse-eight.net/
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Windows.Forms;
+using CecSharp;
+using LibCECTray.Properties;
+using LibCECTray.controller.applications;
+using LibCECTray.settings;
+using LibCECTray.ui;
+
+namespace LibCECTray.controller
+{
+  internal class CECController : CecCallbackMethods
+  {
+    public CECController(CECTray gui)
+    {
+      _gui = gui;
+      CECActions = new Actions(this);
+
+      InitialiseGui();
+
+      Settings.SettingChanged += OnSettingChanged;
+    }
+
+    #region Settings
+    /// <summary>
+    /// Called when a setting changed
+    /// </summary>
+    /// <param name="setting">The setting that changed</param>
+    /// <param name="oldValue">The old value</param>
+    /// <param name="newValue">The new value</param>
+    private void OnSettingChanged(CECSetting setting, object oldValue, object newValue)
+    {
+      if (setting.KeyName == CECSettings.KeyHDMIPort)
+      {
+        CECSettingByte byteSetting = setting as CECSettingByte;
+        if (byteSetting != null)
+        {
+          if (!Settings.OverridePhysicalAddress.Value)
+            Config.HDMIPort = byteSetting.Value;
+          CECActions.SetConnectedDevice(Settings.ConnectedDevice.Value, byteSetting.Value);
+        }
+      }
+      else if (setting.KeyName == CECSettings.KeyConnectedToHDMIDevice)
+      {
+        CECSettingLogicalAddress laSetting = setting as CECSettingLogicalAddress;
+        if (laSetting != null)
+        {
+          if (!Settings.OverridePhysicalAddress.Value)
+            Config.BaseDevice = laSetting.Value;
+          CECActions.SetConnectedDevice(laSetting.Value, Settings.HDMIPort.Value);
+        }
+      }
+      else if (setting.KeyName == CECSettings.KeyPhysicalAddress)
+      {
+        CECSettingUShort ushortSetting = setting as CECSettingUShort;
+        if (ushortSetting != null && Settings.OverridePhysicalAddress.Value && Config.PhysicalAddress != ushortSetting.Value)
+        {
+          Config.PhysicalAddress = ushortSetting.Value;
+          CECActions.SetPhysicalAddress(ushortSetting.Value);
+        }
+      }
+      else if (setting.KeyName == CECSettings.KeyOverridePhysicalAddress)
+      {
+        CECSettingBool boolSetting = setting as CECSettingBool;
+        if (boolSetting != null)
+        {
+          Settings.PhysicalAddress.Enabled = boolSetting.Value;
+          Settings.HDMIPort.Enabled = !boolSetting.Value;
+          Settings.ConnectedDevice.Enabled = !boolSetting.Value;
+          if (boolSetting.Value)
+          {
+            Config.BaseDevice = Settings.ConnectedDevice.Value;
+            Config.HDMIPort = 0;
+            Config.PhysicalAddress = Settings.PhysicalAddress.Value;
+          }
+          else
+          {
+            Config.BaseDevice = Settings.ConnectedDevice.Value;
+            Config.HDMIPort = Settings.HDMIPort.Value;
+            Config.PhysicalAddress = 0xFFFF;
+          }
+        }
+      }
+      else if (setting.KeyName == CECSettings.KeyDeviceType)
+      {
+        CECSettingDeviceType dtSetting = setting as CECSettingDeviceType;
+        if (dtSetting != null)
+        {
+          if (dtSetting.Value != Config.DeviceTypes.Types[0] && Settings.OverrideTVVendor.Value)
+          {
+            Config.DeviceTypes.Types[0] = dtSetting.Value;
+            if (!_deviceChangeWarningDisplayed)
+            {
+              _deviceChangeWarningDisplayed = true;
+              MessageBox.Show(Resources.device_type_changed, Resources.app_name, MessageBoxButtons.OK,
+                              MessageBoxIcon.Warning);
+            }
+          }
+        }
+      }
+      else if (setting.KeyName == CECSettings.KeyOverrideTVVendor)
+      {
+        CECSettingBool boolSetting = setting as CECSettingBool;
+        if (boolSetting != null)
+        {
+          Settings.TVVendor.Enabled = boolSetting.Value;
+          Settings.TVVendor.Value = boolSetting.Value ? Lib.GetDeviceVendorId(CecLogicalAddress.Tv) : CecVendorId.Unknown;
+          Config.TvVendor = boolSetting.Value ? Settings.TVVendor.Value : CecVendorId.Unknown;
+        }
+      }
+      else if (setting.KeyName == CECSettings.KeyActivateSource)
+      {
+        CECSettingBool boolSetting = setting as CECSettingBool;
+        if (boolSetting != null)
+          Config.ActivateSource = boolSetting.Value;
+      }
+      else if (setting.KeyName == CECSettings.KeyTVVendor)
+      {
+        CECSettingVendorId vendorSetting = setting as CECSettingVendorId;
+        if (vendorSetting != null && Settings.OverrideTVVendor.Value)
+          Config.TvVendor = vendorSetting.Value;
+      }
+      else if (setting.KeyName == CECSettings.KeyWakeDevices)
+      {
+        CECSettingLogicalAddresses laSetting = setting as CECSettingLogicalAddresses;
+        if (laSetting != null)
+          Config.WakeDevices = laSetting.Value;
+      }
+      else if (setting.KeyName == CECSettings.KeyPowerOffDevices)
+      {
+        CECSettingLogicalAddresses laSetting = setting as CECSettingLogicalAddresses;
+        if (laSetting != null)
+          Config.PowerOffDevices = laSetting.Value;
+      }
+    }
+
+    /// <summary>
+    /// Persist all known settings in the registry
+    /// </summary>
+    public void PersistSettings()
+    {
+      /* save settings in the eeprom */
+      Lib.SetConfiguration(Config);
+      Lib.PersistConfiguration(Config);
+
+      /* and in the registry */
+      Settings.Persist();
+    }
+
+    /// <summary>
+    /// Reset all settings to their default values
+    /// </summary>
+    public void ResetDefaultSettings()
+    {
+      SetControlsEnabled(false);
+      _gui.ShowHideAdvanced(false);
+
+      CECActions.SuppressUpdates = true;
+      Settings.SetDefaultValues();
+      _config = null;
+      Lib.SetConfiguration(Config);
+      CECActions.SuppressUpdates = false;
+
+      _gui.ShowHideAdvanced(Settings.AdvancedMode.Value);
+      SetControlsEnabled(true);
+    }
+    #endregion
+
+    /// <summary>
+    /// Opens a connection to libCEC and register known applications
+    /// </summary>
+    public void Initialise()
+    {
+      CECActions.ConnectToDevice(Config);
+      Applications.Initialise(this);
+    }
+
+    /// <summary>
+    /// Closes the connection to libCEC
+    /// </summary>
+    public void Close()
+    {
+      Lib.DisableCallbacks();
+      Lib.StandbyDevices(CecLogicalAddress.Broadcast);
+      Lib.Close();
+    }
+
+    /// <summary>
+    /// Register a new application controller, which will add a new tab for the application
+    /// </summary>
+    /// <param name="app">The new application to register</param>
+    /// <returns>True when registered, false otherwise</returns>
+    public bool RegisterApplication(ApplicationController app)
+    {
+      if (_applications.Contains(app)) return false;
+      _applications.Add(app);
+
+      _gui.SuspendLayout();
+      _gui.TabControls.Add(app.UiControl);
+      _gui.ResumeLayout();
+
+      app.Initialise();
+
+      return true;
+    }
+
+    #region GUI controls
+    /// <summary>
+    /// Initialises the UI
+    /// </summary>
+    private void InitialiseGui()
+    {
+      _gui.SuspendLayout();
+      _gui.InitialiseSettingsComponent(Settings);
+
+      // add the controller tabs to the gui
+      foreach (var ui in ApplicationUIs)
+        _gui.TabControls.Add(ui);
+
+      // enable/disable advanced mode
+      _gui.ShowHideAdvanced(Settings.AdvancedMode.Value);
+
+      _gui.ResumeLayout();
+    }
+
+    /// <summary>
+    /// Display a dialog
+    /// </summary>
+    /// <param name="control">The dialog to display</param>
+    /// <param name="modal">True when modal</param>
+    public void DisplayDialog(Form control, bool modal)
+    {
+      _gui.DisplayDialog(control, modal);
+    }
+
+    /// <summary>
+    /// Changes the status text of this window
+    /// </summary>
+    /// <param name="status">The new status text</param>
+    public void SetStatusText(string status)
+    {
+      _gui.SetStatusText(status);
+    }
+
+    /// <summary>
+    /// Changes the progress bar value
+    /// </summary>
+    /// <param name="progress">The new progress percentage</param>
+    /// <param name="visible">True to make the bar visible, false otherwise</param>
+    public void SetProgressBar(int progress, bool visible)
+    {
+      _gui.SetProgressBar(progress, visible);
+    }
+
+    /// <summary>
+    /// Enable/disable all controls
+    /// </summary>
+    /// <param name="val">True to enable, false to disable</param>
+    public void SetControlsEnabled(bool val)
+    {
+      Settings.Enabled = val;
+      foreach (var app in _applications)
+        app.UiControl.SetEnabled(val);
+      _gui.SetControlsEnabled(val);
+    }
+
+    /// <summary>
+    /// (re)check the logical addresses of the active devices on the bus
+    /// </summary>
+    public void CheckActiveDevices()
+    {
+      var activeDevices = Lib.GetActiveDevices();
+      List<string> deviceList = new List<string>();
+      foreach (var activeDevice in activeDevices.Addresses)
+      {
+        if (activeDevice != CecLogicalAddress.Unknown)
+          deviceList.Add(string.Format("{0,1:X} : {1}", (int)activeDevice, Lib.ToString(activeDevice)));
+      }
+      deviceList.Add(string.Format("{0,1:X} : {1}", (int)CecLogicalAddress.Broadcast, Lib.ToString(CecLogicalAddress.Broadcast)));
+
+      _gui.SetActiveDevices(deviceList.ToArray());
+    }
+
+    /// <summary>
+    /// Show/hide the taskbar entry
+    /// </summary>
+    /// <param name="val">True to show, false to hide</param>
+    public void SetShowInTaskbar(bool val)
+    {
+      _gui.SetShowInTaskbar(val);
+    }
+
+    /// <summary>
+    /// Show or hide this window
+    /// </summary>
+    /// <param name="val">True to show, false to hide</param>
+    public void Hide(bool val)
+    {
+      _gui.SafeHide(val);
+    }
+    #endregion
+
+    #region Callbacks called by libCEC
+    public override int ReceiveCommand(CecCommand command)
+    {
+      return 0;
+    }
+
+    public override int ReceiveKeypress(CecKeypress key)
+    {
+      foreach (var app in _applications)
+      {
+        bool keySent = app.SendKey(key, app.UiName == _gui.SelectedTabName);
+
+        if (keySent)
+        {
+          string strLog = string.Format("sent key '{0}' to '{1}'", (int) key.Keycode, app.UiName) + Environment.NewLine;
+          _gui.AddLogMessage(strLog);
+          break;
+        }
+      }
+
+      return 1;
+    }
+
+    public override int ReceiveLogMessage(CecLogMessage message)
+    {
+      _gui.AddLogMessage(message);
+      return 1;
+    }
+
+    public override int ConfigurationChanged(LibCECConfiguration config)
+    {
+      Settings.PhysicalAddress.Value = Config.PhysicalAddress;
+      Settings.ConnectedDevice.Value = Config.BaseDevice == CecLogicalAddress.AudioSystem ? CecLogicalAddress.AudioSystem : CecLogicalAddress.Tv;
+      Settings.HDMIPort.Value = Config.HDMIPort;
+      Settings.WakeDevices.Value = Config.WakeDevices;
+      Settings.PowerOffDevices.Value = Config.PowerOffDevices;
+      Settings.ActivateSource.Value = Config.ActivateSource;
+      Settings.DeviceType.Value = config.DeviceTypes.Types[0];
+
+      if (config.TvVendor != CecVendorId.Unknown)
+      {
+        Settings.OverrideTVVendor.Value = true;
+        Settings.TVVendor.Value = config.TvVendor;
+      }
+      else
+      {
+        Settings.OverrideTVVendor.Value = false;
+      }
+
+      _gui.SetControlText(_gui, Resources.app_name + " - libCEC " + Lib.ToString(Config.ServerVersion));
+
+      CECActions.UpdatePhysicalAddress();
+      return 1;
+    }
+
+    public override void SourceActivated(CecLogicalAddress logicalAddress, bool activated)
+    {
+      if (!activated)
+        return;
+
+      foreach (var app in _applications)
+      {
+        if (app.AutoStartApplication.Value)
+          app.Start(false);
+      }
+    }
+    #endregion
+
+    #region Members
+    /// <summary>
+    /// List of tab pages for each application that the UI supports
+    /// </summary>
+    public List<ControllerTabPage> ApplicationUIs
+    {
+      get
+      {
+        List<ControllerTabPage> retVal = new List<ControllerTabPage>();
+        foreach (var app in _applications)
+          retVal.Add(app.UiControl);
+        return retVal;
+      }
+    }
+
+    /// <summary>
+    /// List of application controllers that the UI supports
+    /// </summary>
+    private readonly List<ApplicationController> _applications = new List<ApplicationController>();
+
+    /// <summary>
+    /// Settings that are persisted in the registry (when not using the default value)
+    /// </summary>
+    public CECSettings Settings
+    {
+      get { return _settings ?? (_settings = new CECSettings(OnSettingChanged)); }
+    }
+    private CECSettings _settings;
+
+    /// <summary>
+    /// libCEC configuration for the application
+    /// </summary>
+    private LibCECConfiguration Config
+    {
+      get
+      {
+        if (_config == null)
+        {
+          _config = new LibCECConfiguration { DeviceName = "CEC Tray", ClientVersion = CecClientVersion.Version2_0_0 };
+          _config.DeviceTypes.Types[0] = CecDeviceType.RecordingDevice;
+          _config.SetCallbacks(this);
+
+          if (Settings.OverridePhysicalAddress.Value)
+          {
+            _config.PhysicalAddress = Settings.PhysicalAddress.Value;
+            _config.HDMIPort = 0;
+            _config.BaseDevice = CecLogicalAddress.Unknown;
+          }
+          else
+          {
+            _config.PhysicalAddress = 0;
+            _config.HDMIPort = Settings.HDMIPort.Value;
+            _config.BaseDevice = Settings.ConnectedDevice.Value;
+          }
+          _config.ActivateSource = Settings.ActivateSource.Value;
+          _config.DeviceTypes.Types[0] = Settings.DeviceType.Value;
+          if (Settings.OverrideTVVendor.Value)
+            _config.TvVendor = Settings.TVVendor.Value;
+          _config.WakeDevices = Settings.WakeDevices.Value;
+          _config.PowerOffDevices = Settings.PowerOffDevices.Value;
+        }
+        return _config;
+      }
+    }
+    private LibCECConfiguration _config;
+
+    /// <summary>
+    /// Get build info from libCEC
+    /// </summary>
+    public string LibInfo
+    {
+      get { return Lib.GetLibInfo(); }
+    }
+
+    /// <summary>
+    /// libCEC API version
+    /// </summary>
+    public string LibServerVersion
+    {
+      get { return Lib.ToString(Config.ServerVersion); }
+    }
+
+    /// <summary>
+    /// libCEC client API version
+    /// </summary>
+    public string LibClientVersion
+    {
+      get { return Lib.ToString(Config.ClientVersion); }
+    }
+
+    /// <summary>
+    /// Get the usb vendor id
+    /// </summary>
+    public ushort AdapterVendorId
+    {
+      get { return Lib.GetAdapterVendorId(); }
+    }
+
+    /// <summary>
+    /// Get the usb product id
+    /// </summary>
+    public ushort AdapterProductId
+    {
+      get { return Lib.GetAdapterProductId(); }
+    }
+
+
+    /// <summary>
+    /// libCEC
+    /// </summary>
+    public LibCecSharp Lib
+    {
+      get { return _lib ?? (_lib = new LibCecSharp(Config)); }
+    }
+    private LibCecSharp _lib;
+
+    private readonly CECTray _gui;
+    public Actions CECActions;
+    private bool _deviceChangeWarningDisplayed;
+
+    #endregion
+  }
+}
diff --git a/src/LibCecTray/controller/actions/ConnectToDevice.cs b/src/LibCecTray/controller/actions/ConnectToDevice.cs
new file mode 100644 (file)
index 0000000..02be838
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing       <license@pulse-eight.com>
+ *     http://www.pulse-eight.com/
+ *     http://www.pulse-eight.net/
+ */
+
+using CecSharp;
+using System.Windows.Forms;
+using LibCECTray.Properties;
+
+namespace LibCECTray.controller.actions
+{
+  class ConnectToDevice : UpdateProcess
+  {
+    public ConnectToDevice(LibCecSharp lib, LibCECConfiguration config)
+    {
+      _lib = lib;
+      _config = config;
+    }
+
+    public override void Process()
+    {
+      SendEvent(UpdateEventType.StatusText, Resources.action_opening_connection);
+      SendEvent(UpdateEventType.ProgressBar, 10);
+
+      //TODO read the com port setting from the configuration
+      var adapters = _lib.FindAdapters(string.Empty);
+      if (adapters.Length == 0)
+      {
+        var result = MessageBox.Show(Resources.could_not_connect_try_again, Resources.app_name, MessageBoxButtons.YesNo);
+        if (result == DialogResult.No)
+        {
+          SendEvent(UpdateEventType.ExitApplication);
+          return;
+        }
+        adapters = _lib.FindAdapters(string.Empty);
+      }
+
+      while (!_lib.Open(adapters[0].ComPort, 10000))
+      {
+        var result = MessageBox.Show(Resources.could_not_connect_try_again, Resources.app_name, MessageBoxButtons.YesNo);
+        if (result != DialogResult.No) continue;
+        SendEvent(UpdateEventType.ExitApplication);
+        return;
+      }
+
+      SendEvent(UpdateEventType.ProgressBar, 20);
+      SendEvent(UpdateEventType.StatusText, Resources.action_sending_power_on);
+      _lib.PowerOnDevices(CecLogicalAddress.Broadcast);
+
+      SendEvent(UpdateEventType.StatusText, Resources.action_detecting_tv_vendor);
+      SendEvent(UpdateEventType.ProgressBar, 30);
+      SendEvent(UpdateEventType.TVVendorId, (int)_lib.GetDeviceVendorId(CecLogicalAddress.Tv));
+
+      SendEvent(UpdateEventType.ProgressBar, 50);
+      SendEvent(UpdateEventType.StatusText, Resources.action_detecting_avr);
+
+      bool hasAVRDevice = _lib.IsActiveDevice(CecLogicalAddress.AudioSystem);
+      SendEvent(UpdateEventType.HasAVRDevice, hasAVRDevice);
+
+      if (hasAVRDevice)
+      {
+        SendEvent(UpdateEventType.ProgressBar, 60);
+        SendEvent(UpdateEventType.StatusText, Resources.action_detecting_avr_vendor);
+        SendEvent(UpdateEventType.AVRVendorId, (int)_lib.GetDeviceVendorId(CecLogicalAddress.AudioSystem));
+      }
+
+      if (!_lib.GetDevicePowerStatus(CecLogicalAddress.Tv).Equals(CecPowerStatus.On))
+      {
+        SendEvent(UpdateEventType.ProgressBar, 70);
+        SendEvent(UpdateEventType.StatusText, Resources.action_activating_source);
+        _lib.SetActiveSource(CecDeviceType.Reserved);
+      }
+
+      SendEvent(UpdateEventType.ProgressBar, 80);
+      SendEvent(UpdateEventType.StatusText, Resources.action_reading_device_configuration);
+
+      _lib.GetCurrentConfiguration(_config);
+      SendEvent(_config);
+
+      SendEvent(UpdateEventType.ProgressBar, 90);
+      SendEvent(UpdateEventType.StatusText, Resources.action_polling_active_devices);
+      SendEvent(UpdateEventType.PollDevices);
+
+      SendEvent(UpdateEventType.ProgressBar, 100);
+      SendEvent(UpdateEventType.StatusText, Resources.ready);
+    }
+
+    private readonly LibCecSharp _lib;
+    private readonly LibCECConfiguration _config;
+  }
+}
diff --git a/src/LibCecTray/controller/actions/GetCurrentPhysicalAddress.cs b/src/LibCecTray/controller/actions/GetCurrentPhysicalAddress.cs
new file mode 100644 (file)
index 0000000..ada74ca
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing       <license@pulse-eight.com>
+ *     http://www.pulse-eight.com/
+ *     http://www.pulse-eight.net/
+ */
+
+using CecSharp;
+using LibCECTray.Properties;
+
+namespace LibCECTray.controller.actions
+{
+  class GetCurrentPhysicalAddress : UpdateProcess
+  {
+    public GetCurrentPhysicalAddress(LibCecSharp lib)
+    {
+      _lib = lib;
+    }
+
+    public override void Process()
+    {
+      SendEvent(UpdateEventType.ProgressBar, 10);
+      SendEvent(UpdateEventType.StatusText, Resources.action_requesting_physical_address);
+
+      LibCECConfiguration config = new LibCECConfiguration();
+      _lib.GetCurrentConfiguration(config);
+      var physicalAddress = _lib.GetDevicePhysicalAddress(config.LogicalAddresses.Primary);
+
+      if (physicalAddress != 0xFFFF &&
+          physicalAddress != 0)
+        SendEvent(UpdateEventType.PhysicalAddress, physicalAddress);
+
+      SendEvent(UpdateEventType.ProgressBar, 100);
+      SendEvent(UpdateEventType.StatusText, Resources.ready);
+    }
+
+    private readonly LibCecSharp _lib;
+  }
+}
diff --git a/src/LibCecTray/controller/actions/RescanDevices.cs b/src/LibCecTray/controller/actions/RescanDevices.cs
new file mode 100644 (file)
index 0000000..4d661a1
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing       <license@pulse-eight.com>
+ *     http://www.pulse-eight.com/
+ *     http://www.pulse-eight.net/
+ */
+
+using CecSharp;
+using LibCECTray.Properties;
+
+namespace LibCECTray.controller.actions
+{
+  class RescanDevices : UpdateProcess
+  {
+    public RescanDevices(LibCecSharp lib)
+    {
+      _lib = lib;
+    }
+
+    public override void Process()
+    {
+      SendEvent(UpdateEventType.ProgressBar, 10);
+      SendEvent(UpdateEventType.StatusText, Resources.action_polling_active_devices);
+      _lib.RescanActiveDevices();
+
+      SendEvent(UpdateEventType.ProgressBar, 80);
+      SendEvent(UpdateEventType.StatusText, Resources.action_refreshing_device_list);
+      SendEvent(UpdateEventType.PollDevices);
+
+      SendEvent(UpdateEventType.ProgressBar, 100);
+      SendEvent(UpdateEventType.StatusText, Resources.ready);
+    }
+
+    private readonly LibCecSharp _lib;
+  }
+}
diff --git a/src/LibCecTray/controller/actions/SendActivateSource.cs b/src/LibCecTray/controller/actions/SendActivateSource.cs
new file mode 100644 (file)
index 0000000..624ddc8
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing       <license@pulse-eight.com>
+ *     http://www.pulse-eight.com/
+ *     http://www.pulse-eight.net/
+ */
+
+using CecSharp;
+using LibCECTray.Properties;
+
+namespace LibCECTray.controller.actions
+{
+  class SendActivateSource : UpdateProcess
+  {
+    public SendActivateSource(LibCecSharp lib, CecLogicalAddress address)
+    {
+      _lib = lib;
+      _address = address;
+    }
+
+    public override void Process()
+    {
+      SendEvent(UpdateEventType.StatusText, string.Format(string.Format(Resources.action_sending_command_to, _lib.ToString(CecOpcode.SetStreamPath), _lib.ToString(_address))));
+      SendEvent(UpdateEventType.ProgressBar, 50);
+
+      var bResult = _lib.SetStreamPath(_address);
+      SendEvent(UpdateEventType.StatusText, bResult ? Resources.command_sent_successfully : string.Format(Resources.command_not_acked, _lib.ToString(CecOpcode.SetStreamPath)));
+      SendEvent(UpdateEventType.ProgressBar, 100);
+    }
+
+    private readonly LibCecSharp _lib;
+    private readonly CecLogicalAddress _address;
+  }
+}
diff --git a/src/LibCecTray/controller/actions/SendImageViewOn.cs b/src/LibCecTray/controller/actions/SendImageViewOn.cs
new file mode 100644 (file)
index 0000000..69bff63
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing       <license@pulse-eight.com>
+ *     http://www.pulse-eight.com/
+ *     http://www.pulse-eight.net/
+ */
+
+using CecSharp;
+using LibCECTray.Properties;
+
+namespace LibCECTray.controller.actions
+{
+  class SendImageViewOn : UpdateProcess
+  {
+    public SendImageViewOn(LibCecSharp lib, CecLogicalAddress address)
+    {
+      _lib = lib;
+      _address = address;
+    }
+
+    public override void Process()
+    {
+      SendEvent(UpdateEventType.StatusText, string.Format(string.Format(Resources.action_sending_command_to, _lib.ToString(CecOpcode.ImageViewOn), _lib.ToString(_address))));
+      SendEvent(UpdateEventType.ProgressBar, 50);
+
+      var bResult = _lib.PowerOnDevices(_address);
+      SendEvent(UpdateEventType.StatusText, bResult ? Resources.command_sent_successfully : string.Format(Resources.command_not_acked, _lib.ToString(CecOpcode.ImageViewOn)));
+      SendEvent(UpdateEventType.ProgressBar, 100);
+    }
+
+    private readonly LibCecSharp _lib;
+    private readonly CecLogicalAddress _address;
+  }
+}
diff --git a/src/LibCecTray/controller/actions/SendStandby.cs b/src/LibCecTray/controller/actions/SendStandby.cs
new file mode 100644 (file)
index 0000000..500d9ea
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing       <license@pulse-eight.com>
+ *     http://www.pulse-eight.com/
+ *     http://www.pulse-eight.net/
+ */
+
+using CecSharp;
+using LibCECTray.Properties;
+
+namespace LibCECTray.controller.actions
+{
+  class SendStandby : UpdateProcess
+  {
+    public SendStandby(LibCecSharp lib, CecLogicalAddress address)
+    {
+      _lib = lib;
+      _address = address;
+    }
+
+    public override void Process()
+    {
+      SendEvent(UpdateEventType.StatusText, string.Format(string.Format(Resources.action_sending_command_to, _lib.ToString(CecOpcode.Standby), _lib.ToString(_address))));
+      SendEvent(UpdateEventType.ProgressBar, 50);
+
+      var bResult = _lib.StandbyDevices(_address);
+      SendEvent(UpdateEventType.StatusText, bResult ? Resources.command_sent_successfully : string.Format(Resources.command_not_acked, _lib.ToString(CecOpcode.Standby)));
+      SendEvent(UpdateEventType.ProgressBar, 100);
+    }
+
+    private readonly LibCecSharp _lib;
+    private readonly CecLogicalAddress _address;
+  }
+}
diff --git a/src/LibCecTray/controller/actions/ShowDeviceInfo.cs b/src/LibCecTray/controller/actions/ShowDeviceInfo.cs
new file mode 100644 (file)
index 0000000..f64486b
--- /dev/null
@@ -0,0 +1,83 @@
+using CecSharp;
+using LibCECTray.Properties;
+using LibCECTray.ui;
+
+namespace LibCECTray.controller.actions
+{
+  class ShowDeviceInfo : UpdateProcess
+  {
+    public ShowDeviceInfo(CECController controller, LibCecSharp lib, CecLogicalAddress address)
+    {
+      _controller = controller;
+      _lib = lib;
+      _address = address;
+    }
+
+    public virtual void ShowDialog(CecLogicalAddress address, ref LibCecSharp lib,
+      bool devicePresent, CecVendorId vendor, bool isActiveSource, ushort physicalAddress,
+      CecVersion version, CecPowerStatus power, string osdName, string menuLanguage)
+    {
+      DeviceInformation di = new DeviceInformation(_controller, _address, ref _lib, devicePresent, vendor, isActiveSource, physicalAddress, version, power, osdName, menuLanguage);
+      _controller.DisplayDialog(di, false);
+    }
+
+    public override void Process()
+    {
+      CecVendorId vendor = CecVendorId.Unknown;
+      bool isActiveSource = false;
+      ushort physicalAddress = 0xFFFF;
+      CecVersion version = CecVersion.Unknown;
+      CecPowerStatus power = CecPowerStatus.Unknown;
+      string osdName = Resources.unknown;
+      string menuLanguage = Resources.unknown;
+
+      SendEvent(UpdateEventType.StatusText, string.Format(Resources.action_check_device_present, _lib.ToString(_address)));
+      SendEvent(UpdateEventType.ProgressBar, 10);
+
+      bool devicePresent = _lib.IsActiveDevice(_address);
+      if (devicePresent)
+      {
+        SendEvent(UpdateEventType.StatusText, Resources.action_requesting_vendor_id);
+        SendEvent(UpdateEventType.ProgressBar, 20);
+        vendor = _lib.GetDeviceVendorId(_address);
+
+        SendEvent(UpdateEventType.StatusText, Resources.action_requesting_active_source_state);
+        SendEvent(UpdateEventType.ProgressBar, 30);
+        isActiveSource = _lib.IsActiveSource(_address);
+
+        SendEvent(UpdateEventType.StatusText, Resources.action_requesting_physical_address);
+        SendEvent(UpdateEventType.ProgressBar, 40);
+        physicalAddress = _lib.GetDevicePhysicalAddress(_address);
+
+        SendEvent(UpdateEventType.StatusText, Resources.action_requesting_cec_version);
+        SendEvent(UpdateEventType.ProgressBar, 50);
+        version = _lib.GetDeviceCecVersion(_address);
+
+        SendEvent(UpdateEventType.StatusText, Resources.action_requesting_power_status);
+        SendEvent(UpdateEventType.ProgressBar, 60);
+        power = _lib.GetDevicePowerStatus(_address);
+
+        SendEvent(UpdateEventType.StatusText, Resources.action_requesting_osd_name);
+        SendEvent(UpdateEventType.ProgressBar, 70);
+        osdName = _lib.GetDeviceOSDName(_address);
+
+        SendEvent(UpdateEventType.StatusText, Resources.action_requesting_menu_language);
+        SendEvent(UpdateEventType.ProgressBar, 80);
+        menuLanguage = _lib.GetDeviceMenuLanguage(_address);
+      }
+
+      SendEvent(UpdateEventType.StatusText, Resources.action_showing_device_information);
+      SendEvent(UpdateEventType.ProgressBar, 90);
+      SendEvent(UpdateEventType.ProcessCompleted, true);
+
+      ShowDialog(_address, ref _lib, devicePresent, vendor, isActiveSource, physicalAddress, version, power, osdName, menuLanguage);
+
+      SendEvent(UpdateEventType.StatusText, Resources.ready);
+      SendEvent(UpdateEventType.ProgressBar, 100);
+    }
+
+    private readonly CECController _controller;
+    private LibCecSharp _lib;
+    private readonly CecLogicalAddress _address;
+  }
+}
diff --git a/src/LibCecTray/controller/actions/UpdateConfiguration.cs b/src/LibCecTray/controller/actions/UpdateConfiguration.cs
new file mode 100644 (file)
index 0000000..f0ea918
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing       <license@pulse-eight.com>
+ *     http://www.pulse-eight.com/
+ *     http://www.pulse-eight.net/
+ */
+
+using CecSharp;
+using LibCECTray.Properties;
+
+namespace LibCECTray.controller.actions
+{
+  internal sealed class UpdateConfiguration : UpdateProcess
+  {
+    public UpdateConfiguration(LibCecSharp lib, LibCECConfiguration config)
+    {
+      _lib = lib;
+      _config = config;
+    }
+
+    public override void Process()
+    {
+      SendEvent(UpdateEventType.ProgressBar, 10);
+      SendEvent(UpdateEventType.StatusText, Resources.action_setting_new_libcec_configuration);
+
+      _lib.SetConfiguration(_config);
+
+      SendEvent(UpdateEventType.ProgressBar, 100);
+      SendEvent(UpdateEventType.StatusText, Resources.ready);
+    }
+
+    private readonly LibCecSharp _lib;
+    private readonly LibCECConfiguration _config;
+  }
+}
diff --git a/src/LibCecTray/controller/actions/UpdateConnectedDevice.cs b/src/LibCecTray/controller/actions/UpdateConnectedDevice.cs
new file mode 100644 (file)
index 0000000..8c80d40
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing       <license@pulse-eight.com>
+ *     http://www.pulse-eight.com/
+ *     http://www.pulse-eight.net/
+ */
+
+using CecSharp;
+using LibCECTray.Properties;
+
+namespace LibCECTray.controller.actions
+{
+  class UpdateConnectedDevice : UpdateProcess
+  {
+    public UpdateConnectedDevice(LibCecSharp lib, CecLogicalAddress address, int portNumber)
+    {
+      _lib = lib;
+      _address = address;
+      _portNumber = portNumber;
+    }
+
+    public override void Process()
+    {
+      SendEvent(UpdateEventType.StatusText, Resources.action_requesting_physical_address);
+      SendEvent(UpdateEventType.ProgressBar, 0);
+
+      var iPhysicalAddress = _lib.GetDevicePhysicalAddress(_address);
+      SendEvent(UpdateEventType.BaseDevicePhysicalAddress, iPhysicalAddress);
+
+      SendEvent(UpdateEventType.StatusText, Resources.action_setting_new_libcec_configuration);
+      SendEvent(UpdateEventType.ProgressBar, 25);
+
+      if (!_lib.SetHDMIPort(_address, (byte)_portNumber))
+      {
+        SendEvent(UpdateEventType.StatusText, string.Format(Resources.command_not_acked, "SetHDMIPort"));
+      }
+      else
+      {
+        LibCECConfiguration config = new LibCECConfiguration();
+        _lib.GetCurrentConfiguration(config);
+
+        SendEvent(UpdateEventType.StatusText, Resources.action_activating_source);
+        SendEvent(UpdateEventType.ProgressBar, 50);
+        _lib.SetActiveSource(config.DeviceTypes.Types[0]);
+
+        SendEvent(UpdateEventType.StatusText, Resources.action_reading_device_configuration);
+        SendEvent(UpdateEventType.ProgressBar, 75);
+        _lib.GetCurrentConfiguration(config);
+
+        SendEvent(config);
+        SendEvent(UpdateEventType.StatusText, Resources.ready);
+      }
+      SendEvent(UpdateEventType.ProgressBar, 100);
+    }
+
+    private readonly LibCecSharp       _lib;
+    private readonly CecLogicalAddress _address;
+    private readonly int               _portNumber;
+  }
+}
diff --git a/src/LibCecTray/controller/actions/UpdateDeviceInfo.cs b/src/LibCecTray/controller/actions/UpdateDeviceInfo.cs
new file mode 100644 (file)
index 0000000..d0ecaed
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing       <license@pulse-eight.com>
+ *     http://www.pulse-eight.com/
+ *     http://www.pulse-eight.net/
+ */
+
+using CecSharp;
+using LibCECTray.ui;
+
+namespace LibCECTray.controller.actions
+{
+  class UpdateDeviceInfo : ShowDeviceInfo
+  {
+    public UpdateDeviceInfo(CECController controller, LibCecSharp lib, DeviceInformation dialog) :
+      base(controller, lib, dialog.Address)
+    {
+      _dialog = dialog;
+    }
+
+    public override void ShowDialog(CecLogicalAddress address, ref LibCecSharp lib,
+      bool devicePresent, CecVendorId vendor, bool isActiveSource, ushort physicalAddress,
+      CecVersion version, CecPowerStatus power, string osdName, string menuLanguage)
+    {
+      _dialog.Update(devicePresent, vendor, isActiveSource, physicalAddress, version, power, osdName, menuLanguage);
+    }
+
+    private readonly DeviceInformation _dialog;
+  }
+}
diff --git a/src/LibCecTray/controller/actions/UpdateEvent.cs b/src/LibCecTray/controller/actions/UpdateEvent.cs
new file mode 100644 (file)
index 0000000..b9713af
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing       <license@pulse-eight.com>
+ *     http://www.pulse-eight.com/
+ *     http://www.pulse-eight.net/
+ */
+
+using System;
+using CecSharp;
+
+namespace LibCECTray.controller.actions
+{
+  internal enum UpdateEventType
+  {
+    ProcessCompleted,
+    StatusText,
+    ProgressBar,
+    TVVendorId,
+    BaseDevicePhysicalAddress,
+    BaseDevice,
+    HDMIPort,
+    PhysicalAddress,
+    HasAVRDevice,
+    AVRVendorId,
+    Configuration,
+    PollDevices,
+    ExitApplication
+  }
+
+  class UpdateEvent : EventArgs
+  {
+    public UpdateEvent(UpdateEventType type)
+    {
+      Type = type;
+    }
+
+    public UpdateEvent(UpdateEventType type, bool value)
+    {
+      Type = type;
+      BoolValue = value;
+    }
+
+    public UpdateEvent(UpdateEventType type, int value)
+    {
+      Type = type;
+      IntValue = value;
+    }
+
+    public UpdateEvent(UpdateEventType type, string value)
+    {
+      Type = type;
+      StringValue = value;
+    }
+
+    public UpdateEvent(LibCECConfiguration config)
+    {
+      Type = UpdateEventType.Configuration;
+      ConfigValue = config;
+    }
+
+    public UpdateEventType Type;
+    public bool BoolValue;
+    public int IntValue = -1;
+    public string StringValue = String.Empty;
+    public LibCECConfiguration ConfigValue;
+  }
+
+  internal abstract class UpdateProcess
+  {
+    public void SendEvent(UpdateEventType type)
+    {
+      if (EventHandler != null)
+        EventHandler(this, new UpdateEvent(type));
+    }
+
+    public void SendEvent(UpdateEventType type, bool value)
+    {
+      if (EventHandler != null)
+        EventHandler(this, new UpdateEvent(type, value));
+    }
+
+    public void SendEvent(UpdateEventType type, int value)
+    {
+      if (EventHandler != null)
+        EventHandler(this, new UpdateEvent(type, value));
+    }
+
+    public void SendEvent(UpdateEventType type, string value)
+    {
+      if (EventHandler != null)
+        EventHandler(this, new UpdateEvent(type, value));
+    }
+
+    public void SendEvent(LibCECConfiguration config)
+    {
+      if (EventHandler != null)
+        EventHandler(this, new UpdateEvent(config));
+    }
+
+    public void Run()
+    {
+      Process();
+      SendEvent(UpdateEventType.ProcessCompleted, true);
+    }
+
+    public abstract void Process();
+    public event EventHandler<UpdateEvent> EventHandler;
+  }
+}
diff --git a/src/LibCecTray/controller/actions/UpdatePhysicalAddress.cs b/src/LibCecTray/controller/actions/UpdatePhysicalAddress.cs
new file mode 100644 (file)
index 0000000..d35fdce
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing       <license@pulse-eight.com>
+ *     http://www.pulse-eight.com/
+ *     http://www.pulse-eight.net/
+ */
+
+using CecSharp;
+using LibCECTray.Properties;
+
+namespace LibCECTray.controller.actions
+{
+  class UpdatePhysicalAddress : UpdateProcess
+  {
+    public UpdatePhysicalAddress(LibCecSharp lib, ushort physicalAddress)
+    {
+      _lib = lib;
+      _physicalAddress = physicalAddress;
+    }
+
+    public override void Process()
+    {
+      SendEvent(UpdateEventType.BaseDevicePhysicalAddress, 0);
+      SendEvent(UpdateEventType.StatusText, Resources.action_setting_new_libcec_configuration);
+      SendEvent(UpdateEventType.ProgressBar, 25);
+
+      if (!_lib.SetPhysicalAddress(_physicalAddress))
+      {
+        SendEvent(UpdateEventType.StatusText, string.Format(Resources.command_not_acked, "SetPhysicalAddress"));
+      }
+      else
+      {
+        LibCECConfiguration config = new LibCECConfiguration();
+        _lib.GetCurrentConfiguration(config);
+
+        SendEvent(UpdateEventType.StatusText, Resources.action_activating_source);
+        SendEvent(UpdateEventType.ProgressBar, 50);
+        _lib.SetActiveSource(config.DeviceTypes.Types[0]);
+
+        SendEvent(UpdateEventType.StatusText, Resources.action_reading_device_configuration);
+        SendEvent(UpdateEventType.ProgressBar, 75);
+        _lib.GetCurrentConfiguration(config);
+
+        SendEvent(config);
+        SendEvent(UpdateEventType.StatusText, Resources.ready);
+      }
+      SendEvent(UpdateEventType.ProgressBar, 100);
+    }
+
+    private readonly LibCecSharp _lib;
+    private readonly ushort _physicalAddress;
+  }
+}
diff --git a/src/LibCecTray/controller/applications/ApplicationController.cs b/src/LibCecTray/controller/applications/ApplicationController.cs
new file mode 100644 (file)
index 0000000..7d0b23d
--- /dev/null
@@ -0,0 +1,399 @@
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing       <license@pulse-eight.com>
+ *     http://www.pulse-eight.com/
+ *     http://www.pulse-eight.net/
+ */
+
+using System;
+using System.Diagnostics;
+using System.Drawing;
+using System.IO;
+using System.Windows.Forms;
+using CecSharp;
+using LibCECTray.Properties;
+using LibCECTray.settings;
+using Timer = System.Timers.Timer;
+
+namespace LibCECTray.controller.applications
+{
+  public delegate void OnApplicationRunningChanged(bool running);
+
+  /// <summary>
+  /// Controls an application on the PC: send key presses, open the application, close it, etc.
+  /// </summary>
+  class ApplicationController
+  {
+    public ApplicationController(CECSettings settings, string uiName, string processName, string filename, string workingDirectory)
+    {
+      Settings = settings;
+      UiName = uiName;
+      ProcessName = processName;
+      ApplicationFilename = filename;
+      ApplicationWorkingDirectory = workingDirectory;
+      SuppressApplicationStart = false;
+      IsInternal = false;
+    }
+
+    public static ApplicationController FromString(CECSettings settings, string serialisedConfig)
+    {
+      var splitString = serialisedConfig.Split(';');
+      if (splitString.Length != 4)
+        throw new InvalidDataException("incorrect number of parameters");
+
+      return new ApplicationController(settings, splitString[0], splitString[1], splitString[2], splitString[3]);
+    }
+
+    public string AsString()
+    {
+      return string.Format("{0};{1};{2};{3}", UiName, ProcessName, ApplicationFilename, ApplicationWorkingDirectory);
+    }
+
+    public void BindButtonConfiguration(DataGridView gridView, BindingSource bindingSource)
+    {
+      CecButtonGridView = gridView;
+
+      DataGridViewCell buttonCellTemplate = new DataGridViewTextBoxCell();
+      CecButtonGridView.Columns.Add(new DataGridViewColumn(buttonCellTemplate)
+                                      {
+                                        DataPropertyName = "CecButtonName",
+                                        Name = Resources.config_cec_button,
+                                        ReadOnly = true,
+                                        Width = 150
+                                      });
+
+      DataGridViewButtonCell mappedToCellTemplate = new DataGridViewButtonCell();
+      CecButtonGridView.Columns.Add(new DataGridViewColumn(mappedToCellTemplate)
+                                      {
+                                        DataPropertyName = "MappedButtonName",
+                                        Name = Resources.config_button_mapped_to,
+                                        ReadOnly = true,
+                                        Width = 350
+                                      });
+
+      bindingSource.DataSource = ButtonConfig;
+      CecButtonGridView.DataSource = bindingSource;
+
+      gridView.CellFormatting += delegate(object sender, DataGridViewCellFormattingEventArgs args)
+                                   {
+                                     DataGridView grid = sender as DataGridView;
+                                     var data = grid != null ? grid.Rows[args.RowIndex].DataBoundItem as CecButtonConfigItem : null;
+                                     if (data == null || !data.Enabled)
+                                     {
+                                       args.CellStyle.ForeColor = Color.Gray;
+                                     }
+                                   };
+
+      gridView.CellClick += delegate(object sender, DataGridViewCellEventArgs args)
+                              {
+                                var item = args.RowIndex < ButtonConfig.Count ? ButtonConfig[args.RowIndex] : null;
+                                if (item == null)
+                                  return;
+                                (new CecButtonConfigUI(item)).ShowDialog();
+                              };
+
+      foreach (var item in _buttonConfig)
+      {
+        item.SettingChanged += delegate
+                                 {
+                                   gridView.Refresh();
+                                 };
+      }
+    }
+
+    #region Start and stop the application
+    /// <summary>
+    /// Check if the application is running
+    /// </summary>
+    /// <returns>True when running, false otherwise</returns>
+    public virtual bool IsRunning()
+    {
+      return FindInstance() != IntPtr.Zero;
+    }
+
+    /// <summary>
+    /// Start the application if it's not running already, and suppress further starts for 5 seconds
+    /// </summary>
+    /// <returns>True when started or suppressed, false otherwise</returns>
+    public virtual bool Start(bool bExitAfterStarting)
+    {
+      if (IsRunning())
+      {
+        SetForeground();
+        return true;
+      }
+
+      if (SuppressApplicationStart)
+        return false;
+
+      SuppressApplicationStart = true;
+      Timer timer = new Timer {Interval = 5000, AutoReset = false};
+      timer.Elapsed += delegate { SuppressApplicationStart = false; };
+      timer.Start();
+
+      try
+      {
+        using (
+          Process runningProcess = new Process
+                                     {
+                                       StartInfo =
+                                         {
+                                           WorkingDirectory = ApplicationWorkingDirectory,
+                                           FileName = ApplicationFilename
+                                         }
+                                     })
+        {
+          // start maximised if the option is enabled
+          if (StartFullScreen.Value)
+            runningProcess.StartInfo.WindowStyle = ProcessWindowStyle.Maximized;
+
+          runningProcess.Start();
+        }
+      }
+      catch (Exception)
+      {
+        return false;
+      }
+
+      if (bExitAfterStarting)
+        Application.Exit();
+
+      return true;
+    }
+
+    /// <summary>
+    /// Initialise the controller and autostart the application
+    /// </summary>
+    public virtual void Initialise()
+    {
+      Timer timer = new Timer { Interval = 1000, AutoReset = true };
+      timer.Elapsed += delegate { CheckApplicationEnabled(); };
+      timer.Start();
+
+      if (AutoStartApplication.Value)
+        Start(false);
+    }
+
+    public event OnApplicationRunningChanged ApplicationRunningChanged;
+
+    private void CheckApplicationEnabled()
+    {
+      var isRunning = IsRunning();
+      if (isRunning != _applicationRunning && ApplicationRunningChanged != null)
+        ApplicationRunningChanged(isRunning);
+
+      _applicationRunning = isRunning;
+      UiControl.SetStartButtonEnabled(!isRunning && !SuppressApplicationStart);
+    }
+    #endregion
+
+    #region Send input to the application
+    /// <summary>
+    /// Send a keypress to the application if it's running
+    /// </summary>
+    /// <param name="key">The keypress to send</param>
+    /// <param name="isSelectedTab">True when this tab is currently selected in the UI</param>
+    /// <returns>True when sent, false otherwise</returns>
+    public virtual bool SendKey(CecKeypress key, bool isSelectedTab)
+    {
+      if (isSelectedTab)
+        UiControl.SelectKeypressRow(UiControl, CecButtonGridView, key);
+
+      if (isSelectedTab && SuppressKeypressWhenSelected.Value)
+        return false;
+
+      if (!ControlApplication.Value)
+        return false;
+
+      var mappedButton = ButtonConfig[key];
+      if (mappedButton == null || mappedButton.Value.Empty())
+        return false;
+
+      var controlWindow = FindInstance();
+      if (controlWindow != IntPtr.Zero && key.Duration == 0)
+        return mappedButton.Value.Transmit(controlWindow);
+
+      return false;
+    }
+    #endregion
+
+    #region Process control
+    /// <summary>
+    /// Make this application the foreground application if it's running
+    /// </summary>
+    public virtual void SetForeground()
+    {
+      var wmcInstance = FindInstance();
+      if (wmcInstance != IntPtr.Zero)
+        WindowsAPI.SetForegroundWindow(wmcInstance);
+    }
+
+    /// <summary>
+    /// The main window handle of the application if it's running.
+    /// </summary>
+    /// <returns>The main window handle, or IntPtr.Zero if it's not found</returns>
+    protected virtual IntPtr FindInstance()
+    {
+      var processes = Process.GetProcessesByName(ProcessName);
+      return processes.Length > 0 ? processes[0].MainWindowHandle : IntPtr.Zero;
+    }
+    #endregion
+
+    #region Members
+    /// <summary>
+    /// The name of the process in the process manager
+    /// </summary>
+    public string ProcessName { set; get; }
+
+    /// <summary>
+    /// The filename of the application
+    /// </summary>
+    public string ApplicationFilename { set; get; }
+
+    /// <summary>
+    /// The working directory of the application
+    /// </summary>
+    public string ApplicationWorkingDirectory { set; get; }
+
+    /// <summary>
+    /// Don't start the application while true
+    /// </summary>
+    public bool SuppressApplicationStart { get; private set; }
+
+    /// <summary>
+    /// The name of the application how it shows up in this application
+    /// </summary>
+    public string UiName { set; get; }
+
+    /// <summary>
+    /// True when this application should be autostarted when this application is activated, or made the active source
+    /// </summary>
+    public CECSettingBool AutoStartApplication
+    {
+      get
+      {
+        if (!Settings.ContainsKey(ProcessName + "_autostart"))
+        {
+          CECSettingBool setting = new CECSettingBool(ProcessName + "_autostart", "Autostart application", false, null);
+          Settings.Load(setting);
+          Settings[ProcessName + "_autostart"] = setting;
+        }
+        return Settings[ProcessName + "_autostart"].AsSettingBool;
+      }
+    }
+
+    /// <summary>
+    /// True when keypresses should be routed to this application
+    /// </summary>
+    public CECSettingBool ControlApplication
+    {
+      get
+      {
+        if (!Settings.ContainsKey(ProcessName + "_control"))
+        {
+          CECSettingBool setting = new CECSettingBool(ProcessName + "_control", "Control application", true, null);
+          Settings.Load(setting);
+          Settings[ProcessName + "_control"] = setting;
+        }
+        return Settings[ProcessName + "_control"].AsSettingBool;
+      }
+    }
+
+    /// <summary>
+    /// True when this application should be autostarted when this application is activated, or made the active source
+    /// </summary>
+    public CECSettingBool SuppressKeypressWhenSelected
+    {
+      get
+      {
+        if (!Settings.ContainsKey(ProcessName + "_suppress_when_selected"))
+        {
+          CECSettingBool setting = new CECSettingBool(ProcessName + "_suppress_when_selected", "Suppress keypress when this tab is selected", true, null);
+          Settings.Load(setting);
+          Settings[ProcessName + "_suppress_when_selected"] = setting;
+        }
+        return Settings[ProcessName + "_suppress_when_selected"].AsSettingBool;
+      }
+    }
+
+    /// <summary>
+    /// True when the application should be started in full screen mode
+    /// </summary>
+    public CECSettingBool StartFullScreen
+    {
+      get
+      {
+        if (!Settings.ContainsKey(ProcessName + "_start_fullscreen"))
+        {
+          CECSettingBool setting = new CECSettingBool(ProcessName + "_start_fullscreen", "Start in full screen mode", true, null);
+          Settings.Load(setting);
+          Settings[ProcessName + "_start_fullscreen"] = setting;
+        }
+        return Settings[ProcessName + "_start_fullscreen"].AsSettingBool;
+      }
+    }
+
+    protected ControllerTabPage UIControlInternal;
+    public virtual ControllerTabPage UiControl
+    {
+      get { return UIControlInternal ?? (UIControlInternal = new ApplicationControllerUI(this)); }
+    }
+
+    private CecButtonConfig _buttonConfig;
+    public CecButtonConfig ButtonConfig
+    {
+      get { return _buttonConfig ?? (_buttonConfig = new CecButtonConfig(this)); }
+    }
+
+    public CECSettings Settings;
+    protected DataGridView CecButtonGridView;
+
+    public virtual ApplicationAction DefaultValue(CecKeypress key)
+    {
+      return null;
+    }
+
+    public virtual bool HasDefaultValue(CecKeypress key)
+    {
+      return DefaultValue(key) != null;
+    }
+
+    public bool IsInternal { protected set; get; }
+    public bool CanConfigureProcess
+    {
+      get
+      {
+        return !IsInternal;
+      }
+    }
+
+    private bool _applicationRunning;
+
+    #endregion
+  }
+}
diff --git a/src/LibCecTray/controller/applications/ApplicationControllerUI.Designer.cs b/src/LibCecTray/controller/applications/ApplicationControllerUI.Designer.cs
new file mode 100644 (file)
index 0000000..5850fae
--- /dev/null
@@ -0,0 +1,159 @@
+namespace LibCECTray.controller.applications
+{
+  partial class ApplicationControllerUI
+  {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing)
+    {
+      if (disposing && (components != null))
+      {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent()
+    {
+      this.components = new System.ComponentModel.Container();
+      this.cbAutoStartApplication = new System.Windows.Forms.CheckBox();
+      this.bStartApplication = new System.Windows.Forms.Button();
+      this.cbControlApplication = new System.Windows.Forms.CheckBox();
+      this.dgButtonConfig = new System.Windows.Forms.DataGridView();
+      this.buttonBindingSource = new System.Windows.Forms.BindingSource(this.components);
+      this.cbSuppressKeypress = new System.Windows.Forms.CheckBox();
+      this.bConfigure = new System.Windows.Forms.Button();
+      this.cbStartFullScreen = new System.Windows.Forms.CheckBox();
+      ((System.ComponentModel.ISupportInitialize)(this.dgButtonConfig)).BeginInit();
+      ((System.ComponentModel.ISupportInitialize)(this.buttonBindingSource)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // cbAutoStartApplication
+      // 
+      this.cbAutoStartApplication.AutoSize = true;
+      this.cbAutoStartApplication.Checked = true;
+      this.cbAutoStartApplication.CheckState = System.Windows.Forms.CheckState.Checked;
+      this.cbAutoStartApplication.Enabled = false;
+      this.cbAutoStartApplication.Location = new System.Drawing.Point(131, 14);
+      this.cbAutoStartApplication.Name = "cbAutoStartApplication";
+      this.cbAutoStartApplication.Size = new System.Drawing.Size(91, 17);
+      this.cbAutoStartApplication.TabIndex = 38;
+      this.cbAutoStartApplication.Text = "app_autostart";
+      this.cbAutoStartApplication.UseVisualStyleBackColor = true;
+      // 
+      // bStartApplication
+      // 
+      this.bStartApplication.Enabled = false;
+      this.bStartApplication.Location = new System.Drawing.Point(12, 318);
+      this.bStartApplication.Name = "bStartApplication";
+      this.bStartApplication.Size = new System.Drawing.Size(119, 23);
+      this.bStartApplication.TabIndex = 37;
+      this.bStartApplication.Text = "Start application";
+      this.bStartApplication.UseVisualStyleBackColor = true;
+      this.bStartApplication.Click += new System.EventHandler(this.BStartApplicationClick);
+      // 
+      // cbControlApplication
+      // 
+      this.cbControlApplication.AutoSize = true;
+      this.cbControlApplication.Checked = true;
+      this.cbControlApplication.CheckState = System.Windows.Forms.CheckState.Checked;
+      this.cbControlApplication.Enabled = false;
+      this.cbControlApplication.Location = new System.Drawing.Point(12, 14);
+      this.cbControlApplication.Name = "cbControlApplication";
+      this.cbControlApplication.Size = new System.Drawing.Size(82, 17);
+      this.cbControlApplication.TabIndex = 36;
+      this.cbControlApplication.Text = "app_control";
+      this.cbControlApplication.UseVisualStyleBackColor = true;
+      // 
+      // dgButtonConfig
+      // 
+      this.dgButtonConfig.AllowUserToAddRows = false;
+      this.dgButtonConfig.AllowUserToDeleteRows = false;
+      this.dgButtonConfig.AutoGenerateColumns = false;
+      this.dgButtonConfig.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
+      this.dgButtonConfig.DataSource = this.buttonBindingSource;
+      this.dgButtonConfig.Location = new System.Drawing.Point(12, 60);
+      this.dgButtonConfig.Name = "dgButtonConfig";
+      this.dgButtonConfig.Size = new System.Drawing.Size(566, 252);
+      this.dgButtonConfig.TabIndex = 40;
+      // 
+      // cbSuppressKeypress
+      // 
+      this.cbSuppressKeypress.AutoSize = true;
+      this.cbSuppressKeypress.Checked = true;
+      this.cbSuppressKeypress.CheckState = System.Windows.Forms.CheckState.Checked;
+      this.cbSuppressKeypress.Enabled = false;
+      this.cbSuppressKeypress.Location = new System.Drawing.Point(262, 14);
+      this.cbSuppressKeypress.Name = "cbSuppressKeypress";
+      this.cbSuppressKeypress.Size = new System.Drawing.Size(170, 17);
+      this.cbSuppressKeypress.TabIndex = 41;
+      this.cbSuppressKeypress.Text = "app_suppress_when_selected";
+      this.cbSuppressKeypress.UseVisualStyleBackColor = true;
+      // 
+      // bConfigure
+      // 
+      this.bConfigure.Location = new System.Drawing.Point(503, 8);
+      this.bConfigure.Name = "bConfigure";
+      this.bConfigure.Size = new System.Drawing.Size(75, 23);
+      this.bConfigure.TabIndex = 42;
+      this.bConfigure.Text = "Configure";
+      this.bConfigure.UseVisualStyleBackColor = true;
+      this.bConfigure.Click += new System.EventHandler(this.BConfigureClick);
+      // 
+      // cbStartFullScreen
+      // 
+      this.cbStartFullScreen.AutoSize = true;
+      this.cbStartFullScreen.Checked = true;
+      this.cbStartFullScreen.CheckState = System.Windows.Forms.CheckState.Checked;
+      this.cbStartFullScreen.Enabled = false;
+      this.cbStartFullScreen.Location = new System.Drawing.Point(12, 37);
+      this.cbStartFullScreen.Name = "cbStartFullScreen";
+      this.cbStartFullScreen.Size = new System.Drawing.Size(121, 17);
+      this.cbStartFullScreen.TabIndex = 43;
+      this.cbStartFullScreen.Text = "app_start_fullscreen";
+      this.cbStartFullScreen.UseVisualStyleBackColor = true;
+      // 
+      // ApplicationControllerUI
+      // 
+      this.ClientSize = new System.Drawing.Size(576, 306);
+      this.Controls.Add(this.cbStartFullScreen);
+      this.Controls.Add(this.bConfigure);
+      this.Controls.Add(this.cbSuppressKeypress);
+      this.Controls.Add(this.dgButtonConfig);
+      this.Controls.Add(this.cbAutoStartApplication);
+      this.Controls.Add(this.bStartApplication);
+      this.Controls.Add(this.cbControlApplication);
+      this.Name = "ApplicationControllerUI";
+      ((System.ComponentModel.ISupportInitialize)(this.dgButtonConfig)).EndInit();
+      ((System.ComponentModel.ISupportInitialize)(this.buttonBindingSource)).EndInit();
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.CheckBox cbAutoStartApplication;
+    private System.Windows.Forms.Button bStartApplication;
+    private System.Windows.Forms.CheckBox cbControlApplication;
+    private System.Windows.Forms.DataGridView dgButtonConfig;
+    private System.Windows.Forms.BindingSource buttonBindingSource;
+    private System.Windows.Forms.CheckBox cbSuppressKeypress;
+    private System.Windows.Forms.Button bConfigure;
+    private System.Windows.Forms.CheckBox cbStartFullScreen;
+
+  }
+}
diff --git a/src/LibCecTray/controller/applications/ApplicationControllerUI.cs b/src/LibCecTray/controller/applications/ApplicationControllerUI.cs
new file mode 100644 (file)
index 0000000..7ba18f0
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing       <license@pulse-eight.com>
+ *     http://www.pulse-eight.com/
+ *     http://www.pulse-eight.net/
+ */
+
+using System;
+
+namespace LibCECTray.controller.applications
+{
+  partial class ApplicationControllerUI : ControllerTabPage
+  {
+    public ApplicationControllerUI()
+    {
+      InitializeComponent();
+    }
+
+    public ApplicationControllerUI(ApplicationController controller)
+    {
+      _controller = controller;
+      InitializeComponent();
+      Name = controller.UiName;
+      Text = controller.UiName;
+
+      _controller.BindButtonConfiguration(dgButtonConfig, buttonBindingSource);
+      _controller.AutoStartApplication.ReplaceControls(this, Controls, cbAutoStartApplication);
+      _controller.ControlApplication.ReplaceControls(this, Controls, cbControlApplication);
+      _controller.SuppressKeypressWhenSelected.ReplaceControls(this, Controls, cbSuppressKeypress);
+      _controller.StartFullScreen.ReplaceControls(this, Controls, cbStartFullScreen);
+
+      bConfigure.Enabled = _controller.CanConfigureProcess;
+    }
+
+    public override sealed string Text
+    {
+      get { return base.Text; }
+      set { base.Text = value; }
+    }
+
+    private void BStartApplicationClick(object sender, EventArgs e)
+    {
+      bStartApplication.Enabled = false;
+      _controller.Start(false);
+    }
+
+    public override void SetEnabled(bool val)
+    {
+      SetControlEnabled(cbAutoStartApplication, val);
+      SetControlEnabled(cbControlApplication, val);
+      SetControlEnabled(bStartApplication, !_controller.IsRunning() && !_controller.SuppressApplicationStart && val);
+    }
+
+    public override void SetStartButtonEnabled(bool val)
+    {
+      SetControlEnabled(bStartApplication, val);
+    }
+
+    private readonly ApplicationController _controller;
+
+    private void BConfigureClick(object sender, EventArgs e)
+    {
+      bConfigure.Enabled = false;
+      ConfigureApplication appConfig = new ConfigureApplication(_controller);
+      appConfig.Disposed += delegate { bConfigure.Enabled = true; };
+      DisplayDialog(appConfig, false);
+    }
+  }
+}
diff --git a/src/LibCecTray/controller/applications/ApplicationControllerUI.resx b/src/LibCecTray/controller/applications/ApplicationControllerUI.resx
new file mode 100644 (file)
index 0000000..f5c4adb
--- /dev/null
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <metadata name="buttonBindingSource.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>17, 17</value>
+  </metadata>
+</root>
\ No newline at end of file
diff --git a/src/LibCecTray/controller/applications/ApplicationInput.cs b/src/LibCecTray/controller/applications/ApplicationInput.cs
new file mode 100644 (file)
index 0000000..c4c02d9
--- /dev/null
@@ -0,0 +1,441 @@
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing       <license@pulse-eight.com>
+ *     http://www.pulse-eight.com/
+ *     http://www.pulse-eight.net/
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Windows.Forms;
+using CecSharp;
+using LibCECTray.Properties;
+
+namespace LibCECTray.controller.applications
+{
+  /// <summary>
+  /// The type of the action that is executed
+  /// </summary>
+  enum ActionType
+  {
+    Generic = 0,
+    CloseControllerApplication = 1,
+    StartApplication = 2,
+    SendKey = 3
+  }
+
+  /// <summary>
+  /// Class that contains one or more actions that can be executed or sent to the application
+  /// </summary>
+  abstract class ApplicationAction
+  {
+    /// <summary>
+    /// Constructor
+    /// </summary>
+    /// <param name="controller">The controller instance of the application that this action is targeting</param>
+    /// <param name="type">The type of the action that is executed</param>
+    protected ApplicationAction(ApplicationController controller, ActionType type)
+    {
+      Controller = controller;
+      ActionType = type;
+    }
+
+    /// <summary>
+    /// The type of the action that is executed
+    /// </summary>
+    public ActionType ActionType { private set; get; }
+
+    /// <summary>
+    /// Execute the action
+    /// </summary>
+    /// <param name="windowHandle">The window of the application that is targeted</param>
+    /// <returns>True when executed, false otherwise</returns>
+    public abstract bool Transmit(IntPtr windowHandle);
+
+    /// <summary>
+    /// Serialisable string representation of this action
+    /// </summary>
+    /// <returns>The requested string</returns>
+    public abstract string AsString();
+
+    /// <summary>
+    /// String representation of this action in human readable form
+    /// </summary>
+    /// <returns>The requested string</returns>
+    public abstract string AsFriendlyString();
+
+    /// <summary>
+    /// Check whether this action is empty (not doing anything)
+    /// </summary>
+    /// <returns>True when empty, false otherwise</returns>
+    public abstract bool Empty();
+
+    /// <summary>
+    /// Checks whether the given action can be appended to this one.
+    /// </summary>
+    /// <param name="value">The action to check</param>
+    /// <returns>True when it can be appended, false otherwise</returns>
+    public abstract bool CanAppend(ApplicationAction value);
+
+    /// <summary>
+    /// Append the given action to this action, and return the combined result
+    /// </summary>
+    /// <param name="value">The action to append to this one</param>
+    /// <returns>The combined result</returns>
+    public abstract ApplicationAction Append(ApplicationAction value);
+
+    /// <summary>
+    /// Remove item at the given index from this action
+    /// </summary>
+    /// <param name="index">The index of the item to remove</param>
+    /// <returns>True when removed, false otherwise</returns>
+    public abstract ApplicationAction RemoveKey(int index);
+
+    /// <summary>
+    /// The prefix to use for serialisation for this type
+    /// </summary>
+    protected string TypePrefix
+    {
+      get { return Enum.GetName(typeof(ActionType), ActionType); }
+    }
+
+    /// <summary>
+    /// Get the parameter value from a string representation of an action of this type
+    /// </summary>
+    /// <param name="value">The value to get the parameter from</param>
+    /// <returns>The parameter</returns>
+    protected string GetParameterFromString(string value)
+    {
+      var trimmedItem = value.Trim();
+      if (!trimmedItem.StartsWith(TypePrefix + "(") || !trimmedItem.EndsWith(")"))
+        return string.Empty;
+
+      return trimmedItem.Substring(TypePrefix.Length + 1, trimmedItem.Length - TypePrefix.Length - 2);
+    }
+
+    protected readonly ApplicationController Controller;
+  }
+
+  /// <summary>
+  /// Closes LibCecTray
+  /// </summary>
+  internal class ApplicationActionCloseController : ApplicationAction
+  {
+    public ApplicationActionCloseController(ApplicationController controller)
+      : base(controller, ActionType.CloseControllerApplication)
+    {
+    }
+
+    public override bool Transmit(IntPtr windowHandle)
+    {
+      Application.Exit();
+      return true;
+    }
+
+    public override string AsString()
+    {
+      return TypePrefix;
+    }
+
+    public override string AsFriendlyString()
+    {
+      return string.Format("[{0}]", Resources.action_type_close_controller_application);
+    }
+
+    public static bool HasDefaultValue(CecKeypress key)
+    {
+      return DefaultValue(key) != null;
+    }
+
+    public static ApplicationAction DefaultValue(CecKeypress key)
+    {
+      switch (key.Keycode)
+      {
+        case CecUserControlCode.Power:
+        case CecUserControlCode.PowerOnFunction:
+        case CecUserControlCode.PowerOffFunction:
+        case CecUserControlCode.PowerToggleFunction:
+          return new ApplicationActionCloseController(null);
+      }
+      return null;
+    }
+
+    public override bool Empty()
+    {
+      return false;
+    }
+
+    public override bool CanAppend(ApplicationAction value)
+    {
+      return false;
+    }
+
+    public override ApplicationAction Append(ApplicationAction value)
+    {
+      return this;
+    }
+
+    public override ApplicationAction RemoveKey(int index)
+    {
+      return null;
+    }
+
+    public static ApplicationAction FromString(ApplicationController controller, string value)
+    {
+      ApplicationActionCloseController retVal = new ApplicationActionCloseController(controller);
+      return value.Trim().Equals(retVal.AsString()) ? retVal : null;
+    }
+  }
+
+  /// <summary>
+  /// Starts an application
+  /// </summary>
+  internal class ApplicationActionStart : ApplicationAction
+  {
+    public ApplicationActionStart(ApplicationController controller) :
+      base(controller, ActionType.StartApplication)
+    {
+    }
+
+    public override bool Transmit(IntPtr windowHandle)
+    {
+      return Controller.Start(false);
+    }
+
+    public override string AsString()
+    {
+      return TypePrefix;
+    }
+
+    public override string AsFriendlyString()
+    {
+      return string.Format("[{0}]", Resources.action_type_start_application);
+    }
+
+    public override bool Empty()
+    {
+      return false;
+    }
+
+    public override bool CanAppend(ApplicationAction value)
+    {
+      return false;
+    }
+
+    public override ApplicationAction Append(ApplicationAction value)
+    {
+      return this;
+    }
+
+    public override ApplicationAction RemoveKey(int index)
+    {
+      return null;
+    }
+
+    public static ApplicationAction FromString(ApplicationController controller, string value)
+    {
+      ApplicationActionStart retVal = new ApplicationActionStart(controller);
+      return value.Trim().Equals(retVal.AsString()) ? retVal : null;
+    }
+
+    public static bool HasDefaultValue(CecKeypress key)
+    {
+      return DefaultValue(key) != null;
+    }
+
+    public static ApplicationAction DefaultValue(CecKeypress key)
+    {
+      return null;
+    }
+  }
+
+  /// <summary>
+  /// Sends one or more actions to an application
+  /// </summary>
+  internal class ApplicationInput : ApplicationAction
+  {
+    public ApplicationInput(ApplicationController controller) :
+      base(controller, ActionType.Generic)
+    {
+    }
+
+    public static string FriendlyActionName(ActionType type)
+    {
+      switch (type)
+      {
+        case ActionType.Generic:
+          return Resources.action_type_generic;
+        case ActionType.CloseControllerApplication:
+          return Resources.action_type_close_controller_application;
+        case ActionType.StartApplication:
+          return Resources.action_type_start_application;
+        case ActionType.SendKey:
+          return Resources.action_type_sendkey;
+        default:
+          return type.ToString();
+      }
+    }
+
+    public static ApplicationAction DefaultValue(ApplicationController controller, CecKeypress key)
+    {
+      return controller.HasDefaultValue(key) ? controller.DefaultValue(key) : new ApplicationInput(null);
+    }
+
+    public override bool Empty()
+    {
+      foreach (var item in _input)
+        if (!item.Empty())
+          return false;
+      return true;
+    }
+
+    public override bool CanAppend(ApplicationAction value)
+    {
+      return true;
+    }
+
+    public override ApplicationAction Append(ApplicationAction value)
+    {
+      if (value.Empty())
+        return this;
+
+      var added = false;
+      if (_input.Count > 0)
+      {
+        if (_input[_input.Count - 1].CanAppend(value))
+        {
+          _input[_input.Count - 1].Append(value);
+          added = true;
+        }
+      }
+      if (!added)
+        _input.Add(value);
+
+      return this;
+    }
+
+    public override bool Transmit(IntPtr windowHandle)
+    {
+      var retval = true;
+      foreach (var input in _input)
+      {
+        retval &= input.Transmit(windowHandle);
+      }
+      return retval;
+    }
+
+    public override string AsString()
+    {
+      StringBuilder sb = new StringBuilder();
+      foreach (var input in _input)
+      {
+        sb.AppendFormat("{0} ", input.AsString());
+      }
+      return sb.ToString().TrimEnd();
+    }
+
+    public override string AsFriendlyString()
+    {
+      StringBuilder sb = new StringBuilder();
+      foreach (var input in _input)
+        sb.AppendFormat("{0} ", input.AsFriendlyString());
+      return sb.ToString().Trim();
+    }
+
+    public override ApplicationAction RemoveKey(int index)
+    {
+      var ptr = 0;
+      for (var itemPtr = 0; itemPtr < _input.Count; itemPtr++)
+      {
+        var item = _input[itemPtr];
+        var currentPtr = item.AsFriendlyString().Length;
+        if (index <= ptr + currentPtr)
+        {
+          var newItem = item.RemoveKey(index - ptr);
+          if (newItem == null || newItem.Empty())
+            _input.Remove(item);
+          else
+            _input[itemPtr] = newItem;
+          break;
+        }
+        ptr += currentPtr;
+      }
+      return this;
+    }
+
+    public ApplicationInput RemoveItem(int index)
+    {
+      return RemoveKey(index) as ApplicationInput;
+    }
+
+    public static ApplicationInput FromString(ApplicationController controller, string value)
+    {
+      ApplicationInput retVal = new ApplicationInput(controller);
+      var split = value.Trim().Split(' ');
+      foreach (var item in split)
+      {
+        var addAction = KeyInput.FromString(controller, item);
+
+        if (addAction == null || addAction.Empty())
+          addAction = ApplicationActionCloseController.FromString(controller, item);
+
+        if (addAction == null || addAction.Empty())
+          addAction = ApplicationActionStart.FromString(controller, item);
+
+        if (addAction != null && !addAction.Empty())
+          retVal.Append(addAction);
+      }
+      return retVal;
+    }
+
+    public ApplicationInput AddKey(WindowsAPI.VirtualKeyCode keyCode)
+    {
+      var key = new KeyInput(Controller, keyCode);
+      if (!key.Empty())
+        Append(key);
+      return this;
+    }
+
+    public ApplicationInput AddAction(ActionType action)
+    {
+      switch (action)
+      {
+        case ActionType.CloseControllerApplication:
+          Append(new ApplicationActionCloseController(Controller));
+          break;
+        case ActionType.StartApplication:
+          Append(new ApplicationActionStart(Controller));
+          break;
+      }
+      return this;
+    }
+
+    private readonly List<ApplicationAction> _input = new List<ApplicationAction>();
+  }
+}
diff --git a/src/LibCecTray/controller/applications/Applications.cs b/src/LibCecTray/controller/applications/Applications.cs
new file mode 100644 (file)
index 0000000..0b1d26f
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing       <license@pulse-eight.com>
+ *     http://www.pulse-eight.com/
+ *     http://www.pulse-eight.net/
+ */
+
+using System.Collections.Generic;
+using System.Text;
+using LibCECTray.controller.applications.@internal;
+using LibCECTray.settings;
+
+namespace LibCECTray.controller.applications
+{
+  class Applications : CECSettingString
+  {
+    private Applications() :
+      base("global_applications", "Applications", string.Empty, null)
+    {
+    }
+
+    public static ApplicationController Get(string key)
+    {
+      return (_instance != null && _instance.Value.ContainsKey(key))
+               ? _instance.Value[key]
+               : null;
+    }
+
+    public static List<ApplicationController> GetAll()
+    {
+      List<ApplicationController> retVal = new List<ApplicationController>();
+      if (_instance != null)
+      {
+        foreach (var app in _instance.Value.Values)
+          retVal.Add(app);
+      }
+      return retVal;
+    }
+
+    public new Dictionary<string, ApplicationController> Value
+    {
+      get
+      {
+        if (_controllers == null)
+        {
+          _controllers = DefaultValue;
+          var split = base.Value.Split('~');
+          foreach (var item in split)
+          {
+            if (item.Length > 0)
+            {
+              var app = ApplicationController.FromString(_controller.Settings, item);
+              if (app != null)
+                _controllers.Add(app.ProcessName, app);
+            }
+          }
+        }
+
+        return _controllers;
+      }
+
+      set
+      {
+        StringBuilder sb = new StringBuilder();
+        foreach (var app in value.Values)
+        {
+          sb.AppendFormat("{0}~", app.AsString());
+        }
+        base.Value = sb.ToString();
+      }
+    }
+
+    public new Dictionary<string, ApplicationController> DefaultValue
+    {
+      get
+      {
+        var defaultValues = new Dictionary<string, ApplicationController>();
+        WMCController wmcController = new WMCController(_controller.Settings);
+        defaultValues.Add(wmcController.ProcessName, wmcController);
+        XBMCController xbmcController = new XBMCController(_controller.Settings);
+        defaultValues.Add(xbmcController.ProcessName, xbmcController);
+
+        return defaultValues;
+      }
+
+      set
+      {
+        StringBuilder sb = new StringBuilder();
+        foreach (var app in value.Values)
+        {
+          sb.AppendFormat("{0}~", app.AsString());
+        }
+        base.DefaultValue = sb.ToString();
+      }
+    }
+
+    public static void Initialise(CECController controller)
+    {
+      _controller = controller;
+      _instance = new Applications();
+      controller.Settings["global_applications"] = _instance;
+      controller.Settings.Load(_instance);
+
+      foreach (var app in _instance.Value)
+        _controller.RegisterApplication(app.Value);
+    }
+
+    private static Applications _instance;
+    private static CECController _controller;
+    private Dictionary<string, ApplicationController> _controllers;
+  }
+}
diff --git a/src/LibCecTray/controller/applications/CecButtonConfig.cs b/src/LibCecTray/controller/applications/CecButtonConfig.cs
new file mode 100644 (file)
index 0000000..35300bd
--- /dev/null
@@ -0,0 +1,321 @@
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing       <license@pulse-eight.com>
+ *     http://www.pulse-eight.com/
+ *     http://www.pulse-eight.net/
+ */
+
+using System.Collections.Generic;
+using CecSharp;
+using LibCECTray.settings;
+using System;
+
+namespace LibCECTray.controller.applications
+{
+  class CecButtonConfigItem : CECSettingString
+  {
+    public CecButtonConfigItem(ApplicationController controller, CecKeypress key) :
+      base(CECSettingType.Button, null, ButtonName(key.Keycode), ApplicationInput.DefaultValue(controller, key).AsString(), null)
+    {
+      Key = key;
+    }
+
+    public new ApplicationInput Value
+    {
+      get
+      {
+        return base.Value != null
+                 ? ApplicationInput.FromString(Controller, base.Value)
+                 : new ApplicationInput(Controller);
+      }
+      set
+      {
+        base.Value = value == null ? null : value.AsString();
+      }
+    }
+
+    public new ApplicationInput DefaultValue
+    {
+      get { return base.DefaultValue != null ? ApplicationInput.FromString(Controller, base.DefaultValue) : null; }
+      set { base.DefaultValue = value.AsString(); }
+    }
+
+    public string MappedButtonName
+    {
+      get { return Value == null ? string.Empty : Value.AsFriendlyString(); }
+      set { base.Value = value; }
+    }
+
+    public new bool Enabled
+    {
+      get
+      {
+        return _enabled || !string.IsNullOrEmpty(base.Value);
+      }
+      set
+      {
+        _enabled = value;
+      }
+    }
+    private bool _enabled;
+
+    public string CecButtonName
+    {
+      get { return ButtonName(Key.Keycode); }
+    }
+
+    public void SetController(ApplicationController controller)
+    {
+      Controller = controller;
+      KeyName = string.Format("{0}_key_{1}", controller.ProcessName, (int)Key.Keycode);
+    }
+
+    public static string ButtonName(CecUserControlCode key)
+    {
+      switch (key)
+      {
+        case CecUserControlCode.Select:
+          return "Select";
+        case CecUserControlCode.Up:
+          return "Up";
+        case CecUserControlCode.Down:
+          return "Down";
+        case CecUserControlCode.Left:
+          return "Left";
+        case CecUserControlCode.Right:
+          return "Right";
+        case CecUserControlCode.RightUp:
+          return "Right+Up";
+        case CecUserControlCode.RightDown:
+          return "Right+Down";
+        case CecUserControlCode.LeftUp:
+          return "Left+Up";
+        case CecUserControlCode.LeftDown:
+          return "Left+Down";
+        case CecUserControlCode.RootMenu:
+          return "Root menu";
+        case CecUserControlCode.SetupMenu:
+          return "Setup menu";
+        case CecUserControlCode.ContentsMenu:
+          return "Contents menu";
+        case CecUserControlCode.FavoriteMenu:
+          return "Favourite menu";
+        case CecUserControlCode.Exit:
+          return "Exit";
+        case CecUserControlCode.Number0:
+          return "0";
+        case CecUserControlCode.Number1:
+          return "1";
+        case CecUserControlCode.Number2:
+          return "2";
+        case CecUserControlCode.Number3:
+          return "3";
+        case CecUserControlCode.Number4:
+          return "4";
+        case CecUserControlCode.Number5:
+          return "5";
+        case CecUserControlCode.Number6:
+          return "6";
+        case CecUserControlCode.Number7:
+          return "7";
+        case CecUserControlCode.Number8:
+          return "8";
+        case CecUserControlCode.Number9:
+          return "9";
+        case CecUserControlCode.Dot:
+          return ".";
+        case CecUserControlCode.Enter:
+          return "Enter";
+        case CecUserControlCode.Clear:
+          return "Clear";
+        case CecUserControlCode.NextFavorite:
+          return "Next favourite";
+        case CecUserControlCode.ChannelUp:
+          return "Channel up";
+        case CecUserControlCode.ChannelDown:
+          return "Channel down";
+        case CecUserControlCode.PreviousChannel:
+          return "Previous channel";
+        case CecUserControlCode.SoundSelect:
+          return "Sound select";
+        case CecUserControlCode.InputSelect:
+          return "Input select";
+        case CecUserControlCode.DisplayInformation:
+          return "Display information";
+        case CecUserControlCode.Help:
+          return "Help";
+        case CecUserControlCode.PageUp:
+          return "Page up";
+        case CecUserControlCode.PageDown:
+          return "Page down";
+        case CecUserControlCode.Power:
+          return "Power";
+        case CecUserControlCode.VolumeUp:
+          return "Volume up";
+        case CecUserControlCode.VolumeDown:
+          return "Volume down";
+        case CecUserControlCode.Mute:
+          return "Mute";
+        case CecUserControlCode.Play:
+          return "Play";
+        case CecUserControlCode.Stop:
+          return "Stop";
+        case CecUserControlCode.Pause:
+          return "Pause";
+        case CecUserControlCode.Record:
+          return "Record";
+        case CecUserControlCode.Rewind:
+          return "Rewind";
+        case CecUserControlCode.FastForward:
+          return "Fast forward";
+        case CecUserControlCode.Eject:
+          return "Eject";
+        case CecUserControlCode.Forward:
+          return "Forward";
+        case CecUserControlCode.Backward:
+          return "Backward";
+        case CecUserControlCode.StopRecord:
+          return "Stop record";
+        case CecUserControlCode.PauseRecord:
+          return "Pause record";
+        case CecUserControlCode.Angle:
+          return "Angle";
+        case CecUserControlCode.SubPicture:
+          return "Sub picture";
+        case CecUserControlCode.VideoOnDemand:
+          return "Video on demand";
+        case CecUserControlCode.ElectronicProgramGuide:
+          return "Electronic program guide";
+        case CecUserControlCode.TimerProgramming:
+          return "Timer programming";
+        case CecUserControlCode.InitialConfiguration:
+          return "Initial configuration";
+        case CecUserControlCode.PlayFunction:
+          return "Play (function)";
+        case CecUserControlCode.PausePlayFunction:
+          return "Pause play (function)";
+        case CecUserControlCode.RecordFunction:
+          return "Record (function)";
+        case CecUserControlCode.PauseRecordFunction:
+          return "Pause record (function)";
+        case CecUserControlCode.StopFunction:
+          return "Stop (function)";
+        case CecUserControlCode.MuteFunction:
+          return "Mute (function)";
+        case CecUserControlCode.RestoreVolumeFunction:
+          return "Restore volume";
+        case CecUserControlCode.TuneFunction:
+          return "Tune";
+        case CecUserControlCode.SelectMediaFunction:
+          return "Select media";
+        case CecUserControlCode.SelectAVInputFunction:
+          return "Select AV input";
+        case CecUserControlCode.SelectAudioInputFunction:
+          return "Select audio input";
+        case CecUserControlCode.PowerToggleFunction:
+          return "Power toggle";
+        case CecUserControlCode.PowerOffFunction:
+          return "Power off";
+        case CecUserControlCode.PowerOnFunction:
+          return "Power on";
+        case CecUserControlCode.F1Blue:
+          return "F1 (blue)";
+        case CecUserControlCode.F2Red:
+          return "F2 (red)";
+        case CecUserControlCode.F3Green:
+          return "F3 (green)";
+        case CecUserControlCode.F4Yellow:
+          return "F4 (yellow)";
+        case CecUserControlCode.F5:
+          return "F5";
+        case CecUserControlCode.Data:
+          return "Data";
+        case CecUserControlCode.SamsungReturn:
+          return "Return (Samsung)";
+      }
+      return "Unknown";
+    }
+
+    public CecKeypress Key { get; private set; }
+    public ApplicationController Controller { get; private set; }
+  }
+
+  internal class CecButtonConfig : List<CecButtonConfigItem>
+  {
+    public CecButtonConfig(ApplicationController controller)
+    {
+      _controller = controller;
+
+      foreach (CecUserControlCode key in Enum.GetValues(typeof(CecUserControlCode)))
+        AddConfigItem(new CecButtonConfigItem(controller, (new CecKeypress { Keycode = key })));
+
+      Load();
+    }
+
+    private void AddConfigItem(CecButtonConfigItem item)
+    {
+      if (!HasItem(item) && item.Key.Keycode != CecUserControlCode.Unknown)
+        Add(item);
+    }
+
+    public bool HasItem(CecButtonConfigItem item)
+    {
+      foreach (var entry in  this)
+      {
+        if (item.Key.Keycode == entry.Key.Keycode)
+          return true;
+      }
+      return false;
+    }
+
+    public void Load()
+    {
+      foreach (var item in this)
+      {
+        item.SetController(_controller);
+        _controller.Settings[item.KeyName] = item;
+        _controller.Settings.Load(item);
+      }
+    }
+
+    public CecButtonConfigItem this[CecKeypress key]
+    {
+      get
+      {
+        foreach (var item in this)
+        {
+          if (item.Key.Keycode == key.Keycode)
+            return item;
+        }
+        return null;
+      }
+    }
+
+    private readonly ApplicationController _controller;
+  }
+}
diff --git a/src/LibCecTray/controller/applications/CecButtonConfigUI.Designer.cs b/src/LibCecTray/controller/applications/CecButtonConfigUI.Designer.cs
new file mode 100644 (file)
index 0000000..c552036
--- /dev/null
@@ -0,0 +1,223 @@
+namespace LibCECTray.controller.applications
+{
+  partial class CecButtonConfigUI
+  {
+    /// <summary>
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary>
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing)
+    {
+      if (disposing && (components != null))
+      {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Windows Form Designer generated code
+
+    /// <summary>
+    /// Required method for Designer support - do not modify
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent()
+    {
+      this.components = new System.ComponentModel.Container();
+      this.lButtonName = new System.Windows.Forms.Label();
+      this.tbAction = new System.Windows.Forms.TextBox();
+      this.label1 = new System.Windows.Forms.Label();
+      this.bDefault = new System.Windows.Forms.Button();
+      this.bClose = new System.Windows.Forms.Button();
+      this.label2 = new System.Windows.Forms.Label();
+      this.cbAddKey = new System.Windows.Forms.ComboBox();
+      this.bAddKey = new System.Windows.Forms.Button();
+      this.bClear = new System.Windows.Forms.Button();
+      this.label3 = new System.Windows.Forms.Label();
+      this.label4 = new System.Windows.Forms.Label();
+      this.cbAddAction = new System.Windows.Forms.ComboBox();
+      this.bAddAction = new System.Windows.Forms.Button();
+      this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
+      this.SuspendLayout();
+      // 
+      // lButtonName
+      // 
+      this.lButtonName.AutoSize = true;
+      this.lButtonName.Location = new System.Drawing.Point(91, 9);
+      this.lButtonName.Name = "lButtonName";
+      this.lButtonName.Size = new System.Drawing.Size(72, 13);
+      this.lButtonName.TabIndex = 0;
+      this.lButtonName.Text = "[button name]";
+      // 
+      // tbAction
+      // 
+      this.tbAction.Location = new System.Drawing.Point(79, 32);
+      this.tbAction.Name = "tbAction";
+      this.tbAction.ReadOnly = true;
+      this.tbAction.Size = new System.Drawing.Size(187, 20);
+      this.tbAction.TabIndex = 1;
+      this.toolTip1.SetToolTip(this.tbAction, "click on an entry to remove it");
+      this.tbAction.KeyDown += new System.Windows.Forms.KeyEventHandler(this.ButtonControlCheckSelection);
+      this.tbAction.KeyUp += new System.Windows.Forms.KeyEventHandler(this.ButtonControlCheckSelection);
+      this.tbAction.MouseDown += new System.Windows.Forms.MouseEventHandler(this.ButtonControlCheckSelection);
+      this.tbAction.MouseUp += new System.Windows.Forms.MouseEventHandler(this.ButtonControlCheckSelection);
+      // 
+      // label1
+      // 
+      this.label1.AutoSize = true;
+      this.label1.Location = new System.Drawing.Point(12, 35);
+      this.label1.Name = "label1";
+      this.label1.Size = new System.Drawing.Size(61, 13);
+      this.label1.TabIndex = 2;
+      this.label1.Text = "Mapped to:";
+      // 
+      // bDefault
+      // 
+      this.bDefault.Location = new System.Drawing.Point(15, 125);
+      this.bDefault.Name = "bDefault";
+      this.bDefault.Size = new System.Drawing.Size(75, 23);
+      this.bDefault.TabIndex = 3;
+      this.bDefault.Text = "Default";
+      this.bDefault.UseVisualStyleBackColor = true;
+      this.bDefault.Click += new System.EventHandler(this.BDefaultClick);
+      // 
+      // bClose
+      // 
+      this.bClose.Location = new System.Drawing.Point(178, 125);
+      this.bClose.Name = "bClose";
+      this.bClose.Size = new System.Drawing.Size(75, 23);
+      this.bClose.TabIndex = 4;
+      this.bClose.Text = "Close";
+      this.bClose.UseVisualStyleBackColor = true;
+      this.bClose.Click += new System.EventHandler(this.BCloseClick);
+      // 
+      // label2
+      // 
+      this.label2.AutoSize = true;
+      this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+      this.label2.Location = new System.Drawing.Point(9, 9);
+      this.label2.Name = "label2";
+      this.label2.Size = new System.Drawing.Size(76, 13);
+      this.label2.TabIndex = 5;
+      this.label2.Text = "CEC Button:";
+      // 
+      // cbAddKey
+      // 
+      this.cbAddKey.FormattingEnabled = true;
+      this.cbAddKey.Location = new System.Drawing.Point(79, 58);
+      this.cbAddKey.Name = "cbAddKey";
+      this.cbAddKey.Size = new System.Drawing.Size(150, 21);
+      this.cbAddKey.TabIndex = 6;
+      // 
+      // bAddKey
+      // 
+      this.bAddKey.Location = new System.Drawing.Point(235, 57);
+      this.bAddKey.Name = "bAddKey";
+      this.bAddKey.Size = new System.Drawing.Size(31, 23);
+      this.bAddKey.TabIndex = 7;
+      this.bAddKey.Text = "+";
+      this.bAddKey.UseVisualStyleBackColor = true;
+      this.bAddKey.Click += new System.EventHandler(this.BAddKeyClick);
+      // 
+      // bClear
+      // 
+      this.bClear.Location = new System.Drawing.Point(97, 125);
+      this.bClear.Name = "bClear";
+      this.bClear.Size = new System.Drawing.Size(75, 23);
+      this.bClear.TabIndex = 8;
+      this.bClear.Text = "Clear";
+      this.bClear.UseVisualStyleBackColor = true;
+      this.bClear.Click += new System.EventHandler(this.BClearClick);
+      // 
+      // label3
+      // 
+      this.label3.AutoSize = true;
+      this.label3.Location = new System.Drawing.Point(12, 61);
+      this.label3.Name = "label3";
+      this.label3.Size = new System.Drawing.Size(49, 13);
+      this.label3.TabIndex = 9;
+      this.label3.Text = "Add key:";
+      // 
+      // label4
+      // 
+      this.label4.AutoSize = true;
+      this.label4.Location = new System.Drawing.Point(12, 88);
+      this.label4.Name = "label4";
+      this.label4.Size = new System.Drawing.Size(61, 13);
+      this.label4.TabIndex = 10;
+      this.label4.Text = "Add action:";
+      // 
+      // cbAddAction
+      // 
+      this.cbAddAction.FormattingEnabled = true;
+      this.cbAddAction.Location = new System.Drawing.Point(79, 85);
+      this.cbAddAction.Name = "cbAddAction";
+      this.cbAddAction.Size = new System.Drawing.Size(150, 21);
+      this.cbAddAction.TabIndex = 11;
+      // 
+      // bAddAction
+      // 
+      this.bAddAction.Location = new System.Drawing.Point(235, 83);
+      this.bAddAction.Name = "bAddAction";
+      this.bAddAction.Size = new System.Drawing.Size(31, 23);
+      this.bAddAction.TabIndex = 12;
+      this.bAddAction.Text = "+";
+      this.bAddAction.UseVisualStyleBackColor = true;
+      this.bAddAction.Click += new System.EventHandler(this.BAddActionClick);
+      // 
+      // toolTip1
+      // 
+      this.toolTip1.IsBalloon = true;
+      // 
+      // CecButtonConfigUI
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.ClientSize = new System.Drawing.Size(281, 162);
+      this.Controls.Add(this.bAddAction);
+      this.Controls.Add(this.cbAddAction);
+      this.Controls.Add(this.label4);
+      this.Controls.Add(this.label3);
+      this.Controls.Add(this.bClear);
+      this.Controls.Add(this.bAddKey);
+      this.Controls.Add(this.cbAddKey);
+      this.Controls.Add(this.label2);
+      this.Controls.Add(this.bClose);
+      this.Controls.Add(this.bDefault);
+      this.Controls.Add(this.label1);
+      this.Controls.Add(this.tbAction);
+      this.Controls.Add(this.lButtonName);
+      this.Name = "CecButtonConfigUI";
+      this.ShowIcon = false;
+      this.ShowInTaskbar = false;
+      this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
+      this.Text = "Button configuration";
+      this.TopMost = true;
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.Label lButtonName;
+    private System.Windows.Forms.TextBox tbAction;
+    private System.Windows.Forms.Label label1;
+    private System.Windows.Forms.Button bDefault;
+    private System.Windows.Forms.Button bClose;
+    private System.Windows.Forms.Label label2;
+    private System.Windows.Forms.ComboBox cbAddKey;
+    private System.Windows.Forms.Button bAddKey;
+    private System.Windows.Forms.Button bClear;
+    private System.Windows.Forms.Label label3;
+    private System.Windows.Forms.Label label4;
+    private System.Windows.Forms.ComboBox cbAddAction;
+    private System.Windows.Forms.Button bAddAction;
+    private System.Windows.Forms.ToolTip toolTip1;
+  }
+}
\ No newline at end of file
diff --git a/src/LibCecTray/controller/applications/CecButtonConfigUI.cs b/src/LibCecTray/controller/applications/CecButtonConfigUI.cs
new file mode 100644 (file)
index 0000000..bab8c94
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing       <license@pulse-eight.com>
+ *     http://www.pulse-eight.com/
+ *     http://www.pulse-eight.net/
+ */
+
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using System.Windows.Forms;
+using LibCECTray.ui;
+
+namespace LibCECTray.controller.applications
+{
+  partial class CecButtonConfigUI : Form
+  {
+    public CecButtonConfigUI(CecButtonConfigItem button)
+    {
+      _button = button;
+      InitializeComponent();
+
+      var keys = Enum.GetValues(typeof (WindowsAPI.VirtualKeyCode));
+      string[] friendlyNames = new string[keys.Length];
+      for (int i = 0; i < keys.Length; i++)
+        friendlyNames[i] = WindowsAPI.GetVirtualKeyName((WindowsAPI.VirtualKeyCode)keys.GetValue(i));
+      Array.Sort(friendlyNames);
+      foreach (var item in friendlyNames)
+        cbAddKey.Items.Add(item);
+
+      button.SettingChanged += delegate
+                                 {
+                                   _lastSelectedText = 0;
+                                   tbAction.Text = button.Value.AsFriendlyString().Trim();
+                                 };
+
+      lButtonName.Text = button.Label.Text;
+      tbAction.Text = button.Value.AsFriendlyString().Trim();
+
+      //TODO
+      cbAddAction.Items.Add(ApplicationInput.FriendlyActionName(ActionType.CloseControllerApplication));
+      cbAddAction.Items.Add(ApplicationInput.FriendlyActionName(ActionType.StartApplication));
+
+      // take the icon of the main window
+      ComponentResourceManager resources = new ComponentResourceManager(typeof(CECTray));
+      Icon = resources.GetObject("$this.Icon") as Icon;
+    }
+
+    private void ButtonControlCheckSelection(object sender, MouseEventArgs e)
+    {
+      ButtonControlCheckSelection();
+    }
+
+    private void ButtonControlCheckSelection(object sender, KeyEventArgs e)
+    {
+      ButtonControlCheckSelection();
+    }
+
+    private void ButtonControlCheckSelection()
+    {
+      if (tbAction.SelectionStart != _lastSelectedText)
+      {
+        _lastSelectedText = SelectionChanged(tbAction.SelectionStart) ? 0 : tbAction.SelectionStart;
+      }
+    }
+
+    private bool SelectionChanged(int selection)
+    {
+      _button.Value = _button.Value.RemoveItem(selection);
+      return true;
+    }
+
+    public CecButtonConfigUI()
+    {
+      InitializeComponent();
+    }
+
+    private void BCloseClick(object sender, EventArgs e)
+    {
+      Hide();
+    }
+
+    private void BDefaultClick(object sender, EventArgs e)
+    {
+      _button.Value = _button.DefaultValue;
+    }
+
+    private void BClearClick(object sender, EventArgs e)
+    {
+      _button.Value = null;
+    }
+
+    private void BAddKeyClick(object sender, EventArgs e)
+    {
+      foreach (var item in Enum.GetValues(typeof(WindowsAPI.VirtualKeyCode)))
+      {
+        if (cbAddKey.Text.Equals(WindowsAPI.GetVirtualKeyName((WindowsAPI.VirtualKeyCode)item)))
+        {
+          _button.Value = _button.Value.AddKey((WindowsAPI.VirtualKeyCode) item);
+          break;
+        }
+      }
+    }
+
+    private void BAddActionClick(object sender, EventArgs e)
+    {
+      foreach (var item in Enum.GetValues(typeof(ActionType)))
+      {
+        if (cbAddAction.Text.ToUpper().Equals(ApplicationInput.FriendlyActionName((ActionType)item).ToUpper()))
+        {
+          _button.Value = _button.Value.AddAction((ActionType)item);
+          break;
+        }
+      }
+    }
+
+    private int _lastSelectedText;
+    private readonly CecButtonConfigItem _button;
+  }
+}
diff --git a/src/LibCecTray/controller/applications/CecButtonConfigUI.resx b/src/LibCecTray/controller/applications/CecButtonConfigUI.resx
new file mode 100644 (file)
index 0000000..84f73fc
--- /dev/null
@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <metadata name="toolTip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>17, 17</value>
+  </metadata>
+  <metadata name="toolTip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>17, 17</value>
+  </metadata>
+</root>
\ No newline at end of file
diff --git a/src/LibCecTray/controller/applications/ConfigureApplication.Designer.cs b/src/LibCecTray/controller/applications/ConfigureApplication.Designer.cs
new file mode 100644 (file)
index 0000000..e9724df
--- /dev/null
@@ -0,0 +1,184 @@
+namespace LibCECTray.controller.applications
+{
+  partial class ConfigureApplication
+  {
+    /// <summary>
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary>
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing)
+    {
+      if (disposing && (components != null))
+      {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Windows Form Designer generated code
+
+    /// <summary>
+    /// Required method for Designer support - do not modify
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent()
+    {
+      this.lFilename = new System.Windows.Forms.Label();
+      this.tbFilename = new System.Windows.Forms.TextBox();
+      this.bFindFile = new System.Windows.Forms.Button();
+      this.lProcessName = new System.Windows.Forms.Label();
+      this.tbProcessName = new System.Windows.Forms.TextBox();
+      this.tbWorkingDir = new System.Windows.Forms.TextBox();
+      this.lWorkingDir = new System.Windows.Forms.Label();
+      this.bOK = new System.Windows.Forms.Button();
+      this.bCancel = new System.Windows.Forms.Button();
+      this.tbUiName = new System.Windows.Forms.TextBox();
+      this.lUiName = new System.Windows.Forms.Label();
+      this.SuspendLayout();
+      // 
+      // lFilename
+      // 
+      this.lFilename.AutoSize = true;
+      this.lFilename.Location = new System.Drawing.Point(12, 17);
+      this.lFilename.Name = "lFilename";
+      this.lFilename.Size = new System.Drawing.Size(46, 13);
+      this.lFilename.TabIndex = 0;
+      this.lFilename.Text = "filename";
+      // 
+      // tbFilename
+      // 
+      this.tbFilename.Location = new System.Drawing.Point(93, 14);
+      this.tbFilename.Name = "tbFilename";
+      this.tbFilename.Size = new System.Drawing.Size(229, 20);
+      this.tbFilename.TabIndex = 1;
+      this.tbFilename.Text = "filename";
+      // 
+      // bFindFile
+      // 
+      this.bFindFile.Location = new System.Drawing.Point(328, 12);
+      this.bFindFile.Name = "bFindFile";
+      this.bFindFile.Size = new System.Drawing.Size(44, 23);
+      this.bFindFile.TabIndex = 2;
+      this.bFindFile.Text = "...";
+      this.bFindFile.UseVisualStyleBackColor = true;
+      this.bFindFile.Click += new System.EventHandler(this.BFindFileClick);
+      // 
+      // lProcessName
+      // 
+      this.lProcessName.AutoSize = true;
+      this.lProcessName.Location = new System.Drawing.Point(12, 70);
+      this.lProcessName.Name = "lProcessName";
+      this.lProcessName.Size = new System.Drawing.Size(76, 13);
+      this.lProcessName.TabIndex = 3;
+      this.lProcessName.Text = "process_name";
+      // 
+      // tbProcessName
+      // 
+      this.tbProcessName.Location = new System.Drawing.Point(93, 67);
+      this.tbProcessName.Name = "tbProcessName";
+      this.tbProcessName.Size = new System.Drawing.Size(279, 20);
+      this.tbProcessName.TabIndex = 4;
+      this.tbProcessName.Text = "process_name";
+      // 
+      // tbWorkingDir
+      // 
+      this.tbWorkingDir.Location = new System.Drawing.Point(93, 41);
+      this.tbWorkingDir.Name = "tbWorkingDir";
+      this.tbWorkingDir.Size = new System.Drawing.Size(279, 20);
+      this.tbWorkingDir.TabIndex = 6;
+      this.tbWorkingDir.Text = "working_dir";
+      // 
+      // lWorkingDir
+      // 
+      this.lWorkingDir.AutoSize = true;
+      this.lWorkingDir.Location = new System.Drawing.Point(12, 44);
+      this.lWorkingDir.Name = "lWorkingDir";
+      this.lWorkingDir.Size = new System.Drawing.Size(61, 13);
+      this.lWorkingDir.TabIndex = 5;
+      this.lWorkingDir.Text = "working_dir";
+      // 
+      // bOK
+      // 
+      this.bOK.Location = new System.Drawing.Point(204, 129);
+      this.bOK.Name = "bOK";
+      this.bOK.Size = new System.Drawing.Size(75, 23);
+      this.bOK.TabIndex = 7;
+      this.bOK.Text = "OK";
+      this.bOK.UseVisualStyleBackColor = true;
+      this.bOK.Click += new System.EventHandler(this.BOkClick);
+      // 
+      // bCancel
+      // 
+      this.bCancel.Location = new System.Drawing.Point(91, 129);
+      this.bCancel.Name = "bCancel";
+      this.bCancel.Size = new System.Drawing.Size(75, 23);
+      this.bCancel.TabIndex = 8;
+      this.bCancel.Text = "Cancel";
+      this.bCancel.UseVisualStyleBackColor = true;
+      this.bCancel.Click += new System.EventHandler(this.BCancelClick);
+      // 
+      // tbUiName
+      // 
+      this.tbUiName.Location = new System.Drawing.Point(93, 93);
+      this.tbUiName.Name = "tbUiName";
+      this.tbUiName.Size = new System.Drawing.Size(279, 20);
+      this.tbUiName.TabIndex = 10;
+      this.tbUiName.Text = "ui_name";
+      // 
+      // lUiName
+      // 
+      this.lUiName.AutoSize = true;
+      this.lUiName.Location = new System.Drawing.Point(12, 96);
+      this.lUiName.Name = "lUiName";
+      this.lUiName.Size = new System.Drawing.Size(47, 13);
+      this.lUiName.TabIndex = 9;
+      this.lUiName.Text = "ui_name";
+      // 
+      // ConfigureApplication
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.ClientSize = new System.Drawing.Size(384, 165);
+      this.Controls.Add(this.tbUiName);
+      this.Controls.Add(this.lUiName);
+      this.Controls.Add(this.bCancel);
+      this.Controls.Add(this.bOK);
+      this.Controls.Add(this.tbWorkingDir);
+      this.Controls.Add(this.lWorkingDir);
+      this.Controls.Add(this.tbProcessName);
+      this.Controls.Add(this.lProcessName);
+      this.Controls.Add(this.bFindFile);
+      this.Controls.Add(this.tbFilename);
+      this.Controls.Add(this.lFilename);
+      this.MaximizeBox = false;
+      this.MinimizeBox = false;
+      this.Name = "ConfigureApplication";
+      this.ShowIcon = false;
+      this.ShowInTaskbar = false;
+      this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
+      this.Text = "ConfigureApplication";
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.Label lFilename;
+    private System.Windows.Forms.TextBox tbFilename;
+    private System.Windows.Forms.Button bFindFile;
+    private System.Windows.Forms.Label lProcessName;
+    private System.Windows.Forms.TextBox tbProcessName;
+    private System.Windows.Forms.TextBox tbWorkingDir;
+    private System.Windows.Forms.Label lWorkingDir;
+    private System.Windows.Forms.Button bOK;
+    private System.Windows.Forms.Button bCancel;
+    private System.Windows.Forms.TextBox tbUiName;
+    private System.Windows.Forms.Label lUiName;
+  }
+}
\ No newline at end of file
diff --git a/src/LibCecTray/controller/applications/ConfigureApplication.cs b/src/LibCecTray/controller/applications/ConfigureApplication.cs
new file mode 100644 (file)
index 0000000..3bcd10c
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing       <license@pulse-eight.com>
+ *     http://www.pulse-eight.com/
+ *     http://www.pulse-eight.net/
+ */
+
+using System;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.Drawing;
+using System.IO;
+using System.Windows.Forms;
+using LibCECTray.Properties;
+using LibCECTray.settings;
+using LibCECTray.ui;
+
+namespace LibCECTray.controller.applications
+{
+  partial class ConfigureApplication : Form
+  {
+    public ConfigureApplication(ApplicationController controller) :
+      this(null, null)
+    {
+      _controller = controller;
+      tbFilename.Text = controller.ApplicationFilename;
+      tbWorkingDir.Text = controller.ApplicationWorkingDirectory;
+      tbUiName.Text = controller.UiName;
+      tbProcessName.Text = controller.ProcessName;
+
+      Text = string.Format(Resources.configure_application, controller.UiName);
+
+      if (!_controller.CanConfigureProcess)
+      {
+        tbFilename.Enabled = false;
+        tbWorkingDir.Enabled = false;
+        tbUiName.Enabled = false;
+        tbProcessName.Enabled = false;
+        bFindFile.Enabled = false;
+      }
+    }
+
+    public override sealed string Text
+    {
+      get { return base.Text; }
+      set { base.Text = value; }
+    }
+
+    public ConfigureApplication(CECSettings settings, CECController controller)
+    {
+      _cecController = controller;
+      _settings = settings;
+      InitializeComponent();
+
+      // take the icon of the main window
+      ComponentResourceManager resources = new ComponentResourceManager(typeof(CECTray));
+      Icon = resources.GetObject("$this.Icon") as Icon;
+
+      Text = Resources.add_new_application;
+    }
+
+    private void BFindFileClick(object sender, EventArgs e)
+    {
+      OpenFileDialog dialog = new OpenFileDialog
+                                {
+                                  Title = Resources.select_exe_file,
+                                  InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
+                                  Filter = Resources.exe_file_filter,
+                                  FilterIndex = 1
+                                };
+
+      if (dialog.ShowDialog() != DialogResult.OK) return;
+
+      var fileName = dialog.SafeFileName;
+      if (fileName != null && File.Exists(dialog.FileName))
+      {
+        var versionInfo = FileVersionInfo.GetVersionInfo(dialog.FileName);
+        var path = dialog.FileName.Substring(0, dialog.FileName.Length - fileName.Length);
+        if (path.EndsWith("\\"))
+          path = path.Substring(0, path.Length - 1);
+
+        tbFilename.Text = fileName;
+        tbWorkingDir.Text = path;
+        tbUiName.Text = versionInfo.FileDescription;
+        tbProcessName.Text = fileName;
+        Text = string.Format(Resources.configure_application, versionInfo.FileDescription);
+      }
+      else
+      {
+        tbFilename.Text = string.Empty;
+        tbWorkingDir.Text = string.Empty;
+        tbUiName.Text = string.Empty;
+        tbProcessName.Text = string.Empty;
+        Text = Resources.add_new_application;
+      }
+    }
+
+    private void BOkClick(object sender, EventArgs e)
+    {
+      if (_controller != null)
+      {
+        _controller.ApplicationFilename = tbFilename.Text;
+        _controller.ApplicationWorkingDirectory = tbWorkingDir.Text;
+        _controller.UiName = tbUiName.Text;
+        _controller.ProcessName = tbProcessName.Text;
+        _controller.Settings.Persist();
+      }
+      else if (_cecController != null)
+      {
+        ApplicationController newController = new ApplicationController(_settings, tbUiName.Text, tbProcessName.Text, tbFilename.Text, tbWorkingDir.Text);
+        if (_cecController.RegisterApplication(newController))
+          newController.Settings.Persist();
+      }
+      Dispose();
+    }
+
+    private void BCancelClick(object sender, EventArgs e)
+    {
+      //TODO
+      Dispose();
+    }
+
+    private ApplicationController _controller;
+    private CECController _cecController;
+    private CECSettings _settings;
+  }
+}
similarity index 91%
rename from src/cec-config-gui/Properties/Resources.resx
rename to src/LibCecTray/controller/applications/ConfigureApplication.resx
index af7dbebbacef595e3089c01c05671016c21a8304..19dc0dd8b3964e653690c64d095c5d28283828b7 100644 (file)
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <root>
   <!-- 
     Microsoft ResX Schema 
@@ -46,7 +46,7 @@
     
     mimetype: application/x-microsoft.net.object.binary.base64
     value   : The object must be serialized with 
-            : System.Serialization.Formatters.Binary.BinaryFormatter
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
             : and then encoded with base64 encoding.
     
     mimetype: application/x-microsoft.net.object.soap.base64
@@ -60,6 +60,7 @@
             : and then encoded with base64 encoding.
     -->
   <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
     <xsd:element name="root" msdata:IsDataSet="true">
       <xsd:complexType>
         <xsd:choice maxOccurs="unbounded">
               <xsd:sequence>
                 <xsd:element name="value" type="xsd:string" minOccurs="0" />
               </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" />
+              <xsd:attribute name="name" use="required" type="xsd:string" />
               <xsd:attribute name="type" type="xsd:string" />
               <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
             </xsd:complexType>
           </xsd:element>
           <xsd:element name="assembly">
                 <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                 <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
               </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
               <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
               <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
             </xsd:complexType>
           </xsd:element>
           <xsd:element name="resheader">
diff --git a/src/LibCecTray/controller/applications/IControllerTabPage.cs b/src/LibCecTray/controller/applications/IControllerTabPage.cs
new file mode 100644 (file)
index 0000000..308ce74
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing       <license@pulse-eight.com>
+ *     http://www.pulse-eight.com/
+ *     http://www.pulse-eight.net/
+ */
+
+using LibCECTray.ui;
+
+namespace LibCECTray.controller.applications
+{
+  internal interface IControllerTabPage : IAsyncControls
+  {
+    void SetEnabled(bool val);
+    void SetStartButtonEnabled(bool val);
+  }
+
+  internal abstract class ControllerTabPage : AsyncTabPage, IControllerTabPage
+  {
+    public abstract void SetEnabled(bool val);
+    public abstract void SetStartButtonEnabled(bool val);
+  }
+}
diff --git a/src/LibCecTray/controller/applications/KeyInput.cs b/src/LibCecTray/controller/applications/KeyInput.cs
new file mode 100644 (file)
index 0000000..f37fd10
--- /dev/null
@@ -0,0 +1,236 @@
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing       <license@pulse-eight.com>
+ *     http://www.pulse-eight.com/
+ *     http://www.pulse-eight.net/
+ */
+
+using System.Collections.Generic;
+using System;
+using System.Globalization;
+using System.Text;
+
+namespace LibCECTray.controller.applications
+{
+  class KeyInput : ApplicationAction
+  {
+    public KeyInput(ApplicationController controller) :
+      base(controller, ActionType.SendKey)
+    {
+    }
+
+    public KeyInput(ApplicationController controller, WindowsAPI.VirtualKeyCode keyCode) :
+      base(controller, ActionType.SendKey)
+    {
+      AddKey(keyCode);
+    }
+
+    public static ApplicationAction FromString(ApplicationController controller, string value)
+    {
+      KeyInput retVal = new KeyInput(controller);
+      var split = value.Trim().Split(' ');
+      foreach (var item in split)
+      {
+        var param = retVal.GetParameterFromString(item);
+        ushort iValue;
+        if (ushort.TryParse(param, NumberStyles.AllowHexSpecifier, null, out iValue))
+          retVal.AddKey((WindowsAPI.VirtualKeyCode)iValue);
+      }
+      return retVal;
+    }
+
+    public int KeyCount
+    {
+      get
+      {
+        int count = 0;
+        foreach (var input in _input)
+          if (input.Data.Keyboard.Flags == 0)
+            count++;
+        return count;
+      }
+    }
+
+    public override string AsString()
+    {
+      StringBuilder sb = new StringBuilder();
+      foreach (var input in _input)
+      {
+        if (input.Data.Keyboard.Flags == 0)
+          sb.AppendFormat("{0}({1:X}) ", TypePrefix, input.Data.Keyboard.KeyCode);
+      }
+      return sb.ToString().Trim();
+    }
+
+    public override string AsFriendlyString()
+    {
+      StringBuilder sb = new StringBuilder();
+      bool bMultipleKeys = KeyCount > 1;
+      foreach (var input in _input)
+      {
+        if (input.Data.Keyboard.Flags == 0)
+        {
+          sb.AppendFormat(bMultipleKeys ? "[{0}] " : "{0} ",
+                          WindowsAPI.GetVirtualKeyName((WindowsAPI.VirtualKeyCode) input.Data.Keyboard.KeyCode));
+        }
+      }
+      return sb.ToString().Trim();
+    }
+
+    public int Size()
+    {
+      return _input.Count;
+    }
+
+    public override bool Empty()
+    {
+      return _input.Count == 0;
+    }
+
+    public override bool CanAppend(ApplicationAction value)
+    {
+      return (value.ActionType == ActionType.SendKey);
+    }
+
+    public override ApplicationAction Append(ApplicationAction value)
+    {
+      if (value.ActionType == ActionType.SendKey)
+        AddKey(value as KeyInput);
+
+      return this;
+    }
+
+    public WindowsAPI.Input[] ToArray()
+    {
+      return _input.ToArray();
+    }
+
+    public void AddKey(WindowsAPI.VirtualKeyCode keyCode)
+    {
+      AddKeyDown(keyCode);
+      AddKeyUp(keyCode);
+    }
+
+    private void AddKeyDown(WindowsAPI.VirtualKeyCode keyCode)
+    {
+      var key = new WindowsAPI.Input {
+        Type = WindowsAPI.InputType.Keyboard,
+        Data = {
+          Keyboard = new WindowsAPI.KeyboardInput {
+            KeyCode = (UInt16) keyCode,
+            Scan = 0,
+            Flags = 0,
+            Time = 0,
+            ExtraInfo = IntPtr.Zero
+          }
+        }
+      };
+
+      _input.Add(key);
+    }
+
+    private void AddKeyUp(WindowsAPI.VirtualKeyCode keyCode)
+    {
+      var key = new WindowsAPI.Input {
+        Type = WindowsAPI.InputType.Keyboard,
+        Data = {
+          Keyboard = new WindowsAPI.KeyboardInput {
+            KeyCode = (UInt16) keyCode,
+            Scan = 0,
+            Flags = (uint)WindowsAPI.KeyEvent.KeyUp,
+            Time = 0,
+            ExtraInfo = IntPtr.Zero
+          }
+        }
+      };
+
+      _input.Add(key);
+    }
+
+    public KeyInput AddKey(KeyInput input)
+    {
+      if (input != null)
+      {
+        foreach (var item in input._input)
+          _input.Add(item);
+      }
+      return this;
+    }
+
+    public override bool Transmit(IntPtr windowHandle)
+    {
+      var inputAr = ToArray();
+      if (inputAr.Length == 0)
+        return false;
+
+      try
+      {
+        return WindowsAPI.SendInputTo(windowHandle, (uint) inputAr.Length, inputAr,
+                                      System.Runtime.InteropServices.Marshal.SizeOf(typeof (WindowsAPI.Input)));
+      }
+      catch (Exception e)
+      {
+        Console.Error.WriteLine(e.Message);
+        return false;
+      }
+    }
+
+    public ApplicationAction RemoveItem(int index)
+    {
+      //both keyup and keydown
+      if (index * 2 + 1 < _input.Count)
+      {
+        _input.RemoveAt(index * 2);
+        _input.RemoveAt(index * 2);
+      }
+      return this;
+    }
+
+    public override ApplicationAction RemoveKey(int index)
+    {
+      var current = 0;
+      var item = 0;
+      foreach (var input in _input)
+      {
+        if (input.Data.Keyboard.Flags == 0)
+        {
+          var tmp = string.Format(KeyCount > 1 ? "[{0}] " : "{0} ",
+                                  WindowsAPI.GetVirtualKeyName((WindowsAPI.VirtualKeyCode) input.Data.Keyboard.KeyCode));
+          current += tmp.Length + 1;
+          if (index <= current)
+            return RemoveItem(item);
+          item++;
+        }
+      }
+
+      return this;
+    }
+
+    private readonly List<WindowsAPI.Input> _input = new List<WindowsAPI.Input>();
+  }
+}
\ No newline at end of file
diff --git a/src/LibCecTray/controller/applications/WindowsAPI.cs b/src/LibCecTray/controller/applications/WindowsAPI.cs
new file mode 100644 (file)
index 0000000..90453dc
--- /dev/null
@@ -0,0 +1,454 @@
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing       <license@pulse-eight.com>
+ *     http://www.pulse-eight.com/
+ *     http://www.pulse-eight.net/
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using System.Diagnostics;
+using System.Reflection;
+using LibCECTray.Properties;
+
+namespace LibCECTray.controller.applications
+{
+  /// <summary>
+  /// Windows API methods and types
+  /// </summary>
+  internal class WindowsAPI
+  {
+    #region Types
+    public enum VirtualKeyCode : ushort
+    {
+      VK_LBUTTON = 0x01,
+      VK_RBUTTON = 0x02,
+      VK_CANCEL = 0x03,
+      VK_MBUTTON = 0x04,
+      VK_XBUTTON1 = 0x05,
+      VK_XBUTTON2 = 0x06,
+      VK_BACK = 0x08,
+      VK_TAB = 0x09,
+      VK_CLEAR = 0x0C,
+      VK_RETURN = 0x0D,
+      VK_SHIFT = 0x10,
+      VK_CONTROL = 0x11,
+      VK_MENU = 0x12,
+      VK_PAUSE = 0x13,
+      VK_CAPITAL = 0x14,
+      VK_KANA = 0x15,
+      VK_HANGEUL = 0x15,
+      VK_HANGUL = 0x15,
+      VK_JUNJA = 0x17,
+      VK_FINAL = 0x18,
+      VK_HANJA = 0x19,
+      VK_KANJI = 0x19,
+      VK_ESCAPE = 0x1B,
+      VK_CONVERT = 0x1C,
+      VK_NONCONVERT = 0x1D,
+      VK_ACCEPT = 0x1E,
+      VK_MODECHANGE = 0x1F,
+      VK_SPACE = 0x20,
+      VK_PRIOR = 0x21,
+      VK_NEXT = 0x22,
+      VK_END = 0x23,
+      VK_HOME = 0x24,
+      VK_LEFT = 0x25,
+      VK_UP = 0x26,
+      VK_RIGHT = 0x27,
+      VK_DOWN = 0x28,
+      VK_SELECT = 0x29,
+      VK_PRINT = 0x2A,
+      VK_EXECUTE = 0x2B,
+      VK_SNAPSHOT = 0x2C,
+      VK_INSERT = 0x2D,
+      VK_DELETE = 0x2E,
+      VK_HELP = 0x2F,
+      VK_0 = 0x30,
+      VK_1 = 0x31,
+      VK_2 = 0x32,
+      VK_3 = 0x33,
+      VK_4 = 0x34,
+      VK_5 = 0x35,
+      VK_6 = 0x36,
+      VK_7 = 0x37,
+      VK_8 = 0x38,
+      VK_9 = 0x39,
+      VK_B = 0x42,
+      VK_C = 0x43,
+      VK_D = 0x44,
+      VK_E = 0x45,
+      VK_F = 0x46,
+      VK_G = 0x47,
+      VK_H = 0x48,
+      VK_I = 0x49,
+      VK_J = 0x4A,
+      VK_K = 0x4B,
+      VK_L = 0x4C,
+      VK_M = 0x4D,
+      VK_N = 0x4E,
+      VK_O = 0x4F,
+      VK_P = 0x50,
+      VK_Q = 0x51,
+      VK_R = 0x52,
+      VK_S = 0x53,
+      VK_T = 0x54,
+      VK_U = 0x55,
+      VK_V = 0x56,
+      VK_W = 0x57,
+      VK_X = 0x58,
+      VK_Y = 0x59,
+      VK_Z = 0x5A,
+      VK_LWIN = 0x5B,
+      VK_RWIN = 0x5C,
+      VK_APPS = 0x5D,
+      VK_SLEEP = 0x5F,
+      VK_NUMPAD0 = 0x60,
+      VK_NUMPAD1 = 0x61,
+      VK_NUMPAD2 = 0x62,
+      VK_NUMPAD3 = 0x63,
+      VK_NUMPAD4 = 0x64,
+      VK_NUMPAD5 = 0x65,
+      VK_NUMPAD6 = 0x66,
+      VK_NUMPAD7 = 0x67,
+      VK_NUMPAD8 = 0x68,
+      VK_NUMPAD9 = 0x69,
+      VK_MULTIPLY = 0x6A,
+      VK_ADD = 0x6B,
+      VK_SEPARATOR = 0x6C,
+      VK_SUBTRACT = 0x6D,
+      VK_DECIMAL = 0x6E,
+      VK_DIVIDE = 0x6F,
+      VK_F1 = 0x70,
+      VK_F2 = 0x71,
+      VK_F3 = 0x72,
+      VK_F4 = 0x73,
+      VK_F5 = 0x74,
+      VK_F6 = 0x75,
+      VK_F7 = 0x76,
+      VK_F8 = 0x77,
+      VK_F9 = 0x78,
+      VK_F10 = 0x79,
+      VK_F11 = 0x7A,
+      VK_F12 = 0x7B,
+      VK_F13 = 0x7C,
+      VK_F14 = 0x7D,
+      VK_F15 = 0x7E,
+      VK_F16 = 0x7F,
+      VK_F17 = 0x80,
+      VK_F18 = 0x81,
+      VK_F19 = 0x82,
+      VK_F20 = 0x83,
+      VK_F21 = 0x84,
+      VK_F22 = 0x85,
+      VK_F23 = 0x86,
+      VK_F24 = 0x87,
+      VK_NUMLOCK = 0x90,
+      VK_SCROLL = 0x91,
+      VK_LSHIFT = 0xA0,
+      VK_RSHIFT = 0xA1,
+      VK_LCONTROL = 0xA2,
+      VK_RCONTROL = 0xA3,
+      VK_LMENU = 0xA4,
+      VK_RMENU = 0xA5,
+      VK_BROWSER_BACK = 0xA6,
+      VK_BROWSER_FORWARD = 0xA7,
+      VK_BROWSER_REFRESH = 0xA8,
+      VK_BROWSER_STOP = 0xA9,
+      VK_BROWSER_SEARCH = 0xAA,
+      VK_BROWSER_FAVORITES = 0xAB,
+      VK_BROWSER_HOME = 0xAC,
+      VK_VOLUME_MUTE = 0xAD,
+      VK_VOLUME_DOWN = 0xAE,
+      VK_VOLUME_UP = 0xAF,
+      VK_MEDIA_NEXT_TRACK = 0xB0,
+      VK_MEDIA_PREV_TRACK = 0xB1,
+      VK_MEDIA_STOP = 0xB2,
+      VK_MEDIA_PLAY_PAUSE = 0xB3,
+      VK_LAUNCH_MAIL = 0xB4,
+      VK_LAUNCH_MEDIA_SELECT = 0xB5,
+      VK_LAUNCH_APP1 = 0xB6,
+      VK_LAUNCH_APP2 = 0xB7,
+      VK_OEM_1 = 0xBA,
+      VK_OEM_PLUS = 0xBB,
+      VK_OEM_COMMA = 0xBC,
+      VK_OEM_MINUS = 0xBD,
+      VK_OEM_PERIOD = 0xBE,
+      VK_OEM_2 = 0xBF,
+      VK_OEM_3 = 0xC0,
+      VK_OEM_4 = 0xDB,
+      VK_OEM_5 = 0xDC,
+      VK_OEM_6 = 0xDD,
+      VK_OEM_7 = 0xDE,
+      VK_OEM_8 = 0xDF,
+      VK_OEM_102 = 0xE2,
+      VK_PROCESSKEY = 0xE5,
+      VK_PACKET = 0xE7,
+      VK_ATTN = 0xF6,
+      VK_CRSEL = 0xF7,
+      VK_EXSEL = 0xF8,
+      VK_EREOF = 0xF9,
+      VK_PLAY = 0xFA,
+      VK_ZOOM = 0xFB,
+      VK_NONAME = 0xFC,
+      VK_PA1 = 0xFD,
+      VK_OEM_CLEAR = 0xFE,
+    }
+
+    public static string GetVirtualKeyName(VirtualKeyCode key)
+    {
+      var keyName = Enum.GetName(typeof(VirtualKeyCode), key).ToUpper();
+      var friendlyName = Resources.ResourceManager.GetString(keyName, Resources.Culture);
+      return friendlyName ?? keyName.ToLower().Substring(3).Replace('_', ' ');
+    }
+
+    public enum InputType : uint
+    {
+      Mouse = 0,
+      Keyboard = 1,
+      Hardware = 2
+    }
+
+    public enum KeyEvent : uint
+    {
+      ExtendedKey = 0x0001,
+      KeyUp = 0x0002,
+      Unicode = 0x0003,
+      ScanCode = 0x0008
+    }
+
+    public enum XButton : uint
+    {
+      One = 0x0001,
+      Two = 0x0002
+    }
+
+    public enum MouseEvent : uint
+    {
+      Move = 0x0001,
+      LeftDown = 0x0002,
+      LeftUp = 0x0004,
+      RightDown = 0x0008,
+      RightUp = 0x0010,
+      MiddleDown = 0x0020,
+      Middleup = 0x0040,
+      XDown = 0x0080,
+      XUp = 0x0100,
+      Wheel = 0x0800,
+      VirtualDesk = 0x4000,
+      Absolute = 0x8000
+    }
+
+    public enum ShowType
+    {
+      ShowNormal = 1
+    }
+
+    #pragma warning disable 649
+    public struct MouseInput
+    {
+      public Int32 X;
+      public Int32 Y;
+      public UInt32 MouseData;
+      public UInt32 Flags;
+      public UInt32 Time;
+      public IntPtr ExtraInfo;
+    }
+    public struct KeyboardInput
+    {
+      public UInt16 KeyCode;
+      public UInt16 Scan;
+      public UInt32 Flags;
+      public UInt32 Time;
+      public IntPtr ExtraInfo;
+    }
+    public struct HardwareInput
+    {
+      public UInt32 Msg;
+      public UInt16 ParamL;
+      public UInt16 ParamH;
+    }
+
+    [StructLayout(LayoutKind.Explicit)]
+    public struct CombinedInput
+    {
+      [FieldOffset(0)]
+      public MouseInput Mouse;
+      [FieldOffset(0)]
+      public KeyboardInput Keyboard;
+      [FieldOffset(0)]
+      public HardwareInput Hardware;
+    }
+
+    public struct Input
+    {
+      public InputType Type;
+      public CombinedInput Data;
+    }
+    #pragma warning restore 649
+    #endregion
+
+    #region DllImports
+    [DllImport("kernel32.dll")]
+    public static extern uint GetCurrentThreadId();
+
+    [DllImport("kernel32.dll", SetLastError = true)]
+    public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [Out] byte[] lpBuffer,
+                                                int dwSize, out int lpNumberOfBytesRead);
+
+    [DllImport("user32.dll")]
+    public static extern IntPtr GetForegroundWindow();
+
+    [DllImport("user32.dll", SetLastError = true)]
+    public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
+
+    [DllImport("user32.dll")]
+    public static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach);
+
+    [DllImport("user32.dll", SetLastError = true)]
+    public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass,
+                                             string lpszWindow);
+
+    [DllImport("user32.Dll", EntryPoint = "PostMessageA")]
+    public static extern bool PostMessage(IntPtr hWnd, uint msg, int wParam, int lParam);
+
+    [DllImport("user32.dll")]
+    public static extern byte VkKeyScan(char ch);
+
+    [DllImport("user32.dll")]
+    public static extern uint MapVirtualKey(uint uCode, uint uMapType);
+
+    [DllImport("user32.dll")]
+    public static extern IntPtr SetFocus(IntPtr hWnd);
+
+    [DllImport("user32.dll", CharSet = CharSet.Unicode)]
+    [return: MarshalAs(UnmanagedType.Bool)]
+    public static extern bool SetForegroundWindow(IntPtr hWnd);
+
+    [DllImport("user32.dll", CharSet = CharSet.Unicode)]
+    [return: MarshalAs(UnmanagedType.Bool)]
+    public static extern bool AllowSetForegroundWindow(int dwProcessId);
+
+    [DllImport("user32.dll")]
+    public static extern uint SendInput(uint numberOfInputs,
+                                        [MarshalAs(UnmanagedType.LPArray, SizeConst = 1)] Input[] input, int structSize);
+
+    [DllImport("user32.dll")]
+    public static extern IntPtr GetMessageExtraInfo();
+
+    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
+    public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);
+
+    [DllImport("user32.dll", CharSet = CharSet.Unicode)]
+    public static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);
+
+    [DllImport("user32.dll", CharSet = CharSet.Unicode)]
+    public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
+    #endregion
+
+    /// <summary>
+    /// Forces a window to the foreground
+    /// </summary>
+    /// <param name="windowHandle">Window that becomes the foreground window</param>
+    /// <returns>True when succeeded, false otherwise</returns>
+    public static bool ForceForeground(IntPtr windowHandle)
+    {
+      // get current foreground
+      var currentForeground = GetForegroundWindow();
+
+      // window already foreground window
+      if (currentForeground == windowHandle)
+        return true;
+
+      // get thread id
+      uint temp;
+      var windowThreadId = GetWindowThreadProcessId(windowHandle, out temp);
+
+      // attach thread input
+      if (currentForeground != IntPtr.Zero && !AttachThreadInput(GetCurrentThreadId(), windowThreadId, true))
+        return false;
+
+      // switch foreground
+      SetForegroundWindow(windowHandle);
+      while (GetForegroundWindow() != windowHandle){}
+
+      // (re)attach input
+      if (currentForeground != IntPtr.Zero)
+        AttachThreadInput(GetCurrentThreadId(), windowThreadId, false);
+
+      return (GetForegroundWindow() == windowHandle);
+    }
+
+    /// <summary>
+    /// Makes an application the foreground window and send input to it
+    /// </summary>
+    /// <param name="windowHandle">The window to send the input to</param>
+    /// <param name="numberOfInputs">Number of inputs in the input parameter</param>
+    /// <param name="input">The input to send</param>
+    /// <param name="structSize">The size of an input struct</param>
+    /// <returns>True when sent false otherwise</returns>
+    public static bool SendInputTo(IntPtr windowHandle, uint numberOfInputs, Input[] input, int structSize)
+    {
+      return ShowWindowAsync(windowHandle, (int)ShowType.ShowNormal) &&
+             ForceForeground(windowHandle) &&
+             SendInput(numberOfInputs, input, structSize) == 0;
+    }
+
+    /// <summary>
+    /// Find a window handle given it's name
+    /// </summary>
+    /// <param name="name">The name of the window</param>
+    /// <returns>The requested handle, or IntPtr.Zero when not found</returns>
+    public static IntPtr FindWindow(string name)
+    {
+      foreach (var proc in Process.GetProcesses())
+      {
+        if (proc.MainWindowTitle == name)
+          return proc.MainWindowHandle;
+      }
+
+      return IntPtr.Zero;
+    }
+
+    /// <summary>
+    /// Check whether there's another instance of this program running, and return the process when found
+    /// </summary>
+    /// <returns>The running process, or null when not found</returns>
+    public static Process RunningInstance()
+    {
+      var current = Process.GetCurrentProcess();
+      foreach (var process in Process.GetProcessesByName(current.ProcessName))
+      {
+        if (process.Id != current.Id && Assembly.GetExecutingAssembly().Location.Replace("/", "\\") == current.MainModule.FileName)
+          return process;
+      }
+
+      return null;
+    }
+  }
+}
\ No newline at end of file
diff --git a/src/LibCecTray/controller/applications/internal/WMCController.cs b/src/LibCecTray/controller/applications/internal/WMCController.cs
new file mode 100644 (file)
index 0000000..2379730
--- /dev/null
@@ -0,0 +1,220 @@
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing       <license@pulse-eight.com>
+ *     http://www.pulse-eight.com/
+ *     http://www.pulse-eight.net/
+ */
+
+using System;
+using CecSharp;
+using LibCECTray.Properties;
+using LibCECTray.settings;
+
+namespace LibCECTray.controller.applications.@internal
+{
+  internal class WMCController : ApplicationController
+  {
+    public WMCController(CECSettings settings) :
+      base(settings,
+           Resources.application_windows_media_center,
+           "ehshell",
+           "ehshell.exe",
+           Environment.GetFolderPath(Environment.SpecialFolder.System) + @"\..\ehome")
+    {
+      IsInternal = true;
+    }
+
+    public override ApplicationAction DefaultValue(CecKeypress key)
+    {
+      KeyInput keyInput = new KeyInput(null);
+      switch (key.Keycode)
+      {
+        case CecUserControlCode.RightUp:
+          keyInput.AddKey(WindowsAPI.VirtualKeyCode.VK_RIGHT);
+          keyInput.AddKey(WindowsAPI.VirtualKeyCode.VK_UP);
+          break;
+        case CecUserControlCode.LeftUp:
+          keyInput.AddKey(WindowsAPI.VirtualKeyCode.VK_LEFT);
+          keyInput.AddKey(WindowsAPI.VirtualKeyCode.VK_UP);
+          break;
+        case CecUserControlCode.Up:
+          keyInput.AddKey(WindowsAPI.VirtualKeyCode.VK_UP);
+          break;
+        case CecUserControlCode.RightDown:
+          keyInput.AddKey(WindowsAPI.VirtualKeyCode.VK_RIGHT);
+          keyInput.AddKey(WindowsAPI.VirtualKeyCode.VK_DOWN);
+          break;
+        case CecUserControlCode.LeftDown:
+          keyInput.AddKey(WindowsAPI.VirtualKeyCode.VK_LEFT);
+          keyInput.AddKey(WindowsAPI.VirtualKeyCode.VK_DOWN);
+          break;
+        case CecUserControlCode.Down:
+          keyInput.AddKey(WindowsAPI.VirtualKeyCode.VK_DOWN);
+          break;
+        case CecUserControlCode.Left:
+          keyInput.AddKey(WindowsAPI.VirtualKeyCode.VK_LEFT);
+          break;
+        case CecUserControlCode.Right:
+          keyInput.AddKey(WindowsAPI.VirtualKeyCode.VK_RIGHT);
+          break;
+        case CecUserControlCode.Select:
+          keyInput.AddKey(WindowsAPI.VirtualKeyCode.VK_RETURN);
+          break;
+        case CecUserControlCode.Exit:
+        case CecUserControlCode.SamsungReturn:
+          keyInput.AddKey(WindowsAPI.VirtualKeyCode.VK_BACK);
+          break;
+        case CecUserControlCode.RootMenu:
+        case CecUserControlCode.SetupMenu:
+        case CecUserControlCode.ContentsMenu:
+        case CecUserControlCode.FavoriteMenu:
+          keyInput.AddKey(WindowsAPI.VirtualKeyCode.VK_MENU);
+          break;
+        case CecUserControlCode.Number0:
+          keyInput.AddKey(WindowsAPI.VirtualKeyCode.VK_NUMPAD0);
+          break;
+        case CecUserControlCode.Number1:
+          keyInput.AddKey(WindowsAPI.VirtualKeyCode.VK_NUMPAD1);
+          break;
+        case CecUserControlCode.Number2:
+          keyInput.AddKey(WindowsAPI.VirtualKeyCode.VK_NUMPAD2);
+          break;
+        case CecUserControlCode.Number3:
+          keyInput.AddKey(WindowsAPI.VirtualKeyCode.VK_NUMPAD3);
+          break;
+        case CecUserControlCode.Number4:
+          keyInput.AddKey(WindowsAPI.VirtualKeyCode.VK_NUMPAD4);
+          break;
+        case CecUserControlCode.Number5:
+          keyInput.AddKey(WindowsAPI.VirtualKeyCode.VK_NUMPAD5);
+          break;
+        case CecUserControlCode.Number6:
+          keyInput.AddKey(WindowsAPI.VirtualKeyCode.VK_NUMPAD6);
+          break;
+        case CecUserControlCode.Number7:
+          keyInput.AddKey(WindowsAPI.VirtualKeyCode.VK_NUMPAD7);
+          break;
+        case CecUserControlCode.Number8:
+          keyInput.AddKey(WindowsAPI.VirtualKeyCode.VK_NUMPAD8);
+          break;
+        case CecUserControlCode.Number9:
+          keyInput.AddKey(WindowsAPI.VirtualKeyCode.VK_NUMPAD9);
+          break;
+        case CecUserControlCode.Dot:
+          keyInput.AddKey(WindowsAPI.VirtualKeyCode.VK_SELECT);
+          break;
+        case CecUserControlCode.Enter:
+          keyInput.AddKey(WindowsAPI.VirtualKeyCode.VK_RETURN);
+          break;
+        case CecUserControlCode.Clear:
+          keyInput.AddKey(WindowsAPI.VirtualKeyCode.VK_CLEAR);
+          break;
+        case CecUserControlCode.F1Blue:
+          keyInput.AddKey(WindowsAPI.VirtualKeyCode.VK_F1);
+          break;
+        case CecUserControlCode.F2Red:
+          keyInput.AddKey(WindowsAPI.VirtualKeyCode.VK_F2);
+          break;
+        case CecUserControlCode.F3Green:
+          keyInput.AddKey(WindowsAPI.VirtualKeyCode.VK_F3);
+          break;
+        case CecUserControlCode.F4Yellow:
+          keyInput.AddKey(WindowsAPI.VirtualKeyCode.VK_F4);
+          break;
+        case CecUserControlCode.F5:
+          keyInput.AddKey(WindowsAPI.VirtualKeyCode.VK_F5);
+          break;
+        case CecUserControlCode.ChannelUp:
+        case CecUserControlCode.PageUp:
+          keyInput.AddKey(WindowsAPI.VirtualKeyCode.VK_MEDIA_NEXT_TRACK);
+          break;
+        case CecUserControlCode.ChannelDown:
+        case CecUserControlCode.PageDown:
+          keyInput.AddKey(WindowsAPI.VirtualKeyCode.VK_MEDIA_PREV_TRACK);
+          break;
+        case CecUserControlCode.VolumeUp:
+          keyInput.AddKey(WindowsAPI.VirtualKeyCode.VK_VOLUME_UP);
+          break;
+        case CecUserControlCode.VolumeDown:
+          keyInput.AddKey(WindowsAPI.VirtualKeyCode.VK_VOLUME_DOWN);
+          break;
+        case CecUserControlCode.Mute:
+        case CecUserControlCode.MuteFunction:
+          keyInput.AddKey(WindowsAPI.VirtualKeyCode.VK_VOLUME_MUTE);
+          break;
+        case CecUserControlCode.Play:
+        case CecUserControlCode.PlayFunction:
+        case CecUserControlCode.Pause:
+        case CecUserControlCode.PausePlayFunction:
+        case CecUserControlCode.PauseRecord:
+        case CecUserControlCode.PauseRecordFunction:
+          keyInput.AddKey(WindowsAPI.VirtualKeyCode.VK_MEDIA_PLAY_PAUSE);
+          break;
+        case CecUserControlCode.Stop:
+        case CecUserControlCode.StopFunction:
+        case CecUserControlCode.StopRecord:
+          keyInput.AddKey(WindowsAPI.VirtualKeyCode.VK_MEDIA_STOP);
+          break;
+        case CecUserControlCode.Rewind:
+        case CecUserControlCode.Backward:
+          keyInput.AddKey(WindowsAPI.VirtualKeyCode.VK_LEFT);
+          break;
+        case CecUserControlCode.Forward:
+        case CecUserControlCode.FastForward:
+          keyInput.AddKey(WindowsAPI.VirtualKeyCode.VK_RIGHT);
+          break;
+
+        //currently unmapped
+        //case CecUserControlCode.NextFavorite:
+        //case CecUserControlCode.PreviousChannel:
+        //case CecUserControlCode.SoundSelect:
+        //case CecUserControlCode.InputSelect:
+        //case CecUserControlCode.DisplayInformation:
+        //case CecUserControlCode.Help:
+        //case CecUserControlCode.Record:
+        //case CecUserControlCode.Eject:
+        //case CecUserControlCode.Angle:
+        //case CecUserControlCode.SubPicture:
+        //case CecUserControlCode.VideoOnDemand:
+        //case CecUserControlCode.ElectronicProgramGuide:
+        //case CecUserControlCode.TimerProgramming:
+        //case CecUserControlCode.RecordFunction:
+        //case CecUserControlCode.RestoreVolumeFunction:
+        //case CecUserControlCode.TuneFunction:
+        //case CecUserControlCode.SelectMediaFunction:
+        //case CecUserControlCode.SelectAVInputFunction:
+        //case CecUserControlCode.SelectAudioInputFunction:
+        //case CecUserControlCode.Data:
+        //default:
+        //  break;
+      }
+
+      return keyInput.Empty() ? null : keyInput;
+    }
+  }
+}
diff --git a/src/LibCecTray/controller/applications/internal/XBMCController.cs b/src/LibCecTray/controller/applications/internal/XBMCController.cs
new file mode 100644 (file)
index 0000000..c269788
--- /dev/null
@@ -0,0 +1,475 @@
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing       <license@pulse-eight.com>
+ *     http://www.pulse-eight.com/
+ *     http://www.pulse-eight.net/
+ */
+
+using System;
+using System.Globalization;
+using System.IO;
+using System.Text;
+using System.Windows.Forms;
+using System.Xml;
+using CecSharp;
+using LibCECTray.Properties;
+using LibCECTray.settings;
+
+namespace LibCECTray.controller.applications.@internal
+{
+       internal class XBMCController : ApplicationController
+       {
+    public XBMCController(CECSettings settings) :
+      base(settings,
+           Resources.application_xbmc,
+           "XBMC",
+           "XBMC.exe",
+           Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) + @"\XBMC")
+    {
+      IsInternal = true;
+      AutoStartApplication.Value = false;
+      ControlApplication.Value = false;
+
+      LoadXMLConfiguration();
+
+      ApplicationRunningChanged += RunningChanged;
+    }
+
+         static void RunningChanged(bool running)
+    {
+      if (running)
+      {
+        // XBMC is running, close the application, or we'll block communication
+        Application.Exit();
+      }
+    }
+
+    public override ApplicationAction DefaultValue(CecKeypress key)
+         {
+           return null;
+         }
+
+    public override ControllerTabPage UiControl
+    {
+      get { return UIControlInternal ?? (UIControlInternal = new XBMCControllerUI(this)); }
+    }
+
+    public bool LoadXMLConfiguration()
+    {
+      var xbmcDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\XBMC\userdata\peripheral_data";
+      return LoadXMLConfiguration(xbmcDir + string.Format(@"\usb_{0:X}_{1:X}.xml", Program.Instance.Controller.AdapterVendorId, Program.Instance.Controller.AdapterProductId)) ||
+             LoadXMLConfiguration(xbmcDir + @"\usb_2548_1001.xml") ||
+             LoadXMLConfiguration(xbmcDir + @"\usb_2548_1002.xml");
+    }
+
+    public bool LoadXMLConfiguration(string filename)
+    {
+      bool gotConfig = false;
+      if (File.Exists(filename))
+      {
+        XmlTextReader reader = new XmlTextReader(filename);
+        while (reader.Read())
+        {
+          gotConfig = true;
+          switch (reader.NodeType)
+          {
+            case XmlNodeType.Element:
+              if (reader.Name.ToLower() == "setting")
+              {
+                string name = string.Empty;
+                string value = string.Empty;
+
+                while (reader.MoveToNextAttribute())
+                {
+                  if (reader.Name.ToLower().Equals("id"))
+                    name = reader.Value.ToLower();
+                  if (reader.Name.ToLower().Equals("value"))
+                    value = reader.Value;
+                }
+
+                switch (name)
+                {
+                  case "cec_hdmi_port":
+                    {
+                      byte iPort;
+                      if (byte.TryParse(value, out iPort))
+                        Settings.HDMIPort.Value = iPort;
+                    }
+                    break;
+                  case "connected_device":
+                    {
+                      int iDevice;
+                      if (int.TryParse(value, out iDevice))
+                        Settings.ConnectedDevice.Value = iDevice == 36038 ? CecLogicalAddress.AudioSystem : CecLogicalAddress.Tv;
+                    }
+                    break;
+                  case "cec_power_on_startup":
+                    if (value.Equals("1") || value.ToLower().Equals("true") || value.ToLower().Equals("yes"))
+                    {
+                      Settings.ActivateSource.Value = true;
+                      Settings.WakeDevices.Value.Set(CecLogicalAddress.Tv);
+                    }
+                    break;
+                  case "cec_power_off_shutdown":
+                    if (value.Equals("1") || value.ToLower().Equals("true") || value.ToLower().Equals("yes"))
+                      Settings.PowerOffDevices.Value.Set(CecLogicalAddress.Broadcast);
+                    break;
+                  case "cec_standby_screensaver":
+                    StandbyScreensaver.Value = value.Equals("1") || value.ToLower().Equals("true") || value.ToLower().Equals("yes");
+                    break;
+                  case "standby_pc_on_tv_standby":
+                    PowerOffOnStandby.Value = value.Equals("1") || value.ToLower().Equals("true") || value.ToLower().Equals("yes");
+                    break;
+                  case "use_tv_menu_language":
+                    UseTVLanguage.Value = value.Equals("1") || value.ToLower().Equals("true") || value.ToLower().Equals("yes");
+                    break;
+                  // 1.5.0+ settings
+                  case "physical_address":
+                    {
+                      ushort physicalAddress;
+                      if (ushort.TryParse(value, NumberStyles.AllowHexSpecifier, null, out physicalAddress))
+                        Settings.PhysicalAddress.Value = physicalAddress;
+                    }
+                    break;
+                  case "device_type":
+                    {
+                      ushort iType;
+                      if (ushort.TryParse(value, out iType))
+                        Settings.DeviceType.Value = (CecDeviceType)iType;
+                    }
+                    break;
+                  case "tv_vendor":
+                    {
+                      UInt64 iVendor;
+                      if (UInt64.TryParse(value, out iVendor))
+                        Settings.TVVendor.Value = (CecVendorId)iVendor;
+                    }
+                    break;
+                  case "wake_device":
+                    {
+                      int iWakeDevices;
+                      if (int.TryParse(value, out iWakeDevices))
+                      {
+                        Settings.WakeDevices.Value.Clear();
+                        switch (iWakeDevices)
+                        {
+                          case 36037:
+                            Settings.WakeDevices.Value.Set(CecLogicalAddress.Tv);
+                            break;
+                          case 36038:
+                            Settings.WakeDevices.Value.Set(CecLogicalAddress.AudioSystem);
+                            break;
+                          case 36039:
+                            Settings.WakeDevices.Value.Set(CecLogicalAddress.Tv);
+                            Settings.WakeDevices.Value.Set(CecLogicalAddress.AudioSystem);
+                            break;
+                        }
+                      }
+                    }
+                    break;
+                  case "wake_devices_advanced":
+                    {
+                      Settings.WakeDevices.Value.Clear();
+                      string[] split = value.Split(new[] { ' ' });
+                      foreach (string dev in split)
+                      {
+                        byte iLogicalAddress;
+                        if (byte.TryParse(dev, out iLogicalAddress))
+                          Settings.WakeDevices.Value.Set((CecLogicalAddress)iLogicalAddress);
+                      }
+                    }
+                    break;
+                  case "standby_devices":
+                    {
+                      int iStandbyDevices;
+                      if (int.TryParse(value, out iStandbyDevices))
+                      {
+                        Settings.PowerOffDevices.Value.Clear();
+                        switch (iStandbyDevices)
+                        {
+                          case 36037:
+                            Settings.PowerOffDevices.Value.Set(CecLogicalAddress.Tv);
+                            break;
+                          case 36038:
+                            Settings.PowerOffDevices.Value.Set(CecLogicalAddress.AudioSystem);
+                            break;
+                          case 36039:
+                            Settings.PowerOffDevices.Value.Set(CecLogicalAddress.Tv);
+                            Settings.PowerOffDevices.Value.Set(CecLogicalAddress.AudioSystem);
+                            break;
+                        }
+                      }
+                    }
+                    break;
+                  case "standby_devices_advanced":
+                    {
+                      Settings.PowerOffDevices.Value.Clear();
+                      string[] split = value.Split(new[] { ' ' });
+                      foreach (string dev in split)
+                      {
+                        byte iLogicalAddress;
+                        if (byte.TryParse(dev, out iLogicalAddress))
+                          Settings.PowerOffDevices.Value.Set((CecLogicalAddress)iLogicalAddress);
+                      }
+                    }
+                    break;
+                  case "enabled":
+                    break;
+                  case "port":
+                    //TODO
+                    break;
+                  // 1.5.1 settings
+                  case "send_inactive_source":
+                    SendInactiveSource.Value = value.Equals("1") || value.ToLower().Equals("true") || value.ToLower().Equals("yes");
+                    break;
+                  // 1.9.0+ settings
+                  case "pause_playback_on_deactivate":
+                    PausePlaybackOnDeactivate.Value = value.Equals("1") || value.ToLower().Equals("true") || value.ToLower().Equals("yes");
+                    break;
+                }
+              }
+              break;
+          }
+        }
+      }
+      return gotConfig;
+    }
+
+    static bool HasAdvancedDeviceIdSet(CecLogicalAddresses addresses)
+    {
+      foreach (var val in addresses.Addresses)
+        if (val != CecLogicalAddress.Tv && val != CecLogicalAddress.AudioSystem)
+          return true;
+      return false;
+    }
+
+    public void SaveXMLConfiguration()
+    {
+      Settings.Persist();
+
+      var xbmcDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\XBMC\userdata\peripheral_data";
+      if (!Directory.Exists(xbmcDir))
+        Directory.CreateDirectory(xbmcDir);
+
+      if (!Directory.Exists(xbmcDir))
+      {
+        // couldn't create directory
+        MessageBox.Show(string.Format(Resources.could_not_create_directory, xbmcDir), Resources.error,
+                        MessageBoxButtons.OK, MessageBoxIcon.Error);
+        return;
+      }
+
+      SaveFileDialog dialog = new SaveFileDialog
+      {
+        Title = Resources.store_settings_where,
+        InitialDirectory = xbmcDir,
+        FileName = string.Format("usb_{0:X}_{1:X}.xml", Program.Instance.Controller.AdapterVendorId, Program.Instance.Controller.AdapterProductId),
+        Filter = Resources.xml_file_filter,
+        FilterIndex = 1
+      };
+      if (dialog.ShowDialog() != DialogResult.OK) return;
+
+      FileStream fs = null;
+      string error = string.Empty;
+      try
+      {
+        fs = (FileStream)dialog.OpenFile();
+      }
+      catch (Exception ex)
+      {
+        error = ex.Message;
+      }
+      if (fs == null)
+      {
+        MessageBox.Show(string.Format(Resources.cannot_open_file, dialog.FileName) + (error.Length > 0 ? ": " + error : string.Empty), Resources.app_name, MessageBoxButtons.OK, MessageBoxIcon.Error);
+      }
+      else
+      {
+        StreamWriter writer = new StreamWriter(fs);
+        StringBuilder output = new StringBuilder();
+        output.AppendLine("<settings>");
+        output.AppendLine("<setting id=\"cec_hdmi_port\" value=\"" + Settings.HDMIPort.Value + "\" />");
+        output.AppendLine("<setting id=\"connected_device\" value=\"" + (Settings.ConnectedDevice.Value == CecLogicalAddress.AudioSystem ? 36038 : 36037) + "\" />");
+        output.AppendLine("<setting id=\"cec_power_on_startup\" value=\"" + (Settings.ActivateSource.Value ? 1 : 0) + "\" />");
+        output.AppendLine("<setting id=\"cec_power_off_shutdown\" value=\"" + (Settings.PowerOffDevices.Value.IsSet(CecLogicalAddress.Broadcast) ? 1 : 0) + "\" />");
+        output.AppendLine("<setting id=\"cec_standby_screensaver\" value=\"" + (StandbyScreensaver.Value ? 1 : 0) + "\" />");
+        output.AppendLine("<setting id=\"standby_pc_on_tv_standby\" value=\"" + (PowerOffOnStandby.Value ? 1 : 0) + "\" />");
+        output.AppendLine("<setting id=\"use_tv_menu_language\" value=\"" + (UseTVLanguage.Value ? 1 : 0) + "\" />");
+        output.AppendLine("<setting id=\"enabled\" value=\"1\" />");
+        output.AppendLine("<setting id=\"port\" value=\"\" />");
+
+        // only supported by 1.5.0+ clients
+        output.AppendLine("<!-- the following lines are only supported by v1.5.0+ clients -->");
+        output.AppendLine("<setting id=\"activate_source\" value=\"" + (Settings.ActivateSource.Value ? 1 : 0) + "\" />");
+        output.AppendLine("<setting id=\"physical_address\" value=\"" + string.Format("{0,4:X}", Settings.OverridePhysicalAddress.Value ? Settings.PhysicalAddress.Value : 0).Trim() + "\" />");
+        output.AppendLine("<setting id=\"device_type\" value=\"" + (int)Settings.DeviceType.Value + "\" />");
+        output.AppendLine("<setting id=\"tv_vendor\" value=\"" + string.Format("{0,6:X}", Settings.OverrideTVVendor.Value ? (int)Settings.TVVendor.Value : 0).Trim() + "\" />");
+
+        if (HasAdvancedDeviceIdSet(Settings.WakeDevices.Value))
+        {
+          output.Append("<setting id=\"wake_devices_advanced\" value=\"");
+          StringBuilder strWakeDevices = new StringBuilder();
+          foreach (CecLogicalAddress addr in Settings.WakeDevices.Value.Addresses)
+            if (addr != CecLogicalAddress.Unknown)
+              strWakeDevices.Append(" " + (int)addr);
+          output.Append(strWakeDevices.ToString().Trim());
+          output.AppendLine("\" />");
+        }
+
+        if (Settings.WakeDevices.Value.IsSet(CecLogicalAddress.Tv) &&
+            Settings.WakeDevices.Value.IsSet(CecLogicalAddress.AudioSystem))
+          output.Append("<setting id=\"wake_devices\" value=\"36039\">");
+        else if (Settings.WakeDevices.Value.IsSet(CecLogicalAddress.Tv))
+          output.Append("<setting id=\"wake_devices\" value=\"36037\">");
+        else if (Settings.WakeDevices.Value.IsSet(CecLogicalAddress.AudioSystem))
+          output.Append("<setting id=\"wake_devices\" value=\"36038\">");
+        else
+          output.Append("<setting id=\"wake_devices\" value=\"231\">");
+
+        if (HasAdvancedDeviceIdSet(Settings.PowerOffDevices.Value))
+        {
+          output.Append("<setting id=\"standby_devices_advanced\" value=\"");
+          StringBuilder strSleepDevices = new StringBuilder();
+          foreach (CecLogicalAddress addr in Settings.PowerOffDevices.Value.Addresses)
+            if (addr != CecLogicalAddress.Unknown)
+              strSleepDevices.Append(" " + (int) addr);
+          output.Append(strSleepDevices.ToString().Trim());
+          output.AppendLine("\" />");
+        }
+
+        if (Settings.PowerOffDevices.Value.IsSet(CecLogicalAddress.Tv) &&
+            Settings.PowerOffDevices.Value.IsSet(CecLogicalAddress.AudioSystem))
+          output.Append("<setting id=\"standby_devices\" value=\"36039\">");
+        else if (Settings.PowerOffDevices.Value.IsSet(CecLogicalAddress.Tv))
+          output.Append("<setting id=\"standby_devices\" value=\"36037\">");
+        else if (Settings.PowerOffDevices.Value.IsSet(CecLogicalAddress.AudioSystem))
+          output.Append("<setting id=\"standby_devices\" value=\"36038\">");
+        else
+          output.Append("<setting id=\"standby_devices\" value=\"231\">");
+
+        // only supported by 1.5.1+ clients
+        output.AppendLine("<!-- the following lines are only supported by v1.5.1+ clients -->");
+        output.AppendLine("<setting id=\"send_inactive_source\" value=\"" + (SendInactiveSource.Value ? 1 : 0) + "\" />");
+
+        // only supported by 1.9.0+ clients
+        output.AppendLine("<setting id=\"pause_playback_on_deactivate\" value=\"" + (PausePlaybackOnDeactivate.Value ? 1 : 0) + "\" />");
+
+        output.AppendLine("</settings>");
+        writer.Write(output.ToString());
+        writer.Close();
+        fs.Close();
+        fs.Dispose();
+        MessageBox.Show(Resources.settings_stored, Resources.app_name, MessageBoxButtons.OK, MessageBoxIcon.Information);
+      }
+    }
+
+    public CECSettingBool UseTVLanguage
+    {
+      get
+      {
+        if (!Settings.ContainsKey(ProcessName + "_use_tv_language"))
+        {
+          CECSettingBool setting = new CECSettingBool(ProcessName + "_use_tv_language", Resources.app_use_tv_language, true, null);
+          Settings.Load(setting);
+          Settings[ProcessName + "_use_tv_language"] = setting;
+        }
+        return Settings[ProcessName + "_use_tv_language"].AsSettingBool;
+      }
+    }
+
+    public CECSettingBool StandbyScreensaver
+    {
+      get
+      {
+        if (!Settings.ContainsKey(ProcessName + "_standby_screensaver"))
+        {
+          CECSettingBool setting = new CECSettingBool(ProcessName + "_standby_screensaver", Resources.app_standby_screensaver, true, null);
+          Settings.Load(setting);
+          Settings[ProcessName + "_standby_screensaver"] = setting;
+        }
+        return Settings[ProcessName + "_standby_screensaver"].AsSettingBool;
+      }
+    }
+
+    public CECSettingBool ActivateSource
+    {
+      get
+      {
+        if (!Settings.ContainsKey(ProcessName + "_activate_source"))
+        {
+          CECSettingBool setting = new CECSettingBool(ProcessName + "_activate_source", Resources.global_activate_source, true, null);
+          Settings.Load(setting);
+          Settings[ProcessName + "_activate_source"] = setting;
+        }
+        return Settings[ProcessName + "_activate_source"].AsSettingBool;
+      }
+    }
+
+    public CECSettingBool PowerOffOnStandby
+    {
+      get
+      {
+        if (!Settings.ContainsKey(ProcessName + "_standby_on_tv_standby"))
+        {
+          CECSettingBool setting = new CECSettingBool(ProcessName + "_standby_on_tv_standby", Resources.app_standby_on_tv_standby, true, null);
+          Settings.Load(setting);
+          Settings[ProcessName + "_standby_on_tv_standby"] = setting;
+        }
+        return Settings[ProcessName + "_standby_on_tv_standby"].AsSettingBool;
+      }
+    }
+
+    public CECSettingBool SendInactiveSource
+    {
+      get
+      {
+        if (!Settings.ContainsKey(ProcessName + "_send_inactive_source"))
+        {
+          CECSettingBool setting = new CECSettingBool(ProcessName + "_send_inactive_source", Resources.app_send_inactive_source, true, null);
+          Settings.Load(setting);
+          Settings[ProcessName + "_send_inactive_source"] = setting;
+        }
+        return Settings[ProcessName + "_send_inactive_source"].AsSettingBool;
+      }
+    }
+
+    public CECSettingBool PausePlaybackOnDeactivate
+    {
+      get
+      {
+        if (!Settings.ContainsKey(ProcessName + "_pause_playback_on_deactivate"))
+        {
+          CECSettingBool setting = new CECSettingBool(ProcessName + "_pause_playback_on_deactivate", Resources.app_pause_playback_on_deactivate, true, null);
+          Settings.Load(setting);
+          Settings[ProcessName + "_pause_playback_on_deactivate"] = setting;
+        }
+        return Settings[ProcessName + "_pause_playback_on_deactivate"].AsSettingBool;
+      }
+    }
+       }
+}
diff --git a/src/LibCecTray/controller/applications/internal/XBMCControllerUI.Designer.cs b/src/LibCecTray/controller/applications/internal/XBMCControllerUI.Designer.cs
new file mode 100644 (file)
index 0000000..df02422
--- /dev/null
@@ -0,0 +1,192 @@
+namespace LibCECTray.controller.applications.@internal
+{
+       partial class XBMCControllerUI
+       {
+               /// <summary>
+               /// Required designer variable.
+               /// </summary>
+               private System.ComponentModel.IContainer components = null;
+
+               /// <summary>
+               /// Clean up any resources being used.
+               /// </summary>
+               /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+               protected override void Dispose(bool disposing)
+               {
+                       if (disposing && (components != null))
+                       {
+                               components.Dispose();
+                       }
+                       base.Dispose(disposing);
+               }
+
+               #region Windows Form Designer generated code
+
+               /// <summary>
+               /// Required method for Designer support - do not modify
+               /// the contents of this method with the code editor.
+               /// </summary>
+               private void InitializeComponent()
+               {
+      this.components = new System.ComponentModel.Container();
+      this.cbStartFullScreen = new System.Windows.Forms.CheckBox();
+      this.buttonBindingSource = new System.Windows.Forms.BindingSource(this.components);
+      this.bConfigure = new System.Windows.Forms.Button();
+      this.bStartApplication = new System.Windows.Forms.Button();
+      this.cbStandbyScreensaver = new System.Windows.Forms.CheckBox();
+      this.cbUseTvLanguage = new System.Windows.Forms.CheckBox();
+      this.bLoadConfig = new System.Windows.Forms.Button();
+      this.bSaveConfig = new System.Windows.Forms.Button();
+      this.cbStandbyTvStandby = new System.Windows.Forms.CheckBox();
+      this.cbInactiveSource = new System.Windows.Forms.CheckBox();
+      this.cbPauseOnDeactivate = new System.Windows.Forms.CheckBox();
+      ((System.ComponentModel.ISupportInitialize)(this.buttonBindingSource)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // cbStartFullScreen
+      // 
+      this.cbStartFullScreen.AutoSize = true;
+      this.cbStartFullScreen.Checked = true;
+      this.cbStartFullScreen.CheckState = System.Windows.Forms.CheckState.Checked;
+      this.cbStartFullScreen.Enabled = false;
+      this.cbStartFullScreen.Location = new System.Drawing.Point(12, 12);
+      this.cbStartFullScreen.Name = "cbStartFullScreen";
+      this.cbStartFullScreen.Size = new System.Drawing.Size(121, 17);
+      this.cbStartFullScreen.TabIndex = 50;
+      this.cbStartFullScreen.Text = "app_start_fullscreen";
+      this.cbStartFullScreen.UseVisualStyleBackColor = true;
+      // 
+      // bConfigure
+      // 
+      this.bConfigure.Location = new System.Drawing.Point(503, 8);
+      this.bConfigure.Name = "bConfigure";
+      this.bConfigure.Size = new System.Drawing.Size(75, 23);
+      this.bConfigure.TabIndex = 49;
+      this.bConfigure.Text = "Configure";
+      this.bConfigure.UseVisualStyleBackColor = true;
+      this.bConfigure.Click += new System.EventHandler(this.BConfigureClick);
+      // 
+      // bStartApplication
+      // 
+      this.bStartApplication.Enabled = false;
+      this.bStartApplication.Location = new System.Drawing.Point(11, 271);
+      this.bStartApplication.Name = "bStartApplication";
+      this.bStartApplication.Size = new System.Drawing.Size(119, 23);
+      this.bStartApplication.TabIndex = 45;
+      this.bStartApplication.Text = "Start application";
+      this.bStartApplication.UseVisualStyleBackColor = true;
+      this.bStartApplication.Click += new System.EventHandler(this.BStartApplicationClick);
+      // 
+      // cbStandbyScreensaver
+      // 
+      this.cbStandbyScreensaver.AutoSize = true;
+      this.cbStandbyScreensaver.Enabled = false;
+      this.cbStandbyScreensaver.Location = new System.Drawing.Point(11, 66);
+      this.cbStandbyScreensaver.Name = "cbStandbyScreensaver";
+      this.cbStandbyScreensaver.Size = new System.Drawing.Size(151, 17);
+      this.cbStandbyScreensaver.TabIndex = 53;
+      this.cbStandbyScreensaver.Text = "app_standby_screensaver";
+      this.cbStandbyScreensaver.UseVisualStyleBackColor = true;
+      // 
+      // cbUseTvLanguage
+      // 
+      this.cbUseTvLanguage.AutoSize = true;
+      this.cbUseTvLanguage.Enabled = false;
+      this.cbUseTvLanguage.Location = new System.Drawing.Point(11, 43);
+      this.cbUseTvLanguage.Name = "cbUseTvLanguage";
+      this.cbUseTvLanguage.Size = new System.Drawing.Size(132, 17);
+      this.cbUseTvLanguage.TabIndex = 51;
+      this.cbUseTvLanguage.Text = "app_use_tv_language";
+      this.cbUseTvLanguage.UseVisualStyleBackColor = true;
+      // 
+      // bLoadConfig
+      // 
+      this.bLoadConfig.Enabled = false;
+      this.bLoadConfig.Location = new System.Drawing.Point(186, 271);
+      this.bLoadConfig.Name = "bLoadConfig";
+      this.bLoadConfig.Size = new System.Drawing.Size(119, 23);
+      this.bLoadConfig.TabIndex = 55;
+      this.bLoadConfig.Text = "Import configuration";
+      this.bLoadConfig.UseVisualStyleBackColor = true;
+      this.bLoadConfig.Click += new System.EventHandler(this.BLoadConfigClick);
+      // 
+      // bSaveConfig
+      // 
+      this.bSaveConfig.Enabled = false;
+      this.bSaveConfig.Location = new System.Drawing.Point(311, 271);
+      this.bSaveConfig.Name = "bSaveConfig";
+      this.bSaveConfig.Size = new System.Drawing.Size(119, 23);
+      this.bSaveConfig.TabIndex = 56;
+      this.bSaveConfig.Text = "Save configuration";
+      this.bSaveConfig.UseVisualStyleBackColor = true;
+      this.bSaveConfig.Click += new System.EventHandler(this.BSaveConfigClick);
+      // 
+      // cbStandbyTvStandby
+      // 
+      this.cbStandbyTvStandby.AutoSize = true;
+      this.cbStandbyTvStandby.Enabled = false;
+      this.cbStandbyTvStandby.Location = new System.Drawing.Point(11, 89);
+      this.cbStandbyTvStandby.Name = "cbStandbyTvStandby";
+      this.cbStandbyTvStandby.Size = new System.Drawing.Size(163, 17);
+      this.cbStandbyTvStandby.TabIndex = 57;
+      this.cbStandbyTvStandby.Text = "app_standby_on_tv_standby";
+      this.cbStandbyTvStandby.UseVisualStyleBackColor = true;
+      // 
+      // cbInactiveSource
+      // 
+      this.cbInactiveSource.AutoSize = true;
+      this.cbInactiveSource.Enabled = false;
+      this.cbInactiveSource.Location = new System.Drawing.Point(11, 112);
+      this.cbInactiveSource.Name = "cbInactiveSource";
+      this.cbInactiveSource.Size = new System.Drawing.Size(154, 17);
+      this.cbInactiveSource.TabIndex = 58;
+      this.cbInactiveSource.Text = "app_send_inactive_source";
+      this.cbInactiveSource.UseVisualStyleBackColor = true;
+      // 
+      // cbPauseOnDeactivate
+      // 
+      this.cbPauseOnDeactivate.AutoSize = true;
+      this.cbPauseOnDeactivate.Enabled = false;
+      this.cbPauseOnDeactivate.Location = new System.Drawing.Point(11, 135);
+      this.cbPauseOnDeactivate.Name = "cbPauseOnDeactivate";
+      this.cbPauseOnDeactivate.Size = new System.Drawing.Size(202, 17);
+      this.cbPauseOnDeactivate.TabIndex = 59;
+      this.cbPauseOnDeactivate.Text = "app_pause_playback_on_deactivate";
+      this.cbPauseOnDeactivate.UseVisualStyleBackColor = true;
+      // 
+      // XBMCControllerUI
+      // 
+      this.ClientSize = new System.Drawing.Size(576, 306);
+      this.Controls.Add(this.cbPauseOnDeactivate);
+      this.Controls.Add(this.cbInactiveSource);
+      this.Controls.Add(this.cbStandbyTvStandby);
+      this.Controls.Add(this.bSaveConfig);
+      this.Controls.Add(this.bLoadConfig);
+      this.Controls.Add(this.cbStandbyScreensaver);
+      this.Controls.Add(this.cbUseTvLanguage);
+      this.Controls.Add(this.cbStartFullScreen);
+      this.Controls.Add(this.bConfigure);
+      this.Controls.Add(this.bStartApplication);
+      this.Name = "XBMCControllerUI";
+      this.Text = "XBMCControllerUI";
+      ((System.ComponentModel.ISupportInitialize)(this.buttonBindingSource)).EndInit();
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+               }
+
+               #endregion
+
+    private System.Windows.Forms.CheckBox cbStartFullScreen;
+    private System.Windows.Forms.BindingSource buttonBindingSource;
+    private System.Windows.Forms.Button bConfigure;
+    private System.Windows.Forms.Button bStartApplication;
+    private System.Windows.Forms.CheckBox cbStandbyScreensaver;
+    private System.Windows.Forms.CheckBox cbUseTvLanguage;
+    private System.Windows.Forms.Button bLoadConfig;
+    private System.Windows.Forms.Button bSaveConfig;
+    private System.Windows.Forms.CheckBox cbStandbyTvStandby;
+    private System.Windows.Forms.CheckBox cbInactiveSource;
+    private System.Windows.Forms.CheckBox cbPauseOnDeactivate;
+       }
+}
\ No newline at end of file
diff --git a/src/LibCecTray/controller/applications/internal/XBMCControllerUI.cs b/src/LibCecTray/controller/applications/internal/XBMCControllerUI.cs
new file mode 100644 (file)
index 0000000..7c2226f
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing       <license@pulse-eight.com>
+ *     http://www.pulse-eight.com/
+ *     http://www.pulse-eight.net/
+ */
+
+using System;
+using System.Windows.Forms;
+using LibCECTray.Properties;
+
+namespace LibCECTray.controller.applications.@internal
+{
+  internal partial class XBMCControllerUI : ControllerTabPage
+       {
+               public XBMCControllerUI()
+               {
+                       InitializeComponent();
+               }
+
+    public XBMCControllerUI(XBMCController controller)
+    {
+      _controller = controller;
+      InitializeComponent();
+      Name = controller.UiName;
+      Text = controller.UiName;
+
+      _controller.StartFullScreen.ReplaceControls(this, Controls, cbStartFullScreen);
+      _controller.UseTVLanguage.ReplaceControls(this, Controls, cbUseTvLanguage);
+      _controller.StandbyScreensaver.ReplaceControls(this, Controls, cbStandbyScreensaver);
+      _controller.PowerOffOnStandby.ReplaceControls(this, Controls, cbStandbyTvStandby);
+      _controller.SendInactiveSource.ReplaceControls(this, Controls, cbInactiveSource);
+      _controller.PausePlaybackOnDeactivate.ReplaceControls(this, Controls, cbPauseOnDeactivate);
+
+      SetEnabled(false);
+    }
+
+    public override sealed string Text
+    {
+      get { return base.Text; }
+      set { base.Text = value; }
+    }
+
+    public override sealed void SetEnabled(bool val)
+    {
+      SetControlEnabled(bStartApplication, !_controller.IsRunning() && !_controller.SuppressApplicationStart && val);
+      SetControlEnabled(_controller.StartFullScreen.ValueControl, val);
+      SetControlEnabled(_controller.StandbyScreensaver.ValueControl, val);
+      SetControlEnabled(_controller.UseTVLanguage.ValueControl, val);
+      SetControlEnabled(_controller.ActivateSource.ValueControl, val);
+      SetControlEnabled(_controller.PowerOffOnStandby.ValueControl, val);
+      SetControlEnabled(_controller.SendInactiveSource.ValueControl, val);
+      SetControlEnabled(bSaveConfig, val);
+      SetControlEnabled(bLoadConfig, val);
+      SetControlEnabled(bConfigure, _controller.CanConfigureProcess && val);
+      SetControlEnabled(_controller.PausePlaybackOnDeactivate.ValueControl, val);
+    }
+
+    public override void SetStartButtonEnabled(bool val)
+    {
+      SetControlEnabled(bStartApplication, !_controller.IsRunning() && !_controller.SuppressApplicationStart && val);
+    }
+
+    private void BConfigureClick(object sender, EventArgs e)
+    {
+      bConfigure.Enabled = false;
+      ConfigureApplication appConfig = new ConfigureApplication(_controller);
+      appConfig.Disposed += delegate { bConfigure.Enabled = true; };
+      DisplayDialog(appConfig, false);
+    }
+
+    private readonly XBMCController _controller;
+
+    private void BStartApplicationClick(object sender, EventArgs e)
+    {
+      if (MessageBox.Show(Resources.start_xbmc_exit_tray, Resources.title_are_you_sure, MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.Yes)
+      {
+        bStartApplication.Enabled = false;
+        _controller.Start(true);
+      }
+    }
+
+    private void BLoadConfigClick(object sender, EventArgs e)
+    {
+      _controller.LoadXMLConfiguration();
+    }
+
+    private void BSaveConfigClick(object sender, EventArgs e)
+    {
+      _controller.SaveXMLConfiguration();
+    }
+       }
+}
diff --git a/src/LibCecTray/controller/applications/internal/XBMCControllerUI.resx b/src/LibCecTray/controller/applications/internal/XBMCControllerUI.resx
new file mode 100644 (file)
index 0000000..f5c4adb
--- /dev/null
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <metadata name="buttonBindingSource.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>17, 17</value>
+  </metadata>
+</root>
\ No newline at end of file
diff --git a/src/LibCecTray/settings/CECSetting.cs b/src/LibCecTray/settings/CECSetting.cs
new file mode 100644 (file)
index 0000000..5a32ad2
--- /dev/null
@@ -0,0 +1,378 @@
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing       <license@pulse-eight.com>
+ *     http://www.pulse-eight.com/
+ *     http://www.pulse-eight.net/
+ */
+
+using System.Drawing;
+using LibCECTray.ui;
+using Microsoft.Win32;
+using System.Windows.Forms;
+
+namespace LibCECTray.settings
+{
+  enum CECSettingSerialisationType
+  {
+    Numeric,
+    String
+  }
+
+  enum CECSettingType
+  {
+    Numeric,
+    String,
+    Bool,
+    Byte,
+    DeviceType,
+    LogicalAddress,
+    LogicalAddresses,
+    UShort,
+    VendorId,
+    Button,
+    Generic
+  }
+
+  /// <summary>
+  /// Base class for settings that can be persisted in the registry
+  /// </summary>
+  abstract class CECSetting
+  {
+    /// <summary>
+    /// Create a new setting
+    /// </summary>
+    /// <param name="type">The type of this setting</param>
+    /// <param name="serialisationType">The serialisationType of the setting</param>
+    /// <param name="keyName">The name of the key in the registry</param>
+    /// <param name="friendlyName">The name of the setting in the UI</param>
+    /// <param name="defaultValue">Default value of the setting</param>
+    /// <param name="changedHandler">Called when the setting changed</param>
+    protected CECSetting(CECSettingType type, CECSettingSerialisationType serialisationType, string keyName, string friendlyName, object defaultValue, SettingChangedHandler changedHandler)
+    {
+      SettingType = type;
+      SettingSerialisationType = serialisationType;
+      KeyName = keyName;
+      FriendlyName = friendlyName;
+      DefaultValue = defaultValue;
+      _value = defaultValue;
+
+      if (changedHandler != null)
+        SettingChanged += changedHandler;
+    }
+
+    #region Serialisation methods
+    /// <summary>
+    /// Get the value of the setting in a form that can be stored in the registry
+    /// </summary>
+    /// <returns>The serialised value</returns>
+    protected abstract string GetSerialisedValue();
+
+    /// <summary>
+    /// Set the value from the serialised form of it.
+    /// </summary>
+    /// <param name="value">The serialised value</param>
+    protected abstract void SetSerialisedValue(string value);
+
+    /// <summary>
+    /// Get the default value of the setting in a form that can be stored in the registry
+    /// </summary>
+    /// <returns>The serialised default value</returns>
+    protected abstract string GetSerialisedDefaultValue();
+
+    /// <summary>
+    /// Set the default value from the serialised form of it.
+    /// </summary>
+    /// <param name="value">The serialised default value</param>
+    protected abstract void SetSerialisedDefaultValue(string value);
+    #endregion
+
+    /// <summary>
+    /// Set the value to the default.
+    /// </summary>
+    public void ResetDefaultValue()
+    {
+      Value = DefaultValue;
+    }
+
+    #region Read/Write the corresponding registry key
+    /// <summary>
+    /// Load the value from the registry
+    /// </summary>
+    /// <param name="key">The registry key to read the value from</param>
+    public void Load(RegistryKey key)
+    {
+      _value = key.GetValue(KeyName) ?? DefaultValue;
+      Changed = false;
+    }
+
+    /// <summary>
+    /// Persist the value in the registry
+    /// </summary>
+    /// <param name="key">The registry key to save the value to</param>
+    public void Persist(RegistryKey key)
+    {
+      if (_value != DefaultValue)
+        key.SetValue(KeyName, _value);
+    }
+    #endregion
+
+    #region GUI control replacement
+    /// <summary>
+    /// Replaces the controls in the form that was generated by the gui designer
+    /// </summary>
+    /// <param name="form">The form which contains the controls that are to be replaced</param>
+    /// <param name="controls">The controls container which contains the controls that are to be replaced</param>
+    /// <param name="labelControl">The label control to replace</param>
+    /// <param name="valueControl">The value control to replace</param>
+    public void ReplaceControls(IAsyncControls form, Control.ControlCollection controls, Control labelControl, Control valueControl)
+    {
+      Form = form;
+      ReplaceControl(controls, labelControl, Label);
+      ReplaceControl(controls, valueControl, ValueControl);
+    }
+
+    /// <summary>
+    /// Replaces the controls in the form that was generated by the gui designer
+    /// </summary>
+    /// <param name="form">The form which contains the controls that are to be replaced</param>
+    /// <param name="controls">The controls container which contains the controls that are to be replaced</param>
+    /// <param name="valueControl">The value control to replace</param>
+    public void ReplaceControls(AsyncForm form, Control.ControlCollection controls, Control valueControl)
+    {
+      Form = form;
+      ReplaceControl(controls, valueControl, ValueControl);
+    }
+
+    /// <summary>
+    /// Replaces the controls in the form that was generated by the gui designer
+    /// </summary>
+    /// <param name="controls">The controls container which contains the controls that are to be replaced</param>
+    /// <param name="originalControl">The control to replace</param>
+    /// <param name="replacement">The replacement</param>
+    protected static void ReplaceControl(Control.ControlCollection controls, Control originalControl, Control replacement)
+    {
+      if (originalControl == null)
+        return;
+
+      var location = originalControl.Location;
+      var originalSize = originalControl.Size;
+      var tabIndex = originalControl.TabIndex;
+
+      controls.Remove(originalControl);
+
+      if (replacement != null)
+      {
+        controls.Add(replacement);
+        replacement.Location = location;
+        replacement.Size = originalSize;
+        replacement.TabIndex = tabIndex;
+      }
+    }
+    #endregion
+
+    /// <summary>
+    /// A setting changed
+    /// </summary>
+    /// <param name="setting">The setting that changed</param>
+    /// <param name="oldValue">The old value</param>
+    /// <param name="newValue">The new value</param>
+    public delegate void SettingChangedHandler(CECSetting setting, object oldValue, object newValue);
+
+    /// <summary>
+    /// Checks if a setting may be enabled
+    /// </summary>
+    /// <param name="setting">The setting</param>
+    /// <param name="value">The value that the controller wants to set</param>
+    /// <returns>The Enabled value that will be used</returns>
+    public delegate bool EnableSettingHandler(CECSetting setting, bool value);
+
+    #region Convenience methods
+    public CECSettingBool AsSettingBool
+    {
+      get { return this as CECSettingBool; }
+    }
+    public CECSettingByte AsSettingByte
+    {
+      get { return this as CECSettingByte; }
+    }
+    public CECSettingDeviceType AsSettingDeviceType
+    {
+      get { return this as CECSettingDeviceType; }
+    }
+    public CECSettingLogicalAddress AsSettingLogicalAddress
+    {
+      get { return this as CECSettingLogicalAddress; }
+    }
+    public CECSettingLogicalAddresses AsSettingLogicalAddresses
+    {
+      get { return this as CECSettingLogicalAddresses; }
+    }
+    public CECSettingNumeric AsSettingNumeric
+    {
+      get { return this as CECSettingNumeric; }
+    }
+    public CECSettingString AsSettingString
+    {
+      get { return this as CECSettingString; }
+    }
+    public CECSettingUShort AsSettingUShort
+    {
+      get { return this as CECSettingUShort; }
+    }
+    public CECSettingVendorId AsSettingVendorId
+    {
+      get { return this as CECSettingVendorId; }
+    }
+    #endregion
+
+    #region Members
+    /// <summary>
+    /// Name of the key in the registry
+    /// </summary>
+    public string KeyName { protected set; get; }
+
+    /// <summary>
+    /// Name of the setting in the UI
+    /// </summary>
+    public string FriendlyName { protected set; get; }
+
+    /// <summary>
+    /// The current value of the setting
+    /// </summary>
+    public object Value {
+      get { return _value; }
+      set
+      {
+        if (_value == value) return;
+        Changed = true;
+        var oldValue = _value;
+        _value = value;
+        if (SettingChanged != null)
+          SettingChanged(this, oldValue, value);
+      }
+    }
+    private object _value;
+
+    /// <summary>
+    /// The default value of the setting
+    /// </summary>
+    public object DefaultValue { protected set; get; }
+
+    /// <summary>
+    /// The serialisationType of this setting
+    /// </summary>
+    public CECSettingSerialisationType SettingSerialisationType { private set; get; }
+
+    /// <summary>
+    /// The type of this setting
+    /// </summary>
+    public CECSettingType SettingType { private set; get; }
+
+    /// <summary>
+    /// True when changed and changes have not been persisted yet, false otherwise.
+    /// </summary>
+    public bool Changed { protected set; get; }
+
+    /// <summary>
+    /// The gui Control that contains the value
+    /// </summary>
+    public virtual Control ValueControl { get { return BaseValueControl; } }
+
+    /// <summary>
+    /// The value control to use in the gui
+    /// </summary>
+    protected Control BaseValueControl;
+
+    /// <summary>
+    /// True when changing the value of the ValueControl requires an invoke, false otherwise
+    /// </summary>
+    public virtual bool InvokeRequired
+    {
+      get { return BaseValueControl != null && BaseValueControl.InvokeRequired; }
+    }
+
+    /// <summary>
+    /// The label with the description for this setting
+    /// </summary>
+    public Label Label
+    {
+      get {
+        return _label ??
+               (_label = new Label {AutoSize = true, Size = new Size(100, 13), Text = FriendlyName});
+      }
+    }
+    private Label _label;
+
+    /// <summary>
+    /// Setting changed
+    /// </summary>
+    public event SettingChangedHandler SettingChanged;
+
+    /// <summary>
+    /// Setting will be enabled
+    /// </summary>
+    public EnableSettingHandler EnableSetting;
+
+    /// <summary>
+    /// The initial enabled state
+    /// </summary>
+    protected bool InitialEnabledValue
+    {
+      get { return _enabled; }
+    }
+
+    /// <summary>
+    /// The enabled state of the gui control
+    /// </summary>
+    public virtual bool Enabled
+    {
+      set
+      {
+        var newValue = value;
+        if (EnableSetting != null)
+          newValue = EnableSetting(this, value);
+
+        _enabled = newValue;
+        if (Form != null)
+          Form.SetControlEnabled(ValueControl, newValue);
+      }
+      get
+      {
+        return ValueControl != null ? ValueControl.Enabled : _enabled;
+      }
+    }
+
+    /// <summary>
+    /// The for that contains the gui controls
+    /// </summary>
+    protected IAsyncControls Form;
+
+    private bool _enabled = true;
+    #endregion
+  }
+}
diff --git a/src/LibCecTray/settings/CECSettingBool.cs b/src/LibCecTray/settings/CECSettingBool.cs
new file mode 100644 (file)
index 0000000..056661b
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing       <license@pulse-eight.com>
+ *     http://www.pulse-eight.com/
+ *     http://www.pulse-eight.net/
+ */
+
+using System.Windows.Forms;
+using LibCECTray.ui;
+
+namespace LibCECTray.settings
+{
+  /// <summary>
+  /// A setting of type bool that can be persisted in the registry
+  /// </summary>
+  class CECSettingBool : CECSettingNumeric
+  {
+    public CECSettingBool(string keyName, string friendlyName, bool defaultValue, SettingChangedHandler changedHandler) :
+      base(CECSettingType.Bool, keyName, friendlyName, defaultValue ? 1 : 0, changedHandler)
+    {
+    }
+
+    public new bool Value
+    {
+      get { return base.Value == 1; }
+      set
+      {
+        base.Value = value ? 1 : 0;
+        CheckBox control = BaseValueControl as CheckBox;
+        if (control != null && Form != null)
+          Form.SetCheckboxChecked(control, value);
+      }
+    }
+
+    public new bool DefaultValue
+    {
+      get { return base.DefaultValue == 1; }
+      set { base.DefaultValue = value ? 1 : 0; }
+    }
+
+    public new CheckBox ValueControl
+    {
+      get
+      {
+        if (BaseValueControl == null)
+        {
+          CheckBox control = new CheckBox
+                               {
+                                 AutoSize = true,
+                                 Size = new System.Drawing.Size(150, 17),
+                                 Text = Label.Text,
+                                 UseVisualStyleBackColor = true,
+                                 Enabled = InitialEnabledValue,
+                                 Checked = Value
+                               };
+          control.CheckedChanged += delegate { Value = control.Checked; };
+          BaseValueControl = control;
+        }
+        return BaseValueControl as CheckBox;
+      }
+    }
+
+    public void ReplaceControls(IAsyncControls form, Control.ControlCollection controls, Control labelControl, CheckBox valueControl)
+    {
+      Form = form;
+      ReplaceControl(controls, labelControl, Label);
+      ReplaceControl(controls, valueControl, ValueControl);
+    }
+
+    public void ReplaceControls(IAsyncControls form, Control.ControlCollection controls, CheckBox valueControl)
+    {
+      Form = form;
+      ReplaceControl(controls, valueControl, ValueControl);
+    }
+  }
+}
diff --git a/src/LibCecTray/settings/CECSettingByte.cs b/src/LibCecTray/settings/CECSettingByte.cs
new file mode 100644 (file)
index 0000000..e135bfc
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing       <license@pulse-eight.com>
+ *     http://www.pulse-eight.com/
+ *     http://www.pulse-eight.net/
+ */
+
+namespace LibCECTray.settings
+{
+  /// <summary>
+  /// A setting of type byte that can be persisted in the registry
+  /// </summary>
+  class CECSettingByte : CECSettingNumeric
+  {
+    public CECSettingByte(string keyName, string friendlyName, byte defaultValue, SettingChangedHandler changedHandler) :
+      base(CECSettingType.Byte, keyName, friendlyName, defaultValue, changedHandler)
+    {
+    }
+
+    public new byte Value
+    {
+      get { return base.Value <= byte.MaxValue && base.Value >= byte.MinValue ? (byte)base.Value : byte.MaxValue; }
+      set { base.Value = value; }
+    }
+
+    public new byte DefaultValue
+    {
+      get { return base.DefaultValue <= byte.MaxValue && base.DefaultValue >= byte.MinValue ? (byte)base.DefaultValue : byte.MaxValue; }
+      set { base.DefaultValue = value; }
+    }
+  }
+}
diff --git a/src/LibCecTray/settings/CECSettingDeviceType.cs b/src/LibCecTray/settings/CECSettingDeviceType.cs
new file mode 100644 (file)
index 0000000..0faf5c3
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing       <license@pulse-eight.com>
+ *     http://www.pulse-eight.com/
+ *     http://www.pulse-eight.net/
+ */
+
+using System.Windows.Forms;
+using CecSharp;
+using LibCECTray.Properties;
+
+namespace LibCECTray.settings
+{
+  /// <summary>
+  /// A setting of type CecDeviceType that can be persisted in the registry
+  /// </summary>
+  class CECSettingDeviceType : CECSettingNumeric
+  {
+    public CECSettingDeviceType(string keyName, string friendlyName, CecDeviceType defaultValue, SettingChangedHandler changedHandler) :
+      base(CECSettingType.DeviceType, keyName, friendlyName, (int)defaultValue, changedHandler, OnFormat)
+    {
+      LowerLimit = (int) CecDeviceType.Tv;
+      UpperLimit = (int) CecDeviceType.AudioSystem;
+    }
+
+    private static void OnFormat(object sender, ListControlConvertEventArgs listControlConvertEventArgs)
+    {
+      int iValue;
+      if (int.TryParse((string)listControlConvertEventArgs.Value, out iValue))
+        listControlConvertEventArgs.Value = FormatValue(iValue);
+    }
+
+    public new CecDeviceType Value
+    {
+      get { return base.Value >= (int)CecDeviceType.Tv && base.Value <= (int)CecDeviceType.AudioSystem ? (CecDeviceType)base.Value : CecDeviceType.Reserved; }
+      set
+      {
+        base.Value = (int)value;
+        if (Form == null) return;
+        switch (value)
+        {
+          case CecDeviceType.RecordingDevice:
+            Form.SetControlText(ValueControl, Resources.device_recorder);
+            break;
+          case CecDeviceType.PlaybackDevice:
+            Form.SetControlText(ValueControl, Resources.device_playbackdevice);
+            break;
+          case CecDeviceType.Tuner:
+            Form.SetControlText(ValueControl, Resources.device_tuner);
+            break;
+          default:
+            Form.SetControlText(ValueControl, Resources.device_recorder);
+            break;
+        }
+      }
+    }
+
+    public new CecDeviceType DefaultValue
+    {
+      get { return base.DefaultValue >= (int)CecDeviceType.Tv && base.DefaultValue <= (int)CecDeviceType.AudioSystem ? (CecDeviceType)base.DefaultValue : CecDeviceType.Reserved; }
+      set { base.DefaultValue = (int)value; }
+    }
+
+    private static string FormatValue(int value)
+    {
+      switch ((CecDeviceType)value)
+      {
+        case CecDeviceType.Tv:
+          return Resources.device_tv;
+        case CecDeviceType.PlaybackDevice:
+          return Resources.device_playbackdevice;
+        case CecDeviceType.AudioSystem:
+          return Resources.device_audiosystem;
+        case CecDeviceType.RecordingDevice:
+          return Resources.device_recorder;
+        case CecDeviceType.Tuner:
+          return Resources.device_tuner;
+        case CecDeviceType.Reserved:
+          return Resources.device_reserved;
+      }
+      return Resources.unknown;
+    }
+
+    protected override bool AllowedValue(int value)
+    {
+      if ((CecDeviceType)value == CecDeviceType.Reserved)
+        return false;
+      for (var i = 0; i < _allowedTypeMask.Types.Length; i++)
+      {
+        if (_allowedTypeMask.Types[i] == (CecDeviceType) value)
+          return true;
+      }
+      return false;
+    }
+
+    private CecDeviceTypeList _allowedTypeMask;
+    public CecDeviceTypeList AllowedTypeMask
+    {
+      get
+      {
+        return _allowedTypeMask ?? (_allowedTypeMask = new CecDeviceTypeList
+                                                         {
+                                                           Types =
+                                                             new[]
+                                                               {
+                                                                 CecDeviceType.Tv, CecDeviceType.PlaybackDevice,
+                                                                 CecDeviceType.RecordingDevice,
+                                                                 CecDeviceType.AudioSystem, CecDeviceType.Tuner
+                                                               }
+                                                         });
+      }
+      set
+      {
+        _allowedTypeMask = value;
+        ResetItems(true);
+      }
+    }
+  }
+}
diff --git a/src/LibCecTray/settings/CECSettingLogicalAddress.cs b/src/LibCecTray/settings/CECSettingLogicalAddress.cs
new file mode 100644 (file)
index 0000000..252b5c3
--- /dev/null
@@ -0,0 +1,105 @@
+using System.Windows.Forms;
+using CecSharp;
+using LibCECTray.Properties;
+
+namespace LibCECTray.settings
+{
+  /// <summary>
+  /// A setting of type CecLogicalAddress that can be persisted in the registry
+  /// </summary>
+  class CECSettingLogicalAddress : CECSettingNumeric
+  {
+    public CECSettingLogicalAddress(string keyName, string friendlyName, CecLogicalAddress defaultValue, SettingChangedHandler changedHandler) :
+      base(CECSettingType.LogicalAddress, keyName, friendlyName, (int)defaultValue, changedHandler, OnFormat)
+    {
+      LowerLimit = (int) CecLogicalAddress.Tv;
+      UpperLimit = (int) CecLogicalAddress.Broadcast;
+    }
+
+    private static void OnFormat(object sender, ListControlConvertEventArgs listControlConvertEventArgs)
+    {
+      int iValue;
+      if (int.TryParse((string)listControlConvertEventArgs.Value, out iValue))
+        listControlConvertEventArgs.Value = FormatValue(iValue);
+    }
+
+    public new CecLogicalAddress Value
+    {
+      get { return base.Value >= (int)CecLogicalAddress.Tv && base.Value <= (int)CecLogicalAddress.Broadcast ? (CecLogicalAddress)base.Value : CecLogicalAddress.Unknown; }
+      set { base.Value = (int)value; }
+    }
+
+    public new CecLogicalAddress DefaultValue
+    {
+      get { return base.DefaultValue >= (int)CecLogicalAddress.Tv && base.DefaultValue <= (int)CecLogicalAddress.Broadcast ? (CecLogicalAddress)base.DefaultValue : CecLogicalAddress.Unknown; }
+      set { base.DefaultValue = (int)value; }
+    }
+
+    private static string FormatValue(int value)
+    {
+      switch ((CecLogicalAddress)value)
+      {
+        case CecLogicalAddress.AudioSystem:
+          return CECSettings.VendorNames[value] == null || CECSettings.VendorNames[value].Length == 0 ? Resources.device_audiosystem : CECSettings.VendorNames[value] + " " + Resources.device_audiosystem;
+        case CecLogicalAddress.Broadcast:
+          return Resources.device_broadcast;
+        case CecLogicalAddress.FreeUse:
+          return Resources.device_free_use;
+        case CecLogicalAddress.PlaybackDevice1:
+          return CECSettings.VendorNames[value] == null || CECSettings.VendorNames[value].Length == 0 ? Resources.device_playbackdevice + " 1" : CECSettings.VendorNames[value] + " " + Resources.device_playbackdevice + " 1";
+        case CecLogicalAddress.PlaybackDevice2:
+          return CECSettings.VendorNames[value] == null || CECSettings.VendorNames[value].Length == 0 ? Resources.device_playbackdevice + " 2" : CECSettings.VendorNames[value] + " " + Resources.device_playbackdevice + " 2";
+        case CecLogicalAddress.PlaybackDevice3:
+          return CECSettings.VendorNames[value] == null || CECSettings.VendorNames[value].Length == 0 ? Resources.device_playbackdevice + " 3" : CECSettings.VendorNames[value] + " " + Resources.device_playbackdevice + " 3";
+        case CecLogicalAddress.RecordingDevice1:
+          return CECSettings.VendorNames[value] == null || CECSettings.VendorNames[value].Length == 0 ? Resources.device_recorder + " 1" : CECSettings.VendorNames[value] + " " + Resources.device_recorder + " 1";
+        case CecLogicalAddress.RecordingDevice2:
+          return CECSettings.VendorNames[value] == null || CECSettings.VendorNames[value].Length == 0 ? Resources.device_recorder + " 2" : CECSettings.VendorNames[value] + " " + Resources.device_recorder + " 2";
+        case CecLogicalAddress.RecordingDevice3:
+          return CECSettings.VendorNames[value] == null || CECSettings.VendorNames[value].Length == 0 ? Resources.device_recorder + " 3" : CECSettings.VendorNames[value] + " " + Resources.device_recorder + " 3";
+        case CecLogicalAddress.Reserved1:
+          return Resources.device_reserved + " 1";
+        case CecLogicalAddress.Reserved2:
+          return Resources.device_reserved + " 2";
+        case CecLogicalAddress.Tuner1:
+          return CECSettings.VendorNames[value] == null || CECSettings.VendorNames[value].Length == 0 ? Resources.device_tuner + " 1" : CECSettings.VendorNames[value] + " " + Resources.device_tuner + " 1";
+        case CecLogicalAddress.Tuner2:
+          return CECSettings.VendorNames[value] == null || CECSettings.VendorNames[value].Length == 0 ? Resources.device_tuner + " 2" : CECSettings.VendorNames[value] + " " + Resources.device_tuner + " 2";
+        case CecLogicalAddress.Tuner3:
+          return CECSettings.VendorNames[value] == null || CECSettings.VendorNames[value].Length == 0 ? Resources.device_tuner + " 3" : CECSettings.VendorNames[value] + " " + Resources.device_tuner + " 3";
+        case CecLogicalAddress.Tuner4:
+          return CECSettings.VendorNames[value] == null || CECSettings.VendorNames[value].Length == 0 ? Resources.device_tuner + " 4" : CECSettings.VendorNames[value] + " " + Resources.device_tuner + " 4";
+        case CecLogicalAddress.Tv:
+          return CECSettings.VendorNames[value] == null || CECSettings.VendorNames[value].Length == 0 ? Resources.device_tv : CECSettings.VendorNames[value] + " " + Resources.device_tv;
+        default:
+          return Resources.unknown;
+      }
+    }
+
+    protected override bool AllowedValue(int value)
+    {
+      return AllowedAddressMask.IsSet((CecLogicalAddress)value);
+    }
+
+    private CecLogicalAddresses _allowedAddressMask;
+    public CecLogicalAddresses AllowedAddressMask
+    {
+      get
+      {
+        if (_allowedAddressMask == null)
+        {
+          _allowedAddressMask = new CecLogicalAddresses();
+          for (int iPtr = 0; iPtr < 16; iPtr++)
+            _allowedAddressMask.Set((CecLogicalAddress)iPtr);
+        }
+        return _allowedAddressMask;
+      }
+      set
+      {
+        _allowedAddressMask = value;
+        ResetItems(true);
+      }
+    }
+  }
+
+}
diff --git a/src/LibCecTray/settings/CECSettingLogicalAddresses.cs b/src/LibCecTray/settings/CECSettingLogicalAddresses.cs
new file mode 100644 (file)
index 0000000..0a9950c
--- /dev/null
@@ -0,0 +1,209 @@
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing       <license@pulse-eight.com>
+ *     http://www.pulse-eight.com/
+ *     http://www.pulse-eight.net/
+ */
+
+using System;
+using System.Windows.Forms;
+using CecSharp;
+using LibCECTray.Properties;
+using LibCECTray.ui;
+
+namespace LibCECTray.settings
+{
+  /// <summary>
+  /// A setting of type CecLogicalAddresses that can be persisted in the registry
+  /// </summary>
+  class CECSettingLogicalAddresses : CECSettingNumeric
+  {
+    public CECSettingLogicalAddresses(string keyName, string friendlyName, CecLogicalAddresses defaultValue, SettingChangedHandler changedHandler) :
+      base(CECSettingType.LogicalAddresses, keyName, friendlyName, SerialiseLogicalAddresses(defaultValue), changedHandler)
+    {
+    }
+
+    private static int SerialiseLogicalAddresses(CecLogicalAddresses addresses)
+    {
+      var retVal = 0;
+      for (int addr = (int)CecLogicalAddress.Tv; addr <= (int)CecLogicalAddress.Broadcast; addr++)
+      {
+        if (addresses.IsSet((CecLogicalAddress)addr))
+        {
+          retVal += (int)Math.Pow(2, addr);
+        }
+      }
+
+      return retVal;
+    }
+
+    private static CecLogicalAddresses DeserialiseLogicalAddresses(int addresses)
+    {
+      CecLogicalAddresses retVal = new CecLogicalAddresses();
+      if (addresses == 0)
+        return retVal;
+
+      for (int addr = (int)CecLogicalAddress.Tv; addr <= (int)CecLogicalAddress.Broadcast; addr++)
+      {
+        int val = (int)Math.Pow(2, addr);
+        if ((addresses & val) == val)
+          retVal.Set((CecLogicalAddress)addr);
+      }
+
+      return retVal;
+    }
+
+    public new CecLogicalAddresses Value
+    {
+      get { return DeserialiseLogicalAddresses(base.Value); }
+      set
+      {
+        base.Value = SerialiseLogicalAddresses(value);
+        if (Form == null) return;
+        for (int iPtr = 0; iPtr < 15; iPtr++)
+          Form.SetCheckboxItemChecked(ValueControl, iPtr, value.IsSet((CecLogicalAddress) iPtr));
+      }
+    }
+
+    public new CecLogicalAddresses DefaultValue
+    {
+      get { return DeserialiseLogicalAddresses(base.DefaultValue); }
+      set { base.DefaultValue = SerialiseLogicalAddresses(value); }
+    }
+
+    public static CecLogicalAddress GetLogicalAddressFromString(string name)
+    {
+      switch (name.Substring(0, 1).ToLower())
+      {
+        case "0":
+          return CecLogicalAddress.Tv;
+        case "1":
+          return CecLogicalAddress.RecordingDevice1;
+        case "2":
+          return CecLogicalAddress.RecordingDevice2;
+        case "3":
+          return CecLogicalAddress.Tuner1;
+        case "4":
+          return CecLogicalAddress.PlaybackDevice1;
+        case "5":
+          return CecLogicalAddress.AudioSystem;
+        case "6":
+          return CecLogicalAddress.Tuner2;
+        case "7":
+          return CecLogicalAddress.Tuner3;
+        case "8":
+          return CecLogicalAddress.PlaybackDevice2;
+        case "9":
+          return CecLogicalAddress.RecordingDevice3;
+        case "a":
+          return CecLogicalAddress.Tuner4;
+        case "b":
+          return CecLogicalAddress.PlaybackDevice3;
+        case "c":
+          return CecLogicalAddress.Reserved1;
+        case "d":
+          return CecLogicalAddress.Reserved2;
+        case "e":
+          return CecLogicalAddress.FreeUse;
+        case "f":
+          return CecLogicalAddress.Broadcast;
+        default:
+          return CecLogicalAddress.Unknown;
+      }
+    }
+
+    public new CheckedListBox ValueControl
+    {
+      get
+      {
+        if (BaseValueControl == null)
+        {
+          CheckedListBox control = new CheckedListBox
+          {
+            FormattingEnabled = true,
+            Name = KeyName,
+            Size = new System.Drawing.Size(118, 94),
+            Enabled = InitialEnabledValue
+          };
+          control.Items.AddRange(new object[] {
+            "0: " + Resources.device_tv,
+            "1: " + Resources.device_recorder + " 1",
+            "2: " + Resources.device_recorder + " 2",
+            "3: " + Resources.device_tuner + " 1",
+            "4: " + Resources.device_playbackdevice + " 1",
+            "5: " + Resources.device_audiosystem,
+            "6: " + Resources.device_tuner + " 2",
+            "7: " + Resources.device_tuner + " 3",
+            "8: " + Resources.device_playbackdevice + " 2",
+            "9: " + Resources.device_recorder + " 3",
+            "A: " + Resources.device_tuner + " 4",
+            "B: " + Resources.device_playbackdevice + " 3",
+            "C: " + Resources.device_reserved + " 1",
+            "D: " + Resources.device_reserved + " 2",
+            "E: " + Resources.device_free_use,
+            "F: " + Resources.device_broadcast});
+          control.SelectedValueChanged += delegate
+          {
+            CecLogicalAddresses addr = new CecLogicalAddresses();
+            foreach (var item in ((CheckedListBox)BaseValueControl).CheckedItems)
+            {
+              string c = item as string;
+              addr.Set(GetLogicalAddressFromString(c));
+            }
+            Value = addr;
+          };
+          BaseValueControl = control;
+        }
+        return BaseValueControl as CheckedListBox;
+      }
+    }
+
+    public void ReplaceControls(IAsyncControls form, Control.ControlCollection controls, Control labelControl, CheckedListBox valueControl)
+    {
+      Form = form;
+      ReplaceControl(controls, labelControl, Label);
+      ReplaceControl(controls, valueControl, ValueControl);
+    }
+
+    public void ReplaceControls(IAsyncControls form, Control.ControlCollection controls, CheckedListBox valueControl)
+    {
+      Form = form;
+      ReplaceControl(controls, valueControl, ValueControl);
+    }
+
+    public override bool Enabled
+    {
+      set
+      {
+        if (Form != null)
+          Form.SetControlEnabled(ValueControl, value);
+      }
+      get { return base.Enabled; }
+    }
+  }
+}
diff --git a/src/LibCecTray/settings/CECSettingNumeric.cs b/src/LibCecTray/settings/CECSettingNumeric.cs
new file mode 100644 (file)
index 0000000..cee77e3
--- /dev/null
@@ -0,0 +1,244 @@
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing       <license@pulse-eight.com>
+ *     http://www.pulse-eight.com/
+ *     http://www.pulse-eight.net/
+ */
+
+using System.Collections.Generic;
+using System.Windows.Forms;
+using LibCECTray.ui;
+
+namespace LibCECTray.settings
+{
+  /// <summary>
+  /// A setting of type integer that can be persisted in the registry
+  /// </summary>
+  class CECSettingNumeric : CECSetting
+  {
+    public CECSettingNumeric(CECSettingType type, string keyName, string friendlyName, int defaultValue, SettingChangedHandler changedHandler, ListControlConvertEventHandler format, List<int> items) :
+      base(type, CECSettingSerialisationType.Numeric, keyName, friendlyName, defaultValue, changedHandler)
+    {
+      BaseItems = items;
+      Format += format;
+    }
+
+    public CECSettingNumeric(CECSettingType type, string keyName, string friendlyName, int defaultValue, SettingChangedHandler changedHandler, ListControlConvertEventHandler format) :
+      this(type, keyName, friendlyName, defaultValue, changedHandler, format, new List<int>())
+    {
+    }
+
+    public CECSettingNumeric(string keyName, string friendlyName, int defaultValue, SettingChangedHandler changedHandler, ListControlConvertEventHandler format) :
+      this(CECSettingType.Numeric, keyName, friendlyName, defaultValue, changedHandler, format)
+    {
+    }
+
+    public CECSettingNumeric(string keyName, string friendlyName, int defaultValue, SettingChangedHandler changedHandler) :
+      this(CECSettingType.Numeric, keyName, friendlyName, defaultValue, changedHandler, null)
+    {
+    }
+
+    public CECSettingNumeric(CECSettingType type, string keyName, string friendlyName, int defaultValue, SettingChangedHandler changedHandler) :
+      this(type, keyName, friendlyName, defaultValue, changedHandler, null)
+    {
+    }
+
+    #region Serialisation methods
+    protected override string GetSerialisedValue()
+    {
+      return string.Format("{0}", Value);
+    }
+
+    protected override void SetSerialisedValue(string value)
+    {
+      int intValue;
+      Value = int.TryParse(value, out intValue) ? intValue : DefaultValue;
+    }
+
+    protected override string GetSerialisedDefaultValue()
+    {
+      return string.Format("{0}", DefaultValue);
+    }
+
+    protected override void SetSerialisedDefaultValue(string value)
+    {
+      int intValue;
+      DefaultValue = int.TryParse(value, out intValue) ? intValue : int.MinValue;
+    }
+    #endregion
+
+    public new int Value
+    {
+      get
+      {
+        return base.Value != null ? (int)base.Value : int.MaxValue;
+      }
+      set
+      {
+        base.Value = value;
+        ComboBox control = BaseValueControl as ComboBox;
+        if (Form != null && control != null && BaseItems.Contains(value))
+        {
+          Form.SetSelectedIndex(control, BaseItems.IndexOf(value));
+        }
+      }
+    }
+
+    public new int DefaultValue
+    {
+      get
+      {
+        return base.DefaultValue != null ? (int)base.DefaultValue : int.MaxValue;
+      }
+      set
+      {
+        base.DefaultValue = value;
+      }
+    }
+
+    public int LowerLimit { get; set; }
+
+    public int UpperLimit { get; set; }
+
+    public int Step
+    {
+      get { return _step; }
+      set { _step = value; }
+    }
+    private int _step = 1;
+
+    protected virtual bool AllowedValue(int value)
+    {
+      return true;
+    }
+
+    protected virtual void CreateValueControl()
+    {
+      if (BaseValueControl != null) return;
+      ComboBox control = new ComboBox
+                           {
+                             FormattingEnabled = true,
+                             Name = KeyName,
+                             Size = new System.Drawing.Size(Width, Height),
+                             AutoCompleteMode = AutoCompleteMode.Append,
+                             Enabled = InitialEnabledValue
+                           };
+
+      if (Format != null)
+      {
+        control.Format += Format;
+        control.FormattingEnabled = true;
+      }
+      BaseValueControl = control;
+
+      ResetItems(BaseItems.Count == 0);
+
+      control.SelectedValueChanged += delegate
+                                        {
+                                          Value = BaseItems[control.SelectedIndex];
+                                        };
+    }
+
+    public override Control ValueControl
+    {
+      get
+      {
+        CreateValueControl();
+        return BaseValueControl;
+      }
+    }
+
+    public void ResetItems(bool clear)
+    {
+      ComboBox control = BaseValueControl as ComboBox;
+      if (control == null) return;
+      if (clear)
+        BaseItems.Clear();
+
+      List<object> cbItems = new List<object>();
+      foreach (var item in Items)
+        cbItems.Add(string.Format("{0}", item));
+
+      Form.SetComboBoxItems(control, Items.IndexOf(Value), cbItems.ToArray());
+    }
+
+    public virtual void ReplaceControls(IAsyncControls form, Control.ControlCollection controls, Control labelControl, ComboBox valueControl)
+    {
+      Form = form;
+      ReplaceControl(controls, labelControl, Label);
+      ReplaceControl(controls, valueControl, ValueControl);
+    }
+
+    public virtual void ReplaceControls(IAsyncControls form, Control.ControlCollection controls, ComboBox valueControl)
+    {
+      Form = form;
+      ReplaceControl(controls, valueControl, ValueControl);
+    }
+
+    public override bool Enabled
+    {
+      set { base.Enabled = (SettingType == CECSettingType.Bool || BaseItems.Count > 1) && value; }
+      get { return base.Enabled; }
+    }
+
+    public int Width = 100;
+    public int Height = 21;
+
+    public event ListControlConvertEventHandler Format;
+    protected readonly List<int> BaseItems = new List<int>();
+    public virtual List<int> Items
+    {
+      get
+      {
+        if (BaseItems.Count == 0)
+        {
+          for (var i = LowerLimit; i < UpperLimit; i += Step)
+          {
+            if (AllowedValue(i))
+              BaseItems.Add(i);
+          }
+        }
+        return BaseItems;
+      }
+      protected set
+      {
+        ComboBox control = BaseValueControl as ComboBox;
+        if (control == null) return;
+        List<object> cbItems = new List<object>();
+        BaseItems.Clear();
+        foreach (var item in value)
+        {
+          BaseItems.Add(item);
+          cbItems.Add(string.Format("{0}", item));
+        }
+
+        Form.SetComboBoxItems(control, BaseItems.IndexOf(Value), cbItems.ToArray());
+      }
+    }
+  }
+}
diff --git a/src/LibCecTray/settings/CECSettingString.cs b/src/LibCecTray/settings/CECSettingString.cs
new file mode 100644 (file)
index 0000000..b2bffe9
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing       <license@pulse-eight.com>
+ *     http://www.pulse-eight.com/
+ *     http://www.pulse-eight.net/
+ */
+
+using System.Windows.Forms;
+using LibCECTray.ui;
+
+namespace LibCECTray.settings
+{
+
+  /// <summary>
+  /// A setting of type string that can be persisted in the registry
+  /// </summary>
+  class CECSettingString : CECSetting
+  {
+    public CECSettingString(string keyName, string friendlyName, string defaultValue, SettingChangedHandler changedHandler) :
+      this(CECSettingType.String, keyName, friendlyName, defaultValue, changedHandler)
+    {
+    }
+
+    public CECSettingString(CECSettingType type, string keyName, string friendlyName, string defaultValue, SettingChangedHandler changedHandler) :
+      base(type, CECSettingSerialisationType.String, keyName, friendlyName, defaultValue, changedHandler)
+    {
+    }
+
+    #region Serialisation methods
+    protected override string GetSerialisedValue()
+    {
+      return Value;
+    }
+
+    protected override void SetSerialisedValue(string value)
+    {
+      Value = value;
+    }
+
+    protected override string GetSerialisedDefaultValue()
+    {
+      return DefaultValue;
+    }
+
+    protected override void SetSerialisedDefaultValue(string value)
+    {
+      DefaultValue = value;
+    }
+    #endregion
+
+    public new string Value
+    {
+      get
+      {
+        return (string)base.Value;
+      }
+      set
+      {
+        base.Value = value;
+        if (BaseValueControl != null && Form != null)
+          Form.SetControlText(BaseValueControl, value);
+      }
+    }
+
+    public new string DefaultValue
+    {
+      get
+      {
+        return (string)base.DefaultValue;
+      }
+      set
+      {
+        base.DefaultValue = value;
+      }
+    }
+
+    public new Control ValueControl
+    {
+      get
+      {
+        if (BaseValueControl == null)
+        {
+          TextBox control = new TextBox
+                               {
+                                 Size = new System.Drawing.Size(100, 20),
+                                 Enabled = InitialEnabledValue,
+                                 Text = Value
+                               };
+          control.TextChanged += delegate { Value = control.Text; };
+          BaseValueControl = control;
+        }
+        return BaseValueControl;
+      }
+    }
+
+    public void ReplaceControls(IAsyncControls form, Control.ControlCollection controls, Control labelControl, TextBox valueControl)
+    {
+      Form = form;
+      ReplaceControl(controls, labelControl, Label);
+      ReplaceControl(controls, valueControl, ValueControl);
+      if (ValueControl != null && Form != null)
+        Form.SetControlText(ValueControl, Value);
+    }
+
+    public void ReplaceControls(IAsyncControls form, Control.ControlCollection controls, TextBox valueControl)
+    {
+      Form = form;
+      ReplaceControl(controls, valueControl, ValueControl);
+    }
+  }
+}
diff --git a/src/LibCecTray/settings/CECSettingUShort.cs b/src/LibCecTray/settings/CECSettingUShort.cs
new file mode 100644 (file)
index 0000000..68adcf1
--- /dev/null
@@ -0,0 +1,69 @@
+using System.Globalization;
+using System.Windows.Forms;
+
+namespace LibCECTray.settings
+{
+  /// <summary>
+  /// A setting of type ushort that can be persisted in the registry
+  /// </summary>
+  class CECSettingUShort : CECSettingString
+  {
+    public CECSettingUShort(string keyName, string friendlyName, ushort defaultValue, SettingChangedHandler changedHandler) :
+      base(CECSettingType.UShort, keyName, friendlyName, string.Format("{0,4:X}", defaultValue), changedHandler)
+    {
+    }
+
+    public new ushort Value
+    {
+      get
+      {
+        ushort iValue;
+        return base.Value != null && ushort.TryParse(base.Value, NumberStyles.AllowHexSpecifier, null, out iValue) ? iValue : ushort.MinValue;
+      }
+      set
+      {
+        base.Value = string.Format("{0,4:X}", value);
+        if (Form != null)
+          Form.SetControlText(ValueControl, base.Value);
+      }
+    }
+
+    public new ushort DefaultValue
+    {
+      get
+      {
+        ushort iValue;
+        return base.DefaultValue != null && ushort.TryParse(base.DefaultValue, NumberStyles.AllowHexSpecifier, null, out iValue) ? iValue : ushort.MinValue;
+      }
+      set { base.DefaultValue = string.Format("{0,4:X}", value); }
+    }
+
+    public new Control ValueControl
+    {
+      get
+      {
+        if (BaseValueControl == null)
+        {
+          TextBox control = new TextBox
+                              {
+                                MaxLength = 4,
+                                Size = new System.Drawing.Size(100, 20),
+                                Enabled = InitialEnabledValue,
+                                Text = string.Format("{0,4:X}", Value)
+                              };
+          control.TextChanged += delegate
+                                   {
+                                     ushort iValue;
+                                     if (
+                                       !ushort.TryParse(control.Text, NumberStyles.AllowHexSpecifier, null,
+                                                        out iValue))
+                                       iValue = DefaultValue;
+                                     Value = iValue;
+                                   };
+          BaseValueControl = control;
+        }
+        return BaseValueControl;
+      }
+    }
+  }
+}
diff --git a/src/LibCecTray/settings/CECSettingVendorId.cs b/src/LibCecTray/settings/CECSettingVendorId.cs
new file mode 100644 (file)
index 0000000..49ba2e7
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing       <license@pulse-eight.com>
+ *     http://www.pulse-eight.com/
+ *     http://www.pulse-eight.net/
+ */
+
+using System.Collections.Generic;
+using System.Windows.Forms;
+using CecSharp;
+using LibCECTray.Properties;
+
+namespace LibCECTray.settings
+{
+  /// <summary>
+  /// A setting of type CecVendorId that can be persisted in the registry
+  /// </summary>
+  class CECSettingVendorId : CECSettingNumeric
+  {
+    public CECSettingVendorId(string keyName, string friendlyName, CecVendorId defaultValue, SettingChangedHandler changedHandler) :
+      base(CECSettingType.VendorId, keyName, friendlyName, (int)defaultValue, changedHandler, OnFormat, new List<int>
+                 {
+                   (int) CecVendorId.Unknown,
+                   (int) CecVendorId.Akai,
+                   (int) CecVendorId.Benq,
+                   (int) CecVendorId.Daewoo,
+                   (int) CecVendorId.Grundig,
+                   (int) CecVendorId.LG,
+                   (int) CecVendorId.Medion,
+                   (int) CecVendorId.Onkyo,
+                   (int) CecVendorId.Panasonic,
+                   (int) CecVendorId.Philips,
+                   (int) CecVendorId.Pioneer,
+                   (int) CecVendorId.Samsung,
+                   (int) CecVendorId.Sharp,
+                   (int) CecVendorId.Sony,
+                   (int) CecVendorId.Toshiba,
+                   (int) CecVendorId.Vizio,
+                   (int) CecVendorId.Yamaha
+                 })
+    {
+    }
+
+    private static void OnFormat(object sender, ListControlConvertEventArgs listControlConvertEventArgs)
+    {
+      int iValue;
+      if (int.TryParse((string)listControlConvertEventArgs.Value, out iValue))
+        listControlConvertEventArgs.Value = FormatValue(iValue);
+    }
+
+    private static string FormatValue(int value)
+    {
+      switch ((CecVendorId)value)
+      {
+        case CecVendorId.Akai:
+          return "Akai";
+        case CecVendorId.Benq:
+          return "Benq";
+        case CecVendorId.Daewoo:
+          return "Daewoo";
+        case CecVendorId.Grundig:
+          return "Grundig";
+        case CecVendorId.LG:
+          return "LG";
+        case CecVendorId.Medion:
+          return "Medion";
+        case CecVendorId.Onkyo:
+          return "Onkyo";
+        case CecVendorId.Panasonic:
+          return "Panasonic";
+        case CecVendorId.Philips:
+          return "Philips";
+        case CecVendorId.Pioneer:
+          return "Pioneer";
+        case CecVendorId.Samsung:
+          return "Samsung";
+        case CecVendorId.Sharp:
+          return "Sharp";
+        case CecVendorId.Sony:
+          return "Sony";
+        case CecVendorId.Toshiba:
+          return "Toshiba";
+        case CecVendorId.Vizio:
+          return "Vizio";
+        case CecVendorId.Yamaha:
+          return "Yamaha";
+        default:
+          return Resources.autodetect;
+      }
+    }
+
+    public new CecVendorId Value
+    {
+      get { return base.Value >= 0 && base.Value <= 0xFFFFFF ? (CecVendorId)base.Value : CecVendorId.Unknown; }
+      set { base.Value = (int)value; }
+    }
+
+    public new CecVendorId DefaultValue
+    {
+      get { return base.DefaultValue >= 0 && base.DefaultValue <= 0xFFFFFF ? (CecVendorId)base.DefaultValue : CecVendorId.Unknown; }
+      set { base.DefaultValue = (int)value; }
+    }
+  }
+
+}
diff --git a/src/LibCecTray/settings/CECSettings.cs b/src/LibCecTray/settings/CECSettings.cs
new file mode 100644 (file)
index 0000000..e7e8a5c
--- /dev/null
@@ -0,0 +1,451 @@
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing       <license@pulse-eight.com>
+ *     http://www.pulse-eight.com/
+ *     http://www.pulse-eight.net/
+ */
+
+using System.Windows.Forms;
+using CecSharp;
+using System.Collections.Generic;
+using LibCECTray.Properties;
+using Microsoft.Win32;
+
+namespace LibCECTray.settings
+{
+  class CECSettings
+  {
+    private const string RegistryCompanyName = "Pulse-Eight";
+    private const string RegistryApplicationName = "libCECTray";
+
+    #region Key names
+    public static string KeyHDMIPort = "global_hdmi_port";
+    public static string KeyConnectedToHDMIDevice = "global_connected_to_hdmi_device";
+    public static string KeyActivateSource = "global_activate_source";
+    public static string KeyAdvancedMode = "global_advanced_mode";
+    public static string KeyPhysicalAddress = "global_physical_address";
+    public static string KeyOverridePhysicalAddress = "global_override_physical_address";
+    public static string KeyDeviceType = "global_device_type";
+    public static string KeyTVVendor = "global_tv_vendor";
+    public static string KeyOverrideTVVendor = "global_override_tv_vendor";
+    public static string KeyWakeDevices = "global_wake_devices";
+    public static string KeyPowerOffDevices = "global_standby_devices";
+    public static string KeyStartHidden = "global_start_hidden";
+    #endregion
+
+    public CECSettings(CECSetting.SettingChangedHandler changedHandler)
+    {
+      _changedHandler = changedHandler;
+      Load();
+    }
+
+    /// <summary>
+    /// Resets all settings to their default values
+    /// </summary>
+    public void SetDefaultValues()
+    {
+      foreach (var setting in _settings.Values)
+        setting.ResetDefaultValue();
+    }
+
+    /// <summary>
+    /// Loads all known settings from the registry
+    /// </summary>
+    private void Load()
+    {
+      using (var subRegKey = Registry.CurrentUser.OpenSubKey(RegistryKeyName, true))
+      {
+        if (subRegKey == null) return;
+        foreach (var setting in _settings.Values)
+          if (!setting.KeyName.StartsWith("global_"))
+            setting.Load(subRegKey);
+        subRegKey.Close();
+      }
+    }
+
+    /// <summary>
+    /// Load a setting value from the registry
+    /// </summary>
+    /// <param name="setting">The setting to load</param>
+    public void Load(CECSetting setting)
+    {
+      using (var subRegKey = Registry.CurrentUser.OpenSubKey(RegistryKeyName, true))
+      {
+        if (subRegKey == null) return;
+        setting.Load(subRegKey);
+        subRegKey.Close();
+      }
+      setting.SettingChanged += OnSettingChanged;
+    }
+
+    /// <summary>
+    /// Persist all settings in the registry
+    /// </summary>
+    /// <returns>True when persisted, false otherwise</returns>
+    public bool Persist()
+    {
+      if (CreateRegistryKey())
+      {
+        using (var subRegKey = Registry.CurrentUser.OpenSubKey(RegistryKeyName, true))
+        {
+          if (subRegKey != null)
+          {
+            foreach (var setting in _settings.Values)
+              setting.Persist(subRegKey);
+            subRegKey.Close();
+            return true;
+          }
+        }
+      }
+      return false;
+    }
+
+    private bool EnableHDMIPortSetting(CECSetting setting, bool value)
+    {
+      return value && !OverridePhysicalAddress.Value;
+    }
+
+    private bool EnablePhysicalAddressSetting(CECSetting setting, bool value)
+    {
+      return value && OverridePhysicalAddress.Value;
+    }
+
+    private bool EnableSettingTVVendor(CECSetting setting, bool value)
+    {
+      return value && OverrideTVVendor.Value;
+    }
+
+    private void OnSettingChanged(CECSetting setting, object oldValue, object newValue)
+    {
+      if (SettingChanged != null)
+        SettingChanged(setting, oldValue, newValue);
+    }
+
+    #region Global settings
+    public CECSettingByte HDMIPort
+    {
+      get
+      {
+        if (!_settings.ContainsKey(KeyHDMIPort))
+        {
+          CECSettingByte setting = new CECSettingByte(KeyHDMIPort, "HDMI port", 1, _changedHandler) { LowerLimit = 1, UpperLimit = 15, EnableSetting = EnableHDMIPortSetting };
+          setting.Format += delegate(object sender, ListControlConvertEventArgs args)
+          {
+            ushort tmp;
+            if (ushort.TryParse((string)args.Value, out tmp))
+              args.Value = "HDMI " + args.Value;
+          };
+
+          Load(setting);
+          _settings[KeyHDMIPort] = setting;
+        }
+        return _settings[KeyHDMIPort].AsSettingByte;
+      }
+    }
+
+    public CECSettingLogicalAddress ConnectedDevice
+    {
+      get
+      {
+        if (!_settings.ContainsKey(KeyConnectedToHDMIDevice))
+        {
+          CecLogicalAddresses allowedMask = new CecLogicalAddresses();
+          allowedMask.Set(CecLogicalAddress.Tv); allowedMask.Set(CecLogicalAddress.AudioSystem);
+          CECSettingLogicalAddress setting = new CECSettingLogicalAddress(KeyConnectedToHDMIDevice,
+                                                                          Resources.global_connected_to_hdmi_device,
+                                                                          CecLogicalAddress.Tv, _changedHandler)
+                                               {
+                                                 AllowedAddressMask = allowedMask,
+                                                 Enabled = false,
+                                                 EnableSetting = EnableHDMIPortSetting
+                                               };
+          Load(setting);
+          _settings[KeyConnectedToHDMIDevice] = setting;
+        }
+        return _settings[KeyConnectedToHDMIDevice].AsSettingLogicalAddress;
+      }
+    }
+
+    public CECSettingBool ActivateSource
+    {
+      get
+      {
+        if (!_settings.ContainsKey(KeyActivateSource))
+        {
+          CECSettingBool setting = new CECSettingBool(KeyActivateSource, Resources.global_activate_source, true,
+                                                      _changedHandler) {Enabled = false};
+          Load(setting);
+          _settings[KeyActivateSource] = setting;
+        }
+        return _settings[KeyActivateSource].AsSettingBool;
+      }
+    }
+
+    public CECSettingBool AdvancedMode
+    {
+      get
+      {
+        if (!_settings.ContainsKey(KeyAdvancedMode))
+        {
+          CECSettingBool setting = new CECSettingBool(KeyAdvancedMode, Resources.global_advanced_mode, false,
+                                                      _changedHandler) {Enabled = false};
+          Load(setting);
+          _settings[KeyAdvancedMode] = setting;
+        }
+        return _settings[KeyAdvancedMode].AsSettingBool;
+      }
+    }
+
+    public CECSettingUShort PhysicalAddress
+    {
+      get
+      {
+        if (!_settings.ContainsKey(KeyPhysicalAddress))
+        {
+          CECSettingUShort setting = new CECSettingUShort(KeyPhysicalAddress, Resources.global_physical_address, 0xFFFF, _changedHandler) { Enabled = false, EnableSetting = EnablePhysicalAddressSetting };
+          Load(setting);
+          _settings[KeyPhysicalAddress] = setting;
+        }
+        return _settings[KeyPhysicalAddress].AsSettingUShort;
+      }
+    }
+
+    public CECSettingBool OverridePhysicalAddress
+    {
+      get
+      {
+        if (!_settings.ContainsKey(KeyAdvancedMode))
+        {
+          CECSettingBool setting = new CECSettingBool(KeyOverridePhysicalAddress,
+                                                      Resources.global_override_physical_address, false, _changedHandler);
+          Load(setting);
+          _settings[KeyOverridePhysicalAddress] = setting;
+        }
+        return _settings[KeyOverridePhysicalAddress].AsSettingBool;
+      }
+    }
+
+    public CECSettingDeviceType DeviceType
+    {
+      get
+      {
+        if (!_settings.ContainsKey(KeyDeviceType))
+        {
+          CecDeviceTypeList allowedTypes = new CecDeviceTypeList();
+          allowedTypes.Types[(int)CecDeviceType.RecordingDevice] = CecDeviceType.RecordingDevice;
+          allowedTypes.Types[(int)CecDeviceType.PlaybackDevice] = CecDeviceType.PlaybackDevice;
+
+          CECSettingDeviceType setting = new CECSettingDeviceType(KeyDeviceType, Resources.global_device_type,
+                                                                  CecDeviceType.RecordingDevice, _changedHandler) { Enabled = false, AllowedTypeMask = allowedTypes };
+          Load(setting);
+          _settings[KeyDeviceType] = setting;
+        }
+        return _settings[KeyDeviceType].AsSettingDeviceType;
+      }
+    }
+
+    public CECSettingVendorId TVVendor
+    {
+      get
+      {
+        if (!_settings.ContainsKey(KeyTVVendor))
+        {
+          CECSettingVendorId setting = new CECSettingVendorId(KeyTVVendor, Resources.global_tv_vendor,
+                                                              CecVendorId.Unknown, _changedHandler)
+                                         {Enabled = false, EnableSetting = EnableSettingTVVendor};
+          Load(setting);
+          _settings[KeyTVVendor] = setting;
+        }
+        return _settings[KeyTVVendor].AsSettingVendorId;
+      }
+    }
+
+    public CECSettingBool OverrideTVVendor
+    {
+      get
+      {
+        if (!_settings.ContainsKey(KeyOverrideTVVendor))
+        {
+          CECSettingBool setting = new CECSettingBool(KeyOverrideTVVendor, Resources.global_override_tv_vendor, false,
+                                                      _changedHandler) {Enabled = false};
+          Load(setting);
+          _settings[KeyOverrideTVVendor] = setting;
+        }
+        return _settings[KeyOverrideTVVendor].AsSettingBool;
+      }
+    }
+
+    public CECSettingLogicalAddresses WakeDevices
+    {
+      get
+      {
+        if (!_settings.ContainsKey(KeyWakeDevices))
+        {
+          CecLogicalAddresses defaultDeviceList = new CecLogicalAddresses();
+          defaultDeviceList.Set(CecLogicalAddress.Tv);
+          CECSettingLogicalAddresses setting = new CECSettingLogicalAddresses(KeyWakeDevices,
+                                                                              Resources.global_wake_devices,
+                                                                              defaultDeviceList, _changedHandler)
+                                                 {Enabled = false};
+          Load(setting);
+          _settings[KeyWakeDevices] = setting;
+        }
+        return _settings[KeyWakeDevices].AsSettingLogicalAddresses;
+      }
+    }
+
+    public CECSettingLogicalAddresses PowerOffDevices
+    {
+      get
+      {
+        if (!_settings.ContainsKey(KeyPowerOffDevices))
+        {
+          CecLogicalAddresses defaultDeviceList = new CecLogicalAddresses();
+          defaultDeviceList.Set(CecLogicalAddress.Tv);
+          CECSettingLogicalAddresses setting = new CECSettingLogicalAddresses(KeyPowerOffDevices,
+                                                                              Resources.global_standby_devices,
+                                                                              defaultDeviceList,
+                                                                              _changedHandler) {Enabled = false};
+          Load(setting);
+          _settings[KeyPowerOffDevices] = setting;
+        }
+        return _settings[KeyPowerOffDevices].AsSettingLogicalAddresses;
+      }
+    }
+
+    public CECSettingBool StartHidden
+    {
+      get
+      {
+        if (!_settings.ContainsKey(KeyStartHidden))
+        {
+          CECSettingBool setting = new CECSettingBool(KeyStartHidden, Resources.global_start_hidden, false, _changedHandler);
+          Load(setting);
+          _settings[KeyStartHidden] = setting;
+        }
+        return _settings[KeyStartHidden].AsSettingBool;
+      }
+    }
+    #endregion
+
+    public bool ContainsKey(string key)
+    {
+      return _settings.ContainsKey(key);
+    }
+
+    public void SetVendorName(CecLogicalAddress address, CecVendorId vendorId, string vendorName)
+    {
+      VendorNames[(int)address] = vendorName;
+
+      if (address == CecLogicalAddress.Tv && vendorId == CecVendorId.Panasonic)
+      {
+        DeviceType.AllowedTypeMask = new CecDeviceTypeList {Types = new[] {CecDeviceType.PlaybackDevice}};
+      }
+
+      foreach (var setting in _settings)
+      {
+        if (setting.Value.SettingType == CECSettingType.LogicalAddress)
+          setting.Value.AsSettingLogicalAddress.ResetItems(true);
+      }
+    }
+
+    public bool Enabled
+    {
+      set
+      {
+        CECSetting[] settings = new CECSetting[_settings.Count + 10];
+        _settings.Values.CopyTo(settings, 0);
+        foreach (var setting in settings)
+          if (setting != null)
+            setting.Enabled = value;
+      }
+      get
+      {
+        var enabled = true;
+        foreach (var setting in _settings)
+          enabled &= setting.Value.Enabled;
+        return enabled;
+      }
+    }
+
+    /// <summary>
+    /// Read or write one of the settings, given it's key
+    /// </summary>
+    /// <param name="key">The key of the setting</param>
+    /// <returns>The setting</returns>
+    public CECSetting this[string key]
+    {
+      get { return _settings.ContainsKey(key) ? _settings[key] : null; }
+      set {_settings[key] = value; }
+    }
+
+    /// <summary>
+    /// Create the registry key that holds all settings.
+    /// </summary>
+    /// <returns>True when created (or already existing), false otherwise</returns>
+    private static bool CreateRegistryKey()
+    {
+      using (var regKey = Registry.CurrentUser.OpenSubKey("Software", true))
+      {
+        if (regKey != null)
+        {
+          regKey.CreateSubKey(RegistryCompanyName);
+          regKey.Close();
+        }
+        else
+        {
+          return false;
+        }
+      }
+      using (var regKey = Registry.CurrentUser.OpenSubKey("Software\\" + RegistryCompanyName, true))
+      {
+        if (regKey != null)
+        {
+          regKey.CreateSubKey(RegistryApplicationName);
+          regKey.Close();
+        }
+        else
+        {
+          return false;
+        }
+      }
+      return true;
+    }
+
+    private readonly Dictionary<string, CECSetting> _settings = new Dictionary<string, CECSetting>();
+    private static string RegistryKeyName
+    {
+      get { return string.Format("Software\\{0}\\{1}", RegistryCompanyName, RegistryApplicationName); }
+    }
+
+    private readonly CECSetting.SettingChangedHandler _changedHandler;
+    public event CECSetting.SettingChangedHandler SettingChanged;
+
+    public static readonly string[] VendorNames = new string[15];
+  }
+}
diff --git a/src/LibCecTray/ui/About.Designer.cs b/src/LibCecTray/ui/About.Designer.cs
new file mode 100644 (file)
index 0000000..675cadb
--- /dev/null
@@ -0,0 +1,86 @@
+namespace LibCECTray.ui
+{
+  partial class About
+  {
+    /// <summary>
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary>
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing)
+    {
+      if (disposing && (components != null))
+      {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Windows Form Designer generated code
+
+    /// <summary>
+    /// Required method for Designer support - do not modify
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent()
+    {
+      System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(About));
+      this.label1 = new System.Windows.Forms.Label();
+      this.lVersionInfo = new System.Windows.Forms.Label();
+      this.lBuildInfo = new System.Windows.Forms.Label();
+      this.SuspendLayout();
+      // 
+      // label1
+      // 
+      this.label1.AutoSize = true;
+      this.label1.Location = new System.Drawing.Point(13, 13);
+      this.label1.Name = "label1";
+      this.label1.Size = new System.Drawing.Size(366, 117);
+      this.label1.TabIndex = 0;
+      this.label1.Text = resources.GetString("label1.Text");
+      // 
+      // lVersionInfo
+      // 
+      this.lVersionInfo.AutoSize = true;
+      this.lVersionInfo.Location = new System.Drawing.Point(16, 150);
+      this.lVersionInfo.Name = "lVersionInfo";
+      this.lVersionInfo.Size = new System.Drawing.Size(101, 13);
+      this.lVersionInfo.TabIndex = 1;
+      this.lVersionInfo.Text = "[libCEC version info]";
+      // 
+      // lBuildInfo
+      // 
+      this.lBuildInfo.AutoSize = true;
+      this.lBuildInfo.Location = new System.Drawing.Point(16, 173);
+      this.lBuildInfo.Name = "lBuildInfo";
+      this.lBuildInfo.Size = new System.Drawing.Size(89, 13);
+      this.lBuildInfo.TabIndex = 2;
+      this.lBuildInfo.Text = "[libCEC build info]";
+      // 
+      // About
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.ClientSize = new System.Drawing.Size(464, 212);
+      this.Controls.Add(this.lBuildInfo);
+      this.Controls.Add(this.lVersionInfo);
+      this.Controls.Add(this.label1);
+      this.Name = "About";
+      this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
+      this.Text = "About";
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.Label label1;
+    private System.Windows.Forms.Label lVersionInfo;
+    private System.Windows.Forms.Label lBuildInfo;
+  }
+}
\ No newline at end of file
diff --git a/src/LibCecTray/ui/About.cs b/src/LibCecTray/ui/About.cs
new file mode 100644 (file)
index 0000000..70a9b9c
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing       <license@pulse-eight.com>
+ *     http://www.pulse-eight.com/
+ *     http://www.pulse-eight.net/
+ */
+
+using System.Windows.Forms;
+using LibCECTray.Properties;
+using System.ComponentModel;
+using System.Drawing;
+
+namespace LibCECTray.ui
+{
+  /// <summary>
+  /// Popup that is displayed when the "about" button is clicked
+  /// </summary>
+  partial class About : Form
+  {
+    public About(string serverVersion, string clientVersion, string libInfo) :
+      this()
+    {
+      lVersionInfo.Text = string.Format(Resources.about_libcec_version, serverVersion, clientVersion);
+      lBuildInfo.Text = libInfo;
+    }
+
+    public About()
+    {
+      InitializeComponent();
+
+      // take the icon of the main window
+      ComponentResourceManager resources = new ComponentResourceManager(typeof(CECTray));
+      Icon = resources.GetObject("$this.Icon") as Icon;
+    }
+  }
+}
diff --git a/src/LibCecTray/ui/About.resx b/src/LibCecTray/ui/About.resx
new file mode 100644 (file)
index 0000000..be9d282
--- /dev/null
@@ -0,0 +1,131 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <data name="label1.Text" xml:space="preserve">
+    <value>libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
+libCEC(R) is an original work, containing original code.
+
+libCEC(R) is a trademark of Pulse-Eight Limited.
+
+This program is dual-licensed; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.</value>
+  </data>
+</root>
\ No newline at end of file
diff --git a/src/LibCecTray/ui/AsyncForm.cs b/src/LibCecTray/ui/AsyncForm.cs
new file mode 100644 (file)
index 0000000..d3d6ae8
--- /dev/null
@@ -0,0 +1,703 @@
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing       <license@pulse-eight.com>
+ *     http://www.pulse-eight.com/
+ *     http://www.pulse-eight.net/
+ */
+
+using System;
+using System.Windows.Forms;
+using CecSharp;
+using LibCECTray.controller.applications;
+
+namespace LibCECTray.ui
+{
+  interface IAsyncControls
+  {
+    void SetControlEnabled(Control control, bool val);
+    void SetControlText(Control control, string val);
+    void SetToolStripMenuText(ToolStripMenuItem item, string val);
+    void SetCheckboxChecked(CheckBox control, bool val);
+    void SetCheckboxItemChecked(CheckedListBox control, int index, bool val);
+    void SetProgressValue(ProgressBar control, int val);
+    void SetComboBoxItems(ComboBox control, int selectedIndex, object[] val);
+    void SetControlVisible(Control control, bool val);
+    void DisplayDialog(Form control, bool modal);
+    void SafeHide(bool val);
+    void SetSelectedIndex(ComboBox control, int index);
+    string GetSelectedTabName(TabControl container, TabControl.TabPageCollection tabPages);
+    void SelectKeypressRow(Control container, DataGridView dgView, CecKeypress key);
+  }
+
+  /// <summary>
+  /// Utility methods to change GUI content from another thread
+  /// </summary>
+  class AsyncControls
+  {
+    /// <summary>
+    /// Enable or disable a control
+    /// </summary>
+    /// <param name="container">The control that contains the control to change</param>
+    /// <param name="control">The control to change</param>
+    /// <param name="val">True to enable, false to disable</param>
+    public static void SetControlEnabled(Control container, Control control, bool val)
+    {
+      if (container == null || control == null) return;
+      if (container.InvokeRequired)
+      {
+        SetControlEnabledCallback d = SetControlEnabled;
+        try
+        {
+          container.Invoke(d, new object[] { container, control, val });
+        }
+        catch { }
+      }
+      else
+      {
+        control.Enabled = val;
+      }
+    }
+    private delegate void SetControlEnabledCallback(Control container, Control control, bool val);
+
+    /// <summary>
+    /// Change the text label of a control
+    /// </summary>
+    /// <param name="container">The control that contains the control to change</param>
+    /// <param name="control">The control to change</param>
+    /// <param name="val">The new text</param>
+    public static void SetControlText(Control container, Control control, string val)
+    {
+      if (container == null || control == null) return;
+      if (container.InvokeRequired)
+      {
+        SetControlTextCallback d = SetControlText;
+        try
+        {
+          container.Invoke(d, new object[] { container, control, val });
+        }
+        catch { }
+      }
+      else
+      {
+        control.Text = val;
+      }
+    }
+    private delegate void SetControlTextCallback(Control container, Control control, string val);
+
+    /// <summary>
+    /// Change the checked status of a checkbox
+    /// </summary>
+    /// <param name="container">The control that contains the control to change</param>
+    /// <param name="control">The control to change</param>
+    /// <param name="val">True to change to checked, false to change to unchecked</param>
+    public static void SetCheckboxChecked(Control container, CheckBox control, bool val)
+    {
+      if (container.InvokeRequired)
+      {
+        SetCheckboxCheckedCallback d = SetCheckboxChecked;
+        try
+        {
+          container.Invoke(d, new object[] { container, control, val });
+        }
+        catch { }
+      }
+      else
+      {
+        control.Checked = val;
+      }
+    }
+    private delegate void SetCheckboxCheckedCallback(Control container, CheckBox control, bool val);
+
+    /// <summary>
+    /// Change the checked status of an item in a CheckedListBox
+    /// </summary>
+    /// <param name="container">The control that contains the control to change</param>
+    /// <param name="control">The control to change</param>
+    /// <param name="index">The index of the checkbox in the list to change</param>
+    /// <param name="val">True to change to checked, false to change to unchecked</param>
+    public static void SetCheckboxItemChecked(Control container, CheckedListBox control, int index, bool val)
+    {
+      if (container.InvokeRequired)
+      {
+        SetCheckboxItemCheckedCallback d = SetCheckboxItemChecked;
+        try
+        {
+          container.Invoke(d, new object[] { container, control, index, val });
+        }
+        catch (Exception) { }
+      }
+      else
+      {
+        control.SetItemChecked(index, val);
+      }
+    }
+    private delegate void SetCheckboxItemCheckedCallback(Control container, CheckedListBox control, int index, bool val);
+
+    /// <summary>
+    /// Changes the toolstrip menu text
+    /// </summary>
+    /// <param name="container">The control that contains the control to change</param>
+    /// <param name="item">The toolstrip menu item to change</param>
+    /// <param name="val">The new value</param>
+    public static void SetToolStripMenuText(Control container, ToolStripMenuItem item, string val)
+    {
+      if (container.InvokeRequired)
+      {
+        SetToolStripMenuTextCallback d = SetToolStripMenuText;
+        try
+        {
+          container.Invoke(d, new object[] { container, item, val });
+        }
+        catch (Exception) { }
+      }
+      else
+      {
+        item.Text = val;
+      }
+    }
+    private delegate void SetToolStripMenuTextCallback(Control container, ToolStripMenuItem item, string val);
+
+    /// <summary>
+    /// Changes the progress value of a progress bar
+    /// </summary>
+    /// <param name="container">The control that contains the control to change</param>
+    /// <param name="control">The control to change</param>
+    /// <param name="val">The new percentage</param>
+    public static void SetProgressValue(Control container, ProgressBar control, int val)
+    {
+      if (container.InvokeRequired)
+      {
+        SetProgressValueCallback d = SetProgressValue;
+        try
+        {
+          container.Invoke(d, new object[] { container, control, val });
+        }
+        catch (Exception) { }
+      }
+      else
+      {
+        control.Value = val;
+      }
+    }
+    private delegate void SetProgressValueCallback(Control container, ProgressBar control, int val);
+
+    /// <summary>
+    /// Replaces the items of a combobox
+    /// </summary>
+    /// <param name="container">The control that contains the control to change</param>
+    /// <param name="control">The control to change</param>
+    /// <param name="selectedIndex">The new selection index</param>
+    /// <param name="val">The new content</param>
+    public static void SetComboBoxItems(Control container, ComboBox control, int selectedIndex, object[] val)
+    {
+      if (container.InvokeRequired)
+      {
+        SetComboBoxItemsCallback d = SetComboBoxItems;
+        try
+        {
+          container.Invoke(d, new object[] { container, control, selectedIndex, val });
+        }
+        catch (Exception) { }
+      }
+      else
+      {
+        control.Items.Clear();
+        control.Items.AddRange(val);
+        if (control.Items.Count > 0)
+          control.SelectedIndex = selectedIndex;
+      }
+    }
+    private delegate void SetComboBoxItemsCallback(Control container, ComboBox control, int selectedIndex, object[] val);
+
+    /// <summary>
+    /// Make a control visible or invisible
+    /// </summary>
+    /// <param name="container">The control that contains the control to change</param>
+    /// <param name="control">The control to change</param>
+    /// <param name="val">True to make it visible, false to make it invisible</param>
+    public static void SetControlVisible(Control container, Control control, bool val)
+    {
+      if (container.InvokeRequired)
+      {
+        SetControlVisibleCallback d = SetControlVisible;
+        try
+        {
+          container.Invoke(d, new object[] { container, control, val });
+        }
+        catch (Exception) { }
+      }
+      else
+      {
+        control.Visible = val;
+      }
+    }
+    private delegate void SetControlVisibleCallback(Control container, Control control, bool val);
+
+    /// <summary>
+    /// Display a new dialog
+    /// </summary>
+    /// <param name="container">The control that contains the control to change</param>
+    /// <param name="control">The control to display</param>
+    /// <param name="modal">True to make it a modal dialog</param>
+    public static void DisplayDialog(Control container, Form control, bool modal)
+    {
+      if (container.InvokeRequired)
+      {
+        DisplayDialogCallback d = DisplayDialog;
+        try
+        {
+          container.Invoke(d, new object[] { container, control, modal });
+        }
+        catch (Exception) { }
+      }
+      else
+      {
+        if (modal)
+          control.ShowDialog(container);
+        else
+          control.Show(container);
+      }
+    }
+    private delegate void DisplayDialogCallback(Control container, Form control, bool modal);
+
+    /// <summary>
+    /// Hides a control
+    /// </summary>
+    /// <param name="container">The control to hide</param>
+    /// <param name="val">True to hide, false to show</param>
+    public static void SafeHide(Control container, bool val)
+    {
+      if (container.InvokeRequired)
+      {
+        SafeHideCallback d = SafeHide;
+        try
+        {
+          container.Invoke(d, new object[] { container, val });
+        }
+        catch (Exception) { }
+      }
+      else
+      {
+        if (val)
+          container.Hide();
+        else
+          container.Show();
+      }
+    }
+    private delegate void SafeHideCallback(Control container, bool val);
+
+    /// <summary>
+    /// Change the selected index
+    /// </summary>
+    /// <param name="container">The control that contains the control to change</param>
+    /// <param name="control">The control to change</param>
+    /// <param name="index">The new selected index</param>
+    public static void SetSelectedIndex(Control container, ComboBox control, int index)
+    {
+      if (container.InvokeRequired)
+      {
+        SetSelectedIndexCallback d = SetSelectedIndex;
+        try
+        {
+          container.Invoke(d, new object[] { container, control, index });
+        }
+        catch (Exception) { }
+      }
+      else
+      {
+        control.SelectedIndex = index;
+      }
+    }
+    private delegate void SetSelectedIndexCallback(Control container, ComboBox control, int index);
+
+    /// <summary>
+    /// Get the name of the selected tab in a TabControl
+    /// </summary>
+    /// <param name="container">The tab container</param>
+    /// <param name="tabPages">The tab pages</param>
+    /// <returns>The name of the selected tab</returns>
+    public static string GetSelectedTabName(TabControl container, TabControl.TabPageCollection tabPages)
+    {
+      if (container.InvokeRequired)
+      {
+        GetSelectedTabNameCallback d = GetSelectedTabName;
+        try
+        {
+          return container.Invoke(d, new object[] { container, tabPages }) as string;
+        }
+        catch (Exception) { }
+      }
+      else
+      {
+        return tabPages[container.SelectedIndex].Name;
+      }
+      return string.Empty;
+    }
+    private delegate string GetSelectedTabNameCallback(TabControl container, TabControl.TabPageCollection tabPages);
+
+    /// <summary>
+    /// Selects the row with the given CecKeypress for a datagrid
+    /// </summary>
+    /// <param name="container">The datagrid container</param>
+    /// <param name="dgView">The datagrid</param>
+    /// <param name="key">The key to selected</param>
+    public static void SelectKeypressRow(Control container, DataGridView dgView, CecKeypress key)
+    {
+      if (dgView.InvokeRequired)
+      {
+        SelectKeypressRowCallback d = SelectKeypressRow;
+        try
+        {
+          container.Invoke(d, new object[] { container, dgView, key });
+        }
+        catch (Exception) { }
+      }
+      else
+      {
+        var rowIndex = -1;
+        foreach (DataGridViewRow row in dgView.Rows)
+        {
+          CecButtonConfigItem item = row.DataBoundItem as CecButtonConfigItem;
+          if (item != null && item.Key.Keycode == key.Keycode)
+          {
+            rowIndex = row.Index;
+            row.Selected = true;
+            item.Enabled = true;
+          }
+          else
+          {
+            row.Selected = false;
+          }
+        }
+        if (rowIndex > -1)
+          dgView.FirstDisplayedScrollingRowIndex = rowIndex;
+      }
+    }
+    private delegate void SelectKeypressRowCallback(Control container, DataGridView dgView, CecKeypress key);
+  }
+
+  /// <summary>
+  /// Form that implements IAsyncControls
+  /// </summary>
+  class AsyncForm : Form, IAsyncControls
+  {
+    /// <summary>
+    /// Changes the ShowInTaskbar value
+    /// </summary>
+    /// <param name="val">True to show, false to hide</param>
+    public void SetShowInTaskbar(bool val)
+    {
+      if (InvokeRequired)
+      {
+        SetShowInTaskbarCallback d = SetShowInTaskbar;
+        try
+        {
+          Invoke(d, new object[] { val });
+        }
+        catch (Exception) { }
+      }
+      else
+      {
+        ShowInTaskbar = val;
+      }
+    }
+    private delegate void SetShowInTaskbarCallback(bool val);
+
+    /// <summary>
+    /// Enable or disable a control
+    /// </summary>
+    /// <param name="control">The control to change</param>
+    /// <param name="val">True to enable, false to disable</param>
+    public void SetControlEnabled(Control control, bool val)
+    {
+      AsyncControls.SetControlEnabled(this, control, val);
+    }
+
+    /// <summary>
+    /// Change the text label of a control
+    /// </summary>
+    /// <param name="control">The control to change</param>
+    /// <param name="val">The new text</param>
+    public void SetControlText(Control control, string val)
+    {
+      AsyncControls.SetControlText(this, control, val);
+    }
+
+    /// <summary>
+    /// Changes the toolstrip menu text
+    /// </summary>
+    /// <param name="item">The toolstrip menu item to change</param>
+    /// <param name="val">The new value</param>
+    public void SetToolStripMenuText(ToolStripMenuItem item, string val)
+    {
+      AsyncControls.SetToolStripMenuText(this, item, val);
+    }
+
+    /// <summary>
+    /// Change the checked status of a checkbox
+    /// </summary>
+    /// <param name="control">The control to change</param>
+    /// <param name="val">True to change to checked, false to change to unchecked</param>
+    public void SetCheckboxChecked(CheckBox control, bool val)
+    {
+      AsyncControls.SetCheckboxChecked(this, control, val);
+    }
+
+    /// <summary>
+    /// Change the checked status of an item in a CheckedListBox
+    /// </summary>
+    /// <param name="control">The control to change</param>
+    /// <param name="index">The index of the checkbox in the list to change</param>
+    /// <param name="val">True to change to checked, false to change to unchecked</param>
+    public void SetCheckboxItemChecked(CheckedListBox control, int index, bool val)
+    {
+      AsyncControls.SetCheckboxItemChecked(this, control, index, val);
+    }
+
+    /// <summary>
+    /// Changes the progress value of a progress bar
+    /// </summary>
+    /// <param name="control">The control to change</param>
+    /// <param name="val">The new percentage</param>
+    public void SetProgressValue(ProgressBar control, int val)
+    {
+      AsyncControls.SetProgressValue(this, control, val);
+    }
+
+    /// <summary>
+    /// Replaces the items of a combobox
+    /// </summary>
+    /// <param name="control">The control to change</param>
+    /// <param name="selectedIndex">The new selection index</param>
+    /// <param name="val">The new content</param>
+    public void SetComboBoxItems(ComboBox control, int selectedIndex, object[] val)
+    {
+      AsyncControls.SetComboBoxItems(this, control, selectedIndex, val);
+    }
+
+    /// <summary>
+    /// Make a control visible or invisible
+    /// </summary>
+    /// <param name="control">The control to change</param>
+    /// <param name="val">True to make it visible, false to make it invisible</param>
+    public void SetControlVisible(Control control, bool val)
+    {
+      AsyncControls.SetControlVisible(this, control, val);
+    }
+
+    /// <summary>
+    /// Display a new dialog
+    /// </summary>
+    /// <param name="control">The control to display</param>
+    /// <param name="modal">True to make it a modal dialog</param>
+    public void DisplayDialog(Form control, bool modal)
+    {
+      AsyncControls.DisplayDialog(this, control, modal);
+    }
+
+    /// <summary>
+    /// Hides a control
+    /// </summary>
+    /// <param name="val">True to hide, false to show</param>
+    public void SafeHide(bool val)
+    {
+      AsyncControls.SafeHide(this, val);
+    }
+
+    /// <summary>
+    /// Change the selected index
+    /// </summary>
+    /// <param name="control">The control to change</param>
+    /// <param name="index">The new selected index</param>
+    public void SetSelectedIndex(ComboBox control, int index)
+    {
+      AsyncControls.SetSelectedIndex(this, control, index);
+    }
+
+    /// <summary>
+    /// Get the name of the selected tab in a TabControl
+    /// </summary>
+    /// <param name="container">The tab container</param>
+    /// <param name="tabPages">The tab pages</param>
+    /// <returns>The name of the selected tab</returns>
+    public string GetSelectedTabName(TabControl container, TabControl.TabPageCollection tabPages)
+    {
+      return AsyncControls.GetSelectedTabName(container, tabPages);
+    }
+
+    /// <summary>
+    /// Selects the row with the given CecKeypress for a datagrid
+    /// </summary>
+    /// <param name="container">The datagrid container</param>
+    /// <param name="dgView">The datagrid</param>
+    /// <param name="key">The key to selected</param>
+    public void SelectKeypressRow(Control container, DataGridView dgView, CecKeypress key)
+    {
+      AsyncControls.SelectKeypressRow(container, dgView, key);
+    }
+  }
+
+  /// <summary>
+  /// TabPage that implements IAsyncControls
+  /// </summary>
+  class AsyncTabPage : TabPage, IAsyncControls
+  {
+    /// <summary>
+    /// Enable or disable a control
+    /// </summary>
+    /// <param name="control">The control to change</param>
+    /// <param name="val">True to enable, false to disable</param>
+    public void SetControlEnabled(Control control, bool val)
+    {
+      AsyncControls.SetControlEnabled(this, control, val);
+    }
+
+    /// <summary>
+    /// Change the text label of a control
+    /// </summary>
+    /// <param name="control">The control to change</param>
+    /// <param name="val">The new text</param>
+    public void SetControlText(Control control, string val)
+    {
+      AsyncControls.SetControlText(this, control, val);
+    }
+
+    /// <summary>
+    /// Changes the toolstrip menu text
+    /// </summary>
+    /// <param name="item">The toolstrip menu item to change</param>
+    /// <param name="val">The new value</param>
+    public void SetToolStripMenuText(ToolStripMenuItem item, string val)
+    {
+      AsyncControls.SetToolStripMenuText(this, item, val);
+    }
+
+    /// <summary>
+    /// Change the checked status of a checkbox
+    /// </summary>
+    /// <param name="control">The control to change</param>
+    /// <param name="val">True to change to checked, false to change to unchecked</param>
+    public void SetCheckboxChecked(CheckBox control, bool val)
+    {
+      AsyncControls.SetCheckboxChecked(this, control, val);
+    }
+
+    /// <summary>
+    /// Change the checked status of an item in a CheckedListBox
+    /// </summary>
+    /// <param name="control">The control to change</param>
+    /// <param name="index">The index of the checkbox in the list to change</param>
+    /// <param name="val">True to change to checked, false to change to unchecked</param>
+    public void SetCheckboxItemChecked(CheckedListBox control, int index, bool val)
+    {
+      AsyncControls.SetCheckboxItemChecked(this, control, index, val);
+    }
+
+    /// <summary>
+    /// Changes the progress value of a progress bar
+    /// </summary>
+    /// <param name="control">The control to change</param>
+    /// <param name="val">The new percentage</param>
+    public void SetProgressValue(ProgressBar control, int val)
+    {
+      AsyncControls.SetProgressValue(this, control, val);
+    }
+
+    /// <summary>
+    /// Replaces the items of a combobox
+    /// </summary>
+    /// <param name="control">The control to change</param>
+    /// <param name="selectedIndex">The new selection index</param>
+    /// <param name="val">The new content</param>
+    public void SetComboBoxItems(ComboBox control, int selectedIndex, object[] val)
+    {
+      AsyncControls.SetComboBoxItems(this, control, selectedIndex, val);
+    }
+
+    /// <summary>
+    /// Make a control visible or invisible
+    /// </summary>
+    /// <param name="control">The control to change</param>
+    /// <param name="val">True to make it visible, false to make it invisible</param>
+    public void SetControlVisible(Control control, bool val)
+    {
+      AsyncControls.SetControlVisible(this, control, val);
+    }
+
+    /// <summary>
+    /// Display a new dialog
+    /// </summary>
+    /// <param name="control">The control to display</param>
+    /// <param name="modal">True to make it a modal dialog</param>
+    public void DisplayDialog(Form control, bool modal)
+    {
+      AsyncControls.DisplayDialog(this, control, modal);
+    }
+
+    /// <summary>
+    /// Hides a control
+    /// </summary>
+    /// <param name="val">True to hide, false to show</param>
+    public void SafeHide(bool val)
+    {
+      AsyncControls.SafeHide(this, val);
+    }
+
+    /// <summary>
+    /// Change the selected index
+    /// </summary>
+    /// <param name="control">The control to change</param>
+    /// <param name="index">The new selected index</param>
+    public void SetSelectedIndex(ComboBox control, int index)
+    {
+      AsyncControls.SetSelectedIndex(this, control, index);
+    }
+
+    /// <summary>
+    /// Get the name of the selected tab in a TabControl
+    /// </summary>
+    /// <param name="container">The tab container</param>
+    /// <param name="tabPages">The tab pages</param>
+    /// <returns>The name of the selected tab</returns>
+    public string GetSelectedTabName(TabControl container, TabControl.TabPageCollection tabPages)
+    {
+      return AsyncControls.GetSelectedTabName(container, tabPages);
+    }
+
+    /// <summary>
+    /// Selects the row with the given CecKeypress for a datagrid
+    /// </summary>
+    /// <param name="container">The datagrid container</param>
+    /// <param name="dgView">The datagrid</param>
+    /// <param name="key">The key to selected</param>
+    public void SelectKeypressRow(Control container, DataGridView dgView, CecKeypress key)
+    {
+      AsyncControls.SelectKeypressRow(container, dgView, key);
+    }
+  }
+}
similarity index 64%
rename from src/cec-config-gui/CecConfigGUI.Designer.cs
rename to src/LibCecTray/ui/CECTray.Designer.cs
index 417aec229f63df1f4532dd6980731ac9360ef09c..34db4123f4213faec88e1e68c6d5429f3d43881e 100644 (file)
@@ -1,6 +1,6 @@
-namespace CecConfigGui
+namespace LibCECTray.ui
 {
-  partial class CecConfigGUI
+  partial class CECTray
   {
     /// <summary>
     /// Required designer variable.
     private void InitializeComponent()
     {
       this.components = new System.ComponentModel.Container();
-      System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(CecConfigGUI));
-      this.tabControl1 = new System.Windows.Forms.TabControl();
+      System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(CECTray));
+      this.pProgress = new System.Windows.Forms.ProgressBar();
+      this.lStatus = new System.Windows.Forms.Label();
+      this.helpPortNumber = new System.Windows.Forms.ToolTip(this.components);
+      this.cbPortNumber = new System.Windows.Forms.ComboBox();
+      this.helpConnectedHDMIDevice = new System.Windows.Forms.ToolTip(this.components);
+      this.cbConnectedDevice = new System.Windows.Forms.ComboBox();
+      this.helpPhysicalAddress = new System.Windows.Forms.ToolTip(this.components);
+      this.tbPhysicalAddress = new System.Windows.Forms.TextBox();
+      this.helpDeviceType = new System.Windows.Forms.ToolTip(this.components);
+      this.cbDeviceType = new System.Windows.Forms.ComboBox();
+      this.cbVendorId = new System.Windows.Forms.ComboBox();
+      this.trayIcon = new System.Windows.Forms.NotifyIcon(this.components);
+      this.trayIconMenu = new System.Windows.Forms.ContextMenuStrip(this.components);
+      this.tsAdvanced = new System.Windows.Forms.ToolStripMenuItem();
+      this.tsMenuShowHide = new System.Windows.Forms.ToolStripMenuItem();
+      this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
+      this.tsMenuClose = new System.Windows.Forms.ToolStripMenuItem();
+      this.LogOutput = new System.Windows.Forms.TabPage();
+      this.bSaveLog = new System.Windows.Forms.Button();
+      this.bClearLog = new System.Windows.Forms.Button();
+      this.cbLogDebug = new System.Windows.Forms.CheckBox();
+      this.cbLogTraffic = new System.Windows.Forms.CheckBox();
+      this.cbLogNotice = new System.Windows.Forms.CheckBox();
+      this.cbLogWarning = new System.Windows.Forms.CheckBox();
+      this.cbLogError = new System.Windows.Forms.CheckBox();
+      this.tbLog = new System.Windows.Forms.TextBox();
+      this.tbTestCommands = new System.Windows.Forms.TabPage();
+      this.bRescanDevices = new System.Windows.Forms.Button();
+      this.bMute = new System.Windows.Forms.Button();
+      this.bVolDown = new System.Windows.Forms.Button();
+      this.bVolUp = new System.Windows.Forms.Button();
+      this.bActivateSource = new System.Windows.Forms.Button();
+      this.bScan = new System.Windows.Forms.Button();
+      this.bStandby = new System.Windows.Forms.Button();
+      this.bSendImageViewOn = new System.Windows.Forms.Button();
+      this.lDestination = new System.Windows.Forms.Label();
+      this.cbCommandDestination = new System.Windows.Forms.ComboBox();
       this.Configuration = new System.Windows.Forms.TabPage();
       this.cbOverrideAddress = new System.Windows.Forms.CheckBox();
       this.bReloadConfig = new System.Windows.Forms.Button();
       this.cbVendorOverride = new System.Windows.Forms.CheckBox();
-      this.cbVendorId = new System.Windows.Forms.ComboBox();
       this.lPowerOff = new System.Windows.Forms.Label();
       this.cbPowerOffDevices = new System.Windows.Forms.CheckedListBox();
       this.lWakeDevices = new System.Windows.Forms.Label();
       this.cbWakeDevices = new System.Windows.Forms.CheckedListBox();
-      this.cbPowerOffOnStandby = new System.Windows.Forms.CheckBox();
-      this.cbPowerOffScreensaver = new System.Windows.Forms.CheckBox();
       this.cbActivateSource = new System.Windows.Forms.CheckBox();
-      this.cbUseTVMenuLanguage = new System.Windows.Forms.CheckBox();
       this.lPlayerConfig = new System.Windows.Forms.Label();
       this.lAdapterConfig = new System.Windows.Forms.Label();
-      this.cbDeviceType = new System.Windows.Forms.ComboBox();
       this.bClose = new System.Windows.Forms.Button();
       this.bSaveConfig = new System.Windows.Forms.Button();
-      this.cbPortNumber = new System.Windows.Forms.ComboBox();
-      this.lConnectedPhysicalAddress = new System.Windows.Forms.Label();
-      this.tbPhysicalAddress = new System.Windows.Forms.TextBox();
-      this.cbConnectedDevice = new System.Windows.Forms.ComboBox();
       this.lDeviceType = new System.Windows.Forms.Label();
       this.lConnectedDevice = new System.Windows.Forms.Label();
       this.lPortNumber = new System.Windows.Forms.Label();
-      this.tbButtons = new System.Windows.Forms.TabPage();
-      this.label1 = new System.Windows.Forms.Label();
-      this.dgButtons = new System.Windows.Forms.DataGridView();
-      this.CecButtonName = new System.Windows.Forms.DataGridViewTextBoxColumn();
-      this.cecButtonConfigBindingSource = new System.Windows.Forms.BindingSource(this.components);
-      this.tbTestCommands = new System.Windows.Forms.TabPage();
-      this.bRescanDevices = new System.Windows.Forms.Button();
-      this.bMute = new System.Windows.Forms.Button();
-      this.bVolDown = new System.Windows.Forms.Button();
-      this.bVolUp = new System.Windows.Forms.Button();
-      this.bActivateSource = new System.Windows.Forms.Button();
-      this.bScan = new System.Windows.Forms.Button();
-      this.bStandby = new System.Windows.Forms.Button();
-      this.bSendImageViewOn = new System.Windows.Forms.Button();
-      this.lDestination = new System.Windows.Forms.Label();
-      this.cbCommandDestination = new System.Windows.Forms.ComboBox();
-      this.LogOutput = new System.Windows.Forms.TabPage();
-      this.bSaveLog = new System.Windows.Forms.Button();
-      this.bClearLog = new System.Windows.Forms.Button();
-      this.cbLogDebug = new System.Windows.Forms.CheckBox();
-      this.cbLogTraffic = new System.Windows.Forms.CheckBox();
-      this.cbLogNotice = new System.Windows.Forms.CheckBox();
-      this.cbLogWarning = new System.Windows.Forms.CheckBox();
-      this.cbLogError = new System.Windows.Forms.CheckBox();
-      this.tbLog = new System.Windows.Forms.TextBox();
-      this.pProgress = new System.Windows.Forms.ProgressBar();
-      this.lStatus = new System.Windows.Forms.Label();
-      this.helpPortNumber = new System.Windows.Forms.ToolTip(this.components);
-      this.helpConnectedHDMIDevice = new System.Windows.Forms.ToolTip(this.components);
-      this.helpPhysicalAddress = new System.Windows.Forms.ToolTip(this.components);
-      this.helpDeviceType = new System.Windows.Forms.ToolTip(this.components);
-      this.cbSendInactiveSource = new System.Windows.Forms.CheckBox();
-      this.tabControl1.SuspendLayout();
-      this.Configuration.SuspendLayout();
-      this.tbButtons.SuspendLayout();
-      ((System.ComponentModel.ISupportInitialize)(this.dgButtons)).BeginInit();
-      ((System.ComponentModel.ISupportInitialize)(this.cecButtonConfigBindingSource)).BeginInit();
-      this.tbTestCommands.SuspendLayout();
+      this.tabPanel = new System.Windows.Forms.TabControl();
+      this.menuStrip1 = new System.Windows.Forms.MenuStrip();
+      this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+      this.hideToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+      this.advancedModeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+      this.closeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+      this.applicationsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+      this.addNewApplicationToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+      this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+      this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+      this.cbStartMinimised = new System.Windows.Forms.CheckBox();
+      this.trayIconMenu.SuspendLayout();
       this.LogOutput.SuspendLayout();
+      this.tbTestCommands.SuspendLayout();
+      this.Configuration.SuspendLayout();
+      this.tabPanel.SuspendLayout();
+      this.menuStrip1.SuspendLayout();
       this.SuspendLayout();
       // 
-      // tabControl1
+      // pProgress
       // 
-      this.tabControl1.Controls.Add(this.Configuration);
-      this.tabControl1.Controls.Add(this.tbButtons);
-      this.tabControl1.Controls.Add(this.tbTestCommands);
-      this.tabControl1.Controls.Add(this.LogOutput);
-      this.tabControl1.Location = new System.Drawing.Point(12, 12);
-      this.tabControl1.Name = "tabControl1";
-      this.tabControl1.SelectedIndex = 0;
-      this.tabControl1.Size = new System.Drawing.Size(600, 385);
-      this.tabControl1.TabIndex = 0;
-      this.tabControl1.SelectedIndexChanged += new System.EventHandler(this.tabControl1_SelectedIndexChanged);
+      this.pProgress.Location = new System.Drawing.Point(314, 407);
+      this.pProgress.Name = "pProgress";
+      this.pProgress.Size = new System.Drawing.Size(298, 23);
+      this.pProgress.TabIndex = 1;
       // 
-      // Configuration
+      // lStatus
       // 
-      this.Configuration.Controls.Add(this.cbSendInactiveSource);
-      this.Configuration.Controls.Add(this.cbOverrideAddress);
-      this.Configuration.Controls.Add(this.bReloadConfig);
-      this.Configuration.Controls.Add(this.cbVendorOverride);
-      this.Configuration.Controls.Add(this.cbVendorId);
-      this.Configuration.Controls.Add(this.lPowerOff);
-      this.Configuration.Controls.Add(this.cbPowerOffDevices);
-      this.Configuration.Controls.Add(this.lWakeDevices);
-      this.Configuration.Controls.Add(this.cbWakeDevices);
-      this.Configuration.Controls.Add(this.cbPowerOffOnStandby);
-      this.Configuration.Controls.Add(this.cbPowerOffScreensaver);
-      this.Configuration.Controls.Add(this.cbActivateSource);
-      this.Configuration.Controls.Add(this.cbUseTVMenuLanguage);
-      this.Configuration.Controls.Add(this.lPlayerConfig);
-      this.Configuration.Controls.Add(this.lAdapterConfig);
-      this.Configuration.Controls.Add(this.cbDeviceType);
-      this.Configuration.Controls.Add(this.bClose);
-      this.Configuration.Controls.Add(this.bSaveConfig);
-      this.Configuration.Controls.Add(this.cbPortNumber);
-      this.Configuration.Controls.Add(this.lConnectedPhysicalAddress);
-      this.Configuration.Controls.Add(this.tbPhysicalAddress);
-      this.Configuration.Controls.Add(this.cbConnectedDevice);
-      this.Configuration.Controls.Add(this.lDeviceType);
-      this.Configuration.Controls.Add(this.lConnectedDevice);
-      this.Configuration.Controls.Add(this.lPortNumber);
-      this.Configuration.Location = new System.Drawing.Point(4, 22);
-      this.Configuration.Name = "Configuration";
-      this.Configuration.Padding = new System.Windows.Forms.Padding(3);
-      this.Configuration.Size = new System.Drawing.Size(592, 359);
-      this.Configuration.TabIndex = 0;
-      this.Configuration.Text = "Configuration";
-      this.Configuration.UseVisualStyleBackColor = true;
+      this.lStatus.AutoSize = true;
+      this.lStatus.Location = new System.Drawing.Point(12, 416);
+      this.lStatus.Name = "lStatus";
+      this.lStatus.Size = new System.Drawing.Size(61, 13);
+      this.lStatus.TabIndex = 2;
+      this.lStatus.Text = "Initialising...";
       // 
-      // cbOverrideAddress
+      // cbPortNumber
       // 
-      this.cbOverrideAddress.AutoSize = true;
-      this.cbOverrideAddress.Enabled = false;
-      this.cbOverrideAddress.Location = new System.Drawing.Point(10, 97);
-      this.cbOverrideAddress.Name = "cbOverrideAddress";
-      this.cbOverrideAddress.Size = new System.Drawing.Size(147, 17);
-      this.cbOverrideAddress.TabIndex = 31;
-      this.cbOverrideAddress.Text = "Override physical address";
-      this.cbOverrideAddress.UseVisualStyleBackColor = true;
-      this.cbOverrideAddress.CheckedChanged += new System.EventHandler(this.cbOverrideAddress_CheckedChanged);
+      this.cbPortNumber.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.Append;
+      this.cbPortNumber.Enabled = false;
+      this.cbPortNumber.FormattingEnabled = true;
+      this.cbPortNumber.Location = new System.Drawing.Point(174, 40);
+      this.cbPortNumber.Name = "cbPortNumber";
+      this.cbPortNumber.Size = new System.Drawing.Size(133, 21);
+      this.cbPortNumber.TabIndex = 11;
+      this.cbPortNumber.Text = "global_hdmi_port";
+      this.helpPortNumber.SetToolTip(this.cbPortNumber, "The HDMI port number, to which you connected your USB-CEC adapter.");
       // 
-      // bReloadConfig
+      // cbConnectedDevice
       // 
-      this.bReloadConfig.Enabled = false;
-      this.bReloadConfig.Location = new System.Drawing.Point(358, 330);
-      this.bReloadConfig.Name = "bReloadConfig";
-      this.bReloadConfig.Size = new System.Drawing.Size(125, 23);
-      this.bReloadConfig.TabIndex = 30;
-      this.bReloadConfig.Text = "Reload configuration";
-      this.bReloadConfig.UseVisualStyleBackColor = true;
-      this.bReloadConfig.Click += new System.EventHandler(this.bReloadConfig_Click);
+      this.cbConnectedDevice.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.Append;
+      this.cbConnectedDevice.Enabled = false;
+      this.cbConnectedDevice.FormattingEnabled = true;
+      this.cbConnectedDevice.Location = new System.Drawing.Point(174, 67);
+      this.cbConnectedDevice.Name = "cbConnectedDevice";
+      this.cbConnectedDevice.Size = new System.Drawing.Size(133, 21);
+      this.cbConnectedDevice.TabIndex = 5;
+      this.cbConnectedDevice.Text = "global_connected_to_hdmi_device";
+      this.helpConnectedHDMIDevice.SetToolTip(this.cbConnectedDevice, "The HDMI device to which the USB-CEC adapter is connected");
       // 
-      // cbVendorOverride
+      // tbPhysicalAddress
       // 
-      this.cbVendorOverride.AutoSize = true;
-      this.cbVendorOverride.Enabled = false;
-      this.cbVendorOverride.Location = new System.Drawing.Point(10, 156);
-      this.cbVendorOverride.Name = "cbVendorOverride";
-      this.cbVendorOverride.Size = new System.Drawing.Size(130, 17);
-      this.cbVendorOverride.TabIndex = 29;
-      this.cbVendorOverride.Text = "Override TV vendor id";
-      this.cbVendorOverride.UseVisualStyleBackColor = true;
-      this.cbVendorOverride.CheckedChanged += new System.EventHandler(this.cbVendorOverride_CheckedChanged);
+      this.tbPhysicalAddress.Enabled = false;
+      this.tbPhysicalAddress.Location = new System.Drawing.Point(174, 95);
+      this.tbPhysicalAddress.MaxLength = 4;
+      this.tbPhysicalAddress.Name = "tbPhysicalAddress";
+      this.tbPhysicalAddress.Size = new System.Drawing.Size(38, 20);
+      this.tbPhysicalAddress.TabIndex = 6;
+      this.tbPhysicalAddress.Text = "global_override_physical_address";
+      this.helpPhysicalAddress.SetToolTip(this.tbPhysicalAddress, "The physical address of the adapter. Leave this untouched if you want to autodete" +
+              "ct this value.");
+      // 
+      // cbDeviceType
+      // 
+      this.cbDeviceType.Enabled = false;
+      this.cbDeviceType.FormattingEnabled = true;
+      this.cbDeviceType.Location = new System.Drawing.Point(174, 123);
+      this.cbDeviceType.Name = "cbDeviceType";
+      this.cbDeviceType.Size = new System.Drawing.Size(133, 21);
+      this.cbDeviceType.TabIndex = 14;
+      this.cbDeviceType.Text = "global_device_type";
+      this.helpDeviceType.SetToolTip(this.cbDeviceType, "Set this to \'Player\' when your TV is having problems with \'Recorder\'");
       // 
       // cbVendorId
       // 
       this.cbVendorId.Enabled = false;
       this.cbVendorId.FormattingEnabled = true;
-      this.cbVendorId.Items.AddRange(new object[] {
-            "- autodetect -",
-            "LG",
-            "Onkyo",
-            "Panasonic",
-            "Philips",
-            "Pioneer",
-            "Samsung",
-            "Sony",
-            "Yamaha"});
       this.cbVendorId.Location = new System.Drawing.Point(174, 153);
       this.cbVendorId.Name = "cbVendorId";
-      this.cbVendorId.Size = new System.Drawing.Size(157, 21);
+      this.cbVendorId.Size = new System.Drawing.Size(133, 21);
       this.cbVendorId.TabIndex = 28;
-      this.cbVendorId.Text = "- autodetect -";
+      this.cbVendorId.Text = "global_override_tv_vendor";
       this.helpDeviceType.SetToolTip(this.cbVendorId, "Only set this value when autodetection isn\'t working");
       // 
-      // lPowerOff
+      // trayIcon
       // 
-      this.lPowerOff.AutoSize = true;
-      this.lPowerOff.Location = new System.Drawing.Point(465, 203);
-      this.lPowerOff.Name = "lPowerOff";
-      this.lPowerOff.Size = new System.Drawing.Size(124, 13);
-      this.lPowerOff.TabIndex = 26;
-      this.lPowerOff.Text = "Power off when stopping";
+      this.trayIcon.ContextMenuStrip = this.trayIconMenu;
+      this.trayIcon.Icon = ((System.Drawing.Icon)(resources.GetObject("trayIcon.Icon")));
+      this.trayIcon.Text = "Pulse-Eight USB-CEC Adapter";
+      this.trayIcon.Visible = true;
+      this.trayIcon.Click += new System.EventHandler(this.TrayIconClick);
       // 
-      // cbPowerOffDevices
+      // trayIconMenu
       // 
-      this.cbPowerOffDevices.Enabled = false;
-      this.cbPowerOffDevices.FormattingEnabled = true;
-      this.cbPowerOffDevices.Items.AddRange(new object[] {
-            "0: TV",
-            "1: Recorder 1",
-            "2: Recorder 2",
-            "3: Tuner 1",
-            "4: Playback 1",
-            "5: Audio system",
-            "6: Tuner 2",
-            "7: Tuner 3",
-            "8: Playback 2",
-            "9: Recorder 3",
-            "A: Tuner 4",
-            "B: Playback 3",
-            "C: Reserved 1",
-            "D: Reserved 2",
-            "E: Free use",
-            "F: Broadcast"});
-      this.cbPowerOffDevices.Location = new System.Drawing.Point(467, 220);
-      this.cbPowerOffDevices.Name = "cbPowerOffDevices";
-      this.cbPowerOffDevices.Size = new System.Drawing.Size(118, 94);
-      this.cbPowerOffDevices.TabIndex = 25;
+      this.trayIconMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+            this.tsAdvanced,
+            this.tsMenuShowHide,
+            this.toolStripSeparator1,
+            this.tsMenuClose});
+      this.trayIconMenu.Name = "trayIconMenu";
+      this.trayIconMenu.Size = new System.Drawing.Size(162, 76);
       // 
-      // lWakeDevices
+      // tsAdvanced
       // 
-      this.lWakeDevices.AutoSize = true;
-      this.lWakeDevices.Location = new System.Drawing.Point(345, 203);
-      this.lWakeDevices.Name = "lWakeDevices";
-      this.lWakeDevices.Size = new System.Drawing.Size(102, 13);
-      this.lWakeDevices.TabIndex = 24;
-      this.lWakeDevices.Text = "Wake when starting";
+      this.tsAdvanced.Name = "tsAdvanced";
+      this.tsAdvanced.Size = new System.Drawing.Size(161, 22);
+      this.tsAdvanced.Text = "Advanced mode";
+      this.tsAdvanced.Click += new System.EventHandler(this.TsAdvancedClick);
       // 
-      // cbWakeDevices
+      // tsMenuShowHide
       // 
-      this.cbWakeDevices.Enabled = false;
-      this.cbWakeDevices.FormattingEnabled = true;
-      this.cbWakeDevices.Items.AddRange(new object[] {
-            "0: TV",
-            "1: Recorder 1",
-            "2: Recorder 2",
-            "3: Tuner 1",
-            "4: Playback 1",
-            "5: Audio system",
-            "6: Tuner 2",
-            "7: Tuner 3",
-            "8: Playback 2",
-            "9: Recorder 3",
-            "A: Tuner 4",
-            "B: Playback 3",
-            "C: Reserved 1",
-            "D: Reserved 2",
-            "E: Free use",
-            "F: Broadcast"});
-      this.cbWakeDevices.Location = new System.Drawing.Point(337, 220);
-      this.cbWakeDevices.Name = "cbWakeDevices";
-      this.cbWakeDevices.Size = new System.Drawing.Size(118, 94);
-      this.cbWakeDevices.TabIndex = 23;
+      this.tsMenuShowHide.Name = "tsMenuShowHide";
+      this.tsMenuShowHide.Size = new System.Drawing.Size(161, 22);
+      this.tsMenuShowHide.Text = "Hide";
+      this.tsMenuShowHide.Click += new System.EventHandler(this.TsMenuShowHideClick);
       // 
-      // cbPowerOffOnStandby
+      // toolStripSeparator1
       // 
-      this.cbPowerOffOnStandby.AutoSize = true;
-      this.cbPowerOffOnStandby.Enabled = false;
-      this.cbPowerOffOnStandby.Location = new System.Drawing.Point(9, 278);
-      this.cbPowerOffOnStandby.Name = "cbPowerOffOnStandby";
-      this.cbPowerOffOnStandby.Size = new System.Drawing.Size(292, 17);
-      this.cbPowerOffOnStandby.TabIndex = 22;
-      this.cbPowerOffOnStandby.Text = "Put this PC in standby mode when the TV is switched off";
-      this.cbPowerOffOnStandby.UseVisualStyleBackColor = true;
+      this.toolStripSeparator1.Name = "toolStripSeparator1";
+      this.toolStripSeparator1.Size = new System.Drawing.Size(158, 6);
       // 
-      // cbPowerOffScreensaver
-      // 
-      this.cbPowerOffScreensaver.AutoSize = true;
-      this.cbPowerOffScreensaver.Enabled = false;
-      this.cbPowerOffScreensaver.Location = new System.Drawing.Point(9, 255);
-      this.cbPowerOffScreensaver.Name = "cbPowerOffScreensaver";
-      this.cbPowerOffScreensaver.Size = new System.Drawing.Size(301, 17);
-      this.cbPowerOffScreensaver.TabIndex = 21;
-      this.cbPowerOffScreensaver.Text = "Put devices in standby mode when activating screensaver";
-      this.cbPowerOffScreensaver.UseVisualStyleBackColor = true;
-      // 
-      // cbActivateSource
-      // 
-      this.cbActivateSource.AutoSize = true;
-      this.cbActivateSource.Enabled = false;
-      this.cbActivateSource.Location = new System.Drawing.Point(9, 232);
-      this.cbActivateSource.Name = "cbActivateSource";
-      this.cbActivateSource.Size = new System.Drawing.Size(284, 17);
-      this.cbActivateSource.TabIndex = 19;
-      this.cbActivateSource.Text = "Make the media player the active source when starting";
-      this.cbActivateSource.UseVisualStyleBackColor = true;
+      // tsMenuClose
       // 
-      // cbUseTVMenuLanguage
+      this.tsMenuClose.Name = "tsMenuClose";
+      this.tsMenuClose.Size = new System.Drawing.Size(161, 22);
+      this.tsMenuClose.Text = "Exit";
+      this.tsMenuClose.Click += new System.EventHandler(this.TsMenuCloseClick);
       // 
-      this.cbUseTVMenuLanguage.AutoSize = true;
-      this.cbUseTVMenuLanguage.Enabled = false;
-      this.cbUseTVMenuLanguage.Location = new System.Drawing.Point(10, 209);
-      this.cbUseTVMenuLanguage.Name = "cbUseTVMenuLanguage";
-      this.cbUseTVMenuLanguage.Size = new System.Drawing.Size(168, 17);
-      this.cbUseTVMenuLanguage.TabIndex = 18;
-      this.cbUseTVMenuLanguage.Text = "Use the TV\'s language setting";
-      this.cbUseTVMenuLanguage.UseVisualStyleBackColor = true;
-      // 
-      // lPlayerConfig
-      // 
-      this.lPlayerConfig.AutoSize = true;
-      this.lPlayerConfig.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
-      this.lPlayerConfig.Location = new System.Drawing.Point(6, 182);
-      this.lPlayerConfig.Name = "lPlayerConfig";
-      this.lPlayerConfig.Size = new System.Drawing.Size(198, 24);
-      this.lPlayerConfig.TabIndex = 16;
-      this.lPlayerConfig.Text = "Player Configuration";
-      // 
-      // lAdapterConfig
-      // 
-      this.lAdapterConfig.AutoSize = true;
-      this.lAdapterConfig.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
-      this.lAdapterConfig.Location = new System.Drawing.Point(6, 3);
-      this.lAdapterConfig.Name = "lAdapterConfig";
-      this.lAdapterConfig.Size = new System.Drawing.Size(213, 24);
-      this.lAdapterConfig.TabIndex = 15;
-      this.lAdapterConfig.Text = "Adapter Configuration";
-      // 
-      // cbDeviceType
-      // 
-      this.cbDeviceType.Enabled = false;
-      this.cbDeviceType.FormattingEnabled = true;
-      this.cbDeviceType.Items.AddRange(new object[] {
-            "Recorder",
-            "Player",
-            "Tuner"});
-      this.cbDeviceType.Location = new System.Drawing.Point(174, 123);
-      this.cbDeviceType.Name = "cbDeviceType";
-      this.cbDeviceType.Size = new System.Drawing.Size(157, 21);
-      this.cbDeviceType.TabIndex = 14;
-      this.cbDeviceType.Text = "Recorder";
-      this.helpDeviceType.SetToolTip(this.cbDeviceType, "Set this to \'Player\' when your TV is having problems with \'Recorder\'");
-      this.cbDeviceType.SelectedIndexChanged += new System.EventHandler(this.cbDeviceType_SelectedIndexChanged);
-      // 
-      // bClose
+      // LogOutput
       // 
-      this.bClose.Enabled = false;
-      this.bClose.Location = new System.Drawing.Point(96, 330);
-      this.bClose.Name = "bClose";
-      this.bClose.Size = new System.Drawing.Size(125, 23);
-      this.bClose.TabIndex = 13;
-      this.bClose.Text = "Close";
-      this.bClose.UseVisualStyleBackColor = true;
-      this.bClose.Click += new System.EventHandler(this.bCancel_Click);
+      this.LogOutput.Controls.Add(this.bSaveLog);
+      this.LogOutput.Controls.Add(this.bClearLog);
+      this.LogOutput.Controls.Add(this.cbLogDebug);
+      this.LogOutput.Controls.Add(this.cbLogTraffic);
+      this.LogOutput.Controls.Add(this.cbLogNotice);
+      this.LogOutput.Controls.Add(this.cbLogWarning);
+      this.LogOutput.Controls.Add(this.cbLogError);
+      this.LogOutput.Controls.Add(this.tbLog);
+      this.LogOutput.Location = new System.Drawing.Point(4, 22);
+      this.LogOutput.Name = "LogOutput";
+      this.LogOutput.Padding = new System.Windows.Forms.Padding(3);
+      this.LogOutput.Size = new System.Drawing.Size(592, 344);
+      this.LogOutput.TabIndex = 1;
+      this.LogOutput.Text = "Log Output";
+      this.LogOutput.UseVisualStyleBackColor = true;
       // 
-      // bSaveConfig
+      // bSaveLog
       // 
-      this.bSaveConfig.Enabled = false;
-      this.bSaveConfig.Location = new System.Drawing.Point(227, 330);
-      this.bSaveConfig.Name = "bSaveConfig";
-      this.bSaveConfig.Size = new System.Drawing.Size(125, 23);
-      this.bSaveConfig.TabIndex = 12;
-      this.bSaveConfig.Text = "Save configuration";
-      this.bSaveConfig.UseVisualStyleBackColor = true;
-      this.bSaveConfig.Click += new System.EventHandler(this.bSave_Click);
+      this.bSaveLog.Location = new System.Drawing.Point(429, 318);
+      this.bSaveLog.Name = "bSaveLog";
+      this.bSaveLog.Size = new System.Drawing.Size(75, 23);
+      this.bSaveLog.TabIndex = 7;
+      this.bSaveLog.Text = "Persist";
+      this.bSaveLog.UseVisualStyleBackColor = true;
+      this.bSaveLog.Click += new System.EventHandler(this.BSaveLogClick);
       // 
-      // cbPortNumber
+      // bClearLog
       // 
-      this.cbPortNumber.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.Append;
-      this.cbPortNumber.Enabled = false;
-      this.cbPortNumber.FormattingEnabled = true;
-      this.cbPortNumber.Items.AddRange(new object[] {
-            "1",
-            "2",
-            "3",
-            "4"});
-      this.cbPortNumber.Location = new System.Drawing.Point(174, 40);
-      this.cbPortNumber.Name = "cbPortNumber";
-      this.cbPortNumber.Size = new System.Drawing.Size(38, 21);
-      this.cbPortNumber.TabIndex = 11;
-      this.cbPortNumber.Text = "1";
-      this.helpPortNumber.SetToolTip(this.cbPortNumber, "The HDMI port number, to which you connected your USB-CEC adapter.");
-      this.cbPortNumber.SelectedIndexChanged += new System.EventHandler(this.connectedDevice_SelectedIndexChanged);
+      this.bClearLog.Location = new System.Drawing.Point(510, 318);
+      this.bClearLog.Name = "bClearLog";
+      this.bClearLog.Size = new System.Drawing.Size(75, 23);
+      this.bClearLog.TabIndex = 6;
+      this.bClearLog.Text = "Clear";
+      this.bClearLog.UseVisualStyleBackColor = true;
+      this.bClearLog.Click += new System.EventHandler(this.BClearLogClick);
       // 
-      // lConnectedPhysicalAddress
+      // cbLogDebug
       // 
-      this.lConnectedPhysicalAddress.AutoSize = true;
-      this.lConnectedPhysicalAddress.Location = new System.Drawing.Point(340, 71);
-      this.lConnectedPhysicalAddress.Name = "lConnectedPhysicalAddress";
-      this.lConnectedPhysicalAddress.Size = new System.Drawing.Size(75, 13);
-      this.lConnectedPhysicalAddress.TabIndex = 10;
-      this.lConnectedPhysicalAddress.Text = "Address: 0000";
+      this.cbLogDebug.AutoSize = true;
+      this.cbLogDebug.Checked = true;
+      this.cbLogDebug.CheckState = System.Windows.Forms.CheckState.Checked;
+      this.cbLogDebug.Location = new System.Drawing.Point(268, 324);
+      this.cbLogDebug.Name = "cbLogDebug";
+      this.cbLogDebug.Size = new System.Drawing.Size(58, 17);
+      this.cbLogDebug.TabIndex = 5;
+      this.cbLogDebug.Text = "Debug";
+      this.cbLogDebug.UseVisualStyleBackColor = true;
       // 
-      // tbPhysicalAddress
+      // cbLogTraffic
       // 
-      this.tbPhysicalAddress.Enabled = false;
-      this.tbPhysicalAddress.Location = new System.Drawing.Point(174, 95);
-      this.tbPhysicalAddress.MaxLength = 4;
-      this.tbPhysicalAddress.Name = "tbPhysicalAddress";
-      this.tbPhysicalAddress.Size = new System.Drawing.Size(38, 20);
-      this.tbPhysicalAddress.TabIndex = 6;
-      this.tbPhysicalAddress.Text = "1000";
-      this.helpPhysicalAddress.SetToolTip(this.tbPhysicalAddress, "The physical address of the adapter. Leave this untouched if you want to autodete" +
-              "ct this value.");
-      this.tbPhysicalAddress.TextChanged += new System.EventHandler(this.tbPhysicalAddress_TextChanged);
+      this.cbLogTraffic.AutoSize = true;
+      this.cbLogTraffic.Checked = true;
+      this.cbLogTraffic.CheckState = System.Windows.Forms.CheckState.Checked;
+      this.cbLogTraffic.Location = new System.Drawing.Point(206, 324);
+      this.cbLogTraffic.Name = "cbLogTraffic";
+      this.cbLogTraffic.Size = new System.Drawing.Size(56, 17);
+      this.cbLogTraffic.TabIndex = 4;
+      this.cbLogTraffic.Text = "Traffic";
+      this.cbLogTraffic.UseVisualStyleBackColor = true;
       // 
-      // cbConnectedDevice
+      // cbLogNotice
       // 
-      this.cbConnectedDevice.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.Append;
-      this.cbConnectedDevice.Enabled = false;
-      this.cbConnectedDevice.FormattingEnabled = true;
-      this.cbConnectedDevice.Location = new System.Drawing.Point(174, 67);
-      this.cbConnectedDevice.Name = "cbConnectedDevice";
-      this.cbConnectedDevice.Size = new System.Drawing.Size(157, 21);
-      this.cbConnectedDevice.TabIndex = 5;
-      this.helpConnectedHDMIDevice.SetToolTip(this.cbConnectedDevice, "The HDMI device to which the USB-CEC adapter is connected");
-      this.cbConnectedDevice.SelectedIndexChanged += new System.EventHandler(this.connectedDevice_SelectedIndexChanged);
+      this.cbLogNotice.AutoSize = true;
+      this.cbLogNotice.Checked = true;
+      this.cbLogNotice.CheckState = System.Windows.Forms.CheckState.Checked;
+      this.cbLogNotice.Location = new System.Drawing.Point(137, 324);
+      this.cbLogNotice.Name = "cbLogNotice";
+      this.cbLogNotice.Size = new System.Drawing.Size(62, 17);
+      this.cbLogNotice.TabIndex = 3;
+      this.cbLogNotice.Text = "Notices";
+      this.cbLogNotice.UseVisualStyleBackColor = true;
       // 
-      // lDeviceType
+      // cbLogWarning
       // 
-      this.lDeviceType.AutoSize = true;
-      this.lDeviceType.Location = new System.Drawing.Point(6, 126);
-      this.lDeviceType.Name = "lDeviceType";
-      this.lDeviceType.Size = new System.Drawing.Size(64, 13);
-      this.lDeviceType.TabIndex = 3;
-      this.lDeviceType.Text = "Device type";
+      this.cbLogWarning.AutoSize = true;
+      this.cbLogWarning.Checked = true;
+      this.cbLogWarning.CheckState = System.Windows.Forms.CheckState.Checked;
+      this.cbLogWarning.Location = new System.Drawing.Point(65, 324);
+      this.cbLogWarning.Name = "cbLogWarning";
+      this.cbLogWarning.Size = new System.Drawing.Size(66, 17);
+      this.cbLogWarning.TabIndex = 2;
+      this.cbLogWarning.Text = "Warning";
+      this.cbLogWarning.UseVisualStyleBackColor = true;
       // 
-      // lConnectedDevice
+      // cbLogError
       // 
-      this.lConnectedDevice.AutoSize = true;
-      this.lConnectedDevice.Location = new System.Drawing.Point(6, 70);
-      this.lConnectedDevice.Name = "lConnectedDevice";
-      this.lConnectedDevice.Size = new System.Drawing.Size(137, 13);
-      this.lConnectedDevice.TabIndex = 1;
-      this.lConnectedDevice.Text = "Connected to HDMI device";
+      this.cbLogError.AutoSize = true;
+      this.cbLogError.Checked = true;
+      this.cbLogError.CheckState = System.Windows.Forms.CheckState.Checked;
+      this.cbLogError.Location = new System.Drawing.Point(6, 324);
+      this.cbLogError.Name = "cbLogError";
+      this.cbLogError.Size = new System.Drawing.Size(53, 17);
+      this.cbLogError.TabIndex = 1;
+      this.cbLogError.Text = "Errors";
+      this.cbLogError.UseVisualStyleBackColor = true;
       // 
-      // lPortNumber
+      // tbLog
       // 
-      this.lPortNumber.AutoSize = true;
-      this.lPortNumber.Location = new System.Drawing.Point(6, 43);
-      this.lPortNumber.Name = "lPortNumber";
-      this.lPortNumber.Size = new System.Drawing.Size(95, 13);
-      this.lPortNumber.TabIndex = 0;
-      this.lPortNumber.Text = "HDMI Port number";
-      // 
-      // tbButtons
-      // 
-      this.tbButtons.Controls.Add(this.label1);
-      this.tbButtons.Controls.Add(this.dgButtons);
-      this.tbButtons.Location = new System.Drawing.Point(4, 22);
-      this.tbButtons.Name = "tbButtons";
-      this.tbButtons.Padding = new System.Windows.Forms.Padding(3);
-      this.tbButtons.Size = new System.Drawing.Size(592, 359);
-      this.tbButtons.TabIndex = 2;
-      this.tbButtons.Text = "Button Configuration";
-      this.tbButtons.UseVisualStyleBackColor = true;
-      // 
-      // label1
-      // 
-      this.label1.AutoSize = true;
-      this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 20.25F, ((System.Drawing.FontStyle)((System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Italic))), System.Drawing.GraphicsUnit.Point, ((byte)(0)));
-      this.label1.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(192)))), ((int)(((byte)(64)))), ((int)(((byte)(0)))));
-      this.label1.Location = new System.Drawing.Point(118, 252);
-      this.label1.Name = "label1";
-      this.label1.Size = new System.Drawing.Size(354, 31);
-      this.label1.TabIndex = 1;
-      this.label1.Text = "NOT IMPLEMENTED YET";
-      // 
-      // dgButtons
-      // 
-      this.dgButtons.AllowUserToAddRows = false;
-      this.dgButtons.AllowUserToDeleteRows = false;
-      this.dgButtons.AllowUserToResizeColumns = false;
-      this.dgButtons.AllowUserToResizeRows = false;
-      this.dgButtons.AutoGenerateColumns = false;
-      this.dgButtons.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
-      this.dgButtons.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
-            this.CecButtonName});
-      this.dgButtons.DataSource = this.cecButtonConfigBindingSource;
-      this.dgButtons.Location = new System.Drawing.Point(7, 7);
-      this.dgButtons.Name = "dgButtons";
-      this.dgButtons.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
-      this.dgButtons.Size = new System.Drawing.Size(579, 346);
-      this.dgButtons.TabIndex = 0;
-      this.dgButtons.CellFormatting += new System.Windows.Forms.DataGridViewCellFormattingEventHandler(this.dataGridView1_CellFormatting);
-      // 
-      // CecButtonName
-      // 
-      this.CecButtonName.DataPropertyName = "CecButtonName";
-      this.CecButtonName.FillWeight = 260F;
-      this.CecButtonName.HeaderText = "Button";
-      this.CecButtonName.Name = "CecButtonName";
-      this.CecButtonName.ReadOnly = true;
-      this.CecButtonName.Width = 260;
-      // 
-      // cecButtonConfigBindingSource
-      // 
-      this.cecButtonConfigBindingSource.DataSource = typeof(CecConfigGui.CecButtonConfig);
+      this.tbLog.Location = new System.Drawing.Point(6, 0);
+      this.tbLog.Multiline = true;
+      this.tbLog.Name = "tbLog";
+      this.tbLog.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
+      this.tbLog.Size = new System.Drawing.Size(580, 312);
+      this.tbLog.TabIndex = 0;
       // 
       // tbTestCommands
       // 
       this.tbTestCommands.Location = new System.Drawing.Point(4, 22);
       this.tbTestCommands.Name = "tbTestCommands";
       this.tbTestCommands.Padding = new System.Windows.Forms.Padding(3);
-      this.tbTestCommands.Size = new System.Drawing.Size(592, 359);
+      this.tbTestCommands.Size = new System.Drawing.Size(592, 344);
       this.tbTestCommands.TabIndex = 3;
       this.tbTestCommands.Text = "CEC tester";
       this.tbTestCommands.UseVisualStyleBackColor = true;
       this.bRescanDevices.TabIndex = 9;
       this.bRescanDevices.Text = "Re-scan devices";
       this.bRescanDevices.UseVisualStyleBackColor = true;
-      this.bRescanDevices.Click += new System.EventHandler(this.bRescanDevices_Click);
+      this.bRescanDevices.Click += new System.EventHandler(this.BRescanDevicesClick);
       // 
       // bMute
       // 
       this.bMute.TabIndex = 8;
       this.bMute.Text = "Mute";
       this.bMute.UseVisualStyleBackColor = true;
-      this.bMute.Click += new System.EventHandler(this.bMute_Click);
+      this.bMute.Click += new System.EventHandler(this.BMuteClick);
       // 
       // bVolDown
       // 
       this.bVolDown.TabIndex = 7;
       this.bVolDown.Text = "Volume down";
       this.bVolDown.UseVisualStyleBackColor = true;
-      this.bVolDown.Click += new System.EventHandler(this.bVolDown_Click);
+      this.bVolDown.Click += new System.EventHandler(this.BVolDownClick);
       // 
       // bVolUp
       // 
       this.bVolUp.TabIndex = 6;
       this.bVolUp.Text = "Volume up";
       this.bVolUp.UseVisualStyleBackColor = true;
-      this.bVolUp.Click += new System.EventHandler(this.bVolUp_Click);
+      this.bVolUp.Click += new System.EventHandler(this.BVolUpClick);
       // 
       // bActivateSource
       // 
       this.bActivateSource.TabIndex = 5;
       this.bActivateSource.Text = "Make device active";
       this.bActivateSource.UseVisualStyleBackColor = true;
-      this.bActivateSource.Click += new System.EventHandler(this.bActivateSource_Click);
+      this.bActivateSource.Click += new System.EventHandler(this.BActivateSourceClick);
       // 
       // bScan
       // 
       this.bScan.TabIndex = 4;
       this.bScan.Text = "Device information";
       this.bScan.UseVisualStyleBackColor = true;
-      this.bScan.Click += new System.EventHandler(this.bScan_Click);
+      this.bScan.Click += new System.EventHandler(this.BScanClick);
       // 
       // bStandby
       // 
       this.bStandby.TabIndex = 3;
       this.bStandby.Text = "Put device in standby";
       this.bStandby.UseVisualStyleBackColor = true;
-      this.bStandby.Click += new System.EventHandler(this.bStandby_Click);
+      this.bStandby.Click += new System.EventHandler(this.BStandbyClick);
       // 
       // bSendImageViewOn
       // 
       this.bSendImageViewOn.TabIndex = 2;
       this.bSendImageViewOn.Text = "Power on device";
       this.bSendImageViewOn.UseVisualStyleBackColor = true;
-      this.bSendImageViewOn.Click += new System.EventHandler(this.bSendImageViewOn_Click);
+      this.bSendImageViewOn.Click += new System.EventHandler(this.BSendImageViewOnClick);
       // 
       // lDestination
       // 
-      this.lDestination.AutoSize = true;
-      this.lDestination.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
-      this.lDestination.Location = new System.Drawing.Point(420, 3);
-      this.lDestination.Name = "lDestination";
-      this.lDestination.Size = new System.Drawing.Size(138, 24);
-      this.lDestination.TabIndex = 1;
-      this.lDestination.Text = "Target device";
+      this.lDestination.AutoSize = true;
+      this.lDestination.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+      this.lDestination.Location = new System.Drawing.Point(420, 3);
+      this.lDestination.Name = "lDestination";
+      this.lDestination.Size = new System.Drawing.Size(138, 24);
+      this.lDestination.TabIndex = 1;
+      this.lDestination.Text = "Target device";
+      // 
+      // cbCommandDestination
+      // 
+      this.cbCommandDestination.FormattingEnabled = true;
+      this.cbCommandDestination.Items.AddRange(new object[] {
+            "0: TV",
+            "F: Broadcast"});
+      this.cbCommandDestination.Location = new System.Drawing.Point(437, 30);
+      this.cbCommandDestination.Name = "cbCommandDestination";
+      this.cbCommandDestination.Size = new System.Drawing.Size(121, 21);
+      this.cbCommandDestination.TabIndex = 0;
+      this.cbCommandDestination.Text = "0: TV";
+      this.cbCommandDestination.SelectedIndexChanged += new System.EventHandler(this.CbCommandDestinationSelectedIndexChanged);
+      // 
+      // Configuration
+      // 
+      this.Configuration.Controls.Add(this.cbStartMinimised);
+      this.Configuration.Controls.Add(this.cbOverrideAddress);
+      this.Configuration.Controls.Add(this.bReloadConfig);
+      this.Configuration.Controls.Add(this.cbVendorOverride);
+      this.Configuration.Controls.Add(this.cbVendorId);
+      this.Configuration.Controls.Add(this.lPowerOff);
+      this.Configuration.Controls.Add(this.cbPowerOffDevices);
+      this.Configuration.Controls.Add(this.lWakeDevices);
+      this.Configuration.Controls.Add(this.cbWakeDevices);
+      this.Configuration.Controls.Add(this.cbActivateSource);
+      this.Configuration.Controls.Add(this.lPlayerConfig);
+      this.Configuration.Controls.Add(this.lAdapterConfig);
+      this.Configuration.Controls.Add(this.cbDeviceType);
+      this.Configuration.Controls.Add(this.bClose);
+      this.Configuration.Controls.Add(this.bSaveConfig);
+      this.Configuration.Controls.Add(this.cbPortNumber);
+      this.Configuration.Controls.Add(this.tbPhysicalAddress);
+      this.Configuration.Controls.Add(this.cbConnectedDevice);
+      this.Configuration.Controls.Add(this.lDeviceType);
+      this.Configuration.Controls.Add(this.lConnectedDevice);
+      this.Configuration.Controls.Add(this.lPortNumber);
+      this.Configuration.Location = new System.Drawing.Point(4, 22);
+      this.Configuration.Name = "Configuration";
+      this.Configuration.Padding = new System.Windows.Forms.Padding(3);
+      this.Configuration.Size = new System.Drawing.Size(592, 344);
+      this.Configuration.TabIndex = 0;
+      this.Configuration.Text = "Configuration";
+      this.Configuration.UseVisualStyleBackColor = true;
+      // 
+      // cbOverrideAddress
+      // 
+      this.cbOverrideAddress.AutoSize = true;
+      this.cbOverrideAddress.Enabled = false;
+      this.cbOverrideAddress.Location = new System.Drawing.Point(10, 97);
+      this.cbOverrideAddress.Name = "cbOverrideAddress";
+      this.cbOverrideAddress.Size = new System.Drawing.Size(151, 17);
+      this.cbOverrideAddress.TabIndex = 31;
+      this.cbOverrideAddress.Text = "override_physical_address";
+      this.cbOverrideAddress.UseVisualStyleBackColor = true;
+      // 
+      // bReloadConfig
       // 
-      // cbCommandDestination
+      this.bReloadConfig.Enabled = false;
+      this.bReloadConfig.Location = new System.Drawing.Point(357, 315);
+      this.bReloadConfig.Name = "bReloadConfig";
+      this.bReloadConfig.Size = new System.Drawing.Size(125, 23);
+      this.bReloadConfig.TabIndex = 30;
+      this.bReloadConfig.Text = "Reset configuration";
+      this.bReloadConfig.UseVisualStyleBackColor = true;
+      this.bReloadConfig.Click += new System.EventHandler(this.BReloadConfigClick);
       // 
-      this.cbCommandDestination.FormattingEnabled = true;
-      this.cbCommandDestination.Items.AddRange(new object[] {
-            "0: TV",
-            "F: Broadcast"});
-      this.cbCommandDestination.Location = new System.Drawing.Point(437, 30);
-      this.cbCommandDestination.Name = "cbCommandDestination";
-      this.cbCommandDestination.Size = new System.Drawing.Size(121, 21);
-      this.cbCommandDestination.TabIndex = 0;
-      this.cbCommandDestination.Text = "0: TV";
-      this.cbCommandDestination.SelectedIndexChanged += new System.EventHandler(this.cbCommandDestination_SelectedIndexChanged);
+      // cbVendorOverride
       // 
-      // LogOutput
+      this.cbVendorOverride.AutoSize = true;
+      this.cbVendorOverride.Enabled = false;
+      this.cbVendorOverride.Location = new System.Drawing.Point(10, 156);
+      this.cbVendorOverride.Name = "cbVendorOverride";
+      this.cbVendorOverride.Size = new System.Drawing.Size(118, 17);
+      this.cbVendorOverride.TabIndex = 29;
+      this.cbVendorOverride.Text = "override_tv_vendor";
+      this.cbVendorOverride.UseVisualStyleBackColor = true;
       // 
-      this.LogOutput.Controls.Add(this.bSaveLog);
-      this.LogOutput.Controls.Add(this.bClearLog);
-      this.LogOutput.Controls.Add(this.cbLogDebug);
-      this.LogOutput.Controls.Add(this.cbLogTraffic);
-      this.LogOutput.Controls.Add(this.cbLogNotice);
-      this.LogOutput.Controls.Add(this.cbLogWarning);
-      this.LogOutput.Controls.Add(this.cbLogError);
-      this.LogOutput.Controls.Add(this.tbLog);
-      this.LogOutput.Location = new System.Drawing.Point(4, 22);
-      this.LogOutput.Name = "LogOutput";
-      this.LogOutput.Padding = new System.Windows.Forms.Padding(3);
-      this.LogOutput.Size = new System.Drawing.Size(592, 359);
-      this.LogOutput.TabIndex = 1;
-      this.LogOutput.Text = "Log Output";
-      this.LogOutput.UseVisualStyleBackColor = true;
+      // lPowerOff
       // 
-      // bSaveLog
+      this.lPowerOff.AutoSize = true;
+      this.lPowerOff.Location = new System.Drawing.Point(448, 35);
+      this.lPowerOff.Name = "lPowerOff";
+      this.lPowerOff.Size = new System.Drawing.Size(87, 13);
+      this.lPowerOff.TabIndex = 26;
+      this.lPowerOff.Text = "standby_devices";
       // 
-      this.bSaveLog.Location = new System.Drawing.Point(430, 330);
-      this.bSaveLog.Name = "bSaveLog";
-      this.bSaveLog.Size = new System.Drawing.Size(75, 23);
-      this.bSaveLog.TabIndex = 7;
-      this.bSaveLog.Text = "Save";
-      this.bSaveLog.UseVisualStyleBackColor = true;
-      this.bSaveLog.Click += new System.EventHandler(this.bSaveLog_Click);
+      // cbPowerOffDevices
       // 
-      // bClearLog
+      this.cbPowerOffDevices.Enabled = false;
+      this.cbPowerOffDevices.FormattingEnabled = true;
+      this.cbPowerOffDevices.Items.AddRange(new object[] {
+            "global_standby_devices"});
+      this.cbPowerOffDevices.Location = new System.Drawing.Point(450, 52);
+      this.cbPowerOffDevices.Name = "cbPowerOffDevices";
+      this.cbPowerOffDevices.Size = new System.Drawing.Size(118, 94);
+      this.cbPowerOffDevices.TabIndex = 25;
       // 
-      this.bClearLog.Location = new System.Drawing.Point(511, 330);
-      this.bClearLog.Name = "bClearLog";
-      this.bClearLog.Size = new System.Drawing.Size(75, 23);
-      this.bClearLog.TabIndex = 6;
-      this.bClearLog.Text = "Clear";
-      this.bClearLog.UseVisualStyleBackColor = true;
-      this.bClearLog.Click += new System.EventHandler(this.bClearLog_Click);
+      // lWakeDevices
       // 
-      // cbLogDebug
+      this.lWakeDevices.AutoSize = true;
+      this.lWakeDevices.Location = new System.Drawing.Point(328, 35);
+      this.lWakeDevices.Name = "lWakeDevices";
+      this.lWakeDevices.Size = new System.Drawing.Size(76, 13);
+      this.lWakeDevices.TabIndex = 24;
+      this.lWakeDevices.Text = "wake_devices";
       // 
-      this.cbLogDebug.AutoSize = true;
-      this.cbLogDebug.Checked = true;
-      this.cbLogDebug.CheckState = System.Windows.Forms.CheckState.Checked;
-      this.cbLogDebug.Location = new System.Drawing.Point(269, 336);
-      this.cbLogDebug.Name = "cbLogDebug";
-      this.cbLogDebug.Size = new System.Drawing.Size(58, 17);
-      this.cbLogDebug.TabIndex = 5;
-      this.cbLogDebug.Text = "Debug";
-      this.cbLogDebug.UseVisualStyleBackColor = true;
+      // cbWakeDevices
       // 
-      // cbLogTraffic
+      this.cbWakeDevices.Enabled = false;
+      this.cbWakeDevices.FormattingEnabled = true;
+      this.cbWakeDevices.Items.AddRange(new object[] {
+            "global_wake_devices"});
+      this.cbWakeDevices.Location = new System.Drawing.Point(320, 52);
+      this.cbWakeDevices.Name = "cbWakeDevices";
+      this.cbWakeDevices.Size = new System.Drawing.Size(118, 94);
+      this.cbWakeDevices.TabIndex = 23;
       // 
-      this.cbLogTraffic.AutoSize = true;
-      this.cbLogTraffic.Checked = true;
-      this.cbLogTraffic.CheckState = System.Windows.Forms.CheckState.Checked;
-      this.cbLogTraffic.Location = new System.Drawing.Point(207, 336);
-      this.cbLogTraffic.Name = "cbLogTraffic";
-      this.cbLogTraffic.Size = new System.Drawing.Size(56, 17);
-      this.cbLogTraffic.TabIndex = 4;
-      this.cbLogTraffic.Text = "Traffic";
-      this.cbLogTraffic.UseVisualStyleBackColor = true;
+      // cbActivateSource
       // 
-      // cbLogNotice
+      this.cbActivateSource.AutoSize = true;
+      this.cbActivateSource.Enabled = false;
+      this.cbActivateSource.Location = new System.Drawing.Point(9, 209);
+      this.cbActivateSource.Name = "cbActivateSource";
+      this.cbActivateSource.Size = new System.Drawing.Size(136, 17);
+      this.cbActivateSource.TabIndex = 19;
+      this.cbActivateSource.Text = "global_activate_source";
+      this.cbActivateSource.UseVisualStyleBackColor = true;
       // 
-      this.cbLogNotice.AutoSize = true;
-      this.cbLogNotice.Checked = true;
-      this.cbLogNotice.CheckState = System.Windows.Forms.CheckState.Checked;
-      this.cbLogNotice.Location = new System.Drawing.Point(138, 336);
-      this.cbLogNotice.Name = "cbLogNotice";
-      this.cbLogNotice.Size = new System.Drawing.Size(62, 17);
-      this.cbLogNotice.TabIndex = 3;
-      this.cbLogNotice.Text = "Notices";
-      this.cbLogNotice.UseVisualStyleBackColor = true;
+      // lPlayerConfig
       // 
-      // cbLogWarning
+      this.lPlayerConfig.AutoSize = true;
+      this.lPlayerConfig.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+      this.lPlayerConfig.Location = new System.Drawing.Point(6, 182);
+      this.lPlayerConfig.Name = "lPlayerConfig";
+      this.lPlayerConfig.Size = new System.Drawing.Size(198, 24);
+      this.lPlayerConfig.TabIndex = 16;
+      this.lPlayerConfig.Text = "Player Configuration";
       // 
-      this.cbLogWarning.AutoSize = true;
-      this.cbLogWarning.Checked = true;
-      this.cbLogWarning.CheckState = System.Windows.Forms.CheckState.Checked;
-      this.cbLogWarning.Location = new System.Drawing.Point(66, 336);
-      this.cbLogWarning.Name = "cbLogWarning";
-      this.cbLogWarning.Size = new System.Drawing.Size(66, 17);
-      this.cbLogWarning.TabIndex = 2;
-      this.cbLogWarning.Text = "Warning";
-      this.cbLogWarning.UseVisualStyleBackColor = true;
+      // lAdapterConfig
       // 
-      // cbLogError
+      this.lAdapterConfig.AutoSize = true;
+      this.lAdapterConfig.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+      this.lAdapterConfig.Location = new System.Drawing.Point(6, 3);
+      this.lAdapterConfig.Name = "lAdapterConfig";
+      this.lAdapterConfig.Size = new System.Drawing.Size(213, 24);
+      this.lAdapterConfig.TabIndex = 15;
+      this.lAdapterConfig.Text = "Adapter Configuration";
       // 
-      this.cbLogError.AutoSize = true;
-      this.cbLogError.Checked = true;
-      this.cbLogError.CheckState = System.Windows.Forms.CheckState.Checked;
-      this.cbLogError.Location = new System.Drawing.Point(7, 336);
-      this.cbLogError.Name = "cbLogError";
-      this.cbLogError.Size = new System.Drawing.Size(53, 17);
-      this.cbLogError.TabIndex = 1;
-      this.cbLogError.Text = "Errors";
-      this.cbLogError.UseVisualStyleBackColor = true;
+      // bClose
       // 
-      // tbLog
+      this.bClose.Enabled = false;
+      this.bClose.Location = new System.Drawing.Point(95, 315);
+      this.bClose.Name = "bClose";
+      this.bClose.Size = new System.Drawing.Size(125, 23);
+      this.bClose.TabIndex = 13;
+      this.bClose.Text = "Close";
+      this.bClose.UseVisualStyleBackColor = true;
+      this.bClose.Click += new System.EventHandler(this.BCancelClick);
       // 
-      this.tbLog.Location = new System.Drawing.Point(6, 6);
-      this.tbLog.Multiline = true;
-      this.tbLog.Name = "tbLog";
-      this.tbLog.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
-      this.tbLog.Size = new System.Drawing.Size(580, 318);
-      this.tbLog.TabIndex = 0;
+      // bSaveConfig
       // 
-      // pProgress
+      this.bSaveConfig.Enabled = false;
+      this.bSaveConfig.Location = new System.Drawing.Point(226, 315);
+      this.bSaveConfig.Name = "bSaveConfig";
+      this.bSaveConfig.Size = new System.Drawing.Size(125, 23);
+      this.bSaveConfig.TabIndex = 12;
+      this.bSaveConfig.Text = "Persist configuration";
+      this.bSaveConfig.UseVisualStyleBackColor = true;
+      this.bSaveConfig.Click += new System.EventHandler(this.BSaveClick);
       // 
-      this.pProgress.Location = new System.Drawing.Point(314, 407);
-      this.pProgress.Name = "pProgress";
-      this.pProgress.Size = new System.Drawing.Size(298, 23);
-      this.pProgress.TabIndex = 1;
+      // lDeviceType
       // 
-      // lStatus
+      this.lDeviceType.AutoSize = true;
+      this.lDeviceType.Location = new System.Drawing.Point(6, 126);
+      this.lDeviceType.Name = "lDeviceType";
+      this.lDeviceType.Size = new System.Drawing.Size(65, 13);
+      this.lDeviceType.TabIndex = 3;
+      this.lDeviceType.Text = "device_type";
       // 
-      this.lStatus.AutoSize = true;
-      this.lStatus.Location = new System.Drawing.Point(12, 416);
-      this.lStatus.Name = "lStatus";
-      this.lStatus.Size = new System.Drawing.Size(61, 13);
-      this.lStatus.TabIndex = 2;
-      this.lStatus.Text = "Initialising...";
+      // lConnectedDevice
       // 
-      // cbSendInactiveSource
+      this.lConnectedDevice.AutoSize = true;
+      this.lConnectedDevice.Location = new System.Drawing.Point(6, 70);
+      this.lConnectedDevice.Name = "lConnectedDevice";
+      this.lConnectedDevice.Size = new System.Drawing.Size(139, 13);
+      this.lConnectedDevice.TabIndex = 1;
+      this.lConnectedDevice.Text = "connected_to_hdmi_device";
       // 
-      this.cbSendInactiveSource.AutoSize = true;
-      this.cbSendInactiveSource.Enabled = false;
-      this.cbSendInactiveSource.Location = new System.Drawing.Point(9, 301);
-      this.cbSendInactiveSource.Name = "cbSendInactiveSource";
-      this.cbSendInactiveSource.Size = new System.Drawing.Size(261, 17);
-      this.cbSendInactiveSource.TabIndex = 32;
-      this.cbSendInactiveSource.Text = "Send \'inactive source\' when shutting down XBMC";
-      this.cbSendInactiveSource.UseVisualStyleBackColor = true;
+      // lPortNumber
       // 
-      // CecConfigGUI
+      this.lPortNumber.AutoSize = true;
+      this.lPortNumber.Location = new System.Drawing.Point(6, 43);
+      this.lPortNumber.Name = "lPortNumber";
+      this.lPortNumber.Size = new System.Drawing.Size(53, 13);
+      this.lPortNumber.TabIndex = 0;
+      this.lPortNumber.Text = "hdmi_port";
+      // 
+      // tabPanel
+      // 
+      this.tabPanel.Controls.Add(this.Configuration);
+      this.tabPanel.Controls.Add(this.tbTestCommands);
+      this.tabPanel.Controls.Add(this.LogOutput);
+      this.tabPanel.Location = new System.Drawing.Point(12, 27);
+      this.tabPanel.Name = "tabPanel";
+      this.tabPanel.SelectedIndex = 0;
+      this.tabPanel.Size = new System.Drawing.Size(600, 370);
+      this.tabPanel.TabIndex = 0;
+      this.tabPanel.SelectedIndexChanged += new System.EventHandler(this.TabControl1SelectedIndexChanged);
+      // 
+      // menuStrip1
+      // 
+      this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+            this.fileToolStripMenuItem,
+            this.applicationsToolStripMenuItem,
+            this.helpToolStripMenuItem});
+      this.menuStrip1.Location = new System.Drawing.Point(0, 0);
+      this.menuStrip1.Name = "menuStrip1";
+      this.menuStrip1.Size = new System.Drawing.Size(624, 24);
+      this.menuStrip1.TabIndex = 3;
+      this.menuStrip1.Text = "menuStrip1";
+      // 
+      // fileToolStripMenuItem
+      // 
+      this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+            this.hideToolStripMenuItem,
+            this.advancedModeToolStripMenuItem,
+            this.closeToolStripMenuItem});
+      this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
+      this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20);
+      this.fileToolStripMenuItem.Text = "File";
+      // 
+      // hideToolStripMenuItem
+      // 
+      this.hideToolStripMenuItem.Name = "hideToolStripMenuItem";
+      this.hideToolStripMenuItem.Size = new System.Drawing.Size(161, 22);
+      this.hideToolStripMenuItem.Text = "Hide";
+      this.hideToolStripMenuItem.Click += new System.EventHandler(this.HideToolStripMenuItemClick);
+      // 
+      // advancedModeToolStripMenuItem
+      // 
+      this.advancedModeToolStripMenuItem.Name = "advancedModeToolStripMenuItem";
+      this.advancedModeToolStripMenuItem.Size = new System.Drawing.Size(161, 22);
+      this.advancedModeToolStripMenuItem.Text = "Advanced mode";
+      this.advancedModeToolStripMenuItem.Click += new System.EventHandler(this.AdvancedModeToolStripMenuItemClick);
+      // 
+      // closeToolStripMenuItem
+      // 
+      this.closeToolStripMenuItem.Name = "closeToolStripMenuItem";
+      this.closeToolStripMenuItem.Size = new System.Drawing.Size(161, 22);
+      this.closeToolStripMenuItem.Text = "Close";
+      this.closeToolStripMenuItem.Click += new System.EventHandler(this.CloseToolStripMenuItemClick);
+      // 
+      // applicationsToolStripMenuItem
+      // 
+      this.applicationsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+            this.addNewApplicationToolStripMenuItem});
+      this.applicationsToolStripMenuItem.Enabled = false;
+      this.applicationsToolStripMenuItem.Name = "applicationsToolStripMenuItem";
+      this.applicationsToolStripMenuItem.Size = new System.Drawing.Size(85, 20);
+      this.applicationsToolStripMenuItem.Text = "Applications";
+      // 
+      // addNewApplicationToolStripMenuItem
+      // 
+      this.addNewApplicationToolStripMenuItem.Enabled = false;
+      this.addNewApplicationToolStripMenuItem.Name = "addNewApplicationToolStripMenuItem";
+      this.addNewApplicationToolStripMenuItem.Size = new System.Drawing.Size(183, 22);
+      this.addNewApplicationToolStripMenuItem.Text = "Add new application";
+      this.addNewApplicationToolStripMenuItem.Click += new System.EventHandler(this.AddNewApplicationToolStripMenuItemClick);
+      // 
+      // helpToolStripMenuItem
+      // 
+      this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+            this.aboutToolStripMenuItem});
+      this.helpToolStripMenuItem.Name = "helpToolStripMenuItem";
+      this.helpToolStripMenuItem.Size = new System.Drawing.Size(44, 20);
+      this.helpToolStripMenuItem.Text = "Help";
+      // 
+      // aboutToolStripMenuItem
+      // 
+      this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem";
+      this.aboutToolStripMenuItem.Size = new System.Drawing.Size(107, 22);
+      this.aboutToolStripMenuItem.Text = "About";
+      this.aboutToolStripMenuItem.Click += new System.EventHandler(this.AboutToolStripMenuItemClick);
+      // 
+      // cbStartMinimised
+      // 
+      this.cbStartMinimised.AutoSize = true;
+      this.cbStartMinimised.Enabled = false;
+      this.cbStartMinimised.Location = new System.Drawing.Point(9, 232);
+      this.cbStartMinimised.Name = "cbStartMinimised";
+      this.cbStartMinimised.Size = new System.Drawing.Size(118, 17);
+      this.cbStartMinimised.TabIndex = 32;
+      this.cbStartMinimised.Text = "global_start_hidden";
+      this.cbStartMinimised.UseVisualStyleBackColor = true;
+      // 
+      // CECTray
       // 
       this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
       this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
       this.ClientSize = new System.Drawing.Size(624, 442);
+      this.Controls.Add(this.menuStrip1);
       this.Controls.Add(this.lStatus);
       this.Controls.Add(this.pProgress);
-      this.Controls.Add(this.tabControl1);
+      this.Controls.Add(this.tabPanel);
       this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
       this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
+      this.MainMenuStrip = this.menuStrip1;
       this.MaximizeBox = false;
-      this.Name = "CecConfigGUI";
-      this.Text = "Pulse-Eight USB-CEC Adapter";
-      this.tabControl1.ResumeLayout(false);
-      this.Configuration.ResumeLayout(false);
-      this.Configuration.PerformLayout();
-      this.tbButtons.ResumeLayout(false);
-      this.tbButtons.PerformLayout();
-      ((System.ComponentModel.ISupportInitialize)(this.dgButtons)).EndInit();
-      ((System.ComponentModel.ISupportInitialize)(this.cecButtonConfigBindingSource)).EndInit();
-      this.tbTestCommands.ResumeLayout(false);
-      this.tbTestCommands.PerformLayout();
+      this.Name = "CECTray";
+      this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
+      this.Load += new System.EventHandler(this.CECTrayLoad);
+      this.Resize += new System.EventHandler(this.CECTrayResize);
+      this.trayIconMenu.ResumeLayout(false);
       this.LogOutput.ResumeLayout(false);
       this.LogOutput.PerformLayout();
+      this.tbTestCommands.ResumeLayout(false);
+      this.tbTestCommands.PerformLayout();
+      this.Configuration.ResumeLayout(false);
+      this.Configuration.PerformLayout();
+      this.tabPanel.ResumeLayout(false);
+      this.menuStrip1.ResumeLayout(false);
+      this.menuStrip1.PerformLayout();
       this.ResumeLayout(false);
       this.PerformLayout();
 
 
     #endregion
 
-    private System.Windows.Forms.TabControl tabControl1;
-    private System.Windows.Forms.TabPage Configuration;
-    private System.Windows.Forms.TabPage LogOutput;
-    private System.Windows.Forms.Label lPortNumber;
-    private System.Windows.Forms.Label lDeviceType;
-    private System.Windows.Forms.Label lConnectedDevice;
-    private System.Windows.Forms.ComboBox cbConnectedDevice;
-    private System.Windows.Forms.TextBox tbPhysicalAddress;
     private System.Windows.Forms.ProgressBar pProgress;
-    private System.Windows.Forms.Label lStatus;
-    private System.Windows.Forms.TextBox tbLog;
-    private System.Windows.Forms.ComboBox cbPortNumber;
-    private System.Windows.Forms.Button bClose;
-    private System.Windows.Forms.Button bSaveConfig;
-    private System.Windows.Forms.ComboBox cbDeviceType;
-    private System.Windows.Forms.CheckBox cbPowerOffOnStandby;
-    private System.Windows.Forms.CheckBox cbPowerOffScreensaver;
-    private System.Windows.Forms.CheckBox cbActivateSource;
-    private System.Windows.Forms.CheckBox cbUseTVMenuLanguage;
-    private System.Windows.Forms.Label lPlayerConfig;
+    public System.Windows.Forms.Label lStatus;
     private System.Windows.Forms.ToolTip helpPortNumber;
     private System.Windows.Forms.ToolTip helpConnectedHDMIDevice;
     private System.Windows.Forms.ToolTip helpDeviceType;
     private System.Windows.Forms.ToolTip helpPhysicalAddress;
-    private System.Windows.Forms.TabPage tbButtons;
+    private System.Windows.Forms.NotifyIcon trayIcon;
+    private System.Windows.Forms.ContextMenuStrip trayIconMenu;
+    private System.Windows.Forms.ToolStripMenuItem tsMenuClose;
+    private System.Windows.Forms.ToolStripMenuItem tsMenuShowHide;
+    private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;
+    private System.Windows.Forms.ToolStripMenuItem tsAdvanced;
+    private System.Windows.Forms.TabPage LogOutput;
+    private System.Windows.Forms.Button bSaveLog;
+    private System.Windows.Forms.Button bClearLog;
     private System.Windows.Forms.CheckBox cbLogDebug;
     private System.Windows.Forms.CheckBox cbLogTraffic;
     private System.Windows.Forms.CheckBox cbLogNotice;
     private System.Windows.Forms.CheckBox cbLogWarning;
     private System.Windows.Forms.CheckBox cbLogError;
-    private System.Windows.Forms.Button bClearLog;
-    private System.Windows.Forms.Button bSaveLog;
-    private System.Windows.Forms.DataGridView dgButtons;
-    private System.Windows.Forms.BindingSource cecButtonConfigBindingSource;
-    private System.Windows.Forms.DataGridViewTextBoxColumn CecButtonName;
-    private System.Windows.Forms.DataGridViewTextBoxColumn playerButtonDataGridViewTextBoxColumn;
+    private System.Windows.Forms.TextBox tbLog;
     private System.Windows.Forms.TabPage tbTestCommands;
-    private System.Windows.Forms.ComboBox cbCommandDestination;
-    private System.Windows.Forms.Button bStandby;
-    private System.Windows.Forms.Button bSendImageViewOn;
-    private System.Windows.Forms.Label lDestination;
-    private System.Windows.Forms.Button bActivateSource;
-    private System.Windows.Forms.Button bScan;
+    private System.Windows.Forms.Button bRescanDevices;
     private System.Windows.Forms.Button bMute;
     private System.Windows.Forms.Button bVolDown;
     private System.Windows.Forms.Button bVolUp;
-    private System.Windows.Forms.Label label1;
-    private System.Windows.Forms.Label lWakeDevices;
-    private System.Windows.Forms.CheckedListBox cbWakeDevices;
-    private System.Windows.Forms.Label lPowerOff;
-    private System.Windows.Forms.CheckedListBox cbPowerOffDevices;
+    private System.Windows.Forms.Button bActivateSource;
+    private System.Windows.Forms.Button bScan;
+    private System.Windows.Forms.Button bStandby;
+    private System.Windows.Forms.Button bSendImageViewOn;
+    private System.Windows.Forms.Label lDestination;
+    private System.Windows.Forms.ComboBox cbCommandDestination;
+    private System.Windows.Forms.TabPage Configuration;
+    private System.Windows.Forms.CheckBox cbOverrideAddress;
+    private System.Windows.Forms.Button bReloadConfig;
     private System.Windows.Forms.CheckBox cbVendorOverride;
     private System.Windows.Forms.ComboBox cbVendorId;
-    private System.Windows.Forms.Button bReloadConfig;
-    private System.Windows.Forms.Button bRescanDevices;
-    private System.Windows.Forms.Label lConnectedPhysicalAddress;
+    private System.Windows.Forms.Label lPowerOff;
+    private System.Windows.Forms.CheckedListBox cbPowerOffDevices;
+    private System.Windows.Forms.Label lWakeDevices;
+    private System.Windows.Forms.CheckedListBox cbWakeDevices;
+    private System.Windows.Forms.CheckBox cbActivateSource;
+    private System.Windows.Forms.Label lPlayerConfig;
     private System.Windows.Forms.Label lAdapterConfig;
-    private System.Windows.Forms.CheckBox cbOverrideAddress;
-    private System.Windows.Forms.CheckBox cbSendInactiveSource;
+    private System.Windows.Forms.ComboBox cbDeviceType;
+    private System.Windows.Forms.Button bClose;
+    private System.Windows.Forms.Button bSaveConfig;
+    private System.Windows.Forms.ComboBox cbPortNumber;
+    private System.Windows.Forms.TextBox tbPhysicalAddress;
+    private System.Windows.Forms.ComboBox cbConnectedDevice;
+    private System.Windows.Forms.Label lDeviceType;
+    private System.Windows.Forms.Label lConnectedDevice;
+    private System.Windows.Forms.Label lPortNumber;
+    private System.Windows.Forms.TabControl tabPanel;
+    private System.Windows.Forms.MenuStrip menuStrip1;
+    private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
+    private System.Windows.Forms.ToolStripMenuItem hideToolStripMenuItem;
+    private System.Windows.Forms.ToolStripMenuItem closeToolStripMenuItem;
+    private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem;
+    private System.Windows.Forms.ToolStripMenuItem aboutToolStripMenuItem;
+    private System.Windows.Forms.ToolStripMenuItem advancedModeToolStripMenuItem;
+    private System.Windows.Forms.ToolStripMenuItem applicationsToolStripMenuItem;
+    private System.Windows.Forms.ToolStripMenuItem addNewApplicationToolStripMenuItem;
+    private System.Windows.Forms.CheckBox cbStartMinimised;
   }
 }
\ No newline at end of file
diff --git a/src/LibCecTray/ui/CECTray.cs b/src/LibCecTray/ui/CECTray.cs
new file mode 100644 (file)
index 0000000..a781ce7
--- /dev/null
@@ -0,0 +1,506 @@
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing       <license@pulse-eight.com>
+ *     http://www.pulse-eight.com/
+ *     http://www.pulse-eight.net/
+ */
+
+using System;
+using System.Windows.Forms;
+using CecSharp;
+using System.IO;
+using LibCECTray.Properties;
+using LibCECTray.controller;
+using LibCECTray.controller.applications;
+using LibCECTray.settings;
+
+namespace LibCECTray.ui
+{
+  /// <summary>
+  /// The tab pages in this application
+  /// </summary>
+  internal enum ConfigTab
+  {
+    Configuration,
+    KeyConfiguration,
+    Tester,
+    Log,
+    WMC,
+    XBMC
+  }
+
+  /// <summary>
+  /// Main LibCecTray GUI
+  /// </summary>
+  partial class CECTray : AsyncForm
+  {
+    public CECTray()
+    {
+      Text = Resources.app_name;
+      InitializeComponent();
+      _controller = new CECController(this);
+      VisibleChanged += delegate
+                       {
+                         if (!Visible)
+                           OnHide();
+                         else
+                           OnShow();
+                       };
+    }
+
+    public override sealed string Text
+    {
+      get { return base.Text; }
+      set { base.Text = value; }
+    }
+
+    private void CECTrayLoad(object sender, EventArgs e)
+    {
+      _controller.Initialise();
+    }
+
+    protected override void Dispose(bool disposing)
+    {
+      Hide();
+      if (disposing)
+      {
+        _controller.Close();
+      }
+      if (disposing && (components != null))
+      {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Configuration tab
+    /// <summary>
+    /// Replaces the gui controls by the ones that are bound to the settings.
+    /// this is a fugly way to do it, but the gui designer doesn't allow us to ref CECSettings, since it uses symbols from LibCecSharp
+    /// </summary>
+    public void InitialiseSettingsComponent(CECSettings settings)
+    {
+      settings.WakeDevices.ReplaceControls(this, Configuration.Controls, lWakeDevices, cbWakeDevices);
+      settings.PowerOffDevices.ReplaceControls(this, Configuration.Controls, lPowerOff, cbPowerOffDevices);
+      settings.OverridePhysicalAddress.ReplaceControls(this, Configuration.Controls, cbOverrideAddress);
+      settings.OverrideTVVendor.ReplaceControls(this, Configuration.Controls, cbVendorOverride);
+      settings.PhysicalAddress.ReplaceControls(this, Configuration.Controls, tbPhysicalAddress);
+      settings.HDMIPort.ReplaceControls(this, Configuration.Controls, lPortNumber, cbPortNumber);
+      settings.ConnectedDevice.ReplaceControls(this, Configuration.Controls, lConnectedDevice, cbConnectedDevice);
+      settings.ActivateSource.ReplaceControls(this, Configuration.Controls, cbActivateSource);
+      settings.DeviceType.ReplaceControls(this, Configuration.Controls, lDeviceType, cbDeviceType);
+      settings.TVVendor.ReplaceControls(this, Configuration.Controls, cbVendorId);
+      settings.StartHidden.ReplaceControls(this, Configuration.Controls, cbStartMinimised);
+    }
+
+    private void BSaveClick(object sender, EventArgs e)
+    {
+      _controller.PersistSettings();
+    }
+   
+    private void BReloadConfigClick(object sender, EventArgs e)
+    {
+      _controller.ResetDefaultSettings();
+    }
+    #endregion
+
+    #region CEC Tester tab
+    delegate void SetActiveDevicesCallback(string[] activeDevices);
+    public void SetActiveDevices(string[] activeDevices)
+    {
+      if (cbCommandDestination.InvokeRequired)
+      {
+        SetActiveDevicesCallback d = SetActiveDevices;
+        try
+        {
+          Invoke(d, new object[] { activeDevices });
+        }
+        catch (Exception) { }
+      }
+      else
+      {
+        cbCommandDestination.Items.Clear();
+        foreach (string item in activeDevices)
+          cbCommandDestination.Items.Add(item);
+      }
+    }
+
+    delegate CecLogicalAddress GetTargetDeviceCallback();
+    private CecLogicalAddress GetTargetDevice()
+    {
+      if (cbCommandDestination.InvokeRequired)
+      {
+        GetTargetDeviceCallback d = GetTargetDevice;
+        CecLogicalAddress retval = CecLogicalAddress.Unknown;
+        try
+        {
+          retval = (CecLogicalAddress)Invoke(d, new object[] { });
+        }
+        catch (Exception) { }
+        return retval;
+      }
+
+      return CECSettingLogicalAddresses.GetLogicalAddressFromString(cbCommandDestination.Text);
+    }
+
+    private void BSendImageViewOnClick(object sender, EventArgs e)
+    {
+      _controller.CECActions.SendImageViewOn(GetTargetDevice());
+    }
+
+    private void BStandbyClick(object sender, EventArgs e)
+    {
+      _controller.CECActions.SendStandby(GetTargetDevice());
+    }
+
+    private void BScanClick(object sender, EventArgs e)
+    {
+      _controller.CECActions.ShowDeviceInfo(GetTargetDevice());
+    }
+
+    private void BActivateSourceClick(object sender, EventArgs e)
+    {
+      _controller.CECActions.ActivateSource(GetTargetDevice());
+    }
+
+    private void CbCommandDestinationSelectedIndexChanged(object sender, EventArgs e)
+    {
+      bool enableVolumeButtons = (GetTargetDevice() == CecLogicalAddress.AudioSystem);
+      bVolUp.Enabled = enableVolumeButtons;
+      bVolDown.Enabled = enableVolumeButtons;
+      bMute.Enabled = enableVolumeButtons;
+      bActivateSource.Enabled = (GetTargetDevice() != CecLogicalAddress.Broadcast);
+      bScan.Enabled = (GetTargetDevice() != CecLogicalAddress.Broadcast);
+    }
+
+    private void BVolUpClick(object sender, EventArgs e)
+    {
+      _controller.Lib.VolumeUp(true);
+    }
+
+    private void BVolDownClick(object sender, EventArgs e)
+    {
+      _controller.Lib.VolumeDown(true);
+    }
+
+    private void BMuteClick(object sender, EventArgs e)
+    {
+      _controller.Lib.MuteAudio(true);
+    }
+
+    private void BRescanDevicesClick(object sender, EventArgs e)
+    {
+      _controller.CECActions.RescanDevices();
+    }
+    #endregion
+
+    #region Log tab
+    delegate void UpdateLogCallback();
+    private void UpdateLog()
+    {
+      if (tbLog.InvokeRequired)
+      {
+        UpdateLogCallback d = UpdateLog;
+        try
+        {
+          Invoke(d, new object[] { });
+        }
+        catch (Exception) { }
+      }
+      else
+      {
+        tbLog.Text = _log;
+        tbLog.Select(tbLog.Text.Length, 0);
+        tbLog.ScrollToCaret();
+      }
+    }
+
+    public void AddLogMessage(CecLogMessage message)
+    {
+      string strLevel = "";
+      bool display = false;
+      switch (message.Level)
+      {
+        case CecLogLevel.Error:
+          strLevel = "ERROR:   ";
+          display = cbLogError.Checked;
+          break;
+        case CecLogLevel.Warning:
+          strLevel = "WARNING: ";
+          display = cbLogWarning.Checked;
+          break;
+        case CecLogLevel.Notice:
+          strLevel = "NOTICE:  ";
+          display = cbLogNotice.Checked;
+          break;
+        case CecLogLevel.Traffic:
+          strLevel = "TRAFFIC: ";
+          display = cbLogTraffic.Checked;
+          break;
+        case CecLogLevel.Debug:
+          strLevel = "DEBUG:   ";
+          display = cbLogDebug.Checked;
+          break;
+      }
+
+      if (display)
+      {
+        string strLog = string.Format("{0} {1,16} {2}", strLevel, message.Time, message.Message) + Environment.NewLine;
+        AddLogMessage(strLog);
+      }
+    }
+
+    public void AddLogMessage(string message)
+    {
+      _log += message;
+
+      if (_selectedTab == ConfigTab.Log)
+        UpdateLog();
+    }
+
+    private void BClearLogClick(object sender, EventArgs e)
+    {
+      _log = string.Empty;
+      UpdateLog();
+    }
+
+    private void BSaveLogClick(object sender, EventArgs e)
+    {
+      SaveFileDialog dialog = new SaveFileDialog
+      {
+        Title = Resources.where_do_you_want_to_store_the_log,
+        InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
+        FileName = Resources.cec_log_filename,
+        Filter = Resources.cec_log_filter,
+        FilterIndex = 1
+      };
+
+      if (dialog.ShowDialog() == DialogResult.OK)
+      {
+        FileStream fs = (FileStream)dialog.OpenFile();
+        if (!fs.CanWrite)
+        {
+          MessageBox.Show(string.Format(Resources.cannot_open_for_writing, dialog.FileName), Resources.app_name, MessageBoxButtons.OK, MessageBoxIcon.Error);
+        }
+        else
+        {
+          StreamWriter writer = new StreamWriter(fs);
+          writer.Write(_log);
+          writer.Close();
+          fs.Close();
+          fs.Dispose();
+          MessageBox.Show(string.Format(Resources.log_stored_as, dialog.FileName), Resources.app_name, MessageBoxButtons.OK, MessageBoxIcon.Information);
+        }
+      }
+    }
+    #endregion
+
+    #region Tray icon and window controls
+    private void HideToolStripMenuItemClick(object sender, EventArgs e)
+    {
+      ShowHideToggle();
+    }
+
+    private void CloseToolStripMenuItemClick(object sender, EventArgs e)
+    {
+      Dispose();
+    }
+
+    private void AboutToolStripMenuItemClick(object sender, EventArgs e)
+    {
+      (new About(_controller.LibServerVersion, _controller.LibClientVersion, _controller.LibInfo)).ShowDialog();
+    }
+
+    private void AdvancedModeToolStripMenuItemClick(object sender, EventArgs e)
+    {
+      _controller.Settings.AdvancedMode.Value = !advancedModeToolStripMenuItem.Checked;
+      ShowHideAdvanced(!advancedModeToolStripMenuItem.Checked);
+    }
+
+    private void BCancelClick(object sender, EventArgs e)
+    {
+      Dispose();
+    }
+
+    private void TrayIconClick(object sender, EventArgs e)
+    {
+      if (e is MouseEventArgs && (e as MouseEventArgs).Button == MouseButtons.Left)
+        ShowHideToggle();
+    }
+
+    public void OnHide()
+    {
+      ShowInTaskbar = false;
+      Visible = false;
+      tsMenuShowHide.Text = Resources.show;
+    }
+
+    public void OnShow()
+    {
+      ShowInTaskbar = true;
+      WindowState = FormWindowState.Normal;
+      Activate();
+      tsMenuShowHide.Text = Resources.hide;
+    }
+
+    private void ShowHideToggle()
+    {
+      if (Visible && WindowState != FormWindowState.Minimized)
+      {
+        _controller.Settings.StartHidden.Value = true;
+        Hide();
+      }
+      else
+      {
+        _controller.Settings.StartHidden.Value = false;
+        Show();
+      }
+    }
+
+    private void TsMenuCloseClick(object sender, EventArgs e)
+    {
+      Dispose();
+    }
+
+    private void CECTrayResize(object sender, EventArgs e)
+    {
+      if (WindowState == FormWindowState.Minimized)
+        Hide();
+      else
+        Show();
+    }
+
+    private void TsMenuShowHideClick(object sender, EventArgs e)
+    {
+      ShowHideToggle();
+    }
+
+    public void ShowHideAdvanced(bool setTo)
+    {
+      if (setTo)
+      {
+        tsAdvanced.Checked = true;
+        advancedModeToolStripMenuItem.Checked = true;
+        SuspendLayout();
+        if (!tabPanel.Controls.Contains(tbTestCommands))
+          TabControls.Add(tbTestCommands);
+        if (!tabPanel.Controls.Contains(LogOutput))
+          TabControls.Add(LogOutput);
+        ResumeLayout();
+      }
+      else
+      {
+        tsAdvanced.Checked = false;
+        advancedModeToolStripMenuItem.Checked = false;
+        SuspendLayout();
+        tabPanel.Controls.Remove(tbTestCommands);
+        tabPanel.Controls.Remove(LogOutput);
+        ResumeLayout();
+      }
+    }
+
+    private void TsAdvancedClick(object sender, EventArgs e)
+    {
+      _controller.Settings.AdvancedMode.Value = !tsAdvanced.Checked;
+      ShowHideAdvanced(!tsAdvanced.Checked);
+    }
+
+    public void SetStatusText(string status)
+    {
+      SetControlText(lStatus, status);
+    }
+
+    public void SetProgressBar(int progress, bool visible)
+    {
+      SetControlVisible(pProgress, visible);
+      SetProgressValue(pProgress, progress);
+    }
+
+    public void SetControlsEnabled(bool val)
+    {
+      //main tab
+      SetControlEnabled(bClose, val);
+      SetControlEnabled(bSaveConfig, val);
+      SetControlEnabled(bReloadConfig, val);
+
+      //tester tab
+      SetControlEnabled(bRescanDevices, val);
+      SetControlEnabled(bSendImageViewOn, val);
+      SetControlEnabled(bStandby, val);
+      SetControlEnabled(bActivateSource, val);
+      SetControlEnabled(bScan, val);
+
+      bool enableVolumeButtons = (GetTargetDevice() == CecLogicalAddress.AudioSystem) && val;
+      SetControlEnabled(bVolUp, enableVolumeButtons);
+      SetControlEnabled(bVolDown, enableVolumeButtons);
+      SetControlEnabled(bMute, enableVolumeButtons);
+    }
+
+    private void TabControl1SelectedIndexChanged(object sender, EventArgs e)
+    {
+      switch (tabPanel.TabPages[tabPanel.SelectedIndex].Name)
+      {
+        case "tbTestCommands":
+          _selectedTab = ConfigTab.Tester;
+          break;
+        case "LogOutput":
+          _selectedTab = ConfigTab.Log;
+          UpdateLog();
+          break;
+        default:
+          _selectedTab = ConfigTab.Configuration;
+          break;
+      }
+    }
+    #endregion
+
+    #region Class members
+    private ConfigTab _selectedTab = ConfigTab.Configuration;
+    private string _log = string.Empty;
+    private readonly CECController _controller;
+    public CECController Controller
+    {
+      get { return _controller; }
+    }
+    public Control.ControlCollection TabControls
+    {
+      get { return tabPanel.Controls; }
+    }
+    public string SelectedTabName
+    {
+      get { return GetSelectedTabName(tabPanel, tabPanel.TabPages); }
+    }
+    #endregion
+
+    private void AddNewApplicationToolStripMenuItemClick(object sender, EventArgs e)
+    {
+      ConfigureApplication appConfig = new ConfigureApplication(_controller.Settings, _controller);
+      _controller.DisplayDialog(appConfig, false);
+    }
+  }
+}
similarity index 50%
rename from src/cec-config-gui/CecConfigGUI.resx
rename to src/LibCecTray/ui/CECTray.resx
index 2efbf9440b272f7b5f3b35b920eea33fca4cd3ad..39e72ff3d2b1468d90eea499640ebaeccab5c94d 100644 (file)
   <resheader name="writer">
     <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </resheader>
-  <metadata name="helpDeviceType.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
-    <value>524, 17</value>
-  </metadata>
   <metadata name="helpPortNumber.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
     <value>17, 17</value>
   </metadata>
-  <metadata name="helpPhysicalAddress.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
-    <value>362, 17</value>
-  </metadata>
   <metadata name="helpConnectedHDMIDevice.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
     <value>160, 17</value>
   </metadata>
-  <metadata name="CecButtonName.UserAddedColumn" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
-    <value>True</value>
+  <metadata name="helpPhysicalAddress.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>362, 17</value>
+  </metadata>
+  <metadata name="helpDeviceType.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>524, 17</value>
   </metadata>
-  <metadata name="cecButtonConfigBindingSource.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+  <metadata name="trayIcon.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
     <value>662, 17</value>
   </metadata>
+  <metadata name="trayIconMenu.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>757, 17</value>
+  </metadata>
   <assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+  <data name="trayIcon.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+    <value>
+        AAABAAYAEBAAAAAAIABoBAAAZgAAACAgAAAAACAAqBAAAM4EAAAwMAAAAAAgAKglAAB2FQAAQEAAAAAA
+        IAAoQgAAHjsAAICAAAAAACAAKAgBAEZ9AAAAAAAAAAAgACggBABuhQEAKAAAABAAAAAgAAAAAQAgAAAA
+        AABABAAAAAAAAAAAAAAAAAAAAAAAAP///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAABwAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAA
+        AAkAAAAJAAAACQAAAAkAAAAJAAAACQgICAf///8BAAAAWwAAAHUAAABtAAAAbQAAAG0AAABtAAAAbQAA
+        AG0AAABtAAAAbQAAAG0AAABtAAAAbQAAAG0BAQFzBAQEXQAAAHMAAAB7AAAAswAAAK0AAACpAAAARQAA
+        ALkAAACjAAAAqwAAAFkAAAAVAAAAkwAAAAcAAACh////AQMDA3EAAABzAAAAmwAAAGMAAAAZAAAAzQAA
+        AMUAAAAdAAAAuQAAANcAAACNAAAASwAAALkAAAAJAAAAy////wEDAwNxAAAAcwAAAJsAAACTAAAANwAA
+        AM0AAADLAAAAEQAAAD8AAACFAAAAtwAAAI0AAAC5AAAACQAAAMv///8BAwMDcQAAAHMAAACRAAAAvwAA
+        AKcAAADBAAAAVwAAAMMAAADHAAAAewAAAGkAAAAZAAAAxwAAALMAAADjAAAAbwMDA3EAAAB1AAAANQAA
+        ADEAAAAxAAAAMQAAADEAAAAxAAAAMQAAADEAAAAxAAAAMQAAADEAAAAxAAAAMQICAjMDAwN1AAAAbQAA
+        AF0AAABXAAAAVwAAAFcAAABXAAAAVwAAAFcAAABXAAAAVwAAAFcAAABXAAAAVwAAAFcBAQFbBAQEbwAA
+        AHMAAABDAAAAE////wEAAAA/AAAAXQAAAG8AAAB1AAAAVwAAAGsAAABZAAAAawAAAHcAAABXAAAAMwMD
+        A3EAAABzAAAASwAAAEsAAAAjAAAAX////wEAAAA3AAAAg////wEAAAALAAAAEwAAAHcAAABrAAAAE///
+        /wEDAwNxAAAAcwAAAEsAAAArAAAASwAAAIv///8BAAAANQAAAIX///8BAAAARQAAAE8AAAALAAAAdwAA
+        AEP///8BAwMDcQAAAHMAAAA/AAAAYQAAAGcAAABj////AQAAAC0AAABt////AQAAADkAAABZAAAAYwAA
+        AHEAAABXAAAAKwMDA3EAAABrAAAATQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAA
+        AEEAAABBAAAAQQEBAUsEBARt////AQAAAC0AAAAxAAAAMQAAADEAAAAxAAAAMQAAADEAAAAxAAAAMQAA
+        ADEAAAAxAAAAMQAAADECAgItHBwcA////wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA
+        //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//KAAAACAAAABAAAAAAQAgAAAAAACAEAAAAAAAAAAA
+        AAAAAAAAAAAAAP///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAACQAAABEAAAARAAAAEQAA
+        ABEAAAARAAAAEQAAABEAAAARAAAAEQAAABEAAAARAAAAEQAAABEAAAARAAAAEQAAABEAAAARAAAAEQAA
+        ABEAAAARAAAAEQAAABEAAAARAAAAEQAAABEAAAARICAgB////wH///8B////AQAAAGsAAADnAAAA1wAA
+        ANcAAADXAAAA1wAAANcAAADXAAAA1wAAANcAAADXAAAA1wAAANcAAADXAAAA1wAAANcAAADXAAAA1wAA
+        ANcAAADXAAAA1wAAANcAAADXAAAA1wAAANcAAADXAAAA1wAAANkCAgLlBQUFc////wEAAAAfAAAA3QAA
+        ABP///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////ARUVFQ0CAgLTDQ0NKwAA
+        AEEAAACnAAAAIQAAAJcAAACXAAAAlwAAAJcAAACXAAAAZQAAAJcAAAAFAAAAGwAAAI0AAAC3AAAAiQAA
+        AEsAAACJAAAAdwAAAIX///8B////AQAAACEAAACXAAAAQ////wEAAAALAAAAlwAAAFn///8B////AQUF
+        BZUAAABPAAAAQQAAAKUAAAA3AAAA/wAAAN0AAADDAAAAwwAAAMMAAACnAAAA/wAAABUAAADfAAAA+QAA
+        AKkAAADJAAAA8QAAAOUAAADJAAAA3////wH///8BAAAANQAAAP8AAABx////AQAAABEAAAD/AAAAlf//
+        /wH///8BBQUFkwAAAE8AAABBAAAApQAAADcAAAD/AAAAc////wH///8B////AQAAAJ0AAAD/AAAAcQAA
+        AP8AAABj////AQAAABUAAADZAAAA5QAAAMkAAADf////Af///wEAAAA1AAAA/wAAAHH///8BAAAAEQAA
+        AP8AAACV////Af///wEFBQWTAAAATwAAAEEAAAClAAAANwAAAP8AAACtAAAAaQAAAGH///8BAAAAnQAA
+        AP8AAACjAAAA/wAAABP///8BAAAA9QAAAP8AAADlAAAAyQAAAO0AAABpAAAAaQAAAIkAAAD/AAAAcf//
+        /wEAAAARAAAA/wAAAJX///8B////AQUFBZMAAABPAAAAQQAAAKUAAAA3AAAA/wAAAPMAAADnAAAA1///
+        /wEAAACdAAAA/wAAAKkAAAD/AAAACf///wEAAAApAAAAKwAAACcAAADJAAAA/wAAAPsAAAD7AAAA+wAA
+        AP8AAABx////AQAAABEAAAD/AAAAlf///wH///8BBQUFkwAAAE8AAABBAAAApQAAADcAAAD/AAAAc///
+        /wH///8B////AQAAAJ0AAAD/AAAAgQAAAP8AAAA7////AQAAAAMAAACjAAAAWwAAAMkAAADhAAAAAwAA
+        AAMAAAA3AAAA/wAAAHH///8BAAAAEQAAAP8AAACV////Af///wEFBQWTAAAATwAAAEEAAAClAAAANwAA
+        AP8AAAC7AAAAgwAAAIMAAABzAAAAnQAAAP8AAAAjAAAA8wAAANsAAABnAAAAoQAAAP8AAABtAAAAyQAA
+        AN////8B////AQAAADUAAAD/AAAAlwAAAIMAAACLAAAA/wAAAMsAAACDAAAAIQUFBZMAAABPAAAAQQAA
+        AKUAAAAxAAAA4QAAAOEAAADhAAAA4QAAAMUAAACJAAAA4QAAAAcAAAA7AAAAywAAAPsAAADvAAAAjQAA
+        AAMAAACxAAAAxf///wH///8BAAAALwAAAOEAAACjAAAA4QAAAOEAAADhAAAA4QAAAOEAAAA3BQUFkwAA
+        AE8AAAA9AAAAr////wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAA///
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEEBASdAgICSwAAAAsAAADdAAAAdQAAAF8AAABfAAAAXwAAAF8AAABfAAAAXwAAAF8AAABfAAAAXwAA
+        AF8AAABfAAAAXwAAAF8AAABfAAAAXwAAAF8AAABfAAAAXwAAAF8AAABfAAAAXwAAAF8AAABfAAAAXwAA
+        AF8AAABfAwMDawICAt0VFRUR////AQAAALcAAADFAAAArwAAAK8AAACvAAAArwAAAK8AAACvAAAArwAA
+        AK8AAACvAAAArwAAAK8AAACvAAAArwAAAK8AAACvAAAArwAAAK8AAACvAAAArwAAAK8AAACvAAAArwAA
+        AK8AAACvAAAArwAAAK8CAgK7AgICwTU1NQMAAAAxAAAAyf///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEDAwO3BwcHPwAAAEEAAACl////AQAAAHEAAAAf////Af//
+        /wH///8B////AQAAADEAAACxAAAAqQAAALEAAABJAAAARQAAALsAAACtAAAArQAAAK0AAAA1AAAAqwAA
+        AKcAAACpAAAAQwAAAGEAAACxAAAArQAAAK0AAACtAAAAHwUFBZMAAABPAAAAQQAAAKX///8BAAAAlQAA
+        ACf///8B////Af///wEAAAADAAAAxwAAABf///8BAAAABwAAALsAAABpAAAAZf///wH///8BAAAACwAA
+        AL8AAAAV////AQAAAAcAAAC7AAAAiwAAAD3///8B////Af///wH///8BBQUFkwAAAE8AAABBAAAApf//
+        /wEAAACVAAAAJ////wH///8B////AQAAAB8AAACh////Af///wH///8BAAAAcwAAAJ8AAABl////Af//
+        /wEAAAAHAAAAIf///wH///8B////AQAAAK8AAACVAAAAPf///wH///8B////Af///wEFBQWTAAAATwAA
+        AEEAAACl////AQAAAJUAAACLAAAAdwAAAGkAAAAjAAAAIwAAAJn///8B////Af///wEAAABrAAAAowAA
+        AGX///8B////Af///wH///8BAAAABQAAAEMAAACnAAAAhQAAAH8AAABZAAAAJQAAACUAAAAD////AQUF
+        BZMAAABPAAAAQQAAAKX///8BAAAAlQAAAE8AAAAvAAAAPwAAAK8AAABXAAAAmf///wH///8B////AQAA
+        AGsAAACjAAAAZf///wH///8B////AQAAAEsAAAC/AAAAdwAAACH///8BAAAAfwAAAKEAAACDAAAAgwAA
+        AAX///8BBQUFkwAAAE8AAABBAAAApf///wEAAACVAAAAJ////wH///8BAAAAOwAAAKMAAACZ////Af//
+        /wH///8BAAAAawAAAKMAAABl////Af///wH///8BAAAAwwAAAAn///8B////AQAAAAsAAAB/AAAAPf//
+        /wH///8B////Af///wEFBQWTAAAATwAAAEEAAACl////AQAAAJUAAAAn////AQAAAAkAAACNAAAAeQAA
+        AJn///8B////Af///wEAAABrAAAAowAAAGX///8B////Af///wEAAAC7AAAAE////wEAAAArAAAAqwAA
+        AH8AAAA9////Af///wH///8B////AQUFBZMAAABPAAAAQQAAAKX///8BAAAAaQAAAK0AAACrAAAApQAA
+        AF8AAAAXAAAAY////wH///8B////AQAAAEcAAABrAAAAQ////wH///8B////AQAAACsAAAClAAAAqQAA
+        AJsAAAAXAAAAWQAAAK8AAACvAAAArwAAAKn///8BBQUFkwAAAE8AAAAzAAAAw////wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEEBASvBgYGQQAAAAMAAAC3AAAAsQAA
+        AIEAAACBAAAAgQAAAIEAAACBAAAAgQAAAIEAAACBAAAAgQAAAIEAAACBAAAAgQAAAIEAAACBAAAAgQAA
+        AIEAAACBAAAAgQAAAIEAAACBAAAAgQAAAIEAAACBAAAAgQAAAIEAAACDAgICpwICAsEpKSkF////AQAA
+        AAUAAABPAAAAYQAAAGEAAABhAAAAYQAAAGEAAABhAAAAYQAAAGEAAABhAAAAYQAAAGEAAABhAAAAYQAA
+        AGEAAABhAAAAYQAAAGEAAABhAAAAYQAAAGEAAABhAAAAYQAAAGEAAABhAAAAYQAAAGEFBQVPHBwcB///
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgAAAAwAAAAYAAAAAEAIAAAAAAAgCUAAAAA
+        AAAAAAAAAAAAAAAAAAD///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAAAFAAAAGQAAABkAAAAZAAAAGQAAABkAAAAZAAAAGQAA
+        ABkAAAAZAAAAGQAAABkAAAAZAAAAGQAAABkAAAAZAAAAGQAAABkAAAAZAAAAGQAAABkAAAAZAAAAGQAA
+        ABkAAAAZAAAAGQAAABkAAAAZAAAAGQAAABkAAAAZAAAAGQAAABkAAAAZAAAAGQAAABkAAAAZAAAAGQAA
+        ABkAAAAZBQUFF4GBgQP///8B////Af///wH///8B////AQAAAF0AAADlAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wMDA+kICAhp////Af///wH///8BAAAATwAAAP0AAAClAAAASwAA
+        AEUAAABFAAAARQAAAEUAAABFAAAARQAAAEUAAABFAAAARQAAAEUAAABFAAAARQAAAEUAAABFAAAARQAA
+        AEUAAABFAAAARQAAAEUAAABFAAAARQAAAEUAAABFAAAARQAAAEUAAABFAAAARQAAAEUAAABFAAAARQAA
+        AEUAAABFAAAARQAAAEUAAABFAAAARQAAAEUAAABFAQEBSQcHB5EAAAD9CQkJYf///wH///8BAAAAwwAA
+        ALn///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEGBgadBAQE1///
+        /wH///8BAAAA3wAAAHv///8BAAAAUQAAAGMAAABjAAAAYwAAAGMAAABjAAAAYwAAAGMAAAAzAAAAYwAA
+        AGMAAAAF////Af///wEAAABDAAAAhQAAAJUAAABrAAAADQAAAD8AAABjAAAANQAAAGMAAABjAAAAIf//
+        /wH///8B////AQAAAB8AAABjAAAAYwAAABH///8B////AQAAAAsAAABjAAAAYwAAACf///8B////Af//
+        /wELCwthAAAA9f///wH///8BAAAA3wAAAHf///8BAAAA0QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAACBAAAA/wAAAP8AAAALAAAACwAAALMAAAD/AAAA/wAAAP8AAAD/AAAA1QAAALMAAAD/AAAAhwAA
+        AP8AAAD/AAAAUf///wH///8B////AQAAAFEAAAD/AAAA/wAAACv///8B////AQAAABsAAAD/AAAA/wAA
+        AGH///8B////Af///wEMDAxdAAAA9f///wH///8BAAAA3wAAAHf///8BAAAA0QAAAP8AAADhAAAApQAA
+        AKUAAAClAAAApQAAAKUAAAB5AAAA/wAAAP8AAAALAAAAlQAAAP8AAAD/AAAAvQAAAG8AAACPAAAA9wAA
+        AP0AAAD/AAAAhwAAAP8AAAD/AAAAUf///wH///8B////AQAAAFEAAAD/AAAA/wAAACv///8B////AQAA
+        ABsAAAD/AAAA/wAAAGH///8B////Af///wEMDAxdAAAA9f///wH///8BAAAA3wAAAHf///8BAAAA0QAA
+        AP8AAACt////Af///wH///8B////Af///wEAAABrAAAA/wAAAP8AAAAfAAAA+QAAAP8AAACzAAAAA///
+        /wH///8BAAAAXQAAAP8AAAD/AAAAhwAAAP8AAAD/AAAAUf///wH///8B////AQAAAFEAAAD/AAAA/wAA
+        ACv///8B////AQAAABsAAAD/AAAA/wAAAGH///8B////Af///wEMDAxdAAAA9f///wH///8BAAAA3wAA
+        AHf///8BAAAA0QAAAP8AAACt////Af///wH///8B////Af///wEAAABrAAAA/wAAAP8AAABbAAAA/wAA
+        AP8AAABB////Af///wEAAACTAAAAoQAAAP8AAAD/AAAAhwAAAP8AAAD/AAAAUf///wH///8B////AQAA
+        AFEAAAD/AAAA/wAAACv///8B////AQAAABsAAAD/AAAA/wAAAGH///8B////Af///wEMDAxdAAAA9f//
+        /wH///8BAAAA3wAAAHf///8BAAAA0QAAAP8AAADfAAAAnQAAAJ0AAACdAAAAPf///wEAAABrAAAA/wAA
+        AP8AAAB7AAAA/wAAAP8AAAAR////Af///wEAAADxAAAA/wAAAP8AAAD/AAAAhwAAAP8AAAD/AAAAvQAA
+        AJ0AAACdAAAAnQAAAL0AAAD/AAAA/wAAACv///8B////AQAAABsAAAD/AAAA/wAAAGH///8B////Af//
+        /wEMDAxdAAAA9f///wH///8BAAAA3wAAAHf///8BAAAA0QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAY///
+        /wEAAABrAAAA/wAAAP8AAACBAAAA/wAAAP8AAAAJ////Af///wEAAAA9AAAAPwAAAD8AAAA/AAAARQAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAACv///8B////AQAAABsAAAD/AAAA/wAA
+        AGH///8B////Af///wEMDAxdAAAA9f///wH///8BAAAA3wAAAHf///8BAAAA0QAAAP8AAADLAAAAXQAA
+        AF0AAABdAAAAJf///wEAAABrAAAA/wAAAP8AAABtAAAA/wAAAP8AAAAh////Af///wH///8BAAAACQAA
+        AA////8BAAAALwAAAP8AAAD/AAAApQAAAH0AAAB9AAAAfQAAAKUAAAD/AAAA/wAAACv///8B////AQAA
+        ABsAAAD/AAAA/wAAAGH///8B////Af///wEMDAxdAAAA9f///wH///8BAAAA3wAAAHf///8BAAAA0QAA
+        AP8AAACt////Af///wH///8B////Af///wEAAABrAAAA/wAAAP8AAAA1AAAA/wAAAP8AAABx////Af//
+        /wH///8BAAAAZQAAAPkAAAC/AAAAOwAAAP8AAAD/AAAAUf///wH///8B////AQAAAFEAAAD/AAAA/wAA
+        ACv///8B////AQAAABsAAAD/AAAA/wAAAGH///8B////Af///wEMDAxdAAAA9f///wH///8BAAAA3wAA
+        AHf///8BAAAA0QAAAP8AAADDAAAARQAAAEUAAABFAAAARQAAADcAAABrAAAA/wAAAP8AAAALAAAAwQAA
+        AP8AAADzAAAAVwAAABEAAABBAAAA6QAAAP8AAADFAAAALwAAAP8AAAD/AAAAUf///wH///8B////AQAA
+        AFEAAAD/AAAA/wAAAEcAAABFAAAARQAAAFcAAAD/AAAA/wAAAIsAAABFAAAAO////wEMDAxdAAAA9f//
+        /wH///8BAAAA3wAAAHf///8BAAAA0QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAM8AAABrAAAA/wAA
+        AP8AAAALAAAAJQAAAOcAAAD/AAAA/wAAAP0AAAD/AAAA/wAAAPcAAAA1AAAALwAAAP8AAAD/AAAAUf//
+        /wH///8B////AQAAAFEAAAD/AAAA/wAAAJcAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA3f//
+        /wEMDAxdAAAA9f///wH///8BAAAA3wAAAHf///8BAAAAqwAAANEAAADRAAAA0QAAANEAAADRAAAA0QAA
+        AKsAAABZAAAA0QAAANEAAAAJ////AQAAAB0AAACbAAAA6QAAAP0AAADzAAAAtwAAADX///8BAAAAJwAA
+        ANEAAADRAAAAQ////wH///8B////AQAAAEEAAADRAAAA0QAAAHsAAADRAAAA0QAAANEAAADRAAAA0QAA
+        ANEAAADRAAAAtf///wEMDAxdAAAA9f///wH///8BAAAA3wAAAHn///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAAf///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEMDAxfAAAA9f///wH///8BAAAAvQAAAMMAAAAD////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEGBgapBAQE0f///wH///8BAAAAQwAA
+        APsAAAC7AAAAjwAAAI8AAACPAAAAjwAAAI8AAACPAAAAjwAAAI8AAACPAAAAjwAAAI8AAACPAAAAjwAA
+        AI8AAACPAAAAjwAAAI8AAACPAAAAjwAAAI8AAACPAAAAjwAAAI8AAACPAAAAjwAAAI8AAACPAAAAjwAA
+        AI8AAACPAAAAjwAAAI8AAACPAAAAjwAAAI8AAACPAAAAjwAAAI8AAACPAAAAjwQEBKsAAAD9CgoKU///
+        /wH///8BAAAADQAAANcAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/QAA
+        AP0CAgLjFBQUFf///wH///8BAAAAjQAAAPEAAAA7AAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAA
+        AAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAA
+        AAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAA
+        AAkAAAAJBgYGCRMTEykBAQHlBQUFn////wH///8BAAAA1wAAAJH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEJCQl1AgIC6////wH///8BAAAA3wAAAHf///8B////AQAA
+        AJEAAAAn////Af///wH///8B////Af///wH///8B////AQAAABUAAACRAAAA1wAAAOcAAADLAAAAcQAA
+        AAUAAAAFAAAAtQAAALkAAAC5AAAAuQAAALkAAAC5AAAAaQAAABEAAACBAAAAxwAAANcAAAC3AAAAYQAA
+        AAMAAAApAAAApQAAAKUAAAClAAAApQAAAKUAAAClAAAAf////wEMDAxdAAAA9f///wH///8BAAAA3wAA
+        AHf///8B////AQAAAN8AAAA7////Af///wH///8B////Af///wH///8BAAAADQAAANcAAACnAAAALwAA
+        ABUAAAA9AAAAxwAAAKEAAAAFAAAA+QAAAFsAAABJAAAASQAAAEkAAABJAAAAPQAAANcAAAClAAAAOwAA
+        ACMAAABHAAAAxQAAAJkAAAA/AAAA5wAAAF8AAABfAAAAXwAAAF8AAABfAAAASf///wEMDAxdAAAA9f//
+        /wH///8BAAAA3wAAAHf///8B////AQAAAN8AAAA7////Af///wH///8B////Af///wH///8BAAAAbwAA
+        AMkAAAAD////Af///wH///8BAAAAEwAAAO8AAAA1AAAA+QAAABn///8B////Af///wH///8BAAAAkQAA
+        AKX///8B////Af///wH///8BAAAAEQAAAPUAAABbAAAA2f///wH///8B////Af///wH///8B////Af//
+        /wEMDAxdAAAA9f///wH///8BAAAA3wAAAHf///8B////AQAAAN8AAAA7////Af///wH///8B////Af//
+        /wH///8BAAAAqQAAAHf///8B////Af///wH///8B////AQAAALEAAABxAAAA+QAAABn///8B////Af//
+        /wH///8BAAAAOQAAAB////8B////Af///wH///8BAAAAAwAAAO0AAABtAAAA2f///wH///8B////Af//
+        /wH///8B////Af///wEMDAxdAAAA9f///wH///8BAAAA3wAAAHf///8B////AQAAAN8AAAA7////Af//
+        /wH///8B////Af///wH///8BAAAAswAAAGX///8B////Af///wH///8B////AQAAAKEAAAB9AAAA+QAA
+        ABn///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAAFAAAAfQAAAOMAAABFAAAA2f//
+        /wH///8B////Af///wH///8B////Af///wEMDAxdAAAA9f///wH///8BAAAA3wAAAHf///8B////AQAA
+        AN8AAADDAAAAsQAAALEAAACnAAAAeQAAABv///8BAAAAswAAAGX///8B////Af///wH///8B////AQAA
+        AKEAAAB9AAAA+QAAABn///8B////Af///wH///8B////Af///wH///8BAAAAJwAAAHsAAADZAAAA0QAA
+        AC8AAAA/AAAA4QAAADcAAAA3AAAANwAAADcAAAAD////Af///wEMDAxdAAAA9f///wH///8BAAAA3wAA
+        AHf///8B////AQAAAN8AAABxAAAARwAAAEcAAABTAAAAjwAAAOcAAAAtAAAAswAAAGX///8B////Af//
+        /wH///8B////AQAAAKEAAAB9AAAA+QAAABn///8B////Af///wH///8B////AQAAADMAAADBAAAA7QAA
+        AJ0AAABHAAAAA////wEAAAA/AAAA9wAAAMUAAADFAAAAxQAAAMUAAAAJ////Af///wEMDAxdAAAA9f//
+        /wH///8BAAAA3wAAAHf///8B////AQAAAN8AAAA7////Af///wH///8B////AQAAAIEAAAClAAAAswAA
+        AGX///8B////Af///wH///8B////AQAAAKEAAAB9AAAA+QAAABn///8B////Af///wH///8BAAAAIQAA
+        AO8AAAB1AAAAC////wH///8B////Af///wEAAAA/AAAA2f///wH///8B////Af///wH///8B////Af//
+        /wEMDAxdAAAA9f///wH///8BAAAA3wAAAHf///8B////AQAAAN8AAAA7////Af///wH///8B////AQAA
+        AFMAAADFAAAAswAAAGX///8B////Af///wH///8B////AQAAAKEAAAB9AAAA+QAAABn///8B////Af//
+        /wH///8BAAAAaQAAALX///8B////Af///wH///8BAAAABwAAABEAAAA/AAAA2f///wH///8B////Af//
+        /wH///8B////Af///wEMDAxdAAAA9f///wH///8BAAAA3wAAAHf///8B////AQAAAN8AAAA7////Af//
+        /wH///8B////AQAAAJUAAAChAAAAswAAAGX///8B////Af///wH///8B////AQAAAKEAAAB9AAAA+QAA
+        ABn///8B////Af///wH///8BAAAAWwAAAMP///8B////Af///wH///8BAAAAcQAAALcAAAA/AAAA2f//
+        /wH///8B////Af///wH///8B////Af///wEMDAxdAAAA9f///wH///8BAAAA3wAAAHf///8B////AQAA
+        AN8AAACTAAAAcwAAAHMAAAB9AAAAuQAAAOEAAAAlAAAAswAAAGX///8B////Af///wH///8B////AQAA
+        AKEAAAB9AAAA+QAAABn///8B////Af///wH///8BAAAACwAAAM8AAAChAAAARwAAAEMAAACLAAAA6wAA
+        AC8AAAA/AAAA6wAAAHkAAAB5AAAAeQAAAHkAAAB5AAAAN////wEMDAxdAAAA9f///wH///8BAAAA3wAA
+        AHf///8B////AQAAAH0AAACPAAAAjwAAAI8AAACFAAAAWwAAAA3///8BAAAAVwAAADH///8B////Af//
+        /wH///8B////AQAAAE0AAAA7AAAAdwAAAA3///8B////Af///wH///8B////AQAAAA8AAAB5AAAAuQAA
+        AL0AAACLAAAAIf///wEAAAAjAAAAjwAAAI8AAACPAAAAjwAAAI8AAACPAAAAQf///wEMDAxdAAAA9f//
+        /wH///8BAAAA2QAAAIn///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEKCgptAQEB7////wH///8BAAAAlQAAAO0AAAAr////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////ARQUFB0CAgLdBQUFp////wH///8BAAAAEwAAANEAAAD5AAAAyQAAAMMAAADDAAAAwwAA
+        AMMAAADDAAAAwwAAAMMAAADDAAAAwwAAAMMAAADDAAAAwwAAAMMAAADDAAAAwwAAAMMAAADDAAAAwwAA
+        AMMAAADDAAAAwwAAAMMAAADDAAAAwwAAAMMAAADDAAAAwwAAAMMAAADDAAAAwwAAAMMAAADDAAAAwwAA
+        AMMAAADDAAAAwwAAAMMAAADDAAAAyQEBAfUCAgLbEhISG////wH///8B////AQAAAAkAAABpAAAAjwAA
+        AI8AAACPAAAAjwAAAI8AAACPAAAAjwAAAI8AAACPAAAAjwAAAI8AAACPAAAAjwAAAI8AAACPAAAAjwAA
+        AI8AAACPAAAAjwAAAI8AAACPAAAAjwAAAI8AAACPAAAAjwAAAI8AAACPAAAAjwAAAI8AAACPAAAAjwAA
+        AI8AAACPAAAAjwAAAI8AAACPAAAAjwAAAI8AAACPAAAAjwkJCWscHBwN////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAAAAAD//wAA
+        AAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA
+        //8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAA
+        AAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA
+        //8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAA
+        AAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA
+        //8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAA
+        AAAAAP//AAAAAAAA//8oAAAAQAAAAIAAAAABACAAAAAAAABCAAAAAAAAAAAAAAAAAAAAAAAA////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAAHQAAACEAAAAhAAAAIQAAACEAAAAhAAAAIQAAACEAAAAhAAAAIQAAACEAAAAhAAAAIQAA
+        ACEAAAAhAAAAIQAAACEAAAAhAAAAIQAAACEAAAAhAAAAIQAAACEAAAAhAAAAIQAAACEAAAAhAAAAIQAA
+        ACEAAAAhAAAAIQAAACEAAAAhAAAAIQAAACEAAAAhAAAAIQAAACEAAAAhAAAAIQAAACEAAAAhAAAAIQAA
+        ACEAAAAhAAAAIQAAACEAAAAhAAAAIQAAACEAAAAhAAAAIQAAACEdHR0X////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAABLAAAA0QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wUF
+        BdcNDQ1Z////Af///wH///8B////Af///wEAAABfAAAA/QAAAP8AAADLAAAAsQAAALEAAACxAAAAsQAA
+        ALEAAACxAAAAsQAAALEAAACxAAAAsQAAALEAAACxAAAAsQAAALEAAACxAAAAsQAAALEAAACxAAAAsQAA
+        ALEAAACxAAAAsQAAALEAAACxAAAAsQAAALEAAACxAAAAsQAAALEAAACxAAAAsQAAALEAAACxAAAAsQAA
+        ALEAAACxAAAAsQAAALEAAACxAAAAsQAAALEAAACxAAAAsQAAALEAAACxAAAAsQAAALEAAACxAAAAsQAA
+        ALEAAACxAAAAswMDA8EBAQH7AAAA/wsLC3f///8B////Af///wEAAAAXAAAA8wAAAPcAAABL////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BFRUVMQICAukAAAD7GRkZKf///wH///8BAAAAZwAA
+        AP8AAACL////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEMDAxlAAAA/wkJ
+        CYH///8B////AQAAAH8AAAD/AAAAUf///wEAAAAVAAAALwAAAC8AAAAvAAAALwAAAC8AAAAvAAAALwAA
+        AC8AAAAvAAAALwAAABEAAAAvAAAALwAAAC8AAAAD////Af///wH///8BAAAACQAAAEUAAABrAAAAbwAA
+        AEkAAAAF////AQAAACkAAAAvAAAAJwAAABsAAAAvAAAALwAAACX///8B////Af///wH///8B////AQAA
+        ABUAAAAvAAAALwAAACv///8B////Af///wH///8BAAAABwAAAC8AAAAvAAAALwAAAAn///8B////Af//
+        /wH///8BIiIiLQAAAP8AAACb////Af///wEAAAB/AAAA/wAAAEn///8BAAAAbQAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABXAAAA/wAAAP8AAAD/AAAADf///wH///8BAAAAZwAA
+        AOsAAAD/AAAA/wAAAP8AAAD/AAAA2QAAAC0AAADXAAAA/wAAAMsAAACTAAAA/wAAAP8AAADB////Af//
+        /wH///8B////Af///wEAAABrAAAA/wAAAP8AAADj////Af///wH///8B////AQAAACMAAAD/AAAA/wAA
+        AP8AAAAt////Af///wH///8B////ASgoKCcAAAD/AAAAm////wH///8BAAAAfwAAAP8AAABJ////AQAA
+        AG0AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAVwAAAP8AAAD/AAAA/wAA
+        AA3///8BAAAAgwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADjAAAA4QAAAP8AAADLAAAAkwAA
+        AP8AAAD/AAAAwf///wH///8B////Af///wH///8BAAAAawAAAP8AAAD/AAAA4////wH///8B////Af//
+        /wEAAAAjAAAA/wAAAP8AAAD/AAAALf///wH///8B////Af///wEoKCgnAAAA/wAAAJv///8B////AQAA
+        AH8AAAD/AAAASf///wEAAABtAAAA/wAAAP8AAADzAAAAhwAAAIcAAACHAAAAhwAAAIcAAACHAAAAhwAA
+        AEkAAAD/AAAA/wAAAP8AAAANAAAAOQAAAP0AAAD/AAAA/wAAAOUAAABrAAAAOwAAAFcAAADPAAAA/wAA
+        AP8AAAD/AAAAywAAAJMAAAD/AAAA/wAAAMH///8B////Af///wH///8B////AQAAAGsAAAD/AAAA/wAA
+        AOP///8B////Af///wH///8BAAAAIwAAAP8AAAD/AAAA/wAAAC3///8B////Af///wH///8BKCgoJwAA
+        AP8AAACb////Af///wEAAAB/AAAA/wAAAEn///8BAAAAbQAAAP8AAAD/AAAA5////wH///8B////Af//
+        /wH///8B////Af///wEAAAA7AAAA/wAAAP8AAAD/AAAADQAAAK0AAAD/AAAA/wAAAO0AAAAh////Af//
+        /wH///8BAAAADQAAANsAAAD/AAAA/wAAAMsAAACTAAAA/wAAAP8AAADB////Af///wH///8B////Af//
+        /wEAAABrAAAA/wAAAP8AAADj////Af///wH///8B////AQAAACMAAAD/AAAA/wAAAP8AAAAt////Af//
+        /wH///8B////ASgoKCcAAAD/AAAAm////wH///8BAAAAfwAAAP8AAABJ////AQAAAG0AAAD/AAAA/wAA
+        AOf///8B////Af///wH///8B////Af///wH///8BAAAAOwAAAP8AAAD/AAAA/wAAABMAAAD1AAAA/wAA
+        AP8AAAB/////Af///wH///8BAAAAIwAAACUAAACJAAAA/wAAAP8AAADLAAAAkwAAAP8AAAD/AAAAwf//
+        /wH///8B////Af///wH///8BAAAAawAAAP8AAAD/AAAA4////wH///8B////Af///wEAAAAjAAAA/wAA
+        AP8AAAD/AAAALf///wH///8B////Af///wEoKCgnAAAA/wAAAJv///8B////AQAAAH8AAAD/AAAASf//
+        /wEAAABtAAAA/wAAAP8AAADn////Af///wH///8B////Af///wH///8B////AQAAADsAAAD/AAAA/wAA
+        AP8AAAA7AAAA/wAAAP8AAAD/AAAANf///wH///8B////AQAAAO0AAAD/AAAA/wAAAP8AAAD/AAAAywAA
+        AJMAAAD/AAAA/wAAAMH///8B////Af///wH///8B////AQAAAGsAAAD/AAAA/wAAAOP///8B////Af//
+        /wH///8BAAAAIwAAAP8AAAD/AAAA/wAAAC3///8B////Af///wH///8BKCgoJwAAAP8AAACb////Af//
+        /wEAAAB/AAAA/wAAAEn///8BAAAAbQAAAP8AAAD/AAAA+wAAANMAAADTAAAA0wAAANMAAACz////Af//
+        /wEAAAA7AAAA/wAAAP8AAAD/AAAAUwAAAP8AAAD/AAAA/wAAABH///8B////Af///wEAAADtAAAA/wAA
+        AP8AAAD/AAAA/wAAAMsAAACTAAAA/wAAAP8AAADzAAAA0wAAANMAAADTAAAA0wAAANMAAADlAAAA/wAA
+        AP8AAADj////Af///wH///8B////AQAAACMAAAD/AAAA/wAAAP8AAAAt////Af///wH///8B////ASgo
+        KCcAAAD/AAAAm////wH///8BAAAAfwAAAP8AAABJ////AQAAAG0AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA2f///wH///8BAAAAOwAAAP8AAAD/AAAA/wAAAFkAAAD/AAAA/wAAAP8AAAAL////Af//
+        /wH///8BAAAATwAAAFUAAABVAAAAVQAAAFUAAABDAAAAkwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA4////wH///8B////Af///wEAAAAjAAAA/wAAAP8AAAD/AAAALf//
+        /wH///8B////Af///wEoKCgnAAAA/wAAAJv///8B////AQAAAH8AAAD/AAAASf///wEAAABtAAAA/wAA
+        AP8AAAD7AAAA0QAAANEAAADRAAAA0QAAALH///8B////AQAAADsAAAD/AAAA/wAAAP8AAABLAAAA/wAA
+        AP8AAAD/AAAAF////wH///8B////Af///wH///8B////Af///wH///8B////AQAAAJMAAAD/AAAA/wAA
+        AP0AAAD3AAAA9wAAAPcAAAD3AAAA9wAAAPsAAAD/AAAA/wAAAOP///8B////Af///wH///8BAAAAIwAA
+        AP8AAAD/AAAA/wAAAC3///8B////Af///wH///8BKCgoJwAAAP8AAACb////Af///wEAAAB/AAAA/wAA
+        AEn///8BAAAAbQAAAP8AAAD/AAAA5////wH///8B////Af///wH///8B////Af///wEAAAA7AAAA/wAA
+        AP8AAAD/AAAAJwAAAP8AAAD/AAAA/wAAAEf///8B////Af///wH///8B////AQAAAFMAAABTAAAAEf//
+        /wEAAACTAAAA/wAAAP8AAADBAAAABQAAAAUAAAAFAAAABQAAAAUAAABtAAAA/wAAAP8AAADj////Af//
+        /wH///8B////AQAAACMAAAD/AAAA/wAAAP8AAAAt////Af///wH///8B////ASgoKCcAAAD/AAAAm///
+        /wH///8BAAAAfwAAAP8AAABJ////AQAAAG0AAAD/AAAA/wAAAOf///8B////Af///wH///8B////Af//
+        /wH///8BAAAAOwAAAP8AAAD/AAAA/wAAAA0AAADVAAAA/wAAAP8AAACn////Af///wH///8B////AQAA
+        AAkAAADlAAAA/wAAAPsAAABdAAAAkwAAAP8AAAD/AAAAwf///wH///8B////Af///wH///8BAAAAawAA
+        AP8AAAD/AAAA4////wH///8B////Af///wEAAAAjAAAA/wAAAP8AAAD/AAAALf///wH///8B////Af//
+        /wEoKCgnAAAA/wAAAJv///8B////AQAAAH8AAAD/AAAASf///wEAAABtAAAA/wAAAP8AAADnAAAABwAA
+        AAcAAAAHAAAABwAAAAcAAAAHAAAABQAAADsAAAD/AAAA/wAAAP8AAAANAAAAbwAAAP8AAAD/AAAA/wAA
+        AHMAAAAD////AQAAAAUAAACbAAAA/wAAAP8AAAD7AAAAHwAAAJMAAAD/AAAA/wAAAMH///8B////Af//
+        /wH///8B////AQAAAGsAAAD/AAAA/wAAAOMAAAAFAAAABwAAAAcAAAAHAAAAKQAAAP8AAAD/AAAA/wAA
+        ADEAAAAHAAAABwAAAAX///8BKCgoJwAAAP8AAACb////Af///wEAAAB/AAAA/wAAAEn///8BAAAAbQAA
+        AP8AAAD/AAAA/wAAAP0AAAD9AAAA/QAAAP0AAAD9AAAA/QAAAL8AAAA7AAAA/wAAAP8AAAD/AAAADQAA
+        AAcAAADNAAAA/wAAAP8AAAD/AAAA4QAAALkAAADjAAAA/wAAAP8AAAD/AAAAl////wEAAACTAAAA/wAA
+        AP8AAADB////Af///wH///8B////Af///wEAAABrAAAA/wAAAP8AAADjAAAAjwAAAP0AAAD9AAAA/QAA
+        AP0AAAD/AAAA/wAAAP8AAAD9AAAA/QAAAP0AAAB7////ASgoKCcAAAD/AAAAm////wH///8BAAAAfwAA
+        AP8AAABJ////AQAAAG0AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAC/AAAAOwAA
+        AP8AAAD/AAAA/wAAAA3///8BAAAAGQAAAM0AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAwQAA
+        AAv///8BAAAAkwAAAP8AAAD/AAAAwf///wH///8B////Af///wH///8BAAAAawAAAP8AAAD/AAAA4wAA
+        AI8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAe////wEoKCgnAAAA/wAA
+        AJv///8B////AQAAAH8AAAD/AAAASf///wEAAABTAAAAwQAAAMEAAADBAAAAwQAAAMEAAADBAAAAwQAA
+        AMEAAADBAAAAkQAAAC0AAADBAAAAwQAAAMEAAAAL////Af///wEAAAAHAAAAaQAAAMUAAAD1AAAA/QAA
+        APcAAADJAAAAawAAAAX///8B////AQAAAG8AAADBAAAAwQAAAJP///8B////Af///wH///8B////AQAA
+        AFEAAADBAAAAwQAAAK0AAABtAAAAwQAAAMEAAADBAAAAwQAAAMEAAADBAAAAwQAAAMEAAADBAAAAwQAA
+        AF////8BKCgoJwAAAP8AAACb////Af///wEAAAB/AAAA/wAAAEv///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAAAwAAAAsAAAAD////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AScnJykAAAD/AAAAm////wH///8BAAAAcwAAAP8AAABx////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wETExNLAAAA/wUFBY3///8B////AQAA
+        ACkAAAD9AAAA5wAAACH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEjIyMRBAQE0QAA
+        AP8VFRVB////Af///wH///8BAAAAjQAAAP8AAADvAAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAA
+        AL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAA
+        AL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAA
+        AL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAA
+        AL8CAgK5AgIC4wAAAP8HBwel////Af///wH///8B////AQAAAB0AAADzAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8BAQH7GBgYL////wH///8B////AQAAAAMAAADJAAAA/wAA
+        ALcAAABfAAAAXwAAAF8AAABfAAAAXwAAAF8AAABfAAAAXwAAAF8AAABfAAAAXwAAAF8AAABfAAAAXwAA
+        AF8AAABfAAAAXwAAAF8AAABfAAAAXwAAAF8AAABfAAAAXwAAAF8AAABfAAAAXwAAAF8AAABfAAAAXwAA
+        AF8AAABfAAAAXwAAAF8AAABfAAAAXwAAAF8AAABfAAAAXwAAAF8AAABfAAAAXwAAAF8AAABfAAAAXwAA
+        AF8AAABfAAAAXwAAAF8AAABfAAAAXwAAAF8AAABfAAAAXwgICFcICAibAAAA/wMDA9s1NTUJ////Af//
+        /wEAAABHAAAA/wAAAMMAAAAF////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQcH
+        B58AAAD/DQ0NYf///wH///8BAAAAewAAAP8AAABf////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEYGBg7AAAA/wMDA5f///8B////AQAAAH8AAAD/AAAAS////wH///8BAAAAFwAA
+        AIcAAAAr////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAAMAAABbAAAAswAA
+        ANsAAADfAAAAwwAAAH0AAAAR////Af///wEAAABrAAAAowAAAKMAAACjAAAAowAAAKMAAACjAAAAowAA
+        AKMAAAAP////AQAAAEcAAACdAAAAxQAAAMkAAACrAAAAZQAAAAn///8BAAAAAwAAAIUAAACHAAAAhwAA
+        AIcAAACHAAAAhwAAAIcAAACHAAAAhwAAADH///8BJycnKQAAAP8AAACb////Af///wEAAAB/AAAA/wAA
+        AEn///8B////AQAAACkAAAD/AAAAT////wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AAkAAAC3AAAA/wAAALkAAAB5AAAAcQAAAJcAAADvAAAA4wAAAC3///8BAAAAqQAAAO8AAAC3AAAAtwAA
+        ALcAAAC3AAAAtwAAALcAAAC3AAAAGQAAAK8AAAD/AAAAxQAAAIsAAACDAAAApwAAAPEAAADbAAAAJQAA
+        AAMAAAD5AAAA5wAAANEAAADRAAAA0QAAANEAAADRAAAA0QAAANEAAABL////ASgoKCcAAAD/AAAAm///
+        /wH///8BAAAAfwAAAP8AAABJ////Af///wEAAAApAAAA/wAAAE////8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAACLAAAA/QAAAFX///8B////Af///wH///8BAAAAGQAAANUAAADXAAAABwAA
+        AKkAAADL////Af///wH///8B////Af///wH///8B////AQAAAJ8AAAD1AAAATf///wH///8B////Af//
+        /wEAAAAZAAAA0QAAAM8AAAAFAAAA+QAAAHf///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEoKCgnAAAA/wAAAJv///8B////AQAAAH8AAAD/AAAASf///wH///8BAAAAKQAAAP8AAABP////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAAAJAAAA8QAAAKH///8B////Af///wH///8B////Af//
+        /wEAAABBAAAA/wAAAFEAAACpAAAAy////wH///8B////Af///wH///8B////AQAAAC0AAAD9AAAAaf//
+        /wH///8B////Af///wH///8B////AQAAAEsAAAD/AAAAMwAAAPkAAAB3////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BKCgoJwAAAP8AAACb////Af///wEAAAB/AAAA/wAAAEn///8B////AQAA
+        ACkAAAD/AAAAT////wH///8B////Af///wH///8B////Af///wH///8BAAAAMwAAAP8AAABR////Af//
+        /wH///8B////Af///wH///8BAAAAAwAAAO8AAACLAAAAqQAAAMv///8B////Af///wH///8B////Af//
+        /wEAAAAZAAAAewAAAAf///8B////Af///wH///8B////Af///wEAAAA3AAAA/wAAAEUAAAD5AAAAd///
+        /wH///8B////Af///wH///8B////Af///wH///8B////ASgoKCcAAAD/AAAAm////wH///8BAAAAfwAA
+        AP8AAABJ////Af///wEAAAApAAAA/wAAAE////8B////Af///wH///8B////Af///wH///8B////AQAA
+        AEUAAAD/AAAANf///wH///8B////Af///wH///8B////Af///wEAAADXAAAAnwAAAKkAAADL////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAiQAA
+        AP0AAAAfAAAA+QAAAHf///8B////Af///wH///8B////Af///wH///8B////Af///wEoKCgnAAAA/wAA
+        AJv///8B////AQAAAH8AAAD/AAAASf///wH///8BAAAAKQAAAP8AAABP////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAABFAAAA/wAAADP///8B////Af///wH///8B////Af///wH///8BAAAA1QAA
+        AJ8AAACpAAAAy////wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAAAZAAAAlQAAAP0AAACXAAAAAwAAAPkAAAB3////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BKCgoJwAAAP8AAACb////Af///wEAAAB/AAAA/wAAAEn///8B////AQAAACkAAAD/AAAA8wAA
+        AO0AAADtAAAA7QAAAOMAAADBAAAAeQAAABH///8BAAAARQAAAP8AAAAz////Af///wH///8B////Af//
+        /wH///8B////AQAAANUAAACfAAAAqQAAAMv///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAADwAAAF0AAACxAAAA+QAAAPMAAAB9AAAABQAAAAMAAAD5AAAAnwAAAEkAAABJAAAASQAA
+        AEkAAABJAAAABf///wH///8B////ASgoKCcAAAD/AAAAm////wH///8BAAAAfwAAAP8AAABJ////Af//
+        /wEAAAApAAAA/wAAAI8AAABfAAAAXwAAAF8AAABpAAAAkQAAAOkAAADfAAAAIQAAAEUAAAD/AAAAM///
+        /wH///8B////Af///wH///8B////Af///wEAAADVAAAAnwAAAKkAAADL////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAAAbAAAAmQAAAPUAAAD9AAAAwwAAAG0AAAAT////Af///wEAAAADAAAA+QAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAA////8B////Af///wEoKCgnAAAA/wAAAJv///8B////AQAA
+        AH8AAAD/AAAASf///wH///8BAAAAKQAAAP8AAABP////Af///wH///8B////Af///wEAAAAVAAAA3wAA
+        AK8AAABFAAAA/wAAADP///8B////Af///wH///8B////Af///wH///8BAAAA1QAAAJ8AAACpAAAAy///
+        /wH///8B////Af///wH///8B////Af///wEAAAApAAAA6QAAAO0AAAB9AAAAHf///wH///8B////Af//
+        /wH///8BAAAAAwAAAPkAAAB7AAAABwAAAAcAAAAHAAAABwAAAAf///8B////Af///wH///8BKCgoJwAA
+        AP8AAACb////Af///wEAAAB/AAAA/wAAAEn///8B////AQAAACkAAAD/AAAAT////wH///8B////Af//
+        /wH///8B////AQAAAH8AAAD3AAAASQAAAP8AAAAz////Af///wH///8B////Af///wH///8B////AQAA
+        ANUAAACfAAAAqQAAAMv///8B////Af///wH///8B////Af///wH///8BAAAAswAAAOUAAAAd////Af//
+        /wH///8B////Af///wH///8B////AQAAAAMAAAD5AAAAd////wH///8B////Af///wH///8B////Af//
+        /wH///8B////ASgoKCcAAAD/AAAAm////wH///8BAAAAfwAAAP8AAABJ////Af///wEAAAApAAAA/wAA
+        AE////8B////Af///wH///8B////Af///wEAAABtAAAA/wAAAE8AAAD/AAAAM////wH///8B////Af//
+        /wH///8B////Af///wEAAADVAAAAnwAAAKkAAADL////Af///wH///8B////Af///wH///8B////AQAA
+        AOUAAACP////Af///wH///8B////Af///wH///8BAAAAHwAAAAkAAAADAAAA+QAAAHf///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEoKCgnAAAA/wAAAJv///8B////AQAAAH8AAAD/AAAASf//
+        /wH///8BAAAAKQAAAP8AAABP////Af///wH///8B////Af///wH///8BAAAAqQAAAOMAAABHAAAA/wAA
+        ADP///8B////Af///wH///8B////Af///wH///8BAAAA1QAAAJ8AAACpAAAAy////wH///8B////Af//
+        /wH///8B////Af///wEAAADZAAAAnf///wH///8B////Af///wH///8BAAAAAwAAAMkAAACtAAAAAwAA
+        APkAAAB3////Af///wH///8B////Af///wH///8B////Af///wH///8BKCgoJwAAAP8AAACb////Af//
+        /wEAAAB/AAAA/wAAAEn///8B////AQAAACkAAAD/AAAAT////wH///8B////AQAAAAMAAAAhAAAAiwAA
+        AP8AAAB3AAAARQAAAP8AAAAz////Af///wH///8B////Af///wH///8B////AQAAANUAAACfAAAAqQAA
+        AMv///8B////Af///wH///8B////Af///wH///8BAAAAfQAAAPcAAABH////Af///wH///8BAAAACwAA
+        AJ0AAAD7AAAAPQAAAAMAAAD5AAAAdwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAP///8B////ASgo
+        KCcAAAD/AAAAm////wH///8BAAAAfwAAAP8AAABJ////Af///wEAAAApAAAA/wAAAPMAAADtAAAA7QAA
+        AO0AAAD1AAAA/wAAAPMAAAB7AAAAAwAAAEUAAAD/AAAAM////wH///8B////Af///wH///8B////Af//
+        /wEAAADVAAAAnwAAAKkAAADL////Af///wH///8B////Af///wH///8B////AQAAAAcAAACnAAAA/wAA
+        AMsAAAClAAAAswAAAO0AAAD1AAAAXf///wEAAAADAAAA+QAAAPkAAADzAAAA8wAAAPMAAADzAAAA8wAA
+        APMAAADn////Af///wEoKCgnAAAA/wAAAJv///8B////AQAAAH8AAAD/AAAAS////wH///8BAAAAEwAA
+        AGkAAABpAAAAaQAAAGkAAABpAAAAXwAAAEMAAAAL////Af///wEAAAAXAAAATQAAABH///8B////Af//
+        /wH///8B////Af///wH///8BAAAAQQAAADEAAAAzAAAAPf///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAAD8AAACNAAAArQAAAKMAAABzAAAAG////wH///8BAAAAAwAAAGcAAABpAAAAaQAA
+        AGkAAABpAAAAaQAAAGkAAABpAAAAY////wH///8BKCgoJwAAAP8AAACb////Af///wEAAAB/AAAA/wAA
+        AFP///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////ASAgIDEAAAD/AQEBmf//
+        /wH///8BAAAATwAAAP8AAAC3////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEJCQmPAAAA/wwMDGn///8B////AQAAAAUAAADVAAAA/wAAAJ8AAAAjAAAACQAAAAkAAAAJAAAACQAA
+        AAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAA
+        AAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAA
+        AAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAA
+        AAkAAAAJAAAACxwcHBkJCQmDAAAA/QICAuUpKSkP////Af///wH///8BAAAAKQAAAOEAAAD/AAAA/wAA
+        APsAAAD7AAAA+wAAAPsAAAD7AAAA+wAAAPsAAAD7AAAA+wAAAPsAAAD7AAAA+wAAAPsAAAD7AAAA+wAA
+        APsAAAD7AAAA+wAAAPsAAAD7AAAA+wAAAPsAAAD7AAAA+wAAAPsAAAD7AAAA+wAAAPsAAAD7AAAA+wAA
+        APsAAAD7AAAA+wAAAPsAAAD7AAAA+wAAAPsAAAD7AAAA+wAAAPsAAAD7AAAA+wAAAPsAAAD7AAAA+wAA
+        APsAAAD7AAAA+wAAAPsAAAD7AAAA+wAAAP0AAAD/AAAA/wICAukQEBA3////Af///wH///8B////Af//
+        /wEAAAARAAAAewAAAL0AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAA
+        AL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAA
+        AL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAA
+        AL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AgICuQoKCoMcHBwX////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAAAIAAAAAAAQAAAQAgAAAAAAAACAEAAAAAAAAA
+        AAAAAAAAAAAAAP///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAAMAAAAzAAAAQQAA
+        AEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAA
+        AEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAA
+        AEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAA
+        AEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAA
+        AEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAA
+        AEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAA
+        AEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAP11d
+        XR3ExMQD////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAAA0AAABzAAAA1QAAAP0AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/woKCt0UFBSFOjo6Ff///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAA/AAAA3wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8EBATrGxsbXf///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAAUQAAAPkAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD9FhYWff//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAADMAAAD3AAAA/wAAAP8AAAD/AAAA+wAA
+        ALsAAAB1AAAAYwAAAGMAAABjAAAAYwAAAGMAAABjAAAAYwAAAGMAAABjAAAAYwAAAGMAAABjAAAAYwAA
+        AGMAAABjAAAAYwAAAGMAAABjAAAAYwAAAGMAAABjAAAAYwAAAGMAAABjAAAAYwAAAGMAAABjAAAAYwAA
+        AGMAAABjAAAAYwAAAGMAAABjAAAAYwAAAGMAAABjAAAAYwAAAGMAAABjAAAAYwAAAGMAAABjAAAAYwAA
+        AGMAAABjAAAAYwAAAGMAAABjAAAAYwAAAGMAAABjAAAAYwAAAGMAAABjAAAAYwAAAGMAAABjAAAAYwAA
+        AGMAAABjAAAAYwAAAGMAAABjAAAAYwAAAGMAAABjAAAAYwAAAGMAAABjAAAAYwAAAGMAAABjAAAAYwAA
+        AGMAAABjAAAAYwAAAGMAAABjAAAAYwAAAGMAAABjAAAAYwAAAGMAAABjAAAAYwAAAGMAAABjAAAAYwAA
+        AGMAAABjAAAAYwAAAGMAAABjAAAAYwAAAGMAAABjAAAAYwAAAGMAAABjAAAAYwAAAGMAAABjAAAAYwAA
+        AG0AAABtEhISnQUFBfEAAAD/AAAA/wAAAP8AAAD9GhoaX////wH///8B////Af///wH///8B////Af//
+        /wEAAAAFAAAA0QAAAP8AAAD/AAAA/wAAANsAAAA3////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BPz8/FQ0NDasAAAD/AAAA/wAA
+        AP8EBATvQEBAGf///wH///8B////Af///wH///8B////AQAAAFUAAAD/AAAA/wAAAP8AAADhAAAAG///
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BpKSkBQ4ODqkAAAD/AAAA/wAAAP8SEhKJ////Af///wH///8B////Af//
+        /wH///8BAAAAsQAAAP8AAAD/AAAA/wAAAE3///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BQ0NDEwUF
+        Be0AAAD/AAAA/wkJCeG/v78D////Af///wH///8B////Af///wEAAADpAAAA/wAAAP8AAADdAAAAA///
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BEhISlQAAAP8AAAD/AAAA/01NTSP///8B////Af//
+        /wH///8B////AQAAAP8AAAD/AAAA/wAAAKn///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEdHR1hAAAA/wAAAP8AAAD/AAAAOf///wH///8B////Af///wH///8BAAAA/wAAAP8AAAD/AAAAl///
+        /wH///8B////Af///wEAAABRAAAAXQAAAF0AAABdAAAAXQAAAF0AAABdAAAAXQAAAF0AAABdAAAAXQAA
+        AF0AAABdAAAAXQAAAF0AAABdAAAAXQAAAF0AAABdAAAAXQAAAF8AAAAVAAAAKwAAAF0AAABdAAAAXQAA
+        AF0AAABdAAAAXQAAAAn///8B////Af///wH///8B////Af///wH///8B////AQAAAB8AAABrAAAApQAA
+        AM0AAADfAAAA4wAAANsAAACzAAAAbQAAABP///8B////Af///wEAAABBAAAAXQAAAF0AAABdAAAAXQAA
+        ADkAAAAPAAAAXwAAAF0AAABdAAAAXQAAAF0AAABdAAAAMf///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAATwAAAF0AAABdAAAAXQAAAF0AAABdAAAASf///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAABkAAABfAAAAXQAAAF0AAABdAAAAXQAAAF8AAAAh////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AScnJ1EAAAD/AAAA/wAAAP8AAAA5////Af//
+        /wH///8B////Af///wEAAAD/AAAA/wAAAP8AAACT////Af///wH///8B////AQAAANcAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAADkAAABzAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD9AAAAGf///wH///8B////Af//
+        /wH///8B////AQAAAC0AAACxAAAA+wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA8QAA
+        AHMAAAAD////AQAAAK8AAAD/AAAA/wAAAP8AAAD/AAAAmQAAACcAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAACD////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAADVAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAADH////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAARQAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAFn///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BKCgoTwAAAP8AAAD/AAAA/wAAADn///8B////Af///wH///8B////AQAAAP8AAAD/AAAA/wAA
+        AJP///8B////Af///wH///8BAAAA1wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAOQAAAHMAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP0AAAAZ////Af///wH///8B////Af///wEAAAB1AAAA+QAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAKsAAAAFAAAArwAAAP8AAAD/AAAA/wAA
+        AP8AAACXAAAAJwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAIP///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAANMAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAMf///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAABFAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAWf//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEoKChPAAAA/wAAAP8AAAD/AAAAOf//
+        /wH///8B////Af///wH///8BAAAA/wAAAP8AAAD/AAAAk////wH///8B////Af///wEAAADXAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAA5AAAAcwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/QAAABn///8B////Af//
+        /wH///8BAAAAlQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAI8AAACvAAAA/wAAAP8AAAD/AAAA/wAAAJcAAAAnAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAAg////wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAA0wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAAx////wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AEUAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABZ////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////ASgoKE8AAAD/AAAA/wAAAP8AAAA5////Af///wH///8B////Af///wEAAAD/AAAA/wAA
+        AP8AAACT////Af///wH///8B////AQAAANcAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAADkAAABzAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD9AAAAGf///wH///8B////AQAAAHMAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+wAAANUAAAD/AAAA/wAA
+        AP8AAAD/AAAAlwAAACcAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAACD////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAADTAAAA/wAAAP8AAAD/AAAA/wAAAP8AAADH////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAARQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AFn///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BKCgoTwAAAP8AAAD/AAAA/wAA
+        ADn///8B////Af///wH///8B////AQAAAP8AAAD/AAAA/wAAAJP///8B////Af///wH///8BAAAA1wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPsAAAD7AAAA+wAAAPsAAAD7AAAA+wAAAPsAAAD7AAAA+wAA
+        APsAAAD7AAAA+wAAAPsAAAD9AAAAOQAAAHMAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP0AAAAZ////Af//
+        /wEAAAAtAAAA+QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADxAAAApwAAAHcAAABxAAAAiwAA
+        AM8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAACXAAAAJwAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAIP///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        ANMAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAMf///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAABFAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAWf///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEoKChPAAAA/wAAAP8AAAD/AAAAOf///wH///8B////Af///wH///8BAAAA/wAA
+        AP8AAAD/AAAAk////wH///8B////Af///wEAAADXAAAA/wAAAP8AAAD/AAAA/wAAAP8AAADRAAAAEQAA
+        ABEAAAARAAAAEQAAABEAAAARAAAAEQAAABEAAAARAAAAEQAAABEAAAARAAAAEQAAABEAAAAFAAAAcwAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/QAAABn///8B////AQAAALUAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAAlQAAABH///8B////Af///wH///8BAAAAAwAAAFEAAADrAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAJcAAAAnAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAg////wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAA0wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAx///
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAAEUAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAABZ////Af///wH///8B////Af///wH///8B////Af///wH///8B////ASgoKE8AAAD/AAAA/wAA
+        AP8AAAA5////Af///wH///8B////Af///wEAAAD/AAAA/wAAAP8AAACT////Af///wH///8B////AQAA
+        ANcAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAM////8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAABzAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD9AAAAGf//
+        /wEAAAAvAAAA/QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAH////8B////Af///wH///8B////Af//
+        /wH///8B////AQAAADEAAAD1AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAlwAAACcAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAACD////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAADTAAAA/wAAAP8AAAD/AAAA/wAAAP8AAADH////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAARQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAFn///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BKCgoTwAAAP8AAAD/AAAA/wAAADn///8B////Af///wH///8B////AQAA
+        AP8AAAD/AAAA/wAAAJP///8B////Af///wH///8BAAAA1wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAz///
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AHMAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP0AAAAZ////AQAAAIsAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAC3AAAAA////wH///8B////Af///wH///8B////Af///wH///8B////AQAAAHcAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAACXAAAAJwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAIP///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAANMAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AMf///8B////Af///wH///8B////Af///wH///8B////Af///wEAAABFAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAAWf///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEoKChPAAAA/wAA
+        AP8AAAD/AAAAOf///wH///8B////Af///wH///8BAAAA/wAAAP8AAAD/AAAAk////wH///8B////Af//
+        /wEAAADXAAAA/wAAAP8AAAD/AAAA/wAAAP8AAADP////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAAcwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/QAA
+        ABkAAAADAAAA1wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAADH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAAEQAAAPUAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAJcAAAAnAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAAg////wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAA0wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAx////wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAAEUAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABZ////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////ASgoKE8AAAD/AAAA/wAAAP8AAAA5////Af///wH///8B////Af//
+        /wEAAAD/AAAA/wAAAP8AAACT////Af///wH///8B////AQAAANcAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AM////8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAABzAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD9AAAAGQAAABkAAAD9AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAADL////Af///wH///8B////Af///wH///8B////AQAAAD8AAABJAAAASQAAAEkAAABJAAAA1QAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAAlwAAACcAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAACD////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAADTAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAADH////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAARQAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAFn///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BKCgoTwAA
+        AP8AAAD/AAAA/wAAADn///8B////Af///wH///8B////AQAAAP8AAAD/AAAA/wAAAJP///8B////Af//
+        /wH///8BAAAA1wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAz////wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAAHMAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP0AAAAZAAAASwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAIP///8B////Af///wH///8B////Af//
+        /wH///8BAAAA2wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAACXAAAAJwAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAIP///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAANMAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAMf///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAABFAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAWf///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEoKChPAAAA/wAAAP8AAAD/AAAAOf///wH///8B////Af//
+        /wH///8BAAAA/wAAAP8AAAD/AAAAk////wH///8B////Af///wEAAADXAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAADP////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAAcwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/QAAABkAAABtAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAAT////wH///8B////Af///wH///8B////Af///wEAAADbAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAJcAAAAnAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAg///
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAA0wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAAx////wH///8B////Af///wH///8B////Af///wH///8B////AQAAAEUAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAABZ////Af///wH///8B////Af///wH///8B////Af///wH///8B////ASgo
+        KE8AAAD/AAAA/wAAAP8AAAA5////Af///wH///8B////Af///wEAAAD/AAAA/wAAAP8AAACT////Af//
+        /wH///8B////AQAAANcAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAO0AAAClAAAApQAAAKUAAAClAAAApQAA
+        AKUAAAClAAAApQAAAKUAAAB1////Af///wH///8B////Af///wEAAABzAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD9AAAAGQAAAIUAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAAr////Af///wH///8B////Af//
+        /wH///8B////AQAAANsAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAlwAA
+        ACcAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADRAAAApQAAAKUAAAClAAAApQAAAKUAAAClAAAApQAA
+        AKUAAAClAAAApQAAAKUAAADvAAAA/wAAAP8AAAD/AAAA/wAAAP8AAADH////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAARQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAFn///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BKCgoTwAAAP8AAAD/AAAA/wAAADn///8B////Af//
+        /wH///8B////AQAAAP8AAAD/AAAA/wAAAJP///8B////Af///wH///8BAAAA1wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAALP///8B////Af//
+        /wH///8B////AQAAAHMAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP0AAAAZAAAAlwAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAABn///8B////Af///wH///8B////Af///wH///8BAAAA2wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAACXAAAAJwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAMf///8B////Af///wH///8B////Af///wH///8B////Af///wEAAABFAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAAWf///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEoKChPAAAA/wAAAP8AAAD/AAAAOf///wH///8B////Af///wH///8BAAAA/wAAAP8AAAD/AAAAk///
+        /wH///8B////Af///wEAAADXAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAAs////wH///8B////Af///wH///8BAAAAcwAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/QAAABkAAACZAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD9AAAAFf///wH///8B////Af//
+        /wH///8B////Af///wEAAACRAAAAqQAAAKkAAACpAAAAqQAAAKkAAACpAAAAqQAAAKkAAACpAAAAqQAA
+        AGUAAAAnAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAx////wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAEUAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABZ////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////ASgoKE8AAAD/AAAA/wAAAP8AAAA5////Af//
+        /wH///8B////Af///wEAAAD/AAAA/wAAAP8AAACT////Af///wH///8B////AQAAANcAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAACz////Af//
+        /wH///8B////Af///wEAAABzAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD9AAAAGQAAAJkAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP0AAAAV////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAACcAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAADH////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAARQAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAFn///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BKCgoTwAAAP8AAAD/AAAA/wAAADn///8B////Af///wH///8B////AQAAAP8AAAD/AAAA/wAA
+        AJP///8B////Af///wH///8BAAAA1wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAALP///8B////Af///wH///8B////AQAAAHMAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP0AAAAZAAAAiQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAB////8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAAJwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAMf///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAABFAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAWf//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEoKChPAAAA/wAAAP8AAAD/AAAAOf//
+        /wH///8B////Af///wH///8BAAAA/wAAAP8AAAD/AAAAk////wH///8B////Af///wEAAADXAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAADtAAAAowAAAKMAAACjAAAAowAAAKMAAACjAAAAowAAAKMAAACjAAAAc///
+        /wH///8B////Af///wH///8BAAAAcwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/QAAABkAAABxAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAAPf///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAAnAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA9wAAAO8AAADvAAAA7wAAAO8AAADvAAAA7wAAAO8AAADvAAAA7wAAAO8AAADvAAAA/QAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAAx////wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AEUAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABZ////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////ASgoKE8AAAD/AAAA/wAAAP8AAAA5////Af///wH///8B////Af///wEAAAD/AAAA/wAA
+        AP8AAACT////Af///wH///8B////AQAAANcAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAM////8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAABzAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD9AAAAGQAAAEsAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABp////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAAFAAAAFf///wH///8B////Af//
+        /wH///8B////AQAAACcAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAACFAAAABwAAAAcAAAAHAAAABwAA
+        AAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAADVAAAA/wAAAP8AAAD/AAAA/wAAAP8AAADH////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAARQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AFn///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BKCgoTwAAAP8AAAD/AAAA/wAA
+        ADn///8B////Af///wH///8B////AQAAAP8AAAD/AAAA/wAAAJP///8B////Af///wH///8BAAAA1wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAAz////wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAHMAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP0AAAAZAAAAGwAA
+        AP0AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAK3///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAADsAAAD7AAAAyQAAAIMAAAA/AAAAB////wH///8BAAAAJwAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAIP///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        ANMAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAMf///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAABFAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAWf///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEoKChPAAAA/wAAAP8AAAD/AAAAOf///wH///8B////Af///wH///8BAAAA/wAA
+        AP8AAAD/AAAAk////wH///8B////Af///wEAAADXAAAA/wAAAP8AAAD/AAAA/wAAAP8AAADP////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAcwAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/QAAABn///8BAAAA0wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA9wAA
+        ABf///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAnQAAAP8AAAD/AAAA/wAA
+        AP8AAADvAAAAqwAAAAUAAAAnAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAg////wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAA0wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAx///
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAAEUAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAABZ////Af///wH///8B////Af///wH///8B////Af///wH///8B////ASgoKE8AAAD/AAAA/wAA
+        AP8AAAA5////Af///wH///8B////Af///wEAAAD/AAAA/wAAAP8AAACT////Af///wH///8B////AQAA
+        ANcAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAM////8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAABzAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD9AAAAGf//
+        /wEAAACDAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAk////wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAACEAAAD5AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADB////AQAAACcAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAACD////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAADTAAAA/wAAAP8AAAD/AAAA/wAAAP8AAADH////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAARQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAFn///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BKCgoTwAAAP8AAAD/AAAA/wAAADn///8B////Af///wH///8B////AQAA
+        AP8AAAD/AAAA/wAAAJP///8B////Af///wH///8BAAAA1wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAz///
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AHMAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP0AAAAZ////AQAAACEAAAD7AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD9AAAAV////wH///8B////Af///wH///8B////Af///wEAAAAFAAAAuQAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAG3///8BAAAAJwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAIP///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAANMAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AMf///8B////Af///wH///8B////Af///wH///8B////Af///wEAAABFAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAAWf///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEoKChPAAAA/wAA
+        AP8AAAD/AAAAOf///wH///8B////Af///wH///8BAAAA/wAAAP8AAAD/AAAAk////wH///8B////Af//
+        /wEAAADXAAAA/wAAAP8AAAD/AAAA/wAAAP8AAADRAAAADQAAAA0AAAANAAAADQAAAA0AAAANAAAADQAA
+        AA0AAAANAAAADQAAAA0AAAANAAAADQAAAAf///8BAAAAcwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/QAA
+        ABn///8B////AQAAAJ0AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD5AAAAeQAAAAn///8B////Af//
+        /wH///8BAAAAEQAAAK0AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADvAAAAEf///wEAAAAnAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAAg////wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAA0wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAxwAAAAMAAAANAAAADQAAAA0AAAANAAAADQAA
+        AA0AAAANAAAADQAAAE0AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABhAAAADQAAAA0AAAANAAAADQAA
+        AA0AAAAN////Af///wH///8B////ASgoKE8AAAD/AAAA/wAAAP8AAAA5////Af///wH///8B////Af//
+        /wEAAAD/AAAA/wAAAP8AAACT////Af///wH///8B////AQAAANcAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD9AAAA/QAAAP0AAAD9AAAA/QAAAP0AAAD9AAAA/QAAAP0AAAD9AAAA/QAAAP0AAAD9AAAAf///
+        /wEAAABzAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD9AAAAGf///wH///8BAAAAGQAAAOsAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA5wAAAJsAAAB1AAAAdQAAAJ8AAADvAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAH////8B////AQAAACcAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAACD////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAADTAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAADHAAAAIQAAAP0AAAD9AAAA/QAAAP0AAAD9AAAA/QAAAP0AAAD9AAAA/QAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP0AAAD9AAAA/QAAAP0AAAD9AAAA/QAAAPX///8B////Af///wH///8BKCgoTwAA
+        AP8AAAD/AAAA/wAAADn///8B////Af///wH///8B////AQAAAP8AAAD/AAAA/wAAAJP///8B////Af//
+        /wH///8BAAAA1wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAACB////AQAAAHMAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP0AAAAZ////Af///wH///8BAAAATQAAAP0AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADXAAAACf///wH///8BAAAAJwAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAIP///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAANMAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAMcAAAAhAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA9////wH///8B////Af///wEoKChPAAAA/wAAAP8AAAD/AAAAOf///wH///8B////Af//
+        /wH///8BAAAA/wAAAP8AAAD/AAAAk////wH///8B////Af///wEAAADXAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AIH///8BAAAAcwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/QAAABn///8B////Af///wH///8BAAAAYwAA
+        APsAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA7wAAACv///8B////Af///wEAAAAnAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAg///
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAA0wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAAxwAAACEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD3////Af///wH///8B////ASgo
+        KE8AAAD/AAAA/wAAAP8AAAA5////Af///wH///8B////Af///wEAAAD/AAAA/wAAAP8AAACT////Af//
+        /wH///8B////AQAAANcAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAgf///wEAAABzAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD9AAAAGf///wH///8B////Af///wH///8BAAAATQAAAOsAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAOEAAAAz////Af///wH///8B////AQAA
+        ACcAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAACD////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAADTAAAA/wAAAP8AAAD/AAAA/wAAAP8AAADHAAAAIQAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAPf///8B////Af///wH///8BKCgoTwAAAP8AAAD/AAAA/wAAADn///8B////Af//
+        /wH///8B////AQAAAP8AAAD/AAAA/wAAAJP///8B////Af///wH///8BAAAA1wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAACB////AQAAAHMAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP0AAAAZ////Af///wH///8B////Af//
+        /wH///8BAAAAFwAAAJcAAAD1AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        APcAAACZAAAAE////wH///8B////Af///wH///8BAAAAJwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AIP///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAANMAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAMcAAAAhAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA9////wH///8B////Af//
+        /wEoKChPAAAA/wAAAP8AAAD/AAAAOf///wH///8B////Af///wH///8BAAAA/wAAAP8AAAD/AAAAk///
+        /wH///8B////Af///wEAAABxAAAAhQAAAIUAAACFAAAAhQAAAIUAAACFAAAAhQAAAIUAAACFAAAAhQAA
+        AIUAAACFAAAAhQAAAIUAAACFAAAAhQAAAIUAAACFAAAAhQAAAEP///8BAAAAPQAAAIUAAACFAAAAhQAA
+        AIUAAACFAAAAgwAAAA3///8B////Af///wH///8B////Af///wH///8B////AQAAABcAAABpAAAArQAA
+        AN8AAAD3AAAA+wAAAPsAAAD3AAAA4wAAALUAAABxAAAAG////wH///8B////Af///wH///8B////Af//
+        /wEAAAAVAAAAhQAAAIUAAACFAAAAhQAAAIUAAACFAAAARf///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAAbwAAAIUAAACFAAAAhQAAAIUAAACFAAAAZwAAABEAAACFAAAAhQAA
+        AIUAAACFAAAAhQAAAIUAAACFAAAAhQAAAIUAAACFAAAAhQAAAIUAAACFAAAAhQAAAIUAAACFAAAAhQAA
+        AIUAAACFAAAAhQAAAIUAAACB////Af///wH///8B////ASgoKE8AAAD/AAAA/wAAAP8AAAA5////Af//
+        /wH///8B////Af///wEAAAD/AAAA/wAAAP8AAACT////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAAAUAAAATAAAAFQAAAAf///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BJycnTwAAAP8AAAD/AAAA/wAAADn///8B////Af///wH///8B////AQAAAP8AAAD/AAAA/wAA
+        AJf///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEnJydRAAAA/wAAAP8AAAD/AAAAOf//
+        /wH///8B////Af///wH///8BAAAA+wAAAP8AAAD/AAAArf///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AR8fH2UAAAD/AAAA/wAAAP8MDAw1////Af///wH///8B////Af///wEAAADPAAAA/wAA
+        AP8AAAD3AAAAG////wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BDQ0NxwAAAP8AAAD/AgIC95GR
+        kQ3///8B////Af///wH///8B////AQAAAIEAAAD/AAAA/wAAAP8AAACh////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////ASEhIVMAAAD/AAAA/wAAAP8PDw+1////Af///wH///8B////Af///wH///8BAAAAHQAA
+        APcAAAD/AAAA/wAAAP8AAACBAAAAA////wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEjIyM/AwMD8QAAAP8AAAD/AAAA/SMj
+        I0n///8B////Af///wH///8B////Af///wH///8BAAAAfQAAAP8AAAD/AAAA/wAAAP8AAADBAAAAfwAA
+        AH8AAAB9AAAAfQAAAH0AAAB9AAAAfQAAAH0AAAB9AAAAfQAAAH0AAAB9AAAAfQAAAH0AAAB9AAAAfQAA
+        AH0AAAB9AAAAfQAAAH0AAAB9AAAAfQAAAH0AAAB9AAAAfQAAAH0AAAB9AAAAfQAAAH0AAAB9AAAAfQAA
+        AH0AAAB9AAAAfQAAAH0AAAB9AAAAfQAAAH0AAAB9AAAAfQAAAH0AAAB9AAAAfQAAAH0AAAB9AAAAfQAA
+        AH0AAAB9AAAAfQAAAH0AAAB9AAAAfQAAAH0AAAB9AAAAfQAAAH0AAAB9AAAAfQAAAH0AAAB9AAAAfQAA
+        AH0AAAB9AAAAfQAAAH0AAAB9AAAAfQAAAH0AAAB9AAAAfQAAAH0AAAB9AAAAfQAAAH0AAAB9AAAAfQAA
+        AH0AAAB9AAAAfQAAAH0AAAB9AAAAfQAAAH0AAAB9AAAAfQAAAH0AAAB9AAAAfQAAAH0AAAB/AAAAfwAA
+        AH8AAAB9AAAAfQAAAH0AAAB9AAAAfQAAAH0AAAB9AAAAfQAAAH0AAAB9AAAAfQAAAH8AAAB/AAAAfwAA
+        AH0SEhJtDAwMmQICAvcAAAD/AAAA/wAAAP8MDAyt////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAAAFAAAAtQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/BwcH1UFB
+        QRX///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAALAAAAzwAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wUFBe9EREQb////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAAGsAAAD9AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/w8P
+        D5nKysoD////Af///wH///8B////Af///wH///8B////Af///wEAAABHAAAA/QAAAP8AAAD/AAAA/wAA
+        APMAAAC/AAAAvQAAALsAAAC7AAAAuwAAALsAAAC7AAAAuwAAALsAAAC7AAAAuwAAALsAAAC7AAAAuwAA
+        ALsAAAC7AAAAuwAAALsAAAC7AAAAuwAAALsAAAC7AAAAuwAAALsAAAC7AAAAuwAAALsAAAC7AAAAuwAA
+        ALsAAAC7AAAAuwAAALsAAAC7AAAAuwAAALsAAAC7AAAAuwAAALsAAAC7AAAAuwAAALsAAAC7AAAAuwAA
+        ALsAAAC7AAAAuwAAALsAAAC7AAAAuwAAALsAAAC7AAAAuwAAALsAAAC7AAAAuwAAALsAAAC7AAAAuwAA
+        ALsAAAC7AAAAuwAAALsAAAC7AAAAuwAAALsAAAC7AAAAuwAAALsAAAC7AAAAuwAAALsAAAC7AAAAuwAA
+        ALsAAAC7AAAAuwAAALsAAAC7AAAAuwAAALsAAAC7AAAAuwAAALsAAAC7AAAAuwAAALsAAAC7AAAAuwAA
+        ALsAAAC7AAAAuwAAALsAAAC7AAAAuwAAALsAAAC7AAAAuwAAALsAAAC7AAAAuwAAALsAAAC7AAAAuwAA
+        ALsAAAC7AAAAuxMTE58GBgbXAAAA/wAAAP8AAAD/AAAA/xISEnf///8B////Af///wH///8B////Af//
+        /wH///8BAAAACwAAAN8AAAD/AAAA/wAAAP8AAADHAAAAH////wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AWlpaQkTExOLAAAA/QAA
+        AP8AAAD/AgIC9zU1NSX///8B////Af///wH///8B////Af///wEAAABjAAAA/wAAAP8AAAD/AAAA0wAA
+        AA3///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEPDw+PAAAA/wAAAP8AAAD/ERERlf///wH///8B////Af//
+        /wH///8B////AQAAALkAAAD/AAAA/wAAAP8AAAA9////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AWdn
+        ZwsHBwfjAAAA/wAAAP8HBwfrtra2Bf///wH///8B////Af///wH///8BAAAA7QAAAP8AAAD/AAAA1f//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////ARMTE4sAAAD/AAAA/wAAAP87Ozsn////Af//
+        /wH///8B////Af///wEAAAD/AAAA/wAAAP8AAACn////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BHx8fXwAAAP8AAAD/AAAA/wAAADn///8B////Af///wH///8B////AQAAAP8AAAD/AAAA/wAA
+        AJX///8B////Af///wH///8B////Af///wEAAAAHAAAAEwAAABEAAAAL////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAACQAAAEcAAACFAAAAqwAAAMEAAADDAAAAvQAAAJ8AAABxAAAALf//
+        /wH///8B////Af///wH///8B////Af///wEAAAAZAAAARwAAAEcAAABHAAAARwAAAEcAAABHAAAARwAA
+        AEcAAABHAAAARwAAAEcAAABHAAAARwAAAEcAAABHAAAARwAAAEcAAAAN////Af///wH///8B////Af//
+        /wEAAAAhAAAAWQAAAIEAAACVAAAAlwAAAIsAAABtAAAAPQAAAAn///8B////Af///wH///8B////Af//
+        /wH///8BAAAAEQAAABEAAAARAAAAEQAAABEAAAARAAAAEQAAABEAAAARAAAAEQAAABEAAAARAAAAEQAA
+        ABEAAAARAAAAEQAAABEAAAARAAAADf///wH///8B////Af///wEnJydRAAAA/wAAAP8AAAD/AAAAOf//
+        /wH///8B////Af///wH///8BAAAA/wAAAP8AAAD/AAAAk////wH///8B////Af///wH///8B////AQAA
+        AFMAAAD9AAAA/QAAAJv///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAACwAAAHsAAADpAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD9AAAAxwAAAEX///8B////Af///wH///8B////AQAA
+        AFEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAC3///8B////Af///wEAAABTAAAAxwAAAP0AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA7wAAAJkAAAAj////Af///wH///8B////AQAAAAcAAADzAAAA/QAAAP0AAAD9AAAA/QAA
+        AP0AAAD9AAAA/QAAAP0AAAD9AAAA/QAAAP0AAAD9AAAA/QAAAP0AAAD9AAAA/QAAAP0AAAC1////Af//
+        /wH///8B////ASgoKE8AAAD/AAAA/wAAAP8AAAA5////Af///wH///8B////Af///wEAAAD/AAAA/wAA
+        AP8AAACT////Af///wH///8B////Af///wH///8BAAAAUwAAAP8AAAD/AAAAm////wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAACUAAADVAAAA/wAAAP8AAAD/AAAA/wAAAPUAAADjAAAA2wAAAOUAAAD5AAAA/wAA
+        AP8AAAD/AAAA/wAAAJMAAAAH////Af///wH///8BAAAAUQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAK////wEAAAAdAAAAuwAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA9wAAAPMAAAD7AAAA/wAAAP8AAAD/AAAA/wAAAPcAAAB1AAAAA///
+        /wH///8BAAAABwAAAPUAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAALX///8B////Af///wH///8BKCgoTwAAAP8AAAD/AAAA/wAA
+        ADn///8B////Af///wH///8B////AQAAAP8AAAD/AAAA/wAAAJP///8B////Af///wH///8B////Af//
+        /wEAAABTAAAA/wAAAP8AAACb////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAAhAAAA5QAAAP8AAAD/AAAA+wAA
+        AKMAAAA/AAAADf///wH///8B////AQAAABMAAABRAAAAvQAAAP8AAAD/AAAA/wAAAKcAAAAD////Af//
+        /wEAAABRAAAA/wAAAP8AAADDAAAAbQAAAG0AAABtAAAAbQAAAG0AAABtAAAAbQAAAG0AAABtAAAAbQAA
+        AG0AAABtAAAAbQAAAG0AAAATAAAAJQAAAOEAAAD/AAAA/wAAAP0AAAC5AAAAXwAAACMAAAAPAAAACQAA
+        ABMAAAAvAAAAbQAAAMkAAAD/AAAA/wAAAP8AAACT////Af///wEAAAAHAAAA9QAAAP8AAAD5AAAApQAA
+        AKUAAAClAAAApQAAAKUAAAClAAAApQAAAKUAAAClAAAApQAAAKUAAAClAAAApQAAAKUAAAClAAAAd///
+        /wH///8B////Af///wEoKChPAAAA/wAAAP8AAAD/AAAAOf///wH///8B////Af///wH///8BAAAA/wAA
+        AP8AAAD/AAAAk////wH///8B////Af///wH///8B////AQAAAFMAAAD/AAAA/wAAAJv///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAABQAAAMcAAAD/AAAA/wAAAOkAAAA9////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAAYQAAAPcAAAD/AAAA/wAAAHH///8B////AQAAAFEAAAD/AAAA/wAAAJf///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAA8AAADZAAAA/wAA
+        AP8AAADfAAAAPf///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAF0AAAD1AAAA/wAA
+        AP8AAABf////AQAAAAcAAAD1AAAA/wAAAO3///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////ASgoKE8AAAD/AAAA/wAA
+        AP8AAAA5////Af///wH///8B////Af///wEAAAD/AAAA/wAAAP8AAACT////Af///wH///8B////Af//
+        /wH///8BAAAAUwAAAP8AAAD/AAAAm////wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAABfAAAA/wAAAP8AAAD1AAAAL///
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAXQAAAP8AAAD/AAAA8QAA
+        ABX///8BAAAAUQAAAP8AAAD/AAAAl////wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAAlwAAAP8AAAD/AAAA1wAAABn///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAE8AAAD/AAAA/wAAAOMAAAAHAAAABwAAAPUAAAD/AAAA7f//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BKCgoTwAAAP8AAAD/AAAA/wAAADn///8B////Af///wH///8B////AQAA
+        AP8AAAD/AAAA/wAAAJP///8B////Af///wH///8B////Af///wEAAABTAAAA/wAAAP8AAACb////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAAMsAAAD/AAAA/wAAAHv///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAAtwAAAP8AAAD/AAAAef///wEAAABRAAAA/wAAAP8AAACX////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAACcAAAD7AAAA/wAA
+        APUAAAAp////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        ALsAAAD/AAAA/wAAAEUAAAAHAAAA9QAAAP8AAADt////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEoKChPAAAA/wAA
+        AP8AAAD/AAAAOf///wH///8B////Af///wH///8BAAAA/wAAAP8AAAD/AAAAk////wH///8B////Af//
+        /wH///8B////AQAAAFMAAAD/AAAA/wAAAJv///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAAfAAAA/QAAAP8AAADzAAAAE///
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAABHAAAA/wAA
+        AP8AAADL////AQAAAFEAAAD/AAAA/wAAAJf///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAAiwAAAP8AAAD/AAAAhf///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAAcwAAAP8AAAD/AAAAdwAAAAcAAAD1AAAA/wAA
+        AO3///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////ASgoKE8AAAD/AAAA/wAAAP8AAAA5////Af///wH///8B////Af//
+        /wEAAAD/AAAA/wAAAP8AAACT////Af///wH///8B////Af///wH///8BAAAAUwAAAP8AAAD/AAAAm///
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAAFUAAAD/AAAA/wAAALn///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAAkAAADzAAAA/wAAAPcAAAAPAAAAUQAAAP8AAAD/AAAAl///
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAABlAAAAzwAA
+        APcAAAAX////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAABhAAAA/wAAAP8AAACFAAAABwAAAPUAAAD/AAAA7f///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BKCgoTwAA
+        AP8AAAD/AAAA/wAAADn///8B////Af///wH///8B////AQAAAP8AAAD/AAAA/wAAAJP///8B////Af//
+        /wH///8B////Af///wEAAABTAAAA/wAAAP8AAACb////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAcwAAAP8AAAD/AAAAh///
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AM0AAAD/AAAA/wAAACkAAABRAAAA/wAAAP8AAACX////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAAADAAAAI////wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAAHcAAAD/AAAA/wAAAH8AAAAHAAAA9QAA
+        AP8AAADt////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEoKChPAAAA/wAAAP8AAAD/AAAAOf///wH///8B////Af//
+        /wH///8BAAAA/wAAAP8AAAD/AAAAk////wH///8B////Af///wH///8B////AQAAAFMAAAD/AAAA/wAA
+        AJv///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAACFAAAA/wAAAP8AAABt////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAAswAAAP8AAAD/AAAAOwAAAFEAAAD/AAAA/wAA
+        AJf///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAAwQAAAP8AAAD/AAAAVwAAAAcAAAD1AAAA/wAAAO3///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////ASgo
+        KE8AAAD/AAAA/wAAAP8AAAA5////Af///wH///8B////Af///wEAAAD/AAAA/wAAAP8AAACT////Af//
+        /wH///8B////Af///wH///8BAAAAUwAAAP8AAAD/AAAAm////wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAIkAAAD/AAAA/wAA
+        AGX///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAACrAAAA/wAAAP8AAABBAAAAUQAAAP8AAAD/AAAAl////wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAAGEAAAD/AAAA/wAAAPcAAAAVAAAABwAA
+        APUAAAD/AAAA7f///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BKCgoTwAAAP8AAAD/AAAA/wAAADn///8B////Af//
+        /wH///8B////AQAAAP8AAAD/AAAA/wAAAJP///8B////Af///wH///8B////Af///wEAAABTAAAA/wAA
+        AP8AAACb////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAAiQAAAP8AAAD/AAAAZf///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAAKsAAAD/AAAA/wAAAEEAAABRAAAA/wAA
+        AP8AAACX////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AAUAAAB5AAAA+wAAAP8AAAD/AAAAj////wEAAAAHAAAA9QAAAP8AAADt////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEoKChPAAAA/wAAAP8AAAD/AAAAOf///wH///8B////Af///wH///8BAAAA/wAAAP8AAAD/AAAAk///
+        /wH///8B////Af///wH///8B////AQAAAFMAAAD/AAAA/wAAAJv///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAACJAAAA/wAA
+        AP8AAABl////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAAqwAAAP8AAAD/AAAAQQAAAFEAAAD/AAAA/wAAAJf///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAAkAAABbAAAA1QAAAP8AAAD/AAAA/wAAAMcAAAAL////AQAA
+        AAcAAAD1AAAA/wAAAO3///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////ASgoKE8AAAD/AAAA/wAAAP8AAAA5////Af//
+        /wH///8B////Af///wEAAAD/AAAA/wAAAP8AAACT////Af///wH///8B////Af///wH///8BAAAAUwAA
+        AP8AAAD/AAAA8QAAANsAAADbAAAA2wAAANsAAADbAAAA2wAAANsAAADPAAAAuwAAAJsAAABpAAAAI///
+        /wH///8B////Af///wH///8B////AQAAAIkAAAD/AAAA/wAAAGX///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAACrAAAA/wAAAP8AAABBAAAAUQAA
+        AP8AAAD/AAAAl////wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAAwAAADcAAACPAAAA5wAA
+        AP8AAAD/AAAA/wAAAP8AAACnAAAADf///wH///8BAAAABwAAAPUAAAD/AAAA7f///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BKCgoTwAAAP8AAAD/AAAA/wAAADn///8B////Af///wH///8B////AQAAAP8AAAD/AAAA/wAA
+        AJP///8B////Af///wH///8B////Af///wEAAABTAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAvwAAAD////8B////Af///wH///8BAAAAiQAA
+        AP8AAAD/AAAAZf///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAAKsAAAD/AAAA/wAAAEEAAABRAAAA/wAAAP8AAACX////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAAADAAAAOQAAAI8AAADhAAAA/wAAAP8AAAD/AAAA/wAAAP8AAADNAAAATf///wH///8B////Af//
+        /wEAAAAHAAAA9QAAAP8AAAD3AAAAkwAAAJMAAACTAAAAkwAAAJMAAACTAAAAkwAAAJMAAACTAAAAkwAA
+        AJMAAAAR////Af///wH///8B////Af///wH///8B////Af///wEoKChPAAAA/wAAAP8AAAD/AAAAOf//
+        /wH///8B////Af///wH///8BAAAA/wAAAP8AAAD/AAAAk////wH///8B////Af///wH///8B////AQAA
+        AFMAAAD/AAAA/wAAAOUAAAC9AAAAvQAAAL0AAAC9AAAAvQAAAL0AAAC9AAAAxwAAANsAAAD3AAAA/wAA
+        AP8AAAD/AAAA/QAAAIUAAAAD////Af///wEAAACJAAAA/wAAAP8AAABl////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAqwAAAP8AAAD/AAAAQQAA
+        AFEAAAD/AAAA/wAAAJf///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAAALAAAAbwAAANUAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        APcAAACrAAAARwAAAAP///8B////Af///wH///8B////AQAAAAcAAAD1AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAB3///8B////Af///wH///8B////Af//
+        /wH///8B////ASgoKE8AAAD/AAAA/wAAAP8AAAA5////Af///wH///8B////Af///wEAAAD/AAAA/wAA
+        AP8AAACT////Af///wH///8B////Af///wH///8BAAAAUwAAAP8AAAD/AAAAm////wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAAkAAABDAAAApwAAAP0AAAD/AAAA/wAAAIH///8B////AQAA
+        AIkAAAD/AAAA/wAAAGX///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAACrAAAA/wAAAP8AAABBAAAAUQAAAP8AAAD/AAAAl////wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAADAAAAZQAA
+        AOcAAAD/AAAA/wAAAP8AAAD/AAAA9QAAALEAAABfAAAAE////wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAABwAAAPUAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAAHf///wH///8B////Af///wH///8B////Af///wH///8BKCgoTwAAAP8AAAD/AAAA/wAA
+        ADn///8B////Af///wH///8B////AQAAAP8AAAD/AAAA/wAAAJP///8B////Af///wH///8B////Af//
+        /wEAAABTAAAA/wAAAP8AAACb////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAAUwAAAPsAAAD/AAAA+wAAACv///8BAAAAiQAAAP8AAAD/AAAAZf///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAKsAAAD/AAAA/wAA
+        AEEAAABRAAAA/wAAAP8AAACX////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAABwAAAKkAAAD/AAAA/wAAAP8AAAD9AAAAxQAAAGMAAAAR////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAAHAAAA9QAAAP8AAADvAAAADwAA
+        AA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAD////Af///wH///8B////Af//
+        /wH///8B////Af///wEoKChPAAAA/wAAAP8AAAD/AAAAOf///wH///8B////Af///wH///8BAAAA/wAA
+        AP8AAAD/AAAAk////wH///8B////Af///wH///8B////AQAAAFMAAAD/AAAA/wAAAJv///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAhwAAAP8AAAD/AAAAl///
+        /wEAAACJAAAA/wAAAP8AAABl////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAAqwAAAP8AAAD/AAAAQQAAAFEAAAD/AAAA/wAAAJf///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAACdAAAA/wAA
+        AP8AAAD/AAAAtwAAADX///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAAAcAAAD1AAAA/wAAAO3///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////ASgoKE8AAAD/AAAA/wAA
+        AP8AAAA5////Af///wH///8B////Af///wEAAAD/AAAA/wAAAP8AAACT////Af///wH///8B////Af//
+        /wH///8BAAAAUwAAAP8AAAD/AAAAm////wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAAAdAAAA/QAAAP8AAADdAAAAAwAAAIkAAAD/AAAA/wAAAGX///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAACrAAAA/wAA
+        AP8AAABBAAAAUQAAAP8AAAD/AAAAl////wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAAOQAAAP8AAAD/AAAA/QAAAHP///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAABwAAAPUAAAD/AAAA7f//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BKCgoTwAAAP8AAAD/AAAA/wAAADn///8B////Af///wH///8B////AQAA
+        AP8AAAD/AAAA/wAAAJP///8B////Af///wH///8B////Af///wEAAABTAAAA/wAAAP8AAACb////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAAMAAADhAAAA/wAA
+        AP0AAAALAAAAiQAAAP8AAAD/AAAAZf///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAKsAAAD/AAAA/wAAAEEAAABRAAAA/wAAAP8AAACX////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAACVAAAA/wAA
+        AP8AAACZ////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAAAHAAAA9QAAAP8AAADt////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEoKChPAAAA/wAA
+        AP8AAAD/AAAAOf///wH///8B////Af///wH///8BAAAA/wAAAP8AAAD/AAAAk////wH///8B////Af//
+        /wH///8B////AQAAAFMAAAD/AAAA/wAAAJv///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAANEAAAD/AAAA/wAAABcAAACJAAAA/wAAAP8AAABl////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAqwAA
+        AP8AAAD/AAAAQQAAAFEAAAD/AAAA/wAAAJf///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAMUAAAD/AAAA/wAAADP///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAAcAAAD1AAAA/wAA
+        AO3///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////ASgoKE8AAAD/AAAA/wAAAP8AAAA5////Af///wH///8B////Af//
+        /wEAAAD/AAAA/wAAAP8AAACT////Af///wH///8B////Af///wH///8BAAAAUwAAAP8AAAD/AAAAm///
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAADAAAA3wAA
+        AP8AAAD/AAAADwAAAIkAAAD/AAAA/wAAAGX///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAACrAAAA/wAAAP8AAABBAAAAUQAAAP8AAAD/AAAAl///
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAA1QAA
+        AP8AAAD7AAAAE////wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAAB7AAAAH////wH///8BAAAABwAAAPUAAAD/AAAA7f///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BKCgoTwAA
+        AP8AAAD/AAAA/wAAADn///8B////Af///wH///8B////AQAAAP8AAAD/AAAA/wAAAJP///8B////Af//
+        /wH///8B////Af///wEAAABTAAAA/wAAAP8AAACb////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAB0AAAD9AAAA/wAAAOcAAAADAAAAiQAAAP8AAAD/AAAAZf//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AKsAAAD/AAAA/wAAAEEAAABRAAAA/wAAAP8AAACX////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAADLAAAA/wAAAP0AAAAb////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAATQAAAP8AAAD5AAAAc////wEAAAAHAAAA9QAA
+        AP8AAADt////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEoKChPAAAA/wAAAP8AAAD/AAAAOf///wH///8B////Af//
+        /wH///8BAAAA/wAAAP8AAAD/AAAAk////wH///8B////Af///wH///8B////AQAAAFMAAAD/AAAA/wAA
+        AJv///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAjQAA
+        AP8AAAD/AAAAp////wEAAACJAAAA/wAAAP8AAABl////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAAqwAAAP8AAAD/AAAAQQAAAFEAAAD/AAAA/wAA
+        AJf///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AJkAAAD/AAAA/wAAAF3///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AAsAAADZAAAA/wAAAP8AAABN////AQAAAAcAAAD1AAAA/wAAAO3///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////ASgo
+        KE8AAAD/AAAA/wAAAP8AAAA5////Af///wH///8B////Af///wEAAAD/AAAA/wAAAP8AAACT////Af//
+        /wH///8B////Af///wH///8BAAAAUwAAAP8AAAD/AAAAm////wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAGcAAAD7AAAA/wAAAP0AAAA/////AQAAAIkAAAD/AAAA/wAA
+        AGX///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAACrAAAA/wAAAP8AAABBAAAAUQAAAP8AAAD/AAAAl////wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAAQQAAAP8AAAD/AAAA3QAAABP///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAAAHAAAArwAAAP8AAAD/AAAAxQAAAAP///8BAAAABwAA
+        APUAAAD/AAAA7f///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BKCgoTwAAAP8AAAD/AAAA/wAAADn///8B////Af//
+        /wH///8B////AQAAAP8AAAD/AAAA/wAAAJP///8B////Af///wH///8B////Af///wEAAABTAAAA/wAA
+        AP8AAACb////Af///wH///8B////Af///wH///8B////AQAAAAMAAAAFAAAAHwAAAF8AAADDAAAA/wAA
+        AP8AAAD/AAAAm////wH///8BAAAAiQAAAP8AAAD/AAAAZf///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAAKsAAAD/AAAA/wAAAEEAAABRAAAA/wAA
+        AP8AAACX////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAAswAAAP8AAAD/AAAA0wAAADH///8B////Af///wH///8B////Af///wH///8BAAAAKQAA
+        AMEAAAD/AAAA/wAAAPMAAAAp////Af///wEAAAAHAAAA9QAAAP8AAADtAAAAAwAAAAMAAAADAAAAAwAA
+        AAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAAD////Af///wH///8B////Af//
+        /wEoKChPAAAA/wAAAP8AAAD/AAAAOf///wH///8B////Af///wH///8BAAAA/wAAAP8AAAD/AAAAk///
+        /wH///8B////Af///wH///8B////AQAAAFMAAAD/AAAA/wAAAPEAAADbAAAA2wAAANsAAADbAAAA2wAA
+        ANsAAADbAAAA4QAAAPMAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAJ8AAAAH////Af///wEAAACJAAAA/wAA
+        AP8AAABl////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAAqwAAAP8AAAD/AAAAQQAAAFEAAAD/AAAA/wAAAJf///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAAVAAAA1wAAAP8AAAD/AAAA/QAA
+        ALsAAAB1AAAAUwAAAEUAAABVAAAAdwAAALkAAAD7AAAA/wAAAP8AAAD1AAAASf///wH///8B////AQAA
+        AAcAAAD1AAAA/wAAAP0AAADnAAAA6QAAAOkAAADpAAAA6QAAAOkAAADpAAAA6QAAAOkAAADpAAAA6QAA
+        AOkAAADpAAAA6QAAAM////8B////Af///wH///8B////ASgoKE8AAAD/AAAA/wAAAP8AAAA5////Af//
+        /wH///8B////Af///wEAAAD/AAAA/wAAAP8AAACT////Af///wH///8B////Af///wH///8BAAAAUwAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/QAA
+        AM0AAABN////Af///wH///8B////AQAAAIkAAAD/AAAA/wAAAGX///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAACrAAAA/wAAAP8AAABBAAAAUQAA
+        AP8AAAD/AAAAl////wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAAAVAAAAsQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA1QAAADP///8B////Af///wH///8BAAAABwAAAPUAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA4////wH///8B////Af//
+        /wH///8BKCgoTwAAAP8AAAD/AAAA/wAAADn///8B////Af///wH///8B////AQAAAP8AAAD/AAAA/wAA
+        AJP///8B////Af///wH///8B////Af///wEAAABFAAAA0QAAANEAAADRAAAA0QAAANEAAADRAAAA0QAA
+        ANEAAADRAAAA0QAAAMcAAAC3AAAAmwAAAG0AAAAr////Af///wH///8B////Af///wH///8BAAAAVQAA
+        AJkAAACZAAAAPf///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAAGkAAACZAAAAmQAAACkAAAAxAAAAmQAAAJkAAABb////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAARQAA
+        ALMAAAD1AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD5AAAAwwAAAGMAAAAH////Af///wH///8B////Af//
+        /wEAAAAFAAAAyQAAANEAAADRAAAA0QAAANEAAADRAAAA0QAAANEAAADRAAAA0QAAANEAAADRAAAA0QAA
+        ANEAAADRAAAA0QAAANEAAAC7////Af///wH///8B////Af///wEoKChPAAAA/wAAAP8AAAD/AAAAOf//
+        /wH///8B////Af///wH///8BAAAA/wAAAP8AAAD/AAAAlf///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAAAsAAAA3AAAAVQAAAGEAAABTAAAAOQAA
+        ABH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////ASgoKE8AAAD/AAAA/wAAAP8AAAA5////Af///wH///8B////Af///wEAAAD/AAAA/wAA
+        AP8AAACV////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BJycnUQAAAP8AAAD/AAAA/wAA
+        ADn///8B////Af///wH///8B////AQAAAPcAAAD/AAAA/wAAALn///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEbGxtxAAAA/wAAAP8AAAD/FBQUMf///wH///8B////Af///wH///8BAAAAxQAA
+        AP8AAAD/AAAA+wAAACn///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BqqqqBQoKCtEAAAD/AAAA/wQE
+        BPOjo6MJ////Af///wH///8B////Af///wEAAAB1AAAA/wAAAP8AAAD/AAAAtQAAAAX///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEZGRlrAAAA/wAAAP8AAAD/EBAQqf///wH///8B////Af///wH///8B////AQAA
+        ABMAAADvAAAA/wAAAP8AAAD/AAAAnwAAAAn///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BHR0dXQICAvkAAAD/AAAA/wAA
+        AP0pKSk5////Af///wH///8B////Af///wH///8B////AQAAAGcAAAD/AAAA/wAAAP8AAAD/AAAA2QAA
+        AGsAAAAhAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAA
+        AA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAA
+        AA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAA
+        AA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAA
+        AA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAA
+        AA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAA
+        AA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAA
+        ABkAAAAZJiYmRwwMDLEAAAD9AAAA/wAAAP8AAAD/EBAQl////wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAAJkAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPsAAAD3AAAA9wAAAPcAAAD3AAAA9wAA
+        APcAAAD3AAAA9wAAAPcAAAD3AAAA9wAAAPcAAAD3AAAA9wAAAPcAAAD3AAAA9wAAAPcAAAD3AAAA9wAA
+        APcAAAD3AAAA9wAAAPcAAAD3AAAA9wAAAPcAAAD3AAAA9wAAAPcAAAD3AAAA9wAAAPcAAAD3AAAA9wAA
+        APcAAAD3AAAA9wAAAPcAAAD3AAAA9wAAAPcAAAD3AAAA9wAAAPcAAAD3AAAA9wAAAPcAAAD3AAAA9wAA
+        APcAAAD3AAAA9wAAAPcAAAD3AAAA9wAAAPcAAAD3AAAA9wAAAPcAAAD3AAAA9wAAAPcAAAD3AAAA9wAA
+        APcAAAD3AAAA9wAAAPcAAAD3AAAA9wAAAPcAAAD3AAAA9wAAAPcAAAD3AAAA9wAAAPcAAAD3AAAA9wAA
+        APcAAAD3AAAA9wAAAPcAAAD3AAAA9wAAAPcAAAD3AAAA9wAAAPcAAAD3AAAA9wAAAPcAAAD3AAAA9wAA
+        APcAAAD3AAAA9wAAAPcAAAD3AAAA9wAAAPcAAAD3AAAA/QAAAP0AAAD/AAAA/wAAAP8AAAD/AAAA/woK
+        CsFLS0sL////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAABQAAAIkAAAD9AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8ODg6rQkJCDf///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAD8AAADFAAAA/QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8KCgrTGxsbV///
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAAArAAAAdwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAA
+        AH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAA
+        AH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAA
+        AH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAA
+        AH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAA
+        AH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAA
+        AH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAA
+        AH8AAAB/AAAAfwAAAH0TExNpNjY2NcPDwwP///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgAAAAAAQAAAAIAAAEAIAAAAAAAACAEAAAA
+        AAAAAAAAAAAAAAAAAAD///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAAAUAAABNAAAAfwAAAH8AAAB/AAAAfwAA
+        AH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAA
+        AH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAA
+        AH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAA
+        AH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAA
+        AH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAA
+        AH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAA
+        AH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAA
+        AH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAA
+        AH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAA
+        AH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAA
+        AH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAA
+        AH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAA
+        AH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAA
+        AH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB/AAAAfwAAAH8AAAB3RUVFTY+P
+        jyfExMQH////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAAKwAAAIUAAADPAAAA+wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/EBAQ2SUlJZ1aWlo/1dXVA////wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAAAtAAAArQAAAPcAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/xYWFs06OjpV////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAAsAAACHAAAA+QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA9xQUFLtbW1sn////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAACEAAADPAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/BQUF8To6Ol3///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAACkAAADlAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD3NTU1df//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAACkAAADzAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        APcmJiaD////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAABcAAADfAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD3AAAAxQAAAMUAAADFAAAAxQAAAMUAAADFAAAAxQAAAMUAAADFAAAAxQAA
+        AMUAAADFAAAAxQAAAMUAAADFAAAAxQAAAMUAAADFAAAAxQAAAMUAAADFAAAAxQAAAMUAAADFAAAAxQAA
+        AMUAAADFAAAAxQAAAMUAAADFAAAAxQAAAMUAAADFAAAAxQAAAMUAAADFAAAAxQAAAMUAAADFAAAAxQAA
+        AMUAAADFAAAAxQAAAMUAAADFAAAAxQAAAMUAAADFAAAAxQAAAMUAAADFAAAAxQAAAMUAAADFAAAAxQAA
+        AMUAAADFAAAAxQAAAMUAAADFAAAAxQAAAMUAAADFAAAAxQAAAMUAAADFAAAAxQAAAMUAAADFAAAAxQAA
+        AMUAAADFAAAAxQAAAMUAAADFAAAAxQAAAMUAAADFAAAAxQAAAMUAAADFAAAAxQAAAMUAAADFAAAAxQAA
+        AMUAAADFAAAAxQAAAMUAAADFAAAAxQAAAMUAAADFAAAAxQAAAMUAAADFAAAAxQAAAMUAAADFAAAAxQAA
+        AMUAAADFAAAAxQAAAMUAAADFAAAAxQAAAMUAAADFAAAAxQAAAMUAAADFAAAAxQAAAMUAAADFAAAAxQAA
+        AMUAAADFAAAAxQAAAMUAAADFAAAAxQAAAMUAAADFAAAAxQAAAMUAAADFAAAAxQAAAMUAAADFAAAAxQAA
+        AMUAAADFAAAAxQAAAMUAAADFAAAAxQAAAMUAAADFAAAAxQAAAMUAAADFAAAAxQAAAMUAAADFAAAAxQAA
+        AMUAAADFAAAAxQAAAMUAAADFAAAAxQAAAMUAAADFAAAAxQAAAMUAAADFAAAAxQAAAMUAAADFAAAAxQAA
+        AMUAAADFAAAAxQAAAMUAAADFAAAAxQAAAMUAAADFAAAAxQAAAMUAAADFAAAAxQAAAMUAAADFAAAAxQAA
+        AMUAAADFAAAAxQAAAMUAAADFAAAAxQAAAMUAAADFAAAAxQAAAMUAAADFAAAAxQAAAMUAAADFAAAAxQAA
+        AMUAAADFAAAAxQAAAMUAAADFAAAAxQAAAMUAAADFAAAAxQAAAMUAAADFAAAAxQAAAMUAAADFAAAAxQAA
+        AMUAAADFAAAA1wAAANcAAADXAAAA1wcHB/8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA9zk5OV////8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAACzAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA8QAAAKUAAABJAAAAFf///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wGWlpYdPj4+WRsbG8MAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8GBgbvSkpKK////wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAABhAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAAtQAAACf///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BPj4+TwwMDNsAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/xQUFL/Z2dkD////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAAATAAAA4QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD7AAAAdwAAAAP///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wGBgYEZEhISuQAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/Pj4+Xf///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAAcQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD9AAAAaf///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AaSk
+        pA8UFBS3AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/xMTE9XOzs4F////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAACQAAANcAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAAif///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8Bh4eHFw0NDdkAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/R0dHSf///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAAD0AAAD9AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA0wAAAAv///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wFDQ0NFAAAA9wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/yMjI6P///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAACJAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAFf///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////ARsbG78AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8MDAzfv7+/Cf//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAvwAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAN8AAAAL////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wFAQEBTAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/3h4
+        eDH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAOUAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAACb////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BoaGhFwgICO8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP80NDRV////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAD9AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAAX////wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEZGRnNAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AQEBb////wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAEf///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAAD////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BIiIitwAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAG////8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPsAAAA7////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAAEQAAADkAAABdAAAAjQAAAKsAAAC3AAAAxwAAAMcAAADHAAAAvwAA
+        AKsAAACHAAAARwAAABX///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////ASYmJqkAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAABv////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD5AAAALf///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAAhQAAALsAAAC7AAAAuwAAALsAAAC7AAAAuwAAALsAAAC7AAAAuwAAALsAAAC7AAAAuwAA
+        ALsAAAC7AAAAuwAAALsAAAC7AAAAuwAAALsAAAC7AAAAuwAAALsAAAC7AAAAuwAAALsAAAC7AAAAuwAA
+        ALsAAAC7AAAAuwAAALsAAAC7AAAAuwAAALsAAAC7AAAAuwAAALsAAAC7AAAAuwAAALsAAAC7AAAAU///
+        /wEAAAAFAAAApQAAALsAAAC7AAAAuwAAALsAAAC7AAAAuwAAALsAAAC7AAAAuwAAALsAAAC7AAAAuQAA
+        ACX///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAABUAAABhAAAAtwAAAOcAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAADrAAAAsQAAAEv///8B////Af///wH///8B////Af///wH///8BAAAARwAA
+        AL0AAAC7AAAAuwAAALsAAAC7AAAAuwAAALsAAAC7AAAAuwAAALkAAAAn////AQAAADkAAAC7AAAAuwAA
+        ALsAAAC7AAAAuwAAALsAAAC7AAAAuwAAALsAAAC7AAAAuwAAALsAAACvAAAAE////wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAAB7AAAAuwAAALsAAAC7AAAAuwAAALsAAAC7AAAAuwAAALsAAAC7AAAAuwAA
+        ALsAAAC7AAAAZ////wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAABjAAAAuwAAALsAAAC7AAAAuwAAALsAAAC7AAAAuwAA
+        ALsAAAC7AAAAuwAAALsAAAC7AAAAgf///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEoKCibAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAAb////wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+QAAAC3///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAALEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AHP///8BAAAABwAAAOEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP0AAAAz////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAAJwAAAJ8AAADxAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD9AAAAzQAAAD////8B////Af///wH///8B////AQAA
+        AGEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD9AAAANf///wEAAABPAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA7QAAABn///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAAqwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAI////8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAAiQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAALH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BKCgomwAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAG////8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPkAAAAt////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAACxAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAABx////AQAAAAcAAADfAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD7AAAAMf///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAAAXAAAAmQAAAPsAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD9AAAAjwAAAA3///8B////Af//
+        /wEAAABfAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+wAAADP///8BAAAATQAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAO0AAAAZ////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAKkAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAACN////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAAIcAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAACx////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////ASgo
+        KJsAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABv////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD5AAAALf///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAAsQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAAcf///wEAAAAHAAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA+wAAADH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAABVAAAA5wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADDAAAAF///
+        /wH///8BAAAAXwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPsAAAAz////AQAA
+        AE0AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADtAAAAGf//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAACpAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAAjf///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAACHAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAsf///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEoKCibAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAb////wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+QAAAC3///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAALEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAHH///8BAAAABwAAAN8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAPsAAAAx////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AAMAAACDAAAA+wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        ANMAAAAT////AQAAAF8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD7AAAAM///
+        /wEAAABNAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA7QAA
+        ABn///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAAqQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAI3///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAhwAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAALH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BKCgomwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAG////8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPkAAAAt////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAACxAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAABx////AQAAAAcAAADfAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD7AAAAMf///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AAkAAACnAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAAvQAAAAcAAABfAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+wAA
+        ADP///8BAAAATQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AO0AAAAZ////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAAKkAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAACN////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAIcAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAACx////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////ASgoKJsAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABv////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD5AAAALf//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAAsQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAAcf///wEAAAAHAAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA+wAAADH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AAMAAACjAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAB3AAAAXwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        APsAAAAz////AQAAAE0AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAADtAAAAGf///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAACpAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAjf///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAACHAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAsf///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEoKCibAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAb////wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+QAA
+        AC3///8B////Af///wH///8B////Af///wH///8B////AQAAALEAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAHH///8BAAAABwAAAN8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPsAAAAx////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAACBAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA8QAAAHUAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD7AAAAM////wEAAABNAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA7QAAABn///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAqQAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAI3///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAhwAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAALH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BKCgomwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAG////8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        APkAAAAt////Af///wH///8B////Af///wH///8B////Af///wEAAACxAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABx////AQAAAAcAAADfAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD7AAAAMf///wH///8B////Af///wH///8B////Af//
+        /wEAAABPAAAA/QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADhAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA+wAAADP///8BAAAATQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAO0AAAAZ////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAKkAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAACN////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AIcAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAACx////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////ASgoKJsAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABv////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD5AAAALf///wH///8B////Af///wH///8B////Af///wH///8BAAAAsQAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAcf///wEAAAAHAAAA3wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+wAAADH///8B////Af///wH///8B////Af//
+        /wEAAAAXAAAA5QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPsAAADrAAAA3wAAAN8AAADfAAAA6wAAAPsAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAPsAAAAz////AQAAAE0AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAADtAAAAGf///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAACpAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAjf///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAACHAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAsf//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEoKCibAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAb///
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA+QAAAC3///8B////Af///wH///8B////Af///wH///8B////AQAAALEAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD9AAAA+QAAAPkAAAD5AAAA+QAA
+        APkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAA
+        APkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAG////8BAAAABwAAAN8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPsAAAAx////Af///wH///8B////Af//
+        /wH///8BAAAAlwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD9AAAAxQAAAGsAAAAzAAAAEf///wH///8B////AQAAABEAAAA3AAAAcQAA
+        AM0AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD7AAAAM////wEAAABNAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA7QAAABn///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAqQAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAI3///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAAhwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        ALH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BKCgomwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AG////8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAPkAAAAt////Af///wH///8B////Af///wH///8B////Af///wEAAACxAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAApwAAAB8AAAAfAAAAHwAA
+        AB8AAAAfAAAAHwAAAB8AAAAfAAAAHwAAAB8AAAAfAAAAHwAAAB8AAAAfAAAAHwAAAB8AAAAfAAAAHwAA
+        AB8AAAAfAAAAHwAAAB8AAAAfAAAAHwAAAB8AAAAfAAAAHwAAACEAAAAP////AQAAAAcAAADfAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD7AAAAMf///wH///8B////Af//
+        /wH///8BAAAALwAAAP0AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAADJAAAAPwAAAAP///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAAAHAAAATwAAAN8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA+wAAADP///8BAAAATQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAO0AAAAZ////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AKkAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAACN////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAAIcAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAACx////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////ASgoKJsAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAABv////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD5AAAALf///wH///8B////Af///wH///8B////Af///wH///8BAAAAsQAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAJ////8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAAHAAAA3wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+wAAADH///8B////Af//
+        /wH///8B////AQAAAKsAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP0AAACJAAAABf///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAAATAAAAsQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPsAAAAz////AQAAAE0AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADtAAAAGf///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAACpAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAjf//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAACHAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAAsf///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEoKCibAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAAb////wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA+QAAAC3///8B////Af///wH///8B////Af///wH///8B////AQAA
+        ALEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAACf////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAABwAA
+        AN8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPsAAAAx////Af//
+        /wH///8B////AQAAACsAAAD3AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP0AAAB5////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAAkAAACvAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD7AAAAM////wEAAABNAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA7QAAABn///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAAqQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AI3///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAAhwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAALH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BKCgomwAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAG////8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPkAAAAt////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAACxAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAn///
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AAcAAADfAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD7AAAAMf//
+        /wH///8B////Af///wEAAACPAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAACD////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAADwAAANUAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+wAAADP///8BAAAATQAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAO0AAAAZ////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAAKkAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAACN////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAIcAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAACx////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////ASgoKJsAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAABv////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD5AAAALf///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAAsQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AJ////8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAAAHAAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+wAA
+        ADH///8B////Af///wEAAAANAAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAC7AAAABf///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAA5AAAA+QAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPsAAAAz////AQAAAE0AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADtAAAAGf///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAACpAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAAjf///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAACHAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAAsf///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEoKCibAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAAb////wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+QAAAC3///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAALEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAACf////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAABwAAAN8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        APsAAAAx////Af///wH///8BAAAAQQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD1AAAAL////wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAKkAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD7AAAAM////wEAAABNAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA7QAAABn///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAAqQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAI3///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAAhwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAALH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BKCgomwAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAG////8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPkAAAAt////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAACxAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAAn////wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAAAcAAADfAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD7AAAAMf///wH///8B////AQAAAJMAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAAmf///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAA9AAAA/QAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+wAAADP///8BAAAATQAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAO0AAAAZ////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAKkAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAACN////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAAIcAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAACx////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////ASgo
+        KJsAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABv////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD5AAAALf///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAAsQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAJ////8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAAAHAAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA+wAAADH///8B////AQAAAAUAAADLAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/QAAACv///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAABwAA
+        ANcAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPsAAAAz////AQAA
+        AE0AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADtAAAAGf//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAACpAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAAjf///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAACHAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAsf///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEoKCibAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAb////wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+QAAAC3///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAALEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAACf////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAABwAAAN8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAPsAAAAx////Af///wEAAAAZAAAA+wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAL////8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAACXAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD7AAAAM///
+        /wEAAABNAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA7QAA
+        ABn///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAAqQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAI3///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAhwAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAALH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BKCgomwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAG////8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPkAAAAt////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAACxAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAAn////wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAAcAAADfAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD7AAAAMf///wH///8BAAAARQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABt////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAABpAAAAkQAAAJEAAACRAAAAkQAAAJEAAACRAAAAkQAA
+        AJEAAACRAAAAvwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+wAA
+        ADP///8BAAAATQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AO0AAAAZ////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAAKkAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAACN////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAIcAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAACx////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////ASgoKJsAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABv////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD5AAAALf//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAAsQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAJ////8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAAAHAAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA+wAAADH///8B////AQAAAH8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAJf///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAAtQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        APsAAAAz////AQAAAE0AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAADtAAAAGf///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAACpAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAjf///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAACHAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAsf///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEoKCibAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAb////wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+QAA
+        AC3///8B////Af///wH///8B////Af///wH///8B////AQAAALEAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAACf////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAABwAAAN8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPsAAAAx////Af///wEAAACnAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA2wAAAAn///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAALUAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD7AAAAM////wEAAABNAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA7QAAABn///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAqQAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAI3///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAhwAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAALH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BKCgomwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAG////8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        APkAAAAt////Af///wH///8B////Af///wH///8B////Af///wEAAACxAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAn////wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAAAcAAADfAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD7AAAAMf///wH///8BAAAAyQAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAK////8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAC1AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA+wAAADP///8BAAAATQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAO0AAAAZ////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAKkAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAACN////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AIcAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAACx////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////ASgoKJsAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABv////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD5AAAALf///wH///8B////Af///wH///8B////Af///wH///8BAAAAsQAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAJ////8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAAHAAAA3wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+wAAADH///8B////AQAAAOkAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAACJ////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAtQAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAPsAAAAz////AQAAAE0AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAADtAAAAGf///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAACpAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAjf///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAACHAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAsf//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEoKCibAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAb///
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA+QAAAC3///8B////Af///wH///8B////Af///wH///8B////AQAAALEAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAC3AAAASwAAAEsAAABLAAAASwAA
+        AEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAA
+        AB////8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAABwAAAN8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPsAAAAx////AQAAAAkAAAD3AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAYf///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAALUAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD7AAAAM////wEAAABNAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA8QAAAFcAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAA
+        AEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAAvwAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAI3///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAAhwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        ALH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BKCgomwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AG////8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAPkAAAAt////Af///wH///8B////Af///wH///8B////Af///wEAAACxAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAABr////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAAcAAADfAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD7AAAAMf///wEAAAAbAAAA+QAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAEX///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAC1AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA+wAAADP///8BAAAATQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAACN////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAAIcAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAACx////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////ASgoKJsAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAABv////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD5AAAALf///wH///8B////Af///wH///8B////Af///wH///8BAAAAsQAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAAZf///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAAHAAAA3wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+wAAADH///8BAAAALwAA
+        APsAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAA7////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAtQAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPsAAAAz////AQAAAE0AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAjf//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAACHAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAAsf///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEoKCibAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAAb////wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA+QAAAC3///8B////Af///wH///8B////Af///wH///8B////AQAA
+        ALEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAGX///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAABwAA
+        AN8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPsAAAAx////AQAA
+        ADUAAAD9AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD7AAAAKf//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        ALUAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD7AAAAM////wEAAABNAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AI3///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAAhwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAALH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BKCgomwAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAG////8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPkAAAAt////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAACxAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAABl////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AAcAAADfAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD7AAAAMf//
+        /wEAAAA1AAAA/QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+wAA
+        ACn///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAAC3AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/QAAADX///8BAAAATQAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAACN////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAIcAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAACx////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////ASgoKJsAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAABv////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD5AAAALf///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAAsQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAAZf///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAAAHAAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+wAA
+        ADH///8BAAAANQAAAP0AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        APsAAAAp////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAAOQAAAFEAAABRAAAAUQAAAFEAAABRAAAAUQAAAFEAAABRAAAAUQAAAFEAAABRAAAAUQAA
+        AFEAAABRAAAAUQAAAFEAAABRAAAAUQAAAFEAAABRAAAAUQAAAFEAAAAR////AQAAAE0AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAAjf///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAACHAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAAsf///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEoKCibAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAAb////wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+QAAAC3///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAALEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAGX///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAABwAAAN8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        APsAAAAx////AQAAADUAAAD9AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD7AAAAKf///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAABNAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAI3///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAAhwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAALH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BKCgomwAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAG////8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPkAAAAt////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAACxAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABl////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAAAcAAADfAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD7AAAAMf///wEAAAA1AAAA/QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA+wAAACn///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAATQAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAACN////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAAIcAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAACx////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////ASgo
+        KJsAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABv////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD5AAAALf///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAAsQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAZf///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAAAHAAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA+wAAADH///8BAAAAIQAAAPkAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAA3////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AE0AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAAjf///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAACHAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAsf///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEoKCibAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAb////wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+QAAAC3///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAALEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAGX///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAABwAAAN8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAPsAAAAx////AQAAABMAAAD5AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAAQ////wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAABNAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAI3///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAhwAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAALH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BKCgomwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAG////8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPkAAAAt////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAACxAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABr////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAAcAAADfAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD7AAAAMf///wH///8BAAAA8wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAGP///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAATQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAACN////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAIcAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAACx////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////ASgoKJsAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABv////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD5AAAALf//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAAsQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAALUAAABFAAAARQAAAEUAAABFAAAARQAAAEUAAABFAAAARQAA
+        AEUAAABFAAAARQAAAEUAAABFAAAARQAAAEUAAABFAAAARQAAAEUAAABFAAAAHf///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAAAHAAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA+wAAADH///8B////AQAAANMAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAACN////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAAE0AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD9AAAA4QAAAN8AAADfAAAA3wAAAN8AAADfAAAA3wAAAN8AAADfAAAA3wAAAN8AAADfAAAA3wAA
+        AN8AAADfAAAA3wAAAN8AAADfAAAA3wAAAN8AAADfAAAA3wAAAN8AAAD1AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAjf///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAACHAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAsf///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEoKCibAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAb////wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+QAA
+        AC3///8B////Af///wH///8B////Af///wH///8B////AQAAALEAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAACf////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAABwAAAN8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPsAAAAx////Af///wEAAACtAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAs////wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAABNAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA7QAAACMAAAANAAAADQAAAA0AAAANAAAADQAAAA0AAAANAAAADQAAAA0AAAANAAAADQAA
+        AA0AAAANAAAADQAAAA0AAAANAAAADQAAAA0AAAANAAAADQAAAA0AAAANAAAArQAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAI3///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAhwAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAALH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BKCgomwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAG////8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        APkAAAAt////Af///wH///8B////Af///wH///8B////Af///wEAAACxAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAn////wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAAAcAAADfAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD7AAAAMf///wH///8BAAAAfwAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAOMAAAAN////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAAANAAAAPwAAAA////8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAATQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAO0AAAAZ////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAKkAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAACN////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AIcAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAACx////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////ASgoKJsAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABv////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD5AAAALf///wH///8B////Af///wH///8B////Af///wH///8BAAAAsQAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAJ////8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAAHAAAA3wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+wAAADH///8B////AQAAAFEAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAMf///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAARwAAAP8AAADvAAAAswAAAG8AAAAtAAAACf///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAE0AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAADtAAAAGf///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAACpAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAjf///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAACHAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAsf//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEoKCibAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAb///
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA+QAAAC3///8B////Af///wH///8B////Af///wH///8B////AQAAALEAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAACf////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAABwAAAN8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPsAAAAx////Af///wEAAAAXAAAA+QAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAIX///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAKEAAAD/AAAA/wAAAP8AAAD/AAAA+wAAANkAAACjAAAAVQAA
+        ABv///8B////Af///wH///8B////Af///wEAAABNAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA7QAAABn///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAqQAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAI3///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAAhwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        ALH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BKCgomwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AG////8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAPkAAAAt////Af///wH///8B////Af///wH///8B////Af///wEAAACxAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAn////wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAAcAAADfAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD7AAAAMf///wH///8BAAAABQAA
+        AMkAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADdAAAABf//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAABcAAADvAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAADzAAAAzQAAAIEAAABBAAAAA////wH///8BAAAATQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAO0AAAAZ////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AKkAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAACN////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAAIcAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAACx////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////ASgoKJsAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAABv////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD5AAAALf///wH///8B////Af///wH///8B////Af///wH///8BAAAAsQAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAJ////8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAAHAAAA3wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+wAAADH///8B////Af//
+        /wEAAACJAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AFP///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAABtAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA6wAAAA3///8B////AQAAAE0AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADtAAAAGf///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAACpAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAjf//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAACHAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAAsf///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEoKCibAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAAb////wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA+QAAAC3///8B////Af///wH///8B////Af///wH///8B////AQAA
+        ALEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAACf////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAABwAA
+        AN8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPsAAAAx////Af//
+        /wH///8BAAAANQAAAP0AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAADRAAAAB////wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAAAJAAAA5QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAK3///8B////Af///wEAAABNAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA7QAAABn///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAAqQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AI3///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAAhwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAALH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BKCgomwAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAG////8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPkAAAAt////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAACxAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAn///
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AAcAAADfAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD7AAAAMf//
+        /wH///8B////AQAAAAcAAADRAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAHX///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAAdwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABd////Af///wH///8BAAAATQAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAO0AAAAZ////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAAKkAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAACN////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAIcAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAACx////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////ASgoKJsAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAABv////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD5AAAALf///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAAsQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AJ////8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAAAHAAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+wAA
+        ADH///8B////Af///wH///8BAAAAbwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD1AAAAO////wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAAKQAAAPEAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADtAAAAG////wH///8B////AQAAAE0AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADtAAAAGf///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAACpAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAAjf///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAACHAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAAsf///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEoKCibAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAAb////wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+QAAAC3///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAALEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAACf////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAABwAAAN8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        APsAAAAx////Af///wH///8B////AQAAABUAAADtAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAOkAAAA1////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAAEQAAAM0AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAp////wH///8B////Af///wEAAABNAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA7QAAABn///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAAqQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAI3///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAAhwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAALH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BKCgomwAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAG////8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPkAAAAt////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAACxAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAAn////wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAAAcAAADfAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD7AAAAMf///wH///8B////Af///wH///8BAAAAgQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA6wAAAEv///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAAFwAAAL8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/QAAAEH///8B////Af///wH///8BAAAATQAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAO0AAAAZ////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAKkAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAACN////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAAIcAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAACx////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////ASgo
+        KJsAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABv////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD5AAAALf///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAAsQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAKcAAAAZAAAAGQAAABkAAAAZAAAAGQAAABkAAAAZAAAAGQAAABkAAAAZAAAAGQAA
+        ABkAAAAZAAAAGQAAABkAAAAZAAAAGQAAABkAAAAZAAAAGQAAABkAAAAZAAAAGQAAABkAAAAZAAAAGQAA
+        ABkAAAAD////Af///wEAAAAHAAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA+wAAADH///8B////Af///wH///8B////AQAAABEAAADlAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD5AAAAmwAAAB3///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAAQwAAAN8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAMMAAAAD////Af///wH///8B////AQAA
+        AE0AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADtAAAAGf//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAACpAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAAjf///wEAAAAHAAAAGwAAABkAAAAZAAAAGQAAABkAAAAZAAAAGQAA
+        ABkAAAAZAAAAGQAAABkAAAAZAAAAGQAAABkAAAAZAAAAGQAAABkAAACTAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAtwAAABcAAAAZAAAAGQAAABkAAAAZAAAAGQAA
+        ABkAAAAZAAAAGQAAABkAAAAZAAAAGQAAABn///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEoKCibAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAb////wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+QAAAC3///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAALEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD9AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAA
+        APkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAA
+        APkAAADnAAAAF////wH///8BAAAABwAAAN8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAPsAAAAx////Af///wH///8B////Af///wH///8BAAAAWwAAAP0AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD1AAAAqQAA
+        AFUAAAAZAAAADQAAAAcAAAAHAAAADQAAAB8AAABfAAAAwQAAAP0AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABF////Af///wH///8B////Af//
+        /wEAAABNAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA7QAA
+        ABn///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAAqQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAI3///8BAAAAPwAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAA
+        APkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA/QAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP0AAAD5AAAA+QAAAPkAAAD5AAAA+QAA
+        APkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAADp////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BKCgomwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAG////8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPkAAAAt////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAACxAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA6wAAABf///8B////AQAAAAcAAADfAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD7AAAAMf///wH///8B////Af///wH///8B////AQAAAAMAAACvAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAOkAAADVAAAA0wAAAOkAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAC3////Af///wH///8B////Af//
+        /wH///8BAAAATQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AO0AAAAZ////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAAKkAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAACN////AQAAAEEAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA7////wH///8B////Af///wH///8B////Af//
+        /wH///8B////ASgoKJsAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABv////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD5AAAALf//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAAsQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAOsAAAAX////Af///wEAAAAHAAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA+wAAADH///8B////Af///wH///8B////Af///wH///8BAAAAGwAA
+        AOEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADvAAAAI////wH///8B////Af//
+        /wH///8B////AQAAAE0AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAADtAAAAGf///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAACpAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAjf///wEAAABBAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAO////8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEoKCibAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAb////wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+QAA
+        AC3///8B////Af///wH///8B////Af///wH///8B////AQAAALEAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAADrAAAAF////wH///8BAAAABwAAAN8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPsAAAAx////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAAA3AAAA8wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAbf///wH///8B////Af//
+        /wH///8B////Af///wEAAABNAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA7QAAABn///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAqQAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAI3///8BAAAAQQAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADv////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BKCgomwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAG////8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        APkAAAAt////Af///wH///8B////Af///wH///8B////Af///wEAAACxAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA6wAAABf///8B////AQAAAAcAAADfAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD7AAAAMf///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAAEsAAAD1AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAnf///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAATQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAO0AAAAZ////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAKkAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAACN////AQAAAEEAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA7////wH///8B////Af//
+        /wH///8B////Af///wH///8B////ASgoKJsAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABv////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD5AAAALf///wH///8B////Af///wH///8B////Af///wH///8BAAAAsQAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAOsAAAAX////Af///wEAAAAHAAAA3wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+wAAADH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAASwAAAPEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAuwAAAAn///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAE0AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAADtAAAAGf///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAACpAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAjf///wEAAABBAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAO////8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEoKCibAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAb///
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA+QAAAC3///8B////Af///wH///8B////Af///wH///8B////AQAAALEAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADrAAAAF////wH///8BAAAABwAAAN8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPsAAAAx////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAAA7AAAA4QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAswAAAA////8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAABNAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA7QAAABn///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAqQAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAI3///8BAAAAQQAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADv////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BKCgomwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AG////8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAPkAAAAt////Af///wH///8B////Af///wH///8B////Af///wEAAACxAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA6wAAABf///8B////AQAAAAcAAADfAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD7AAAAMf///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAABcAAACzAAAA/QAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD7AAAAjQAAAAf///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAATQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAO0AAAAZ////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AKkAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAACN////AQAA
+        AEEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA7///
+        /wH///8B////Af///wH///8B////Af///wH///8B////ASgoKJsAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAABv////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD5AAAALf///wH///8B////Af///wH///8B////Af///wH///8BAAAAsQAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAOsAAAAX////Af///wEAAAAHAAAA3wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+wAAADH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAFsAAADdAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAS////wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAAE0AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADtAAAAGf///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAACpAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAjf//
+        /wEAAABBAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AO////8B////Af///wH///8B////Af///wH///8B////Af///wEoKCibAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAAb////wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA+QAAAC3///8B////Af///wH///8B////Af///wH///8B////AQAA
+        ALEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADrAAAAF////wH///8BAAAABwAA
+        AN8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPsAAAAx////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAADwAA
+        AG8AAADXAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAOMAAAB1AAAAEf///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAABNAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA7QAAABn///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAAqQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AI3///8BAAAAQQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAADv////Af///wH///8B////Af///wH///8B////Af///wH///8BKCgomwAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAG////8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPkAAAAt////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAACxAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA6wAAABf///8B////AQAA
+        AAcAAADhAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD9AAAAM///
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAACwAAAEsAAACpAAAA7wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD5AAAAtwAAAF8AAAAP////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAATwAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAO0AAAAZ////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAAKsAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAACP////AQAAAEEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA7////wH///8B////Af///wH///8B////Af///wH///8B////ASgoKJsAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAABv////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD5AAAALf///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAABwAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAA
+        AAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAA
+        AAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAn///8B////Af//
+        /wH///8BAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAA
+        AAP///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAAkAAAA/AAAAdwAAAKcAAADTAAAA7QAAAPEAAAD1AAAA+QAA
+        APcAAAD1AAAA8QAAAO0AAADbAAAAswAAAIUAAABNAAAAEf///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAAMAAAAJAAAACQAA
+        AAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJ////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAAAHAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAA
+        AAkAAAAJAAAABf///wEAAAADAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAA
+        AAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAA
+        AAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAA
+        AAkAAAAJAAAACQAAAAn///8B////Af///wH///8B////Af///wH///8B////Af///wEoKCibAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAAb////wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+QAAAC3///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAATAAAAIQAA
+        ACsAAAArAAAAIwAAABEAAAAH////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BKCgomwAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAG////8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPkAAAAr////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AScn
+        J5sAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABv////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD7AAAAOf///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEmJiapAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAb////wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+QAAAC3///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BKCgomwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAG////8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPkAAAAp////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////ASYmJpkAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABv////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAADvAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD9AAAAlf//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AZWVlRkNDQ3jAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/GRkZYf///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAAtwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AOMAAAAP////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wE/Pz9bAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/4eHhyn///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAAIUAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAAX////wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BGhoaxQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/w0NDd2/v78J////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAA1AAAA+wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAANsAAAAN////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BQUFBUQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8lJSWZ////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAABQAAAM8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAAmf///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8Bbm5uHQsLC98AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/VlZWQf//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAABpAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAB1////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BoKCgERISEsUAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/FhYWzdLS
+        0gX///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAACwAA
+        AN0AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAIkAAAAJ////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BY2NjHw8PD8cAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA9zs7
+        O0////8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAABPAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAxQAAAEX///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wG0tLQLKioqbQoKCuEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/xYW
+        FrP///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAAKMAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD9AAAA+wAA
+        AP8AAAD/AAAA+wAAAPsAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAA
+        APkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAA
+        APkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAA
+        APkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAA
+        APkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAA
+        APkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAA
+        APkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAA
+        APkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAA
+        APkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAA
+        APkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAA
+        APkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAA
+        APkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+wAAAPsAAAD7AAAA+wAA
+        APsAAAD7AAAA+wAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAA
+        APkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPsAAAD7AAAA+wAAAPsAAAD7AAAA+wAA
+        APsAAAD7AAAA8xEREdsUFBTVBAQE6wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wgI
+        COVlZWUf////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAAARAAAA0QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wIC
+        AvVBQUFN////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAACEAAADjAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        APc6Ojpp////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAAJwAAANkAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        APc6Ojpl////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAABlAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8YGBjFv7+/Cf///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAABdAAAA+wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/xQUFK+9vb0J////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAABXAAAA+QAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/GBgYrcrKygf///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAA1AAAA9QAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8hISGR////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAANAAAA2wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAM8AAAB9AAAAfQAAAH8AAAB5AAAAeQAAAHkAAAB5AAAAeQAA
+        AHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAA
+        AHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAA
+        AHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAA
+        AHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAA
+        AHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAA
+        AHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAA
+        AHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAA
+        AHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAA
+        AHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAA
+        AHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAA
+        AHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAA
+        AHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAA
+        AHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAA
+        AHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAAAHkAAABxWVlZQ3FxcTchISF9BwcH5QAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA9zIyMk////8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAiQAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA8wAAAHUAAAAH////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AWlp
+        aR8dHR2tAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8LCwvfn5+fEf///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAJwAAAPMAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA6wAAADv///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B2NjYAywsLIEAAAD3AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/ygoKH3///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAJEAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA8QAAADP///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BKCgohQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8KCgrhlpaWE///
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAABMAAADnAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAFv///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Adra2gMSEhK3AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/zk5
+        OWH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAABNAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAALMAAAAD////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BZ2dnKQMDA/MAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8fHx+5////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAmQAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPsAAAA7////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wElJSWfAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/BQUF8ba2thP///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AMsAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADPAAAAA////wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BWVlZQQAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP9lZWU7////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAADtAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAh////wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Abi4uAsNDQ3fAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/IiIiX////wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAFf///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BHBwcxQAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAG////8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABF////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////ASIi
+        IrUAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABv////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD7AAAAM////wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAAAsAAAAjAAAARwAAAGcAAACBAAAAhwAA
+        AIcAAACHAAAAhwAAAG8AAABXAAAAKwAAAA8AAAAD////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AAMAAAANAAAAEwAAACcAAAAvAAAALwAAAC8AAAAhAAAAEwAAAAsAAAAD////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEnJyejAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAb////wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+QAAAC3///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAFwAAACMAAAAjAAAAIwAA
+        ACMAAAAjAAAACf///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAAAjAAAAaQAAALEAAADnAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADzAAAAuwAAAH8AAAAvAAAAA////wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAXQAAAIsAAACLAAAAiwAA
+        AIsAAACLAAAAiwAAAIsAAACLAAAAiwAAAIsAAACLAAAAiwAAAIsAAACLAAAAiwAAAIsAAACLAAAAiwAA
+        AIsAAACLAAAAiwAAAIsAAACLAAAAiwAAAIsAAACLAAAAiwAAAIsAAACLAAAAiwAAAIsAAACLAAAAiwAA
+        AI0AAAAv////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAAjAAAAXQAA
+        AJsAAADFAAAA6QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP0AAADlAAAAwwAAAJcAAABbAAAAI///
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAAwAA
+        ACEAAAAjAAAAIwAAACMAAAAjAAAAIwAAACMAAAAjAAAAIwAAACMAAAAjAAAAIwAAACMAAAAjAAAAIwAA
+        ACMAAAAjAAAAIwAAACMAAAAjAAAAIwAAACMAAAAjAAAAIwAAACMAAAAjAAAAIwAAACMAAAAjAAAAIwAA
+        ACMAAAAjAAAAIwAAACMAAAAjAAAAIwAAACMAAAAP////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BKCgomwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAG////8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPkAAAAt////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAKMAAAD5AAAA+QAA
+        APkAAAD5AAAA+QAAADn///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAD0AAACtAAAA9QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+QAAAMcAAABVAAAABf//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAKMAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAAV////wH///8B////Af///wH///8B////Af///wH///8BAAAACQAAAFsAAADBAAAA9QAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        APcAAADFAAAAZwAAABP///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AA0AAADnAAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAA
+        APkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAA
+        APkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD7AAAAa////wH///8B////Af///wH///8B////Af//
+        /wH///8B////ASgoKJsAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABv////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD5AAAALf//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAClAAAA/wAA
+        AP8AAAD/AAAA/wAAAP0AAAA5////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAAJwAAALMAAAD5AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AM8AAAA/////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAChAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAFf///8B////Af///wH///8B////Af///wEAAAAFAAAAZQAAANsAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAADpAAAAewAAAA////8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAAANAAAA6wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAG3///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEoKCibAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAb////wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+QAA
+        AC3///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAApQAA
+        AP8AAAD/AAAA/wAAAP8AAAD9AAAAOf///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAAADAAAAYQAAAPMAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA+wAAAIsAAAAJ////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAoQAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAABX////Af///wH///8B////Af///wEAAAAxAAAAzQAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADjAAAATf///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAADQAAAOsAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABt////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BKCgomwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAG////8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        APkAAAAt////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AKUAAAD/AAAA/wAAAP8AAAD/AAAA/QAAADn///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAAADAAAAkQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD5AAAA3wAAAMsAAADBAAAAsQAAAL0AAADDAAAA0wAAAOsAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAAtwAAABf///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AKEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAAV////wH///8B////Af///wEAAABtAAAA8wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+QAAAOcAAADnAAAA5wAAAPMAAAD9AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP0AAACLAAAAB////wH///8B////Af//
+        /wH///8B////AQAAAA0AAADrAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAbf///wH///8B////Af//
+        /wH///8B////Af///wH///8B////ASgoKJsAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABv////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD5AAAALf///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAAClAAAA/wAAAP8AAAD/AAAA/wAAAP0AAAA5////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAAADAAAAlQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA8wAA
+        AKUAAABZAAAAJQAAAAv///8B////Af///wH///8B////AQAAAAMAAAAVAAAANwAAAHkAAADHAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADTAAAAEf///wH///8B////Af///wH///8B////Af//
+        /wEAAAChAAAA/wAAAP8AAAD/AAAA/wAAAP8AAADbAAAA0wAAANMAAADTAAAA0wAAANMAAADTAAAA0wAA
+        ANMAAADTAAAA0wAAANMAAADTAAAA0wAAANMAAADTAAAA0wAAANMAAADTAAAA0wAAANMAAADTAAAA0wAA
+        ANMAAADTAAAA0wAAANMAAADTAAAA1QAAAEn///8B////AQAAAAMAAACJAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA1wAAAJcAAABXAAAAMQAAACMAAAATAAAAEwAAABMAAAAdAAAAKQAA
+        AEUAAAB3AAAArwAAAO8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAKcAAAAH////Af//
+        /wH///8B////Af///wEAAAANAAAA6wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAG////8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEoKCibAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAb///
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA+QAAAC3///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAApQAAAP8AAAD/AAAA/wAAAP8AAAD9AAAAOf///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAAgQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADzAAAAgQAA
+        ABf///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAABQAA
+        AD0AAAC7AAAA/QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAALsAAAAH////Af///wH///8B////Af//
+        /wH///8BAAAAoQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAMwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAA
+        AAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAA
+        AAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAD////Af///wEAAACLAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAPsAAACpAAAAOQAAAAf///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAAARAAAAXwAAAMsAAAD9AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAnf//
+        /wH///8B////Af///wH///8BAAAADQAAAOsAAAD/AAAA/wAAAP8AAAD/AAAA5QAAAEcAAABLAAAASwAA
+        AEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAA
+        AEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAAAf////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BKCgomwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AG////8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAPkAAAAt////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAAKUAAAD/AAAA/wAAAP8AAAD/AAAA/QAAADn///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAARQAAAPkAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADBAAAAJf//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAAGEAAADvAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAi////wH///8B////Af//
+        /wH///8B////AQAAAKEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAC3///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAABvAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAMEAAAAv////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAAYwAAAO0AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAABn////Af///wH///8B////AQAAAA0AAADrAAAA/wAAAP8AAAD/AAAA/wAAANv///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////ASgoKJsAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAABv////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD5AAAALf///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAAClAAAA/wAAAP8AAAD/AAAA/wAAAP0AAAA5////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAADwAAANsAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAACjAAAAC///
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAALwAAAOMAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPkAAAA5////Af//
+        /wH///8B////Af///wEAAAChAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAAt////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAA5AAAA9QAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/QAAAH8AAAAH////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAAjAAAA1QAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA7wAAACH///8B////Af///wEAAAANAAAA6wAAAP8AAAD/AAAA/wAAAP8AAADb////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEoKCibAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAAb////wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA+QAAAC3///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAApQAAAP8AAAD/AAAA/wAAAP8AAAD9AAAAOf///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAH0AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAACpAAAAB///
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAAAxAAAA7QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAxwAA
+        AAX///8B////Af///wH///8BAAAAoQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAALf///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAAJAAAA1wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA+QAAAF3///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAABsAAADfAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAACd////Af///wH///8BAAAADQAAAOsAAAD/AAAA/wAAAP8AAAD/AAAA2///
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BKCgomwAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAG////8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPkAAAAt////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAKUAAAD/AAAA/wAAAP8AAAD/AAAA/QAAADn///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAABEAAADpAAAA/wAAAP8AAAD/AAAA/wAAAP8AAADVAAAAD///
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAAFUAAAD9AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAABN////Af///wH///8B////AQAAAKEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAC3///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAfQAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/QAAAGf///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAQQAA
+        AP0AAAD/AAAA/wAAAP8AAAD/AAAA8QAAABv///8B////AQAAAA0AAADrAAAA/wAAAP8AAAD/AAAA/wAA
+        ANv///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////ASgoKJsAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAABv////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD5AAAALf///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAAClAAAA/wAAAP8AAAD/AAAA/wAAAP0AAAA5////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAABnAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAPf//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAADAAAArwAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAAvf///wH///8B////Af///wEAAAChAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAAt////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAFwAAAOsAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAJf///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAACtAAAA/wAAAP8AAAD/AAAA/wAAAP8AAABn////Af///wEAAAANAAAA6wAAAP8AAAD/AAAA/wAA
+        AP8AAADb////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEoKCibAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAAb////wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+QAAAC3///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAApQAAAP8AAAD/AAAA/wAAAP8AAAD9AAAAOf//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAAyQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAr///
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAADUAAAD5AAAA/wAA
+        AP8AAAD/AAAA/wAAAPsAAAAn////Af///wH///8BAAAAoQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAALf//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAIEAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAANsAAAAN////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAAQQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAqf///wH///8BAAAADQAAAOsAAAD/AAAA/wAA
+        AP8AAAD/AAAA2////wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BKCgomwAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAG////8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPkAAAAt////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAAKUAAAD/AAAA/wAAAP8AAAD/AAAA/QAA
+        ADn///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAAHQAAAPsAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AD////8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAuwAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAAdf///wH///8B////AQAAAKEAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AC3///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAA0AAADdAAAA/wAA
+        AP8AAAD/AAAA/wAAAP0AAABP////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAABEAAADtAAAA/wAAAP8AAAD/AAAA/wAAANkAAAAF////AQAAAA0AAADrAAAA/wAA
+        AP8AAAD/AAAA/wAAANv///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////ASgo
+        KJsAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABv////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD5AAAALf///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAClAAAA/wAAAP8AAAD/AAAA/wAA
+        AP0AAAA5////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAAFsAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        ANEAAAAH////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AF0AAAD/AAAA/wAAAP8AAAD/AAAA/wAAALv///8B////Af///wEAAAChAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAAt////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAABFAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAADF////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAAADAAAAyQAAAP8AAAD/AAAA/wAAAP8AAAD1AAAAC////wEAAAANAAAA6wAA
+        AP8AAAD/AAAA/wAAAP8AAADb////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEoKCibAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAb////wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+QAAAC3///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAApQAAAP8AAAD/AAAA/wAA
+        AP8AAAD9AAAAOf///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAACPAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAACT////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAAAhAAAA9QAAAP8AAAD/AAAA/wAAAP8AAADlAAAAC////wH///8BAAAAoQAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAALf///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAeQAA
+        APUAAAD/AAAA/wAAAP8AAAD/AAAAUf///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAMEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAA3///8BAAAADQAA
+        AOsAAAD/AAAA/wAAAP8AAAD/AAAA2////wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BKCgomwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAG////8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPkAAAAt////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAKUAAAD/AAAA/wAA
+        AP8AAAD/AAAA/QAAADn///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAvwAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAAUf///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAANkAAAD/AAAA/wAAAP8AAAD/AAAA+QAAACv///8B////AQAAAKEAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAC3///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAAAhAAAAcwAAAMsAAAD/AAAA4QAAAAv///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAADBAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAAN////AQAA
+        AA0AAADrAAAA/wAAAP8AAAD/AAAA/wAAANv///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////ASgoKJsAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABv////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD5AAAALf//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAClAAAA/wAA
+        AP8AAAD/AAAA/wAAAP0AAAA5////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAANsAAAD/AAAA/wAA
+        AP8AAAD/AAAA+QAAAC3///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAACtAAAA/wAAAP8AAAD/AAAA/wAAAP8AAABH////Af///wEAAAChAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAAt////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAAAFAAAAMQAAAFX///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAAAHAAAAzwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAADf//
+        /wEAAAANAAAA6wAAAP8AAAD/AAAA/wAAAP8AAADb////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEoKCibAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAb////wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+QAA
+        AC3///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAApQAA
+        AP8AAAD/AAAA/wAAAP8AAAD9AAAAOf///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAAsAAADnAAAA/wAA
+        AP8AAAD/AAAA/wAAAOsAAAAN////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAAhQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAW////wH///8BAAAAoQAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAALf///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAAFQAAAPUAAAD/AAAA/wAAAP8AAAD/AAAA6QAA
+        AAn///8BAAAADQAAAOsAAAD/AAAA/wAAAP8AAAD/AAAA2////wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BKCgomwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAG////8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        APkAAAAt////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AKUAAAD/AAAA/wAAAP8AAAD/AAAA/QAAADn///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAAVAAAA7QAA
+        AP8AAAD/AAAA/wAAAP8AAADh////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAHMAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAGn///8B////AQAA
+        AKEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAC3///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAAEsAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AMcAAAAD////AQAAAA0AAADrAAAA/wAAAP8AAAD/AAAA/wAAANv///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////ASgoKJsAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABv////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD5AAAALf///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAAClAAAA/wAAAP8AAAD/AAAA/wAAAP0AAAA5////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAIQAA
+        APMAAAD/AAAA/wAAAP8AAAD/AAAA1f///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAABdAAAA/wAAAP8AAAD/AAAA/wAAAP8AAACB////Af//
+        /wEAAAChAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAAt////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAC3AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAACT////Af///wEAAAANAAAA6wAAAP8AAAD/AAAA/wAAAP8AAADb////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEoKCibAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAb///
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA+QAAAC3///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAApQAAAP8AAAD/AAAA/wAAAP8AAAD9AAAAOf///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        ACEAAADzAAAA/wAAAP8AAAD/AAAA/wAAAMf///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAAVwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAf///
+        /wH///8BAAAAoQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAALf///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAABXAAAA/QAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAAR////wH///8BAAAADQAAAOsAAAD/AAAA/wAAAP8AAAD/AAAA2////wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BKCgomwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AG////8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAPkAAAAt////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAAKUAAAD/AAAA/wAAAP8AAAD/AAAA/QAAADn///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAAAhAAAA8wAAAP8AAAD/AAAA/wAAAP8AAADH////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAAFcAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AH////8B////AQAAAKEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAC3///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAA/AAAA7wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA3QAAAA3///8B////AQAAAA0AAADrAAAA/wAAAP8AAAD/AAAA/wAAANv///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////ASgoKJsAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAABv////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD5AAAALf///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAAClAAAA/wAAAP8AAAD/AAAA/wAAAP0AAAA5////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAAIQAAAPMAAAD/AAAA/wAAAP8AAAD/AAAAx////wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAABXAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAB/////Af///wEAAAChAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAAt////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAABRAAAA7wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAG3///8B////Af///wEAAAANAAAA6wAAAP8AAAD/AAAA/wAAAP8AAADb////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEoKCibAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAAb////wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA+QAAAC3///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAApQAAAP8AAAD/AAAA/wAAAP8AAAD9AAAAOf///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAACEAAADzAAAA/wAAAP8AAAD/AAAA/wAAAMf///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAVwAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAAf////wH///8BAAAAoQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAALf///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAABMAAACZAAAA+QAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAMkAAAAH////Af///wH///8BAAAADQAAAOsAAAD/AAAA/wAAAP8AAAD/AAAA2///
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BKCgomwAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAG////8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPkAAAAt////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAKUAAAD/AAAA/wAAAP8AAAD/AAAA/QAAADn///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAAAhAAAA8wAAAP8AAAD/AAAA/wAAAP8AAADH////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAFcAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAH////8B////AQAAAKEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAC3///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAADwAAAHEAAADlAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAO0AAAAl////Af///wH///8B////AQAAAA0AAADrAAAA/wAAAP8AAAD/AAAA/wAA
+        ANv///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////ASgoKJsAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAABv////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD5AAAALf///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAAClAAAA/wAAAP8AAAD/AAAA/wAAAP0AAAA3////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAAIQAAAPMAAAD/AAAA/wAAAP8AAAD/AAAAx////wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAABXAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAB/////Af///wEAAAChAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAAt////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAAAhAAAAfQAAAOEAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAO8AAAA9////Af///wH///8B////Af///wEAAAANAAAA6wAAAP8AAAD/AAAA/wAA
+        AP8AAADb////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEoKCibAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAAb////wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+QAAAC3///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAApQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAxQAA
+        ALUAAAC1AAAAtQAAALUAAAC1AAAAtQAAALUAAAC1AAAAtQAAALUAAAC1AAAAtQAAALUAAAC1AAAArQAA
+        AJMAAACDAAAAaQAAAE8AAAApAAAABf///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAACEAAADzAAAA/wAAAP8AAAD/AAAA/wAAAMf///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAVwAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAAf////wH///8BAAAAoQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAALf//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAACwAAAE0AAACtAAAA8QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAOEAAAAz////Af///wH///8B////Af///wH///8BAAAADQAAAOsAAAD/AAAA/wAA
+        AP8AAAD/AAAA2////wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BKCgomwAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAG////8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPkAAAAt////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAAKUAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA9wAAAOkAAAC1AAAAawAAAB0AAAAD////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAAAhAAAA8wAAAP8AAAD/AAAA/wAAAP8AAADH////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AFcAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAH////8B////AQAAAKEAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AC3///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAAAkAAABDAAAAkwAAAOkAAAD9AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/QAAAKkAAAAV////Af///wH///8B////Af///wH///8B////AQAAAA0AAADrAAAA/wAA
+        AP8AAAD/AAAA/wAAANv///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////ASgo
+        KJsAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABv////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD5AAAALf///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAClAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD7AAAAtwAAAEkAAAAF////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAAIQAAAPMAAAD/AAAA/wAAAP8AAAD/AAAAx///
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAABXAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAB/////Af///wEAAAChAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAAt////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAAAPAAAARwAAAJ8AAADrAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA1wAAAFP///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAANAAAA6wAA
+        AP8AAAD/AAAA/wAAAP8AAADfAAAAJQAAACUAAAAlAAAAJQAAACUAAAAlAAAAJQAAACUAAAAlAAAAJQAA
+        ACUAAAAlAAAAJQAAACUAAAAlAAAAJQAAACUAAAAlAAAAJQAAACUAAAAlAAAAJQAAAAn///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEoKCibAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAb////wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+QAAAC3///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAApQAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAwQAA
+        ADP///8B////Af///wH///8B////Af///wH///8B////AQAAACEAAADzAAAA/wAAAP8AAAD/AAAA/wAA
+        AMf///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAAVwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAf////wH///8BAAAAoQAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAALf///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAABwAA
+        AEcAAACfAAAA4wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAADXAAAAYwAAAAn///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAADQAA
+        AOsAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAA7////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BKCgomwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAG////8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPkAAAAt////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAKUAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD1AAAAewAAAAP///8B////Af///wH///8B////Af///wEAAAAhAAAA8wAAAP8AAAD/AAAA/wAA
+        AP8AAADH////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAAFcAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAH////8B////AQAAAKEAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAC3///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAAfAAAAfwAA
+        ANkAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AL8AAABXAAAAC////wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AA0AAADrAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD9AAAAN///
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////ASgoKJsAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABv////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD5AAAALf//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAClAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAACXAAAAeQAAAHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAAAHkAAAB5AAAAeQAA
+        AHkAAAB5AAAAeQAAAHkAAACDAAAAmQAAAKcAAADFAAAA6QAAAPcAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAACZAAAABf///wH///8B////Af///wH///8BAAAAIQAAAPMAAAD/AAAA/wAA
+        AP8AAAD/AAAAx////wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAABXAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAB/////Af///wEAAAChAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAAt////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAACsAAACjAAAA9wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP0AAADfAAAAiQAA
+        ACkAAAAD////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAAANAAAA6wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/QAA
+        ADf///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEoKCibAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAb////wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+QAA
+        AC3///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAApQAA
+        AP8AAAD/AAAA/wAAAP8AAAD9AAAAOf///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAAlAAAAWwAAAK0AAADxAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAJf///8B////Af///wH///8B////AQAAACEAAADzAAAA/wAA
+        AP8AAAD/AAAA/wAAAMf///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAAVwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAf////wH///8BAAAAoQAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAALf///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAJwAAAKMAAAD9AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD9AAAA2wAAAJcAAABFAAAAA///
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAADQAAAOsAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP0AAAA3////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BKCgomwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAG////8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        APkAAAAt////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AKUAAAD/AAAA/wAAAP8AAAD/AAAA/QAAADn///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAHwAA
+        AI0AAAD5AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAZ////wH///8B////Af///wEAAAAhAAAA8wAA
+        AP8AAAD/AAAA/wAAAP8AAADH////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAFcAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAH////8B////AQAA
+        AKEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAC3///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAAHAAAAdwAAAPEAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAANcAAACPAAAAOwAAAAn///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAAA0AAADrAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAAOf///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////ASgoKJsAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABv////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD5AAAALf///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAAClAAAA/wAAAP8AAAD/AAAA/wAAAP0AAAA5////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAAPQAAAOUAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAO8AAAAd////Af///wH///8BAAAAIQAA
+        APMAAAD/AAAA/wAAAP8AAAD/AAAAx////wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAABXAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAB/////Af//
+        /wEAAAChAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAAt////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAAXAAAAuQAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADrAAAAlQAAADcAAAAJ////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAAANAAAA6wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAHQAAAB0AAAAdAAAAHQAA
+        AB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAA
+        AB0AAAAdAAAAHQAAAAf///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEoKCibAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAb///
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA+QAAAC3///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAApQAAAP8AAAD/AAAA/wAAAP8AAAD9AAAAOf///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAAAnAAAA6wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAj////wH///8B////AQAA
+        ACEAAADzAAAA/wAAAP8AAAD/AAAA/wAAAMf///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAAVwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAf///
+        /wH///8BAAAAoQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAALf///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAAZAAAA0wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA9wAAAL8AAABVAAAACf///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAADQAAAOsAAAD/AAAA/wAAAP8AAAD/AAAA2////wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BKCgomwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AG////8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAPkAAAAt////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAAKUAAAD/AAAA/wAAAP8AAAD/AAAA/QAAADn///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAFkAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAOsAAAAX////Af//
+        /wEAAAAhAAAA8wAAAP8AAAD/AAAA/wAAAP8AAADH////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAAFcAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AH////8B////AQAAAKEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAC3///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAANAAAAzQAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD1AAAAnwAAADX///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAA0AAADrAAAA/wAAAP8AAAD/AAAA/wAAANv///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////ASgoKJsAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAABv////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD5AAAALf///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAAClAAAA/wAAAP8AAAD/AAAA/wAAAP0AAAA5////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAAwwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAW///
+        /wH///8BAAAAIQAAAPMAAAD/AAAA/wAAAP8AAAD/AAAAx////wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAABXAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAB/////Af///wEAAAChAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAAt////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAmQAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAC7AAAAL////wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAAANAAAA6wAAAP8AAAD/AAAA/wAAAP8AAADb////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEoKCibAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAAb////wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA+QAAAC3///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAApQAAAP8AAAD/AAAA/wAAAP8AAAD9AAAAOf///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAAFcAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AKX///8B////AQAAACEAAADzAAAA/wAAAP8AAAD/AAAA/wAAAMf///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAVwAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAAf////wH///8BAAAAoQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAALf///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAANwAAAPsAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAPkAAAB1AAAABf///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAADQAAAOsAAAD/AAAA/wAAAP8AAAD/AAAA2///
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BKCgomwAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAG////8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPkAAAAt////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAKUAAAD/AAAA/wAAAP8AAAD/AAAA/QAAADn///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAAXAAAA+QAAAP8AAAD/AAAA/wAA
+        AP8AAADTAAAAB////wEAAAAhAAAA8wAAAP8AAAD/AAAA/wAAAP8AAADH////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAFcAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAH////8B////AQAAAKEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAC3///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAKkAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAPkAAABb////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAAA0AAADrAAAA/wAAAP8AAAD/AAAA/wAA
+        ANv///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////ASgoKJsAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAABv////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD5AAAALf///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAAClAAAA/wAAAP8AAAD/AAAA/wAAAP0AAAA5////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAABwAAANEAAAD/AAAA/wAA
+        AP8AAAD/AAAA9wAAAA////8BAAAAIQAAAPMAAAD/AAAA/wAAAP8AAAD/AAAAx////wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAABXAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAB/////Af///wEAAAChAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAAt////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAA8AAAD1AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAB/////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAANAAAA6wAAAP8AAAD/AAAA/wAA
+        AP8AAADb////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEoKCibAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAAb////wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+QAAAC3///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAApQAAAP8AAAD/AAAA/wAAAP8AAAD9AAAAOf//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAACzAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAAZ////AQAAACEAAADzAAAA/wAAAP8AAAD/AAAA/wAAAMf///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAVwAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAAf////wH///8BAAAAoQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAALf//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAABNAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAADbAAAAC////wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAADQAAAOsAAAD/AAAA/wAA
+        AP8AAAD/AAAA2////wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BKCgomwAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAG////8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPkAAAAt////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAAKUAAAD/AAAA/wAAAP8AAAD/AAAA/QAA
+        ADn///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAowAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAALf///wEAAAAhAAAA8wAAAP8AAAD/AAAA/wAAAP8AAADH////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AFcAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAH////8B////AQAAAKEAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AC3///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAeQAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAAhf///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAA0AAADrAAAA/wAA
+        AP8AAAD/AAAA/wAAANv///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////ASgo
+        KJsAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABv////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD5AAAALf///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAClAAAA/wAAAP8AAAD/AAAA/wAA
+        AP0AAAA5////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AKMAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAC3///8BAAAAIQAAAPMAAAD/AAAA/wAAAP8AAAD/AAAAx///
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAABXAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAB/////Af///wEAAAChAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAAt////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AJsAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAEf///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAANAAAA6wAA
+        AP8AAAD/AAAA/wAAAP8AAADb////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEoKCibAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAb////wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+QAAAC3///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAApQAAAP8AAAD/AAAA/wAA
+        AP8AAAD9AAAAOf///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAACvAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAAn////AQAAACEAAADzAAAA/wAAAP8AAAD/AAAA/wAA
+        AMf///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAAVwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAf////wH///8BAAAAoQAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAALf///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAACpAAAA/wAAAP8AAAD/AAAA/wAAAPkAAAAr////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAAKwAAAAf///8B////Af///wH///8B////Af///wH///8BAAAADQAA
+        AOsAAAD/AAAA/wAAAP8AAAD/AAAA2////wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BKCgomwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAG////8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPkAAAAt////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAKUAAAD/AAAA/wAA
+        AP8AAAD/AAAA/QAAADn///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAAAFAAAAzQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAEf///wEAAAAhAAAA8wAAAP8AAAD/AAAA/wAA
+        AP8AAADH////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAAFcAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAH////8B////AQAAAKEAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAC3///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAAqQAAAP8AAAD/AAAA/wAAAP8AAADxAAAAH////wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAABQAAAN0AAADbAAAAaQAAAA3///8B////Af///wH///8B////AQAA
+        AA0AAADrAAAA/wAAAP8AAAD/AAAA/wAAANv///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////ASgoKJsAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABv////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD5AAAALf//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAClAAAA/wAA
+        AP8AAAD/AAAA/wAAAP0AAAA5////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAAFQAAAPcAAAD/AAAA/wAAAP8AAAD/AAAA4wAAAAn///8BAAAAIQAAAPMAAAD/AAAA/wAA
+        AP8AAAD/AAAAx////wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAABXAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAB/////Af///wEAAAChAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAAt////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAAKcAAAD/AAAA/wAAAP8AAAD/AAAA9QAAACP///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAFkAAAD/AAAA/wAAAP8AAADnAAAAfQAAAA////8B////Af//
+        /wEAAAANAAAA6wAAAP8AAAD/AAAA/wAAAP8AAADb////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEoKCibAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAb////wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+QAA
+        AC3///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAApQAA
+        AP8AAAD/AAAA/wAAAP8AAAD9AAAAOf///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAAFsAAAD/AAAA/wAAAP8AAAD/AAAA/wAAALn///8B////AQAAACEAAADzAAAA/wAA
+        AP8AAAD/AAAA/wAAAMf///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAAVwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAf////wH///8BAAAAoQAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAALf///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAACFAAAA/wAAAP8AAAD/AAAA/wAAAP8AAABD////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAAcAAADVAAAA/wAAAP8AAAD/AAAA/wAAAPsAAABB////Af//
+        /wH///8BAAAADQAAAOsAAAD/AAAA/wAAAP8AAAD/AAAA2////wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BKCgomwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAG////8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        APkAAAAt////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AKUAAAD/AAAA/wAAAP8AAAD/AAAA/QAAADn///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAADHAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAB7////Af///wEAAAAhAAAA8wAA
+        AP8AAAD/AAAA/wAAAP8AAADH////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAFcAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAH////8B////AQAA
+        AKEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAC3///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAAVwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAg////wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAABzAAAA/wAAAP8AAAD/AAAA/wAAAP8AAADRAAAAA///
+        /wH///8B////AQAAAA0AAADrAAAA/wAAAP8AAAD/AAAA/wAAANv///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////ASgoKJsAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABv////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD5AAAALf///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAAClAAAA/wAAAP8AAAD/AAAA/wAAAP0AAAA5////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAABrAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD5AAAALf///wH///8BAAAAIQAA
+        APMAAAD/AAAA/wAAAP8AAAD/AAAAx////wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAABXAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAB/////Af//
+        /wEAAAChAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAAt////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAABcAAAD5AAAA/wAAAP8AAAD/AAAA/wAAAN8AAAAP////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAAArAAAA7wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAX///
+        /wH///8B////Af///wEAAAANAAAA6wAAAP8AAAD/AAAA/wAAAP8AAADb////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEoKCibAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAb///
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA+QAAAC3///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAApQAAAP8AAAD/AAAA/wAAAP8AAAD9AAAAOf///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAABDAAAA8QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAvQAAAAP///8B////AQAA
+        ACEAAADzAAAA/wAAAP8AAAD/AAAA/wAAAMf///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAAVwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAf///
+        /wH///8BAAAAoQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAALf///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAAtQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAff//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAAAXAAAA1wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA0wAA
+        AAX///8B////Af///wH///8BAAAADQAAAOsAAAD/AAAA/wAAAP8AAAD/AAAA2////wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BKCgomwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AG////8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAPkAAAAt////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAAKUAAAD/AAAA/wAAAP8AAAD/AAAA/QAAADn///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAABnAAAA8QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+wAAADv///8B////Af//
+        /wEAAAAhAAAA8wAAAP8AAAD/AAAA/wAAAP8AAADH////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAAFcAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AH////8B////AQAAAKEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAC3///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAAEkAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        APkAAABJ////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAAAXAAAA0QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/QAA
+        AEf///8B////Af///wH///8B////AQAAAA0AAADrAAAA/wAAAP8AAAD/AAAA/wAAANv///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////ASgoKJsAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAABv////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD5AAAALf///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAAClAAAA/wAAAP8AAAD/AAAA/wAAAP0AAAA5////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAAAwAAAEsAAADDAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAJn///8B////Af//
+        /wH///8BAAAAIQAAAPMAAAD/AAAA/wAAAP8AAAD/AAAAx////wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAABXAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAB/////Af///wEAAAChAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAAt////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAADAAAAtwAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA8QAAAF3///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAAAzAAAA2wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AJX///8B////Af///wH///8B////Af///wEAAAANAAAA6wAAAP8AAAD/AAAA/wAAAP8AAADb////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEoKCibAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAAb////wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA+QAAAC3///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAApQAAAP8AAAD/AAAA/wAAAP8AAAD9AAAAOf///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAAUAAAAHAAAADwAA
+        ACUAAABVAAAAlwAAAOEAAAD9AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAMUAAAAL////Af//
+        /wH///8B////AQAAACEAAADzAAAA/wAAAP8AAAD/AAAA/wAAAMf///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAVwAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAAf////wH///8BAAAAoQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAALf///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAACUAAADtAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD9AAAApQAAAB////8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAABcAAACNAAAA9wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AM8AAAAP////Af///wH///8B////Af///wH///8BAAAADQAAAOsAAAD/AAAA/wAAAP8AAAD/AAAA2wAA
+        AAUAAAAFAAAABQAAAAUAAAAFAAAABQAAAAUAAAAFAAAABQAAAAUAAAAFAAAABQAAAAUAAAAFAAAABQAA
+        AAUAAAAFAAAABQAAAAUAAAAFAAAABQAAAAUAAAAFAAAABQAAAAUAAAAFAAAABQAAAAUAAAAFAAAABf//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BKCgomwAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAG////8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPkAAAAt////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAKUAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAMUAAAC5AAAAuQAA
+        ALkAAAC5AAAAuQAAALkAAAC5AAAAuQAAALkAAAC5AAAAuQAAALkAAAC5AAAAuQAAALcAAADPAAAA2QAA
+        APcAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAMkAAAAZ////Af//
+        /wH///8B////Af///wEAAAAhAAAA8wAAAP8AAAD/AAAA/wAAAP8AAADH////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAFcAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAH////8B////AQAAAKEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAC3///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAUwAA
+        APsAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADzAAAApQAAAEkAAAAZAAAAA////wH///8B////Af//
+        /wH///8B////Af///wEAAAAZAAAARwAAAJ8AAADzAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AOEAAAAb////Af///wH///8B////Af///wH///8B////AQAAAA0AAADrAAAA/wAAAP8AAAD/AAAA/wAA
+        APkAAADPAAAA0QAAANEAAADRAAAA0QAAANEAAADRAAAA0QAAANEAAADRAAAA0QAAANEAAADRAAAA0QAA
+        ANEAAADRAAAA0QAAANEAAADRAAAA0QAAANEAAADRAAAA0QAAANEAAADRAAAA0QAAANEAAADRAAAA0QAA
+        AKf///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////ASgoKJsAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAABv////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD5AAAALf///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAAClAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAKMAAAAP////Af//
+        /wH///8B////Af///wH///8BAAAAIQAAAPMAAAD/AAAA/wAAAP8AAAD/AAAAx////wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAABXAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAB/////Af///wEAAAChAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAAt////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAABpAAAA+QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA7wAAAMsAAACzAAAAlwAA
+        AIkAAACJAAAAnwAAALMAAADNAAAA7wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        ANkAAAAj////Af///wH///8B////Af///wH///8B////Af///wEAAAANAAAA6wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAADH////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEoKCibAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAAb////wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+QAAAC3///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAApQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA2wAAAFMAAAAD////Af//
+        /wH///8B////Af///wH///8B////AQAAACEAAADzAAAA/wAAAP8AAAD/AAAA/wAAAMf///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAVwAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAAf////wH///8BAAAAoQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAALf//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAAE8AAADrAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        ALUAAAAX////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAADQAAAOsAAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAAx////wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BKCgomwAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAG////8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////AQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPkAAAAt////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAAKUAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPkAAADRAAAAZQAAAAf///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAAAhAAAA8wAAAP8AAAD/AAAA/wAAAP8AAADH////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+        AFcAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAH////8B////AQAAAKEAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AC3///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAAIwAAALkAAAD9AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA6wAA
+        AG0AAAAD////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAA0AAADrAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAMf///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////ASgo
+        KJsAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABv////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD5AAAALf///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAClAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP0AAADhAAAAvwAAAHUAAAAz////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAAIwAAAPkAAAD/AAAA/wAAAP8AAAD/AAAAy///
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAABbAAAA/wAAAP8AAAD/AAAA/wAAAP8AAACF////Af///wEAAACjAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAAx////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAASQAAAMMAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADnAAAAjQAA
+        ABv///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAANAAAA6wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAADH////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEoKCibAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAb////wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+QAAAC3///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAbwAAAKEAAAChAAAAoQAA
+        AKEAAAChAAAAoQAAAKEAAAChAAAAoQAAAKEAAAChAAAAoQAAAKEAAAChAAAAoQAAAKEAAAChAAAAoQAA
+        AKEAAAChAAAAjwAAAI0AAAB7AAAAYwAAAEMAAAApAAAAD////wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAAAcAAAAzAAAANQAAADUAAAA1AAAANQAA
+        ACn///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAAEwAAADUAAAA1AAAANQAAADUAAAA1AAAAG////wH///8BAAAAIQAAADUAAAA1AAAANQAA
+        ADUAAAA1AAAACf///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAADAAAAOwAAAJEAAADZAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA6wAAAK8AAABfAAAAE///
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAACQAA
+        AJsAAAChAAAAoQAAAKEAAAChAAAAoQAAAKEAAAChAAAAoQAAAKEAAAChAAAAoQAAAKEAAAChAAAAoQAA
+        AKEAAAChAAAAoQAAAKEAAAChAAAAoQAAAKEAAAChAAAAoQAAAKEAAAChAAAAoQAAAKEAAAChAAAAoQAA
+        AKEAAAChAAAAoQAAAKEAAAChAAAAgf///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BKCgomwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAG////8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////AQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPkAAAAt////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAACQAA
+        ACMAAABZAAAAgQAAAJ0AAACxAAAAvwAAAL8AAACtAAAAoQAAAIcAAABfAAAAMQAAAA3///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////ASgoKJsAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABv////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD5AAAAMf//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEoKCifAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAb////wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+wAA
+        ADP///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BJiYmowAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAG////8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        APkAAAAt////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////ASgoKJsAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABv////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD5AAAAM////wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEoKCihAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAb///
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAA4QAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAALf///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wGDg4MrAQEB9QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/zAw
+        MFP///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAK0AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAADvAAAAH////wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BLi4ucQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP+dnZ0f////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAABrAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAIH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BqqqqDw8PD9cAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8WFhbP0NDQBf///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAAJQAA
+        APcAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADtAAAAI////wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////ATAwMHUAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/JiYmhf///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wEAAAC5AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAMcAAAAN////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AUlJST8CAgL1AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AgIC9XR0dC3///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAASwAAAP0AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAqwAAAA3///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AUlJSS8JCQnjAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/yAgIK3///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAAC9AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADDAAAAH///
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////AUJCQlMHBwftAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wEBAfVMTEwx////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAALQAAAPcAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AO0AAAB1AAAAF////wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8Bfn5+JxkZGaUAAAD3AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8jIyOH////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wEAAAB1AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAOsAAACnAAAAZQAAAB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAA
+        AB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAA
+        AB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAA
+        AB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAA
+        AB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAA
+        AB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAA
+        AB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAA
+        AB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAA
+        AB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAA
+        AB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAA
+        AB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAA
+        AB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAA
+        AB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAA
+        AB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAAAB0AAAAdAAAAHQAA
+        AB0AAAAdAAAAHQAAADEAAAAxAAAAMQAAAC80NDRjHh4etQAAAPcAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8QEBDJsrKyDf///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAAAwAAAKEAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADvAAAA7wAAAO8AAADvAAAA7wAAAO8AAADvAAAA7wAA
+        AO8AAADvAAAA7wAAAO8AAADvAAAA7wAAAO8AAADvAAAA7wAAAO8AAADvAAAA7wAAAO8AAADvAAAA7wAA
+        AO8AAADvAAAA7wAAAO8AAADvAAAA7wAAAO8AAADvAAAA7wAAAO8AAADvAAAA7wAAAO8AAADvAAAA7wAA
+        AO8AAADvAAAA7wAAAO8AAADvAAAA7wAAAO8AAADvAAAA7wAAAO8AAADvAAAA7wAAAO8AAADvAAAA7wAA
+        AO8AAADvAAAA7wAAAO8AAADvAAAA7wAAAO8AAADvAAAA7wAAAO8AAADvAAAA7wAAAO8AAADvAAAA7wAA
+        AO8AAADvAAAA7wAAAO8AAADvAAAA7wAAAO8AAADvAAAA7wAAAO8AAADvAAAA7wAAAO8AAADvAAAA7wAA
+        AO8AAADvAAAA7wAAAO8AAADvAAAA7wAAAO8AAADvAAAA7wAAAO8AAADvAAAA7wAAAO8AAADvAAAA7wAA
+        AO8AAADvAAAA7wAAAO8AAADvAAAA7wAAAO8AAADvAAAA7wAAAO8AAADvAAAA7wAAAO8AAADvAAAA7wAA
+        AO8AAADvAAAA7wAAAO8AAADvAAAA7wAAAO8AAADvAAAA7wAAAO8AAADvAAAA7wAAAO8AAADvAAAA7wAA
+        AO8AAADvAAAA7wAAAO8AAADvAAAA7wAAAO8AAADvAAAA7wAAAO8AAADvAAAA7wAAAO8AAADvAAAA7wAA
+        AO8AAADvAAAA7wAAAO8AAADvAAAA7wAAAO8AAADvAAAA7wAAAO8AAADvAAAA7wAAAO8AAADvAAAA7wAA
+        AO8AAADvAAAA7wAAAO8AAADvAAAA7wAAAO8AAADvAAAA7wAAAO8AAADvAAAA7wAAAO8AAADvAAAA7wAA
+        AO8AAADvAAAA7wAAAO8AAADvAAAA7wAAAO8AAADvAAAA7wAAAO8AAADvAAAA7wAAAO8AAADvAAAA7wAA
+        AO8AAADvAAAA7wAAAO8AAADvAAAA7wAAAO8AAADvAAAA7wAAAO8AAADvAAAA7wAAAO8AAADvAAAA7wAA
+        AO8AAADvAAAA7wAAAO8AAAD9AAAA/QAAAP0AAAD9AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8LCwvfS0tLJf///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAANAAAAtwAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8HBwftREREN////wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAAAA0AAAClAAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8MDAzVQkJCL////wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BAAAABQAA
+        AHsAAAD3AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8WFha3cHBwHf///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8BAAAANQAAAMcAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wgICOUxMTFh19fXA////wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wEAAAADAAAAUQAAAMcAAAD5AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/ERER2SgoKHeYmJgT////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8BAAAAMwAAAHcAAADdAAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+        AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD3CwsL4R0d
+        HcMoKCiNVVVVQ8PDwwf///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+        /wH///8B////Af///wH///8BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
+</value>
+  </data>
+  <metadata name="menuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>884, 17</value>
+  </metadata>
   <data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         AAABAAYAEBAAAAAAIABoBAAAZgAAACAgAAAAACAAqBAAAM4EAAAwMAAAAAAgAKglAAB2FQAAQEAAAAAA
similarity index 98%
rename from src/cec-config-gui/DeviceInformation.Designer.cs
rename to src/LibCecTray/ui/DeviceInformation.Designer.cs
index c2ea74fe50378e57cd07009dcf88d8156f76acd9..689b021d68ea955789490c9821c9a343ae8108f6 100644 (file)
@@ -1,4 +1,4 @@
-namespace CecConfigGui
+namespace LibCECTray.ui
 {
   partial class DeviceInformation
   {
       this.lInactiveSource.Text = "no";
       this.lInactiveSource.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
       this.lInactiveSource.Visible = false;
-      this.lInactiveSource.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.lInactiveSource_LinkClicked);
+      this.lInactiveSource.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.LInactiveSourceLinkClicked);
       // 
       // lPowerStatus
       // 
       this.lPowerStatus.TabStop = true;
       this.lPowerStatus.Text = "unknown";
       this.lPowerStatus.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
-      this.lPowerStatus.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.lStandby_LinkClicked);
+      this.lPowerStatus.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.LStandbyLinkClicked);
       // 
       // bUpdate
       // 
       this.bUpdate.TabIndex = 31;
       this.bUpdate.Text = "Refresh";
       this.bUpdate.UseVisualStyleBackColor = true;
-      this.bUpdate.Click += new System.EventHandler(this.button1_Click);
+      this.bUpdate.Click += new System.EventHandler(this.Button1Click);
       // 
       // DeviceInformation
       // 
       this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
       this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
       this.MaximizeBox = false;
+      this.MinimizeBox = false;
       this.Name = "DeviceInformation";
       this.ShowInTaskbar = false;
       this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
-      this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
+      this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
       this.Text = "Device: [unknown]";
       this.ResumeLayout(false);
       this.PerformLayout();
diff --git a/src/LibCecTray/ui/DeviceInformation.cs b/src/LibCecTray/ui/DeviceInformation.cs
new file mode 100644 (file)
index 0000000..135ff73
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing       <license@pulse-eight.com>
+ *     http://www.pulse-eight.com/
+ *     http://www.pulse-eight.net/
+ */
+
+using System;
+using System.Windows.Forms;
+using CecSharp;
+using LibCECTray.Properties;
+using LibCECTray.controller;
+
+namespace LibCECTray.ui
+{
+  partial class DeviceInformation : AsyncForm
+  {
+    public DeviceInformation(CECController controller, CecLogicalAddress address, ref LibCecSharp lib,
+      bool devicePresent, CecVendorId vendor, bool isActiveSource, ushort physicalAddress,
+      CecVersion version, CecPowerStatus power, string osdName, string menuLanguage)
+    {
+      _controller = controller;
+      _lib = lib;
+      Address = address;
+      InitializeComponent();
+      lDevice.Text = lib.ToString(address);
+      lLogicalAddress.Text = String.Format("{0,1:X}", (int)address);
+      Update(devicePresent, vendor, isActiveSource, physicalAddress, version, power, osdName, menuLanguage);
+    }
+
+    public void Update(bool devicePresent, CecVendorId vendor, bool isActiveSource, ushort physicalAddress,
+      CecVersion version, CecPowerStatus power, string osdName, string menuLanguage)
+    {
+      SetControlText(lPhysicalAddress, String.Format("{0,4:X}", physicalAddress));
+      SetControlText(lDevicePresent, devicePresent ? Resources.yes : Resources.no);
+      SetControlVisible(lActiveSource, isActiveSource);
+      SetControlVisible(lInactiveSource, !isActiveSource);
+      SetControlText(lVendor, vendor != CecVendorId.Unknown ? _lib.ToString(vendor) : Resources.unknown);
+      SetControlText(lCecVersion, _lib.ToString(version));
+      SetControlText(lPowerStatus, _lib.ToString(power));
+      SetControlText(lOsdName, osdName);
+      SetControlText(lMenuLanguage, menuLanguage);
+      SetControlText(this, "Device: " + osdName);
+    }
+
+    private void LInactiveSourceLinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
+    {
+      SetControlVisible(lInactiveSource, false);
+      SetControlVisible(lActiveSource, true);
+      _controller.CECActions.ActivateSource(Address);
+    }
+
+    private void LStandbyLinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
+    {
+      LinkLabel label = sender as LinkLabel;
+      bool sendPowerOn = label != null && label.Text != _lib.ToString(CecPowerStatus.InTransitionStandbyToOn) &&
+        label.Text != _lib.ToString(CecPowerStatus.On);
+
+      SetControlText(lPowerStatus, _lib.ToString(sendPowerOn ? CecPowerStatus.On : CecPowerStatus.Standby));
+      if (sendPowerOn)
+        _controller.CECActions.SendImageViewOn(Address);
+      else
+        _controller.CECActions.SendStandby(Address);
+    }
+
+
+    private void Button1Click(object sender, EventArgs e)
+    {
+      _controller.CECActions.UpdateInfoPanel(this);
+    }
+
+    public CecLogicalAddress Address
+    {
+      private set;
+      get;
+    }
+    private readonly CECController _controller;
+    private readonly LibCecSharp _lib;
+  }
+}
diff --git a/src/cec-config-gui/AsyncForm.cs b/src/cec-config-gui/AsyncForm.cs
deleted file mode 100644 (file)
index c4d02bf..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-using System;
-using System.Windows.Forms;
-
-namespace CecConfigGui
-{
-  public class AsyncForm : Form
-  {
-    delegate void SetControlEnabledCallback(Control control, bool val);
-    public void SetControlEnabled(Control control, bool val)
-    {
-      if (control.InvokeRequired)
-      {
-        SetControlEnabledCallback d = SetControlEnabled;
-        try
-        {
-          Invoke(d, new object[] { control, val });
-        }
-        catch (Exception) { }
-      }
-      else
-      {
-        control.Enabled = val;
-      }
-    }
-
-    delegate void SetControlTextCallback(Control control, string val);
-    public void SetControlText(Control control, string val)
-    {
-      if (control.InvokeRequired)
-      {
-        SetControlTextCallback d = SetControlText;
-        try
-        {
-          Invoke(d, new object[] { control, val });
-        }
-        catch (Exception) { }
-      }
-      else
-      {
-        control.Text = val;
-      }
-    }
-
-    delegate void SetCheckboxCheckedCallback(CheckBox control, bool val);
-    public void SetCheckboxChecked(CheckBox control, bool val)
-    {
-      if (control.InvokeRequired)
-      {
-        SetCheckboxCheckedCallback d = SetCheckboxChecked;
-        try
-        {
-          Invoke(d, new object[] { control, val });
-        }
-        catch (Exception) { }
-      }
-      else
-      {
-        control.Checked = val;
-      }
-    }
-
-    delegate void SetCheckboxItemCheckedCallback(CheckedListBox control, int index, bool val);
-    public void SetCheckboxItemChecked(CheckedListBox control, int index, bool val)
-    {
-      if (control.InvokeRequired)
-      {
-        SetCheckboxItemCheckedCallback d = SetCheckboxItemChecked;
-        try
-        {
-          Invoke(d, new object[] { control, index, val });
-        }
-        catch (Exception) { }
-      }
-      else
-      {
-        control.SetItemChecked(index, val);
-      }
-    }
-
-    delegate void SetProgressValueCallback(ProgressBar control, int val);
-    public void SetProgressValue(ProgressBar control, int val)
-    {
-      if (control.InvokeRequired)
-      {
-        SetProgressValueCallback d = SetProgressValue;
-        try
-        {
-          Invoke(d, new object[] { control, val });
-        }
-        catch (Exception) { }
-      }
-      else
-      {
-        control.Value = val;
-      }
-    }
-
-    delegate void SetComboBoxItemsCallback(ComboBox control, string selectedText, object[] val);
-    public void SetComboBoxItems(ComboBox control, string selectedText, object[] val)
-    {
-      if (control.InvokeRequired)
-      {
-        SetComboBoxItemsCallback d = SetComboBoxItems;
-        try
-        {
-          Invoke(d, new object[] { control, selectedText, val });
-        }
-        catch (Exception) { }
-      }
-      else
-      {
-        control.Items.Clear();
-        control.Items.AddRange(val);
-        control.Text = selectedText;
-      }
-    }
-
-    delegate void SetControlVisibleCallback(Control control, bool val);
-    public void SetControlVisible(Control control, bool val)
-    {
-      if (control.InvokeRequired)
-      {
-        SetControlVisibleCallback d = SetControlVisible;
-        try
-        {
-          Invoke(d, new object[] { control, val });
-        }
-        catch (Exception) { }
-      }
-      else
-      {
-        control.Visible = val;
-      }
-    }
-
-    delegate void DisplayDialogCallback(Form control, bool modal);
-    public void DisplayDialog(Form control, bool modal)
-    {
-      if (InvokeRequired)
-      {
-        DisplayDialogCallback d = DisplayDialog;
-        try
-        {
-          Invoke(d, new object[] { control, modal });
-        }
-        catch (Exception) { }
-      }
-      else
-      {
-        if (modal)
-          control.ShowDialog(this);
-        else
-          control.Show(this);
-      }
-    }
-  }
-}
diff --git a/src/cec-config-gui/CecButtonConfig.cs b/src/cec-config-gui/CecButtonConfig.cs
deleted file mode 100644 (file)
index 1fb070d..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-using System.Collections.Generic;
-
-namespace CecConfigGui
-{
-  class CecButtonConfigItem
-  {
-    public CecButtonConfigItem(string name, CecSharp.CecKeypress key, string playerButton)
-    {
-      CecButtonName = name;
-      Key = key;
-      PlayerButton = playerButton;
-      _enabled = false;
-    }
-
-    public string PlayerButton { get; set; }
-    private bool _enabled;
-
-    public bool Enabled
-    {
-      get
-      {
-        return _enabled || PlayerButton.Length > 0;
-      }
-      set
-      {
-        _enabled = value;
-      }
-    }
-    public string CecButtonName { get; private set; }
-    public CecSharp.CecKeypress Key { get; private set; }
-  }
-
-  class CecButtonConfig : List<CecButtonConfigItem>
-  {
-  }
-}
diff --git a/src/cec-config-gui/CecConfigGUI.cs b/src/cec-config-gui/CecConfigGUI.cs
deleted file mode 100644 (file)
index 0e83c6a..0000000
+++ /dev/null
@@ -1,1223 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Drawing;
-using System.Text;
-using System.Windows.Forms;
-using System.Threading;
-using CecSharp;
-using CecConfigGui.actions;
-using System.Globalization;
-using System.IO;
-using System.Xml;
-
-namespace CecConfigGui
-{
-  internal enum ConfigTab
-  {
-    Configuration,
-    KeyConfiguration,
-    Tester,
-    Log
-  }
-
-  public partial class CecConfigGUI : AsyncForm
-  {
-    public CecConfigGUI()
-    {
-      Config = new LibCECConfiguration();
-      Config.DeviceTypes.Types[0] = CecDeviceType.RecordingDevice;
-      Config.DeviceName = "CEC Config";
-      Config.GetSettingsFromROM = true;
-      Config.ClientVersion = CecClientVersion.Version1_9_0;
-      Callbacks = new CecCallbackWrapper(this);
-      Config.SetCallbacks(Callbacks);
-      LoadXMLConfiguration(ref Config);
-      Lib = new LibCecSharp(Config);
-      Lib.InitVideoStandalone();
-
-      InitializeComponent();
-      LoadButtonConfiguration();
-
-      ActiveProcess = new ConnectToDevice(ref Lib, Config);
-      ActiveProcess.EventHandler += ProcessEventHandler;
-      (new Thread(ActiveProcess.Run)).Start();
-    }
-
-    private bool LoadXMLConfiguration(ref LibCECConfiguration config)
-    {
-      bool gotConfig = false;
-      string xbmcDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\XBMC\userdata\peripheral_data";
-      string defaultDir = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
-      string file = defaultDir + @"\usb_2548_1001.xml";
-      if (File.Exists(xbmcDir + @"\usb_2548_1001.xml"))
-        file = xbmcDir + @"\usb_2548_1001.xml";
-
-      if (File.Exists(file))
-      {
-        XmlTextReader reader = new XmlTextReader(file);
-        while (reader.Read())
-        {
-          gotConfig = true;
-          switch (reader.NodeType)
-          {
-            case XmlNodeType.Element:
-              if (reader.Name.ToLower() == "setting")
-              {
-                string name = string.Empty;
-                string value = string.Empty;
-
-                while (reader.MoveToNextAttribute())
-                {
-                  if (reader.Name.ToLower().Equals("id"))
-                    name = reader.Value.ToLower();
-                  if (reader.Name.ToLower().Equals("value"))
-                    value = reader.Value;
-                }
-
-                switch (name)
-                {
-                  case "cec_hdmi_port":
-                    {
-                      byte iPort;
-                      if (byte.TryParse(value, out iPort))
-                        config.HDMIPort = iPort;
-                    }
-                    break;
-                  case "connected_device":
-                    {
-                      ushort iDevice;
-                      if (ushort.TryParse(value, out iDevice))
-                        config.BaseDevice = (CecLogicalAddress)iDevice;
-                    }
-                    break;
-                  case "cec_power_on_startup":
-                    if (value.Equals("1") || value.ToLower().Equals("true") || value.ToLower().Equals("yes"))
-                    {
-                      config.ActivateSource = true;
-                      config.WakeDevices.Set(CecLogicalAddress.Tv);
-                    }
-                    break;
-                  case "cec_power_off_shutdown":
-                    if (value.Equals("1") || value.ToLower().Equals("true") || value.ToLower().Equals("yes"))
-                      config.PowerOffDevices.Set(CecLogicalAddress.Broadcast);
-                    break;
-                  case "cec_standby_screensaver":
-                    config.PowerOffScreensaver = value.Equals("1") || value.ToLower().Equals("true") || value.ToLower().Equals("yes");
-                    break;
-                  case "standby_pc_on_tv_standby":
-                    config.PowerOffOnStandby = value.Equals("1") || value.ToLower().Equals("true") || value.ToLower().Equals("yes");
-                    break;
-                  case "use_tv_menu_language":
-                    config.UseTVMenuLanguage = value.Equals("1") || value.ToLower().Equals("true") || value.ToLower().Equals("yes");
-                    break;
-                  // 1.5.0+ settings
-                  case "physical_address":
-                    {
-                      ushort physicalAddress = 0;
-                      if (ushort.TryParse(value, NumberStyles.AllowHexSpecifier, null, out physicalAddress))
-                        config.PhysicalAddress = physicalAddress;
-                    }
-                    break;
-                  case "device_type":
-                    {
-                      ushort iType;
-                      if (ushort.TryParse(value, out iType))
-                        config.DeviceTypes.Types[0] = (CecDeviceType)iType;
-                    }
-                    break;
-                  case "tv_vendor":
-                    {
-                      UInt64 iVendor;
-                      if (UInt64.TryParse(value, out iVendor))
-                        config.TvVendor = (CecVendorId)iVendor;
-                    }
-                    break;
-                  case "wake_devices":
-                    {
-                      config.WakeDevices.Clear();
-                      string[] split = value.Split(new[] { ' ' });
-                      foreach (string dev in split)
-                      {
-                        byte iLogicalAddress;
-                        if (byte.TryParse(dev, out iLogicalAddress))
-                          config.WakeDevices.Set((CecLogicalAddress)iLogicalAddress);
-                      }
-                    }
-                    break;
-                  case "standby_devices":
-                    {
-                      config.PowerOffDevices.Clear();
-                      string[] split = value.Split(new char[] { ' ' });
-                      foreach (string dev in split)
-                      {
-                        byte iLogicalAddress;
-                        if (byte.TryParse(dev, out iLogicalAddress))
-                          config.PowerOffDevices.Set((CecLogicalAddress)iLogicalAddress);
-                      }
-                    }
-                    break;
-                  case "enabled":
-                    break;
-                  case "port":
-                    //TODO
-                    break;
-                  // 1.5.1 settings
-                  case "send_inactive_source":
-                    config.SendInactiveSource = value.Equals("1") || value.ToLower().Equals("true") || value.ToLower().Equals("yes");
-                    break;
-                  default:
-                    break;
-                }
-              }
-              break;
-            default:
-              break;
-          }
-        }
-      }
-      return gotConfig;
-    }
-
-    private void LoadButtonConfiguration()
-    {
-      //TODO load the real configuration
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Select", (new CecKeypress { Keycode = CecUserControlCode.Select }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Up", (new CecKeypress { Keycode = CecUserControlCode.Up }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Down", (new CecKeypress { Keycode = CecUserControlCode.Down }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Left", (new CecKeypress { Keycode = CecUserControlCode.Left }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Right", (new CecKeypress { Keycode = CecUserControlCode.Right }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Right+Up", (new CecKeypress { Keycode = CecUserControlCode.RightUp }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Right+Down", (new CecKeypress { Keycode = CecUserControlCode.RightDown }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Left+Up", (new CecKeypress { Keycode = CecUserControlCode.LeftUp }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Left+Down", (new CecKeypress { Keycode = CecUserControlCode.LeftDown }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Root menu", (new CecKeypress { Keycode = CecUserControlCode.RootMenu }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Setup menu", (new CecKeypress { Keycode = CecUserControlCode.SetupMenu }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Contents menu", (new CecKeypress { Keycode = CecUserControlCode.ContentsMenu }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Favourite menu", (new CecKeypress { Keycode = CecUserControlCode.FavoriteMenu }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Exit", (new CecKeypress { Keycode = CecUserControlCode.Exit }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("0", (new CecKeypress { Keycode = CecUserControlCode.Number0 }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("1", (new CecKeypress { Keycode = CecUserControlCode.Number1 }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("2", (new CecKeypress { Keycode = CecUserControlCode.Number2 }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("3", (new CecKeypress { Keycode = CecUserControlCode.Number3 }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("4", (new CecKeypress { Keycode = CecUserControlCode.Number4 }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("5", (new CecKeypress { Keycode = CecUserControlCode.Number5 }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("6", (new CecKeypress { Keycode = CecUserControlCode.Number6 }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("7", (new CecKeypress { Keycode = CecUserControlCode.Number7 }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("8", (new CecKeypress { Keycode = CecUserControlCode.Number8 }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("9", (new CecKeypress { Keycode = CecUserControlCode.Number9 }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem(".", (new CecKeypress { Keycode = CecUserControlCode.Dot }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Enter", (new CecKeypress { Keycode = CecUserControlCode.Enter }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Clear", (new CecKeypress { Keycode = CecUserControlCode.Clear }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Next favourite", (new CecKeypress { Keycode = CecUserControlCode.NextFavorite }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Channel up", (new CecKeypress { Keycode = CecUserControlCode.ChannelUp }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Channel down", (new CecKeypress { Keycode = CecUserControlCode.ChannelDown }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Previous channel", (new CecKeypress { Keycode = CecUserControlCode.PreviousChannel }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Sound select", (new CecKeypress { Keycode = CecUserControlCode.SoundSelect }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Input select", (new CecKeypress { Keycode = CecUserControlCode.InputSelect }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Display information", (new CecKeypress { Keycode = CecUserControlCode.DisplayInformation }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Help", (new CecKeypress { Keycode = CecUserControlCode.Help }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Page up", (new CecKeypress { Keycode = CecUserControlCode.PageUp }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Page down", (new CecKeypress { Keycode = CecUserControlCode.PageDown }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Power", (new CecKeypress { Keycode = CecUserControlCode.Power }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Volume up", (new CecKeypress { Keycode = CecUserControlCode.VolumeUp }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Volume down", (new CecKeypress { Keycode = CecUserControlCode.VolumeDown }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Mute", (new CecKeypress { Keycode = CecUserControlCode.Mute }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Play", (new CecKeypress { Keycode = CecUserControlCode.Play }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Stop", (new CecKeypress { Keycode = CecUserControlCode.Stop }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Pause", (new CecKeypress { Keycode = CecUserControlCode.Pause }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Record", (new CecKeypress { Keycode = CecUserControlCode.Record }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Rewind", (new CecKeypress { Keycode = CecUserControlCode.Rewind }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Fast forward", (new CecKeypress { Keycode = CecUserControlCode.FastForward }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Eject", (new CecKeypress { Keycode = CecUserControlCode.Eject }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Forward", (new CecKeypress { Keycode = CecUserControlCode.Forward }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Backward", (new CecKeypress { Keycode = CecUserControlCode.Backward }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Stop record", (new CecKeypress { Keycode = CecUserControlCode.StopRecord }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Pause record", (new CecKeypress { Keycode = CecUserControlCode.PauseRecord }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Angle", (new CecKeypress { Keycode = CecUserControlCode.Angle }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Sub picture", (new CecKeypress { Keycode = CecUserControlCode.SubPicture }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Video on demand", (new CecKeypress { Keycode = CecUserControlCode.VideoOnDemand }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Electronic program guide", (new CecKeypress { Keycode = CecUserControlCode.ElectronicProgramGuide }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Timer programming", (new CecKeypress { Keycode = CecUserControlCode.TimerProgramming }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Initial configuration", (new CecKeypress { Keycode = CecUserControlCode.InitialConfiguration }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Play (function)", (new CecKeypress { Keycode = CecUserControlCode.PlayFunction }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Pause play (function)", (new CecKeypress { Keycode = CecUserControlCode.PausePlayFunction }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Record (function)", (new CecKeypress { Keycode = CecUserControlCode.RecordFunction }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Pause record (function)", (new CecKeypress { Keycode = CecUserControlCode .PauseRecordFunction }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Stop (function)", (new CecKeypress { Keycode = CecUserControlCode.StopFunction }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Mute (function)", (new CecKeypress { Keycode = CecUserControlCode.MuteFunction }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Restore volume", (new CecKeypress { Keycode = CecUserControlCode.RestoreVolumeFunction }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Tune", (new CecKeypress { Keycode = CecUserControlCode.TuneFunction }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Select media", (new CecKeypress { Keycode = CecUserControlCode.SelectMediaFunction }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Select AV input", (new CecKeypress { Keycode = CecUserControlCode.SelectAVInputFunction }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Select audio input", (new CecKeypress { Keycode = CecUserControlCode.SelectAudioInputFunction }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Power toggle", (new CecKeypress { Keycode = CecUserControlCode.PowerToggleFunction }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Power off", (new CecKeypress { Keycode = CecUserControlCode.PowerOffFunction }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Power on", (new CecKeypress { Keycode = CecUserControlCode.PowerOnFunction }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("F1 (blue)", (new CecKeypress { Keycode = CecUserControlCode.F1Blue }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("F2 (red)", (new CecKeypress { Keycode = CecUserControlCode.F2Red }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("F3 (green)", (new CecKeypress { Keycode = CecUserControlCode.F3Green }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("F4 (yellow)", (new CecKeypress { Keycode = CecUserControlCode.F4Yellow }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("F5", (new CecKeypress { Keycode = CecUserControlCode.F5 }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Data", (new CecKeypress { Keycode = CecUserControlCode.Data }), string.Empty));
-      cecButtonConfigBindingSource.Add(new CecButtonConfigItem("Return (Samsung)", (new CecKeypress { Keycode = CecUserControlCode.SamsungReturn }), string.Empty));
-    }
-
-    private void ProcessEventHandler(object src, UpdateEvent updateEvent)
-    {
-      switch (updateEvent.Type)
-      {
-        case UpdateEventType.StatusText:
-          SetControlText(lStatus, updateEvent.StringValue);
-          break;
-        case UpdateEventType.PhysicalAddress:
-          Config.PhysicalAddress = (ushort)updateEvent.IntValue;
-          SetControlText(tbPhysicalAddress, string.Format("{0,4:X}", updateEvent.IntValue));
-          break;
-        case UpdateEventType.ProgressBar:
-          SetControlVisible(pProgress, true);
-          SetProgressValue(pProgress, updateEvent.IntValue);
-          break;
-        case UpdateEventType.TVVendorId:
-          TVVendor = (CecVendorId)updateEvent.IntValue;
-          UpdateSelectedDevice();
-          break;
-        case UpdateEventType.BaseDevicePhysicalAddress:
-          SetControlText(lConnectedPhysicalAddress, string.Format("Address: {0,4:X}", updateEvent.IntValue));
-          break;
-        case UpdateEventType.BaseDevice:
-          Config.BaseDevice = (CecLogicalAddress)updateEvent.IntValue;
-          break;
-        case UpdateEventType.HDMIPort:
-          Config.HDMIPort = (byte)updateEvent.IntValue;
-          break;
-        case UpdateEventType.MenuLanguage:
-          SetControlText(cbUseTVMenuLanguage, "Use the TV's language setting" + (updateEvent.StringValue.Length > 0 ? " (" + updateEvent.StringValue + ")" : ""));
-          break;
-        case UpdateEventType.HasAVRDevice:
-          if (HasAVRDevice != updateEvent.BoolValue)
-          {
-            HasAVRDevice = updateEvent.BoolValue;
-            UpdateSelectedDevice();
-          }
-          break;
-        case UpdateEventType.AVRVendorId:
-          AVRVendor = (CecVendorId)updateEvent.IntValue;
-          UpdateSelectedDevice();
-          break;
-        case UpdateEventType.Configuration:
-          SuppressUpdates = true;
-          ConfigurationChanged(updateEvent.ConfigValue);
-          SuppressUpdates = false;
-          break;
-        case UpdateEventType.PollDevices:
-          CheckActiveDevices();
-          break;
-        case UpdateEventType.ProcessCompleted:
-          ActiveProcess = null;
-          SetControlsEnabled(true);
-          if (UpdatingInfoPanel != null)
-          {
-            UpdatingInfoPanel.SetControlEnabled(UpdatingInfoPanel.bUpdate, true);
-            UpdatingInfoPanel = null;
-          }
-          SetControlVisible(pProgress, false);
-          break;
-        case UpdateEventType.ExitApplication:
-          ActiveProcess = null;
-          SetControlsEnabled(false);
-          SetControlVisible(pProgress, false);
-          Application.Exit();
-          break;
-      }
-    }
-
-    private void SetControlsEnabled(bool val)
-    {
-      SetControlEnabled(cbPortNumber, val && !cbOverrideAddress.Checked);
-      SetControlEnabled(cbConnectedDevice, cbConnectedDevice.Items.Count > 1 && !cbOverrideAddress.Checked && val);
-      SetControlEnabled(cbOverrideAddress, val);
-      SetControlEnabled(tbPhysicalAddress, val && !Config.AutodetectAddress && cbOverrideAddress.Checked);
-      SetControlEnabled(cbDeviceType, val);
-      SetControlEnabled(cbUseTVMenuLanguage, val);
-      SetControlEnabled(cbActivateSource, val);
-      SetControlEnabled(cbPowerOffScreensaver, val);
-      SetControlEnabled(cbPowerOffOnStandby, val);
-      SetControlEnabled(cbWakeDevices, val);
-      SetControlEnabled(cbPowerOffDevices, val);
-      SetControlEnabled(cbVendorOverride, val);
-      SetControlEnabled(cbVendorId, val && cbVendorOverride.Checked);
-      SetControlEnabled(cbSendInactiveSource, val);
-      SetControlEnabled(bClose, val);
-      SetControlEnabled(bSaveConfig, val);
-      SetControlEnabled(bReloadConfig, val);
-      SetControlEnabled(bRescanDevices, val);
-
-      SetControlEnabled(bSendImageViewOn, val);
-      SetControlEnabled(bStandby, val);
-      SetControlEnabled(bActivateSource, val);
-      SetControlEnabled(bScan, val);
-
-      bool enableVolumeButtons = (GetTargetDevice() == CecLogicalAddress.AudioSystem) && val;
-      SetControlEnabled(bVolUp, enableVolumeButtons);
-      SetControlEnabled(bVolDown, enableVolumeButtons);
-      SetControlEnabled(bMute, enableVolumeButtons);
-    }
-
-    private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
-    {
-      switch (tabControl1.SelectedIndex)
-      {
-        case 0:
-          SelectedTab = ConfigTab.Configuration;
-          break;
-        case 1:
-          SelectedTab = ConfigTab.KeyConfiguration;
-          break;
-        case 2:
-          SelectedTab = ConfigTab.Tester;
-          break;
-        case 3:
-          SelectedTab = ConfigTab.Log;
-          UpdateLog();
-          break;
-        default:
-          SelectedTab = ConfigTab.Configuration;
-          break;
-      }
-    }
-
-    protected override void Dispose(bool disposing)
-    {
-      if (disposing)
-      {
-        Lib.DisableCallbacks();
-        Lib.StandbyDevices(CecLogicalAddress.Broadcast);
-        Lib.Close();
-      }
-      if (disposing && (components != null))
-      {
-        components.Dispose();
-      }
-      base.Dispose(disposing);
-    }
-
-    #region Actions
-    public void ReloadXmlConfiguration()
-    {
-      LoadXMLConfiguration(ref Config);
-      Lib.SetConfiguration(Config);
-      ConfigurationChanged(Config);
-    }
-
-    public void UpdateInfoPanel(DeviceInformation panel)
-    {
-      if (!SuppressUpdates && ActiveProcess == null)
-      {
-        SetControlsEnabled(false);
-        UpdatingInfoPanel = panel;
-        panel.SetControlEnabled(panel.bUpdate, false);
-        ActiveProcess = new UpdateDeviceInfo(this, ref Lib, panel);
-        ActiveProcess.EventHandler += ProcessEventHandler;
-        (new Thread(ActiveProcess.Run)).Start();
-      }
-    }
-
-    public void SetPhysicalAddress(ushort physicalAddress)
-    {
-      if (!SuppressUpdates && ActiveProcess == null && cbOverrideAddress.Checked)
-      {
-        SetControlsEnabled(false);
-        SetControlText(cbPortNumber, string.Empty);
-        SetControlText(cbConnectedDevice, string.Empty);
-        ActiveProcess = new UpdatePhysicalAddress(ref Lib, physicalAddress);
-        ActiveProcess.EventHandler += ProcessEventHandler;
-        (new Thread(ActiveProcess.Run)).Start();
-      }
-    }
-
-    public void UpdateConfigurationAsync()
-    {
-      if (!SuppressUpdates && ActiveProcess == null)
-      {
-        SetControlsEnabled(false);
-        ActiveProcess = new UpdateConfiguration(ref Lib, Config);
-        ActiveProcess.EventHandler += ProcessEventHandler;
-        (new Thread(ActiveProcess.Run)).Start();
-      }
-    }
-
-    public void SendImageViewOn(CecLogicalAddress address)
-    {
-      if (!SuppressUpdates && ActiveProcess == null)
-      {
-        SetControlsEnabled(false);
-        ActiveProcess = new SendImageViewOn(ref Lib, address);
-        ActiveProcess.EventHandler += ProcessEventHandler;
-        (new Thread(ActiveProcess.Run)).Start();
-      }
-    }
-
-    public void ActivateSource(CecLogicalAddress address)
-    {
-      if (!SuppressUpdates && ActiveProcess == null)
-      {
-        SetControlsEnabled(false);
-        ActiveProcess = new SendActivateSource(ref Lib, address);
-        ActiveProcess.EventHandler += ProcessEventHandler;
-        (new Thread(ActiveProcess.Run)).Start();
-      }
-    }
-
-    public void SendStandby(CecLogicalAddress address)
-    {
-      if (!SuppressUpdates && ActiveProcess == null)
-      {
-        SetControlsEnabled(false);
-        ActiveProcess = new SendStandby(ref Lib, address);
-        ActiveProcess.EventHandler += ProcessEventHandler;
-        (new Thread(ActiveProcess.Run)).Start();
-      }
-    }
-
-    public void ShowDeviceInfo(CecLogicalAddress address)
-    {
-      if (!SuppressUpdates && ActiveProcess == null)
-      {
-        SetControlsEnabled(false);
-        ActiveProcess = new ShowDeviceInfo(this, ref Lib, address);
-        ActiveProcess.EventHandler += ProcessEventHandler;
-        (new Thread(ActiveProcess.Run)).Start();
-      }
-    }
-    #endregion
-
-    #region Configuration tab
-    private void cbOverrideAddress_CheckedChanged(object sender, EventArgs e)
-    {
-      SetControlEnabled(tbPhysicalAddress, ((CheckBox)sender).Checked);
-      SetControlEnabled(cbPortNumber, !((CheckBox)sender).Checked);
-      SetControlEnabled(cbConnectedDevice, !((CheckBox)sender).Checked && cbConnectedDevice.Items.Count > 1);
-    }
-
-    private void tbPhysicalAddress_TextChanged(object sender, EventArgs e)
-    {
-      if (tbPhysicalAddress.Text.Length != 4 ||
-          cbOverrideAddress.Checked)
-        return;
-      ushort physicalAddress = 0;
-      if (!ushort.TryParse(tbPhysicalAddress.Text, NumberStyles.AllowHexSpecifier, null, out physicalAddress))
-        return;
-
-      SetPhysicalAddress(physicalAddress);
-    }
-
-    private void UpdateSelectedDevice()
-    {
-      if (HasAVRDevice)
-        SetComboBoxItems(cbConnectedDevice, Config.BaseDevice == CecLogicalAddress.AudioSystem ? AVRVendorString : TVVendorString, new object[] { TVVendorString, AVRVendorString });
-      else
-        SetComboBoxItems(cbConnectedDevice, TVVendorString, new object[] { TVVendorString });
-    }
-
-    public void SetConnectedDevice(CecLogicalAddress address, int portnumber)
-    {
-      if (!SuppressUpdates && ActiveProcess == null)
-      {
-        SetControlsEnabled(false);
-        ActiveProcess = new UpdateConnectedDevice(ref Lib, address, portnumber);
-        ActiveProcess.EventHandler += ProcessEventHandler;
-        (new Thread(ActiveProcess.Run)).Start();
-      }
-    }
-
-    private void connectedDevice_SelectedIndexChanged(object sender, EventArgs e)
-    {
-      SetConnectedDevice(SelectedConnectedDevice, SelectedPortNumber);
-    }
-
-    private void bCancel_Click(object sender, EventArgs e)
-    {
-      Dispose();
-    }
-
-    private void bSave_Click(object sender, EventArgs e)
-    {
-      SetControlsEnabled(false);
-
-      Config.UseTVMenuLanguage = cbUseTVMenuLanguage.Checked;
-      Config.ActivateSource = cbActivateSource.Checked;
-      Config.PowerOffScreensaver = cbPowerOffScreensaver.Checked;
-      Config.PowerOffOnStandby = cbPowerOffOnStandby.Checked;
-      Config.SendInactiveSource = cbSendInactiveSource.Checked;
-      Config.WakeDevices = WakeDevices;
-      Config.PowerOffDevices = PowerOffDevices;
-
-      /* save settings in the eeprom */
-      Lib.PersistConfiguration(Config);
-
-      /* and in xml */
-      if (ActiveProcess == null)
-      {
-        SetControlsEnabled(false);
-        string xbmcDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\XBMC\userdata\peripheral_data";
-        string defaultDir = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
-
-        SaveFileDialog dialog = new SaveFileDialog()
-        {
-          Title = "Where do you want to store the settings?",
-          InitialDirectory = Directory.Exists(xbmcDir) ? xbmcDir : defaultDir,
-          FileName = "usb_2548_1001.xml",
-          Filter = "xml files (*.xml)|*.xml|All files (*.*)|*.*",
-          FilterIndex = 1
-        };
-
-        if (dialog.ShowDialog() == DialogResult.OK)
-        {
-          FileStream fs = null;
-          string error = string.Empty;
-          try
-          {
-            fs = (FileStream)dialog.OpenFile();
-          }
-          catch (Exception ex)
-          {
-            error = ex.Message;
-          }
-          if (fs == null)
-          {
-            MessageBox.Show("Cannot open '" + dialog.FileName + "' for writing" + (error.Length > 0 ? ": " + error : string.Empty ), "Pulse-Eight USB-CEC Adapter", MessageBoxButtons.OK, MessageBoxIcon.Error);
-          }
-          else
-          {
-            StreamWriter writer = new StreamWriter(fs);
-            StringBuilder output = new StringBuilder();
-            output.AppendLine("<settings>");
-            output.AppendLine("<setting id=\"cec_hdmi_port\" value=\"" + Config.HDMIPort + "\" />");
-            output.AppendLine("<setting id=\"connected_device\" value=\"" + (Config.BaseDevice == CecLogicalAddress.AudioSystem ? 5 : 0) + "\" />");
-            output.AppendLine("<setting id=\"cec_power_on_startup\" value=\"" + (Config.ActivateSource ? 1 : 0) + "\" />");
-            output.AppendLine("<setting id=\"cec_power_off_shutdown\" value=\"" + (Config.PowerOffDevices.IsSet(CecLogicalAddress.Broadcast) ? 1 : 0) + "\" />");
-            output.AppendLine("<setting id=\"cec_standby_screensaver\" value=\"" + (Config.PowerOffScreensaver ? 1 : 0) + "\" />");
-            output.AppendLine("<setting id=\"standby_pc_on_tv_standby\" value=\"" + (Config.PowerOffOnStandby ? 1 : 0) + "\" />");
-            output.AppendLine("<setting id=\"use_tv_menu_language\" value=\"" + (Config.UseTVMenuLanguage ? 1 : 0) + "\" />");
-            output.AppendLine("<setting id=\"enabled\" value=\"1\" />");
-            output.AppendLine("<setting id=\"port\" value=\"\" />");
-
-            // only supported by 1.5.0+ clients
-            output.AppendLine("<!-- the following lines are only supported by v1.5.0+ clients -->");
-            output.AppendLine("<setting id=\"activate_source\" value=\"" + (Config.ActivateSource ? 1 : 0) + "\" />");
-            output.AppendLine("<setting id=\"physical_address\" value=\"" + string.Format("{0,4:X}", cbOverrideAddress.Checked ? Config.PhysicalAddress : 0).Trim() + "\" />");
-            output.AppendLine("<setting id=\"device_type\" value=\"" + (int)Config.DeviceTypes.Types[0] + "\" />");
-            output.AppendLine("<setting id=\"tv_vendor\" value=\"" + string.Format("{0,6:X}", (int)Config.TvVendor).Trim() + "\" />");
-
-            output.Append("<setting id=\"wake_devices\" value=\"");
-            StringBuilder strWakeDevices = new StringBuilder();
-            foreach (CecLogicalAddress addr in Config.WakeDevices.Addresses)
-              if (addr != CecLogicalAddress.Unknown)
-                strWakeDevices.Append(" " + (int)addr);
-            output.Append(strWakeDevices.ToString().Trim());
-            output.AppendLine("\" />");
-
-            output.Append("<setting id=\"standby_devices\" value=\"");
-            StringBuilder strSleepDevices = new StringBuilder();
-            foreach (CecLogicalAddress addr in Config.PowerOffDevices.Addresses)
-              if (addr != CecLogicalAddress.Unknown)
-                strSleepDevices.Append(" " + (int)addr);
-            output.Append(strSleepDevices.ToString().Trim()); 
-            output.AppendLine("\" />");
-
-            // only supported by 1.5.1+ clients
-            output.AppendLine("<!-- the following lines are only supported by v1.5.1+ clients -->");
-            output.AppendLine("<setting id=\"send_inactive_source\" value=\"" + (Config.SendInactiveSource ? 1 : 0) + "\" />");
-
-            output.AppendLine("</settings>");
-            writer.Write(output.ToString());
-            writer.Close();
-            fs.Close();
-            fs.Dispose();
-            MessageBox.Show("Settings are stored.", "Pulse-Eight USB-CEC Adapter", MessageBoxButtons.OK, MessageBoxIcon.Information);
-          }
-        }
-        SetControlsEnabled(true);
-      }
-    }
-
-    private void bReloadConfig_Click(object sender, EventArgs e)
-    {
-      if (Lib.CanPersistConfiguration())
-      {
-        Lib.GetCurrentConfiguration(Config);
-        ConfigurationChanged(Config);
-      }
-      else
-      {
-        ReloadXmlConfiguration();
-      }
-    }
-
-    private void cbVendorOverride_CheckedChanged(object sender, EventArgs e)
-    {
-      if (cbVendorOverride.Checked)
-      {
-        cbVendorId.Enabled = true;
-        switch (cbVendorId.Text)
-        {
-          case "LG":
-            Config.TvVendor = CecVendorId.LG;
-            break;
-          case "Onkyo":
-            Config.TvVendor = CecVendorId.Onkyo;
-            break;
-          case "Panasonic":
-            Config.TvVendor = CecVendorId.Panasonic;
-            break;
-          case "Philips":
-            Config.TvVendor = CecVendorId.Philips;
-            break;
-          case "Pioneer":
-            Config.TvVendor = CecVendorId.Pioneer;
-            break;
-          case "Samsung":
-            Config.TvVendor = CecVendorId.Samsung;
-            break;
-          case "Sony":
-            Config.TvVendor = CecVendorId.Sony;
-            break;
-          case "Yamaha":
-            Config.TvVendor = CecVendorId.Yamaha;
-            break;
-          default:
-            Config.TvVendor = CecVendorId.Unknown;
-            break;
-        }
-      }
-      else
-      {
-        cbVendorId.Enabled = false;
-        Config.TvVendor = CecVendorId.Unknown;
-      }
-    }
-
-    private void cbDeviceType_SelectedIndexChanged(object sender, EventArgs e)
-    {
-      CecDeviceType type = SelectedDeviceType;
-      if (type != Config.DeviceTypes.Types[0])
-      {
-        Config.DeviceTypes.Types[0] = type;
-        if (!DeviceChangeWarningDisplayed)
-        {
-          DeviceChangeWarningDisplayed = true;
-          MessageBox.Show("You have changed the device type. Save the configuration, and restart the application to use the new setting.", "Pulse-Eight USB-CEC Adapter", MessageBoxButtons.OK, MessageBoxIcon.Warning);
-        }
-      }
-    }
-    #endregion
-
-    #region Key configuration tab
-    delegate void SelectKeypressRowCallback(CecKeypress key);
-    private void SelectKeypressRow(CecKeypress key)
-    {
-      if (dgButtons.InvokeRequired)
-      {
-        SelectKeypressRowCallback d = SelectKeypressRow;
-        try
-        {
-          Invoke(d, new object[] { key });
-        }
-        catch (Exception) { }
-      }
-      else
-      {
-        int rowIndex = -1;
-        foreach (DataGridViewRow row in dgButtons.Rows)
-        {
-          CecButtonConfigItem item = row.DataBoundItem as CecButtonConfigItem;
-          if (item != null && item.Key.Keycode == key.Keycode)
-          {
-            rowIndex = row.Index;
-            row.Selected = true;
-            item.Enabled = true;
-          }
-          else
-          {
-            row.Selected = false;
-          }
-        }
-        if (rowIndex > -1)
-          dgButtons.FirstDisplayedScrollingRowIndex = rowIndex;
-      }
-    }
-
-    private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
-    {
-      DataGridView grid = sender as DataGridView;
-      CecButtonConfigItem data = grid.Rows[e.RowIndex].DataBoundItem as CecButtonConfigItem;
-      if (data == null || !data.Enabled)
-        e.CellStyle.ForeColor = Color.Gray;
-    }
-    #endregion
-
-    #region CEC Tester tab
-    public void CheckActiveDevices()
-    {
-      CecLogicalAddresses activeDevices = Lib.GetActiveDevices();
-      List<string> deviceList = new List<string>();
-      foreach (CecLogicalAddress activeDevice in activeDevices.Addresses)
-      {
-        if (activeDevice != CecLogicalAddress.Unknown)
-          deviceList.Add(string.Format("{0,1:X} : {1}", (int)activeDevice, Lib.ToString(activeDevice)));
-      }
-      deviceList.Add(string.Format("{0,1:X} : {1}", (int)CecLogicalAddress.Broadcast, Lib.ToString(CecLogicalAddress.Broadcast)));
-
-      SetActiveDevices(deviceList.ToArray());
-    }
-
-    delegate void SetActiveDevicesCallback(string[] activeDevices);
-    private void SetActiveDevices(string[] activeDevices)
-    {
-      if (cbCommandDestination.InvokeRequired)
-      {
-        SetActiveDevicesCallback d = SetActiveDevices;
-        try
-        {
-          Invoke(d, new object[] { activeDevices });
-        }
-        catch (Exception) { }
-      }
-      else
-      {
-        cbCommandDestination.Items.Clear();
-        foreach (string item in activeDevices)
-          cbCommandDestination.Items.Add(item);
-      }
-    }
-
-    delegate CecLogicalAddress GetTargetDeviceCallback();
-    private CecLogicalAddress GetTargetDevice()
-    {
-      if (cbCommandDestination.InvokeRequired)
-      {
-        GetTargetDeviceCallback d = GetTargetDevice;
-        CecLogicalAddress retval = CecLogicalAddress.Unknown;
-        try
-        {
-          retval = (CecLogicalAddress)Invoke(d, new object[] { });
-        }
-        catch (Exception) { }
-        return retval;
-      }
-
-      return GetLogicalAddressFromString(cbCommandDestination.Text);
-    }
-
-    private CecLogicalAddress GetLogicalAddressFromString(string name)
-    {
-      switch (name.Substring(0, 1).ToLower())
-      {
-        case "0":
-          return CecLogicalAddress.Tv;
-        case "1":
-          return CecLogicalAddress.RecordingDevice1;
-        case "2":
-          return CecLogicalAddress.RecordingDevice2;
-        case "3":
-          return CecLogicalAddress.Tuner1;
-        case "4":
-          return CecLogicalAddress.PlaybackDevice1;
-        case "5":
-          return CecLogicalAddress.AudioSystem;
-        case "6":
-          return CecLogicalAddress.Tuner2;
-        case "7":
-          return CecLogicalAddress.Tuner3;
-        case "8":
-          return CecLogicalAddress.PlaybackDevice2;
-        case "9":
-          return CecLogicalAddress.RecordingDevice3;
-        case "a":
-          return CecLogicalAddress.Tuner4;
-        case "b":
-          return CecLogicalAddress.PlaybackDevice3;
-        case "c":
-          return CecLogicalAddress.Reserved1;
-        case "d":
-          return CecLogicalAddress.Reserved2;
-        case "e":
-          return CecLogicalAddress.FreeUse;
-        case "f":
-          return CecLogicalAddress.Broadcast;
-        default:
-          return CecLogicalAddress.Unknown;
-      }
-    }
-
-    private void bSendImageViewOn_Click(object sender, EventArgs e)
-    {
-      SendImageViewOn(GetTargetDevice());
-    }
-
-    private void bStandby_Click(object sender, EventArgs e)
-    {
-      SendStandby(GetTargetDevice());
-    }
-
-    private void bScan_Click(object sender, EventArgs e)
-    {
-      ShowDeviceInfo(GetTargetDevice());
-    }
-
-    private void bActivateSource_Click(object sender, EventArgs e)
-    {
-      ActivateSource(GetTargetDevice());
-    }
-
-    private void cbCommandDestination_SelectedIndexChanged(object sender, EventArgs e)
-    {
-      bool enableVolumeButtons = (GetTargetDevice() == CecLogicalAddress.AudioSystem);
-      bVolUp.Enabled = enableVolumeButtons;
-      bVolDown.Enabled = enableVolumeButtons;
-      bMute.Enabled = enableVolumeButtons;
-      bActivateSource.Enabled = (GetTargetDevice() != CecLogicalAddress.Broadcast);
-      bScan.Enabled = (GetTargetDevice() != CecLogicalAddress.Broadcast);
-    }
-
-    private void bVolUp_Click(object sender, EventArgs e)
-    {
-      SetControlsEnabled(false);
-      Lib.VolumeUp(true);
-      SetControlsEnabled(true);
-    }
-
-    private void bVolDown_Click(object sender, EventArgs e)
-    {
-      SetControlsEnabled(false);
-      Lib.VolumeDown(true);
-      SetControlsEnabled(true);
-    }
-
-    private void bMute_Click(object sender, EventArgs e)
-    {
-      SetControlsEnabled(false);
-      Lib.MuteAudio(true);
-      SetControlsEnabled(true);
-    }
-
-    private void bRescanDevices_Click(object sender, EventArgs e)
-    {
-      if (!SuppressUpdates && ActiveProcess == null)
-      {
-        SetControlsEnabled(false);
-        ActiveProcess = new RescanDevices(ref Lib);
-        ActiveProcess.EventHandler += ProcessEventHandler;
-        (new Thread(ActiveProcess.Run)).Start();
-      }
-    }
-    #endregion
-
-    #region Log tab
-    delegate void UpdateLogCallback();
-    private void UpdateLog()
-    {
-      if (tbLog.InvokeRequired)
-      {
-        UpdateLogCallback d = UpdateLog;
-        try
-        {
-          Invoke(d, new object[] { });
-        }
-        catch (Exception) { }
-      }
-      else
-      {
-        tbLog.Text = Log;
-        tbLog.Select(tbLog.Text.Length, 0);
-        tbLog.ScrollToCaret();
-      }
-    }
-
-    private void AddLogMessage(CecLogMessage message)
-    {
-      string strLevel = "";
-      bool display = false;
-      switch (message.Level)
-      {
-        case CecLogLevel.Error:
-          strLevel = "ERROR:   ";
-          display = cbLogError.Checked;
-          break;
-        case CecLogLevel.Warning:
-          strLevel = "WARNING: ";
-          display = cbLogWarning.Checked;
-          break;
-        case CecLogLevel.Notice:
-          strLevel = "NOTICE:  ";
-          display = cbLogNotice.Checked;
-          break;
-        case CecLogLevel.Traffic:
-          strLevel = "TRAFFIC: ";
-          display = cbLogTraffic.Checked;
-          break;
-        case CecLogLevel.Debug:
-          strLevel = "DEBUG:   ";
-          display = cbLogDebug.Checked;
-          break;
-        default:
-          break;
-      }
-
-      if (display)
-      {
-        string strLog = string.Format("{0} {1,16} {2}", strLevel, message.Time, message.Message) + System.Environment.NewLine;
-        Log += strLog;
-      }
-
-      if (SelectedTab == ConfigTab.Log)
-        UpdateLog();
-    }
-
-    private void bClearLog_Click(object sender, EventArgs e)
-    {
-      Log = string.Empty;
-      UpdateLog();
-    }
-
-    private void bSaveLog_Click(object sender, EventArgs e)
-    {
-      SaveFileDialog dialog = new SaveFileDialog()
-      {
-        Title = "Where do you want to store the log file?",
-        InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
-        FileName = "cec-log.txt",
-        Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*",
-        FilterIndex = 1
-      };
-
-      if (dialog.ShowDialog() == DialogResult.OK)
-      {
-        FileStream fs = (FileStream)dialog.OpenFile();
-        if (fs == null)
-        {
-          MessageBox.Show("Cannot open '" + dialog.FileName + "' for writing", "Pulse-Eight USB-CEC Adapter", MessageBoxButtons.OK, MessageBoxIcon.Error);
-        }
-        else
-        {
-          StreamWriter writer = new StreamWriter(fs);
-          writer.Write(Log);
-          writer.Close();
-          fs.Close();
-          fs.Dispose();
-          MessageBox.Show("The log file was stored as '" + dialog.FileName + "'.", "Pulse-Eight USB-CEC Adapter", MessageBoxButtons.OK, MessageBoxIcon.Information);
-        }
-      }
-    }
-    #endregion
-
-    #region LibCecSharp callbacks
-    public int ConfigurationChanged(LibCECConfiguration config)
-    {
-      Config = config;
-      SetControlText(tbPhysicalAddress, string.Format("{0,4:X}", Config.PhysicalAddress));
-      SetControlText(cbConnectedDevice, Config.BaseDevice == CecLogicalAddress.AudioSystem ? AVRVendorString : TVVendorString);
-      SetControlText(cbPortNumber, Config.HDMIPort.ToString());
-      switch (config.DeviceTypes.Types[0])
-      {
-        case CecDeviceType.RecordingDevice:
-          SetControlText(cbDeviceType, "Recorder");
-          break;
-        case CecDeviceType.PlaybackDevice:
-          SetControlText(cbDeviceType, "Player");
-          break;
-        case CecDeviceType.Tuner:
-          SetControlText(cbDeviceType, "Tuner");
-          break;
-        default:
-          SetControlText(cbDeviceType, "Recorder");
-          break;
-      }
-      if (config.TvVendor != CecVendorId.Unknown)
-      {
-        SetCheckboxChecked(cbVendorOverride, true);
-        SetControlText(cbVendorId, Lib.ToString(config.TvVendor));
-      }
-      else
-      {
-        SetCheckboxChecked(cbVendorOverride, false);
-        SetControlText(cbVendorId, Lib.ToString(TVVendor));
-      }
-
-      SetCheckboxChecked(cbUseTVMenuLanguage, Config.UseTVMenuLanguage);
-      SetCheckboxChecked(cbActivateSource, Config.ActivateSource);
-      SetCheckboxChecked(cbPowerOffScreensaver, Config.PowerOffScreensaver);
-      SetCheckboxChecked(cbPowerOffOnStandby, Config.PowerOffOnStandby);
-      SetCheckboxChecked(cbSendInactiveSource, Config.SendInactiveSource);
-      UpdateSelectedDevice();
-
-      for (int iPtr = 0; iPtr < 15; iPtr++)
-        SetCheckboxItemChecked(cbWakeDevices, iPtr, Config.WakeDevices.IsSet((CecLogicalAddress)iPtr));
-      for (int iPtr = 0; iPtr < 15; iPtr++)
-        SetCheckboxItemChecked(cbPowerOffDevices, iPtr, Config.PowerOffDevices.IsSet((CecLogicalAddress)iPtr));
-
-      SetControlText(this, "Pulse-Eight USB-CEC Adapter - libCEC " + Lib.ToString(Config.ServerVersion));
-      return 1;
-    }
-
-    public int ReceiveCommand(CecCommand command)
-    {
-      return 1;
-    }
-
-    public int ReceiveKeypress(CecKeypress key)
-    {
-      SelectKeypressRow(key);
-      return 1;
-    }
-
-    public int ReceiveLogMessage(CecLogMessage message)
-    {
-      try
-      {
-        AddLogMessage(message);
-      }
-      catch (Exception) { }
-      return 1;
-    }
-    #endregion
-
-    #region Class members
-    public bool HasAVRDevice { get; private set; }
-    #region TV Vendor
-    private CecVendorId _tvVendor = CecVendorId.Unknown;
-    public CecVendorId TVVendor
-    {
-      get { return _tvVendor;}
-      private set { _tvVendor = value; }
-    }
-    public string TVVendorString
-    {
-      get
-      {
-        return TVVendor != CecVendorId.Unknown ?
-          "Television (" + Lib.ToString(TVVendor) + ")" :
-          "Television";
-      }
-    }
-    #endregion
-    #region AVR Vendor
-    private CecVendorId _avrVendor = CecVendorId.Unknown;
-    public CecVendorId AVRVendor
-    {
-      get { return _avrVendor; }
-      private set { _avrVendor = value; }
-    }
-    public string AVRVendorString
-    {
-      get
-      {
-        return AVRVendor != CecVendorId.Unknown ?
-          "AVR (" + Lib.ToString(AVRVendor) + ")" :
-          "AVR";
-      }
-    }
-    #endregion
-    public CecLogicalAddress SelectedConnectedDevice
-    {
-      get
-      {
-        return (cbConnectedDevice.Text.Equals(AVRVendorString)) ? CecLogicalAddress.AudioSystem : CecLogicalAddress.Tv;
-      }
-    }
-    public CecDeviceType SelectedDeviceType
-    {
-      get
-      {
-        switch (cbDeviceType.Text.ToLower())
-        {
-          case "player":
-            return CecDeviceType.PlaybackDevice;
-          case "tuner":
-            return CecDeviceType.Tuner;
-          default:
-            return CecDeviceType.RecordingDevice;
-        }
-      }
-    }
-    public int SelectedPortNumber
-    {
-      get
-      {
-        int iPortNumber = 0;
-        if (!int.TryParse(cbPortNumber.Text, out iPortNumber))
-          iPortNumber = 1;
-        return iPortNumber;
-      }
-    }
-    protected LibCECConfiguration Config;
-    protected LibCecSharp Lib;
-    private CecCallbackWrapper Callbacks;
-    private UpdateProcess ActiveProcess = null;
-    private bool SuppressUpdates = true;
-    private ConfigTab SelectedTab = ConfigTab.Configuration;
-    private string Log = string.Empty;
-    private DeviceInformation UpdatingInfoPanel = null;
-    private bool DeviceChangeWarningDisplayed = false;
-    public CecLogicalAddresses WakeDevices
-    {
-      get
-      {
-        CecLogicalAddresses addr = new CecLogicalAddresses();
-        foreach (object item in cbWakeDevices.CheckedItems)
-        {
-          string c = item as string;
-          addr.Set(GetLogicalAddressFromString(c));
-        }
-        return addr;
-      }
-    }
-    public CecLogicalAddresses PowerOffDevices
-    {
-      get
-      {
-        CecLogicalAddresses addr = new CecLogicalAddresses();
-        foreach (object item in cbPowerOffDevices.CheckedItems)
-        {
-          string c = item as string;
-          addr.Set(GetLogicalAddressFromString(c));
-        }
-        return addr;
-      }
-    }
-    #endregion
-  }
-
-  /// <summary>
-  /// A little wrapper that is needed because we already inherit form
-  /// </summary>
-  internal class CecCallbackWrapper : CecCallbackMethods
-  {
-    public CecCallbackWrapper(CecConfigGUI gui)
-    {
-      Gui = gui;
-    }
-
-    public override int ReceiveCommand(CecCommand command)
-    {
-      return Gui.ReceiveCommand(command);
-    }
-
-    public override int ReceiveKeypress(CecKeypress key)
-    {
-      return Gui.ReceiveKeypress(key);
-    }
-
-    public override int ReceiveLogMessage(CecLogMessage message)
-    {
-      return Gui.ReceiveLogMessage(message);
-    }
-
-    public override int ConfigurationChanged(LibCECConfiguration config)
-    {
-      return Gui.ConfigurationChanged(config);
-    }
-
-    private CecConfigGUI Gui;
-  }
-}
diff --git a/src/cec-config-gui/DeviceInformation.cs b/src/cec-config-gui/DeviceInformation.cs
deleted file mode 100644 (file)
index f7992e3..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-using System;
-using System.Windows.Forms;
-using CecSharp;
-
-namespace CecConfigGui
-{
-  public partial class DeviceInformation : AsyncForm
-  {
-    public DeviceInformation(CecConfigGUI gui, CecLogicalAddress address, ref LibCecSharp lib,
-      bool devicePresent, CecVendorId vendor, bool isActiveSource, ushort physicalAddress,
-      CecVersion version, CecPowerStatus power, string osdName, string menuLanguage)
-    {
-      Gui = gui;
-      Lib = lib;
-      Address = address;
-      InitializeComponent();
-      lDevice.Text = lib.ToString(address);
-      lLogicalAddress.Text = String.Format("{0,1:X}", (int)address);
-      Update(devicePresent, vendor, isActiveSource, physicalAddress, version, power, osdName, menuLanguage);
-    }
-
-    public void Update(bool devicePresent, CecVendorId vendor, bool isActiveSource, ushort physicalAddress,
-      CecVersion version, CecPowerStatus power, string osdName, string menuLanguage)
-    {
-      SetControlText(lPhysicalAddress, String.Format("{0,4:X}", physicalAddress));
-      SetControlText(lDevicePresent, devicePresent ? "yes" : "no");
-      SetControlVisible(lActiveSource, isActiveSource);
-      SetControlVisible(lInactiveSource, !isActiveSource);
-      SetControlText(lVendor, vendor != CecVendorId.Unknown ? Lib.ToString(vendor) : "unknown");
-      SetControlText(lCecVersion, Lib.ToString(version));
-      SetControlText(lPowerStatus, Lib.ToString(power));
-      SetControlText(lOsdName, osdName);
-      SetControlText(lMenuLanguage, menuLanguage);
-      SetControlText(this, "Device: " + osdName);
-    }
-
-    private void lInactiveSource_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
-    {
-      SetControlVisible(lInactiveSource, false);
-      SetControlVisible(lActiveSource, true);
-      Gui.ActivateSource(Address);
-    }
-
-    private void lStandby_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
-    {
-      LinkLabel label = sender as LinkLabel;
-      bool sendPowerOn = label.Text != Lib.ToString(CecPowerStatus.InTransitionStandbyToOn) &&
-        label.Text != Lib.ToString(CecPowerStatus.On);
-
-      SetControlText(lPowerStatus, Lib.ToString(sendPowerOn ? CecPowerStatus.On : CecPowerStatus.Standby));
-      if (sendPowerOn)
-        Gui.SendImageViewOn(Address);
-      else
-        Gui.SendStandby(Address);
-    }
-
-
-    private void button1_Click(object sender, EventArgs e)
-    {
-      Gui.UpdateInfoPanel(this);
-    }
-
-    public CecLogicalAddress Address
-    {
-      private set;
-      get;
-    }
-    private CecConfigGUI Gui;
-    private LibCecSharp Lib;
-  }
-}
diff --git a/src/cec-config-gui/Program.cs b/src/cec-config-gui/Program.cs
deleted file mode 100644 (file)
index 25dbf33..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-using System;
-using System.Windows.Forms;
-
-namespace CecConfigGui
-{
-  static class Program
-  {
-    /// <summary>
-    /// The main entry point for the application.
-    /// </summary>
-    [STAThread]
-    static void Main()
-    {
-      Application.EnableVisualStyles();
-      Application.SetCompatibleTextRenderingDefault(false);
-      Application.Run(new CecConfigGUI());
-    }
-  }
-}
diff --git a/src/cec-config-gui/Properties/DataSources/CecButtonConfig.datasource b/src/cec-config-gui/Properties/DataSources/CecButtonConfig.datasource
deleted file mode 100644 (file)
index 0c133af..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    This file is automatically generated by Visual Studio .Net. It is 
-    used to store generic object data source configuration information.  
-    Renaming the file extension or editing the content of this file may   
-    cause the file to be unrecognizable by the program.
--->
-<GenericObjectDataSource DisplayName="CecButtonConfig" Version="1.0" xmlns="urn:schemas-microsoft-com:xml-msdatasource">
-   <TypeInfo>CecConfigGui.CecButtonConfig, cec-config-gui, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null</TypeInfo>
-</GenericObjectDataSource>
\ No newline at end of file
diff --git a/src/cec-config-gui/Properties/Resources.Designer.cs b/src/cec-config-gui/Properties/Resources.Designer.cs
deleted file mode 100644 (file)
index 3ca0535..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated by a tool.
-//     Runtime Version:2.0.50727.5448
-//
-//     Changes to this file may cause incorrect behavior and will be lost if
-//     the code is regenerated.
-// </auto-generated>
-//------------------------------------------------------------------------------
-
-namespace CecConfigGui.Properties {
-    using System;
-    
-    
-    /// <summary>
-    ///   A strongly-typed resource class, for looking up localized strings, etc.
-    /// </summary>
-    // This class was auto-generated by the StronglyTypedResourceBuilder
-    // class via a tool like ResGen or Visual Studio.
-    // To add or remove a member, edit your .ResX file then rerun ResGen
-    // with the /str option, or rebuild your VS project.
-    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")]
-    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
-    internal class Resources {
-        
-        private static global::System.Resources.ResourceManager resourceMan;
-        
-        private static global::System.Globalization.CultureInfo resourceCulture;
-        
-        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
-        internal Resources() {
-        }
-        
-        /// <summary>
-        ///   Returns the cached ResourceManager instance used by this class.
-        /// </summary>
-        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
-        internal static global::System.Resources.ResourceManager ResourceManager {
-            get {
-                if (object.ReferenceEquals(resourceMan, null)) {
-                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("CecConfigGui.Properties.Resources", typeof(Resources).Assembly);
-                    resourceMan = temp;
-                }
-                return resourceMan;
-            }
-        }
-        
-        /// <summary>
-        ///   Overrides the current thread's CurrentUICulture property for all
-        ///   resource lookups using this strongly typed resource class.
-        /// </summary>
-        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
-        internal static global::System.Globalization.CultureInfo Culture {
-            get {
-                return resourceCulture;
-            }
-            set {
-                resourceCulture = value;
-            }
-        }
-    }
-}
diff --git a/src/cec-config-gui/Properties/Settings.Designer.cs b/src/cec-config-gui/Properties/Settings.Designer.cs
deleted file mode 100644 (file)
index c1a7961..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated by a tool.
-//     Runtime Version:2.0.50727.5448
-//
-//     Changes to this file may cause incorrect behavior and will be lost if
-//     the code is regenerated.
-// </auto-generated>
-//------------------------------------------------------------------------------
-
-namespace CecConfigGui.Properties {
-    
-    
-    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
-    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "9.0.0.0")]
-    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
-        
-        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
-        
-        public static Settings Default {
-            get {
-                return defaultInstance;
-            }
-        }
-    }
-}
diff --git a/src/cec-config-gui/Properties/Settings.settings b/src/cec-config-gui/Properties/Settings.settings
deleted file mode 100644 (file)
index 3964565..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version='1.0' encoding='utf-8'?>
-<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
-  <Profiles>
-    <Profile Name="(Default)" />
-  </Profiles>
-  <Settings />
-</SettingsFile>
diff --git a/src/cec-config-gui/actions/ConnectToDevice.cs b/src/cec-config-gui/actions/ConnectToDevice.cs
deleted file mode 100644 (file)
index 8c198f4..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-using CecSharp;
-using System.Windows.Forms;
-
-namespace CecConfigGui.actions
-{
-  class ConnectToDevice : UpdateProcess
-  {
-    public ConnectToDevice(ref LibCecSharp lib, LibCECConfiguration config)
-    {
-      Lib = lib;
-      Config = config;
-    }
-
-    public override void Process()
-    {
-      SendEvent(UpdateEventType.StatusText, "Opening connection...");
-      SendEvent(UpdateEventType.ProgressBar, 10);
-
-      //TODO read the com port setting from the configuration
-      CecAdapter[] adapters = Lib.FindAdapters(string.Empty);
-      if (adapters.Length == 0)
-      {
-        DialogResult result = MessageBox.Show("Could not detect to any CEC adapter. Please check your configuration. Do you want to try again?", "Pulse-Eight USB-CEC Adapter", MessageBoxButtons.YesNo);
-        if (result == DialogResult.No)
-        {
-          SendEvent(UpdateEventType.ExitApplication);
-          return;
-        }
-        else
-          adapters = Lib.FindAdapters(string.Empty);
-      }
-
-      while (!Lib.Open(adapters[0].ComPort, 10000))
-      {
-        DialogResult result = MessageBox.Show("Could not connect to any CEC adapter. Please check your configuration. Do you want to try again?", "Pulse-Eight USB-CEC Adapter", MessageBoxButtons.YesNo);
-        if (result == DialogResult.No)
-        {
-          SendEvent(UpdateEventType.ExitApplication);
-          return;
-        }
-      }
-
-      SendEvent(UpdateEventType.ProgressBar, 20);
-      SendEvent(UpdateEventType.StatusText, "Sending power on commands...");
-      Lib.PowerOnDevices(CecLogicalAddress.Broadcast);
-
-      SendEvent(UpdateEventType.StatusText, "Detecting TV vendor...");
-      SendEvent(UpdateEventType.ProgressBar, 30);
-      SendEvent(UpdateEventType.TVVendorId, (int)Lib.GetDeviceVendorId(CecLogicalAddress.Tv));
-
-      SendEvent(UpdateEventType.StatusText, "Detecting menu language...");
-      SendEvent(UpdateEventType.ProgressBar, 40);
-      SendEvent(UpdateEventType.MenuLanguage, Lib.GetDeviceMenuLanguage(CecLogicalAddress.Tv));
-
-      SendEvent(UpdateEventType.ProgressBar, 50);
-      SendEvent(UpdateEventType.StatusText, "Detecting AVR devices...");
-
-      bool hasAVRDevice = Lib.IsActiveDevice(CecLogicalAddress.AudioSystem);
-      SendEvent(UpdateEventType.HasAVRDevice, hasAVRDevice);
-
-      if (hasAVRDevice)
-      {
-        SendEvent(UpdateEventType.ProgressBar, 60);
-        SendEvent(UpdateEventType.StatusText, "Detecting AVR vendor...");
-        SendEvent(UpdateEventType.AVRVendorId, (int)Lib.GetDeviceVendorId(CecLogicalAddress.AudioSystem));
-      }
-
-      if (!Lib.GetDevicePowerStatus(CecLogicalAddress.Tv).Equals(CecPowerStatus.On))
-      {
-        SendEvent(UpdateEventType.ProgressBar, 70);
-        SendEvent(UpdateEventType.StatusText, "Activating the source...");
-        Lib.SetActiveSource(CecDeviceType.Reserved);
-      }
-
-      SendEvent(UpdateEventType.ProgressBar, 80);
-      SendEvent(UpdateEventType.StatusText, "Reading device configuration...");
-
-      Lib.GetCurrentConfiguration(Config);
-      SendEvent(Config);
-
-      SendEvent(UpdateEventType.ProgressBar, 90);
-      SendEvent(UpdateEventType.StatusText, "Polling active devices");
-      SendEvent(UpdateEventType.PollDevices);
-
-      SendEvent(UpdateEventType.ProgressBar, 100);
-      SendEvent(UpdateEventType.StatusText, "Ready.");
-    }
-
-    private LibCecSharp Lib;
-    private LibCECConfiguration Config;
-  }
-}
diff --git a/src/cec-config-gui/actions/RescanDevices.cs b/src/cec-config-gui/actions/RescanDevices.cs
deleted file mode 100644 (file)
index 33c6be9..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-using CecSharp;
-
-namespace CecConfigGui.actions
-{
-  class RescanDevices : UpdateProcess
-  {
-    public RescanDevices(ref LibCecSharp lib)
-    {
-      Lib = lib;
-    }
-
-    public override void Process()
-    {
-      SendEvent(UpdateEventType.ProgressBar, 10);
-      SendEvent(UpdateEventType.StatusText, "Polling active devices");
-      Lib.RescanActiveDevices();
-
-      SendEvent(UpdateEventType.ProgressBar, 80);
-      SendEvent(UpdateEventType.StatusText, "Refreshing device list");
-      SendEvent(UpdateEventType.PollDevices);
-
-      SendEvent(UpdateEventType.ProgressBar, 100);
-      SendEvent(UpdateEventType.StatusText, "Ready.");
-    }
-
-    private LibCecSharp Lib;
-  }
-}
diff --git a/src/cec-config-gui/actions/SendActivateSource.cs b/src/cec-config-gui/actions/SendActivateSource.cs
deleted file mode 100644 (file)
index 1470c19..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-using CecSharp;
-
-namespace CecConfigGui.actions
-{
-  class SendActivateSource : UpdateProcess
-  {
-    public SendActivateSource(ref LibCecSharp lib, CecLogicalAddress address)
-    {
-      Lib = lib;
-      Address = address;
-    }
-
-    public override void Process()
-    {
-      SendEvent(UpdateEventType.StatusText, "Sending the 'activate source' command to " + Lib.ToString(Address) + "...");
-      SendEvent(UpdateEventType.ProgressBar, 50);
-
-      bool bResult = Lib.SetStreamPath(Address);
-      SendEvent(UpdateEventType.StatusText, bResult ? "Command sent successfully." : "The 'active source' command was not acked.");
-      SendEvent(UpdateEventType.ProgressBar, 100);
-    }
-
-    private LibCecSharp Lib;
-    private CecLogicalAddress Address;
-  }
-}
diff --git a/src/cec-config-gui/actions/SendImageViewOn.cs b/src/cec-config-gui/actions/SendImageViewOn.cs
deleted file mode 100644 (file)
index 6757073..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-using CecSharp;
-
-namespace CecConfigGui.actions
-{
-  class SendImageViewOn : UpdateProcess
-  {
-    public SendImageViewOn(ref LibCecSharp lib, CecLogicalAddress address)
-    {
-      Lib = lib;
-      Address = address;
-    }
-
-    public override void Process()
-    {
-      SendEvent(UpdateEventType.StatusText, "Sending the 'power on' command to " + Lib.ToString(Address) + "...");
-      SendEvent(UpdateEventType.ProgressBar, 50);
-
-      bool bResult = Lib.PowerOnDevices(Address);
-      SendEvent(UpdateEventType.StatusText, bResult ? "Command sent successfully." : "The 'image view on' command was not acked.");
-      SendEvent(UpdateEventType.ProgressBar, 100);
-    }
-
-    private LibCecSharp Lib;
-    private CecLogicalAddress Address;
-  }
-}
diff --git a/src/cec-config-gui/actions/SendStandby.cs b/src/cec-config-gui/actions/SendStandby.cs
deleted file mode 100644 (file)
index 99bd023..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-using CecSharp;
-
-namespace CecConfigGui.actions
-{
-  class SendStandby : UpdateProcess
-  {
-    public SendStandby(ref LibCecSharp lib, CecLogicalAddress address)
-    {
-      Lib = lib;
-      Address = address;
-    }
-
-    public override void Process()
-    {
-      SendEvent(UpdateEventType.StatusText, "Sending the 'standby' command to " + Lib.ToString(Address) + "...");
-      SendEvent(UpdateEventType.ProgressBar, 50);
-
-      bool bResult = Lib.StandbyDevices(Address);
-      SendEvent(UpdateEventType.StatusText, bResult ? "Command sent successfully." : "The 'standby' command was not acked.");
-      SendEvent(UpdateEventType.ProgressBar, 100);
-    }
-
-    private LibCecSharp Lib;
-    private CecLogicalAddress Address;
-  }
-}
diff --git a/src/cec-config-gui/actions/ShowDeviceInfo.cs b/src/cec-config-gui/actions/ShowDeviceInfo.cs
deleted file mode 100644 (file)
index 8e6a48d..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-using CecSharp;
-
-namespace CecConfigGui.actions
-{
-  class ShowDeviceInfo : UpdateProcess
-  {
-    public ShowDeviceInfo(CecConfigGUI gui, ref LibCecSharp lib, CecLogicalAddress address)
-    {
-      Gui = gui;
-      Lib = lib;
-      Address = address;
-    }
-
-    public virtual void ShowDialog(CecConfigGUI gui, CecLogicalAddress address, ref LibCecSharp lib,
-      bool devicePresent, CecVendorId vendor, bool isActiveSource, ushort physicalAddress,
-      CecVersion version, CecPowerStatus power, string osdName, string menuLanguage)
-    {
-      DeviceInformation di = new DeviceInformation(Gui, Address, ref Lib, devicePresent, vendor, isActiveSource, physicalAddress, version, power, osdName, menuLanguage);
-      Gui.DisplayDialog(di, false);
-    }
-
-    public override void Process()
-    {
-      CecVendorId vendor = CecVendorId.Unknown;
-      bool isActiveSource = false;
-      ushort physicalAddress = 0xFFFF;
-      CecVersion version = CecVersion.Unknown;
-      CecPowerStatus power = CecPowerStatus.Unknown;
-      string osdName = "unknown";
-      string menuLanguage = "unknown";
-
-      SendEvent(UpdateEventType.StatusText, "Checking device presense...");
-      SendEvent(UpdateEventType.ProgressBar, 10);
-
-      bool devicePresent = Lib.IsActiveDevice(Address);
-      if (devicePresent)
-      {
-        SendEvent(UpdateEventType.StatusText, "Requesting the vendor ID...");
-        SendEvent(UpdateEventType.ProgressBar, 20);
-        vendor = Lib.GetDeviceVendorId(Address);
-
-        SendEvent(UpdateEventType.StatusText, "Requesting active source state...");
-        SendEvent(UpdateEventType.ProgressBar, 30);
-        isActiveSource = Lib.IsActiveSource(Address);
-
-        SendEvent(UpdateEventType.StatusText, "Requesting physical address...");
-        SendEvent(UpdateEventType.ProgressBar, 40);
-        physicalAddress = Lib.GetDevicePhysicalAddress(Address);
-
-        SendEvent(UpdateEventType.StatusText, "Requesting CEC version...");
-        SendEvent(UpdateEventType.ProgressBar, 50);
-        version = Lib.GetDeviceCecVersion(Address);
-
-        SendEvent(UpdateEventType.StatusText, "Requesting power status...");
-        SendEvent(UpdateEventType.ProgressBar, 60);
-        power = Lib.GetDevicePowerStatus(Address);
-
-        SendEvent(UpdateEventType.StatusText, "Requesting OSD name...");
-        SendEvent(UpdateEventType.ProgressBar, 70);
-        osdName = Lib.GetDeviceOSDName(Address);
-
-        SendEvent(UpdateEventType.StatusText, "Requesting menu language...");
-        SendEvent(UpdateEventType.ProgressBar, 80);
-        menuLanguage = Lib.GetDeviceMenuLanguage(Address);
-      }
-
-      SendEvent(UpdateEventType.StatusText, "Showing device information");
-      SendEvent(UpdateEventType.ProgressBar, 90);
-      SendEvent(UpdateEventType.ProcessCompleted, true);
-
-      ShowDialog(Gui, Address, ref Lib, devicePresent, vendor, isActiveSource, physicalAddress, version, power, osdName, menuLanguage);
-
-      SendEvent(UpdateEventType.StatusText, "Ready.");
-      SendEvent(UpdateEventType.ProgressBar, 100);
-    }
-
-    private CecConfigGUI Gui;
-    private LibCecSharp Lib;
-    private CecLogicalAddress Address;
-  }
-}
diff --git a/src/cec-config-gui/actions/UpdateConfiguration.cs b/src/cec-config-gui/actions/UpdateConfiguration.cs
deleted file mode 100644 (file)
index af41205..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-using CecSharp;
-
-namespace CecConfigGui.actions
-{
-  class UpdateConfiguration : UpdateProcess
-  {
-    public UpdateConfiguration(ref LibCecSharp lib, LibCECConfiguration config)
-    {
-      Lib = lib;
-      Config = config;
-    }
-
-    public override void Process()
-    {
-      SendEvent(UpdateEventType.ProgressBar, 10);
-      SendEvent(UpdateEventType.StatusText, "Setting the new configuration");
-
-      Lib.SetConfiguration(Config);
-
-      SendEvent(UpdateEventType.ProgressBar, 100);
-      SendEvent(UpdateEventType.StatusText, "Ready.");
-    }
-
-    private LibCecSharp Lib;
-    private LibCECConfiguration Config;
-  }
-}
diff --git a/src/cec-config-gui/actions/UpdateConnectedDevice.cs b/src/cec-config-gui/actions/UpdateConnectedDevice.cs
deleted file mode 100644 (file)
index 3fb635b..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-using CecSharp;
-
-namespace CecConfigGui.actions
-{
-  class UpdateConnectedDevice : UpdateProcess
-  {
-    public UpdateConnectedDevice(ref LibCecSharp lib, CecLogicalAddress address, int portNumber)
-    {
-      Lib = lib;
-      Address = address;
-      PortNumber = portNumber;
-    }
-
-    public override void Process()
-    {
-      SendEvent(UpdateEventType.StatusText, "Requesting physical address...");
-      SendEvent(UpdateEventType.ProgressBar, 0);
-
-      ushort iPhysicalAddress = Lib.GetDevicePhysicalAddress(Address);
-      SendEvent(UpdateEventType.BaseDevicePhysicalAddress, iPhysicalAddress);
-
-      SendEvent(UpdateEventType.StatusText, "Setting new configuration...");
-      SendEvent(UpdateEventType.ProgressBar, 25);
-
-      if (!Lib.SetHDMIPort(Address, (byte)PortNumber))
-      {
-        SendEvent(UpdateEventType.StatusText, "Could not activate the new source");
-      }
-      else
-      {
-        LibCECConfiguration config = new LibCECConfiguration();
-        Lib.GetCurrentConfiguration(config);
-
-        SendEvent(UpdateEventType.StatusText, "Activating source...");
-        SendEvent(UpdateEventType.ProgressBar, 50);
-        Lib.SetActiveSource(config.DeviceTypes.Types[0]);
-
-        SendEvent(UpdateEventType.StatusText, "Reading configuration...");
-        SendEvent(UpdateEventType.ProgressBar, 75);
-        Lib.GetCurrentConfiguration(config);
-
-        SendEvent(config);
-        SendEvent(UpdateEventType.StatusText, "Ready.");
-      }
-      SendEvent(UpdateEventType.ProgressBar, 100);
-    }
-
-    private LibCecSharp       Lib;
-    private CecLogicalAddress Address;
-    private int               PortNumber;
-  }
-}
diff --git a/src/cec-config-gui/actions/UpdateDeviceInfo.cs b/src/cec-config-gui/actions/UpdateDeviceInfo.cs
deleted file mode 100644 (file)
index 4fbf393..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-using CecSharp;
-
-namespace CecConfigGui.actions
-{
-  class UpdateDeviceInfo : ShowDeviceInfo
-  {
-    public UpdateDeviceInfo(CecConfigGUI gui, ref LibCecSharp lib, DeviceInformation dialog) :
-      base(gui, ref lib, dialog.Address)
-    {
-      Dialog = dialog;
-    }
-
-    public override void ShowDialog(CecConfigGUI gui, CecLogicalAddress address, ref LibCecSharp lib,
-      bool devicePresent, CecVendorId vendor, bool isActiveSource, ushort physicalAddress,
-      CecVersion version, CecPowerStatus power, string osdName, string menuLanguage)
-    {
-      Dialog.Update(devicePresent, vendor, isActiveSource, physicalAddress, version, power, osdName, menuLanguage);
-    }
-
-    private DeviceInformation Dialog;
-  }
-}
diff --git a/src/cec-config-gui/actions/UpdateEvent.cs b/src/cec-config-gui/actions/UpdateEvent.cs
deleted file mode 100644 (file)
index 4a3e701..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-using System;
-using CecSharp;
-
-namespace CecConfigGui
-{
-  public enum UpdateEventType
-  {
-    ProcessCompleted,
-    StatusText,
-    ProgressBar,
-    TVVendorId,
-    BaseDevicePhysicalAddress,
-    BaseDevice,
-    HDMIPort,
-    PhysicalAddress,
-    HasAVRDevice,
-    AVRVendorId,
-    Configuration,
-    MenuLanguage,
-    PollDevices,
-    ExitApplication
-  }
-
-  public class UpdateEvent : EventArgs
-  {
-    public UpdateEvent(UpdateEventType type)
-    {
-      Type = type;
-    }
-
-    public UpdateEvent(UpdateEventType type, bool value)
-    {
-      Type = type;
-      BoolValue = value;
-    }
-
-    public UpdateEvent(UpdateEventType type, int value)
-    {
-      Type = type;
-      IntValue = value;
-    }
-
-    public UpdateEvent(UpdateEventType type, string value)
-    {
-      Type = type;
-      StringValue = value;
-    }
-
-    public UpdateEvent(LibCECConfiguration config)
-    {
-      Type = UpdateEventType.Configuration;
-      ConfigValue = config;
-    }
-
-    public UpdateEventType     Type;
-    public bool                BoolValue   = false;
-    public int                 IntValue    = -1;
-    public string              StringValue = String.Empty;
-    public LibCECConfiguration ConfigValue = null;
-  }
-
-  public abstract class UpdateProcess
-  {
-      public void SendEvent(UpdateEventType type)
-    {
-      EventHandler<UpdateEvent> temp = EventHandler;
-      if (temp != null)
-        temp(this, new UpdateEvent(type));
-    }
-
-    public void SendEvent(UpdateEventType type, bool value)
-    {
-      EventHandler<UpdateEvent> temp = EventHandler;
-      if (temp != null)
-        temp(this, new UpdateEvent(type, value));
-    }
-
-    public void SendEvent(UpdateEventType type, int value)
-    {
-      EventHandler<UpdateEvent> temp = EventHandler;
-      if (temp != null)
-        temp(this, new UpdateEvent(type, value));
-    }
-
-    public void SendEvent(UpdateEventType type, string value)
-    {
-      EventHandler<UpdateEvent> temp = EventHandler;
-      if (temp != null)
-        temp(this, new UpdateEvent(type, value));
-    }
-
-    public void SendEvent(LibCECConfiguration config)
-    {
-      EventHandler<UpdateEvent> temp = EventHandler;
-      if (temp != null)
-        temp(this, new UpdateEvent(config));
-    }
-
-    public void Run()
-    {
-      Process();
-      SendEvent(UpdateEventType.ProcessCompleted, true);
-    }
-
-    public abstract void Process();
-    public event EventHandler<UpdateEvent> EventHandler;
-  }
-}
diff --git a/src/cec-config-gui/actions/UpdatePhysicalAddress.cs b/src/cec-config-gui/actions/UpdatePhysicalAddress.cs
deleted file mode 100644 (file)
index fab7304..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-using CecSharp;
-
-namespace CecConfigGui.actions
-{
-  class UpdatePhysicalAddress : UpdateProcess
-  {
-    public UpdatePhysicalAddress(ref LibCecSharp lib, ushort physicalAddress)
-    {
-      Lib = lib;
-      PhysicalAddress = physicalAddress;
-    }
-
-    public override void Process()
-    {
-      SendEvent(UpdateEventType.BaseDevicePhysicalAddress, 0);
-      SendEvent(UpdateEventType.StatusText, "Setting new configuration...");
-      SendEvent(UpdateEventType.ProgressBar, 25);
-
-      if (!Lib.SetPhysicalAddress(PhysicalAddress))
-      {
-        SendEvent(UpdateEventType.StatusText, "Could not activate the new source");
-      }
-      else
-      {
-        LibCECConfiguration config = new LibCECConfiguration();
-        Lib.GetCurrentConfiguration(config);
-
-        SendEvent(UpdateEventType.StatusText, "Activating source...");
-        SendEvent(UpdateEventType.ProgressBar, 50);
-        Lib.SetActiveSource(config.DeviceTypes.Types[0]);
-
-        SendEvent(UpdateEventType.StatusText, "Reading configuration...");
-        SendEvent(UpdateEventType.ProgressBar, 75);
-        Lib.GetCurrentConfiguration(config);
-
-        SendEvent(config);
-        SendEvent(UpdateEventType.StatusText, "Ready.");
-      }
-      SendEvent(UpdateEventType.ProgressBar, 100);
-    }
-
-    protected LibCecSharp Lib;
-    protected ushort PhysicalAddress;
-  }
-}
diff --git a/src/cec-config-gui/cec-config-gui.csproj b/src/cec-config-gui/cec-config-gui.csproj
deleted file mode 100644 (file)
index 4422144..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
-    <DebugSymbols>true</DebugSymbols>
-    <OutputPath>..\..\build\</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <DebugType>full</DebugType>
-    <PlatformTarget>x64</PlatformTarget>
-    <ErrorReport>prompt</ErrorReport>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
-    <OutputPath>..\..\build\</OutputPath>
-    <DefineConstants>TRACE</DefineConstants>
-    <Optimize>true</Optimize>
-    <DebugType>pdbonly</DebugType>
-    <PlatformTarget>x64</PlatformTarget>
-    <ErrorReport>prompt</ErrorReport>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
-    <DebugSymbols>true</DebugSymbols>
-    <OutputPath>..\..\build\</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <DebugType>full</DebugType>
-    <PlatformTarget>x86</PlatformTarget>
-    <ErrorReport>prompt</ErrorReport>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
-    <OutputPath>..\..\build\</OutputPath>
-    <DefineConstants>TRACE</DefineConstants>
-    <Optimize>true</Optimize>
-    <DebugType>pdbonly</DebugType>
-    <PlatformTarget>x86</PlatformTarget>
-    <ErrorReport>prompt</ErrorReport>
-  </PropertyGroup>
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProductVersion>9.0.21022</ProductVersion>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{58C106FE-C159-46D3-97E1-73AB83232670}</ProjectGuid>
-    <OutputType>WinExe</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>CecConfigGui</RootNamespace>
-    <AssemblyName>cec-config-gui</AssemblyName>
-    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
-    <FileAlignment>512</FileAlignment>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="System" />
-    <Reference Include="System.Data" />
-    <Reference Include="System.Deployment" />
-    <Reference Include="System.Drawing" />
-    <Reference Include="System.Windows.Forms" />
-    <Reference Include="System.Xml" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="actions\UpdateConfiguration.cs" />
-    <Compile Include="actions\ConnectToDevice.cs" />
-    <Compile Include="actions\RescanDevices.cs" />
-    <Compile Include="actions\SendActivateSource.cs" />
-    <Compile Include="actions\SendImageViewOn.cs" />
-    <Compile Include="actions\SendStandby.cs" />
-    <Compile Include="actions\ShowDeviceInfo.cs" />
-    <Compile Include="actions\UpdateConnectedDevice.cs" />
-    <Compile Include="actions\UpdateDeviceInfo.cs" />
-    <Compile Include="actions\UpdatePhysicalAddress.cs" />
-    <Compile Include="AsyncForm.cs">
-      <SubType>Form</SubType>
-    </Compile>
-    <Compile Include="CecButtonConfig.cs" />
-    <Compile Include="CecConfigGUI.cs">
-      <SubType>Form</SubType>
-    </Compile>
-    <Compile Include="CecConfigGUI.Designer.cs">
-      <DependentUpon>CecConfigGUI.cs</DependentUpon>
-    </Compile>
-    <Compile Include="DeviceInformation.cs">
-      <SubType>Form</SubType>
-    </Compile>
-    <Compile Include="DeviceInformation.Designer.cs">
-      <DependentUpon>DeviceInformation.cs</DependentUpon>
-    </Compile>
-    <Compile Include="Program.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
-    <EmbeddedResource Include="CecConfigGUI.resx">
-      <DependentUpon>CecConfigGUI.cs</DependentUpon>
-      <SubType>Designer</SubType>
-    </EmbeddedResource>
-    <EmbeddedResource Include="DeviceInformation.resx">
-      <DependentUpon>DeviceInformation.cs</DependentUpon>
-      <SubType>Designer</SubType>
-    </EmbeddedResource>
-    <EmbeddedResource Include="Properties\Resources.resx">
-      <Generator>ResXFileCodeGenerator</Generator>
-      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
-      <SubType>Designer</SubType>
-    </EmbeddedResource>
-    <Compile Include="Properties\Resources.Designer.cs">
-      <AutoGen>True</AutoGen>
-      <DependentUpon>Resources.resx</DependentUpon>
-      <DesignTime>True</DesignTime>
-    </Compile>
-    <None Include="Properties\DataSources\CecButtonConfig.datasource" />
-    <None Include="Properties\Settings.settings">
-      <Generator>SettingsSingleFileGenerator</Generator>
-      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
-    </None>
-    <Compile Include="Properties\Settings.Designer.cs">
-      <AutoGen>True</AutoGen>
-      <DependentUpon>Settings.settings</DependentUpon>
-      <DesignTimeSharedInput>True</DesignTimeSharedInput>
-    </Compile>
-    <Compile Include="actions\UpdateEvent.cs" />
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\..\project\LibCecSharp.vcproj">
-      <Project>{E54D4581-CD59-4687-BB10-694B8192EABA}</Project>
-      <Name>LibCecSharp</Name>
-    </ProjectReference>
-  </ItemGroup>
-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-       Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
-</Project>
\ No newline at end of file
index a3d2b77f5666a592ba6b21d72a5307becf68e913..380adeee91475a4585a853c17460004130e0abba 100644 (file)
@@ -39,6 +39,7 @@
 #include <fstream>
 #include <string>
 #include <sstream>
+#include <signal.h>
 #include "../lib/platform/threads/mutex.h"
 #include "../lib/platform/util/timeutils.h"
 #include "../lib/implementations/CECCommandHandler.h"
@@ -109,7 +110,7 @@ bool GetWord(string& data, string& word)
   return true;
 }
 
-int CecLogMessage(void *UNUSED(cbParam), const cec_log_message &message)
+int CecLogMessage(void *UNUSED(cbParam), const cec_log_message message)
 {
   switch (message.level)
   {
@@ -126,14 +127,14 @@ int CecLogMessage(void *UNUSED(cbParam), const cec_log_message &message)
   return 0;
 }
 
-int CecKeyPress(void *UNUSED(cbParam), const cec_keypress &key)
+int CecKeyPress(void *UNUSED(cbParam), const cec_keypress key)
 {
   g_lastKey = key.keycode;
   g_keyEvent.Signal();
   return 0;
 }
 
-int CecCommand(void *UNUSED(cbParam), const cec_command &command)
+int CecCommand(void *UNUSED(cbParam), const cec_command command)
 {
   g_lastCommand = command.opcode;
   g_responseEvent.Signal();
@@ -159,13 +160,13 @@ bool OpenConnection(cec_device_type type = CEC_DEVICE_TYPE_RECORDING_DEVICE)
   g_config.Clear();
   snprintf(g_config.strDeviceName, 13, "CEC-config");
   g_config.callbackParam      = NULL;
-  g_config.clientVersion      = (uint32_t)CEC_CLIENT_VERSION_1_9_0;
+  g_config.clientVersion      = (uint32_t)CEC_CLIENT_VERSION_2_0_0;
   g_callbacks.CBCecLogMessage = &CecLogMessage;
   g_callbacks.CBCecKeyPress   = &CecKeyPress;
   g_callbacks.CBCecCommand    = &CecCommand;
   g_config.callbacks          = &g_callbacks;
 
-  g_config.deviceTypes.add(type);
+  g_config.deviceTypes.Add(type);
 
   g_parser = LibCecInitialise(&g_config);
   if (!g_parser)
@@ -293,20 +294,17 @@ bool PowerOnTV(uint64_t iTimeout = 60000)
   uint64_t iNow = GetTimeMs();
   uint64_t iTarget = iNow + iTimeout;
 
+  currentTvPower = g_parser->GetDevicePowerStatus(CECDEVICE_TV);
   if (currentTvPower != CEC_POWER_STATUS_ON)
   {
-    currentTvPower = g_parser->GetDevicePowerStatus(CECDEVICE_TV);
-    if (currentTvPower != CEC_POWER_STATUS_ON)
+    PrintToStdOut("Sending 'power on' command to the TV\n=== Please wait ===");
+    g_parser->PowerOnDevices(CECDEVICE_TV);
+    while (iTarget > iNow)
     {
-      PrintToStdOut("Sending 'power on' command to the TV\n=== Please wait ===");
-      g_parser->PowerOnDevices(CECDEVICE_TV);
-      while (iTarget > iNow)
-      {
-        g_responseEvent.Wait((uint32_t)(iTarget - iNow));
-        if (g_lastCommand == CEC_OPCODE_REQUEST_ACTIVE_SOURCE)
-          break;
-        iNow = GetTimeMs();
-      }
+      g_responseEvent.Wait((uint32_t)(iTarget - iNow));
+      if (g_lastCommand == CEC_OPCODE_REQUEST_ACTIVE_SOURCE)
+        break;
+      iNow = GetTimeMs();
     }
   }
 
@@ -318,8 +316,24 @@ bool PowerOnTV(uint64_t iTimeout = 60000)
   return currentTvPower == CEC_POWER_STATUS_ON;
 }
 
+void sighandler(int iSignal)
+{
+  PrintToStdOut("signal caught: %d - exiting", iSignal);
+
+  g_parser->Close();
+  UnloadLibCec(g_parser);
+
+  exit(1);
+}
+
 int main (int UNUSED(argc), char *UNUSED(argv[]))
 {
+  if (signal(SIGINT, sighandler) == SIG_ERR)
+  {
+    PrintToStdOut("can't register sighandler");
+    return -1;
+  }
+
   g_callbacks.Clear();
   g_config.Clear();
   PrintToStdOut("=== USB-CEC Adapter Configuration ===\n");
index c9525af15ace48fd132a3c78771d65873fdf79ee..d6f8100dec9daa25b26b7e55986eeaf8e85f6858 100644 (file)
@@ -47,14 +47,20 @@ using namespace PLATFORM;
 #define LIB_CEC     m_processor->GetLib()
 #define ToString(x) CCECTypeUtils::ToString(x)
 
+#define COMBO_KEY        CEC_USER_CONTROL_CODE_STOP
+#define COMBO_TIMEOUT_MS 1000
+
 CCECClient::CCECClient(CCECProcessor *processor, const libcec_configuration &configuration) :
     m_processor(processor),
     m_bInitialised(false),
     m_bRegistered(false),
     m_iCurrentButton(CEC_USER_CONTROL_CODE_UNKNOWN),
     m_buttontime(0),
-    m_iPreventForwardingPowerOffCommand(0)
+    m_iPreventForwardingPowerOffCommand(0),
+    m_iLastKeypressTime(0)
 {
+  m_lastKeypress.keycode = CEC_USER_CONTROL_CODE_UNKNOWN;
+  m_lastKeypress.duration = 0;
   m_configuration.Clear();
   // set the initial configuration
   SetConfiguration(configuration);
@@ -454,7 +460,7 @@ bool CCECClient::SetLogicalAddress(const cec_logical_address iLogicalAddress)
 
   if (GetPrimaryLogicalAdddress() != iLogicalAddress)
   {
-    LIB_CEC->AddLog(CEC_LOG_NOTICE, "<< setting primary logical address to %1x", iLogicalAddress);
+    LIB_CEC->AddLog(CEC_LOG_NOTICE, "setting primary logical address to %1x", iLogicalAddress);
     {
       CLockObject lock(m_mutex);
       m_configuration.logicalAddresses.primary = iLogicalAddress;
@@ -478,8 +484,8 @@ bool CCECClient::Transmit(const cec_command &data, bool bIsReply)
 
 bool CCECClient::SendPowerOnDevices(const cec_logical_address address /* = CECDEVICE_TV */)
 {
-  // if the broadcast address if set as destination and the client version >=1.5.0, read the wakeDevices setting
-  if (address == CECDEVICE_BROADCAST && m_configuration.clientVersion >= CEC_CLIENT_VERSION_1_5_0)
+  // if the broadcast address if set as destination, read the wakeDevices setting
+  if (address == CECDEVICE_BROADCAST)
   {
     CECDEVICEVEC devices;
     m_processor->GetDevices()->GetWakeDevices(m_configuration, devices);
@@ -491,8 +497,8 @@ bool CCECClient::SendPowerOnDevices(const cec_logical_address address /* = CECDE
 
 bool CCECClient::SendStandbyDevices(const cec_logical_address address /* = CECDEVICE_BROADCAST */)
 {
-  // if the broadcast address if set as destination and the client version >=1.5.0, read the standbyDevices setting
-  if (address == CECDEVICE_BROADCAST && m_configuration.clientVersion >= CEC_CLIENT_VERSION_1_5_0)
+  // if the broadcast address if set as destination, read the standbyDevices setting
+  if (address == CECDEVICE_BROADCAST)
   {
     CECDEVICEVEC devices;
     m_processor->GetDevices()->GetPowerOffDevices(m_configuration, devices);
@@ -756,59 +762,31 @@ bool CCECClient::GetCurrentConfiguration(libcec_configuration &configuration)
 
   // client version 1.5.0
   snprintf(configuration.strDeviceName, 13, "%s", m_configuration.strDeviceName);
-  configuration.deviceTypes          = m_configuration.deviceTypes;
-  configuration.bAutodetectAddress   = m_configuration.bAutodetectAddress;
-  configuration.iPhysicalAddress     = m_configuration.iPhysicalAddress;
-  configuration.baseDevice           = m_configuration.baseDevice;
-  configuration.iHDMIPort            = m_configuration.iHDMIPort;
-  configuration.clientVersion        = m_configuration.clientVersion;
-  configuration.serverVersion        = m_configuration.serverVersion;
-  configuration.tvVendor             = m_configuration.tvVendor;
-
-  configuration.bGetSettingsFromROM  = m_configuration.bGetSettingsFromROM;
-  configuration.bUseTVMenuLanguage   = m_configuration.bUseTVMenuLanguage;
-  configuration.bActivateSource      = m_configuration.bActivateSource;
-  configuration.wakeDevices          = m_configuration.wakeDevices;
-  configuration.powerOffDevices      = m_configuration.powerOffDevices;
-  configuration.bPowerOffScreensaver = m_configuration.bPowerOffScreensaver;
-  configuration.bPowerOffOnStandby   = m_configuration.bPowerOffOnStandby;
-
-  // client version 1.5.1
-  if (configuration.clientVersion >= CEC_CLIENT_VERSION_1_5_1)
-    configuration.bSendInactiveSource = m_configuration.bSendInactiveSource;
-
-  // client version 1.5.3
-  if (configuration.clientVersion >= CEC_CLIENT_VERSION_1_5_3)
-    configuration.logicalAddresses    = m_configuration.logicalAddresses;
-
-  // client version 1.6.0
-  if (configuration.clientVersion >= CEC_CLIENT_VERSION_1_6_0)
-  {
-    configuration.iFirmwareVersion          = m_configuration.iFirmwareVersion;
-    configuration.bPowerOffDevicesOnStandby = m_configuration.bPowerOffDevicesOnStandby;
-    configuration.bShutdownOnStandby        = m_configuration.bShutdownOnStandby;
-  }
-
-  // client version 1.6.2
-  if (configuration.clientVersion >= CEC_CLIENT_VERSION_1_6_2)
-  {
-    memcpy(configuration.strDeviceLanguage, m_configuration.strDeviceLanguage, 3);
-    configuration.iFirmwareBuildDate      = m_configuration.iFirmwareBuildDate;
-  }
-
-  // client version 1.6.3
-  if (configuration.clientVersion >= CEC_CLIENT_VERSION_1_6_3)
-  {
-    configuration.bMonitorOnly            = m_configuration.bMonitorOnly;
-  }
-
-  // client version 1.8.0
-  if (configuration.clientVersion >= CEC_CLIENT_VERSION_1_8_0)
-    configuration.cecVersion              = m_configuration.cecVersion;
-
-  // client version 1.8.2
-  if (configuration.clientVersion >= CEC_CLIENT_VERSION_1_8_2)
-    configuration.adapterType             = m_configuration.adapterType;
+  configuration.deviceTypes               = m_configuration.deviceTypes;
+  configuration.bAutodetectAddress        = m_configuration.bAutodetectAddress;
+  configuration.iPhysicalAddress          = m_configuration.iPhysicalAddress;
+  configuration.baseDevice                = m_configuration.baseDevice;
+  configuration.iHDMIPort                 = m_configuration.iHDMIPort;
+  configuration.clientVersion             = m_configuration.clientVersion;
+  configuration.serverVersion             = m_configuration.serverVersion;
+  configuration.tvVendor                  = m_configuration.tvVendor;
+  configuration.bGetSettingsFromROM       = m_configuration.bGetSettingsFromROM;
+  configuration.bUseTVMenuLanguage        = m_configuration.bUseTVMenuLanguage;
+  configuration.bActivateSource           = m_configuration.bActivateSource;
+  configuration.wakeDevices               = m_configuration.wakeDevices;
+  configuration.powerOffDevices           = m_configuration.powerOffDevices;
+  configuration.bPowerOffScreensaver      = m_configuration.bPowerOffScreensaver;
+  configuration.bPowerOffOnStandby        = m_configuration.bPowerOffOnStandby;
+  configuration.bSendInactiveSource       = m_configuration.bSendInactiveSource;
+  configuration.logicalAddresses          = m_configuration.logicalAddresses;
+  configuration.iFirmwareVersion          = m_configuration.iFirmwareVersion;
+  configuration.bPowerOffDevicesOnStandby = m_configuration.bPowerOffDevicesOnStandby;
+  configuration.bShutdownOnStandby        = m_configuration.bShutdownOnStandby;
+  memcpy(configuration.strDeviceLanguage,  m_configuration.strDeviceLanguage, 3);
+  configuration.iFirmwareBuildDate        = m_configuration.iFirmwareBuildDate;
+  configuration.bMonitorOnly              = m_configuration.bMonitorOnly;
+  configuration.cecVersion                = m_configuration.cecVersion;
+  configuration.adapterType               = m_configuration.adapterType;
 
   return true;
 }
@@ -836,48 +814,21 @@ bool CCECClient::SetConfiguration(const libcec_configuration &configuration)
   // just copy these
   {
     CLockObject lock(m_mutex);
-    m_configuration.bUseTVMenuLanguage   = configuration.bUseTVMenuLanguage;
-    m_configuration.bActivateSource      = configuration.bActivateSource;
-    m_configuration.bGetSettingsFromROM  = configuration.bGetSettingsFromROM;
-    m_configuration.wakeDevices          = configuration.wakeDevices;
-    m_configuration.powerOffDevices      = configuration.powerOffDevices;
-    m_configuration.bPowerOffScreensaver = configuration.bPowerOffScreensaver;
-    m_configuration.bPowerOffOnStandby   = configuration.bPowerOffOnStandby;
-
-    // client version 1.5.1
-    if (configuration.clientVersion >= CEC_CLIENT_VERSION_1_5_1)
-      m_configuration.bSendInactiveSource = configuration.bSendInactiveSource;
-
-    // client version 1.6.0
-    if (configuration.clientVersion >= CEC_CLIENT_VERSION_1_6_0)
-    {
-      m_configuration.bPowerOffDevicesOnStandby = configuration.bPowerOffDevicesOnStandby;
-      m_configuration.bShutdownOnStandby        = configuration.bShutdownOnStandby;
-    }
-
-    // client version 1.6.2
-    if (configuration.clientVersion >= CEC_CLIENT_VERSION_1_6_2)
-    {
-      memcpy(m_configuration.strDeviceLanguage, configuration.strDeviceLanguage, 3);
-    }
-
-    // client version 1.6.3
-    if (configuration.clientVersion >= CEC_CLIENT_VERSION_1_6_3)
-    {
-      m_configuration.bMonitorOnly = configuration.bMonitorOnly;
-    }
-
-    // client version 1.8.0
-    if (configuration.clientVersion >= CEC_CLIENT_VERSION_1_8_0)
-      m_configuration.cecVersion   = configuration.cecVersion;
-
-    // client version 1.8.2
-    if (configuration.clientVersion >= CEC_CLIENT_VERSION_1_8_2)
-      m_configuration.adapterType  = configuration.adapterType;
-
-    // ensure that there is at least 1 device type set
-    if (m_configuration.deviceTypes.IsEmpty())
-      m_configuration.deviceTypes.Add(CEC_DEVICE_TYPE_RECORDING_DEVICE);
+    m_configuration.bUseTVMenuLanguage         = configuration.bUseTVMenuLanguage;
+    m_configuration.bActivateSource            = configuration.bActivateSource;
+    m_configuration.bGetSettingsFromROM        = configuration.bGetSettingsFromROM;
+    m_configuration.wakeDevices                = configuration.wakeDevices;
+    m_configuration.powerOffDevices            = configuration.powerOffDevices;
+    m_configuration.bPowerOffScreensaver       = configuration.bPowerOffScreensaver;
+    m_configuration.bPowerOffOnStandby         = configuration.bPowerOffOnStandby;
+    m_configuration.bSendInactiveSource        = configuration.bSendInactiveSource;
+    m_configuration.bPowerOffDevicesOnStandby  = configuration.bPowerOffDevicesOnStandby;
+    m_configuration.bShutdownOnStandby         = configuration.bShutdownOnStandby;
+    memcpy(m_configuration.strDeviceLanguage,   configuration.strDeviceLanguage, 3);
+    m_configuration.bMonitorOnly               = configuration.bMonitorOnly;
+    m_configuration.cecVersion                 = configuration.cecVersion;
+    m_configuration.adapterType                = configuration.adapterType;
+    m_configuration.deviceTypes.Add(CEC_DEVICE_TYPE_RECORDING_DEVICE);
   }
 
   bool bNeedReinit(false);
@@ -935,18 +886,18 @@ void CCECClient::AddCommand(const cec_command &command)
 
   if (command.destination == CECDEVICE_BROADCAST || GetLogicalAddresses().IsSet(command.destination))
   {
-    LIB_CEC->AddLog(CEC_LOG_NOTICE, ">> %s (%X) -> %s (%X): %s (%2X)", ToString(command.initiator), command.initiator, ToString(command.destination), command.destination, ToString(command.opcode), command.opcode);
+    LIB_CEC->AddLog(CEC_LOG_DEBUG, ">> %s (%X) -> %s (%X): %s (%2X)", ToString(command.initiator), command.initiator, ToString(command.destination), command.destination, ToString(command.opcode), command.opcode);
     CallbackAddCommand(command);
   }
 }
 
 int CCECClient::MenuStateChanged(const cec_menu_state newState)
 {
-  LIB_CEC->AddLog(CEC_LOG_NOTICE, ">> %s: %s", ToString(CEC_OPCODE_MENU_REQUEST), ToString(newState));
+  LIB_CEC->AddLog(CEC_LOG_DEBUG, ">> %s: %s", ToString(CEC_OPCODE_MENU_REQUEST), ToString(newState));
   return CallbackMenuStateChanged(newState);
 }
 
-void CCECClient::AddKey(void)
+void CCECClient::AddKey(bool bSendComboKey /* = false */)
 {
   cec_keypress key;
   key.keycode = CEC_USER_CONTROL_CODE_UNKNOWN;
@@ -956,10 +907,14 @@ void CCECClient::AddKey(void)
     if (m_iCurrentButton != CEC_USER_CONTROL_CODE_UNKNOWN)
     {
       key.duration = (unsigned int) (GetTimeMs() - m_buttontime);
-      key.keycode = m_iCurrentButton;
 
-      m_iCurrentButton = CEC_USER_CONTROL_CODE_UNKNOWN;
-      m_buttontime = 0;
+      if (key.duration > COMBO_TIMEOUT_MS || m_iCurrentButton != COMBO_KEY || bSendComboKey)
+      {
+        key.keycode = m_iCurrentButton;
+
+        m_iCurrentButton = CEC_USER_CONTROL_CODE_UNKNOWN;
+        m_buttontime = 0;
+      }
     }
   }
 
@@ -972,14 +927,39 @@ void CCECClient::AddKey(void)
 
 void CCECClient::AddKey(const cec_keypress &key)
 {
+  // send back the previous key if there is one
+  AddKey();
+
+  cec_keypress transmitKey(key);
+
   {
     CLockObject lock(m_mutex);
-    m_iCurrentButton = key.duration > 0 ? CEC_USER_CONTROL_CODE_UNKNOWN : key.keycode;
-    m_buttontime = key.duration > 0 ? 0 : GetTimeMs();
+    if (key.duration > 0 || key.keycode > CEC_USER_CONTROL_CODE_MAX)
+    {
+      transmitKey.keycode = CEC_USER_CONTROL_CODE_UNKNOWN;
+    }
+    else if (m_iCurrentButton == COMBO_KEY)
+    {
+      // stop + ok -> exit
+      if (key.keycode == CEC_USER_CONTROL_CODE_SELECT)
+        transmitKey.keycode = CEC_USER_CONTROL_CODE_EXIT;
+      // stop + pause -> root menu
+      else if (key.keycode == CEC_USER_CONTROL_CODE_ROOT_MENU)
+        transmitKey.keycode = CEC_USER_CONTROL_CODE_ROOT_MENU;
+      // stop + play -> dot (which is handled as context menu in xbmc)
+      else if (key.keycode == CEC_USER_CONTROL_CODE_PLAY)
+        transmitKey.keycode = CEC_USER_CONTROL_CODE_DOT;
+      // default, send back the previous key
+      else
+        AddKey(true);
+    }
+
+    m_iCurrentButton = transmitKey.keycode;
+    m_buttontime = m_iCurrentButton == CEC_USER_CONTROL_CODE_UNKNOWN || key.duration > 0 ? 0 : GetTimeMs();
   }
 
-  LIB_CEC->AddLog(CEC_LOG_DEBUG, "key pressed: %s (%1x)", ToString(key.keycode), key.keycode);
-  CallbackAddKey(key);
+  LIB_CEC->AddLog(CEC_LOG_DEBUG, "key pressed: %s (%1x)", ToString(transmitKey.keycode), transmitKey.keycode);
+  CallbackAddKey(transmitKey);
 }
 
 void CCECClient::SetCurrentButton(const cec_user_control_code iButtonCode)
@@ -1001,7 +981,8 @@ void CCECClient::CheckKeypressTimeout(void)
     uint64_t iNow = GetTimeMs();
 
     if (m_iCurrentButton != CEC_USER_CONTROL_CODE_UNKNOWN &&
-        iNow - m_buttontime > CEC_BUTTON_TIMEOUT)
+          ((m_iCurrentButton == COMBO_KEY && iNow - m_buttontime > COMBO_TIMEOUT_MS) ||
+          (m_iCurrentButton != COMBO_KEY && iNow - m_buttontime > CEC_BUTTON_TIMEOUT)))
     {
       key.duration = (unsigned int) (iNow - m_buttontime);
       key.keycode = m_iCurrentButton;
@@ -1032,21 +1013,6 @@ bool CCECClient::PingAdapter(void)
   return m_processor ? m_processor->PingAdapter() : false;
 }
 
-bool CCECClient::GetNextLogMessage(cec_log_message *message)
-{
-  return (m_logBuffer.Pop(*message));
-}
-
-bool CCECClient::GetNextKeypress(cec_keypress *key)
-{
-  return m_keyBuffer.Pop(*key);
-}
-
-bool CCECClient::GetNextCommand(cec_command *command)
-{
-  return m_commandBuffer.Pop(*command);
-}
-
 std::string CCECClient::GetConnectionInfo(void)
 {
   CStdString strLog;
@@ -1055,7 +1021,7 @@ std::string CCECClient::GetConnectionInfo(void)
   {
     time_t buildTime = (time_t)m_configuration.iFirmwareBuildDate;
     strLog.AppendFormat(", firmware build date: %s", asctime(gmtime(&buildTime)));
-    strLog = strLog.Left((int)strLog.length() - 1); // strip \n added by asctime
+    strLog = strLog.substr(0, strLog.length() > 0 ? (size_t)(strLog.length() - 1) : 0); // strip \n added by asctime
     strLog.append(" +0000");
   }
 
@@ -1071,8 +1037,8 @@ std::string CCECClient::GetConnectionInfo(void)
 
   if (!CLibCEC::IsValidPhysicalAddress(m_configuration.iPhysicalAddress))
     strLog.AppendFormat(", base device: %s (%X), HDMI port number: %d", ToString(m_configuration.baseDevice), m_configuration.baseDevice, m_configuration.iHDMIPort);
-  else
-    strLog.AppendFormat(", physical address: %04x", m_configuration.iPhysicalAddress);
+  uint16_t iPhysicalAddress = GetPrimaryDevice()->GetPhysicalAddress(GetLogicalAddresses().primary, false);
+  strLog.AppendFormat(", physical address: %x.%x.%x.%x", (iPhysicalAddress >> 12) & 0xF, (iPhysicalAddress >> 8) & 0xF, (iPhysicalAddress >> 4) & 0xF, iPhysicalAddress & 0xF);
 
   strLog.AppendFormat(", %s", LIB_CEC->GetLibInfo());
 
@@ -1397,48 +1363,42 @@ void CCECClient::SourceDeactivated(const cec_logical_address logicalAddress)
 
 void CCECClient::CallbackAddCommand(const cec_command &command)
 {
-  {
-    CLockObject lock(m_cbMutex);
-    if (m_configuration.callbacks && m_configuration.callbacks->CBCecCommand)
-    {
-      m_configuration.callbacks->CBCecCommand(m_configuration.callbackParam, command);
-      return;
-    }
-  }
-  m_commandBuffer.Push(command);
+  CLockObject lock(m_cbMutex);
+  if (m_configuration.callbacks && m_configuration.callbacks->CBCecCommand)
+    m_configuration.callbacks->CBCecCommand(m_configuration.callbackParam, command);
 }
 
 void CCECClient::CallbackAddKey(const cec_keypress &key)
 {
+  CLockObject lock(m_cbMutex);
+  if (m_configuration.callbacks && m_configuration.callbacks->CBCecKeyPress)
   {
-    CLockObject lock(m_cbMutex);
-    if (m_configuration.callbacks && m_configuration.callbacks->CBCecKeyPress)
+    // prevent double taps
+    int64_t now = GetTimeMs();
+    if (m_lastKeypress.keycode != key.keycode ||
+        key.duration > 0 ||
+        now - m_iLastKeypressTime >= m_configuration.iDoubleTapTimeoutMs)
     {
+      // no double tap
+      if (key.duration == 0)
+        m_iLastKeypressTime = now;
+      m_lastKeypress = key;
       m_configuration.callbacks->CBCecKeyPress(m_configuration.callbackParam, key);
-      return;
     }
   }
-  m_keyBuffer.Push(key);
 }
 
 void CCECClient::CallbackAddLog(const cec_log_message &message)
 {
-  {
-    CLockObject lock(m_cbMutex);
-    if (m_configuration.callbacks && m_configuration.callbacks->CBCecLogMessage)
-    {
-      m_configuration.callbacks->CBCecLogMessage(m_configuration.callbackParam, message);
-      return;
-    }
-  }
-  m_logBuffer.Push(message);
+  CLockObject lock(m_cbMutex);
+  if (m_configuration.callbacks && m_configuration.callbacks->CBCecLogMessage)
+    m_configuration.callbacks->CBCecLogMessage(m_configuration.callbackParam, message);
 }
 
 void CCECClient::CallbackConfigurationChanged(const libcec_configuration &config)
 {
   CLockObject lock(m_cbMutex);
   if (m_configuration.callbacks &&
-      m_configuration.clientVersion >= CEC_CLIENT_VERSION_1_5_0 &&
       m_configuration.callbacks->CBCecConfigurationChanged &&
       m_processor->CECInitialised())
     m_configuration.callbacks->CBCecConfigurationChanged(m_configuration.callbackParam, config);
@@ -1448,7 +1408,6 @@ void CCECClient::CallbackSourceActivated(bool bActivated, const cec_logical_addr
 {
   CLockObject lock(m_cbMutex);
   if (m_configuration.callbacks &&
-      m_configuration.clientVersion >= CEC_CLIENT_VERSION_1_7_1 &&
       m_configuration.callbacks->CBCecSourceActivated)
     m_configuration.callbacks->CBCecSourceActivated(m_configuration.callbackParam, logicalAddress, bActivated ? 1 : 0);
 }
@@ -1457,7 +1416,6 @@ void CCECClient::CallbackAlert(const libcec_alert type, const libcec_parameter &
 {
   CLockObject lock(m_cbMutex);
   if (m_configuration.callbacks &&
-      m_configuration.clientVersion >= CEC_CLIENT_VERSION_1_6_0 &&
       m_configuration.callbacks->CBCecAlert)
     m_configuration.callbacks->CBCecAlert(m_configuration.callbackParam, type, param);
 }
@@ -1466,7 +1424,6 @@ int CCECClient::CallbackMenuStateChanged(const cec_menu_state newState)
 {
   CLockObject lock(m_cbMutex);
   if (m_configuration.callbacks &&
-      m_configuration.clientVersion >= CEC_CLIENT_VERSION_1_6_2 &&
       m_configuration.callbacks->CBCecMenuStateChanged)
     return m_configuration.callbacks->CBCecMenuStateChanged(m_configuration.callbackParam, newState);
   return 0;
index be72448a5127fb0218021b37051b3eacab1cc171..11a6504d826aaa14b3f59e7cec1100f55bc2e249 100644 (file)
@@ -127,9 +127,6 @@ namespace CEC
     // client-specific part of ICECAdapter
     virtual bool                  EnableCallbacks(void *cbParam, ICECCallbacks *callbacks);
     virtual bool                  PingAdapter(void);
-    virtual bool                  GetNextLogMessage(cec_log_message *message); /**< @deprecated will be removed in v2.0 */
-    virtual bool                  GetNextKeypress(cec_keypress *key);          /**< @deprecated will be removed in v2.0 */
-    virtual bool                  GetNextCommand(cec_command *command);        /**< @deprecated will be removed in v2.0 */
     virtual bool                  Transmit(const cec_command &data, bool bIsReply);
     virtual bool                  SetLogicalAddress(const cec_logical_address iLogicalAddress);
     virtual bool                  SetPhysicalAddress(const uint16_t iPhysicalAddress);
@@ -178,7 +175,7 @@ namespace CEC
     virtual int                   MenuStateChanged(const cec_menu_state newState);
     virtual void                  Alert(const libcec_alert type, const libcec_parameter &param) { CallbackAlert(type, param); }
     virtual void                  AddLog(const cec_log_message &message) { CallbackAddLog(message); }
-    virtual void                  AddKey(void);
+    virtual void                  AddKey(bool bSendComboKey = false);
     virtual void                  AddKey(const cec_keypress &key);
     virtual void                  SetCurrentButton(const cec_user_control_code iButtonCode);
     virtual void                  CheckKeypressTimeout(void);
@@ -301,17 +298,16 @@ namespace CEC
     virtual int  CallbackMenuStateChanged(const cec_menu_state newState);
     virtual void CallbackSourceActivated(bool bActivated, const cec_logical_address logicalAddress);
 
-    CCECProcessor *                         m_processor;      /**< a pointer to the processor */
-    libcec_configuration                    m_configuration;  /**< the configuration of this client */
-    bool                                    m_bInitialised;   /**< true when initialised, false otherwise */
-    bool                                    m_bRegistered;    /**< true when registered in the processor, false otherwise */
-    PLATFORM::CMutex                        m_mutex;          /**< mutex for changes to this instance */
-    PLATFORM::CMutex                        m_cbMutex;        /**< mutex that is held when doing anything with callbacks */
-    cec_user_control_code                   m_iCurrentButton; /**< the control code of the button that's currently held down (if any) */
-    int64_t                                 m_buttontime;     /**< the timestamp when the button was pressed (in seconds since epoch), or 0 if none was pressed. */
-    int64_t                                 m_iPreventForwardingPowerOffCommand; /**< prevent forwarding standby commands until this time */
-    PLATFORM::SyncedBuffer<cec_log_message> m_logBuffer;      /**< @deprecated will be removed in v2.0. buffer for log messages */
-    PLATFORM::SyncedBuffer<cec_keypress>    m_keyBuffer;      /**< @deprecated will be removed in v2.0. buffer for keypresses */
-    PLATFORM::SyncedBuffer<cec_command>     m_commandBuffer;  /**< @deprecated will be removed in v2.0. buffer for commands */
+    CCECProcessor *       m_processor;                         /**< a pointer to the processor */
+    libcec_configuration  m_configuration;                     /**< the configuration of this client */
+    bool                  m_bInitialised;                      /**< true when initialised, false otherwise */
+    bool                  m_bRegistered;                       /**< true when registered in the processor, false otherwise */
+    PLATFORM::CMutex      m_mutex;                             /**< mutex for changes to this instance */
+    PLATFORM::CMutex      m_cbMutex;                           /**< mutex that is held when doing anything with callbacks */
+    cec_user_control_code m_iCurrentButton;                    /**< the control code of the button that's currently held down (if any) */
+    int64_t               m_buttontime;                        /**< the timestamp when the button was pressed (in seconds since epoch), or 0 if none was pressed. */
+    int64_t               m_iPreventForwardingPowerOffCommand; /**< prevent forwarding standby commands until this time */
+    int64_t               m_iLastKeypressTime;                 /**< last time a key press was sent to the client */
+    cec_keypress          m_lastKeypress;                      /**< the last key press that was sent to the client */
   };
 }
index 019cfdd7667f5e29ead4e15398244a01fb1c3fd5..a8679b81b611d4b231edb70ae3dd88954835c05b 100644 (file)
@@ -44,6 +44,13 @@ namespace CEC
     CCECInputBuffer(void) : m_bHasData(false) {}
     virtual ~CCECInputBuffer(void)
     {
+      Broadcast();
+    }
+
+    void Broadcast(void)
+    {
+      PLATFORM::CLockObject lock(m_mutex);
+      m_bHasData = true;
       m_condition.Broadcast();
     }
 
index 9d496404d30a338b61a9acbb43ef70f3c2b34c06..824744cc061d9e52bfd11c69099508d050b81575 100644 (file)
@@ -104,6 +104,8 @@ void CCECProcessor::Close(void)
   SetCECInitialised(false);
 
   // stop the processor
+  StopThread(-1);
+  m_inBuffer.Broadcast();
   StopThread();
 
   // close the connection
@@ -222,7 +224,7 @@ void *CCECProcessor::Process(void)
     if (m_inBuffer.Pop(command, CEC_PROCESSOR_SIGNAL_WAIT_TIME))
       ProcessCommand(command);
 
-    if (CECInitialised())
+    if (CECInitialised() && !IsStopped())
     {
       // check clients for keypress timeouts
       m_libcec->CheckKeypressTimeout();
@@ -437,7 +439,9 @@ bool CCECProcessor::Transmit(const cec_command &data, bool bIsReply)
     iLineTimeout = m_iRetryLineTimeout;
   }
 
-  return adapterState == ADAPTER_MESSAGE_STATE_SENT_ACKED;
+  return bIsReply ?
+      adapterState == ADAPTER_MESSAGE_STATE_SENT_ACKED || adapterState == ADAPTER_MESSAGE_STATE_SENT || adapterState == ADAPTER_MESSAGE_STATE_WAITING_TO_BE_SENT :
+      adapterState == ADAPTER_MESSAGE_STATE_SENT_ACKED;
 }
 
 void CCECProcessor::TransmitAbort(cec_logical_address source, cec_logical_address destination, cec_opcode opcode, cec_abort_reason reason /* = CEC_ABORT_REASON_UNRECOGNIZED_OPCODE */)
@@ -704,7 +708,13 @@ bool CCECProcessor::RegisterClient(CCECClient *client)
 
   libcec_configuration &configuration = *client->GetConfiguration();
 
-  if (configuration.clientVersion >= CEC_CLIENT_VERSION_1_6_3 && configuration.bMonitorOnly == 1)
+  if (configuration.clientVersion < CEC_CLIENT_VERSION_2_0_0)
+  {
+    m_libcec->AddLog(CEC_LOG_ERROR, "failed to register a new CEC client: client version %s is no longer supported", ToString((cec_client_version)configuration.clientVersion));
+    return false;
+  }
+
+  if (configuration.bMonitorOnly == 1)
     return true;
 
   if (!CECInitialised())
@@ -851,7 +861,7 @@ bool CCECProcessor::UnregisterClient(CCECClient *client)
 
 void CCECProcessor::UnregisterClients(void)
 {
-  m_libcec->AddLog(CEC_LOG_NOTICE, "unregistering all CEC clients");
+  m_libcec->AddLog(CEC_LOG_DEBUG, "unregistering all CEC clients");
 
   vector<CCECClient *> clients = m_libcec->GetClients();
   for (vector<CCECClient *>::iterator client = clients.begin(); client != clients.end(); client++)
@@ -931,6 +941,8 @@ void CCECProcessor::HandleLogicalAddressLost(cec_logical_address oldAddress)
 
   m_libcec->AddLog(CEC_LOG_NOTICE, "logical address %x was taken by another device, allocating a new address", oldAddress);
   CCECClient* client = GetClient(oldAddress);
+  if (!client)
+    client = GetPrimaryClient();
   if (client)
   {
     if (m_addrAllocator)
@@ -942,6 +954,16 @@ void CCECProcessor::HandleLogicalAddressLost(cec_logical_address oldAddress)
   }
 }
 
+uint16_t CCECProcessor::GetAdapterVendorId(void) const
+{
+  return m_communication ? m_communication->GetAdapterVendorId() : 0;
+}
+
+uint16_t CCECProcessor::GetAdapterProductId(void) const
+{
+  return m_communication ? m_communication->GetAdapterProductId() : 0;
+}
+
 CCECAllocateLogicalAddress::CCECAllocateLogicalAddress(CCECProcessor* processor, CCECClient* client) :
     m_processor(processor),
     m_client(client) { }
index e1f6d68517eee2908cc7f1b6906e72db0f29240b..dff892e8b9ee2b1e5e588640705a451ff9977605 100644 (file)
@@ -143,6 +143,9 @@ namespace CEC
       void SwitchMonitoring(bool bSwitchTo);
 
       bool AllocateLogicalAddresses(CCECClient* client);
+
+      uint16_t GetAdapterVendorId(void) const;
+      uint16_t GetAdapterProductId(void) const;
     private:
       bool OpenConnection(const char *strPort, uint16_t iBaudRate, uint32_t iTimeoutMs, bool bStartListening = true);
       void SetCECInitialised(bool bSetTo = true);
index 548fc9723132e1dcbd9895eebd28cde2336df9fe..6662182f50802be831d67e4f6174686fa842b766 100644 (file)
@@ -510,6 +510,8 @@ namespace CEC
         return "Vizio";
       case CEC_VENDOR_BROADCOM:
         return "Broadcom";
+      case CEC_VENDOR_LOEWE:
+        return "Loewe";
       default:
         return "Unknown";
       }
@@ -551,6 +553,10 @@ namespace CEC
         return "1.8.2";
       case CEC_CLIENT_VERSION_1_9_0:
         return "1.9.0";
+      case CEC_CLIENT_VERSION_1_99_0:
+        return "2.0.0-pre";
+      case CEC_CLIENT_VERSION_2_0_0:
+        return "2.0.0";
       default:
         return "Unknown";
       }
@@ -592,6 +598,10 @@ namespace CEC
         return "1.8.2";
       case CEC_SERVER_VERSION_1_9_0:
         return "1.9.0";
+      case CEC_SERVER_VERSION_1_99_0:
+        return "2.0.0-pre";
+      case CEC_CLIENT_VERSION_2_0_0:
+        return "2.0.0";
       default:
         return "Unknown";
       }
index 252e1dcfe9f48545f183b82698b87cb325d029a3..904204a2c8e97a1b7dd01f43ff34125966777382 100644 (file)
@@ -36,7 +36,6 @@
 #include "adapter/AdapterFactory.h"
 #include "adapter/AdapterCommunication.h"
 #include "CECProcessor.h"
-#include "CECTypeUtils.h"
 #include "devices/CECAudioSystem.h"
 #include "devices/CECBusDevice.h"
 #include "devices/CECPlaybackDevice.h"
@@ -51,16 +50,7 @@ using namespace std;
 using namespace CEC;
 using namespace PLATFORM;
 
-//TODO replace deprecated constructor in 2.0
-CLibCEC::CLibCEC(const char *UNUSED(strDeviceName), cec_device_type_list UNUSED(types), uint16_t UNUSED(iPhysicalAddress) /* = 0 */) :
-    m_iStartTime(GetTimeMs()),
-    m_client(NULL)
-{
-  m_cec = new CCECProcessor(this);
-}
-
-//TODO replace deprecated constructor in 2.0
-CLibCEC::CLibCEC(libcec_configuration *UNUSED(configuration)) :
+CLibCEC::CLibCEC(void) :
     m_iStartTime(GetTimeMs()),
     m_client(NULL)
 {
@@ -342,21 +332,6 @@ cec_logical_addresses CLibCEC::GetLogicalAddresses(void)
   return addresses;
 }
 
-bool CLibCEC::GetNextLogMessage(cec_log_message *message)
-{
-  return m_client ? m_client->GetNextLogMessage(message) : false;
-}
-
-bool CLibCEC::GetNextKeypress(cec_keypress *key)
-{
-  return m_client ? m_client->GetNextKeypress(key) : false;
-}
-
-bool CLibCEC::GetNextCommand(cec_command *command)
-{
-  return m_client ? m_client->GetNextCommand(command) : false;
-}
-
 cec_device_type CLibCEC::GetType(cec_logical_address address)
 {
   return CCECTypeUtils::GetType(address);
@@ -378,71 +353,6 @@ bool CLibCEC::IsValidPhysicalAddress(uint16_t iPhysicalAddress)
          iPhysicalAddress <= CEC_MAX_PHYSICAL_ADDRESS;
 }
 
-const char *CLibCEC::ToString(const cec_device_type type)
-{
-  return CCECTypeUtils::ToString(type);
-}
-
-const char *CLibCEC::ToString(const cec_menu_state state)
-{
-  return CCECTypeUtils::ToString(state);
-}
-
-const char *CLibCEC::ToString(const cec_version version)
-{
-  return CCECTypeUtils::ToString(version);
-}
-
-const char *CLibCEC::ToString(const cec_power_status status)
-{
-  return CCECTypeUtils::ToString(status);
-}
-
-const char *CLibCEC::ToString(const cec_logical_address address)
-{
-  return CCECTypeUtils::ToString(address);
-}
-
-const char *CLibCEC::ToString(const cec_deck_control_mode mode)
-{
-  return CCECTypeUtils::ToString(mode);
-}
-
-const char *CLibCEC::ToString(const cec_deck_info status)
-{
-  return CCECTypeUtils::ToString(status);
-}
-
-const char *CLibCEC::ToString(const cec_opcode opcode)
-{
-  return CCECTypeUtils::ToString(opcode);
-}
-
-const char *CLibCEC::ToString(const cec_system_audio_status mode)
-{
-  return CCECTypeUtils::ToString(mode);
-}
-
-const char *CLibCEC::ToString(const cec_audio_status status)
-{
-  return CCECTypeUtils::ToString(status);
-}
-
-const char *CLibCEC::ToString(const cec_vendor_id vendor)
-{
-  return CCECTypeUtils::ToString(vendor);
-}
-
-const char *CLibCEC::ToString(const cec_client_version version)
-{
-  return CCECTypeUtils::ToString(version);
-}
-
-const char *CLibCEC::ToString(const cec_server_version version)
-{
-  return CCECTypeUtils::ToString(version);
-}
-
 void CLibCEC::CheckKeypressTimeout(void)
 {
   // check all clients
@@ -484,18 +394,6 @@ void CLibCEC::Alert(const libcec_alert type, const libcec_parameter &param)
     (*it)->Alert(type, param);
 }
 
-bool CLibCEC::SetActiveView(void)
-{
-  AddLog(CEC_LOG_WARNING, "deprecated method %s called", __FUNCTION__);
-  return SetActiveSource();
-}
-
-bool CLibCEC::EnablePhysicalAddressDetection(void)
-{
-  AddLog(CEC_LOG_WARNING, "deprecated method %s called", __FUNCTION__);
-  return true;
-}
-
 CCECClient *CLibCEC::RegisterClient(libcec_configuration &configuration)
 {
   if (!m_cec)
@@ -520,7 +418,7 @@ CCECClient *CLibCEC::RegisterClient(libcec_configuration &configuration)
 
 void CLibCEC::UnregisterClients(void)
 {
-  if (m_cec)
+  if (m_cec && m_cec->IsRunning())
     m_cec->UnregisterClients();
 
   m_clients.clear();
@@ -534,7 +432,7 @@ void * CECInitialise(libcec_configuration *configuration)
     return NULL;
 
   // create a new libCEC instance
-  CLibCEC *lib = new CLibCEC(NULL);
+  CLibCEC *lib = new CLibCEC;
 
   // register a new client
   CCECClient *client(NULL);
@@ -566,18 +464,6 @@ void * CECInit(const char *strDeviceName, CEC::cec_device_type_list types)
   return CECInitialise(&configuration);
 }
 
-void * CECCreate(const char *strDeviceName, CEC::cec_logical_address iLogicalAddress /* = CEC::CECDEVICE_PLAYBACKDEVICE1 */, uint16_t iPhysicalAddress /* = CEC_DEFAULT_PHYSICAL_ADDRESS */)
-{
-  libcec_configuration configuration; configuration.Clear();
-
-  // client version < 1.5.0
-  snprintf(configuration.strDeviceName, 13, "%s", strDeviceName);
-  configuration.iPhysicalAddress = iPhysicalAddress;
-  configuration.deviceTypes.Add(CCECTypeUtils::GetType(iLogicalAddress));
-
-  return CECInitialise(&configuration);
-}
-
 bool CECStartBootloader(void)
 {
   bool bReturn(false);
@@ -639,24 +525,16 @@ const char *CLibCEC::GetLibInfo(void)
 #endif
 }
 
-const char *CLibCEC::ToString(const cec_user_control_code key)
-{
-  return CCECTypeUtils::ToString(key);
-}
-
 void CLibCEC::InitVideoStandalone(void)
 {
   CAdapterFactory::InitVideoStandalone();
 }
-
-const char *CLibCEC::ToString(const cec_adapter_type type)
+uint16_t CLibCEC::GetAdapterVendorId(void) const
 {
-  return CCECTypeUtils::ToString(type);
+  return m_cec && m_cec->IsRunning() ? m_cec->GetAdapterVendorId() : 0;
 }
 
-// no longer being used
-void CLibCEC::AddKey(const cec_keypress &UNUSED(key)) {}
-void CLibCEC::ConfigurationChanged(const libcec_configuration &UNUSED(config)) {}
-void CLibCEC::SetCurrentButton(cec_user_control_code UNUSED(iButtonCode)) {}
-CLibCEC *CLibCEC::GetInstance(void) { return NULL; }
-void CLibCEC::SetInstance(CLibCEC *UNUSED(instance)) {}
+uint16_t CLibCEC::GetAdapterProductId(void) const
+{
+  return m_cec && m_cec->IsRunning() ? m_cec->GetAdapterProductId() : 0;
+}
index fa4e6321bf92b9d1b347af2b9d40da3bf8d7036b..56a112bf52e9e42ee49c45eaf05838eb6719a1ab 100644 (file)
@@ -34,6 +34,7 @@
 #include <string>
 #include "cec.h"
 #include "platform/util/buffer.h"
+#include "CECTypeUtils.h"
 
 namespace CEC
 {
@@ -44,14 +45,9 @@ namespace CEC
   class CLibCEC : public ICECAdapter
   {
     public:
-      CLibCEC(const char *strDeviceName, cec_device_type_list types, uint16_t iPhysicalAddress = 0);
-      CLibCEC(libcec_configuration *configuration);
+      CLibCEC(void);
       virtual ~CLibCEC(void);
 
-    /*!
-     * ICECAdapter implementation
-     */
-    //@{
       bool Open(const char *strPort, uint32_t iTimeout = CEC_DEFAULT_CONNECT_TIMEOUT);
       void Close(void);
       bool EnableCallbacks(void *cbParam, ICECCallbacks *callbacks);
@@ -59,21 +55,12 @@ namespace CEC
       bool PingAdapter(void);
       bool StartBootloader(void);
 
-      int8_t GetMinLibVersion(void) const   { return CEC_MIN_LIB_VERSION; };
-      int8_t GetLibVersionMajor(void) const { return CEC_LIB_VERSION_MAJOR; };
-      int8_t GetLibVersionMinor(void) const { return CEC_LIB_VERSION_MINOR; };
-
-      bool GetNextLogMessage(cec_log_message *message);
-      bool GetNextKeypress(cec_keypress *key);
-      bool GetNextCommand(cec_command *command);
-
       bool Transmit(const cec_command &data);
       bool SetLogicalAddress(cec_logical_address iLogicalAddress = CECDEVICE_PLAYBACKDEVICE1);
       bool SetPhysicalAddress(uint16_t iPhysicalAddress = CEC_DEFAULT_PHYSICAL_ADDRESS);
 
       bool PowerOnDevices(cec_logical_address address = CECDEVICE_TV);
       bool StandbyDevices(cec_logical_address address = CECDEVICE_BROADCAST);
-      bool SetActiveView(void);
       bool SetActiveSource(cec_device_type type = CEC_DEVICE_TYPE_RESERVED);
       bool SetDeckControlMode(cec_deck_control_mode mode, bool bSendUpdate = true);
       bool SetDeckInfo(cec_deck_info info, bool bSendUpdate = true);
@@ -97,7 +84,6 @@ namespace CEC
       bool SendKeypress(cec_logical_address iDestination, cec_user_control_code key, bool bWait = true);
       bool SendKeyRelease(cec_logical_address iDestination, bool bWait = true);
       cec_osd_name GetDeviceOSDName(cec_logical_address iAddress);
-      bool EnablePhysicalAddressDetection(void);
       cec_logical_address GetActiveSource(void);
       bool IsActiveSource(cec_logical_address iAddress);
       bool SetStreamPath(cec_logical_address iAddress);
@@ -110,61 +96,47 @@ namespace CEC
       void RescanActiveDevices(void);
       bool IsLibCECActiveSource(void);
 
-      const char *ToString(const cec_menu_state state);
-      const char *ToString(const cec_version version);
-      const char *ToString(const cec_power_status status);
-      const char *ToString(const cec_logical_address address);
-      const char *ToString(const cec_deck_control_mode mode);
-      const char *ToString(const cec_deck_info status);
-      const char *ToString(const cec_opcode opcode);
-      const char *ToString(const cec_system_audio_status mode);
-      const char *ToString(const cec_audio_status status);
-      const char *ToString(const cec_vendor_id vendor);
-      const char *ToString(const cec_client_version version);
-      const char *ToString(const cec_server_version version);
-      const char *ToString(const cec_device_type type);
+      const char *ToString(const cec_menu_state state)         { return CCECTypeUtils::ToString(state); }
+      const char *ToString(const cec_version version)          { return CCECTypeUtils::ToString(version); }
+      const char *ToString(const cec_power_status status)      { return CCECTypeUtils::ToString(status); }
+      const char *ToString(const cec_logical_address address)  { return CCECTypeUtils::ToString(address); }
+      const char *ToString(const cec_deck_control_mode mode)   { return CCECTypeUtils::ToString(mode); }
+      const char *ToString(const cec_deck_info status)         { return CCECTypeUtils::ToString(status); }
+      const char *ToString(const cec_opcode opcode)            { return CCECTypeUtils::ToString(opcode); }
+      const char *ToString(const cec_system_audio_status mode) { return CCECTypeUtils::ToString(mode); }
+      const char *ToString(const cec_audio_status status)      { return CCECTypeUtils::ToString(status); }
+      const char *ToString(const cec_vendor_id vendor)         { return CCECTypeUtils::ToString(vendor); }
+      const char *ToString(const cec_client_version version)   { return CCECTypeUtils::ToString(version); }
+      const char *ToString(const cec_server_version version)   { return CCECTypeUtils::ToString(version); }
+      const char *ToString(const cec_device_type type)         { return CCECTypeUtils::ToString(type); }
+      const char *ToString(const cec_user_control_code key)    { return CCECTypeUtils::ToString(key); }
+      const char *ToString(const cec_adapter_type type)        { return CCECTypeUtils::ToString(type); }
 
       static cec_device_type GetType(cec_logical_address address);
       static uint16_t GetMaskForType(cec_logical_address address);
       static uint16_t GetMaskForType(cec_device_type type);
 
       bool GetDeviceInformation(const char *strPort, libcec_configuration *config, uint32_t iTimeoutMs = CEC_DEFAULT_CONNECT_TIMEOUT);
-    //@}
 
       void AddLog(const cec_log_level level, const char *strFormat, ...);
-      static void AddKey(void) {}                                           //UNUSED
-      static void AddKey(const cec_keypress &key);                          //UNUSED
       void AddCommand(const cec_command &command);
-      static void ConfigurationChanged(const libcec_configuration &config); //UNUSED
-      static void SetCurrentButton(cec_user_control_code iButtonCode);      //UNUSED
       void CheckKeypressTimeout(void);
       void Alert(const libcec_alert type, const libcec_parameter &param);
-      static CLibCEC *GetInstance(void);                                    //UNUSED
-      static void SetInstance(CLibCEC *instance);                           //UNUSED
 
       static bool IsValidPhysicalAddress(uint16_t iPhysicalAddress);
       CCECClient *RegisterClient(libcec_configuration &configuration);
       void UnregisterClients(void);
       std::vector<CCECClient *> GetClients(void) { return m_clients; };
       const char *GetLibInfo(void);
-      const char *ToString(const cec_user_control_code key);
       void InitVideoStandalone(void);
-      const char *ToString(const cec_adapter_type type);
+      uint16_t GetAdapterVendorId(void) const;
+      uint16_t GetAdapterProductId(void) const;
 
       CCECProcessor *           m_cec;
 
     protected:
-      int64_t                                 m_iStartTime;
-      cec_user_control_code                   m_iCurrentButton;             //UNUSED
-      int64_t                                 m_buttontime;                 //UNUSED
-      PLATFORM::SyncedBuffer<cec_log_message> m_logBuffer;                  //UNUSED
-      PLATFORM::SyncedBuffer<cec_keypress>    m_keyBuffer;                  //UNUSED
-      PLATFORM::SyncedBuffer<cec_command>     m_commandBuffer;              //UNUSED
-      ICECCallbacks *                         m_callbacks;                  //UNUSED
-      void *                                  m_cbParam;                    //UNUSED
-      PLATFORM::CMutex                        m_mutex;
-      PLATFORM::CMutex                        m_logMutex;                   //UNUSED
-
+      int64_t                   m_iStartTime;
+      PLATFORM::CMutex          m_mutex;
       CCECClient *              m_client;
       std::vector<CCECClient *> m_clients;
   };
index 2576da0932577e8dbfb48acf5a333b55934fb263..153668db2f6f3c1349d35fd28b0b9a7ca2431264 100644 (file)
@@ -49,12 +49,6 @@ int cec_initialise(libcec_configuration *configuration)
   return (cec_parser != NULL) ? 1 : 0;
 }
 
-int cec_init_typed(const char *strDeviceName, cec_device_type_list deviceTypes)
-{
-  cec_parser = (ICECAdapter *) CECInit(strDeviceName, deviceTypes);
-  return (cec_parser != NULL) ? 1 : 0;
-}
-
 void cec_destroy(void)
 {
   cec_close();
@@ -103,48 +97,6 @@ int cec_start_bootloader(void)
   return -1;
 }
 
-int8_t cec_get_min_lib_version(void)
-{
-  if (cec_parser)
-    return cec_parser->GetMinLibVersion();
-  return -1;
-}
-
-int8_t cec_get_lib_version_major(void)
-{
-  if (cec_parser)
-    return cec_parser->GetLibVersionMajor();
-  return -1;
-}
-
-int8_t cec_get_lib_version_minor(void)
-{
-  if (cec_parser)
-    return cec_parser->GetLibVersionMinor();
-  return -1;
-}
-
-int cec_get_next_log_message(cec_log_message *message)
-{
-  if (cec_parser)
-    return cec_parser->GetNextLogMessage(message) ? 1 : 0;
-  return -1;
-}
-
-int cec_get_next_keypress(cec_keypress *key)
-{
-  if (cec_parser)
-    return cec_parser->GetNextKeypress(key) ? 1 : 0;
-  return -1;
-}
-
-int cec_get_next_command(cec_command *command)
-{
-  if (cec_parser)
-    return cec_parser->GetNextCommand(command) ? 1 : 0;
-  return -1;
-}
-
 int cec_transmit(const CEC::cec_command *data)
 {
   if (cec_parser)
@@ -180,13 +132,6 @@ int cec_standby_devices(cec_logical_address address /* = CECDEVICE_BROADCAST */)
   return -1;
 }
 
-int cec_set_active_view(void)
-{
-  if (cec_parser)
-    return cec_parser->SetActiveView() ? 1 : 0;
-  return -1;
-}
-
 int cec_set_active_source(cec_device_type type)
 {
   if (cec_parser)
@@ -367,11 +312,6 @@ cec_osd_name cec_get_device_osd_name(cec_logical_address iAddress)
   return retVal;
 }
 
-int cec_enable_physical_address_detection(void)
-{
-  return cec_parser ? (cec_parser->EnablePhysicalAddressDetection() ? 1 : 0) : -1;
-}
-
 int cec_set_stream_path_logical(CEC::cec_logical_address iAddress)
 {
   return cec_parser ? (cec_parser->SetStreamPath(iAddress) ? 1 : 0) : -1;
@@ -438,4 +378,14 @@ void cec_init_video_standalone(void)
     cec_parser->InitVideoStandalone();
 }
 
+uint16_t cec_get_adapter_vendor_id(void)
+{
+  return cec_parser ? cec_parser->GetAdapterVendorId() : 0;
+}
+
+uint16_t cec_get_adapter_product_id(void)
+{
+  return cec_parser ? cec_parser->GetAdapterProductId() : 0;
+}
+
 //@}
index 07026713042a19e934bc84af18d4060de42788cb..7dd56b7fdbfebd22eb3a8c86867fbe916193f980 100644 (file)
@@ -211,6 +211,16 @@ namespace CEC
      */
     virtual cec_adapter_type GetAdapterType(void) = 0;
 
+    /*!
+     * @return The (virtual) USB vendor id
+     */
+    virtual uint16_t GetAdapterVendorId(void) const = 0;
+
+    /*!
+     * @return The (virtual) USB product id
+     */
+    virtual uint16_t GetAdapterProductId(void) const = 0;
+
     IAdapterCommunicationCallback *m_callback;
   };
 };
index ab0fa392e12633c54a0c237861bbae481b1fbfcb..cf97ea9f3593e7ab01320f25b7a2deff6811616e 100644 (file)
@@ -91,7 +91,7 @@ uint16_t CUSBCECAdapterCommands::RequestFirmwareVersion(void)
       m_persistedConfiguration.iFirmwareVersion = (response[0] << 8 | response[1]);
     else
     {
-      LIB_CEC->AddLog(CEC_LOG_WARNING, "the adapter did not respond with a correct firmware version (try %d)", iFwVersionTry);
+      LIB_CEC->AddLog(CEC_LOG_WARNING, "the adapter did not respond with a correct firmware version (try %d, size = %d)", iFwVersionTry, response.size);
       CEvent::Sleep(500);
     }
   }
index ae4c8ac60ebdc210e7706af77d55fac74dcf0bd5..9c6743f0851ec8c7a241cddec6c3e6b39418979b 100644 (file)
@@ -36,6 +36,7 @@
 #include "USBCECAdapterCommands.h"
 #include "USBCECAdapterMessageQueue.h"
 #include "USBCECAdapterMessage.h"
+#include "USBCECAdapterDetection.h"
 #include "lib/platform/sockets/serialport.h"
 #include "lib/platform/util/timeutils.h"
 #include "lib/platform/util/util.h"
@@ -59,6 +60,7 @@ using namespace PLATFORM;
 #define CEC_LATEST_ADAPTER_FW_DATE    0x501a4b0c
 
 #define CEC_FW_DATE_EXTENDED_RESPONSE 0x501a4b0c
+#define CEC_FW_DATE_DESCRIPTOR2       0x5045dbf5
 
 #define LIB_CEC m_callback->GetLib()
 
@@ -234,24 +236,33 @@ void CUSBCECAdapterCommunication::Close(void)
     m_port->Close();
 }
 
-cec_adapter_message_state CUSBCECAdapterCommunication::Write(const cec_command &data, bool &bRetry, uint8_t iLineTimeout, bool UNUSED(bIsReply))
+cec_adapter_message_state CUSBCECAdapterCommunication::Write(const cec_command &data, bool &bRetry, uint8_t iLineTimeout, bool bIsReply)
 {
   cec_adapter_message_state retVal(ADAPTER_MESSAGE_STATE_UNKNOWN);
   if (!IsRunning())
     return retVal;
 
   CCECAdapterMessage *output = new CCECAdapterMessage(data, iLineTimeout);
+  output->bFireAndForget = bIsReply;
 
   /* mark as waiting for an ack from the destination */
   MarkAsWaiting(data.destination);
 
   /* send the message */
-  bRetry = (!m_adapterMessageQueue->Write(output) || output->NeedsRetry()) && output->transmit_timeout > 0;
-  if (bRetry)
-    Sleep(CEC_DEFAULT_TRANSMIT_RETRY_WAIT);
-  retVal = output->state;
+  if (bIsReply)
+  {
+    retVal = m_adapterMessageQueue->Write(output) ?
+        ADAPTER_MESSAGE_STATE_WAITING_TO_BE_SENT : ADAPTER_MESSAGE_STATE_ERROR;
+  }
+  else
+  {
+    bRetry = (!m_adapterMessageQueue->Write(output) || output->NeedsRetry()) && output->transmit_timeout > 0;
+    if (bRetry)
+      Sleep(CEC_DEFAULT_TRANSMIT_RETRY_WAIT);
+    retVal = output->state;
 
-  delete output;
+    delete output;
+  }
   return retVal;
 }
 
@@ -273,7 +284,8 @@ void *CUSBCECAdapterCommunication::Process(void)
     }
 
     /* TODO sleep 5 ms so other threads can get a lock */
-    Sleep(5);
+    if (!IsStopped())
+      Sleep(5);
   }
 
   m_adapterMessageQueue->Clear();
@@ -375,7 +387,9 @@ bool CUSBCECAdapterCommunication::WriteToDevice(CCECAdapterMessage *message)
     return false;
   }
 
+#ifdef CEC_DEBUGGING
   LIB_CEC->AddLog(CEC_LOG_DEBUG, "command '%s' sent", message->IsTranmission() ? "CEC transmission" : CCECAdapterMessage::ToString(message->Message()));
+#endif
   message->state = ADAPTER_MESSAGE_STATE_SENT;
   return true;
 }
@@ -600,6 +614,20 @@ bool CUSBCECAdapterCommunication::ProvidesExtendedResponse(void)
   return iBuildDate >= CEC_FW_DATE_EXTENDED_RESPONSE;
 }
 
+uint16_t CUSBCECAdapterCommunication::GetAdapterVendorId(void) const
+{
+  return CEC_VID;
+}
+
+uint16_t CUSBCECAdapterCommunication::GetAdapterProductId(void) const
+{
+  uint32_t iBuildDate(0);
+  if (m_commands)
+    iBuildDate = m_commands->GetPersistedBuildDate();
+
+  return iBuildDate >= CEC_FW_DATE_DESCRIPTOR2 ? CEC_PID2 : CEC_PID;
+}
+
 bool CUSBCECAdapterCommunication::IsRunningLatestFirmware(void)
 {
   return GetFirmwareBuildDate() >= CEC_LATEST_ADAPTER_FW_DATE &&
@@ -711,6 +739,7 @@ void CAdapterEepromWriteThread::Stop(void)
     CLockObject lock(m_mutex);
     if (m_iScheduleEepromWrite > 0)
       m_com->LIB_CEC->AddLog(CEC_LOG_WARNING, "write thread stopped while a write was queued");
+    m_bWrite = true;
     m_condition.Signal();
   }
   StopThread();
@@ -724,6 +753,8 @@ void *CAdapterEepromWriteThread::Process(void)
     if ((m_iScheduleEepromWrite > 0 && m_iScheduleEepromWrite < GetTimeMs()) ||
         m_condition.Wait(m_mutex, m_bWrite, 100))
     {
+      if (IsStopped())
+        break;
       m_bWrite = false;
       if (m_com->m_commands->WriteEEPROM())
       {
index 2192456010ca99c7dae30f42285a8ed387d79dd3..04199e2bc079b3a7371aa5455da23bc3f856f2bc 100644 (file)
@@ -88,6 +88,8 @@ namespace CEC
     cec_vendor_id GetVendorId(void) { return CEC_VENDOR_UNKNOWN; }
     bool SupportsSourceLogicalAddress(const cec_logical_address UNUSED(address)) { return true; }
     cec_adapter_type GetAdapterType(void);
+    uint16_t GetAdapterVendorId(void) const;
+    uint16_t GetAdapterProductId(void) const;
     ///}
 
     bool ProvidesExtendedResponse(void);
index 5d72b5efbbb7ab9a1916e487d00cb9e62259d8cf..d441a48a787b3756141862fdd346b9c5f8898b05 100644 (file)
@@ -440,7 +440,7 @@ uint8_t CUSBCECAdapterDetection::FindAdapters(cec_adapter *deviceList, uint8_t i
   tmp = (void *)strDevicePath;
 #endif
 
-  iBufSize = 0; /* silence "unused" warning on linux/osx */
+  iBufSize = 0; if(!iBufSize){} /* silence "unused" warning on linux/osx */
 
   return iFound;
 }
index dfccd65bb2c3bd61a603f0b0f652157e217ce9c2..37478b9632036770d6e480537c94252d074d9ad6 100644 (file)
 
 namespace CEC
 {
+  #define CEC_VID  0x2548
+  #define CEC_PID  0x1001
+  #define CEC_PID2 0x1002
+  
   class CUSBCECAdapterDetection
   {
   public:
index 64efd062f5f58ab60a2666e4c6c82bab673cabb3..5756283a60d883acddd2bd05a4d2d4201d29c56b 100644 (file)
@@ -174,7 +174,7 @@ const char *CCECAdapterMessage::ToString(cec_adapter_messagecode msgCode)
   case MSGCODE_TRANSMIT_IDLETIME:
     return "TRANSMIT_IDLETIME";
   case MSGCODE_TRANSMIT_ACK_POLARITY:
-    return "TRANSMIT_ACK_POLARITY";
+    return "CEC transmission";
   case MSGCODE_TRANSMIT_LINE_TIMEOUT:
     return "TRANSMIT_LINE_TIMEOUT";
   case MSGCODE_TRANSMIT_SUCCEEDED:
@@ -266,6 +266,7 @@ void CCECAdapterMessage::Clear(void)
   packet.Clear();
   lineTimeout         = 3;
   bNextByteIsEscaped  = false;
+  bFireAndForget      = false;
 }
 
 void CCECAdapterMessage::Shift(uint8_t iShiftBy)
@@ -377,18 +378,27 @@ bool CCECAdapterMessage::IsACK(void) const
       false;
 }
 
-bool CCECAdapterMessage::IsError(void) const
+bool CCECAdapterMessage::MessageCodeIsError(const cec_adapter_messagecode code)
 {
-  cec_adapter_messagecode code = Message();
   return (code == MSGCODE_HIGH_ERROR ||
-          code == MSGCODE_LOW_ERROR ||
-          code == MSGCODE_RECEIVE_FAILED ||
-          code == MSGCODE_COMMAND_REJECTED ||
-          code == MSGCODE_TRANSMIT_LINE_TIMEOUT ||
-          code == MSGCODE_TRANSMIT_FAILED_LINE ||
-          code == MSGCODE_TRANSMIT_FAILED_ACK ||
-          code == MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA ||
-          code == MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE);
+           code == MSGCODE_LOW_ERROR ||
+           code == MSGCODE_RECEIVE_FAILED ||
+           code == MSGCODE_COMMAND_REJECTED ||
+           code == MSGCODE_TRANSMIT_LINE_TIMEOUT ||
+           code == MSGCODE_TRANSMIT_FAILED_LINE ||
+           code == MSGCODE_TRANSMIT_FAILED_ACK ||
+           code == MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA ||
+           code == MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE);
+}
+
+bool CCECAdapterMessage::IsError(void) const
+{
+  return MessageCodeIsError(Message());
+}
+
+bool CCECAdapterMessage::ReplyIsError(void) const
+{
+  return MessageCodeIsError(Reply());
 }
 
 bool CCECAdapterMessage::NeedsRetry(void) const
index f8ae4135362167378a5e4e61257484eeb1c87781..89005e8694ff54419e7a93ddddc199dc5a9b50bc 100644 (file)
@@ -202,10 +202,22 @@ namespace CEC
     bool IsACK(void) const;
 
     /*!
-     * @return True when this message has been replied with an error code, false otherwise.
+     * @brief Checks whether the given messagecode is an error message.
+     * @param code The code to check.
+     * @return True when it's an error, false otherwise.
+     */
+    static bool MessageCodeIsError(const cec_adapter_messagecode code);
+
+    /*!
+     * @return True when this message contains an error code, false otherwise.
      */
     bool IsError(void) const;
 
+    /*!
+     * @return True when this message has been replied with an error code, false otherwise.
+     */
+    bool ReplyIsError(void) const;
+
     /*!
      * @return True when this message has been replied with an error code and needs to be retried, false otherwise.
      */
@@ -238,12 +250,12 @@ namespace CEC
      */
     cec_adapter_messagecode Reply(void) const;
 
-    uint8_t                               maxTries;             /**< the maximum number of times to try to send this message */
     cec_datapacket                        response;             /**< the response to this message */
     cec_datapacket                        packet;               /**< the actual data */
     cec_adapter_message_state             state;                /**< the current state of this message */
     int32_t                               transmit_timeout;     /**< the timeout to use when sending this message */
     uint8_t                               lineTimeout;          /**< the default CEC line timeout to use when sending this message */
+    bool                                  bFireAndForget;       /**< true to auto delete, don't wait for a response */
 
   private:
     bool                                  bNextByteIsEscaped;   /**< true when the next byte that is added will be escaped, false otherwise */
index b05a20e7c26412a36bcef80cb208039d106ed8cc..1b14f445f30e9bfc43afbef5304296d3277cb619 100644 (file)
@@ -50,7 +50,8 @@ CCECAdapterMessageQueueEntry::CCECAdapterMessageQueueEntry(CCECAdapterMessageQue
     m_message(message),
     m_iPacketsLeft(message->IsTranmission() ? message->Size() / 4 : 1),
     m_bSucceeded(false),
-    m_bWaiting(true) {}
+    m_bWaiting(true),
+    m_queueTimeout(message->transmit_timeout) {}
 
 CCECAdapterMessageQueueEntry::~CCECAdapterMessageQueueEntry(void) { }
 
@@ -133,6 +134,9 @@ bool CCECAdapterMessageQueueEntry::IsResponseOld(const CCECAdapterMessage &msg)
 
 bool CCECAdapterMessageQueueEntry::IsResponse(const CCECAdapterMessage &msg)
 {
+  if (m_message->state == ADAPTER_MESSAGE_STATE_SENT_ACKED)
+    return false;
+
   cec_adapter_messagecode thisMsgCode = m_message->Message();
   cec_adapter_messagecode msgCode = msg.Message();
   cec_adapter_messagecode msgResponse = msg.ResponseTo();
@@ -146,10 +150,7 @@ bool CCECAdapterMessageQueueEntry::IsResponse(const CCECAdapterMessage &msg)
 
   // response without a msgcode
   if (msgResponse == MSGCODE_NOTHING)
-  {
-    m_queue->m_com->m_callback->GetLib()->AddLog(CEC_LOG_WARNING, "no response code received");
-    return true;
-  }
+    return false;
 
   // commands that only repond with accepted/rejected
   if (thisMsgCode == MSGCODE_PING ||
@@ -175,10 +176,7 @@ bool CCECAdapterMessageQueueEntry::IsResponse(const CCECAdapterMessage &msg)
   return ((msgCode == MSGCODE_COMMAND_ACCEPTED || msgCode == MSGCODE_COMMAND_REJECTED) &&
       (msgResponse == MSGCODE_TRANSMIT_ACK_POLARITY || msgResponse == MSGCODE_TRANSMIT || msgResponse == MSGCODE_TRANSMIT_EOM)) ||
       msgCode == MSGCODE_TIMEOUT_ERROR ||
-      msgCode == MSGCODE_HIGH_ERROR ||
-      msgCode == MSGCODE_LOW_ERROR ||
       msgCode == MSGCODE_RECEIVE_FAILED ||
-      msgCode == MSGCODE_TRANSMIT_FAILED_LINE ||
       msgCode == MSGCODE_TRANSMIT_FAILED_ACK ||
       msgCode == MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA ||
       msgCode == MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE ||
@@ -205,12 +203,14 @@ bool CCECAdapterMessageQueueEntry::MessageReceivedCommandAccepted(const CCECAdap
       /* decrease by 1 */
       m_iPacketsLeft--;
 
+#ifdef CEC_DEBUGGING
       /* log this message */
       CStdString strLog;
       strLog.Format("%s - command accepted", ToString());
       if (m_iPacketsLeft > 0)
         strLog.AppendFormat(" - waiting for %d more", m_iPacketsLeft);
       m_queue->m_com->m_callback->GetLib()->AddLog(CEC_LOG_DEBUG, strLog);
+#endif
 
       /* no more packets left and not a transmission, so we're done */
       if (!m_message->IsTranmission() && m_iPacketsLeft == 0)
@@ -236,7 +236,9 @@ bool CCECAdapterMessageQueueEntry::MessageReceivedTransmitSucceeded(const CCECAd
     if (m_iPacketsLeft == 0)
     {
       /* transmission succeeded, so we're done */
-      m_queue->m_com->m_callback->GetLib()->AddLog(CEC_LOG_DEBUG, "%s - transmit succeeded", ToString());
+#ifdef CEC_DEBUGGING
+      m_queue->m_com->m_callback->GetLib()->AddLog(CEC_LOG_DEBUG, "%s - transmit succeeded", m_message->ToString().c_str());
+#endif
       m_message->state = ADAPTER_MESSAGE_STATE_SENT_ACKED;
       m_message->response = message.packet;
     }
@@ -258,7 +260,9 @@ bool CCECAdapterMessageQueueEntry::MessageReceivedResponse(const CCECAdapterMess
 {
   {
     CLockObject lock(m_mutex);
+#ifdef CEC_DEBUGGING
     m_queue->m_com->m_callback->GetLib()->AddLog(CEC_LOG_DEBUG, "%s - received response - %s", ToString(), message.ToString().c_str());
+#endif
     m_message->response = message.packet;
     if (m_message->IsTranmission())
       m_message->state = message.Message() == MSGCODE_TRANSMIT_SUCCEEDED ? ADAPTER_MESSAGE_STATE_SENT_ACKED : ADAPTER_MESSAGE_STATE_SENT_NOT_ACKED;
@@ -276,6 +280,11 @@ bool CCECAdapterMessageQueueEntry::ProvidesExtendedResponse(void)
   return m_queue && m_queue->ProvidesExtendedResponse();
 }
 
+bool CCECAdapterMessageQueueEntry::TimedOutOrSucceeded(void) const
+{
+  return m_message->bFireAndForget && (m_bSucceeded || m_queueTimeout.TimeLeft() == 0);
+}
+
 CCECAdapterMessageQueue::CCECAdapterMessageQueue(CUSBCECAdapterCommunication *com) :
   PLATFORM::CThread(),
   m_com(com),
@@ -287,8 +296,9 @@ CCECAdapterMessageQueue::CCECAdapterMessageQueue(CUSBCECAdapterCommunication *co
 
 CCECAdapterMessageQueue::~CCECAdapterMessageQueue(void)
 {
+  StopThread(-1);
   Clear();
-  StopThread(0);
+  StopThread();
   delete m_incomingAdapterMessage;
 }
 
@@ -321,10 +331,35 @@ void *CCECAdapterMessageQueue::Process(void)
         break;
       }
     }
+
+    CheckTimedOutMessages();
   }
   return NULL;
 }
 
+void CCECAdapterMessageQueue::CheckTimedOutMessages(void)
+{
+  CLockObject lock(m_mutex);
+  vector<uint64_t> timedOut;
+  for (map<uint64_t, CCECAdapterMessageQueueEntry *>::iterator it = m_messages.begin(); it != m_messages.end(); it++)
+  {
+    if (it->second->TimedOutOrSucceeded())
+    {
+      timedOut.push_back(it->first);
+      if (!it->second->m_bSucceeded)
+        m_com->m_callback->GetLib()->AddLog(CEC_LOG_DEBUG, "command '%s' was not acked by the controller", CCECAdapterMessage::ToString(it->second->m_message->Message()));
+      delete it->second->m_message;
+      delete it->second;
+    }
+  }
+
+  for (vector<uint64_t>::iterator it = timedOut.begin(); it != timedOut.end(); it++)
+  {
+    uint64_t iEntryId = *it;
+    m_messages.erase(iEntryId);
+  }
+}
+
 void CCECAdapterMessageQueue::MessageReceived(const CCECAdapterMessage &msg)
 {
   bool bHandled(false);
@@ -337,7 +372,12 @@ void CCECAdapterMessageQueue::MessageReceived(const CCECAdapterMessage &msg)
   {
     /* the message wasn't handled */
     bool bIsError(m_com->HandlePoll(msg));
+#ifdef CEC_DEBUGGING
     m_com->m_callback->GetLib()->AddLog(bIsError ? CEC_LOG_WARNING : CEC_LOG_DEBUG, msg.ToString().c_str());
+#else
+    if (bIsError)
+      m_com->m_callback->GetLib()->AddLog(CEC_LOG_WARNING, msg.ToString().c_str());
+#endif
 
     /* push this message to the current frame */
     if (!bIsError && msg.PushToCecCommand(m_currentCECFrame))
@@ -387,6 +427,13 @@ bool CCECAdapterMessageQueue::Write(CCECAdapterMessage *msg)
   }
 
   CCECAdapterMessageQueueEntry *entry = new CCECAdapterMessageQueueEntry(this, msg);
+  if (!entry)
+  {
+    m_com->m_callback->GetLib()->AddLog(CEC_LOG_ERROR, "couldn't create queue entry for '%s'", CCECAdapterMessage::ToString(msg->Message()));
+    msg->state = ADAPTER_MESSAGE_STATE_ERROR;
+    return false;
+  }
+
   uint64_t iEntryId(0);
   /* add to the wait for ack queue */
   if (msg->Message() != MSGCODE_START_BOOTLOADER)
@@ -400,7 +447,7 @@ bool CCECAdapterMessageQueue::Write(CCECAdapterMessage *msg)
   m_writeQueue.Push(entry);
 
   bool bReturn(true);
-  if (entry)
+  if (!msg->bFireAndForget)
   {
     if (!entry->Wait(msg->transmit_timeout <= 5 ? CEC_DEFAULT_TRANSMIT_WAIT : msg->transmit_timeout))
     {
@@ -414,6 +461,10 @@ bool CCECAdapterMessageQueue::Write(CCECAdapterMessage *msg)
       CLockObject lock(m_mutex);
       m_messages.erase(iEntryId);
     }
+
+    if (msg->ReplyIsError())
+      msg->state = ADAPTER_MESSAGE_STATE_ERROR;
+
     delete entry;
   }
 
index b81c908fafb6bf2b4ed5a7ba84df0b1b90441ffb..7e01436372250ec30ae63c7911f87343e6bdc82b 100644 (file)
@@ -33,6 +33,7 @@
 
 #include "lib/platform/threads/threads.h"
 #include "lib/platform/util/buffer.h"
+#include "lib/platform/util/timeutils.h"
 #include <map>
 #include "USBCECAdapterMessage.h"
 
@@ -118,6 +119,11 @@ namespace CEC
 
     bool ProvidesExtendedResponse(void);
 
+    /*!
+     * @return True when a fire and forget packet timed out or succeeded, false otherwise
+     */
+    bool TimedOutOrSucceeded(void) const;
+
     CCECAdapterMessageQueue *  m_queue;
     CCECAdapterMessage *       m_message;      /**< the message that was sent */
     uint8_t                    m_iPacketsLeft; /**< the amount of acks that we're waiting on */
@@ -125,6 +131,7 @@ namespace CEC
     bool                       m_bWaiting;     /**< true while a thread is waiting or when it hasn't started waiting yet */
     PLATFORM::CCondition<bool> m_condition;    /**< the condition to wait on */
     PLATFORM::CMutex           m_mutex;        /**< mutex for changes to this class */
+    PLATFORM::CTimeout         m_queueTimeout;   /**< ack timeout for fire and forget commands */
   };
 
   class CCECAdapterMessageQueue : public PLATFORM::CThread
@@ -170,6 +177,8 @@ namespace CEC
 
     virtual void *Process(void);
 
+    void CheckTimedOutMessages(void);
+
   private:
     CUSBCECAdapterCommunication *                          m_com;                    /**< the communication handler */
     PLATFORM::CMutex                                       m_mutex;                  /**< mutex for changes to this class */
index 5d13368e50a3c569667ab0b812ed3d824b534c50..daaa72ab17d96eda8c3184c142fa921f05f3de70 100644 (file)
@@ -61,7 +61,8 @@ void rpi_cec_callback(void *callback_data, uint32_t p0, uint32_t p1, uint32_t p2
 CRPiCECAdapterCommunication::CRPiCECAdapterCommunication(IAdapterCommunicationCallback *callback) :
     IAdapterCommunication(callback),
     m_logicalAddress(CECDEVICE_UNKNOWN),
-    m_bLogicalAddressChanged(false)
+    m_bLogicalAddressChanged(false),
+    m_previousLogicalAddress(CECDEVICE_FREEUSE)
 {
   m_queue = new CRPiCECAdapterMessageQueue(this);
 }
@@ -174,6 +175,7 @@ void CRPiCECAdapterCommunication::OnDataReceived(uint32_t header, uint32_t p0, u
   case VC_CEC_LOGICAL_ADDR:
     {
       CLockObject lock(m_mutex);
+      m_previousLogicalAddress = m_logicalAddress;
       if (CEC_CB_RC(header) == VCHIQ_SUCCESS)
       {
         m_bLogicalAddressChanged = true;
@@ -182,7 +184,7 @@ void CRPiCECAdapterCommunication::OnDataReceived(uint32_t header, uint32_t p0, u
       }
       else
       {
-        m_logicalAddress = CECDEVICE_BROADCAST;
+        m_logicalAddress = CECDEVICE_FREEUSE;
         LIB_CEC->AddLog(CEC_LOG_DEBUG, "failed to change the logical address, reset to %s (%x)", LIB_CEC->ToString(m_logicalAddress), m_logicalAddress);
       }
       m_logicalAddressCondition.Signal();
@@ -191,7 +193,7 @@ void CRPiCECAdapterCommunication::OnDataReceived(uint32_t header, uint32_t p0, u
   case VC_CEC_LOGICAL_ADDR_LOST:
     {
       // the logical address was taken by another device
-      cec_logical_address previousAddress = m_logicalAddress;
+      cec_logical_address previousAddress = m_logicalAddress == CECDEVICE_BROADCAST ? m_previousLogicalAddress : m_logicalAddress;
       m_logicalAddress = CECDEVICE_UNKNOWN;
 
       // notify libCEC that we lost our LA when the connection was initialised
index 7f815450c27b60a87e28cc4256d7b4ed80880acf..3cbbdde6551e612870dfbfc153049ec02c3a51a7 100644 (file)
  *     http://www.pulse-eight.net/
  */
 
+#include "env.h"
 #if defined(HAVE_RPI_API)
 
 #include "lib/adapter/AdapterCommunication.h"
 #include "lib/platform/threads/threads.h"
 
+#define RPI_ADAPTER_VID 0x2708
+#define RPI_ADAPTER_PID 0x1001
+
 extern "C" {
 #include <interface/vmcs_host/vc_cecservice.h>
 #include <interface/vchiq_arm/vchiq_if.h>
@@ -79,6 +83,8 @@ namespace CEC
     cec_vendor_id GetVendorId(void) { return CEC_VENDOR_BROADCOM; }
     bool SupportsSourceLogicalAddress(const cec_logical_address address) { return address > CECDEVICE_TV && address < CECDEVICE_BROADCAST; }
     cec_adapter_type GetAdapterType(void) { return ADAPTERTYPE_RPI; };
+    uint16_t GetAdapterVendorId(void) const { return RPI_ADAPTER_VID; }
+    uint16_t GetAdapterProductId(void) const { return RPI_ADAPTER_PID; }
     ///}
 
     bool IsInitialised(void);
@@ -102,6 +108,7 @@ namespace CEC
     PLATFORM::CMutex            m_mutex;
     VCHI_INSTANCE_T             m_vchi_instance;
     VCHI_CONNECTION_T *         m_vchi_connection;
+    cec_logical_address         m_previousLogicalAddress;
   };
 };
 
index 91a3e99d13c3c9a34c80d9da3f44eefd52563d4c..add3e6f3f6286137370a5d53fa3982012c8ce8d9 100644 (file)
@@ -83,7 +83,7 @@ bool CCECAudioSystem::TransmitAudioStatus(cec_logical_address dest, bool bIsRepl
   uint8_t state;
   {
     CLockObject lock(m_mutex);
-    LIB_CEC->AddLog(CEC_LOG_NOTICE, "<< %x -> %x: audio status '%2x'", m_iLogicalAddress, dest, m_audioStatus);
+    LIB_CEC->AddLog(CEC_LOG_DEBUG, "<< %x -> %x: audio status '%2x'", m_iLogicalAddress, dest, m_audioStatus);
     state = m_audioStatus;
   }
 
@@ -95,7 +95,7 @@ bool CCECAudioSystem::TransmitSetSystemAudioMode(cec_logical_address dest, bool
   cec_system_audio_status state;
   {
     CLockObject lock(m_mutex);
-    LIB_CEC->AddLog(CEC_LOG_NOTICE, "<< %x -> %x: set system audio mode '%2x'", m_iLogicalAddress, dest, m_audioStatus);
+    LIB_CEC->AddLog(CEC_LOG_DEBUG, "<< %x -> %x: set system audio mode '%2x'", m_iLogicalAddress, dest, m_audioStatus);
     state = m_systemAudioStatus;
   }
 
@@ -107,7 +107,7 @@ bool CCECAudioSystem::TransmitSystemAudioModeStatus(cec_logical_address dest, bo
   cec_system_audio_status state;
   {
     CLockObject lock(m_mutex);
-    LIB_CEC->AddLog(CEC_LOG_NOTICE, "<< %x -> %x: system audio mode '%s'", m_iLogicalAddress, dest, ToString(m_systemAudioStatus));
+    LIB_CEC->AddLog(CEC_LOG_DEBUG, "<< %x -> %x: system audio mode '%s'", m_iLogicalAddress, dest, ToString(m_systemAudioStatus));
     state = m_systemAudioStatus;
   }
 
index 2998a622021786c7e3e9ba162870f1b92aa45373..e3d4cfdeea8876a2d2d36d87f1d85aadab57d717 100644 (file)
@@ -306,7 +306,7 @@ bool CCECBusDevice::RequestCecVersion(const cec_logical_address initiator, bool
       !IsUnsupportedFeature(CEC_OPCODE_GET_CEC_VERSION))
   {
     MarkBusy();
-    LIB_CEC->AddLog(CEC_LOG_NOTICE, "<< requesting CEC version of '%s' (%X)", GetLogicalAddressName(), m_iLogicalAddress);
+    LIB_CEC->AddLog(CEC_LOG_DEBUG, "<< requesting CEC version of '%s' (%X)", GetLogicalAddressName(), m_iLogicalAddress);
     bReturn = m_handler->TransmitRequestCecVersion(initiator, m_iLogicalAddress, bWaitForResponse);
     MarkReady();
   }
@@ -318,7 +318,7 @@ bool CCECBusDevice::TransmitCECVersion(const cec_logical_address destination, bo
   cec_version version;
   {
     CLockObject lock(m_mutex);
-    LIB_CEC->AddLog(CEC_LOG_NOTICE, "<< %s (%X) -> %s (%X): cec version %s", GetLogicalAddressName(), m_iLogicalAddress, ToString(destination), destination, ToString(m_cecVersion));
+    LIB_CEC->AddLog(CEC_LOG_DEBUG, "<< %s (%X) -> %s (%X): cec version %s", GetLogicalAddressName(), m_iLogicalAddress, ToString(destination), destination, ToString(m_cecVersion));
     version = m_cecVersion;
   }
 
@@ -375,7 +375,7 @@ bool CCECBusDevice::RequestMenuLanguage(const cec_logical_address initiator, boo
       !IsUnsupportedFeature(CEC_OPCODE_GET_MENU_LANGUAGE))
   {
     MarkBusy();
-    LIB_CEC->AddLog(CEC_LOG_NOTICE, "<< requesting menu language of '%s' (%X)", GetLogicalAddressName(), m_iLogicalAddress);
+    LIB_CEC->AddLog(CEC_LOG_DEBUG, "<< requesting menu language of '%s' (%X)", GetLogicalAddressName(), m_iLogicalAddress);
     bReturn = m_handler->TransmitRequestMenuLanguage(initiator, m_iLogicalAddress, bWaitForResponse);
     MarkReady();
   }
@@ -402,13 +402,13 @@ bool CCECBusDevice::TransmitSetMenuLanguage(const cec_logical_address destinatio
   MarkBusy();
   if (lang[0] == '?' && lang[1] == '?' && lang[2] == '?')
   {
-    LIB_CEC->AddLog(CEC_LOG_NOTICE, "<< %s (%X) -> %s (%X): Menu language feature abort", GetLogicalAddressName(), m_iLogicalAddress, ToString(destination), destination);
+    LIB_CEC->AddLog(CEC_LOG_DEBUG, "<< %s (%X) -> %s (%X): menu language feature abort", GetLogicalAddressName(), m_iLogicalAddress, ToString(destination), destination);
     m_processor->TransmitAbort(m_iLogicalAddress, destination, CEC_OPCODE_GIVE_DEVICE_VENDOR_ID);
     bReturn = true;
   }
   else
   {
-    LIB_CEC->AddLog(CEC_LOG_NOTICE, "<< %s (%X) -> broadcast (F): Menu language '%s'", GetLogicalAddressName(), m_iLogicalAddress, lang);
+    LIB_CEC->AddLog(CEC_LOG_DEBUG, "<< %s (%X) -> broadcast (F): menu language '%s'", GetLogicalAddressName(), m_iLogicalAddress, lang);
     bReturn = m_handler->TransmitSetMenuLanguage(m_iLogicalAddress, lang, bIsReply);
   }
   MarkReady();
@@ -420,7 +420,7 @@ bool CCECBusDevice::TransmitOSDString(const cec_logical_address destination, cec
   bool bReturn(false);
   if (!m_processor->GetDevice(destination)->IsUnsupportedFeature(CEC_OPCODE_SET_OSD_STRING))
   {
-    LIB_CEC->AddLog(CEC_LOG_NOTICE, "<< %s (%X) -> %s (%X): display OSD message '%s'", GetLogicalAddressName(), m_iLogicalAddress, ToString(destination), destination, strMessage);
+    LIB_CEC->AddLog(CEC_LOG_DEBUG, "<< %s (%X) -> %s (%X): display OSD message '%s'", GetLogicalAddressName(), m_iLogicalAddress, ToString(destination), destination, strMessage);
     MarkBusy();
     bReturn = m_handler->TransmitOSDString(m_iLogicalAddress, destination, duration, strMessage, bIsReply);
     MarkReady();
@@ -473,7 +473,7 @@ bool CCECBusDevice::RequestOSDName(const cec_logical_address initiator, bool bWa
       !IsUnsupportedFeature(CEC_OPCODE_GIVE_OSD_NAME))
   {
     MarkBusy();
-    LIB_CEC->AddLog(CEC_LOG_NOTICE, "<< requesting OSD name of '%s' (%X)", GetLogicalAddressName(), m_iLogicalAddress);
+    LIB_CEC->AddLog(CEC_LOG_DEBUG, "<< requesting OSD name of '%s' (%X)", GetLogicalAddressName(), m_iLogicalAddress);
     bReturn = m_handler->TransmitRequestOSDName(initiator, m_iLogicalAddress, bWaitForResponse);
     MarkReady();
   }
@@ -485,7 +485,7 @@ bool CCECBusDevice::TransmitOSDName(const cec_logical_address destination, bool
   CStdString strDeviceName;
   {
     CLockObject lock(m_mutex);
-    LIB_CEC->AddLog(CEC_LOG_NOTICE, "<< %s (%X) -> %s (%X): OSD name '%s'", GetLogicalAddressName(), m_iLogicalAddress, ToString(destination), destination, m_strDeviceName.c_str());
+    LIB_CEC->AddLog(CEC_LOG_DEBUG, "<< %s (%X) -> %s (%X): OSD name '%s'", GetLogicalAddressName(), m_iLogicalAddress, ToString(destination), destination, m_strDeviceName.c_str());
     strDeviceName = m_strDeviceName;
   }
 
@@ -548,7 +548,7 @@ bool CCECBusDevice::RequestPhysicalAddress(const cec_logical_address initiator,
   if (!IsHandledByLibCEC())
   {
     MarkBusy();
-    LIB_CEC->AddLog(CEC_LOG_NOTICE, "<< requesting physical address of '%s' (%X)", GetLogicalAddressName(), m_iLogicalAddress);
+    LIB_CEC->AddLog(CEC_LOG_DEBUG, "<< requesting physical address of '%s' (%X)", GetLogicalAddressName(), m_iLogicalAddress);
     bReturn = m_handler->TransmitRequestPhysicalAddress(initiator, m_iLogicalAddress, bWaitForResponse);
     MarkReady();
   }
@@ -564,7 +564,7 @@ bool CCECBusDevice::TransmitPhysicalAddress(bool bIsReply)
     if (m_iPhysicalAddress == CEC_INVALID_PHYSICAL_ADDRESS)
       return false;
 
-    LIB_CEC->AddLog(CEC_LOG_NOTICE, "<< %s (%X) -> broadcast (F): physical adddress %4x", GetLogicalAddressName(), m_iLogicalAddress, m_iPhysicalAddress);
+    LIB_CEC->AddLog(CEC_LOG_DEBUG, "<< %s (%X) -> broadcast (F): physical adddress %4x", GetLogicalAddressName(), m_iLogicalAddress, m_iPhysicalAddress);
     iPhysicalAddress = m_iPhysicalAddress;
     type = m_type;
   }
@@ -623,7 +623,7 @@ bool CCECBusDevice::RequestPowerStatus(const cec_logical_address initiator, bool
       !IsUnsupportedFeature(CEC_OPCODE_GIVE_DEVICE_POWER_STATUS))
   {
     MarkBusy();
-    LIB_CEC->AddLog(CEC_LOG_NOTICE, "<< requesting power status of '%s' (%X)", GetLogicalAddressName(), m_iLogicalAddress);
+    LIB_CEC->AddLog(CEC_LOG_DEBUG, "<< requesting power status of '%s' (%X)", GetLogicalAddressName(), m_iLogicalAddress);
     bReturn = m_handler->TransmitRequestPowerStatus(initiator, m_iLogicalAddress, bWaitForResponse);
     MarkReady();
   }
@@ -635,7 +635,7 @@ bool CCECBusDevice::TransmitPowerState(const cec_logical_address destination, bo
   cec_power_status state;
   {
     CLockObject lock(m_mutex);
-    LIB_CEC->AddLog(CEC_LOG_NOTICE, "<< %s (%X) -> %s (%X): %s", GetLogicalAddressName(), m_iLogicalAddress, ToString(destination), destination, ToString(m_powerStatus));
+    LIB_CEC->AddLog(CEC_LOG_DEBUG, "<< %s (%X) -> %s (%X): %s", GetLogicalAddressName(), m_iLogicalAddress, ToString(destination), destination, ToString(m_powerStatus));
     state = m_powerStatus;
   }
 
@@ -696,7 +696,7 @@ bool CCECBusDevice::RequestVendorId(const cec_logical_address initiator, bool bW
   if (!IsHandledByLibCEC() && initiator != CECDEVICE_UNKNOWN)
   {
     MarkBusy();
-    LIB_CEC->AddLog(CEC_LOG_NOTICE, "<< requesting vendor ID of '%s' (%X)", GetLogicalAddressName(), m_iLogicalAddress);
+    LIB_CEC->AddLog(CEC_LOG_DEBUG, "<< requesting vendor ID of '%s' (%X)", GetLogicalAddressName(), m_iLogicalAddress);
     bReturn = m_handler->TransmitRequestVendorId(initiator, m_iLogicalAddress, bWaitForResponse);
     MarkReady();
 
@@ -720,14 +720,14 @@ bool CCECBusDevice::TransmitVendorID(const cec_logical_address destination, bool
   {
     if (bSendAbort)
     {
-      LIB_CEC->AddLog(CEC_LOG_NOTICE, "<< %s (%X) -> %s (%X): vendor id feature abort", GetLogicalAddressName(), m_iLogicalAddress, ToString(destination), destination);
+      LIB_CEC->AddLog(CEC_LOG_DEBUG, "<< %s (%X) -> %s (%X): vendor id feature abort", GetLogicalAddressName(), m_iLogicalAddress, ToString(destination), destination);
       m_processor->TransmitAbort(m_iLogicalAddress, destination, CEC_OPCODE_GIVE_DEVICE_VENDOR_ID);
       bReturn = true;
     }
   }
   else
   {
-    LIB_CEC->AddLog(CEC_LOG_NOTICE, "<< %s (%X) -> %s (%X): vendor id %s (%x)", GetLogicalAddressName(), m_iLogicalAddress, ToString(destination), destination, ToString((cec_vendor_id)iVendorId), iVendorId);
+    LIB_CEC->AddLog(CEC_LOG_DEBUG, "<< %s (%X) -> %s (%X): vendor id %s (%x)", GetLogicalAddressName(), m_iLogicalAddress, ToString(destination), destination, ToString((cec_vendor_id)iVendorId), iVendorId);
     bReturn = m_handler->TransmitVendorID(m_iLogicalAddress, iVendorId, bIsReply);
   }
   MarkReady();
@@ -736,6 +736,9 @@ bool CCECBusDevice::TransmitVendorID(const cec_logical_address destination, bool
 
 cec_bus_device_status CCECBusDevice::GetStatus(bool bForcePoll /* = false */, bool bSuppressPoll /* = false */)
 {
+  if (m_iLogicalAddress == CECDEVICE_BROADCAST)
+    return CEC_DEVICE_STATUS_NOT_PRESENT;
+
   cec_bus_device_status status(CEC_DEVICE_STATUS_UNKNOWN);
   bool bNeedsPoll(false);
 
@@ -830,7 +833,7 @@ bool CCECBusDevice::TransmitPoll(const cec_logical_address dest, bool bIsReply)
     return bReturn;
 
   MarkBusy();
-  LIB_CEC->AddLog(CEC_LOG_NOTICE, "<< %s (%X) -> %s (%X): POLL", GetLogicalAddressName(), m_iLogicalAddress, ToString(dest), dest);
+  LIB_CEC->AddLog(CEC_LOG_DEBUG, "<< %s (%X) -> %s (%X): POLL", GetLogicalAddressName(), m_iLogicalAddress, ToString(dest), dest);
   bReturn = m_handler->TransmitPoll(m_iLogicalAddress, destination, bIsReply);
   LIB_CEC->AddLog(CEC_LOG_DEBUG, bReturn ? ">> POLL sent" : ">> POLL not sent");
 
@@ -891,7 +894,7 @@ bool CCECBusDevice::TransmitMenuState(const cec_logical_address dest, bool bIsRe
   cec_menu_state menuState;
   {
     CLockObject lock(m_mutex);
-    LIB_CEC->AddLog(CEC_LOG_NOTICE, "<< %s (%X) -> %s (%X): menu state '%s'", GetLogicalAddressName(), m_iLogicalAddress, ToString(dest), dest, ToString(m_menuState));
+    LIB_CEC->AddLog(CEC_LOG_DEBUG, "<< %s (%X) -> %s (%X): menu state '%s'", GetLogicalAddressName(), m_iLogicalAddress, ToString(dest), dest, ToString(m_menuState));
     menuState = m_menuState;
   }
 
@@ -927,7 +930,7 @@ bool CCECBusDevice::RequestActiveSource(bool bWaitForResponse /* = true */)
   if (IsHandledByLibCEC())
   {
     MarkBusy();
-    LIB_CEC->AddLog(CEC_LOG_NOTICE, "<< requesting active source");
+    LIB_CEC->AddLog(CEC_LOG_DEBUG, "<< requesting active source");
 
     bReturn = m_handler->TransmitRequestActiveSource(m_iLogicalAddress, bWaitForResponse);
     MarkReady();
@@ -1107,20 +1110,17 @@ bool CCECBusDevice::PowerOn(const cec_logical_address initiator)
   GetVendorId(initiator); // ensure that we got the vendor id, because the implementations vary per vendor
 
   MarkBusy();
-  cec_power_status currentStatus = GetPowerStatus(initiator, false);
-  if (currentStatus != CEC_POWER_STATUS_IN_TRANSITION_STANDBY_TO_ON &&
-    currentStatus != CEC_POWER_STATUS_ON)
+  cec_power_status currentStatus;
+  if (m_iLogicalAddress == CECDEVICE_TV ||
+      ((currentStatus = GetPowerStatus(initiator, false)) != CEC_POWER_STATUS_IN_TRANSITION_STANDBY_TO_ON &&
+        currentStatus != CEC_POWER_STATUS_ON))
   {
     LIB_CEC->AddLog(CEC_LOG_NOTICE, "<< powering on '%s' (%X)", GetLogicalAddressName(), m_iLogicalAddress);
-    if (m_handler->PowerOn(initiator, m_iLogicalAddress))
-    {
-      SetPowerStatus(CEC_POWER_STATUS_IN_TRANSITION_STANDBY_TO_ON);
-      bReturn = true;
-    }
+    bReturn = m_handler->PowerOn(initiator, m_iLogicalAddress);
   }
   else
   {
-    LIB_CEC->AddLog(CEC_LOG_NOTICE, "'%s' (%X) is already '%s'", GetLogicalAddressName(), m_iLogicalAddress, ToString(currentStatus));
+    LIB_CEC->AddLog(CEC_LOG_DEBUG, "'%s' (%X) is already '%s'", GetLogicalAddressName(), m_iLogicalAddress, ToString(currentStatus));
   }
 
   MarkReady();
@@ -1131,7 +1131,7 @@ bool CCECBusDevice::Standby(const cec_logical_address initiator)
 {
   GetVendorId(initiator); // ensure that we got the vendor id, because the implementations vary per vendor
 
-  LIB_CEC->AddLog(CEC_LOG_DEBUG, "<< putting '%s' (%X) in standby mode", GetLogicalAddressName(), m_iLogicalAddress);
+  LIB_CEC->AddLog(CEC_LOG_NOTICE, "<< putting '%s' (%X) in standby mode", GetLogicalAddressName(), m_iLogicalAddress);
   MarkBusy();
   bool bReturn = m_handler->TransmitStandby(initiator, m_iLogicalAddress);
   MarkReady();
@@ -1291,7 +1291,7 @@ bool CCECBusDevice::TryLogicalAddress(cec_version libCECSpecVersion /* = CEC_VER
 
   if (!TransmitPoll(m_iLogicalAddress, false))
   {
-    LIB_CEC->AddLog(CEC_LOG_NOTICE, "using logical address '%s'", GetLogicalAddressName());
+    LIB_CEC->AddLog(CEC_LOG_DEBUG, "using logical address '%s'", GetLogicalAddressName());
     SetDeviceStatus(CEC_DEVICE_STATUS_HANDLED_BY_LIBCEC, libCECSpecVersion);
 
     return true;
index ac5371efd72046965bd05094b6e5583b6876a968..d5acfe9e8dba6edcb2615800e2febb3150c24ae7 100644 (file)
@@ -88,7 +88,7 @@ bool CCECPlaybackDevice::TransmitDeckStatus(cec_logical_address dest, bool bIsRe
   cec_deck_info state;
   {
     CLockObject lock(m_mutex);
-    m_processor->GetLib()->AddLog(CEC_LOG_NOTICE, "<< %s (%X) -> %s (%X): deck status '%s'", GetLogicalAddressName(), m_iLogicalAddress, ToString(dest), dest, ToString(m_deckStatus));
+    m_processor->GetLib()->AddLog(CEC_LOG_DEBUG, "<< %s (%X) -> %s (%X): deck status '%s'", GetLogicalAddressName(), m_iLogicalAddress, ToString(dest), dest, ToString(m_deckStatus));
     state = m_deckStatus;
   }
 
index f20f6af9c063d2b4dd66e4909aa49ceade9e3bf6..269cbde0d183fbdef4411fa4cc1f975c05869337 100644 (file)
@@ -673,9 +673,6 @@ int CCECCommandHandler::HandleUserControlPressed(const cec_command &command)
 
   CCECClient *client = device->GetClient();
   if (client)
-    client->AddKey();
-
-  if (command.parameters[0] <= CEC_USER_CONTROL_CODE_MAX)
     client->SetCurrentButton((cec_user_control_code) command.parameters[0]);
 
   if (command.parameters[0] == CEC_USER_CONTROL_CODE_POWER ||
@@ -1124,9 +1121,7 @@ bool CCECCommandHandler::ActivateSource(bool bTransmitDelayedCommandsOnly /* = f
     VendorPreActivateSourceHook();
 
     // power on the TV
-    bool bActiveSourceFailed(false);
-    if (m_processor->GetDevice(CECDEVICE_TV)->GetPowerStatus(m_busDevice->GetLogicalAddress()) != CEC_POWER_STATUS_ON)
-      bActiveSourceFailed = !m_busDevice->TransmitImageViewOn();
+    bool bActiveSourceFailed = !m_busDevice->TransmitImageViewOn();
 
     // check if we're allowed to switch sources
     bool bSourceSwitchAllowed = SourceSwitchAllowed();
index 072d71182ec2c92ca7c780ab68b41ecb0330c249..227d8a0aa3b67e25ebe4ec8f71a4f51c85a22d1a 100644 (file)
@@ -61,7 +61,8 @@ CVLCommandHandler::CVLCommandHandler(CCECBusDevice *busDevice,
                                      int64_t iActiveSourcePending /* = 0 */) :
     CCECCommandHandler(busDevice, iTransmitTimeout, iTransmitWait, iTransmitRetries, iActiveSourcePending),
     m_iPowerUpEventReceived(0),
-    m_bCapabilitiesSent(false)
+    m_bCapabilitiesSent(false),
+    m_bPowerStatusRequested(false)
 {
   m_vendorId = CEC_VENDOR_PANASONIC;
 }
@@ -90,6 +91,9 @@ bool CVLCommandHandler::InitHandler(void)
 
 int CVLCommandHandler::HandleDeviceVendorCommandWithId(const cec_command &command)
 {
+  if (!m_processor->IsHandledByLibCEC(command.destination))
+    return CEC_ABORT_REASON_INVALID_OPERAND;
+
   if (command.parameters[0] != 0x00 ||
       command.parameters[1] != 0x80 ||
       command.parameters[2] != 0x45)
@@ -233,7 +237,8 @@ int CVLCommandHandler::HandleVendorCommand(const cec_command &command)
   if (command.parameters.size == 3 &&
       command.parameters[0] == 0x10 &&
       command.parameters[1] == 0x01 &&
-      command.parameters[2] == 0x05)
+      command.parameters[2] == 0x05 &&
+      m_processor->IsHandledByLibCEC(command.destination))
   {
     SendVendorCommandCapabilities(m_processor->GetLogicalAddress(), command.initiator);
     return COMMAND_HANDLED;
@@ -242,8 +247,17 @@ int CVLCommandHandler::HandleVendorCommand(const cec_command &command)
   return CEC_ABORT_REASON_INVALID_OPERAND;
 }
 
+bool CVLCommandHandler::TransmitRequestPowerStatus(const cec_logical_address iInitiator, const cec_logical_address iDestination, bool bWaitForResponse /* = true */)
+{
+  m_bPowerStatusRequested = true;
+  return CCECCommandHandler::TransmitRequestPowerStatus(iInitiator, iDestination, bWaitForResponse);
+}
+
 bool CVLCommandHandler::SourceSwitchAllowed(void)
 {
+  if (!PowerUpEventReceived() && !m_bPowerStatusRequested)
+    TransmitRequestPowerStatus(m_processor->GetPrimaryDevice()->GetLogicalAddress(), CECDEVICE_TV, false);
+
   return PowerUpEventReceived();
 }
 
index 3ad80b49150b53749bc61d0f306f972631a5a00c..ae6b9f60d63a291b3d34c5449ed87ffd91e10c67 100644 (file)
@@ -55,6 +55,7 @@ namespace CEC
     bool PowerUpEventReceived(void);
     bool SupportsDeviceType(const cec_device_type type) const { return type != CEC_DEVICE_TYPE_RECORDING_DEVICE; };
     cec_device_type GetReplacementDeviceType(const cec_device_type type) const { return type == CEC_DEVICE_TYPE_RECORDING_DEVICE ? CEC_DEVICE_TYPE_PLAYBACK_DEVICE : type; }
+    bool TransmitRequestPowerStatus(const cec_logical_address iInitiator, const cec_logical_address iDestination, bool bWaitForResponse = true);
 
     bool SourceSwitchAllowed(void);
 
@@ -66,5 +67,6 @@ namespace CEC
     PLATFORM::CMutex m_mutex;
     uint64_t         m_iPowerUpEventReceived;
     bool             m_bCapabilitiesSent;
+    bool             m_bPowerStatusRequested;
   };
 };
index 9d98d9ad9285f3646046597b9ef1a71bc35f08d9..739c6a71823d76ee002f306fb11888325775010e 100644 (file)
@@ -87,7 +87,7 @@ namespace PLATFORM
     {
       FD_ZERO(&port);
       FD_SET(socket, &port);
-      int returnv = select(socket + 1, NULL, &port, NULL, tv);
+      ssize_t returnv = (ssize_t)select(socket + 1, NULL, &port, NULL, tv);
       if (returnv < 0)
       {
         *iError = errno;
@@ -146,7 +146,7 @@ namespace PLATFORM
 
       FD_ZERO(&port);
       FD_SET(socket, &port);
-      int32_t returnv = select(socket + 1, &port, NULL, NULL, tv);
+      ssize_t returnv = (ssize_t)select(socket + 1, &port, NULL, NULL, tv);
 
       if (returnv == -1)
       {
@@ -243,7 +243,7 @@ namespace PLATFORM
     {
       if (iTimeoutMs > 0)
       {
-        int iPollResult = poll(&fds, 1, iTarget - iNow);
+        int iPollResult = poll(&fds, 1, (int)(iTarget - iNow));
         if (iPollResult == 0)
         {
           *iError = ETIMEDOUT;
@@ -320,7 +320,7 @@ namespace PLATFORM
         pfd.events = POLLOUT;
         pfd.revents = 0;
 
-        int iPollResult = poll(&pfd, 1, iTimeout);
+        int iPollResult = poll(&pfd, 1, (int)iTimeout);
         if (iPollResult == 0)
           *iError = ETIMEDOUT;
         else if (iPollResult == -1)
index c1b3b22461bbc002b0dfc788573fc8ede862002d..0089521caa370ae6a929f0a0f92459435da28416 100644 (file)
@@ -60,6 +60,7 @@ inline bool RemoveLock(const char *strDeviceName)
   return dev_unlock(strDeviceName, 0) == 0;
   #else
   void *tmp = (void*)strDeviceName; // silence unused warning
+  tmp = NULL;
   return true;
   #endif
 }
@@ -95,7 +96,7 @@ ssize_t CSerialSocket::Read(void* data, size_t len, uint64_t iTimeoutMs /* = 0 *
 //setting all this stuff up is a pain in the ass
 bool CSerialSocket::Open(uint64_t iTimeoutMs /* = 0 */)
 {
-  iTimeoutMs = 0;
+  iTimeoutMs = 0; if (!iTimeoutMs){} // silence unused warning
   if (IsOpen())
   {
     m_iError = EINVAL;
index 00953db0e0cdada4aee48de1cdf4f191a04806bb..286cc3274dd6240e73acba22886188a64553063d 100644 (file)
@@ -86,9 +86,12 @@ namespace PLATFORM
 
     inline bool Lock(void)
     {
-      MutexLock(m_mutex);
-      ++m_iLockCount;
-      return true;
+      if (MutexLock(m_mutex))
+      {
+        ++m_iLockCount;
+        return true;
+      }
+      return false;
     }
 
     inline void Unlock(void)
index 36477708d4750e6c2e035ca739d067f06cdff26a..d99cbf6bee34345aa9a54256a881676124094c29 100644 (file)
@@ -49,7 +49,7 @@ namespace PLATFORM
       StopThread(0);
       void *retVal = NULL;
       if (m_thread != INVALID_THREAD_VALUE)
-        ThreadsWait(m_thread, &retVal);
+        if (ThreadsWait(m_thread, &retVal)){}; // silence unused warning
     }
 
     static void *ThreadHandler(CThread *thread)
index 63b3bf12e4899aede8b612eb943413428bd00ad8..00f53bf1ac3a9ab0f890f158ccdae80b6969b615 100644 (file)
@@ -1,5 +1,4 @@
 #pragma once
-#include "lib/platform/os.h"
 #include <string>
 #include <stdint.h>
 #include <vector>
 #if !defined (SS_ANSI) && defined(_MSC_VER)
   #undef SS_IS_INTRESOURCE
   #if defined(_WIN64)
-    #define SS_IS_INTRESOURCE(_r) (((unsigned __int64)(_r) >> 16) == 0)
+    #define SS_IS_INTRESOURCE(_r) (((uint64_t)(_r) >> 16) == 0)
   #else
     #define SS_IS_INTRESOURCE(_r) (((unsigned long)(_r) >> 16) == 0)
   #endif
@@ -865,7 +864,11 @@ inline const Type& SSMAX(const Type& arg1, const Type& arg2)
       PWSTR pNextDstW      = pDstW;
       SSCodeCvt::result res  = SSCodeCvt::ok;
       const SSCodeCvt& conv  = SS_USE_FACET(loc, SSCodeCvt);
+#if defined(TARGET_DARWIN) || defined(__FreeBSD__) || defined(TARGET_ANDROID)
+      SSCodeCvt::state_type st= { { 0 } };
+#else
       SSCodeCvt::state_type st= { 0 };
+#endif
       res            = conv.in(st,
                     pSrcA, pSrcA + nSrc, pNextSrcA,
                     pDstW, pDstW + nDst, pNextDstW);
@@ -908,7 +911,11 @@ inline const Type& SSMAX(const Type& arg1, const Type& arg2)
       PCWSTR pNextSrcW    = pSrcW;
       SSCodeCvt::result res  = SSCodeCvt::ok;
       const SSCodeCvt& conv  = SS_USE_FACET(loc, SSCodeCvt);
+#if defined(TARGET_DARWIN) || defined(__FreeBSD__) || defined(TARGET_ANDROID)
+      SSCodeCvt::state_type st= { { 0 } };
+#else
       SSCodeCvt::state_type st= { 0 };
+#endif
       res            = conv.out(st,
                     pSrcW, pSrcW + nSrc, pNextSrcW,
                     pDstA, pDstA + nDst, pNextDstA);
index 4b57a29c7d340e180f04f29222eaae9d140f7802..30fcac84167d6ec483b7d37e6d43fe535d1cd4f5 100644 (file)
@@ -54,6 +54,7 @@ namespace PLATFORM
         CLockObject lock(m_mutex);
         while (!m_buffer.empty())
           m_buffer.pop();
+        m_bHasMessages = true;
         m_condition.Broadcast();
       }
 
@@ -94,11 +95,11 @@ namespace PLATFORM
         }
 
         // pop the first item
+        m_bHasMessages = !m_buffer.empty();
         if (!m_buffer.empty())
         {
           entry = m_buffer.front();
           m_buffer.pop();
-          m_bHasMessages = !m_buffer.empty();
           bReturn = true;
         }
         return bReturn;
index 091e962faf39bfb46303d3b81acc61ecc6b60c99..f696ff798717bc304a91ebf9cdd17ed6f52db98e 100644 (file)
@@ -43,7 +43,7 @@ namespace PLATFORM
   typedef CRITICAL_SECTION* mutex_t;
   #define MutexCreate(mutex)                       ::InitializeCriticalSection(mutex = new CRITICAL_SECTION)
   #define MutexDelete(mutex)                       ::DeleteCriticalSection(mutex); delete mutex
-  #define MutexLock(mutex)                         ::EnterCriticalSection(mutex)
+  inline bool MutexLock(mutex_t mutex)             {::EnterCriticalSection(mutex); return true; }
   #define MutexTryLock(mutex)                      (::TryEnterCriticalSection(mutex) != 0)
   #define MutexUnlock(mutex)                       ::LeaveCriticalSection(mutex)
 
index 2fc62690c407732b92bb263a34ac93c267595a6d..d47eb056d65a06df9684b8ce68f3cd078945fbdd 100644 (file)
@@ -65,6 +65,7 @@ typedef _W64 int   ssize_t;
 #endif
 
 #define snprintf _snprintf
+#define strdup _strdup
 
 #if defined(_MSC_VER)
 #pragma warning (push)
index 84133a931c5b7ceca64591ecdfe85ed646123bd0..d170bfa44a791be7606384ef6f2bc8cbfb7d5c8b 100644 (file)
@@ -39,6 +39,7 @@
 #include <fstream>
 #include <string>
 #include <sstream>
+#include <signal.h>
 #include "../lib/platform/os.h"
 #include "../lib/implementations/CECCommandHandler.h"
 #include "../lib/platform/util/StdString.h"
@@ -47,7 +48,7 @@ using namespace CEC;
 using namespace std;
 using namespace PLATFORM;
 
-#define CEC_CONFIG_VERSION CEC_CLIENT_VERSION_1_9_0;
+#define CEC_CONFIG_VERSION CEC_CLIENT_VERSION_2_0_0;
 
 #include "../../include/cecloader.h"
 
@@ -128,7 +129,7 @@ bool GetWord(string& data, string& word)
   return true;
 }
 
-int CecLogMessage(void *UNUSED(cbParam), const cec_log_message &message)
+int CecLogMessage(void *UNUSED(cbParam), const cec_log_message message)
 {
   if ((message.level & g_cecLogLevel) == message.level)
   {
@@ -170,17 +171,17 @@ int CecLogMessage(void *UNUSED(cbParam), const cec_log_message &message)
   return 0;
 }
 
-int CecKeyPress(void *UNUSED(cbParam), const cec_keypress &UNUSED(key))
+int CecKeyPress(void *UNUSED(cbParam), const cec_keypress UNUSED(key))
 {
   return 0;
 }
 
-int CecCommand(void *UNUSED(cbParam), const cec_command &UNUSED(command))
+int CecCommand(void *UNUSED(cbParam), const cec_command UNUSED(command))
 {
   return 0;
 }
 
-int CecAlert(void *UNUSED(cbParam), const libcec_alert type, const libcec_parameter &UNUSED(param))
+int CecAlert(void *UNUSED(cbParam), const libcec_alert type, const libcec_parameter UNUSED(param))
 {
   switch (type)
   {
@@ -654,7 +655,7 @@ bool ProcessCommandVEN(ICECAdapter *parser, const string &command, string &argum
       if (iDev >= 0 && iDev < 15)
       {
         uint64_t iVendor = parser->GetDeviceVendorId((cec_logical_address) iDev);
-        PrintToStdOut("vendor id: %06x", iVendor);
+        PrintToStdOut("vendor id: %06llx", iVendor);
         return true;
       }
     }
@@ -856,7 +857,7 @@ bool ProcessCommandSCAN(ICECAdapter *parser, const string &command, string & UNU
         cec_power_status power    = parser->GetDevicePowerStatus((cec_logical_address)iPtr);
         cec_osd_name osdName      = parser->GetDeviceOSDName((cec_logical_address)iPtr);
         CStdString strAddr;
-        strAddr.Format("%04x", iPhysicalAddress);
+        strAddr.Format("%x.%x.%x.%x", (iPhysicalAddress >> 12) & 0xF, (iPhysicalAddress >> 8) & 0xF, (iPhysicalAddress >> 4) & 0xF, iPhysicalAddress & 0xF);
         cec_menu_language lang;
         lang.device = CECDEVICE_UNKNOWN;
         parser->GetDeviceMenuLanguage((cec_logical_address)iPtr, &lang);
@@ -987,25 +988,25 @@ bool ProcessCommandLineArguments(int argc, char *argv[])
           {
             if (!g_bSingleCommand)
               cout << "== using device type 'playback device'" << endl;
-            g_config.deviceTypes.add(CEC_DEVICE_TYPE_PLAYBACK_DEVICE);
+            g_config.deviceTypes.Add(CEC_DEVICE_TYPE_PLAYBACK_DEVICE);
           }
           else if (!strcmp(argv[iArgPtr + 1], "r"))
           {
             if (!g_bSingleCommand)
               cout << "== using device type 'recording device'" << endl;
-            g_config.deviceTypes.add(CEC_DEVICE_TYPE_RECORDING_DEVICE);
+            g_config.deviceTypes.Add(CEC_DEVICE_TYPE_RECORDING_DEVICE);
           }
           else if (!strcmp(argv[iArgPtr + 1], "t"))
           {
             if (!g_bSingleCommand)
               cout << "== using device type 'tuner'" << endl;
-            g_config.deviceTypes.add(CEC_DEVICE_TYPE_TUNER);
+            g_config.deviceTypes.Add(CEC_DEVICE_TYPE_TUNER);
           }
           else if (!strcmp(argv[iArgPtr + 1], "a"))
           {
             if (!g_bSingleCommand)
               cout << "== using device type 'audio system'" << endl;
-            g_config.deviceTypes.add(CEC_DEVICE_TYPE_AUDIO_SYSTEM);
+            g_config.deviceTypes.Add(CEC_DEVICE_TYPE_AUDIO_SYSTEM);
           }
           else
           {
@@ -1129,8 +1130,20 @@ bool ProcessCommandLineArguments(int argc, char *argv[])
   return bReturn;
 }
 
+void sighandler(int iSignal)
+{
+  PrintToStdOut("signal caught: %d - exiting", iSignal);
+  g_bExit = true;
+}
+
 int main (int argc, char *argv[])
 {
+  if (signal(SIGINT, sighandler) == SIG_ERR)
+  {
+    PrintToStdOut("can't register sighandler");
+    return -1;
+  }
+
   g_config.Clear();
   g_callbacks.Clear();
   snprintf(g_config.strDeviceName, 13, "CECTester");
@@ -1152,7 +1165,7 @@ int main (int argc, char *argv[])
   {
     if (!g_bSingleCommand)
       cout << "No device type given. Using 'recording device'" << endl;
-    g_config.deviceTypes.add(CEC_DEVICE_TYPE_RECORDING_DEVICE);
+    g_config.deviceTypes.Add(CEC_DEVICE_TYPE_RECORDING_DEVICE);
   }
 
   ICECAdapter *parser = LibCecInitialise(&g_config);
index b4d1ca7100cfb744cd86b69b2483511e0386b0f2..90012c24033cc93a91bc9b1f9e6b39b91f4ccac6 100644 (file)
@@ -71,11 +71,11 @@ echo. Cleaning LibCecSharp (x64)
 echo. Compiling LibCecSharp (x64)
 %COMPILER9% LibCecSharp.sln /build "Release|x64" /project LibCecSharp
 %COMPILER9% LibCecSharp.sln /build "Release|x64" /project CecSharpTester
-%COMPILER9% LibCecSharp.sln /build "Release|x64" /project cec-config-gui
+%COMPILER9% LibCecSharp.sln /build "Release|x64" /project LibCecTray
 
 copy ..\build\LibCecSharp.dll ..\build\x64\LibCecSharp.dll
 copy ..\build\CecSharpTester.exe ..\build\x64\CecSharpTester.exe
-copy ..\build\cec-config-gui.exe ..\build\x64\cec-config-gui.exe
+copy ..\build\cec-tray.exe ..\build\x64\cec-tray.exe
 
 :libcecsharpx86
 rem Compile LibCecSharp (x86)
@@ -84,15 +84,15 @@ echo. Cleaning LibCecSharp (x86)
 echo. Compiling LibCecSharp (x86)
 %COMPILER9% LibCecSharp.sln /build "Release|x86" /project LibCecSharp
 %COMPILER9% LibCecSharp.sln /build "Release|x86" /project CecSharpTester
-%COMPILER9% LibCecSharp.sln /build "Release|x86" /project cec-config-gui
+%COMPILER9% LibCecSharp.sln /build "Release|x86" /project LibCecTray
 
 :NOSDK9
 rem Clean things up before creating the installer
 del /q /f ..\build\LibCecSharp.pdb
 del /q /f ..\build\CecSharpTester.pdb
-del /q /f ..\build\cec-config-gui.pdb
-del /q /f ..\build\cec-config-gui.vshost.exe.manifest
-del /q /f ..\build\cec-config-gui.vshost.exe
+del /q /f ..\build\cec-tray.pdb
+del /q /f ..\build\cec-tray.vshost.exe.manifest
+del /q /f ..\build\cec-.vshost.exe
 copy ..\build\cec-client.x64.exe ..\build\x64\cec-client.x64.exe
 del /q /f ..\build\cec-client.x64.exe
 copy ..\build\libcec.x64.dll ..\build\x64\libcec.x64.dll
@@ -108,12 +108,12 @@ CALL ..\support\private\sign-binary.cmd ..\build\cec-client.exe
 CALL ..\support\private\sign-binary.cmd ..\build\CecSharpTester.exe
 CALL ..\support\private\sign-binary.cmd ..\build\libcec.dll
 CALL ..\support\private\sign-binary.cmd ..\build\LibCecSharp.dll
-CALL ..\support\private\sign-binary.cmd ..\build\cec-config-gui.exe
+CALL ..\support\private\sign-binary.cmd ..\build\cec-tray.exe
 CALL ..\support\private\sign-binary.cmd ..\build\x64\cec-client.x64.exe
 CALL ..\support\private\sign-binary.cmd ..\build\x64\CecSharpTester.exe
 CALL ..\support\private\sign-binary.cmd ..\build\x64\libcec.x64.dll
 CALL ..\support\private\sign-binary.cmd ..\build\x64\LibCecSharp.dll
-CALL ..\support\private\sign-binary.cmd ..\build\x64\cec-config-gui.exe
+CALL ..\support\private\sign-binary.cmd ..\build\x64\cec-tray.exe
 
 :CREATEINSTALLER
 echo. Creating the installer
@@ -155,10 +155,11 @@ echo. The installer could not be created. The most likely cause is that somethin
 :EXIT
 del /q /f ..\build\cec-client.exe
 del /q /f ..\build\CecSharpTester.exe
-del /q /f ..\build\cec-config-gui.exe
+del /q /f ..\build\cec-tray.exe
 del /q /f ..\build\*.dll
 del /q /f ..\build\*.lib
 del /q /f ..\build\*.exp
+del /q /f ..\build\*.xml
 del /s /f /q ..\build\x64
 rmdir ..\build\x64
 cd ..\support