Qt5 user interface.

Qmake setup for daemon and UI, no longer uses old makefile.
Minor USB fixes.
This commit is contained in:
ccMSC
2014-11-17 05:02:11 -07:00
parent ce3130ffea
commit 50ab9f05cb
23 changed files with 1621 additions and 388 deletions
+5
View File
@@ -1,3 +1,8 @@
.DS_Store
._*
bin/
tmp-*/
*.pro.*
Makefile
moc_*
ui_*
+141
View File
@@ -0,0 +1,141 @@
The daemon provides devices at `/dev/input/ckb*`, where * is the device number, starting at 1. Up to 9 keyboards may be connected at once (note: not tested...) and controlled independently. Hot-plugging is supported; if you unplug a keyboard while the daemon is running and then plug it back in, the keyboard's previous settings will be restored. If a keyboard is plugged in which has not yet been assigned any settings, its saved settings will be loaded from the hardware. The daemon additionally provides `/dev/input/ckb0`, which can be used to control keyboards when they are not plugged in. Settings are only remembered as long as the daemon is running; if you restart the daemon, all settings will be forgotten.
After running the daemon, it will log some status messages to the terminal and you should now be able to access `/dev/input/ckb*`. The easiest way to see it in action is to open a new terminal in the same directory and run `bin/ckb [animation] [foreground] [background]` (or `bin/ckb` by itself to see a list of animations). `ckb` accepts colors in hexadecimal format (`RRGGBB`) or recognizes the names `white`, `black`, `red`, `yellow`, `green`, `cyan`, `blue`, and `magenta`.
`/dev/input/ckb0` contains the following files:
- `connected`: A list of all connected keyboards, one per line. Each line contains a device path followed by the device's serial number and its description.
- `cmd`: Keyboard controller. More information below.
- `notify0`: Keyboard notifications. See Notification section.
Other `ckb*` devices contain the following:
- `model`: Device description/model.
- `serial`: Device serial number. `model` and `serial` will match the info found in `ckb0/connected`
- `cmd`: Keyboard controller.
- `notify0`: Keyboard notifications.
Commands
--------
The `/dev/input/ckb*/cmd` nodes accept input in the form of text commands. They may be written by any user. Commands should be given in the following format:
`[device <serial>] [mode <n>] command1 [paramter1] [command2] [parameter2] [command3] [parameter3] ...`
In a terminal shell, you can do this with e.g. `echo foo > /dev/input/ckb1/cmd`. Programmatically, you can open and write them as regular files. When programming, you must append a newline character and flush the output before your command(s) will actually be read.
The `device` command, followed by the keyboard's serial number, specifies which keyboard to control. It is only required when issuing commands to `ckb0` or when controlling a keyboard that is not plugged in. In all other cases, the device is inferred from the control path. Additionally, the following commands may be issued to `ckb0` without any device: `layout`, `fps`, `notifyon`, and `notifyoff`. See below for documentation.
Keyboard layout
---------------
ckb currently supports both US and UK keyboard layouts. By default, the keyboard layout will be detected from the system locale. You can override this by specifying `--layout=<country>` at the command-line. For instance, `ckb-daemon --layout=uk` makes the UK layout default regardless of locale. You can also change it after starting the daemon by issuing `layout <country>` to `/dev/input/ckb0/cmd` (without including any device ID). It can be overwritten on a per-keyboard basis by issuing the `layout` command to `ckb*/cmd`. Sending the command to `ckb0` does not change the layout of any already-connected keyboards, it only changes the default.
Note that changing a keyboard's layout will reset all bindings and remove all macros associated with the keyboard. This is because not all keys are supported by all layouts (for instance, the UK has a separate hash key which is not present on the US layout). You can re-add the bindings manually after resetting the layout.
Profiles and modes
------------------
Keyboard settings are grouped into modes, where each mode has its own independent binding and lighting setup. By default, all commands will update the currently selected mode. The `mode <n>` command may be used to change the settings for a different mode. Up to 64 modes are available. Each keyboard has one profile, which may be given a name. Modes 1 through 3 may be saved to the device hardware (only mode 1 for K70s). Only the RGB settings can be saved, not the bindings or any other info. Commands are as follows:
- `profilename <name>` sets the profile's name. The name must be written without spaces; to add a space, use `%20`.
- `name <name>` sets the current mode's name. Use `mode <n> name <name>` to set a different mode's name.
- `mode <n> switch` switches the keyboard to mode N.
- `hwload` loads the RGB profile from the hardware. The profile's bindings are not affected.
- `hwsave` saves the RGB profile to the hardware.
- `erase` erases the current mode, resetting its lighting and bindings. Use `mode <n> erase` to erase a different mode.
- `eraseprofile` resets the entire profile, erasing its name and all of its modes.
LED commands
------------
The backlighting is controlled by the `rgb` commands. Any of the following combinations may be used:
- `rgb off` turns lighting off. No further color changes will take effect until you issue `rgb on`.
- `rgb on` turns lighting on.
- `rgb <RRGGBB>` sets the entire keyboard to the color specified by the hex constant RRGGBB.
- `rgb <key>:<RRGGBB>` sets the specified key to the specified hex color. See `src/ckb-daemon/keyboard_*.c` for a list of key names in each layout.
**Examples:**
- `rgb ffffff` makes the whole keyboard white.
- `rgb 000000` makes the whole keyboard black. This is NOT equivalent to `rgb off` as the keys are still considered "on" but are simply not lit.
- `rgb esc:ff0000` sets the Esc key red but leaves the rest of the keyboard unchanged.
Multiple keys may be changed to one color when separated with commas, for instance:
- `rgb w,a,s,d:0000ff` sets the WASD keys to blue.
Additionally, multiple commands may be combined into one, for instance:
- `rgb ffffff esc:ff0000 w,a,s,d:0000ff` sets the Esc key red, the WASD keys blue, and the rest of the keyboard white (note the lack of a key name before `ffffff`, implying the whole keyboard is to be set).
By default, the controller runs at 60FPS, meaning that attempts to animate the LEDs faster than that will be ignored. The keyboard's internal LED controller runs at 60Hz, so this should be a sensible maximum. If you wish to set it lower, you can start `ckb-daemon` with the `--fps=<rate>` option. You can also issue `fps <rate>` to `/dev/input/ckb0/cmd` after starting the daemon. Note that the FPS is global and cannot be set on a per-keyboard basis.
Indicators
----------
The indicator LEDs (Num Lock, Caps Lock, Scroll Lock) are controlled with the `i` commands.
- `ioff <led>` turns an indicator off permanently. Valid LED names are `num`, `caps`, and `scroll`.
- `ion <led>` turns an indicator on permanently.
- `iauto <led>` turns an indicator off or on automatically (default behavior).
Binding keys
------------
Keys may be rebound through use of the `bind` commands. Binding is a 1-to-1 operation that translates one keypress to a different keypress, regardless of circumstance; simple, but inflexible.
- `bind <key1>:<key2>` remaps key1 to key2. Again, see `src/ckb-daemon/keyboard_*.c` for a list of key names.
- `unbind <key>` unbinds a key, causing it to lose all function.
- `rebind <key>` resets a key, returning it to its default binding.
**Examples:**
- `bind g1:esc` makes G1 become an alternate Esc key (the actual Esc key is not changed).
- `bind caps:tab tab:caps` switches the functions of the Tab and Caps Lock keys.
- `unbind lwin rwin` disables both Windows keys, even without using the keyboard's Windows Lock function.
- `rebind all` resets the whole keyboard to its default bindings.
Key macros
----------
Macros are a more advanced form of key binding, controlled with the `macro` command.
- `macro <keys>:<command>` binds a key combination to a command, where the command is a series of key presses. To combine keys, separate them with `+`; for instance, `lctrl+a` binds a macro to (left) Ctrl+A. In the command field, enter `+<key>` to trigger a key down or `-<key>` to trigger a key up. To simulate a key press, use `+<key>,-<key>`.
- `macro <keys>:clear` clears commands associated with a key combination. Only one macro may be assigned per combination; assigning a second one will overwrite the first.
- `macro clear` clears all macros.
**Examples:**
- `macro g1:+lctrl,+a,-a,-lctrl` triggers a Ctrl+A when G1 is pressed.
- `macro g2+g3:+lalt,+f4,-f4,-lalt` triggers an Alt+F4 when both G1 and G2 are pressed.
Assigning a macro to a key will cause its binding to be ignored; for instance, `macro a:+b,-b` will cause A to generate a B character regardless of its binding. However, `macro lctrl+a:+b,-b` will cause A to generate a B only when Ctrl is also held down. Macros currently do not have any repeating options and will be triggered only once, when the key is pressed down. This feature will be added soon.
Notifications
-------------
The keyboard can be configured to generate user-readable notifications on keypress events. These are controlled with the `notify` commands. In order to see events, read from `/dev/input/ckb*/notify0`. In a terminal, you can do this like `cat /dev/input/ckb1/notify0`. Programmatically, you can open it for reading like a regular file.
Note that the file can only reliably be read by one application: if you try to open it in two different programs, they may both fail to get data. Data will be buffered as long as no programs are reading, so you will receive all unread notifications as soon as you open the file. If you'd like to read notifications from two separate applications, send the command `notifyon <n>` to the keyboard you wish to receive notifications from, where N is a number between 1 and 9. If `/dev/input/ckb*/notify<n>` does not already exist, it will be created, and you can read notifications from there without disrupting any other program currently reading them. To close a notification node, send `notifyoff <n>`.
Notifications are printed in the format of one notification per line. If you are reading from `ckb0/notify*` you will see notifications for all keyboards, with `device <serial>` printed at the beginning of each line. Reading from `ckb1` or above will show you only notifications for that keyboard, with no serial number.
Notification commands are as follows:
- `notify <key>:on` or simply `notify <key>` enables notifications for a key. Each key will generate two notifications: `key +<key>` when the key is pressed, and `key -<key>` when it is released.
- `notify <key>:off` turns notifications off for a key.
**Examples:**
- `notify w a s d` sends notifications whenever W, A, S, or D is pressed.
- `notify g1 g2 g3 g4 g5 g6 g7 g8 g9 g10 g11 g12 g13 g14 g15 g16 g17 g18 mr m1 m2 m3 light lock` prints a notification whenever a non-standard key is pressed.
- `notify all:off` turns all key notifications off.
**Note:** Key notifications are _not_ affected by bindings. For instance, if you run `echo bind a:b notify a > /dev/input/ckb1/cmd` and then press the A key, the notifications will read `key +a` `key -a`, despite the fact that the character printed on screen will be `b`. Likewise, unbinding a key or assigning a macro to a key does not affect the notifications.
Additionally, the following notifications will be generated at `ckb0/notify*` regardless of circumstance:
- `device <serial> added at <path>` whenever a device is connected.
- `device <serial> removed from <path>` whenever a device is disconnected. These messages are only generated at `ckb0/notify*`, not at the node for the actual device.
- `fps <rate>` when the FPS is changed.
- `layout <country>` when the default layout is changed.
Getting parameters
------------------
Parameters can be retrieved using the `get` command. The data will be sent out as a notification. Generally, the syntax to get the data associated with a command is `get :<command>` (note the colon), and the associated data will be returned in the form of `<command> <data>`. The following data may be gotten:
- `get :hello` simply prints `hello` to the notification nodes. This may be useful to determine whether or not the daemon is responding. It can only be issued to `ckb0` with no `device` command; in any other circumstance, it will be ignored.
- `get :fps` gets the current frame rate. Returns `fps <rate>`. Like `:hello`, this will be ignored if it is issued to an actual keyboard.
- `get :layout` gets the current keyboard layout. Returns `layout <country>`. This may be issued to `ckb0` to get the default layout or to any keyboard to get the keyboard's layout.
- `get :mode` returns the current mode in the form of a `switch` command. (Note: Do not use this in a line containing a `mode` command or it will return the mode that you selected, rather than the keyboard's current mode).
- `get :rgb` returns an `rgb` command equivalent to the current RGB state of the current mode. To see the RGB settings for another mode, use `mode <n> get :rgb`. Keep in mind that the keyboard hardware has a very limited color precision, so a command like `rgb 123456 get :rgb` may not output `rgb 123456`. The only guarantee is that it will output the RGB color as seen by the keyboard.
- `get :hwrgb` does the same thing, but retrieves the colors currently stored in the hardware profile (**Note:** This may not be accurate after loading from the hardware. See Caveats section). The output is the same except that it says `hwrgb` instead of `rgb`.
Security
--------
By default, all of the `ckb*` nodes may be accessed by any user. For most single-user systems this should not present any security issues, since only one person will have access to the computer anyway. However, if you'd like to restrict the users that can write to the `cmd` nodes or read from the `notify` nodes, you can specify the `--gid=<group>` option at start up. For instance, on most systems you could run `ckb-daemon --gid=1000` make them accessible only by the system's primary user. `ckb-daemon` must still be run as root, regardless of which `gid` you specify. The `gid` option may only be set at startup and cannot be changed while the daemon is running.
-16
View File
@@ -1,16 +0,0 @@
DAEMON_SRC := src/ckb-daemon/main.c src/ckb-daemon/usb.c src/ckb-daemon/device.c src/ckb-daemon/input.c src/ckb-daemon/led.c src/ckb-daemon/keyboard.c src/ckb-daemon/keyboard_us.c src/ckb-daemon/keyboard_uk.c src/ckb-daemon/devnode.c src/ckb-daemon/notify.c
CKB_SRC := src/ckb/main.c
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Linux)
DAEMON_SRC += src/ckb-daemon/usb_linux.c src/ckb-daemon/input_linux.c -ludev -lpthread
endif
ifeq ($(UNAME_S),Darwin)
DAEMON_SRC += src/ckb-daemon/usb_mac.c src/ckb-daemon/input_mac.c src/ckb-daemon/extra_mac.m -framework IOKit -framework CoreFoundation -framework CoreGraphics -framework AppKit -liconv
endif
build:
rm -rf bin
mkdir bin
gcc $(DAEMON_SRC) -o bin/ckb-daemon -std=c99 -O2
gcc $(CKB_SRC) -o bin/ckb -lm -std=c99 -O2 -DKEYMAP_DEFAULT
+22 -144
View File
@@ -1,21 +1,25 @@
ckb: Corsair K70/K95 Driver for Linux and OSX
=============================================
ckb is divided into two parts: a daemon program which must be run as root and communicates with the USB device, and a utility program, which provides several animations and may be run as any user.
The daemon provides devices at `/dev/input/ckb*`, where * is the device number, starting at 1. Up to 9 keyboards may be connected at once (note: not tested...) and controlled independently. Hot-plugging is supported; if you unplug a keyboard while the daemon is running and then plug it back in, the keyboard's previous settings will be restored. If a keyboard is plugged in which has not yet been assigned any settings, its saved settings will be loaded from the hardware. The daemon additionally provides `/dev/input/ckb0`, which can be used to control keyboards when they are not plugged in. Settings are only remembered as long as the daemon is running; if you restart the daemon, all settings will be forgotten.
The user-runnable utility is currently very limited. It only supports one keyboard and has a limited selection of animations with little configuration. The plan is to replace it with a more robust Qt-based utility, creating something like Corsair's proprietary Windows controller.
ckb is a userspace (i.e. non-kernel) driver for Corsair RGB keyboards for Linux and OSX. It contains a daemon program, which runs in the background and must be started as root, as well as a user interface which may be run as any user.
Building for Linux
------------------
`libudev`, `gcc`, and `glibc` are required. Check with your package manager to make sure you have the correct libraries/headers installed (Note: on Ubuntu you need `libudev-dev`). You also need a kernel with uinput support (all distros should ship with this by default; don't worry about it unless you're running a custom kernel). You can build ckb by running `make` in the directory you downloaded it to. The binaries will be placed in `bin` assuming they compile successfully.
`qt5-base`, `libudev`, `gcc`, `g++`, and `glibc` are required. Check with your package manager to make sure you have the correct libraries/headers installed (Note: on Ubuntu you need `qt5-default` and `libudev-dev`). You also need a kernel with uinput support (all distros should ship with this by default; don't worry about it unless you're running a custom kernel).
You can build the project by running `qmake && make` in the directory you downloaded it to. The binaries will be placed in a new `bin` directory assuming they compile successfully. To start the daemon, run `sudo bin/ckb-daemon`. After that, open the `ckb` binary as a normal user to start the user interface.
Building for OSX
----------------
You can build ckb by running `make` from Terminal in the directory you downloaded it to. You should be prompted to install developer tools if you don't have them already (you can also get them by downloading Xcode from the App Store). The binaries will be placed in `bin` assuming they compile successfully.
Install Qt5 from here: http://www.qt.io/download-open-source/ (you'll also be propmted to install Xcode from the app store if you don't have it already)
Open ckb.pro in Qt Creator. You should be prompted to configure the project (the default settings should work fine). Right-click on "ckb [master]" on the left-hand pane and select "Run qmake" from the drop-down menu. Now press Cmd+B to build the project. The binaries should be placed in a newly-created `bin` directory assuming they compile successfully. Exit Qt Creator.
**Note:** The project is intended to compile on OSX Yosemite. If you're running an earlier version, find the `QMAKE_MAC_SDK` lines in `ckb.pro`, `src/ckb-daemon/ckb-daemon.pro`, and `src/ckb/ckb.pro`. Edit them from `macosx10.10` to your OSX version, e.g. `macosx10.9` for Mountain Lion.
ckb-daemon needs to be run as root. Open the `bin` directory in a Terminal window and run `sudo ./ckb-daemon`. Then open `ckb.app` as a normal application to start the user interface.
**Mac notes:**
- The keyboard devices are located at `/tmp/ckb*` and not `/dev/input/ckb*`. So wherever you see `/dev/input/ckb` in this document, replace it with `/tmp/ckb`.
@@ -24,149 +28,23 @@ You can build ckb by running `make` from Terminal in the directory you downloade
Usage
-----
After building, run `sudo bin/ckb-daemon` to start the daemon. It will log some status messages to the terminal and you should now be able to access `/dev/input/ckb*`. The easiest way to see it in action is to open a new terminal in the same directory and run `bin/ckb [animation] [foreground] [background]` (or `bin/ckb` by itself to see a list of animations). `ckb` accepts colors in hexadecimal format (`RRGGBB`) or recognizes the names `white`, `black`, `red`, `yellow`, `green`, `cyan`, `blue`, and `magenta`.
See `DAEMON.md` for info about the daemon program.
`/dev/input/ckb0` contains the following files:
- `connected`: A list of all connected keyboards, one per line. Each line contains a device path followed by the device's serial number and its description.
- `cmd`: Keyboard controller. More information below.
- `notify0`: Keyboard notifications. See Notification section.
The user interface is currently very limited and only supports a handful of options. They should be self-explanatory.
Other `ckb*` devices contain the following:
- `model`: Device description/model.
- `serial`: Device serial number. `model` and `serial` will match the info found in `ckb0/connected`
- `cmd`: Keyboard controller.
- `notify0`: Keyboard notifications.
**Coming soon:**
- More animations
- Reactive lighting for keypresses
- Key rebinding
- Key macros
- Loading and saving hardware profiles
Commands
--------
The `/dev/input/ckb*/cmd` nodes accept input in the form of text commands. They may be written by any user. Commands should be given in the following format:
`[device <serial>] [mode <n>] command1 [paramter1] [command2] [parameter2] [command3] [parameter3] ...`
In a terminal shell, you can do this with e.g. `echo foo > /dev/input/ckb1/cmd`. Programmatically, you can open and write them as regular files. When programming, you must append a newline character and flush the output before your command(s) will actually be read.
The `device` command, followed by the keyboard's serial number, specifies which keyboard to control. It is only required when issuing commands to `ckb0` or when controlling a keyboard that is not plugged in. In all other cases, the device is inferred from the control path. Additionally, the following commands may be issued to `ckb0` without any device: `layout`, `fps`, `notifyon`, and `notifyoff`. See below for documentation.
Keyboard layout
---------------
ckb currently supports both US and UK keyboard layouts. By default, the keyboard layout will be detected from the system locale. You can override this by specifying `--layout=<country>` at the command-line. For instance, `ckb-daemon --layout=uk` makes the UK layout default regardless of locale. You can also change it after starting the daemon by issuing `layout <country>` to `/dev/input/ckb0/cmd` (without including any device ID). It can be overwritten on a per-keyboard basis by issuing the `layout` command to `ckb*/cmd`. Sending the command to `ckb0` does not change the layout of any already-connected keyboards, it only changes the default.
Note that changing a keyboard's layout will reset all bindings and remove all macros associated with the keyboard. This is because not all keys are supported by all layouts (for instance, the UK has a separate hash key which is not present on the US layout). You can re-add the bindings manually after resetting the layout.
Profiles and modes
------------------
Keyboard settings are grouped into modes, where each mode has its own independent binding and lighting setup. By default, all commands will update the currently selected mode. The `mode <n>` command may be used to change the settings for a different mode. Up to 64 modes are available. Each keyboard has one profile, which may be given a name. Modes 1 through 3 may be saved to the device hardware (only mode 1 for K70s). Only the RGB settings can be saved, not the bindings or any other info. Commands are as follows:
- `profilename <name>` sets the profile's name. The name must be written without spaces; to add a space, use `%20`.
- `name <name>` sets the current mode's name. Use `mode <n> name <name>` to set a different mode's name.
- `mode <n> switch` switches the keyboard to mode N.
- `hwload` loads the RGB profile from the hardware. The profile's bindings are not affected.
- `hwsave` saves the RGB profile to the hardware.
- `erase` erases the current mode, resetting its lighting and bindings. Use `mode <n> erase` to erase a different mode.
- `eraseprofile` resets the entire profile, erasing its name and all of its modes.
LED commands
------------
The backlighting is controlled by the `rgb` commands. Any of the following combinations may be used:
- `rgb off` turns lighting off. No further color changes will take effect until you issue `rgb on`.
- `rgb on` turns lighting on.
- `rgb <RRGGBB>` sets the entire keyboard to the color specified by the hex constant RRGGBB.
- `rgb <key>:<RRGGBB>` sets the specified key to the specified hex color. See `src/ckb-daemon/keyboard_*.c` for a list of key names in each layout.
**Examples:**
- `rgb ffffff` makes the whole keyboard white.
- `rgb 000000` makes the whole keyboard black. This is NOT equivalent to `rgb off` as the keys are still considered "on" but are simply not lit.
- `rgb esc:ff0000` sets the Esc key red but leaves the rest of the keyboard unchanged.
Multiple keys may be changed to one color when separated with commas, for instance:
- `rgb w,a,s,d:0000ff` sets the WASD keys to blue.
Additionally, multiple commands may be combined into one, for instance:
- `rgb ffffff esc:ff0000 w,a,s,d:0000ff` sets the Esc key red, the WASD keys blue, and the rest of the keyboard white (note the lack of a key name before `ffffff`, implying the whole keyboard is to be set).
By default, the controller runs at 60FPS, meaning that attempts to animate the LEDs faster than that will be ignored. The keyboard's internal LED controller runs at 60Hz, so this should be a sensible maximum. If you wish to set it lower, you can start `ckb-daemon` with the `--fps=<rate>` option. You can also issue `fps <rate>` to `/dev/input/ckb0/cmd` after starting the daemon. Note that the FPS is global and cannot be set on a per-keyboard basis.
Indicators
----------
The indicator LEDs (Num Lock, Caps Lock, Scroll Lock) are controlled with the `i` commands.
- `ioff <led>` turns an indicator off permanently. Valid LED names are `num`, `caps`, and `scroll`.
- `ion <led>` turns an indicator on permanently.
- `iauto <led>` turns an indicator off or on automatically (default behavior).
Binding keys
------------
Keys may be rebound through use of the `bind` commands. Binding is a 1-to-1 operation that translates one keypress to a different keypress, regardless of circumstance; simple, but inflexible.
- `bind <key1>:<key2>` remaps key1 to key2. Again, see `src/ckb-daemon/keyboard_*.c` for a list of key names.
- `unbind <key>` unbinds a key, causing it to lose all function.
- `rebind <key>` resets a key, returning it to its default binding.
**Examples:**
- `bind g1:esc` makes G1 become an alternate Esc key (the actual Esc key is not changed).
- `bind caps:tab tab:caps` switches the functions of the Tab and Caps Lock keys.
- `unbind lwin rwin` disables both Windows keys, even without using the keyboard's Windows Lock function.
- `rebind all` resets the whole keyboard to its default bindings.
Key macros
----------
Macros are a more advanced form of key binding, controlled with the `macro` command.
- `macro <keys>:<command>` binds a key combination to a command, where the command is a series of key presses. To combine keys, separate them with `+`; for instance, `lctrl+a` binds a macro to (left) Ctrl+A. In the command field, enter `+<key>` to trigger a key down or `-<key>` to trigger a key up. To simulate a key press, use `+<key>,-<key>`.
- `macro <keys>:clear` clears commands associated with a key combination. Only one macro may be assigned per combination; assigning a second one will overwrite the first.
- `macro clear` clears all macros.
**Examples:**
- `macro g1:+lctrl,+a,-a,-lctrl` triggers a Ctrl+A when G1 is pressed.
- `macro g2+g3:+lalt,+f4,-f4,-lalt` triggers an Alt+F4 when both G1 and G2 are pressed.
Assigning a macro to a key will cause its binding to be ignored; for instance, `macro a:+b,-b` will cause A to generate a B character regardless of its binding. However, `macro lctrl+a:+b,-b` will cause A to generate a B only when Ctrl is also held down. Macros currently do not have any repeating options and will be triggered only once, when the key is pressed down. This feature will be added soon.
Notifications
-------------
The keyboard can be configured to generate user-readable notifications on keypress events. These are controlled with the `notify` commands. In order to see events, read from `/dev/input/ckb*/notify0`. In a terminal, you can do this like `cat /dev/input/ckb1/notify0`. Programmatically, you can open it for reading like a regular file.
Note that the file can only reliably be read by one application: if you try to open it in two different programs, they may both fail to get data. Data will be buffered as long as no programs are reading, so you will receive all unread notifications as soon as you open the file. If you'd like to read notifications from two separate applications, send the command `notifyon <n>` to the keyboard you wish to receive notifications from, where N is a number between 1 and 9. If `/dev/input/ckb*/notify<n>` does not already exist, it will be created, and you can read notifications from there without disrupting any other program currently reading them. To close a notification node, send `notifyoff <n>`.
Notifications are printed in the format of one notification per line. If you are reading from `ckb0/notify*` you will see notifications for all keyboards, with `device <serial>` printed at the beginning of each line. Reading from `ckb1` or above will show you only notifications for that keyboard, with no serial number.
Notification commands are as follows:
- `notify <key>:on` or simply `notify <key>` enables notifications for a key. Each key will generate two notifications: `key +<key>` when the key is pressed, and `key -<key>` when it is released.
- `notify <key>:off` turns notifications off for a key.
**Examples:**
- `notify w a s d` sends notifications whenever W, A, S, or D is pressed.
- `notify g1 g2 g3 g4 g5 g6 g7 g8 g9 g10 g11 g12 g13 g14 g15 g16 g17 g18 mr m1 m2 m3 light lock` prints a notification whenever a non-standard key is pressed.
- `notify all:off` turns all key notifications off.
**Note:** Key notifications are _not_ affected by bindings. For instance, if you run `echo bind a:b notify a > /dev/input/ckb1/cmd` and then press the A key, the notifications will read `key +a` `key -a`, despite the fact that the character printed on screen will be `b`. Likewise, unbinding a key or assigning a macro to a key does not affect the notifications.
Additionally, the following notifications will be generated at `ckb0/notify*` regardless of circumstance:
- `device <serial> added at <path>` whenever a device is connected.
- `device <serial> removed from <path>` whenever a device is disconnected. These messages are only generated at `ckb0/notify*`, not at the node for the actual device.
- `fps <rate>` when the FPS is changed.
- `layout <country>` when the default layout is changed.
Getting parameters
------------------
Parameters can be retrieved using the `get` command. The data will be sent out as a notification. Generally, the syntax to get the data associated with a command is `get :<command>` (note the colon), and the associated data will be returned in the form of `<command> <data>`. The following data may be gotten:
- `get :hello` simply prints `hello` to the notification nodes. This may be useful to determine whether or not the daemon is responding. It can only be issued to `ckb0` with no `device` command; in any other circumstance, it will be ignored.
- `get :fps` gets the current frame rate. Returns `fps <rate>`. Like `:hello`, this will be ignored if it is issued to an actual keyboard.
- `get :layout` gets the current keyboard layout. Returns `layout <country>`. This may be issued to `ckb0` to get the default layout or to any keyboard to get the keyboard's layout.
- `get :mode` returns the current mode in the form of a `switch` command. (Note: Do not use this in a line containing a `mode` command or it will return the mode that you selected, rather than the keyboard's current mode).
- `get :rgb` returns an `rgb` command equivalent to the current RGB state of the current mode. To see the RGB settings for another mode, use `mode <n> get :rgb`. Keep in mind that the keyboard hardware has a very limited color precision, so a command like `rgb 123456 get :rgb` may not output `rgb 123456`. The only guarantee is that it will output the RGB color as seen by the keyboard.
- `get :hwrgb` does the same thing, but retrieves the colors currently stored in the hardware profile (**Note:** This may not be accurate after loading from the hardware. See Caveats section). The output is the same except that it says `hwrgb` instead of `rgb`.
Security
--------
By default, all of the `ckb*` nodes may be accessed by any user. For most single-user systems this should not present any security issues, since only one person will have access to the computer anyway. However, if you'd like to restrict the users that can write to the `cmd` nodes or read from the `notify` nodes, you can specify the `--gid=<group>` option at start up. For instance, on most systems you could run `ckb-daemon --gid=1000` make them accessible only by the system's primary user. `ckb-daemon` must still be run as root, regardless of which `gid` you specify. The `gid` option may only be set at startup and cannot be changed while the daemon is running.
Closing ckb will actually minimize it to the system tray. Use the Exit option from the menu to quit the application.
Known issues
------------
- When loading settings from the hardware, all three modes end up with the same RGB configuration. This is a hardware bug and it affects CUE as well.
- The system tray icon doesn't always appear in Linux. Apparently this is a known Qt bug.
- (Daemon) When loading settings from the hardware, all three modes end up with the same RGB configuration. This is a hardware bug and it affects CUE as well.
- It's not possible for the daemon to determine which hardware mode was in use, so the keyboard always starts on mode 1. Again, this is a hardware issue (although thanks to the above problem, it doesn't really matter anyway).
- The Linux driver doesn't work 100% consistently and can be very slow to start up or shut down. This seems to be a driver/firmware conflict at an OS level, so it probably can't be fixed in ckb.
+7
View File
@@ -0,0 +1,7 @@
TEMPLATE = subdirs
SUBDIRS = ckb-daemon ckb
QMAKE_MAC_SDK = macosx10.10
ckb-daemon.file = src/ckb-daemon/ckb-daemon.pro
ckb.file = src/ckb/ckb.pro
+61
View File
@@ -0,0 +1,61 @@
#-------------------------------------------------
#
# Project created by QtCreator 2014-11-15T21:21:10
#
#-------------------------------------------------
QT += core
QT -= gui
TARGET = ckb-daemon
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
QMAKE_MAC_SDK = macosx10.10
QMAKE_CFLAGS += -std=c99
CONFIG += warn_off
macx {
LIBS += -framework IOKit -framework CoreFoundation -framework CoreGraphics -framework AppKit -liconv
} else {
LIBS += -lpthread -ludev
}
OBJECTS_DIR = $$PWD/../../tmp-ckb-daemon
DESTDIR = $$PWD/../../bin
SOURCES += \
device.c \
devnode.c \
input_linux.c \
input_mac.c \
input.c \
keyboard_uk.c \
keyboard_us.c \
keyboard.c \
led.c \
main.c \
notify.c \
usb_linux.c \
usb_mac.c \
usb.c
HEADERS += \
device.h \
devnode.h \
includes.h \
input.h \
keyboard_mac.h \
keyboard.h \
led.h \
notify.h \
os.h \
structures.h \
usb.h
OBJECTIVE_SOURCES += \
extra_mac.m
+1 -1
View File
@@ -100,7 +100,7 @@ void inputupdate(usbdevice* kb){
// Print a notification if desired
int notify = mode->notify[byte] & mask;
if(notify){
if(map->name && map->led >= 0){
if(map->name && map->led){
nprintf(kb, 0, 0, "key %c%s\n", new ? '+' : '-', map->name);
if(new && (map->scan == KEY_VOLUMEUP || map->scan == KEY_VOLUMEDOWN))
nprintf(kb, 0, 0, "%s up", map->name);
-2
View File
@@ -95,8 +95,6 @@ int loadrgb(usbdevice* kb, keylight* light, int mode){
return 0;
}
// Generates data for an RGB command to match the given RGB data. Returns a string like "ff0000" or "w:ff0000 a:00ff00 ..."
// The result must be freed later.
char* printrgb(keylight* light, const key* keymap){
int length = 0;
// Unpack LED data back to 8bpc format.
+2 -2
View File
@@ -147,10 +147,10 @@ int openusb(struct udev_device* dev, int model){
kb->model = model;
if(kb->handle <= 0){
printf("Error: Failed to open USB device: %s\n", strerror(errno));
closehandle(kb);
// Don't try again if it failed with ENOENT or EINVAL
if(errno != ENOENT && errno != EINVAL)
if(errno != ENOENT && errno != ENODEV && errno != EINVAL)
connectstatus |= 2;
closehandle(kb);
return -1;
}
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

+32
View File
@@ -0,0 +1,32 @@
#-------------------------------------------------
#
# Project created by QtCreator 2014-11-15T21:35:37
#
#-------------------------------------------------
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = ckb
TEMPLATE = app
QMAKE_MAC_SDK = macosx10.10
OBJECTS_DIR = $$PWD/../../tmp-ckb
DESTDIR = $$PWD/../../bin
SOURCES += main.cpp\
mainwindow.cpp \
kbwidget.cpp \
colorbutton.cpp
HEADERS += mainwindow.h \
kbwidget.h \
colorbutton.h
FORMS += mainwindow.ui \
kbwidget.ui
RESOURCES += \
image.qrc
+30
View File
@@ -0,0 +1,30 @@
#include "colorbutton.h"
#include <QColorDialog>
#include <QPainter>
ColorButton::ColorButton(QWidget *parent) :
QPushButton(parent), color(QColor(255, 255, 255))
{
connect(this, SIGNAL(clicked()), this, SLOT(pickColor()));
updateImage();
}
void ColorButton::updateImage(){
const int w = 12, h = 12;
QImage image(w, h, QImage::Format_RGB888);
QPainter painter(&image);
painter.setPen(Qt::NoPen);
painter.fillRect(0, 0, w, h, QColor(0, 0, 0));
painter.fillRect(1, 1, w - 2, h - 2, color);
setIcon(QIcon(QPixmap::fromImage(image)));
setText(" " + color.name().toUpper());
}
void ColorButton::pickColor(){
QColor newColor = QColorDialog::getColor(color, this);
if(newColor.isValid()){
color = newColor;
updateImage();
emit colorChanged(color);
}
}
+22
View File
@@ -0,0 +1,22 @@
#ifndef COLORBUTTON_H
#define COLORBUTTON_H
#include <QPushButton>
class ColorButton : public QPushButton
{
Q_OBJECT
public:
explicit ColorButton(QWidget *parent = 0);
QColor color;
void updateImage();
signals:
void colorChanged(QColor newColor);
private slots:
void pickColor();
};
#endif // COLORBUTTON_H
+5
View File
@@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/img">
<file>ckb-logo.png</file>
</qresource>
</RCC>
+156
View File
@@ -0,0 +1,156 @@
#include "kbwidget.h"
#include "ui_kbwidget.h"
#include <cmath>
// Keyboard LED positions, measured roughly in 16th inches. Most keys are 3/4" apart.
struct keypos {
const char* name;
int x, y;
};
keypos positions_us[] = {
{"mr", 38, 0}, {"m1", 50, 0}, {"m2", 62, 0}, {"m3", 74, 0}, {"light", 222, 0}, {"lock", 234, 0}, {"mute", 273, 0},
{"g1", 0, 14}, {"g2", 11, 14}, {"g3", 22, 14}, {"esc", 38, 14}, {"f1", 58, 14}, {"f2", 70, 14}, {"f3", 82, 14}, {"f4", 94, 14}, {"f5", 114, 14}, {"f6", 126, 14}, {"f7", 138, 14}, {"f8", 150, 14}, {"f9", 170, 14}, {"f10", 182, 14}, {"f11", 194, 14}, {"f12", 206, 14}, {"prtscn", 222, 14}, {"scroll", 234, 14}, {"pause", 246, 14}, {"stop", 262, 14}, {"prev", 273, 14}, {"play", 285, 14}, {"next", 296, 14},
{"g4", 0, 25}, {"g5", 11, 25}, {"g6", 22, 25}, {"grave", 38, 27}, {"1", 50, 27}, {"2", 62, 27}, {"3", 74, 27}, {"4", 86, 27}, {"5", 98, 27}, {"6", 110, 27}, {"7", 122, 27}, {"8", 134, 27}, {"9", 146, 27}, {"0", 158, 27}, {"minus", 170, 27}, {"equal", 182, 27}, {"bspace", 200, 27}, {"ins", 222, 27}, {"home", 234, 27}, {"pgup", 246, 27}, {"numlock", 261, 27}, {"numslash", 273, 27}, {"numstar", 285, 27}, {"numminus", 297, 27},
{"g7", 0, 39}, {"g8", 11, 39}, {"g9", 22, 39}, {"tab", 42, 39}, {"q", 56, 39}, {"w", 68, 39}, {"e", 80, 39}, {"r", 92, 39}, {"t", 104, 39}, {"y", 116, 39}, {"u", 128, 39}, {"i", 140, 39}, {"o", 152, 39}, {"p", 164, 39}, {"lbrace", 178, 39}, {"rbrace", 190, 39}, {"bslash", 202, 39}, {"del", 222, 39}, {"end", 234, 39}, {"pgdn", 246, 39}, {"num7", 261, 39}, {"num8", 273, 39}, {"num9", 285, 39}, {"numplus", 297, 33},
{"g10", 0, 50}, {"g11", 11, 50}, {"g12", 22, 50}, {"caps", 44, 51}, {"a", 59, 51}, {"s", 71, 51}, {"d", 83, 51}, {"f", 95, 51}, {"g", 107, 51}, {"h", 119, 51}, {"j", 131, 51}, {"k", 143, 51}, {"l", 155, 51}, {"colon", 167, 51}, {"quote", 179, 51}, {"enter", 198, 51}, {"num4", 273, 51}, {"num5", 273, 51}, {"num6", 285, 51},
{"g13", 0, 64}, {"g14", 11, 64}, {"g15", 22, 64}, {"lshift", 46, 63}, {"z", 65, 63}, {"x", 77, 63}, {"c", 89, 63}, {"v", 101, 63}, {"b", 113, 63}, {"n", 125, 63}, {"m", 137, 63}, {"comma", 149, 63}, {"dot", 161, 63}, {"slash", 173, 63}, {"rshift", 195, 63}, {"up", 234, 63}, {"num1", 261, 63}, {"num2", 273, 63}, {"num3", 285, 63}, {"numenter", 297, 69},
{"g16", 0, 75}, {"g17", 11, 75}, {"g18", 22, 75}, {"lctrl", 42, 75}, {"lwin", 56, 75}, {"lalt", 70, 75}, {"space", 122, 75}, {"ralt", 164, 75}, {"rwin", 178, 75}, {"rmenu", 190, 75}, {"rctrl", 202, 75}, {"left", 222, 75}, {"down", 234, 75}, {"right", 246, 75}, {"num0", 267, 75}, {"numdot", 285, 75},
};
keypos positions_uk[] = {
{"mr", 38, 0}, {"m1", 50, 0}, {"m2", 62, 0}, {"m3", 74, 0}, {"light", 222, 0}, {"lock", 234, 0}, {"mute", 273, 0},
{"g1", 0, 14}, {"g2", 11, 14}, {"g3", 22, 14}, {"esc", 38, 14}, {"f1", 58, 14}, {"f2", 70, 14}, {"f3", 82, 14}, {"f4", 94, 14}, {"f5", 114, 14}, {"f6", 126, 14}, {"f7", 138, 14}, {"f8", 150, 14}, {"f9", 170, 14}, {"f10", 182, 14}, {"f11", 194, 14}, {"f12", 206, 14}, {"prtscn", 222, 14}, {"scroll", 234, 14}, {"pause", 246, 14}, {"stop", 262, 14}, {"prev", 273, 14}, {"play", 285, 14}, {"next", 296, 14},
{"g4", 0, 25}, {"g5", 11, 25}, {"g6", 22, 25}, {"grave", 38, 27}, {"1", 50, 27}, {"2", 62, 27}, {"3", 74, 27}, {"4", 86, 27}, {"5", 98, 27}, {"6", 110, 27}, {"7", 122, 27}, {"8", 134, 27}, {"9", 146, 27}, {"0", 158, 27}, {"minus", 170, 27}, {"equal", 182, 27}, {"bspace", 200, 27}, {"ins", 222, 27}, {"home", 234, 27}, {"pgup", 246, 27}, {"numlock", 261, 27}, {"numslash", 273, 27}, {"numstar", 285, 27}, {"numminus", 297, 27},
{"g7", 0, 39}, {"g8", 11, 39}, {"g9", 22, 39}, {"tab", 42, 39}, {"q", 56, 39}, {"w", 68, 39}, {"e", 80, 39}, {"r", 92, 39}, {"t", 104, 39}, {"y", 116, 39}, {"u", 128, 39}, {"i", 140, 39}, {"o", 152, 39}, {"p", 164, 39}, {"lbrace", 178, 39}, {"rbrace", 190, 39}, {"del", 222, 39}, {"end", 234, 39}, {"pgdn", 246, 39}, {"num7", 261, 39}, {"num8", 273, 39}, {"num9", 285, 39}, {"numplus", 297, 33},
{"g10", 0, 50}, {"g11", 11, 50}, {"g12", 22, 50}, {"caps", 44, 51}, {"a", 59, 51}, {"s", 71, 51}, {"d", 83, 51}, {"f", 95, 51}, {"g", 107, 51}, {"h", 119, 51}, {"j", 131, 51}, {"k", 143, 51}, {"l", 155, 51}, {"colon", 167, 51}, {"quote", 179, 51}, {"hash", 191, 51}, {"enter", 198, 51}, {"num4", 273, 51}, {"num5", 273, 51}, {"num6", 285, 51},
{"g13", 0, 64}, {"g14", 11, 64}, {"g15", 22, 64}, {"lshift", 46, 63}, {"bslash", 53, 63}, {"z", 65, 63}, {"x", 77, 63}, {"c", 89, 63}, {"v", 101, 63}, {"b", 113, 63}, {"n", 125, 63}, {"m", 137, 63}, {"comma", 149, 63}, {"dot", 161, 63}, {"slash", 173, 63}, {"rshift", 195, 63}, {"up", 234, 63}, {"num1", 261, 63}, {"num2", 273, 63}, {"num3", 285, 63}, {"numenter", 297, 69},
{"g16", 0, 75}, {"g17", 11, 75}, {"g18", 22, 75}, {"lctrl", 42, 75}, {"lwin", 56, 75}, {"lalt", 70, 75}, {"space", 122, 75}, {"ralt", 164, 75}, {"rwin", 178, 75}, {"rmenu", 190, 75}, {"rctrl", 202, 75}, {"left", 222, 75}, {"down", 234, 75}, {"right", 246, 75}, {"num0", 267, 75}, {"numdot", 285, 75},
};
#define WIDTH 298
#define HEIGHT 76
#define N_POSITIONS_US (sizeof(positions_us)/sizeof(keypos))
#define N_POSITIONS_UK (sizeof(positions_uk)/sizeof(keypos))
void KbWidget::frameUpdate(){
if(!cmd.isOpen())
return;
static int prevBG = -1;
static int frame = 0;
int bg = ui->bgButton->color.rgba() & 0xFFFFFF;
int fg = ui->fgButton->color.rgba() & 0xFFFFFF;
int rate = ui->framerateBox->currentIndex() + 3;
keypos* positions = (ui->layoutBox->currentIndex() == 1) ? positions_uk : positions_us;
int N_POSITIONS = (positions == positions_uk) ? N_POSITIONS_UK : N_POSITIONS_US;
if(!(frame++ % rate)){
switch(ui->animBox->currentIndex()){
case 0:
// No animation
if(bg != prevBG){
cmd.write(QString().sprintf("rgb %06x\n", bg).toLatin1());
cmd.flush();
}
break;
case 1: {
// Wave
float size = WIDTH + 36.f;
static float wavepos = -36.f;
cmd.write("rgb");
for(int i = 0; i < N_POSITIONS; i++){
float r = (bg >> 16) & 0xFF;
float g = (bg >> 8) & 0xFF;
float b = bg & 0xFF;
float distance = fabs(positions[i].x - wavepos);
if(distance <= 36.f){
r = r * distance / 36.f + ((fg >> 16) & 0xFF) * (1.f - distance / 36.f);
g = g * distance / 36.f + ((fg >> 8) & 0xFF) * (1.f - distance / 36.f);
b = b * distance / 36.f + (fg & 0xFF) * (1.f - distance / 36.f);
}
cmd.write(QString().sprintf(" %s:%02x%02x%02x", positions[i].name, (int)r, (int)g, (int)b).toLatin1());
}
cmd.write("\n");
cmd.flush();
wavepos += (size + 36.f) / 2.f / 60.f * rate;
if(wavepos >= size)
wavepos = -36.f;
break;
}
case 2: {
// Ripple
float size = sqrt(WIDTH*WIDTH/2. + HEIGHT*HEIGHT/2.);
float cx = WIDTH / 2.f, cy = HEIGHT / 2.f;
static float ringpos = -36.f;
cmd.write("rgb");
for(int i = 0; i < N_POSITIONS; i++){
float r = (bg >> 16) & 0xFF;
float g = (bg >> 8) & 0xFF;
float b = bg & 0xFF;
float distance = fabs(sqrt(pow(positions[i].x - cx, 2.) + pow(positions[i].y - cy, 2.)) - ringpos);
if(distance <= 36.f){
r = r * distance / 36.f + ((fg >> 16) & 0xFF) * (1.f - distance / 36.f);
g = g * distance / 36.f + ((fg >> 8) & 0xFF) * (1.f - distance / 36.f);
b = b * distance / 36.f + (fg & 0xFF) * (1.f - distance / 36.f);
}
cmd.write(QString().sprintf(" %s:%02x%02x%02x", positions[i].name, (int)r, (int)g, (int)b).toLatin1());
}
cmd.write("\n");
cmd.flush();
ringpos += (size + 36.f) / 60.f * rate;
if(ringpos >= size)
ringpos = -36.f;
break;
}
}
prevBG = bg;
}
}
KbWidget::KbWidget(QWidget *parent, const QString &path) :
QWidget(parent), devpath(path), cmd(path + "/cmd"),
ui(new Ui::KbWidget)
{
ui->setupUi(this);
QFile mpath(path + "/model"), spath(path + "/serial");
if(mpath.open(QFile::ReadOnly)){
model = mpath.read(100);
model = model.trimmed();
mpath.close();
}
if(spath.open(QFile::ReadOnly)){
serial = spath.read(100);
serial = serial.trimmed();
spath.close();
ui->serialLabel->setText(serial);
}
cmd.open(QFile::ReadWrite);
cmd.write("rgb on\n");
cmd.flush();
ui->bgButton->color = QColor(255, 0, 0);
ui->bgButton->updateImage();
connect(ui->bgButton, SIGNAL(colorChanged(QColor)), this, SLOT(changeBG(QColor)));
connect(ui->fgButton, SIGNAL(colorChanged(QColor)), this, SLOT(changeFG(QColor)));
}
KbWidget::~KbWidget(){
cmd.close();
delete ui;
}
void KbWidget::changeFG(QColor newColor){
fg = newColor;
}
void KbWidget::changeBG(QColor newColor){
bg = newColor;
}
void KbWidget::on_lightCheckbox_clicked(bool checked){
if(checked)
cmd.write("rgb on\n");
else
cmd.write("rgb off\n");
cmd.flush();
}
+39
View File
@@ -0,0 +1,39 @@
#ifndef KBWIDGET_H
#define KBWIDGET_H
#include <QWidget>
#include <QFile>
namespace Ui {
class KbWidget;
}
class KbWidget : public QWidget
{
Q_OBJECT
public:
explicit KbWidget(QWidget *parent, const QString& path);
~KbWidget();
QString devpath;
QString serial;
QString model;
QFile cmd;
QColor fg, bg;
public slots:
void frameUpdate();
void changeFG(QColor newColor);
void changeBG(QColor newColor);
private slots:
void on_lightCheckbox_clicked(bool checked);
private:
Ui::KbWidget *ui;
};
#endif // KBWIDGET_H
+231
View File
@@ -0,0 +1,231 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>KbWidget</class>
<widget class="QWidget" name="KbWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>773</width>
<height>539</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="4" column="1">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Serial number:</string>
</property>
</widget>
</item>
<item row="8" column="2">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Animation color:</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Animation:</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Layout:</string>
</property>
</widget>
</item>
<item row="4" column="2">
<widget class="QComboBox" name="framerateBox">
<item>
<property name="text">
<string>60</string>
</property>
</item>
<item>
<property name="text">
<string>30</string>
</property>
</item>
<item>
<property name="text">
<string>15</string>
</property>
</item>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Base color:</string>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="ColorButton" name="bgButton">
<property name="text">
<string> #000000</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>FPS:</string>
</property>
</widget>
</item>
<item row="0" column="2" colspan="2">
<widget class="QLabel" name="serialLabel">
<property name="text">
<string>N/A</string>
</property>
</widget>
</item>
<item row="7" column="2">
<widget class="ColorButton" name="fgButton">
<property name="text">
<string> #FFFFFF</string>
</property>
</widget>
</item>
<item row="0" column="1">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
</spacer>
</item>
<item row="4" column="3">
<widget class="QLabel" name="label_3">
<property name="text">
<string> Try adjusting this if you experience animation issues.</string>
</property>
</widget>
</item>
<item row="4" column="4">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="6" column="2">
<widget class="QComboBox" name="animBox">
<item>
<property name="text">
<string>None</string>
</property>
</item>
<item>
<property name="text">
<string>Wave</string>
</property>
</item>
<item>
<property name="text">
<string>Ripple</string>
</property>
</item>
</widget>
</item>
<item row="2" column="2">
<widget class="QComboBox" name="layoutBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string>United States</string>
</property>
</item>
<item>
<property name="text">
<string>United Kingdom</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Enable lighting:</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QCheckBox" name="lightCheckbox">
<property name="text">
<string/>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>ColorButton</class>
<extends>QPushButton</extends>
<header location="global">colorbutton.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
-223
View File
@@ -1,223 +0,0 @@
#define _DEFAULT_SOURCE
#ifdef __linux
#include <features.h>
#endif
#include <stdio.h>
#include <unistd.h>
#include <time.h>
#include <dirent.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define N_KEYS 144
FILE* output = 0;
// Keyboard LED positions, measured roughly in 16th inches. Most keys are 3/4" apart.
typedef struct {
const char* name;
int x, y;
} keypos;
#ifdef KEYMAP_UK
keypos positions[] = {
{"mr", 38, 0}, {"m1", 50, 0}, {"m2", 62, 0}, {"m3", 74, 0}, {"light", 222, 0}, {"lock", 234, 0}, {"mute", 273, 0},
{"g1", 0, 14}, {"g2", 11, 14}, {"g3", 22, 14}, {"esc", 38, 14}, {"f1", 58, 14}, {"f2", 70, 14}, {"f3", 82, 14}, {"f4", 94, 14}, {"f5", 114, 14}, {"f6", 126, 14}, {"f7", 138, 14}, {"f8", 150, 14}, {"f9", 170, 14}, {"f10", 182, 14}, {"f11", 194, 14}, {"f12", 206, 14}, {"prtscn", 222, 14}, {"scroll", 234, 14}, {"pause", 246, 14}, {"stop", 262, 14}, {"prev", 273, 14}, {"play", 285, 14}, {"next", 296, 14},
{"g4", 0, 25}, {"g5", 11, 25}, {"g6", 22, 25}, {"grave", 38, 27}, {"1", 50, 27}, {"2", 62, 27}, {"3", 74, 27}, {"4", 86, 27}, {"5", 98, 27}, {"6", 110, 27}, {"7", 122, 27}, {"8", 134, 27}, {"9", 146, 27}, {"0", 158, 27}, {"minus", 170, 27}, {"equal", 182, 27}, {"bspace", 200, 27}, {"ins", 222, 27}, {"home", 234, 27}, {"pgup", 246, 27}, {"numlock", 261, 27}, {"numslash", 273, 27}, {"numstar", 285, 27}, {"numminus", 297, 27},
{"g7", 0, 39}, {"g8", 11, 39}, {"g9", 22, 39}, {"tab", 42, 39}, {"q", 56, 39}, {"w", 68, 39}, {"e", 80, 39}, {"r", 92, 39}, {"t", 104, 39}, {"y", 116, 39}, {"u", 128, 39}, {"i", 140, 39}, {"o", 152, 39}, {"p", 164, 39}, {"lbrace", 178, 39}, {"rbrace", 190, 39}, {"del", 222, 39}, {"end", 234, 39}, {"pgdn", 246, 39}, {"num7", 261, 39}, {"num8", 273, 39}, {"num9", 285, 39}, {"numplus", 297, 33},
{"g10", 0, 50}, {"g11", 11, 50}, {"g12", 22, 50}, {"caps", 44, 51}, {"a", 59, 51}, {"s", 71, 51}, {"d", 83, 51}, {"f", 95, 51}, {"g", 107, 51}, {"h", 119, 51}, {"j", 131, 51}, {"k", 143, 51}, {"l", 155, 51}, {"colon", 167, 51}, {"quote", 179, 51}, {"hash", 191, 51}, {"enter", 198, 51}, {"num4", 273, 51}, {"num5", 273, 51}, {"num6", 285, 51},
{"g13", 0, 64}, {"g14", 11, 64}, {"g15", 22, 64}, {"lshift", 46, 63}, {"bslash", 53, 63}, {"z", 65, 63}, {"x", 77, 63}, {"c", 89, 63}, {"v", 101, 63}, {"b", 113, 63}, {"n", 125, 63}, {"m", 137, 63}, {"comma", 149, 63}, {"dot", 161, 63}, {"slash", 173, 63}, {"rshift", 195, 63}, {"up", 234, 63}, {"num1", 261, 63}, {"num2", 273, 63}, {"num3", 285, 63}, {"numenter", 297, 69},
{"g16", 0, 75}, {"g17", 11, 75}, {"g18", 22, 75}, {"lctrl", 42, 75}, {"lwin", 56, 75}, {"lalt", 70, 75}, {"space", 122, 75}, {"ralt", 164, 75}, {"rwin", 178, 75}, {"rmenu", 190, 75}, {"rctrl", 202, 75}, {"left", 222, 75}, {"down", 234, 75}, {"right", 246, 75}, {"num0", 267, 75}, {"numdot", 285, 75},
};
#else
keypos positions[] = {
{"mr", 38, 0}, {"m1", 50, 0}, {"m2", 62, 0}, {"m3", 74, 0}, {"light", 222, 0}, {"lock", 234, 0}, {"mute", 273, 0},
{"g1", 0, 14}, {"g2", 11, 14}, {"g3", 22, 14}, {"esc", 38, 14}, {"f1", 58, 14}, {"f2", 70, 14}, {"f3", 82, 14}, {"f4", 94, 14}, {"f5", 114, 14}, {"f6", 126, 14}, {"f7", 138, 14}, {"f8", 150, 14}, {"f9", 170, 14}, {"f10", 182, 14}, {"f11", 194, 14}, {"f12", 206, 14}, {"prtscn", 222, 14}, {"scroll", 234, 14}, {"pause", 246, 14}, {"stop", 262, 14}, {"prev", 273, 14}, {"play", 285, 14}, {"next", 296, 14},
{"g4", 0, 25}, {"g5", 11, 25}, {"g6", 22, 25}, {"grave", 38, 27}, {"1", 50, 27}, {"2", 62, 27}, {"3", 74, 27}, {"4", 86, 27}, {"5", 98, 27}, {"6", 110, 27}, {"7", 122, 27}, {"8", 134, 27}, {"9", 146, 27}, {"0", 158, 27}, {"minus", 170, 27}, {"equal", 182, 27}, {"bspace", 200, 27}, {"ins", 222, 27}, {"home", 234, 27}, {"pgup", 246, 27}, {"numlock", 261, 27}, {"numslash", 273, 27}, {"numstar", 285, 27}, {"numminus", 297, 27},
{"g7", 0, 39}, {"g8", 11, 39}, {"g9", 22, 39}, {"tab", 42, 39}, {"q", 56, 39}, {"w", 68, 39}, {"e", 80, 39}, {"r", 92, 39}, {"t", 104, 39}, {"y", 116, 39}, {"u", 128, 39}, {"i", 140, 39}, {"o", 152, 39}, {"p", 164, 39}, {"lbrace", 178, 39}, {"rbrace", 190, 39}, {"bslash", 202, 39}, {"del", 222, 39}, {"end", 234, 39}, {"pgdn", 246, 39}, {"num7", 261, 39}, {"num8", 273, 39}, {"num9", 285, 39}, {"numplus", 297, 33},
{"g10", 0, 50}, {"g11", 11, 50}, {"g12", 22, 50}, {"caps", 44, 51}, {"a", 59, 51}, {"s", 71, 51}, {"d", 83, 51}, {"f", 95, 51}, {"g", 107, 51}, {"h", 119, 51}, {"j", 131, 51}, {"k", 143, 51}, {"l", 155, 51}, {"colon", 167, 51}, {"quote", 179, 51}, {"enter", 198, 51}, {"num4", 273, 51}, {"num5", 273, 51}, {"num6", 285, 51},
{"g13", 0, 64}, {"g14", 11, 64}, {"g15", 22, 64}, {"lshift", 46, 63}, {"z", 65, 63}, {"x", 77, 63}, {"c", 89, 63}, {"v", 101, 63}, {"b", 113, 63}, {"n", 125, 63}, {"m", 137, 63}, {"comma", 149, 63}, {"dot", 161, 63}, {"slash", 173, 63}, {"rshift", 195, 63}, {"up", 234, 63}, {"num1", 261, 63}, {"num2", 273, 63}, {"num3", 285, 63}, {"numenter", 297, 69},
{"g16", 0, 75}, {"g17", 11, 75}, {"g18", 22, 75}, {"lctrl", 42, 75}, {"lwin", 56, 75}, {"lalt", 70, 75}, {"space", 122, 75}, {"ralt", 164, 75}, {"rwin", 178, 75}, {"rmenu", 190, 75}, {"rctrl", 202, 75}, {"left", 222, 75}, {"down", 234, 75}, {"right", 246, 75}, {"num0", 267, 75}, {"numdot", 285, 75},
};
#endif
#define WIDTH 298
#define HEIGHT 76
#define N_POSITIONS (sizeof(positions)/sizeof(keypos))
void mainloop_random(float fr, float fg, float fb, float br, float bg, float bb){
static float r[N_KEYS], g[N_KEYS], b[N_KEYS];
static float rspeed[N_KEYS], gspeed[N_KEYS], bspeed[N_KEYS];
static int firstrun = 1;
static int frame = 0;
// On first run, fill all colors randomly
if(firstrun){
srand(time(NULL));
for(int i = 0; i < N_KEYS; i++){
r[i] = rand() % 256;
g[i] = rand() % 256;
b[i] = rand() % 256;
}
firstrun = 0;
}
// On frame 0, pick a new set of colors to cycle to and choose the appropriate speeds to get there by frame 120
if(frame == 0){
for(int i = 0; i < N_KEYS; i++){
float r2 = rand() % 256;
float g2 = rand() % 256;
float b2 = rand() % 256;
rspeed[i] = (r2 - r[i]) / 120.f;
gspeed[i] = (g2 - g[i]) / 120.f;
bspeed[i] = (b2 - b[i]) / 120.f;
}
}
// Update and output the keys
fprintf(output, "rgb on ");
for(int i = 0; i < N_KEYS; i++){
r[i] += rspeed[i];
g[i] += gspeed[i];
b[i] += bspeed[i];
fprintf(output, " #%d:%02x%02x%02x", i, (int)(r[i]), (int)(g[i]), (int)(b[i]));
}
fputc('\n', output);
fflush(output);
frame = (frame + 1) % 120;
}
void mainloop_wave(float fr, float fg, float fb, float br, float bg, float bb){
float size = WIDTH + 36.f;
static float wavepos = -36.f;
fprintf(output, "rgb on ");
for(int i = 0; i < N_POSITIONS; i++){
float r = br;
float g = bg;
float b = bb;
float distance = fabs(positions[i].x - wavepos);
if(distance <= 36.f){
r = r * distance / 36.f + fr * (1.f - distance / 36.f);
g = g * distance / 36.f + fg * (1.f - distance / 36.f);
b = b * distance / 36.f + fb * (1.f - distance / 36.f);
}
fprintf(output, " %s:%02x%02x%02x", positions[i].name, (int)r, (int)g, (int)b);
}
fputc('\n', output);
fflush(output);
wavepos += (size + 36.f) / 2.f / 60.f;
if(wavepos >= size)
wavepos = -36.f;
}
void mainloop_ripple(float fr, float fg, float fb, float br, float bg, float bb){
float size = sqrt(WIDTH*WIDTH/2. + HEIGHT*HEIGHT/2.);
float cx = WIDTH / 2.f, cy = HEIGHT / 2.f;
static float ringpos = -36.f;
fprintf(output, "rgb on");
for(int i = 0; i < N_POSITIONS; i++){
float r = br;
float g = bg;
float b = bb;
float distance = fabs(sqrt(pow(positions[i].x - cx, 2.) + pow(positions[i].y - cy, 2.)) - ringpos);
if(distance <= 36.f){
r = r * distance / 36.f + fr * (1.f - distance / 36.f);
g = g * distance / 36.f + fg * (1.f - distance / 36.f);
b = b * distance / 36.f + fb * (1.f - distance / 36.f);
}
fprintf(output, " %s:%02x%02x%02x", positions[i].name, (int)r, (int)g, (int)b);
}
fputc('\n', output);
fflush(output);
ringpos += (size + 36.f) / 60.f;
if(ringpos >= size)
ringpos = -36.f;
}
void mainloop_gradient(float fr, float fg, float fb, float br, float bg, float bb){
static float grad = 1.f;
int r = fr * grad + br * (1.f - grad);
int g = fg * grad + bg * (1.f - grad);
int b = fb * grad + bb * (1.f - grad);
fprintf(output, "rgb on %02x%02x%02x\n", r, g, b);
fflush(output);
if(grad == 0.f)
exit(0);
grad -= 1.f / 2.f / 60.f;
if(grad < 0.f)
grad = 0.f;
}
void mainloop_solid(float fr, float fg, float fb, float br, float bg, float bb){
fprintf(output, "rgb on %02x%02x%02x\n", (int)fr, (int)fg, (int)fb);
fflush(output);
exit(0);
}
int readcolor(const char* clr){
if(!strcmp(clr, "red"))
return 0xff0000;
if(!strcmp(clr, "green"))
return 0x00ff00;
if(!strcmp(clr, "blue"))
return 0x0000ff;
if(!strcmp(clr, "cyan"))
return 0x00ffff;
if(!strcmp(clr, "magenta"))
return 0xff00ff;
if(!strcmp(clr, "yellow"))
return 0xffff00;
if(!strcmp(clr, "white"))
return 0xffffff;
if(!strcmp(clr, "black"))
return 0x000000;
int rgb;
if(sscanf(clr, "%6x", &rgb) == 1)
return rgb;
return 0;
}
int main(int argc, char** argv){
if(argc < 2){
printf("Usage: ckb (solid | gradient | ripple | wave | random) [foreground] [background]\n");
exit(0);
}
void (*mainloop)(float,float,float,float,float,float);
if(!strcmp(argv[1], "solid"))
mainloop = mainloop_solid;
else if(!strcmp(argv[1], "gradient"))
mainloop = mainloop_gradient;
else if(!strcmp(argv[1], "ripple"))
mainloop = mainloop_ripple;
else if(!strcmp(argv[1], "wave"))
mainloop = mainloop_wave;
else if(!strcmp(argv[1], "random"))
mainloop = mainloop_random;
else {
printf("Usage: ckb (solid | gradient | ripple | wave | random) [foreground] [background]\n");
exit(0);
}
#ifdef __linux
output = fopen("/dev/input/ckb1/cmd", "w");
#else
output = fopen("/tmp/ckb1/cmd", "w");
#endif
if(!output){
printf("Unable to open input device\n");
exit(-1);
}
int foreground = 0xffffff, background = 0xffffff;
if(argc >= 3)
foreground = background = readcolor(argv[2]);
if(argc >= 4)
background = readcolor(argv[3]);
float fr = (foreground >> 16) & 0xff, fg = (foreground >> 8) & 0xff, fb = foreground & 0xff;
float br = (background >> 16) & 0xff, bg = (background >> 8) & 0xff, bb = background & 0xff;
while(1){
mainloop(fr, fg, fb, br, bg, bb);
usleep(16667);
}
return 0;
}
+29
View File
@@ -0,0 +1,29 @@
#include "mainwindow.h"
#include <QApplication>
#include <QSharedMemory>
#include <cstring>
QSharedMemory appShare("ckb");
bool isRunning(){
if(!appShare.create(16)){
if(!appShare.attach() || !appShare.lock())
return false;
void* data = appShare.data();
snprintf((char*)data, 16, "Open");
appShare.unlock();
return true;
}
return false;
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
if(isRunning())
return 0;
MainWindow w;
w.show();
return a.exec();
}
+136
View File
@@ -0,0 +1,136 @@
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QSharedMemory>
#include <QMessageBox>
extern QSharedMemory appShare;
static const QString noKbMsg = "No keyboard detected";
#ifndef __APPLE__
static const QString devpath = "/dev/input/ckb%1";
#else
static const QString devpath = "/tmp/ckb%1";
#endif
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
trayIconMenu = new QMenu(this);
restoreAction = new QAction(tr("Restore"), this);
closeAction = new QAction(tr("Exit"), this);
trayIconMenu->addAction(restoreAction);
trayIconMenu->addAction(closeAction);
trayIcon = new QSystemTrayIcon(QIcon(":/img/ckb-logo.png"), this);
trayIcon->setContextMenu(trayIconMenu);
trayIcon->show();
ui->tabWidget->addTab(noKbWidget = new QWidget(this), noKbMsg);
connect(ui->actionExit, SIGNAL(triggered()), qApp, SLOT(quit()));
connect(ui->actionAbout, SIGNAL(triggered()), this, SLOT(about()));
connect(closeAction, SIGNAL(triggered()), qApp, SLOT(quit()));
connect(restoreAction, SIGNAL(triggered()), this, SLOT(show()));
eventTimer = new QTimer(this);
connect(eventTimer, SIGNAL(timeout()), this, SLOT(timerTick()));
eventTimer->start(16);
scanKeyboards();
}
void MainWindow::scanKeyboards(){
QString rootdev = devpath.arg(0);
QFile connected(rootdev + "/connected");
if(!connected.open(QFile::ReadOnly)){
// No root controller
if(ui->tabWidget->currentWidget() != noKbWidget){
while(ui->tabWidget->count() > 0)
ui->tabWidget->removeTab(0);
ui->tabWidget->addTab(noKbWidget, noKbMsg);
}
foreach(KbWidget* w, kbWidgets)
w->deleteLater();
kbWidgets.clear();
}
// Check if any currently-connected keyboards have been removed
QList<KbWidget*> kbWidgets2 = kbWidgets;
foreach(KbWidget* w, kbWidgets2){
if(!w->cmd.isOpen()){
w->deleteLater();
ui->tabWidget->removeTab(kbWidgets.indexOf(w));
kbWidgets.removeAll(w);
}
}
QString line;
int count = kbWidgets.count();
while((line = connected.readLine()) != ""){
QString dev = line.split(" ")[0];
if(dev == "")
break;
// Connected already?
KbWidget* widget = 0;
foreach(KbWidget* w, kbWidgets){
if(w->devpath == dev){
widget = w;
break;
}
}
if(widget)
continue;
// Add the keyboard
widget = new KbWidget(this, dev);
if(!widget->cmd.isOpen()){
delete widget;
continue;
}
count++;
kbWidgets.append(widget);
ui->tabWidget->addTab(widget, widget->model);
connect(eventTimer, SIGNAL(timeout()), widget, SLOT(frameUpdate()));
}
connected.close();
if(count == 0){
// No keyboards found
if(ui->tabWidget->currentWidget() != noKbWidget){
while(ui->tabWidget->count() > 0)
ui->tabWidget->removeTab(0);
ui->tabWidget->addTab(noKbWidget, noKbMsg);
}
foreach(KbWidget* w, kbWidgets)
w->deleteLater();
kbWidgets.clear();
} else if(ui->tabWidget->widget(0) == noKbWidget){
// Remove "no keyboard detected" if it's there
ui->tabWidget->removeTab(0);
}
}
void MainWindow::closeEvent(QCloseEvent *event){
QMessageBox::information(this, "ckb", "ckb will still run in the background.\nTo close it, use the Exit option from the menu.");
hide();
event->ignore();
}
void MainWindow::timerTick(){
// Check if another instance requested this in the foreground
if(appShare.lock()){
void* data = appShare.data();
if((QString)QByteArray((const char*)data) == "Open")
show();
// Remove the request
*(char*)data = 0;
appShare.unlock();
}
scanKeyboards();
}
void MainWindow::about(){
QMessageBox::information(this, "About ckb", "ckb v0.0.1\nhttps://github.com/ccMSC/ckb\n\nLicensed under GPL v2");
}
MainWindow::~MainWindow(){
delete ui;
}
+44
View File
@@ -0,0 +1,44 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QSystemTrayIcon>
#include <QCloseEvent>
#include <QTimer>
#include "kbwidget.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
QTimer* eventTimer;
void scanKeyboards();
QWidget* noKbWidget;
QList<KbWidget*> kbWidgets;
QAction* restoreAction;
QAction* closeAction;
QMenu* trayIconMenu;
QSystemTrayIcon* trayIcon;
void closeEvent(QCloseEvent *event);
public slots:
void timerTick();
void about();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
+87
View File
@@ -0,0 +1,87 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>600</width>
<height>500</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>600</width>
<height>500</height>
</size>
</property>
<property name="windowTitle">
<string>ckb</string>
</property>
<property name="windowIcon">
<iconset resource="image.qrc">
<normaloff>:/img/ckb-logo.png</normaloff>:/img/ckb-logo.png</iconset>
</property>
<property name="unifiedTitleAndToolBarOnMac">
<bool>true</bool>
</property>
<widget class="QWidget" name="centralWidget">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>-1</number>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>600</width>
<height>24</height>
</rect>
</property>
<property name="nativeMenuBar">
<bool>true</bool>
</property>
<widget class="QMenu" name="menuFile">
<property name="title">
<string>File</string>
</property>
<addaction name="actionExit"/>
</widget>
<widget class="QMenu" name="menuHelp">
<property name="title">
<string>Help</string>
</property>
<addaction name="actionAbout"/>
</widget>
<addaction name="menuFile"/>
<addaction name="menuHelp"/>
</widget>
<widget class="QStatusBar" name="statusBar"/>
<action name="actionExit">
<property name="text">
<string>Exit</string>
</property>
<property name="shortcut">
<string>Ctrl+Q</string>
</property>
</action>
<action name="actionAbout">
<property name="text">
<string>About</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources>
<include location="image.qrc"/>
</resources>
<connections/>
</ui>
+571
View File
@@ -0,0 +1,571 @@
/****************************************************************************
** Resource object code
**
** Created by: The Resource Compiler for Qt version 5.3.2
**
** WARNING! All changes made in this file will be lost!
*****************************************************************************/
#include <QtCore/qglobal.h>
static const unsigned char qt_resource_data[] = {
// /home/elaine/Documents/Code/C++/ckb/ckb/src/ckb/ckb-logo.png
0x0,0x0,0x1f,0x46,
0x89,
0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,
0x0,0x0,0xc0,0x0,0x0,0x0,0xc0,0x8,0x6,0x0,0x0,0x0,0x52,0xdc,0x6c,0x7,
0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,
0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0xa,0x4f,0x69,0x43,0x43,0x50,0x50,0x68,0x6f,
0x74,0x6f,0x73,0x68,0x6f,0x70,0x20,0x49,0x43,0x43,0x20,0x70,0x72,0x6f,0x66,0x69,
0x6c,0x65,0x0,0x0,0x78,0xda,0x9d,0x53,0x67,0x54,0x53,0xe9,0x16,0x3d,0xf7,0xde,
0xf4,0x42,0x4b,0x88,0x80,0x94,0x4b,0x6f,0x52,0x15,0x8,0x20,0x52,0x42,0x8b,0x80,
0x14,0x91,0x26,0x2a,0x21,0x9,0x10,0x4a,0x88,0x21,0xa1,0xd9,0x15,0x51,0xc1,0x11,
0x45,0x45,0x4,0x1b,0xc8,0xa0,0x88,0x3,0x8e,0x8e,0x80,0x8c,0x15,0x51,0x2c,0xc,
0x8a,0xa,0xd8,0x7,0xe4,0x21,0xa2,0x8e,0x83,0xa3,0x88,0x8a,0xca,0xfb,0xe1,0x7b,
0xa3,0x6b,0xd6,0xbc,0xf7,0xe6,0xcd,0xfe,0xb5,0xd7,0x3e,0xe7,0xac,0xf3,0x9d,0xb3,
0xcf,0x7,0xc0,0x8,0xc,0x96,0x48,0x33,0x51,0x35,0x80,0xc,0xa9,0x42,0x1e,0x11,
0xe0,0x83,0xc7,0xc4,0xc6,0xe1,0xe4,0x2e,0x40,0x81,0xa,0x24,0x70,0x0,0x10,0x8,
0xb3,0x64,0x21,0x73,0xfd,0x23,0x1,0x0,0xf8,0x7e,0x3c,0x3c,0x2b,0x22,0xc0,0x7,
0xbe,0x0,0x1,0x78,0xd3,0xb,0x8,0x0,0xc0,0x4d,0x9b,0xc0,0x30,0x1c,0x87,0xff,
0xf,0xea,0x42,0x99,0x5c,0x1,0x80,0x84,0x1,0xc0,0x74,0x91,0x38,0x4b,0x8,0x80,
0x14,0x0,0x40,0x7a,0x8e,0x42,0xa6,0x0,0x40,0x46,0x1,0x80,0x9d,0x98,0x26,0x53,
0x0,0xa0,0x4,0x0,0x60,0xcb,0x63,0x62,0xe3,0x0,0x50,0x2d,0x0,0x60,0x27,0x7f,
0xe6,0xd3,0x0,0x80,0x9d,0xf8,0x99,0x7b,0x1,0x0,0x5b,0x94,0x21,0x15,0x1,0xa0,
0x91,0x0,0x20,0x13,0x65,0x88,0x44,0x0,0x68,0x3b,0x0,0xac,0xcf,0x56,0x8a,0x45,
0x0,0x58,0x30,0x0,0x14,0x66,0x4b,0xc4,0x39,0x0,0xd8,0x2d,0x0,0x30,0x49,0x57,
0x66,0x48,0x0,0xb0,0xb7,0x0,0xc0,0xce,0x10,0xb,0xb2,0x0,0x8,0xc,0x0,0x30,
0x51,0x88,0x85,0x29,0x0,0x4,0x7b,0x0,0x60,0xc8,0x23,0x23,0x78,0x0,0x84,0x99,
0x0,0x14,0x46,0xf2,0x57,0x3c,0xf1,0x2b,0xae,0x10,0xe7,0x2a,0x0,0x0,0x78,0x99,
0xb2,0x3c,0xb9,0x24,0x39,0x45,0x81,0x5b,0x8,0x2d,0x71,0x7,0x57,0x57,0x2e,0x1e,
0x28,0xce,0x49,0x17,0x2b,0x14,0x36,0x61,0x2,0x61,0x9a,0x40,0x2e,0xc2,0x79,0x99,
0x19,0x32,0x81,0x34,0xf,0xe0,0xf3,0xcc,0x0,0x0,0xa0,0x91,0x15,0x11,0xe0,0x83,
0xf3,0xfd,0x78,0xce,0xe,0xae,0xce,0xce,0x36,0x8e,0xb6,0xe,0x5f,0x2d,0xea,0xbf,
0x6,0xff,0x22,0x62,0x62,0xe3,0xfe,0xe5,0xcf,0xab,0x70,0x40,0x0,0x0,0xe1,0x74,
0x7e,0xd1,0xfe,0x2c,0x2f,0xb3,0x1a,0x80,0x3b,0x6,0x80,0x6d,0xfe,0xa2,0x25,0xee,
0x4,0x68,0x5e,0xb,0xa0,0x75,0xf7,0x8b,0x66,0xb2,0xf,0x40,0xb5,0x0,0xa0,0xe9,
0xda,0x57,0xf3,0x70,0xf8,0x7e,0x3c,0x3c,0x45,0xa1,0x90,0xb9,0xd9,0xd9,0xe5,0xe4,
0xe4,0xd8,0x4a,0xc4,0x42,0x5b,0x61,0xca,0x57,0x7d,0xfe,0x67,0xc2,0x5f,0xc0,0x57,
0xfd,0x6c,0xf9,0x7e,0x3c,0xfc,0xf7,0xf5,0xe0,0xbe,0xe2,0x24,0x81,0x32,0x5d,0x81,
0x47,0x4,0xf8,0xe0,0xc2,0xcc,0xf4,0x4c,0xa5,0x1c,0xcf,0x92,0x9,0x84,0x62,0xdc,
0xe6,0x8f,0x47,0xfc,0xb7,0xb,0xff,0xfc,0x1d,0xd3,0x22,0xc4,0x49,0x62,0xb9,0x58,
0x2a,0x14,0xe3,0x51,0x12,0x71,0x8e,0x44,0x9a,0x8c,0xf3,0x32,0xa5,0x22,0x89,0x42,
0x92,0x29,0xc5,0x25,0xd2,0xff,0x64,0xe2,0xdf,0x2c,0xfb,0x3,0x3e,0xdf,0x35,0x0,
0xb0,0x6a,0x3e,0x1,0x7b,0x91,0x2d,0xa8,0x5d,0x63,0x3,0xf6,0x4b,0x27,0x10,0x58,
0x74,0xc0,0xe2,0xf7,0x0,0x0,0xf2,0xbb,0x6f,0xc1,0xd4,0x28,0x8,0x3,0x80,0x68,
0x83,0xe1,0xcf,0x77,0xff,0xef,0x3f,0xfd,0x47,0xa0,0x25,0x0,0x80,0x66,0x49,0x92,
0x71,0x0,0x0,0x5e,0x44,0x24,0x2e,0x54,0xca,0xb3,0x3f,0xc7,0x8,0x0,0x0,0x44,
0xa0,0x81,0x2a,0xb0,0x41,0x1b,0xf4,0xc1,0x18,0x2c,0xc0,0x6,0x1c,0xc1,0x5,0xdc,
0xc1,0xb,0xfc,0x60,0x36,0x84,0x42,0x24,0xc4,0xc2,0x42,0x10,0x42,0xa,0x64,0x80,
0x1c,0x72,0x60,0x29,0xac,0x82,0x42,0x28,0x86,0xcd,0xb0,0x1d,0x2a,0x60,0x2f,0xd4,
0x40,0x1d,0x34,0xc0,0x51,0x68,0x86,0x93,0x70,0xe,0x2e,0xc2,0x55,0xb8,0xe,0x3d,
0x70,0xf,0xfa,0x61,0x8,0x9e,0xc1,0x28,0xbc,0x81,0x9,0x4,0x41,0xc8,0x8,0x13,
0x61,0x21,0xda,0x88,0x1,0x62,0x8a,0x58,0x23,0x8e,0x8,0x17,0x99,0x85,0xf8,0x21,
0xc1,0x48,0x4,0x12,0x8b,0x24,0x20,0xc9,0x88,0x14,0x51,0x22,0x4b,0x91,0x35,0x48,
0x31,0x52,0x8a,0x54,0x20,0x55,0x48,0x1d,0xf2,0x3d,0x72,0x2,0x39,0x87,0x5c,0x46,
0xba,0x91,0x3b,0xc8,0x0,0x32,0x82,0xfc,0x86,0xbc,0x47,0x31,0x94,0x81,0xb2,0x51,
0x3d,0xd4,0xc,0xb5,0x43,0xb9,0xa8,0x37,0x1a,0x84,0x46,0xa2,0xb,0xd0,0x64,0x74,
0x31,0x9a,0x8f,0x16,0xa0,0x9b,0xd0,0x72,0xb4,0x1a,0x3d,0x8c,0x36,0xa1,0xe7,0xd0,
0xab,0x68,0xf,0xda,0x8f,0x3e,0x43,0xc7,0x30,0xc0,0xe8,0x18,0x7,0x33,0xc4,0x6c,
0x30,0x2e,0xc6,0xc3,0x42,0xb1,0x38,0x2c,0x9,0x93,0x63,0xcb,0xb1,0x22,0xac,0xc,
0xab,0xc6,0x1a,0xb0,0x56,0xac,0x3,0xbb,0x89,0xf5,0x63,0xcf,0xb1,0x77,0x4,0x12,
0x81,0x45,0xc0,0x9,0x36,0x4,0x77,0x42,0x20,0x61,0x1e,0x41,0x48,0x58,0x4c,0x58,
0x4e,0xd8,0x48,0xa8,0x20,0x1c,0x24,0x34,0x11,0xda,0x9,0x37,0x9,0x3,0x84,0x51,
0xc2,0x27,0x22,0x93,0xa8,0x4b,0xb4,0x26,0xba,0x11,0xf9,0xc4,0x18,0x62,0x32,0x31,
0x87,0x58,0x48,0x2c,0x23,0xd6,0x12,0x8f,0x13,0x2f,0x10,0x7b,0x88,0x43,0xc4,0x37,
0x24,0x12,0x89,0x43,0x32,0x27,0xb9,0x90,0x2,0x49,0xb1,0xa4,0x54,0xd2,0x12,0xd2,
0x46,0xd2,0x6e,0x52,0x23,0xe9,0x2c,0xa9,0x9b,0x34,0x48,0x1a,0x23,0x93,0xc9,0xda,
0x64,0x6b,0xb2,0x7,0x39,0x94,0x2c,0x20,0x2b,0xc8,0x85,0xe4,0x9d,0xe4,0xc3,0xe4,
0x33,0xe4,0x1b,0xe4,0x21,0xf2,0x5b,0xa,0x9d,0x62,0x40,0x71,0xa4,0xf8,0x53,0xe2,
0x28,0x52,0xca,0x6a,0x4a,0x19,0xe5,0x10,0xe5,0x34,0xe5,0x6,0x65,0x98,0x32,0x41,
0x55,0xa3,0x9a,0x52,0xdd,0xa8,0xa1,0x54,0x11,0x35,0x8f,0x5a,0x42,0xad,0xa1,0xb6,
0x52,0xaf,0x51,0x87,0xa8,0x13,0x34,0x75,0x9a,0x39,0xcd,0x83,0x16,0x49,0x4b,0xa5,
0xad,0xa2,0x95,0xd3,0x1a,0x68,0x17,0x68,0xf7,0x69,0xaf,0xe8,0x74,0xba,0x11,0xdd,
0x95,0x1e,0x4e,0x97,0xd0,0x57,0xd2,0xcb,0xe9,0x47,0xe8,0x97,0xe8,0x3,0xf4,0x77,
0xc,0xd,0x86,0x15,0x83,0xc7,0x88,0x67,0x28,0x19,0x9b,0x18,0x7,0x18,0x67,0x19,
0x77,0x18,0xaf,0x98,0x4c,0xa6,0x19,0xd3,0x8b,0x19,0xc7,0x54,0x30,0x37,0x31,0xeb,
0x98,0xe7,0x99,0xf,0x99,0x6f,0x55,0x58,0x2a,0xb6,0x2a,0x7c,0x15,0x91,0xca,0xa,
0x95,0x4a,0x95,0x26,0x95,0x1b,0x2a,0x2f,0x54,0xa9,0xaa,0xa6,0xaa,0xde,0xaa,0xb,
0x55,0xf3,0x55,0xcb,0x54,0x8f,0xa9,0x5e,0x53,0x7d,0xae,0x46,0x55,0x33,0x53,0xe3,
0xa9,0x9,0xd4,0x96,0xab,0x55,0xaa,0x9d,0x50,0xeb,0x53,0x1b,0x53,0x67,0xa9,0x3b,
0xa8,0x87,0xaa,0x67,0xa8,0x6f,0x54,0x3f,0xa4,0x7e,0x59,0xfd,0x89,0x6,0x59,0xc3,
0x4c,0xc3,0x4f,0x43,0xa4,0x51,0xa0,0xb1,0x5f,0xe3,0xbc,0xc6,0x20,0xb,0x63,0x19,
0xb3,0x78,0x2c,0x21,0x6b,0xd,0xab,0x86,0x75,0x81,0x35,0xc4,0x26,0xb1,0xcd,0xd9,
0x7c,0x76,0x2a,0xbb,0x98,0xfd,0x1d,0xbb,0x8b,0x3d,0xaa,0xa9,0xa1,0x39,0x43,0x33,
0x4a,0x33,0x57,0xb3,0x52,0xf3,0x94,0x66,0x3f,0x7,0xe3,0x98,0x71,0xf8,0x9c,0x74,
0x4e,0x9,0xe7,0x28,0xa7,0x97,0xf3,0x7e,0x8a,0xde,0x14,0xef,0x29,0xe2,0x29,0x1b,
0xa6,0x34,0x4c,0xb9,0x31,0x65,0x5c,0x6b,0xaa,0x96,0x97,0x96,0x58,0xab,0x48,0xab,
0x51,0xab,0x47,0xeb,0xbd,0x36,0xae,0xed,0xa7,0x9d,0xa6,0xbd,0x45,0xbb,0x59,0xfb,
0x81,0xe,0x41,0xc7,0x4a,0x27,0x5c,0x27,0x47,0x67,0x8f,0xce,0x5,0x9d,0xe7,0x53,
0xd9,0x53,0xdd,0xa7,0xa,0xa7,0x16,0x4d,0x3d,0x3a,0xf5,0xae,0x2e,0xaa,0x6b,0xa5,
0x1b,0xa1,0xbb,0x44,0x77,0xbf,0x6e,0xa7,0xee,0x98,0x9e,0xbe,0x5e,0x80,0x9e,0x4c,
0x6f,0xa7,0xde,0x79,0xbd,0xe7,0xfa,0x1c,0x7d,0x2f,0xfd,0x54,0xfd,0x6d,0xfa,0xa7,
0xf5,0x47,0xc,0x58,0x6,0xb3,0xc,0x24,0x6,0xdb,0xc,0xce,0x18,0x3c,0xc5,0x35,
0x71,0x6f,0x3c,0x1d,0x2f,0xc7,0xdb,0xf1,0x51,0x43,0x5d,0xc3,0x40,0x43,0xa5,0x61,
0x95,0x61,0x97,0xe1,0x84,0x91,0xb9,0xd1,0x3c,0xa3,0xd5,0x46,0x8d,0x46,0xf,0x8c,
0x69,0xc6,0x5c,0xe3,0x24,0xe3,0x6d,0xc6,0x6d,0xc6,0xa3,0x26,0x6,0x26,0x21,0x26,
0x4b,0x4d,0xea,0x4d,0xee,0x9a,0x52,0x4d,0xb9,0xa6,0x29,0xa6,0x3b,0x4c,0x3b,0x4c,
0xc7,0xcd,0xcc,0xcd,0xa2,0xcd,0xd6,0x99,0x35,0x9b,0x3d,0x31,0xd7,0x32,0xe7,0x9b,
0xe7,0x9b,0xd7,0x9b,0xdf,0xb7,0x60,0x5a,0x78,0x5a,0x2c,0xb6,0xa8,0xb6,0xb8,0x65,
0x49,0xb2,0xe4,0x5a,0xa6,0x59,0xee,0xb6,0xbc,0x6e,0x85,0x5a,0x39,0x59,0xa5,0x58,
0x55,0x5a,0x5d,0xb3,0x46,0xad,0x9d,0xad,0x25,0xd6,0xbb,0xad,0xbb,0xa7,0x11,0xa7,
0xb9,0x4e,0x93,0x4e,0xab,0x9e,0xd6,0x67,0xc3,0xb0,0xf1,0xb6,0xc9,0xb6,0xa9,0xb7,
0x19,0xb0,0xe5,0xd8,0x6,0xdb,0xae,0xb6,0x6d,0xb6,0x7d,0x61,0x67,0x62,0x17,0x67,
0xb7,0xc5,0xae,0xc3,0xee,0x93,0xbd,0x93,0x7d,0xba,0x7d,0x8d,0xfd,0x3d,0x7,0xd,
0x87,0xd9,0xe,0xab,0x1d,0x5a,0x1d,0x7e,0x73,0xb4,0x72,0x14,0x3a,0x56,0x3a,0xde,
0x9a,0xce,0x9c,0xee,0x3f,0x7d,0xc5,0xf4,0x96,0xe9,0x2f,0x67,0x58,0xcf,0x10,0xcf,
0xd8,0x33,0xe3,0xb6,0x13,0xcb,0x29,0xc4,0x69,0x9d,0x53,0x9b,0xd3,0x47,0x67,0x17,
0x67,0xb9,0x73,0x83,0xf3,0x88,0x8b,0x89,0x4b,0x82,0xcb,0x2e,0x97,0x3e,0x2e,0x9b,
0x1b,0xc6,0xdd,0xc8,0xbd,0xe4,0x4a,0x74,0xf5,0x71,0x5d,0xe1,0x7a,0xd2,0xf5,0x9d,
0x9b,0xb3,0x9b,0xc2,0xed,0xa8,0xdb,0xaf,0xee,0x36,0xee,0x69,0xee,0x87,0xdc,0x9f,
0xcc,0x34,0x9f,0x29,0x9e,0x59,0x33,0x73,0xd0,0xc3,0xc8,0x43,0xe0,0x51,0xe5,0xd1,
0x3f,0xb,0x9f,0x95,0x30,0x6b,0xdf,0xac,0x7e,0x4f,0x43,0x4f,0x81,0x67,0xb5,0xe7,
0x23,0x2f,0x63,0x2f,0x91,0x57,0xad,0xd7,0xb0,0xb7,0xa5,0x77,0xaa,0xf7,0x61,0xef,
0x17,0x3e,0xf6,0x3e,0x72,0x9f,0xe3,0x3e,0xe3,0x3c,0x37,0xde,0x32,0xde,0x59,0x5f,
0xcc,0x37,0xc0,0xb7,0xc8,0xb7,0xcb,0x4f,0xc3,0x6f,0x9e,0x5f,0x85,0xdf,0x43,0x7f,
0x23,0xff,0x64,0xff,0x7a,0xff,0xd1,0x0,0xa7,0x80,0x25,0x1,0x67,0x3,0x89,0x81,
0x41,0x81,0x5b,0x2,0xfb,0xf8,0x7a,0x7c,0x21,0xbf,0x8e,0x3f,0x3a,0xdb,0x65,0xf6,
0xb2,0xd9,0xed,0x41,0x8c,0xa0,0xb9,0x41,0x15,0x41,0x8f,0x82,0xad,0x82,0xe5,0xc1,
0xad,0x21,0x68,0xc8,0xec,0x90,0xad,0x21,0xf7,0xe7,0x98,0xce,0x91,0xce,0x69,0xe,
0x85,0x50,0x7e,0xe8,0xd6,0xd0,0x7,0x61,0xe6,0x61,0x8b,0xc3,0x7e,0xc,0x27,0x85,
0x87,0x85,0x57,0x86,0x3f,0x8e,0x70,0x88,0x58,0x1a,0xd1,0x31,0x97,0x35,0x77,0xd1,
0xdc,0x43,0x73,0xdf,0x44,0xfa,0x44,0x96,0x44,0xde,0x9b,0x67,0x31,0x4f,0x39,0xaf,
0x2d,0x4a,0x35,0x2a,0x3e,0xaa,0x2e,0x6a,0x3c,0xda,0x37,0xba,0x34,0xba,0x3f,0xc6,
0x2e,0x66,0x59,0xcc,0xd5,0x58,0x9d,0x58,0x49,0x6c,0x4b,0x1c,0x39,0x2e,0x2a,0xae,
0x36,0x6e,0x6c,0xbe,0xdf,0xfc,0xed,0xf3,0x87,0xe2,0x9d,0xe2,0xb,0xe3,0x7b,0x17,
0x98,0x2f,0xc8,0x5d,0x70,0x79,0xa1,0xce,0xc2,0xf4,0x85,0xa7,0x16,0xa9,0x2e,0x12,
0x2c,0x3a,0x96,0x40,0x4c,0x88,0x4e,0x38,0x94,0xf0,0x41,0x10,0x2a,0xa8,0x16,0x8c,
0x25,0xf2,0x13,0x77,0x25,0x8e,0xa,0x79,0xc2,0x1d,0xc2,0x67,0x22,0x2f,0xd1,0x36,
0xd1,0x88,0xd8,0x43,0x5c,0x2a,0x1e,0x4e,0xf2,0x48,0x2a,0x4d,0x7a,0x92,0xec,0x91,
0xbc,0x35,0x79,0x24,0xc5,0x33,0xa5,0x2c,0xe5,0xb9,0x84,0x27,0xa9,0x90,0xbc,0x4c,
0xd,0x4c,0xdd,0x9b,0x3a,0x9e,0x16,0x9a,0x76,0x20,0x6d,0x32,0x3d,0x3a,0xbd,0x31,
0x83,0x92,0x91,0x90,0x71,0x42,0xaa,0x21,0x4d,0x93,0xb6,0x67,0xea,0x67,0xe6,0x66,
0x76,0xcb,0xac,0x65,0x85,0xb2,0xfe,0xc5,0x6e,0x8b,0xb7,0x2f,0x1e,0x95,0x7,0xc9,
0x6b,0xb3,0x90,0xac,0x5,0x59,0x2d,0xa,0xb6,0x42,0xa6,0xe8,0x54,0x5a,0x28,0xd7,
0x2a,0x7,0xb2,0x67,0x65,0x57,0x66,0xbf,0xcd,0x89,0xca,0x39,0x96,0xab,0x9e,0x2b,
0xcd,0xed,0xcc,0xb3,0xca,0xdb,0x90,0x37,0x9c,0xef,0x9f,0xff,0xed,0x12,0xc2,0x12,
0xe1,0x92,0xb6,0xa5,0x86,0x4b,0x57,0x2d,0x1d,0x58,0xe6,0xbd,0xac,0x6a,0x39,0xb2,
0x3c,0x71,0x79,0xdb,0xa,0xe3,0x15,0x5,0x2b,0x86,0x56,0x6,0xac,0x3c,0xb8,0x8a,
0xb6,0x2a,0x6d,0xd5,0x4f,0xab,0xed,0x57,0x97,0xae,0x7e,0xbd,0x26,0x7a,0x4d,0x6b,
0x81,0x5e,0xc1,0xca,0x82,0xc1,0xb5,0x1,0x6b,0xeb,0xb,0x55,0xa,0xe5,0x85,0x7d,
0xeb,0xdc,0xd7,0xed,0x5d,0x4f,0x58,0x2f,0x59,0xdf,0xb5,0x61,0xfa,0x86,0x9d,0x1b,
0x3e,0x15,0x89,0x8a,0xae,0x14,0xdb,0x17,0x97,0x15,0x7f,0xd8,0x28,0xdc,0x78,0xe5,
0x1b,0x87,0x6f,0xca,0xbf,0x99,0xdc,0x94,0xb4,0xa9,0xab,0xc4,0xb9,0x64,0xcf,0x66,
0xd2,0x66,0xe9,0xe6,0xde,0x2d,0x9e,0x5b,0xe,0x96,0xaa,0x97,0xe6,0x97,0xe,0x6e,
0xd,0xd9,0xda,0xb4,0xd,0xdf,0x56,0xb4,0xed,0xf5,0xf6,0x45,0xdb,0x2f,0x97,0xcd,
0x28,0xdb,0xbb,0x83,0xb6,0x43,0xb9,0xa3,0xbf,0x3c,0xb8,0xbc,0x65,0xa7,0xc9,0xce,
0xcd,0x3b,0x3f,0x54,0xa4,0x54,0xf4,0x54,0xfa,0x54,0x36,0xee,0xd2,0xdd,0xb5,0x61,
0xd7,0xf8,0x6e,0xd1,0xee,0x1b,0x7b,0xbc,0xf6,0x34,0xec,0xd5,0xdb,0x5b,0xbc,0xf7,
0xfd,0x3e,0xc9,0xbe,0xdb,0x55,0x1,0x55,0x4d,0xd5,0x66,0xd5,0x65,0xfb,0x49,0xfb,
0xb3,0xf7,0x3f,0xae,0x89,0xaa,0xe9,0xf8,0x96,0xfb,0x6d,0x5d,0xad,0x4e,0x6d,0x71,
0xed,0xc7,0x3,0xd2,0x3,0xfd,0x7,0x23,0xe,0xb6,0xd7,0xb9,0xd4,0xd5,0x1d,0xd2,
0x3d,0x54,0x52,0x8f,0xd6,0x2b,0xeb,0x47,0xe,0xc7,0x1f,0xbe,0xfe,0x9d,0xef,0x77,
0x2d,0xd,0x36,0xd,0x55,0x8d,0x9c,0xc6,0xe2,0x23,0x70,0x44,0x79,0xe4,0xe9,0xf7,
0x9,0xdf,0xf7,0x1e,0xd,0x3a,0xda,0x76,0x8c,0x7b,0xac,0xe1,0x7,0xd3,0x1f,0x76,
0x1d,0x67,0x1d,0x2f,0x6a,0x42,0x9a,0xf2,0x9a,0x46,0x9b,0x53,0x9a,0xfb,0x5b,0x62,
0x5b,0xba,0x4f,0xcc,0x3e,0xd1,0xd6,0xea,0xde,0x7a,0xfc,0x47,0xdb,0x1f,0xf,0x9c,
0x34,0x3c,0x59,0x79,0x4a,0xf3,0x54,0xc9,0x69,0xda,0xe9,0x82,0xd3,0x93,0x67,0xf2,
0xcf,0x8c,0x9d,0x95,0x9d,0x7d,0x7e,0x2e,0xf9,0xdc,0x60,0xdb,0xa2,0xb6,0x7b,0xe7,
0x63,0xce,0xdf,0x6a,0xf,0x6f,0xef,0xba,0x10,0x74,0xe1,0xd2,0x45,0xff,0x8b,0xe7,
0x3b,0xbc,0x3b,0xce,0x5c,0xf2,0xb8,0x74,0xf2,0xb2,0xdb,0xe5,0x13,0x57,0xb8,0x57,
0x9a,0xaf,0x3a,0x5f,0x6d,0xea,0x74,0xea,0x3c,0xfe,0x93,0xd3,0x4f,0xc7,0xbb,0x9c,
0xbb,0x9a,0xae,0xb9,0x5c,0x6b,0xb9,0xee,0x7a,0xbd,0xb5,0x7b,0x66,0xf7,0xe9,0x1b,
0x9e,0x37,0xce,0xdd,0xf4,0xbd,0x79,0xf1,0x16,0xff,0xd6,0xd5,0x9e,0x39,0x3d,0xdd,
0xbd,0xf3,0x7a,0x6f,0xf7,0xc5,0xf7,0xf5,0xdf,0x16,0xdd,0x7e,0x72,0x27,0xfd,0xce,
0xcb,0xbb,0xd9,0x77,0x27,0xee,0xad,0xbc,0x4f,0xbc,0x5f,0xf4,0x40,0xed,0x41,0xd9,
0x43,0xdd,0x87,0xd5,0x3f,0x5b,0xfe,0xdc,0xd8,0xef,0xdc,0x7f,0x6a,0xc0,0x77,0xa0,
0xf3,0xd1,0xdc,0x47,0xf7,0x6,0x85,0x83,0xcf,0xfe,0x91,0xf5,0x8f,0xf,0x43,0x5,
0x8f,0x99,0x8f,0xcb,0x86,0xd,0x86,0xeb,0x9e,0x38,0x3e,0x39,0x39,0xe2,0x3f,0x72,
0xfd,0xe9,0xfc,0xa7,0x43,0xcf,0x64,0xcf,0x26,0x9e,0x17,0xfe,0xa2,0xfe,0xcb,0xae,
0x17,0x16,0x2f,0x7e,0xf8,0xd5,0xeb,0xd7,0xce,0xd1,0x98,0xd1,0xa1,0x97,0xf2,0x97,
0x93,0xbf,0x6d,0x7c,0xa5,0xfd,0xea,0xc0,0xeb,0x19,0xaf,0xdb,0xc6,0xc2,0xc6,0x1e,
0xbe,0xc9,0x78,0x33,0x31,0x5e,0xf4,0x56,0xfb,0xed,0xc1,0x77,0xdc,0x77,0x1d,0xef,
0xa3,0xdf,0xf,0x4f,0xe4,0x7c,0x20,0x7f,0x28,0xff,0x68,0xf9,0xb1,0xf5,0x53,0xd0,
0xa7,0xfb,0x93,0x19,0x93,0x93,0xff,0x4,0x3,0x98,0xf3,0xfc,0x63,0x33,0x2d,0xdb,
0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a,0x25,0x0,0x0,0x80,0x83,
0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75,0x30,0x0,0x0,0xea,0x60,
0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5,0x46,0x0,0x0,0x14,0x71,
0x49,0x44,0x41,0x54,0x78,0xda,0xec,0x9d,0x7b,0x6c,0x94,0x55,0xde,0xc7,0xbf,0xcf,
0x5c,0x5a,0x5a,0xda,0xe9,0xb4,0xe,0xb4,0x40,0x4b,0xa1,0x90,0x6c,0xd8,0x40,0x55,
0xd8,0x17,0x6a,0x49,0x5c,0x1b,0xf0,0x82,0x2c,0xb8,0x8b,0x6b,0x94,0xb0,0x8a,0x60,
0x5c,0xf1,0x65,0x95,0x18,0x75,0xff,0x40,0x36,0x31,0x28,0x9b,0xc8,0x22,0x21,0xe2,
0xee,0xa2,0x89,0xaf,0x64,0xb3,0x8,0x55,0x76,0xdf,0x0,0x6b,0x61,0x17,0x61,0x9,
0x5e,0x2,0x12,0x62,0x40,0x10,0x34,0xd9,0xca,0xdb,0xb,0xbd,0xd1,0x2b,0x2d,0x6d,
0x67,0xe6,0x9c,0xdf,0xfb,0xc7,0x3c,0xcf,0x33,0x33,0x58,0xa0,0x85,0x4e,0x2f,0x4f,
0xbf,0x1f,0x33,0x74,0x2e,0x67,0x66,0x1e,0xe7,0x7c,0xbf,0xe7,0xfc,0x7e,0xe7,0x9c,
0xe7,0x3c,0x86,0x88,0x80,0x90,0x91,0x8a,0x8b,0x3f,0x1,0xa1,0x1,0x8,0xa1,0x1,
0x8,0xa1,0x1,0x8,0xa1,0x1,0x8,0xa1,0x1,0x8,0xa1,0x1,0x8,0xa1,0x1,0x8,
0xa1,0x1,0x8,0xa1,0x1,0x8,0xa1,0x1,0x8,0xa1,0x1,0x8,0xa1,0x1,0x8,0xa1,
0x1,0x8,0xa1,0x1,0x8,0xa1,0x1,0x8,0xa1,0x1,0x8,0xa1,0x1,0x8,0xa1,0x1,
0x8,0xa1,0x1,0x8,0x19,0xd2,0x78,0x12,0xf1,0xa1,0x25,0x25,0x25,0xd6,0xdd,0x34,
0x0,0xcf,0x2,0x78,0xc,0xc0,0x64,0x0,0x6,0x7f,0x72,0xa2,0x45,0x0,0x11,0xc8,
0xf,0x6e,0x1a,0x5a,0xb,0x44,0x44,0x89,0x96,0xb,0x5a,0xa4,0x54,0xa9,0xf0,0x9f,
0xb5,0xd6,0xed,0x0,0x70,0xea,0xd4,0xa9,0xe1,0x61,0x0,0x93,0x9,0x0,0xf6,0x3,
0x98,0xc1,0x2a,0x27,0x0,0x0,0x1,0x44,0x34,0x4,0x62,0xde,0x17,0x68,0x11,0x88,
0x8e,0x88,0x5f,0x44,0x4c,0x3,0x68,0x88,0xd6,0xb7,0x69,0x91,0x59,0x0,0x1e,0x7,
0xb0,0x40,0x44,0xaa,0x87,0x53,0x8,0x94,0xe,0xe0,0x20,0xc5,0x4f,0x6c,0xed,0x5b,
0x62,0xb7,0xee,0x6b,0xd,0xd1,0x3a,0x2a,0x7e,0x6d,0x3e,0x27,0x1a,0xda,0x2c,0xab,
0x45,0x43,0x6b,0x3d,0x43,0x8b,0x1c,0x54,0x4a,0xa5,0xf,0x27,0x3,0x3c,0xb,0x60,
0x1a,0xab,0x9d,0x58,0x4d,0xbf,0x29,0x7d,0x88,0x44,0x5a,0x7f,0xb3,0x43,0x0,0x44,
0x47,0x7b,0x5,0x48,0xc4,0x14,0xa6,0x9,0x22,0xe6,0x10,0x88,0xd6,0xd3,0x44,0xe4,
0xd9,0xe1,0x64,0x80,0xe5,0xac,0x74,0x12,0xd,0x7b,0x22,0xa2,0xd7,0xb1,0xf1,0xbe,
0xd6,0xd0,0xda,0x6c,0xed,0xcd,0xd6,0x5f,0x2b,0xb3,0x97,0x50,0x62,0xf7,0xe,0xda,
0x2c,0x27,0x5a,0x3f,0x39,0x6c,0x92,0x60,0x0,0xe3,0x58,0xf3,0x24,0xa2,0x7f,0x6d,
0x8a,0xde,0x34,0x82,0x8e,0x86,0x37,0x10,0x44,0x5a,0x79,0x1d,0xe9,0x23,0xcc,0x90,
0x27,0x26,0x44,0x8a,0x79,0x4e,0xeb,0x9c,0xe1,0x64,0x0,0xe,0xaf,0x92,0x98,0xd1,
0x1d,0x4b,0xfc,0x91,0x50,0xc7,0xea,0x11,0xc4,0x34,0x82,0x40,0xc7,0xf7,0xe,0xe6,
0x4d,0x8b,0x8e,0xb9,0x2f,0xae,0xe1,0x64,0x80,0x3e,0x6d,0x38,0x1a,0xe,0x87,0x11,
0xa,0x85,0xa0,0xb5,0xa6,0x6a,0x1c,0x14,0xf6,0xd8,0xff,0x99,0xb1,0xbc,0x56,0xda,
0xcc,0x7,0x0,0x8f,0xd7,0x3,0xb7,0xdb,0x6d,0x87,0x40,0x10,0x2b,0xdc,0xb1,0x86,
0x43,0xe3,0x7b,0x3,0xad,0xb5,0xc,0x27,0x3,0xdc,0x10,0xc3,0x88,0x4c,0x9,0x34,
0x35,0x35,0xc1,0xed,0x76,0x63,0xcc,0x98,0x31,0xf0,0x7a,0xbd,0x14,0x8f,0x3,0x5a,
0x7d,0x40,0xa0,0x23,0xc3,0x3d,0x66,0xeb,0x1f,0x1d,0xe2,0x84,0x8,0xba,0x83,0xdd,
0xa8,0xad,0xad,0x45,0x28,0x14,0x42,0xd6,0x6d,0xb7,0xc5,0x88,0x3f,0x46,0xf4,0x91,
0xa1,0x50,0xd3,0x20,0x3a,0x61,0x8d,0xa3,0x67,0xb0,0xc4,0xaf,0x94,0x42,0x43,0x43,
0x3,0xe6,0xce,0x9d,0x8b,0x85,0xb,0x17,0xa2,0xa8,0xa8,0x8,0x69,0x69,0x69,0x54,
0x90,0xe3,0xc,0x1,0x18,0x66,0xab,0x6f,0xd1,0xde,0xde,0x8e,0xcf,0x3e,0xfb,0xc,
0xbb,0x77,0xef,0x96,0x23,0x47,0x8e,0x18,0x63,0xc7,0x8e,0x85,0x61,0x18,0xf1,0x21,
0x90,0x9d,0x2b,0x44,0x7b,0x90,0x84,0x68,0x31,0x11,0x1f,0x5c,0x52,0x52,0xd2,0xc,
0xc0,0x7f,0x3d,0x3,0xd4,0xd6,0xd6,0x62,0xc9,0x92,0x25,0x78,0xfd,0xf5,0xd7,0xa9,
0x92,0x11,0x1c,0x2a,0x3d,0xbf,0xe6,0xf9,0xf0,0x8e,0xf,0x76,0xb8,0xc7,0x8f,0x1f,
0x6f,0xe8,0xb0,0x8a,0x19,0x19,0xd2,0x50,0x71,0x9,0xb1,0x6e,0xa9,0xa8,0xa8,0xc8,
0x74,0x44,0xb2,0xda,0xd4,0xd4,0x84,0xd9,0xb3,0x67,0x53,0xfc,0x23,0x1d,0x3,0x78,
0xeb,0xad,0xb7,0x5c,0x45,0x73,0xee,0x52,0xf5,0x75,0xf5,0x22,0x22,0x50,0xb1,0xa1,
0x50,0xcc,0x4d,0x6b,0xe5,0x8c,0xd1,0x9a,0x70,0x38,0xc,0xc3,0x30,0xb0,0x74,0xe9,
0x52,0xa,0x80,0x0,0x80,0xeb,0x89,0x27,0x1e,0xbf,0xa2,0x94,0xa,0x75,0x7,0x83,
0x71,0xeb,0x82,0xac,0xbc,0xc1,0x1a,0xd,0x72,0x84,0x1,0x42,0xa1,0x10,0x72,0x72,
0x72,0x30,0x73,0xe6,0x4c,0x56,0x3d,0x1,0x0,0xfc,0xf4,0xa7,0x3f,0x4d,0x99,0x30,
0x61,0x82,0xa7,0xb3,0xb3,0xd3,0x9c,0x10,0x33,0x27,0xc5,0xb4,0x86,0x68,0x15,0xc9,
0x7,0x54,0x62,0xc,0x30,0xe0,0x49,0xb0,0xd6,0x1a,0x5e,0xaf,0x97,0x9,0x2f,0xb1,
0xf1,0xf9,0x7c,0xde,0xa4,0xa4,0x24,0x28,0xa5,0xe2,0x46,0x81,0xec,0xb5,0x41,0x66,
0x2f,0xe0,0x8,0x3,0x44,0x46,0x6,0x4,0x4a,0x29,0xd6,0x3c,0xb1,0xc3,0x62,0xa5,
0x54,0x74,0x32,0xcc,0x9e,0x5,0x8e,0x9f,0x10,0x73,0x8c,0x1,0x8,0xb9,0x1a,0x2b,
0xf9,0x55,0x5a,0xdb,0xf3,0x2,0xa2,0x23,0xb3,0xc4,0xd6,0x9a,0x20,0x1a,0x80,0x38,
0x16,0x31,0x63,0x7f,0x6b,0x35,0xa8,0x12,0x1,0x62,0xc2,0x1f,0x1a,0x80,0x38,0xdb,
0x0,0xd6,0xb2,0x68,0xad,0xa1,0x23,0x4b,0x47,0xa1,0x44,0x22,0xeb,0x84,0xcc,0x90,
0x88,0x6,0x20,0x8e,0xc5,0x1a,0xf5,0xb1,0x97,0x3e,0xc4,0xe4,0x2,0x56,0x1e,0x40,
0x3,0x10,0xe7,0x1a,0x20,0x66,0x1,0x5c,0xec,0x82,0xb8,0x48,0x32,0xac,0x90,0xa0,
0xe,0x80,0x6,0x20,0x43,0x25,0x4,0x12,0x7b,0x65,0xa8,0x88,0x8a,0xb6,0xfc,0x30,
0xcf,0x17,0xe0,0x28,0x10,0x71,0x74,0xf,0xa0,0x75,0xfc,0xe9,0x90,0xd6,0x48,0x90,
0xbd,0x32,0x94,0x6,0x20,0xe,0x6e,0xfd,0x45,0xf7,0x78,0xe,0x40,0xcc,0xa9,0x94,
0xcc,0x1,0x88,0xa3,0x73,0x80,0x98,0xf3,0x7f,0x11,0x7b,0x1e,0xb1,0x36,0x4f,0x9c,
0x67,0xe,0x40,0x9c,0x1e,0x2,0xc5,0x9e,0xe,0x69,0x8e,0x4,0x21,0x66,0xaf,0x20,
0x1a,0xa0,0x9f,0x7e,0xe8,0xe6,0xe6,0x66,0x9c,0x3a,0x75,0xa,0xe7,0xcf,0x9f,0x47,
0x4d,0x4d,0xd,0x2e,0x5f,0xbe,0x8c,0xae,0xae,0x2e,0x28,0xa5,0xe0,0xf1,0x78,0x90,
0x9c,0x9c,0xc,0xaf,0xd7,0x8b,0xac,0xac,0x2c,0xe4,0xe7,0xe7,0x63,0xda,0xb4,0x69,
0x98,0x3a,0x75,0x2a,0xd2,0xd3,0xd3,0xa9,0xd4,0x44,0x85,0x41,0xd6,0xe,0x10,0x12,
0xbb,0x57,0x10,0xcc,0xd6,0x5f,0x98,0x3,0xdc,0x2a,0x65,0x65,0x65,0x38,0x7e,0xfc,
0x38,0xe,0x1c,0x38,0x80,0x6f,0xbf,0xfd,0x16,0xad,0xad,0xad,0xbd,0x7e,0xaf,0xdb,
0xed,0x46,0x20,0x10,0xc0,0xac,0x59,0xb3,0x30,0x6f,0xde,0x3c,0x14,0x15,0x15,0xa1,
0xb8,0xb8,0x98,0xaa,0xed,0x4f,0x3,0x20,0xfe,0x4,0xfa,0x48,0x4,0x14,0x3d,0x89,
0x3e,0x41,0x11,0x90,0xb3,0xd,0x50,0x5b,0x5b,0x8b,0xf7,0xdf,0x7f,0x1f,0x7f,0xfd,
0xeb,0x5f,0xf1,0xcd,0x37,0xdf,0xdc,0xf4,0xe7,0x28,0xa5,0x50,0x57,0x57,0x87,0xb2,
0xb2,0x32,0x94,0x95,0x95,0x1,0x0,0x8a,0x8a,0x8a,0xb0,0x7c,0xf9,0x72,0x3c,0xf1,
0xc4,0x13,0x48,0x4d,0x4d,0xa5,0x82,0xfb,0xa1,0x67,0x6,0x0,0x51,0x11,0xd1,0xc7,
0x85,0x44,0x3a,0x32,0x23,0x9c,0x8,0x1c,0xb9,0x7d,0xc9,0xe5,0xcb,0x97,0xb1,0x61,
0xc3,0x6,0x14,0x16,0x16,0x62,0xed,0xda,0xb5,0xb7,0x24,0xfe,0x6b,0x71,0xec,0xd8,
0x31,0x3c,0xfb,0xec,0xb3,0xb8,0xf3,0xce,0x3b,0xf1,0xd6,0x5b,0x6f,0x51,0xc1,0xb7,
0x6c,0x0,0x31,0x93,0x61,0x7b,0x83,0xdc,0xe8,0xd,0xe,0x3a,0x21,0x26,0xd1,0x7c,
0xfc,0xf1,0xc7,0x98,0x3d,0x7b,0x36,0xd6,0xad,0x5b,0x87,0x86,0x86,0x86,0x84,0x7f,
0xdf,0x77,0xdf,0x7d,0x87,0x35,0x6b,0xd6,0xe0,0xee,0xbb,0xef,0xc6,0xc9,0x93,0x27,
0xa9,0xe4,0x5b,0x8,0x82,0x0,0x44,0xcf,0x6,0xd3,0x62,0xef,0xa,0x61,0xe6,0xc2,
0x34,0xc0,0x8d,0x78,0xf1,0xc5,0x17,0xf1,0xb3,0x9f,0xfd,0xc,0xe7,0xcf,0x9f,0x1f,
0xf0,0xef,0xfe,0xf4,0xd3,0x4f,0xf1,0x93,0x9f,0xfc,0x4,0x9b,0x36,0x6d,0xa2,0x96,
0x6f,0x2a,0x9,0x36,0x43,0xa0,0xd8,0x3d,0x85,0xec,0xad,0x55,0x84,0x33,0xc1,0xd7,
0xa3,0xae,0xae,0xe,0x4b,0x96,0x2c,0xc1,0x17,0x5f,0x7c,0x31,0x28,0xdf,0x6f,0x18,
0x6,0x5c,0x2e,0x17,0x94,0x52,0x78,0xf9,0xe5,0x97,0x51,0x53,0x53,0x83,0x37,0xdf,
0x7c,0x93,0xaa,0xee,0x4b,0x8,0x64,0xa,0x3c,0x92,0xb,0x58,0x3b,0x49,0xeb,0xe8,
0xde,0xa2,0x4c,0x82,0x7b,0xa6,0xaa,0xaa,0xa,0xb,0x16,0x2c,0xc0,0x99,0x33,0x67,
0x6,0x55,0xfc,0x2e,0x97,0xb,0x5e,0xaf,0x17,0x5a,0x6b,0x6c,0xde,0xbc,0x19,0x1d,
0x1d,0x1d,0xd8,0xb6,0x6d,0x1b,0x95,0xdd,0x9b,0xd6,0x3f,0x56,0xe4,0x66,0xeb,0x6f,
0x6d,0xaa,0x85,0x4,0x8a,0x7f,0xd8,0x1b,0xa0,0xbe,0xbe,0x1e,0xf7,0xdc,0x73,0xf,
0xfe,0xf3,0x9f,0xff,0xc,0x9a,0xf8,0x63,0xd,0x60,0x99,0xc0,0x30,0xc,0xbc,0xf3,
0xce,0x3b,0xf0,0xf9,0x7c,0xd8,0xb8,0x71,0x23,0x15,0xde,0x8b,0xf8,0xdf,0x1a,0xe7,
0x8f,0xe,0x87,0x4a,0xc2,0xc5,0x3f,0xac,0x73,0x80,0xf6,0xf6,0x76,0xdc,0x7b,0xef,
0xbd,0x83,0x2a,0x7e,0x97,0xcb,0x5,0xb7,0xdb,0x1d,0xf7,0xd7,0xe5,0x72,0x21,0x2d,
0x2d,0xd,0x3e,0x9f,0xf,0x7f,0xf8,0xc3,0x1f,0xf0,0xf6,0xdb,0x6f,0x53,0xdf,0xbd,
0xb2,0x80,0x99,0x3,0xe8,0xc4,0xee,0x4,0xe7,0x98,0x1e,0xe0,0xc9,0x27,0x9f,0xc4,
0xe9,0xd3,0xa7,0xfb,0xe5,0xb3,0xf2,0xf2,0xf2,0x10,0x8,0x4,0x90,0x96,0x96,0x6,
0x11,0xc1,0xe5,0xcb,0x97,0x51,0x5f,0x5f,0x8f,0x9a,0x9a,0x9a,0x1e,0x85,0xf,0x20,
0xae,0xd5,0xbf,0xda,0x4,0x86,0x61,0x20,0x25,0x25,0x5,0x9d,0x9d,0x9d,0xd8,0xb8,
0x71,0x23,0x1e,0x79,0xe4,0x11,0x64,0x67,0x67,0x53,0xe5,0x37,0x8,0x83,0xec,0x1e,
0x0,0x32,0x60,0xdf,0x3b,0x2c,0xd,0xb0,0x65,0xcb,0x16,0xfc,0xed,0x6f,0x7f,0xbb,
0xe9,0xf7,0x4f,0x9a,0x34,0x9,0x25,0x25,0x25,0x58,0xb2,0x64,0x9,0xa6,0x4c,0x99,
0x82,0x9c,0x9c,0x1c,0xf8,0xfd,0x7e,0x5b,0xdc,0x4a,0x29,0x34,0x37,0x37,0xe3,0xe2,
0xc5,0x8b,0xf8,0xfa,0xeb,0xaf,0xb1,0x63,0xc7,0xe,0x7c,0xfe,0xf9,0xe7,0x68,0x6b,
0x6b,0x83,0x88,0xd8,0x62,0x37,0xc,0xe3,0x7,0xe2,0x8f,0xed,0x9,0xac,0xde,0x80,
0x9b,0xfe,0xf6,0xc6,0x0,0x12,0xf7,0x97,0x6,0xb8,0x6,0x27,0x4e,0x9c,0xc0,0xb,
0x2f,0xbc,0x70,0x53,0xef,0xbd,0xfd,0xf6,0xdb,0xb1,0x66,0xcd,0x1a,0x3c,0xfa,0xe8,
0xa3,0xd7,0x9d,0xbd,0xb5,0x96,0x3e,0x4,0x2,0x1,0x14,0x16,0x16,0x62,0xd9,0xb2,
0x65,0x28,0x2f,0x2f,0xc7,0x7b,0xef,0xbd,0x87,0x3f,0xfd,0xe9,0x4f,0x68,0x69,0x69,
0x81,0x52,0xa,0xa3,0x46,0x8d,0xba,0xa6,0x9,0xdc,0x6e,0x37,0x82,0xc1,0x20,0x9e,
0x7b,0xee,0x39,0x64,0x65,0x65,0x51,0xe1,0x37,0xce,0x2,0x6,0xe5,0x7b,0x87,0x5d,
0xe,0xf0,0xcc,0x33,0xcf,0xdc,0xd4,0xfb,0x7e,0xf7,0xbb,0xdf,0xe1,0xf8,0xf1,0xe3,
0x58,0xb1,0x62,0xc5,0x4d,0x2d,0x5d,0x28,0x28,0x28,0xc0,0x86,0xd,0x1b,0x70,0xf2,
0xe4,0x49,0xfc,0xf2,0x97,0xbf,0x84,0x52,0xa,0x1d,0x1d,0x1d,0xf0,0x7a,0xbd,0x3f,
0x10,0xbf,0xc7,0xe3,0xc1,0xa5,0x4b,0x97,0x70,0xd7,0x5d,0x77,0x61,0xe5,0xca,0x95,
0x54,0x77,0x1f,0x7a,0x0,0x1a,0xe0,0x3a,0x6c,0xdd,0xba,0x15,0x5f,0x7d,0xf5,0x55,
0x9f,0xde,0x93,0x94,0x94,0x84,0x3d,0x7b,0xf6,0x60,0xfd,0xfa,0xf5,0x48,0x4e,0x4e,
0xbe,0xe5,0x63,0x28,0x28,0x28,0xc0,0x47,0x1f,0x7d,0x84,0xad,0x5b,0xb7,0x2,0x0,
0x9a,0x9b,0x9b,0xe1,0xf5,0x7a,0xed,0x56,0xdf,0x6a,0xf9,0x45,0xa4,0xdf,0xbe,0x73,
0x84,0x74,0x1,0x34,0xc0,0xf5,0x68,0x6a,0x6a,0xc2,0xba,0x75,0xeb,0xfa,0xf4,0x1e,
0x9f,0xcf,0x87,0xa3,0x47,0x8f,0x62,0xf1,0xe2,0xc5,0xfd,0x7e,0x3c,0xbf,0xf9,0xcd,
0x6f,0x70,0xe0,0xc0,0x1,0x64,0x66,0x66,0xe2,0xd2,0xa5,0x4b,0xf0,0x78,0x3c,0x76,
0xdc,0x5f,0x57,0x57,0x87,0xa7,0x9f,0x7e,0x1a,0xf3,0xe6,0xcd,0xa3,0xb0,0x87,0x38,
0xc3,0xc6,0x0,0xdb,0xb6,0x6d,0x43,0x5b,0x5b,0x5b,0x9f,0xde,0x53,0x5a,0x5a,0x8a,
0x39,0x73,0xe6,0x24,0xec,0x98,0xee,0xbf,0xff,0x7e,0xec,0xdb,0xb7,0xf,0xd9,0xd9,
0xd9,0xa8,0xa9,0xa9,0x81,0xd7,0xeb,0x45,0x63,0x63,0x23,0xa6,0x4c,0x99,0x82,0x57,
0x5e,0x79,0x85,0xea,0xa2,0x1,0xfa,0x87,0x8e,0x8e,0xe,0x6c,0xde,0xbc,0xb9,0x4f,
0xef,0xd9,0xb0,0x61,0x3,0x1e,0x78,0xe0,0x81,0x84,0x1f,0xdb,0xdc,0xb9,0x73,0xf1,
0x8f,0x7f,0xfc,0x3,0xd9,0xd9,0xd9,0xb8,0x70,0xe1,0x2,0x82,0xc1,0x20,0xde,0x7e,
0xfb,0x6d,0xe4,0xe4,0xe4,0x50,0x5d,0xc3,0x80,0x61,0x31,0xa,0x54,0x5a,0x5a,0x8a,
0xc6,0xc6,0xc6,0x3e,0x89,0x72,0xed,0xda,0xb5,0x3,0x76,0x7c,0x33,0x67,0xce,0xc4,
0xd1,0xa3,0x47,0xf1,0xab,0x5f,0xfd,0xa,0xf3,0xe7,0xcf,0x1f,0x10,0xe3,0x91,0x11,
0x64,0x80,0x9d,0x3b,0x77,0xf6,0xa9,0x7c,0x5f,0x7b,0x8b,0xfe,0x60,0xea,0xd4,0xa9,
0x38,0x76,0xec,0x18,0x15,0xc5,0x10,0xa8,0x7f,0xa9,0xa8,0xa8,0xc0,0x27,0x9f,0x7c,
0xd2,0xeb,0xf2,0x8b,0x17,0x2f,0xc6,0xec,0xd9,0xb3,0x59,0xb3,0xc4,0x19,0x6,0xd8,
0xbf,0x7f,0x7f,0x9f,0xca,0x33,0xf9,0x24,0x8e,0x32,0x80,0x75,0xe,0x6e,0x6f,0x98,
0x35,0x6b,0x16,0x5b,0x7f,0xe2,0x1c,0x3,0x74,0x76,0x76,0xf6,0xe9,0x34,0xc3,0x87,
0x1e,0x7a,0x88,0x35,0x4a,0x9c,0x63,0x80,0x33,0x67,0xce,0xa0,0xba,0xba,0xba,0xd7,
0xe5,0xef,0xbb,0xef,0x3e,0xd6,0x28,0x71,0x8e,0x1,0xca,0xcb,0xcb,0x7b,0x5d,0x36,
0x2f,0x2f,0xf,0x77,0xde,0x79,0x27,0x6b,0x94,0x38,0xc7,0x0,0x17,0x2e,0x5c,0xe8,
0x75,0xd9,0xe9,0xd3,0xa7,0x23,0x29,0x29,0x89,0x35,0x4a,0x9c,0x63,0x80,0xef,0xbf,
0xff,0xbe,0xd7,0x65,0x67,0xcc,0x98,0xc1,0xda,0x24,0xce,0x32,0x40,0x65,0x65,0x65,
0xaf,0xcb,0x4e,0x9d,0x3a,0x95,0xb5,0x49,0x9c,0x63,0x0,0x11,0xe9,0xd3,0xc6,0x56,
0x19,0x19,0x19,0xac,0x4d,0xe2,0x1c,0x3,0x28,0xa5,0xd0,0xd5,0xd5,0xd5,0xeb,0xf2,
0xdc,0x9f,0x93,0x38,0xca,0x0,0xe1,0x70,0x18,0xdd,0xdd,0xdd,0xbd,0x2e,0xcf,0xf3,
0x6e,0x89,0xe3,0x42,0xa0,0x60,0x30,0xd8,0xfb,0xff,0x11,0x97,0x8b,0xb5,0x49,0x9c,
0x63,0x0,0xc3,0x30,0xfa,0xd4,0xaa,0x87,0xc3,0x61,0xd6,0x26,0x71,0x8e,0x1,0xdc,
0x6e,0x77,0x9f,0xc6,0xf5,0xfb,0x12,0x2e,0x11,0xe2,0x38,0x3,0x5c,0xb9,0x72,0x85,
0xb5,0x49,0x9c,0x63,0x0,0x97,0xcb,0x85,0xcc,0xcc,0xcc,0x5e,0x97,0x6f,0x6a,0x6a,
0x62,0x6d,0x12,0xe7,0x18,0x0,0x0,0x26,0x4c,0x98,0xd0,0xeb,0xb2,0xe7,0xce,0x9d,
0x63,0x6d,0x12,0x67,0x19,0x20,0x3f,0x3f,0xbf,0xd7,0x65,0xcf,0x9e,0x3d,0xcb,0xda,
0x24,0xce,0x32,0x40,0x41,0x41,0xc1,0xd,0xcb,0x58,0xfb,0x79,0x9e,0x3f,0x7f,0xbe,
0xcf,0xdb,0xa6,0x10,0x32,0xa4,0xd,0x30,0x71,0xe2,0xc4,0x1b,0x8a,0xdf,0x1a,0xff,
0xaf,0xaf,0xaf,0xe7,0x49,0xe9,0xc4,0x59,0x6,0x28,0x2c,0x2c,0xbc,0xe6,0xc5,0xa9,
0x63,0x2f,0x4e,0xe1,0xf5,0x7a,0x21,0x22,0x38,0x7c,0xf8,0x30,0x6b,0x94,0x38,0xc7,
0x0,0x63,0xc6,0x8c,0x41,0x61,0x61,0xe1,0x35,0x5b,0x7e,0x6b,0x43,0x5a,0x6b,0xc2,
0xec,0xc0,0x81,0x3,0x8,0x85,0x42,0xac,0x55,0xe2,0xc,0x3,0x0,0x40,0x49,0x49,
0x49,0x8f,0xe2,0xbf,0xfa,0xe2,0x14,0x69,0x69,0x69,0x38,0x75,0xea,0x14,0x7b,0x1,
0xe2,0x2c,0x3,0xc4,0x6e,0x6c,0x7b,0xf5,0x35,0xb9,0x62,0xb7,0x24,0xb7,0x26,0xcd,
0xac,0x5d,0x9b,0x9,0x71,0x84,0x1,0xee,0xb8,0xe3,0xe,0xfc,0xe8,0x47,0x3f,0x8a,
0x1c,0x6c,0xf,0x57,0x62,0x89,0xbd,0x22,0x4b,0x66,0x66,0x26,0xca,0xca,0xca,0x70,
0xf0,0xe0,0xc1,0x41,0x3b,0xde,0xc1,0xda,0xe7,0x9e,0x38,0xd4,0x0,0x5e,0xaf,0x17,
0x8f,0x3c,0xf2,0x48,0xf4,0x80,0xaf,0x63,0x82,0x94,0x94,0x14,0x78,0x3c,0x1e,0x6c,
0xd8,0xb0,0x1,0x4a,0xa9,0x1,0x3d,0xce,0x70,0x38,0x8c,0x47,0x1f,0x7d,0x14,0x8f,
0x3d,0xf6,0x18,0x55,0x45,0x3,0xf4,0x2f,0xcb,0x97,0x2f,0x87,0xdb,0xed,0x86,0x52,
0xea,0x9a,0xe2,0xb7,0xae,0xd9,0x95,0x9d,0x9d,0x8d,0xa3,0x47,0x8f,0xe2,0xf5,0xd7,
0x5f,0x1f,0xb0,0xe3,0xb,0x6,0x83,0x78,0xf8,0xe1,0x87,0xf1,0xe1,0x87,0x1f,0xe2,
0xc3,0xf,0x3f,0xc4,0xfa,0xf5,0xeb,0xa9,0x2c,0x1a,0xa0,0xff,0x98,0x3a,0x75,0x2a,
0x96,0x2d,0x5b,0x6,0x0,0xf0,0x78,0x3c,0xd7,0xd,0x83,0x3c,0x1e,0xf,0x72,0x72,
0x72,0xf0,0xc6,0x1b,0x6f,0xe0,0xef,0x7f,0xff,0x7b,0xc2,0x8f,0xad,0xba,0xba,0x1a,
0x8b,0x16,0x2d,0xc2,0xde,0xbd,0x7b,0x91,0x9f,0x9f,0x8f,0x9c,0x9c,0x1c,0xbc,0xf6,
0xda,0x6b,0xd8,0xbb,0x77,0x2f,0xd5,0x45,0x3,0xf4,0x1f,0x2f,0xbd,0xf4,0x12,0x5c,
0x2e,0x17,0x3a,0x3b,0x3b,0xaf,0x29,0x7e,0x6b,0x56,0x78,0xd4,0xa8,0x51,0x48,0x49,
0x49,0xc1,0xaa,0x55,0xab,0x12,0x3a,0x2a,0xf4,0xf5,0xd7,0x5f,0xe3,0x17,0xbf,0xf8,
0x5,0x8e,0x1c,0x39,0x82,0xc9,0x93,0x27,0xc3,0x30,0xc,0xa4,0xa6,0xa6,0x22,0x35,
0x35,0x15,0x6b,0xd6,0xac,0x19,0xb4,0x6b,0x18,0x13,0x7,0x1a,0x60,0xc6,0x8c,0x19,
0x78,0xea,0xa9,0xa7,0x10,0xa,0x85,0xec,0xcb,0x11,0x5d,0x7d,0x49,0x52,0x6b,0x56,
0x58,0x44,0x90,0x99,0x99,0x89,0xce,0xce,0x4e,0x2c,0x5d,0xba,0x14,0xbb,0x77,0xef,
0xee,0xf7,0xe3,0xd9,0xbe,0x7d,0x3b,0x4a,0x4a,0x4a,0x70,0xfa,0xf4,0xe9,0xb8,0x45,
0x7b,0x5a,0x6b,0x4,0x2,0x1,0x54,0x55,0x55,0x61,0xd5,0xaa,0x55,0x54,0x18,0xd,
0xd0,0x7f,0xfc,0xfe,0xf7,0xbf,0x47,0x6e,0x6e,0x2e,0x5a,0x5b,0x5b,0xe3,0xae,0xc9,
0x15,0xdb,0xfa,0x5b,0x28,0xa5,0x30,0x76,0xec,0x58,0x84,0xc3,0x61,0xac,0x58,0xb1,
0x2,0xaf,0xbc,0xf2,0xa,0x5a,0x5b,0x5b,0x6f,0xf9,0x18,0x4e,0x9f,0x3e,0x8d,0xc7,
0x1f,0x7f,0x1c,0xab,0x57,0xaf,0x86,0xd6,0x1a,0x13,0x26,0x4c,0x80,0x48,0xfc,0x95,
0xcd,0xb5,0xd6,0xc8,0xcd,0xcd,0xc5,0x27,0x9f,0x7c,0x82,0x57,0x5f,0x7d,0x95,0x2a,
0xa3,0x1,0xfa,0x87,0x40,0x20,0x80,0xf5,0xeb,0xd7,0x23,0x18,0xc,0x22,0x1c,0xe,
0xdb,0x89,0xef,0xd5,0xe2,0x8f,0x15,0x62,0x46,0x46,0x6,0x7c,0x3e,0x1f,0xde,0x78,
0xe3,0xd,0x3c,0xf8,0xe0,0x83,0xd8,0xbe,0x7d,0x3b,0x5a,0x5a,0x5a,0xfa,0xfc,0xdd,
0x27,0x4f,0x9e,0xc4,0x4b,0x2f,0xbd,0x84,0x45,0x8b,0x16,0xa1,0xb4,0xb4,0x14,0x81,
0x40,0x0,0x7e,0xbf,0x1f,0x5a,0xeb,0x1e,0xcb,0x5b,0x9,0xf9,0xc6,0x8d,0x1b,0xf1,
0xf1,0xc7,0x1f,0x53,0x69,0x43,0x94,0x61,0x77,0xa1,0xec,0x15,0x2b,0x56,0xe0,0xe8,
0xd1,0xa3,0xd8,0xbe,0x7d,0x3b,0x26,0x4d,0x9a,0x74,0xc3,0xf2,0x22,0x82,0xe4,0xe4,
0x64,0xe4,0xe5,0xe5,0xe1,0xcc,0x99,0x33,0x58,0xb9,0x72,0x25,0xb6,0x6e,0xdd,0x8a,
0xe2,0xe2,0x62,0x2c,0x58,0xb0,0x0,0x53,0xa6,0x4c,0x41,0x20,0x10,0x40,0x7a,0x7a,
0xba,0x3d,0x99,0x76,0xe5,0xca,0x15,0x34,0x37,0x37,0xe3,0xd2,0xa5,0x4b,0xf8,0xec,
0xb3,0xcf,0x70,0xf8,0xf0,0x61,0x7c,0xfe,0xf9,0xe7,0x68,0x68,0x68,0x40,0x20,0x10,
0x40,0x6e,0x6e,0xee,0xf,0x5a,0xfd,0x9e,0xbe,0x37,0x3d,0x3d,0x1d,0x75,0x75,0x75,
0x38,0x74,0xe8,0x10,0x16,0x2e,0x5c,0x48,0xb5,0xd,0x41,0x8c,0x44,0x4c,0xdc,0x94,
0x94,0x94,0x34,0x3,0xf0,0xf7,0xf4,0x5a,0x47,0x47,0x7,0xb2,0xb3,0xb3,0xb1,0x73,
0xe7,0x4e,0xa4,0xa5,0xa5,0xdd,0xd4,0xe7,0xb7,0xb5,0xb5,0xe1,0x9e,0x7b,0xee,0xc1,
0xd9,0xb3,0x67,0x91,0x9b,0x9b,0x7b,0xcd,0x56,0xb8,0xa7,0x56,0x59,0x6b,0x8d,0xe6,
0xe6,0x66,0x84,0x42,0x21,0x78,0xbd,0x5e,0xa4,0xa7,0xa7,0x63,0xfc,0xf8,0xf1,0xf0,
0xfb,0xfd,0x48,0x4d,0x4d,0x85,0x52,0xa,0xed,0xed,0xed,0x68,0x68,0x68,0x40,0x6d,
0x6d,0x2d,0xba,0xba,0xba,0xa0,0x94,0x42,0x46,0x46,0x6,0x52,0x53,0x53,0x7b,0x3d,
0xd1,0xe5,0x72,0xb9,0x70,0xf1,0xe2,0x45,0x4c,0x9e,0x3c,0x19,0x65,0x65,0x65,0xbd,
0x32,0xeb,0x48,0xa5,0xa5,0xa5,0x5,0x93,0x27,0x4f,0xbe,0x51,0xcf,0xdc,0x22,0x22,
0x99,0xfd,0xfd,0xdd,0x9e,0xe1,0xf8,0x83,0xf9,0x7c,0x3e,0xec,0xd8,0xb1,0x3,0xf,
0x3e,0xf8,0x20,0xea,0xeb,0xeb,0x31,0x76,0xec,0xd8,0x5e,0x99,0x40,0x44,0x60,0x18,
0x6,0xb2,0xb2,0xb2,0xec,0xc7,0x4a,0x29,0x7c,0xff,0xfd,0xf7,0x8,0x85,0x42,0x50,
0x4a,0xc1,0x30,0xc,0x78,0x3c,0x1e,0x24,0x25,0x25,0x61,0xf4,0xe8,0xd1,0x71,0xab,
0x51,0xfb,0x22,0xfe,0xfa,0xfa,0x7a,0x8c,0x19,0x33,0x6,0xa5,0xa5,0xa5,0x14,0x3f,
0x73,0x80,0xfe,0x67,0xda,0xb4,0x69,0xd8,0xb1,0x63,0x7,0x92,0x93,0x93,0x51,0x5b,
0x5b,0x7b,0x53,0xfb,0x2,0x59,0x62,0x4f,0x4b,0x4b,0x43,0x66,0x66,0x26,0x2,0x81,
0x0,0x6e,0xbb,0xed,0x36,0x64,0x64,0x64,0x20,0x25,0x25,0xe5,0xa6,0x3e,0xd3,0xe5,
0x72,0xa1,0xba,0xba,0x1a,0x69,0x69,0x69,0xd8,0xb5,0x6b,0x17,0x37,0xed,0xa5,0x1,
0x12,0x47,0x71,0x71,0x31,0x76,0xed,0xda,0x5,0x9f,0xcf,0x87,0xba,0xba,0xba,0x41,
0xdf,0x1c,0xcb,0xe5,0x72,0xa1,0xaa,0xaa,0xa,0xb9,0xb9,0xb9,0xd8,0xb3,0x67,0xf,
0x8a,0x8b,0x8b,0xa9,0x30,0x1a,0x20,0xb1,0xcc,0x9f,0x3f,0x1f,0x7b,0xf6,0xec,0x41,
0x7e,0x7e,0x3e,0x2e,0x5c,0xb8,0x60,0x87,0x31,0x3,0x2d,0xfc,0x50,0x28,0x84,0xf2,
0xf2,0x72,0xcc,0x9c,0x39,0x13,0x7b,0xf7,0xee,0xe5,0xb5,0xca,0x68,0x80,0x81,0x63,
0xf6,0xec,0xd9,0xf8,0xe7,0x3f,0xff,0x89,0x85,0xb,0x17,0xa2,0xb2,0xb2,0xd2,0x1e,
0xef,0x4f,0xb4,0x11,0xac,0xcf,0x6f,0x68,0x68,0x40,0x75,0x75,0x35,0x9e,0x7e,0xfa,
0x69,0x1c,0x3e,0x7c,0x18,0x3f,0xfe,0xf1,0x8f,0xa9,0x2c,0x1a,0x60,0x60,0xc9,0xcd,
0xcd,0xc5,0xde,0xbd,0x7b,0xb1,0x69,0xd3,0x26,0xa4,0xa6,0xa6,0xa2,0xb2,0xb2,0x12,
0xdd,0xdd,0xdd,0x9,0x33,0x81,0x61,0x18,0xe8,0xe8,0xe8,0x40,0x45,0x45,0x5,0x26,
0x4d,0x9a,0x84,0x9d,0x3b,0x77,0xe2,0xdd,0x77,0xdf,0x45,0x4a,0x4a,0xa,0x55,0x35,
0x8c,0xb4,0xea,0xb8,0x1d,0x65,0x5f,0x7c,0xf1,0x45,0xec,0xdf,0xbf,0x1f,0xcf,0x3c,
0xf3,0xc,0x82,0xc1,0x20,0xaa,0xaa,0xaa,0xd0,0xdc,0xdc,0x6c,0x8f,0x0,0xdd,0xaa,
0xe8,0x95,0x52,0x68,0x6c,0x6c,0x44,0x55,0x55,0x15,0x46,0x8d,0x1a,0x85,0x75,0xeb,
0xd6,0xe1,0x5f,0xff,0xfa,0x17,0x97,0x41,0x27,0x9e,0x84,0x9c,0x68,0xe1,0x71,0xe2,
0x2f,0x35,0x7d,0xfa,0x74,0xfc,0xf1,0x8f,0x7f,0xc4,0xaa,0x55,0xab,0xf0,0xde,0x7b,
0xef,0xe1,0xc8,0x91,0x23,0x38,0x75,0xea,0x14,0xdc,0x6e,0x37,0x7c,0x3e,0x1f,0x92,
0x92,0x92,0xe0,0x76,0xbb,0xed,0xb5,0x44,0x3d,0x19,0x43,0x44,0xa0,0xb5,0x86,0xd6,
0x1a,0xa1,0x50,0x8,0xc1,0x60,0x10,0xad,0xad,0xad,0x70,0xbb,0xdd,0x98,0x39,0x73,
0x26,0x16,0x2c,0x58,0x80,0xa7,0x9e,0x7a,0xa,0x79,0x79,0x79,0x94,0xe6,0xad,0x2a,
0x5b,0xa4,0xb2,0xab,0xab,0xab,0x16,0xc0,0x7f,0x5d,0xa7,0xd8,0x97,0x34,0x40,0x1f,
0x99,0x31,0x63,0x6,0xb6,0x6c,0xd9,0x82,0xa6,0xa6,0x26,0x1c,0x3a,0x74,0x8,0xc7,
0x8f,0x1f,0xc7,0x89,0x13,0x27,0x50,0x59,0x59,0x89,0x8e,0x8e,0xe,0xb4,0xb6,0xb6,
0xa2,0xab,0xab,0xcb,0x9e,0x43,0x70,0xbb,0xdd,0xb6,0xf0,0x5d,0x2e,0x17,0x92,0x93,
0x93,0x91,0x9a,0x9a,0x8a,0x8c,0x8c,0xc,0xe4,0xe6,0xe6,0xa2,0xa8,0xa8,0x8,0xc5,
0xc5,0xc5,0x98,0x3f,0x7f,0x3e,0x2f,0xc8,0xd1,0xbf,0x83,0x8,0x9d,0x7e,0xbf,0x7f,
0x75,0x6d,0x6d,0xed,0xff,0x2,0xe8,0x69,0x3b,0xc0,0x16,0x0,0xcf,0x27,0x24,0x94,
0x1d,0x8e,0x33,0xc1,0xb7,0x42,0x57,0x57,0x17,0x2a,0x2b,0x2b,0xf1,0xed,0xb7,0xdf,
0xa2,0xb2,0xb2,0x12,0xd,0xd,0xd,0x8,0x6,0x83,0xe8,0xee,0xee,0x46,0x57,0x57,
0x17,0xc,0xc3,0x40,0x4a,0x4a,0xa,0x46,0x8f,0x1e,0x8d,0xcc,0xcc,0x4c,0xe4,0xe5,
0xe5,0xa1,0xb0,0xb0,0x10,0xe3,0xc7,0x8f,0xc7,0xa8,0x51,0xa3,0xa8,0xd6,0xc4,0xf4,
0x0,0xad,0x9b,0x36,0x6d,0xf2,0xff,0xf6,0xb7,0xbf,0x9d,0xe,0x60,0xb,0x80,0x79,
0x31,0x2f,0x1f,0x2,0xb0,0x16,0xc0,0x97,0x89,0xd0,0xea,0x88,0x33,0x0,0x19,0x92,
0xb4,0xb6,0xb5,0xb5,0x4d,0x2a,0x28,0x28,0x68,0x69,0x6c,0x6c,0x4,0x80,0xe9,0x0,
0x52,0x0,0x74,0x2,0x38,0x13,0x1b,0x96,0x32,0x9,0x26,0x8e,0xec,0x4,0x7c,0x3e,
0x1f,0xd6,0xae,0x5d,0x6b,0x3d,0x3e,0x3,0xe0,0x44,0xac,0xf8,0x13,0x16,0x7e,0xf1,
0xb7,0x27,0x43,0x85,0x55,0xab,0x56,0xdd,0x70,0x3b,0x4c,0x1a,0x80,0x38,0x96,0xd4,
0xd4,0x54,0x1c,0x3b,0x76,0xc,0xe3,0xc6,0x8d,0xa3,0x1,0xc8,0xc8,0x64,0xdc,0xb8,
0x71,0x38,0x76,0xec,0x58,0xaf,0x76,0x6,0xa7,0x1,0x88,0x23,0x99,0x38,0x71,0x22,
0xe,0x1e,0x3c,0x38,0x20,0xe1,0x10,0xd,0x40,0x86,0x24,0x5,0x5,0x5,0x3,0x12,
0xe,0x79,0xf8,0x53,0x93,0xa1,0x1e,0xe,0x1d,0x38,0x70,0x80,0x6,0x20,0x23,0x37,
0x1c,0xfa,0xf5,0xaf,0x7f,0xcd,0x10,0x88,0x10,0x1a,0x80,0x10,0x1a,0x80,0x10,0x1a,
0x80,0x10,0x1a,0x80,0x10,0x1a,0x80,0x10,0x1a,0x80,0x10,0x1a,0x80,0x10,0x1a,0x80,
0x10,0x1a,0x80,0x10,0x1a,0x80,0x10,0x1a,0x80,0x10,0x1a,0x80,0x10,0x1a,0x80,0x10,
0x1a,0x80,0x10,0x1a,0x80,0x10,0x1a,0x80,0x10,0x1a,0x80,0xd0,0x0,0xfc,0x9,0x8,
0xd,0x40,0x8,0xd,0x40,0x8,0xd,0x40,0x8,0xd,0x40,0x8,0xd,0x40,0x8,0xd,
0x40,0x8,0xd,0x40,0x8,0xd,0x40,0x8,0xd,0xd0,0x4f,0x88,0xf0,0x87,0x27,0x23,
0xd4,0x0,0x11,0xf1,0x6b,0xfe,0xf2,0x64,0xe4,0x19,0x40,0xcc,0x7f,0xd9,0x3,0x90,
0xa1,0x82,0x67,0xe0,0xc4,0x2f,0x80,0x8e,0x5c,0xea,0x52,0x40,0x7,0x90,0x91,0xd6,
0x3,0x98,0xe2,0xd7,0x5a,0x20,0x5a,0xec,0xfe,0x80,0x10,0xc7,0xf7,0x0,0x22,0x2,
0x11,0x1d,0x13,0x2,0x9,0x4,0x6,0x7f,0x7d,0xe2,0x70,0x3,0x48,0x24,0xd8,0xb1,
0xc2,0x1e,0x11,0x44,0x8c,0xa0,0x85,0x1d,0x0,0x71,0xb6,0x1,0x22,0x97,0xb5,0x8f,
0x84,0x3b,0xda,0x7a,0xac,0x1,0xad,0x5,0x9a,0xed,0x3f,0x89,0xc7,0x70,0x9c,0x1,
0xec,0xd6,0xdf,0xba,0xaf,0x23,0x8f,0xb5,0x39,0x4,0xe4,0x72,0x73,0xe,0x8e,0xd8,
0xb8,0x1d,0x95,0x4,0x8b,0x44,0xc5,0x2e,0xf6,0x2d,0x12,0xfe,0x18,0x0,0x82,0xdd,
0x5d,0x68,0x6f,0x6f,0x67,0xb5,0x13,0x8b,0x46,0x0,0x9d,0x8e,0x31,0x80,0x16,0x81,
0x16,0xd,0xd1,0x3a,0x12,0xf2,0x88,0x86,0x20,0x12,0xfb,0x27,0x79,0x3c,0xa8,0xae,
0xbe,0x88,0x13,0x5f,0x9e,0x60,0xb5,0x13,0x8b,0x83,0x0,0xba,0x1d,0x63,0x80,0x48,
0x73,0x1f,0x9d,0xf8,0x82,0x46,0x24,0x4,0x12,0xd,0x97,0xc7,0x3,0xad,0x35,0xde,
0xdf,0xfe,0x3e,0xd3,0x60,0x2,0x0,0x61,0x0,0x6f,0x3a,0x2e,0x4,0xd2,0x22,0x66,
0xf,0xa0,0xa1,0xc5,0xfc,0xab,0x1,0xad,0x35,0xb2,0xb2,0xb2,0xf0,0xe9,0xa7,0x9f,
0x1a,0xcf,0x3d,0xf7,0x5c,0x18,0x1c,0xf,0x1a,0xc9,0x4,0x1,0x3c,0xc,0xe0,0xbc,
0xa3,0x92,0xe0,0x48,0xf8,0x63,0xe,0x79,0x4a,0x64,0xe4,0xc7,0xca,0x5,0xb4,0xd6,
0x10,0x11,0x8c,0x1d,0x3b,0x16,0x1f,0x7c,0xf0,0x81,0xab,0xa2,0xa2,0x22,0xfc,0xf3,
0x9f,0xff,0xfc,0xca,0xbc,0x79,0xf3,0x46,0xfb,0xfd,0x7e,0xcf,0xf5,0x4c,0x15,0x19,
0x2c,0xb8,0xbe,0x5f,0x24,0xb6,0x17,0x72,0x2e,0x1d,0x0,0xfe,0xcf,0xef,0xf7,0x7,
0x0,0x24,0xd,0xc3,0xe3,0x6f,0x1,0xb0,0xf,0xc0,0x3b,0x0,0xce,0xe,0xe6,0x81,
0x18,0x92,0x0,0xa1,0xcc,0x9d,0x5b,0xdc,0xac,0x5,0x7e,0x31,0xc5,0xae,0xcd,0x5c,
0x0,0xa2,0x23,0xf9,0x81,0xf9,0x3c,0x0,0xd4,0xd6,0xd6,0x1,0x90,0x60,0x4e,0x4e,
0x8e,0xc7,0xeb,0xf5,0xba,0xa2,0xe5,0xcd,0x1c,0x22,0xa6,0xbc,0xd2,0x1a,0xd0,0x2,
0xd,0xd,0x51,0x3a,0x26,0xd7,0x30,0xcd,0x15,0x77,0x5f,0x0,0x2d,0x91,0xdc,0x43,
0x60,0x1b,0xd0,0x1a,0x9d,0x1a,0xe6,0x54,0x1,0x78,0x67,0xce,0x9c,0x39,0x9b,0x57,
0xaf,0x5e,0xed,0x5a,0xb4,0x68,0x91,0x67,0x98,0x1d,0x7f,0x10,0xc0,0x95,0xa1,0x70,
0x20,0x9,0x31,0x40,0x71,0xf1,0x5d,0xcd,0x5a,0x8b,0xdf,0x12,0xb0,0x88,0x86,0xb2,
0x7a,0x81,0x1f,0x8,0x5b,0x23,0x14,0xa,0xa3,0xb3,0xb3,0x13,0xe1,0x70,0x38,0x22,
0x5e,0xa5,0xec,0xd7,0x23,0x37,0x5,0xd1,0x80,0x32,0x13,0x6b,0xd1,0xda,0xbc,0x2f,
0x90,0x91,0xbd,0xb2,0x6e,0x2b,0x80,0xe7,0xef,0xbe,0xfb,0x6e,0xec,0xda,0xb5,0xb,
0xe3,0xc6,0x8d,0x63,0x50,0x35,0x14,0xc,0x50,0x54,0x54,0xd4,0xa2,0x45,0x67,0x88,
0x8e,0xcf,0x5,0x62,0x5b,0x69,0x1d,0x93,0x1f,0xc4,0x3e,0x96,0x38,0xe1,0x5b,0xe5,
0x23,0x6,0xb0,0x72,0x89,0x58,0x63,0x69,0xfb,0x3b,0xc4,0x1e,0x69,0xb2,0xbe,0xd7,
0x5e,0x76,0x21,0x8e,0x36,0xca,0x32,0x0,0x1f,0x4c,0x9c,0x38,0x11,0xff,0xfe,0xf7,
0xbf,0x51,0x50,0x50,0x40,0x55,0xf,0x81,0x24,0x38,0x1c,0x11,0xa2,0x6,0x4c,0x51,
0xdb,0x37,0x1d,0xd,0x69,0xec,0xc7,0x96,0x80,0x4d,0x83,0x44,0x5f,0xd7,0x76,0x1e,
0x11,0x6d,0xf1,0x35,0xb4,0x15,0xd2,0x68,0x73,0x95,0xa9,0x55,0x36,0x6e,0xb5,0xe9,
0x88,0x10,0x3f,0x0,0xac,0x4,0x80,0x8a,0x8a,0xa,0xdc,0x7b,0xef,0xbd,0xa8,0xa8,
0xa8,0xa0,0xaa,0x7,0xdb,0x0,0x5a,0xeb,0x5a,0x2b,0xe,0x57,0x3f,0x68,0xd9,0xc5,
0xbc,0xe9,0x98,0x58,0x5f,0x45,0x47,0x8a,0x54,0xec,0xa8,0x91,0xd5,0x3b,0x28,0x53,
0xf8,0xda,0x4c,0xa8,0xad,0xde,0x43,0x5d,0x65,0xa8,0xab,0xcc,0x26,0x23,0x22,0x44,
0xa,0x58,0x77,0xca,0xcb,0xcb,0x51,0x54,0x54,0x84,0x9a,0x9a,0x1a,0x2a,0x7b,0x90,
0x7b,0x80,0xbf,0xf4,0x1c,0xd2,0x98,0x62,0xd7,0x2a,0xee,0x39,0xad,0xa2,0xf9,0x80,
0xb5,0x5c,0x3a,0x7e,0xf8,0x34,0x92,0xd0,0xc6,0x25,0xc6,0xd6,0xcd,0x32,0x89,0x9d,
0x1f,0x98,0x79,0x86,0xe8,0x91,0x92,0x1f,0x5c,0x8a,0x7d,0x50,0x53,0x53,0x83,0xa2,
0xa2,0x22,0x94,0x97,0x97,0x53,0xdd,0x83,0x68,0x80,0x6d,0x5a,0xcb,0xb9,0xd8,0x56,
0x38,0x9a,0x3,0x5c,0x15,0xfa,0xc4,0xc6,0xf2,0x96,0x9,0xcc,0xd1,0xa2,0xa8,0x98,
0x25,0x12,0x2,0x49,0x64,0x21,0x5d,0x54,0xe8,0xb0,0x82,0x1d,0x7b,0xf9,0x85,0xbd,
0xec,0x62,0xe4,0xd4,0xe1,0xff,0x5c,0xfd,0x84,0x15,0xe,0x9d,0x3b,0x77,0x8e,0xa,
0x1f,0xc,0x3,0x28,0xa5,0xda,0x44,0xf4,0xfd,0xa2,0xf5,0x37,0x71,0x2d,0xfd,0x55,
0x37,0x2b,0x39,0x56,0x66,0xec,0x6f,0x8d,0x14,0x59,0xaf,0xc5,0x25,0xc7,0x66,0xe8,
0x23,0xca,0x12,0xbb,0x8e,0xb6,0xfa,0xd6,0xcc,0xb3,0xf9,0xbc,0x60,0xc4,0x38,0xe0,
0x2f,0x0,0x3e,0xe8,0xe9,0x85,0xf2,0xf2,0x72,0xec,0xdb,0xb7,0x8f,0xa,0xbf,0x1,
0x9,0x19,0x3f,0x36,0x43,0x8f,0x4a,0x1,0x8a,0xb4,0xd6,0xff,0x2d,0x5a,0x2f,0xd5,
0xa2,0xf3,0xaf,0x39,0xda,0x23,0xd1,0xd0,0x25,0x1a,0xe3,0x5b,0x9,0xaf,0xd8,0xf7,
0xed,0x51,0xa4,0xab,0xc6,0xf5,0xed,0x31,0x7f,0x19,0x31,0x27,0x5b,0x56,0x1,0x78,
0x17,0x91,0x61,0xd0,0x6b,0xe2,0xf7,0xfb,0xa9,0xf0,0x1b,0x60,0x8,0xcf,0x50,0x27,
0xc,0x81,0x8,0xa1,0x1,0x8,0xa1,0x1,0x8,0xa1,0x1,0x8,0xa1,0x1,0x8,0xa1,
0x1,0x8,0xa1,0x1,0x8,0xa1,0x1,0x8,0xa1,0x1,0x8,0xa1,0x1,0x8,0xa1,0x1,
0x8,0xa1,0x1,0x8,0xa1,0x1,0x8,0xa1,0x1,0x8,0xa1,0x1,0x8,0xa1,0x1,0x8,
0xa1,0x1,0x8,0xa1,0x1,0x8,0xa1,0x1,0x8,0xa1,0x1,0x8,0x19,0xa2,0xfc,0xff,
0x0,0xd4,0xad,0x4a,0xf3,0x4a,0x84,0x50,0x5b,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,
0x44,0xae,0x42,0x60,0x82,
};
static const unsigned char qt_resource_name[] = {
// img
0x0,0x3,
0x0,0x0,0x70,0x37,
0x0,0x69,
0x0,0x6d,0x0,0x67,
// ckb-logo.png
0x0,0xc,
0x8,0xa4,0xff,0x27,
0x0,0x63,
0x0,0x6b,0x0,0x62,0x0,0x2d,0x0,0x6c,0x0,0x6f,0x0,0x67,0x0,0x6f,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67,
};
static const unsigned char qt_resource_struct[] = {
// :
0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x1,
// :/img
0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x2,
// :/img/ckb-logo.png
0x0,0x0,0x0,0xc,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,
};
QT_BEGIN_NAMESPACE
extern Q_CORE_EXPORT bool qRegisterResourceData
(int, const unsigned char *, const unsigned char *, const unsigned char *);
extern Q_CORE_EXPORT bool qUnregisterResourceData
(int, const unsigned char *, const unsigned char *, const unsigned char *);
QT_END_NAMESPACE
int QT_MANGLE_NAMESPACE(qInitResources_image)()
{
QT_PREPEND_NAMESPACE(qRegisterResourceData)
(0x01, qt_resource_struct, qt_resource_name, qt_resource_data);
return 1;
}
Q_CONSTRUCTOR_FUNCTION(QT_MANGLE_NAMESPACE(qInitResources_image))
int QT_MANGLE_NAMESPACE(qCleanupResources_image)()
{
QT_PREPEND_NAMESPACE(qUnregisterResourceData)
(0x01, qt_resource_struct, qt_resource_name, qt_resource_data);
return 1;
}
Q_DESTRUCTOR_FUNCTION(QT_MANGLE_NAMESPACE(qCleanupResources_image))