From 196449e5c31d00088884afc2842df2e19bfbe0bb Mon Sep 17 00:00:00 2001 From: Brent Atkinson Date: Mon, 12 Jan 2015 15:06:11 -0500 Subject: [PATCH 01/74] Moved rom deletion to gamelist, fixed halt on removal. --- es-app/src/guis/GuiGamelistOptions.cpp | 5 +---- .../src/views/gamelist/BasicGameListView.cpp | 22 +++++++++++++++++++ es-app/src/views/gamelist/BasicGameListView.h | 1 + es-app/src/views/gamelist/IGameListView.h | 1 + 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/es-app/src/guis/GuiGamelistOptions.cpp b/es-app/src/guis/GuiGamelistOptions.cpp index 635f97e19b..95fceef8e7 100644 --- a/es-app/src/guis/GuiGamelistOptions.cpp +++ b/es-app/src/guis/GuiGamelistOptions.cpp @@ -75,10 +75,7 @@ void GuiGamelistOptions::openMetaDataEd() p.system = file->getSystem(); mWindow->pushGui(new GuiMetaDataEd(mWindow, &file->metadata, file->metadata.getMDD(), p, file->getPath().filename().string(), std::bind(&IGameListView::onFileChanged, getGamelist(), file, FILE_METADATA_CHANGED), [this, file] { - boost::filesystem::remove(file->getPath()); //actually delete the file on the filesystem - file->getParent()->removeChild(file); //unlink it so list repopulations triggered from onFileChanged won't see it - getGamelist()->onFileChanged(file, FILE_REMOVED); //tell the view - delete file; //free it + getGamelist()->remove(file); })); } diff --git a/es-app/src/views/gamelist/BasicGameListView.cpp b/es-app/src/views/gamelist/BasicGameListView.cpp index af4ccbfe4d..d3cbc017a1 100644 --- a/es-app/src/views/gamelist/BasicGameListView.cpp +++ b/es-app/src/views/gamelist/BasicGameListView.cpp @@ -86,6 +86,28 @@ void BasicGameListView::launch(FileData* game) ViewController::get()->launch(game); } +void BasicGameListView::remove(FileData *game) +{ + boost::filesystem::remove(game->getPath()); // actually delete the file on the filesystem + if (getCursor() == game) // Select next element in list, or prev if none + { + std::vector siblings = game->getParent()->getChildren(); + auto gameIter = std::find(siblings.begin(), siblings.end(), game); + auto gamePos = std::distance(siblings.begin(), gameIter); + if (gameIter != siblings.end()) + { + if ((gamePos + 1) < siblings.size()) + { + setCursor(siblings.at(gamePos + 1)); + } else if ((gamePos - 1) > 0) { + setCursor(siblings.at(gamePos - 1)); + } + } + } + delete game; // remove before repopulating (removes from parent) + onFileChanged(game, FILE_REMOVED); // update the view, with game removed +} + std::vector BasicGameListView::getHelpPrompts() { std::vector prompts; diff --git a/es-app/src/views/gamelist/BasicGameListView.h b/es-app/src/views/gamelist/BasicGameListView.h index 23145f5cb9..a1bf0b5d6f 100644 --- a/es-app/src/views/gamelist/BasicGameListView.h +++ b/es-app/src/views/gamelist/BasicGameListView.h @@ -23,6 +23,7 @@ class BasicGameListView : public ISimpleGameListView protected: virtual void populateList(const std::vector& files) override; virtual void launch(FileData* game) override; + virtual void remove(FileData* game) override; TextListComponent mList; }; diff --git a/es-app/src/views/gamelist/IGameListView.h b/es-app/src/views/gamelist/IGameListView.h index 6f9ef054d4..ec98a9de97 100644 --- a/es-app/src/views/gamelist/IGameListView.h +++ b/es-app/src/views/gamelist/IGameListView.h @@ -32,6 +32,7 @@ class IGameListView : public GuiComponent virtual void setCursor(FileData*) = 0; virtual bool input(InputConfig* config, Input input) override; + virtual void remove(FileData* game) = 0; virtual const char* getName() const = 0; From 65f2409d9162a74bd8eaed979919883a5cd1e6bd Mon Sep 17 00:00:00 2001 From: Florian Date: Sun, 19 Apr 2015 11:57:10 +0200 Subject: [PATCH 02/74] CHG: Additional input types, user-defined input config scripts --- data/ResourceUtil.cpp | 146 +- data/Resources.h | 143 +- data/converted/arrow_svg.cpp | 168 +- data/converted/busy_0_svg.cpp | 241 +- data/converted/busy_1_svg.cpp | 249 +- data/converted/busy_2_svg.cpp | 249 +- data/converted/busy_3_svg.cpp | 247 +- data/converted/button_filled_png.cpp | 1 + data/converted/button_png.cpp | 1 + data/converted/checkbox_checked_svg.cpp | 253 +- data/converted/checkbox_unchecked_svg.cpp | 170 +- data/converted/fav_add_svg.cpp | 122 +- data/converted/fav_remove_svg.cpp | 112 +- data/converted/frame_png.cpp | 1 + data/converted/help_analog_down_svg.cpp | 289 ++ data/converted/help_analog_left_svg.cpp | 292 ++ data/converted/help_analog_right_svg.cpp | 290 ++ data/converted/help_analog_thumb_svg.cpp | 298 ++ data/converted/help_analog_up_svg.cpp | 294 ++ data/converted/help_button_a_svg.cpp | 195 +- data/converted/help_button_b_svg.cpp | 279 +- data/converted/help_button_l_svg.cpp | 204 +- data/converted/help_button_r_svg.cpp | 243 +- data/converted/help_button_select_svg.cpp | 370 +- data/converted/help_button_start_svg.cpp | 334 +- data/converted/help_button_x_svg.cpp | 191 +- data/converted/help_button_y_svg.cpp | 184 +- data/converted/help_dpad_all_svg.cpp | 641 ++-- data/converted/help_dpad_down_svg.cpp | 560 ++- data/converted/help_dpad_left_svg.cpp | 568 ++- data/converted/help_dpad_leftright_svg.cpp | 581 ++- data/converted/help_dpad_right_svg.cpp | 572 ++- data/converted/help_dpad_up_svg.cpp | 568 ++- data/converted/help_dpad_updown_svg.cpp | 585 ++- data/converted/off_svg.cpp | 242 +- data/converted/on_svg.cpp | 204 +- .../opensans_hebrew_condensed_light_ttf.cpp | 1 + .../opensans_hebrew_condensed_regular_ttf.cpp | 1 + data/converted/option_arrow_svg.cpp | 168 +- data/converted/scroll_gradient_png.cpp | 1 + data/converted/slider_knob_svg.cpp | 124 +- data/converted/splash_svg.cpp | 3240 ++++++++--------- data/converted/star_filled_svg.cpp | 214 +- data/converted/star_unfilled_svg.cpp | 356 +- .../textinput_ninepatch_active_png.cpp | 1 + data/converted/textinput_ninepatch_png.cpp | 1 + data/converted/window_icon_256_png.cpp | 1 + data/resources/help/analog_down.svg | 15 + data/resources/help/analog_left.svg | 17 + data/resources/help/analog_right.svg | 15 + data/resources/help/analog_thumb.svg | 13 + data/resources/help/analog_up.svg | 17 + es-core/CMakeLists.txt | 5 + es-core/src/InputManager.cpp | 128 +- es-core/src/InputManager.h | 2 + es-core/src/components/ComponentList.cpp | 4 +- es-core/src/components/DateTimeComponent.cpp | 4 +- es-core/src/guis/GuiInputConfig.cpp | 131 +- es-core/src/guis/GuiInputConfig.h | 3 + 59 files changed, 8130 insertions(+), 6419 deletions(-) create mode 100644 data/converted/help_analog_down_svg.cpp create mode 100644 data/converted/help_analog_left_svg.cpp create mode 100644 data/converted/help_analog_right_svg.cpp create mode 100644 data/converted/help_analog_thumb_svg.cpp create mode 100644 data/converted/help_analog_up_svg.cpp create mode 100644 data/resources/help/analog_down.svg create mode 100644 data/resources/help/analog_left.svg create mode 100644 data/resources/help/analog_right.svg create mode 100644 data/resources/help/analog_thumb.svg create mode 100644 data/resources/help/analog_up.svg diff --git a/data/ResourceUtil.cpp b/data/ResourceUtil.cpp index 910ac2cb83..48b92defe1 100644 --- a/data/ResourceUtil.cpp +++ b/data/ResourceUtil.cpp @@ -2,91 +2,101 @@ #include "Resources.h" -const size_t res2hNrOfFiles = 40; +const size_t res2hNrOfFiles = 45; const Res2hEntry res2hFiles[res2hNrOfFiles] = { - {":/arrow.svg", arrow_svg_size, arrow_svg_data}, - {":/busy_0.svg", busy_0_svg_size, busy_0_svg_data}, - {":/busy_1.svg", busy_1_svg_size, busy_1_svg_data}, - {":/busy_2.svg", busy_2_svg_size, busy_2_svg_data}, - {":/busy_3.svg", busy_3_svg_size, busy_3_svg_data}, - {":/button.png", button_png_size, button_png_data}, + {":/scroll_gradient.png", scroll_gradient_png_size, scroll_gradient_png_data}, + {":/star_filled.svg", star_filled_svg_size, star_filled_svg_data}, + {":/window_icon_256.png", window_icon_256_png_size, window_icon_256_png_data}, + {":/off.svg", off_svg_size, off_svg_data}, {":/button_filled.png", button_filled_png_size, button_filled_png_data}, - {":/checkbox_checked.svg", checkbox_checked_svg_size, checkbox_checked_svg_data}, {":/checkbox_unchecked.svg", checkbox_unchecked_svg_size, checkbox_unchecked_svg_data}, - {":/fav_add.svg", fav_add_svg_size, fav_add_svg_data}, - {":/fav_remove.svg", fav_remove_svg_size, fav_remove_svg_data}, - {":/frame.png", frame_png_size, frame_png_data}, - {":/off.svg", off_svg_size, off_svg_data}, + {":/opensans_hebrew_condensed_regular.ttf", opensans_hebrew_condensed_regular_ttf_size, opensans_hebrew_condensed_regular_ttf_data}, {":/on.svg", on_svg_size, on_svg_data}, + {":/busy_3.svg", busy_3_svg_size, busy_3_svg_data}, {":/opensans_hebrew_condensed_light.ttf", opensans_hebrew_condensed_light_ttf_size, opensans_hebrew_condensed_light_ttf_data}, - {":/opensans_hebrew_condensed_regular.ttf", opensans_hebrew_condensed_regular_ttf_size, opensans_hebrew_condensed_regular_ttf_data}, + {":/checkbox_checked.svg", checkbox_checked_svg_size, checkbox_checked_svg_data}, + {":/textinput_ninepatch.png", textinput_ninepatch_png_size, textinput_ninepatch_png_data}, {":/option_arrow.svg", option_arrow_svg_size, option_arrow_svg_data}, - {":/scroll_gradient.png", scroll_gradient_png_size, scroll_gradient_png_data}, - {":/slider_knob.svg", slider_knob_svg_size, slider_knob_svg_data}, + {":/textinput_ninepatch_active.png", textinput_ninepatch_active_png_size, textinput_ninepatch_active_png_data}, {":/splash.svg", splash_svg_size, splash_svg_data}, - {":/star_filled.svg", star_filled_svg_size, star_filled_svg_data}, + {":/frame.png", frame_png_size, frame_png_data}, + {":/slider_knob.svg", slider_knob_svg_size, slider_knob_svg_data}, + {":/button.png", button_png_size, button_png_data}, + {":/busy_1.svg", busy_1_svg_size, busy_1_svg_data}, + {":/fav_remove.svg", fav_remove_svg_size, fav_remove_svg_data}, + {":/arrow.svg", arrow_svg_size, arrow_svg_data}, {":/star_unfilled.svg", star_unfilled_svg_size, star_unfilled_svg_data}, - {":/textinput_ninepatch.png", textinput_ninepatch_png_size, textinput_ninepatch_png_data}, - {":/textinput_ninepatch_active.png", textinput_ninepatch_active_png_size, textinput_ninepatch_active_png_data}, - {":/window_icon_256.png", window_icon_256_png_size, window_icon_256_png_data}, + {":/busy_2.svg", busy_2_svg_size, busy_2_svg_data}, + {":/busy_0.svg", busy_0_svg_size, busy_0_svg_data}, + {":/fav_add.svg", fav_add_svg_size, fav_add_svg_data}, + {":/help/dpad_leftright.svg", help_dpad_leftright_svg_size, help_dpad_leftright_svg_data}, + {":/help/dpad_all.svg", help_dpad_all_svg_size, help_dpad_all_svg_data}, + {":/help/button_x.svg", help_button_x_svg_size, help_button_x_svg_data}, {":/help/button_a.svg", help_button_a_svg_size, help_button_a_svg_data}, - {":/help/button_b.svg", help_button_b_svg_size, help_button_b_svg_data}, {":/help/button_l.svg", help_button_l_svg_size, help_button_l_svg_data}, - {":/help/button_r.svg", help_button_r_svg_size, help_button_r_svg_data}, - {":/help/button_select.svg", help_button_select_svg_size, help_button_select_svg_data}, - {":/help/button_start.svg", help_button_start_svg_size, help_button_start_svg_data}, - {":/help/button_x.svg", help_button_x_svg_size, help_button_x_svg_data}, - {":/help/button_y.svg", help_button_y_svg_size, help_button_y_svg_data}, - {":/help/dpad_all.svg", help_dpad_all_svg_size, help_dpad_all_svg_data}, {":/help/dpad_down.svg", help_dpad_down_svg_size, help_dpad_down_svg_data}, + {":/help/analog_up.svg", help_analog_up_svg_size, help_analog_up_svg_data}, {":/help/dpad_left.svg", help_dpad_left_svg_size, help_dpad_left_svg_data}, - {":/help/dpad_leftright.svg", help_dpad_leftright_svg_size, help_dpad_leftright_svg_data}, - {":/help/dpad_right.svg", help_dpad_right_svg_size, help_dpad_right_svg_data}, + {":/help/button_start.svg", help_button_start_svg_size, help_button_start_svg_data}, {":/help/dpad_up.svg", help_dpad_up_svg_size, help_dpad_up_svg_data}, - {":/help/dpad_updown.svg", help_dpad_updown_svg_size, help_dpad_updown_svg_data} + {":/help/analog_down.svg", help_analog_down_svg_size, help_analog_down_svg_data}, + {":/help/button_y.svg", help_button_y_svg_size, help_button_y_svg_data}, + {":/help/button_select.svg", help_button_select_svg_size, help_button_select_svg_data}, + {":/help/button_b.svg", help_button_b_svg_size, help_button_b_svg_data}, + {":/help/dpad_updown.svg", help_dpad_updown_svg_size, help_dpad_updown_svg_data}, + {":/help/dpad_right.svg", help_dpad_right_svg_size, help_dpad_right_svg_data}, + {":/help/button_r.svg", help_button_r_svg_size, help_button_r_svg_data}, + {":/help/analog_thumb.svg", help_analog_thumb_svg_size, help_analog_thumb_svg_data}, + {":/help/analog_left.svg", help_analog_left_svg_size, help_analog_left_svg_data}, + {":/help/analog_right.svg", help_analog_right_svg_size, help_analog_right_svg_data} }; res2hMapType::value_type mapTemp[] = { - std::make_pair(":/arrow.svg", res2hFiles[0]), - std::make_pair(":/busy_0.svg", res2hFiles[1]), - std::make_pair(":/busy_1.svg", res2hFiles[2]), - std::make_pair(":/busy_2.svg", res2hFiles[3]), - std::make_pair(":/busy_3.svg", res2hFiles[4]), - std::make_pair(":/button.png", res2hFiles[5]), - std::make_pair(":/button_filled.png", res2hFiles[6]), - std::make_pair(":/checkbox_checked.svg", res2hFiles[7]), - std::make_pair(":/checkbox_unchecked.svg", res2hFiles[8]), - std::make_pair(":/fav_add.svg", res2hFiles[9]), - std::make_pair(":/fav_remove.svg", res2hFiles[10]), - std::make_pair(":/frame.png", res2hFiles[11]), - std::make_pair(":/off.svg", res2hFiles[12]), - std::make_pair(":/on.svg", res2hFiles[13]), - std::make_pair(":/opensans_hebrew_condensed_light.ttf", res2hFiles[14]), - std::make_pair(":/opensans_hebrew_condensed_regular.ttf", res2hFiles[15]), - std::make_pair(":/option_arrow.svg", res2hFiles[16]), - std::make_pair(":/scroll_gradient.png", res2hFiles[17]), - std::make_pair(":/slider_knob.svg", res2hFiles[18]), - std::make_pair(":/splash.svg", res2hFiles[19]), - std::make_pair(":/star_filled.svg", res2hFiles[20]), + std::make_pair(":/scroll_gradient.png", res2hFiles[0]), + std::make_pair(":/star_filled.svg", res2hFiles[1]), + std::make_pair(":/window_icon_256.png", res2hFiles[2]), + std::make_pair(":/off.svg", res2hFiles[3]), + std::make_pair(":/button_filled.png", res2hFiles[4]), + std::make_pair(":/checkbox_unchecked.svg", res2hFiles[5]), + std::make_pair(":/opensans_hebrew_condensed_regular.ttf", res2hFiles[6]), + std::make_pair(":/on.svg", res2hFiles[7]), + std::make_pair(":/busy_3.svg", res2hFiles[8]), + std::make_pair(":/opensans_hebrew_condensed_light.ttf", res2hFiles[9]), + std::make_pair(":/checkbox_checked.svg", res2hFiles[10]), + std::make_pair(":/textinput_ninepatch.png", res2hFiles[11]), + std::make_pair(":/option_arrow.svg", res2hFiles[12]), + std::make_pair(":/textinput_ninepatch_active.png", res2hFiles[13]), + std::make_pair(":/splash.svg", res2hFiles[14]), + std::make_pair(":/frame.png", res2hFiles[15]), + std::make_pair(":/slider_knob.svg", res2hFiles[16]), + std::make_pair(":/button.png", res2hFiles[17]), + std::make_pair(":/busy_1.svg", res2hFiles[18]), + std::make_pair(":/fav_remove.svg", res2hFiles[19]), + std::make_pair(":/arrow.svg", res2hFiles[20]), std::make_pair(":/star_unfilled.svg", res2hFiles[21]), - std::make_pair(":/textinput_ninepatch.png", res2hFiles[22]), - std::make_pair(":/textinput_ninepatch_active.png", res2hFiles[23]), - std::make_pair(":/window_icon_256.png", res2hFiles[24]), - std::make_pair(":/help/button_a.svg", res2hFiles[25]), - std::make_pair(":/help/button_b.svg", res2hFiles[26]), - std::make_pair(":/help/button_l.svg", res2hFiles[27]), - std::make_pair(":/help/button_r.svg", res2hFiles[28]), - std::make_pair(":/help/button_select.svg", res2hFiles[29]), - std::make_pair(":/help/button_start.svg", res2hFiles[30]), - std::make_pair(":/help/button_x.svg", res2hFiles[31]), - std::make_pair(":/help/button_y.svg", res2hFiles[32]), - std::make_pair(":/help/dpad_all.svg", res2hFiles[33]), - std::make_pair(":/help/dpad_down.svg", res2hFiles[34]), - std::make_pair(":/help/dpad_left.svg", res2hFiles[35]), - std::make_pair(":/help/dpad_leftright.svg", res2hFiles[36]), - std::make_pair(":/help/dpad_right.svg", res2hFiles[37]), - std::make_pair(":/help/dpad_up.svg", res2hFiles[38]), - std::make_pair(":/help/dpad_updown.svg", res2hFiles[39]) + std::make_pair(":/busy_2.svg", res2hFiles[22]), + std::make_pair(":/busy_0.svg", res2hFiles[23]), + std::make_pair(":/fav_add.svg", res2hFiles[24]), + std::make_pair(":/help/dpad_leftright.svg", res2hFiles[25]), + std::make_pair(":/help/dpad_all.svg", res2hFiles[26]), + std::make_pair(":/help/button_x.svg", res2hFiles[27]), + std::make_pair(":/help/button_a.svg", res2hFiles[28]), + std::make_pair(":/help/button_l.svg", res2hFiles[29]), + std::make_pair(":/help/dpad_down.svg", res2hFiles[30]), + std::make_pair(":/help/analog_up.svg", res2hFiles[31]), + std::make_pair(":/help/dpad_left.svg", res2hFiles[32]), + std::make_pair(":/help/button_start.svg", res2hFiles[33]), + std::make_pair(":/help/dpad_up.svg", res2hFiles[34]), + std::make_pair(":/help/analog_down.svg", res2hFiles[35]), + std::make_pair(":/help/button_y.svg", res2hFiles[36]), + std::make_pair(":/help/button_select.svg", res2hFiles[37]), + std::make_pair(":/help/button_b.svg", res2hFiles[38]), + std::make_pair(":/help/dpad_updown.svg", res2hFiles[39]), + std::make_pair(":/help/dpad_right.svg", res2hFiles[40]), + std::make_pair(":/help/button_r.svg", res2hFiles[41]), + std::make_pair(":/help/analog_thumb.svg", res2hFiles[42]), + std::make_pair(":/help/analog_left.svg", res2hFiles[43]), + std::make_pair(":/help/analog_right.svg", res2hFiles[44]) }; res2hMapType res2hMap(mapTemp, mapTemp + sizeof mapTemp / sizeof mapTemp[0]); diff --git a/data/Resources.h b/data/Resources.h index 376ed4658a..25268351fb 100644 --- a/data/Resources.h +++ b/data/Resources.h @@ -5,125 +5,140 @@ #include #include -extern const size_t arrow_svg_size; -extern const unsigned char arrow_svg_data[]; - -extern const size_t busy_0_svg_size; -extern const unsigned char busy_0_svg_data[]; - -extern const size_t busy_1_svg_size; -extern const unsigned char busy_1_svg_data[]; +extern const size_t scroll_gradient_png_size; +extern const unsigned char scroll_gradient_png_data[]; -extern const size_t busy_2_svg_size; -extern const unsigned char busy_2_svg_data[]; +extern const size_t star_filled_svg_size; +extern const unsigned char star_filled_svg_data[]; -extern const size_t busy_3_svg_size; -extern const unsigned char busy_3_svg_data[]; +extern const size_t window_icon_256_png_size; +extern const unsigned char window_icon_256_png_data[]; -extern const size_t button_png_size; -extern const unsigned char button_png_data[]; +extern const size_t off_svg_size; +extern const unsigned char off_svg_data[]; extern const size_t button_filled_png_size; extern const unsigned char button_filled_png_data[]; -extern const size_t checkbox_checked_svg_size; -extern const unsigned char checkbox_checked_svg_data[]; - extern const size_t checkbox_unchecked_svg_size; extern const unsigned char checkbox_unchecked_svg_data[]; -extern const size_t fav_add_svg_size; -extern const unsigned char fav_add_svg_data[]; - -extern const size_t fav_remove_svg_size; -extern const unsigned char fav_remove_svg_data[]; - -extern const size_t frame_png_size; -extern const unsigned char frame_png_data[]; - -extern const size_t off_svg_size; -extern const unsigned char off_svg_data[]; +extern const size_t opensans_hebrew_condensed_regular_ttf_size; +extern const unsigned char opensans_hebrew_condensed_regular_ttf_data[]; extern const size_t on_svg_size; extern const unsigned char on_svg_data[]; +extern const size_t busy_3_svg_size; +extern const unsigned char busy_3_svg_data[]; + extern const size_t opensans_hebrew_condensed_light_ttf_size; extern const unsigned char opensans_hebrew_condensed_light_ttf_data[]; -extern const size_t opensans_hebrew_condensed_regular_ttf_size; -extern const unsigned char opensans_hebrew_condensed_regular_ttf_data[]; +extern const size_t checkbox_checked_svg_size; +extern const unsigned char checkbox_checked_svg_data[]; + +extern const size_t textinput_ninepatch_png_size; +extern const unsigned char textinput_ninepatch_png_data[]; extern const size_t option_arrow_svg_size; extern const unsigned char option_arrow_svg_data[]; -extern const size_t scroll_gradient_png_size; -extern const unsigned char scroll_gradient_png_data[]; +extern const size_t textinput_ninepatch_active_png_size; +extern const unsigned char textinput_ninepatch_active_png_data[]; + +extern const size_t splash_svg_size; +extern const unsigned char splash_svg_data[]; + +extern const size_t frame_png_size; +extern const unsigned char frame_png_data[]; extern const size_t slider_knob_svg_size; extern const unsigned char slider_knob_svg_data[]; -extern const size_t splash_svg_size; -extern const unsigned char splash_svg_data[]; +extern const size_t button_png_size; +extern const unsigned char button_png_data[]; -extern const size_t star_filled_svg_size; -extern const unsigned char star_filled_svg_data[]; +extern const size_t busy_1_svg_size; +extern const unsigned char busy_1_svg_data[]; + +extern const size_t fav_remove_svg_size; +extern const unsigned char fav_remove_svg_data[]; + +extern const size_t arrow_svg_size; +extern const unsigned char arrow_svg_data[]; extern const size_t star_unfilled_svg_size; extern const unsigned char star_unfilled_svg_data[]; -extern const size_t textinput_ninepatch_png_size; -extern const unsigned char textinput_ninepatch_png_data[]; +extern const size_t busy_2_svg_size; +extern const unsigned char busy_2_svg_data[]; -extern const size_t textinput_ninepatch_active_png_size; -extern const unsigned char textinput_ninepatch_active_png_data[]; +extern const size_t busy_0_svg_size; +extern const unsigned char busy_0_svg_data[]; -extern const size_t window_icon_256_png_size; -extern const unsigned char window_icon_256_png_data[]; +extern const size_t fav_add_svg_size; +extern const unsigned char fav_add_svg_data[]; + +extern const size_t help_dpad_leftright_svg_size; +extern const unsigned char help_dpad_leftright_svg_data[]; + +extern const size_t help_dpad_all_svg_size; +extern const unsigned char help_dpad_all_svg_data[]; + +extern const size_t help_button_x_svg_size; +extern const unsigned char help_button_x_svg_data[]; extern const size_t help_button_a_svg_size; extern const unsigned char help_button_a_svg_data[]; -extern const size_t help_button_b_svg_size; -extern const unsigned char help_button_b_svg_data[]; - extern const size_t help_button_l_svg_size; extern const unsigned char help_button_l_svg_data[]; -extern const size_t help_button_r_svg_size; -extern const unsigned char help_button_r_svg_data[]; +extern const size_t help_dpad_down_svg_size; +extern const unsigned char help_dpad_down_svg_data[]; -extern const size_t help_button_select_svg_size; -extern const unsigned char help_button_select_svg_data[]; +extern const size_t help_analog_up_svg_size; +extern const unsigned char help_analog_up_svg_data[]; + +extern const size_t help_dpad_left_svg_size; +extern const unsigned char help_dpad_left_svg_data[]; extern const size_t help_button_start_svg_size; extern const unsigned char help_button_start_svg_data[]; -extern const size_t help_button_x_svg_size; -extern const unsigned char help_button_x_svg_data[]; +extern const size_t help_dpad_up_svg_size; +extern const unsigned char help_dpad_up_svg_data[]; + +extern const size_t help_analog_down_svg_size; +extern const unsigned char help_analog_down_svg_data[]; extern const size_t help_button_y_svg_size; extern const unsigned char help_button_y_svg_data[]; -extern const size_t help_dpad_all_svg_size; -extern const unsigned char help_dpad_all_svg_data[]; - -extern const size_t help_dpad_down_svg_size; -extern const unsigned char help_dpad_down_svg_data[]; +extern const size_t help_button_select_svg_size; +extern const unsigned char help_button_select_svg_data[]; -extern const size_t help_dpad_left_svg_size; -extern const unsigned char help_dpad_left_svg_data[]; +extern const size_t help_button_b_svg_size; +extern const unsigned char help_button_b_svg_data[]; -extern const size_t help_dpad_leftright_svg_size; -extern const unsigned char help_dpad_leftright_svg_data[]; +extern const size_t help_dpad_updown_svg_size; +extern const unsigned char help_dpad_updown_svg_data[]; extern const size_t help_dpad_right_svg_size; extern const unsigned char help_dpad_right_svg_data[]; -extern const size_t help_dpad_up_svg_size; -extern const unsigned char help_dpad_up_svg_data[]; +extern const size_t help_button_r_svg_size; +extern const unsigned char help_button_r_svg_data[]; -extern const size_t help_dpad_updown_svg_size; -extern const unsigned char help_dpad_updown_svg_data[]; +extern const size_t help_analog_thumb_svg_size; +extern const unsigned char help_analog_thumb_svg_data[]; + +extern const size_t help_analog_left_svg_size; +extern const unsigned char help_analog_left_svg_data[]; + +extern const size_t help_analog_right_svg_size; +extern const unsigned char help_analog_right_svg_data[]; struct Res2hEntry { const std::string relativeFileName; diff --git a/data/converted/arrow_svg.cpp b/data/converted/arrow_svg.cpp index 781bda0592..8b9af722e3 100644 --- a/data/converted/arrow_svg.cpp +++ b/data/converted/arrow_svg.cpp @@ -2,91 +2,91 @@ #include "../Resources.h" -const size_t arrow_svg_size = 849; -const unsigned char arrow_svg_data[849] = { +const size_t arrow_svg_size = 838; +const unsigned char arrow_svg_data[838] = { 0x3c,0x3f,0x78,0x6d,0x6c,0x20,0x76,0x65,0x72,0x73, 0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x30,0x22,0x20, 0x65,0x6e,0x63,0x6f,0x64,0x69,0x6e,0x67,0x3d,0x22, - 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0d,0x0a, - 0x3c,0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72, - 0x61,0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62, - 0x65,0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61, - 0x74,0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33, - 0x2c,0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f, - 0x72,0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e, - 0x20,0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72, - 0x73,0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30, - 0x20,0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20, - 0x20,0x2d,0x2d,0x3e,0x0d,0x0a,0x3c,0x21,0x44,0x4f, - 0x43,0x54,0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20, - 0x50,0x55,0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f, - 0x2f,0x57,0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20, - 0x53,0x56,0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45, - 0x4e,0x22,0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, - 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, - 0x67,0x2f,0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73, - 0x2f,0x53,0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44, - 0x54,0x44,0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64, - 0x74,0x64,0x22,0x3e,0x0d,0x0a,0x3c,0x73,0x76,0x67, - 0x20,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22, - 0x31,0x2e,0x31,0x22,0x20,0x69,0x64,0x3d,0x22,0x45, - 0x62,0x65,0x6e,0x65,0x5f,0x31,0x22,0x20,0x78,0x6d, - 0x6c,0x6e,0x73,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a, - 0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f, - 0x72,0x67,0x2f,0x32,0x30,0x30,0x30,0x2f,0x73,0x76, - 0x67,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78, - 0x6c,0x69,0x6e,0x6b,0x3d,0x22,0x68,0x74,0x74,0x70, - 0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e, - 0x6f,0x72,0x67,0x2f,0x31,0x39,0x39,0x39,0x2f,0x78, - 0x6c,0x69,0x6e,0x6b,0x22,0x20,0x78,0x3d,0x22,0x30, - 0x70,0x78,0x22,0x20,0x79,0x3d,0x22,0x30,0x70,0x78, - 0x22,0x0d,0x0a,0x09,0x20,0x77,0x69,0x64,0x74,0x68, - 0x3d,0x22,0x31,0x32,0x2e,0x31,0x36,0x35,0x70,0x78, - 0x22,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3d,0x22, - 0x32,0x31,0x2e,0x39,0x32,0x31,0x70,0x78,0x22,0x20, - 0x76,0x69,0x65,0x77,0x42,0x6f,0x78,0x3d,0x22,0x30, - 0x20,0x30,0x20,0x31,0x32,0x2e,0x31,0x36,0x35,0x20, - 0x32,0x31,0x2e,0x39,0x32,0x31,0x22,0x20,0x65,0x6e, - 0x61,0x62,0x6c,0x65,0x2d,0x62,0x61,0x63,0x6b,0x67, - 0x72,0x6f,0x75,0x6e,0x64,0x3d,0x22,0x6e,0x65,0x77, - 0x20,0x30,0x20,0x30,0x20,0x31,0x32,0x2e,0x31,0x36, - 0x35,0x20,0x32,0x31,0x2e,0x39,0x32,0x31,0x22,0x20, - 0x78,0x6d,0x6c,0x3a,0x73,0x70,0x61,0x63,0x65,0x3d, - 0x22,0x70,0x72,0x65,0x73,0x65,0x72,0x76,0x65,0x22, - 0x3e,0x0d,0x0a,0x3c,0x67,0x3e,0x0d,0x0a,0x09,0x3c, - 0x70,0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d, - 0x22,0x23,0x37,0x37,0x37,0x37,0x37,0x37,0x22,0x20, - 0x64,0x3d,0x22,0x4d,0x30,0x2e,0x37,0x35,0x2c,0x32, - 0x31,0x2e,0x39,0x32,0x31,0x63,0x2d,0x30,0x2e,0x31, - 0x39,0x37,0x2c,0x30,0x2d,0x30,0x2e,0x33,0x39,0x35, - 0x2d,0x30,0x2e,0x30,0x37,0x37,0x2d,0x30,0x2e,0x35, - 0x34,0x32,0x2d,0x30,0x2e,0x32,0x33,0x31,0x63,0x2d, - 0x30,0x2e,0x32,0x38,0x37,0x2d,0x30,0x2e,0x32,0x39, - 0x39,0x2d,0x30,0x2e,0x32,0x37,0x36,0x2d,0x30,0x2e, - 0x37,0x37,0x33,0x2c,0x30,0x2e,0x30,0x32,0x33,0x2d, - 0x31,0x2e,0x30,0x36,0x31,0x6c,0x31,0x30,0x2e,0x30, - 0x39,0x38,0x2d,0x39,0x2e,0x36,0x36,0x38,0x0d,0x0a, - 0x09,0x09,0x4c,0x30,0x2e,0x32,0x33,0x31,0x2c,0x31, - 0x2e,0x32,0x39,0x32,0x63,0x2d,0x30,0x2e,0x32,0x39, - 0x39,0x2d,0x30,0x2e,0x32,0x38,0x36,0x2d,0x30,0x2e, - 0x33,0x31,0x2d,0x30,0x2e,0x37,0x36,0x31,0x2d,0x30, - 0x2e,0x30,0x32,0x33,0x2d,0x31,0x2e,0x30,0x36,0x63, - 0x30,0x2e,0x32,0x38,0x36,0x2d,0x30,0x2e,0x33,0x2c, - 0x30,0x2e,0x37,0x36,0x31,0x2d,0x30,0x2e,0x33,0x31, - 0x2c,0x31,0x2e,0x30,0x36,0x2d,0x30,0x2e,0x30,0x32, - 0x33,0x6c,0x31,0x30,0x2e,0x36,0x36,0x35,0x2c,0x31, - 0x30,0x2e,0x32,0x31,0x31,0x0d,0x0a,0x09,0x09,0x63, - 0x30,0x2e,0x31,0x34,0x37,0x2c,0x30,0x2e,0x31,0x34, - 0x31,0x2c,0x30,0x2e,0x32,0x33,0x31,0x2c,0x30,0x2e, - 0x33,0x33,0x37,0x2c,0x30,0x2e,0x32,0x33,0x31,0x2c, - 0x30,0x2e,0x35,0x34,0x32,0x73,0x2d,0x30,0x2e,0x30, - 0x38,0x34,0x2c,0x30,0x2e,0x34,0x2d,0x30,0x2e,0x32, - 0x33,0x31,0x2c,0x30,0x2e,0x35,0x34,0x32,0x4c,0x31, - 0x2e,0x32,0x36,0x39,0x2c,0x32,0x31,0x2e,0x37,0x31, - 0x33,0x43,0x31,0x2e,0x31,0x32,0x34,0x2c,0x32,0x31, - 0x2e,0x38,0x35,0x32,0x2c,0x30,0x2e,0x39,0x33,0x37, - 0x2c,0x32,0x31,0x2e,0x39,0x32,0x31,0x2c,0x30,0x2e, - 0x37,0x35,0x2c,0x32,0x31,0x2e,0x39,0x32,0x31,0x7a, - 0x22,0x2f,0x3e,0x0d,0x0a,0x3c,0x2f,0x67,0x3e,0x0d, - 0x0a,0x3c,0x2f,0x73,0x76,0x67,0x3e,0x0d,0x0a + 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0a,0x3c, + 0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72,0x61, + 0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62,0x65, + 0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61,0x74, + 0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33,0x2c, + 0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f,0x72, + 0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e,0x20, + 0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72,0x73, + 0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30,0x20, + 0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20,0x20, + 0x2d,0x2d,0x3e,0x0a,0x3c,0x21,0x44,0x4f,0x43,0x54, + 0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20,0x50,0x55, + 0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f,0x2f,0x57, + 0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20,0x53,0x56, + 0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45,0x4e,0x22, + 0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73,0x2f,0x53, + 0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44,0x54,0x44, + 0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64,0x74,0x64, + 0x22,0x3e,0x0a,0x3c,0x73,0x76,0x67,0x20,0x76,0x65, + 0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x31, + 0x22,0x20,0x69,0x64,0x3d,0x22,0x45,0x62,0x65,0x6e, + 0x65,0x5f,0x31,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73, + 0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x32,0x30,0x30,0x30,0x2f,0x73,0x76,0x67,0x22,0x20, + 0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78,0x6c,0x69,0x6e, + 0x6b,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f, + 0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67, + 0x2f,0x31,0x39,0x39,0x39,0x2f,0x78,0x6c,0x69,0x6e, + 0x6b,0x22,0x20,0x78,0x3d,0x22,0x30,0x70,0x78,0x22, + 0x20,0x79,0x3d,0x22,0x30,0x70,0x78,0x22,0x0a,0x09, + 0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x31,0x32, + 0x2e,0x31,0x36,0x35,0x70,0x78,0x22,0x20,0x68,0x65, + 0x69,0x67,0x68,0x74,0x3d,0x22,0x32,0x31,0x2e,0x39, + 0x32,0x31,0x70,0x78,0x22,0x20,0x76,0x69,0x65,0x77, + 0x42,0x6f,0x78,0x3d,0x22,0x30,0x20,0x30,0x20,0x31, + 0x32,0x2e,0x31,0x36,0x35,0x20,0x32,0x31,0x2e,0x39, + 0x32,0x31,0x22,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65, + 0x2d,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e, + 0x64,0x3d,0x22,0x6e,0x65,0x77,0x20,0x30,0x20,0x30, + 0x20,0x31,0x32,0x2e,0x31,0x36,0x35,0x20,0x32,0x31, + 0x2e,0x39,0x32,0x31,0x22,0x20,0x78,0x6d,0x6c,0x3a, + 0x73,0x70,0x61,0x63,0x65,0x3d,0x22,0x70,0x72,0x65, + 0x73,0x65,0x72,0x76,0x65,0x22,0x3e,0x0a,0x3c,0x67, + 0x3e,0x0a,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66, + 0x69,0x6c,0x6c,0x3d,0x22,0x23,0x37,0x37,0x37,0x37, + 0x37,0x37,0x22,0x20,0x64,0x3d,0x22,0x4d,0x30,0x2e, + 0x37,0x35,0x2c,0x32,0x31,0x2e,0x39,0x32,0x31,0x63, + 0x2d,0x30,0x2e,0x31,0x39,0x37,0x2c,0x30,0x2d,0x30, + 0x2e,0x33,0x39,0x35,0x2d,0x30,0x2e,0x30,0x37,0x37, + 0x2d,0x30,0x2e,0x35,0x34,0x32,0x2d,0x30,0x2e,0x32, + 0x33,0x31,0x63,0x2d,0x30,0x2e,0x32,0x38,0x37,0x2d, + 0x30,0x2e,0x32,0x39,0x39,0x2d,0x30,0x2e,0x32,0x37, + 0x36,0x2d,0x30,0x2e,0x37,0x37,0x33,0x2c,0x30,0x2e, + 0x30,0x32,0x33,0x2d,0x31,0x2e,0x30,0x36,0x31,0x6c, + 0x31,0x30,0x2e,0x30,0x39,0x38,0x2d,0x39,0x2e,0x36, + 0x36,0x38,0x0a,0x09,0x09,0x4c,0x30,0x2e,0x32,0x33, + 0x31,0x2c,0x31,0x2e,0x32,0x39,0x32,0x63,0x2d,0x30, + 0x2e,0x32,0x39,0x39,0x2d,0x30,0x2e,0x32,0x38,0x36, + 0x2d,0x30,0x2e,0x33,0x31,0x2d,0x30,0x2e,0x37,0x36, + 0x31,0x2d,0x30,0x2e,0x30,0x32,0x33,0x2d,0x31,0x2e, + 0x30,0x36,0x63,0x30,0x2e,0x32,0x38,0x36,0x2d,0x30, + 0x2e,0x33,0x2c,0x30,0x2e,0x37,0x36,0x31,0x2d,0x30, + 0x2e,0x33,0x31,0x2c,0x31,0x2e,0x30,0x36,0x2d,0x30, + 0x2e,0x30,0x32,0x33,0x6c,0x31,0x30,0x2e,0x36,0x36, + 0x35,0x2c,0x31,0x30,0x2e,0x32,0x31,0x31,0x0a,0x09, + 0x09,0x63,0x30,0x2e,0x31,0x34,0x37,0x2c,0x30,0x2e, + 0x31,0x34,0x31,0x2c,0x30,0x2e,0x32,0x33,0x31,0x2c, + 0x30,0x2e,0x33,0x33,0x37,0x2c,0x30,0x2e,0x32,0x33, + 0x31,0x2c,0x30,0x2e,0x35,0x34,0x32,0x73,0x2d,0x30, + 0x2e,0x30,0x38,0x34,0x2c,0x30,0x2e,0x34,0x2d,0x30, + 0x2e,0x32,0x33,0x31,0x2c,0x30,0x2e,0x35,0x34,0x32, + 0x4c,0x31,0x2e,0x32,0x36,0x39,0x2c,0x32,0x31,0x2e, + 0x37,0x31,0x33,0x43,0x31,0x2e,0x31,0x32,0x34,0x2c, + 0x32,0x31,0x2e,0x38,0x35,0x32,0x2c,0x30,0x2e,0x39, + 0x33,0x37,0x2c,0x32,0x31,0x2e,0x39,0x32,0x31,0x2c, + 0x30,0x2e,0x37,0x35,0x2c,0x32,0x31,0x2e,0x39,0x32, + 0x31,0x7a,0x22,0x2f,0x3e,0x0a,0x3c,0x2f,0x67,0x3e, + 0x0a,0x3c,0x2f,0x73,0x76,0x67,0x3e,0x0a }; + diff --git a/data/converted/busy_0_svg.cpp b/data/converted/busy_0_svg.cpp index 732d087fc9..d7146d82a1 100644 --- a/data/converted/busy_0_svg.cpp +++ b/data/converted/busy_0_svg.cpp @@ -2,82 +2,81 @@ #include "../Resources.h" -const size_t busy_0_svg_size = 1369; -const unsigned char busy_0_svg_data[1369] = { +const size_t busy_0_svg_size = 1347; +const unsigned char busy_0_svg_data[1347] = { 0x3c,0x3f,0x78,0x6d,0x6c,0x20,0x76,0x65,0x72,0x73, 0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x30,0x22,0x20, 0x65,0x6e,0x63,0x6f,0x64,0x69,0x6e,0x67,0x3d,0x22, - 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0d,0x0a, - 0x3c,0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72, - 0x61,0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62, - 0x65,0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61, - 0x74,0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33, - 0x2c,0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f, - 0x72,0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e, - 0x20,0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72, - 0x73,0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30, - 0x20,0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20, - 0x20,0x2d,0x2d,0x3e,0x0d,0x0a,0x3c,0x21,0x44,0x4f, - 0x43,0x54,0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20, - 0x50,0x55,0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f, - 0x2f,0x57,0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20, - 0x53,0x56,0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45, - 0x4e,0x22,0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, - 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, - 0x67,0x2f,0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73, - 0x2f,0x53,0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44, - 0x54,0x44,0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64, - 0x74,0x64,0x22,0x3e,0x0d,0x0a,0x3c,0x73,0x76,0x67, - 0x20,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22, - 0x31,0x2e,0x31,0x22,0x20,0x69,0x64,0x3d,0x22,0x45, - 0x62,0x65,0x6e,0x65,0x5f,0x31,0x22,0x20,0x78,0x6d, - 0x6c,0x6e,0x73,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a, - 0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f, - 0x72,0x67,0x2f,0x32,0x30,0x30,0x30,0x2f,0x73,0x76, - 0x67,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78, - 0x6c,0x69,0x6e,0x6b,0x3d,0x22,0x68,0x74,0x74,0x70, - 0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e, - 0x6f,0x72,0x67,0x2f,0x31,0x39,0x39,0x39,0x2f,0x78, - 0x6c,0x69,0x6e,0x6b,0x22,0x20,0x78,0x3d,0x22,0x30, - 0x70,0x78,0x22,0x20,0x79,0x3d,0x22,0x30,0x70,0x78, - 0x22,0x0d,0x0a,0x09,0x20,0x77,0x69,0x64,0x74,0x68, - 0x3d,0x22,0x32,0x31,0x2e,0x30,0x30,0x32,0x70,0x78, - 0x22,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3d,0x22, - 0x32,0x32,0x2e,0x30,0x30,0x32,0x70,0x78,0x22,0x20, - 0x76,0x69,0x65,0x77,0x42,0x6f,0x78,0x3d,0x22,0x30, - 0x20,0x30,0x20,0x32,0x31,0x2e,0x30,0x30,0x32,0x20, - 0x32,0x32,0x2e,0x30,0x30,0x32,0x22,0x20,0x65,0x6e, - 0x61,0x62,0x6c,0x65,0x2d,0x62,0x61,0x63,0x6b,0x67, - 0x72,0x6f,0x75,0x6e,0x64,0x3d,0x22,0x6e,0x65,0x77, - 0x20,0x30,0x20,0x30,0x20,0x32,0x31,0x2e,0x30,0x30, - 0x32,0x20,0x32,0x32,0x2e,0x30,0x30,0x32,0x22,0x20, - 0x78,0x6d,0x6c,0x3a,0x73,0x70,0x61,0x63,0x65,0x3d, - 0x22,0x70,0x72,0x65,0x73,0x65,0x72,0x76,0x65,0x22, - 0x3e,0x0d,0x0a,0x3c,0x67,0x20,0x6f,0x70,0x61,0x63, - 0x69,0x74,0x79,0x3d,0x22,0x30,0x2e,0x35,0x22,0x3e, - 0x0d,0x0a,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66, - 0x69,0x6c,0x6c,0x3d,0x22,0x23,0x37,0x37,0x37,0x37, - 0x37,0x37,0x22,0x20,0x64,0x3d,0x22,0x4d,0x32,0x31, - 0x2e,0x30,0x30,0x32,0x2c,0x32,0x31,0x2e,0x32,0x39, - 0x33,0x63,0x30,0x2c,0x30,0x2e,0x33,0x39,0x2d,0x30, - 0x2e,0x33,0x31,0x39,0x2c,0x30,0x2e,0x37,0x30,0x39, - 0x2d,0x30,0x2e,0x37,0x30,0x39,0x2c,0x30,0x2e,0x37, - 0x30,0x39,0x68,0x2d,0x37,0x2e,0x39,0x33,0x37,0x63, - 0x2d,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2d,0x30,0x2e, - 0x37,0x30,0x39,0x2d,0x30,0x2e,0x33,0x31,0x39,0x2d, - 0x30,0x2e,0x37,0x30,0x39,0x2d,0x30,0x2e,0x37,0x30, - 0x39,0x76,0x2d,0x38,0x2e,0x33,0x37,0x39,0x0d,0x0a, - 0x09,0x09,0x63,0x30,0x2d,0x30,0x2e,0x33,0x39,0x2c, - 0x30,0x2e,0x33,0x31,0x39,0x2d,0x30,0x2e,0x37,0x30, - 0x39,0x2c,0x30,0x2e,0x37,0x30,0x39,0x2d,0x30,0x2e, - 0x37,0x30,0x39,0x68,0x37,0x2e,0x39,0x33,0x37,0x63, - 0x30,0x2e,0x33,0x39,0x2c,0x30,0x2c,0x30,0x2e,0x37, - 0x30,0x39,0x2c,0x30,0x2e,0x33,0x31,0x39,0x2c,0x30, + 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0a,0x3c, + 0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72,0x61, + 0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62,0x65, + 0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61,0x74, + 0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33,0x2c, + 0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f,0x72, + 0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e,0x20, + 0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72,0x73, + 0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30,0x20, + 0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20,0x20, + 0x2d,0x2d,0x3e,0x0a,0x3c,0x21,0x44,0x4f,0x43,0x54, + 0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20,0x50,0x55, + 0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f,0x2f,0x57, + 0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20,0x53,0x56, + 0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45,0x4e,0x22, + 0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73,0x2f,0x53, + 0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44,0x54,0x44, + 0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64,0x74,0x64, + 0x22,0x3e,0x0a,0x3c,0x73,0x76,0x67,0x20,0x76,0x65, + 0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x31, + 0x22,0x20,0x69,0x64,0x3d,0x22,0x45,0x62,0x65,0x6e, + 0x65,0x5f,0x31,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73, + 0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x32,0x30,0x30,0x30,0x2f,0x73,0x76,0x67,0x22,0x20, + 0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78,0x6c,0x69,0x6e, + 0x6b,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f, + 0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67, + 0x2f,0x31,0x39,0x39,0x39,0x2f,0x78,0x6c,0x69,0x6e, + 0x6b,0x22,0x20,0x78,0x3d,0x22,0x30,0x70,0x78,0x22, + 0x20,0x79,0x3d,0x22,0x30,0x70,0x78,0x22,0x0a,0x09, + 0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x32,0x31, + 0x2e,0x30,0x30,0x32,0x70,0x78,0x22,0x20,0x68,0x65, + 0x69,0x67,0x68,0x74,0x3d,0x22,0x32,0x32,0x2e,0x30, + 0x30,0x32,0x70,0x78,0x22,0x20,0x76,0x69,0x65,0x77, + 0x42,0x6f,0x78,0x3d,0x22,0x30,0x20,0x30,0x20,0x32, + 0x31,0x2e,0x30,0x30,0x32,0x20,0x32,0x32,0x2e,0x30, + 0x30,0x32,0x22,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65, + 0x2d,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e, + 0x64,0x3d,0x22,0x6e,0x65,0x77,0x20,0x30,0x20,0x30, + 0x20,0x32,0x31,0x2e,0x30,0x30,0x32,0x20,0x32,0x32, + 0x2e,0x30,0x30,0x32,0x22,0x20,0x78,0x6d,0x6c,0x3a, + 0x73,0x70,0x61,0x63,0x65,0x3d,0x22,0x70,0x72,0x65, + 0x73,0x65,0x72,0x76,0x65,0x22,0x3e,0x0a,0x3c,0x67, + 0x20,0x6f,0x70,0x61,0x63,0x69,0x74,0x79,0x3d,0x22, + 0x30,0x2e,0x35,0x22,0x3e,0x0a,0x09,0x3c,0x70,0x61, + 0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23, + 0x37,0x37,0x37,0x37,0x37,0x37,0x22,0x20,0x64,0x3d, + 0x22,0x4d,0x32,0x31,0x2e,0x30,0x30,0x32,0x2c,0x32, + 0x31,0x2e,0x32,0x39,0x33,0x63,0x30,0x2c,0x30,0x2e, + 0x33,0x39,0x2d,0x30,0x2e,0x33,0x31,0x39,0x2c,0x30, + 0x2e,0x37,0x30,0x39,0x2d,0x30,0x2e,0x37,0x30,0x39, + 0x2c,0x30,0x2e,0x37,0x30,0x39,0x68,0x2d,0x37,0x2e, + 0x39,0x33,0x37,0x63,0x2d,0x30,0x2e,0x33,0x39,0x2c, + 0x30,0x2d,0x30,0x2e,0x37,0x30,0x39,0x2d,0x30,0x2e, + 0x33,0x31,0x39,0x2d,0x30,0x2e,0x37,0x30,0x39,0x2d, + 0x30,0x2e,0x37,0x30,0x39,0x76,0x2d,0x38,0x2e,0x33, + 0x37,0x39,0x0a,0x09,0x09,0x63,0x30,0x2d,0x30,0x2e, + 0x33,0x39,0x2c,0x30,0x2e,0x33,0x31,0x39,0x2d,0x30, 0x2e,0x37,0x30,0x39,0x2c,0x30,0x2e,0x37,0x30,0x39, - 0x56,0x32,0x31,0x2e,0x32,0x39,0x33,0x7a,0x22,0x2f, - 0x3e,0x0d,0x0a,0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x3c, - 0x67,0x20,0x6f,0x70,0x61,0x63,0x69,0x74,0x79,0x3d, - 0x22,0x30,0x2e,0x35,0x22,0x3e,0x0d,0x0a,0x09,0x3c, + 0x2d,0x30,0x2e,0x37,0x30,0x39,0x68,0x37,0x2e,0x39, + 0x33,0x37,0x63,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2c, + 0x30,0x2e,0x37,0x30,0x39,0x2c,0x30,0x2e,0x33,0x31, + 0x39,0x2c,0x30,0x2e,0x37,0x30,0x39,0x2c,0x30,0x2e, + 0x37,0x30,0x39,0x56,0x32,0x31,0x2e,0x32,0x39,0x33, + 0x7a,0x22,0x2f,0x3e,0x0a,0x3c,0x2f,0x67,0x3e,0x0a, + 0x3c,0x67,0x20,0x6f,0x70,0x61,0x63,0x69,0x74,0x79, + 0x3d,0x22,0x30,0x2e,0x35,0x22,0x3e,0x0a,0x09,0x3c, 0x70,0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d, 0x22,0x23,0x37,0x37,0x37,0x37,0x37,0x37,0x22,0x20, 0x64,0x3d,0x22,0x4d,0x32,0x31,0x2e,0x30,0x30,0x32, @@ -89,56 +88,56 @@ const unsigned char busy_0_svg_data[1369] = { 0x2c,0x30,0x2d,0x30,0x2e,0x37,0x30,0x39,0x2d,0x30, 0x2e,0x33,0x31,0x39,0x2d,0x30,0x2e,0x37,0x30,0x39, 0x2d,0x30,0x2e,0x37,0x30,0x38,0x56,0x30,0x2e,0x37, - 0x30,0x38,0x0d,0x0a,0x09,0x09,0x63,0x30,0x2d,0x30, - 0x2e,0x33,0x39,0x2c,0x30,0x2e,0x33,0x31,0x39,0x2d, + 0x30,0x38,0x0a,0x09,0x09,0x63,0x30,0x2d,0x30,0x2e, + 0x33,0x39,0x2c,0x30,0x2e,0x33,0x31,0x39,0x2d,0x30, + 0x2e,0x37,0x30,0x38,0x2c,0x30,0x2e,0x37,0x30,0x39, + 0x2d,0x30,0x2e,0x37,0x30,0x38,0x68,0x37,0x2e,0x39, + 0x33,0x37,0x63,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2c, + 0x30,0x2e,0x37,0x30,0x39,0x2c,0x30,0x2e,0x33,0x31, + 0x39,0x2c,0x30,0x2e,0x37,0x30,0x39,0x2c,0x30,0x2e, + 0x37,0x30,0x38,0x56,0x39,0x2e,0x30,0x38,0x38,0x7a, + 0x22,0x2f,0x3e,0x0a,0x3c,0x2f,0x67,0x3e,0x0a,0x3c, + 0x67,0x20,0x6f,0x70,0x61,0x63,0x69,0x74,0x79,0x3d, + 0x22,0x30,0x2e,0x35,0x22,0x3e,0x0a,0x09,0x3c,0x70, + 0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22, + 0x23,0x37,0x37,0x37,0x37,0x37,0x37,0x22,0x20,0x64, + 0x3d,0x22,0x4d,0x39,0x2e,0x33,0x35,0x34,0x2c,0x32, + 0x31,0x2e,0x32,0x39,0x33,0x63,0x30,0x2c,0x30,0x2e, + 0x33,0x39,0x2d,0x30,0x2e,0x33,0x31,0x39,0x2c,0x30, + 0x2e,0x37,0x30,0x39,0x2d,0x30,0x2e,0x37,0x30,0x38, + 0x2c,0x30,0x2e,0x37,0x30,0x39,0x48,0x30,0x2e,0x37, + 0x30,0x38,0x43,0x30,0x2e,0x33,0x31,0x39,0x2c,0x32, + 0x32,0x2e,0x30,0x30,0x32,0x2c,0x30,0x2c,0x32,0x31, + 0x2e,0x36,0x38,0x33,0x2c,0x30,0x2c,0x32,0x31,0x2e, + 0x32,0x39,0x33,0x76,0x2d,0x38,0x2e,0x33,0x37,0x39, + 0x0a,0x09,0x09,0x63,0x30,0x2d,0x30,0x2e,0x33,0x39, + 0x2c,0x30,0x2e,0x33,0x31,0x39,0x2d,0x30,0x2e,0x37, + 0x30,0x39,0x2c,0x30,0x2e,0x37,0x30,0x38,0x2d,0x30, + 0x2e,0x37,0x30,0x39,0x68,0x37,0x2e,0x39,0x33,0x38, + 0x63,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2c,0x30,0x2e, + 0x37,0x30,0x38,0x2c,0x30,0x2e,0x33,0x31,0x39,0x2c, 0x30,0x2e,0x37,0x30,0x38,0x2c,0x30,0x2e,0x37,0x30, - 0x39,0x2d,0x30,0x2e,0x37,0x30,0x38,0x68,0x37,0x2e, - 0x39,0x33,0x37,0x63,0x30,0x2e,0x33,0x39,0x2c,0x30, - 0x2c,0x30,0x2e,0x37,0x30,0x39,0x2c,0x30,0x2e,0x33, - 0x31,0x39,0x2c,0x30,0x2e,0x37,0x30,0x39,0x2c,0x30, - 0x2e,0x37,0x30,0x38,0x56,0x39,0x2e,0x30,0x38,0x38, - 0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x3c,0x2f,0x67,0x3e, - 0x0d,0x0a,0x3c,0x67,0x20,0x6f,0x70,0x61,0x63,0x69, - 0x74,0x79,0x3d,0x22,0x30,0x2e,0x35,0x22,0x3e,0x0d, - 0x0a,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69, - 0x6c,0x6c,0x3d,0x22,0x23,0x37,0x37,0x37,0x37,0x37, - 0x37,0x22,0x20,0x64,0x3d,0x22,0x4d,0x39,0x2e,0x33, - 0x35,0x34,0x2c,0x32,0x31,0x2e,0x32,0x39,0x33,0x63, + 0x39,0x56,0x32,0x31,0x2e,0x32,0x39,0x33,0x7a,0x22, + 0x2f,0x3e,0x0a,0x3c,0x2f,0x67,0x3e,0x0a,0x3c,0x67, + 0x3e,0x0a,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66, + 0x69,0x6c,0x6c,0x3d,0x22,0x23,0x37,0x37,0x37,0x37, + 0x37,0x37,0x22,0x20,0x64,0x3d,0x22,0x4d,0x39,0x2e, + 0x33,0x35,0x34,0x2c,0x39,0x2e,0x30,0x38,0x37,0x63, 0x30,0x2c,0x30,0x2e,0x33,0x39,0x2d,0x30,0x2e,0x33, - 0x31,0x39,0x2c,0x30,0x2e,0x37,0x30,0x39,0x2d,0x30, - 0x2e,0x37,0x30,0x38,0x2c,0x30,0x2e,0x37,0x30,0x39, + 0x31,0x39,0x2c,0x30,0x2e,0x37,0x30,0x38,0x2d,0x30, + 0x2e,0x37,0x30,0x38,0x2c,0x30,0x2e,0x37,0x30,0x38, 0x48,0x30,0x2e,0x37,0x30,0x38,0x43,0x30,0x2e,0x33, - 0x31,0x39,0x2c,0x32,0x32,0x2e,0x30,0x30,0x32,0x2c, - 0x30,0x2c,0x32,0x31,0x2e,0x36,0x38,0x33,0x2c,0x30, - 0x2c,0x32,0x31,0x2e,0x32,0x39,0x33,0x76,0x2d,0x38, - 0x2e,0x33,0x37,0x39,0x0d,0x0a,0x09,0x09,0x63,0x30, - 0x2d,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2e,0x33,0x31, - 0x39,0x2d,0x30,0x2e,0x37,0x30,0x39,0x2c,0x30,0x2e, - 0x37,0x30,0x38,0x2d,0x30,0x2e,0x37,0x30,0x39,0x68, - 0x37,0x2e,0x39,0x33,0x38,0x63,0x30,0x2e,0x33,0x39, - 0x2c,0x30,0x2c,0x30,0x2e,0x37,0x30,0x38,0x2c,0x30, - 0x2e,0x33,0x31,0x39,0x2c,0x30,0x2e,0x37,0x30,0x38, - 0x2c,0x30,0x2e,0x37,0x30,0x39,0x56,0x32,0x31,0x2e, - 0x32,0x39,0x33,0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x3c, - 0x2f,0x67,0x3e,0x0d,0x0a,0x3c,0x67,0x3e,0x0d,0x0a, - 0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69,0x6c, - 0x6c,0x3d,0x22,0x23,0x37,0x37,0x37,0x37,0x37,0x37, - 0x22,0x20,0x64,0x3d,0x22,0x4d,0x39,0x2e,0x33,0x35, - 0x34,0x2c,0x39,0x2e,0x30,0x38,0x37,0x63,0x30,0x2c, - 0x30,0x2e,0x33,0x39,0x2d,0x30,0x2e,0x33,0x31,0x39, - 0x2c,0x30,0x2e,0x37,0x30,0x38,0x2d,0x30,0x2e,0x37, - 0x30,0x38,0x2c,0x30,0x2e,0x37,0x30,0x38,0x48,0x30, - 0x2e,0x37,0x30,0x38,0x43,0x30,0x2e,0x33,0x31,0x39, - 0x2c,0x39,0x2e,0x37,0x39,0x36,0x2c,0x30,0x2c,0x39, - 0x2e,0x34,0x37,0x37,0x2c,0x30,0x2c,0x39,0x2e,0x30, - 0x38,0x37,0x56,0x30,0x2e,0x37,0x30,0x38,0x0d,0x0a, - 0x09,0x09,0x43,0x30,0x2c,0x30,0x2e,0x33,0x31,0x39, - 0x2c,0x30,0x2e,0x33,0x31,0x39,0x2c,0x30,0x2c,0x30, - 0x2e,0x37,0x30,0x38,0x2c,0x30,0x68,0x37,0x2e,0x39, - 0x33,0x38,0x63,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2c, - 0x30,0x2e,0x37,0x30,0x38,0x2c,0x30,0x2e,0x33,0x31, - 0x39,0x2c,0x30,0x2e,0x37,0x30,0x38,0x2c,0x30,0x2e, - 0x37,0x30,0x38,0x56,0x39,0x2e,0x30,0x38,0x37,0x7a, - 0x22,0x2f,0x3e,0x0d,0x0a,0x3c,0x2f,0x67,0x3e,0x0d, - 0x0a,0x3c,0x2f,0x73,0x76,0x67,0x3e,0x0d,0x0a + 0x31,0x39,0x2c,0x39,0x2e,0x37,0x39,0x36,0x2c,0x30, + 0x2c,0x39,0x2e,0x34,0x37,0x37,0x2c,0x30,0x2c,0x39, + 0x2e,0x30,0x38,0x37,0x56,0x30,0x2e,0x37,0x30,0x38, + 0x0a,0x09,0x09,0x43,0x30,0x2c,0x30,0x2e,0x33,0x31, + 0x39,0x2c,0x30,0x2e,0x33,0x31,0x39,0x2c,0x30,0x2c, + 0x30,0x2e,0x37,0x30,0x38,0x2c,0x30,0x68,0x37,0x2e, + 0x39,0x33,0x38,0x63,0x30,0x2e,0x33,0x39,0x2c,0x30, + 0x2c,0x30,0x2e,0x37,0x30,0x38,0x2c,0x30,0x2e,0x33, + 0x31,0x39,0x2c,0x30,0x2e,0x37,0x30,0x38,0x2c,0x30, + 0x2e,0x37,0x30,0x38,0x56,0x39,0x2e,0x30,0x38,0x37, + 0x7a,0x22,0x2f,0x3e,0x0a,0x3c,0x2f,0x67,0x3e,0x0a, + 0x3c,0x2f,0x73,0x76,0x67,0x3e,0x0a }; + diff --git a/data/converted/busy_1_svg.cpp b/data/converted/busy_1_svg.cpp index 6bbc474e17..d7f7f68324 100644 --- a/data/converted/busy_1_svg.cpp +++ b/data/converted/busy_1_svg.cpp @@ -2,81 +2,80 @@ #include "../Resources.h" -const size_t busy_1_svg_size = 1369; -const unsigned char busy_1_svg_data[1369] = { +const size_t busy_1_svg_size = 1347; +const unsigned char busy_1_svg_data[1347] = { 0x3c,0x3f,0x78,0x6d,0x6c,0x20,0x76,0x65,0x72,0x73, 0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x30,0x22,0x20, 0x65,0x6e,0x63,0x6f,0x64,0x69,0x6e,0x67,0x3d,0x22, - 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0d,0x0a, - 0x3c,0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72, - 0x61,0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62, - 0x65,0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61, - 0x74,0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33, - 0x2c,0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f, - 0x72,0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e, - 0x20,0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72, - 0x73,0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30, - 0x20,0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20, - 0x20,0x2d,0x2d,0x3e,0x0d,0x0a,0x3c,0x21,0x44,0x4f, - 0x43,0x54,0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20, - 0x50,0x55,0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f, - 0x2f,0x57,0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20, - 0x53,0x56,0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45, - 0x4e,0x22,0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, - 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, - 0x67,0x2f,0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73, - 0x2f,0x53,0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44, - 0x54,0x44,0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64, - 0x74,0x64,0x22,0x3e,0x0d,0x0a,0x3c,0x73,0x76,0x67, - 0x20,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22, - 0x31,0x2e,0x31,0x22,0x20,0x69,0x64,0x3d,0x22,0x45, - 0x62,0x65,0x6e,0x65,0x5f,0x31,0x22,0x20,0x78,0x6d, - 0x6c,0x6e,0x73,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a, - 0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f, - 0x72,0x67,0x2f,0x32,0x30,0x30,0x30,0x2f,0x73,0x76, - 0x67,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78, - 0x6c,0x69,0x6e,0x6b,0x3d,0x22,0x68,0x74,0x74,0x70, - 0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e, - 0x6f,0x72,0x67,0x2f,0x31,0x39,0x39,0x39,0x2f,0x78, - 0x6c,0x69,0x6e,0x6b,0x22,0x20,0x78,0x3d,0x22,0x30, - 0x70,0x78,0x22,0x20,0x79,0x3d,0x22,0x30,0x70,0x78, - 0x22,0x0d,0x0a,0x09,0x20,0x77,0x69,0x64,0x74,0x68, - 0x3d,0x22,0x32,0x31,0x2e,0x30,0x30,0x32,0x70,0x78, - 0x22,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3d,0x22, - 0x32,0x32,0x2e,0x30,0x30,0x32,0x70,0x78,0x22,0x20, - 0x76,0x69,0x65,0x77,0x42,0x6f,0x78,0x3d,0x22,0x30, - 0x20,0x30,0x20,0x32,0x31,0x2e,0x30,0x30,0x32,0x20, - 0x32,0x32,0x2e,0x30,0x30,0x32,0x22,0x20,0x65,0x6e, - 0x61,0x62,0x6c,0x65,0x2d,0x62,0x61,0x63,0x6b,0x67, - 0x72,0x6f,0x75,0x6e,0x64,0x3d,0x22,0x6e,0x65,0x77, - 0x20,0x30,0x20,0x30,0x20,0x32,0x31,0x2e,0x30,0x30, - 0x32,0x20,0x32,0x32,0x2e,0x30,0x30,0x32,0x22,0x20, - 0x78,0x6d,0x6c,0x3a,0x73,0x70,0x61,0x63,0x65,0x3d, - 0x22,0x70,0x72,0x65,0x73,0x65,0x72,0x76,0x65,0x22, - 0x3e,0x0d,0x0a,0x3c,0x67,0x20,0x6f,0x70,0x61,0x63, - 0x69,0x74,0x79,0x3d,0x22,0x30,0x2e,0x35,0x22,0x3e, - 0x0d,0x0a,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66, - 0x69,0x6c,0x6c,0x3d,0x22,0x23,0x37,0x37,0x37,0x37, - 0x37,0x37,0x22,0x20,0x64,0x3d,0x22,0x4d,0x32,0x31, - 0x2e,0x30,0x30,0x32,0x2c,0x32,0x31,0x2e,0x32,0x39, - 0x33,0x63,0x30,0x2c,0x30,0x2e,0x33,0x39,0x2d,0x30, - 0x2e,0x33,0x31,0x39,0x2c,0x30,0x2e,0x37,0x30,0x39, - 0x2d,0x30,0x2e,0x37,0x30,0x39,0x2c,0x30,0x2e,0x37, - 0x30,0x39,0x68,0x2d,0x37,0x2e,0x39,0x33,0x37,0x63, - 0x2d,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2d,0x30,0x2e, - 0x37,0x30,0x39,0x2d,0x30,0x2e,0x33,0x31,0x39,0x2d, - 0x30,0x2e,0x37,0x30,0x39,0x2d,0x30,0x2e,0x37,0x30, - 0x39,0x76,0x2d,0x38,0x2e,0x33,0x37,0x39,0x0d,0x0a, - 0x09,0x09,0x63,0x30,0x2d,0x30,0x2e,0x33,0x39,0x2c, - 0x30,0x2e,0x33,0x31,0x39,0x2d,0x30,0x2e,0x37,0x30, - 0x39,0x2c,0x30,0x2e,0x37,0x30,0x39,0x2d,0x30,0x2e, - 0x37,0x30,0x39,0x68,0x37,0x2e,0x39,0x33,0x37,0x63, - 0x30,0x2e,0x33,0x39,0x2c,0x30,0x2c,0x30,0x2e,0x37, - 0x30,0x39,0x2c,0x30,0x2e,0x33,0x31,0x39,0x2c,0x30, + 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0a,0x3c, + 0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72,0x61, + 0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62,0x65, + 0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61,0x74, + 0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33,0x2c, + 0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f,0x72, + 0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e,0x20, + 0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72,0x73, + 0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30,0x20, + 0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20,0x20, + 0x2d,0x2d,0x3e,0x0a,0x3c,0x21,0x44,0x4f,0x43,0x54, + 0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20,0x50,0x55, + 0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f,0x2f,0x57, + 0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20,0x53,0x56, + 0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45,0x4e,0x22, + 0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73,0x2f,0x53, + 0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44,0x54,0x44, + 0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64,0x74,0x64, + 0x22,0x3e,0x0a,0x3c,0x73,0x76,0x67,0x20,0x76,0x65, + 0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x31, + 0x22,0x20,0x69,0x64,0x3d,0x22,0x45,0x62,0x65,0x6e, + 0x65,0x5f,0x31,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73, + 0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x32,0x30,0x30,0x30,0x2f,0x73,0x76,0x67,0x22,0x20, + 0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78,0x6c,0x69,0x6e, + 0x6b,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f, + 0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67, + 0x2f,0x31,0x39,0x39,0x39,0x2f,0x78,0x6c,0x69,0x6e, + 0x6b,0x22,0x20,0x78,0x3d,0x22,0x30,0x70,0x78,0x22, + 0x20,0x79,0x3d,0x22,0x30,0x70,0x78,0x22,0x0a,0x09, + 0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x32,0x31, + 0x2e,0x30,0x30,0x32,0x70,0x78,0x22,0x20,0x68,0x65, + 0x69,0x67,0x68,0x74,0x3d,0x22,0x32,0x32,0x2e,0x30, + 0x30,0x32,0x70,0x78,0x22,0x20,0x76,0x69,0x65,0x77, + 0x42,0x6f,0x78,0x3d,0x22,0x30,0x20,0x30,0x20,0x32, + 0x31,0x2e,0x30,0x30,0x32,0x20,0x32,0x32,0x2e,0x30, + 0x30,0x32,0x22,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65, + 0x2d,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e, + 0x64,0x3d,0x22,0x6e,0x65,0x77,0x20,0x30,0x20,0x30, + 0x20,0x32,0x31,0x2e,0x30,0x30,0x32,0x20,0x32,0x32, + 0x2e,0x30,0x30,0x32,0x22,0x20,0x78,0x6d,0x6c,0x3a, + 0x73,0x70,0x61,0x63,0x65,0x3d,0x22,0x70,0x72,0x65, + 0x73,0x65,0x72,0x76,0x65,0x22,0x3e,0x0a,0x3c,0x67, + 0x20,0x6f,0x70,0x61,0x63,0x69,0x74,0x79,0x3d,0x22, + 0x30,0x2e,0x35,0x22,0x3e,0x0a,0x09,0x3c,0x70,0x61, + 0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23, + 0x37,0x37,0x37,0x37,0x37,0x37,0x22,0x20,0x64,0x3d, + 0x22,0x4d,0x32,0x31,0x2e,0x30,0x30,0x32,0x2c,0x32, + 0x31,0x2e,0x32,0x39,0x33,0x63,0x30,0x2c,0x30,0x2e, + 0x33,0x39,0x2d,0x30,0x2e,0x33,0x31,0x39,0x2c,0x30, + 0x2e,0x37,0x30,0x39,0x2d,0x30,0x2e,0x37,0x30,0x39, + 0x2c,0x30,0x2e,0x37,0x30,0x39,0x68,0x2d,0x37,0x2e, + 0x39,0x33,0x37,0x63,0x2d,0x30,0x2e,0x33,0x39,0x2c, + 0x30,0x2d,0x30,0x2e,0x37,0x30,0x39,0x2d,0x30,0x2e, + 0x33,0x31,0x39,0x2d,0x30,0x2e,0x37,0x30,0x39,0x2d, + 0x30,0x2e,0x37,0x30,0x39,0x76,0x2d,0x38,0x2e,0x33, + 0x37,0x39,0x0a,0x09,0x09,0x63,0x30,0x2d,0x30,0x2e, + 0x33,0x39,0x2c,0x30,0x2e,0x33,0x31,0x39,0x2d,0x30, 0x2e,0x37,0x30,0x39,0x2c,0x30,0x2e,0x37,0x30,0x39, - 0x56,0x32,0x31,0x2e,0x32,0x39,0x33,0x7a,0x22,0x2f, - 0x3e,0x0d,0x0a,0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x3c, - 0x67,0x3e,0x0d,0x0a,0x09,0x3c,0x70,0x61,0x74,0x68, + 0x2d,0x30,0x2e,0x37,0x30,0x39,0x68,0x37,0x2e,0x39, + 0x33,0x37,0x63,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2c, + 0x30,0x2e,0x37,0x30,0x39,0x2c,0x30,0x2e,0x33,0x31, + 0x39,0x2c,0x30,0x2e,0x37,0x30,0x39,0x2c,0x30,0x2e, + 0x37,0x30,0x39,0x56,0x32,0x31,0x2e,0x32,0x39,0x33, + 0x7a,0x22,0x2f,0x3e,0x0a,0x3c,0x2f,0x67,0x3e,0x0a, + 0x3c,0x67,0x3e,0x0a,0x09,0x3c,0x70,0x61,0x74,0x68, 0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x37,0x37, 0x37,0x37,0x37,0x37,0x22,0x20,0x64,0x3d,0x22,0x4d, 0x32,0x31,0x2e,0x30,0x30,0x32,0x2c,0x39,0x2e,0x30, @@ -87,58 +86,58 @@ const unsigned char busy_1_svg_data[1369] = { 0x63,0x2d,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2d,0x30, 0x2e,0x37,0x30,0x39,0x2d,0x30,0x2e,0x33,0x31,0x39, 0x2d,0x30,0x2e,0x37,0x30,0x39,0x2d,0x30,0x2e,0x37, - 0x30,0x38,0x56,0x30,0x2e,0x37,0x30,0x38,0x0d,0x0a, - 0x09,0x09,0x63,0x30,0x2d,0x30,0x2e,0x33,0x39,0x2c, - 0x30,0x2e,0x33,0x31,0x39,0x2d,0x30,0x2e,0x37,0x30, - 0x38,0x2c,0x30,0x2e,0x37,0x30,0x39,0x2d,0x30,0x2e, - 0x37,0x30,0x38,0x68,0x37,0x2e,0x39,0x33,0x37,0x63, - 0x30,0x2e,0x33,0x39,0x2c,0x30,0x2c,0x30,0x2e,0x37, - 0x30,0x39,0x2c,0x30,0x2e,0x33,0x31,0x39,0x2c,0x30, - 0x2e,0x37,0x30,0x39,0x2c,0x30,0x2e,0x37,0x30,0x38, - 0x56,0x39,0x2e,0x30,0x38,0x38,0x7a,0x22,0x2f,0x3e, - 0x0d,0x0a,0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x3c,0x67, - 0x20,0x6f,0x70,0x61,0x63,0x69,0x74,0x79,0x3d,0x22, - 0x30,0x2e,0x35,0x22,0x3e,0x0d,0x0a,0x09,0x3c,0x70, - 0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22, - 0x23,0x37,0x37,0x37,0x37,0x37,0x37,0x22,0x20,0x64, - 0x3d,0x22,0x4d,0x39,0x2e,0x33,0x35,0x34,0x2c,0x32, - 0x31,0x2e,0x32,0x39,0x33,0x63,0x30,0x2c,0x30,0x2e, - 0x33,0x39,0x2d,0x30,0x2e,0x33,0x31,0x39,0x2c,0x30, - 0x2e,0x37,0x30,0x39,0x2d,0x30,0x2e,0x37,0x30,0x38, - 0x2c,0x30,0x2e,0x37,0x30,0x39,0x48,0x30,0x2e,0x37, - 0x30,0x38,0x43,0x30,0x2e,0x33,0x31,0x39,0x2c,0x32, - 0x32,0x2e,0x30,0x30,0x32,0x2c,0x30,0x2c,0x32,0x31, - 0x2e,0x36,0x38,0x33,0x2c,0x30,0x2c,0x32,0x31,0x2e, - 0x32,0x39,0x33,0x76,0x2d,0x38,0x2e,0x33,0x37,0x39, - 0x0d,0x0a,0x09,0x09,0x63,0x30,0x2d,0x30,0x2e,0x33, - 0x39,0x2c,0x30,0x2e,0x33,0x31,0x39,0x2d,0x30,0x2e, - 0x37,0x30,0x39,0x2c,0x30,0x2e,0x37,0x30,0x38,0x2d, - 0x30,0x2e,0x37,0x30,0x39,0x68,0x37,0x2e,0x39,0x33, - 0x38,0x63,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2c,0x30, - 0x2e,0x37,0x30,0x38,0x2c,0x30,0x2e,0x33,0x31,0x39, - 0x2c,0x30,0x2e,0x37,0x30,0x38,0x2c,0x30,0x2e,0x37, - 0x30,0x39,0x56,0x32,0x31,0x2e,0x32,0x39,0x33,0x7a, - 0x22,0x2f,0x3e,0x0d,0x0a,0x3c,0x2f,0x67,0x3e,0x0d, - 0x0a,0x3c,0x67,0x20,0x6f,0x70,0x61,0x63,0x69,0x74, - 0x79,0x3d,0x22,0x30,0x2e,0x35,0x22,0x3e,0x0d,0x0a, - 0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69,0x6c, - 0x6c,0x3d,0x22,0x23,0x37,0x37,0x37,0x37,0x37,0x37, - 0x22,0x20,0x64,0x3d,0x22,0x4d,0x39,0x2e,0x33,0x35, - 0x34,0x2c,0x39,0x2e,0x30,0x38,0x37,0x63,0x30,0x2c, - 0x30,0x2e,0x33,0x39,0x2d,0x30,0x2e,0x33,0x31,0x39, - 0x2c,0x30,0x2e,0x37,0x30,0x38,0x2d,0x30,0x2e,0x37, - 0x30,0x38,0x2c,0x30,0x2e,0x37,0x30,0x38,0x48,0x30, - 0x2e,0x37,0x30,0x38,0x43,0x30,0x2e,0x33,0x31,0x39, - 0x2c,0x39,0x2e,0x37,0x39,0x36,0x2c,0x30,0x2c,0x39, - 0x2e,0x34,0x37,0x37,0x2c,0x30,0x2c,0x39,0x2e,0x30, - 0x38,0x37,0x56,0x30,0x2e,0x37,0x30,0x38,0x0d,0x0a, - 0x09,0x09,0x43,0x30,0x2c,0x30,0x2e,0x33,0x31,0x39, - 0x2c,0x30,0x2e,0x33,0x31,0x39,0x2c,0x30,0x2c,0x30, - 0x2e,0x37,0x30,0x38,0x2c,0x30,0x68,0x37,0x2e,0x39, - 0x33,0x38,0x63,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2c, - 0x30,0x2e,0x37,0x30,0x38,0x2c,0x30,0x2e,0x33,0x31, - 0x39,0x2c,0x30,0x2e,0x37,0x30,0x38,0x2c,0x30,0x2e, - 0x37,0x30,0x38,0x56,0x39,0x2e,0x30,0x38,0x37,0x7a, - 0x22,0x2f,0x3e,0x0d,0x0a,0x3c,0x2f,0x67,0x3e,0x0d, - 0x0a,0x3c,0x2f,0x73,0x76,0x67,0x3e,0x0d,0x0a + 0x30,0x38,0x56,0x30,0x2e,0x37,0x30,0x38,0x0a,0x09, + 0x09,0x63,0x30,0x2d,0x30,0x2e,0x33,0x39,0x2c,0x30, + 0x2e,0x33,0x31,0x39,0x2d,0x30,0x2e,0x37,0x30,0x38, + 0x2c,0x30,0x2e,0x37,0x30,0x39,0x2d,0x30,0x2e,0x37, + 0x30,0x38,0x68,0x37,0x2e,0x39,0x33,0x37,0x63,0x30, + 0x2e,0x33,0x39,0x2c,0x30,0x2c,0x30,0x2e,0x37,0x30, + 0x39,0x2c,0x30,0x2e,0x33,0x31,0x39,0x2c,0x30,0x2e, + 0x37,0x30,0x39,0x2c,0x30,0x2e,0x37,0x30,0x38,0x56, + 0x39,0x2e,0x30,0x38,0x38,0x7a,0x22,0x2f,0x3e,0x0a, + 0x3c,0x2f,0x67,0x3e,0x0a,0x3c,0x67,0x20,0x6f,0x70, + 0x61,0x63,0x69,0x74,0x79,0x3d,0x22,0x30,0x2e,0x35, + 0x22,0x3e,0x0a,0x09,0x3c,0x70,0x61,0x74,0x68,0x20, + 0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x37,0x37,0x37, + 0x37,0x37,0x37,0x22,0x20,0x64,0x3d,0x22,0x4d,0x39, + 0x2e,0x33,0x35,0x34,0x2c,0x32,0x31,0x2e,0x32,0x39, + 0x33,0x63,0x30,0x2c,0x30,0x2e,0x33,0x39,0x2d,0x30, + 0x2e,0x33,0x31,0x39,0x2c,0x30,0x2e,0x37,0x30,0x39, + 0x2d,0x30,0x2e,0x37,0x30,0x38,0x2c,0x30,0x2e,0x37, + 0x30,0x39,0x48,0x30,0x2e,0x37,0x30,0x38,0x43,0x30, + 0x2e,0x33,0x31,0x39,0x2c,0x32,0x32,0x2e,0x30,0x30, + 0x32,0x2c,0x30,0x2c,0x32,0x31,0x2e,0x36,0x38,0x33, + 0x2c,0x30,0x2c,0x32,0x31,0x2e,0x32,0x39,0x33,0x76, + 0x2d,0x38,0x2e,0x33,0x37,0x39,0x0a,0x09,0x09,0x63, + 0x30,0x2d,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2e,0x33, + 0x31,0x39,0x2d,0x30,0x2e,0x37,0x30,0x39,0x2c,0x30, + 0x2e,0x37,0x30,0x38,0x2d,0x30,0x2e,0x37,0x30,0x39, + 0x68,0x37,0x2e,0x39,0x33,0x38,0x63,0x30,0x2e,0x33, + 0x39,0x2c,0x30,0x2c,0x30,0x2e,0x37,0x30,0x38,0x2c, + 0x30,0x2e,0x33,0x31,0x39,0x2c,0x30,0x2e,0x37,0x30, + 0x38,0x2c,0x30,0x2e,0x37,0x30,0x39,0x56,0x32,0x31, + 0x2e,0x32,0x39,0x33,0x7a,0x22,0x2f,0x3e,0x0a,0x3c, + 0x2f,0x67,0x3e,0x0a,0x3c,0x67,0x20,0x6f,0x70,0x61, + 0x63,0x69,0x74,0x79,0x3d,0x22,0x30,0x2e,0x35,0x22, + 0x3e,0x0a,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66, + 0x69,0x6c,0x6c,0x3d,0x22,0x23,0x37,0x37,0x37,0x37, + 0x37,0x37,0x22,0x20,0x64,0x3d,0x22,0x4d,0x39,0x2e, + 0x33,0x35,0x34,0x2c,0x39,0x2e,0x30,0x38,0x37,0x63, + 0x30,0x2c,0x30,0x2e,0x33,0x39,0x2d,0x30,0x2e,0x33, + 0x31,0x39,0x2c,0x30,0x2e,0x37,0x30,0x38,0x2d,0x30, + 0x2e,0x37,0x30,0x38,0x2c,0x30,0x2e,0x37,0x30,0x38, + 0x48,0x30,0x2e,0x37,0x30,0x38,0x43,0x30,0x2e,0x33, + 0x31,0x39,0x2c,0x39,0x2e,0x37,0x39,0x36,0x2c,0x30, + 0x2c,0x39,0x2e,0x34,0x37,0x37,0x2c,0x30,0x2c,0x39, + 0x2e,0x30,0x38,0x37,0x56,0x30,0x2e,0x37,0x30,0x38, + 0x0a,0x09,0x09,0x43,0x30,0x2c,0x30,0x2e,0x33,0x31, + 0x39,0x2c,0x30,0x2e,0x33,0x31,0x39,0x2c,0x30,0x2c, + 0x30,0x2e,0x37,0x30,0x38,0x2c,0x30,0x68,0x37,0x2e, + 0x39,0x33,0x38,0x63,0x30,0x2e,0x33,0x39,0x2c,0x30, + 0x2c,0x30,0x2e,0x37,0x30,0x38,0x2c,0x30,0x2e,0x33, + 0x31,0x39,0x2c,0x30,0x2e,0x37,0x30,0x38,0x2c,0x30, + 0x2e,0x37,0x30,0x38,0x56,0x39,0x2e,0x30,0x38,0x37, + 0x7a,0x22,0x2f,0x3e,0x0a,0x3c,0x2f,0x67,0x3e,0x0a, + 0x3c,0x2f,0x73,0x76,0x67,0x3e,0x0a }; + diff --git a/data/converted/busy_2_svg.cpp b/data/converted/busy_2_svg.cpp index 46896deb6f..543b728a91 100644 --- a/data/converted/busy_2_svg.cpp +++ b/data/converted/busy_2_svg.cpp @@ -2,81 +2,80 @@ #include "../Resources.h" -const size_t busy_2_svg_size = 1369; -const unsigned char busy_2_svg_data[1369] = { +const size_t busy_2_svg_size = 1347; +const unsigned char busy_2_svg_data[1347] = { 0x3c,0x3f,0x78,0x6d,0x6c,0x20,0x76,0x65,0x72,0x73, 0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x30,0x22,0x20, 0x65,0x6e,0x63,0x6f,0x64,0x69,0x6e,0x67,0x3d,0x22, - 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0d,0x0a, - 0x3c,0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72, - 0x61,0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62, - 0x65,0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61, - 0x74,0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33, - 0x2c,0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f, - 0x72,0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e, - 0x20,0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72, - 0x73,0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30, - 0x20,0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20, - 0x20,0x2d,0x2d,0x3e,0x0d,0x0a,0x3c,0x21,0x44,0x4f, - 0x43,0x54,0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20, - 0x50,0x55,0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f, - 0x2f,0x57,0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20, - 0x53,0x56,0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45, - 0x4e,0x22,0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, - 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, - 0x67,0x2f,0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73, - 0x2f,0x53,0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44, - 0x54,0x44,0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64, - 0x74,0x64,0x22,0x3e,0x0d,0x0a,0x3c,0x73,0x76,0x67, - 0x20,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22, - 0x31,0x2e,0x31,0x22,0x20,0x69,0x64,0x3d,0x22,0x45, - 0x62,0x65,0x6e,0x65,0x5f,0x31,0x22,0x20,0x78,0x6d, - 0x6c,0x6e,0x73,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a, - 0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f, - 0x72,0x67,0x2f,0x32,0x30,0x30,0x30,0x2f,0x73,0x76, - 0x67,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78, - 0x6c,0x69,0x6e,0x6b,0x3d,0x22,0x68,0x74,0x74,0x70, - 0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e, - 0x6f,0x72,0x67,0x2f,0x31,0x39,0x39,0x39,0x2f,0x78, - 0x6c,0x69,0x6e,0x6b,0x22,0x20,0x78,0x3d,0x22,0x30, - 0x70,0x78,0x22,0x20,0x79,0x3d,0x22,0x30,0x70,0x78, - 0x22,0x0d,0x0a,0x09,0x20,0x77,0x69,0x64,0x74,0x68, - 0x3d,0x22,0x32,0x31,0x2e,0x30,0x30,0x32,0x70,0x78, - 0x22,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3d,0x22, - 0x32,0x32,0x2e,0x30,0x30,0x32,0x70,0x78,0x22,0x20, - 0x76,0x69,0x65,0x77,0x42,0x6f,0x78,0x3d,0x22,0x30, - 0x20,0x30,0x20,0x32,0x31,0x2e,0x30,0x30,0x32,0x20, - 0x32,0x32,0x2e,0x30,0x30,0x32,0x22,0x20,0x65,0x6e, - 0x61,0x62,0x6c,0x65,0x2d,0x62,0x61,0x63,0x6b,0x67, - 0x72,0x6f,0x75,0x6e,0x64,0x3d,0x22,0x6e,0x65,0x77, - 0x20,0x30,0x20,0x30,0x20,0x32,0x31,0x2e,0x30,0x30, - 0x32,0x20,0x32,0x32,0x2e,0x30,0x30,0x32,0x22,0x20, - 0x78,0x6d,0x6c,0x3a,0x73,0x70,0x61,0x63,0x65,0x3d, - 0x22,0x70,0x72,0x65,0x73,0x65,0x72,0x76,0x65,0x22, - 0x3e,0x0d,0x0a,0x3c,0x67,0x3e,0x0d,0x0a,0x09,0x3c, - 0x70,0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d, - 0x22,0x23,0x37,0x37,0x37,0x37,0x37,0x37,0x22,0x20, - 0x64,0x3d,0x22,0x4d,0x32,0x31,0x2e,0x30,0x30,0x32, - 0x2c,0x32,0x31,0x2e,0x32,0x39,0x33,0x63,0x30,0x2c, - 0x30,0x2e,0x33,0x39,0x2d,0x30,0x2e,0x33,0x31,0x39, - 0x2c,0x30,0x2e,0x37,0x30,0x39,0x2d,0x30,0x2e,0x37, - 0x30,0x39,0x2c,0x30,0x2e,0x37,0x30,0x39,0x68,0x2d, - 0x37,0x2e,0x39,0x33,0x37,0x63,0x2d,0x30,0x2e,0x33, - 0x39,0x2c,0x30,0x2d,0x30,0x2e,0x37,0x30,0x39,0x2d, - 0x30,0x2e,0x33,0x31,0x39,0x2d,0x30,0x2e,0x37,0x30, - 0x39,0x2d,0x30,0x2e,0x37,0x30,0x39,0x76,0x2d,0x38, - 0x2e,0x33,0x37,0x39,0x0d,0x0a,0x09,0x09,0x63,0x30, - 0x2d,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2e,0x33,0x31, - 0x39,0x2d,0x30,0x2e,0x37,0x30,0x39,0x2c,0x30,0x2e, - 0x37,0x30,0x39,0x2d,0x30,0x2e,0x37,0x30,0x39,0x68, - 0x37,0x2e,0x39,0x33,0x37,0x63,0x30,0x2e,0x33,0x39, - 0x2c,0x30,0x2c,0x30,0x2e,0x37,0x30,0x39,0x2c,0x30, + 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0a,0x3c, + 0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72,0x61, + 0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62,0x65, + 0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61,0x74, + 0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33,0x2c, + 0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f,0x72, + 0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e,0x20, + 0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72,0x73, + 0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30,0x20, + 0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20,0x20, + 0x2d,0x2d,0x3e,0x0a,0x3c,0x21,0x44,0x4f,0x43,0x54, + 0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20,0x50,0x55, + 0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f,0x2f,0x57, + 0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20,0x53,0x56, + 0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45,0x4e,0x22, + 0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73,0x2f,0x53, + 0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44,0x54,0x44, + 0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64,0x74,0x64, + 0x22,0x3e,0x0a,0x3c,0x73,0x76,0x67,0x20,0x76,0x65, + 0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x31, + 0x22,0x20,0x69,0x64,0x3d,0x22,0x45,0x62,0x65,0x6e, + 0x65,0x5f,0x31,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73, + 0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x32,0x30,0x30,0x30,0x2f,0x73,0x76,0x67,0x22,0x20, + 0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78,0x6c,0x69,0x6e, + 0x6b,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f, + 0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67, + 0x2f,0x31,0x39,0x39,0x39,0x2f,0x78,0x6c,0x69,0x6e, + 0x6b,0x22,0x20,0x78,0x3d,0x22,0x30,0x70,0x78,0x22, + 0x20,0x79,0x3d,0x22,0x30,0x70,0x78,0x22,0x0a,0x09, + 0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x32,0x31, + 0x2e,0x30,0x30,0x32,0x70,0x78,0x22,0x20,0x68,0x65, + 0x69,0x67,0x68,0x74,0x3d,0x22,0x32,0x32,0x2e,0x30, + 0x30,0x32,0x70,0x78,0x22,0x20,0x76,0x69,0x65,0x77, + 0x42,0x6f,0x78,0x3d,0x22,0x30,0x20,0x30,0x20,0x32, + 0x31,0x2e,0x30,0x30,0x32,0x20,0x32,0x32,0x2e,0x30, + 0x30,0x32,0x22,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65, + 0x2d,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e, + 0x64,0x3d,0x22,0x6e,0x65,0x77,0x20,0x30,0x20,0x30, + 0x20,0x32,0x31,0x2e,0x30,0x30,0x32,0x20,0x32,0x32, + 0x2e,0x30,0x30,0x32,0x22,0x20,0x78,0x6d,0x6c,0x3a, + 0x73,0x70,0x61,0x63,0x65,0x3d,0x22,0x70,0x72,0x65, + 0x73,0x65,0x72,0x76,0x65,0x22,0x3e,0x0a,0x3c,0x67, + 0x3e,0x0a,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66, + 0x69,0x6c,0x6c,0x3d,0x22,0x23,0x37,0x37,0x37,0x37, + 0x37,0x37,0x22,0x20,0x64,0x3d,0x22,0x4d,0x32,0x31, + 0x2e,0x30,0x30,0x32,0x2c,0x32,0x31,0x2e,0x32,0x39, + 0x33,0x63,0x30,0x2c,0x30,0x2e,0x33,0x39,0x2d,0x30, 0x2e,0x33,0x31,0x39,0x2c,0x30,0x2e,0x37,0x30,0x39, - 0x2c,0x30,0x2e,0x37,0x30,0x39,0x56,0x32,0x31,0x2e, - 0x32,0x39,0x33,0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x3c, - 0x2f,0x67,0x3e,0x0d,0x0a,0x3c,0x67,0x20,0x6f,0x70, - 0x61,0x63,0x69,0x74,0x79,0x3d,0x22,0x30,0x2e,0x35, - 0x22,0x3e,0x0d,0x0a,0x09,0x3c,0x70,0x61,0x74,0x68, + 0x2d,0x30,0x2e,0x37,0x30,0x39,0x2c,0x30,0x2e,0x37, + 0x30,0x39,0x68,0x2d,0x37,0x2e,0x39,0x33,0x37,0x63, + 0x2d,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2d,0x30,0x2e, + 0x37,0x30,0x39,0x2d,0x30,0x2e,0x33,0x31,0x39,0x2d, + 0x30,0x2e,0x37,0x30,0x39,0x2d,0x30,0x2e,0x37,0x30, + 0x39,0x76,0x2d,0x38,0x2e,0x33,0x37,0x39,0x0a,0x09, + 0x09,0x63,0x30,0x2d,0x30,0x2e,0x33,0x39,0x2c,0x30, + 0x2e,0x33,0x31,0x39,0x2d,0x30,0x2e,0x37,0x30,0x39, + 0x2c,0x30,0x2e,0x37,0x30,0x39,0x2d,0x30,0x2e,0x37, + 0x30,0x39,0x68,0x37,0x2e,0x39,0x33,0x37,0x63,0x30, + 0x2e,0x33,0x39,0x2c,0x30,0x2c,0x30,0x2e,0x37,0x30, + 0x39,0x2c,0x30,0x2e,0x33,0x31,0x39,0x2c,0x30,0x2e, + 0x37,0x30,0x39,0x2c,0x30,0x2e,0x37,0x30,0x39,0x56, + 0x32,0x31,0x2e,0x32,0x39,0x33,0x7a,0x22,0x2f,0x3e, + 0x0a,0x3c,0x2f,0x67,0x3e,0x0a,0x3c,0x67,0x20,0x6f, + 0x70,0x61,0x63,0x69,0x74,0x79,0x3d,0x22,0x30,0x2e, + 0x35,0x22,0x3e,0x0a,0x09,0x3c,0x70,0x61,0x74,0x68, 0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x37,0x37, 0x37,0x37,0x37,0x37,0x22,0x20,0x64,0x3d,0x22,0x4d, 0x32,0x31,0x2e,0x30,0x30,0x32,0x2c,0x39,0x2e,0x30, @@ -87,58 +86,58 @@ const unsigned char busy_2_svg_data[1369] = { 0x63,0x2d,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2d,0x30, 0x2e,0x37,0x30,0x39,0x2d,0x30,0x2e,0x33,0x31,0x39, 0x2d,0x30,0x2e,0x37,0x30,0x39,0x2d,0x30,0x2e,0x37, - 0x30,0x38,0x56,0x30,0x2e,0x37,0x30,0x38,0x0d,0x0a, - 0x09,0x09,0x63,0x30,0x2d,0x30,0x2e,0x33,0x39,0x2c, - 0x30,0x2e,0x33,0x31,0x39,0x2d,0x30,0x2e,0x37,0x30, - 0x38,0x2c,0x30,0x2e,0x37,0x30,0x39,0x2d,0x30,0x2e, - 0x37,0x30,0x38,0x68,0x37,0x2e,0x39,0x33,0x37,0x63, - 0x30,0x2e,0x33,0x39,0x2c,0x30,0x2c,0x30,0x2e,0x37, - 0x30,0x39,0x2c,0x30,0x2e,0x33,0x31,0x39,0x2c,0x30, - 0x2e,0x37,0x30,0x39,0x2c,0x30,0x2e,0x37,0x30,0x38, - 0x56,0x39,0x2e,0x30,0x38,0x38,0x7a,0x22,0x2f,0x3e, - 0x0d,0x0a,0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x3c,0x67, - 0x20,0x6f,0x70,0x61,0x63,0x69,0x74,0x79,0x3d,0x22, - 0x30,0x2e,0x35,0x22,0x3e,0x0d,0x0a,0x09,0x3c,0x70, - 0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22, - 0x23,0x37,0x37,0x37,0x37,0x37,0x37,0x22,0x20,0x64, - 0x3d,0x22,0x4d,0x39,0x2e,0x33,0x35,0x34,0x2c,0x32, - 0x31,0x2e,0x32,0x39,0x33,0x63,0x30,0x2c,0x30,0x2e, - 0x33,0x39,0x2d,0x30,0x2e,0x33,0x31,0x39,0x2c,0x30, - 0x2e,0x37,0x30,0x39,0x2d,0x30,0x2e,0x37,0x30,0x38, - 0x2c,0x30,0x2e,0x37,0x30,0x39,0x48,0x30,0x2e,0x37, - 0x30,0x38,0x43,0x30,0x2e,0x33,0x31,0x39,0x2c,0x32, - 0x32,0x2e,0x30,0x30,0x32,0x2c,0x30,0x2c,0x32,0x31, - 0x2e,0x36,0x38,0x33,0x2c,0x30,0x2c,0x32,0x31,0x2e, - 0x32,0x39,0x33,0x76,0x2d,0x38,0x2e,0x33,0x37,0x39, - 0x0d,0x0a,0x09,0x09,0x63,0x30,0x2d,0x30,0x2e,0x33, - 0x39,0x2c,0x30,0x2e,0x33,0x31,0x39,0x2d,0x30,0x2e, - 0x37,0x30,0x39,0x2c,0x30,0x2e,0x37,0x30,0x38,0x2d, - 0x30,0x2e,0x37,0x30,0x39,0x68,0x37,0x2e,0x39,0x33, - 0x38,0x63,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2c,0x30, - 0x2e,0x37,0x30,0x38,0x2c,0x30,0x2e,0x33,0x31,0x39, - 0x2c,0x30,0x2e,0x37,0x30,0x38,0x2c,0x30,0x2e,0x37, - 0x30,0x39,0x56,0x32,0x31,0x2e,0x32,0x39,0x33,0x7a, - 0x22,0x2f,0x3e,0x0d,0x0a,0x3c,0x2f,0x67,0x3e,0x0d, - 0x0a,0x3c,0x67,0x20,0x6f,0x70,0x61,0x63,0x69,0x74, - 0x79,0x3d,0x22,0x30,0x2e,0x35,0x22,0x3e,0x0d,0x0a, - 0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69,0x6c, - 0x6c,0x3d,0x22,0x23,0x37,0x37,0x37,0x37,0x37,0x37, - 0x22,0x20,0x64,0x3d,0x22,0x4d,0x39,0x2e,0x33,0x35, - 0x34,0x2c,0x39,0x2e,0x30,0x38,0x37,0x63,0x30,0x2c, - 0x30,0x2e,0x33,0x39,0x2d,0x30,0x2e,0x33,0x31,0x39, - 0x2c,0x30,0x2e,0x37,0x30,0x38,0x2d,0x30,0x2e,0x37, - 0x30,0x38,0x2c,0x30,0x2e,0x37,0x30,0x38,0x48,0x30, - 0x2e,0x37,0x30,0x38,0x43,0x30,0x2e,0x33,0x31,0x39, - 0x2c,0x39,0x2e,0x37,0x39,0x36,0x2c,0x30,0x2c,0x39, - 0x2e,0x34,0x37,0x37,0x2c,0x30,0x2c,0x39,0x2e,0x30, - 0x38,0x37,0x56,0x30,0x2e,0x37,0x30,0x38,0x0d,0x0a, - 0x09,0x09,0x43,0x30,0x2c,0x30,0x2e,0x33,0x31,0x39, - 0x2c,0x30,0x2e,0x33,0x31,0x39,0x2c,0x30,0x2c,0x30, - 0x2e,0x37,0x30,0x38,0x2c,0x30,0x68,0x37,0x2e,0x39, - 0x33,0x38,0x63,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2c, - 0x30,0x2e,0x37,0x30,0x38,0x2c,0x30,0x2e,0x33,0x31, - 0x39,0x2c,0x30,0x2e,0x37,0x30,0x38,0x2c,0x30,0x2e, - 0x37,0x30,0x38,0x56,0x39,0x2e,0x30,0x38,0x37,0x7a, - 0x22,0x2f,0x3e,0x0d,0x0a,0x3c,0x2f,0x67,0x3e,0x0d, - 0x0a,0x3c,0x2f,0x73,0x76,0x67,0x3e,0x0d,0x0a + 0x30,0x38,0x56,0x30,0x2e,0x37,0x30,0x38,0x0a,0x09, + 0x09,0x63,0x30,0x2d,0x30,0x2e,0x33,0x39,0x2c,0x30, + 0x2e,0x33,0x31,0x39,0x2d,0x30,0x2e,0x37,0x30,0x38, + 0x2c,0x30,0x2e,0x37,0x30,0x39,0x2d,0x30,0x2e,0x37, + 0x30,0x38,0x68,0x37,0x2e,0x39,0x33,0x37,0x63,0x30, + 0x2e,0x33,0x39,0x2c,0x30,0x2c,0x30,0x2e,0x37,0x30, + 0x39,0x2c,0x30,0x2e,0x33,0x31,0x39,0x2c,0x30,0x2e, + 0x37,0x30,0x39,0x2c,0x30,0x2e,0x37,0x30,0x38,0x56, + 0x39,0x2e,0x30,0x38,0x38,0x7a,0x22,0x2f,0x3e,0x0a, + 0x3c,0x2f,0x67,0x3e,0x0a,0x3c,0x67,0x20,0x6f,0x70, + 0x61,0x63,0x69,0x74,0x79,0x3d,0x22,0x30,0x2e,0x35, + 0x22,0x3e,0x0a,0x09,0x3c,0x70,0x61,0x74,0x68,0x20, + 0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x37,0x37,0x37, + 0x37,0x37,0x37,0x22,0x20,0x64,0x3d,0x22,0x4d,0x39, + 0x2e,0x33,0x35,0x34,0x2c,0x32,0x31,0x2e,0x32,0x39, + 0x33,0x63,0x30,0x2c,0x30,0x2e,0x33,0x39,0x2d,0x30, + 0x2e,0x33,0x31,0x39,0x2c,0x30,0x2e,0x37,0x30,0x39, + 0x2d,0x30,0x2e,0x37,0x30,0x38,0x2c,0x30,0x2e,0x37, + 0x30,0x39,0x48,0x30,0x2e,0x37,0x30,0x38,0x43,0x30, + 0x2e,0x33,0x31,0x39,0x2c,0x32,0x32,0x2e,0x30,0x30, + 0x32,0x2c,0x30,0x2c,0x32,0x31,0x2e,0x36,0x38,0x33, + 0x2c,0x30,0x2c,0x32,0x31,0x2e,0x32,0x39,0x33,0x76, + 0x2d,0x38,0x2e,0x33,0x37,0x39,0x0a,0x09,0x09,0x63, + 0x30,0x2d,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2e,0x33, + 0x31,0x39,0x2d,0x30,0x2e,0x37,0x30,0x39,0x2c,0x30, + 0x2e,0x37,0x30,0x38,0x2d,0x30,0x2e,0x37,0x30,0x39, + 0x68,0x37,0x2e,0x39,0x33,0x38,0x63,0x30,0x2e,0x33, + 0x39,0x2c,0x30,0x2c,0x30,0x2e,0x37,0x30,0x38,0x2c, + 0x30,0x2e,0x33,0x31,0x39,0x2c,0x30,0x2e,0x37,0x30, + 0x38,0x2c,0x30,0x2e,0x37,0x30,0x39,0x56,0x32,0x31, + 0x2e,0x32,0x39,0x33,0x7a,0x22,0x2f,0x3e,0x0a,0x3c, + 0x2f,0x67,0x3e,0x0a,0x3c,0x67,0x20,0x6f,0x70,0x61, + 0x63,0x69,0x74,0x79,0x3d,0x22,0x30,0x2e,0x35,0x22, + 0x3e,0x0a,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66, + 0x69,0x6c,0x6c,0x3d,0x22,0x23,0x37,0x37,0x37,0x37, + 0x37,0x37,0x22,0x20,0x64,0x3d,0x22,0x4d,0x39,0x2e, + 0x33,0x35,0x34,0x2c,0x39,0x2e,0x30,0x38,0x37,0x63, + 0x30,0x2c,0x30,0x2e,0x33,0x39,0x2d,0x30,0x2e,0x33, + 0x31,0x39,0x2c,0x30,0x2e,0x37,0x30,0x38,0x2d,0x30, + 0x2e,0x37,0x30,0x38,0x2c,0x30,0x2e,0x37,0x30,0x38, + 0x48,0x30,0x2e,0x37,0x30,0x38,0x43,0x30,0x2e,0x33, + 0x31,0x39,0x2c,0x39,0x2e,0x37,0x39,0x36,0x2c,0x30, + 0x2c,0x39,0x2e,0x34,0x37,0x37,0x2c,0x30,0x2c,0x39, + 0x2e,0x30,0x38,0x37,0x56,0x30,0x2e,0x37,0x30,0x38, + 0x0a,0x09,0x09,0x43,0x30,0x2c,0x30,0x2e,0x33,0x31, + 0x39,0x2c,0x30,0x2e,0x33,0x31,0x39,0x2c,0x30,0x2c, + 0x30,0x2e,0x37,0x30,0x38,0x2c,0x30,0x68,0x37,0x2e, + 0x39,0x33,0x38,0x63,0x30,0x2e,0x33,0x39,0x2c,0x30, + 0x2c,0x30,0x2e,0x37,0x30,0x38,0x2c,0x30,0x2e,0x33, + 0x31,0x39,0x2c,0x30,0x2e,0x37,0x30,0x38,0x2c,0x30, + 0x2e,0x37,0x30,0x38,0x56,0x39,0x2e,0x30,0x38,0x37, + 0x7a,0x22,0x2f,0x3e,0x0a,0x3c,0x2f,0x67,0x3e,0x0a, + 0x3c,0x2f,0x73,0x76,0x67,0x3e,0x0a }; + diff --git a/data/converted/busy_3_svg.cpp b/data/converted/busy_3_svg.cpp index 8172c7c5f9..49a16d2680 100644 --- a/data/converted/busy_3_svg.cpp +++ b/data/converted/busy_3_svg.cpp @@ -2,82 +2,81 @@ #include "../Resources.h" -const size_t busy_3_svg_size = 1369; -const unsigned char busy_3_svg_data[1369] = { +const size_t busy_3_svg_size = 1347; +const unsigned char busy_3_svg_data[1347] = { 0x3c,0x3f,0x78,0x6d,0x6c,0x20,0x76,0x65,0x72,0x73, 0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x30,0x22,0x20, 0x65,0x6e,0x63,0x6f,0x64,0x69,0x6e,0x67,0x3d,0x22, - 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0d,0x0a, - 0x3c,0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72, - 0x61,0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62, - 0x65,0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61, - 0x74,0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33, - 0x2c,0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f, - 0x72,0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e, - 0x20,0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72, - 0x73,0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30, - 0x20,0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20, - 0x20,0x2d,0x2d,0x3e,0x0d,0x0a,0x3c,0x21,0x44,0x4f, - 0x43,0x54,0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20, - 0x50,0x55,0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f, - 0x2f,0x57,0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20, - 0x53,0x56,0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45, - 0x4e,0x22,0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, - 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, - 0x67,0x2f,0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73, - 0x2f,0x53,0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44, - 0x54,0x44,0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64, - 0x74,0x64,0x22,0x3e,0x0d,0x0a,0x3c,0x73,0x76,0x67, - 0x20,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22, - 0x31,0x2e,0x31,0x22,0x20,0x69,0x64,0x3d,0x22,0x45, - 0x62,0x65,0x6e,0x65,0x5f,0x31,0x22,0x20,0x78,0x6d, - 0x6c,0x6e,0x73,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a, - 0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f, - 0x72,0x67,0x2f,0x32,0x30,0x30,0x30,0x2f,0x73,0x76, - 0x67,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78, - 0x6c,0x69,0x6e,0x6b,0x3d,0x22,0x68,0x74,0x74,0x70, - 0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e, - 0x6f,0x72,0x67,0x2f,0x31,0x39,0x39,0x39,0x2f,0x78, - 0x6c,0x69,0x6e,0x6b,0x22,0x20,0x78,0x3d,0x22,0x30, - 0x70,0x78,0x22,0x20,0x79,0x3d,0x22,0x30,0x70,0x78, - 0x22,0x0d,0x0a,0x09,0x20,0x77,0x69,0x64,0x74,0x68, - 0x3d,0x22,0x32,0x31,0x2e,0x30,0x30,0x32,0x70,0x78, - 0x22,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3d,0x22, - 0x32,0x32,0x2e,0x30,0x30,0x32,0x70,0x78,0x22,0x20, - 0x76,0x69,0x65,0x77,0x42,0x6f,0x78,0x3d,0x22,0x30, - 0x20,0x30,0x20,0x32,0x31,0x2e,0x30,0x30,0x32,0x20, - 0x32,0x32,0x2e,0x30,0x30,0x32,0x22,0x20,0x65,0x6e, - 0x61,0x62,0x6c,0x65,0x2d,0x62,0x61,0x63,0x6b,0x67, - 0x72,0x6f,0x75,0x6e,0x64,0x3d,0x22,0x6e,0x65,0x77, - 0x20,0x30,0x20,0x30,0x20,0x32,0x31,0x2e,0x30,0x30, - 0x32,0x20,0x32,0x32,0x2e,0x30,0x30,0x32,0x22,0x20, - 0x78,0x6d,0x6c,0x3a,0x73,0x70,0x61,0x63,0x65,0x3d, - 0x22,0x70,0x72,0x65,0x73,0x65,0x72,0x76,0x65,0x22, - 0x3e,0x0d,0x0a,0x3c,0x67,0x20,0x6f,0x70,0x61,0x63, - 0x69,0x74,0x79,0x3d,0x22,0x30,0x2e,0x35,0x22,0x3e, - 0x0d,0x0a,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66, - 0x69,0x6c,0x6c,0x3d,0x22,0x23,0x37,0x37,0x37,0x37, - 0x37,0x37,0x22,0x20,0x64,0x3d,0x22,0x4d,0x32,0x31, - 0x2e,0x30,0x30,0x32,0x2c,0x32,0x31,0x2e,0x32,0x39, - 0x33,0x63,0x30,0x2c,0x30,0x2e,0x33,0x39,0x2d,0x30, - 0x2e,0x33,0x31,0x39,0x2c,0x30,0x2e,0x37,0x30,0x39, - 0x2d,0x30,0x2e,0x37,0x30,0x39,0x2c,0x30,0x2e,0x37, - 0x30,0x39,0x68,0x2d,0x37,0x2e,0x39,0x33,0x37,0x63, - 0x2d,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2d,0x30,0x2e, - 0x37,0x30,0x39,0x2d,0x30,0x2e,0x33,0x31,0x39,0x2d, - 0x30,0x2e,0x37,0x30,0x39,0x2d,0x30,0x2e,0x37,0x30, - 0x39,0x76,0x2d,0x38,0x2e,0x33,0x37,0x39,0x0d,0x0a, - 0x09,0x09,0x63,0x30,0x2d,0x30,0x2e,0x33,0x39,0x2c, - 0x30,0x2e,0x33,0x31,0x39,0x2d,0x30,0x2e,0x37,0x30, - 0x39,0x2c,0x30,0x2e,0x37,0x30,0x39,0x2d,0x30,0x2e, - 0x37,0x30,0x39,0x68,0x37,0x2e,0x39,0x33,0x37,0x63, - 0x30,0x2e,0x33,0x39,0x2c,0x30,0x2c,0x30,0x2e,0x37, - 0x30,0x39,0x2c,0x30,0x2e,0x33,0x31,0x39,0x2c,0x30, + 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0a,0x3c, + 0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72,0x61, + 0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62,0x65, + 0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61,0x74, + 0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33,0x2c, + 0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f,0x72, + 0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e,0x20, + 0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72,0x73, + 0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30,0x20, + 0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20,0x20, + 0x2d,0x2d,0x3e,0x0a,0x3c,0x21,0x44,0x4f,0x43,0x54, + 0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20,0x50,0x55, + 0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f,0x2f,0x57, + 0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20,0x53,0x56, + 0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45,0x4e,0x22, + 0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73,0x2f,0x53, + 0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44,0x54,0x44, + 0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64,0x74,0x64, + 0x22,0x3e,0x0a,0x3c,0x73,0x76,0x67,0x20,0x76,0x65, + 0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x31, + 0x22,0x20,0x69,0x64,0x3d,0x22,0x45,0x62,0x65,0x6e, + 0x65,0x5f,0x31,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73, + 0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x32,0x30,0x30,0x30,0x2f,0x73,0x76,0x67,0x22,0x20, + 0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78,0x6c,0x69,0x6e, + 0x6b,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f, + 0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67, + 0x2f,0x31,0x39,0x39,0x39,0x2f,0x78,0x6c,0x69,0x6e, + 0x6b,0x22,0x20,0x78,0x3d,0x22,0x30,0x70,0x78,0x22, + 0x20,0x79,0x3d,0x22,0x30,0x70,0x78,0x22,0x0a,0x09, + 0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x32,0x31, + 0x2e,0x30,0x30,0x32,0x70,0x78,0x22,0x20,0x68,0x65, + 0x69,0x67,0x68,0x74,0x3d,0x22,0x32,0x32,0x2e,0x30, + 0x30,0x32,0x70,0x78,0x22,0x20,0x76,0x69,0x65,0x77, + 0x42,0x6f,0x78,0x3d,0x22,0x30,0x20,0x30,0x20,0x32, + 0x31,0x2e,0x30,0x30,0x32,0x20,0x32,0x32,0x2e,0x30, + 0x30,0x32,0x22,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65, + 0x2d,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e, + 0x64,0x3d,0x22,0x6e,0x65,0x77,0x20,0x30,0x20,0x30, + 0x20,0x32,0x31,0x2e,0x30,0x30,0x32,0x20,0x32,0x32, + 0x2e,0x30,0x30,0x32,0x22,0x20,0x78,0x6d,0x6c,0x3a, + 0x73,0x70,0x61,0x63,0x65,0x3d,0x22,0x70,0x72,0x65, + 0x73,0x65,0x72,0x76,0x65,0x22,0x3e,0x0a,0x3c,0x67, + 0x20,0x6f,0x70,0x61,0x63,0x69,0x74,0x79,0x3d,0x22, + 0x30,0x2e,0x35,0x22,0x3e,0x0a,0x09,0x3c,0x70,0x61, + 0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23, + 0x37,0x37,0x37,0x37,0x37,0x37,0x22,0x20,0x64,0x3d, + 0x22,0x4d,0x32,0x31,0x2e,0x30,0x30,0x32,0x2c,0x32, + 0x31,0x2e,0x32,0x39,0x33,0x63,0x30,0x2c,0x30,0x2e, + 0x33,0x39,0x2d,0x30,0x2e,0x33,0x31,0x39,0x2c,0x30, + 0x2e,0x37,0x30,0x39,0x2d,0x30,0x2e,0x37,0x30,0x39, + 0x2c,0x30,0x2e,0x37,0x30,0x39,0x68,0x2d,0x37,0x2e, + 0x39,0x33,0x37,0x63,0x2d,0x30,0x2e,0x33,0x39,0x2c, + 0x30,0x2d,0x30,0x2e,0x37,0x30,0x39,0x2d,0x30,0x2e, + 0x33,0x31,0x39,0x2d,0x30,0x2e,0x37,0x30,0x39,0x2d, + 0x30,0x2e,0x37,0x30,0x39,0x76,0x2d,0x38,0x2e,0x33, + 0x37,0x39,0x0a,0x09,0x09,0x63,0x30,0x2d,0x30,0x2e, + 0x33,0x39,0x2c,0x30,0x2e,0x33,0x31,0x39,0x2d,0x30, 0x2e,0x37,0x30,0x39,0x2c,0x30,0x2e,0x37,0x30,0x39, - 0x56,0x32,0x31,0x2e,0x32,0x39,0x33,0x7a,0x22,0x2f, - 0x3e,0x0d,0x0a,0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x3c, - 0x67,0x20,0x6f,0x70,0x61,0x63,0x69,0x74,0x79,0x3d, - 0x22,0x30,0x2e,0x35,0x22,0x3e,0x0d,0x0a,0x09,0x3c, + 0x2d,0x30,0x2e,0x37,0x30,0x39,0x68,0x37,0x2e,0x39, + 0x33,0x37,0x63,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2c, + 0x30,0x2e,0x37,0x30,0x39,0x2c,0x30,0x2e,0x33,0x31, + 0x39,0x2c,0x30,0x2e,0x37,0x30,0x39,0x2c,0x30,0x2e, + 0x37,0x30,0x39,0x56,0x32,0x31,0x2e,0x32,0x39,0x33, + 0x7a,0x22,0x2f,0x3e,0x0a,0x3c,0x2f,0x67,0x3e,0x0a, + 0x3c,0x67,0x20,0x6f,0x70,0x61,0x63,0x69,0x74,0x79, + 0x3d,0x22,0x30,0x2e,0x35,0x22,0x3e,0x0a,0x09,0x3c, 0x70,0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d, 0x22,0x23,0x37,0x37,0x37,0x37,0x37,0x37,0x22,0x20, 0x64,0x3d,0x22,0x4d,0x32,0x31,0x2e,0x30,0x30,0x32, @@ -89,56 +88,56 @@ const unsigned char busy_3_svg_data[1369] = { 0x2c,0x30,0x2d,0x30,0x2e,0x37,0x30,0x39,0x2d,0x30, 0x2e,0x33,0x31,0x39,0x2d,0x30,0x2e,0x37,0x30,0x39, 0x2d,0x30,0x2e,0x37,0x30,0x38,0x56,0x30,0x2e,0x37, - 0x30,0x38,0x0d,0x0a,0x09,0x09,0x63,0x30,0x2d,0x30, - 0x2e,0x33,0x39,0x2c,0x30,0x2e,0x33,0x31,0x39,0x2d, - 0x30,0x2e,0x37,0x30,0x38,0x2c,0x30,0x2e,0x37,0x30, - 0x39,0x2d,0x30,0x2e,0x37,0x30,0x38,0x68,0x37,0x2e, - 0x39,0x33,0x37,0x63,0x30,0x2e,0x33,0x39,0x2c,0x30, - 0x2c,0x30,0x2e,0x37,0x30,0x39,0x2c,0x30,0x2e,0x33, - 0x31,0x39,0x2c,0x30,0x2e,0x37,0x30,0x39,0x2c,0x30, - 0x2e,0x37,0x30,0x38,0x56,0x39,0x2e,0x30,0x38,0x38, - 0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x3c,0x2f,0x67,0x3e, - 0x0d,0x0a,0x3c,0x67,0x3e,0x0d,0x0a,0x09,0x3c,0x70, - 0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22, - 0x23,0x37,0x37,0x37,0x37,0x37,0x37,0x22,0x20,0x64, - 0x3d,0x22,0x4d,0x39,0x2e,0x33,0x35,0x34,0x2c,0x32, - 0x31,0x2e,0x32,0x39,0x33,0x63,0x30,0x2c,0x30,0x2e, - 0x33,0x39,0x2d,0x30,0x2e,0x33,0x31,0x39,0x2c,0x30, - 0x2e,0x37,0x30,0x39,0x2d,0x30,0x2e,0x37,0x30,0x38, - 0x2c,0x30,0x2e,0x37,0x30,0x39,0x48,0x30,0x2e,0x37, - 0x30,0x38,0x43,0x30,0x2e,0x33,0x31,0x39,0x2c,0x32, - 0x32,0x2e,0x30,0x30,0x32,0x2c,0x30,0x2c,0x32,0x31, - 0x2e,0x36,0x38,0x33,0x2c,0x30,0x2c,0x32,0x31,0x2e, - 0x32,0x39,0x33,0x76,0x2d,0x38,0x2e,0x33,0x37,0x39, - 0x0d,0x0a,0x09,0x09,0x63,0x30,0x2d,0x30,0x2e,0x33, - 0x39,0x2c,0x30,0x2e,0x33,0x31,0x39,0x2d,0x30,0x2e, - 0x37,0x30,0x39,0x2c,0x30,0x2e,0x37,0x30,0x38,0x2d, - 0x30,0x2e,0x37,0x30,0x39,0x68,0x37,0x2e,0x39,0x33, - 0x38,0x63,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2c,0x30, - 0x2e,0x37,0x30,0x38,0x2c,0x30,0x2e,0x33,0x31,0x39, - 0x2c,0x30,0x2e,0x37,0x30,0x38,0x2c,0x30,0x2e,0x37, - 0x30,0x39,0x56,0x32,0x31,0x2e,0x32,0x39,0x33,0x7a, - 0x22,0x2f,0x3e,0x0d,0x0a,0x3c,0x2f,0x67,0x3e,0x0d, - 0x0a,0x3c,0x67,0x20,0x6f,0x70,0x61,0x63,0x69,0x74, - 0x79,0x3d,0x22,0x30,0x2e,0x35,0x22,0x3e,0x0d,0x0a, - 0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69,0x6c, - 0x6c,0x3d,0x22,0x23,0x37,0x37,0x37,0x37,0x37,0x37, - 0x22,0x20,0x64,0x3d,0x22,0x4d,0x39,0x2e,0x33,0x35, - 0x34,0x2c,0x39,0x2e,0x30,0x38,0x37,0x63,0x30,0x2c, - 0x30,0x2e,0x33,0x39,0x2d,0x30,0x2e,0x33,0x31,0x39, - 0x2c,0x30,0x2e,0x37,0x30,0x38,0x2d,0x30,0x2e,0x37, - 0x30,0x38,0x2c,0x30,0x2e,0x37,0x30,0x38,0x48,0x30, - 0x2e,0x37,0x30,0x38,0x43,0x30,0x2e,0x33,0x31,0x39, - 0x2c,0x39,0x2e,0x37,0x39,0x36,0x2c,0x30,0x2c,0x39, - 0x2e,0x34,0x37,0x37,0x2c,0x30,0x2c,0x39,0x2e,0x30, - 0x38,0x37,0x56,0x30,0x2e,0x37,0x30,0x38,0x0d,0x0a, - 0x09,0x09,0x43,0x30,0x2c,0x30,0x2e,0x33,0x31,0x39, - 0x2c,0x30,0x2e,0x33,0x31,0x39,0x2c,0x30,0x2c,0x30, - 0x2e,0x37,0x30,0x38,0x2c,0x30,0x68,0x37,0x2e,0x39, - 0x33,0x38,0x63,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2c, - 0x30,0x2e,0x37,0x30,0x38,0x2c,0x30,0x2e,0x33,0x31, - 0x39,0x2c,0x30,0x2e,0x37,0x30,0x38,0x2c,0x30,0x2e, - 0x37,0x30,0x38,0x56,0x39,0x2e,0x30,0x38,0x37,0x7a, - 0x22,0x2f,0x3e,0x0d,0x0a,0x3c,0x2f,0x67,0x3e,0x0d, - 0x0a,0x3c,0x2f,0x73,0x76,0x67,0x3e,0x0d,0x0a + 0x30,0x38,0x0a,0x09,0x09,0x63,0x30,0x2d,0x30,0x2e, + 0x33,0x39,0x2c,0x30,0x2e,0x33,0x31,0x39,0x2d,0x30, + 0x2e,0x37,0x30,0x38,0x2c,0x30,0x2e,0x37,0x30,0x39, + 0x2d,0x30,0x2e,0x37,0x30,0x38,0x68,0x37,0x2e,0x39, + 0x33,0x37,0x63,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2c, + 0x30,0x2e,0x37,0x30,0x39,0x2c,0x30,0x2e,0x33,0x31, + 0x39,0x2c,0x30,0x2e,0x37,0x30,0x39,0x2c,0x30,0x2e, + 0x37,0x30,0x38,0x56,0x39,0x2e,0x30,0x38,0x38,0x7a, + 0x22,0x2f,0x3e,0x0a,0x3c,0x2f,0x67,0x3e,0x0a,0x3c, + 0x67,0x3e,0x0a,0x09,0x3c,0x70,0x61,0x74,0x68,0x20, + 0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x37,0x37,0x37, + 0x37,0x37,0x37,0x22,0x20,0x64,0x3d,0x22,0x4d,0x39, + 0x2e,0x33,0x35,0x34,0x2c,0x32,0x31,0x2e,0x32,0x39, + 0x33,0x63,0x30,0x2c,0x30,0x2e,0x33,0x39,0x2d,0x30, + 0x2e,0x33,0x31,0x39,0x2c,0x30,0x2e,0x37,0x30,0x39, + 0x2d,0x30,0x2e,0x37,0x30,0x38,0x2c,0x30,0x2e,0x37, + 0x30,0x39,0x48,0x30,0x2e,0x37,0x30,0x38,0x43,0x30, + 0x2e,0x33,0x31,0x39,0x2c,0x32,0x32,0x2e,0x30,0x30, + 0x32,0x2c,0x30,0x2c,0x32,0x31,0x2e,0x36,0x38,0x33, + 0x2c,0x30,0x2c,0x32,0x31,0x2e,0x32,0x39,0x33,0x76, + 0x2d,0x38,0x2e,0x33,0x37,0x39,0x0a,0x09,0x09,0x63, + 0x30,0x2d,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2e,0x33, + 0x31,0x39,0x2d,0x30,0x2e,0x37,0x30,0x39,0x2c,0x30, + 0x2e,0x37,0x30,0x38,0x2d,0x30,0x2e,0x37,0x30,0x39, + 0x68,0x37,0x2e,0x39,0x33,0x38,0x63,0x30,0x2e,0x33, + 0x39,0x2c,0x30,0x2c,0x30,0x2e,0x37,0x30,0x38,0x2c, + 0x30,0x2e,0x33,0x31,0x39,0x2c,0x30,0x2e,0x37,0x30, + 0x38,0x2c,0x30,0x2e,0x37,0x30,0x39,0x56,0x32,0x31, + 0x2e,0x32,0x39,0x33,0x7a,0x22,0x2f,0x3e,0x0a,0x3c, + 0x2f,0x67,0x3e,0x0a,0x3c,0x67,0x20,0x6f,0x70,0x61, + 0x63,0x69,0x74,0x79,0x3d,0x22,0x30,0x2e,0x35,0x22, + 0x3e,0x0a,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66, + 0x69,0x6c,0x6c,0x3d,0x22,0x23,0x37,0x37,0x37,0x37, + 0x37,0x37,0x22,0x20,0x64,0x3d,0x22,0x4d,0x39,0x2e, + 0x33,0x35,0x34,0x2c,0x39,0x2e,0x30,0x38,0x37,0x63, + 0x30,0x2c,0x30,0x2e,0x33,0x39,0x2d,0x30,0x2e,0x33, + 0x31,0x39,0x2c,0x30,0x2e,0x37,0x30,0x38,0x2d,0x30, + 0x2e,0x37,0x30,0x38,0x2c,0x30,0x2e,0x37,0x30,0x38, + 0x48,0x30,0x2e,0x37,0x30,0x38,0x43,0x30,0x2e,0x33, + 0x31,0x39,0x2c,0x39,0x2e,0x37,0x39,0x36,0x2c,0x30, + 0x2c,0x39,0x2e,0x34,0x37,0x37,0x2c,0x30,0x2c,0x39, + 0x2e,0x30,0x38,0x37,0x56,0x30,0x2e,0x37,0x30,0x38, + 0x0a,0x09,0x09,0x43,0x30,0x2c,0x30,0x2e,0x33,0x31, + 0x39,0x2c,0x30,0x2e,0x33,0x31,0x39,0x2c,0x30,0x2c, + 0x30,0x2e,0x37,0x30,0x38,0x2c,0x30,0x68,0x37,0x2e, + 0x39,0x33,0x38,0x63,0x30,0x2e,0x33,0x39,0x2c,0x30, + 0x2c,0x30,0x2e,0x37,0x30,0x38,0x2c,0x30,0x2e,0x33, + 0x31,0x39,0x2c,0x30,0x2e,0x37,0x30,0x38,0x2c,0x30, + 0x2e,0x37,0x30,0x38,0x56,0x39,0x2e,0x30,0x38,0x37, + 0x7a,0x22,0x2f,0x3e,0x0a,0x3c,0x2f,0x67,0x3e,0x0a, + 0x3c,0x2f,0x73,0x76,0x67,0x3e,0x0a }; + diff --git a/data/converted/button_filled_png.cpp b/data/converted/button_filled_png.cpp index 755754b1b4..e85f96e5cf 100644 --- a/data/converted/button_filled_png.cpp +++ b/data/converted/button_filled_png.cpp @@ -122,3 +122,4 @@ const unsigned char button_filled_png_data[1168] = { 0x1a,0x41,0x6b,0xc2,0x11,0x6c,0x00,0x00,0x00,0x00, 0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82 }; + diff --git a/data/converted/button_png.cpp b/data/converted/button_png.cpp index de4959dd28..72603af201 100644 --- a/data/converted/button_png.cpp +++ b/data/converted/button_png.cpp @@ -129,3 +129,4 @@ const unsigned char button_png_data[1231] = { 0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60, 0x82 }; + diff --git a/data/converted/checkbox_checked_svg.cpp b/data/converted/checkbox_checked_svg.cpp index 06848c9556..5a3acb2fb8 100644 --- a/data/converted/checkbox_checked_svg.cpp +++ b/data/converted/checkbox_checked_svg.cpp @@ -2,140 +2,139 @@ #include "../Resources.h" -const size_t checkbox_checked_svg_size = 1337; -const unsigned char checkbox_checked_svg_data[1337] = { +const size_t checkbox_checked_svg_size = 1314; +const unsigned char checkbox_checked_svg_data[1314] = { 0x3c,0x3f,0x78,0x6d,0x6c,0x20,0x76,0x65,0x72,0x73, 0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x30,0x22,0x20, 0x65,0x6e,0x63,0x6f,0x64,0x69,0x6e,0x67,0x3d,0x22, - 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0d,0x0a, - 0x3c,0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72, - 0x61,0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62, - 0x65,0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61, - 0x74,0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33, - 0x2c,0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f, - 0x72,0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e, - 0x20,0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72, - 0x73,0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30, - 0x20,0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20, - 0x20,0x2d,0x2d,0x3e,0x0d,0x0a,0x3c,0x21,0x44,0x4f, - 0x43,0x54,0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20, - 0x50,0x55,0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f, - 0x2f,0x57,0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20, - 0x53,0x56,0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45, - 0x4e,0x22,0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, - 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, - 0x67,0x2f,0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73, - 0x2f,0x53,0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44, - 0x54,0x44,0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64, - 0x74,0x64,0x22,0x3e,0x0d,0x0a,0x3c,0x73,0x76,0x67, - 0x20,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22, - 0x31,0x2e,0x31,0x22,0x20,0x69,0x64,0x3d,0x22,0x45, - 0x62,0x65,0x6e,0x65,0x5f,0x31,0x22,0x20,0x78,0x6d, - 0x6c,0x6e,0x73,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a, - 0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f, - 0x72,0x67,0x2f,0x32,0x30,0x30,0x30,0x2f,0x73,0x76, - 0x67,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78, - 0x6c,0x69,0x6e,0x6b,0x3d,0x22,0x68,0x74,0x74,0x70, - 0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e, - 0x6f,0x72,0x67,0x2f,0x31,0x39,0x39,0x39,0x2f,0x78, - 0x6c,0x69,0x6e,0x6b,0x22,0x20,0x78,0x3d,0x22,0x30, - 0x70,0x78,0x22,0x20,0x79,0x3d,0x22,0x30,0x70,0x78, - 0x22,0x0d,0x0a,0x09,0x20,0x77,0x69,0x64,0x74,0x68, - 0x3d,0x22,0x32,0x31,0x2e,0x39,0x36,0x32,0x70,0x78, - 0x22,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3d,0x22, - 0x32,0x31,0x2e,0x39,0x35,0x39,0x70,0x78,0x22,0x20, - 0x76,0x69,0x65,0x77,0x42,0x6f,0x78,0x3d,0x22,0x30, - 0x20,0x30,0x20,0x32,0x31,0x2e,0x39,0x36,0x32,0x20, - 0x32,0x31,0x2e,0x39,0x35,0x39,0x22,0x20,0x65,0x6e, - 0x61,0x62,0x6c,0x65,0x2d,0x62,0x61,0x63,0x6b,0x67, - 0x72,0x6f,0x75,0x6e,0x64,0x3d,0x22,0x6e,0x65,0x77, - 0x20,0x30,0x20,0x30,0x20,0x32,0x31,0x2e,0x39,0x36, - 0x32,0x20,0x32,0x31,0x2e,0x39,0x35,0x39,0x22,0x20, - 0x78,0x6d,0x6c,0x3a,0x73,0x70,0x61,0x63,0x65,0x3d, - 0x22,0x70,0x72,0x65,0x73,0x65,0x72,0x76,0x65,0x22, - 0x3e,0x0d,0x0a,0x3c,0x70,0x61,0x74,0x68,0x20,0x66, - 0x69,0x6c,0x6c,0x3d,0x22,0x23,0x37,0x37,0x37,0x37, - 0x37,0x37,0x22,0x20,0x64,0x3d,0x22,0x4d,0x31,0x37, - 0x2e,0x37,0x31,0x2c,0x31,0x2e,0x35,0x63,0x31,0x2e, - 0x35,0x31,0x38,0x2c,0x30,0x2c,0x32,0x2e,0x37,0x35, - 0x32,0x2c,0x31,0x2e,0x32,0x33,0x34,0x2c,0x32,0x2e, - 0x37,0x35,0x32,0x2c,0x32,0x2e,0x37,0x35,0x32,0x76, - 0x31,0x33,0x2e,0x34,0x35,0x35,0x63,0x30,0x2c,0x31, - 0x2e,0x35,0x31,0x38,0x2d,0x31,0x2e,0x32,0x33,0x34, - 0x2c,0x32,0x2e,0x37,0x35,0x32,0x2d,0x32,0x2e,0x37, - 0x35,0x32,0x2c,0x32,0x2e,0x37,0x35,0x32,0x48,0x34, - 0x2e,0x32,0x35,0x32,0x0d,0x0a,0x09,0x63,0x2d,0x31, - 0x2e,0x35,0x31,0x38,0x2c,0x30,0x2d,0x32,0x2e,0x37, - 0x35,0x32,0x2d,0x31,0x2e,0x32,0x33,0x34,0x2d,0x32, - 0x2e,0x37,0x35,0x32,0x2d,0x32,0x2e,0x37,0x35,0x32, - 0x56,0x34,0x2e,0x32,0x35,0x32,0x43,0x31,0x2e,0x35, - 0x2c,0x32,0x2e,0x37,0x33,0x34,0x2c,0x32,0x2e,0x37, - 0x33,0x34,0x2c,0x31,0x2e,0x35,0x2c,0x34,0x2e,0x32, - 0x35,0x32,0x2c,0x31,0x2e,0x35,0x48,0x31,0x37,0x2e, - 0x37,0x31,0x20,0x4d,0x31,0x37,0x2e,0x37,0x31,0x2c, - 0x30,0x48,0x34,0x2e,0x32,0x35,0x32,0x43,0x31,0x2e, - 0x39,0x31,0x34,0x2c,0x30,0x2c,0x30,0x2c,0x31,0x2e, - 0x39,0x31,0x34,0x2c,0x30,0x2c,0x34,0x2e,0x32,0x35, - 0x32,0x76,0x31,0x33,0x2e,0x34,0x35,0x35,0x0d,0x0a, - 0x09,0x63,0x30,0x2c,0x32,0x2e,0x33,0x33,0x39,0x2c, - 0x31,0x2e,0x39,0x31,0x34,0x2c,0x34,0x2e,0x32,0x35, - 0x32,0x2c,0x34,0x2e,0x32,0x35,0x32,0x2c,0x34,0x2e, - 0x32,0x35,0x32,0x48,0x31,0x37,0x2e,0x37,0x31,0x63, - 0x32,0x2e,0x33,0x33,0x39,0x2c,0x30,0x2c,0x34,0x2e, - 0x32,0x35,0x32,0x2d,0x31,0x2e,0x39,0x31,0x33,0x2c, - 0x34,0x2e,0x32,0x35,0x32,0x2d,0x34,0x2e,0x32,0x35, - 0x32,0x56,0x34,0x2e,0x32,0x35,0x32,0x43,0x32,0x31, - 0x2e,0x39,0x36,0x32,0x2c,0x31,0x2e,0x39,0x31,0x34, - 0x2c,0x32,0x30,0x2e,0x30,0x34,0x39,0x2c,0x30,0x2c, - 0x31,0x37,0x2e,0x37,0x31,0x2c,0x30,0x4c,0x31,0x37, - 0x2e,0x37,0x31,0x2c,0x30,0x7a,0x22,0x2f,0x3e,0x0d, - 0x0a,0x3c,0x67,0x3e,0x0d,0x0a,0x09,0x3c,0x67,0x3e, - 0x0d,0x0a,0x09,0x09,0x0d,0x0a,0x09,0x09,0x09,0x3c, - 0x72,0x65,0x63,0x74,0x20,0x78,0x3d,0x22,0x31,0x30, - 0x2e,0x32,0x33,0x32,0x22,0x20,0x79,0x3d,0x22,0x31, - 0x2e,0x30,0x37,0x39,0x22,0x20,0x74,0x72,0x61,0x6e, - 0x73,0x66,0x6f,0x72,0x6d,0x3d,0x22,0x6d,0x61,0x74, - 0x72,0x69,0x78,0x28,0x30,0x2e,0x37,0x30,0x37,0x31, - 0x20,0x30,0x2e,0x37,0x30,0x37,0x31,0x20,0x2d,0x30, - 0x2e,0x37,0x30,0x37,0x31,0x20,0x30,0x2e,0x37,0x30, - 0x37,0x31,0x20,0x31,0x30,0x2e,0x39,0x38,0x30,0x31, - 0x20,0x2d,0x34,0x2e,0x35,0x34,0x39,0x34,0x29,0x22, - 0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x37,0x37, - 0x37,0x37,0x37,0x37,0x22,0x20,0x77,0x69,0x64,0x74, - 0x68,0x3d,0x22,0x31,0x2e,0x35,0x22,0x20,0x68,0x65, - 0x69,0x67,0x68,0x74,0x3d,0x22,0x31,0x39,0x2e,0x38, - 0x22,0x2f,0x3e,0x0d,0x0a,0x09,0x3c,0x2f,0x67,0x3e, - 0x0d,0x0a,0x09,0x3c,0x67,0x3e,0x0d,0x0a,0x09,0x09, - 0x0d,0x0a,0x09,0x09,0x09,0x3c,0x72,0x65,0x63,0x74, - 0x20,0x78,0x3d,0x22,0x31,0x30,0x2e,0x32,0x33,0x32, - 0x22,0x20,0x79,0x3d,0x22,0x31,0x2e,0x30,0x37,0x39, - 0x22,0x20,0x74,0x72,0x61,0x6e,0x73,0x66,0x6f,0x72, - 0x6d,0x3d,0x22,0x6d,0x61,0x74,0x72,0x69,0x78,0x28, - 0x30,0x2e,0x37,0x30,0x37,0x31,0x20,0x30,0x2e,0x37, - 0x30,0x37,0x31,0x20,0x2d,0x30,0x2e,0x37,0x30,0x37, - 0x31,0x20,0x30,0x2e,0x37,0x30,0x37,0x31,0x20,0x31, - 0x30,0x2e,0x39,0x38,0x30,0x31,0x20,0x2d,0x34,0x2e, - 0x35,0x34,0x39,0x34,0x29,0x22,0x20,0x66,0x69,0x6c, - 0x6c,0x3d,0x22,0x23,0x37,0x37,0x37,0x37,0x37,0x37, - 0x22,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x31, - 0x2e,0x35,0x22,0x20,0x68,0x65,0x69,0x67,0x68,0x74, - 0x3d,0x22,0x31,0x39,0x2e,0x38,0x22,0x2f,0x3e,0x0d, - 0x0a,0x09,0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x09,0x3c, - 0x67,0x3e,0x0d,0x0a,0x09,0x09,0x0d,0x0a,0x09,0x09, - 0x09,0x3c,0x72,0x65,0x63,0x74,0x20,0x78,0x3d,0x22, - 0x31,0x2e,0x30,0x38,0x32,0x22,0x20,0x79,0x3d,0x22, - 0x31,0x30,0x2e,0x32,0x33,0x22,0x20,0x74,0x72,0x61, + 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0a,0x3c, + 0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72,0x61, + 0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62,0x65, + 0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61,0x74, + 0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33,0x2c, + 0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f,0x72, + 0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e,0x20, + 0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72,0x73, + 0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30,0x20, + 0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20,0x20, + 0x2d,0x2d,0x3e,0x0a,0x3c,0x21,0x44,0x4f,0x43,0x54, + 0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20,0x50,0x55, + 0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f,0x2f,0x57, + 0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20,0x53,0x56, + 0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45,0x4e,0x22, + 0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73,0x2f,0x53, + 0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44,0x54,0x44, + 0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64,0x74,0x64, + 0x22,0x3e,0x0a,0x3c,0x73,0x76,0x67,0x20,0x76,0x65, + 0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x31, + 0x22,0x20,0x69,0x64,0x3d,0x22,0x45,0x62,0x65,0x6e, + 0x65,0x5f,0x31,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73, + 0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x32,0x30,0x30,0x30,0x2f,0x73,0x76,0x67,0x22,0x20, + 0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78,0x6c,0x69,0x6e, + 0x6b,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f, + 0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67, + 0x2f,0x31,0x39,0x39,0x39,0x2f,0x78,0x6c,0x69,0x6e, + 0x6b,0x22,0x20,0x78,0x3d,0x22,0x30,0x70,0x78,0x22, + 0x20,0x79,0x3d,0x22,0x30,0x70,0x78,0x22,0x0a,0x09, + 0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x32,0x31, + 0x2e,0x39,0x36,0x32,0x70,0x78,0x22,0x20,0x68,0x65, + 0x69,0x67,0x68,0x74,0x3d,0x22,0x32,0x31,0x2e,0x39, + 0x35,0x39,0x70,0x78,0x22,0x20,0x76,0x69,0x65,0x77, + 0x42,0x6f,0x78,0x3d,0x22,0x30,0x20,0x30,0x20,0x32, + 0x31,0x2e,0x39,0x36,0x32,0x20,0x32,0x31,0x2e,0x39, + 0x35,0x39,0x22,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65, + 0x2d,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e, + 0x64,0x3d,0x22,0x6e,0x65,0x77,0x20,0x30,0x20,0x30, + 0x20,0x32,0x31,0x2e,0x39,0x36,0x32,0x20,0x32,0x31, + 0x2e,0x39,0x35,0x39,0x22,0x20,0x78,0x6d,0x6c,0x3a, + 0x73,0x70,0x61,0x63,0x65,0x3d,0x22,0x70,0x72,0x65, + 0x73,0x65,0x72,0x76,0x65,0x22,0x3e,0x0a,0x3c,0x70, + 0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22, + 0x23,0x37,0x37,0x37,0x37,0x37,0x37,0x22,0x20,0x64, + 0x3d,0x22,0x4d,0x31,0x37,0x2e,0x37,0x31,0x2c,0x31, + 0x2e,0x35,0x63,0x31,0x2e,0x35,0x31,0x38,0x2c,0x30, + 0x2c,0x32,0x2e,0x37,0x35,0x32,0x2c,0x31,0x2e,0x32, + 0x33,0x34,0x2c,0x32,0x2e,0x37,0x35,0x32,0x2c,0x32, + 0x2e,0x37,0x35,0x32,0x76,0x31,0x33,0x2e,0x34,0x35, + 0x35,0x63,0x30,0x2c,0x31,0x2e,0x35,0x31,0x38,0x2d, + 0x31,0x2e,0x32,0x33,0x34,0x2c,0x32,0x2e,0x37,0x35, + 0x32,0x2d,0x32,0x2e,0x37,0x35,0x32,0x2c,0x32,0x2e, + 0x37,0x35,0x32,0x48,0x34,0x2e,0x32,0x35,0x32,0x0a, + 0x09,0x63,0x2d,0x31,0x2e,0x35,0x31,0x38,0x2c,0x30, + 0x2d,0x32,0x2e,0x37,0x35,0x32,0x2d,0x31,0x2e,0x32, + 0x33,0x34,0x2d,0x32,0x2e,0x37,0x35,0x32,0x2d,0x32, + 0x2e,0x37,0x35,0x32,0x56,0x34,0x2e,0x32,0x35,0x32, + 0x43,0x31,0x2e,0x35,0x2c,0x32,0x2e,0x37,0x33,0x34, + 0x2c,0x32,0x2e,0x37,0x33,0x34,0x2c,0x31,0x2e,0x35, + 0x2c,0x34,0x2e,0x32,0x35,0x32,0x2c,0x31,0x2e,0x35, + 0x48,0x31,0x37,0x2e,0x37,0x31,0x20,0x4d,0x31,0x37, + 0x2e,0x37,0x31,0x2c,0x30,0x48,0x34,0x2e,0x32,0x35, + 0x32,0x43,0x31,0x2e,0x39,0x31,0x34,0x2c,0x30,0x2c, + 0x30,0x2c,0x31,0x2e,0x39,0x31,0x34,0x2c,0x30,0x2c, + 0x34,0x2e,0x32,0x35,0x32,0x76,0x31,0x33,0x2e,0x34, + 0x35,0x35,0x0a,0x09,0x63,0x30,0x2c,0x32,0x2e,0x33, + 0x33,0x39,0x2c,0x31,0x2e,0x39,0x31,0x34,0x2c,0x34, + 0x2e,0x32,0x35,0x32,0x2c,0x34,0x2e,0x32,0x35,0x32, + 0x2c,0x34,0x2e,0x32,0x35,0x32,0x48,0x31,0x37,0x2e, + 0x37,0x31,0x63,0x32,0x2e,0x33,0x33,0x39,0x2c,0x30, + 0x2c,0x34,0x2e,0x32,0x35,0x32,0x2d,0x31,0x2e,0x39, + 0x31,0x33,0x2c,0x34,0x2e,0x32,0x35,0x32,0x2d,0x34, + 0x2e,0x32,0x35,0x32,0x56,0x34,0x2e,0x32,0x35,0x32, + 0x43,0x32,0x31,0x2e,0x39,0x36,0x32,0x2c,0x31,0x2e, + 0x39,0x31,0x34,0x2c,0x32,0x30,0x2e,0x30,0x34,0x39, + 0x2c,0x30,0x2c,0x31,0x37,0x2e,0x37,0x31,0x2c,0x30, + 0x4c,0x31,0x37,0x2e,0x37,0x31,0x2c,0x30,0x7a,0x22, + 0x2f,0x3e,0x0a,0x3c,0x67,0x3e,0x0a,0x09,0x3c,0x67, + 0x3e,0x0a,0x09,0x09,0x0a,0x09,0x09,0x09,0x3c,0x72, + 0x65,0x63,0x74,0x20,0x78,0x3d,0x22,0x31,0x30,0x2e, + 0x32,0x33,0x32,0x22,0x20,0x79,0x3d,0x22,0x31,0x2e, + 0x30,0x37,0x39,0x22,0x20,0x74,0x72,0x61,0x6e,0x73, + 0x66,0x6f,0x72,0x6d,0x3d,0x22,0x6d,0x61,0x74,0x72, + 0x69,0x78,0x28,0x30,0x2e,0x37,0x30,0x37,0x31,0x20, + 0x30,0x2e,0x37,0x30,0x37,0x31,0x20,0x2d,0x30,0x2e, + 0x37,0x30,0x37,0x31,0x20,0x30,0x2e,0x37,0x30,0x37, + 0x31,0x20,0x31,0x30,0x2e,0x39,0x38,0x30,0x31,0x20, + 0x2d,0x34,0x2e,0x35,0x34,0x39,0x34,0x29,0x22,0x20, + 0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x37,0x37,0x37, + 0x37,0x37,0x37,0x22,0x20,0x77,0x69,0x64,0x74,0x68, + 0x3d,0x22,0x31,0x2e,0x35,0x22,0x20,0x68,0x65,0x69, + 0x67,0x68,0x74,0x3d,0x22,0x31,0x39,0x2e,0x38,0x22, + 0x2f,0x3e,0x0a,0x09,0x3c,0x2f,0x67,0x3e,0x0a,0x09, + 0x3c,0x67,0x3e,0x0a,0x09,0x09,0x0a,0x09,0x09,0x09, + 0x3c,0x72,0x65,0x63,0x74,0x20,0x78,0x3d,0x22,0x31, + 0x30,0x2e,0x32,0x33,0x32,0x22,0x20,0x79,0x3d,0x22, + 0x31,0x2e,0x30,0x37,0x39,0x22,0x20,0x74,0x72,0x61, 0x6e,0x73,0x66,0x6f,0x72,0x6d,0x3d,0x22,0x6d,0x61, 0x74,0x72,0x69,0x78,0x28,0x30,0x2e,0x37,0x30,0x37, 0x31,0x20,0x30,0x2e,0x37,0x30,0x37,0x31,0x20,0x2d, 0x30,0x2e,0x37,0x30,0x37,0x31,0x20,0x30,0x2e,0x37, - 0x30,0x37,0x31,0x20,0x31,0x30,0x2e,0x39,0x37,0x39, - 0x33,0x20,0x2d,0x34,0x2e,0x35,0x34,0x39,0x34,0x29, + 0x30,0x37,0x31,0x20,0x31,0x30,0x2e,0x39,0x38,0x30, + 0x31,0x20,0x2d,0x34,0x2e,0x35,0x34,0x39,0x34,0x29, 0x22,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x37, 0x37,0x37,0x37,0x37,0x37,0x22,0x20,0x77,0x69,0x64, - 0x74,0x68,0x3d,0x22,0x31,0x39,0x2e,0x38,0x22,0x20, - 0x68,0x65,0x69,0x67,0x68,0x74,0x3d,0x22,0x31,0x2e, - 0x35,0x22,0x2f,0x3e,0x0d,0x0a,0x09,0x3c,0x2f,0x67, - 0x3e,0x0d,0x0a,0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x3c, - 0x2f,0x73,0x76,0x67,0x3e,0x0d,0x0a + 0x74,0x68,0x3d,0x22,0x31,0x2e,0x35,0x22,0x20,0x68, + 0x65,0x69,0x67,0x68,0x74,0x3d,0x22,0x31,0x39,0x2e, + 0x38,0x22,0x2f,0x3e,0x0a,0x09,0x3c,0x2f,0x67,0x3e, + 0x0a,0x09,0x3c,0x67,0x3e,0x0a,0x09,0x09,0x0a,0x09, + 0x09,0x09,0x3c,0x72,0x65,0x63,0x74,0x20,0x78,0x3d, + 0x22,0x31,0x2e,0x30,0x38,0x32,0x22,0x20,0x79,0x3d, + 0x22,0x31,0x30,0x2e,0x32,0x33,0x22,0x20,0x74,0x72, + 0x61,0x6e,0x73,0x66,0x6f,0x72,0x6d,0x3d,0x22,0x6d, + 0x61,0x74,0x72,0x69,0x78,0x28,0x30,0x2e,0x37,0x30, + 0x37,0x31,0x20,0x30,0x2e,0x37,0x30,0x37,0x31,0x20, + 0x2d,0x30,0x2e,0x37,0x30,0x37,0x31,0x20,0x30,0x2e, + 0x37,0x30,0x37,0x31,0x20,0x31,0x30,0x2e,0x39,0x37, + 0x39,0x33,0x20,0x2d,0x34,0x2e,0x35,0x34,0x39,0x34, + 0x29,0x22,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23, + 0x37,0x37,0x37,0x37,0x37,0x37,0x22,0x20,0x77,0x69, + 0x64,0x74,0x68,0x3d,0x22,0x31,0x39,0x2e,0x38,0x22, + 0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3d,0x22,0x31, + 0x2e,0x35,0x22,0x2f,0x3e,0x0a,0x09,0x3c,0x2f,0x67, + 0x3e,0x0a,0x3c,0x2f,0x67,0x3e,0x0a,0x3c,0x2f,0x73, + 0x76,0x67,0x3e,0x0a }; + diff --git a/data/converted/checkbox_unchecked_svg.cpp b/data/converted/checkbox_unchecked_svg.cpp index a800cb7828..bc31f03740 100644 --- a/data/converted/checkbox_unchecked_svg.cpp +++ b/data/converted/checkbox_unchecked_svg.cpp @@ -2,92 +2,92 @@ #include "../Resources.h" -const size_t checkbox_unchecked_svg_size = 859; -const unsigned char checkbox_unchecked_svg_data[859] = { +const size_t checkbox_unchecked_svg_size = 850; +const unsigned char checkbox_unchecked_svg_data[850] = { 0x3c,0x3f,0x78,0x6d,0x6c,0x20,0x76,0x65,0x72,0x73, 0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x30,0x22,0x20, 0x65,0x6e,0x63,0x6f,0x64,0x69,0x6e,0x67,0x3d,0x22, - 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0d,0x0a, - 0x3c,0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72, - 0x61,0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62, - 0x65,0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61, - 0x74,0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33, - 0x2c,0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f, - 0x72,0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e, - 0x20,0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72, - 0x73,0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30, - 0x20,0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20, - 0x20,0x2d,0x2d,0x3e,0x0d,0x0a,0x3c,0x21,0x44,0x4f, - 0x43,0x54,0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20, - 0x50,0x55,0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f, - 0x2f,0x57,0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20, - 0x53,0x56,0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45, - 0x4e,0x22,0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, - 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, - 0x67,0x2f,0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73, - 0x2f,0x53,0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44, - 0x54,0x44,0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64, - 0x74,0x64,0x22,0x3e,0x0d,0x0a,0x3c,0x73,0x76,0x67, - 0x20,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22, - 0x31,0x2e,0x31,0x22,0x20,0x69,0x64,0x3d,0x22,0x45, - 0x62,0x65,0x6e,0x65,0x5f,0x31,0x22,0x20,0x78,0x6d, - 0x6c,0x6e,0x73,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a, - 0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f, - 0x72,0x67,0x2f,0x32,0x30,0x30,0x30,0x2f,0x73,0x76, - 0x67,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78, - 0x6c,0x69,0x6e,0x6b,0x3d,0x22,0x68,0x74,0x74,0x70, - 0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e, - 0x6f,0x72,0x67,0x2f,0x31,0x39,0x39,0x39,0x2f,0x78, - 0x6c,0x69,0x6e,0x6b,0x22,0x20,0x78,0x3d,0x22,0x30, - 0x70,0x78,0x22,0x20,0x79,0x3d,0x22,0x30,0x70,0x78, - 0x22,0x0d,0x0a,0x09,0x20,0x77,0x69,0x64,0x74,0x68, - 0x3d,0x22,0x32,0x31,0x2e,0x39,0x36,0x32,0x70,0x78, - 0x22,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3d,0x22, - 0x32,0x31,0x2e,0x39,0x35,0x39,0x70,0x78,0x22,0x20, - 0x76,0x69,0x65,0x77,0x42,0x6f,0x78,0x3d,0x22,0x30, - 0x20,0x30,0x20,0x32,0x31,0x2e,0x39,0x36,0x32,0x20, - 0x32,0x31,0x2e,0x39,0x35,0x39,0x22,0x20,0x65,0x6e, - 0x61,0x62,0x6c,0x65,0x2d,0x62,0x61,0x63,0x6b,0x67, - 0x72,0x6f,0x75,0x6e,0x64,0x3d,0x22,0x6e,0x65,0x77, - 0x20,0x30,0x20,0x30,0x20,0x32,0x31,0x2e,0x39,0x36, - 0x32,0x20,0x32,0x31,0x2e,0x39,0x35,0x39,0x22,0x20, - 0x78,0x6d,0x6c,0x3a,0x73,0x70,0x61,0x63,0x65,0x3d, - 0x22,0x70,0x72,0x65,0x73,0x65,0x72,0x76,0x65,0x22, - 0x3e,0x0d,0x0a,0x3c,0x70,0x61,0x74,0x68,0x20,0x66, - 0x69,0x6c,0x6c,0x3d,0x22,0x23,0x37,0x37,0x37,0x37, - 0x37,0x37,0x22,0x20,0x64,0x3d,0x22,0x4d,0x31,0x37, - 0x2e,0x37,0x31,0x2c,0x31,0x2e,0x35,0x63,0x31,0x2e, - 0x35,0x31,0x38,0x2c,0x30,0x2c,0x32,0x2e,0x37,0x35, - 0x32,0x2c,0x31,0x2e,0x32,0x33,0x34,0x2c,0x32,0x2e, - 0x37,0x35,0x32,0x2c,0x32,0x2e,0x37,0x35,0x32,0x76, - 0x31,0x33,0x2e,0x34,0x35,0x35,0x63,0x30,0x2c,0x31, - 0x2e,0x35,0x31,0x38,0x2d,0x31,0x2e,0x32,0x33,0x34, - 0x2c,0x32,0x2e,0x37,0x35,0x32,0x2d,0x32,0x2e,0x37, - 0x35,0x32,0x2c,0x32,0x2e,0x37,0x35,0x32,0x48,0x34, - 0x2e,0x32,0x35,0x32,0x0d,0x0a,0x09,0x63,0x2d,0x31, - 0x2e,0x35,0x31,0x38,0x2c,0x30,0x2d,0x32,0x2e,0x37, - 0x35,0x32,0x2d,0x31,0x2e,0x32,0x33,0x34,0x2d,0x32, - 0x2e,0x37,0x35,0x32,0x2d,0x32,0x2e,0x37,0x35,0x32, - 0x56,0x34,0x2e,0x32,0x35,0x32,0x43,0x31,0x2e,0x35, - 0x2c,0x32,0x2e,0x37,0x33,0x34,0x2c,0x32,0x2e,0x37, - 0x33,0x34,0x2c,0x31,0x2e,0x35,0x2c,0x34,0x2e,0x32, - 0x35,0x32,0x2c,0x31,0x2e,0x35,0x48,0x31,0x37,0x2e, - 0x37,0x31,0x20,0x4d,0x31,0x37,0x2e,0x37,0x31,0x2c, - 0x30,0x48,0x34,0x2e,0x32,0x35,0x32,0x43,0x31,0x2e, - 0x39,0x31,0x34,0x2c,0x30,0x2c,0x30,0x2c,0x31,0x2e, - 0x39,0x31,0x34,0x2c,0x30,0x2c,0x34,0x2e,0x32,0x35, - 0x32,0x76,0x31,0x33,0x2e,0x34,0x35,0x35,0x0d,0x0a, - 0x09,0x63,0x30,0x2c,0x32,0x2e,0x33,0x33,0x39,0x2c, - 0x31,0x2e,0x39,0x31,0x34,0x2c,0x34,0x2e,0x32,0x35, - 0x32,0x2c,0x34,0x2e,0x32,0x35,0x32,0x2c,0x34,0x2e, - 0x32,0x35,0x32,0x48,0x31,0x37,0x2e,0x37,0x31,0x63, - 0x32,0x2e,0x33,0x33,0x39,0x2c,0x30,0x2c,0x34,0x2e, - 0x32,0x35,0x32,0x2d,0x31,0x2e,0x39,0x31,0x33,0x2c, - 0x34,0x2e,0x32,0x35,0x32,0x2d,0x34,0x2e,0x32,0x35, - 0x32,0x56,0x34,0x2e,0x32,0x35,0x32,0x43,0x32,0x31, - 0x2e,0x39,0x36,0x32,0x2c,0x31,0x2e,0x39,0x31,0x34, - 0x2c,0x32,0x30,0x2e,0x30,0x34,0x39,0x2c,0x30,0x2c, - 0x31,0x37,0x2e,0x37,0x31,0x2c,0x30,0x4c,0x31,0x37, - 0x2e,0x37,0x31,0x2c,0x30,0x7a,0x22,0x2f,0x3e,0x0d, - 0x0a,0x3c,0x2f,0x73,0x76,0x67,0x3e,0x0d,0x0a + 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0a,0x3c, + 0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72,0x61, + 0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62,0x65, + 0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61,0x74, + 0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33,0x2c, + 0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f,0x72, + 0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e,0x20, + 0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72,0x73, + 0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30,0x20, + 0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20,0x20, + 0x2d,0x2d,0x3e,0x0a,0x3c,0x21,0x44,0x4f,0x43,0x54, + 0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20,0x50,0x55, + 0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f,0x2f,0x57, + 0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20,0x53,0x56, + 0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45,0x4e,0x22, + 0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73,0x2f,0x53, + 0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44,0x54,0x44, + 0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64,0x74,0x64, + 0x22,0x3e,0x0a,0x3c,0x73,0x76,0x67,0x20,0x76,0x65, + 0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x31, + 0x22,0x20,0x69,0x64,0x3d,0x22,0x45,0x62,0x65,0x6e, + 0x65,0x5f,0x31,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73, + 0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x32,0x30,0x30,0x30,0x2f,0x73,0x76,0x67,0x22,0x20, + 0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78,0x6c,0x69,0x6e, + 0x6b,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f, + 0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67, + 0x2f,0x31,0x39,0x39,0x39,0x2f,0x78,0x6c,0x69,0x6e, + 0x6b,0x22,0x20,0x78,0x3d,0x22,0x30,0x70,0x78,0x22, + 0x20,0x79,0x3d,0x22,0x30,0x70,0x78,0x22,0x0a,0x09, + 0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x32,0x31, + 0x2e,0x39,0x36,0x32,0x70,0x78,0x22,0x20,0x68,0x65, + 0x69,0x67,0x68,0x74,0x3d,0x22,0x32,0x31,0x2e,0x39, + 0x35,0x39,0x70,0x78,0x22,0x20,0x76,0x69,0x65,0x77, + 0x42,0x6f,0x78,0x3d,0x22,0x30,0x20,0x30,0x20,0x32, + 0x31,0x2e,0x39,0x36,0x32,0x20,0x32,0x31,0x2e,0x39, + 0x35,0x39,0x22,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65, + 0x2d,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e, + 0x64,0x3d,0x22,0x6e,0x65,0x77,0x20,0x30,0x20,0x30, + 0x20,0x32,0x31,0x2e,0x39,0x36,0x32,0x20,0x32,0x31, + 0x2e,0x39,0x35,0x39,0x22,0x20,0x78,0x6d,0x6c,0x3a, + 0x73,0x70,0x61,0x63,0x65,0x3d,0x22,0x70,0x72,0x65, + 0x73,0x65,0x72,0x76,0x65,0x22,0x3e,0x0a,0x3c,0x70, + 0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22, + 0x23,0x37,0x37,0x37,0x37,0x37,0x37,0x22,0x20,0x64, + 0x3d,0x22,0x4d,0x31,0x37,0x2e,0x37,0x31,0x2c,0x31, + 0x2e,0x35,0x63,0x31,0x2e,0x35,0x31,0x38,0x2c,0x30, + 0x2c,0x32,0x2e,0x37,0x35,0x32,0x2c,0x31,0x2e,0x32, + 0x33,0x34,0x2c,0x32,0x2e,0x37,0x35,0x32,0x2c,0x32, + 0x2e,0x37,0x35,0x32,0x76,0x31,0x33,0x2e,0x34,0x35, + 0x35,0x63,0x30,0x2c,0x31,0x2e,0x35,0x31,0x38,0x2d, + 0x31,0x2e,0x32,0x33,0x34,0x2c,0x32,0x2e,0x37,0x35, + 0x32,0x2d,0x32,0x2e,0x37,0x35,0x32,0x2c,0x32,0x2e, + 0x37,0x35,0x32,0x48,0x34,0x2e,0x32,0x35,0x32,0x0a, + 0x09,0x63,0x2d,0x31,0x2e,0x35,0x31,0x38,0x2c,0x30, + 0x2d,0x32,0x2e,0x37,0x35,0x32,0x2d,0x31,0x2e,0x32, + 0x33,0x34,0x2d,0x32,0x2e,0x37,0x35,0x32,0x2d,0x32, + 0x2e,0x37,0x35,0x32,0x56,0x34,0x2e,0x32,0x35,0x32, + 0x43,0x31,0x2e,0x35,0x2c,0x32,0x2e,0x37,0x33,0x34, + 0x2c,0x32,0x2e,0x37,0x33,0x34,0x2c,0x31,0x2e,0x35, + 0x2c,0x34,0x2e,0x32,0x35,0x32,0x2c,0x31,0x2e,0x35, + 0x48,0x31,0x37,0x2e,0x37,0x31,0x20,0x4d,0x31,0x37, + 0x2e,0x37,0x31,0x2c,0x30,0x48,0x34,0x2e,0x32,0x35, + 0x32,0x43,0x31,0x2e,0x39,0x31,0x34,0x2c,0x30,0x2c, + 0x30,0x2c,0x31,0x2e,0x39,0x31,0x34,0x2c,0x30,0x2c, + 0x34,0x2e,0x32,0x35,0x32,0x76,0x31,0x33,0x2e,0x34, + 0x35,0x35,0x0a,0x09,0x63,0x30,0x2c,0x32,0x2e,0x33, + 0x33,0x39,0x2c,0x31,0x2e,0x39,0x31,0x34,0x2c,0x34, + 0x2e,0x32,0x35,0x32,0x2c,0x34,0x2e,0x32,0x35,0x32, + 0x2c,0x34,0x2e,0x32,0x35,0x32,0x48,0x31,0x37,0x2e, + 0x37,0x31,0x63,0x32,0x2e,0x33,0x33,0x39,0x2c,0x30, + 0x2c,0x34,0x2e,0x32,0x35,0x32,0x2d,0x31,0x2e,0x39, + 0x31,0x33,0x2c,0x34,0x2e,0x32,0x35,0x32,0x2d,0x34, + 0x2e,0x32,0x35,0x32,0x56,0x34,0x2e,0x32,0x35,0x32, + 0x43,0x32,0x31,0x2e,0x39,0x36,0x32,0x2c,0x31,0x2e, + 0x39,0x31,0x34,0x2c,0x32,0x30,0x2e,0x30,0x34,0x39, + 0x2c,0x30,0x2c,0x31,0x37,0x2e,0x37,0x31,0x2c,0x30, + 0x4c,0x31,0x37,0x2e,0x37,0x31,0x2c,0x30,0x7a,0x22, + 0x2f,0x3e,0x0a,0x3c,0x2f,0x73,0x76,0x67,0x3e,0x0a }; + diff --git a/data/converted/fav_add_svg.cpp b/data/converted/fav_add_svg.cpp index 4bd2a33047..02365f5fee 100644 --- a/data/converted/fav_add_svg.cpp +++ b/data/converted/fav_add_svg.cpp @@ -2,71 +2,71 @@ #include "../Resources.h" -const size_t fav_add_svg_size = 650; -const unsigned char fav_add_svg_data[650] = { +const size_t fav_add_svg_size = 638; +const unsigned char fav_add_svg_data[638] = { 0x3c,0x3f,0x78,0x6d,0x6c,0x20,0x76,0x65,0x72,0x73, 0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x30,0x22,0x20, 0x65,0x6e,0x63,0x6f,0x64,0x69,0x6e,0x67,0x3d,0x22, - 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0d,0x0a, - 0x3c,0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72, - 0x61,0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62, - 0x65,0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61, - 0x74,0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33, - 0x2c,0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f, - 0x72,0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e, - 0x20,0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72, - 0x73,0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30, - 0x20,0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20, - 0x20,0x2d,0x2d,0x3e,0x0d,0x0a,0x3c,0x21,0x44,0x4f, - 0x43,0x54,0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20, - 0x50,0x55,0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f, - 0x2f,0x57,0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20, - 0x53,0x56,0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45, - 0x4e,0x22,0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, - 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, - 0x67,0x2f,0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73, - 0x2f,0x53,0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44, - 0x54,0x44,0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64, - 0x74,0x64,0x22,0x3e,0x0d,0x0a,0x3c,0x73,0x76,0x67, - 0x20,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22, - 0x31,0x2e,0x31,0x22,0x20,0x69,0x64,0x3d,0x22,0x45, - 0x62,0x65,0x6e,0x65,0x5f,0x31,0x22,0x20,0x78,0x6d, - 0x6c,0x6e,0x73,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a, - 0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f, - 0x72,0x67,0x2f,0x32,0x30,0x30,0x30,0x2f,0x73,0x76, - 0x67,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78, - 0x6c,0x69,0x6e,0x6b,0x3d,0x22,0x68,0x74,0x74,0x70, - 0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e, - 0x6f,0x72,0x67,0x2f,0x31,0x39,0x39,0x39,0x2f,0x78, - 0x6c,0x69,0x6e,0x6b,0x22,0x20,0x78,0x3d,0x22,0x30, - 0x70,0x78,0x22,0x20,0x79,0x3d,0x22,0x30,0x70,0x78, - 0x22,0x0d,0x0a,0x09,0x20,0x77,0x69,0x64,0x74,0x68, - 0x3d,0x22,0x32,0x31,0x2e,0x30,0x30,0x32,0x70,0x78, - 0x22,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3d,0x22, - 0x32,0x32,0x2e,0x30,0x30,0x32,0x70,0x78,0x22,0x20, - 0x76,0x69,0x65,0x77,0x42,0x6f,0x78,0x3d,0x22,0x30, - 0x20,0x30,0x20,0x32,0x31,0x2e,0x30,0x30,0x32,0x20, - 0x32,0x32,0x2e,0x30,0x30,0x32,0x22,0x20,0x65,0x6e, - 0x61,0x62,0x6c,0x65,0x2d,0x62,0x61,0x63,0x6b,0x67, - 0x72,0x6f,0x75,0x6e,0x64,0x3d,0x22,0x6e,0x65,0x77, - 0x20,0x30,0x20,0x30,0x20,0x32,0x31,0x2e,0x30,0x30, - 0x32,0x20,0x32,0x32,0x2e,0x30,0x30,0x32,0x22,0x20, - 0x78,0x6d,0x6c,0x3a,0x73,0x70,0x61,0x63,0x65,0x3d, - 0x22,0x70,0x72,0x65,0x73,0x65,0x72,0x76,0x65,0x22, - 0x3e,0x0d,0x0a,0x3c,0x67,0x3e,0x0d,0x0a,0x09,0x3c, - 0x72,0x65,0x63,0x74,0x20,0x79,0x3d,0x22,0x31,0x30, - 0x2e,0x32,0x35,0x31,0x22,0x20,0x66,0x69,0x6c,0x6c, - 0x3d,0x22,0x23,0x37,0x37,0x37,0x37,0x37,0x37,0x22, + 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0a,0x3c, + 0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72,0x61, + 0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62,0x65, + 0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61,0x74, + 0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33,0x2c, + 0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f,0x72, + 0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e,0x20, + 0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72,0x73, + 0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30,0x20, + 0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20,0x20, + 0x2d,0x2d,0x3e,0x0a,0x3c,0x21,0x44,0x4f,0x43,0x54, + 0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20,0x50,0x55, + 0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f,0x2f,0x57, + 0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20,0x53,0x56, + 0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45,0x4e,0x22, + 0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73,0x2f,0x53, + 0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44,0x54,0x44, + 0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64,0x74,0x64, + 0x22,0x3e,0x0a,0x3c,0x73,0x76,0x67,0x20,0x76,0x65, + 0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x31, + 0x22,0x20,0x69,0x64,0x3d,0x22,0x45,0x62,0x65,0x6e, + 0x65,0x5f,0x31,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73, + 0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x32,0x30,0x30,0x30,0x2f,0x73,0x76,0x67,0x22,0x20, + 0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78,0x6c,0x69,0x6e, + 0x6b,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f, + 0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67, + 0x2f,0x31,0x39,0x39,0x39,0x2f,0x78,0x6c,0x69,0x6e, + 0x6b,0x22,0x20,0x78,0x3d,0x22,0x30,0x70,0x78,0x22, + 0x20,0x79,0x3d,0x22,0x30,0x70,0x78,0x22,0x0a,0x09, 0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x32,0x31, - 0x2e,0x30,0x30,0x32,0x22,0x20,0x68,0x65,0x69,0x67, - 0x68,0x74,0x3d,0x22,0x31,0x2e,0x35,0x22,0x2f,0x3e, - 0x0d,0x0a,0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x3c,0x67, - 0x3e,0x0d,0x0a,0x09,0x3c,0x72,0x65,0x63,0x74,0x20, - 0x78,0x3d,0x22,0x39,0x2e,0x37,0x35,0x31,0x22,0x20, + 0x2e,0x30,0x30,0x32,0x70,0x78,0x22,0x20,0x68,0x65, + 0x69,0x67,0x68,0x74,0x3d,0x22,0x32,0x32,0x2e,0x30, + 0x30,0x32,0x70,0x78,0x22,0x20,0x76,0x69,0x65,0x77, + 0x42,0x6f,0x78,0x3d,0x22,0x30,0x20,0x30,0x20,0x32, + 0x31,0x2e,0x30,0x30,0x32,0x20,0x32,0x32,0x2e,0x30, + 0x30,0x32,0x22,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65, + 0x2d,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e, + 0x64,0x3d,0x22,0x6e,0x65,0x77,0x20,0x30,0x20,0x30, + 0x20,0x32,0x31,0x2e,0x30,0x30,0x32,0x20,0x32,0x32, + 0x2e,0x30,0x30,0x32,0x22,0x20,0x78,0x6d,0x6c,0x3a, + 0x73,0x70,0x61,0x63,0x65,0x3d,0x22,0x70,0x72,0x65, + 0x73,0x65,0x72,0x76,0x65,0x22,0x3e,0x0a,0x3c,0x67, + 0x3e,0x0a,0x09,0x3c,0x72,0x65,0x63,0x74,0x20,0x79, + 0x3d,0x22,0x31,0x30,0x2e,0x32,0x35,0x31,0x22,0x20, 0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x37,0x37,0x37, 0x37,0x37,0x37,0x22,0x20,0x77,0x69,0x64,0x74,0x68, - 0x3d,0x22,0x31,0x2e,0x35,0x22,0x20,0x68,0x65,0x69, - 0x67,0x68,0x74,0x3d,0x22,0x32,0x32,0x2e,0x30,0x30, - 0x32,0x22,0x2f,0x3e,0x0d,0x0a,0x3c,0x2f,0x67,0x3e, - 0x0d,0x0a,0x3c,0x2f,0x73,0x76,0x67,0x3e,0x0d,0x0a + 0x3d,0x22,0x32,0x31,0x2e,0x30,0x30,0x32,0x22,0x20, + 0x68,0x65,0x69,0x67,0x68,0x74,0x3d,0x22,0x31,0x2e, + 0x35,0x22,0x2f,0x3e,0x0a,0x3c,0x2f,0x67,0x3e,0x0a, + 0x3c,0x67,0x3e,0x0a,0x09,0x3c,0x72,0x65,0x63,0x74, + 0x20,0x78,0x3d,0x22,0x39,0x2e,0x37,0x35,0x31,0x22, + 0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x37,0x37, + 0x37,0x37,0x37,0x37,0x22,0x20,0x77,0x69,0x64,0x74, + 0x68,0x3d,0x22,0x31,0x2e,0x35,0x22,0x20,0x68,0x65, + 0x69,0x67,0x68,0x74,0x3d,0x22,0x32,0x32,0x2e,0x30, + 0x30,0x32,0x22,0x2f,0x3e,0x0a,0x3c,0x2f,0x67,0x3e, + 0x0a,0x3c,0x2f,0x73,0x76,0x67,0x3e,0x0a }; + diff --git a/data/converted/fav_remove_svg.cpp b/data/converted/fav_remove_svg.cpp index 086ae9e76a..07ea8f7593 100644 --- a/data/converted/fav_remove_svg.cpp +++ b/data/converted/fav_remove_svg.cpp @@ -2,64 +2,64 @@ #include "../Resources.h" -const size_t fav_remove_svg_size = 576; -const unsigned char fav_remove_svg_data[576] = { +const size_t fav_remove_svg_size = 567; +const unsigned char fav_remove_svg_data[567] = { 0x3c,0x3f,0x78,0x6d,0x6c,0x20,0x76,0x65,0x72,0x73, 0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x30,0x22,0x20, 0x65,0x6e,0x63,0x6f,0x64,0x69,0x6e,0x67,0x3d,0x22, - 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0d,0x0a, - 0x3c,0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72, - 0x61,0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62, - 0x65,0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61, - 0x74,0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33, - 0x2c,0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f, - 0x72,0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e, - 0x20,0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72, - 0x73,0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30, - 0x20,0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20, - 0x20,0x2d,0x2d,0x3e,0x0d,0x0a,0x3c,0x21,0x44,0x4f, - 0x43,0x54,0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20, - 0x50,0x55,0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f, - 0x2f,0x57,0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20, - 0x53,0x56,0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45, - 0x4e,0x22,0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, - 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, - 0x67,0x2f,0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73, - 0x2f,0x53,0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44, - 0x54,0x44,0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64, - 0x74,0x64,0x22,0x3e,0x0d,0x0a,0x3c,0x73,0x76,0x67, - 0x20,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22, - 0x31,0x2e,0x31,0x22,0x20,0x69,0x64,0x3d,0x22,0x45, - 0x62,0x65,0x6e,0x65,0x5f,0x31,0x22,0x20,0x78,0x6d, - 0x6c,0x6e,0x73,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a, - 0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f, - 0x72,0x67,0x2f,0x32,0x30,0x30,0x30,0x2f,0x73,0x76, - 0x67,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78, - 0x6c,0x69,0x6e,0x6b,0x3d,0x22,0x68,0x74,0x74,0x70, - 0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e, - 0x6f,0x72,0x67,0x2f,0x31,0x39,0x39,0x39,0x2f,0x78, - 0x6c,0x69,0x6e,0x6b,0x22,0x20,0x78,0x3d,0x22,0x30, - 0x70,0x78,0x22,0x20,0x79,0x3d,0x22,0x30,0x70,0x78, - 0x22,0x0d,0x0a,0x09,0x20,0x77,0x69,0x64,0x74,0x68, - 0x3d,0x22,0x32,0x31,0x2e,0x30,0x30,0x32,0x70,0x78, - 0x22,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3d,0x22, - 0x32,0x32,0x2e,0x30,0x30,0x32,0x70,0x78,0x22,0x20, - 0x76,0x69,0x65,0x77,0x42,0x6f,0x78,0x3d,0x22,0x30, - 0x20,0x30,0x20,0x32,0x31,0x2e,0x30,0x30,0x32,0x20, - 0x32,0x32,0x2e,0x30,0x30,0x32,0x22,0x20,0x65,0x6e, - 0x61,0x62,0x6c,0x65,0x2d,0x62,0x61,0x63,0x6b,0x67, - 0x72,0x6f,0x75,0x6e,0x64,0x3d,0x22,0x6e,0x65,0x77, - 0x20,0x30,0x20,0x30,0x20,0x32,0x31,0x2e,0x30,0x30, - 0x32,0x20,0x32,0x32,0x2e,0x30,0x30,0x32,0x22,0x20, - 0x78,0x6d,0x6c,0x3a,0x73,0x70,0x61,0x63,0x65,0x3d, - 0x22,0x70,0x72,0x65,0x73,0x65,0x72,0x76,0x65,0x22, - 0x3e,0x0d,0x0a,0x3c,0x67,0x3e,0x0d,0x0a,0x09,0x3c, - 0x72,0x65,0x63,0x74,0x20,0x79,0x3d,0x22,0x31,0x30, - 0x2e,0x32,0x35,0x31,0x22,0x20,0x66,0x69,0x6c,0x6c, - 0x3d,0x22,0x23,0x37,0x37,0x37,0x37,0x37,0x37,0x22, + 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0a,0x3c, + 0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72,0x61, + 0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62,0x65, + 0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61,0x74, + 0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33,0x2c, + 0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f,0x72, + 0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e,0x20, + 0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72,0x73, + 0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30,0x20, + 0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20,0x20, + 0x2d,0x2d,0x3e,0x0a,0x3c,0x21,0x44,0x4f,0x43,0x54, + 0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20,0x50,0x55, + 0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f,0x2f,0x57, + 0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20,0x53,0x56, + 0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45,0x4e,0x22, + 0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73,0x2f,0x53, + 0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44,0x54,0x44, + 0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64,0x74,0x64, + 0x22,0x3e,0x0a,0x3c,0x73,0x76,0x67,0x20,0x76,0x65, + 0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x31, + 0x22,0x20,0x69,0x64,0x3d,0x22,0x45,0x62,0x65,0x6e, + 0x65,0x5f,0x31,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73, + 0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x32,0x30,0x30,0x30,0x2f,0x73,0x76,0x67,0x22,0x20, + 0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78,0x6c,0x69,0x6e, + 0x6b,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f, + 0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67, + 0x2f,0x31,0x39,0x39,0x39,0x2f,0x78,0x6c,0x69,0x6e, + 0x6b,0x22,0x20,0x78,0x3d,0x22,0x30,0x70,0x78,0x22, + 0x20,0x79,0x3d,0x22,0x30,0x70,0x78,0x22,0x0a,0x09, 0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x32,0x31, - 0x2e,0x30,0x30,0x32,0x22,0x20,0x68,0x65,0x69,0x67, - 0x68,0x74,0x3d,0x22,0x31,0x2e,0x35,0x22,0x2f,0x3e, - 0x0d,0x0a,0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x3c,0x2f, - 0x73,0x76,0x67,0x3e,0x0d,0x0a + 0x2e,0x30,0x30,0x32,0x70,0x78,0x22,0x20,0x68,0x65, + 0x69,0x67,0x68,0x74,0x3d,0x22,0x32,0x32,0x2e,0x30, + 0x30,0x32,0x70,0x78,0x22,0x20,0x76,0x69,0x65,0x77, + 0x42,0x6f,0x78,0x3d,0x22,0x30,0x20,0x30,0x20,0x32, + 0x31,0x2e,0x30,0x30,0x32,0x20,0x32,0x32,0x2e,0x30, + 0x30,0x32,0x22,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65, + 0x2d,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e, + 0x64,0x3d,0x22,0x6e,0x65,0x77,0x20,0x30,0x20,0x30, + 0x20,0x32,0x31,0x2e,0x30,0x30,0x32,0x20,0x32,0x32, + 0x2e,0x30,0x30,0x32,0x22,0x20,0x78,0x6d,0x6c,0x3a, + 0x73,0x70,0x61,0x63,0x65,0x3d,0x22,0x70,0x72,0x65, + 0x73,0x65,0x72,0x76,0x65,0x22,0x3e,0x0a,0x3c,0x67, + 0x3e,0x0a,0x09,0x3c,0x72,0x65,0x63,0x74,0x20,0x79, + 0x3d,0x22,0x31,0x30,0x2e,0x32,0x35,0x31,0x22,0x20, + 0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x37,0x37,0x37, + 0x37,0x37,0x37,0x22,0x20,0x77,0x69,0x64,0x74,0x68, + 0x3d,0x22,0x32,0x31,0x2e,0x30,0x30,0x32,0x22,0x20, + 0x68,0x65,0x69,0x67,0x68,0x74,0x3d,0x22,0x31,0x2e, + 0x35,0x22,0x2f,0x3e,0x0a,0x3c,0x2f,0x67,0x3e,0x0a, + 0x3c,0x2f,0x73,0x76,0x67,0x3e,0x0a }; + diff --git a/data/converted/frame_png.cpp b/data/converted/frame_png.cpp index 1e986b9146..2afd0f94e8 100644 --- a/data/converted/frame_png.cpp +++ b/data/converted/frame_png.cpp @@ -178,3 +178,4 @@ const unsigned char frame_png_data[1729] = { 0xb5,0x2e,0x8e,0x23,0xf2,0x34,0xce,0x00,0x00,0x00, 0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82 }; + diff --git a/data/converted/help_analog_down_svg.cpp b/data/converted/help_analog_down_svg.cpp new file mode 100644 index 0000000000..1a58a01893 --- /dev/null +++ b/data/converted/help_analog_down_svg.cpp @@ -0,0 +1,289 @@ +//this file was auto-generated from "analog_down.svg" by res2h + +#include "../Resources.h" + +const size_t help_analog_down_svg_size = 2809; +const unsigned char help_analog_down_svg_data[2809] = { + 0x3c,0x3f,0x78,0x6d,0x6c,0x20,0x76,0x65,0x72,0x73, + 0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x30,0x22,0x20, + 0x65,0x6e,0x63,0x6f,0x64,0x69,0x6e,0x67,0x3d,0x22, + 0x55,0x54,0x46,0x2d,0x38,0x22,0x3f,0x3e,0x0a,0x3c, + 0x21,0x44,0x4f,0x43,0x54,0x59,0x50,0x45,0x20,0x73, + 0x76,0x67,0x20,0x50,0x55,0x42,0x4c,0x49,0x43,0x20, + 0x22,0x2d,0x2f,0x2f,0x57,0x33,0x43,0x2f,0x2f,0x44, + 0x54,0x44,0x20,0x53,0x56,0x47,0x20,0x31,0x2e,0x31, + 0x2f,0x2f,0x45,0x4e,0x22,0x20,0x22,0x68,0x74,0x74, + 0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33, + 0x2e,0x6f,0x72,0x67,0x2f,0x47,0x72,0x61,0x70,0x68, + 0x69,0x63,0x73,0x2f,0x53,0x56,0x47,0x2f,0x31,0x2e, + 0x31,0x2f,0x44,0x54,0x44,0x2f,0x73,0x76,0x67,0x31, + 0x31,0x2e,0x64,0x74,0x64,0x22,0x3e,0x0a,0x3c,0x73, + 0x76,0x67,0x20,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e, + 0x3d,0x22,0x31,0x2e,0x31,0x22,0x20,0x78,0x6d,0x6c, + 0x6e,0x73,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, + 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, + 0x67,0x2f,0x32,0x30,0x30,0x30,0x2f,0x73,0x76,0x67, + 0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78,0x6c, + 0x69,0x6e,0x6b,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a, + 0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f, + 0x72,0x67,0x2f,0x31,0x39,0x39,0x39,0x2f,0x78,0x6c, + 0x69,0x6e,0x6b,0x22,0x20,0x78,0x3d,0x22,0x30,0x22, + 0x20,0x79,0x3d,0x22,0x30,0x22,0x20,0x77,0x69,0x64, + 0x74,0x68,0x3d,0x22,0x33,0x37,0x2e,0x30,0x36,0x31, + 0x22,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3d,0x22, + 0x33,0x37,0x2e,0x30,0x36,0x31,0x22,0x20,0x76,0x69, + 0x65,0x77,0x42,0x6f,0x78,0x3d,0x22,0x30,0x2c,0x20, + 0x30,0x2c,0x20,0x33,0x37,0x2e,0x30,0x36,0x31,0x2c, + 0x20,0x33,0x37,0x2e,0x30,0x36,0x31,0x22,0x3e,0x0a, + 0x20,0x20,0x3c,0x67,0x20,0x69,0x64,0x3d,0x22,0x45, + 0x62,0x65,0x6e,0x65,0x5f,0x31,0x22,0x3e,0x0a,0x20, + 0x20,0x20,0x20,0x3c,0x70,0x61,0x74,0x68,0x20,0x64, + 0x3d,0x22,0x4d,0x32,0x32,0x2e,0x31,0x34,0x35,0x2c, + 0x31,0x38,0x2e,0x35,0x31,0x32,0x20,0x43,0x32,0x32, + 0x2e,0x31,0x34,0x35,0x2c,0x32,0x30,0x2e,0x35,0x32, + 0x35,0x20,0x32,0x30,0x2e,0x35,0x30,0x36,0x2c,0x32, + 0x32,0x2e,0x31,0x36,0x31,0x20,0x31,0x38,0x2e,0x34, + 0x39,0x34,0x2c,0x32,0x32,0x2e,0x31,0x36,0x31,0x20, + 0x43,0x31,0x36,0x2e,0x34,0x38,0x32,0x2c,0x32,0x32, + 0x2e,0x31,0x36,0x31,0x20,0x31,0x34,0x2e,0x38,0x34, + 0x34,0x2c,0x32,0x30,0x2e,0x35,0x32,0x33,0x20,0x31, + 0x34,0x2e,0x38,0x34,0x34,0x2c,0x31,0x38,0x2e,0x35, + 0x31,0x32,0x20,0x43,0x31,0x34,0x2e,0x38,0x34,0x34, + 0x2c,0x31,0x36,0x2e,0x34,0x39,0x39,0x20,0x31,0x36, + 0x2e,0x34,0x38,0x33,0x2c,0x31,0x34,0x2e,0x38,0x36, + 0x32,0x20,0x31,0x38,0x2e,0x34,0x39,0x34,0x2c,0x31, + 0x34,0x2e,0x38,0x36,0x32,0x20,0x43,0x32,0x30,0x2e, + 0x35,0x30,0x37,0x2c,0x31,0x34,0x2e,0x38,0x36,0x31, + 0x20,0x32,0x32,0x2e,0x31,0x34,0x35,0x2c,0x31,0x36, + 0x2e,0x34,0x39,0x39,0x20,0x32,0x32,0x2e,0x31,0x34, + 0x35,0x2c,0x31,0x38,0x2e,0x35,0x31,0x32,0x20,0x7a, + 0x20,0x4d,0x31,0x36,0x2e,0x33,0x34,0x33,0x2c,0x31, + 0x38,0x2e,0x35,0x31,0x32,0x20,0x43,0x31,0x36,0x2e, + 0x33,0x34,0x33,0x2c,0x31,0x39,0x2e,0x36,0x39,0x38, + 0x20,0x31,0x37,0x2e,0x33,0x30,0x38,0x2c,0x32,0x30, + 0x2e,0x36,0x36,0x31,0x20,0x31,0x38,0x2e,0x34,0x39, + 0x33,0x2c,0x32,0x30,0x2e,0x36,0x36,0x31,0x20,0x43, + 0x31,0x39,0x2e,0x36,0x37,0x38,0x2c,0x32,0x30,0x2e, + 0x36,0x36,0x31,0x20,0x32,0x30,0x2e,0x36,0x34,0x34, + 0x2c,0x31,0x39,0x2e,0x36,0x39,0x36,0x20,0x32,0x30, + 0x2e,0x36,0x34,0x34,0x2c,0x31,0x38,0x2e,0x35,0x31, + 0x32,0x20,0x43,0x32,0x30,0x2e,0x36,0x34,0x34,0x2c, + 0x31,0x37,0x2e,0x33,0x32,0x36,0x20,0x31,0x39,0x2e, + 0x36,0x37,0x38,0x2c,0x31,0x36,0x2e,0x33,0x36,0x32, + 0x20,0x31,0x38,0x2e,0x34,0x39,0x33,0x2c,0x31,0x36, + 0x2e,0x33,0x36,0x32,0x20,0x43,0x31,0x37,0x2e,0x33, + 0x30,0x38,0x2c,0x31,0x36,0x2e,0x33,0x36,0x31,0x20, + 0x31,0x36,0x2e,0x33,0x34,0x33,0x2c,0x31,0x37,0x2e, + 0x33,0x32,0x36,0x20,0x31,0x36,0x2e,0x33,0x34,0x33, + 0x2c,0x31,0x38,0x2e,0x35,0x31,0x32,0x20,0x7a,0x22, + 0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46, + 0x46,0x46,0x46,0x46,0x22,0x2f,0x3e,0x0a,0x20,0x20, + 0x20,0x20,0x3c,0x70,0x61,0x74,0x68,0x20,0x64,0x3d, + 0x22,0x4d,0x38,0x2e,0x35,0x38,0x2c,0x31,0x35,0x2e, + 0x35,0x30,0x37,0x20,0x4c,0x38,0x2e,0x35,0x38,0x2c, + 0x32,0x31,0x2e,0x35,0x31,0x39,0x20,0x43,0x38,0x2e, + 0x35,0x38,0x2c,0x32,0x31,0x2e,0x37,0x39,0x32,0x20, + 0x38,0x2e,0x34,0x33,0x2c,0x32,0x32,0x2e,0x30,0x34, + 0x34,0x20,0x38,0x2e,0x31,0x39,0x2c,0x32,0x32,0x2e, + 0x31,0x37,0x36,0x20,0x43,0x37,0x2e,0x39,0x34,0x39, + 0x2c,0x32,0x32,0x2e,0x33,0x30,0x38,0x20,0x37,0x2e, + 0x36,0x35,0x36,0x2c,0x32,0x32,0x2e,0x32,0x39,0x37, + 0x20,0x37,0x2e,0x34,0x32,0x34,0x2c,0x32,0x32,0x2e, + 0x31,0x35,0x20,0x4c,0x32,0x2e,0x37,0x34,0x2c,0x31, + 0x39,0x2e,0x31,0x34,0x35,0x20,0x43,0x32,0x2e,0x33, + 0x30,0x39,0x2c,0x31,0x38,0x2e,0x38,0x36,0x39,0x20, + 0x32,0x2e,0x33,0x31,0x2c,0x31,0x38,0x2e,0x31,0x35, + 0x39,0x20,0x32,0x2e,0x37,0x34,0x2c,0x31,0x37,0x2e, + 0x38,0x38,0x31,0x20,0x4c,0x37,0x2e,0x34,0x32,0x34, + 0x2c,0x31,0x34,0x2e,0x38,0x37,0x36,0x20,0x43,0x37, + 0x2e,0x36,0x35,0x35,0x2c,0x31,0x34,0x2e,0x37,0x32, + 0x39,0x20,0x37,0x2e,0x39,0x34,0x38,0x2c,0x31,0x34, + 0x2e,0x37,0x31,0x37,0x20,0x38,0x2e,0x31,0x39,0x2c, + 0x31,0x34,0x2e,0x38,0x35,0x20,0x43,0x38,0x2e,0x34, + 0x33,0x2c,0x31,0x34,0x2e,0x39,0x38,0x20,0x38,0x2e, + 0x35,0x38,0x2c,0x31,0x35,0x2e,0x32,0x33,0x32,0x20, + 0x38,0x2e,0x35,0x38,0x2c,0x31,0x35,0x2e,0x35,0x30, + 0x37,0x20,0x7a,0x20,0x4d,0x37,0x2e,0x30,0x38,0x2c, + 0x32,0x30,0x2e,0x31,0x34,0x36,0x20,0x4c,0x37,0x2e, + 0x30,0x38,0x2c,0x31,0x36,0x2e,0x38,0x37,0x38,0x20, + 0x4c,0x34,0x2e,0x35,0x33,0x35,0x2c,0x31,0x38,0x2e, + 0x35,0x31,0x33,0x20,0x4c,0x37,0x2e,0x30,0x38,0x2c, + 0x32,0x30,0x2e,0x31,0x34,0x36,0x20,0x7a,0x22,0x20, + 0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46, + 0x46,0x46,0x46,0x22,0x2f,0x3e,0x0a,0x20,0x20,0x20, + 0x20,0x3c,0x67,0x3e,0x0a,0x20,0x20,0x20,0x20,0x20, + 0x20,0x3c,0x70,0x61,0x74,0x68,0x20,0x64,0x3d,0x22, + 0x4d,0x31,0x38,0x2e,0x34,0x39,0x34,0x2c,0x33,0x33, + 0x2e,0x39,0x31,0x38,0x20,0x4c,0x32,0x31,0x2e,0x34, + 0x39,0x38,0x2c,0x32,0x39,0x2e,0x32,0x33,0x34,0x20, + 0x4c,0x31,0x35,0x2e,0x34,0x38,0x38,0x2c,0x32,0x39, + 0x2e,0x32,0x33,0x34,0x20,0x4c,0x31,0x38,0x2e,0x34, + 0x39,0x34,0x2c,0x33,0x33,0x2e,0x39,0x31,0x38,0x20, + 0x7a,0x22,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23, + 0x46,0x46,0x46,0x46,0x46,0x46,0x22,0x2f,0x3e,0x0a, + 0x20,0x20,0x20,0x20,0x20,0x20,0x3c,0x70,0x61,0x74, + 0x68,0x20,0x64,0x3d,0x22,0x4d,0x32,0x32,0x2e,0x32, + 0x34,0x38,0x2c,0x32,0x39,0x2e,0x32,0x33,0x34,0x20, + 0x43,0x32,0x32,0x2e,0x32,0x34,0x38,0x2c,0x32,0x39, + 0x2e,0x33,0x37,0x35,0x20,0x32,0x32,0x2e,0x32,0x30, + 0x38,0x2c,0x32,0x39,0x2e,0x35,0x31,0x36,0x20,0x32, + 0x32,0x2e,0x31,0x32,0x39,0x2c,0x32,0x39,0x2e,0x36, + 0x33,0x39,0x20,0x4c,0x31,0x39,0x2e,0x31,0x32,0x36, + 0x2c,0x33,0x34,0x2e,0x33,0x32,0x33,0x20,0x43,0x31, + 0x38,0x2e,0x39,0x38,0x38,0x2c,0x33,0x34,0x2e,0x35, + 0x33,0x38,0x20,0x31,0x38,0x2e,0x37,0x35,0x2c,0x33, + 0x34,0x2e,0x36,0x36,0x38,0x20,0x31,0x38,0x2e,0x34, + 0x39,0x35,0x2c,0x33,0x34,0x2e,0x36,0x36,0x38,0x20, + 0x43,0x31,0x38,0x2e,0x32,0x34,0x2c,0x33,0x34,0x2e, + 0x36,0x36,0x38,0x20,0x31,0x38,0x2e,0x30,0x30,0x32, + 0x2c,0x33,0x34,0x2e,0x35,0x33,0x38,0x20,0x31,0x37, + 0x2e,0x38,0x36,0x34,0x2c,0x33,0x34,0x2e,0x33,0x32, + 0x33,0x20,0x4c,0x31,0x34,0x2e,0x38,0x35,0x38,0x2c, + 0x32,0x39,0x2e,0x36,0x33,0x39,0x20,0x43,0x31,0x34, + 0x2e,0x37,0x31,0x2c,0x32,0x39,0x2e,0x34,0x30,0x39, + 0x20,0x31,0x34,0x2e,0x37,0x2c,0x32,0x39,0x2e,0x31, + 0x31,0x35,0x20,0x31,0x34,0x2e,0x38,0x33,0x31,0x2c, + 0x32,0x38,0x2e,0x38,0x37,0x33,0x20,0x43,0x31,0x34, + 0x2e,0x39,0x36,0x32,0x2c,0x32,0x38,0x2e,0x36,0x33, + 0x33,0x20,0x31,0x35,0x2e,0x32,0x31,0x35,0x2c,0x32, + 0x38,0x2e,0x34,0x38,0x33,0x20,0x31,0x35,0x2e,0x34, + 0x38,0x39,0x2c,0x32,0x38,0x2e,0x34,0x38,0x33,0x20, + 0x4c,0x32,0x31,0x2e,0x34,0x39,0x39,0x2c,0x32,0x38, + 0x2e,0x34,0x38,0x33,0x20,0x43,0x32,0x31,0x2e,0x37, + 0x37,0x33,0x2c,0x32,0x38,0x2e,0x34,0x38,0x33,0x20, + 0x32,0x32,0x2e,0x30,0x32,0x35,0x2c,0x32,0x38,0x2e, + 0x36,0x33,0x31,0x20,0x32,0x32,0x2e,0x31,0x35,0x37, + 0x2c,0x32,0x38,0x2e,0x38,0x37,0x33,0x20,0x43,0x32, + 0x32,0x2e,0x32,0x31,0x38,0x2c,0x32,0x38,0x2e,0x39, + 0x38,0x37,0x20,0x32,0x32,0x2e,0x32,0x34,0x38,0x2c, + 0x32,0x39,0x2e,0x31,0x31,0x31,0x20,0x32,0x32,0x2e, + 0x32,0x34,0x38,0x2c,0x32,0x39,0x2e,0x32,0x33,0x34, + 0x20,0x7a,0x20,0x4d,0x31,0x38,0x2e,0x34,0x39,0x34, + 0x2c,0x33,0x32,0x2e,0x35,0x32,0x39,0x20,0x4c,0x32, + 0x30,0x2e,0x31,0x32,0x36,0x2c,0x32,0x39,0x2e,0x39, + 0x38,0x34,0x20,0x4c,0x31,0x36,0x2e,0x38,0x36,0x31, + 0x2c,0x32,0x39,0x2e,0x39,0x38,0x34,0x20,0x4c,0x31, + 0x38,0x2e,0x34,0x39,0x34,0x2c,0x33,0x32,0x2e,0x35, + 0x32,0x39,0x20,0x7a,0x22,0x20,0x66,0x69,0x6c,0x6c, + 0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46,0x46,0x22, + 0x2f,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x2f,0x67, + 0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x70,0x61,0x74, + 0x68,0x20,0x64,0x3d,0x22,0x4d,0x32,0x32,0x2e,0x32, + 0x34,0x38,0x2c,0x37,0x2e,0x38,0x34,0x38,0x20,0x43, + 0x32,0x32,0x2e,0x32,0x34,0x38,0x2c,0x37,0x2e,0x39, + 0x37,0x32,0x20,0x32,0x32,0x2e,0x32,0x31,0x38,0x2c, + 0x38,0x2e,0x30,0x39,0x34,0x20,0x32,0x32,0x2e,0x31, + 0x35,0x36,0x2c,0x38,0x2e,0x32,0x30,0x36,0x20,0x43, + 0x32,0x32,0x2e,0x30,0x32,0x34,0x2c,0x38,0x2e,0x34, + 0x34,0x37,0x20,0x32,0x31,0x2e,0x37,0x37,0x32,0x2c, + 0x38,0x2e,0x35,0x39,0x38,0x20,0x32,0x31,0x2e,0x34, + 0x39,0x38,0x2c,0x38,0x2e,0x35,0x39,0x38,0x20,0x4c, + 0x31,0x35,0x2e,0x34,0x38,0x38,0x2c,0x38,0x2e,0x35, + 0x39,0x38,0x20,0x43,0x31,0x35,0x2e,0x32,0x31,0x34, + 0x2c,0x38,0x2e,0x35,0x39,0x38,0x20,0x31,0x34,0x2e, + 0x39,0x36,0x32,0x2c,0x38,0x2e,0x34,0x34,0x39,0x20, + 0x31,0x34,0x2e,0x38,0x33,0x2c,0x38,0x2e,0x32,0x30, + 0x36,0x20,0x43,0x31,0x34,0x2e,0x36,0x39,0x39,0x2c, + 0x37,0x2e,0x39,0x36,0x37,0x20,0x31,0x34,0x2e,0x37, + 0x30,0x37,0x2c,0x37,0x2e,0x36,0x37,0x33,0x20,0x31, + 0x34,0x2e,0x38,0x35,0x37,0x2c,0x37,0x2e,0x34,0x34, + 0x31,0x20,0x4c,0x31,0x37,0x2e,0x38,0x36,0x32,0x2c, + 0x32,0x2e,0x37,0x35,0x36,0x20,0x43,0x31,0x38,0x2c, + 0x32,0x2e,0x35,0x34,0x31,0x20,0x31,0x38,0x2e,0x32, + 0x33,0x38,0x2c,0x32,0x2e,0x34,0x31,0x31,0x20,0x31, + 0x38,0x2e,0x34,0x39,0x33,0x2c,0x32,0x2e,0x34,0x31, + 0x31,0x20,0x43,0x31,0x38,0x2e,0x37,0x34,0x38,0x2c, + 0x32,0x2e,0x34,0x31,0x31,0x20,0x31,0x38,0x2e,0x39, + 0x38,0x36,0x2c,0x32,0x2e,0x35,0x34,0x31,0x20,0x31, + 0x39,0x2e,0x31,0x32,0x34,0x2c,0x32,0x2e,0x37,0x35, + 0x36,0x20,0x4c,0x32,0x32,0x2e,0x31,0x32,0x38,0x2c, + 0x37,0x2e,0x34,0x34,0x31,0x20,0x43,0x32,0x32,0x2e, + 0x32,0x30,0x38,0x2c,0x37,0x2e,0x35,0x36,0x35,0x20, + 0x32,0x32,0x2e,0x32,0x34,0x38,0x2c,0x37,0x2e,0x37, + 0x30,0x37,0x20,0x32,0x32,0x2e,0x32,0x34,0x38,0x2c, + 0x37,0x2e,0x38,0x34,0x38,0x20,0x7a,0x20,0x4d,0x31, + 0x36,0x2e,0x38,0x36,0x2c,0x37,0x2e,0x30,0x39,0x38, + 0x20,0x4c,0x32,0x30,0x2e,0x31,0x32,0x36,0x2c,0x37, + 0x2e,0x30,0x39,0x38,0x20,0x4c,0x31,0x38,0x2e,0x34, + 0x39,0x33,0x2c,0x34,0x2e,0x35,0x35,0x32,0x20,0x4c, + 0x31,0x36,0x2e,0x38,0x36,0x2c,0x37,0x2e,0x30,0x39, + 0x38,0x20,0x7a,0x22,0x20,0x66,0x69,0x6c,0x6c,0x3d, + 0x22,0x23,0x46,0x46,0x46,0x46,0x46,0x46,0x22,0x2f, + 0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x70,0x61,0x74, + 0x68,0x20,0x64,0x3d,0x22,0x4d,0x33,0x34,0x2e,0x35, + 0x39,0x2c,0x31,0x38,0x2e,0x35,0x31,0x33,0x20,0x4c, + 0x33,0x34,0x2e,0x35,0x39,0x2c,0x31,0x38,0x2e,0x35, + 0x31,0x33,0x20,0x43,0x33,0x34,0x2e,0x35,0x39,0x2c, + 0x31,0x38,0x2e,0x37,0x36,0x38,0x20,0x33,0x34,0x2e, + 0x34,0x36,0x2c,0x31,0x39,0x2e,0x30,0x30,0x35,0x20, + 0x33,0x34,0x2e,0x32,0x34,0x35,0x2c,0x31,0x39,0x2e, + 0x31,0x34,0x34,0x20,0x4c,0x32,0x39,0x2e,0x35,0x36, + 0x31,0x2c,0x32,0x32,0x2e,0x31,0x34,0x39,0x20,0x43, + 0x32,0x39,0x2e,0x33,0x33,0x2c,0x32,0x32,0x2e,0x32, + 0x39,0x36,0x20,0x32,0x39,0x2e,0x30,0x33,0x37,0x2c, + 0x32,0x32,0x2e,0x33,0x30,0x37,0x20,0x32,0x38,0x2e, + 0x37,0x39,0x35,0x2c,0x32,0x32,0x2e,0x31,0x37,0x35, + 0x20,0x43,0x32,0x38,0x2e,0x35,0x35,0x33,0x2c,0x32, + 0x32,0x2e,0x30,0x34,0x33,0x20,0x32,0x38,0x2e,0x34, + 0x30,0x34,0x2c,0x32,0x31,0x2e,0x37,0x39,0x31,0x20, + 0x32,0x38,0x2e,0x34,0x30,0x34,0x2c,0x32,0x31,0x2e, + 0x35,0x31,0x38,0x20,0x4c,0x32,0x38,0x2e,0x34,0x30, + 0x34,0x2c,0x31,0x35,0x2e,0x35,0x30,0x36,0x20,0x43, + 0x32,0x38,0x2e,0x34,0x30,0x34,0x2c,0x31,0x35,0x2e, + 0x32,0x33,0x33,0x20,0x32,0x38,0x2e,0x35,0x35,0x32, + 0x2c,0x31,0x34,0x2e,0x39,0x38,0x31,0x20,0x32,0x38, + 0x2e,0x37,0x39,0x35,0x2c,0x31,0x34,0x2e,0x38,0x34, + 0x39,0x20,0x43,0x32,0x39,0x2e,0x30,0x33,0x35,0x2c, + 0x31,0x34,0x2e,0x37,0x31,0x36,0x20,0x32,0x39,0x2e, + 0x33,0x32,0x38,0x2c,0x31,0x34,0x2e,0x37,0x32,0x38, + 0x20,0x32,0x39,0x2e,0x35,0x36,0x31,0x2c,0x31,0x34, + 0x2e,0x38,0x37,0x35,0x20,0x4c,0x33,0x34,0x2e,0x32, + 0x34,0x35,0x2c,0x31,0x37,0x2e,0x38,0x38,0x20,0x43, + 0x33,0x34,0x2e,0x34,0x36,0x2c,0x31,0x38,0x2e,0x30, + 0x32,0x20,0x33,0x34,0x2e,0x35,0x39,0x2c,0x31,0x38, + 0x2e,0x32,0x35,0x37,0x20,0x33,0x34,0x2e,0x35,0x39, + 0x2c,0x31,0x38,0x2e,0x35,0x31,0x33,0x20,0x7a,0x20, + 0x4d,0x32,0x39,0x2e,0x39,0x30,0x36,0x2c,0x32,0x30, + 0x2e,0x31,0x34,0x36,0x20,0x4c,0x33,0x32,0x2e,0x34, + 0x35,0x31,0x2c,0x31,0x38,0x2e,0x35,0x31,0x33,0x20, + 0x4c,0x32,0x39,0x2e,0x39,0x30,0x36,0x2c,0x31,0x36, + 0x2e,0x38,0x37,0x38,0x20,0x4c,0x32,0x39,0x2e,0x39, + 0x30,0x36,0x2c,0x32,0x30,0x2e,0x31,0x34,0x36,0x20, + 0x7a,0x22,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23, + 0x46,0x46,0x46,0x46,0x46,0x46,0x22,0x2f,0x3e,0x0a, + 0x20,0x20,0x20,0x20,0x3c,0x70,0x61,0x74,0x68,0x20, + 0x64,0x3d,0x22,0x4d,0x31,0x38,0x2e,0x35,0x33,0x2c, + 0x30,0x20,0x43,0x32,0x38,0x2e,0x37,0x36,0x35,0x2c, + 0x30,0x20,0x33,0x37,0x2e,0x30,0x36,0x31,0x2c,0x38, + 0x2e,0x32,0x39,0x36,0x20,0x33,0x37,0x2e,0x30,0x36, + 0x31,0x2c,0x31,0x38,0x2e,0x35,0x33,0x31,0x20,0x43, + 0x33,0x37,0x2e,0x30,0x36,0x31,0x2c,0x32,0x38,0x2e, + 0x37,0x36,0x35,0x20,0x32,0x38,0x2e,0x37,0x36,0x35, + 0x2c,0x33,0x37,0x2e,0x30,0x36,0x31,0x20,0x31,0x38, + 0x2e,0x35,0x33,0x2c,0x33,0x37,0x2e,0x30,0x36,0x31, + 0x20,0x43,0x38,0x2e,0x32,0x39,0x36,0x2c,0x33,0x37, + 0x2e,0x30,0x36,0x31,0x20,0x30,0x2c,0x32,0x38,0x2e, + 0x37,0x36,0x35,0x20,0x30,0x2c,0x31,0x38,0x2e,0x35, + 0x33,0x31,0x20,0x43,0x30,0x2c,0x38,0x2e,0x32,0x39, + 0x36,0x20,0x38,0x2e,0x32,0x39,0x36,0x2c,0x30,0x20, + 0x31,0x38,0x2e,0x35,0x33,0x2c,0x30,0x20,0x7a,0x20, + 0x4d,0x31,0x38,0x2e,0x35,0x33,0x2c,0x31,0x20,0x43, + 0x38,0x2e,0x38,0x34,0x39,0x2c,0x31,0x20,0x31,0x2c, + 0x38,0x2e,0x38,0x34,0x39,0x20,0x31,0x2c,0x31,0x38, + 0x2e,0x35,0x33,0x31,0x20,0x43,0x31,0x2c,0x32,0x38, + 0x2e,0x32,0x31,0x32,0x20,0x38,0x2e,0x38,0x34,0x39, + 0x2c,0x33,0x36,0x2e,0x30,0x36,0x31,0x20,0x31,0x38, + 0x2e,0x35,0x33,0x2c,0x33,0x36,0x2e,0x30,0x36,0x31, + 0x20,0x43,0x32,0x38,0x2e,0x32,0x31,0x32,0x2c,0x33, + 0x36,0x2e,0x30,0x36,0x31,0x20,0x33,0x36,0x2e,0x30, + 0x36,0x31,0x2c,0x32,0x38,0x2e,0x32,0x31,0x32,0x20, + 0x33,0x36,0x2e,0x30,0x36,0x31,0x2c,0x31,0x38,0x2e, + 0x35,0x33,0x31,0x20,0x43,0x33,0x36,0x2e,0x30,0x36, + 0x31,0x2c,0x38,0x2e,0x38,0x34,0x39,0x20,0x32,0x38, + 0x2e,0x32,0x31,0x32,0x2c,0x31,0x20,0x31,0x38,0x2e, + 0x35,0x33,0x2c,0x31,0x20,0x7a,0x22,0x20,0x66,0x69, + 0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46, + 0x46,0x22,0x2f,0x3e,0x0a,0x20,0x20,0x3c,0x2f,0x67, + 0x3e,0x0a,0x3c,0x2f,0x73,0x76,0x67,0x3e,0x0a +}; + diff --git a/data/converted/help_analog_left_svg.cpp b/data/converted/help_analog_left_svg.cpp new file mode 100644 index 0000000000..16f889cf78 --- /dev/null +++ b/data/converted/help_analog_left_svg.cpp @@ -0,0 +1,292 @@ +//this file was auto-generated from "analog_left.svg" by res2h + +#include "../Resources.h" + +const size_t help_analog_left_svg_size = 2834; +const unsigned char help_analog_left_svg_data[2834] = { + 0x3c,0x3f,0x78,0x6d,0x6c,0x20,0x76,0x65,0x72,0x73, + 0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x30,0x22,0x20, + 0x65,0x6e,0x63,0x6f,0x64,0x69,0x6e,0x67,0x3d,0x22, + 0x55,0x54,0x46,0x2d,0x38,0x22,0x3f,0x3e,0x0a,0x3c, + 0x21,0x44,0x4f,0x43,0x54,0x59,0x50,0x45,0x20,0x73, + 0x76,0x67,0x20,0x50,0x55,0x42,0x4c,0x49,0x43,0x20, + 0x22,0x2d,0x2f,0x2f,0x57,0x33,0x43,0x2f,0x2f,0x44, + 0x54,0x44,0x20,0x53,0x56,0x47,0x20,0x31,0x2e,0x31, + 0x2f,0x2f,0x45,0x4e,0x22,0x20,0x22,0x68,0x74,0x74, + 0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33, + 0x2e,0x6f,0x72,0x67,0x2f,0x47,0x72,0x61,0x70,0x68, + 0x69,0x63,0x73,0x2f,0x53,0x56,0x47,0x2f,0x31,0x2e, + 0x31,0x2f,0x44,0x54,0x44,0x2f,0x73,0x76,0x67,0x31, + 0x31,0x2e,0x64,0x74,0x64,0x22,0x3e,0x0a,0x3c,0x73, + 0x76,0x67,0x20,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e, + 0x3d,0x22,0x31,0x2e,0x31,0x22,0x20,0x78,0x6d,0x6c, + 0x6e,0x73,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, + 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, + 0x67,0x2f,0x32,0x30,0x30,0x30,0x2f,0x73,0x76,0x67, + 0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78,0x6c, + 0x69,0x6e,0x6b,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a, + 0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f, + 0x72,0x67,0x2f,0x31,0x39,0x39,0x39,0x2f,0x78,0x6c, + 0x69,0x6e,0x6b,0x22,0x20,0x78,0x3d,0x22,0x30,0x22, + 0x20,0x79,0x3d,0x22,0x30,0x22,0x20,0x77,0x69,0x64, + 0x74,0x68,0x3d,0x22,0x33,0x37,0x2e,0x30,0x36,0x31, + 0x22,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3d,0x22, + 0x33,0x37,0x2e,0x30,0x36,0x31,0x22,0x20,0x76,0x69, + 0x65,0x77,0x42,0x6f,0x78,0x3d,0x22,0x30,0x2c,0x20, + 0x30,0x2c,0x20,0x33,0x37,0x2e,0x30,0x36,0x31,0x2c, + 0x20,0x33,0x37,0x2e,0x30,0x36,0x31,0x22,0x3e,0x0a, + 0x20,0x20,0x3c,0x67,0x20,0x69,0x64,0x3d,0x22,0x45, + 0x62,0x65,0x6e,0x65,0x5f,0x31,0x22,0x3e,0x0a,0x20, + 0x20,0x20,0x20,0x3c,0x67,0x3e,0x0a,0x20,0x20,0x20, + 0x20,0x20,0x20,0x3c,0x70,0x61,0x74,0x68,0x20,0x64, + 0x3d,0x22,0x4d,0x31,0x38,0x2e,0x35,0x33,0x31,0x2c, + 0x32,0x32,0x2e,0x31,0x38,0x31,0x20,0x43,0x31,0x36, + 0x2e,0x35,0x31,0x38,0x2c,0x32,0x32,0x2e,0x31,0x38, + 0x31,0x20,0x31,0x34,0x2e,0x38,0x38,0x32,0x2c,0x32, + 0x30,0x2e,0x35,0x34,0x32,0x20,0x31,0x34,0x2e,0x38, + 0x38,0x32,0x2c,0x31,0x38,0x2e,0x35,0x33,0x20,0x43, + 0x31,0x34,0x2e,0x38,0x38,0x32,0x2c,0x31,0x36,0x2e, + 0x35,0x31,0x38,0x20,0x31,0x36,0x2e,0x35,0x32,0x2c, + 0x31,0x34,0x2e,0x38,0x38,0x20,0x31,0x38,0x2e,0x35, + 0x33,0x31,0x2c,0x31,0x34,0x2e,0x38,0x38,0x20,0x43, + 0x32,0x30,0x2e,0x35,0x34,0x34,0x2c,0x31,0x34,0x2e, + 0x38,0x38,0x20,0x32,0x32,0x2e,0x31,0x38,0x31,0x2c, + 0x31,0x36,0x2e,0x35,0x31,0x39,0x20,0x32,0x32,0x2e, + 0x31,0x38,0x31,0x2c,0x31,0x38,0x2e,0x35,0x33,0x20, + 0x43,0x32,0x32,0x2e,0x31,0x38,0x32,0x2c,0x32,0x30, + 0x2e,0x35,0x34,0x33,0x20,0x32,0x30,0x2e,0x35,0x34, + 0x34,0x2c,0x32,0x32,0x2e,0x31,0x38,0x31,0x20,0x31, + 0x38,0x2e,0x35,0x33,0x31,0x2c,0x32,0x32,0x2e,0x31, + 0x38,0x31,0x20,0x7a,0x20,0x4d,0x31,0x38,0x2e,0x35, + 0x33,0x31,0x2c,0x31,0x36,0x2e,0x33,0x37,0x39,0x20, + 0x43,0x31,0x37,0x2e,0x33,0x34,0x35,0x2c,0x31,0x36, + 0x2e,0x33,0x37,0x39,0x20,0x31,0x36,0x2e,0x33,0x38, + 0x32,0x2c,0x31,0x37,0x2e,0x33,0x34,0x34,0x20,0x31, + 0x36,0x2e,0x33,0x38,0x32,0x2c,0x31,0x38,0x2e,0x35, + 0x32,0x39,0x20,0x43,0x31,0x36,0x2e,0x33,0x38,0x32, + 0x2c,0x31,0x39,0x2e,0x37,0x31,0x34,0x20,0x31,0x37, + 0x2e,0x33,0x34,0x37,0x2c,0x32,0x30,0x2e,0x36,0x38, + 0x20,0x31,0x38,0x2e,0x35,0x33,0x31,0x2c,0x32,0x30, + 0x2e,0x36,0x38,0x20,0x43,0x31,0x39,0x2e,0x37,0x31, + 0x37,0x2c,0x32,0x30,0x2e,0x36,0x38,0x20,0x32,0x30, + 0x2e,0x36,0x38,0x31,0x2c,0x31,0x39,0x2e,0x37,0x31, + 0x34,0x20,0x32,0x30,0x2e,0x36,0x38,0x31,0x2c,0x31, + 0x38,0x2e,0x35,0x32,0x39,0x20,0x43,0x32,0x30,0x2e, + 0x36,0x38,0x32,0x2c,0x31,0x37,0x2e,0x33,0x34,0x34, + 0x20,0x31,0x39,0x2e,0x37,0x31,0x37,0x2c,0x31,0x36, + 0x2e,0x33,0x37,0x39,0x20,0x31,0x38,0x2e,0x35,0x33, + 0x31,0x2c,0x31,0x36,0x2e,0x33,0x37,0x39,0x20,0x7a, + 0x22,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46, + 0x46,0x46,0x46,0x46,0x46,0x22,0x2f,0x3e,0x0a,0x20, + 0x20,0x20,0x20,0x20,0x20,0x3c,0x70,0x61,0x74,0x68, + 0x20,0x64,0x3d,0x22,0x4d,0x32,0x31,0x2e,0x35,0x33, + 0x36,0x2c,0x38,0x2e,0x36,0x31,0x36,0x20,0x4c,0x31, + 0x35,0x2e,0x35,0x32,0x34,0x2c,0x38,0x2e,0x36,0x31, + 0x36,0x20,0x43,0x31,0x35,0x2e,0x32,0x35,0x31,0x2c, + 0x38,0x2e,0x36,0x31,0x36,0x20,0x31,0x34,0x2e,0x39, + 0x39,0x39,0x2c,0x38,0x2e,0x34,0x36,0x36,0x20,0x31, + 0x34,0x2e,0x38,0x36,0x37,0x2c,0x38,0x2e,0x32,0x32, + 0x36,0x20,0x43,0x31,0x34,0x2e,0x37,0x33,0x35,0x2c, + 0x37,0x2e,0x39,0x38,0x35,0x20,0x31,0x34,0x2e,0x37, + 0x34,0x36,0x2c,0x37,0x2e,0x36,0x39,0x32,0x20,0x31, + 0x34,0x2e,0x38,0x39,0x33,0x2c,0x37,0x2e,0x34,0x36, + 0x20,0x4c,0x31,0x37,0x2e,0x38,0x39,0x38,0x2c,0x32, + 0x2e,0x37,0x37,0x36,0x20,0x43,0x31,0x38,0x2e,0x31, + 0x37,0x34,0x2c,0x32,0x2e,0x33,0x34,0x35,0x20,0x31, + 0x38,0x2e,0x38,0x38,0x34,0x2c,0x32,0x2e,0x33,0x34, + 0x36,0x20,0x31,0x39,0x2e,0x31,0x36,0x32,0x2c,0x32, + 0x2e,0x37,0x37,0x36,0x20,0x4c,0x32,0x32,0x2e,0x31, + 0x36,0x37,0x2c,0x37,0x2e,0x34,0x36,0x20,0x43,0x32, + 0x32,0x2e,0x33,0x31,0x34,0x2c,0x37,0x2e,0x36,0x39, + 0x31,0x20,0x32,0x32,0x2e,0x33,0x32,0x36,0x2c,0x37, + 0x2e,0x39,0x38,0x34,0x20,0x32,0x32,0x2e,0x31,0x39, + 0x33,0x2c,0x38,0x2e,0x32,0x32,0x36,0x20,0x43,0x32, + 0x32,0x2e,0x30,0x36,0x33,0x2c,0x38,0x2e,0x34,0x36, + 0x36,0x20,0x32,0x31,0x2e,0x38,0x31,0x31,0x2c,0x38, + 0x2e,0x36,0x31,0x36,0x20,0x32,0x31,0x2e,0x35,0x33, + 0x36,0x2c,0x38,0x2e,0x36,0x31,0x36,0x20,0x7a,0x20, + 0x4d,0x31,0x36,0x2e,0x38,0x39,0x37,0x2c,0x37,0x2e, + 0x31,0x31,0x36,0x20,0x4c,0x32,0x30,0x2e,0x31,0x36, + 0x35,0x2c,0x37,0x2e,0x31,0x31,0x36,0x20,0x4c,0x31, + 0x38,0x2e,0x35,0x33,0x2c,0x34,0x2e,0x35,0x37,0x31, + 0x20,0x4c,0x31,0x36,0x2e,0x38,0x39,0x37,0x2c,0x37, + 0x2e,0x31,0x31,0x36,0x20,0x7a,0x22,0x20,0x66,0x69, + 0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46, + 0x46,0x22,0x2f,0x3e,0x0a,0x20,0x20,0x20,0x20,0x20, + 0x20,0x3c,0x67,0x3e,0x0a,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x3c,0x70,0x61,0x74,0x68,0x20,0x64, + 0x3d,0x22,0x4d,0x33,0x2e,0x31,0x32,0x35,0x2c,0x31, + 0x38,0x2e,0x35,0x33,0x20,0x4c,0x37,0x2e,0x38,0x30, + 0x39,0x2c,0x32,0x31,0x2e,0x35,0x33,0x34,0x20,0x4c, + 0x37,0x2e,0x38,0x30,0x39,0x2c,0x31,0x35,0x2e,0x35, + 0x32,0x34,0x20,0x4c,0x33,0x2e,0x31,0x32,0x35,0x2c, + 0x31,0x38,0x2e,0x35,0x33,0x20,0x7a,0x22,0x20,0x66, + 0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46, + 0x46,0x46,0x22,0x2f,0x3e,0x0a,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x3c,0x70,0x61,0x74,0x68,0x20, + 0x64,0x3d,0x22,0x4d,0x37,0x2e,0x38,0x30,0x39,0x2c, + 0x32,0x32,0x2e,0x32,0x38,0x34,0x20,0x43,0x37,0x2e, + 0x36,0x36,0x38,0x2c,0x32,0x32,0x2e,0x32,0x38,0x34, + 0x20,0x37,0x2e,0x35,0x32,0x37,0x2c,0x32,0x32,0x2e, + 0x32,0x34,0x34,0x20,0x37,0x2e,0x34,0x30,0x34,0x2c, + 0x32,0x32,0x2e,0x31,0x36,0x35,0x20,0x4c,0x32,0x2e, + 0x37,0x32,0x2c,0x31,0x39,0x2e,0x31,0x36,0x32,0x20, + 0x43,0x32,0x2e,0x35,0x30,0x35,0x2c,0x31,0x39,0x2e, + 0x30,0x32,0x34,0x20,0x32,0x2e,0x33,0x37,0x35,0x2c, + 0x31,0x38,0x2e,0x37,0x38,0x36,0x20,0x32,0x2e,0x33, + 0x37,0x35,0x2c,0x31,0x38,0x2e,0x35,0x33,0x31,0x20, + 0x43,0x32,0x2e,0x33,0x37,0x35,0x2c,0x31,0x38,0x2e, + 0x32,0x37,0x36,0x20,0x32,0x2e,0x35,0x30,0x35,0x2c, + 0x31,0x38,0x2e,0x30,0x33,0x38,0x20,0x32,0x2e,0x37, + 0x32,0x2c,0x31,0x37,0x2e,0x39,0x20,0x4c,0x37,0x2e, + 0x34,0x30,0x34,0x2c,0x31,0x34,0x2e,0x38,0x39,0x34, + 0x20,0x43,0x37,0x2e,0x36,0x33,0x34,0x2c,0x31,0x34, + 0x2e,0x37,0x34,0x36,0x20,0x37,0x2e,0x39,0x32,0x38, + 0x2c,0x31,0x34,0x2e,0x37,0x33,0x36,0x20,0x38,0x2e, + 0x31,0x37,0x2c,0x31,0x34,0x2e,0x38,0x36,0x37,0x20, + 0x43,0x38,0x2e,0x34,0x31,0x2c,0x31,0x34,0x2e,0x39, + 0x39,0x38,0x20,0x38,0x2e,0x35,0x36,0x2c,0x31,0x35, + 0x2e,0x32,0x35,0x31,0x20,0x38,0x2e,0x35,0x36,0x2c, + 0x31,0x35,0x2e,0x35,0x32,0x35,0x20,0x4c,0x38,0x2e, + 0x35,0x36,0x2c,0x32,0x31,0x2e,0x35,0x33,0x35,0x20, + 0x43,0x38,0x2e,0x35,0x36,0x2c,0x32,0x31,0x2e,0x38, + 0x30,0x39,0x20,0x38,0x2e,0x34,0x31,0x32,0x2c,0x32, + 0x32,0x2e,0x30,0x36,0x31,0x20,0x38,0x2e,0x31,0x37, + 0x2c,0x32,0x32,0x2e,0x31,0x39,0x33,0x20,0x43,0x38, + 0x2e,0x30,0x35,0x36,0x2c,0x32,0x32,0x2e,0x32,0x35, + 0x34,0x20,0x37,0x2e,0x39,0x33,0x32,0x2c,0x32,0x32, + 0x2e,0x32,0x38,0x34,0x20,0x37,0x2e,0x38,0x30,0x39, + 0x2c,0x32,0x32,0x2e,0x32,0x38,0x34,0x20,0x7a,0x20, + 0x4d,0x34,0x2e,0x35,0x31,0x34,0x2c,0x31,0x38,0x2e, + 0x35,0x33,0x20,0x4c,0x37,0x2e,0x30,0x35,0x39,0x2c, + 0x32,0x30,0x2e,0x31,0x36,0x32,0x20,0x4c,0x37,0x2e, + 0x30,0x35,0x39,0x2c,0x31,0x36,0x2e,0x38,0x39,0x37, + 0x20,0x4c,0x34,0x2e,0x35,0x31,0x34,0x2c,0x31,0x38, + 0x2e,0x35,0x33,0x20,0x7a,0x22,0x20,0x66,0x69,0x6c, + 0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46,0x46, + 0x22,0x2f,0x3e,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, + 0x3c,0x2f,0x67,0x3e,0x0a,0x20,0x20,0x20,0x20,0x20, + 0x20,0x3c,0x70,0x61,0x74,0x68,0x20,0x64,0x3d,0x22, + 0x4d,0x32,0x39,0x2e,0x31,0x39,0x35,0x2c,0x32,0x32, + 0x2e,0x32,0x38,0x34,0x20,0x43,0x32,0x39,0x2e,0x30, + 0x37,0x31,0x2c,0x32,0x32,0x2e,0x32,0x38,0x34,0x20, + 0x32,0x38,0x2e,0x39,0x34,0x39,0x2c,0x32,0x32,0x2e, + 0x32,0x35,0x34,0x20,0x32,0x38,0x2e,0x38,0x33,0x37, + 0x2c,0x32,0x32,0x2e,0x31,0x39,0x32,0x20,0x43,0x32, + 0x38,0x2e,0x35,0x39,0x36,0x2c,0x32,0x32,0x2e,0x30, + 0x36,0x20,0x32,0x38,0x2e,0x34,0x34,0x35,0x2c,0x32, + 0x31,0x2e,0x38,0x30,0x38,0x20,0x32,0x38,0x2e,0x34, + 0x34,0x35,0x2c,0x32,0x31,0x2e,0x35,0x33,0x34,0x20, + 0x4c,0x32,0x38,0x2e,0x34,0x34,0x35,0x2c,0x31,0x35, + 0x2e,0x35,0x32,0x34,0x20,0x43,0x32,0x38,0x2e,0x34, + 0x34,0x35,0x2c,0x31,0x35,0x2e,0x32,0x35,0x20,0x32, + 0x38,0x2e,0x35,0x39,0x34,0x2c,0x31,0x34,0x2e,0x39, + 0x39,0x38,0x20,0x32,0x38,0x2e,0x38,0x33,0x37,0x2c, + 0x31,0x34,0x2e,0x38,0x36,0x36,0x20,0x43,0x32,0x39, + 0x2e,0x30,0x37,0x36,0x2c,0x31,0x34,0x2e,0x37,0x33, + 0x35,0x20,0x32,0x39,0x2e,0x33,0x37,0x2c,0x31,0x34, + 0x2e,0x37,0x34,0x33,0x20,0x32,0x39,0x2e,0x36,0x30, + 0x32,0x2c,0x31,0x34,0x2e,0x38,0x39,0x33,0x20,0x4c, + 0x33,0x34,0x2e,0x32,0x38,0x37,0x2c,0x31,0x37,0x2e, + 0x38,0x39,0x38,0x20,0x43,0x33,0x34,0x2e,0x35,0x30, + 0x32,0x2c,0x31,0x38,0x2e,0x30,0x33,0x36,0x20,0x33, + 0x34,0x2e,0x36,0x33,0x32,0x2c,0x31,0x38,0x2e,0x32, + 0x37,0x34,0x20,0x33,0x34,0x2e,0x36,0x33,0x32,0x2c, + 0x31,0x38,0x2e,0x35,0x32,0x39,0x20,0x43,0x33,0x34, + 0x2e,0x36,0x33,0x32,0x2c,0x31,0x38,0x2e,0x37,0x38, + 0x34,0x20,0x33,0x34,0x2e,0x35,0x30,0x32,0x2c,0x31, + 0x39,0x2e,0x30,0x32,0x32,0x20,0x33,0x34,0x2e,0x32, + 0x38,0x37,0x2c,0x31,0x39,0x2e,0x31,0x36,0x20,0x4c, + 0x32,0x39,0x2e,0x36,0x30,0x32,0x2c,0x32,0x32,0x2e, + 0x31,0x36,0x34,0x20,0x43,0x32,0x39,0x2e,0x34,0x37, + 0x38,0x2c,0x32,0x32,0x2e,0x32,0x34,0x34,0x20,0x32, + 0x39,0x2e,0x33,0x33,0x36,0x2c,0x32,0x32,0x2e,0x32, + 0x38,0x34,0x20,0x32,0x39,0x2e,0x31,0x39,0x35,0x2c, + 0x32,0x32,0x2e,0x32,0x38,0x34,0x20,0x7a,0x20,0x4d, + 0x32,0x39,0x2e,0x39,0x34,0x35,0x2c,0x31,0x36,0x2e, + 0x38,0x39,0x36,0x20,0x4c,0x32,0x39,0x2e,0x39,0x34, + 0x35,0x2c,0x32,0x30,0x2e,0x31,0x36,0x32,0x20,0x4c, + 0x33,0x32,0x2e,0x34,0x39,0x31,0x2c,0x31,0x38,0x2e, + 0x35,0x32,0x39,0x20,0x4c,0x32,0x39,0x2e,0x39,0x34, + 0x35,0x2c,0x31,0x36,0x2e,0x38,0x39,0x36,0x20,0x7a, + 0x22,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46, + 0x46,0x46,0x46,0x46,0x46,0x22,0x2f,0x3e,0x0a,0x20, + 0x20,0x20,0x20,0x20,0x20,0x3c,0x70,0x61,0x74,0x68, + 0x20,0x64,0x3d,0x22,0x4d,0x31,0x38,0x2e,0x35,0x33, + 0x2c,0x33,0x34,0x2e,0x36,0x32,0x36,0x20,0x4c,0x31, + 0x38,0x2e,0x35,0x33,0x2c,0x33,0x34,0x2e,0x36,0x32, + 0x36,0x20,0x43,0x31,0x38,0x2e,0x32,0x37,0x35,0x2c, + 0x33,0x34,0x2e,0x36,0x32,0x36,0x20,0x31,0x38,0x2e, + 0x30,0x33,0x38,0x2c,0x33,0x34,0x2e,0x34,0x39,0x36, + 0x20,0x31,0x37,0x2e,0x38,0x39,0x39,0x2c,0x33,0x34, + 0x2e,0x32,0x38,0x31,0x20,0x4c,0x31,0x34,0x2e,0x38, + 0x39,0x34,0x2c,0x32,0x39,0x2e,0x35,0x39,0x37,0x20, + 0x43,0x31,0x34,0x2e,0x37,0x34,0x37,0x2c,0x32,0x39, + 0x2e,0x33,0x36,0x36,0x20,0x31,0x34,0x2e,0x37,0x33, + 0x36,0x2c,0x32,0x39,0x2e,0x30,0x37,0x33,0x20,0x31, + 0x34,0x2e,0x38,0x36,0x38,0x2c,0x32,0x38,0x2e,0x38, + 0x33,0x31,0x20,0x43,0x31,0x35,0x2c,0x32,0x38,0x2e, + 0x35,0x38,0x39,0x20,0x31,0x35,0x2e,0x32,0x35,0x32, + 0x2c,0x32,0x38,0x2e,0x34,0x34,0x20,0x31,0x35,0x2e, + 0x35,0x32,0x35,0x2c,0x32,0x38,0x2e,0x34,0x34,0x20, + 0x4c,0x32,0x31,0x2e,0x35,0x33,0x37,0x2c,0x32,0x38, + 0x2e,0x34,0x34,0x20,0x43,0x32,0x31,0x2e,0x38,0x31, + 0x2c,0x32,0x38,0x2e,0x34,0x34,0x20,0x32,0x32,0x2e, + 0x30,0x36,0x32,0x2c,0x32,0x38,0x2e,0x35,0x38,0x38, + 0x20,0x32,0x32,0x2e,0x31,0x39,0x34,0x2c,0x32,0x38, + 0x2e,0x38,0x33,0x31,0x20,0x43,0x32,0x32,0x2e,0x33, + 0x32,0x37,0x2c,0x32,0x39,0x2e,0x30,0x37,0x31,0x20, + 0x32,0x32,0x2e,0x33,0x31,0x35,0x2c,0x32,0x39,0x2e, + 0x33,0x36,0x34,0x20,0x32,0x32,0x2e,0x31,0x36,0x38, + 0x2c,0x32,0x39,0x2e,0x35,0x39,0x37,0x20,0x4c,0x31, + 0x39,0x2e,0x31,0x36,0x33,0x2c,0x33,0x34,0x2e,0x32, + 0x38,0x31,0x20,0x43,0x31,0x39,0x2e,0x30,0x32,0x33, + 0x2c,0x33,0x34,0x2e,0x34,0x39,0x36,0x20,0x31,0x38, + 0x2e,0x37,0x38,0x36,0x2c,0x33,0x34,0x2e,0x36,0x32, + 0x36,0x20,0x31,0x38,0x2e,0x35,0x33,0x2c,0x33,0x34, + 0x2e,0x36,0x32,0x36,0x20,0x7a,0x20,0x4d,0x31,0x36, + 0x2e,0x38,0x39,0x37,0x2c,0x32,0x39,0x2e,0x39,0x34, + 0x32,0x20,0x4c,0x31,0x38,0x2e,0x35,0x33,0x2c,0x33, + 0x32,0x2e,0x34,0x38,0x37,0x20,0x4c,0x32,0x30,0x2e, + 0x31,0x36,0x35,0x2c,0x32,0x39,0x2e,0x39,0x34,0x32, + 0x20,0x4c,0x31,0x36,0x2e,0x38,0x39,0x37,0x2c,0x32, + 0x39,0x2e,0x39,0x34,0x32,0x20,0x7a,0x22,0x20,0x66, + 0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46, + 0x46,0x46,0x22,0x2f,0x3e,0x0a,0x20,0x20,0x20,0x20, + 0x3c,0x2f,0x67,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c, + 0x70,0x61,0x74,0x68,0x20,0x64,0x3d,0x22,0x4d,0x31, + 0x38,0x2e,0x35,0x33,0x2c,0x30,0x20,0x43,0x32,0x38, + 0x2e,0x37,0x36,0x35,0x2c,0x30,0x20,0x33,0x37,0x2e, + 0x30,0x36,0x31,0x2c,0x38,0x2e,0x32,0x39,0x36,0x20, + 0x33,0x37,0x2e,0x30,0x36,0x31,0x2c,0x31,0x38,0x2e, + 0x35,0x33,0x31,0x20,0x43,0x33,0x37,0x2e,0x30,0x36, + 0x31,0x2c,0x32,0x38,0x2e,0x37,0x36,0x35,0x20,0x32, + 0x38,0x2e,0x37,0x36,0x35,0x2c,0x33,0x37,0x2e,0x30, + 0x36,0x31,0x20,0x31,0x38,0x2e,0x35,0x33,0x2c,0x33, + 0x37,0x2e,0x30,0x36,0x31,0x20,0x43,0x38,0x2e,0x32, + 0x39,0x36,0x2c,0x33,0x37,0x2e,0x30,0x36,0x31,0x20, + 0x30,0x2c,0x32,0x38,0x2e,0x37,0x36,0x35,0x20,0x30, + 0x2c,0x31,0x38,0x2e,0x35,0x33,0x31,0x20,0x43,0x30, + 0x2c,0x38,0x2e,0x32,0x39,0x36,0x20,0x38,0x2e,0x32, + 0x39,0x36,0x2c,0x30,0x20,0x31,0x38,0x2e,0x35,0x33, + 0x2c,0x30,0x20,0x7a,0x20,0x4d,0x31,0x38,0x2e,0x35, + 0x33,0x2c,0x31,0x20,0x43,0x38,0x2e,0x38,0x34,0x39, + 0x2c,0x31,0x20,0x31,0x2c,0x38,0x2e,0x38,0x34,0x39, + 0x20,0x31,0x2c,0x31,0x38,0x2e,0x35,0x33,0x31,0x20, + 0x43,0x31,0x2c,0x32,0x38,0x2e,0x32,0x31,0x32,0x20, + 0x38,0x2e,0x38,0x34,0x39,0x2c,0x33,0x36,0x2e,0x30, + 0x36,0x31,0x20,0x31,0x38,0x2e,0x35,0x33,0x2c,0x33, + 0x36,0x2e,0x30,0x36,0x31,0x20,0x43,0x32,0x38,0x2e, + 0x32,0x31,0x32,0x2c,0x33,0x36,0x2e,0x30,0x36,0x31, + 0x20,0x33,0x36,0x2e,0x30,0x36,0x31,0x2c,0x32,0x38, + 0x2e,0x32,0x31,0x32,0x20,0x33,0x36,0x2e,0x30,0x36, + 0x31,0x2c,0x31,0x38,0x2e,0x35,0x33,0x31,0x20,0x43, + 0x33,0x36,0x2e,0x30,0x36,0x31,0x2c,0x38,0x2e,0x38, + 0x34,0x39,0x20,0x32,0x38,0x2e,0x32,0x31,0x32,0x2c, + 0x31,0x20,0x31,0x38,0x2e,0x35,0x33,0x2c,0x31,0x20, + 0x7a,0x22,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23, + 0x46,0x46,0x46,0x46,0x46,0x46,0x22,0x2f,0x3e,0x0a, + 0x20,0x20,0x3c,0x2f,0x67,0x3e,0x0a,0x3c,0x2f,0x73, + 0x76,0x67,0x3e,0x0a +}; + diff --git a/data/converted/help_analog_right_svg.cpp b/data/converted/help_analog_right_svg.cpp new file mode 100644 index 0000000000..2f66a33acc --- /dev/null +++ b/data/converted/help_analog_right_svg.cpp @@ -0,0 +1,290 @@ +//this file was auto-generated from "analog_right.svg" by res2h + +#include "../Resources.h" + +const size_t help_analog_right_svg_size = 2813; +const unsigned char help_analog_right_svg_data[2813] = { + 0x3c,0x3f,0x78,0x6d,0x6c,0x20,0x76,0x65,0x72,0x73, + 0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x30,0x22,0x20, + 0x65,0x6e,0x63,0x6f,0x64,0x69,0x6e,0x67,0x3d,0x22, + 0x55,0x54,0x46,0x2d,0x38,0x22,0x3f,0x3e,0x0a,0x3c, + 0x21,0x44,0x4f,0x43,0x54,0x59,0x50,0x45,0x20,0x73, + 0x76,0x67,0x20,0x50,0x55,0x42,0x4c,0x49,0x43,0x20, + 0x22,0x2d,0x2f,0x2f,0x57,0x33,0x43,0x2f,0x2f,0x44, + 0x54,0x44,0x20,0x53,0x56,0x47,0x20,0x31,0x2e,0x31, + 0x2f,0x2f,0x45,0x4e,0x22,0x20,0x22,0x68,0x74,0x74, + 0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33, + 0x2e,0x6f,0x72,0x67,0x2f,0x47,0x72,0x61,0x70,0x68, + 0x69,0x63,0x73,0x2f,0x53,0x56,0x47,0x2f,0x31,0x2e, + 0x31,0x2f,0x44,0x54,0x44,0x2f,0x73,0x76,0x67,0x31, + 0x31,0x2e,0x64,0x74,0x64,0x22,0x3e,0x0a,0x3c,0x73, + 0x76,0x67,0x20,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e, + 0x3d,0x22,0x31,0x2e,0x31,0x22,0x20,0x78,0x6d,0x6c, + 0x6e,0x73,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, + 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, + 0x67,0x2f,0x32,0x30,0x30,0x30,0x2f,0x73,0x76,0x67, + 0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78,0x6c, + 0x69,0x6e,0x6b,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a, + 0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f, + 0x72,0x67,0x2f,0x31,0x39,0x39,0x39,0x2f,0x78,0x6c, + 0x69,0x6e,0x6b,0x22,0x20,0x78,0x3d,0x22,0x30,0x22, + 0x20,0x79,0x3d,0x22,0x30,0x22,0x20,0x77,0x69,0x64, + 0x74,0x68,0x3d,0x22,0x33,0x37,0x2e,0x30,0x36,0x31, + 0x22,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3d,0x22, + 0x33,0x37,0x2e,0x30,0x36,0x31,0x22,0x20,0x76,0x69, + 0x65,0x77,0x42,0x6f,0x78,0x3d,0x22,0x30,0x2c,0x20, + 0x30,0x2c,0x20,0x33,0x37,0x2e,0x30,0x36,0x31,0x2c, + 0x20,0x33,0x37,0x2e,0x30,0x36,0x31,0x22,0x3e,0x0a, + 0x20,0x20,0x3c,0x67,0x20,0x69,0x64,0x3d,0x22,0x45, + 0x62,0x65,0x6e,0x65,0x5f,0x31,0x22,0x3e,0x0a,0x20, + 0x20,0x20,0x20,0x3c,0x70,0x61,0x74,0x68,0x20,0x64, + 0x3d,0x22,0x4d,0x31,0x38,0x2e,0x34,0x37,0x36,0x2c, + 0x31,0x34,0x2e,0x38,0x39,0x38,0x20,0x43,0x32,0x30, + 0x2e,0x34,0x38,0x39,0x2c,0x31,0x34,0x2e,0x38,0x39, + 0x38,0x20,0x32,0x32,0x2e,0x31,0x32,0x35,0x2c,0x31, + 0x36,0x2e,0x35,0x33,0x37,0x20,0x32,0x32,0x2e,0x31, + 0x32,0x35,0x2c,0x31,0x38,0x2e,0x35,0x34,0x39,0x20, + 0x43,0x32,0x32,0x2e,0x31,0x32,0x35,0x2c,0x32,0x30, + 0x2e,0x35,0x36,0x31,0x20,0x32,0x30,0x2e,0x34,0x38, + 0x37,0x2c,0x32,0x32,0x2e,0x31,0x39,0x39,0x20,0x31, + 0x38,0x2e,0x34,0x37,0x36,0x2c,0x32,0x32,0x2e,0x31, + 0x39,0x39,0x20,0x43,0x31,0x36,0x2e,0x34,0x36,0x33, + 0x2c,0x32,0x32,0x2e,0x31,0x39,0x39,0x20,0x31,0x34, + 0x2e,0x38,0x32,0x36,0x2c,0x32,0x30,0x2e,0x35,0x36, + 0x20,0x31,0x34,0x2e,0x38,0x32,0x36,0x2c,0x31,0x38, + 0x2e,0x35,0x34,0x39,0x20,0x43,0x31,0x34,0x2e,0x38, + 0x32,0x35,0x2c,0x31,0x36,0x2e,0x35,0x33,0x36,0x20, + 0x31,0x36,0x2e,0x34,0x36,0x33,0x2c,0x31,0x34,0x2e, + 0x38,0x39,0x38,0x20,0x31,0x38,0x2e,0x34,0x37,0x36, + 0x2c,0x31,0x34,0x2e,0x38,0x39,0x38,0x20,0x7a,0x20, + 0x4d,0x31,0x38,0x2e,0x34,0x37,0x36,0x2c,0x32,0x30, + 0x2e,0x37,0x20,0x43,0x31,0x39,0x2e,0x36,0x36,0x32, + 0x2c,0x32,0x30,0x2e,0x37,0x20,0x32,0x30,0x2e,0x36, + 0x32,0x35,0x2c,0x31,0x39,0x2e,0x37,0x33,0x35,0x20, + 0x32,0x30,0x2e,0x36,0x32,0x35,0x2c,0x31,0x38,0x2e, + 0x35,0x35,0x20,0x43,0x32,0x30,0x2e,0x36,0x32,0x35, + 0x2c,0x31,0x37,0x2e,0x33,0x36,0x35,0x20,0x31,0x39, + 0x2e,0x36,0x36,0x2c,0x31,0x36,0x2e,0x33,0x39,0x39, + 0x20,0x31,0x38,0x2e,0x34,0x37,0x36,0x2c,0x31,0x36, + 0x2e,0x33,0x39,0x39,0x20,0x43,0x31,0x37,0x2e,0x32, + 0x39,0x2c,0x31,0x36,0x2e,0x33,0x39,0x39,0x20,0x31, + 0x36,0x2e,0x33,0x32,0x36,0x2c,0x31,0x37,0x2e,0x33, + 0x36,0x35,0x20,0x31,0x36,0x2e,0x33,0x32,0x36,0x2c, + 0x31,0x38,0x2e,0x35,0x35,0x20,0x43,0x31,0x36,0x2e, + 0x33,0x32,0x35,0x2c,0x31,0x39,0x2e,0x37,0x33,0x35, + 0x20,0x31,0x37,0x2e,0x32,0x39,0x2c,0x32,0x30,0x2e, + 0x37,0x20,0x31,0x38,0x2e,0x34,0x37,0x36,0x2c,0x32, + 0x30,0x2e,0x37,0x20,0x7a,0x22,0x20,0x66,0x69,0x6c, + 0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46,0x46, + 0x22,0x2f,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x70, + 0x61,0x74,0x68,0x20,0x64,0x3d,0x22,0x4d,0x31,0x35, + 0x2e,0x34,0x37,0x31,0x2c,0x32,0x38,0x2e,0x34,0x36, + 0x33,0x20,0x4c,0x32,0x31,0x2e,0x34,0x38,0x33,0x2c, + 0x32,0x38,0x2e,0x34,0x36,0x33,0x20,0x43,0x32,0x31, + 0x2e,0x37,0x35,0x36,0x2c,0x32,0x38,0x2e,0x34,0x36, + 0x33,0x20,0x32,0x32,0x2e,0x30,0x30,0x38,0x2c,0x32, + 0x38,0x2e,0x36,0x31,0x33,0x20,0x32,0x32,0x2e,0x31, + 0x34,0x2c,0x32,0x38,0x2e,0x38,0x35,0x33,0x20,0x43, + 0x32,0x32,0x2e,0x32,0x37,0x32,0x2c,0x32,0x39,0x2e, + 0x30,0x39,0x34,0x20,0x32,0x32,0x2e,0x32,0x36,0x31, + 0x2c,0x32,0x39,0x2e,0x33,0x38,0x37,0x20,0x32,0x32, + 0x2e,0x31,0x31,0x34,0x2c,0x32,0x39,0x2e,0x36,0x31, + 0x39,0x20,0x4c,0x31,0x39,0x2e,0x31,0x30,0x39,0x2c, + 0x33,0x34,0x2e,0x33,0x30,0x33,0x20,0x43,0x31,0x38, + 0x2e,0x38,0x33,0x33,0x2c,0x33,0x34,0x2e,0x37,0x33, + 0x34,0x20,0x31,0x38,0x2e,0x31,0x32,0x33,0x2c,0x33, + 0x34,0x2e,0x37,0x33,0x33,0x20,0x31,0x37,0x2e,0x38, + 0x34,0x35,0x2c,0x33,0x34,0x2e,0x33,0x30,0x33,0x20, + 0x4c,0x31,0x34,0x2e,0x38,0x34,0x2c,0x32,0x39,0x2e, + 0x36,0x31,0x39,0x20,0x43,0x31,0x34,0x2e,0x36,0x39, + 0x33,0x2c,0x32,0x39,0x2e,0x33,0x38,0x38,0x20,0x31, + 0x34,0x2e,0x36,0x38,0x31,0x2c,0x32,0x39,0x2e,0x30, + 0x39,0x35,0x20,0x31,0x34,0x2e,0x38,0x31,0x34,0x2c, + 0x32,0x38,0x2e,0x38,0x35,0x33,0x20,0x43,0x31,0x34, + 0x2e,0x39,0x34,0x34,0x2c,0x32,0x38,0x2e,0x36,0x31, + 0x33,0x20,0x31,0x35,0x2e,0x31,0x39,0x36,0x2c,0x32, + 0x38,0x2e,0x34,0x36,0x33,0x20,0x31,0x35,0x2e,0x34, + 0x37,0x31,0x2c,0x32,0x38,0x2e,0x34,0x36,0x33,0x20, + 0x7a,0x20,0x4d,0x32,0x30,0x2e,0x31,0x31,0x2c,0x32, + 0x39,0x2e,0x39,0x36,0x33,0x20,0x4c,0x31,0x36,0x2e, + 0x38,0x34,0x32,0x2c,0x32,0x39,0x2e,0x39,0x36,0x33, + 0x20,0x4c,0x31,0x38,0x2e,0x34,0x37,0x37,0x2c,0x33, + 0x32,0x2e,0x35,0x30,0x38,0x20,0x4c,0x32,0x30,0x2e, + 0x31,0x31,0x2c,0x32,0x39,0x2e,0x39,0x36,0x33,0x20, + 0x7a,0x22,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23, + 0x46,0x46,0x46,0x46,0x46,0x46,0x22,0x2f,0x3e,0x0a, + 0x20,0x20,0x20,0x20,0x3c,0x67,0x3e,0x0a,0x20,0x20, + 0x20,0x20,0x20,0x20,0x3c,0x70,0x61,0x74,0x68,0x20, + 0x64,0x3d,0x22,0x4d,0x33,0x33,0x2e,0x38,0x38,0x32, + 0x2c,0x31,0x38,0x2e,0x35,0x34,0x39,0x20,0x4c,0x32, + 0x39,0x2e,0x31,0x39,0x38,0x2c,0x31,0x35,0x2e,0x35, + 0x34,0x35,0x20,0x4c,0x32,0x39,0x2e,0x31,0x39,0x38, + 0x2c,0x32,0x31,0x2e,0x35,0x35,0x35,0x20,0x4c,0x33, + 0x33,0x2e,0x38,0x38,0x32,0x2c,0x31,0x38,0x2e,0x35, + 0x34,0x39,0x20,0x7a,0x22,0x20,0x66,0x69,0x6c,0x6c, + 0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46,0x46,0x22, + 0x2f,0x3e,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3c, + 0x70,0x61,0x74,0x68,0x20,0x64,0x3d,0x22,0x4d,0x32, + 0x39,0x2e,0x31,0x39,0x38,0x2c,0x31,0x34,0x2e,0x37, + 0x39,0x35,0x20,0x43,0x32,0x39,0x2e,0x33,0x33,0x39, + 0x2c,0x31,0x34,0x2e,0x37,0x39,0x35,0x20,0x32,0x39, + 0x2e,0x34,0x38,0x2c,0x31,0x34,0x2e,0x38,0x33,0x35, + 0x20,0x32,0x39,0x2e,0x36,0x30,0x33,0x2c,0x31,0x34, + 0x2e,0x39,0x31,0x34,0x20,0x4c,0x33,0x34,0x2e,0x32, + 0x38,0x37,0x2c,0x31,0x37,0x2e,0x39,0x31,0x37,0x20, + 0x43,0x33,0x34,0x2e,0x35,0x30,0x32,0x2c,0x31,0x38, + 0x2e,0x30,0x35,0x35,0x20,0x33,0x34,0x2e,0x36,0x33, + 0x32,0x2c,0x31,0x38,0x2e,0x32,0x39,0x33,0x20,0x33, + 0x34,0x2e,0x36,0x33,0x32,0x2c,0x31,0x38,0x2e,0x35, + 0x34,0x38,0x20,0x43,0x33,0x34,0x2e,0x36,0x33,0x32, + 0x2c,0x31,0x38,0x2e,0x38,0x30,0x33,0x20,0x33,0x34, + 0x2e,0x35,0x30,0x32,0x2c,0x31,0x39,0x2e,0x30,0x34, + 0x31,0x20,0x33,0x34,0x2e,0x32,0x38,0x37,0x2c,0x31, + 0x39,0x2e,0x31,0x37,0x39,0x20,0x4c,0x32,0x39,0x2e, + 0x36,0x30,0x33,0x2c,0x32,0x32,0x2e,0x31,0x38,0x35, + 0x20,0x43,0x32,0x39,0x2e,0x33,0x37,0x33,0x2c,0x32, + 0x32,0x2e,0x33,0x33,0x33,0x20,0x32,0x39,0x2e,0x30, + 0x37,0x39,0x2c,0x32,0x32,0x2e,0x33,0x34,0x33,0x20, + 0x32,0x38,0x2e,0x38,0x33,0x37,0x2c,0x32,0x32,0x2e, + 0x32,0x31,0x32,0x20,0x43,0x32,0x38,0x2e,0x35,0x39, + 0x37,0x2c,0x32,0x32,0x2e,0x30,0x38,0x31,0x20,0x32, + 0x38,0x2e,0x34,0x34,0x37,0x2c,0x32,0x31,0x2e,0x38, + 0x32,0x38,0x20,0x32,0x38,0x2e,0x34,0x34,0x37,0x2c, + 0x32,0x31,0x2e,0x35,0x35,0x34,0x20,0x4c,0x32,0x38, + 0x2e,0x34,0x34,0x37,0x2c,0x31,0x35,0x2e,0x35,0x34, + 0x34,0x20,0x43,0x32,0x38,0x2e,0x34,0x34,0x37,0x2c, + 0x31,0x35,0x2e,0x32,0x37,0x20,0x32,0x38,0x2e,0x35, + 0x39,0x35,0x2c,0x31,0x35,0x2e,0x30,0x31,0x38,0x20, + 0x32,0x38,0x2e,0x38,0x33,0x37,0x2c,0x31,0x34,0x2e, + 0x38,0x38,0x36,0x20,0x43,0x32,0x38,0x2e,0x39,0x35, + 0x31,0x2c,0x31,0x34,0x2e,0x38,0x32,0x35,0x20,0x32, + 0x39,0x2e,0x30,0x37,0x35,0x2c,0x31,0x34,0x2e,0x37, + 0x39,0x35,0x20,0x32,0x39,0x2e,0x31,0x39,0x38,0x2c, + 0x31,0x34,0x2e,0x37,0x39,0x35,0x20,0x7a,0x20,0x4d, + 0x33,0x32,0x2e,0x34,0x39,0x33,0x2c,0x31,0x38,0x2e, + 0x35,0x34,0x39,0x20,0x4c,0x32,0x39,0x2e,0x39,0x34, + 0x38,0x2c,0x31,0x36,0x2e,0x39,0x31,0x37,0x20,0x4c, + 0x32,0x39,0x2e,0x39,0x34,0x38,0x2c,0x32,0x30,0x2e, + 0x31,0x38,0x32,0x20,0x4c,0x33,0x32,0x2e,0x34,0x39, + 0x33,0x2c,0x31,0x38,0x2e,0x35,0x34,0x39,0x20,0x7a, + 0x22,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46, + 0x46,0x46,0x46,0x46,0x46,0x22,0x2f,0x3e,0x0a,0x20, + 0x20,0x20,0x20,0x3c,0x2f,0x67,0x3e,0x0a,0x20,0x20, + 0x20,0x20,0x3c,0x70,0x61,0x74,0x68,0x20,0x64,0x3d, + 0x22,0x4d,0x37,0x2e,0x38,0x31,0x32,0x2c,0x31,0x34, + 0x2e,0x37,0x39,0x35,0x20,0x43,0x37,0x2e,0x39,0x33, + 0x36,0x2c,0x31,0x34,0x2e,0x37,0x39,0x35,0x20,0x38, + 0x2e,0x30,0x35,0x38,0x2c,0x31,0x34,0x2e,0x38,0x32, + 0x35,0x20,0x38,0x2e,0x31,0x37,0x2c,0x31,0x34,0x2e, + 0x38,0x38,0x37,0x20,0x43,0x38,0x2e,0x34,0x31,0x31, + 0x2c,0x31,0x35,0x2e,0x30,0x31,0x39,0x20,0x38,0x2e, + 0x35,0x36,0x32,0x2c,0x31,0x35,0x2e,0x32,0x37,0x31, + 0x20,0x38,0x2e,0x35,0x36,0x32,0x2c,0x31,0x35,0x2e, + 0x35,0x34,0x35,0x20,0x4c,0x38,0x2e,0x35,0x36,0x32, + 0x2c,0x32,0x31,0x2e,0x35,0x35,0x35,0x20,0x43,0x38, + 0x2e,0x35,0x36,0x32,0x2c,0x32,0x31,0x2e,0x38,0x32, + 0x39,0x20,0x38,0x2e,0x34,0x31,0x33,0x2c,0x32,0x32, + 0x2e,0x30,0x38,0x31,0x20,0x38,0x2e,0x31,0x37,0x2c, + 0x32,0x32,0x2e,0x32,0x31,0x33,0x20,0x43,0x37,0x2e, + 0x39,0x33,0x31,0x2c,0x32,0x32,0x2e,0x33,0x34,0x34, + 0x20,0x37,0x2e,0x36,0x33,0x37,0x2c,0x32,0x32,0x2e, + 0x33,0x33,0x36,0x20,0x37,0x2e,0x34,0x30,0x35,0x2c, + 0x32,0x32,0x2e,0x31,0x38,0x36,0x20,0x4c,0x32,0x2e, + 0x37,0x32,0x2c,0x31,0x39,0x2e,0x31,0x38,0x31,0x20, + 0x43,0x32,0x2e,0x35,0x30,0x35,0x2c,0x31,0x39,0x2e, + 0x30,0x34,0x33,0x20,0x32,0x2e,0x33,0x37,0x35,0x2c, + 0x31,0x38,0x2e,0x38,0x30,0x35,0x20,0x32,0x2e,0x33, + 0x37,0x35,0x2c,0x31,0x38,0x2e,0x35,0x35,0x20,0x43, + 0x32,0x2e,0x33,0x37,0x35,0x2c,0x31,0x38,0x2e,0x32, + 0x39,0x35,0x20,0x32,0x2e,0x35,0x30,0x35,0x2c,0x31, + 0x38,0x2e,0x30,0x35,0x37,0x20,0x32,0x2e,0x37,0x32, + 0x2c,0x31,0x37,0x2e,0x39,0x31,0x39,0x20,0x4c,0x37, + 0x2e,0x34,0x30,0x35,0x2c,0x31,0x34,0x2e,0x39,0x31, + 0x35,0x20,0x43,0x37,0x2e,0x35,0x32,0x39,0x2c,0x31, + 0x34,0x2e,0x38,0x33,0x35,0x20,0x37,0x2e,0x36,0x37, + 0x31,0x2c,0x31,0x34,0x2e,0x37,0x39,0x35,0x20,0x37, + 0x2e,0x38,0x31,0x32,0x2c,0x31,0x34,0x2e,0x37,0x39, + 0x35,0x20,0x7a,0x20,0x4d,0x37,0x2e,0x30,0x36,0x32, + 0x2c,0x32,0x30,0x2e,0x31,0x38,0x33,0x20,0x4c,0x37, + 0x2e,0x30,0x36,0x32,0x2c,0x31,0x36,0x2e,0x39,0x31, + 0x37,0x20,0x4c,0x34,0x2e,0x35,0x31,0x36,0x2c,0x31, + 0x38,0x2e,0x35,0x35,0x20,0x4c,0x37,0x2e,0x30,0x36, + 0x32,0x2c,0x32,0x30,0x2e,0x31,0x38,0x33,0x20,0x7a, + 0x22,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46, + 0x46,0x46,0x46,0x46,0x46,0x22,0x2f,0x3e,0x0a,0x20, + 0x20,0x20,0x20,0x3c,0x70,0x61,0x74,0x68,0x20,0x64, + 0x3d,0x22,0x4d,0x31,0x38,0x2e,0x34,0x37,0x37,0x2c, + 0x32,0x2e,0x34,0x35,0x33,0x20,0x4c,0x31,0x38,0x2e, + 0x34,0x37,0x37,0x2c,0x32,0x2e,0x34,0x35,0x33,0x20, + 0x43,0x31,0x38,0x2e,0x37,0x33,0x32,0x2c,0x32,0x2e, + 0x34,0x35,0x33,0x20,0x31,0x38,0x2e,0x39,0x36,0x39, + 0x2c,0x32,0x2e,0x35,0x38,0x33,0x20,0x31,0x39,0x2e, + 0x31,0x30,0x38,0x2c,0x32,0x2e,0x37,0x39,0x38,0x20, + 0x4c,0x32,0x32,0x2e,0x31,0x31,0x33,0x2c,0x37,0x2e, + 0x34,0x38,0x32,0x20,0x43,0x32,0x32,0x2e,0x32,0x36, + 0x2c,0x37,0x2e,0x37,0x31,0x33,0x20,0x32,0x32,0x2e, + 0x32,0x37,0x31,0x2c,0x38,0x2e,0x30,0x30,0x36,0x20, + 0x32,0x32,0x2e,0x31,0x33,0x39,0x2c,0x38,0x2e,0x32, + 0x34,0x38,0x20,0x43,0x32,0x32,0x2e,0x30,0x30,0x37, + 0x2c,0x38,0x2e,0x34,0x39,0x20,0x32,0x31,0x2e,0x37, + 0x35,0x35,0x2c,0x38,0x2e,0x36,0x33,0x39,0x20,0x32, + 0x31,0x2e,0x34,0x38,0x32,0x2c,0x38,0x2e,0x36,0x33, + 0x39,0x20,0x4c,0x31,0x35,0x2e,0x34,0x37,0x2c,0x38, + 0x2e,0x36,0x33,0x39,0x20,0x43,0x31,0x35,0x2e,0x31, + 0x39,0x37,0x2c,0x38,0x2e,0x36,0x33,0x39,0x20,0x31, + 0x34,0x2e,0x39,0x34,0x35,0x2c,0x38,0x2e,0x34,0x39, + 0x31,0x20,0x31,0x34,0x2e,0x38,0x31,0x33,0x2c,0x38, + 0x2e,0x32,0x34,0x38,0x20,0x43,0x31,0x34,0x2e,0x36, + 0x38,0x2c,0x38,0x2e,0x30,0x30,0x38,0x20,0x31,0x34, + 0x2e,0x36,0x39,0x32,0x2c,0x37,0x2e,0x37,0x31,0x35, + 0x20,0x31,0x34,0x2e,0x38,0x33,0x39,0x2c,0x37,0x2e, + 0x34,0x38,0x32,0x20,0x4c,0x31,0x37,0x2e,0x38,0x34, + 0x34,0x2c,0x32,0x2e,0x37,0x39,0x38,0x20,0x43,0x31, + 0x37,0x2e,0x39,0x38,0x34,0x2c,0x32,0x2e,0x35,0x38, + 0x33,0x20,0x31,0x38,0x2e,0x32,0x32,0x31,0x2c,0x32, + 0x2e,0x34,0x35,0x33,0x20,0x31,0x38,0x2e,0x34,0x37, + 0x37,0x2c,0x32,0x2e,0x34,0x35,0x33,0x20,0x7a,0x20, + 0x4d,0x32,0x30,0x2e,0x31,0x31,0x2c,0x37,0x2e,0x31, + 0x33,0x37,0x20,0x4c,0x31,0x38,0x2e,0x34,0x37,0x37, + 0x2c,0x34,0x2e,0x35,0x39,0x32,0x20,0x4c,0x31,0x36, + 0x2e,0x38,0x34,0x32,0x2c,0x37,0x2e,0x31,0x33,0x37, + 0x20,0x4c,0x32,0x30,0x2e,0x31,0x31,0x2c,0x37,0x2e, + 0x31,0x33,0x37,0x20,0x7a,0x22,0x20,0x66,0x69,0x6c, + 0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46,0x46, + 0x22,0x2f,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x70, + 0x61,0x74,0x68,0x20,0x64,0x3d,0x22,0x4d,0x31,0x38, + 0x2e,0x35,0x33,0x2c,0x30,0x20,0x43,0x32,0x38,0x2e, + 0x37,0x36,0x35,0x2c,0x30,0x20,0x33,0x37,0x2e,0x30, + 0x36,0x31,0x2c,0x38,0x2e,0x32,0x39,0x36,0x20,0x33, + 0x37,0x2e,0x30,0x36,0x31,0x2c,0x31,0x38,0x2e,0x35, + 0x33,0x31,0x20,0x43,0x33,0x37,0x2e,0x30,0x36,0x31, + 0x2c,0x32,0x38,0x2e,0x37,0x36,0x35,0x20,0x32,0x38, + 0x2e,0x37,0x36,0x35,0x2c,0x33,0x37,0x2e,0x30,0x36, + 0x31,0x20,0x31,0x38,0x2e,0x35,0x33,0x2c,0x33,0x37, + 0x2e,0x30,0x36,0x31,0x20,0x43,0x38,0x2e,0x32,0x39, + 0x36,0x2c,0x33,0x37,0x2e,0x30,0x36,0x31,0x20,0x30, + 0x2c,0x32,0x38,0x2e,0x37,0x36,0x35,0x20,0x30,0x2c, + 0x31,0x38,0x2e,0x35,0x33,0x31,0x20,0x43,0x30,0x2c, + 0x38,0x2e,0x32,0x39,0x36,0x20,0x38,0x2e,0x32,0x39, + 0x36,0x2c,0x30,0x20,0x31,0x38,0x2e,0x35,0x33,0x2c, + 0x30,0x20,0x7a,0x20,0x4d,0x31,0x38,0x2e,0x35,0x33, + 0x2c,0x31,0x20,0x43,0x38,0x2e,0x38,0x34,0x39,0x2c, + 0x31,0x20,0x31,0x2c,0x38,0x2e,0x38,0x34,0x39,0x20, + 0x31,0x2c,0x31,0x38,0x2e,0x35,0x33,0x31,0x20,0x43, + 0x31,0x2c,0x32,0x38,0x2e,0x32,0x31,0x32,0x20,0x38, + 0x2e,0x38,0x34,0x39,0x2c,0x33,0x36,0x2e,0x30,0x36, + 0x31,0x20,0x31,0x38,0x2e,0x35,0x33,0x2c,0x33,0x36, + 0x2e,0x30,0x36,0x31,0x20,0x43,0x32,0x38,0x2e,0x32, + 0x31,0x32,0x2c,0x33,0x36,0x2e,0x30,0x36,0x31,0x20, + 0x33,0x36,0x2e,0x30,0x36,0x31,0x2c,0x32,0x38,0x2e, + 0x32,0x31,0x32,0x20,0x33,0x36,0x2e,0x30,0x36,0x31, + 0x2c,0x31,0x38,0x2e,0x35,0x33,0x31,0x20,0x43,0x33, + 0x36,0x2e,0x30,0x36,0x31,0x2c,0x38,0x2e,0x38,0x34, + 0x39,0x20,0x32,0x38,0x2e,0x32,0x31,0x32,0x2c,0x31, + 0x20,0x31,0x38,0x2e,0x35,0x33,0x2c,0x31,0x20,0x7a, + 0x22,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46, + 0x46,0x46,0x46,0x46,0x46,0x22,0x2f,0x3e,0x0a,0x20, + 0x20,0x3c,0x2f,0x67,0x3e,0x0a,0x3c,0x2f,0x73,0x76, + 0x67,0x3e,0x0a +}; + diff --git a/data/converted/help_analog_thumb_svg.cpp b/data/converted/help_analog_thumb_svg.cpp new file mode 100644 index 0000000000..5bb06b9ad7 --- /dev/null +++ b/data/converted/help_analog_thumb_svg.cpp @@ -0,0 +1,298 @@ +//this file was auto-generated from "analog_thumb.svg" by res2h + +#include "../Resources.h" + +const size_t help_analog_thumb_svg_size = 2894; +const unsigned char help_analog_thumb_svg_data[2894] = { + 0x3c,0x3f,0x78,0x6d,0x6c,0x20,0x76,0x65,0x72,0x73, + 0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x30,0x22,0x20, + 0x65,0x6e,0x63,0x6f,0x64,0x69,0x6e,0x67,0x3d,0x22, + 0x55,0x54,0x46,0x2d,0x38,0x22,0x3f,0x3e,0x0a,0x3c, + 0x21,0x44,0x4f,0x43,0x54,0x59,0x50,0x45,0x20,0x73, + 0x76,0x67,0x20,0x50,0x55,0x42,0x4c,0x49,0x43,0x20, + 0x22,0x2d,0x2f,0x2f,0x57,0x33,0x43,0x2f,0x2f,0x44, + 0x54,0x44,0x20,0x53,0x56,0x47,0x20,0x31,0x2e,0x31, + 0x2f,0x2f,0x45,0x4e,0x22,0x20,0x22,0x68,0x74,0x74, + 0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33, + 0x2e,0x6f,0x72,0x67,0x2f,0x47,0x72,0x61,0x70,0x68, + 0x69,0x63,0x73,0x2f,0x53,0x56,0x47,0x2f,0x31,0x2e, + 0x31,0x2f,0x44,0x54,0x44,0x2f,0x73,0x76,0x67,0x31, + 0x31,0x2e,0x64,0x74,0x64,0x22,0x3e,0x0a,0x3c,0x73, + 0x76,0x67,0x20,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e, + 0x3d,0x22,0x31,0x2e,0x31,0x22,0x20,0x78,0x6d,0x6c, + 0x6e,0x73,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, + 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, + 0x67,0x2f,0x32,0x30,0x30,0x30,0x2f,0x73,0x76,0x67, + 0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78,0x6c, + 0x69,0x6e,0x6b,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a, + 0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f, + 0x72,0x67,0x2f,0x31,0x39,0x39,0x39,0x2f,0x78,0x6c, + 0x69,0x6e,0x6b,0x22,0x20,0x78,0x3d,0x22,0x30,0x22, + 0x20,0x79,0x3d,0x22,0x30,0x22,0x20,0x77,0x69,0x64, + 0x74,0x68,0x3d,0x22,0x33,0x37,0x2e,0x30,0x36,0x31, + 0x22,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3d,0x22, + 0x33,0x37,0x2e,0x30,0x36,0x31,0x22,0x20,0x76,0x69, + 0x65,0x77,0x42,0x6f,0x78,0x3d,0x22,0x30,0x2c,0x20, + 0x30,0x2c,0x20,0x33,0x37,0x2e,0x30,0x36,0x31,0x2c, + 0x20,0x33,0x37,0x2e,0x30,0x36,0x31,0x22,0x3e,0x0a, + 0x20,0x20,0x3c,0x67,0x20,0x69,0x64,0x3d,0x22,0x45, + 0x62,0x65,0x6e,0x65,0x5f,0x31,0x22,0x3e,0x0a,0x20, + 0x20,0x20,0x20,0x3c,0x70,0x61,0x74,0x68,0x20,0x64, + 0x3d,0x22,0x4d,0x31,0x38,0x2e,0x35,0x33,0x31,0x2c, + 0x32,0x32,0x2e,0x31,0x38,0x31,0x20,0x43,0x31,0x36, + 0x2e,0x35,0x31,0x38,0x2c,0x32,0x32,0x2e,0x31,0x38, + 0x31,0x20,0x31,0x34,0x2e,0x38,0x38,0x32,0x2c,0x32, + 0x30,0x2e,0x35,0x34,0x32,0x20,0x31,0x34,0x2e,0x38, + 0x38,0x32,0x2c,0x31,0x38,0x2e,0x35,0x33,0x20,0x43, + 0x31,0x34,0x2e,0x38,0x38,0x32,0x2c,0x31,0x36,0x2e, + 0x35,0x31,0x38,0x20,0x31,0x36,0x2e,0x35,0x32,0x2c, + 0x31,0x34,0x2e,0x38,0x38,0x20,0x31,0x38,0x2e,0x35, + 0x33,0x31,0x2c,0x31,0x34,0x2e,0x38,0x38,0x20,0x43, + 0x32,0x30,0x2e,0x35,0x34,0x34,0x2c,0x31,0x34,0x2e, + 0x38,0x38,0x20,0x32,0x32,0x2e,0x31,0x38,0x31,0x2c, + 0x31,0x36,0x2e,0x35,0x31,0x39,0x20,0x32,0x32,0x2e, + 0x31,0x38,0x31,0x2c,0x31,0x38,0x2e,0x35,0x33,0x20, + 0x43,0x32,0x32,0x2e,0x31,0x38,0x32,0x2c,0x32,0x30, + 0x2e,0x35,0x34,0x33,0x20,0x32,0x30,0x2e,0x35,0x34, + 0x34,0x2c,0x32,0x32,0x2e,0x31,0x38,0x31,0x20,0x31, + 0x38,0x2e,0x35,0x33,0x31,0x2c,0x32,0x32,0x2e,0x31, + 0x38,0x31,0x20,0x7a,0x20,0x4d,0x31,0x38,0x2e,0x35, + 0x33,0x31,0x2c,0x31,0x36,0x2e,0x33,0x37,0x39,0x20, + 0x43,0x31,0x37,0x2e,0x33,0x34,0x35,0x2c,0x31,0x36, + 0x2e,0x33,0x37,0x39,0x20,0x31,0x36,0x2e,0x33,0x38, + 0x32,0x2c,0x31,0x37,0x2e,0x33,0x34,0x34,0x20,0x31, + 0x36,0x2e,0x33,0x38,0x32,0x2c,0x31,0x38,0x2e,0x35, + 0x32,0x39,0x20,0x43,0x31,0x36,0x2e,0x33,0x38,0x32, + 0x2c,0x31,0x39,0x2e,0x37,0x31,0x34,0x20,0x31,0x37, + 0x2e,0x33,0x34,0x37,0x2c,0x32,0x30,0x2e,0x36,0x38, + 0x20,0x31,0x38,0x2e,0x35,0x33,0x31,0x2c,0x32,0x30, + 0x2e,0x36,0x38,0x20,0x43,0x31,0x39,0x2e,0x37,0x31, + 0x37,0x2c,0x32,0x30,0x2e,0x36,0x38,0x20,0x32,0x30, + 0x2e,0x36,0x38,0x31,0x2c,0x31,0x39,0x2e,0x37,0x31, + 0x34,0x20,0x32,0x30,0x2e,0x36,0x38,0x31,0x2c,0x31, + 0x38,0x2e,0x35,0x32,0x39,0x20,0x43,0x32,0x30,0x2e, + 0x36,0x38,0x32,0x2c,0x31,0x37,0x2e,0x33,0x34,0x34, + 0x20,0x31,0x39,0x2e,0x37,0x31,0x37,0x2c,0x31,0x36, + 0x2e,0x33,0x37,0x39,0x20,0x31,0x38,0x2e,0x35,0x33, + 0x31,0x2c,0x31,0x36,0x2e,0x33,0x37,0x39,0x20,0x7a, + 0x22,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46, + 0x46,0x46,0x46,0x46,0x46,0x22,0x2f,0x3e,0x0a,0x20, + 0x20,0x20,0x20,0x3c,0x70,0x61,0x74,0x68,0x20,0x64, + 0x3d,0x22,0x4d,0x32,0x31,0x2e,0x35,0x33,0x36,0x2c, + 0x38,0x2e,0x36,0x31,0x36,0x20,0x4c,0x31,0x35,0x2e, + 0x35,0x32,0x34,0x2c,0x38,0x2e,0x36,0x31,0x36,0x20, + 0x43,0x31,0x35,0x2e,0x32,0x35,0x31,0x2c,0x38,0x2e, + 0x36,0x31,0x36,0x20,0x31,0x34,0x2e,0x39,0x39,0x39, + 0x2c,0x38,0x2e,0x34,0x36,0x36,0x20,0x31,0x34,0x2e, + 0x38,0x36,0x37,0x2c,0x38,0x2e,0x32,0x32,0x36,0x20, + 0x43,0x31,0x34,0x2e,0x37,0x33,0x35,0x2c,0x37,0x2e, + 0x39,0x38,0x35,0x20,0x31,0x34,0x2e,0x37,0x34,0x36, + 0x2c,0x37,0x2e,0x36,0x39,0x32,0x20,0x31,0x34,0x2e, + 0x38,0x39,0x33,0x2c,0x37,0x2e,0x34,0x36,0x20,0x4c, + 0x31,0x37,0x2e,0x38,0x39,0x38,0x2c,0x32,0x2e,0x37, + 0x37,0x36,0x20,0x43,0x31,0x38,0x2e,0x31,0x37,0x34, + 0x2c,0x32,0x2e,0x33,0x34,0x35,0x20,0x31,0x38,0x2e, + 0x38,0x38,0x34,0x2c,0x32,0x2e,0x33,0x34,0x36,0x20, + 0x31,0x39,0x2e,0x31,0x36,0x32,0x2c,0x32,0x2e,0x37, + 0x37,0x36,0x20,0x4c,0x32,0x32,0x2e,0x31,0x36,0x37, + 0x2c,0x37,0x2e,0x34,0x36,0x20,0x43,0x32,0x32,0x2e, + 0x33,0x31,0x34,0x2c,0x37,0x2e,0x36,0x39,0x31,0x20, + 0x32,0x32,0x2e,0x33,0x32,0x36,0x2c,0x37,0x2e,0x39, + 0x38,0x34,0x20,0x32,0x32,0x2e,0x31,0x39,0x33,0x2c, + 0x38,0x2e,0x32,0x32,0x36,0x20,0x43,0x32,0x32,0x2e, + 0x30,0x36,0x33,0x2c,0x38,0x2e,0x34,0x36,0x36,0x20, + 0x32,0x31,0x2e,0x38,0x31,0x31,0x2c,0x38,0x2e,0x36, + 0x31,0x36,0x20,0x32,0x31,0x2e,0x35,0x33,0x36,0x2c, + 0x38,0x2e,0x36,0x31,0x36,0x20,0x7a,0x20,0x4d,0x31, + 0x36,0x2e,0x38,0x39,0x37,0x2c,0x37,0x2e,0x31,0x31, + 0x36,0x20,0x4c,0x32,0x30,0x2e,0x31,0x36,0x35,0x2c, + 0x37,0x2e,0x31,0x31,0x36,0x20,0x4c,0x31,0x38,0x2e, + 0x35,0x33,0x2c,0x34,0x2e,0x35,0x37,0x31,0x20,0x4c, + 0x31,0x36,0x2e,0x38,0x39,0x37,0x2c,0x37,0x2e,0x31, + 0x31,0x36,0x20,0x7a,0x22,0x20,0x66,0x69,0x6c,0x6c, + 0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46,0x46,0x22, + 0x2f,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x70,0x61, + 0x74,0x68,0x20,0x64,0x3d,0x22,0x4d,0x37,0x2e,0x37, + 0x38,0x32,0x2c,0x31,0x34,0x2e,0x37,0x37,0x36,0x20, + 0x4c,0x38,0x2e,0x31,0x37,0x2c,0x31,0x34,0x2e,0x38, + 0x36,0x37,0x20,0x43,0x38,0x2e,0x34,0x31,0x2c,0x31, + 0x34,0x2e,0x39,0x39,0x38,0x20,0x38,0x2e,0x35,0x36, + 0x2c,0x31,0x35,0x2e,0x32,0x35,0x31,0x20,0x38,0x2e, + 0x35,0x36,0x2c,0x31,0x35,0x2e,0x35,0x32,0x35,0x20, + 0x4c,0x38,0x2e,0x35,0x36,0x2c,0x32,0x31,0x2e,0x35, + 0x33,0x35,0x20,0x43,0x38,0x2e,0x35,0x36,0x2c,0x32, + 0x31,0x2e,0x38,0x30,0x39,0x20,0x38,0x2e,0x34,0x31, + 0x32,0x2c,0x32,0x32,0x2e,0x30,0x36,0x31,0x20,0x38, + 0x2e,0x31,0x37,0x2c,0x32,0x32,0x2e,0x31,0x39,0x33, + 0x20,0x43,0x38,0x2e,0x30,0x35,0x36,0x2c,0x32,0x32, + 0x2e,0x32,0x35,0x34,0x20,0x37,0x2e,0x39,0x33,0x32, + 0x2c,0x32,0x32,0x2e,0x32,0x38,0x34,0x20,0x37,0x2e, + 0x38,0x30,0x39,0x2c,0x32,0x32,0x2e,0x32,0x38,0x34, + 0x20,0x43,0x37,0x2e,0x36,0x36,0x38,0x2c,0x32,0x32, + 0x2e,0x32,0x38,0x34,0x20,0x37,0x2e,0x35,0x32,0x37, + 0x2c,0x32,0x32,0x2e,0x32,0x34,0x34,0x20,0x37,0x2e, + 0x34,0x30,0x34,0x2c,0x32,0x32,0x2e,0x31,0x36,0x35, + 0x20,0x4c,0x32,0x2e,0x37,0x32,0x2c,0x31,0x39,0x2e, + 0x31,0x36,0x32,0x20,0x43,0x32,0x2e,0x35,0x30,0x35, + 0x2c,0x31,0x39,0x2e,0x30,0x32,0x34,0x20,0x32,0x2e, + 0x33,0x37,0x35,0x2c,0x31,0x38,0x2e,0x37,0x38,0x36, + 0x20,0x32,0x2e,0x33,0x37,0x35,0x2c,0x31,0x38,0x2e, + 0x35,0x33,0x31,0x20,0x43,0x32,0x2e,0x33,0x37,0x35, + 0x2c,0x31,0x38,0x2e,0x32,0x37,0x36,0x20,0x32,0x2e, + 0x35,0x30,0x35,0x2c,0x31,0x38,0x2e,0x30,0x33,0x38, + 0x20,0x32,0x2e,0x37,0x32,0x2c,0x31,0x37,0x2e,0x39, + 0x20,0x4c,0x37,0x2e,0x34,0x30,0x34,0x2c,0x31,0x34, + 0x2e,0x38,0x39,0x34,0x20,0x4c,0x37,0x2e,0x37,0x38, + 0x32,0x2c,0x31,0x34,0x2e,0x37,0x37,0x36,0x20,0x7a, + 0x20,0x4d,0x37,0x2e,0x30,0x35,0x39,0x2c,0x31,0x36, + 0x2e,0x38,0x39,0x37,0x20,0x4c,0x34,0x2e,0x35,0x31, + 0x34,0x2c,0x31,0x38,0x2e,0x35,0x33,0x20,0x4c,0x37, + 0x2e,0x30,0x35,0x39,0x2c,0x32,0x30,0x2e,0x31,0x36, + 0x32,0x20,0x4c,0x37,0x2e,0x30,0x35,0x39,0x2c,0x31, + 0x36,0x2e,0x38,0x39,0x37,0x20,0x7a,0x22,0x20,0x66, + 0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46, + 0x46,0x46,0x22,0x2f,0x3e,0x0a,0x20,0x20,0x20,0x20, + 0x3c,0x70,0x61,0x74,0x68,0x20,0x64,0x3d,0x22,0x4d, + 0x32,0x39,0x2e,0x31,0x39,0x35,0x2c,0x32,0x32,0x2e, + 0x32,0x38,0x34,0x20,0x43,0x32,0x39,0x2e,0x30,0x37, + 0x31,0x2c,0x32,0x32,0x2e,0x32,0x38,0x34,0x20,0x32, + 0x38,0x2e,0x39,0x34,0x39,0x2c,0x32,0x32,0x2e,0x32, + 0x35,0x34,0x20,0x32,0x38,0x2e,0x38,0x33,0x37,0x2c, + 0x32,0x32,0x2e,0x31,0x39,0x32,0x20,0x43,0x32,0x38, + 0x2e,0x35,0x39,0x36,0x2c,0x32,0x32,0x2e,0x30,0x36, + 0x20,0x32,0x38,0x2e,0x34,0x34,0x35,0x2c,0x32,0x31, + 0x2e,0x38,0x30,0x38,0x20,0x32,0x38,0x2e,0x34,0x34, + 0x35,0x2c,0x32,0x31,0x2e,0x35,0x33,0x34,0x20,0x4c, + 0x32,0x38,0x2e,0x34,0x34,0x35,0x2c,0x31,0x35,0x2e, + 0x35,0x32,0x34,0x20,0x43,0x32,0x38,0x2e,0x34,0x34, + 0x35,0x2c,0x31,0x35,0x2e,0x32,0x35,0x20,0x32,0x38, + 0x2e,0x35,0x39,0x34,0x2c,0x31,0x34,0x2e,0x39,0x39, + 0x38,0x20,0x32,0x38,0x2e,0x38,0x33,0x37,0x2c,0x31, + 0x34,0x2e,0x38,0x36,0x36,0x20,0x43,0x32,0x39,0x2e, + 0x30,0x37,0x36,0x2c,0x31,0x34,0x2e,0x37,0x33,0x35, + 0x20,0x32,0x39,0x2e,0x33,0x37,0x2c,0x31,0x34,0x2e, + 0x37,0x34,0x33,0x20,0x32,0x39,0x2e,0x36,0x30,0x32, + 0x2c,0x31,0x34,0x2e,0x38,0x39,0x33,0x20,0x4c,0x33, + 0x34,0x2e,0x32,0x38,0x37,0x2c,0x31,0x37,0x2e,0x38, + 0x39,0x38,0x20,0x43,0x33,0x34,0x2e,0x35,0x30,0x32, + 0x2c,0x31,0x38,0x2e,0x30,0x33,0x36,0x20,0x33,0x34, + 0x2e,0x36,0x33,0x32,0x2c,0x31,0x38,0x2e,0x32,0x37, + 0x34,0x20,0x33,0x34,0x2e,0x36,0x33,0x32,0x2c,0x31, + 0x38,0x2e,0x35,0x32,0x39,0x20,0x43,0x33,0x34,0x2e, + 0x36,0x33,0x32,0x2c,0x31,0x38,0x2e,0x37,0x38,0x34, + 0x20,0x33,0x34,0x2e,0x35,0x30,0x32,0x2c,0x31,0x39, + 0x2e,0x30,0x32,0x32,0x20,0x33,0x34,0x2e,0x32,0x38, + 0x37,0x2c,0x31,0x39,0x2e,0x31,0x36,0x20,0x4c,0x32, + 0x39,0x2e,0x36,0x30,0x32,0x2c,0x32,0x32,0x2e,0x31, + 0x36,0x34,0x20,0x43,0x32,0x39,0x2e,0x34,0x37,0x38, + 0x2c,0x32,0x32,0x2e,0x32,0x34,0x34,0x20,0x32,0x39, + 0x2e,0x33,0x33,0x36,0x2c,0x32,0x32,0x2e,0x32,0x38, + 0x34,0x20,0x32,0x39,0x2e,0x31,0x39,0x35,0x2c,0x32, + 0x32,0x2e,0x32,0x38,0x34,0x20,0x7a,0x20,0x4d,0x32, + 0x39,0x2e,0x39,0x34,0x35,0x2c,0x31,0x36,0x2e,0x38, + 0x39,0x36,0x20,0x4c,0x32,0x39,0x2e,0x39,0x34,0x35, + 0x2c,0x32,0x30,0x2e,0x31,0x36,0x32,0x20,0x4c,0x33, + 0x32,0x2e,0x34,0x39,0x31,0x2c,0x31,0x38,0x2e,0x35, + 0x32,0x39,0x20,0x4c,0x32,0x39,0x2e,0x39,0x34,0x35, + 0x2c,0x31,0x36,0x2e,0x38,0x39,0x36,0x20,0x7a,0x22, + 0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46, + 0x46,0x46,0x46,0x46,0x22,0x2f,0x3e,0x0a,0x20,0x20, + 0x20,0x20,0x3c,0x70,0x61,0x74,0x68,0x20,0x64,0x3d, + 0x22,0x4d,0x31,0x38,0x2e,0x35,0x33,0x2c,0x33,0x34, + 0x2e,0x36,0x32,0x36,0x20,0x4c,0x31,0x38,0x2e,0x35, + 0x33,0x2c,0x33,0x34,0x2e,0x36,0x32,0x36,0x20,0x43, + 0x31,0x38,0x2e,0x32,0x37,0x35,0x2c,0x33,0x34,0x2e, + 0x36,0x32,0x36,0x20,0x31,0x38,0x2e,0x30,0x33,0x38, + 0x2c,0x33,0x34,0x2e,0x34,0x39,0x36,0x20,0x31,0x37, + 0x2e,0x38,0x39,0x39,0x2c,0x33,0x34,0x2e,0x32,0x38, + 0x31,0x20,0x4c,0x31,0x34,0x2e,0x38,0x39,0x34,0x2c, + 0x32,0x39,0x2e,0x35,0x39,0x37,0x20,0x43,0x31,0x34, + 0x2e,0x37,0x34,0x37,0x2c,0x32,0x39,0x2e,0x33,0x36, + 0x36,0x20,0x31,0x34,0x2e,0x37,0x33,0x36,0x2c,0x32, + 0x39,0x2e,0x30,0x37,0x33,0x20,0x31,0x34,0x2e,0x38, + 0x36,0x38,0x2c,0x32,0x38,0x2e,0x38,0x33,0x31,0x20, + 0x43,0x31,0x35,0x2c,0x32,0x38,0x2e,0x35,0x38,0x39, + 0x20,0x31,0x35,0x2e,0x32,0x35,0x32,0x2c,0x32,0x38, + 0x2e,0x34,0x34,0x20,0x31,0x35,0x2e,0x35,0x32,0x35, + 0x2c,0x32,0x38,0x2e,0x34,0x34,0x20,0x4c,0x32,0x31, + 0x2e,0x35,0x33,0x37,0x2c,0x32,0x38,0x2e,0x34,0x34, + 0x20,0x43,0x32,0x31,0x2e,0x38,0x31,0x2c,0x32,0x38, + 0x2e,0x34,0x34,0x20,0x32,0x32,0x2e,0x30,0x36,0x32, + 0x2c,0x32,0x38,0x2e,0x35,0x38,0x38,0x20,0x32,0x32, + 0x2e,0x31,0x39,0x34,0x2c,0x32,0x38,0x2e,0x38,0x33, + 0x31,0x20,0x43,0x32,0x32,0x2e,0x33,0x32,0x37,0x2c, + 0x32,0x39,0x2e,0x30,0x37,0x31,0x20,0x32,0x32,0x2e, + 0x33,0x31,0x35,0x2c,0x32,0x39,0x2e,0x33,0x36,0x34, + 0x20,0x32,0x32,0x2e,0x31,0x36,0x38,0x2c,0x32,0x39, + 0x2e,0x35,0x39,0x37,0x20,0x4c,0x31,0x39,0x2e,0x31, + 0x36,0x33,0x2c,0x33,0x34,0x2e,0x32,0x38,0x31,0x20, + 0x43,0x31,0x39,0x2e,0x30,0x32,0x33,0x2c,0x33,0x34, + 0x2e,0x34,0x39,0x36,0x20,0x31,0x38,0x2e,0x37,0x38, + 0x36,0x2c,0x33,0x34,0x2e,0x36,0x32,0x36,0x20,0x31, + 0x38,0x2e,0x35,0x33,0x2c,0x33,0x34,0x2e,0x36,0x32, + 0x36,0x20,0x7a,0x20,0x4d,0x31,0x36,0x2e,0x38,0x39, + 0x37,0x2c,0x32,0x39,0x2e,0x39,0x34,0x32,0x20,0x4c, + 0x31,0x38,0x2e,0x35,0x33,0x2c,0x33,0x32,0x2e,0x34, + 0x38,0x37,0x20,0x4c,0x32,0x30,0x2e,0x31,0x36,0x35, + 0x2c,0x32,0x39,0x2e,0x39,0x34,0x32,0x20,0x4c,0x31, + 0x36,0x2e,0x38,0x39,0x37,0x2c,0x32,0x39,0x2e,0x39, + 0x34,0x32,0x20,0x7a,0x22,0x20,0x66,0x69,0x6c,0x6c, + 0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46,0x46,0x22, + 0x2f,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x70,0x61, + 0x74,0x68,0x20,0x64,0x3d,0x22,0x4d,0x31,0x38,0x2e, + 0x35,0x33,0x2c,0x30,0x20,0x43,0x32,0x38,0x2e,0x37, + 0x36,0x35,0x2c,0x30,0x20,0x33,0x37,0x2e,0x30,0x36, + 0x31,0x2c,0x38,0x2e,0x32,0x39,0x36,0x20,0x33,0x37, + 0x2e,0x30,0x36,0x31,0x2c,0x31,0x38,0x2e,0x35,0x33, + 0x31,0x20,0x43,0x33,0x37,0x2e,0x30,0x36,0x31,0x2c, + 0x32,0x38,0x2e,0x37,0x36,0x35,0x20,0x32,0x38,0x2e, + 0x37,0x36,0x35,0x2c,0x33,0x37,0x2e,0x30,0x36,0x31, + 0x20,0x31,0x38,0x2e,0x35,0x33,0x2c,0x33,0x37,0x2e, + 0x30,0x36,0x31,0x20,0x43,0x38,0x2e,0x32,0x39,0x36, + 0x2c,0x33,0x37,0x2e,0x30,0x36,0x31,0x20,0x30,0x2c, + 0x32,0x38,0x2e,0x37,0x36,0x35,0x20,0x30,0x2c,0x31, + 0x38,0x2e,0x35,0x33,0x31,0x20,0x43,0x30,0x2c,0x38, + 0x2e,0x32,0x39,0x36,0x20,0x38,0x2e,0x32,0x39,0x36, + 0x2c,0x30,0x20,0x31,0x38,0x2e,0x35,0x33,0x2c,0x30, + 0x20,0x7a,0x20,0x4d,0x31,0x38,0x2e,0x35,0x33,0x2c, + 0x31,0x20,0x43,0x38,0x2e,0x38,0x34,0x39,0x2c,0x31, + 0x20,0x31,0x2c,0x38,0x2e,0x38,0x34,0x39,0x20,0x31, + 0x2c,0x31,0x38,0x2e,0x35,0x33,0x31,0x20,0x43,0x31, + 0x2c,0x32,0x38,0x2e,0x32,0x31,0x32,0x20,0x38,0x2e, + 0x38,0x34,0x39,0x2c,0x33,0x36,0x2e,0x30,0x36,0x31, + 0x20,0x31,0x38,0x2e,0x35,0x33,0x2c,0x33,0x36,0x2e, + 0x30,0x36,0x31,0x20,0x43,0x32,0x38,0x2e,0x32,0x31, + 0x32,0x2c,0x33,0x36,0x2e,0x30,0x36,0x31,0x20,0x33, + 0x36,0x2e,0x30,0x36,0x31,0x2c,0x32,0x38,0x2e,0x32, + 0x31,0x32,0x20,0x33,0x36,0x2e,0x30,0x36,0x31,0x2c, + 0x31,0x38,0x2e,0x35,0x33,0x31,0x20,0x43,0x33,0x36, + 0x2e,0x30,0x36,0x31,0x2c,0x38,0x2e,0x38,0x34,0x39, + 0x20,0x32,0x38,0x2e,0x32,0x31,0x32,0x2c,0x31,0x20, + 0x31,0x38,0x2e,0x35,0x33,0x2c,0x31,0x20,0x7a,0x22, + 0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46, + 0x46,0x46,0x46,0x46,0x22,0x2f,0x3e,0x0a,0x20,0x20, + 0x20,0x20,0x3c,0x70,0x61,0x74,0x68,0x20,0x64,0x3d, + 0x22,0x4d,0x31,0x38,0x2e,0x35,0x32,0x39,0x2c,0x32, + 0x32,0x2e,0x31,0x38,0x31,0x20,0x43,0x31,0x36,0x2e, + 0x35,0x31,0x33,0x2c,0x32,0x32,0x2e,0x31,0x38,0x31, + 0x20,0x31,0x34,0x2e,0x38,0x37,0x39,0x2c,0x32,0x30, + 0x2e,0x35,0x34,0x37,0x20,0x31,0x34,0x2e,0x38,0x37, + 0x39,0x2c,0x31,0x38,0x2e,0x35,0x33,0x20,0x43,0x31, + 0x34,0x2e,0x38,0x37,0x39,0x2c,0x31,0x36,0x2e,0x35, + 0x31,0x34,0x20,0x31,0x36,0x2e,0x35,0x31,0x33,0x2c, + 0x31,0x34,0x2e,0x38,0x38,0x20,0x31,0x38,0x2e,0x35, + 0x32,0x39,0x2c,0x31,0x34,0x2e,0x38,0x38,0x20,0x43, + 0x32,0x30,0x2e,0x35,0x34,0x36,0x2c,0x31,0x34,0x2e, + 0x38,0x38,0x20,0x32,0x32,0x2e,0x31,0x38,0x2c,0x31, + 0x36,0x2e,0x35,0x31,0x34,0x20,0x32,0x32,0x2e,0x31, + 0x38,0x2c,0x31,0x38,0x2e,0x35,0x33,0x20,0x43,0x32, + 0x32,0x2e,0x31,0x38,0x2c,0x32,0x30,0x2e,0x35,0x34, + 0x37,0x20,0x32,0x30,0x2e,0x35,0x34,0x36,0x2c,0x32, + 0x32,0x2e,0x31,0x38,0x31,0x20,0x31,0x38,0x2e,0x35, + 0x32,0x39,0x2c,0x32,0x32,0x2e,0x31,0x38,0x31,0x20, + 0x7a,0x22,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23, + 0x46,0x46,0x46,0x46,0x46,0x46,0x22,0x2f,0x3e,0x0a, + 0x20,0x20,0x3c,0x2f,0x67,0x3e,0x0a,0x3c,0x2f,0x73, + 0x76,0x67,0x3e,0x0a +}; + diff --git a/data/converted/help_analog_up_svg.cpp b/data/converted/help_analog_up_svg.cpp new file mode 100644 index 0000000000..bed20f9264 --- /dev/null +++ b/data/converted/help_analog_up_svg.cpp @@ -0,0 +1,294 @@ +//this file was auto-generated from "analog_up.svg" by res2h + +#include "../Resources.h" + +const size_t help_analog_up_svg_size = 2853; +const unsigned char help_analog_up_svg_data[2853] = { + 0x3c,0x3f,0x78,0x6d,0x6c,0x20,0x76,0x65,0x72,0x73, + 0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x30,0x22,0x20, + 0x65,0x6e,0x63,0x6f,0x64,0x69,0x6e,0x67,0x3d,0x22, + 0x55,0x54,0x46,0x2d,0x38,0x22,0x3f,0x3e,0x0a,0x3c, + 0x21,0x44,0x4f,0x43,0x54,0x59,0x50,0x45,0x20,0x73, + 0x76,0x67,0x20,0x50,0x55,0x42,0x4c,0x49,0x43,0x20, + 0x22,0x2d,0x2f,0x2f,0x57,0x33,0x43,0x2f,0x2f,0x44, + 0x54,0x44,0x20,0x53,0x56,0x47,0x20,0x31,0x2e,0x31, + 0x2f,0x2f,0x45,0x4e,0x22,0x20,0x22,0x68,0x74,0x74, + 0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33, + 0x2e,0x6f,0x72,0x67,0x2f,0x47,0x72,0x61,0x70,0x68, + 0x69,0x63,0x73,0x2f,0x53,0x56,0x47,0x2f,0x31,0x2e, + 0x31,0x2f,0x44,0x54,0x44,0x2f,0x73,0x76,0x67,0x31, + 0x31,0x2e,0x64,0x74,0x64,0x22,0x3e,0x0a,0x3c,0x73, + 0x76,0x67,0x20,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e, + 0x3d,0x22,0x31,0x2e,0x31,0x22,0x20,0x78,0x6d,0x6c, + 0x6e,0x73,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, + 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, + 0x67,0x2f,0x32,0x30,0x30,0x30,0x2f,0x73,0x76,0x67, + 0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78,0x6c, + 0x69,0x6e,0x6b,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a, + 0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f, + 0x72,0x67,0x2f,0x31,0x39,0x39,0x39,0x2f,0x78,0x6c, + 0x69,0x6e,0x6b,0x22,0x20,0x78,0x3d,0x22,0x30,0x22, + 0x20,0x79,0x3d,0x22,0x30,0x22,0x20,0x77,0x69,0x64, + 0x74,0x68,0x3d,0x22,0x33,0x37,0x2e,0x30,0x36,0x31, + 0x22,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3d,0x22, + 0x33,0x37,0x2e,0x30,0x36,0x31,0x22,0x20,0x76,0x69, + 0x65,0x77,0x42,0x6f,0x78,0x3d,0x22,0x30,0x2c,0x20, + 0x30,0x2c,0x20,0x33,0x37,0x2e,0x30,0x36,0x31,0x2c, + 0x20,0x33,0x37,0x2e,0x30,0x36,0x31,0x22,0x3e,0x0a, + 0x20,0x20,0x3c,0x67,0x20,0x69,0x64,0x3d,0x22,0x45, + 0x62,0x65,0x6e,0x65,0x5f,0x31,0x22,0x3e,0x0a,0x20, + 0x20,0x20,0x20,0x3c,0x67,0x3e,0x0a,0x20,0x20,0x20, + 0x20,0x20,0x20,0x3c,0x70,0x61,0x74,0x68,0x20,0x64, + 0x3d,0x22,0x4d,0x31,0x34,0x2e,0x38,0x36,0x32,0x2c, + 0x31,0x38,0x2e,0x35,0x36,0x37,0x20,0x43,0x31,0x34, + 0x2e,0x38,0x36,0x32,0x2c,0x31,0x36,0x2e,0x35,0x35, + 0x34,0x20,0x31,0x36,0x2e,0x35,0x30,0x31,0x2c,0x31, + 0x34,0x2e,0x39,0x31,0x38,0x20,0x31,0x38,0x2e,0x35, + 0x31,0x33,0x2c,0x31,0x34,0x2e,0x39,0x31,0x38,0x20, + 0x43,0x32,0x30,0x2e,0x35,0x32,0x35,0x2c,0x31,0x34, + 0x2e,0x39,0x31,0x38,0x20,0x32,0x32,0x2e,0x31,0x36, + 0x33,0x2c,0x31,0x36,0x2e,0x35,0x35,0x36,0x20,0x32, + 0x32,0x2e,0x31,0x36,0x33,0x2c,0x31,0x38,0x2e,0x35, + 0x36,0x37,0x20,0x43,0x32,0x32,0x2e,0x31,0x36,0x33, + 0x2c,0x32,0x30,0x2e,0x35,0x38,0x20,0x32,0x30,0x2e, + 0x35,0x32,0x34,0x2c,0x32,0x32,0x2e,0x32,0x31,0x37, + 0x20,0x31,0x38,0x2e,0x35,0x31,0x33,0x2c,0x32,0x32, + 0x2e,0x32,0x31,0x37,0x20,0x43,0x31,0x36,0x2e,0x35, + 0x2c,0x32,0x32,0x2e,0x32,0x31,0x38,0x20,0x31,0x34, + 0x2e,0x38,0x36,0x32,0x2c,0x32,0x30,0x2e,0x35,0x38, + 0x20,0x31,0x34,0x2e,0x38,0x36,0x32,0x2c,0x31,0x38, + 0x2e,0x35,0x36,0x37,0x20,0x7a,0x20,0x4d,0x32,0x30, + 0x2e,0x36,0x36,0x34,0x2c,0x31,0x38,0x2e,0x35,0x36, + 0x37,0x20,0x43,0x32,0x30,0x2e,0x36,0x36,0x34,0x2c, + 0x31,0x37,0x2e,0x33,0x38,0x31,0x20,0x31,0x39,0x2e, + 0x36,0x39,0x39,0x2c,0x31,0x36,0x2e,0x34,0x31,0x38, + 0x20,0x31,0x38,0x2e,0x35,0x31,0x34,0x2c,0x31,0x36, + 0x2e,0x34,0x31,0x38,0x20,0x43,0x31,0x37,0x2e,0x33, + 0x32,0x39,0x2c,0x31,0x36,0x2e,0x34,0x31,0x38,0x20, + 0x31,0x36,0x2e,0x33,0x36,0x33,0x2c,0x31,0x37,0x2e, + 0x33,0x38,0x33,0x20,0x31,0x36,0x2e,0x33,0x36,0x33, + 0x2c,0x31,0x38,0x2e,0x35,0x36,0x37,0x20,0x43,0x31, + 0x36,0x2e,0x33,0x36,0x33,0x2c,0x31,0x39,0x2e,0x37, + 0x35,0x33,0x20,0x31,0x37,0x2e,0x33,0x32,0x39,0x2c, + 0x32,0x30,0x2e,0x37,0x31,0x37,0x20,0x31,0x38,0x2e, + 0x35,0x31,0x34,0x2c,0x32,0x30,0x2e,0x37,0x31,0x37, + 0x20,0x43,0x31,0x39,0x2e,0x36,0x39,0x39,0x2c,0x32, + 0x30,0x2e,0x37,0x31,0x38,0x20,0x32,0x30,0x2e,0x36, + 0x36,0x34,0x2c,0x31,0x39,0x2e,0x37,0x35,0x33,0x20, + 0x32,0x30,0x2e,0x36,0x36,0x34,0x2c,0x31,0x38,0x2e, + 0x35,0x36,0x37,0x20,0x7a,0x22,0x20,0x66,0x69,0x6c, + 0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46,0x46, + 0x22,0x2f,0x3e,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, + 0x3c,0x70,0x61,0x74,0x68,0x20,0x64,0x3d,0x22,0x4d, + 0x32,0x38,0x2e,0x34,0x32,0x37,0x2c,0x32,0x31,0x2e, + 0x35,0x37,0x32,0x20,0x4c,0x32,0x38,0x2e,0x34,0x32, + 0x37,0x2c,0x31,0x35,0x2e,0x35,0x36,0x20,0x43,0x32, + 0x38,0x2e,0x34,0x32,0x37,0x2c,0x31,0x35,0x2e,0x32, + 0x38,0x37,0x20,0x32,0x38,0x2e,0x35,0x37,0x37,0x2c, + 0x31,0x35,0x2e,0x30,0x33,0x35,0x20,0x32,0x38,0x2e, + 0x38,0x31,0x37,0x2c,0x31,0x34,0x2e,0x39,0x30,0x33, + 0x20,0x43,0x32,0x39,0x2e,0x30,0x35,0x38,0x2c,0x31, + 0x34,0x2e,0x37,0x37,0x31,0x20,0x32,0x39,0x2e,0x33, + 0x35,0x31,0x2c,0x31,0x34,0x2e,0x37,0x38,0x32,0x20, + 0x32,0x39,0x2e,0x35,0x38,0x33,0x2c,0x31,0x34,0x2e, + 0x39,0x32,0x39,0x20,0x4c,0x33,0x34,0x2e,0x32,0x36, + 0x37,0x2c,0x31,0x37,0x2e,0x39,0x33,0x34,0x20,0x43, + 0x33,0x34,0x2e,0x36,0x39,0x38,0x2c,0x31,0x38,0x2e, + 0x32,0x31,0x20,0x33,0x34,0x2e,0x36,0x39,0x37,0x2c, + 0x31,0x38,0x2e,0x39,0x32,0x20,0x33,0x34,0x2e,0x32, + 0x36,0x37,0x2c,0x31,0x39,0x2e,0x31,0x39,0x38,0x20, + 0x4c,0x32,0x39,0x2e,0x35,0x38,0x33,0x2c,0x32,0x32, + 0x2e,0x32,0x30,0x33,0x20,0x43,0x32,0x39,0x2e,0x33, + 0x35,0x32,0x2c,0x32,0x32,0x2e,0x33,0x35,0x20,0x32, + 0x39,0x2e,0x30,0x35,0x39,0x2c,0x32,0x32,0x2e,0x33, + 0x36,0x32,0x20,0x32,0x38,0x2e,0x38,0x31,0x37,0x2c, + 0x32,0x32,0x2e,0x32,0x32,0x39,0x20,0x43,0x32,0x38, + 0x2e,0x35,0x37,0x37,0x2c,0x32,0x32,0x2e,0x30,0x39, + 0x39,0x20,0x32,0x38,0x2e,0x34,0x32,0x37,0x2c,0x32, + 0x31,0x2e,0x38,0x34,0x37,0x20,0x32,0x38,0x2e,0x34, + 0x32,0x37,0x2c,0x32,0x31,0x2e,0x35,0x37,0x32,0x20, + 0x7a,0x20,0x4d,0x32,0x39,0x2e,0x39,0x32,0x37,0x2c, + 0x31,0x36,0x2e,0x39,0x33,0x33,0x20,0x4c,0x32,0x39, + 0x2e,0x39,0x32,0x37,0x2c,0x32,0x30,0x2e,0x32,0x30, + 0x31,0x20,0x4c,0x33,0x32,0x2e,0x34,0x37,0x32,0x2c, + 0x31,0x38,0x2e,0x35,0x36,0x36,0x20,0x4c,0x32,0x39, + 0x2e,0x39,0x32,0x37,0x2c,0x31,0x36,0x2e,0x39,0x33, + 0x33,0x20,0x7a,0x22,0x20,0x66,0x69,0x6c,0x6c,0x3d, + 0x22,0x23,0x46,0x46,0x46,0x46,0x46,0x46,0x22,0x2f, + 0x3e,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3c,0x67, + 0x3e,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x3c,0x70,0x61,0x74,0x68,0x20,0x64,0x3d,0x22,0x4d, + 0x31,0x38,0x2e,0x35,0x31,0x33,0x2c,0x33,0x2e,0x31, + 0x36,0x31,0x20,0x4c,0x31,0x35,0x2e,0x35,0x30,0x39, + 0x2c,0x37,0x2e,0x38,0x34,0x35,0x20,0x4c,0x32,0x31, + 0x2e,0x35,0x31,0x39,0x2c,0x37,0x2e,0x38,0x34,0x35, + 0x20,0x4c,0x31,0x38,0x2e,0x35,0x31,0x33,0x2c,0x33, + 0x2e,0x31,0x36,0x31,0x20,0x7a,0x22,0x20,0x66,0x69, + 0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46, + 0x46,0x22,0x2f,0x3e,0x0a,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x3c,0x70,0x61,0x74,0x68,0x20,0x64, + 0x3d,0x22,0x4d,0x31,0x34,0x2e,0x37,0x35,0x39,0x2c, + 0x37,0x2e,0x38,0x34,0x35,0x20,0x43,0x31,0x34,0x2e, + 0x37,0x35,0x39,0x2c,0x37,0x2e,0x37,0x30,0x34,0x20, + 0x31,0x34,0x2e,0x37,0x39,0x39,0x2c,0x37,0x2e,0x35, + 0x36,0x33,0x20,0x31,0x34,0x2e,0x38,0x37,0x38,0x2c, + 0x37,0x2e,0x34,0x34,0x20,0x4c,0x31,0x37,0x2e,0x38, + 0x38,0x31,0x2c,0x32,0x2e,0x37,0x35,0x36,0x20,0x43, + 0x31,0x38,0x2e,0x30,0x31,0x39,0x2c,0x32,0x2e,0x35, + 0x34,0x31,0x20,0x31,0x38,0x2e,0x32,0x35,0x37,0x2c, + 0x32,0x2e,0x34,0x31,0x31,0x20,0x31,0x38,0x2e,0x35, + 0x31,0x32,0x2c,0x32,0x2e,0x34,0x31,0x31,0x20,0x43, + 0x31,0x38,0x2e,0x37,0x36,0x37,0x2c,0x32,0x2e,0x34, + 0x31,0x31,0x20,0x31,0x39,0x2e,0x30,0x30,0x35,0x2c, + 0x32,0x2e,0x35,0x34,0x31,0x20,0x31,0x39,0x2e,0x31, + 0x34,0x33,0x2c,0x32,0x2e,0x37,0x35,0x36,0x20,0x4c, + 0x32,0x32,0x2e,0x31,0x34,0x39,0x2c,0x37,0x2e,0x34, + 0x34,0x20,0x43,0x32,0x32,0x2e,0x32,0x39,0x37,0x2c, + 0x37,0x2e,0x36,0x37,0x20,0x32,0x32,0x2e,0x33,0x30, + 0x37,0x2c,0x37,0x2e,0x39,0x36,0x34,0x20,0x32,0x32, + 0x2e,0x31,0x37,0x36,0x2c,0x38,0x2e,0x32,0x30,0x36, + 0x20,0x43,0x32,0x32,0x2e,0x30,0x34,0x35,0x2c,0x38, + 0x2e,0x34,0x34,0x36,0x20,0x32,0x31,0x2e,0x37,0x39, + 0x32,0x2c,0x38,0x2e,0x35,0x39,0x36,0x20,0x32,0x31, + 0x2e,0x35,0x31,0x38,0x2c,0x38,0x2e,0x35,0x39,0x36, + 0x20,0x4c,0x31,0x35,0x2e,0x35,0x30,0x38,0x2c,0x38, + 0x2e,0x35,0x39,0x36,0x20,0x43,0x31,0x35,0x2e,0x32, + 0x33,0x34,0x2c,0x38,0x2e,0x35,0x39,0x36,0x20,0x31, + 0x34,0x2e,0x39,0x38,0x32,0x2c,0x38,0x2e,0x34,0x34, + 0x38,0x20,0x31,0x34,0x2e,0x38,0x35,0x2c,0x38,0x2e, + 0x32,0x30,0x36,0x20,0x43,0x31,0x34,0x2e,0x37,0x38, + 0x39,0x2c,0x38,0x2e,0x30,0x39,0x32,0x20,0x31,0x34, + 0x2e,0x37,0x35,0x39,0x2c,0x37,0x2e,0x39,0x36,0x38, + 0x20,0x31,0x34,0x2e,0x37,0x35,0x39,0x2c,0x37,0x2e, + 0x38,0x34,0x35,0x20,0x7a,0x20,0x4d,0x31,0x38,0x2e, + 0x35,0x31,0x33,0x2c,0x34,0x2e,0x35,0x35,0x20,0x4c, + 0x31,0x36,0x2e,0x38,0x38,0x31,0x2c,0x37,0x2e,0x30, + 0x39,0x35,0x20,0x4c,0x32,0x30,0x2e,0x31,0x34,0x36, + 0x2c,0x37,0x2e,0x30,0x39,0x35,0x20,0x4c,0x31,0x38, + 0x2e,0x35,0x31,0x33,0x2c,0x34,0x2e,0x35,0x35,0x20, + 0x7a,0x22,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23, + 0x46,0x46,0x46,0x46,0x46,0x46,0x22,0x2f,0x3e,0x0a, + 0x20,0x20,0x20,0x20,0x20,0x20,0x3c,0x2f,0x67,0x3e, + 0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3c,0x70,0x61, + 0x74,0x68,0x20,0x64,0x3d,0x22,0x4d,0x31,0x34,0x2e, + 0x37,0x35,0x39,0x2c,0x32,0x39,0x2e,0x32,0x33,0x31, + 0x20,0x43,0x31,0x34,0x2e,0x37,0x35,0x39,0x2c,0x32, + 0x39,0x2e,0x31,0x30,0x37,0x20,0x31,0x34,0x2e,0x37, + 0x38,0x39,0x2c,0x32,0x38,0x2e,0x39,0x38,0x35,0x20, + 0x31,0x34,0x2e,0x38,0x35,0x31,0x2c,0x32,0x38,0x2e, + 0x38,0x37,0x33,0x20,0x43,0x31,0x34,0x2e,0x39,0x38, + 0x33,0x2c,0x32,0x38,0x2e,0x36,0x33,0x32,0x20,0x31, + 0x35,0x2e,0x32,0x33,0x35,0x2c,0x32,0x38,0x2e,0x34, + 0x38,0x31,0x20,0x31,0x35,0x2e,0x35,0x30,0x39,0x2c, + 0x32,0x38,0x2e,0x34,0x38,0x31,0x20,0x4c,0x32,0x31, + 0x2e,0x35,0x31,0x39,0x2c,0x32,0x38,0x2e,0x34,0x38, + 0x31,0x20,0x43,0x32,0x31,0x2e,0x37,0x39,0x33,0x2c, + 0x32,0x38,0x2e,0x34,0x38,0x31,0x20,0x32,0x32,0x2e, + 0x30,0x34,0x35,0x2c,0x32,0x38,0x2e,0x36,0x33,0x20, + 0x32,0x32,0x2e,0x31,0x37,0x37,0x2c,0x32,0x38,0x2e, + 0x38,0x37,0x33,0x20,0x43,0x32,0x32,0x2e,0x33,0x30, + 0x38,0x2c,0x32,0x39,0x2e,0x31,0x31,0x32,0x20,0x32, + 0x32,0x2e,0x33,0x2c,0x32,0x39,0x2e,0x34,0x30,0x36, + 0x20,0x32,0x32,0x2e,0x31,0x35,0x2c,0x32,0x39,0x2e, + 0x36,0x33,0x38,0x20,0x4c,0x31,0x39,0x2e,0x31,0x34, + 0x35,0x2c,0x33,0x34,0x2e,0x33,0x32,0x33,0x20,0x43, + 0x31,0x39,0x2e,0x30,0x30,0x37,0x2c,0x33,0x34,0x2e, + 0x35,0x33,0x38,0x20,0x31,0x38,0x2e,0x37,0x36,0x39, + 0x2c,0x33,0x34,0x2e,0x36,0x36,0x38,0x20,0x31,0x38, + 0x2e,0x35,0x31,0x34,0x2c,0x33,0x34,0x2e,0x36,0x36, + 0x38,0x20,0x43,0x31,0x38,0x2e,0x32,0x35,0x39,0x2c, + 0x33,0x34,0x2e,0x36,0x36,0x38,0x20,0x31,0x38,0x2e, + 0x30,0x32,0x31,0x2c,0x33,0x34,0x2e,0x35,0x33,0x38, + 0x20,0x31,0x37,0x2e,0x38,0x38,0x33,0x2c,0x33,0x34, + 0x2e,0x33,0x32,0x33,0x20,0x4c,0x31,0x34,0x2e,0x38, + 0x37,0x39,0x2c,0x32,0x39,0x2e,0x36,0x33,0x38,0x20, + 0x43,0x31,0x34,0x2e,0x37,0x39,0x39,0x2c,0x32,0x39, + 0x2e,0x35,0x31,0x34,0x20,0x31,0x34,0x2e,0x37,0x35, + 0x39,0x2c,0x32,0x39,0x2e,0x33,0x37,0x32,0x20,0x31, + 0x34,0x2e,0x37,0x35,0x39,0x2c,0x32,0x39,0x2e,0x32, + 0x33,0x31,0x20,0x7a,0x20,0x4d,0x32,0x30,0x2e,0x31, + 0x34,0x37,0x2c,0x32,0x39,0x2e,0x39,0x38,0x31,0x20, + 0x4c,0x31,0x36,0x2e,0x38,0x38,0x31,0x2c,0x32,0x39, + 0x2e,0x39,0x38,0x31,0x20,0x4c,0x31,0x38,0x2e,0x35, + 0x31,0x34,0x2c,0x33,0x32,0x2e,0x35,0x32,0x37,0x20, + 0x4c,0x32,0x30,0x2e,0x31,0x34,0x37,0x2c,0x32,0x39, + 0x2e,0x39,0x38,0x31,0x20,0x7a,0x22,0x20,0x66,0x69, + 0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46, + 0x46,0x22,0x2f,0x3e,0x0a,0x20,0x20,0x20,0x20,0x20, + 0x20,0x3c,0x70,0x61,0x74,0x68,0x20,0x64,0x3d,0x22, + 0x4d,0x32,0x2e,0x34,0x31,0x37,0x2c,0x31,0x38,0x2e, + 0x35,0x36,0x36,0x20,0x4c,0x32,0x2e,0x34,0x31,0x37, + 0x2c,0x31,0x38,0x2e,0x35,0x36,0x36,0x20,0x43,0x32, + 0x2e,0x34,0x31,0x37,0x2c,0x31,0x38,0x2e,0x33,0x31, + 0x31,0x20,0x32,0x2e,0x35,0x34,0x37,0x2c,0x31,0x38, + 0x2e,0x30,0x37,0x34,0x20,0x32,0x2e,0x37,0x36,0x32, + 0x2c,0x31,0x37,0x2e,0x39,0x33,0x35,0x20,0x4c,0x37, + 0x2e,0x34,0x34,0x36,0x2c,0x31,0x34,0x2e,0x39,0x33, + 0x20,0x43,0x37,0x2e,0x36,0x37,0x37,0x2c,0x31,0x34, + 0x2e,0x37,0x38,0x33,0x20,0x37,0x2e,0x39,0x37,0x2c, + 0x31,0x34,0x2e,0x37,0x37,0x32,0x20,0x38,0x2e,0x32, + 0x31,0x32,0x2c,0x31,0x34,0x2e,0x39,0x30,0x34,0x20, + 0x43,0x38,0x2e,0x34,0x35,0x34,0x2c,0x31,0x35,0x2e, + 0x30,0x33,0x36,0x20,0x38,0x2e,0x36,0x30,0x33,0x2c, + 0x31,0x35,0x2e,0x32,0x38,0x38,0x20,0x38,0x2e,0x36, + 0x30,0x33,0x2c,0x31,0x35,0x2e,0x35,0x36,0x31,0x20, + 0x4c,0x38,0x2e,0x36,0x30,0x33,0x2c,0x32,0x31,0x2e, + 0x35,0x37,0x33,0x20,0x43,0x38,0x2e,0x36,0x30,0x33, + 0x2c,0x32,0x31,0x2e,0x38,0x34,0x36,0x20,0x38,0x2e, + 0x34,0x35,0x35,0x2c,0x32,0x32,0x2e,0x30,0x39,0x38, + 0x20,0x38,0x2e,0x32,0x31,0x32,0x2c,0x32,0x32,0x2e, + 0x32,0x33,0x20,0x43,0x37,0x2e,0x39,0x37,0x32,0x2c, + 0x32,0x32,0x2e,0x33,0x36,0x33,0x20,0x37,0x2e,0x36, + 0x37,0x39,0x2c,0x32,0x32,0x2e,0x33,0x35,0x31,0x20, + 0x37,0x2e,0x34,0x34,0x36,0x2c,0x32,0x32,0x2e,0x32, + 0x30,0x34,0x20,0x4c,0x32,0x2e,0x37,0x36,0x32,0x2c, + 0x31,0x39,0x2e,0x31,0x39,0x39,0x20,0x43,0x32,0x2e, + 0x35,0x34,0x37,0x2c,0x31,0x39,0x2e,0x30,0x35,0x39, + 0x20,0x32,0x2e,0x34,0x31,0x37,0x2c,0x31,0x38,0x2e, + 0x38,0x32,0x32,0x20,0x32,0x2e,0x34,0x31,0x37,0x2c, + 0x31,0x38,0x2e,0x35,0x36,0x36,0x20,0x7a,0x20,0x4d, + 0x37,0x2e,0x31,0x30,0x31,0x2c,0x31,0x36,0x2e,0x39, + 0x33,0x33,0x20,0x4c,0x34,0x2e,0x35,0x35,0x36,0x2c, + 0x31,0x38,0x2e,0x35,0x36,0x36,0x20,0x4c,0x37,0x2e, + 0x31,0x30,0x31,0x2c,0x32,0x30,0x2e,0x32,0x30,0x31, + 0x20,0x4c,0x37,0x2e,0x31,0x30,0x31,0x2c,0x31,0x36, + 0x2e,0x39,0x33,0x33,0x20,0x7a,0x22,0x20,0x66,0x69, + 0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46, + 0x46,0x22,0x2f,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c, + 0x2f,0x67,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x70, + 0x61,0x74,0x68,0x20,0x64,0x3d,0x22,0x4d,0x31,0x38, + 0x2e,0x35,0x33,0x2c,0x30,0x20,0x43,0x32,0x38,0x2e, + 0x37,0x36,0x35,0x2c,0x30,0x20,0x33,0x37,0x2e,0x30, + 0x36,0x31,0x2c,0x38,0x2e,0x32,0x39,0x36,0x20,0x33, + 0x37,0x2e,0x30,0x36,0x31,0x2c,0x31,0x38,0x2e,0x35, + 0x33,0x31,0x20,0x43,0x33,0x37,0x2e,0x30,0x36,0x31, + 0x2c,0x32,0x38,0x2e,0x37,0x36,0x35,0x20,0x32,0x38, + 0x2e,0x37,0x36,0x35,0x2c,0x33,0x37,0x2e,0x30,0x36, + 0x31,0x20,0x31,0x38,0x2e,0x35,0x33,0x2c,0x33,0x37, + 0x2e,0x30,0x36,0x31,0x20,0x43,0x38,0x2e,0x32,0x39, + 0x36,0x2c,0x33,0x37,0x2e,0x30,0x36,0x31,0x20,0x30, + 0x2c,0x32,0x38,0x2e,0x37,0x36,0x35,0x20,0x30,0x2c, + 0x31,0x38,0x2e,0x35,0x33,0x31,0x20,0x43,0x30,0x2c, + 0x38,0x2e,0x32,0x39,0x36,0x20,0x38,0x2e,0x32,0x39, + 0x36,0x2c,0x30,0x20,0x31,0x38,0x2e,0x35,0x33,0x2c, + 0x30,0x20,0x7a,0x20,0x4d,0x31,0x38,0x2e,0x35,0x33, + 0x2c,0x31,0x20,0x43,0x38,0x2e,0x38,0x34,0x39,0x2c, + 0x31,0x20,0x31,0x2c,0x38,0x2e,0x38,0x34,0x39,0x20, + 0x31,0x2c,0x31,0x38,0x2e,0x35,0x33,0x31,0x20,0x43, + 0x31,0x2c,0x32,0x38,0x2e,0x32,0x31,0x32,0x20,0x38, + 0x2e,0x38,0x34,0x39,0x2c,0x33,0x36,0x2e,0x30,0x36, + 0x31,0x20,0x31,0x38,0x2e,0x35,0x33,0x2c,0x33,0x36, + 0x2e,0x30,0x36,0x31,0x20,0x43,0x32,0x38,0x2e,0x32, + 0x31,0x32,0x2c,0x33,0x36,0x2e,0x30,0x36,0x31,0x20, + 0x33,0x36,0x2e,0x30,0x36,0x31,0x2c,0x32,0x38,0x2e, + 0x32,0x31,0x32,0x20,0x33,0x36,0x2e,0x30,0x36,0x31, + 0x2c,0x31,0x38,0x2e,0x35,0x33,0x31,0x20,0x43,0x33, + 0x36,0x2e,0x30,0x36,0x31,0x2c,0x38,0x2e,0x38,0x34, + 0x39,0x20,0x32,0x38,0x2e,0x32,0x31,0x32,0x2c,0x31, + 0x20,0x31,0x38,0x2e,0x35,0x33,0x2c,0x31,0x20,0x7a, + 0x22,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46, + 0x46,0x46,0x46,0x46,0x46,0x22,0x2f,0x3e,0x0a,0x20, + 0x20,0x3c,0x2f,0x67,0x3e,0x0a,0x3c,0x2f,0x73,0x76, + 0x67,0x3e,0x0a +}; + diff --git a/data/converted/help_button_a_svg.cpp b/data/converted/help_button_a_svg.cpp index 14120f83a2..cedb8d212a 100644 --- a/data/converted/help_button_a_svg.cpp +++ b/data/converted/help_button_a_svg.cpp @@ -2,105 +2,104 @@ #include "../Resources.h" -const size_t help_button_a_svg_size = 981; -const unsigned char help_button_a_svg_data[981] = { +const size_t help_button_a_svg_size = 965; +const unsigned char help_button_a_svg_data[965] = { 0x3c,0x3f,0x78,0x6d,0x6c,0x20,0x76,0x65,0x72,0x73, 0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x30,0x22,0x20, 0x65,0x6e,0x63,0x6f,0x64,0x69,0x6e,0x67,0x3d,0x22, - 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0d,0x0a, - 0x3c,0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72, - 0x61,0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62, - 0x65,0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61, - 0x74,0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33, - 0x2c,0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f, - 0x72,0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e, - 0x20,0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72, - 0x73,0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30, - 0x20,0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20, - 0x20,0x2d,0x2d,0x3e,0x0d,0x0a,0x3c,0x21,0x44,0x4f, - 0x43,0x54,0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20, - 0x50,0x55,0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f, - 0x2f,0x57,0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20, - 0x53,0x56,0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45, - 0x4e,0x22,0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, - 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, - 0x67,0x2f,0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73, - 0x2f,0x53,0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44, - 0x54,0x44,0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64, - 0x74,0x64,0x22,0x3e,0x0d,0x0a,0x3c,0x73,0x76,0x67, - 0x20,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22, - 0x31,0x2e,0x31,0x22,0x20,0x69,0x64,0x3d,0x22,0x5f, - 0x78,0x33,0x30,0x5f,0x22,0x20,0x78,0x6d,0x6c,0x6e, - 0x73,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f, - 0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67, - 0x2f,0x32,0x30,0x30,0x30,0x2f,0x73,0x76,0x67,0x22, - 0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78,0x6c,0x69, - 0x6e,0x6b,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, - 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, - 0x67,0x2f,0x31,0x39,0x39,0x39,0x2f,0x78,0x6c,0x69, - 0x6e,0x6b,0x22,0x20,0x78,0x3d,0x22,0x30,0x70,0x78, - 0x22,0x20,0x79,0x3d,0x22,0x30,0x70,0x78,0x22,0x0d, - 0x0a,0x09,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22, - 0x33,0x37,0x2e,0x30,0x36,0x31,0x70,0x78,0x22,0x20, - 0x68,0x65,0x69,0x67,0x68,0x74,0x3d,0x22,0x33,0x37, - 0x2e,0x30,0x36,0x31,0x70,0x78,0x22,0x20,0x76,0x69, - 0x65,0x77,0x42,0x6f,0x78,0x3d,0x22,0x30,0x20,0x30, - 0x20,0x33,0x37,0x2e,0x30,0x36,0x31,0x20,0x33,0x37, - 0x2e,0x30,0x36,0x31,0x22,0x20,0x65,0x6e,0x61,0x62, - 0x6c,0x65,0x2d,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f, - 0x75,0x6e,0x64,0x3d,0x22,0x6e,0x65,0x77,0x20,0x30, - 0x20,0x30,0x20,0x33,0x37,0x2e,0x30,0x36,0x31,0x20, - 0x33,0x37,0x2e,0x30,0x36,0x31,0x22,0x20,0x78,0x6d, - 0x6c,0x3a,0x73,0x70,0x61,0x63,0x65,0x3d,0x22,0x70, - 0x72,0x65,0x73,0x65,0x72,0x76,0x65,0x22,0x3e,0x0d, - 0x0a,0x3c,0x67,0x3e,0x0d,0x0a,0x09,0x3c,0x67,0x3e, - 0x0d,0x0a,0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20, - 0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46, - 0x46,0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x31, - 0x38,0x2e,0x39,0x31,0x34,0x2c,0x31,0x34,0x2e,0x35, - 0x37,0x39,0x6c,0x2d,0x31,0x2e,0x36,0x38,0x32,0x2c, - 0x35,0x2e,0x33,0x30,0x38,0x68,0x33,0x2e,0x34,0x30, - 0x35,0x6c,0x2d,0x31,0x2e,0x36,0x37,0x2d,0x35,0x2e, - 0x33,0x30,0x38,0x48,0x31,0x38,0x2e,0x39,0x31,0x34, - 0x7a,0x20,0x4d,0x31,0x38,0x2e,0x35,0x33,0x31,0x2c, - 0x33,0x2e,0x30,0x32,0x39,0x63,0x2d,0x38,0x2e,0x35, - 0x36,0x32,0x2c,0x30,0x2d,0x31,0x35,0x2e,0x35,0x30, - 0x31,0x2c,0x36,0x2e,0x39,0x34,0x2d,0x31,0x35,0x2e, - 0x35,0x30,0x31,0x2c,0x31,0x35,0x2e,0x35,0x0d,0x0a, - 0x09,0x09,0x09,0x63,0x30,0x2c,0x38,0x2e,0x35,0x36, - 0x33,0x2c,0x36,0x2e,0x39,0x33,0x39,0x2c,0x31,0x35, - 0x2e,0x35,0x30,0x32,0x2c,0x31,0x35,0x2e,0x35,0x30, - 0x31,0x2c,0x31,0x35,0x2e,0x35,0x30,0x32,0x53,0x33, - 0x34,0x2e,0x30,0x33,0x2c,0x32,0x37,0x2e,0x30,0x39, - 0x31,0x2c,0x33,0x34,0x2e,0x30,0x33,0x2c,0x31,0x38, - 0x2e,0x35,0x32,0x39,0x43,0x33,0x34,0x2e,0x30,0x33, - 0x2c,0x39,0x2e,0x39,0x37,0x2c,0x32,0x37,0x2e,0x30, - 0x39,0x31,0x2c,0x33,0x2e,0x30,0x32,0x39,0x2c,0x31, - 0x38,0x2e,0x35,0x33,0x31,0x2c,0x33,0x2e,0x30,0x32, - 0x39,0x7a,0x20,0x4d,0x32,0x32,0x2e,0x32,0x32,0x37, - 0x2c,0x32,0x34,0x2e,0x39,0x32,0x35,0x0d,0x0a,0x09, - 0x09,0x09,0x6c,0x2d,0x30,0x2e,0x39,0x31,0x39,0x2d, - 0x32,0x2e,0x39,0x31,0x33,0x68,0x2d,0x34,0x2e,0x37, - 0x34,0x31,0x6c,0x2d,0x30,0x2e,0x39,0x31,0x38,0x2c, - 0x32,0x2e,0x39,0x31,0x33,0x68,0x2d,0x32,0x2e,0x37, - 0x33,0x35,0x6c,0x34,0x2e,0x36,0x34,0x36,0x2d,0x31, - 0x33,0x2e,0x35,0x30,0x39,0x68,0x32,0x2e,0x37,0x37, - 0x34,0x6c,0x34,0x2e,0x36,0x32,0x39,0x2c,0x31,0x33, - 0x2e,0x35,0x30,0x39,0x48,0x32,0x32,0x2e,0x32,0x32, - 0x37,0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x09,0x3c,0x2f, - 0x67,0x3e,0x0d,0x0a,0x3c,0x2f,0x67,0x3e,0x0d,0x0a, - 0x3c,0x67,0x20,0x6f,0x70,0x61,0x63,0x69,0x74,0x79, - 0x3d,0x22,0x30,0x22,0x3e,0x0d,0x0a,0x09,0x3c,0x70, - 0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22, - 0x23,0x46,0x46,0x46,0x46,0x46,0x46,0x22,0x20,0x64, - 0x3d,0x22,0x4d,0x33,0x36,0x2e,0x39,0x36,0x31,0x2c, - 0x30,0x2e,0x31,0x76,0x33,0x36,0x2e,0x38,0x36,0x31, - 0x48,0x30,0x2e,0x31,0x56,0x30,0x2e,0x31,0x48,0x33, - 0x36,0x2e,0x39,0x36,0x31,0x20,0x4d,0x33,0x37,0x2e, - 0x30,0x36,0x31,0x2c,0x30,0x48,0x30,0x76,0x33,0x37, - 0x2e,0x30,0x36,0x68,0x33,0x37,0x2e,0x30,0x36,0x31, - 0x56,0x30,0x4c,0x33,0x37,0x2e,0x30,0x36,0x31,0x2c, - 0x30,0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x3c,0x2f,0x67, - 0x3e,0x0d,0x0a,0x3c,0x2f,0x73,0x76,0x67,0x3e,0x0d, - 0x0a + 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0a,0x3c, + 0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72,0x61, + 0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62,0x65, + 0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61,0x74, + 0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33,0x2c, + 0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f,0x72, + 0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e,0x20, + 0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72,0x73, + 0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30,0x20, + 0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20,0x20, + 0x2d,0x2d,0x3e,0x0a,0x3c,0x21,0x44,0x4f,0x43,0x54, + 0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20,0x50,0x55, + 0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f,0x2f,0x57, + 0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20,0x53,0x56, + 0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45,0x4e,0x22, + 0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73,0x2f,0x53, + 0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44,0x54,0x44, + 0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64,0x74,0x64, + 0x22,0x3e,0x0a,0x3c,0x73,0x76,0x67,0x20,0x76,0x65, + 0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x31, + 0x22,0x20,0x69,0x64,0x3d,0x22,0x5f,0x78,0x33,0x30, + 0x5f,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3d,0x22, + 0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77, + 0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f,0x32,0x30, + 0x30,0x30,0x2f,0x73,0x76,0x67,0x22,0x20,0x78,0x6d, + 0x6c,0x6e,0x73,0x3a,0x78,0x6c,0x69,0x6e,0x6b,0x3d, + 0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77, + 0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f,0x31, + 0x39,0x39,0x39,0x2f,0x78,0x6c,0x69,0x6e,0x6b,0x22, + 0x20,0x78,0x3d,0x22,0x30,0x70,0x78,0x22,0x20,0x79, + 0x3d,0x22,0x30,0x70,0x78,0x22,0x0a,0x09,0x20,0x77, + 0x69,0x64,0x74,0x68,0x3d,0x22,0x33,0x37,0x2e,0x30, + 0x36,0x31,0x70,0x78,0x22,0x20,0x68,0x65,0x69,0x67, + 0x68,0x74,0x3d,0x22,0x33,0x37,0x2e,0x30,0x36,0x31, + 0x70,0x78,0x22,0x20,0x76,0x69,0x65,0x77,0x42,0x6f, + 0x78,0x3d,0x22,0x30,0x20,0x30,0x20,0x33,0x37,0x2e, + 0x30,0x36,0x31,0x20,0x33,0x37,0x2e,0x30,0x36,0x31, + 0x22,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0x2d,0x62, + 0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x3d, + 0x22,0x6e,0x65,0x77,0x20,0x30,0x20,0x30,0x20,0x33, + 0x37,0x2e,0x30,0x36,0x31,0x20,0x33,0x37,0x2e,0x30, + 0x36,0x31,0x22,0x20,0x78,0x6d,0x6c,0x3a,0x73,0x70, + 0x61,0x63,0x65,0x3d,0x22,0x70,0x72,0x65,0x73,0x65, + 0x72,0x76,0x65,0x22,0x3e,0x0a,0x3c,0x67,0x3e,0x0a, + 0x09,0x3c,0x67,0x3e,0x0a,0x09,0x09,0x3c,0x70,0x61, + 0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23, + 0x46,0x46,0x46,0x46,0x46,0x46,0x22,0x20,0x64,0x3d, + 0x22,0x4d,0x31,0x38,0x2e,0x39,0x31,0x34,0x2c,0x31, + 0x34,0x2e,0x35,0x37,0x39,0x6c,0x2d,0x31,0x2e,0x36, + 0x38,0x32,0x2c,0x35,0x2e,0x33,0x30,0x38,0x68,0x33, + 0x2e,0x34,0x30,0x35,0x6c,0x2d,0x31,0x2e,0x36,0x37, + 0x2d,0x35,0x2e,0x33,0x30,0x38,0x48,0x31,0x38,0x2e, + 0x39,0x31,0x34,0x7a,0x20,0x4d,0x31,0x38,0x2e,0x35, + 0x33,0x31,0x2c,0x33,0x2e,0x30,0x32,0x39,0x63,0x2d, + 0x38,0x2e,0x35,0x36,0x32,0x2c,0x30,0x2d,0x31,0x35, + 0x2e,0x35,0x30,0x31,0x2c,0x36,0x2e,0x39,0x34,0x2d, + 0x31,0x35,0x2e,0x35,0x30,0x31,0x2c,0x31,0x35,0x2e, + 0x35,0x0a,0x09,0x09,0x09,0x63,0x30,0x2c,0x38,0x2e, + 0x35,0x36,0x33,0x2c,0x36,0x2e,0x39,0x33,0x39,0x2c, + 0x31,0x35,0x2e,0x35,0x30,0x32,0x2c,0x31,0x35,0x2e, + 0x35,0x30,0x31,0x2c,0x31,0x35,0x2e,0x35,0x30,0x32, + 0x53,0x33,0x34,0x2e,0x30,0x33,0x2c,0x32,0x37,0x2e, + 0x30,0x39,0x31,0x2c,0x33,0x34,0x2e,0x30,0x33,0x2c, + 0x31,0x38,0x2e,0x35,0x32,0x39,0x43,0x33,0x34,0x2e, + 0x30,0x33,0x2c,0x39,0x2e,0x39,0x37,0x2c,0x32,0x37, + 0x2e,0x30,0x39,0x31,0x2c,0x33,0x2e,0x30,0x32,0x39, + 0x2c,0x31,0x38,0x2e,0x35,0x33,0x31,0x2c,0x33,0x2e, + 0x30,0x32,0x39,0x7a,0x20,0x4d,0x32,0x32,0x2e,0x32, + 0x32,0x37,0x2c,0x32,0x34,0x2e,0x39,0x32,0x35,0x0a, + 0x09,0x09,0x09,0x6c,0x2d,0x30,0x2e,0x39,0x31,0x39, + 0x2d,0x32,0x2e,0x39,0x31,0x33,0x68,0x2d,0x34,0x2e, + 0x37,0x34,0x31,0x6c,0x2d,0x30,0x2e,0x39,0x31,0x38, + 0x2c,0x32,0x2e,0x39,0x31,0x33,0x68,0x2d,0x32,0x2e, + 0x37,0x33,0x35,0x6c,0x34,0x2e,0x36,0x34,0x36,0x2d, + 0x31,0x33,0x2e,0x35,0x30,0x39,0x68,0x32,0x2e,0x37, + 0x37,0x34,0x6c,0x34,0x2e,0x36,0x32,0x39,0x2c,0x31, + 0x33,0x2e,0x35,0x30,0x39,0x48,0x32,0x32,0x2e,0x32, + 0x32,0x37,0x7a,0x22,0x2f,0x3e,0x0a,0x09,0x3c,0x2f, + 0x67,0x3e,0x0a,0x3c,0x2f,0x67,0x3e,0x0a,0x3c,0x67, + 0x20,0x6f,0x70,0x61,0x63,0x69,0x74,0x79,0x3d,0x22, + 0x30,0x22,0x3e,0x0a,0x09,0x3c,0x70,0x61,0x74,0x68, + 0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46, + 0x46,0x46,0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d, + 0x33,0x36,0x2e,0x39,0x36,0x31,0x2c,0x30,0x2e,0x31, + 0x76,0x33,0x36,0x2e,0x38,0x36,0x31,0x48,0x30,0x2e, + 0x31,0x56,0x30,0x2e,0x31,0x48,0x33,0x36,0x2e,0x39, + 0x36,0x31,0x20,0x4d,0x33,0x37,0x2e,0x30,0x36,0x31, + 0x2c,0x30,0x48,0x30,0x76,0x33,0x37,0x2e,0x30,0x36, + 0x68,0x33,0x37,0x2e,0x30,0x36,0x31,0x56,0x30,0x4c, + 0x33,0x37,0x2e,0x30,0x36,0x31,0x2c,0x30,0x7a,0x22, + 0x2f,0x3e,0x0a,0x3c,0x2f,0x67,0x3e,0x0a,0x3c,0x2f, + 0x73,0x76,0x67,0x3e,0x0a }; + diff --git a/data/converted/help_button_b_svg.cpp b/data/converted/help_button_b_svg.cpp index c1316dc67e..94da0650dd 100644 --- a/data/converted/help_button_b_svg.cpp +++ b/data/converted/help_button_b_svg.cpp @@ -2,96 +2,95 @@ #include "../Resources.h" -const size_t help_button_b_svg_size = 1504; -const unsigned char help_button_b_svg_data[1504] = { +const size_t help_button_b_svg_size = 1483; +const unsigned char help_button_b_svg_data[1483] = { 0x3c,0x3f,0x78,0x6d,0x6c,0x20,0x76,0x65,0x72,0x73, 0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x30,0x22,0x20, 0x65,0x6e,0x63,0x6f,0x64,0x69,0x6e,0x67,0x3d,0x22, - 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0d,0x0a, - 0x3c,0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72, - 0x61,0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62, - 0x65,0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61, - 0x74,0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33, - 0x2c,0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f, - 0x72,0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e, - 0x20,0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72, - 0x73,0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30, - 0x20,0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20, - 0x20,0x2d,0x2d,0x3e,0x0d,0x0a,0x3c,0x21,0x44,0x4f, - 0x43,0x54,0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20, - 0x50,0x55,0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f, - 0x2f,0x57,0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20, - 0x53,0x56,0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45, - 0x4e,0x22,0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, - 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, - 0x67,0x2f,0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73, - 0x2f,0x53,0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44, - 0x54,0x44,0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64, - 0x74,0x64,0x22,0x3e,0x0d,0x0a,0x3c,0x73,0x76,0x67, - 0x20,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22, - 0x31,0x2e,0x31,0x22,0x20,0x69,0x64,0x3d,0x22,0x42, - 0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3d,0x22,0x68, - 0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e, - 0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f,0x32,0x30,0x30, - 0x30,0x2f,0x73,0x76,0x67,0x22,0x20,0x78,0x6d,0x6c, - 0x6e,0x73,0x3a,0x78,0x6c,0x69,0x6e,0x6b,0x3d,0x22, - 0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77, - 0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f,0x31,0x39, - 0x39,0x39,0x2f,0x78,0x6c,0x69,0x6e,0x6b,0x22,0x20, - 0x78,0x3d,0x22,0x30,0x70,0x78,0x22,0x20,0x79,0x3d, - 0x22,0x30,0x70,0x78,0x22,0x0d,0x0a,0x09,0x20,0x77, - 0x69,0x64,0x74,0x68,0x3d,0x22,0x33,0x37,0x2e,0x30, - 0x36,0x31,0x70,0x78,0x22,0x20,0x68,0x65,0x69,0x67, - 0x68,0x74,0x3d,0x22,0x33,0x37,0x2e,0x30,0x36,0x31, - 0x70,0x78,0x22,0x20,0x76,0x69,0x65,0x77,0x42,0x6f, - 0x78,0x3d,0x22,0x30,0x20,0x30,0x20,0x33,0x37,0x2e, - 0x30,0x36,0x31,0x20,0x33,0x37,0x2e,0x30,0x36,0x31, - 0x22,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0x2d,0x62, - 0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x3d, - 0x22,0x6e,0x65,0x77,0x20,0x30,0x20,0x30,0x20,0x33, - 0x37,0x2e,0x30,0x36,0x31,0x20,0x33,0x37,0x2e,0x30, - 0x36,0x31,0x22,0x20,0x78,0x6d,0x6c,0x3a,0x73,0x70, - 0x61,0x63,0x65,0x3d,0x22,0x70,0x72,0x65,0x73,0x65, - 0x72,0x76,0x65,0x22,0x3e,0x0d,0x0a,0x3c,0x67,0x3e, - 0x0d,0x0a,0x09,0x3c,0x67,0x3e,0x0d,0x0a,0x09,0x09, - 0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c, - 0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46,0x46,0x22, - 0x20,0x64,0x3d,0x22,0x4d,0x31,0x39,0x2e,0x34,0x37, - 0x2c,0x31,0x38,0x2e,0x39,0x34,0x39,0x68,0x2d,0x32, - 0x2e,0x36,0x39,0x39,0x76,0x33,0x2e,0x38,0x38,0x37, - 0x68,0x32,0x2e,0x34,0x39,0x36,0x63,0x30,0x2e,0x37, - 0x31,0x37,0x2c,0x30,0x2c,0x31,0x2e,0x32,0x36,0x37, - 0x2d,0x30,0x2e,0x31,0x35,0x34,0x2c,0x31,0x2e,0x36, - 0x34,0x34,0x2d,0x30,0x2e,0x34,0x36,0x37,0x63,0x30, - 0x2e,0x33,0x37,0x38,0x2d,0x30,0x2e,0x33,0x31,0x33, - 0x2c,0x30,0x2e,0x35,0x36,0x33,0x2d,0x30,0x2e,0x37, - 0x37,0x32,0x2c,0x30,0x2e,0x35,0x36,0x33,0x2d,0x31, - 0x2e,0x33,0x38,0x35,0x0d,0x0a,0x09,0x09,0x09,0x63, - 0x30,0x2d,0x30,0x2e,0x36,0x35,0x39,0x2d,0x30,0x2e, - 0x31,0x36,0x2d,0x31,0x2e,0x31,0x36,0x35,0x2d,0x30, - 0x2e,0x34,0x38,0x2d,0x31,0x2e,0x35,0x31,0x33,0x43, - 0x32,0x30,0x2e,0x36,0x37,0x31,0x2c,0x31,0x39,0x2e, - 0x31,0x32,0x34,0x2c,0x32,0x30,0x2e,0x31,0x36,0x33, - 0x2c,0x31,0x38,0x2e,0x39,0x34,0x39,0x2c,0x31,0x39, + 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0a,0x3c, + 0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72,0x61, + 0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62,0x65, + 0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61,0x74, + 0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33,0x2c, + 0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f,0x72, + 0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e,0x20, + 0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72,0x73, + 0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30,0x20, + 0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20,0x20, + 0x2d,0x2d,0x3e,0x0a,0x3c,0x21,0x44,0x4f,0x43,0x54, + 0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20,0x50,0x55, + 0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f,0x2f,0x57, + 0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20,0x53,0x56, + 0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45,0x4e,0x22, + 0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73,0x2f,0x53, + 0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44,0x54,0x44, + 0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64,0x74,0x64, + 0x22,0x3e,0x0a,0x3c,0x73,0x76,0x67,0x20,0x76,0x65, + 0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x31, + 0x22,0x20,0x69,0x64,0x3d,0x22,0x42,0x22,0x20,0x78, + 0x6d,0x6c,0x6e,0x73,0x3d,0x22,0x68,0x74,0x74,0x70, + 0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e, + 0x6f,0x72,0x67,0x2f,0x32,0x30,0x30,0x30,0x2f,0x73, + 0x76,0x67,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3a, + 0x78,0x6c,0x69,0x6e,0x6b,0x3d,0x22,0x68,0x74,0x74, + 0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33, + 0x2e,0x6f,0x72,0x67,0x2f,0x31,0x39,0x39,0x39,0x2f, + 0x78,0x6c,0x69,0x6e,0x6b,0x22,0x20,0x78,0x3d,0x22, + 0x30,0x70,0x78,0x22,0x20,0x79,0x3d,0x22,0x30,0x70, + 0x78,0x22,0x0a,0x09,0x20,0x77,0x69,0x64,0x74,0x68, + 0x3d,0x22,0x33,0x37,0x2e,0x30,0x36,0x31,0x70,0x78, + 0x22,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3d,0x22, + 0x33,0x37,0x2e,0x30,0x36,0x31,0x70,0x78,0x22,0x20, + 0x76,0x69,0x65,0x77,0x42,0x6f,0x78,0x3d,0x22,0x30, + 0x20,0x30,0x20,0x33,0x37,0x2e,0x30,0x36,0x31,0x20, + 0x33,0x37,0x2e,0x30,0x36,0x31,0x22,0x20,0x65,0x6e, + 0x61,0x62,0x6c,0x65,0x2d,0x62,0x61,0x63,0x6b,0x67, + 0x72,0x6f,0x75,0x6e,0x64,0x3d,0x22,0x6e,0x65,0x77, + 0x20,0x30,0x20,0x30,0x20,0x33,0x37,0x2e,0x30,0x36, + 0x31,0x20,0x33,0x37,0x2e,0x30,0x36,0x31,0x22,0x20, + 0x78,0x6d,0x6c,0x3a,0x73,0x70,0x61,0x63,0x65,0x3d, + 0x22,0x70,0x72,0x65,0x73,0x65,0x72,0x76,0x65,0x22, + 0x3e,0x0a,0x3c,0x67,0x3e,0x0a,0x09,0x3c,0x67,0x3e, + 0x0a,0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66, + 0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46, + 0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x31,0x39, 0x2e,0x34,0x37,0x2c,0x31,0x38,0x2e,0x39,0x34,0x39, - 0x7a,0x20,0x4d,0x32,0x30,0x2e,0x33,0x38,0x39,0x2c, - 0x31,0x36,0x2e,0x36,0x33,0x63,0x30,0x2e,0x33,0x39, - 0x2d,0x30,0x2e,0x32,0x39,0x37,0x2c,0x30,0x2e,0x35, - 0x38,0x35,0x2d,0x30,0x2e,0x37,0x32,0x39,0x2c,0x30, - 0x2e,0x35,0x38,0x35,0x2d,0x31,0x2e,0x32,0x39,0x39, - 0x0d,0x0a,0x09,0x09,0x09,0x63,0x30,0x2d,0x30,0x2e, - 0x36,0x32,0x35,0x2d,0x30,0x2e,0x31,0x39,0x37,0x2d, - 0x31,0x2e,0x30,0x38,0x36,0x2d,0x30,0x2e,0x35,0x39, - 0x2d,0x31,0x2e,0x33,0x38,0x33,0x73,0x2d,0x30,0x2e, - 0x39,0x37,0x39,0x2d,0x30,0x2e,0x34,0x34,0x35,0x2d, - 0x31,0x2e,0x37,0x35,0x38,0x2d,0x30,0x2e,0x34,0x34, - 0x35,0x68,0x2d,0x31,0x2e,0x38,0x35,0x35,0x76,0x33, - 0x2e,0x35,0x37,0x32,0x68,0x31,0x2e,0x39,0x34,0x38, - 0x43,0x31,0x39,0x2e,0x34,0x34,0x32,0x2c,0x31,0x37, - 0x2e,0x30,0x37,0x35,0x2c,0x31,0x39,0x2e,0x39,0x39, - 0x39,0x2c,0x31,0x36,0x2e,0x39,0x32,0x37,0x2c,0x32, - 0x30,0x2e,0x33,0x38,0x39,0x2c,0x31,0x36,0x2e,0x36, - 0x33,0x7a,0x0d,0x0a,0x09,0x09,0x09,0x20,0x4d,0x31, + 0x68,0x2d,0x32,0x2e,0x36,0x39,0x39,0x76,0x33,0x2e, + 0x38,0x38,0x37,0x68,0x32,0x2e,0x34,0x39,0x36,0x63, + 0x30,0x2e,0x37,0x31,0x37,0x2c,0x30,0x2c,0x31,0x2e, + 0x32,0x36,0x37,0x2d,0x30,0x2e,0x31,0x35,0x34,0x2c, + 0x31,0x2e,0x36,0x34,0x34,0x2d,0x30,0x2e,0x34,0x36, + 0x37,0x63,0x30,0x2e,0x33,0x37,0x38,0x2d,0x30,0x2e, + 0x33,0x31,0x33,0x2c,0x30,0x2e,0x35,0x36,0x33,0x2d, + 0x30,0x2e,0x37,0x37,0x32,0x2c,0x30,0x2e,0x35,0x36, + 0x33,0x2d,0x31,0x2e,0x33,0x38,0x35,0x0a,0x09,0x09, + 0x09,0x63,0x30,0x2d,0x30,0x2e,0x36,0x35,0x39,0x2d, + 0x30,0x2e,0x31,0x36,0x2d,0x31,0x2e,0x31,0x36,0x35, + 0x2d,0x30,0x2e,0x34,0x38,0x2d,0x31,0x2e,0x35,0x31, + 0x33,0x43,0x32,0x30,0x2e,0x36,0x37,0x31,0x2c,0x31, + 0x39,0x2e,0x31,0x32,0x34,0x2c,0x32,0x30,0x2e,0x31, + 0x36,0x33,0x2c,0x31,0x38,0x2e,0x39,0x34,0x39,0x2c, + 0x31,0x39,0x2e,0x34,0x37,0x2c,0x31,0x38,0x2e,0x39, + 0x34,0x39,0x7a,0x20,0x4d,0x32,0x30,0x2e,0x33,0x38, + 0x39,0x2c,0x31,0x36,0x2e,0x36,0x33,0x63,0x30,0x2e, + 0x33,0x39,0x2d,0x30,0x2e,0x32,0x39,0x37,0x2c,0x30, + 0x2e,0x35,0x38,0x35,0x2d,0x30,0x2e,0x37,0x32,0x39, + 0x2c,0x30,0x2e,0x35,0x38,0x35,0x2d,0x31,0x2e,0x32, + 0x39,0x39,0x0a,0x09,0x09,0x09,0x63,0x30,0x2d,0x30, + 0x2e,0x36,0x32,0x35,0x2d,0x30,0x2e,0x31,0x39,0x37, + 0x2d,0x31,0x2e,0x30,0x38,0x36,0x2d,0x30,0x2e,0x35, + 0x39,0x2d,0x31,0x2e,0x33,0x38,0x33,0x73,0x2d,0x30, + 0x2e,0x39,0x37,0x39,0x2d,0x30,0x2e,0x34,0x34,0x35, + 0x2d,0x31,0x2e,0x37,0x35,0x38,0x2d,0x30,0x2e,0x34, + 0x34,0x35,0x68,0x2d,0x31,0x2e,0x38,0x35,0x35,0x76, + 0x33,0x2e,0x35,0x37,0x32,0x68,0x31,0x2e,0x39,0x34, + 0x38,0x43,0x31,0x39,0x2e,0x34,0x34,0x32,0x2c,0x31, + 0x37,0x2e,0x30,0x37,0x35,0x2c,0x31,0x39,0x2e,0x39, + 0x39,0x39,0x2c,0x31,0x36,0x2e,0x39,0x32,0x37,0x2c, + 0x32,0x30,0x2e,0x33,0x38,0x39,0x2c,0x31,0x36,0x2e, + 0x36,0x33,0x7a,0x0a,0x09,0x09,0x09,0x20,0x4d,0x31, 0x38,0x2e,0x35,0x33,0x2c,0x33,0x2e,0x30,0x33,0x31, 0x63,0x2d,0x38,0x2e,0x35,0x36,0x31,0x2c,0x30,0x2d, 0x31,0x35,0x2e,0x35,0x2c,0x36,0x2e,0x39,0x33,0x38, @@ -101,58 +100,58 @@ const unsigned char help_button_b_svg_data[1504] = { 0x35,0x2e,0x35,0x2c,0x31,0x35,0x2e,0x35,0x63,0x38, 0x2e,0x35,0x36,0x33,0x2c,0x30,0x2c,0x31,0x35,0x2e, 0x35,0x2d,0x36,0x2e,0x39,0x33,0x39,0x2c,0x31,0x35, - 0x2e,0x35,0x2d,0x31,0x35,0x2e,0x35,0x0d,0x0a,0x09, - 0x09,0x09,0x43,0x33,0x34,0x2e,0x30,0x33,0x2c,0x39, - 0x2e,0x39,0x36,0x39,0x2c,0x32,0x37,0x2e,0x30,0x39, - 0x31,0x2c,0x33,0x2e,0x30,0x33,0x31,0x2c,0x31,0x38, - 0x2e,0x35,0x33,0x2c,0x33,0x2e,0x30,0x33,0x31,0x7a, - 0x20,0x4d,0x32,0x32,0x2e,0x38,0x39,0x34,0x2c,0x32, - 0x33,0x2e,0x39,0x32,0x37,0x63,0x2d,0x30,0x2e,0x38, - 0x35,0x34,0x2c,0x30,0x2e,0x36,0x36,0x35,0x2d,0x32, - 0x2e,0x30,0x36,0x33,0x2c,0x30,0x2e,0x39,0x39,0x37, - 0x2d,0x33,0x2e,0x36,0x32,0x37,0x2c,0x30,0x2e,0x39, - 0x39,0x37,0x68,0x2d,0x35,0x2e,0x32,0x30,0x35,0x56, - 0x31,0x31,0x2e,0x34,0x31,0x36,0x68,0x34,0x2e,0x35, - 0x36,0x34,0x0d,0x0a,0x09,0x09,0x09,0x63,0x31,0x2e, - 0x35,0x39,0x2c,0x30,0x2c,0x32,0x2e,0x38,0x33,0x2c, - 0x30,0x2e,0x33,0x31,0x2c,0x33,0x2e,0x37,0x32,0x31, - 0x2c,0x30,0x2e,0x39,0x32,0x39,0x63,0x30,0x2e,0x38, - 0x39,0x31,0x2c,0x30,0x2e,0x36,0x31,0x37,0x2c,0x31, - 0x2e,0x33,0x33,0x36,0x2c,0x31,0x2e,0x35,0x34,0x33, - 0x2c,0x31,0x2e,0x33,0x33,0x36,0x2c,0x32,0x2e,0x37, - 0x37,0x33,0x63,0x30,0x2c,0x30,0x2e,0x36,0x32,0x35, - 0x2d,0x30,0x2e,0x31,0x36,0x36,0x2c,0x31,0x2e,0x31, - 0x38,0x34,0x2d,0x30,0x2e,0x34,0x39,0x36,0x2c,0x31, - 0x2e,0x36,0x37,0x34,0x0d,0x0a,0x09,0x09,0x09,0x63, - 0x2d,0x30,0x2e,0x33,0x33,0x32,0x2c,0x30,0x2e,0x34, - 0x39,0x32,0x2d,0x30,0x2e,0x38,0x31,0x33,0x2c,0x30, - 0x2e,0x38,0x36,0x2d,0x31,0x2e,0x34,0x34,0x31,0x2c, - 0x31,0x2e,0x31,0x30,0x38,0x63,0x30,0x2e,0x38,0x31, - 0x31,0x2c,0x30,0x2e,0x31,0x37,0x34,0x2c,0x31,0x2e, - 0x34,0x31,0x38,0x2c,0x30,0x2e,0x35,0x34,0x34,0x2c, - 0x31,0x2e,0x38,0x32,0x31,0x2c,0x31,0x2e,0x31,0x31, - 0x33,0x63,0x30,0x2e,0x34,0x30,0x35,0x2c,0x30,0x2e, - 0x35,0x36,0x38,0x2c,0x30,0x2e,0x36,0x30,0x37,0x2c, - 0x31,0x2e,0x32,0x32,0x39,0x2c,0x30,0x2e,0x36,0x30, - 0x37,0x2c,0x31,0x2e,0x39,0x37,0x37,0x0d,0x0a,0x09, - 0x09,0x09,0x43,0x32,0x34,0x2e,0x31,0x37,0x34,0x2c, - 0x32,0x32,0x2e,0x32,0x38,0x33,0x2c,0x32,0x33,0x2e, - 0x37,0x34,0x37,0x2c,0x32,0x33,0x2e,0x32,0x36,0x32, - 0x2c,0x32,0x32,0x2e,0x38,0x39,0x34,0x2c,0x32,0x33, - 0x2e,0x39,0x32,0x37,0x7a,0x22,0x2f,0x3e,0x0d,0x0a, - 0x09,0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x3c,0x2f,0x67, - 0x3e,0x0d,0x0a,0x3c,0x67,0x20,0x6f,0x70,0x61,0x63, - 0x69,0x74,0x79,0x3d,0x22,0x30,0x22,0x3e,0x0d,0x0a, - 0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69,0x6c, - 0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46,0x46, - 0x22,0x20,0x64,0x3d,0x22,0x4d,0x33,0x36,0x2e,0x39, - 0x36,0x31,0x2c,0x30,0x2e,0x31,0x76,0x33,0x36,0x2e, - 0x38,0x36,0x31,0x48,0x30,0x2e,0x31,0x56,0x30,0x2e, - 0x31,0x48,0x33,0x36,0x2e,0x39,0x36,0x31,0x20,0x4d, - 0x33,0x37,0x2e,0x30,0x36,0x31,0x2c,0x30,0x48,0x30, - 0x76,0x33,0x37,0x2e,0x30,0x36,0x68,0x33,0x37,0x2e, - 0x30,0x36,0x31,0x56,0x30,0x4c,0x33,0x37,0x2e,0x30, - 0x36,0x31,0x2c,0x30,0x7a,0x22,0x2f,0x3e,0x0d,0x0a, - 0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x3c,0x2f,0x73,0x76, - 0x67,0x3e,0x0d,0x0a + 0x2e,0x35,0x2d,0x31,0x35,0x2e,0x35,0x0a,0x09,0x09, + 0x09,0x43,0x33,0x34,0x2e,0x30,0x33,0x2c,0x39,0x2e, + 0x39,0x36,0x39,0x2c,0x32,0x37,0x2e,0x30,0x39,0x31, + 0x2c,0x33,0x2e,0x30,0x33,0x31,0x2c,0x31,0x38,0x2e, + 0x35,0x33,0x2c,0x33,0x2e,0x30,0x33,0x31,0x7a,0x20, + 0x4d,0x32,0x32,0x2e,0x38,0x39,0x34,0x2c,0x32,0x33, + 0x2e,0x39,0x32,0x37,0x63,0x2d,0x30,0x2e,0x38,0x35, + 0x34,0x2c,0x30,0x2e,0x36,0x36,0x35,0x2d,0x32,0x2e, + 0x30,0x36,0x33,0x2c,0x30,0x2e,0x39,0x39,0x37,0x2d, + 0x33,0x2e,0x36,0x32,0x37,0x2c,0x30,0x2e,0x39,0x39, + 0x37,0x68,0x2d,0x35,0x2e,0x32,0x30,0x35,0x56,0x31, + 0x31,0x2e,0x34,0x31,0x36,0x68,0x34,0x2e,0x35,0x36, + 0x34,0x0a,0x09,0x09,0x09,0x63,0x31,0x2e,0x35,0x39, + 0x2c,0x30,0x2c,0x32,0x2e,0x38,0x33,0x2c,0x30,0x2e, + 0x33,0x31,0x2c,0x33,0x2e,0x37,0x32,0x31,0x2c,0x30, + 0x2e,0x39,0x32,0x39,0x63,0x30,0x2e,0x38,0x39,0x31, + 0x2c,0x30,0x2e,0x36,0x31,0x37,0x2c,0x31,0x2e,0x33, + 0x33,0x36,0x2c,0x31,0x2e,0x35,0x34,0x33,0x2c,0x31, + 0x2e,0x33,0x33,0x36,0x2c,0x32,0x2e,0x37,0x37,0x33, + 0x63,0x30,0x2c,0x30,0x2e,0x36,0x32,0x35,0x2d,0x30, + 0x2e,0x31,0x36,0x36,0x2c,0x31,0x2e,0x31,0x38,0x34, + 0x2d,0x30,0x2e,0x34,0x39,0x36,0x2c,0x31,0x2e,0x36, + 0x37,0x34,0x0a,0x09,0x09,0x09,0x63,0x2d,0x30,0x2e, + 0x33,0x33,0x32,0x2c,0x30,0x2e,0x34,0x39,0x32,0x2d, + 0x30,0x2e,0x38,0x31,0x33,0x2c,0x30,0x2e,0x38,0x36, + 0x2d,0x31,0x2e,0x34,0x34,0x31,0x2c,0x31,0x2e,0x31, + 0x30,0x38,0x63,0x30,0x2e,0x38,0x31,0x31,0x2c,0x30, + 0x2e,0x31,0x37,0x34,0x2c,0x31,0x2e,0x34,0x31,0x38, + 0x2c,0x30,0x2e,0x35,0x34,0x34,0x2c,0x31,0x2e,0x38, + 0x32,0x31,0x2c,0x31,0x2e,0x31,0x31,0x33,0x63,0x30, + 0x2e,0x34,0x30,0x35,0x2c,0x30,0x2e,0x35,0x36,0x38, + 0x2c,0x30,0x2e,0x36,0x30,0x37,0x2c,0x31,0x2e,0x32, + 0x32,0x39,0x2c,0x30,0x2e,0x36,0x30,0x37,0x2c,0x31, + 0x2e,0x39,0x37,0x37,0x0a,0x09,0x09,0x09,0x43,0x32, + 0x34,0x2e,0x31,0x37,0x34,0x2c,0x32,0x32,0x2e,0x32, + 0x38,0x33,0x2c,0x32,0x33,0x2e,0x37,0x34,0x37,0x2c, + 0x32,0x33,0x2e,0x32,0x36,0x32,0x2c,0x32,0x32,0x2e, + 0x38,0x39,0x34,0x2c,0x32,0x33,0x2e,0x39,0x32,0x37, + 0x7a,0x22,0x2f,0x3e,0x0a,0x09,0x3c,0x2f,0x67,0x3e, + 0x0a,0x3c,0x2f,0x67,0x3e,0x0a,0x3c,0x67,0x20,0x6f, + 0x70,0x61,0x63,0x69,0x74,0x79,0x3d,0x22,0x30,0x22, + 0x3e,0x0a,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66, + 0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46, + 0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x33,0x36, + 0x2e,0x39,0x36,0x31,0x2c,0x30,0x2e,0x31,0x76,0x33, + 0x36,0x2e,0x38,0x36,0x31,0x48,0x30,0x2e,0x31,0x56, + 0x30,0x2e,0x31,0x48,0x33,0x36,0x2e,0x39,0x36,0x31, + 0x20,0x4d,0x33,0x37,0x2e,0x30,0x36,0x31,0x2c,0x30, + 0x48,0x30,0x76,0x33,0x37,0x2e,0x30,0x36,0x68,0x33, + 0x37,0x2e,0x30,0x36,0x31,0x56,0x30,0x4c,0x33,0x37, + 0x2e,0x30,0x36,0x31,0x2c,0x30,0x7a,0x22,0x2f,0x3e, + 0x0a,0x3c,0x2f,0x67,0x3e,0x0a,0x3c,0x2f,0x73,0x76, + 0x67,0x3e,0x0a }; + diff --git a/data/converted/help_button_l_svg.cpp b/data/converted/help_button_l_svg.cpp index 2fbb07e096..fb8eb343b7 100644 --- a/data/converted/help_button_l_svg.cpp +++ b/data/converted/help_button_l_svg.cpp @@ -2,109 +2,109 @@ #include "../Resources.h" -const size_t help_button_l_svg_size = 1026; -const unsigned char help_button_l_svg_data[1026] = { +const size_t help_button_l_svg_size = 1013; +const unsigned char help_button_l_svg_data[1013] = { 0x3c,0x3f,0x78,0x6d,0x6c,0x20,0x76,0x65,0x72,0x73, 0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x30,0x22,0x20, 0x65,0x6e,0x63,0x6f,0x64,0x69,0x6e,0x67,0x3d,0x22, - 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0d,0x0a, - 0x3c,0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72, - 0x61,0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62, - 0x65,0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61, - 0x74,0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33, - 0x2c,0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f, - 0x72,0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e, - 0x20,0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72, - 0x73,0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30, - 0x20,0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20, - 0x20,0x2d,0x2d,0x3e,0x0d,0x0a,0x3c,0x21,0x44,0x4f, - 0x43,0x54,0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20, - 0x50,0x55,0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f, - 0x2f,0x57,0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20, - 0x53,0x56,0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45, - 0x4e,0x22,0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, - 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, - 0x67,0x2f,0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73, - 0x2f,0x53,0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44, - 0x54,0x44,0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64, - 0x74,0x64,0x22,0x3e,0x0d,0x0a,0x3c,0x73,0x76,0x67, - 0x20,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22, - 0x31,0x2e,0x31,0x22,0x20,0x69,0x64,0x3d,0x22,0x5f, - 0x78,0x33,0x30,0x5f,0x22,0x20,0x78,0x6d,0x6c,0x6e, - 0x73,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f, - 0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67, - 0x2f,0x32,0x30,0x30,0x30,0x2f,0x73,0x76,0x67,0x22, - 0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78,0x6c,0x69, - 0x6e,0x6b,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, - 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, - 0x67,0x2f,0x31,0x39,0x39,0x39,0x2f,0x78,0x6c,0x69, - 0x6e,0x6b,0x22,0x20,0x78,0x3d,0x22,0x30,0x70,0x78, - 0x22,0x20,0x79,0x3d,0x22,0x30,0x70,0x78,0x22,0x0d, - 0x0a,0x09,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22, - 0x33,0x37,0x2e,0x30,0x36,0x31,0x70,0x78,0x22,0x20, - 0x68,0x65,0x69,0x67,0x68,0x74,0x3d,0x22,0x33,0x37, - 0x2e,0x30,0x36,0x31,0x70,0x78,0x22,0x20,0x76,0x69, - 0x65,0x77,0x42,0x6f,0x78,0x3d,0x22,0x30,0x20,0x30, - 0x20,0x33,0x37,0x2e,0x30,0x36,0x31,0x20,0x33,0x37, - 0x2e,0x30,0x36,0x31,0x22,0x20,0x65,0x6e,0x61,0x62, - 0x6c,0x65,0x2d,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f, - 0x75,0x6e,0x64,0x3d,0x22,0x6e,0x65,0x77,0x20,0x30, - 0x20,0x30,0x20,0x33,0x37,0x2e,0x30,0x36,0x31,0x20, - 0x33,0x37,0x2e,0x30,0x36,0x31,0x22,0x20,0x78,0x6d, - 0x6c,0x3a,0x73,0x70,0x61,0x63,0x65,0x3d,0x22,0x70, - 0x72,0x65,0x73,0x65,0x72,0x76,0x65,0x22,0x3e,0x0d, - 0x0a,0x3c,0x67,0x3e,0x0d,0x0a,0x09,0x3c,0x70,0x61, - 0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23, - 0x46,0x46,0x46,0x46,0x46,0x46,0x22,0x20,0x64,0x3d, - 0x22,0x4d,0x32,0x39,0x2e,0x32,0x35,0x34,0x2c,0x31, - 0x31,0x2e,0x35,0x32,0x36,0x63,0x33,0x2e,0x34,0x37, - 0x38,0x2c,0x30,0x2c,0x36,0x2e,0x33,0x30,0x37,0x2c, - 0x33,0x2e,0x31,0x34,0x2c,0x36,0x2e,0x33,0x30,0x37, - 0x2c,0x36,0x2e,0x39,0x39,0x37,0x63,0x30,0x2c,0x33, - 0x2e,0x38,0x36,0x36,0x2d,0x32,0x2e,0x38,0x32,0x39, - 0x2c,0x37,0x2e,0x30,0x31,0x31,0x2d,0x36,0x2e,0x33, - 0x30,0x37,0x2c,0x37,0x2e,0x30,0x31,0x31,0x48,0x37, - 0x2e,0x37,0x36,0x0d,0x0a,0x09,0x09,0x63,0x2d,0x33, - 0x2e,0x34,0x35,0x32,0x2d,0x30,0x2e,0x30,0x33,0x2d, - 0x36,0x2e,0x32,0x36,0x2d,0x33,0x2e,0x31,0x37,0x37, - 0x2d,0x36,0x2e,0x32,0x36,0x2d,0x37,0x2e,0x30,0x31, - 0x31,0x63,0x30,0x2d,0x33,0x2e,0x38,0x32,0x38,0x2c, - 0x32,0x2e,0x38,0x30,0x38,0x2d,0x36,0x2e,0x39,0x36, - 0x36,0x2c,0x36,0x2e,0x32,0x34,0x37,0x2d,0x36,0x2e, - 0x39,0x39,0x37,0x48,0x32,0x39,0x2e,0x32,0x35,0x34, - 0x20,0x4d,0x32,0x39,0x2e,0x32,0x35,0x34,0x2c,0x31, - 0x30,0x2e,0x30,0x32,0x36,0x63,0x2d,0x30,0x2e,0x30, - 0x32,0x31,0x2c,0x30,0x2d,0x32,0x31,0x2e,0x35,0x30, - 0x37,0x2c,0x30,0x2d,0x32,0x31,0x2e,0x35,0x30,0x37, - 0x2c,0x30,0x0d,0x0a,0x09,0x09,0x43,0x33,0x2e,0x34, - 0x36,0x36,0x2c,0x31,0x30,0x2e,0x30,0x36,0x34,0x2c, - 0x30,0x2c,0x31,0x33,0x2e,0x38,0x34,0x36,0x2c,0x30, - 0x2c,0x31,0x38,0x2e,0x35,0x32,0x33,0x63,0x30,0x2c, - 0x34,0x2e,0x36,0x37,0x38,0x2c,0x33,0x2e,0x34,0x36, - 0x36,0x2c,0x38,0x2e,0x34,0x37,0x33,0x2c,0x37,0x2e, - 0x37,0x34,0x37,0x2c,0x38,0x2e,0x35,0x31,0x31,0x63, - 0x30,0x2c,0x30,0x2c,0x32,0x31,0x2e,0x34,0x38,0x33, - 0x2c,0x30,0x2c,0x32,0x31,0x2e,0x35,0x30,0x37,0x2c, - 0x30,0x63,0x34,0x2e,0x33,0x31,0x33,0x2c,0x30,0x2c, - 0x37,0x2e,0x38,0x30,0x37,0x2d,0x33,0x2e,0x38,0x31, - 0x32,0x2c,0x37,0x2e,0x38,0x30,0x37,0x2d,0x38,0x2e, - 0x35,0x31,0x31,0x0d,0x0a,0x09,0x09,0x53,0x33,0x33, - 0x2e,0x35,0x36,0x36,0x2c,0x31,0x30,0x2e,0x30,0x32, - 0x36,0x2c,0x32,0x39,0x2e,0x32,0x35,0x34,0x2c,0x31, - 0x30,0x2e,0x30,0x32,0x36,0x4c,0x32,0x39,0x2e,0x32, - 0x35,0x34,0x2c,0x31,0x30,0x2e,0x30,0x32,0x36,0x7a, - 0x22,0x2f,0x3e,0x0d,0x0a,0x3c,0x2f,0x67,0x3e,0x0d, - 0x0a,0x3c,0x70,0x6f,0x6c,0x79,0x67,0x6f,0x6e,0x20, - 0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46, - 0x46,0x46,0x46,0x22,0x20,0x70,0x6f,0x69,0x6e,0x74, - 0x73,0x3d,0x22,0x31,0x35,0x2e,0x39,0x32,0x2c,0x32, - 0x32,0x2e,0x32,0x31,0x32,0x20,0x32,0x31,0x2e,0x31, - 0x34,0x31,0x2c,0x32,0x32,0x2e,0x32,0x31,0x32,0x20, - 0x32,0x31,0x2e,0x31,0x34,0x31,0x2c,0x32,0x30,0x2e, - 0x38,0x35,0x20,0x31,0x37,0x2e,0x35,0x34,0x33,0x2c, - 0x32,0x30,0x2e,0x38,0x35,0x20,0x31,0x37,0x2e,0x35, - 0x34,0x33,0x2c,0x31,0x34,0x2e,0x38,0x33,0x33,0x20, - 0x31,0x35,0x2e,0x39,0x32,0x2c,0x31,0x34,0x2e,0x38, - 0x33,0x33,0x20,0x22,0x2f,0x3e,0x0d,0x0a,0x3c,0x2f, - 0x73,0x76,0x67,0x3e,0x0d,0x0a + 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0a,0x3c, + 0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72,0x61, + 0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62,0x65, + 0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61,0x74, + 0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33,0x2c, + 0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f,0x72, + 0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e,0x20, + 0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72,0x73, + 0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30,0x20, + 0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20,0x20, + 0x2d,0x2d,0x3e,0x0a,0x3c,0x21,0x44,0x4f,0x43,0x54, + 0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20,0x50,0x55, + 0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f,0x2f,0x57, + 0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20,0x53,0x56, + 0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45,0x4e,0x22, + 0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73,0x2f,0x53, + 0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44,0x54,0x44, + 0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64,0x74,0x64, + 0x22,0x3e,0x0a,0x3c,0x73,0x76,0x67,0x20,0x76,0x65, + 0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x31, + 0x22,0x20,0x69,0x64,0x3d,0x22,0x5f,0x78,0x33,0x30, + 0x5f,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3d,0x22, + 0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77, + 0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f,0x32,0x30, + 0x30,0x30,0x2f,0x73,0x76,0x67,0x22,0x20,0x78,0x6d, + 0x6c,0x6e,0x73,0x3a,0x78,0x6c,0x69,0x6e,0x6b,0x3d, + 0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77, + 0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f,0x31, + 0x39,0x39,0x39,0x2f,0x78,0x6c,0x69,0x6e,0x6b,0x22, + 0x20,0x78,0x3d,0x22,0x30,0x70,0x78,0x22,0x20,0x79, + 0x3d,0x22,0x30,0x70,0x78,0x22,0x0a,0x09,0x20,0x77, + 0x69,0x64,0x74,0x68,0x3d,0x22,0x33,0x37,0x2e,0x30, + 0x36,0x31,0x70,0x78,0x22,0x20,0x68,0x65,0x69,0x67, + 0x68,0x74,0x3d,0x22,0x33,0x37,0x2e,0x30,0x36,0x31, + 0x70,0x78,0x22,0x20,0x76,0x69,0x65,0x77,0x42,0x6f, + 0x78,0x3d,0x22,0x30,0x20,0x30,0x20,0x33,0x37,0x2e, + 0x30,0x36,0x31,0x20,0x33,0x37,0x2e,0x30,0x36,0x31, + 0x22,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0x2d,0x62, + 0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x3d, + 0x22,0x6e,0x65,0x77,0x20,0x30,0x20,0x30,0x20,0x33, + 0x37,0x2e,0x30,0x36,0x31,0x20,0x33,0x37,0x2e,0x30, + 0x36,0x31,0x22,0x20,0x78,0x6d,0x6c,0x3a,0x73,0x70, + 0x61,0x63,0x65,0x3d,0x22,0x70,0x72,0x65,0x73,0x65, + 0x72,0x76,0x65,0x22,0x3e,0x0a,0x3c,0x67,0x3e,0x0a, + 0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69,0x6c, + 0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46,0x46, + 0x22,0x20,0x64,0x3d,0x22,0x4d,0x32,0x39,0x2e,0x32, + 0x35,0x34,0x2c,0x31,0x31,0x2e,0x35,0x32,0x36,0x63, + 0x33,0x2e,0x34,0x37,0x38,0x2c,0x30,0x2c,0x36,0x2e, + 0x33,0x30,0x37,0x2c,0x33,0x2e,0x31,0x34,0x2c,0x36, + 0x2e,0x33,0x30,0x37,0x2c,0x36,0x2e,0x39,0x39,0x37, + 0x63,0x30,0x2c,0x33,0x2e,0x38,0x36,0x36,0x2d,0x32, + 0x2e,0x38,0x32,0x39,0x2c,0x37,0x2e,0x30,0x31,0x31, + 0x2d,0x36,0x2e,0x33,0x30,0x37,0x2c,0x37,0x2e,0x30, + 0x31,0x31,0x48,0x37,0x2e,0x37,0x36,0x0a,0x09,0x09, + 0x63,0x2d,0x33,0x2e,0x34,0x35,0x32,0x2d,0x30,0x2e, + 0x30,0x33,0x2d,0x36,0x2e,0x32,0x36,0x2d,0x33,0x2e, + 0x31,0x37,0x37,0x2d,0x36,0x2e,0x32,0x36,0x2d,0x37, + 0x2e,0x30,0x31,0x31,0x63,0x30,0x2d,0x33,0x2e,0x38, + 0x32,0x38,0x2c,0x32,0x2e,0x38,0x30,0x38,0x2d,0x36, + 0x2e,0x39,0x36,0x36,0x2c,0x36,0x2e,0x32,0x34,0x37, + 0x2d,0x36,0x2e,0x39,0x39,0x37,0x48,0x32,0x39,0x2e, + 0x32,0x35,0x34,0x20,0x4d,0x32,0x39,0x2e,0x32,0x35, + 0x34,0x2c,0x31,0x30,0x2e,0x30,0x32,0x36,0x63,0x2d, + 0x30,0x2e,0x30,0x32,0x31,0x2c,0x30,0x2d,0x32,0x31, + 0x2e,0x35,0x30,0x37,0x2c,0x30,0x2d,0x32,0x31,0x2e, + 0x35,0x30,0x37,0x2c,0x30,0x0a,0x09,0x09,0x43,0x33, + 0x2e,0x34,0x36,0x36,0x2c,0x31,0x30,0x2e,0x30,0x36, + 0x34,0x2c,0x30,0x2c,0x31,0x33,0x2e,0x38,0x34,0x36, + 0x2c,0x30,0x2c,0x31,0x38,0x2e,0x35,0x32,0x33,0x63, + 0x30,0x2c,0x34,0x2e,0x36,0x37,0x38,0x2c,0x33,0x2e, + 0x34,0x36,0x36,0x2c,0x38,0x2e,0x34,0x37,0x33,0x2c, + 0x37,0x2e,0x37,0x34,0x37,0x2c,0x38,0x2e,0x35,0x31, + 0x31,0x63,0x30,0x2c,0x30,0x2c,0x32,0x31,0x2e,0x34, + 0x38,0x33,0x2c,0x30,0x2c,0x32,0x31,0x2e,0x35,0x30, + 0x37,0x2c,0x30,0x63,0x34,0x2e,0x33,0x31,0x33,0x2c, + 0x30,0x2c,0x37,0x2e,0x38,0x30,0x37,0x2d,0x33,0x2e, + 0x38,0x31,0x32,0x2c,0x37,0x2e,0x38,0x30,0x37,0x2d, + 0x38,0x2e,0x35,0x31,0x31,0x0a,0x09,0x09,0x53,0x33, + 0x33,0x2e,0x35,0x36,0x36,0x2c,0x31,0x30,0x2e,0x30, + 0x32,0x36,0x2c,0x32,0x39,0x2e,0x32,0x35,0x34,0x2c, + 0x31,0x30,0x2e,0x30,0x32,0x36,0x4c,0x32,0x39,0x2e, + 0x32,0x35,0x34,0x2c,0x31,0x30,0x2e,0x30,0x32,0x36, + 0x7a,0x22,0x2f,0x3e,0x0a,0x3c,0x2f,0x67,0x3e,0x0a, + 0x3c,0x70,0x6f,0x6c,0x79,0x67,0x6f,0x6e,0x20,0x66, + 0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46, + 0x46,0x46,0x22,0x20,0x70,0x6f,0x69,0x6e,0x74,0x73, + 0x3d,0x22,0x31,0x35,0x2e,0x39,0x32,0x2c,0x32,0x32, + 0x2e,0x32,0x31,0x32,0x20,0x32,0x31,0x2e,0x31,0x34, + 0x31,0x2c,0x32,0x32,0x2e,0x32,0x31,0x32,0x20,0x32, + 0x31,0x2e,0x31,0x34,0x31,0x2c,0x32,0x30,0x2e,0x38, + 0x35,0x20,0x31,0x37,0x2e,0x35,0x34,0x33,0x2c,0x32, + 0x30,0x2e,0x38,0x35,0x20,0x31,0x37,0x2e,0x35,0x34, + 0x33,0x2c,0x31,0x34,0x2e,0x38,0x33,0x33,0x20,0x31, + 0x35,0x2e,0x39,0x32,0x2c,0x31,0x34,0x2e,0x38,0x33, + 0x33,0x20,0x22,0x2f,0x3e,0x0a,0x3c,0x2f,0x73,0x76, + 0x67,0x3e,0x0a }; + diff --git a/data/converted/help_button_r_svg.cpp b/data/converted/help_button_r_svg.cpp index e76411c976..ea1eceb7a3 100644 --- a/data/converted/help_button_r_svg.cpp +++ b/data/converted/help_button_r_svg.cpp @@ -2,99 +2,98 @@ #include "../Resources.h" -const size_t help_button_r_svg_size = 1331; -const unsigned char help_button_r_svg_data[1331] = { +const size_t help_button_r_svg_size = 1315; +const unsigned char help_button_r_svg_data[1315] = { 0x3c,0x3f,0x78,0x6d,0x6c,0x20,0x76,0x65,0x72,0x73, 0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x30,0x22,0x20, 0x65,0x6e,0x63,0x6f,0x64,0x69,0x6e,0x67,0x3d,0x22, - 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0d,0x0a, - 0x3c,0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72, - 0x61,0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62, - 0x65,0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61, - 0x74,0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33, - 0x2c,0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f, - 0x72,0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e, - 0x20,0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72, - 0x73,0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30, - 0x20,0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20, - 0x20,0x2d,0x2d,0x3e,0x0d,0x0a,0x3c,0x21,0x44,0x4f, - 0x43,0x54,0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20, - 0x50,0x55,0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f, - 0x2f,0x57,0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20, - 0x53,0x56,0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45, - 0x4e,0x22,0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, - 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, - 0x67,0x2f,0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73, - 0x2f,0x53,0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44, - 0x54,0x44,0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64, - 0x74,0x64,0x22,0x3e,0x0d,0x0a,0x3c,0x73,0x76,0x67, - 0x20,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22, - 0x31,0x2e,0x31,0x22,0x20,0x69,0x64,0x3d,0x22,0x5f, - 0x78,0x33,0x30,0x5f,0x22,0x20,0x78,0x6d,0x6c,0x6e, - 0x73,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f, - 0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67, - 0x2f,0x32,0x30,0x30,0x30,0x2f,0x73,0x76,0x67,0x22, - 0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78,0x6c,0x69, - 0x6e,0x6b,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, - 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, - 0x67,0x2f,0x31,0x39,0x39,0x39,0x2f,0x78,0x6c,0x69, - 0x6e,0x6b,0x22,0x20,0x78,0x3d,0x22,0x30,0x70,0x78, - 0x22,0x20,0x79,0x3d,0x22,0x30,0x70,0x78,0x22,0x0d, - 0x0a,0x09,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22, - 0x33,0x37,0x2e,0x30,0x36,0x31,0x70,0x78,0x22,0x20, - 0x68,0x65,0x69,0x67,0x68,0x74,0x3d,0x22,0x33,0x37, - 0x2e,0x30,0x36,0x31,0x70,0x78,0x22,0x20,0x76,0x69, - 0x65,0x77,0x42,0x6f,0x78,0x3d,0x22,0x30,0x20,0x30, - 0x20,0x33,0x37,0x2e,0x30,0x36,0x31,0x20,0x33,0x37, - 0x2e,0x30,0x36,0x31,0x22,0x20,0x65,0x6e,0x61,0x62, - 0x6c,0x65,0x2d,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f, - 0x75,0x6e,0x64,0x3d,0x22,0x6e,0x65,0x77,0x20,0x30, - 0x20,0x30,0x20,0x33,0x37,0x2e,0x30,0x36,0x31,0x20, - 0x33,0x37,0x2e,0x30,0x36,0x31,0x22,0x20,0x78,0x6d, - 0x6c,0x3a,0x73,0x70,0x61,0x63,0x65,0x3d,0x22,0x70, - 0x72,0x65,0x73,0x65,0x72,0x76,0x65,0x22,0x3e,0x0d, - 0x0a,0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69,0x6c, - 0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46,0x46, - 0x22,0x20,0x64,0x3d,0x22,0x4d,0x31,0x36,0x2e,0x39, - 0x37,0x33,0x2c,0x31,0x36,0x2e,0x30,0x38,0x36,0x68, - 0x31,0x2e,0x37,0x37,0x39,0x63,0x30,0x2e,0x37,0x32, - 0x32,0x2c,0x30,0x2c,0x31,0x2e,0x31,0x31,0x37,0x2c, - 0x30,0x2e,0x33,0x31,0x32,0x2c,0x31,0x2e,0x31,0x31, - 0x37,0x2c,0x31,0x2e,0x30,0x32,0x32,0x63,0x30,0x2c, - 0x30,0x2e,0x37,0x34,0x37,0x2d,0x30,0x2e,0x33,0x39, - 0x36,0x2c,0x31,0x2e,0x30,0x36,0x2d,0x31,0x2e,0x31, - 0x31,0x37,0x2c,0x31,0x2e,0x30,0x36,0x68,0x2d,0x31, - 0x2e,0x37,0x37,0x39,0x56,0x31,0x36,0x2e,0x30,0x38, - 0x36,0x7a,0x0d,0x0a,0x09,0x20,0x4d,0x31,0x35,0x2e, - 0x33,0x35,0x33,0x2c,0x32,0x32,0x2e,0x32,0x31,0x32, - 0x68,0x31,0x2e,0x36,0x32,0x76,0x2d,0x32,0x2e,0x38, - 0x38,0x36,0x68,0x31,0x2e,0x36,0x32,0x35,0x63,0x30, - 0x2e,0x38,0x31,0x36,0x2c,0x30,0x2c,0x31,0x2e,0x31, - 0x31,0x37,0x2c,0x30,0x2e,0x33,0x34,0x32,0x2c,0x31, - 0x2e,0x32,0x33,0x2c,0x31,0x2e,0x31,0x31,0x38,0x63, - 0x30,0x2e,0x30,0x38,0x32,0x2c,0x30,0x2e,0x35,0x38, - 0x39,0x2c,0x30,0x2e,0x30,0x36,0x31,0x2c,0x31,0x2e, - 0x33,0x30,0x34,0x2c,0x30,0x2e,0x32,0x35,0x38,0x2c, - 0x31,0x2e,0x37,0x36,0x39,0x68,0x31,0x2e,0x36,0x32, - 0x31,0x0d,0x0a,0x09,0x63,0x2d,0x30,0x2e,0x32,0x38, - 0x39,0x2d,0x30,0x2e,0x34,0x31,0x34,0x2d,0x30,0x2e, - 0x32,0x37,0x39,0x2d,0x31,0x2e,0x32,0x38,0x2d,0x30, - 0x2e,0x33,0x31,0x33,0x2d,0x31,0x2e,0x37,0x34,0x38, - 0x63,0x2d,0x30,0x2e,0x30,0x35,0x31,0x2d,0x30,0x2e, - 0x37,0x34,0x34,0x2d,0x30,0x2e,0x32,0x37,0x35,0x2d, - 0x31,0x2e,0x35,0x32,0x31,0x2d,0x31,0x2e,0x30,0x37, - 0x2d,0x31,0x2e,0x37,0x32,0x38,0x63,0x30,0x2c,0x30, - 0x2c,0x31,0x2e,0x31,0x36,0x36,0x2d,0x30,0x2e,0x33, - 0x30,0x33,0x2c,0x31,0x2e,0x31,0x36,0x36,0x2d,0x31, - 0x2e,0x38,0x37,0x33,0x0d,0x0a,0x09,0x63,0x30,0x2d, - 0x31,0x2e,0x31,0x31,0x38,0x2d,0x30,0x2e,0x38,0x33, - 0x38,0x2d,0x32,0x2e,0x30,0x33,0x36,0x2d,0x32,0x2e, - 0x31,0x36,0x2d,0x32,0x2e,0x30,0x33,0x36,0x68,0x2d, - 0x33,0x2e,0x39,0x37,0x39,0x4c,0x31,0x35,0x2e,0x33, - 0x35,0x33,0x2c,0x32,0x32,0x2e,0x32,0x31,0x32,0x4c, - 0x31,0x35,0x2e,0x33,0x35,0x33,0x2c,0x32,0x32,0x2e, - 0x32,0x31,0x32,0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x3c, - 0x67,0x3e,0x0d,0x0a,0x09,0x3c,0x70,0x61,0x74,0x68, + 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0a,0x3c, + 0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72,0x61, + 0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62,0x65, + 0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61,0x74, + 0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33,0x2c, + 0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f,0x72, + 0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e,0x20, + 0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72,0x73, + 0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30,0x20, + 0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20,0x20, + 0x2d,0x2d,0x3e,0x0a,0x3c,0x21,0x44,0x4f,0x43,0x54, + 0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20,0x50,0x55, + 0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f,0x2f,0x57, + 0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20,0x53,0x56, + 0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45,0x4e,0x22, + 0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73,0x2f,0x53, + 0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44,0x54,0x44, + 0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64,0x74,0x64, + 0x22,0x3e,0x0a,0x3c,0x73,0x76,0x67,0x20,0x76,0x65, + 0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x31, + 0x22,0x20,0x69,0x64,0x3d,0x22,0x5f,0x78,0x33,0x30, + 0x5f,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3d,0x22, + 0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77, + 0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f,0x32,0x30, + 0x30,0x30,0x2f,0x73,0x76,0x67,0x22,0x20,0x78,0x6d, + 0x6c,0x6e,0x73,0x3a,0x78,0x6c,0x69,0x6e,0x6b,0x3d, + 0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77, + 0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f,0x31, + 0x39,0x39,0x39,0x2f,0x78,0x6c,0x69,0x6e,0x6b,0x22, + 0x20,0x78,0x3d,0x22,0x30,0x70,0x78,0x22,0x20,0x79, + 0x3d,0x22,0x30,0x70,0x78,0x22,0x0a,0x09,0x20,0x77, + 0x69,0x64,0x74,0x68,0x3d,0x22,0x33,0x37,0x2e,0x30, + 0x36,0x31,0x70,0x78,0x22,0x20,0x68,0x65,0x69,0x67, + 0x68,0x74,0x3d,0x22,0x33,0x37,0x2e,0x30,0x36,0x31, + 0x70,0x78,0x22,0x20,0x76,0x69,0x65,0x77,0x42,0x6f, + 0x78,0x3d,0x22,0x30,0x20,0x30,0x20,0x33,0x37,0x2e, + 0x30,0x36,0x31,0x20,0x33,0x37,0x2e,0x30,0x36,0x31, + 0x22,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0x2d,0x62, + 0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x3d, + 0x22,0x6e,0x65,0x77,0x20,0x30,0x20,0x30,0x20,0x33, + 0x37,0x2e,0x30,0x36,0x31,0x20,0x33,0x37,0x2e,0x30, + 0x36,0x31,0x22,0x20,0x78,0x6d,0x6c,0x3a,0x73,0x70, + 0x61,0x63,0x65,0x3d,0x22,0x70,0x72,0x65,0x73,0x65, + 0x72,0x76,0x65,0x22,0x3e,0x0a,0x3c,0x70,0x61,0x74, + 0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46, + 0x46,0x46,0x46,0x46,0x46,0x22,0x20,0x64,0x3d,0x22, + 0x4d,0x31,0x36,0x2e,0x39,0x37,0x33,0x2c,0x31,0x36, + 0x2e,0x30,0x38,0x36,0x68,0x31,0x2e,0x37,0x37,0x39, + 0x63,0x30,0x2e,0x37,0x32,0x32,0x2c,0x30,0x2c,0x31, + 0x2e,0x31,0x31,0x37,0x2c,0x30,0x2e,0x33,0x31,0x32, + 0x2c,0x31,0x2e,0x31,0x31,0x37,0x2c,0x31,0x2e,0x30, + 0x32,0x32,0x63,0x30,0x2c,0x30,0x2e,0x37,0x34,0x37, + 0x2d,0x30,0x2e,0x33,0x39,0x36,0x2c,0x31,0x2e,0x30, + 0x36,0x2d,0x31,0x2e,0x31,0x31,0x37,0x2c,0x31,0x2e, + 0x30,0x36,0x68,0x2d,0x31,0x2e,0x37,0x37,0x39,0x56, + 0x31,0x36,0x2e,0x30,0x38,0x36,0x7a,0x0a,0x09,0x20, + 0x4d,0x31,0x35,0x2e,0x33,0x35,0x33,0x2c,0x32,0x32, + 0x2e,0x32,0x31,0x32,0x68,0x31,0x2e,0x36,0x32,0x76, + 0x2d,0x32,0x2e,0x38,0x38,0x36,0x68,0x31,0x2e,0x36, + 0x32,0x35,0x63,0x30,0x2e,0x38,0x31,0x36,0x2c,0x30, + 0x2c,0x31,0x2e,0x31,0x31,0x37,0x2c,0x30,0x2e,0x33, + 0x34,0x32,0x2c,0x31,0x2e,0x32,0x33,0x2c,0x31,0x2e, + 0x31,0x31,0x38,0x63,0x30,0x2e,0x30,0x38,0x32,0x2c, + 0x30,0x2e,0x35,0x38,0x39,0x2c,0x30,0x2e,0x30,0x36, + 0x31,0x2c,0x31,0x2e,0x33,0x30,0x34,0x2c,0x30,0x2e, + 0x32,0x35,0x38,0x2c,0x31,0x2e,0x37,0x36,0x39,0x68, + 0x31,0x2e,0x36,0x32,0x31,0x0a,0x09,0x63,0x2d,0x30, + 0x2e,0x32,0x38,0x39,0x2d,0x30,0x2e,0x34,0x31,0x34, + 0x2d,0x30,0x2e,0x32,0x37,0x39,0x2d,0x31,0x2e,0x32, + 0x38,0x2d,0x30,0x2e,0x33,0x31,0x33,0x2d,0x31,0x2e, + 0x37,0x34,0x38,0x63,0x2d,0x30,0x2e,0x30,0x35,0x31, + 0x2d,0x30,0x2e,0x37,0x34,0x34,0x2d,0x30,0x2e,0x32, + 0x37,0x35,0x2d,0x31,0x2e,0x35,0x32,0x31,0x2d,0x31, + 0x2e,0x30,0x37,0x2d,0x31,0x2e,0x37,0x32,0x38,0x63, + 0x30,0x2c,0x30,0x2c,0x31,0x2e,0x31,0x36,0x36,0x2d, + 0x30,0x2e,0x33,0x30,0x33,0x2c,0x31,0x2e,0x31,0x36, + 0x36,0x2d,0x31,0x2e,0x38,0x37,0x33,0x0a,0x09,0x63, + 0x30,0x2d,0x31,0x2e,0x31,0x31,0x38,0x2d,0x30,0x2e, + 0x38,0x33,0x38,0x2d,0x32,0x2e,0x30,0x33,0x36,0x2d, + 0x32,0x2e,0x31,0x36,0x2d,0x32,0x2e,0x30,0x33,0x36, + 0x68,0x2d,0x33,0x2e,0x39,0x37,0x39,0x4c,0x31,0x35, + 0x2e,0x33,0x35,0x33,0x2c,0x32,0x32,0x2e,0x32,0x31, + 0x32,0x4c,0x31,0x35,0x2e,0x33,0x35,0x33,0x2c,0x32, + 0x32,0x2e,0x32,0x31,0x32,0x7a,0x22,0x2f,0x3e,0x0a, + 0x3c,0x67,0x3e,0x0a,0x09,0x3c,0x70,0x61,0x74,0x68, 0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46, 0x46,0x46,0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d, 0x32,0x39,0x2e,0x32,0x35,0x34,0x2c,0x31,0x31,0x2e, @@ -105,37 +104,37 @@ const unsigned char help_button_r_svg_data[1331] = { 0x36,0x36,0x2d,0x32,0x2e,0x38,0x32,0x39,0x2c,0x37, 0x2e,0x30,0x31,0x32,0x2d,0x36,0x2e,0x33,0x30,0x37, 0x2c,0x37,0x2e,0x30,0x31,0x32,0x48,0x37,0x2e,0x37, - 0x36,0x0d,0x0a,0x09,0x09,0x63,0x2d,0x33,0x2e,0x34, - 0x35,0x32,0x2d,0x30,0x2e,0x30,0x33,0x2d,0x36,0x2e, - 0x32,0x36,0x2d,0x33,0x2e,0x31,0x37,0x37,0x2d,0x36, - 0x2e,0x32,0x36,0x2d,0x37,0x2e,0x30,0x31,0x32,0x63, - 0x30,0x2d,0x33,0x2e,0x38,0x32,0x37,0x2c,0x32,0x2e, - 0x38,0x30,0x38,0x2d,0x36,0x2e,0x39,0x36,0x36,0x2c, - 0x36,0x2e,0x32,0x34,0x37,0x2d,0x36,0x2e,0x39,0x39, - 0x36,0x48,0x32,0x39,0x2e,0x32,0x35,0x34,0x20,0x4d, - 0x32,0x39,0x2e,0x32,0x35,0x34,0x2c,0x31,0x30,0x2e, - 0x30,0x32,0x36,0x63,0x2d,0x30,0x2e,0x30,0x32,0x31, - 0x2c,0x30,0x2d,0x32,0x31,0x2e,0x35,0x30,0x37,0x2c, + 0x36,0x0a,0x09,0x09,0x63,0x2d,0x33,0x2e,0x34,0x35, + 0x32,0x2d,0x30,0x2e,0x30,0x33,0x2d,0x36,0x2e,0x32, + 0x36,0x2d,0x33,0x2e,0x31,0x37,0x37,0x2d,0x36,0x2e, + 0x32,0x36,0x2d,0x37,0x2e,0x30,0x31,0x32,0x63,0x30, + 0x2d,0x33,0x2e,0x38,0x32,0x37,0x2c,0x32,0x2e,0x38, + 0x30,0x38,0x2d,0x36,0x2e,0x39,0x36,0x36,0x2c,0x36, + 0x2e,0x32,0x34,0x37,0x2d,0x36,0x2e,0x39,0x39,0x36, + 0x48,0x32,0x39,0x2e,0x32,0x35,0x34,0x20,0x4d,0x32, + 0x39,0x2e,0x32,0x35,0x34,0x2c,0x31,0x30,0x2e,0x30, + 0x32,0x36,0x63,0x2d,0x30,0x2e,0x30,0x32,0x31,0x2c, 0x30,0x2d,0x32,0x31,0x2e,0x35,0x30,0x37,0x2c,0x30, - 0x0d,0x0a,0x09,0x09,0x43,0x33,0x2e,0x34,0x36,0x36, - 0x2c,0x31,0x30,0x2e,0x30,0x36,0x33,0x2c,0x30,0x2c, - 0x31,0x33,0x2e,0x38,0x34,0x36,0x2c,0x30,0x2c,0x31, - 0x38,0x2e,0x35,0x32,0x32,0x63,0x30,0x2c,0x34,0x2e, - 0x36,0x37,0x39,0x2c,0x33,0x2e,0x34,0x36,0x36,0x2c, - 0x38,0x2e,0x34,0x37,0x33,0x2c,0x37,0x2e,0x37,0x34, - 0x37,0x2c,0x38,0x2e,0x35,0x31,0x32,0x63,0x30,0x2c, - 0x30,0x2c,0x32,0x31,0x2e,0x34,0x38,0x33,0x2c,0x30, - 0x2c,0x32,0x31,0x2e,0x35,0x30,0x37,0x2c,0x30,0x63, - 0x34,0x2e,0x33,0x31,0x33,0x2c,0x30,0x2c,0x37,0x2e, - 0x38,0x30,0x37,0x2d,0x33,0x2e,0x38,0x31,0x32,0x2c, - 0x37,0x2e,0x38,0x30,0x37,0x2d,0x38,0x2e,0x35,0x31, - 0x32,0x0d,0x0a,0x09,0x09,0x43,0x33,0x37,0x2e,0x30, - 0x36,0x31,0x2c,0x31,0x33,0x2e,0x38,0x32,0x33,0x2c, - 0x33,0x33,0x2e,0x35,0x36,0x36,0x2c,0x31,0x30,0x2e, - 0x30,0x32,0x36,0x2c,0x32,0x39,0x2e,0x32,0x35,0x34, - 0x2c,0x31,0x30,0x2e,0x30,0x32,0x36,0x4c,0x32,0x39, - 0x2e,0x32,0x35,0x34,0x2c,0x31,0x30,0x2e,0x30,0x32, - 0x36,0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x3c,0x2f,0x67, - 0x3e,0x0d,0x0a,0x3c,0x2f,0x73,0x76,0x67,0x3e,0x0d, - 0x0a + 0x2d,0x32,0x31,0x2e,0x35,0x30,0x37,0x2c,0x30,0x0a, + 0x09,0x09,0x43,0x33,0x2e,0x34,0x36,0x36,0x2c,0x31, + 0x30,0x2e,0x30,0x36,0x33,0x2c,0x30,0x2c,0x31,0x33, + 0x2e,0x38,0x34,0x36,0x2c,0x30,0x2c,0x31,0x38,0x2e, + 0x35,0x32,0x32,0x63,0x30,0x2c,0x34,0x2e,0x36,0x37, + 0x39,0x2c,0x33,0x2e,0x34,0x36,0x36,0x2c,0x38,0x2e, + 0x34,0x37,0x33,0x2c,0x37,0x2e,0x37,0x34,0x37,0x2c, + 0x38,0x2e,0x35,0x31,0x32,0x63,0x30,0x2c,0x30,0x2c, + 0x32,0x31,0x2e,0x34,0x38,0x33,0x2c,0x30,0x2c,0x32, + 0x31,0x2e,0x35,0x30,0x37,0x2c,0x30,0x63,0x34,0x2e, + 0x33,0x31,0x33,0x2c,0x30,0x2c,0x37,0x2e,0x38,0x30, + 0x37,0x2d,0x33,0x2e,0x38,0x31,0x32,0x2c,0x37,0x2e, + 0x38,0x30,0x37,0x2d,0x38,0x2e,0x35,0x31,0x32,0x0a, + 0x09,0x09,0x43,0x33,0x37,0x2e,0x30,0x36,0x31,0x2c, + 0x31,0x33,0x2e,0x38,0x32,0x33,0x2c,0x33,0x33,0x2e, + 0x35,0x36,0x36,0x2c,0x31,0x30,0x2e,0x30,0x32,0x36, + 0x2c,0x32,0x39,0x2e,0x32,0x35,0x34,0x2c,0x31,0x30, + 0x2e,0x30,0x32,0x36,0x4c,0x32,0x39,0x2e,0x32,0x35, + 0x34,0x2c,0x31,0x30,0x2e,0x30,0x32,0x36,0x7a,0x22, + 0x2f,0x3e,0x0a,0x3c,0x2f,0x67,0x3e,0x0a,0x3c,0x2f, + 0x73,0x76,0x67,0x3e,0x0a }; + diff --git a/data/converted/help_button_select_svg.cpp b/data/converted/help_button_select_svg.cpp index 703015aedf..b43a0ba62e 100644 --- a/data/converted/help_button_select_svg.cpp +++ b/data/converted/help_button_select_svg.cpp @@ -2,196 +2,194 @@ #include "../Resources.h" -const size_t help_button_select_svg_size = 1891; -const unsigned char help_button_select_svg_data[1891] = { +const size_t help_button_select_svg_size = 1866; +const unsigned char help_button_select_svg_data[1866] = { 0x3c,0x3f,0x78,0x6d,0x6c,0x20,0x76,0x65,0x72,0x73, 0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x30,0x22,0x20, 0x65,0x6e,0x63,0x6f,0x64,0x69,0x6e,0x67,0x3d,0x22, - 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0d,0x0a, - 0x3c,0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72, - 0x61,0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62, - 0x65,0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61, - 0x74,0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33, - 0x2c,0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f, - 0x72,0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e, - 0x20,0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72, - 0x73,0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30, - 0x20,0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20, - 0x20,0x2d,0x2d,0x3e,0x0d,0x0a,0x3c,0x21,0x44,0x4f, - 0x43,0x54,0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20, - 0x50,0x55,0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f, - 0x2f,0x57,0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20, - 0x53,0x56,0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45, - 0x4e,0x22,0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, - 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, - 0x67,0x2f,0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73, - 0x2f,0x53,0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44, - 0x54,0x44,0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64, - 0x74,0x64,0x22,0x3e,0x0d,0x0a,0x3c,0x73,0x76,0x67, - 0x20,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22, - 0x31,0x2e,0x31,0x22,0x20,0x69,0x64,0x3d,0x22,0x5f, - 0x78,0x33,0x30,0x5f,0x22,0x20,0x78,0x6d,0x6c,0x6e, - 0x73,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f, - 0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67, - 0x2f,0x32,0x30,0x30,0x30,0x2f,0x73,0x76,0x67,0x22, - 0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78,0x6c,0x69, - 0x6e,0x6b,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, - 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, - 0x67,0x2f,0x31,0x39,0x39,0x39,0x2f,0x78,0x6c,0x69, - 0x6e,0x6b,0x22,0x20,0x78,0x3d,0x22,0x30,0x70,0x78, - 0x22,0x20,0x79,0x3d,0x22,0x30,0x70,0x78,0x22,0x0d, - 0x0a,0x09,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22, - 0x33,0x37,0x2e,0x30,0x36,0x31,0x70,0x78,0x22,0x20, - 0x68,0x65,0x69,0x67,0x68,0x74,0x3d,0x22,0x33,0x37, - 0x2e,0x30,0x36,0x31,0x70,0x78,0x22,0x20,0x76,0x69, - 0x65,0x77,0x42,0x6f,0x78,0x3d,0x22,0x30,0x20,0x30, - 0x20,0x33,0x37,0x2e,0x30,0x36,0x31,0x20,0x33,0x37, - 0x2e,0x30,0x36,0x31,0x22,0x20,0x65,0x6e,0x61,0x62, - 0x6c,0x65,0x2d,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f, - 0x75,0x6e,0x64,0x3d,0x22,0x6e,0x65,0x77,0x20,0x30, - 0x20,0x30,0x20,0x33,0x37,0x2e,0x30,0x36,0x31,0x20, - 0x33,0x37,0x2e,0x30,0x36,0x31,0x22,0x20,0x78,0x6d, - 0x6c,0x3a,0x73,0x70,0x61,0x63,0x65,0x3d,0x22,0x70, - 0x72,0x65,0x73,0x65,0x72,0x76,0x65,0x22,0x3e,0x0d, - 0x0a,0x3c,0x67,0x3e,0x0d,0x0a,0x09,0x3c,0x67,0x3e, - 0x0d,0x0a,0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20, - 0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46, - 0x46,0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x33, - 0x33,0x2e,0x32,0x31,0x37,0x2c,0x31,0x39,0x2e,0x31, - 0x31,0x38,0x48,0x33,0x2e,0x38,0x34,0x35,0x43,0x31, - 0x2e,0x37,0x32,0x32,0x2c,0x31,0x39,0x2e,0x31,0x31, - 0x38,0x2c,0x30,0x2c,0x32,0x30,0x2e,0x38,0x39,0x2c, - 0x30,0x2c,0x32,0x33,0x2e,0x30,0x37,0x35,0x73,0x31, - 0x2e,0x37,0x32,0x32,0x2c,0x33,0x2e,0x39,0x35,0x37, - 0x2c,0x33,0x2e,0x38,0x34,0x35,0x2c,0x33,0x2e,0x39, - 0x35,0x37,0x68,0x32,0x39,0x2e,0x33,0x37,0x32,0x0d, - 0x0a,0x09,0x09,0x09,0x63,0x32,0x2e,0x31,0x32,0x33, - 0x2c,0x30,0x2c,0x33,0x2e,0x38,0x34,0x34,0x2d,0x31, - 0x2e,0x37,0x37,0x31,0x2c,0x33,0x2e,0x38,0x34,0x34, - 0x2d,0x33,0x2e,0x39,0x35,0x37,0x43,0x33,0x37,0x2e, - 0x30,0x36,0x31,0x2c,0x32,0x30,0x2e,0x38,0x38,0x39, - 0x2c,0x33,0x35,0x2e,0x33,0x34,0x2c,0x31,0x39,0x2e, - 0x31,0x31,0x38,0x2c,0x33,0x33,0x2e,0x32,0x31,0x37, - 0x2c,0x31,0x39,0x2e,0x31,0x31,0x38,0x7a,0x22,0x2f, - 0x3e,0x0d,0x0a,0x09,0x3c,0x2f,0x67,0x3e,0x0d,0x0a, - 0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x3c,0x70,0x61,0x74, - 0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46, - 0x46,0x46,0x46,0x46,0x46,0x22,0x20,0x64,0x3d,0x22, - 0x4d,0x33,0x33,0x2e,0x37,0x35,0x37,0x2c,0x31,0x35, - 0x2e,0x35,0x34,0x39,0x68,0x31,0x2e,0x31,0x38,0x36, - 0x56,0x39,0x2e,0x34,0x37,0x34,0x68,0x32,0x2e,0x31, - 0x32,0x34,0x56,0x38,0x2e,0x33,0x34,0x35,0x68,0x2d, - 0x35,0x2e,0x34,0x33,0x33,0x76,0x31,0x2e,0x31,0x32, - 0x38,0x68,0x32,0x2e,0x31,0x32,0x33,0x56,0x31,0x35, - 0x2e,0x35,0x34,0x39,0x7a,0x20,0x4d,0x33,0x30,0x2e, - 0x38,0x35,0x35,0x2c,0x31,0x31,0x2e,0x30,0x30,0x37, - 0x0d,0x0a,0x09,0x63,0x2d,0x30,0x2e,0x31,0x32,0x36, - 0x2d,0x31,0x2e,0x35,0x35,0x34,0x2d,0x31,0x2e,0x31, - 0x34,0x31,0x2d,0x32,0x2e,0x38,0x36,0x34,0x2d,0x33, - 0x2e,0x30,0x38,0x37,0x2d,0x32,0x2e,0x38,0x36,0x34, - 0x63,0x2d,0x32,0x2e,0x32,0x32,0x35,0x2c,0x30,0x2d, - 0x33,0x2e,0x31,0x36,0x32,0x2c,0x31,0x2e,0x37,0x37, - 0x33,0x2d,0x33,0x2e,0x31,0x36,0x32,0x2c,0x33,0x2e, - 0x38,0x30,0x35,0x63,0x30,0x2c,0x32,0x2e,0x30,0x32, - 0x36,0x2c,0x30,0x2e,0x39,0x37,0x39,0x2c,0x33,0x2e, - 0x38,0x30,0x34,0x2c,0x33,0x2e,0x30,0x32,0x31,0x2c, - 0x33,0x2e,0x38,0x30,0x34,0x0d,0x0a,0x09,0x63,0x32, - 0x2e,0x33,0x32,0x38,0x2c,0x30,0x2c,0x33,0x2e,0x30, - 0x36,0x33,0x2d,0x31,0x2e,0x35,0x32,0x31,0x2c,0x33, - 0x2e,0x32,0x32,0x39,0x2d,0x32,0x2e,0x39,0x35,0x38, - 0x68,0x2d,0x31,0x2e,0x32,0x38,0x63,0x2d,0x30,0x2e, - 0x30,0x39,0x39,0x2c,0x30,0x2e,0x37,0x35,0x37,0x2d, - 0x30,0x2e,0x35,0x31,0x2c,0x31,0x2e,0x38,0x32,0x39, - 0x2d,0x31,0x2e,0x37,0x34,0x33,0x2c,0x31,0x2e,0x38, - 0x32,0x39,0x63,0x2d,0x31,0x2e,0x31,0x37,0x35,0x2c, - 0x30,0x2d,0x31,0x2e,0x39,0x38,0x38,0x2d,0x31,0x2e, - 0x30,0x34,0x32,0x2d,0x31,0x2e,0x39,0x38,0x38,0x2d, - 0x32,0x2e,0x35,0x34,0x36,0x0d,0x0a,0x09,0x63,0x30, - 0x2d,0x31,0x2e,0x38,0x37,0x37,0x2c,0x30,0x2e,0x38, - 0x31,0x33,0x2d,0x32,0x2e,0x38,0x30,0x38,0x2c,0x31, - 0x2e,0x39,0x30,0x38,0x2d,0x32,0x2e,0x38,0x30,0x38, - 0x63,0x30,0x2e,0x39,0x39,0x39,0x2c,0x30,0x2c,0x31, - 0x2e,0x37,0x30,0x34,0x2c,0x30,0x2e,0x36,0x34,0x36, - 0x2c,0x31,0x2e,0x38,0x32,0x33,0x2c,0x31,0x2e,0x37, - 0x33,0x37,0x4c,0x33,0x30,0x2e,0x38,0x35,0x35,0x2c, - 0x31,0x31,0x2e,0x30,0x30,0x37,0x4c,0x33,0x30,0x2e, - 0x38,0x35,0x35,0x2c,0x31,0x31,0x2e,0x30,0x30,0x37, - 0x7a,0x20,0x4d,0x31,0x38,0x2e,0x36,0x35,0x39,0x2c, - 0x31,0x35,0x2e,0x35,0x34,0x39,0x68,0x34,0x2e,0x39, - 0x37,0x33,0x56,0x31,0x34,0x2e,0x34,0x32,0x68,0x2d, - 0x33,0x2e,0x37,0x38,0x36,0x0d,0x0a,0x09,0x76,0x2d, - 0x31,0x2e,0x39,0x39,0x38,0x68,0x33,0x2e,0x35,0x37, - 0x33,0x76,0x2d,0x31,0x2e,0x31,0x32,0x39,0x68,0x2d, - 0x33,0x2e,0x35,0x37,0x33,0x56,0x39,0x2e,0x34,0x37, - 0x34,0x68,0x33,0x2e,0x37,0x32,0x31,0x56,0x38,0x2e, - 0x33,0x34,0x35,0x48,0x31,0x38,0x2e,0x36,0x36,0x4c, - 0x31,0x38,0x2e,0x36,0x35,0x39,0x2c,0x31,0x35,0x2e, - 0x35,0x34,0x39,0x4c,0x31,0x38,0x2e,0x36,0x35,0x39, - 0x2c,0x31,0x35,0x2e,0x35,0x34,0x39,0x7a,0x20,0x4d, - 0x31,0x32,0x2e,0x39,0x37,0x39,0x2c,0x31,0x35,0x2e, - 0x35,0x34,0x39,0x68,0x34,0x2e,0x36,0x32,0x35,0x76, - 0x2d,0x31,0x2e,0x31,0x38,0x38,0x68,0x2d,0x33,0x2e, - 0x34,0x33,0x37,0x56,0x38,0x2e,0x33,0x34,0x35,0x0d, - 0x0a,0x09,0x68,0x2d,0x31,0x2e,0x31,0x38,0x38,0x56, - 0x31,0x35,0x2e,0x35,0x34,0x39,0x7a,0x20,0x4d,0x36, - 0x2e,0x37,0x31,0x34,0x2c,0x31,0x35,0x2e,0x35,0x34, - 0x39,0x68,0x34,0x2e,0x39,0x37,0x34,0x56,0x31,0x34, - 0x2e,0x34,0x32,0x48,0x37,0x2e,0x39,0x30,0x32,0x76, - 0x2d,0x31,0x2e,0x39,0x39,0x38,0x68,0x33,0x2e,0x35, - 0x37,0x32,0x76,0x2d,0x31,0x2e,0x31,0x32,0x39,0x48, - 0x37,0x2e,0x39,0x30,0x32,0x56,0x39,0x2e,0x34,0x37, - 0x34,0x68,0x33,0x2e,0x37,0x32,0x36,0x56,0x38,0x2e, - 0x33,0x34,0x35,0x48,0x36,0x2e,0x37,0x31,0x34,0x56, - 0x31,0x35,0x2e,0x35,0x34,0x39,0x7a,0x20,0x4d,0x30, - 0x2e,0x31,0x34,0x39,0x2c,0x31,0x30,0x2e,0x33,0x37, - 0x32,0x0d,0x0a,0x09,0x63,0x30,0x2c,0x32,0x2e,0x39, - 0x35,0x35,0x2c,0x34,0x2e,0x31,0x36,0x37,0x2c,0x31, - 0x2e,0x33,0x39,0x38,0x2c,0x34,0x2e,0x31,0x36,0x37, - 0x2c,0x33,0x2e,0x31,0x38,0x36,0x63,0x30,0x2c,0x30, - 0x2e,0x37,0x39,0x32,0x2d,0x30,0x2e,0x36,0x37,0x33, - 0x2c,0x31,0x2e,0x30,0x36,0x34,0x2d,0x31,0x2e,0x33, - 0x39,0x35,0x2c,0x31,0x2e,0x30,0x36,0x34,0x63,0x2d, - 0x30,0x2e,0x39,0x37,0x36,0x2c,0x30,0x2d,0x31,0x2e, - 0x35,0x39,0x31,0x2d,0x30,0x2e,0x34,0x35,0x36,0x2d, - 0x31,0x2e,0x36,0x32,0x34,0x2d,0x31,0x2e,0x34,0x30, - 0x37,0x48,0x30,0x2e,0x30,0x31,0x35,0x0d,0x0a,0x09, - 0x43,0x30,0x2e,0x30,0x33,0x2c,0x31,0x34,0x2e,0x37, - 0x33,0x2c,0x30,0x2e,0x38,0x34,0x36,0x2c,0x31,0x35, - 0x2e,0x37,0x35,0x2c,0x32,0x2e,0x38,0x38,0x32,0x2c, - 0x31,0x35,0x2e,0x37,0x35,0x63,0x31,0x2e,0x32,0x30, - 0x35,0x2c,0x30,0x2c,0x32,0x2e,0x37,0x31,0x36,0x2d, - 0x30,0x2e,0x34,0x38,0x34,0x2c,0x32,0x2e,0x37,0x31, - 0x36,0x2d,0x32,0x2e,0x33,0x34,0x33,0x63,0x30,0x2d, - 0x33,0x2e,0x30,0x37,0x37,0x2d,0x34,0x2e,0x32,0x31, - 0x33,0x2d,0x31,0x2e,0x34,0x35,0x35,0x2d,0x34,0x2e, - 0x32,0x31,0x33,0x2d,0x33,0x2e,0x31,0x34,0x36,0x0d, - 0x0a,0x09,0x63,0x30,0x2d,0x30,0x2e,0x36,0x37,0x37, - 0x2c,0x30,0x2e,0x35,0x32,0x33,0x2d,0x30,0x2e,0x39, - 0x39,0x31,0x2c,0x31,0x2e,0x33,0x31,0x33,0x2d,0x30, - 0x2e,0x39,0x39,0x31,0x63,0x30,0x2e,0x39,0x39,0x2c, - 0x30,0x2c,0x31,0x2e,0x33,0x38,0x38,0x2c,0x30,0x2e, - 0x36,0x30,0x35,0x2c,0x31,0x2e,0x34,0x32,0x38,0x2c, - 0x31,0x2e,0x31,0x36,0x33,0x48,0x35,0x2e,0x34,0x31, - 0x63,0x2d,0x30,0x2e,0x31,0x35,0x32,0x2d,0x32,0x2e, - 0x30,0x39,0x31,0x2d,0x31,0x2e,0x38,0x39,0x36,0x2d, - 0x32,0x2e,0x32,0x39,0x2d,0x32,0x2e,0x37,0x36,0x37, - 0x2d,0x32,0x2e,0x32,0x39,0x0d,0x0a,0x09,0x43,0x31, + 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0a,0x3c, + 0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72,0x61, + 0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62,0x65, + 0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61,0x74, + 0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33,0x2c, + 0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f,0x72, + 0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e,0x20, + 0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72,0x73, + 0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30,0x20, + 0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20,0x20, + 0x2d,0x2d,0x3e,0x0a,0x3c,0x21,0x44,0x4f,0x43,0x54, + 0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20,0x50,0x55, + 0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f,0x2f,0x57, + 0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20,0x53,0x56, + 0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45,0x4e,0x22, + 0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73,0x2f,0x53, + 0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44,0x54,0x44, + 0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64,0x74,0x64, + 0x22,0x3e,0x0a,0x3c,0x73,0x76,0x67,0x20,0x76,0x65, + 0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x31, + 0x22,0x20,0x69,0x64,0x3d,0x22,0x5f,0x78,0x33,0x30, + 0x5f,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3d,0x22, + 0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77, + 0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f,0x32,0x30, + 0x30,0x30,0x2f,0x73,0x76,0x67,0x22,0x20,0x78,0x6d, + 0x6c,0x6e,0x73,0x3a,0x78,0x6c,0x69,0x6e,0x6b,0x3d, + 0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77, + 0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f,0x31, + 0x39,0x39,0x39,0x2f,0x78,0x6c,0x69,0x6e,0x6b,0x22, + 0x20,0x78,0x3d,0x22,0x30,0x70,0x78,0x22,0x20,0x79, + 0x3d,0x22,0x30,0x70,0x78,0x22,0x0a,0x09,0x20,0x77, + 0x69,0x64,0x74,0x68,0x3d,0x22,0x33,0x37,0x2e,0x30, + 0x36,0x31,0x70,0x78,0x22,0x20,0x68,0x65,0x69,0x67, + 0x68,0x74,0x3d,0x22,0x33,0x37,0x2e,0x30,0x36,0x31, + 0x70,0x78,0x22,0x20,0x76,0x69,0x65,0x77,0x42,0x6f, + 0x78,0x3d,0x22,0x30,0x20,0x30,0x20,0x33,0x37,0x2e, + 0x30,0x36,0x31,0x20,0x33,0x37,0x2e,0x30,0x36,0x31, + 0x22,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0x2d,0x62, + 0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x3d, + 0x22,0x6e,0x65,0x77,0x20,0x30,0x20,0x30,0x20,0x33, + 0x37,0x2e,0x30,0x36,0x31,0x20,0x33,0x37,0x2e,0x30, + 0x36,0x31,0x22,0x20,0x78,0x6d,0x6c,0x3a,0x73,0x70, + 0x61,0x63,0x65,0x3d,0x22,0x70,0x72,0x65,0x73,0x65, + 0x72,0x76,0x65,0x22,0x3e,0x0a,0x3c,0x67,0x3e,0x0a, + 0x09,0x3c,0x67,0x3e,0x0a,0x09,0x09,0x3c,0x70,0x61, + 0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23, + 0x46,0x46,0x46,0x46,0x46,0x46,0x22,0x20,0x64,0x3d, + 0x22,0x4d,0x33,0x33,0x2e,0x32,0x31,0x37,0x2c,0x31, + 0x39,0x2e,0x31,0x31,0x38,0x48,0x33,0x2e,0x38,0x34, + 0x35,0x43,0x31,0x2e,0x37,0x32,0x32,0x2c,0x31,0x39, + 0x2e,0x31,0x31,0x38,0x2c,0x30,0x2c,0x32,0x30,0x2e, + 0x38,0x39,0x2c,0x30,0x2c,0x32,0x33,0x2e,0x30,0x37, + 0x35,0x73,0x31,0x2e,0x37,0x32,0x32,0x2c,0x33,0x2e, + 0x39,0x35,0x37,0x2c,0x33,0x2e,0x38,0x34,0x35,0x2c, + 0x33,0x2e,0x39,0x35,0x37,0x68,0x32,0x39,0x2e,0x33, + 0x37,0x32,0x0a,0x09,0x09,0x09,0x63,0x32,0x2e,0x31, + 0x32,0x33,0x2c,0x30,0x2c,0x33,0x2e,0x38,0x34,0x34, + 0x2d,0x31,0x2e,0x37,0x37,0x31,0x2c,0x33,0x2e,0x38, + 0x34,0x34,0x2d,0x33,0x2e,0x39,0x35,0x37,0x43,0x33, + 0x37,0x2e,0x30,0x36,0x31,0x2c,0x32,0x30,0x2e,0x38, + 0x38,0x39,0x2c,0x33,0x35,0x2e,0x33,0x34,0x2c,0x31, + 0x39,0x2e,0x31,0x31,0x38,0x2c,0x33,0x33,0x2e,0x32, + 0x31,0x37,0x2c,0x31,0x39,0x2e,0x31,0x31,0x38,0x7a, + 0x22,0x2f,0x3e,0x0a,0x09,0x3c,0x2f,0x67,0x3e,0x0a, + 0x3c,0x2f,0x67,0x3e,0x0a,0x3c,0x70,0x61,0x74,0x68, + 0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46, + 0x46,0x46,0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d, + 0x33,0x33,0x2e,0x37,0x35,0x37,0x2c,0x31,0x35,0x2e, + 0x35,0x34,0x39,0x68,0x31,0x2e,0x31,0x38,0x36,0x56, + 0x39,0x2e,0x34,0x37,0x34,0x68,0x32,0x2e,0x31,0x32, + 0x34,0x56,0x38,0x2e,0x33,0x34,0x35,0x68,0x2d,0x35, + 0x2e,0x34,0x33,0x33,0x76,0x31,0x2e,0x31,0x32,0x38, + 0x68,0x32,0x2e,0x31,0x32,0x33,0x56,0x31,0x35,0x2e, + 0x35,0x34,0x39,0x7a,0x20,0x4d,0x33,0x30,0x2e,0x38, + 0x35,0x35,0x2c,0x31,0x31,0x2e,0x30,0x30,0x37,0x0a, + 0x09,0x63,0x2d,0x30,0x2e,0x31,0x32,0x36,0x2d,0x31, + 0x2e,0x35,0x35,0x34,0x2d,0x31,0x2e,0x31,0x34,0x31, + 0x2d,0x32,0x2e,0x38,0x36,0x34,0x2d,0x33,0x2e,0x30, + 0x38,0x37,0x2d,0x32,0x2e,0x38,0x36,0x34,0x63,0x2d, + 0x32,0x2e,0x32,0x32,0x35,0x2c,0x30,0x2d,0x33,0x2e, + 0x31,0x36,0x32,0x2c,0x31,0x2e,0x37,0x37,0x33,0x2d, + 0x33,0x2e,0x31,0x36,0x32,0x2c,0x33,0x2e,0x38,0x30, + 0x35,0x63,0x30,0x2c,0x32,0x2e,0x30,0x32,0x36,0x2c, + 0x30,0x2e,0x39,0x37,0x39,0x2c,0x33,0x2e,0x38,0x30, + 0x34,0x2c,0x33,0x2e,0x30,0x32,0x31,0x2c,0x33,0x2e, + 0x38,0x30,0x34,0x0a,0x09,0x63,0x32,0x2e,0x33,0x32, + 0x38,0x2c,0x30,0x2c,0x33,0x2e,0x30,0x36,0x33,0x2d, + 0x31,0x2e,0x35,0x32,0x31,0x2c,0x33,0x2e,0x32,0x32, + 0x39,0x2d,0x32,0x2e,0x39,0x35,0x38,0x68,0x2d,0x31, + 0x2e,0x32,0x38,0x63,0x2d,0x30,0x2e,0x30,0x39,0x39, + 0x2c,0x30,0x2e,0x37,0x35,0x37,0x2d,0x30,0x2e,0x35, + 0x31,0x2c,0x31,0x2e,0x38,0x32,0x39,0x2d,0x31,0x2e, + 0x37,0x34,0x33,0x2c,0x31,0x2e,0x38,0x32,0x39,0x63, + 0x2d,0x31,0x2e,0x31,0x37,0x35,0x2c,0x30,0x2d,0x31, + 0x2e,0x39,0x38,0x38,0x2d,0x31,0x2e,0x30,0x34,0x32, + 0x2d,0x31,0x2e,0x39,0x38,0x38,0x2d,0x32,0x2e,0x35, + 0x34,0x36,0x0a,0x09,0x63,0x30,0x2d,0x31,0x2e,0x38, + 0x37,0x37,0x2c,0x30,0x2e,0x38,0x31,0x33,0x2d,0x32, + 0x2e,0x38,0x30,0x38,0x2c,0x31,0x2e,0x39,0x30,0x38, + 0x2d,0x32,0x2e,0x38,0x30,0x38,0x63,0x30,0x2e,0x39, + 0x39,0x39,0x2c,0x30,0x2c,0x31,0x2e,0x37,0x30,0x34, + 0x2c,0x30,0x2e,0x36,0x34,0x36,0x2c,0x31,0x2e,0x38, + 0x32,0x33,0x2c,0x31,0x2e,0x37,0x33,0x37,0x4c,0x33, + 0x30,0x2e,0x38,0x35,0x35,0x2c,0x31,0x31,0x2e,0x30, + 0x30,0x37,0x4c,0x33,0x30,0x2e,0x38,0x35,0x35,0x2c, + 0x31,0x31,0x2e,0x30,0x30,0x37,0x7a,0x20,0x4d,0x31, + 0x38,0x2e,0x36,0x35,0x39,0x2c,0x31,0x35,0x2e,0x35, + 0x34,0x39,0x68,0x34,0x2e,0x39,0x37,0x33,0x56,0x31, + 0x34,0x2e,0x34,0x32,0x68,0x2d,0x33,0x2e,0x37,0x38, + 0x36,0x0a,0x09,0x76,0x2d,0x31,0x2e,0x39,0x39,0x38, + 0x68,0x33,0x2e,0x35,0x37,0x33,0x76,0x2d,0x31,0x2e, + 0x31,0x32,0x39,0x68,0x2d,0x33,0x2e,0x35,0x37,0x33, + 0x56,0x39,0x2e,0x34,0x37,0x34,0x68,0x33,0x2e,0x37, + 0x32,0x31,0x56,0x38,0x2e,0x33,0x34,0x35,0x48,0x31, + 0x38,0x2e,0x36,0x36,0x4c,0x31,0x38,0x2e,0x36,0x35, + 0x39,0x2c,0x31,0x35,0x2e,0x35,0x34,0x39,0x4c,0x31, + 0x38,0x2e,0x36,0x35,0x39,0x2c,0x31,0x35,0x2e,0x35, + 0x34,0x39,0x7a,0x20,0x4d,0x31,0x32,0x2e,0x39,0x37, + 0x39,0x2c,0x31,0x35,0x2e,0x35,0x34,0x39,0x68,0x34, + 0x2e,0x36,0x32,0x35,0x76,0x2d,0x31,0x2e,0x31,0x38, + 0x38,0x68,0x2d,0x33,0x2e,0x34,0x33,0x37,0x56,0x38, + 0x2e,0x33,0x34,0x35,0x0a,0x09,0x68,0x2d,0x31,0x2e, + 0x31,0x38,0x38,0x56,0x31,0x35,0x2e,0x35,0x34,0x39, + 0x7a,0x20,0x4d,0x36,0x2e,0x37,0x31,0x34,0x2c,0x31, + 0x35,0x2e,0x35,0x34,0x39,0x68,0x34,0x2e,0x39,0x37, + 0x34,0x56,0x31,0x34,0x2e,0x34,0x32,0x48,0x37,0x2e, + 0x39,0x30,0x32,0x76,0x2d,0x31,0x2e,0x39,0x39,0x38, + 0x68,0x33,0x2e,0x35,0x37,0x32,0x76,0x2d,0x31,0x2e, + 0x31,0x32,0x39,0x48,0x37,0x2e,0x39,0x30,0x32,0x56, + 0x39,0x2e,0x34,0x37,0x34,0x68,0x33,0x2e,0x37,0x32, + 0x36,0x56,0x38,0x2e,0x33,0x34,0x35,0x48,0x36,0x2e, + 0x37,0x31,0x34,0x56,0x31,0x35,0x2e,0x35,0x34,0x39, + 0x7a,0x20,0x4d,0x30,0x2e,0x31,0x34,0x39,0x2c,0x31, + 0x30,0x2e,0x33,0x37,0x32,0x0a,0x09,0x63,0x30,0x2c, + 0x32,0x2e,0x39,0x35,0x35,0x2c,0x34,0x2e,0x31,0x36, + 0x37,0x2c,0x31,0x2e,0x33,0x39,0x38,0x2c,0x34,0x2e, + 0x31,0x36,0x37,0x2c,0x33,0x2e,0x31,0x38,0x36,0x63, + 0x30,0x2c,0x30,0x2e,0x37,0x39,0x32,0x2d,0x30,0x2e, + 0x36,0x37,0x33,0x2c,0x31,0x2e,0x30,0x36,0x34,0x2d, + 0x31,0x2e,0x33,0x39,0x35,0x2c,0x31,0x2e,0x30,0x36, + 0x34,0x63,0x2d,0x30,0x2e,0x39,0x37,0x36,0x2c,0x30, + 0x2d,0x31,0x2e,0x35,0x39,0x31,0x2d,0x30,0x2e,0x34, + 0x35,0x36,0x2d,0x31,0x2e,0x36,0x32,0x34,0x2d,0x31, + 0x2e,0x34,0x30,0x37,0x48,0x30,0x2e,0x30,0x31,0x35, + 0x0a,0x09,0x43,0x30,0x2e,0x30,0x33,0x2c,0x31,0x34, + 0x2e,0x37,0x33,0x2c,0x30,0x2e,0x38,0x34,0x36,0x2c, + 0x31,0x35,0x2e,0x37,0x35,0x2c,0x32,0x2e,0x38,0x38, + 0x32,0x2c,0x31,0x35,0x2e,0x37,0x35,0x63,0x31,0x2e, + 0x32,0x30,0x35,0x2c,0x30,0x2c,0x32,0x2e,0x37,0x31, + 0x36,0x2d,0x30,0x2e,0x34,0x38,0x34,0x2c,0x32,0x2e, + 0x37,0x31,0x36,0x2d,0x32,0x2e,0x33,0x34,0x33,0x63, + 0x30,0x2d,0x33,0x2e,0x30,0x37,0x37,0x2d,0x34,0x2e, + 0x32,0x31,0x33,0x2d,0x31,0x2e,0x34,0x35,0x35,0x2d, + 0x34,0x2e,0x32,0x31,0x33,0x2d,0x33,0x2e,0x31,0x34, + 0x36,0x0a,0x09,0x63,0x30,0x2d,0x30,0x2e,0x36,0x37, + 0x37,0x2c,0x30,0x2e,0x35,0x32,0x33,0x2d,0x30,0x2e, + 0x39,0x39,0x31,0x2c,0x31,0x2e,0x33,0x31,0x33,0x2d, + 0x30,0x2e,0x39,0x39,0x31,0x63,0x30,0x2e,0x39,0x39, + 0x2c,0x30,0x2c,0x31,0x2e,0x33,0x38,0x38,0x2c,0x30, + 0x2e,0x36,0x30,0x35,0x2c,0x31,0x2e,0x34,0x32,0x38, + 0x2c,0x31,0x2e,0x31,0x36,0x33,0x48,0x35,0x2e,0x34, + 0x31,0x63,0x2d,0x30,0x2e,0x31,0x35,0x32,0x2d,0x32, + 0x2e,0x30,0x39,0x31,0x2d,0x31,0x2e,0x38,0x39,0x36, + 0x2d,0x32,0x2e,0x32,0x39,0x2d,0x32,0x2e,0x37,0x36, + 0x37,0x2d,0x32,0x2e,0x32,0x39,0x0a,0x09,0x43,0x31, 0x2e,0x32,0x36,0x36,0x2c,0x38,0x2e,0x31,0x34,0x33, 0x2c,0x30,0x2e,0x31,0x34,0x39,0x2c,0x38,0x2e,0x37, 0x36,0x37,0x2c,0x30,0x2e,0x31,0x34,0x39,0x2c,0x31, - 0x30,0x2e,0x33,0x37,0x32,0x22,0x2f,0x3e,0x0d,0x0a, - 0x3c,0x67,0x20,0x6f,0x70,0x61,0x63,0x69,0x74,0x79, - 0x3d,0x22,0x30,0x22,0x3e,0x0d,0x0a,0x09,0x3c,0x70, - 0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22, - 0x23,0x46,0x46,0x46,0x46,0x46,0x46,0x22,0x20,0x64, - 0x3d,0x22,0x4d,0x33,0x36,0x2e,0x39,0x36,0x31,0x2c, - 0x30,0x2e,0x31,0x76,0x33,0x36,0x2e,0x38,0x36,0x31, - 0x48,0x30,0x2e,0x31,0x56,0x30,0x2e,0x31,0x48,0x33, - 0x36,0x2e,0x39,0x36,0x31,0x20,0x4d,0x33,0x37,0x2e, - 0x30,0x36,0x31,0x2c,0x30,0x48,0x30,0x76,0x33,0x37, - 0x2e,0x30,0x36,0x68,0x33,0x37,0x2e,0x30,0x36,0x31, - 0x56,0x30,0x4c,0x33,0x37,0x2e,0x30,0x36,0x31,0x2c, - 0x30,0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x3c,0x2f,0x67, - 0x3e,0x0d,0x0a,0x3c,0x2f,0x73,0x76,0x67,0x3e,0x0d, - 0x0a + 0x30,0x2e,0x33,0x37,0x32,0x22,0x2f,0x3e,0x0a,0x3c, + 0x67,0x20,0x6f,0x70,0x61,0x63,0x69,0x74,0x79,0x3d, + 0x22,0x30,0x22,0x3e,0x0a,0x09,0x3c,0x70,0x61,0x74, + 0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46, + 0x46,0x46,0x46,0x46,0x46,0x22,0x20,0x64,0x3d,0x22, + 0x4d,0x33,0x36,0x2e,0x39,0x36,0x31,0x2c,0x30,0x2e, + 0x31,0x76,0x33,0x36,0x2e,0x38,0x36,0x31,0x48,0x30, + 0x2e,0x31,0x56,0x30,0x2e,0x31,0x48,0x33,0x36,0x2e, + 0x39,0x36,0x31,0x20,0x4d,0x33,0x37,0x2e,0x30,0x36, + 0x31,0x2c,0x30,0x48,0x30,0x76,0x33,0x37,0x2e,0x30, + 0x36,0x68,0x33,0x37,0x2e,0x30,0x36,0x31,0x56,0x30, + 0x4c,0x33,0x37,0x2e,0x30,0x36,0x31,0x2c,0x30,0x7a, + 0x22,0x2f,0x3e,0x0a,0x3c,0x2f,0x67,0x3e,0x0a,0x3c, + 0x2f,0x73,0x76,0x67,0x3e,0x0a }; + diff --git a/data/converted/help_button_start_svg.cpp b/data/converted/help_button_start_svg.cpp index 8eac864831..06c552c910 100644 --- a/data/converted/help_button_start_svg.cpp +++ b/data/converted/help_button_start_svg.cpp @@ -2,118 +2,117 @@ #include "../Resources.h" -const size_t help_button_start_svg_size = 1791; -const unsigned char help_button_start_svg_data[1791] = { +const size_t help_button_start_svg_size = 1769; +const unsigned char help_button_start_svg_data[1769] = { 0x3c,0x3f,0x78,0x6d,0x6c,0x20,0x76,0x65,0x72,0x73, 0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x30,0x22,0x20, 0x65,0x6e,0x63,0x6f,0x64,0x69,0x6e,0x67,0x3d,0x22, - 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0d,0x0a, - 0x3c,0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72, - 0x61,0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62, - 0x65,0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61, - 0x74,0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33, - 0x2c,0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f, - 0x72,0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e, - 0x20,0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72, - 0x73,0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30, - 0x20,0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20, - 0x20,0x2d,0x2d,0x3e,0x0d,0x0a,0x3c,0x21,0x44,0x4f, - 0x43,0x54,0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20, - 0x50,0x55,0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f, - 0x2f,0x57,0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20, - 0x53,0x56,0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45, - 0x4e,0x22,0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, - 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, - 0x67,0x2f,0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73, - 0x2f,0x53,0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44, - 0x54,0x44,0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64, - 0x74,0x64,0x22,0x3e,0x0d,0x0a,0x3c,0x73,0x76,0x67, - 0x20,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22, - 0x31,0x2e,0x31,0x22,0x20,0x69,0x64,0x3d,0x22,0x5f, - 0x78,0x33,0x30,0x5f,0x22,0x20,0x78,0x6d,0x6c,0x6e, - 0x73,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f, - 0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67, - 0x2f,0x32,0x30,0x30,0x30,0x2f,0x73,0x76,0x67,0x22, - 0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78,0x6c,0x69, - 0x6e,0x6b,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, - 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, - 0x67,0x2f,0x31,0x39,0x39,0x39,0x2f,0x78,0x6c,0x69, - 0x6e,0x6b,0x22,0x20,0x78,0x3d,0x22,0x30,0x70,0x78, - 0x22,0x20,0x79,0x3d,0x22,0x30,0x70,0x78,0x22,0x0d, - 0x0a,0x09,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22, - 0x33,0x37,0x2e,0x30,0x36,0x31,0x70,0x78,0x22,0x20, - 0x68,0x65,0x69,0x67,0x68,0x74,0x3d,0x22,0x33,0x37, - 0x2e,0x30,0x36,0x31,0x70,0x78,0x22,0x20,0x76,0x69, - 0x65,0x77,0x42,0x6f,0x78,0x3d,0x22,0x30,0x20,0x30, - 0x20,0x33,0x37,0x2e,0x30,0x36,0x31,0x20,0x33,0x37, - 0x2e,0x30,0x36,0x31,0x22,0x20,0x65,0x6e,0x61,0x62, - 0x6c,0x65,0x2d,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f, - 0x75,0x6e,0x64,0x3d,0x22,0x6e,0x65,0x77,0x20,0x30, - 0x20,0x30,0x20,0x33,0x37,0x2e,0x30,0x36,0x31,0x20, - 0x33,0x37,0x2e,0x30,0x36,0x31,0x22,0x20,0x78,0x6d, - 0x6c,0x3a,0x73,0x70,0x61,0x63,0x65,0x3d,0x22,0x70, - 0x72,0x65,0x73,0x65,0x72,0x76,0x65,0x22,0x3e,0x0d, - 0x0a,0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69,0x6c, - 0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46,0x46, - 0x22,0x20,0x64,0x3d,0x22,0x4d,0x33,0x33,0x2e,0x30, - 0x36,0x35,0x2c,0x31,0x35,0x2e,0x35,0x34,0x38,0x68, - 0x31,0x2e,0x34,0x33,0x38,0x56,0x39,0x2e,0x34,0x37, - 0x31,0x68,0x32,0x2e,0x35,0x36,0x33,0x76,0x2d,0x31, - 0x2e,0x31,0x33,0x68,0x2d,0x36,0x2e,0x35,0x36,0x33, - 0x76,0x31,0x2e,0x31,0x33,0x68,0x32,0x2e,0x35,0x36, - 0x33,0x4c,0x33,0x33,0x2e,0x30,0x36,0x35,0x2c,0x31, - 0x35,0x2e,0x35,0x34,0x38,0x4c,0x33,0x33,0x2e,0x30, - 0x36,0x35,0x2c,0x31,0x35,0x2e,0x35,0x34,0x38,0x7a, - 0x20,0x4d,0x32,0x34,0x2e,0x33,0x35,0x31,0x2c,0x31, - 0x31,0x2e,0x35,0x37,0x33,0x0d,0x0a,0x09,0x56,0x39, - 0x2e,0x34,0x37,0x31,0x68,0x32,0x2e,0x34,0x38,0x32, - 0x63,0x30,0x2e,0x37,0x35,0x35,0x2c,0x30,0x2c,0x31, - 0x2e,0x32,0x32,0x36,0x2c,0x30,0x2e,0x32,0x39,0x32, - 0x2c,0x31,0x2e,0x32,0x32,0x36,0x2c,0x31,0x2e,0x30, - 0x33,0x39,0x63,0x30,0x2c,0x30,0x2e,0x38,0x30,0x38, - 0x2d,0x30,0x2e,0x34,0x33,0x32,0x2c,0x31,0x2e,0x30, - 0x36,0x33,0x2d,0x31,0x2e,0x32,0x32,0x36,0x2c,0x31, - 0x2e,0x30,0x36,0x33,0x48,0x32,0x34,0x2e,0x33,0x35, - 0x31,0x7a,0x20,0x4d,0x32,0x32,0x2e,0x39,0x31,0x37, + 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0a,0x3c, + 0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72,0x61, + 0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62,0x65, + 0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61,0x74, + 0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33,0x2c, + 0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f,0x72, + 0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e,0x20, + 0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72,0x73, + 0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30,0x20, + 0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20,0x20, + 0x2d,0x2d,0x3e,0x0a,0x3c,0x21,0x44,0x4f,0x43,0x54, + 0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20,0x50,0x55, + 0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f,0x2f,0x57, + 0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20,0x53,0x56, + 0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45,0x4e,0x22, + 0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73,0x2f,0x53, + 0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44,0x54,0x44, + 0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64,0x74,0x64, + 0x22,0x3e,0x0a,0x3c,0x73,0x76,0x67,0x20,0x76,0x65, + 0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x31, + 0x22,0x20,0x69,0x64,0x3d,0x22,0x5f,0x78,0x33,0x30, + 0x5f,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3d,0x22, + 0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77, + 0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f,0x32,0x30, + 0x30,0x30,0x2f,0x73,0x76,0x67,0x22,0x20,0x78,0x6d, + 0x6c,0x6e,0x73,0x3a,0x78,0x6c,0x69,0x6e,0x6b,0x3d, + 0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77, + 0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f,0x31, + 0x39,0x39,0x39,0x2f,0x78,0x6c,0x69,0x6e,0x6b,0x22, + 0x20,0x78,0x3d,0x22,0x30,0x70,0x78,0x22,0x20,0x79, + 0x3d,0x22,0x30,0x70,0x78,0x22,0x0a,0x09,0x20,0x77, + 0x69,0x64,0x74,0x68,0x3d,0x22,0x33,0x37,0x2e,0x30, + 0x36,0x31,0x70,0x78,0x22,0x20,0x68,0x65,0x69,0x67, + 0x68,0x74,0x3d,0x22,0x33,0x37,0x2e,0x30,0x36,0x31, + 0x70,0x78,0x22,0x20,0x76,0x69,0x65,0x77,0x42,0x6f, + 0x78,0x3d,0x22,0x30,0x20,0x30,0x20,0x33,0x37,0x2e, + 0x30,0x36,0x31,0x20,0x33,0x37,0x2e,0x30,0x36,0x31, + 0x22,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0x2d,0x62, + 0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x3d, + 0x22,0x6e,0x65,0x77,0x20,0x30,0x20,0x30,0x20,0x33, + 0x37,0x2e,0x30,0x36,0x31,0x20,0x33,0x37,0x2e,0x30, + 0x36,0x31,0x22,0x20,0x78,0x6d,0x6c,0x3a,0x73,0x70, + 0x61,0x63,0x65,0x3d,0x22,0x70,0x72,0x65,0x73,0x65, + 0x72,0x76,0x65,0x22,0x3e,0x0a,0x3c,0x70,0x61,0x74, + 0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46, + 0x46,0x46,0x46,0x46,0x46,0x22,0x20,0x64,0x3d,0x22, + 0x4d,0x33,0x33,0x2e,0x30,0x36,0x35,0x2c,0x31,0x35, + 0x2e,0x35,0x34,0x38,0x68,0x31,0x2e,0x34,0x33,0x38, + 0x56,0x39,0x2e,0x34,0x37,0x31,0x68,0x32,0x2e,0x35, + 0x36,0x33,0x76,0x2d,0x31,0x2e,0x31,0x33,0x68,0x2d, + 0x36,0x2e,0x35,0x36,0x33,0x76,0x31,0x2e,0x31,0x33, + 0x68,0x32,0x2e,0x35,0x36,0x33,0x4c,0x33,0x33,0x2e, + 0x30,0x36,0x35,0x2c,0x31,0x35,0x2e,0x35,0x34,0x38, + 0x4c,0x33,0x33,0x2e,0x30,0x36,0x35,0x2c,0x31,0x35, + 0x2e,0x35,0x34,0x38,0x7a,0x20,0x4d,0x32,0x34,0x2e, + 0x33,0x35,0x31,0x2c,0x31,0x31,0x2e,0x35,0x37,0x33, + 0x0a,0x09,0x56,0x39,0x2e,0x34,0x37,0x31,0x68,0x32, + 0x2e,0x34,0x38,0x32,0x63,0x30,0x2e,0x37,0x35,0x35, + 0x2c,0x30,0x2c,0x31,0x2e,0x32,0x32,0x36,0x2c,0x30, + 0x2e,0x32,0x39,0x32,0x2c,0x31,0x2e,0x32,0x32,0x36, + 0x2c,0x31,0x2e,0x30,0x33,0x39,0x63,0x30,0x2c,0x30, + 0x2e,0x38,0x30,0x38,0x2d,0x30,0x2e,0x34,0x33,0x32, + 0x2c,0x31,0x2e,0x30,0x36,0x33,0x2d,0x31,0x2e,0x32, + 0x32,0x36,0x2c,0x31,0x2e,0x30,0x36,0x33,0x48,0x32, + 0x34,0x2e,0x33,0x35,0x31,0x7a,0x20,0x4d,0x32,0x32, + 0x2e,0x39,0x31,0x37,0x2c,0x31,0x35,0x2e,0x35,0x34, + 0x38,0x68,0x31,0x2e,0x34,0x33,0x34,0x76,0x2d,0x32, + 0x2e,0x38,0x34,0x36,0x68,0x32,0x2e,0x34,0x34,0x33, + 0x0a,0x09,0x63,0x31,0x2e,0x30,0x35,0x33,0x2c,0x30, + 0x2c,0x31,0x2e,0x31,0x38,0x38,0x2c,0x30,0x2e,0x37, + 0x32,0x37,0x2c,0x31,0x2e,0x31,0x38,0x38,0x2c,0x31, + 0x2e,0x37,0x35,0x35,0x63,0x30,0x2c,0x30,0x2e,0x35, + 0x32,0x36,0x2c,0x30,0x2e,0x30,0x36,0x38,0x2c,0x30, + 0x2e,0x38,0x39,0x2c,0x30,0x2e,0x31,0x37,0x34,0x2c, + 0x31,0x2e,0x30,0x39,0x31,0x68,0x31,0x2e,0x35,0x35, + 0x32,0x63,0x2d,0x30,0x2e,0x32,0x38,0x31,0x2d,0x30, + 0x2e,0x33,0x39,0x35,0x2d,0x30,0x2e,0x32,0x39,0x2d, + 0x31,0x2e,0x31,0x39,0x39,0x2d,0x30,0x2e,0x32,0x39, + 0x2d,0x31,0x2e,0x35,0x34,0x36,0x0a,0x09,0x63,0x30, + 0x2d,0x31,0x2e,0x30,0x31,0x39,0x2d,0x30,0x2e,0x31, + 0x38,0x2d,0x31,0x2e,0x37,0x36,0x36,0x2d,0x30,0x2e, + 0x39,0x39,0x34,0x2d,0x31,0x2e,0x39,0x34,0x35,0x76, + 0x2d,0x30,0x2e,0x30,0x32,0x31,0x63,0x30,0x2e,0x36, + 0x34,0x33,0x2d,0x30,0x2e,0x32,0x31,0x31,0x2c,0x31, + 0x2e,0x31,0x32,0x38,0x2d,0x30,0x2e,0x37,0x39,0x37, + 0x2c,0x31,0x2e,0x31,0x32,0x38,0x2d,0x31,0x2e,0x37, + 0x33,0x37,0x63,0x30,0x2d,0x31,0x2e,0x31,0x31,0x39, + 0x2d,0x30,0x2e,0x35,0x36,0x33,0x2d,0x31,0x2e,0x39, + 0x35,0x34,0x2d,0x32,0x2e,0x33,0x30,0x35,0x2d,0x31, + 0x2e,0x39,0x35,0x34,0x68,0x2d,0x34,0x2e,0x33,0x32, + 0x37,0x4c,0x32,0x32,0x2e,0x39,0x31,0x37,0x2c,0x31, + 0x35,0x2e,0x35,0x34,0x38,0x0a,0x09,0x4c,0x32,0x32, + 0x2e,0x39,0x31,0x37,0x2c,0x31,0x35,0x2e,0x35,0x34, + 0x38,0x7a,0x20,0x4d,0x31,0x34,0x2e,0x30,0x33,0x32, 0x2c,0x31,0x35,0x2e,0x35,0x34,0x38,0x68,0x31,0x2e, - 0x34,0x33,0x34,0x76,0x2d,0x32,0x2e,0x38,0x34,0x36, - 0x68,0x32,0x2e,0x34,0x34,0x33,0x0d,0x0a,0x09,0x63, - 0x31,0x2e,0x30,0x35,0x33,0x2c,0x30,0x2c,0x31,0x2e, - 0x31,0x38,0x38,0x2c,0x30,0x2e,0x37,0x32,0x37,0x2c, - 0x31,0x2e,0x31,0x38,0x38,0x2c,0x31,0x2e,0x37,0x35, - 0x35,0x63,0x30,0x2c,0x30,0x2e,0x35,0x32,0x36,0x2c, - 0x30,0x2e,0x30,0x36,0x38,0x2c,0x30,0x2e,0x38,0x39, - 0x2c,0x30,0x2e,0x31,0x37,0x34,0x2c,0x31,0x2e,0x30, - 0x39,0x31,0x68,0x31,0x2e,0x35,0x35,0x32,0x63,0x2d, - 0x30,0x2e,0x32,0x38,0x31,0x2d,0x30,0x2e,0x33,0x39, - 0x35,0x2d,0x30,0x2e,0x32,0x39,0x2d,0x31,0x2e,0x31, - 0x39,0x39,0x2d,0x30,0x2e,0x32,0x39,0x2d,0x31,0x2e, - 0x35,0x34,0x36,0x0d,0x0a,0x09,0x63,0x30,0x2d,0x31, - 0x2e,0x30,0x31,0x39,0x2d,0x30,0x2e,0x31,0x38,0x2d, - 0x31,0x2e,0x37,0x36,0x36,0x2d,0x30,0x2e,0x39,0x39, - 0x34,0x2d,0x31,0x2e,0x39,0x34,0x35,0x76,0x2d,0x30, - 0x2e,0x30,0x32,0x31,0x63,0x30,0x2e,0x36,0x34,0x33, - 0x2d,0x30,0x2e,0x32,0x31,0x31,0x2c,0x31,0x2e,0x31, - 0x32,0x38,0x2d,0x30,0x2e,0x37,0x39,0x37,0x2c,0x31, - 0x2e,0x31,0x32,0x38,0x2d,0x31,0x2e,0x37,0x33,0x37, - 0x63,0x30,0x2d,0x31,0x2e,0x31,0x31,0x39,0x2d,0x30, - 0x2e,0x35,0x36,0x33,0x2d,0x31,0x2e,0x39,0x35,0x34, - 0x2d,0x32,0x2e,0x33,0x30,0x35,0x2d,0x31,0x2e,0x39, - 0x35,0x34,0x68,0x2d,0x34,0x2e,0x33,0x32,0x37,0x4c, - 0x32,0x32,0x2e,0x39,0x31,0x37,0x2c,0x31,0x35,0x2e, - 0x35,0x34,0x38,0x0d,0x0a,0x09,0x4c,0x32,0x32,0x2e, - 0x39,0x31,0x37,0x2c,0x31,0x35,0x2e,0x35,0x34,0x38, - 0x7a,0x20,0x4d,0x31,0x34,0x2e,0x30,0x33,0x32,0x2c, - 0x31,0x35,0x2e,0x35,0x34,0x38,0x68,0x31,0x2e,0x35, - 0x35,0x31,0x6c,0x30,0x2e,0x37,0x30,0x38,0x2d,0x31, - 0x2e,0x37,0x38,0x36,0x68,0x33,0x2e,0x32,0x31,0x37, - 0x6c,0x30,0x2e,0x37,0x31,0x38,0x2c,0x31,0x2e,0x37, - 0x38,0x36,0x68,0x31,0x2e,0x36,0x30,0x33,0x6c,0x2d, - 0x33,0x2e,0x30,0x34,0x35,0x2d,0x37,0x2e,0x32,0x30, - 0x37,0x68,0x2d,0x31,0x2e,0x37,0x30,0x34,0x4c,0x31, - 0x34,0x2e,0x30,0x33,0x32,0x2c,0x31,0x35,0x2e,0x35, - 0x34,0x38,0x7a,0x20,0x4d,0x31,0x36,0x2e,0x37,0x32, - 0x33,0x2c,0x31,0x32,0x2e,0x36,0x33,0x32,0x0d,0x0a, + 0x35,0x35,0x31,0x6c,0x30,0x2e,0x37,0x30,0x38,0x2d, + 0x31,0x2e,0x37,0x38,0x36,0x68,0x33,0x2e,0x32,0x31, + 0x37,0x6c,0x30,0x2e,0x37,0x31,0x38,0x2c,0x31,0x2e, + 0x37,0x38,0x36,0x68,0x31,0x2e,0x36,0x30,0x33,0x6c, + 0x2d,0x33,0x2e,0x30,0x34,0x35,0x2d,0x37,0x2e,0x32, + 0x30,0x37,0x68,0x2d,0x31,0x2e,0x37,0x30,0x34,0x4c, + 0x31,0x34,0x2e,0x30,0x33,0x32,0x2c,0x31,0x35,0x2e, + 0x35,0x34,0x38,0x7a,0x20,0x4d,0x31,0x36,0x2e,0x37, + 0x32,0x33,0x2c,0x31,0x32,0x2e,0x36,0x33,0x32,0x0a, 0x09,0x4c,0x31,0x37,0x2e,0x39,0x31,0x2c,0x39,0x2e, 0x35,0x39,0x6c,0x31,0x2e,0x31,0x36,0x38,0x2c,0x33, 0x2e,0x30,0x34,0x32,0x48,0x31,0x36,0x2e,0x37,0x32, @@ -124,64 +123,63 @@ const unsigned char help_button_start_svg_data[1791] = { 0x48,0x37,0x2e,0x34,0x32,0x35,0x76,0x31,0x2e,0x31, 0x33,0x68,0x32,0x2e,0x35,0x36,0x37,0x56,0x31,0x35, 0x2e,0x35,0x34,0x38,0x7a,0x20,0x4d,0x30,0x2e,0x31, - 0x38,0x37,0x2c,0x31,0x30,0x2e,0x33,0x36,0x38,0x0d, - 0x0a,0x09,0x63,0x30,0x2c,0x32,0x2e,0x39,0x35,0x36, - 0x2c,0x35,0x2e,0x30,0x33,0x36,0x2c,0x31,0x2e,0x34, - 0x2c,0x35,0x2e,0x30,0x33,0x36,0x2c,0x33,0x2e,0x31, - 0x38,0x38,0x63,0x30,0x2c,0x30,0x2e,0x37,0x39,0x32, - 0x2d,0x30,0x2e,0x38,0x31,0x33,0x2c,0x31,0x2e,0x30, - 0x36,0x34,0x2d,0x31,0x2e,0x36,0x38,0x34,0x2c,0x31, - 0x2e,0x30,0x36,0x34,0x63,0x2d,0x31,0x2e,0x31,0x37, - 0x39,0x2c,0x30,0x2d,0x31,0x2e,0x39,0x32,0x33,0x2d, - 0x30,0x2e,0x34,0x35,0x36,0x2d,0x31,0x2e,0x39,0x36, - 0x33,0x2d,0x31,0x2e,0x34,0x30,0x37,0x48,0x30,0x2e, - 0x30,0x32,0x36,0x0d,0x0a,0x09,0x63,0x30,0x2e,0x30, - 0x32,0x31,0x2c,0x31,0x2e,0x35,0x31,0x36,0x2c,0x31, - 0x2e,0x30,0x30,0x35,0x2c,0x32,0x2e,0x35,0x33,0x38, - 0x2c,0x33,0x2e,0x34,0x36,0x39,0x2c,0x32,0x2e,0x35, - 0x33,0x38,0x63,0x31,0x2e,0x34,0x35,0x35,0x2c,0x30, - 0x2c,0x33,0x2e,0x32,0x38,0x2d,0x30,0x2e,0x34,0x38, - 0x36,0x2c,0x33,0x2e,0x32,0x38,0x2d,0x32,0x2e,0x33, - 0x34,0x35,0x63,0x30,0x2d,0x33,0x2e,0x30,0x37,0x39, - 0x2d,0x35,0x2e,0x30,0x39,0x33,0x2d,0x31,0x2e,0x34, - 0x35,0x34,0x2d,0x35,0x2e,0x30,0x39,0x33,0x2d,0x33, - 0x2e,0x31,0x34,0x38,0x0d,0x0a,0x09,0x63,0x30,0x2d, - 0x30,0x2e,0x36,0x37,0x36,0x2c,0x30,0x2e,0x36,0x33, - 0x32,0x2d,0x30,0x2e,0x39,0x38,0x38,0x2c,0x31,0x2e, - 0x35,0x38,0x39,0x2d,0x30,0x2e,0x39,0x38,0x38,0x63, - 0x31,0x2e,0x31,0x39,0x36,0x2c,0x30,0x2c,0x31,0x2e, - 0x36,0x37,0x36,0x2c,0x30,0x2e,0x36,0x30,0x34,0x2c, - 0x31,0x2e,0x37,0x32,0x36,0x2c,0x31,0x2e,0x31,0x36, - 0x31,0x68,0x31,0x2e,0x35,0x35,0x31,0x63,0x2d,0x30, - 0x2e,0x31,0x38,0x35,0x2d,0x32,0x2e,0x30,0x39,0x33, - 0x2d,0x32,0x2e,0x32,0x39,0x2d,0x32,0x2e,0x32,0x39, - 0x32,0x2d,0x33,0x2e,0x33,0x34,0x35,0x2d,0x32,0x2e, - 0x32,0x39,0x32,0x0d,0x0a,0x09,0x43,0x31,0x2e,0x35, - 0x33,0x36,0x2c,0x38,0x2e,0x31,0x33,0x39,0x2c,0x30, - 0x2e,0x31,0x38,0x37,0x2c,0x38,0x2e,0x37,0x36,0x32, - 0x2c,0x30,0x2e,0x31,0x38,0x37,0x2c,0x31,0x30,0x2e, - 0x33,0x36,0x38,0x22,0x2f,0x3e,0x0d,0x0a,0x3c,0x67, - 0x3e,0x0d,0x0a,0x09,0x3c,0x67,0x3e,0x0d,0x0a,0x09, - 0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69,0x6c, - 0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46,0x46, - 0x22,0x20,0x64,0x3d,0x22,0x4d,0x33,0x33,0x2e,0x32, - 0x31,0x37,0x2c,0x31,0x39,0x2e,0x31,0x31,0x38,0x48, - 0x33,0x2e,0x38,0x34,0x35,0x43,0x31,0x2e,0x37,0x32, - 0x32,0x2c,0x31,0x39,0x2e,0x31,0x31,0x38,0x2c,0x30, - 0x2c,0x32,0x30,0x2e,0x38,0x39,0x2c,0x30,0x2c,0x32, - 0x33,0x2e,0x30,0x37,0x35,0x73,0x31,0x2e,0x37,0x32, - 0x32,0x2c,0x33,0x2e,0x39,0x35,0x37,0x2c,0x33,0x2e, - 0x38,0x34,0x35,0x2c,0x33,0x2e,0x39,0x35,0x37,0x68, - 0x32,0x39,0x2e,0x33,0x37,0x32,0x0d,0x0a,0x09,0x09, - 0x09,0x63,0x32,0x2e,0x31,0x32,0x33,0x2c,0x30,0x2c, - 0x33,0x2e,0x38,0x34,0x34,0x2d,0x31,0x2e,0x37,0x37, - 0x31,0x2c,0x33,0x2e,0x38,0x34,0x34,0x2d,0x33,0x2e, - 0x39,0x35,0x37,0x43,0x33,0x37,0x2e,0x30,0x36,0x31, - 0x2c,0x32,0x30,0x2e,0x38,0x38,0x39,0x2c,0x33,0x35, - 0x2e,0x33,0x34,0x2c,0x31,0x39,0x2e,0x31,0x31,0x38, - 0x2c,0x33,0x33,0x2e,0x32,0x31,0x37,0x2c,0x31,0x39, - 0x2e,0x31,0x31,0x38,0x7a,0x22,0x2f,0x3e,0x0d,0x0a, - 0x09,0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x3c,0x2f,0x67, - 0x3e,0x0d,0x0a,0x3c,0x2f,0x73,0x76,0x67,0x3e,0x0d, - 0x0a + 0x38,0x37,0x2c,0x31,0x30,0x2e,0x33,0x36,0x38,0x0a, + 0x09,0x63,0x30,0x2c,0x32,0x2e,0x39,0x35,0x36,0x2c, + 0x35,0x2e,0x30,0x33,0x36,0x2c,0x31,0x2e,0x34,0x2c, + 0x35,0x2e,0x30,0x33,0x36,0x2c,0x33,0x2e,0x31,0x38, + 0x38,0x63,0x30,0x2c,0x30,0x2e,0x37,0x39,0x32,0x2d, + 0x30,0x2e,0x38,0x31,0x33,0x2c,0x31,0x2e,0x30,0x36, + 0x34,0x2d,0x31,0x2e,0x36,0x38,0x34,0x2c,0x31,0x2e, + 0x30,0x36,0x34,0x63,0x2d,0x31,0x2e,0x31,0x37,0x39, + 0x2c,0x30,0x2d,0x31,0x2e,0x39,0x32,0x33,0x2d,0x30, + 0x2e,0x34,0x35,0x36,0x2d,0x31,0x2e,0x39,0x36,0x33, + 0x2d,0x31,0x2e,0x34,0x30,0x37,0x48,0x30,0x2e,0x30, + 0x32,0x36,0x0a,0x09,0x63,0x30,0x2e,0x30,0x32,0x31, + 0x2c,0x31,0x2e,0x35,0x31,0x36,0x2c,0x31,0x2e,0x30, + 0x30,0x35,0x2c,0x32,0x2e,0x35,0x33,0x38,0x2c,0x33, + 0x2e,0x34,0x36,0x39,0x2c,0x32,0x2e,0x35,0x33,0x38, + 0x63,0x31,0x2e,0x34,0x35,0x35,0x2c,0x30,0x2c,0x33, + 0x2e,0x32,0x38,0x2d,0x30,0x2e,0x34,0x38,0x36,0x2c, + 0x33,0x2e,0x32,0x38,0x2d,0x32,0x2e,0x33,0x34,0x35, + 0x63,0x30,0x2d,0x33,0x2e,0x30,0x37,0x39,0x2d,0x35, + 0x2e,0x30,0x39,0x33,0x2d,0x31,0x2e,0x34,0x35,0x34, + 0x2d,0x35,0x2e,0x30,0x39,0x33,0x2d,0x33,0x2e,0x31, + 0x34,0x38,0x0a,0x09,0x63,0x30,0x2d,0x30,0x2e,0x36, + 0x37,0x36,0x2c,0x30,0x2e,0x36,0x33,0x32,0x2d,0x30, + 0x2e,0x39,0x38,0x38,0x2c,0x31,0x2e,0x35,0x38,0x39, + 0x2d,0x30,0x2e,0x39,0x38,0x38,0x63,0x31,0x2e,0x31, + 0x39,0x36,0x2c,0x30,0x2c,0x31,0x2e,0x36,0x37,0x36, + 0x2c,0x30,0x2e,0x36,0x30,0x34,0x2c,0x31,0x2e,0x37, + 0x32,0x36,0x2c,0x31,0x2e,0x31,0x36,0x31,0x68,0x31, + 0x2e,0x35,0x35,0x31,0x63,0x2d,0x30,0x2e,0x31,0x38, + 0x35,0x2d,0x32,0x2e,0x30,0x39,0x33,0x2d,0x32,0x2e, + 0x32,0x39,0x2d,0x32,0x2e,0x32,0x39,0x32,0x2d,0x33, + 0x2e,0x33,0x34,0x35,0x2d,0x32,0x2e,0x32,0x39,0x32, + 0x0a,0x09,0x43,0x31,0x2e,0x35,0x33,0x36,0x2c,0x38, + 0x2e,0x31,0x33,0x39,0x2c,0x30,0x2e,0x31,0x38,0x37, + 0x2c,0x38,0x2e,0x37,0x36,0x32,0x2c,0x30,0x2e,0x31, + 0x38,0x37,0x2c,0x31,0x30,0x2e,0x33,0x36,0x38,0x22, + 0x2f,0x3e,0x0a,0x3c,0x67,0x3e,0x0a,0x09,0x3c,0x67, + 0x3e,0x0a,0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20, + 0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46, + 0x46,0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x33, + 0x33,0x2e,0x32,0x31,0x37,0x2c,0x31,0x39,0x2e,0x31, + 0x31,0x38,0x48,0x33,0x2e,0x38,0x34,0x35,0x43,0x31, + 0x2e,0x37,0x32,0x32,0x2c,0x31,0x39,0x2e,0x31,0x31, + 0x38,0x2c,0x30,0x2c,0x32,0x30,0x2e,0x38,0x39,0x2c, + 0x30,0x2c,0x32,0x33,0x2e,0x30,0x37,0x35,0x73,0x31, + 0x2e,0x37,0x32,0x32,0x2c,0x33,0x2e,0x39,0x35,0x37, + 0x2c,0x33,0x2e,0x38,0x34,0x35,0x2c,0x33,0x2e,0x39, + 0x35,0x37,0x68,0x32,0x39,0x2e,0x33,0x37,0x32,0x0a, + 0x09,0x09,0x09,0x63,0x32,0x2e,0x31,0x32,0x33,0x2c, + 0x30,0x2c,0x33,0x2e,0x38,0x34,0x34,0x2d,0x31,0x2e, + 0x37,0x37,0x31,0x2c,0x33,0x2e,0x38,0x34,0x34,0x2d, + 0x33,0x2e,0x39,0x35,0x37,0x43,0x33,0x37,0x2e,0x30, + 0x36,0x31,0x2c,0x32,0x30,0x2e,0x38,0x38,0x39,0x2c, + 0x33,0x35,0x2e,0x33,0x34,0x2c,0x31,0x39,0x2e,0x31, + 0x31,0x38,0x2c,0x33,0x33,0x2e,0x32,0x31,0x37,0x2c, + 0x31,0x39,0x2e,0x31,0x31,0x38,0x7a,0x22,0x2f,0x3e, + 0x0a,0x09,0x3c,0x2f,0x67,0x3e,0x0a,0x3c,0x2f,0x67, + 0x3e,0x0a,0x3c,0x2f,0x73,0x76,0x67,0x3e,0x0a }; + diff --git a/data/converted/help_button_x_svg.cpp b/data/converted/help_button_x_svg.cpp index 764cfc39f8..3d1d3093e6 100644 --- a/data/converted/help_button_x_svg.cpp +++ b/data/converted/help_button_x_svg.cpp @@ -2,103 +2,102 @@ #include "../Resources.h" -const size_t help_button_x_svg_size = 965; -const unsigned char help_button_x_svg_data[965] = { +const size_t help_button_x_svg_size = 949; +const unsigned char help_button_x_svg_data[949] = { 0x3c,0x3f,0x78,0x6d,0x6c,0x20,0x76,0x65,0x72,0x73, 0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x30,0x22,0x20, 0x65,0x6e,0x63,0x6f,0x64,0x69,0x6e,0x67,0x3d,0x22, - 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0d,0x0a, - 0x3c,0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72, - 0x61,0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62, - 0x65,0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61, - 0x74,0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33, - 0x2c,0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f, - 0x72,0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e, - 0x20,0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72, - 0x73,0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30, - 0x20,0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20, - 0x20,0x2d,0x2d,0x3e,0x0d,0x0a,0x3c,0x21,0x44,0x4f, - 0x43,0x54,0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20, - 0x50,0x55,0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f, - 0x2f,0x57,0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20, - 0x53,0x56,0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45, - 0x4e,0x22,0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, - 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, - 0x67,0x2f,0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73, - 0x2f,0x53,0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44, - 0x54,0x44,0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64, - 0x74,0x64,0x22,0x3e,0x0d,0x0a,0x3c,0x73,0x76,0x67, - 0x20,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22, - 0x31,0x2e,0x31,0x22,0x20,0x69,0x64,0x3d,0x22,0x5f, - 0x78,0x33,0x30,0x5f,0x22,0x20,0x78,0x6d,0x6c,0x6e, - 0x73,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f, - 0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67, - 0x2f,0x32,0x30,0x30,0x30,0x2f,0x73,0x76,0x67,0x22, - 0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78,0x6c,0x69, - 0x6e,0x6b,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, - 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, - 0x67,0x2f,0x31,0x39,0x39,0x39,0x2f,0x78,0x6c,0x69, - 0x6e,0x6b,0x22,0x20,0x78,0x3d,0x22,0x30,0x70,0x78, - 0x22,0x20,0x79,0x3d,0x22,0x30,0x70,0x78,0x22,0x0d, - 0x0a,0x09,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22, - 0x33,0x37,0x2e,0x30,0x36,0x31,0x70,0x78,0x22,0x20, - 0x68,0x65,0x69,0x67,0x68,0x74,0x3d,0x22,0x33,0x37, - 0x2e,0x30,0x36,0x31,0x70,0x78,0x22,0x20,0x76,0x69, - 0x65,0x77,0x42,0x6f,0x78,0x3d,0x22,0x30,0x20,0x30, - 0x20,0x33,0x37,0x2e,0x30,0x36,0x31,0x20,0x33,0x37, - 0x2e,0x30,0x36,0x31,0x22,0x20,0x65,0x6e,0x61,0x62, - 0x6c,0x65,0x2d,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f, - 0x75,0x6e,0x64,0x3d,0x22,0x6e,0x65,0x77,0x20,0x30, - 0x20,0x30,0x20,0x33,0x37,0x2e,0x30,0x36,0x31,0x20, - 0x33,0x37,0x2e,0x30,0x36,0x31,0x22,0x20,0x78,0x6d, - 0x6c,0x3a,0x73,0x70,0x61,0x63,0x65,0x3d,0x22,0x70, - 0x72,0x65,0x73,0x65,0x72,0x76,0x65,0x22,0x3e,0x0d, - 0x0a,0x3c,0x67,0x3e,0x0d,0x0a,0x09,0x3c,0x67,0x3e, - 0x0d,0x0a,0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20, - 0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46, - 0x46,0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x31, - 0x38,0x2e,0x35,0x33,0x2c,0x33,0x2e,0x30,0x32,0x39, - 0x63,0x2d,0x38,0x2e,0x35,0x36,0x31,0x2c,0x30,0x2d, - 0x31,0x35,0x2e,0x35,0x2c,0x36,0x2e,0x39,0x34,0x2d, - 0x31,0x35,0x2e,0x35,0x2c,0x31,0x35,0x2e,0x35,0x63, - 0x30,0x2c,0x38,0x2e,0x35,0x36,0x33,0x2c,0x36,0x2e, - 0x39,0x33,0x39,0x2c,0x31,0x35,0x2e,0x35,0x30,0x32, - 0x2c,0x31,0x35,0x2e,0x35,0x2c,0x31,0x35,0x2e,0x35, - 0x30,0x32,0x0d,0x0a,0x09,0x09,0x09,0x63,0x38,0x2e, - 0x35,0x36,0x33,0x2c,0x30,0x2c,0x31,0x35,0x2e,0x35, - 0x2d,0x36,0x2e,0x39,0x33,0x39,0x2c,0x31,0x35,0x2e, - 0x35,0x2d,0x31,0x35,0x2e,0x35,0x30,0x32,0x43,0x33, - 0x34,0x2e,0x30,0x33,0x2c,0x39,0x2e,0x39,0x37,0x2c, - 0x32,0x37,0x2e,0x30,0x39,0x31,0x2c,0x33,0x2e,0x30, - 0x32,0x39,0x2c,0x31,0x38,0x2e,0x35,0x33,0x2c,0x33, - 0x2e,0x30,0x32,0x39,0x7a,0x20,0x4d,0x32,0x31,0x2e, - 0x34,0x36,0x35,0x2c,0x32,0x34,0x2e,0x39,0x32,0x35, - 0x6c,0x2d,0x32,0x2e,0x36,0x30,0x37,0x2d,0x34,0x2e, - 0x38,0x37,0x6c,0x2d,0x32,0x2e,0x36,0x30,0x34,0x2c, - 0x34,0x2e,0x38,0x37,0x68,0x2d,0x33,0x2e,0x31,0x36, - 0x34,0x6c,0x34,0x2e,0x31,0x31,0x2d,0x36,0x2e,0x38, - 0x31,0x31,0x0d,0x0a,0x09,0x09,0x09,0x6c,0x2d,0x34, - 0x2e,0x30,0x31,0x2d,0x36,0x2e,0x36,0x39,0x38,0x68, - 0x33,0x2e,0x31,0x33,0x38,0x6c,0x32,0x2e,0x34,0x39, - 0x33,0x2c,0x34,0x2e,0x37,0x38,0x37,0x6c,0x32,0x2e, - 0x35,0x33,0x33,0x2d,0x34,0x2e,0x37,0x38,0x37,0x68, - 0x33,0x2e,0x31,0x35,0x34,0x4c,0x32,0x30,0x2e,0x35, - 0x2c,0x31,0x38,0x2e,0x31,0x31,0x35,0x6c,0x34,0x2e, - 0x32,0x34,0x2c,0x36,0x2e,0x38,0x31,0x31,0x48,0x32, - 0x31,0x2e,0x34,0x36,0x35,0x7a,0x22,0x2f,0x3e,0x0d, - 0x0a,0x09,0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x3c,0x2f, - 0x67,0x3e,0x0d,0x0a,0x3c,0x67,0x20,0x6f,0x70,0x61, - 0x63,0x69,0x74,0x79,0x3d,0x22,0x30,0x22,0x3e,0x0d, - 0x0a,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69, - 0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46, - 0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x33,0x36,0x2e, - 0x39,0x36,0x31,0x2c,0x30,0x2e,0x31,0x76,0x33,0x36, - 0x2e,0x38,0x36,0x31,0x48,0x30,0x2e,0x31,0x56,0x30, - 0x2e,0x31,0x48,0x33,0x36,0x2e,0x39,0x36,0x31,0x20, - 0x4d,0x33,0x37,0x2e,0x30,0x36,0x31,0x2c,0x30,0x48, - 0x30,0x76,0x33,0x37,0x2e,0x30,0x36,0x68,0x33,0x37, - 0x2e,0x30,0x36,0x31,0x56,0x30,0x4c,0x33,0x37,0x2e, - 0x30,0x36,0x31,0x2c,0x30,0x7a,0x22,0x2f,0x3e,0x0d, - 0x0a,0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x3c,0x2f,0x73, - 0x76,0x67,0x3e,0x0d,0x0a + 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0a,0x3c, + 0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72,0x61, + 0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62,0x65, + 0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61,0x74, + 0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33,0x2c, + 0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f,0x72, + 0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e,0x20, + 0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72,0x73, + 0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30,0x20, + 0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20,0x20, + 0x2d,0x2d,0x3e,0x0a,0x3c,0x21,0x44,0x4f,0x43,0x54, + 0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20,0x50,0x55, + 0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f,0x2f,0x57, + 0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20,0x53,0x56, + 0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45,0x4e,0x22, + 0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73,0x2f,0x53, + 0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44,0x54,0x44, + 0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64,0x74,0x64, + 0x22,0x3e,0x0a,0x3c,0x73,0x76,0x67,0x20,0x76,0x65, + 0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x31, + 0x22,0x20,0x69,0x64,0x3d,0x22,0x5f,0x78,0x33,0x30, + 0x5f,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3d,0x22, + 0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77, + 0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f,0x32,0x30, + 0x30,0x30,0x2f,0x73,0x76,0x67,0x22,0x20,0x78,0x6d, + 0x6c,0x6e,0x73,0x3a,0x78,0x6c,0x69,0x6e,0x6b,0x3d, + 0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77, + 0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f,0x31, + 0x39,0x39,0x39,0x2f,0x78,0x6c,0x69,0x6e,0x6b,0x22, + 0x20,0x78,0x3d,0x22,0x30,0x70,0x78,0x22,0x20,0x79, + 0x3d,0x22,0x30,0x70,0x78,0x22,0x0a,0x09,0x20,0x77, + 0x69,0x64,0x74,0x68,0x3d,0x22,0x33,0x37,0x2e,0x30, + 0x36,0x31,0x70,0x78,0x22,0x20,0x68,0x65,0x69,0x67, + 0x68,0x74,0x3d,0x22,0x33,0x37,0x2e,0x30,0x36,0x31, + 0x70,0x78,0x22,0x20,0x76,0x69,0x65,0x77,0x42,0x6f, + 0x78,0x3d,0x22,0x30,0x20,0x30,0x20,0x33,0x37,0x2e, + 0x30,0x36,0x31,0x20,0x33,0x37,0x2e,0x30,0x36,0x31, + 0x22,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0x2d,0x62, + 0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x3d, + 0x22,0x6e,0x65,0x77,0x20,0x30,0x20,0x30,0x20,0x33, + 0x37,0x2e,0x30,0x36,0x31,0x20,0x33,0x37,0x2e,0x30, + 0x36,0x31,0x22,0x20,0x78,0x6d,0x6c,0x3a,0x73,0x70, + 0x61,0x63,0x65,0x3d,0x22,0x70,0x72,0x65,0x73,0x65, + 0x72,0x76,0x65,0x22,0x3e,0x0a,0x3c,0x67,0x3e,0x0a, + 0x09,0x3c,0x67,0x3e,0x0a,0x09,0x09,0x3c,0x70,0x61, + 0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23, + 0x46,0x46,0x46,0x46,0x46,0x46,0x22,0x20,0x64,0x3d, + 0x22,0x4d,0x31,0x38,0x2e,0x35,0x33,0x2c,0x33,0x2e, + 0x30,0x32,0x39,0x63,0x2d,0x38,0x2e,0x35,0x36,0x31, + 0x2c,0x30,0x2d,0x31,0x35,0x2e,0x35,0x2c,0x36,0x2e, + 0x39,0x34,0x2d,0x31,0x35,0x2e,0x35,0x2c,0x31,0x35, + 0x2e,0x35,0x63,0x30,0x2c,0x38,0x2e,0x35,0x36,0x33, + 0x2c,0x36,0x2e,0x39,0x33,0x39,0x2c,0x31,0x35,0x2e, + 0x35,0x30,0x32,0x2c,0x31,0x35,0x2e,0x35,0x2c,0x31, + 0x35,0x2e,0x35,0x30,0x32,0x0a,0x09,0x09,0x09,0x63, + 0x38,0x2e,0x35,0x36,0x33,0x2c,0x30,0x2c,0x31,0x35, + 0x2e,0x35,0x2d,0x36,0x2e,0x39,0x33,0x39,0x2c,0x31, + 0x35,0x2e,0x35,0x2d,0x31,0x35,0x2e,0x35,0x30,0x32, + 0x43,0x33,0x34,0x2e,0x30,0x33,0x2c,0x39,0x2e,0x39, + 0x37,0x2c,0x32,0x37,0x2e,0x30,0x39,0x31,0x2c,0x33, + 0x2e,0x30,0x32,0x39,0x2c,0x31,0x38,0x2e,0x35,0x33, + 0x2c,0x33,0x2e,0x30,0x32,0x39,0x7a,0x20,0x4d,0x32, + 0x31,0x2e,0x34,0x36,0x35,0x2c,0x32,0x34,0x2e,0x39, + 0x32,0x35,0x6c,0x2d,0x32,0x2e,0x36,0x30,0x37,0x2d, + 0x34,0x2e,0x38,0x37,0x6c,0x2d,0x32,0x2e,0x36,0x30, + 0x34,0x2c,0x34,0x2e,0x38,0x37,0x68,0x2d,0x33,0x2e, + 0x31,0x36,0x34,0x6c,0x34,0x2e,0x31,0x31,0x2d,0x36, + 0x2e,0x38,0x31,0x31,0x0a,0x09,0x09,0x09,0x6c,0x2d, + 0x34,0x2e,0x30,0x31,0x2d,0x36,0x2e,0x36,0x39,0x38, + 0x68,0x33,0x2e,0x31,0x33,0x38,0x6c,0x32,0x2e,0x34, + 0x39,0x33,0x2c,0x34,0x2e,0x37,0x38,0x37,0x6c,0x32, + 0x2e,0x35,0x33,0x33,0x2d,0x34,0x2e,0x37,0x38,0x37, + 0x68,0x33,0x2e,0x31,0x35,0x34,0x4c,0x32,0x30,0x2e, + 0x35,0x2c,0x31,0x38,0x2e,0x31,0x31,0x35,0x6c,0x34, + 0x2e,0x32,0x34,0x2c,0x36,0x2e,0x38,0x31,0x31,0x48, + 0x32,0x31,0x2e,0x34,0x36,0x35,0x7a,0x22,0x2f,0x3e, + 0x0a,0x09,0x3c,0x2f,0x67,0x3e,0x0a,0x3c,0x2f,0x67, + 0x3e,0x0a,0x3c,0x67,0x20,0x6f,0x70,0x61,0x63,0x69, + 0x74,0x79,0x3d,0x22,0x30,0x22,0x3e,0x0a,0x09,0x3c, + 0x70,0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d, + 0x22,0x23,0x46,0x46,0x46,0x46,0x46,0x46,0x22,0x20, + 0x64,0x3d,0x22,0x4d,0x33,0x36,0x2e,0x39,0x36,0x31, + 0x2c,0x30,0x2e,0x31,0x76,0x33,0x36,0x2e,0x38,0x36, + 0x31,0x48,0x30,0x2e,0x31,0x56,0x30,0x2e,0x31,0x48, + 0x33,0x36,0x2e,0x39,0x36,0x31,0x20,0x4d,0x33,0x37, + 0x2e,0x30,0x36,0x31,0x2c,0x30,0x48,0x30,0x76,0x33, + 0x37,0x2e,0x30,0x36,0x68,0x33,0x37,0x2e,0x30,0x36, + 0x31,0x56,0x30,0x4c,0x33,0x37,0x2e,0x30,0x36,0x31, + 0x2c,0x30,0x7a,0x22,0x2f,0x3e,0x0a,0x3c,0x2f,0x67, + 0x3e,0x0a,0x3c,0x2f,0x73,0x76,0x67,0x3e,0x0a }; + diff --git a/data/converted/help_button_y_svg.cpp b/data/converted/help_button_y_svg.cpp index adb8fbc494..c05fc3b76c 100644 --- a/data/converted/help_button_y_svg.cpp +++ b/data/converted/help_button_y_svg.cpp @@ -2,99 +2,99 @@ #include "../Resources.h" -const size_t help_button_y_svg_size = 927; -const unsigned char help_button_y_svg_data[927] = { +const size_t help_button_y_svg_size = 911; +const unsigned char help_button_y_svg_data[911] = { 0x3c,0x3f,0x78,0x6d,0x6c,0x20,0x76,0x65,0x72,0x73, 0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x30,0x22,0x20, 0x65,0x6e,0x63,0x6f,0x64,0x69,0x6e,0x67,0x3d,0x22, - 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0d,0x0a, - 0x3c,0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72, - 0x61,0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62, - 0x65,0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61, - 0x74,0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33, - 0x2c,0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f, - 0x72,0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e, - 0x20,0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72, - 0x73,0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30, - 0x20,0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20, - 0x20,0x2d,0x2d,0x3e,0x0d,0x0a,0x3c,0x21,0x44,0x4f, - 0x43,0x54,0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20, - 0x50,0x55,0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f, - 0x2f,0x57,0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20, - 0x53,0x56,0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45, - 0x4e,0x22,0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, - 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, - 0x67,0x2f,0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73, - 0x2f,0x53,0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44, - 0x54,0x44,0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64, - 0x74,0x64,0x22,0x3e,0x0d,0x0a,0x3c,0x73,0x76,0x67, - 0x20,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22, - 0x31,0x2e,0x31,0x22,0x20,0x69,0x64,0x3d,0x22,0x5f, - 0x78,0x33,0x30,0x5f,0x22,0x20,0x78,0x6d,0x6c,0x6e, - 0x73,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f, - 0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67, - 0x2f,0x32,0x30,0x30,0x30,0x2f,0x73,0x76,0x67,0x22, - 0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78,0x6c,0x69, - 0x6e,0x6b,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, - 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, - 0x67,0x2f,0x31,0x39,0x39,0x39,0x2f,0x78,0x6c,0x69, - 0x6e,0x6b,0x22,0x20,0x78,0x3d,0x22,0x30,0x70,0x78, - 0x22,0x20,0x79,0x3d,0x22,0x30,0x70,0x78,0x22,0x0d, - 0x0a,0x09,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22, - 0x33,0x37,0x2e,0x30,0x36,0x31,0x70,0x78,0x22,0x20, - 0x68,0x65,0x69,0x67,0x68,0x74,0x3d,0x22,0x33,0x37, - 0x2e,0x30,0x36,0x31,0x70,0x78,0x22,0x20,0x76,0x69, - 0x65,0x77,0x42,0x6f,0x78,0x3d,0x22,0x30,0x20,0x30, - 0x20,0x33,0x37,0x2e,0x30,0x36,0x31,0x20,0x33,0x37, - 0x2e,0x30,0x36,0x31,0x22,0x20,0x65,0x6e,0x61,0x62, - 0x6c,0x65,0x2d,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f, - 0x75,0x6e,0x64,0x3d,0x22,0x6e,0x65,0x77,0x20,0x30, - 0x20,0x30,0x20,0x33,0x37,0x2e,0x30,0x36,0x31,0x20, - 0x33,0x37,0x2e,0x30,0x36,0x31,0x22,0x20,0x78,0x6d, - 0x6c,0x3a,0x73,0x70,0x61,0x63,0x65,0x3d,0x22,0x70, - 0x72,0x65,0x73,0x65,0x72,0x76,0x65,0x22,0x3e,0x0d, - 0x0a,0x3c,0x67,0x3e,0x0d,0x0a,0x09,0x3c,0x67,0x3e, - 0x0d,0x0a,0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20, - 0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46, - 0x46,0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x31, - 0x38,0x2e,0x35,0x33,0x2c,0x33,0x2e,0x30,0x32,0x39, - 0x63,0x2d,0x38,0x2e,0x35,0x36,0x31,0x2c,0x30,0x2d, - 0x31,0x35,0x2e,0x35,0x2c,0x36,0x2e,0x39,0x34,0x2d, - 0x31,0x35,0x2e,0x35,0x2c,0x31,0x35,0x2e,0x35,0x63, - 0x30,0x2c,0x38,0x2e,0x35,0x36,0x32,0x2c,0x36,0x2e, - 0x39,0x33,0x39,0x2c,0x31,0x35,0x2e,0x35,0x30,0x32, - 0x2c,0x31,0x35,0x2e,0x35,0x2c,0x31,0x35,0x2e,0x35, - 0x30,0x32,0x0d,0x0a,0x09,0x09,0x09,0x63,0x38,0x2e, - 0x35,0x36,0x33,0x2c,0x30,0x2c,0x31,0x35,0x2e,0x35, - 0x2d,0x36,0x2e,0x39,0x34,0x2c,0x31,0x35,0x2e,0x35, - 0x2d,0x31,0x35,0x2e,0x35,0x30,0x32,0x43,0x33,0x34, - 0x2e,0x30,0x33,0x2c,0x39,0x2e,0x39,0x37,0x2c,0x32, - 0x37,0x2e,0x30,0x39,0x31,0x2c,0x33,0x2e,0x30,0x32, - 0x39,0x2c,0x31,0x38,0x2e,0x35,0x33,0x2c,0x33,0x2e, - 0x30,0x32,0x39,0x7a,0x20,0x4d,0x32,0x30,0x2e,0x31, - 0x30,0x32,0x2c,0x32,0x30,0x2e,0x31,0x37,0x34,0x76, - 0x34,0x2e,0x37,0x35,0x68,0x2d,0x32,0x2e,0x37,0x76, - 0x2d,0x34,0x2e,0x38,0x39,0x6c,0x2d,0x34,0x2e,0x35, - 0x35,0x35,0x2d,0x38,0x2e,0x36,0x31,0x38,0x68,0x32, - 0x2e,0x39,0x36,0x39,0x0d,0x0a,0x09,0x09,0x09,0x6c, - 0x32,0x2e,0x39,0x35,0x2c,0x36,0x2e,0x32,0x32,0x36, - 0x68,0x30,0x2e,0x30,0x35,0x36,0x6c,0x32,0x2e,0x39, - 0x35,0x2d,0x36,0x2e,0x32,0x32,0x36,0x68,0x32,0x2e, - 0x39,0x37,0x31,0x4c,0x32,0x30,0x2e,0x31,0x30,0x32, - 0x2c,0x32,0x30,0x2e,0x31,0x37,0x34,0x7a,0x22,0x2f, - 0x3e,0x0d,0x0a,0x09,0x3c,0x2f,0x67,0x3e,0x0d,0x0a, - 0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x3c,0x67,0x20,0x6f, - 0x70,0x61,0x63,0x69,0x74,0x79,0x3d,0x22,0x30,0x22, - 0x3e,0x0d,0x0a,0x09,0x3c,0x70,0x61,0x74,0x68,0x20, - 0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46, - 0x46,0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x33, - 0x36,0x2e,0x39,0x36,0x31,0x2c,0x30,0x2e,0x31,0x76, - 0x33,0x36,0x2e,0x38,0x36,0x31,0x48,0x30,0x2e,0x31, - 0x56,0x30,0x2e,0x31,0x48,0x33,0x36,0x2e,0x39,0x36, - 0x31,0x20,0x4d,0x33,0x37,0x2e,0x30,0x36,0x31,0x2c, - 0x30,0x48,0x30,0x76,0x33,0x37,0x2e,0x30,0x36,0x68, - 0x33,0x37,0x2e,0x30,0x36,0x31,0x56,0x30,0x4c,0x33, - 0x37,0x2e,0x30,0x36,0x31,0x2c,0x30,0x7a,0x22,0x2f, - 0x3e,0x0d,0x0a,0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x3c, - 0x2f,0x73,0x76,0x67,0x3e,0x0d,0x0a + 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0a,0x3c, + 0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72,0x61, + 0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62,0x65, + 0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61,0x74, + 0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33,0x2c, + 0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f,0x72, + 0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e,0x20, + 0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72,0x73, + 0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30,0x20, + 0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20,0x20, + 0x2d,0x2d,0x3e,0x0a,0x3c,0x21,0x44,0x4f,0x43,0x54, + 0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20,0x50,0x55, + 0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f,0x2f,0x57, + 0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20,0x53,0x56, + 0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45,0x4e,0x22, + 0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73,0x2f,0x53, + 0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44,0x54,0x44, + 0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64,0x74,0x64, + 0x22,0x3e,0x0a,0x3c,0x73,0x76,0x67,0x20,0x76,0x65, + 0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x31, + 0x22,0x20,0x69,0x64,0x3d,0x22,0x5f,0x78,0x33,0x30, + 0x5f,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3d,0x22, + 0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77, + 0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f,0x32,0x30, + 0x30,0x30,0x2f,0x73,0x76,0x67,0x22,0x20,0x78,0x6d, + 0x6c,0x6e,0x73,0x3a,0x78,0x6c,0x69,0x6e,0x6b,0x3d, + 0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77, + 0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f,0x31, + 0x39,0x39,0x39,0x2f,0x78,0x6c,0x69,0x6e,0x6b,0x22, + 0x20,0x78,0x3d,0x22,0x30,0x70,0x78,0x22,0x20,0x79, + 0x3d,0x22,0x30,0x70,0x78,0x22,0x0a,0x09,0x20,0x77, + 0x69,0x64,0x74,0x68,0x3d,0x22,0x33,0x37,0x2e,0x30, + 0x36,0x31,0x70,0x78,0x22,0x20,0x68,0x65,0x69,0x67, + 0x68,0x74,0x3d,0x22,0x33,0x37,0x2e,0x30,0x36,0x31, + 0x70,0x78,0x22,0x20,0x76,0x69,0x65,0x77,0x42,0x6f, + 0x78,0x3d,0x22,0x30,0x20,0x30,0x20,0x33,0x37,0x2e, + 0x30,0x36,0x31,0x20,0x33,0x37,0x2e,0x30,0x36,0x31, + 0x22,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0x2d,0x62, + 0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x3d, + 0x22,0x6e,0x65,0x77,0x20,0x30,0x20,0x30,0x20,0x33, + 0x37,0x2e,0x30,0x36,0x31,0x20,0x33,0x37,0x2e,0x30, + 0x36,0x31,0x22,0x20,0x78,0x6d,0x6c,0x3a,0x73,0x70, + 0x61,0x63,0x65,0x3d,0x22,0x70,0x72,0x65,0x73,0x65, + 0x72,0x76,0x65,0x22,0x3e,0x0a,0x3c,0x67,0x3e,0x0a, + 0x09,0x3c,0x67,0x3e,0x0a,0x09,0x09,0x3c,0x70,0x61, + 0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23, + 0x46,0x46,0x46,0x46,0x46,0x46,0x22,0x20,0x64,0x3d, + 0x22,0x4d,0x31,0x38,0x2e,0x35,0x33,0x2c,0x33,0x2e, + 0x30,0x32,0x39,0x63,0x2d,0x38,0x2e,0x35,0x36,0x31, + 0x2c,0x30,0x2d,0x31,0x35,0x2e,0x35,0x2c,0x36,0x2e, + 0x39,0x34,0x2d,0x31,0x35,0x2e,0x35,0x2c,0x31,0x35, + 0x2e,0x35,0x63,0x30,0x2c,0x38,0x2e,0x35,0x36,0x32, + 0x2c,0x36,0x2e,0x39,0x33,0x39,0x2c,0x31,0x35,0x2e, + 0x35,0x30,0x32,0x2c,0x31,0x35,0x2e,0x35,0x2c,0x31, + 0x35,0x2e,0x35,0x30,0x32,0x0a,0x09,0x09,0x09,0x63, + 0x38,0x2e,0x35,0x36,0x33,0x2c,0x30,0x2c,0x31,0x35, + 0x2e,0x35,0x2d,0x36,0x2e,0x39,0x34,0x2c,0x31,0x35, + 0x2e,0x35,0x2d,0x31,0x35,0x2e,0x35,0x30,0x32,0x43, + 0x33,0x34,0x2e,0x30,0x33,0x2c,0x39,0x2e,0x39,0x37, + 0x2c,0x32,0x37,0x2e,0x30,0x39,0x31,0x2c,0x33,0x2e, + 0x30,0x32,0x39,0x2c,0x31,0x38,0x2e,0x35,0x33,0x2c, + 0x33,0x2e,0x30,0x32,0x39,0x7a,0x20,0x4d,0x32,0x30, + 0x2e,0x31,0x30,0x32,0x2c,0x32,0x30,0x2e,0x31,0x37, + 0x34,0x76,0x34,0x2e,0x37,0x35,0x68,0x2d,0x32,0x2e, + 0x37,0x76,0x2d,0x34,0x2e,0x38,0x39,0x6c,0x2d,0x34, + 0x2e,0x35,0x35,0x35,0x2d,0x38,0x2e,0x36,0x31,0x38, + 0x68,0x32,0x2e,0x39,0x36,0x39,0x0a,0x09,0x09,0x09, + 0x6c,0x32,0x2e,0x39,0x35,0x2c,0x36,0x2e,0x32,0x32, + 0x36,0x68,0x30,0x2e,0x30,0x35,0x36,0x6c,0x32,0x2e, + 0x39,0x35,0x2d,0x36,0x2e,0x32,0x32,0x36,0x68,0x32, + 0x2e,0x39,0x37,0x31,0x4c,0x32,0x30,0x2e,0x31,0x30, + 0x32,0x2c,0x32,0x30,0x2e,0x31,0x37,0x34,0x7a,0x22, + 0x2f,0x3e,0x0a,0x09,0x3c,0x2f,0x67,0x3e,0x0a,0x3c, + 0x2f,0x67,0x3e,0x0a,0x3c,0x67,0x20,0x6f,0x70,0x61, + 0x63,0x69,0x74,0x79,0x3d,0x22,0x30,0x22,0x3e,0x0a, + 0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69,0x6c, + 0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46,0x46, + 0x22,0x20,0x64,0x3d,0x22,0x4d,0x33,0x36,0x2e,0x39, + 0x36,0x31,0x2c,0x30,0x2e,0x31,0x76,0x33,0x36,0x2e, + 0x38,0x36,0x31,0x48,0x30,0x2e,0x31,0x56,0x30,0x2e, + 0x31,0x48,0x33,0x36,0x2e,0x39,0x36,0x31,0x20,0x4d, + 0x33,0x37,0x2e,0x30,0x36,0x31,0x2c,0x30,0x48,0x30, + 0x76,0x33,0x37,0x2e,0x30,0x36,0x68,0x33,0x37,0x2e, + 0x30,0x36,0x31,0x56,0x30,0x4c,0x33,0x37,0x2e,0x30, + 0x36,0x31,0x2c,0x30,0x7a,0x22,0x2f,0x3e,0x0a,0x3c, + 0x2f,0x67,0x3e,0x0a,0x3c,0x2f,0x73,0x76,0x67,0x3e, + 0x0a }; + diff --git a/data/converted/help_dpad_all_svg.cpp b/data/converted/help_dpad_all_svg.cpp index 3117c046b8..226a111d53 100644 --- a/data/converted/help_dpad_all_svg.cpp +++ b/data/converted/help_dpad_all_svg.cpp @@ -2,73 +2,72 @@ #include "../Resources.h" -const size_t help_dpad_all_svg_size = 3523; -const unsigned char help_dpad_all_svg_data[3523] = { +const size_t help_dpad_all_svg_size = 3470; +const unsigned char help_dpad_all_svg_data[3470] = { 0x3c,0x3f,0x78,0x6d,0x6c,0x20,0x76,0x65,0x72,0x73, 0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x30,0x22,0x20, 0x65,0x6e,0x63,0x6f,0x64,0x69,0x6e,0x67,0x3d,0x22, - 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0d,0x0a, - 0x3c,0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72, - 0x61,0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62, - 0x65,0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61, - 0x74,0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33, - 0x2c,0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f, - 0x72,0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e, - 0x20,0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72, - 0x73,0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30, - 0x20,0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20, - 0x20,0x2d,0x2d,0x3e,0x0d,0x0a,0x3c,0x21,0x44,0x4f, - 0x43,0x54,0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20, - 0x50,0x55,0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f, - 0x2f,0x57,0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20, - 0x53,0x56,0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45, - 0x4e,0x22,0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, - 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, - 0x67,0x2f,0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73, - 0x2f,0x53,0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44, - 0x54,0x44,0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64, - 0x74,0x64,0x22,0x3e,0x0d,0x0a,0x3c,0x73,0x76,0x67, - 0x20,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22, - 0x31,0x2e,0x31,0x22,0x20,0x69,0x64,0x3d,0x22,0x5f, - 0x78,0x33,0x30,0x5f,0x22,0x20,0x78,0x6d,0x6c,0x6e, - 0x73,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f, - 0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67, - 0x2f,0x32,0x30,0x30,0x30,0x2f,0x73,0x76,0x67,0x22, - 0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78,0x6c,0x69, - 0x6e,0x6b,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, - 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, - 0x67,0x2f,0x31,0x39,0x39,0x39,0x2f,0x78,0x6c,0x69, - 0x6e,0x6b,0x22,0x20,0x78,0x3d,0x22,0x30,0x70,0x78, - 0x22,0x20,0x79,0x3d,0x22,0x30,0x70,0x78,0x22,0x0d, - 0x0a,0x09,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22, - 0x33,0x37,0x2e,0x30,0x36,0x31,0x70,0x78,0x22,0x20, - 0x68,0x65,0x69,0x67,0x68,0x74,0x3d,0x22,0x33,0x37, - 0x2e,0x30,0x36,0x31,0x70,0x78,0x22,0x20,0x76,0x69, - 0x65,0x77,0x42,0x6f,0x78,0x3d,0x22,0x30,0x20,0x30, - 0x20,0x33,0x37,0x2e,0x30,0x36,0x31,0x20,0x33,0x37, - 0x2e,0x30,0x36,0x31,0x22,0x20,0x65,0x6e,0x61,0x62, - 0x6c,0x65,0x2d,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f, - 0x75,0x6e,0x64,0x3d,0x22,0x6e,0x65,0x77,0x20,0x30, - 0x20,0x30,0x20,0x33,0x37,0x2e,0x30,0x36,0x31,0x20, - 0x33,0x37,0x2e,0x30,0x36,0x31,0x22,0x20,0x78,0x6d, - 0x6c,0x3a,0x73,0x70,0x61,0x63,0x65,0x3d,0x22,0x70, - 0x72,0x65,0x73,0x65,0x72,0x76,0x65,0x22,0x3e,0x0d, - 0x0a,0x3c,0x67,0x3e,0x0d,0x0a,0x09,0x3c,0x67,0x3e, - 0x0d,0x0a,0x09,0x09,0x3c,0x67,0x3e,0x0d,0x0a,0x09, - 0x09,0x09,0x3c,0x67,0x3e,0x0d,0x0a,0x09,0x09,0x09, - 0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69,0x6c, - 0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46,0x46, - 0x22,0x20,0x64,0x3d,0x22,0x4d,0x32,0x32,0x2e,0x30, - 0x38,0x35,0x2c,0x33,0x37,0x2e,0x30,0x35,0x38,0x68, - 0x2d,0x37,0x2e,0x31,0x31,0x31,0x63,0x2d,0x32,0x2e, - 0x32,0x38,0x39,0x2c,0x30,0x2d,0x33,0x2e,0x31,0x31, - 0x39,0x2d,0x31,0x2e,0x38,0x36,0x36,0x2d,0x33,0x2e, - 0x31,0x31,0x39,0x2d,0x33,0x2e,0x31,0x32,0x31,0x76, - 0x2d,0x38,0x2e,0x37,0x33,0x32,0x48,0x33,0x2e,0x31, - 0x32,0x31,0x43,0x30,0x2e,0x38,0x33,0x31,0x2c,0x32, - 0x35,0x2e,0x32,0x30,0x35,0x2c,0x30,0x2c,0x32,0x33, - 0x2e,0x33,0x33,0x39,0x2c,0x30,0x2c,0x32,0x32,0x2e, - 0x30,0x38,0x34,0x0d,0x0a,0x09,0x09,0x09,0x09,0x09, + 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0a,0x3c, + 0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72,0x61, + 0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62,0x65, + 0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61,0x74, + 0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33,0x2c, + 0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f,0x72, + 0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e,0x20, + 0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72,0x73, + 0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30,0x20, + 0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20,0x20, + 0x2d,0x2d,0x3e,0x0a,0x3c,0x21,0x44,0x4f,0x43,0x54, + 0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20,0x50,0x55, + 0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f,0x2f,0x57, + 0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20,0x53,0x56, + 0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45,0x4e,0x22, + 0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73,0x2f,0x53, + 0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44,0x54,0x44, + 0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64,0x74,0x64, + 0x22,0x3e,0x0a,0x3c,0x73,0x76,0x67,0x20,0x76,0x65, + 0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x31, + 0x22,0x20,0x69,0x64,0x3d,0x22,0x5f,0x78,0x33,0x30, + 0x5f,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3d,0x22, + 0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77, + 0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f,0x32,0x30, + 0x30,0x30,0x2f,0x73,0x76,0x67,0x22,0x20,0x78,0x6d, + 0x6c,0x6e,0x73,0x3a,0x78,0x6c,0x69,0x6e,0x6b,0x3d, + 0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77, + 0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f,0x31, + 0x39,0x39,0x39,0x2f,0x78,0x6c,0x69,0x6e,0x6b,0x22, + 0x20,0x78,0x3d,0x22,0x30,0x70,0x78,0x22,0x20,0x79, + 0x3d,0x22,0x30,0x70,0x78,0x22,0x0a,0x09,0x20,0x77, + 0x69,0x64,0x74,0x68,0x3d,0x22,0x33,0x37,0x2e,0x30, + 0x36,0x31,0x70,0x78,0x22,0x20,0x68,0x65,0x69,0x67, + 0x68,0x74,0x3d,0x22,0x33,0x37,0x2e,0x30,0x36,0x31, + 0x70,0x78,0x22,0x20,0x76,0x69,0x65,0x77,0x42,0x6f, + 0x78,0x3d,0x22,0x30,0x20,0x30,0x20,0x33,0x37,0x2e, + 0x30,0x36,0x31,0x20,0x33,0x37,0x2e,0x30,0x36,0x31, + 0x22,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0x2d,0x62, + 0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x3d, + 0x22,0x6e,0x65,0x77,0x20,0x30,0x20,0x30,0x20,0x33, + 0x37,0x2e,0x30,0x36,0x31,0x20,0x33,0x37,0x2e,0x30, + 0x36,0x31,0x22,0x20,0x78,0x6d,0x6c,0x3a,0x73,0x70, + 0x61,0x63,0x65,0x3d,0x22,0x70,0x72,0x65,0x73,0x65, + 0x72,0x76,0x65,0x22,0x3e,0x0a,0x3c,0x67,0x3e,0x0a, + 0x09,0x3c,0x67,0x3e,0x0a,0x09,0x09,0x3c,0x67,0x3e, + 0x0a,0x09,0x09,0x09,0x3c,0x67,0x3e,0x0a,0x09,0x09, + 0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69, + 0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46, + 0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x32,0x32,0x2e, + 0x30,0x38,0x35,0x2c,0x33,0x37,0x2e,0x30,0x35,0x38, + 0x68,0x2d,0x37,0x2e,0x31,0x31,0x31,0x63,0x2d,0x32, + 0x2e,0x32,0x38,0x39,0x2c,0x30,0x2d,0x33,0x2e,0x31, + 0x31,0x39,0x2d,0x31,0x2e,0x38,0x36,0x36,0x2d,0x33, + 0x2e,0x31,0x31,0x39,0x2d,0x33,0x2e,0x31,0x32,0x31, + 0x76,0x2d,0x38,0x2e,0x37,0x33,0x32,0x48,0x33,0x2e, + 0x31,0x32,0x31,0x43,0x30,0x2e,0x38,0x33,0x31,0x2c, + 0x32,0x35,0x2e,0x32,0x30,0x35,0x2c,0x30,0x2c,0x32, + 0x33,0x2e,0x33,0x33,0x39,0x2c,0x30,0x2c,0x32,0x32, + 0x2e,0x30,0x38,0x34,0x0a,0x09,0x09,0x09,0x09,0x09, 0x76,0x2d,0x37,0x2e,0x31,0x31,0x63,0x30,0x2d,0x32, 0x2e,0x32,0x38,0x39,0x2c,0x31,0x2e,0x38,0x36,0x37, 0x2d,0x33,0x2e,0x31,0x32,0x2c,0x33,0x2e,0x31,0x32, @@ -81,208 +80,205 @@ const unsigned char help_dpad_all_svg_data[3523] = { 0x2c,0x30,0x2c,0x33,0x2e,0x31,0x32,0x31,0x2c,0x31, 0x2e,0x38,0x36,0x37,0x2c,0x33,0x2e,0x31,0x32,0x31, 0x2c,0x33,0x2e,0x31,0x32,0x31,0x76,0x38,0x2e,0x37, - 0x33,0x33,0x0d,0x0a,0x09,0x09,0x09,0x09,0x09,0x68, - 0x38,0x2e,0x37,0x33,0x31,0x63,0x31,0x2e,0x32,0x30, - 0x31,0x2c,0x30,0x2c,0x32,0x2e,0x31,0x35,0x34,0x2c, - 0x30,0x2e,0x35,0x32,0x35,0x2c,0x32,0x2e,0x36,0x38, - 0x34,0x2c,0x31,0x2e,0x34,0x38,0x63,0x30,0x2e,0x32, - 0x30,0x37,0x2c,0x30,0x2e,0x33,0x37,0x35,0x2c,0x30, - 0x2e,0x34,0x35,0x36,0x2c,0x31,0x2e,0x31,0x31,0x32, - 0x2c,0x30,0x2e,0x34,0x32,0x39,0x2c,0x31,0x2e,0x36, - 0x33,0x39,0x68,0x30,0x2e,0x30,0x30,0x38,0x76,0x37, - 0x2e,0x31,0x31,0x63,0x30,0x2c,0x32,0x2e,0x32,0x39, - 0x2d,0x31,0x2e,0x38,0x36,0x36,0x2c,0x33,0x2e,0x31, - 0x32,0x31,0x2d,0x33,0x2e,0x31,0x32,0x31,0x2c,0x33, - 0x2e,0x31,0x32,0x31,0x68,0x2d,0x38,0x2e,0x37,0x33, - 0x31,0x0d,0x0a,0x09,0x09,0x09,0x09,0x09,0x76,0x38, - 0x2e,0x37,0x33,0x32,0x43,0x32,0x35,0x2e,0x32,0x30, - 0x36,0x2c,0x33,0x36,0x2e,0x32,0x32,0x37,0x2c,0x32, - 0x33,0x2e,0x33,0x34,0x2c,0x33,0x37,0x2e,0x30,0x35, - 0x38,0x2c,0x32,0x32,0x2e,0x30,0x38,0x35,0x2c,0x33, - 0x37,0x2e,0x30,0x35,0x38,0x7a,0x20,0x4d,0x33,0x2e, - 0x31,0x32,0x31,0x2c,0x31,0x33,0x2e,0x33,0x35,0x33, - 0x43,0x32,0x2e,0x37,0x34,0x35,0x2c,0x31,0x33,0x2e, - 0x33,0x35,0x39,0x2c,0x31,0x2e,0x35,0x2c,0x31,0x33, - 0x2e,0x34,0x39,0x32,0x2c,0x31,0x2e,0x35,0x2c,0x31, - 0x34,0x2e,0x39,0x37,0x33,0x76,0x37,0x2e,0x31,0x31, - 0x0d,0x0a,0x09,0x09,0x09,0x09,0x09,0x63,0x30,0x2e, - 0x30,0x30,0x36,0x2c,0x30,0x2e,0x33,0x37,0x36,0x2c, - 0x30,0x2e,0x31,0x33,0x39,0x2c,0x31,0x2e,0x36,0x32, - 0x31,0x2c,0x31,0x2e,0x36,0x32,0x31,0x2c,0x31,0x2e, - 0x36,0x32,0x31,0x68,0x31,0x30,0x2e,0x32,0x33,0x33, - 0x76,0x31,0x30,0x2e,0x32,0x33,0x32,0x63,0x30,0x2e, - 0x30,0x30,0x35,0x2c,0x30,0x2e,0x33,0x37,0x36,0x2c, - 0x30,0x2e,0x31,0x33,0x39,0x2c,0x31,0x2e,0x36,0x32, - 0x31,0x2c,0x31,0x2e,0x36,0x31,0x39,0x2c,0x31,0x2e, - 0x36,0x32,0x31,0x68,0x37,0x2e,0x31,0x30,0x38,0x0d, - 0x0a,0x09,0x09,0x09,0x09,0x09,0x63,0x30,0x2e,0x33, - 0x38,0x34,0x2d,0x30,0x2e,0x30,0x30,0x36,0x2c,0x31, - 0x2e,0x36,0x32,0x34,0x2d,0x30,0x2e,0x31,0x34,0x32, - 0x2c,0x31,0x2e,0x36,0x32,0x34,0x2d,0x31,0x2e,0x36, - 0x32,0x31,0x56,0x32,0x33,0x2e,0x37,0x30,0x35,0x68, - 0x31,0x30,0x2e,0x32,0x33,0x31,0x63,0x30,0x2e,0x33, - 0x37,0x36,0x2d,0x30,0x2e,0x30,0x30,0x36,0x2c,0x31, - 0x2e,0x36,0x32,0x31,0x2d,0x30,0x2e,0x31,0x34,0x2c, - 0x31,0x2e,0x36,0x32,0x31,0x2d,0x31,0x2e,0x36,0x32, - 0x31,0x76,0x2d,0x37,0x2e,0x31,0x32,0x31,0x0d,0x0a, - 0x09,0x09,0x09,0x09,0x09,0x63,0x2d,0x30,0x2e,0x30, - 0x30,0x35,0x2d,0x30,0x2e,0x32,0x38,0x37,0x2d,0x30, - 0x2e,0x31,0x31,0x32,0x2d,0x31,0x2e,0x36,0x30,0x39, - 0x2d,0x31,0x2e,0x36,0x32,0x2d,0x31,0x2e,0x36,0x30, - 0x39,0x48,0x32,0x33,0x2e,0x37,0x30,0x37,0x56,0x33, - 0x2e,0x31,0x32,0x31,0x43,0x32,0x33,0x2e,0x37,0x30, - 0x31,0x2c,0x32,0x2e,0x37,0x34,0x35,0x2c,0x32,0x33, - 0x2e,0x35,0x36,0x38,0x2c,0x31,0x2e,0x35,0x2c,0x32, - 0x32,0x2e,0x30,0x38,0x36,0x2c,0x31,0x2e,0x35,0x68, - 0x2d,0x37,0x2e,0x31,0x31,0x31,0x0d,0x0a,0x09,0x09, - 0x09,0x09,0x09,0x63,0x2d,0x30,0x2e,0x33,0x37,0x36, - 0x2c,0x30,0x2e,0x30,0x30,0x36,0x2d,0x31,0x2e,0x36, - 0x31,0x39,0x2c,0x30,0x2e,0x31,0x33,0x39,0x2d,0x31, + 0x33,0x33,0x0a,0x09,0x09,0x09,0x09,0x09,0x68,0x38, + 0x2e,0x37,0x33,0x31,0x63,0x31,0x2e,0x32,0x30,0x31, + 0x2c,0x30,0x2c,0x32,0x2e,0x31,0x35,0x34,0x2c,0x30, + 0x2e,0x35,0x32,0x35,0x2c,0x32,0x2e,0x36,0x38,0x34, + 0x2c,0x31,0x2e,0x34,0x38,0x63,0x30,0x2e,0x32,0x30, + 0x37,0x2c,0x30,0x2e,0x33,0x37,0x35,0x2c,0x30,0x2e, + 0x34,0x35,0x36,0x2c,0x31,0x2e,0x31,0x31,0x32,0x2c, + 0x30,0x2e,0x34,0x32,0x39,0x2c,0x31,0x2e,0x36,0x33, + 0x39,0x68,0x30,0x2e,0x30,0x30,0x38,0x76,0x37,0x2e, + 0x31,0x31,0x63,0x30,0x2c,0x32,0x2e,0x32,0x39,0x2d, + 0x31,0x2e,0x38,0x36,0x36,0x2c,0x33,0x2e,0x31,0x32, + 0x31,0x2d,0x33,0x2e,0x31,0x32,0x31,0x2c,0x33,0x2e, + 0x31,0x32,0x31,0x68,0x2d,0x38,0x2e,0x37,0x33,0x31, + 0x0a,0x09,0x09,0x09,0x09,0x09,0x76,0x38,0x2e,0x37, + 0x33,0x32,0x43,0x32,0x35,0x2e,0x32,0x30,0x36,0x2c, + 0x33,0x36,0x2e,0x32,0x32,0x37,0x2c,0x32,0x33,0x2e, + 0x33,0x34,0x2c,0x33,0x37,0x2e,0x30,0x35,0x38,0x2c, + 0x32,0x32,0x2e,0x30,0x38,0x35,0x2c,0x33,0x37,0x2e, + 0x30,0x35,0x38,0x7a,0x20,0x4d,0x33,0x2e,0x31,0x32, + 0x31,0x2c,0x31,0x33,0x2e,0x33,0x35,0x33,0x43,0x32, + 0x2e,0x37,0x34,0x35,0x2c,0x31,0x33,0x2e,0x33,0x35, + 0x39,0x2c,0x31,0x2e,0x35,0x2c,0x31,0x33,0x2e,0x34, + 0x39,0x32,0x2c,0x31,0x2e,0x35,0x2c,0x31,0x34,0x2e, + 0x39,0x37,0x33,0x76,0x37,0x2e,0x31,0x31,0x0a,0x09, + 0x09,0x09,0x09,0x09,0x63,0x30,0x2e,0x30,0x30,0x36, + 0x2c,0x30,0x2e,0x33,0x37,0x36,0x2c,0x30,0x2e,0x31, + 0x33,0x39,0x2c,0x31,0x2e,0x36,0x32,0x31,0x2c,0x31, + 0x2e,0x36,0x32,0x31,0x2c,0x31,0x2e,0x36,0x32,0x31, + 0x68,0x31,0x30,0x2e,0x32,0x33,0x33,0x76,0x31,0x30, + 0x2e,0x32,0x33,0x32,0x63,0x30,0x2e,0x30,0x30,0x35, + 0x2c,0x30,0x2e,0x33,0x37,0x36,0x2c,0x30,0x2e,0x31, + 0x33,0x39,0x2c,0x31,0x2e,0x36,0x32,0x31,0x2c,0x31, 0x2e,0x36,0x31,0x39,0x2c,0x31,0x2e,0x36,0x32,0x31, - 0x76,0x31,0x30,0x2e,0x32,0x33,0x32,0x48,0x33,0x2e, - 0x31,0x32,0x31,0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x09, - 0x09,0x09,0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x09,0x09, - 0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x09,0x3c,0x2f,0x67, - 0x3e,0x0d,0x0a,0x09,0x3c,0x67,0x3e,0x0d,0x0a,0x09, - 0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69,0x6c, - 0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46,0x46, - 0x22,0x20,0x64,0x3d,0x22,0x4d,0x31,0x38,0x2e,0x35, - 0x33,0x31,0x2c,0x32,0x32,0x2e,0x31,0x38,0x31,0x63, - 0x2d,0x32,0x2e,0x30,0x31,0x32,0x2c,0x30,0x2d,0x33, - 0x2e,0x36,0x34,0x39,0x2d,0x31,0x2e,0x36,0x33,0x38, - 0x2d,0x33,0x2e,0x36,0x34,0x39,0x2d,0x33,0x2e,0x36, - 0x35,0x31,0x63,0x30,0x2d,0x32,0x2e,0x30,0x31,0x33, - 0x2c,0x31,0x2e,0x36,0x33,0x37,0x2d,0x33,0x2e,0x36, - 0x35,0x2c,0x33,0x2e,0x36,0x34,0x39,0x2d,0x33,0x2e, - 0x36,0x35,0x0d,0x0a,0x09,0x09,0x09,0x63,0x32,0x2e, - 0x30,0x31,0x33,0x2c,0x30,0x2c,0x33,0x2e,0x36,0x35, - 0x2c,0x31,0x2e,0x36,0x33,0x38,0x2c,0x33,0x2e,0x36, - 0x35,0x2c,0x33,0x2e,0x36,0x35,0x43,0x32,0x32,0x2e, - 0x31,0x38,0x31,0x2c,0x32,0x30,0x2e,0x35,0x34,0x34, - 0x2c,0x32,0x30,0x2e,0x35,0x34,0x33,0x2c,0x32,0x32, - 0x2e,0x31,0x38,0x31,0x2c,0x31,0x38,0x2e,0x35,0x33, - 0x31,0x2c,0x32,0x32,0x2e,0x31,0x38,0x31,0x7a,0x20, - 0x4d,0x31,0x38,0x2e,0x35,0x33,0x31,0x2c,0x31,0x36, - 0x2e,0x33,0x38,0x63,0x2d,0x31,0x2e,0x31,0x38,0x35, - 0x2c,0x30,0x2d,0x32,0x2e,0x31,0x34,0x39,0x2c,0x30, - 0x2e,0x39,0x36,0x35,0x2d,0x32,0x2e,0x31,0x34,0x39, - 0x2c,0x32,0x2e,0x31,0x35,0x0d,0x0a,0x09,0x09,0x09, - 0x63,0x30,0x2c,0x31,0x2e,0x31,0x38,0x37,0x2c,0x30, - 0x2e,0x39,0x36,0x34,0x2c,0x32,0x2e,0x31,0x35,0x31, - 0x2c,0x32,0x2e,0x31,0x34,0x39,0x2c,0x32,0x2e,0x31, - 0x35,0x31,0x63,0x31,0x2e,0x31,0x38,0x36,0x2c,0x30, - 0x2c,0x32,0x2e,0x31,0x35,0x2d,0x30,0x2e,0x39,0x36, - 0x35,0x2c,0x32,0x2e,0x31,0x35,0x2d,0x32,0x2e,0x31, - 0x35,0x31,0x43,0x32,0x30,0x2e,0x36,0x38,0x31,0x2c, - 0x31,0x37,0x2e,0x33,0x34,0x34,0x2c,0x31,0x39,0x2e, - 0x37,0x31,0x36,0x2c,0x31,0x36,0x2e,0x33,0x38,0x2c, - 0x31,0x38,0x2e,0x35,0x33,0x31,0x2c,0x31,0x36,0x2e, - 0x33,0x38,0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x09,0x3c, - 0x2f,0x67,0x3e,0x0d,0x0a,0x09,0x3c,0x67,0x3e,0x0d, - 0x0a,0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66, - 0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46, - 0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x31,0x38, - 0x2e,0x35,0x33,0x2c,0x33,0x2e,0x31,0x38,0x33,0x6c, - 0x2d,0x33,0x2e,0x30,0x30,0x35,0x2c,0x34,0x2e,0x36, - 0x38,0x34,0x68,0x36,0x2e,0x30,0x31,0x32,0x4c,0x31, - 0x38,0x2e,0x35,0x33,0x2c,0x33,0x2e,0x31,0x38,0x33, - 0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x09,0x09,0x3c,0x70, - 0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22, - 0x23,0x46,0x46,0x46,0x46,0x46,0x46,0x22,0x20,0x64, - 0x3d,0x22,0x4d,0x32,0x31,0x2e,0x35,0x33,0x36,0x2c, - 0x38,0x2e,0x36,0x31,0x37,0x68,0x2d,0x36,0x2e,0x30, - 0x31,0x32,0x63,0x2d,0x30,0x2e,0x32,0x37,0x34,0x2c, - 0x30,0x2d,0x30,0x2e,0x35,0x32,0x36,0x2d,0x30,0x2e, - 0x31,0x35,0x2d,0x30,0x2e,0x36,0x35,0x38,0x2d,0x30, - 0x2e,0x33,0x39,0x63,0x2d,0x30,0x2e,0x31,0x33,0x31, - 0x2d,0x30,0x2e,0x32,0x34,0x31,0x2d,0x30,0x2e,0x31, - 0x32,0x31,0x2d,0x30,0x2e,0x35,0x33,0x34,0x2c,0x30, - 0x2e,0x30,0x32,0x37,0x2d,0x30,0x2e,0x37,0x36,0x35, - 0x6c,0x33,0x2e,0x30,0x30,0x35,0x2d,0x34,0x2e,0x36, - 0x38,0x34,0x0d,0x0a,0x09,0x09,0x09,0x63,0x30,0x2e, - 0x32,0x37,0x36,0x2d,0x30,0x2e,0x34,0x33,0x31,0x2c, - 0x30,0x2e,0x39,0x38,0x37,0x2d,0x30,0x2e,0x34,0x33, - 0x2c,0x31,0x2e,0x32,0x36,0x32,0x2c,0x30,0x6c,0x33, - 0x2e,0x30,0x30,0x37,0x2c,0x34,0x2e,0x36,0x38,0x34, - 0x63,0x30,0x2e,0x31,0x34,0x38,0x2c,0x30,0x2e,0x32, - 0x33,0x31,0x2c,0x30,0x2e,0x31,0x35,0x39,0x2c,0x30, - 0x2e,0x35,0x32,0x34,0x2c,0x30,0x2e,0x30,0x32,0x37, - 0x2c,0x30,0x2e,0x37,0x36,0x35,0x43,0x32,0x32,0x2e, - 0x30,0x36,0x33,0x2c,0x38,0x2e,0x34,0x36,0x37,0x2c, - 0x32,0x31,0x2e,0x38,0x31,0x31,0x2c,0x38,0x2e,0x36, - 0x31,0x37,0x2c,0x32,0x31,0x2e,0x35,0x33,0x36,0x2c, - 0x38,0x2e,0x36,0x31,0x37,0x7a,0x0d,0x0a,0x09,0x09, - 0x09,0x20,0x4d,0x31,0x36,0x2e,0x38,0x39,0x37,0x2c, - 0x37,0x2e,0x31,0x31,0x37,0x68,0x33,0x2e,0x32,0x36, - 0x37,0x4c,0x31,0x38,0x2e,0x35,0x33,0x2c,0x34,0x2e, - 0x35,0x37,0x32,0x4c,0x31,0x36,0x2e,0x38,0x39,0x37, - 0x2c,0x37,0x2e,0x31,0x31,0x37,0x7a,0x22,0x2f,0x3e, - 0x0d,0x0a,0x09,0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x09, - 0x3c,0x67,0x3e,0x0d,0x0a,0x09,0x09,0x3c,0x70,0x61, + 0x68,0x37,0x2e,0x31,0x30,0x38,0x0a,0x09,0x09,0x09, + 0x09,0x09,0x63,0x30,0x2e,0x33,0x38,0x34,0x2d,0x30, + 0x2e,0x30,0x30,0x36,0x2c,0x31,0x2e,0x36,0x32,0x34, + 0x2d,0x30,0x2e,0x31,0x34,0x32,0x2c,0x31,0x2e,0x36, + 0x32,0x34,0x2d,0x31,0x2e,0x36,0x32,0x31,0x56,0x32, + 0x33,0x2e,0x37,0x30,0x35,0x68,0x31,0x30,0x2e,0x32, + 0x33,0x31,0x63,0x30,0x2e,0x33,0x37,0x36,0x2d,0x30, + 0x2e,0x30,0x30,0x36,0x2c,0x31,0x2e,0x36,0x32,0x31, + 0x2d,0x30,0x2e,0x31,0x34,0x2c,0x31,0x2e,0x36,0x32, + 0x31,0x2d,0x31,0x2e,0x36,0x32,0x31,0x76,0x2d,0x37, + 0x2e,0x31,0x32,0x31,0x0a,0x09,0x09,0x09,0x09,0x09, + 0x63,0x2d,0x30,0x2e,0x30,0x30,0x35,0x2d,0x30,0x2e, + 0x32,0x38,0x37,0x2d,0x30,0x2e,0x31,0x31,0x32,0x2d, + 0x31,0x2e,0x36,0x30,0x39,0x2d,0x31,0x2e,0x36,0x32, + 0x2d,0x31,0x2e,0x36,0x30,0x39,0x48,0x32,0x33,0x2e, + 0x37,0x30,0x37,0x56,0x33,0x2e,0x31,0x32,0x31,0x43, + 0x32,0x33,0x2e,0x37,0x30,0x31,0x2c,0x32,0x2e,0x37, + 0x34,0x35,0x2c,0x32,0x33,0x2e,0x35,0x36,0x38,0x2c, + 0x31,0x2e,0x35,0x2c,0x32,0x32,0x2e,0x30,0x38,0x36, + 0x2c,0x31,0x2e,0x35,0x68,0x2d,0x37,0x2e,0x31,0x31, + 0x31,0x0a,0x09,0x09,0x09,0x09,0x09,0x63,0x2d,0x30, + 0x2e,0x33,0x37,0x36,0x2c,0x30,0x2e,0x30,0x30,0x36, + 0x2d,0x31,0x2e,0x36,0x31,0x39,0x2c,0x30,0x2e,0x31, + 0x33,0x39,0x2d,0x31,0x2e,0x36,0x31,0x39,0x2c,0x31, + 0x2e,0x36,0x32,0x31,0x76,0x31,0x30,0x2e,0x32,0x33, + 0x32,0x48,0x33,0x2e,0x31,0x32,0x31,0x7a,0x22,0x2f, + 0x3e,0x0a,0x09,0x09,0x09,0x3c,0x2f,0x67,0x3e,0x0a, + 0x09,0x09,0x3c,0x2f,0x67,0x3e,0x0a,0x09,0x3c,0x2f, + 0x67,0x3e,0x0a,0x09,0x3c,0x67,0x3e,0x0a,0x09,0x09, + 0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c, + 0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46,0x46,0x22, + 0x20,0x64,0x3d,0x22,0x4d,0x31,0x38,0x2e,0x35,0x33, + 0x31,0x2c,0x32,0x32,0x2e,0x31,0x38,0x31,0x63,0x2d, + 0x32,0x2e,0x30,0x31,0x32,0x2c,0x30,0x2d,0x33,0x2e, + 0x36,0x34,0x39,0x2d,0x31,0x2e,0x36,0x33,0x38,0x2d, + 0x33,0x2e,0x36,0x34,0x39,0x2d,0x33,0x2e,0x36,0x35, + 0x31,0x63,0x30,0x2d,0x32,0x2e,0x30,0x31,0x33,0x2c, + 0x31,0x2e,0x36,0x33,0x37,0x2d,0x33,0x2e,0x36,0x35, + 0x2c,0x33,0x2e,0x36,0x34,0x39,0x2d,0x33,0x2e,0x36, + 0x35,0x0a,0x09,0x09,0x09,0x63,0x32,0x2e,0x30,0x31, + 0x33,0x2c,0x30,0x2c,0x33,0x2e,0x36,0x35,0x2c,0x31, + 0x2e,0x36,0x33,0x38,0x2c,0x33,0x2e,0x36,0x35,0x2c, + 0x33,0x2e,0x36,0x35,0x43,0x32,0x32,0x2e,0x31,0x38, + 0x31,0x2c,0x32,0x30,0x2e,0x35,0x34,0x34,0x2c,0x32, + 0x30,0x2e,0x35,0x34,0x33,0x2c,0x32,0x32,0x2e,0x31, + 0x38,0x31,0x2c,0x31,0x38,0x2e,0x35,0x33,0x31,0x2c, + 0x32,0x32,0x2e,0x31,0x38,0x31,0x7a,0x20,0x4d,0x31, + 0x38,0x2e,0x35,0x33,0x31,0x2c,0x31,0x36,0x2e,0x33, + 0x38,0x63,0x2d,0x31,0x2e,0x31,0x38,0x35,0x2c,0x30, + 0x2d,0x32,0x2e,0x31,0x34,0x39,0x2c,0x30,0x2e,0x39, + 0x36,0x35,0x2d,0x32,0x2e,0x31,0x34,0x39,0x2c,0x32, + 0x2e,0x31,0x35,0x0a,0x09,0x09,0x09,0x63,0x30,0x2c, + 0x31,0x2e,0x31,0x38,0x37,0x2c,0x30,0x2e,0x39,0x36, + 0x34,0x2c,0x32,0x2e,0x31,0x35,0x31,0x2c,0x32,0x2e, + 0x31,0x34,0x39,0x2c,0x32,0x2e,0x31,0x35,0x31,0x63, + 0x31,0x2e,0x31,0x38,0x36,0x2c,0x30,0x2c,0x32,0x2e, + 0x31,0x35,0x2d,0x30,0x2e,0x39,0x36,0x35,0x2c,0x32, + 0x2e,0x31,0x35,0x2d,0x32,0x2e,0x31,0x35,0x31,0x43, + 0x32,0x30,0x2e,0x36,0x38,0x31,0x2c,0x31,0x37,0x2e, + 0x33,0x34,0x34,0x2c,0x31,0x39,0x2e,0x37,0x31,0x36, + 0x2c,0x31,0x36,0x2e,0x33,0x38,0x2c,0x31,0x38,0x2e, + 0x35,0x33,0x31,0x2c,0x31,0x36,0x2e,0x33,0x38,0x7a, + 0x22,0x2f,0x3e,0x0a,0x09,0x3c,0x2f,0x67,0x3e,0x0a, + 0x09,0x3c,0x67,0x3e,0x0a,0x09,0x09,0x3c,0x70,0x61, 0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23, 0x46,0x46,0x46,0x46,0x46,0x46,0x22,0x20,0x64,0x3d, - 0x22,0x4d,0x33,0x2e,0x31,0x32,0x35,0x2c,0x31,0x38, - 0x2e,0x35,0x33,0x6c,0x34,0x2e,0x36,0x38,0x34,0x2c, - 0x33,0x2e,0x30,0x30,0x34,0x76,0x2d,0x36,0x2e,0x30, - 0x31,0x4c,0x33,0x2e,0x31,0x32,0x35,0x2c,0x31,0x38, - 0x2e,0x35,0x33,0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x09, + 0x22,0x4d,0x31,0x38,0x2e,0x35,0x33,0x2c,0x33,0x2e, + 0x31,0x38,0x33,0x6c,0x2d,0x33,0x2e,0x30,0x30,0x35, + 0x2c,0x34,0x2e,0x36,0x38,0x34,0x68,0x36,0x2e,0x30, + 0x31,0x32,0x4c,0x31,0x38,0x2e,0x35,0x33,0x2c,0x33, + 0x2e,0x31,0x38,0x33,0x7a,0x22,0x2f,0x3e,0x0a,0x09, 0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69,0x6c, 0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46,0x46, - 0x22,0x20,0x64,0x3d,0x22,0x4d,0x37,0x2e,0x38,0x30, - 0x39,0x2c,0x32,0x32,0x2e,0x32,0x38,0x34,0x63,0x2d, - 0x30,0x2e,0x31,0x34,0x31,0x2c,0x30,0x2d,0x30,0x2e, - 0x32,0x38,0x32,0x2d,0x30,0x2e,0x30,0x34,0x2d,0x30, - 0x2e,0x34,0x30,0x35,0x2d,0x30,0x2e,0x31,0x31,0x39, - 0x4c,0x32,0x2e,0x37,0x32,0x2c,0x31,0x39,0x2e,0x31, - 0x36,0x31,0x63,0x2d,0x30,0x2e,0x32,0x31,0x35,0x2d, - 0x30,0x2e,0x31,0x33,0x37,0x2d,0x30,0x2e,0x33,0x34, - 0x35,0x2d,0x30,0x2e,0x33,0x37,0x35,0x2d,0x30,0x2e, - 0x33,0x34,0x35,0x2d,0x30,0x2e,0x36,0x33,0x31,0x0d, - 0x0a,0x09,0x09,0x09,0x73,0x30,0x2e,0x31,0x33,0x2d, - 0x30,0x2e,0x34,0x39,0x33,0x2c,0x30,0x2e,0x33,0x34, - 0x35,0x2d,0x30,0x2e,0x36,0x33,0x31,0x6c,0x34,0x2e, - 0x36,0x38,0x34,0x2d,0x33,0x2e,0x30,0x30,0x36,0x63, - 0x30,0x2e,0x32,0x33,0x2d,0x30,0x2e,0x31,0x34,0x37, - 0x2c,0x30,0x2e,0x35,0x32,0x34,0x2d,0x30,0x2e,0x31, - 0x35,0x39,0x2c,0x30,0x2e,0x37,0x36,0x35,0x2d,0x30, - 0x2e,0x30,0x32,0x37,0x63,0x30,0x2e,0x32,0x34,0x2c, - 0x30,0x2e,0x31,0x33,0x31,0x2c,0x30,0x2e,0x33,0x39, - 0x2c,0x30,0x2e,0x33,0x38,0x34,0x2c,0x30,0x2e,0x33, - 0x39,0x2c,0x30,0x2e,0x36,0x35,0x38,0x76,0x36,0x2e, - 0x30,0x31,0x0d,0x0a,0x09,0x09,0x09,0x63,0x30,0x2c, - 0x30,0x2e,0x32,0x37,0x34,0x2d,0x30,0x2e,0x31,0x34, - 0x39,0x2c,0x30,0x2e,0x35,0x32,0x36,0x2d,0x30,0x2e, - 0x33,0x39,0x2c,0x30,0x2e,0x36,0x35,0x38,0x43,0x38, - 0x2e,0x30,0x35,0x36,0x2c,0x32,0x32,0x2e,0x32,0x35, - 0x34,0x2c,0x37,0x2e,0x39,0x33,0x32,0x2c,0x32,0x32, - 0x2e,0x32,0x38,0x34,0x2c,0x37,0x2e,0x38,0x30,0x39, - 0x2c,0x32,0x32,0x2e,0x32,0x38,0x34,0x7a,0x20,0x4d, - 0x34,0x2e,0x35,0x31,0x34,0x2c,0x31,0x38,0x2e,0x35, - 0x33,0x6c,0x32,0x2e,0x35,0x34,0x35,0x2c,0x31,0x2e, - 0x36,0x33,0x32,0x76,0x2d,0x33,0x2e,0x32,0x36,0x35, - 0x4c,0x34,0x2e,0x35,0x31,0x34,0x2c,0x31,0x38,0x2e, - 0x35,0x33,0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x09,0x3c, - 0x2f,0x67,0x3e,0x0d,0x0a,0x09,0x3c,0x67,0x3e,0x0d, - 0x0a,0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66, - 0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46, - 0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x33,0x33, - 0x2e,0x38,0x37,0x39,0x2c,0x31,0x38,0x2e,0x35,0x32, - 0x39,0x6c,0x2d,0x34,0x2e,0x36,0x38,0x35,0x2d,0x33, - 0x2e,0x30,0x30,0x35,0x76,0x36,0x2e,0x30,0x31,0x4c, + 0x22,0x20,0x64,0x3d,0x22,0x4d,0x32,0x31,0x2e,0x35, + 0x33,0x36,0x2c,0x38,0x2e,0x36,0x31,0x37,0x68,0x2d, + 0x36,0x2e,0x30,0x31,0x32,0x63,0x2d,0x30,0x2e,0x32, + 0x37,0x34,0x2c,0x30,0x2d,0x30,0x2e,0x35,0x32,0x36, + 0x2d,0x30,0x2e,0x31,0x35,0x2d,0x30,0x2e,0x36,0x35, + 0x38,0x2d,0x30,0x2e,0x33,0x39,0x63,0x2d,0x30,0x2e, + 0x31,0x33,0x31,0x2d,0x30,0x2e,0x32,0x34,0x31,0x2d, + 0x30,0x2e,0x31,0x32,0x31,0x2d,0x30,0x2e,0x35,0x33, + 0x34,0x2c,0x30,0x2e,0x30,0x32,0x37,0x2d,0x30,0x2e, + 0x37,0x36,0x35,0x6c,0x33,0x2e,0x30,0x30,0x35,0x2d, + 0x34,0x2e,0x36,0x38,0x34,0x0a,0x09,0x09,0x09,0x63, + 0x30,0x2e,0x32,0x37,0x36,0x2d,0x30,0x2e,0x34,0x33, + 0x31,0x2c,0x30,0x2e,0x39,0x38,0x37,0x2d,0x30,0x2e, + 0x34,0x33,0x2c,0x31,0x2e,0x32,0x36,0x32,0x2c,0x30, + 0x6c,0x33,0x2e,0x30,0x30,0x37,0x2c,0x34,0x2e,0x36, + 0x38,0x34,0x63,0x30,0x2e,0x31,0x34,0x38,0x2c,0x30, + 0x2e,0x32,0x33,0x31,0x2c,0x30,0x2e,0x31,0x35,0x39, + 0x2c,0x30,0x2e,0x35,0x32,0x34,0x2c,0x30,0x2e,0x30, + 0x32,0x37,0x2c,0x30,0x2e,0x37,0x36,0x35,0x43,0x32, + 0x32,0x2e,0x30,0x36,0x33,0x2c,0x38,0x2e,0x34,0x36, + 0x37,0x2c,0x32,0x31,0x2e,0x38,0x31,0x31,0x2c,0x38, + 0x2e,0x36,0x31,0x37,0x2c,0x32,0x31,0x2e,0x35,0x33, + 0x36,0x2c,0x38,0x2e,0x36,0x31,0x37,0x7a,0x0a,0x09, + 0x09,0x09,0x20,0x4d,0x31,0x36,0x2e,0x38,0x39,0x37, + 0x2c,0x37,0x2e,0x31,0x31,0x37,0x68,0x33,0x2e,0x32, + 0x36,0x37,0x4c,0x31,0x38,0x2e,0x35,0x33,0x2c,0x34, + 0x2e,0x35,0x37,0x32,0x4c,0x31,0x36,0x2e,0x38,0x39, + 0x37,0x2c,0x37,0x2e,0x31,0x31,0x37,0x7a,0x22,0x2f, + 0x3e,0x0a,0x09,0x3c,0x2f,0x67,0x3e,0x0a,0x09,0x3c, + 0x67,0x3e,0x0a,0x09,0x09,0x3c,0x70,0x61,0x74,0x68, + 0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46, + 0x46,0x46,0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d, + 0x33,0x2e,0x31,0x32,0x35,0x2c,0x31,0x38,0x2e,0x35, + 0x33,0x6c,0x34,0x2e,0x36,0x38,0x34,0x2c,0x33,0x2e, + 0x30,0x30,0x34,0x76,0x2d,0x36,0x2e,0x30,0x31,0x4c, + 0x33,0x2e,0x31,0x32,0x35,0x2c,0x31,0x38,0x2e,0x35, + 0x33,0x7a,0x22,0x2f,0x3e,0x0a,0x09,0x09,0x3c,0x70, + 0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22, + 0x23,0x46,0x46,0x46,0x46,0x46,0x46,0x22,0x20,0x64, + 0x3d,0x22,0x4d,0x37,0x2e,0x38,0x30,0x39,0x2c,0x32, + 0x32,0x2e,0x32,0x38,0x34,0x63,0x2d,0x30,0x2e,0x31, + 0x34,0x31,0x2c,0x30,0x2d,0x30,0x2e,0x32,0x38,0x32, + 0x2d,0x30,0x2e,0x30,0x34,0x2d,0x30,0x2e,0x34,0x30, + 0x35,0x2d,0x30,0x2e,0x31,0x31,0x39,0x4c,0x32,0x2e, + 0x37,0x32,0x2c,0x31,0x39,0x2e,0x31,0x36,0x31,0x63, + 0x2d,0x30,0x2e,0x32,0x31,0x35,0x2d,0x30,0x2e,0x31, + 0x33,0x37,0x2d,0x30,0x2e,0x33,0x34,0x35,0x2d,0x30, + 0x2e,0x33,0x37,0x35,0x2d,0x30,0x2e,0x33,0x34,0x35, + 0x2d,0x30,0x2e,0x36,0x33,0x31,0x0a,0x09,0x09,0x09, + 0x73,0x30,0x2e,0x31,0x33,0x2d,0x30,0x2e,0x34,0x39, + 0x33,0x2c,0x30,0x2e,0x33,0x34,0x35,0x2d,0x30,0x2e, + 0x36,0x33,0x31,0x6c,0x34,0x2e,0x36,0x38,0x34,0x2d, + 0x33,0x2e,0x30,0x30,0x36,0x63,0x30,0x2e,0x32,0x33, + 0x2d,0x30,0x2e,0x31,0x34,0x37,0x2c,0x30,0x2e,0x35, + 0x32,0x34,0x2d,0x30,0x2e,0x31,0x35,0x39,0x2c,0x30, + 0x2e,0x37,0x36,0x35,0x2d,0x30,0x2e,0x30,0x32,0x37, + 0x63,0x30,0x2e,0x32,0x34,0x2c,0x30,0x2e,0x31,0x33, + 0x31,0x2c,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2e,0x33, + 0x38,0x34,0x2c,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2e, + 0x36,0x35,0x38,0x76,0x36,0x2e,0x30,0x31,0x0a,0x09, + 0x09,0x09,0x63,0x30,0x2c,0x30,0x2e,0x32,0x37,0x34, + 0x2d,0x30,0x2e,0x31,0x34,0x39,0x2c,0x30,0x2e,0x35, + 0x32,0x36,0x2d,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2e, + 0x36,0x35,0x38,0x43,0x38,0x2e,0x30,0x35,0x36,0x2c, + 0x32,0x32,0x2e,0x32,0x35,0x34,0x2c,0x37,0x2e,0x39, + 0x33,0x32,0x2c,0x32,0x32,0x2e,0x32,0x38,0x34,0x2c, + 0x37,0x2e,0x38,0x30,0x39,0x2c,0x32,0x32,0x2e,0x32, + 0x38,0x34,0x7a,0x20,0x4d,0x34,0x2e,0x35,0x31,0x34, + 0x2c,0x31,0x38,0x2e,0x35,0x33,0x6c,0x32,0x2e,0x35, + 0x34,0x35,0x2c,0x31,0x2e,0x36,0x33,0x32,0x76,0x2d, + 0x33,0x2e,0x32,0x36,0x35,0x4c,0x34,0x2e,0x35,0x31, + 0x34,0x2c,0x31,0x38,0x2e,0x35,0x33,0x7a,0x22,0x2f, + 0x3e,0x0a,0x09,0x3c,0x2f,0x67,0x3e,0x0a,0x09,0x3c, + 0x67,0x3e,0x0a,0x09,0x09,0x3c,0x70,0x61,0x74,0x68, + 0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46, + 0x46,0x46,0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d, 0x33,0x33,0x2e,0x38,0x37,0x39,0x2c,0x31,0x38,0x2e, - 0x35,0x32,0x39,0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x09, - 0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69,0x6c, - 0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46,0x46, - 0x22,0x20,0x64,0x3d,0x22,0x4d,0x32,0x39,0x2e,0x31, - 0x39,0x35,0x2c,0x32,0x32,0x2e,0x32,0x38,0x34,0x63, - 0x2d,0x30,0x2e,0x31,0x32,0x34,0x2c,0x30,0x2d,0x30, - 0x2e,0x32,0x34,0x37,0x2d,0x30,0x2e,0x30,0x33,0x2d, - 0x30,0x2e,0x33,0x35,0x39,0x2d,0x30,0x2e,0x30,0x39, - 0x32,0x63,0x2d,0x30,0x2e,0x32,0x34,0x31,0x2d,0x30, - 0x2e,0x31,0x33,0x32,0x2d,0x30,0x2e,0x33,0x39,0x31, - 0x2d,0x30,0x2e,0x33,0x38,0x34,0x2d,0x30,0x2e,0x33, - 0x39,0x31,0x2d,0x30,0x2e,0x36,0x35,0x38,0x76,0x2d, - 0x36,0x2e,0x30,0x31,0x0d,0x0a,0x09,0x09,0x09,0x63, + 0x35,0x32,0x39,0x6c,0x2d,0x34,0x2e,0x36,0x38,0x35, + 0x2d,0x33,0x2e,0x30,0x30,0x35,0x76,0x36,0x2e,0x30, + 0x31,0x4c,0x33,0x33,0x2e,0x38,0x37,0x39,0x2c,0x31, + 0x38,0x2e,0x35,0x32,0x39,0x7a,0x22,0x2f,0x3e,0x0a, + 0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69, + 0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46, + 0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x32,0x39,0x2e, + 0x31,0x39,0x35,0x2c,0x32,0x32,0x2e,0x32,0x38,0x34, + 0x63,0x2d,0x30,0x2e,0x31,0x32,0x34,0x2c,0x30,0x2d, + 0x30,0x2e,0x32,0x34,0x37,0x2d,0x30,0x2e,0x30,0x33, + 0x2d,0x30,0x2e,0x33,0x35,0x39,0x2d,0x30,0x2e,0x30, + 0x39,0x32,0x63,0x2d,0x30,0x2e,0x32,0x34,0x31,0x2d, + 0x30,0x2e,0x31,0x33,0x32,0x2d,0x30,0x2e,0x33,0x39, + 0x31,0x2d,0x30,0x2e,0x33,0x38,0x34,0x2d,0x30,0x2e, + 0x33,0x39,0x31,0x2d,0x30,0x2e,0x36,0x35,0x38,0x76, + 0x2d,0x36,0x2e,0x30,0x31,0x0a,0x09,0x09,0x09,0x63, 0x30,0x2d,0x30,0x2e,0x32,0x37,0x34,0x2c,0x30,0x2e, 0x31,0x34,0x39,0x2d,0x30,0x2e,0x35,0x32,0x36,0x2c, 0x30,0x2e,0x33,0x39,0x31,0x2d,0x30,0x2e,0x36,0x35, @@ -294,67 +290,66 @@ const unsigned char help_dpad_all_svg_data[3523] = { 0x30,0x2e,0x32,0x31,0x35,0x2c,0x30,0x2e,0x31,0x33, 0x38,0x2c,0x30,0x2e,0x33,0x34,0x35,0x2c,0x30,0x2e, 0x33,0x37,0x36,0x2c,0x30,0x2e,0x33,0x34,0x35,0x2c, - 0x30,0x2e,0x36,0x33,0x31,0x0d,0x0a,0x09,0x09,0x09, - 0x73,0x2d,0x30,0x2e,0x31,0x33,0x2c,0x30,0x2e,0x34, - 0x39,0x33,0x2d,0x30,0x2e,0x33,0x34,0x35,0x2c,0x30, - 0x2e,0x36,0x33,0x31,0x4c,0x32,0x39,0x2e,0x36,0x2c, - 0x32,0x32,0x2e,0x31,0x36,0x35,0x43,0x32,0x39,0x2e, - 0x34,0x37,0x37,0x2c,0x32,0x32,0x2e,0x32,0x34,0x34, - 0x2c,0x32,0x39,0x2e,0x33,0x33,0x35,0x2c,0x32,0x32, - 0x2e,0x32,0x38,0x34,0x2c,0x32,0x39,0x2e,0x31,0x39, - 0x35,0x2c,0x32,0x32,0x2e,0x32,0x38,0x34,0x7a,0x20, - 0x4d,0x32,0x39,0x2e,0x39,0x34,0x35,0x2c,0x31,0x36, - 0x2e,0x38,0x39,0x36,0x76,0x33,0x2e,0x32,0x36,0x36, - 0x6c,0x32,0x2e,0x35,0x34,0x36,0x2d,0x31,0x2e,0x36, - 0x33,0x33,0x0d,0x0a,0x09,0x09,0x09,0x4c,0x32,0x39, - 0x2e,0x39,0x34,0x35,0x2c,0x31,0x36,0x2e,0x38,0x39, - 0x36,0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x09,0x3c,0x2f, - 0x67,0x3e,0x0d,0x0a,0x09,0x3c,0x67,0x3e,0x0d,0x0a, - 0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69, - 0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46, - 0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x31,0x38,0x2e, - 0x35,0x33,0x2c,0x33,0x33,0x2e,0x38,0x37,0x36,0x6c, - 0x33,0x2e,0x30,0x30,0x37,0x2d,0x34,0x2e,0x36,0x38, - 0x34,0x68,0x2d,0x36,0x2e,0x30,0x31,0x32,0x4c,0x31, - 0x38,0x2e,0x35,0x33,0x2c,0x33,0x33,0x2e,0x38,0x37, - 0x36,0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x09,0x09,0x3c, - 0x70,0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d, - 0x22,0x23,0x46,0x46,0x46,0x46,0x46,0x46,0x22,0x20, - 0x64,0x3d,0x22,0x4d,0x31,0x38,0x2e,0x35,0x33,0x2c, - 0x33,0x34,0x2e,0x36,0x32,0x36,0x4c,0x31,0x38,0x2e, - 0x35,0x33,0x2c,0x33,0x34,0x2e,0x36,0x32,0x36,0x63, - 0x2d,0x30,0x2e,0x32,0x35,0x35,0x2c,0x30,0x2d,0x30, - 0x2e,0x34,0x39,0x33,0x2d,0x30,0x2e,0x31,0x33,0x2d, - 0x30,0x2e,0x36,0x33,0x31,0x2d,0x30,0x2e,0x33,0x34, - 0x35,0x6c,0x2d,0x33,0x2e,0x30,0x30,0x35,0x2d,0x34, - 0x2e,0x36,0x38,0x34,0x0d,0x0a,0x09,0x09,0x09,0x63, - 0x2d,0x30,0x2e,0x31,0x34,0x38,0x2d,0x30,0x2e,0x32, - 0x33,0x31,0x2d,0x30,0x2e,0x31,0x35,0x38,0x2d,0x30, - 0x2e,0x35,0x32,0x34,0x2d,0x30,0x2e,0x30,0x32,0x37, - 0x2d,0x30,0x2e,0x37,0x36,0x35,0x63,0x30,0x2e,0x31, - 0x33,0x32,0x2d,0x30,0x2e,0x32,0x34,0x31,0x2c,0x30, - 0x2e,0x33,0x38,0x34,0x2d,0x30,0x2e,0x33,0x39,0x31, - 0x2c,0x30,0x2e,0x36,0x35,0x38,0x2d,0x30,0x2e,0x33, - 0x39,0x31,0x68,0x36,0x2e,0x30,0x31,0x32,0x63,0x30, - 0x2e,0x32,0x37,0x34,0x2c,0x30,0x2c,0x30,0x2e,0x35, - 0x32,0x36,0x2c,0x30,0x2e,0x31,0x34,0x39,0x2c,0x30, - 0x2e,0x36,0x35,0x38,0x2c,0x30,0x2e,0x33,0x39,0x31, - 0x0d,0x0a,0x09,0x09,0x09,0x63,0x30,0x2e,0x31,0x33, - 0x32,0x2c,0x30,0x2e,0x32,0x34,0x2c,0x30,0x2e,0x31, - 0x32,0x31,0x2c,0x30,0x2e,0x35,0x33,0x34,0x2d,0x30, - 0x2e,0x30,0x32,0x37,0x2c,0x30,0x2e,0x37,0x36,0x35, - 0x6c,0x2d,0x33,0x2e,0x30,0x30,0x37,0x2c,0x34,0x2e, - 0x36,0x38,0x34,0x43,0x31,0x39,0x2e,0x30,0x32,0x33, - 0x2c,0x33,0x34,0x2e,0x34,0x39,0x36,0x2c,0x31,0x38, - 0x2e,0x37,0x38,0x35,0x2c,0x33,0x34,0x2e,0x36,0x32, - 0x36,0x2c,0x31,0x38,0x2e,0x35,0x33,0x2c,0x33,0x34, - 0x2e,0x36,0x32,0x36,0x7a,0x20,0x4d,0x31,0x36,0x2e, - 0x38,0x39,0x37,0x2c,0x32,0x39,0x2e,0x39,0x34,0x32, - 0x6c,0x31,0x2e,0x36,0x33,0x33,0x2c,0x32,0x2e,0x35, - 0x34,0x35,0x0d,0x0a,0x09,0x09,0x09,0x6c,0x31,0x2e, - 0x36,0x33,0x34,0x2d,0x32,0x2e,0x35,0x34,0x35,0x48, - 0x31,0x36,0x2e,0x38,0x39,0x37,0x7a,0x22,0x2f,0x3e, - 0x0d,0x0a,0x09,0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x3c, - 0x2f,0x67,0x3e,0x0d,0x0a,0x3c,0x2f,0x73,0x76,0x67, - 0x3e,0x0d,0x0a + 0x30,0x2e,0x36,0x33,0x31,0x0a,0x09,0x09,0x09,0x73, + 0x2d,0x30,0x2e,0x31,0x33,0x2c,0x30,0x2e,0x34,0x39, + 0x33,0x2d,0x30,0x2e,0x33,0x34,0x35,0x2c,0x30,0x2e, + 0x36,0x33,0x31,0x4c,0x32,0x39,0x2e,0x36,0x2c,0x32, + 0x32,0x2e,0x31,0x36,0x35,0x43,0x32,0x39,0x2e,0x34, + 0x37,0x37,0x2c,0x32,0x32,0x2e,0x32,0x34,0x34,0x2c, + 0x32,0x39,0x2e,0x33,0x33,0x35,0x2c,0x32,0x32,0x2e, + 0x32,0x38,0x34,0x2c,0x32,0x39,0x2e,0x31,0x39,0x35, + 0x2c,0x32,0x32,0x2e,0x32,0x38,0x34,0x7a,0x20,0x4d, + 0x32,0x39,0x2e,0x39,0x34,0x35,0x2c,0x31,0x36,0x2e, + 0x38,0x39,0x36,0x76,0x33,0x2e,0x32,0x36,0x36,0x6c, + 0x32,0x2e,0x35,0x34,0x36,0x2d,0x31,0x2e,0x36,0x33, + 0x33,0x0a,0x09,0x09,0x09,0x4c,0x32,0x39,0x2e,0x39, + 0x34,0x35,0x2c,0x31,0x36,0x2e,0x38,0x39,0x36,0x7a, + 0x22,0x2f,0x3e,0x0a,0x09,0x3c,0x2f,0x67,0x3e,0x0a, + 0x09,0x3c,0x67,0x3e,0x0a,0x09,0x09,0x3c,0x70,0x61, + 0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23, + 0x46,0x46,0x46,0x46,0x46,0x46,0x22,0x20,0x64,0x3d, + 0x22,0x4d,0x31,0x38,0x2e,0x35,0x33,0x2c,0x33,0x33, + 0x2e,0x38,0x37,0x36,0x6c,0x33,0x2e,0x30,0x30,0x37, + 0x2d,0x34,0x2e,0x36,0x38,0x34,0x68,0x2d,0x36,0x2e, + 0x30,0x31,0x32,0x4c,0x31,0x38,0x2e,0x35,0x33,0x2c, + 0x33,0x33,0x2e,0x38,0x37,0x36,0x7a,0x22,0x2f,0x3e, + 0x0a,0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66, + 0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46, + 0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x31,0x38, + 0x2e,0x35,0x33,0x2c,0x33,0x34,0x2e,0x36,0x32,0x36, + 0x4c,0x31,0x38,0x2e,0x35,0x33,0x2c,0x33,0x34,0x2e, + 0x36,0x32,0x36,0x63,0x2d,0x30,0x2e,0x32,0x35,0x35, + 0x2c,0x30,0x2d,0x30,0x2e,0x34,0x39,0x33,0x2d,0x30, + 0x2e,0x31,0x33,0x2d,0x30,0x2e,0x36,0x33,0x31,0x2d, + 0x30,0x2e,0x33,0x34,0x35,0x6c,0x2d,0x33,0x2e,0x30, + 0x30,0x35,0x2d,0x34,0x2e,0x36,0x38,0x34,0x0a,0x09, + 0x09,0x09,0x63,0x2d,0x30,0x2e,0x31,0x34,0x38,0x2d, + 0x30,0x2e,0x32,0x33,0x31,0x2d,0x30,0x2e,0x31,0x35, + 0x38,0x2d,0x30,0x2e,0x35,0x32,0x34,0x2d,0x30,0x2e, + 0x30,0x32,0x37,0x2d,0x30,0x2e,0x37,0x36,0x35,0x63, + 0x30,0x2e,0x31,0x33,0x32,0x2d,0x30,0x2e,0x32,0x34, + 0x31,0x2c,0x30,0x2e,0x33,0x38,0x34,0x2d,0x30,0x2e, + 0x33,0x39,0x31,0x2c,0x30,0x2e,0x36,0x35,0x38,0x2d, + 0x30,0x2e,0x33,0x39,0x31,0x68,0x36,0x2e,0x30,0x31, + 0x32,0x63,0x30,0x2e,0x32,0x37,0x34,0x2c,0x30,0x2c, + 0x30,0x2e,0x35,0x32,0x36,0x2c,0x30,0x2e,0x31,0x34, + 0x39,0x2c,0x30,0x2e,0x36,0x35,0x38,0x2c,0x30,0x2e, + 0x33,0x39,0x31,0x0a,0x09,0x09,0x09,0x63,0x30,0x2e, + 0x31,0x33,0x32,0x2c,0x30,0x2e,0x32,0x34,0x2c,0x30, + 0x2e,0x31,0x32,0x31,0x2c,0x30,0x2e,0x35,0x33,0x34, + 0x2d,0x30,0x2e,0x30,0x32,0x37,0x2c,0x30,0x2e,0x37, + 0x36,0x35,0x6c,0x2d,0x33,0x2e,0x30,0x30,0x37,0x2c, + 0x34,0x2e,0x36,0x38,0x34,0x43,0x31,0x39,0x2e,0x30, + 0x32,0x33,0x2c,0x33,0x34,0x2e,0x34,0x39,0x36,0x2c, + 0x31,0x38,0x2e,0x37,0x38,0x35,0x2c,0x33,0x34,0x2e, + 0x36,0x32,0x36,0x2c,0x31,0x38,0x2e,0x35,0x33,0x2c, + 0x33,0x34,0x2e,0x36,0x32,0x36,0x7a,0x20,0x4d,0x31, + 0x36,0x2e,0x38,0x39,0x37,0x2c,0x32,0x39,0x2e,0x39, + 0x34,0x32,0x6c,0x31,0x2e,0x36,0x33,0x33,0x2c,0x32, + 0x2e,0x35,0x34,0x35,0x0a,0x09,0x09,0x09,0x6c,0x31, + 0x2e,0x36,0x33,0x34,0x2d,0x32,0x2e,0x35,0x34,0x35, + 0x48,0x31,0x36,0x2e,0x38,0x39,0x37,0x7a,0x22,0x2f, + 0x3e,0x0a,0x09,0x3c,0x2f,0x67,0x3e,0x0a,0x3c,0x2f, + 0x67,0x3e,0x0a,0x3c,0x2f,0x73,0x76,0x67,0x3e,0x0a }; + diff --git a/data/converted/help_dpad_down_svg.cpp b/data/converted/help_dpad_down_svg.cpp index e6b58955d7..11fa7c3139 100644 --- a/data/converted/help_dpad_down_svg.cpp +++ b/data/converted/help_dpad_down_svg.cpp @@ -2,84 +2,83 @@ #include "../Resources.h" -const size_t help_dpad_down_svg_size = 3215; -const unsigned char help_dpad_down_svg_data[3215] = { +const size_t help_dpad_down_svg_size = 3167; +const unsigned char help_dpad_down_svg_data[3167] = { 0x3c,0x3f,0x78,0x6d,0x6c,0x20,0x76,0x65,0x72,0x73, 0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x30,0x22,0x20, 0x65,0x6e,0x63,0x6f,0x64,0x69,0x6e,0x67,0x3d,0x22, - 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0d,0x0a, - 0x3c,0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72, - 0x61,0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62, - 0x65,0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61, - 0x74,0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33, - 0x2c,0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f, - 0x72,0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e, - 0x20,0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72, - 0x73,0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30, - 0x20,0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20, - 0x20,0x2d,0x2d,0x3e,0x0d,0x0a,0x3c,0x21,0x44,0x4f, - 0x43,0x54,0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20, - 0x50,0x55,0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f, - 0x2f,0x57,0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20, - 0x53,0x56,0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45, - 0x4e,0x22,0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, - 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, - 0x67,0x2f,0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73, - 0x2f,0x53,0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44, - 0x54,0x44,0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64, - 0x74,0x64,0x22,0x3e,0x0d,0x0a,0x3c,0x73,0x76,0x67, - 0x20,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22, - 0x31,0x2e,0x31,0x22,0x20,0x69,0x64,0x3d,0x22,0x5f, - 0x78,0x33,0x30,0x5f,0x22,0x20,0x78,0x6d,0x6c,0x6e, - 0x73,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f, - 0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67, - 0x2f,0x32,0x30,0x30,0x30,0x2f,0x73,0x76,0x67,0x22, - 0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78,0x6c,0x69, - 0x6e,0x6b,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, - 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, - 0x67,0x2f,0x31,0x39,0x39,0x39,0x2f,0x78,0x6c,0x69, - 0x6e,0x6b,0x22,0x20,0x78,0x3d,0x22,0x30,0x70,0x78, - 0x22,0x20,0x79,0x3d,0x22,0x30,0x70,0x78,0x22,0x0d, - 0x0a,0x09,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22, - 0x33,0x37,0x2e,0x30,0x36,0x31,0x70,0x78,0x22,0x20, - 0x68,0x65,0x69,0x67,0x68,0x74,0x3d,0x22,0x33,0x37, - 0x2e,0x30,0x36,0x31,0x70,0x78,0x22,0x20,0x76,0x69, - 0x65,0x77,0x42,0x6f,0x78,0x3d,0x22,0x30,0x20,0x30, - 0x20,0x33,0x37,0x2e,0x30,0x36,0x31,0x20,0x33,0x37, - 0x2e,0x30,0x36,0x31,0x22,0x20,0x65,0x6e,0x61,0x62, - 0x6c,0x65,0x2d,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f, - 0x75,0x6e,0x64,0x3d,0x22,0x6e,0x65,0x77,0x20,0x30, - 0x20,0x30,0x20,0x33,0x37,0x2e,0x30,0x36,0x31,0x20, - 0x33,0x37,0x2e,0x30,0x36,0x31,0x22,0x20,0x78,0x6d, - 0x6c,0x3a,0x73,0x70,0x61,0x63,0x65,0x3d,0x22,0x70, - 0x72,0x65,0x73,0x65,0x72,0x76,0x65,0x22,0x3e,0x0d, - 0x0a,0x3c,0x67,0x3e,0x0d,0x0a,0x09,0x3c,0x67,0x3e, - 0x0d,0x0a,0x09,0x09,0x3c,0x67,0x3e,0x0d,0x0a,0x09, - 0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69, - 0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46, - 0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x32,0x32,0x2e, - 0x30,0x38,0x36,0x2c,0x33,0x37,0x2e,0x30,0x36,0x68, - 0x2d,0x37,0x2e,0x31,0x31,0x31,0x63,0x2d,0x32,0x2e, - 0x32,0x38,0x39,0x2c,0x30,0x2d,0x33,0x2e,0x31,0x31, - 0x39,0x2d,0x31,0x2e,0x38,0x36,0x36,0x2d,0x33,0x2e, - 0x31,0x31,0x39,0x2d,0x33,0x2e,0x31,0x32,0x31,0x76, - 0x2d,0x38,0x2e,0x37,0x33,0x32,0x48,0x33,0x2e,0x31, - 0x32,0x31,0x43,0x30,0x2e,0x38,0x33,0x31,0x2c,0x32, - 0x35,0x2e,0x32,0x30,0x36,0x2c,0x30,0x2c,0x32,0x33, - 0x2e,0x33,0x34,0x2c,0x30,0x2c,0x32,0x32,0x2e,0x30, - 0x38,0x35,0x0d,0x0a,0x09,0x09,0x09,0x09,0x76,0x2d, - 0x37,0x2e,0x31,0x31,0x63,0x30,0x2d,0x32,0x2e,0x32, - 0x38,0x39,0x2c,0x31,0x2e,0x38,0x36,0x37,0x2d,0x33, - 0x2e,0x31,0x32,0x2c,0x33,0x2e,0x31,0x32,0x31,0x2d, - 0x33,0x2e,0x31,0x32,0x68,0x38,0x2e,0x37,0x33,0x33, - 0x56,0x33,0x2e,0x31,0x32,0x31,0x43,0x31,0x31,0x2e, - 0x38,0x35,0x35,0x2c,0x30,0x2e,0x38,0x33,0x31,0x2c, - 0x31,0x33,0x2e,0x37,0x32,0x2c,0x30,0x2c,0x31,0x34, - 0x2e,0x39,0x37,0x34,0x2c,0x30,0x68,0x37,0x2e,0x31, - 0x31,0x31,0x63,0x32,0x2e,0x32,0x39,0x2c,0x30,0x2c, - 0x33,0x2e,0x31,0x32,0x31,0x2c,0x31,0x2e,0x38,0x36, - 0x37,0x2c,0x33,0x2e,0x31,0x32,0x31,0x2c,0x33,0x2e, - 0x31,0x32,0x31,0x76,0x38,0x2e,0x37,0x33,0x32,0x0d, + 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0a,0x3c, + 0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72,0x61, + 0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62,0x65, + 0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61,0x74, + 0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33,0x2c, + 0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f,0x72, + 0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e,0x20, + 0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72,0x73, + 0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30,0x20, + 0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20,0x20, + 0x2d,0x2d,0x3e,0x0a,0x3c,0x21,0x44,0x4f,0x43,0x54, + 0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20,0x50,0x55, + 0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f,0x2f,0x57, + 0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20,0x53,0x56, + 0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45,0x4e,0x22, + 0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73,0x2f,0x53, + 0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44,0x54,0x44, + 0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64,0x74,0x64, + 0x22,0x3e,0x0a,0x3c,0x73,0x76,0x67,0x20,0x76,0x65, + 0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x31, + 0x22,0x20,0x69,0x64,0x3d,0x22,0x5f,0x78,0x33,0x30, + 0x5f,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3d,0x22, + 0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77, + 0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f,0x32,0x30, + 0x30,0x30,0x2f,0x73,0x76,0x67,0x22,0x20,0x78,0x6d, + 0x6c,0x6e,0x73,0x3a,0x78,0x6c,0x69,0x6e,0x6b,0x3d, + 0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77, + 0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f,0x31, + 0x39,0x39,0x39,0x2f,0x78,0x6c,0x69,0x6e,0x6b,0x22, + 0x20,0x78,0x3d,0x22,0x30,0x70,0x78,0x22,0x20,0x79, + 0x3d,0x22,0x30,0x70,0x78,0x22,0x0a,0x09,0x20,0x77, + 0x69,0x64,0x74,0x68,0x3d,0x22,0x33,0x37,0x2e,0x30, + 0x36,0x31,0x70,0x78,0x22,0x20,0x68,0x65,0x69,0x67, + 0x68,0x74,0x3d,0x22,0x33,0x37,0x2e,0x30,0x36,0x31, + 0x70,0x78,0x22,0x20,0x76,0x69,0x65,0x77,0x42,0x6f, + 0x78,0x3d,0x22,0x30,0x20,0x30,0x20,0x33,0x37,0x2e, + 0x30,0x36,0x31,0x20,0x33,0x37,0x2e,0x30,0x36,0x31, + 0x22,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0x2d,0x62, + 0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x3d, + 0x22,0x6e,0x65,0x77,0x20,0x30,0x20,0x30,0x20,0x33, + 0x37,0x2e,0x30,0x36,0x31,0x20,0x33,0x37,0x2e,0x30, + 0x36,0x31,0x22,0x20,0x78,0x6d,0x6c,0x3a,0x73,0x70, + 0x61,0x63,0x65,0x3d,0x22,0x70,0x72,0x65,0x73,0x65, + 0x72,0x76,0x65,0x22,0x3e,0x0a,0x3c,0x67,0x3e,0x0a, + 0x09,0x3c,0x67,0x3e,0x0a,0x09,0x09,0x3c,0x67,0x3e, + 0x0a,0x09,0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20, + 0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46, + 0x46,0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x32, + 0x32,0x2e,0x30,0x38,0x36,0x2c,0x33,0x37,0x2e,0x30, + 0x36,0x68,0x2d,0x37,0x2e,0x31,0x31,0x31,0x63,0x2d, + 0x32,0x2e,0x32,0x38,0x39,0x2c,0x30,0x2d,0x33,0x2e, + 0x31,0x31,0x39,0x2d,0x31,0x2e,0x38,0x36,0x36,0x2d, + 0x33,0x2e,0x31,0x31,0x39,0x2d,0x33,0x2e,0x31,0x32, + 0x31,0x76,0x2d,0x38,0x2e,0x37,0x33,0x32,0x48,0x33, + 0x2e,0x31,0x32,0x31,0x43,0x30,0x2e,0x38,0x33,0x31, + 0x2c,0x32,0x35,0x2e,0x32,0x30,0x36,0x2c,0x30,0x2c, + 0x32,0x33,0x2e,0x33,0x34,0x2c,0x30,0x2c,0x32,0x32, + 0x2e,0x30,0x38,0x35,0x0a,0x09,0x09,0x09,0x09,0x76, + 0x2d,0x37,0x2e,0x31,0x31,0x63,0x30,0x2d,0x32,0x2e, + 0x32,0x38,0x39,0x2c,0x31,0x2e,0x38,0x36,0x37,0x2d, + 0x33,0x2e,0x31,0x32,0x2c,0x33,0x2e,0x31,0x32,0x31, + 0x2d,0x33,0x2e,0x31,0x32,0x68,0x38,0x2e,0x37,0x33, + 0x33,0x56,0x33,0x2e,0x31,0x32,0x31,0x43,0x31,0x31, + 0x2e,0x38,0x35,0x35,0x2c,0x30,0x2e,0x38,0x33,0x31, + 0x2c,0x31,0x33,0x2e,0x37,0x32,0x2c,0x30,0x2c,0x31, + 0x34,0x2e,0x39,0x37,0x34,0x2c,0x30,0x68,0x37,0x2e, + 0x31,0x31,0x31,0x63,0x32,0x2e,0x32,0x39,0x2c,0x30, + 0x2c,0x33,0x2e,0x31,0x32,0x31,0x2c,0x31,0x2e,0x38, + 0x36,0x37,0x2c,0x33,0x2e,0x31,0x32,0x31,0x2c,0x33, + 0x2e,0x31,0x32,0x31,0x76,0x38,0x2e,0x37,0x33,0x32, 0x0a,0x09,0x09,0x09,0x09,0x68,0x38,0x2e,0x37,0x33, 0x31,0x63,0x32,0x2e,0x32,0x39,0x2c,0x30,0x2c,0x33, 0x2e,0x31,0x32,0x31,0x2c,0x31,0x2e,0x38,0x36,0x35, @@ -89,68 +88,67 @@ const unsigned char help_dpad_down_svg_data[3215] = { 0x33,0x2e,0x31,0x32,0x31,0x2d,0x33,0x2e,0x31,0x32, 0x31,0x2c,0x33,0x2e,0x31,0x32,0x31,0x68,0x2d,0x38, 0x2e,0x37,0x33,0x31,0x76,0x38,0x2e,0x37,0x33,0x32, - 0x0d,0x0a,0x09,0x09,0x09,0x09,0x43,0x32,0x35,0x2e, - 0x32,0x30,0x37,0x2c,0x33,0x36,0x2e,0x32,0x32,0x39, - 0x2c,0x32,0x33,0x2e,0x33,0x34,0x31,0x2c,0x33,0x37, - 0x2e,0x30,0x36,0x2c,0x32,0x32,0x2e,0x30,0x38,0x36, - 0x2c,0x33,0x37,0x2e,0x30,0x36,0x7a,0x20,0x4d,0x33, - 0x2e,0x31,0x32,0x31,0x2c,0x31,0x33,0x2e,0x33,0x35, - 0x34,0x43,0x32,0x2e,0x37,0x34,0x35,0x2c,0x31,0x33, - 0x2e,0x33,0x35,0x39,0x2c,0x31,0x2e,0x35,0x2c,0x31, - 0x33,0x2e,0x34,0x39,0x33,0x2c,0x31,0x2e,0x35,0x2c, - 0x31,0x34,0x2e,0x39,0x37,0x34,0x76,0x37,0x2e,0x31, - 0x31,0x0d,0x0a,0x09,0x09,0x09,0x09,0x63,0x30,0x2e, - 0x30,0x30,0x36,0x2c,0x30,0x2e,0x33,0x37,0x36,0x2c, - 0x30,0x2e,0x31,0x33,0x39,0x2c,0x31,0x2e,0x36,0x32, - 0x31,0x2c,0x31,0x2e,0x36,0x32,0x31,0x2c,0x31,0x2e, - 0x36,0x32,0x31,0x68,0x31,0x30,0x2e,0x32,0x33,0x33, - 0x76,0x31,0x30,0x2e,0x32,0x33,0x32,0x63,0x30,0x2e, - 0x30,0x30,0x35,0x2c,0x30,0x2e,0x33,0x37,0x36,0x2c, + 0x0a,0x09,0x09,0x09,0x09,0x43,0x32,0x35,0x2e,0x32, + 0x30,0x37,0x2c,0x33,0x36,0x2e,0x32,0x32,0x39,0x2c, + 0x32,0x33,0x2e,0x33,0x34,0x31,0x2c,0x33,0x37,0x2e, + 0x30,0x36,0x2c,0x32,0x32,0x2e,0x30,0x38,0x36,0x2c, + 0x33,0x37,0x2e,0x30,0x36,0x7a,0x20,0x4d,0x33,0x2e, + 0x31,0x32,0x31,0x2c,0x31,0x33,0x2e,0x33,0x35,0x34, + 0x43,0x32,0x2e,0x37,0x34,0x35,0x2c,0x31,0x33,0x2e, + 0x33,0x35,0x39,0x2c,0x31,0x2e,0x35,0x2c,0x31,0x33, + 0x2e,0x34,0x39,0x33,0x2c,0x31,0x2e,0x35,0x2c,0x31, + 0x34,0x2e,0x39,0x37,0x34,0x76,0x37,0x2e,0x31,0x31, + 0x0a,0x09,0x09,0x09,0x09,0x63,0x30,0x2e,0x30,0x30, + 0x36,0x2c,0x30,0x2e,0x33,0x37,0x36,0x2c,0x30,0x2e, + 0x31,0x33,0x39,0x2c,0x31,0x2e,0x36,0x32,0x31,0x2c, + 0x31,0x2e,0x36,0x32,0x31,0x2c,0x31,0x2e,0x36,0x32, + 0x31,0x68,0x31,0x30,0x2e,0x32,0x33,0x33,0x76,0x31, + 0x30,0x2e,0x32,0x33,0x32,0x63,0x30,0x2e,0x30,0x30, + 0x35,0x2c,0x30,0x2e,0x33,0x37,0x36,0x2c,0x30,0x2e, + 0x31,0x34,0x2c,0x31,0x2e,0x36,0x32,0x31,0x2c,0x31, + 0x2e,0x36,0x31,0x39,0x2c,0x31,0x2e,0x36,0x32,0x31, + 0x68,0x37,0x2e,0x31,0x30,0x38,0x0a,0x09,0x09,0x09, + 0x09,0x63,0x30,0x2e,0x33,0x38,0x34,0x2d,0x30,0x2e, + 0x30,0x30,0x37,0x2c,0x31,0x2e,0x36,0x32,0x34,0x2d, + 0x30,0x2e,0x31,0x34,0x33,0x2c,0x31,0x2e,0x36,0x32, + 0x34,0x2d,0x31,0x2e,0x36,0x32,0x31,0x56,0x32,0x33, + 0x2e,0x37,0x30,0x36,0x68,0x31,0x30,0x2e,0x32,0x33, + 0x31,0x63,0x30,0x2e,0x33,0x37,0x36,0x2d,0x30,0x2e, + 0x30,0x30,0x36,0x2c,0x31,0x2e,0x36,0x32,0x31,0x2d, 0x30,0x2e,0x31,0x34,0x2c,0x31,0x2e,0x36,0x32,0x31, - 0x2c,0x31,0x2e,0x36,0x31,0x39,0x2c,0x31,0x2e,0x36, - 0x32,0x31,0x68,0x37,0x2e,0x31,0x30,0x38,0x0d,0x0a, - 0x09,0x09,0x09,0x09,0x63,0x30,0x2e,0x33,0x38,0x34, - 0x2d,0x30,0x2e,0x30,0x30,0x37,0x2c,0x31,0x2e,0x36, - 0x32,0x34,0x2d,0x30,0x2e,0x31,0x34,0x33,0x2c,0x31, - 0x2e,0x36,0x32,0x34,0x2d,0x31,0x2e,0x36,0x32,0x31, - 0x56,0x32,0x33,0x2e,0x37,0x30,0x36,0x68,0x31,0x30, - 0x2e,0x32,0x33,0x31,0x63,0x30,0x2e,0x33,0x37,0x36, - 0x2d,0x30,0x2e,0x30,0x30,0x36,0x2c,0x31,0x2e,0x36, - 0x32,0x31,0x2d,0x30,0x2e,0x31,0x34,0x2c,0x31,0x2e, - 0x36,0x32,0x31,0x2d,0x31,0x2e,0x36,0x32,0x31,0x76, - 0x2d,0x37,0x2e,0x31,0x31,0x0d,0x0a,0x09,0x09,0x09, - 0x09,0x63,0x2d,0x30,0x2e,0x30,0x30,0x36,0x2d,0x30, - 0x2e,0x33,0x37,0x36,0x2d,0x30,0x2e,0x31,0x34,0x2d, - 0x31,0x2e,0x36,0x32,0x2d,0x31,0x2e,0x36,0x32,0x31, - 0x2d,0x31,0x2e,0x36,0x32,0x68,0x2d,0x31,0x30,0x2e, - 0x32,0x33,0x56,0x33,0x2e,0x31,0x32,0x31,0x43,0x32, - 0x33,0x2e,0x37,0x30,0x31,0x2c,0x32,0x2e,0x37,0x34, - 0x35,0x2c,0x32,0x33,0x2e,0x35,0x36,0x37,0x2c,0x31, - 0x2e,0x35,0x2c,0x32,0x32,0x2e,0x30,0x38,0x36,0x2c, - 0x31,0x2e,0x35,0x68,0x2d,0x37,0x2e,0x31,0x31,0x31, - 0x0d,0x0a,0x09,0x09,0x09,0x09,0x63,0x2d,0x30,0x2e, - 0x33,0x37,0x36,0x2c,0x30,0x2e,0x30,0x30,0x36,0x2d, - 0x31,0x2e,0x36,0x31,0x39,0x2c,0x30,0x2e,0x31,0x34, - 0x2d,0x31,0x2e,0x36,0x31,0x39,0x2c,0x31,0x2e,0x36, - 0x32,0x31,0x76,0x31,0x30,0x2e,0x32,0x33,0x32,0x4c, - 0x33,0x2e,0x31,0x32,0x31,0x2c,0x31,0x33,0x2e,0x33, - 0x35,0x34,0x4c,0x33,0x2e,0x31,0x32,0x31,0x2c,0x31, - 0x33,0x2e,0x33,0x35,0x34,0x7a,0x22,0x2f,0x3e,0x0d, - 0x0a,0x09,0x09,0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x09, - 0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x09,0x3c,0x67,0x3e, - 0x0d,0x0a,0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20, - 0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46, - 0x46,0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x31, - 0x38,0x2e,0x35,0x33,0x31,0x2c,0x32,0x32,0x2e,0x31, - 0x38,0x31,0x63,0x2d,0x32,0x2e,0x30,0x31,0x33,0x2c, - 0x30,0x2d,0x33,0x2e,0x36,0x34,0x39,0x2d,0x31,0x2e, - 0x36,0x33,0x39,0x2d,0x33,0x2e,0x36,0x34,0x39,0x2d, - 0x33,0x2e,0x36,0x35,0x31,0x73,0x31,0x2e,0x36,0x33, - 0x38,0x2d,0x33,0x2e,0x36,0x35,0x2c,0x33,0x2e,0x36, - 0x34,0x39,0x2d,0x33,0x2e,0x36,0x35,0x63,0x32,0x2e, - 0x30,0x31,0x33,0x2c,0x30,0x2c,0x33,0x2e,0x36,0x35, - 0x2c,0x31,0x2e,0x36,0x33,0x39,0x2c,0x33,0x2e,0x36, - 0x35,0x2c,0x33,0x2e,0x36,0x35,0x0d,0x0a,0x09,0x09, + 0x2d,0x31,0x2e,0x36,0x32,0x31,0x76,0x2d,0x37,0x2e, + 0x31,0x31,0x0a,0x09,0x09,0x09,0x09,0x63,0x2d,0x30, + 0x2e,0x30,0x30,0x36,0x2d,0x30,0x2e,0x33,0x37,0x36, + 0x2d,0x30,0x2e,0x31,0x34,0x2d,0x31,0x2e,0x36,0x32, + 0x2d,0x31,0x2e,0x36,0x32,0x31,0x2d,0x31,0x2e,0x36, + 0x32,0x68,0x2d,0x31,0x30,0x2e,0x32,0x33,0x56,0x33, + 0x2e,0x31,0x32,0x31,0x43,0x32,0x33,0x2e,0x37,0x30, + 0x31,0x2c,0x32,0x2e,0x37,0x34,0x35,0x2c,0x32,0x33, + 0x2e,0x35,0x36,0x37,0x2c,0x31,0x2e,0x35,0x2c,0x32, + 0x32,0x2e,0x30,0x38,0x36,0x2c,0x31,0x2e,0x35,0x68, + 0x2d,0x37,0x2e,0x31,0x31,0x31,0x0a,0x09,0x09,0x09, + 0x09,0x63,0x2d,0x30,0x2e,0x33,0x37,0x36,0x2c,0x30, + 0x2e,0x30,0x30,0x36,0x2d,0x31,0x2e,0x36,0x31,0x39, + 0x2c,0x30,0x2e,0x31,0x34,0x2d,0x31,0x2e,0x36,0x31, + 0x39,0x2c,0x31,0x2e,0x36,0x32,0x31,0x76,0x31,0x30, + 0x2e,0x32,0x33,0x32,0x4c,0x33,0x2e,0x31,0x32,0x31, + 0x2c,0x31,0x33,0x2e,0x33,0x35,0x34,0x4c,0x33,0x2e, + 0x31,0x32,0x31,0x2c,0x31,0x33,0x2e,0x33,0x35,0x34, + 0x7a,0x22,0x2f,0x3e,0x0a,0x09,0x09,0x3c,0x2f,0x67, + 0x3e,0x0a,0x09,0x3c,0x2f,0x67,0x3e,0x0a,0x09,0x3c, + 0x67,0x3e,0x0a,0x09,0x09,0x3c,0x70,0x61,0x74,0x68, + 0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46, + 0x46,0x46,0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d, + 0x31,0x38,0x2e,0x35,0x33,0x31,0x2c,0x32,0x32,0x2e, + 0x31,0x38,0x31,0x63,0x2d,0x32,0x2e,0x30,0x31,0x33, + 0x2c,0x30,0x2d,0x33,0x2e,0x36,0x34,0x39,0x2d,0x31, + 0x2e,0x36,0x33,0x39,0x2d,0x33,0x2e,0x36,0x34,0x39, + 0x2d,0x33,0x2e,0x36,0x35,0x31,0x73,0x31,0x2e,0x36, + 0x33,0x38,0x2d,0x33,0x2e,0x36,0x35,0x2c,0x33,0x2e, + 0x36,0x34,0x39,0x2d,0x33,0x2e,0x36,0x35,0x63,0x32, + 0x2e,0x30,0x31,0x33,0x2c,0x30,0x2c,0x33,0x2e,0x36, + 0x35,0x2c,0x31,0x2e,0x36,0x33,0x39,0x2c,0x33,0x2e, + 0x36,0x35,0x2c,0x33,0x2e,0x36,0x35,0x0a,0x09,0x09, 0x09,0x43,0x32,0x32,0x2e,0x31,0x38,0x32,0x2c,0x32, 0x30,0x2e,0x35,0x34,0x33,0x2c,0x32,0x30,0x2e,0x35, 0x34,0x34,0x2c,0x32,0x32,0x2e,0x31,0x38,0x31,0x2c, @@ -162,61 +160,60 @@ const unsigned char help_dpad_down_svg_data[3215] = { 0x2d,0x32,0x2e,0x31,0x34,0x39,0x2c,0x32,0x2e,0x31, 0x35,0x73,0x30,0x2e,0x39,0x36,0x35,0x2c,0x32,0x2e, 0x31,0x35,0x31,0x2c,0x32,0x2e,0x31,0x34,0x39,0x2c, - 0x32,0x2e,0x31,0x35,0x31,0x0d,0x0a,0x09,0x09,0x09, - 0x63,0x31,0x2e,0x31,0x38,0x36,0x2c,0x30,0x2c,0x32, - 0x2e,0x31,0x35,0x2d,0x30,0x2e,0x39,0x36,0x36,0x2c, - 0x32,0x2e,0x31,0x35,0x2d,0x32,0x2e,0x31,0x35,0x31, - 0x43,0x32,0x30,0x2e,0x36,0x38,0x32,0x2c,0x31,0x37, - 0x2e,0x33,0x34,0x34,0x2c,0x31,0x39,0x2e,0x37,0x31, - 0x37,0x2c,0x31,0x36,0x2e,0x33,0x37,0x39,0x2c,0x31, - 0x38,0x2e,0x35,0x33,0x31,0x2c,0x31,0x36,0x2e,0x33, - 0x37,0x39,0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x09,0x3c, - 0x2f,0x67,0x3e,0x0d,0x0a,0x09,0x3c,0x67,0x3e,0x0d, + 0x32,0x2e,0x31,0x35,0x31,0x0a,0x09,0x09,0x09,0x63, + 0x31,0x2e,0x31,0x38,0x36,0x2c,0x30,0x2c,0x32,0x2e, + 0x31,0x35,0x2d,0x30,0x2e,0x39,0x36,0x36,0x2c,0x32, + 0x2e,0x31,0x35,0x2d,0x32,0x2e,0x31,0x35,0x31,0x43, + 0x32,0x30,0x2e,0x36,0x38,0x32,0x2c,0x31,0x37,0x2e, + 0x33,0x34,0x34,0x2c,0x31,0x39,0x2e,0x37,0x31,0x37, + 0x2c,0x31,0x36,0x2e,0x33,0x37,0x39,0x2c,0x31,0x38, + 0x2e,0x35,0x33,0x31,0x2c,0x31,0x36,0x2e,0x33,0x37, + 0x39,0x7a,0x22,0x2f,0x3e,0x0a,0x09,0x3c,0x2f,0x67, + 0x3e,0x0a,0x09,0x3c,0x67,0x3e,0x0a,0x09,0x09,0x3c, + 0x70,0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d, + 0x22,0x23,0x46,0x46,0x46,0x46,0x46,0x46,0x22,0x20, + 0x64,0x3d,0x22,0x4d,0x32,0x31,0x2e,0x35,0x33,0x36, + 0x2c,0x38,0x2e,0x36,0x31,0x36,0x68,0x2d,0x36,0x2e, + 0x30,0x31,0x32,0x63,0x2d,0x30,0x2e,0x32,0x37,0x33, + 0x2c,0x30,0x2d,0x30,0x2e,0x35,0x32,0x35,0x2d,0x30, + 0x2e,0x31,0x35,0x2d,0x30,0x2e,0x36,0x35,0x37,0x2d, + 0x30,0x2e,0x33,0x39,0x63,0x2d,0x30,0x2e,0x31,0x33, + 0x32,0x2d,0x30,0x2e,0x32,0x34,0x31,0x2d,0x30,0x2e, + 0x31,0x32,0x31,0x2d,0x30,0x2e,0x35,0x33,0x34,0x2c, + 0x30,0x2e,0x30,0x32,0x36,0x2d,0x30,0x2e,0x37,0x36, + 0x36,0x6c,0x33,0x2e,0x30,0x30,0x35,0x2d,0x34,0x2e, + 0x36,0x38,0x34,0x0a,0x09,0x09,0x09,0x63,0x30,0x2e, + 0x32,0x37,0x36,0x2d,0x30,0x2e,0x34,0x33,0x31,0x2c, + 0x30,0x2e,0x39,0x38,0x36,0x2d,0x30,0x2e,0x34,0x33, + 0x2c,0x31,0x2e,0x32,0x36,0x34,0x2c,0x30,0x6c,0x33, + 0x2e,0x30,0x30,0x35,0x2c,0x34,0x2e,0x36,0x38,0x34, + 0x63,0x30,0x2e,0x31,0x34,0x37,0x2c,0x30,0x2e,0x32, + 0x33,0x31,0x2c,0x30,0x2e,0x31,0x35,0x39,0x2c,0x30, + 0x2e,0x35,0x32,0x34,0x2c,0x30,0x2e,0x30,0x32,0x36, + 0x2c,0x30,0x2e,0x37,0x36,0x36,0x43,0x32,0x32,0x2e, + 0x30,0x36,0x33,0x2c,0x38,0x2e,0x34,0x36,0x36,0x2c, + 0x32,0x31,0x2e,0x38,0x31,0x31,0x2c,0x38,0x2e,0x36, + 0x31,0x36,0x2c,0x32,0x31,0x2e,0x35,0x33,0x36,0x2c, + 0x38,0x2e,0x36,0x31,0x36,0x7a,0x0a,0x09,0x09,0x09, + 0x20,0x4d,0x31,0x36,0x2e,0x38,0x39,0x37,0x2c,0x37, + 0x2e,0x31,0x31,0x36,0x68,0x33,0x2e,0x32,0x36,0x38, + 0x4c,0x31,0x38,0x2e,0x35,0x33,0x2c,0x34,0x2e,0x35, + 0x37,0x31,0x4c,0x31,0x36,0x2e,0x38,0x39,0x37,0x2c, + 0x37,0x2e,0x31,0x31,0x36,0x7a,0x22,0x2f,0x3e,0x0a, + 0x09,0x3c,0x2f,0x67,0x3e,0x0a,0x09,0x3c,0x67,0x3e, 0x0a,0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66, 0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46, - 0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x32,0x31, - 0x2e,0x35,0x33,0x36,0x2c,0x38,0x2e,0x36,0x31,0x36, - 0x68,0x2d,0x36,0x2e,0x30,0x31,0x32,0x63,0x2d,0x30, - 0x2e,0x32,0x37,0x33,0x2c,0x30,0x2d,0x30,0x2e,0x35, - 0x32,0x35,0x2d,0x30,0x2e,0x31,0x35,0x2d,0x30,0x2e, - 0x36,0x35,0x37,0x2d,0x30,0x2e,0x33,0x39,0x63,0x2d, - 0x30,0x2e,0x31,0x33,0x32,0x2d,0x30,0x2e,0x32,0x34, - 0x31,0x2d,0x30,0x2e,0x31,0x32,0x31,0x2d,0x30,0x2e, - 0x35,0x33,0x34,0x2c,0x30,0x2e,0x30,0x32,0x36,0x2d, - 0x30,0x2e,0x37,0x36,0x36,0x6c,0x33,0x2e,0x30,0x30, - 0x35,0x2d,0x34,0x2e,0x36,0x38,0x34,0x0d,0x0a,0x09, - 0x09,0x09,0x63,0x30,0x2e,0x32,0x37,0x36,0x2d,0x30, - 0x2e,0x34,0x33,0x31,0x2c,0x30,0x2e,0x39,0x38,0x36, - 0x2d,0x30,0x2e,0x34,0x33,0x2c,0x31,0x2e,0x32,0x36, - 0x34,0x2c,0x30,0x6c,0x33,0x2e,0x30,0x30,0x35,0x2c, - 0x34,0x2e,0x36,0x38,0x34,0x63,0x30,0x2e,0x31,0x34, - 0x37,0x2c,0x30,0x2e,0x32,0x33,0x31,0x2c,0x30,0x2e, - 0x31,0x35,0x39,0x2c,0x30,0x2e,0x35,0x32,0x34,0x2c, - 0x30,0x2e,0x30,0x32,0x36,0x2c,0x30,0x2e,0x37,0x36, - 0x36,0x43,0x32,0x32,0x2e,0x30,0x36,0x33,0x2c,0x38, - 0x2e,0x34,0x36,0x36,0x2c,0x32,0x31,0x2e,0x38,0x31, - 0x31,0x2c,0x38,0x2e,0x36,0x31,0x36,0x2c,0x32,0x31, - 0x2e,0x35,0x33,0x36,0x2c,0x38,0x2e,0x36,0x31,0x36, - 0x7a,0x0d,0x0a,0x09,0x09,0x09,0x20,0x4d,0x31,0x36, - 0x2e,0x38,0x39,0x37,0x2c,0x37,0x2e,0x31,0x31,0x36, - 0x68,0x33,0x2e,0x32,0x36,0x38,0x4c,0x31,0x38,0x2e, - 0x35,0x33,0x2c,0x34,0x2e,0x35,0x37,0x31,0x4c,0x31, - 0x36,0x2e,0x38,0x39,0x37,0x2c,0x37,0x2e,0x31,0x31, - 0x36,0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x09,0x3c,0x2f, - 0x67,0x3e,0x0d,0x0a,0x09,0x3c,0x67,0x3e,0x0d,0x0a, - 0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69, - 0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46, - 0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x37,0x2e,0x38, - 0x30,0x39,0x2c,0x32,0x32,0x2e,0x32,0x38,0x34,0x63, - 0x2d,0x30,0x2e,0x31,0x34,0x31,0x2c,0x30,0x2d,0x30, - 0x2e,0x32,0x38,0x32,0x2d,0x30,0x2e,0x30,0x34,0x2d, - 0x30,0x2e,0x34,0x30,0x35,0x2d,0x30,0x2e,0x31,0x31, - 0x39,0x4c,0x32,0x2e,0x37,0x32,0x2c,0x31,0x39,0x2e, - 0x31,0x36,0x32,0x63,0x2d,0x30,0x2e,0x32,0x31,0x35, - 0x2d,0x30,0x2e,0x31,0x33,0x38,0x2d,0x30,0x2e,0x33, - 0x34,0x35,0x2d,0x30,0x2e,0x33,0x37,0x36,0x2d,0x30, - 0x2e,0x33,0x34,0x35,0x2d,0x30,0x2e,0x36,0x33,0x31, - 0x0d,0x0a,0x09,0x09,0x09,0x73,0x30,0x2e,0x31,0x33, + 0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x37,0x2e, + 0x38,0x30,0x39,0x2c,0x32,0x32,0x2e,0x32,0x38,0x34, + 0x63,0x2d,0x30,0x2e,0x31,0x34,0x31,0x2c,0x30,0x2d, + 0x30,0x2e,0x32,0x38,0x32,0x2d,0x30,0x2e,0x30,0x34, + 0x2d,0x30,0x2e,0x34,0x30,0x35,0x2d,0x30,0x2e,0x31, + 0x31,0x39,0x4c,0x32,0x2e,0x37,0x32,0x2c,0x31,0x39, + 0x2e,0x31,0x36,0x32,0x63,0x2d,0x30,0x2e,0x32,0x31, + 0x35,0x2d,0x30,0x2e,0x31,0x33,0x38,0x2d,0x30,0x2e, + 0x33,0x34,0x35,0x2d,0x30,0x2e,0x33,0x37,0x36,0x2d, + 0x30,0x2e,0x33,0x34,0x35,0x2d,0x30,0x2e,0x36,0x33, + 0x31,0x0a,0x09,0x09,0x09,0x73,0x30,0x2e,0x31,0x33, 0x2d,0x30,0x2e,0x34,0x39,0x33,0x2c,0x30,0x2e,0x33, 0x34,0x35,0x2d,0x30,0x2e,0x36,0x33,0x31,0x6c,0x34, 0x2e,0x36,0x38,0x34,0x2d,0x33,0x2e,0x30,0x30,0x36, @@ -227,103 +224,102 @@ const unsigned char help_dpad_down_svg_data[3215] = { 0x2c,0x30,0x2e,0x31,0x33,0x31,0x2c,0x30,0x2e,0x33, 0x39,0x2c,0x30,0x2e,0x33,0x38,0x34,0x2c,0x30,0x2e, 0x33,0x39,0x2c,0x30,0x2e,0x36,0x35,0x38,0x76,0x36, - 0x2e,0x30,0x31,0x0d,0x0a,0x09,0x09,0x09,0x63,0x30, - 0x2c,0x30,0x2e,0x32,0x37,0x34,0x2d,0x30,0x2e,0x31, - 0x34,0x38,0x2c,0x30,0x2e,0x35,0x32,0x36,0x2d,0x30, - 0x2e,0x33,0x39,0x2c,0x30,0x2e,0x36,0x35,0x38,0x43, - 0x38,0x2e,0x30,0x35,0x36,0x2c,0x32,0x32,0x2e,0x32, - 0x35,0x34,0x2c,0x37,0x2e,0x39,0x33,0x32,0x2c,0x32, - 0x32,0x2e,0x32,0x38,0x34,0x2c,0x37,0x2e,0x38,0x30, - 0x39,0x2c,0x32,0x32,0x2e,0x32,0x38,0x34,0x7a,0x20, - 0x4d,0x34,0x2e,0x35,0x31,0x34,0x2c,0x31,0x38,0x2e, - 0x35,0x33,0x6c,0x32,0x2e,0x35,0x34,0x35,0x2c,0x31, - 0x2e,0x36,0x33,0x32,0x76,0x2d,0x33,0x2e,0x32,0x36, - 0x35,0x4c,0x34,0x2e,0x35,0x31,0x34,0x2c,0x31,0x38, - 0x2e,0x35,0x33,0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x09, - 0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x09,0x3c,0x67,0x3e, - 0x0d,0x0a,0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20, - 0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46, - 0x46,0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x32, - 0x39,0x2e,0x31,0x39,0x35,0x2c,0x32,0x32,0x2e,0x32, - 0x38,0x34,0x63,0x2d,0x30,0x2e,0x31,0x32,0x34,0x2c, - 0x30,0x2d,0x30,0x2e,0x32,0x34,0x36,0x2d,0x30,0x2e, - 0x30,0x33,0x2d,0x30,0x2e,0x33,0x35,0x38,0x2d,0x30, - 0x2e,0x30,0x39,0x32,0x63,0x2d,0x30,0x2e,0x32,0x34, - 0x31,0x2d,0x30,0x2e,0x31,0x33,0x32,0x2d,0x30,0x2e, - 0x33,0x39,0x32,0x2d,0x30,0x2e,0x33,0x38,0x34,0x2d, - 0x30,0x2e,0x33,0x39,0x32,0x2d,0x30,0x2e,0x36,0x35, - 0x38,0x76,0x2d,0x36,0x2e,0x30,0x31,0x0d,0x0a,0x09, - 0x09,0x09,0x63,0x30,0x2d,0x30,0x2e,0x32,0x37,0x34, - 0x2c,0x30,0x2e,0x31,0x34,0x39,0x2d,0x30,0x2e,0x35, - 0x32,0x36,0x2c,0x30,0x2e,0x33,0x39,0x32,0x2d,0x30, - 0x2e,0x36,0x35,0x38,0x63,0x30,0x2e,0x32,0x33,0x39, - 0x2d,0x30,0x2e,0x31,0x33,0x31,0x2c,0x30,0x2e,0x35, - 0x33,0x33,0x2d,0x30,0x2e,0x31,0x32,0x33,0x2c,0x30, - 0x2e,0x37,0x36,0x35,0x2c,0x30,0x2e,0x30,0x32,0x37, - 0x6c,0x34,0x2e,0x36,0x38,0x35,0x2c,0x33,0x2e,0x30, - 0x30,0x35,0x63,0x30,0x2e,0x32,0x31,0x35,0x2c,0x30, - 0x2e,0x31,0x33,0x38,0x2c,0x30,0x2e,0x33,0x34,0x35, - 0x2c,0x30,0x2e,0x33,0x37,0x36,0x2c,0x30,0x2e,0x33, - 0x34,0x35,0x2c,0x30,0x2e,0x36,0x33,0x31,0x0d,0x0a, - 0x09,0x09,0x09,0x73,0x2d,0x30,0x2e,0x31,0x33,0x2c, - 0x30,0x2e,0x34,0x39,0x33,0x2d,0x30,0x2e,0x33,0x34, - 0x35,0x2c,0x30,0x2e,0x36,0x33,0x31,0x6c,0x2d,0x34, - 0x2e,0x36,0x38,0x35,0x2c,0x33,0x2e,0x30,0x30,0x34, - 0x43,0x32,0x39,0x2e,0x34,0x37,0x38,0x2c,0x32,0x32, - 0x2e,0x32,0x34,0x34,0x2c,0x32,0x39,0x2e,0x33,0x33, - 0x36,0x2c,0x32,0x32,0x2e,0x32,0x38,0x34,0x2c,0x32, - 0x39,0x2e,0x31,0x39,0x35,0x2c,0x32,0x32,0x2e,0x32, - 0x38,0x34,0x7a,0x20,0x4d,0x32,0x39,0x2e,0x39,0x34, - 0x35,0x2c,0x31,0x36,0x2e,0x38,0x39,0x36,0x76,0x33, - 0x2e,0x32,0x36,0x36,0x6c,0x32,0x2e,0x35,0x34,0x36, - 0x2d,0x31,0x2e,0x36,0x33,0x33,0x0d,0x0a,0x09,0x09, - 0x09,0x4c,0x32,0x39,0x2e,0x39,0x34,0x35,0x2c,0x31, - 0x36,0x2e,0x38,0x39,0x36,0x7a,0x22,0x2f,0x3e,0x0d, - 0x0a,0x09,0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x09,0x3c, - 0x67,0x3e,0x0d,0x0a,0x09,0x09,0x3c,0x70,0x61,0x74, + 0x2e,0x30,0x31,0x0a,0x09,0x09,0x09,0x63,0x30,0x2c, + 0x30,0x2e,0x32,0x37,0x34,0x2d,0x30,0x2e,0x31,0x34, + 0x38,0x2c,0x30,0x2e,0x35,0x32,0x36,0x2d,0x30,0x2e, + 0x33,0x39,0x2c,0x30,0x2e,0x36,0x35,0x38,0x43,0x38, + 0x2e,0x30,0x35,0x36,0x2c,0x32,0x32,0x2e,0x32,0x35, + 0x34,0x2c,0x37,0x2e,0x39,0x33,0x32,0x2c,0x32,0x32, + 0x2e,0x32,0x38,0x34,0x2c,0x37,0x2e,0x38,0x30,0x39, + 0x2c,0x32,0x32,0x2e,0x32,0x38,0x34,0x7a,0x20,0x4d, + 0x34,0x2e,0x35,0x31,0x34,0x2c,0x31,0x38,0x2e,0x35, + 0x33,0x6c,0x32,0x2e,0x35,0x34,0x35,0x2c,0x31,0x2e, + 0x36,0x33,0x32,0x76,0x2d,0x33,0x2e,0x32,0x36,0x35, + 0x4c,0x34,0x2e,0x35,0x31,0x34,0x2c,0x31,0x38,0x2e, + 0x35,0x33,0x7a,0x22,0x2f,0x3e,0x0a,0x09,0x3c,0x2f, + 0x67,0x3e,0x0a,0x09,0x3c,0x67,0x3e,0x0a,0x09,0x09, + 0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c, + 0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46,0x46,0x22, + 0x20,0x64,0x3d,0x22,0x4d,0x32,0x39,0x2e,0x31,0x39, + 0x35,0x2c,0x32,0x32,0x2e,0x32,0x38,0x34,0x63,0x2d, + 0x30,0x2e,0x31,0x32,0x34,0x2c,0x30,0x2d,0x30,0x2e, + 0x32,0x34,0x36,0x2d,0x30,0x2e,0x30,0x33,0x2d,0x30, + 0x2e,0x33,0x35,0x38,0x2d,0x30,0x2e,0x30,0x39,0x32, + 0x63,0x2d,0x30,0x2e,0x32,0x34,0x31,0x2d,0x30,0x2e, + 0x31,0x33,0x32,0x2d,0x30,0x2e,0x33,0x39,0x32,0x2d, + 0x30,0x2e,0x33,0x38,0x34,0x2d,0x30,0x2e,0x33,0x39, + 0x32,0x2d,0x30,0x2e,0x36,0x35,0x38,0x76,0x2d,0x36, + 0x2e,0x30,0x31,0x0a,0x09,0x09,0x09,0x63,0x30,0x2d, + 0x30,0x2e,0x32,0x37,0x34,0x2c,0x30,0x2e,0x31,0x34, + 0x39,0x2d,0x30,0x2e,0x35,0x32,0x36,0x2c,0x30,0x2e, + 0x33,0x39,0x32,0x2d,0x30,0x2e,0x36,0x35,0x38,0x63, + 0x30,0x2e,0x32,0x33,0x39,0x2d,0x30,0x2e,0x31,0x33, + 0x31,0x2c,0x30,0x2e,0x35,0x33,0x33,0x2d,0x30,0x2e, + 0x31,0x32,0x33,0x2c,0x30,0x2e,0x37,0x36,0x35,0x2c, + 0x30,0x2e,0x30,0x32,0x37,0x6c,0x34,0x2e,0x36,0x38, + 0x35,0x2c,0x33,0x2e,0x30,0x30,0x35,0x63,0x30,0x2e, + 0x32,0x31,0x35,0x2c,0x30,0x2e,0x31,0x33,0x38,0x2c, + 0x30,0x2e,0x33,0x34,0x35,0x2c,0x30,0x2e,0x33,0x37, + 0x36,0x2c,0x30,0x2e,0x33,0x34,0x35,0x2c,0x30,0x2e, + 0x36,0x33,0x31,0x0a,0x09,0x09,0x09,0x73,0x2d,0x30, + 0x2e,0x31,0x33,0x2c,0x30,0x2e,0x34,0x39,0x33,0x2d, + 0x30,0x2e,0x33,0x34,0x35,0x2c,0x30,0x2e,0x36,0x33, + 0x31,0x6c,0x2d,0x34,0x2e,0x36,0x38,0x35,0x2c,0x33, + 0x2e,0x30,0x30,0x34,0x43,0x32,0x39,0x2e,0x34,0x37, + 0x38,0x2c,0x32,0x32,0x2e,0x32,0x34,0x34,0x2c,0x32, + 0x39,0x2e,0x33,0x33,0x36,0x2c,0x32,0x32,0x2e,0x32, + 0x38,0x34,0x2c,0x32,0x39,0x2e,0x31,0x39,0x35,0x2c, + 0x32,0x32,0x2e,0x32,0x38,0x34,0x7a,0x20,0x4d,0x32, + 0x39,0x2e,0x39,0x34,0x35,0x2c,0x31,0x36,0x2e,0x38, + 0x39,0x36,0x76,0x33,0x2e,0x32,0x36,0x36,0x6c,0x32, + 0x2e,0x35,0x34,0x36,0x2d,0x31,0x2e,0x36,0x33,0x33, + 0x0a,0x09,0x09,0x09,0x4c,0x32,0x39,0x2e,0x39,0x34, + 0x35,0x2c,0x31,0x36,0x2e,0x38,0x39,0x36,0x7a,0x22, + 0x2f,0x3e,0x0a,0x09,0x3c,0x2f,0x67,0x3e,0x0a,0x09, + 0x3c,0x67,0x3e,0x0a,0x09,0x09,0x3c,0x70,0x61,0x74, 0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46, 0x46,0x46,0x46,0x46,0x46,0x22,0x20,0x64,0x3d,0x22, 0x4d,0x31,0x38,0x2e,0x35,0x33,0x2c,0x33,0x33,0x2e, 0x38,0x37,0x36,0x6c,0x33,0x2e,0x30,0x30,0x37,0x2d, 0x34,0x2e,0x36,0x38,0x34,0x68,0x2d,0x36,0x2e,0x30, 0x31,0x32,0x4c,0x31,0x38,0x2e,0x35,0x33,0x2c,0x33, - 0x33,0x2e,0x38,0x37,0x36,0x7a,0x22,0x2f,0x3e,0x0d, - 0x0a,0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66, - 0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46, - 0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x31,0x38, - 0x2e,0x35,0x33,0x2c,0x33,0x34,0x2e,0x36,0x32,0x36, - 0x4c,0x31,0x38,0x2e,0x35,0x33,0x2c,0x33,0x34,0x2e, - 0x36,0x32,0x36,0x63,0x2d,0x30,0x2e,0x32,0x35,0x35, - 0x2c,0x30,0x2d,0x30,0x2e,0x34,0x39,0x32,0x2d,0x30, - 0x2e,0x31,0x33,0x2d,0x30,0x2e,0x36,0x33,0x31,0x2d, - 0x30,0x2e,0x33,0x34,0x35,0x6c,0x2d,0x33,0x2e,0x30, - 0x30,0x35,0x2d,0x34,0x2e,0x36,0x38,0x34,0x0d,0x0a, - 0x09,0x09,0x09,0x63,0x2d,0x30,0x2e,0x31,0x34,0x37, - 0x2d,0x30,0x2e,0x32,0x33,0x31,0x2d,0x30,0x2e,0x31, - 0x35,0x38,0x2d,0x30,0x2e,0x35,0x32,0x34,0x2d,0x30, - 0x2e,0x30,0x32,0x36,0x2d,0x30,0x2e,0x37,0x36,0x36, - 0x73,0x30,0x2e,0x33,0x38,0x34,0x2d,0x30,0x2e,0x33, - 0x39,0x31,0x2c,0x30,0x2e,0x36,0x35,0x37,0x2d,0x30, - 0x2e,0x33,0x39,0x31,0x68,0x36,0x2e,0x30,0x31,0x32, - 0x63,0x30,0x2e,0x32,0x37,0x33,0x2c,0x30,0x2c,0x30, - 0x2e,0x35,0x32,0x35,0x2c,0x30,0x2e,0x31,0x34,0x38, - 0x2c,0x30,0x2e,0x36,0x35,0x37,0x2c,0x30,0x2e,0x33, - 0x39,0x31,0x0d,0x0a,0x09,0x09,0x09,0x63,0x30,0x2e, - 0x31,0x33,0x33,0x2c,0x30,0x2e,0x32,0x34,0x2c,0x30, - 0x2e,0x31,0x32,0x31,0x2c,0x30,0x2e,0x35,0x33,0x33, - 0x2d,0x30,0x2e,0x30,0x32,0x36,0x2c,0x30,0x2e,0x37, - 0x36,0x36,0x6c,0x2d,0x33,0x2e,0x30,0x30,0x35,0x2c, - 0x34,0x2e,0x36,0x38,0x34,0x43,0x31,0x39,0x2e,0x30, - 0x32,0x33,0x2c,0x33,0x34,0x2e,0x34,0x39,0x36,0x2c, - 0x31,0x38,0x2e,0x37,0x38,0x36,0x2c,0x33,0x34,0x2e, - 0x36,0x32,0x36,0x2c,0x31,0x38,0x2e,0x35,0x33,0x2c, - 0x33,0x34,0x2e,0x36,0x32,0x36,0x7a,0x20,0x4d,0x31, - 0x36,0x2e,0x38,0x39,0x37,0x2c,0x32,0x39,0x2e,0x39, - 0x34,0x32,0x6c,0x31,0x2e,0x36,0x33,0x33,0x2c,0x32, - 0x2e,0x35,0x34,0x35,0x0d,0x0a,0x09,0x09,0x09,0x6c, - 0x31,0x2e,0x36,0x33,0x35,0x2d,0x32,0x2e,0x35,0x34, - 0x35,0x48,0x31,0x36,0x2e,0x38,0x39,0x37,0x7a,0x22, - 0x2f,0x3e,0x0d,0x0a,0x09,0x3c,0x2f,0x67,0x3e,0x0d, - 0x0a,0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x3c,0x2f,0x73, - 0x76,0x67,0x3e,0x0d,0x0a + 0x33,0x2e,0x38,0x37,0x36,0x7a,0x22,0x2f,0x3e,0x0a, + 0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69, + 0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46, + 0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x31,0x38,0x2e, + 0x35,0x33,0x2c,0x33,0x34,0x2e,0x36,0x32,0x36,0x4c, + 0x31,0x38,0x2e,0x35,0x33,0x2c,0x33,0x34,0x2e,0x36, + 0x32,0x36,0x63,0x2d,0x30,0x2e,0x32,0x35,0x35,0x2c, + 0x30,0x2d,0x30,0x2e,0x34,0x39,0x32,0x2d,0x30,0x2e, + 0x31,0x33,0x2d,0x30,0x2e,0x36,0x33,0x31,0x2d,0x30, + 0x2e,0x33,0x34,0x35,0x6c,0x2d,0x33,0x2e,0x30,0x30, + 0x35,0x2d,0x34,0x2e,0x36,0x38,0x34,0x0a,0x09,0x09, + 0x09,0x63,0x2d,0x30,0x2e,0x31,0x34,0x37,0x2d,0x30, + 0x2e,0x32,0x33,0x31,0x2d,0x30,0x2e,0x31,0x35,0x38, + 0x2d,0x30,0x2e,0x35,0x32,0x34,0x2d,0x30,0x2e,0x30, + 0x32,0x36,0x2d,0x30,0x2e,0x37,0x36,0x36,0x73,0x30, + 0x2e,0x33,0x38,0x34,0x2d,0x30,0x2e,0x33,0x39,0x31, + 0x2c,0x30,0x2e,0x36,0x35,0x37,0x2d,0x30,0x2e,0x33, + 0x39,0x31,0x68,0x36,0x2e,0x30,0x31,0x32,0x63,0x30, + 0x2e,0x32,0x37,0x33,0x2c,0x30,0x2c,0x30,0x2e,0x35, + 0x32,0x35,0x2c,0x30,0x2e,0x31,0x34,0x38,0x2c,0x30, + 0x2e,0x36,0x35,0x37,0x2c,0x30,0x2e,0x33,0x39,0x31, + 0x0a,0x09,0x09,0x09,0x63,0x30,0x2e,0x31,0x33,0x33, + 0x2c,0x30,0x2e,0x32,0x34,0x2c,0x30,0x2e,0x31,0x32, + 0x31,0x2c,0x30,0x2e,0x35,0x33,0x33,0x2d,0x30,0x2e, + 0x30,0x32,0x36,0x2c,0x30,0x2e,0x37,0x36,0x36,0x6c, + 0x2d,0x33,0x2e,0x30,0x30,0x35,0x2c,0x34,0x2e,0x36, + 0x38,0x34,0x43,0x31,0x39,0x2e,0x30,0x32,0x33,0x2c, + 0x33,0x34,0x2e,0x34,0x39,0x36,0x2c,0x31,0x38,0x2e, + 0x37,0x38,0x36,0x2c,0x33,0x34,0x2e,0x36,0x32,0x36, + 0x2c,0x31,0x38,0x2e,0x35,0x33,0x2c,0x33,0x34,0x2e, + 0x36,0x32,0x36,0x7a,0x20,0x4d,0x31,0x36,0x2e,0x38, + 0x39,0x37,0x2c,0x32,0x39,0x2e,0x39,0x34,0x32,0x6c, + 0x31,0x2e,0x36,0x33,0x33,0x2c,0x32,0x2e,0x35,0x34, + 0x35,0x0a,0x09,0x09,0x09,0x6c,0x31,0x2e,0x36,0x33, + 0x35,0x2d,0x32,0x2e,0x35,0x34,0x35,0x48,0x31,0x36, + 0x2e,0x38,0x39,0x37,0x7a,0x22,0x2f,0x3e,0x0a,0x09, + 0x3c,0x2f,0x67,0x3e,0x0a,0x3c,0x2f,0x67,0x3e,0x0a, + 0x3c,0x2f,0x73,0x76,0x67,0x3e,0x0a }; + diff --git a/data/converted/help_dpad_left_svg.cpp b/data/converted/help_dpad_left_svg.cpp index 3e3cca8ac1..dbf730d608 100644 --- a/data/converted/help_dpad_left_svg.cpp +++ b/data/converted/help_dpad_left_svg.cpp @@ -2,84 +2,83 @@ #include "../Resources.h" -const size_t help_dpad_left_svg_size = 3212; -const unsigned char help_dpad_left_svg_data[3212] = { +const size_t help_dpad_left_svg_size = 3164; +const unsigned char help_dpad_left_svg_data[3164] = { 0x3c,0x3f,0x78,0x6d,0x6c,0x20,0x76,0x65,0x72,0x73, 0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x30,0x22,0x20, 0x65,0x6e,0x63,0x6f,0x64,0x69,0x6e,0x67,0x3d,0x22, - 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0d,0x0a, - 0x3c,0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72, - 0x61,0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62, - 0x65,0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61, - 0x74,0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33, - 0x2c,0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f, - 0x72,0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e, - 0x20,0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72, - 0x73,0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30, - 0x20,0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20, - 0x20,0x2d,0x2d,0x3e,0x0d,0x0a,0x3c,0x21,0x44,0x4f, - 0x43,0x54,0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20, - 0x50,0x55,0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f, - 0x2f,0x57,0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20, - 0x53,0x56,0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45, - 0x4e,0x22,0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, - 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, - 0x67,0x2f,0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73, - 0x2f,0x53,0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44, - 0x54,0x44,0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64, - 0x74,0x64,0x22,0x3e,0x0d,0x0a,0x3c,0x73,0x76,0x67, - 0x20,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22, - 0x31,0x2e,0x31,0x22,0x20,0x69,0x64,0x3d,0x22,0x5f, - 0x78,0x33,0x30,0x5f,0x22,0x20,0x78,0x6d,0x6c,0x6e, - 0x73,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f, - 0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67, - 0x2f,0x32,0x30,0x30,0x30,0x2f,0x73,0x76,0x67,0x22, - 0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78,0x6c,0x69, - 0x6e,0x6b,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, - 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, - 0x67,0x2f,0x31,0x39,0x39,0x39,0x2f,0x78,0x6c,0x69, - 0x6e,0x6b,0x22,0x20,0x78,0x3d,0x22,0x30,0x70,0x78, - 0x22,0x20,0x79,0x3d,0x22,0x30,0x70,0x78,0x22,0x0d, - 0x0a,0x09,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22, - 0x33,0x37,0x2e,0x30,0x36,0x31,0x70,0x78,0x22,0x20, - 0x68,0x65,0x69,0x67,0x68,0x74,0x3d,0x22,0x33,0x37, - 0x2e,0x30,0x36,0x31,0x70,0x78,0x22,0x20,0x76,0x69, - 0x65,0x77,0x42,0x6f,0x78,0x3d,0x22,0x30,0x20,0x30, - 0x20,0x33,0x37,0x2e,0x30,0x36,0x31,0x20,0x33,0x37, - 0x2e,0x30,0x36,0x31,0x22,0x20,0x65,0x6e,0x61,0x62, - 0x6c,0x65,0x2d,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f, - 0x75,0x6e,0x64,0x3d,0x22,0x6e,0x65,0x77,0x20,0x30, - 0x20,0x30,0x20,0x33,0x37,0x2e,0x30,0x36,0x31,0x20, - 0x33,0x37,0x2e,0x30,0x36,0x31,0x22,0x20,0x78,0x6d, - 0x6c,0x3a,0x73,0x70,0x61,0x63,0x65,0x3d,0x22,0x70, - 0x72,0x65,0x73,0x65,0x72,0x76,0x65,0x22,0x3e,0x0d, - 0x0a,0x3c,0x67,0x3e,0x0d,0x0a,0x09,0x3c,0x67,0x3e, - 0x0d,0x0a,0x09,0x09,0x3c,0x67,0x3e,0x0d,0x0a,0x09, - 0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69, - 0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46, - 0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x32,0x32,0x2e, - 0x30,0x38,0x36,0x2c,0x33,0x37,0x2e,0x30,0x36,0x68, - 0x2d,0x37,0x2e,0x31,0x31,0x31,0x63,0x2d,0x32,0x2e, - 0x32,0x38,0x39,0x2c,0x30,0x2d,0x33,0x2e,0x31,0x31, - 0x39,0x2d,0x31,0x2e,0x38,0x36,0x36,0x2d,0x33,0x2e, - 0x31,0x31,0x39,0x2d,0x33,0x2e,0x31,0x32,0x31,0x76, - 0x2d,0x38,0x2e,0x37,0x33,0x32,0x48,0x33,0x2e,0x31, - 0x32,0x31,0x43,0x30,0x2e,0x38,0x33,0x31,0x2c,0x32, - 0x35,0x2e,0x32,0x30,0x36,0x2c,0x30,0x2c,0x32,0x33, - 0x2e,0x33,0x34,0x2c,0x30,0x2c,0x32,0x32,0x2e,0x30, - 0x38,0x35,0x0d,0x0a,0x09,0x09,0x09,0x09,0x76,0x2d, - 0x37,0x2e,0x31,0x31,0x63,0x30,0x2d,0x32,0x2e,0x32, - 0x38,0x39,0x2c,0x31,0x2e,0x38,0x36,0x37,0x2d,0x33, - 0x2e,0x31,0x32,0x2c,0x33,0x2e,0x31,0x32,0x31,0x2d, - 0x33,0x2e,0x31,0x32,0x68,0x38,0x2e,0x37,0x33,0x33, - 0x56,0x33,0x2e,0x31,0x32,0x31,0x43,0x31,0x31,0x2e, - 0x38,0x35,0x35,0x2c,0x30,0x2e,0x38,0x33,0x31,0x2c, - 0x31,0x33,0x2e,0x37,0x32,0x2c,0x30,0x2c,0x31,0x34, - 0x2e,0x39,0x37,0x34,0x2c,0x30,0x68,0x37,0x2e,0x31, - 0x31,0x31,0x63,0x32,0x2e,0x32,0x39,0x2c,0x30,0x2c, - 0x33,0x2e,0x31,0x32,0x31,0x2c,0x31,0x2e,0x38,0x36, - 0x37,0x2c,0x33,0x2e,0x31,0x32,0x31,0x2c,0x33,0x2e, - 0x31,0x32,0x31,0x76,0x38,0x2e,0x37,0x33,0x32,0x0d, + 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0a,0x3c, + 0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72,0x61, + 0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62,0x65, + 0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61,0x74, + 0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33,0x2c, + 0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f,0x72, + 0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e,0x20, + 0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72,0x73, + 0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30,0x20, + 0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20,0x20, + 0x2d,0x2d,0x3e,0x0a,0x3c,0x21,0x44,0x4f,0x43,0x54, + 0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20,0x50,0x55, + 0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f,0x2f,0x57, + 0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20,0x53,0x56, + 0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45,0x4e,0x22, + 0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73,0x2f,0x53, + 0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44,0x54,0x44, + 0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64,0x74,0x64, + 0x22,0x3e,0x0a,0x3c,0x73,0x76,0x67,0x20,0x76,0x65, + 0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x31, + 0x22,0x20,0x69,0x64,0x3d,0x22,0x5f,0x78,0x33,0x30, + 0x5f,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3d,0x22, + 0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77, + 0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f,0x32,0x30, + 0x30,0x30,0x2f,0x73,0x76,0x67,0x22,0x20,0x78,0x6d, + 0x6c,0x6e,0x73,0x3a,0x78,0x6c,0x69,0x6e,0x6b,0x3d, + 0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77, + 0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f,0x31, + 0x39,0x39,0x39,0x2f,0x78,0x6c,0x69,0x6e,0x6b,0x22, + 0x20,0x78,0x3d,0x22,0x30,0x70,0x78,0x22,0x20,0x79, + 0x3d,0x22,0x30,0x70,0x78,0x22,0x0a,0x09,0x20,0x77, + 0x69,0x64,0x74,0x68,0x3d,0x22,0x33,0x37,0x2e,0x30, + 0x36,0x31,0x70,0x78,0x22,0x20,0x68,0x65,0x69,0x67, + 0x68,0x74,0x3d,0x22,0x33,0x37,0x2e,0x30,0x36,0x31, + 0x70,0x78,0x22,0x20,0x76,0x69,0x65,0x77,0x42,0x6f, + 0x78,0x3d,0x22,0x30,0x20,0x30,0x20,0x33,0x37,0x2e, + 0x30,0x36,0x31,0x20,0x33,0x37,0x2e,0x30,0x36,0x31, + 0x22,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0x2d,0x62, + 0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x3d, + 0x22,0x6e,0x65,0x77,0x20,0x30,0x20,0x30,0x20,0x33, + 0x37,0x2e,0x30,0x36,0x31,0x20,0x33,0x37,0x2e,0x30, + 0x36,0x31,0x22,0x20,0x78,0x6d,0x6c,0x3a,0x73,0x70, + 0x61,0x63,0x65,0x3d,0x22,0x70,0x72,0x65,0x73,0x65, + 0x72,0x76,0x65,0x22,0x3e,0x0a,0x3c,0x67,0x3e,0x0a, + 0x09,0x3c,0x67,0x3e,0x0a,0x09,0x09,0x3c,0x67,0x3e, + 0x0a,0x09,0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20, + 0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46, + 0x46,0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x32, + 0x32,0x2e,0x30,0x38,0x36,0x2c,0x33,0x37,0x2e,0x30, + 0x36,0x68,0x2d,0x37,0x2e,0x31,0x31,0x31,0x63,0x2d, + 0x32,0x2e,0x32,0x38,0x39,0x2c,0x30,0x2d,0x33,0x2e, + 0x31,0x31,0x39,0x2d,0x31,0x2e,0x38,0x36,0x36,0x2d, + 0x33,0x2e,0x31,0x31,0x39,0x2d,0x33,0x2e,0x31,0x32, + 0x31,0x76,0x2d,0x38,0x2e,0x37,0x33,0x32,0x48,0x33, + 0x2e,0x31,0x32,0x31,0x43,0x30,0x2e,0x38,0x33,0x31, + 0x2c,0x32,0x35,0x2e,0x32,0x30,0x36,0x2c,0x30,0x2c, + 0x32,0x33,0x2e,0x33,0x34,0x2c,0x30,0x2c,0x32,0x32, + 0x2e,0x30,0x38,0x35,0x0a,0x09,0x09,0x09,0x09,0x76, + 0x2d,0x37,0x2e,0x31,0x31,0x63,0x30,0x2d,0x32,0x2e, + 0x32,0x38,0x39,0x2c,0x31,0x2e,0x38,0x36,0x37,0x2d, + 0x33,0x2e,0x31,0x32,0x2c,0x33,0x2e,0x31,0x32,0x31, + 0x2d,0x33,0x2e,0x31,0x32,0x68,0x38,0x2e,0x37,0x33, + 0x33,0x56,0x33,0x2e,0x31,0x32,0x31,0x43,0x31,0x31, + 0x2e,0x38,0x35,0x35,0x2c,0x30,0x2e,0x38,0x33,0x31, + 0x2c,0x31,0x33,0x2e,0x37,0x32,0x2c,0x30,0x2c,0x31, + 0x34,0x2e,0x39,0x37,0x34,0x2c,0x30,0x68,0x37,0x2e, + 0x31,0x31,0x31,0x63,0x32,0x2e,0x32,0x39,0x2c,0x30, + 0x2c,0x33,0x2e,0x31,0x32,0x31,0x2c,0x31,0x2e,0x38, + 0x36,0x37,0x2c,0x33,0x2e,0x31,0x32,0x31,0x2c,0x33, + 0x2e,0x31,0x32,0x31,0x76,0x38,0x2e,0x37,0x33,0x32, 0x0a,0x09,0x09,0x09,0x09,0x68,0x38,0x2e,0x37,0x33, 0x31,0x63,0x32,0x2e,0x32,0x39,0x2c,0x30,0x2c,0x33, 0x2e,0x31,0x32,0x31,0x2c,0x31,0x2e,0x38,0x36,0x35, @@ -89,68 +88,67 @@ const unsigned char help_dpad_left_svg_data[3212] = { 0x33,0x2e,0x31,0x32,0x31,0x2d,0x33,0x2e,0x31,0x32, 0x31,0x2c,0x33,0x2e,0x31,0x32,0x31,0x68,0x2d,0x38, 0x2e,0x37,0x33,0x31,0x76,0x38,0x2e,0x37,0x33,0x32, - 0x0d,0x0a,0x09,0x09,0x09,0x09,0x43,0x32,0x35,0x2e, - 0x32,0x30,0x37,0x2c,0x33,0x36,0x2e,0x32,0x32,0x39, - 0x2c,0x32,0x33,0x2e,0x33,0x34,0x31,0x2c,0x33,0x37, - 0x2e,0x30,0x36,0x2c,0x32,0x32,0x2e,0x30,0x38,0x36, - 0x2c,0x33,0x37,0x2e,0x30,0x36,0x7a,0x20,0x4d,0x33, - 0x2e,0x31,0x32,0x31,0x2c,0x31,0x33,0x2e,0x33,0x35, - 0x34,0x43,0x32,0x2e,0x37,0x34,0x35,0x2c,0x31,0x33, - 0x2e,0x33,0x35,0x39,0x2c,0x31,0x2e,0x35,0x2c,0x31, - 0x33,0x2e,0x34,0x39,0x33,0x2c,0x31,0x2e,0x35,0x2c, - 0x31,0x34,0x2e,0x39,0x37,0x34,0x76,0x37,0x2e,0x31, - 0x31,0x0d,0x0a,0x09,0x09,0x09,0x09,0x63,0x30,0x2e, - 0x30,0x30,0x36,0x2c,0x30,0x2e,0x33,0x37,0x36,0x2c, - 0x30,0x2e,0x31,0x33,0x39,0x2c,0x31,0x2e,0x36,0x32, - 0x31,0x2c,0x31,0x2e,0x36,0x32,0x31,0x2c,0x31,0x2e, - 0x36,0x32,0x31,0x68,0x31,0x30,0x2e,0x32,0x33,0x33, - 0x76,0x31,0x30,0x2e,0x32,0x33,0x32,0x63,0x30,0x2e, - 0x30,0x30,0x35,0x2c,0x30,0x2e,0x33,0x37,0x36,0x2c, + 0x0a,0x09,0x09,0x09,0x09,0x43,0x32,0x35,0x2e,0x32, + 0x30,0x37,0x2c,0x33,0x36,0x2e,0x32,0x32,0x39,0x2c, + 0x32,0x33,0x2e,0x33,0x34,0x31,0x2c,0x33,0x37,0x2e, + 0x30,0x36,0x2c,0x32,0x32,0x2e,0x30,0x38,0x36,0x2c, + 0x33,0x37,0x2e,0x30,0x36,0x7a,0x20,0x4d,0x33,0x2e, + 0x31,0x32,0x31,0x2c,0x31,0x33,0x2e,0x33,0x35,0x34, + 0x43,0x32,0x2e,0x37,0x34,0x35,0x2c,0x31,0x33,0x2e, + 0x33,0x35,0x39,0x2c,0x31,0x2e,0x35,0x2c,0x31,0x33, + 0x2e,0x34,0x39,0x33,0x2c,0x31,0x2e,0x35,0x2c,0x31, + 0x34,0x2e,0x39,0x37,0x34,0x76,0x37,0x2e,0x31,0x31, + 0x0a,0x09,0x09,0x09,0x09,0x63,0x30,0x2e,0x30,0x30, + 0x36,0x2c,0x30,0x2e,0x33,0x37,0x36,0x2c,0x30,0x2e, + 0x31,0x33,0x39,0x2c,0x31,0x2e,0x36,0x32,0x31,0x2c, + 0x31,0x2e,0x36,0x32,0x31,0x2c,0x31,0x2e,0x36,0x32, + 0x31,0x68,0x31,0x30,0x2e,0x32,0x33,0x33,0x76,0x31, + 0x30,0x2e,0x32,0x33,0x32,0x63,0x30,0x2e,0x30,0x30, + 0x35,0x2c,0x30,0x2e,0x33,0x37,0x36,0x2c,0x30,0x2e, + 0x31,0x34,0x2c,0x31,0x2e,0x36,0x32,0x31,0x2c,0x31, + 0x2e,0x36,0x31,0x39,0x2c,0x31,0x2e,0x36,0x32,0x31, + 0x68,0x37,0x2e,0x31,0x30,0x38,0x0a,0x09,0x09,0x09, + 0x09,0x63,0x30,0x2e,0x33,0x38,0x34,0x2d,0x30,0x2e, + 0x30,0x30,0x37,0x2c,0x31,0x2e,0x36,0x32,0x34,0x2d, + 0x30,0x2e,0x31,0x34,0x33,0x2c,0x31,0x2e,0x36,0x32, + 0x34,0x2d,0x31,0x2e,0x36,0x32,0x31,0x56,0x32,0x33, + 0x2e,0x37,0x30,0x36,0x68,0x31,0x30,0x2e,0x32,0x33, + 0x31,0x63,0x30,0x2e,0x33,0x37,0x36,0x2d,0x30,0x2e, + 0x30,0x30,0x36,0x2c,0x31,0x2e,0x36,0x32,0x31,0x2d, 0x30,0x2e,0x31,0x34,0x2c,0x31,0x2e,0x36,0x32,0x31, - 0x2c,0x31,0x2e,0x36,0x31,0x39,0x2c,0x31,0x2e,0x36, - 0x32,0x31,0x68,0x37,0x2e,0x31,0x30,0x38,0x0d,0x0a, - 0x09,0x09,0x09,0x09,0x63,0x30,0x2e,0x33,0x38,0x34, - 0x2d,0x30,0x2e,0x30,0x30,0x37,0x2c,0x31,0x2e,0x36, - 0x32,0x34,0x2d,0x30,0x2e,0x31,0x34,0x33,0x2c,0x31, - 0x2e,0x36,0x32,0x34,0x2d,0x31,0x2e,0x36,0x32,0x31, - 0x56,0x32,0x33,0x2e,0x37,0x30,0x36,0x68,0x31,0x30, - 0x2e,0x32,0x33,0x31,0x63,0x30,0x2e,0x33,0x37,0x36, - 0x2d,0x30,0x2e,0x30,0x30,0x36,0x2c,0x31,0x2e,0x36, - 0x32,0x31,0x2d,0x30,0x2e,0x31,0x34,0x2c,0x31,0x2e, - 0x36,0x32,0x31,0x2d,0x31,0x2e,0x36,0x32,0x31,0x76, - 0x2d,0x37,0x2e,0x31,0x31,0x0d,0x0a,0x09,0x09,0x09, - 0x09,0x63,0x2d,0x30,0x2e,0x30,0x30,0x36,0x2d,0x30, - 0x2e,0x33,0x37,0x36,0x2d,0x30,0x2e,0x31,0x34,0x2d, - 0x31,0x2e,0x36,0x32,0x2d,0x31,0x2e,0x36,0x32,0x31, - 0x2d,0x31,0x2e,0x36,0x32,0x68,0x2d,0x31,0x30,0x2e, - 0x32,0x33,0x56,0x33,0x2e,0x31,0x32,0x31,0x43,0x32, - 0x33,0x2e,0x37,0x30,0x31,0x2c,0x32,0x2e,0x37,0x34, - 0x35,0x2c,0x32,0x33,0x2e,0x35,0x36,0x37,0x2c,0x31, - 0x2e,0x35,0x2c,0x32,0x32,0x2e,0x30,0x38,0x36,0x2c, - 0x31,0x2e,0x35,0x68,0x2d,0x37,0x2e,0x31,0x31,0x31, - 0x0d,0x0a,0x09,0x09,0x09,0x09,0x63,0x2d,0x30,0x2e, - 0x33,0x37,0x36,0x2c,0x30,0x2e,0x30,0x30,0x36,0x2d, - 0x31,0x2e,0x36,0x31,0x39,0x2c,0x30,0x2e,0x31,0x34, - 0x2d,0x31,0x2e,0x36,0x31,0x39,0x2c,0x31,0x2e,0x36, - 0x32,0x31,0x76,0x31,0x30,0x2e,0x32,0x33,0x32,0x4c, - 0x33,0x2e,0x31,0x32,0x31,0x2c,0x31,0x33,0x2e,0x33, - 0x35,0x34,0x4c,0x33,0x2e,0x31,0x32,0x31,0x2c,0x31, - 0x33,0x2e,0x33,0x35,0x34,0x7a,0x22,0x2f,0x3e,0x0d, - 0x0a,0x09,0x09,0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x09, - 0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x09,0x3c,0x67,0x3e, - 0x0d,0x0a,0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20, - 0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46, - 0x46,0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x31, - 0x38,0x2e,0x35,0x33,0x31,0x2c,0x32,0x32,0x2e,0x31, - 0x38,0x31,0x63,0x2d,0x32,0x2e,0x30,0x31,0x33,0x2c, - 0x30,0x2d,0x33,0x2e,0x36,0x34,0x39,0x2d,0x31,0x2e, - 0x36,0x33,0x39,0x2d,0x33,0x2e,0x36,0x34,0x39,0x2d, - 0x33,0x2e,0x36,0x35,0x31,0x73,0x31,0x2e,0x36,0x33, - 0x38,0x2d,0x33,0x2e,0x36,0x35,0x2c,0x33,0x2e,0x36, - 0x34,0x39,0x2d,0x33,0x2e,0x36,0x35,0x63,0x32,0x2e, - 0x30,0x31,0x33,0x2c,0x30,0x2c,0x33,0x2e,0x36,0x35, - 0x2c,0x31,0x2e,0x36,0x33,0x39,0x2c,0x33,0x2e,0x36, - 0x35,0x2c,0x33,0x2e,0x36,0x35,0x0d,0x0a,0x09,0x09, + 0x2d,0x31,0x2e,0x36,0x32,0x31,0x76,0x2d,0x37,0x2e, + 0x31,0x31,0x0a,0x09,0x09,0x09,0x09,0x63,0x2d,0x30, + 0x2e,0x30,0x30,0x36,0x2d,0x30,0x2e,0x33,0x37,0x36, + 0x2d,0x30,0x2e,0x31,0x34,0x2d,0x31,0x2e,0x36,0x32, + 0x2d,0x31,0x2e,0x36,0x32,0x31,0x2d,0x31,0x2e,0x36, + 0x32,0x68,0x2d,0x31,0x30,0x2e,0x32,0x33,0x56,0x33, + 0x2e,0x31,0x32,0x31,0x43,0x32,0x33,0x2e,0x37,0x30, + 0x31,0x2c,0x32,0x2e,0x37,0x34,0x35,0x2c,0x32,0x33, + 0x2e,0x35,0x36,0x37,0x2c,0x31,0x2e,0x35,0x2c,0x32, + 0x32,0x2e,0x30,0x38,0x36,0x2c,0x31,0x2e,0x35,0x68, + 0x2d,0x37,0x2e,0x31,0x31,0x31,0x0a,0x09,0x09,0x09, + 0x09,0x63,0x2d,0x30,0x2e,0x33,0x37,0x36,0x2c,0x30, + 0x2e,0x30,0x30,0x36,0x2d,0x31,0x2e,0x36,0x31,0x39, + 0x2c,0x30,0x2e,0x31,0x34,0x2d,0x31,0x2e,0x36,0x31, + 0x39,0x2c,0x31,0x2e,0x36,0x32,0x31,0x76,0x31,0x30, + 0x2e,0x32,0x33,0x32,0x4c,0x33,0x2e,0x31,0x32,0x31, + 0x2c,0x31,0x33,0x2e,0x33,0x35,0x34,0x4c,0x33,0x2e, + 0x31,0x32,0x31,0x2c,0x31,0x33,0x2e,0x33,0x35,0x34, + 0x7a,0x22,0x2f,0x3e,0x0a,0x09,0x09,0x3c,0x2f,0x67, + 0x3e,0x0a,0x09,0x3c,0x2f,0x67,0x3e,0x0a,0x09,0x3c, + 0x67,0x3e,0x0a,0x09,0x09,0x3c,0x70,0x61,0x74,0x68, + 0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46, + 0x46,0x46,0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d, + 0x31,0x38,0x2e,0x35,0x33,0x31,0x2c,0x32,0x32,0x2e, + 0x31,0x38,0x31,0x63,0x2d,0x32,0x2e,0x30,0x31,0x33, + 0x2c,0x30,0x2d,0x33,0x2e,0x36,0x34,0x39,0x2d,0x31, + 0x2e,0x36,0x33,0x39,0x2d,0x33,0x2e,0x36,0x34,0x39, + 0x2d,0x33,0x2e,0x36,0x35,0x31,0x73,0x31,0x2e,0x36, + 0x33,0x38,0x2d,0x33,0x2e,0x36,0x35,0x2c,0x33,0x2e, + 0x36,0x34,0x39,0x2d,0x33,0x2e,0x36,0x35,0x63,0x32, + 0x2e,0x30,0x31,0x33,0x2c,0x30,0x2c,0x33,0x2e,0x36, + 0x35,0x2c,0x31,0x2e,0x36,0x33,0x39,0x2c,0x33,0x2e, + 0x36,0x35,0x2c,0x33,0x2e,0x36,0x35,0x0a,0x09,0x09, 0x09,0x43,0x32,0x32,0x2e,0x31,0x38,0x32,0x2c,0x32, 0x30,0x2e,0x35,0x34,0x33,0x2c,0x32,0x30,0x2e,0x35, 0x34,0x34,0x2c,0x32,0x32,0x2e,0x31,0x38,0x31,0x2c, @@ -162,56 +160,55 @@ const unsigned char help_dpad_left_svg_data[3212] = { 0x2d,0x32,0x2e,0x31,0x34,0x39,0x2c,0x32,0x2e,0x31, 0x35,0x73,0x30,0x2e,0x39,0x36,0x35,0x2c,0x32,0x2e, 0x31,0x35,0x31,0x2c,0x32,0x2e,0x31,0x34,0x39,0x2c, - 0x32,0x2e,0x31,0x35,0x31,0x0d,0x0a,0x09,0x09,0x09, - 0x63,0x31,0x2e,0x31,0x38,0x36,0x2c,0x30,0x2c,0x32, - 0x2e,0x31,0x35,0x2d,0x30,0x2e,0x39,0x36,0x36,0x2c, - 0x32,0x2e,0x31,0x35,0x2d,0x32,0x2e,0x31,0x35,0x31, - 0x43,0x32,0x30,0x2e,0x36,0x38,0x32,0x2c,0x31,0x37, - 0x2e,0x33,0x34,0x34,0x2c,0x31,0x39,0x2e,0x37,0x31, - 0x37,0x2c,0x31,0x36,0x2e,0x33,0x37,0x39,0x2c,0x31, - 0x38,0x2e,0x35,0x33,0x31,0x2c,0x31,0x36,0x2e,0x33, - 0x37,0x39,0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x09,0x3c, - 0x2f,0x67,0x3e,0x0d,0x0a,0x09,0x3c,0x67,0x3e,0x0d, + 0x32,0x2e,0x31,0x35,0x31,0x0a,0x09,0x09,0x09,0x63, + 0x31,0x2e,0x31,0x38,0x36,0x2c,0x30,0x2c,0x32,0x2e, + 0x31,0x35,0x2d,0x30,0x2e,0x39,0x36,0x36,0x2c,0x32, + 0x2e,0x31,0x35,0x2d,0x32,0x2e,0x31,0x35,0x31,0x43, + 0x32,0x30,0x2e,0x36,0x38,0x32,0x2c,0x31,0x37,0x2e, + 0x33,0x34,0x34,0x2c,0x31,0x39,0x2e,0x37,0x31,0x37, + 0x2c,0x31,0x36,0x2e,0x33,0x37,0x39,0x2c,0x31,0x38, + 0x2e,0x35,0x33,0x31,0x2c,0x31,0x36,0x2e,0x33,0x37, + 0x39,0x7a,0x22,0x2f,0x3e,0x0a,0x09,0x3c,0x2f,0x67, + 0x3e,0x0a,0x09,0x3c,0x67,0x3e,0x0a,0x09,0x09,0x3c, + 0x70,0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d, + 0x22,0x23,0x46,0x46,0x46,0x46,0x46,0x46,0x22,0x20, + 0x64,0x3d,0x22,0x4d,0x32,0x31,0x2e,0x35,0x33,0x36, + 0x2c,0x38,0x2e,0x36,0x31,0x36,0x68,0x2d,0x36,0x2e, + 0x30,0x31,0x32,0x63,0x2d,0x30,0x2e,0x32,0x37,0x33, + 0x2c,0x30,0x2d,0x30,0x2e,0x35,0x32,0x35,0x2d,0x30, + 0x2e,0x31,0x35,0x2d,0x30,0x2e,0x36,0x35,0x37,0x2d, + 0x30,0x2e,0x33,0x39,0x63,0x2d,0x30,0x2e,0x31,0x33, + 0x32,0x2d,0x30,0x2e,0x32,0x34,0x31,0x2d,0x30,0x2e, + 0x31,0x32,0x31,0x2d,0x30,0x2e,0x35,0x33,0x34,0x2c, + 0x30,0x2e,0x30,0x32,0x36,0x2d,0x30,0x2e,0x37,0x36, + 0x36,0x6c,0x33,0x2e,0x30,0x30,0x35,0x2d,0x34,0x2e, + 0x36,0x38,0x34,0x0a,0x09,0x09,0x09,0x63,0x30,0x2e, + 0x32,0x37,0x36,0x2d,0x30,0x2e,0x34,0x33,0x31,0x2c, + 0x30,0x2e,0x39,0x38,0x36,0x2d,0x30,0x2e,0x34,0x33, + 0x2c,0x31,0x2e,0x32,0x36,0x34,0x2c,0x30,0x6c,0x33, + 0x2e,0x30,0x30,0x35,0x2c,0x34,0x2e,0x36,0x38,0x34, + 0x63,0x30,0x2e,0x31,0x34,0x37,0x2c,0x30,0x2e,0x32, + 0x33,0x31,0x2c,0x30,0x2e,0x31,0x35,0x39,0x2c,0x30, + 0x2e,0x35,0x32,0x34,0x2c,0x30,0x2e,0x30,0x32,0x36, + 0x2c,0x30,0x2e,0x37,0x36,0x36,0x43,0x32,0x32,0x2e, + 0x30,0x36,0x33,0x2c,0x38,0x2e,0x34,0x36,0x36,0x2c, + 0x32,0x31,0x2e,0x38,0x31,0x31,0x2c,0x38,0x2e,0x36, + 0x31,0x36,0x2c,0x32,0x31,0x2e,0x35,0x33,0x36,0x2c, + 0x38,0x2e,0x36,0x31,0x36,0x7a,0x0a,0x09,0x09,0x09, + 0x20,0x4d,0x31,0x36,0x2e,0x38,0x39,0x37,0x2c,0x37, + 0x2e,0x31,0x31,0x36,0x68,0x33,0x2e,0x32,0x36,0x38, + 0x4c,0x31,0x38,0x2e,0x35,0x33,0x2c,0x34,0x2e,0x35, + 0x37,0x31,0x4c,0x31,0x36,0x2e,0x38,0x39,0x37,0x2c, + 0x37,0x2e,0x31,0x31,0x36,0x7a,0x22,0x2f,0x3e,0x0a, + 0x09,0x3c,0x2f,0x67,0x3e,0x0a,0x09,0x3c,0x67,0x3e, 0x0a,0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66, 0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46, - 0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x32,0x31, - 0x2e,0x35,0x33,0x36,0x2c,0x38,0x2e,0x36,0x31,0x36, - 0x68,0x2d,0x36,0x2e,0x30,0x31,0x32,0x63,0x2d,0x30, - 0x2e,0x32,0x37,0x33,0x2c,0x30,0x2d,0x30,0x2e,0x35, - 0x32,0x35,0x2d,0x30,0x2e,0x31,0x35,0x2d,0x30,0x2e, - 0x36,0x35,0x37,0x2d,0x30,0x2e,0x33,0x39,0x63,0x2d, - 0x30,0x2e,0x31,0x33,0x32,0x2d,0x30,0x2e,0x32,0x34, - 0x31,0x2d,0x30,0x2e,0x31,0x32,0x31,0x2d,0x30,0x2e, - 0x35,0x33,0x34,0x2c,0x30,0x2e,0x30,0x32,0x36,0x2d, - 0x30,0x2e,0x37,0x36,0x36,0x6c,0x33,0x2e,0x30,0x30, - 0x35,0x2d,0x34,0x2e,0x36,0x38,0x34,0x0d,0x0a,0x09, - 0x09,0x09,0x63,0x30,0x2e,0x32,0x37,0x36,0x2d,0x30, - 0x2e,0x34,0x33,0x31,0x2c,0x30,0x2e,0x39,0x38,0x36, - 0x2d,0x30,0x2e,0x34,0x33,0x2c,0x31,0x2e,0x32,0x36, - 0x34,0x2c,0x30,0x6c,0x33,0x2e,0x30,0x30,0x35,0x2c, - 0x34,0x2e,0x36,0x38,0x34,0x63,0x30,0x2e,0x31,0x34, - 0x37,0x2c,0x30,0x2e,0x32,0x33,0x31,0x2c,0x30,0x2e, - 0x31,0x35,0x39,0x2c,0x30,0x2e,0x35,0x32,0x34,0x2c, - 0x30,0x2e,0x30,0x32,0x36,0x2c,0x30,0x2e,0x37,0x36, - 0x36,0x43,0x32,0x32,0x2e,0x30,0x36,0x33,0x2c,0x38, - 0x2e,0x34,0x36,0x36,0x2c,0x32,0x31,0x2e,0x38,0x31, - 0x31,0x2c,0x38,0x2e,0x36,0x31,0x36,0x2c,0x32,0x31, - 0x2e,0x35,0x33,0x36,0x2c,0x38,0x2e,0x36,0x31,0x36, - 0x7a,0x0d,0x0a,0x09,0x09,0x09,0x20,0x4d,0x31,0x36, - 0x2e,0x38,0x39,0x37,0x2c,0x37,0x2e,0x31,0x31,0x36, - 0x68,0x33,0x2e,0x32,0x36,0x38,0x4c,0x31,0x38,0x2e, - 0x35,0x33,0x2c,0x34,0x2e,0x35,0x37,0x31,0x4c,0x31, - 0x36,0x2e,0x38,0x39,0x37,0x2c,0x37,0x2e,0x31,0x31, - 0x36,0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x09,0x3c,0x2f, - 0x67,0x3e,0x0d,0x0a,0x09,0x3c,0x67,0x3e,0x0d,0x0a, - 0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69, - 0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46, - 0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x33,0x2e,0x31, - 0x32,0x35,0x2c,0x31,0x38,0x2e,0x35,0x33,0x6c,0x34, - 0x2e,0x36,0x38,0x34,0x2c,0x33,0x2e,0x30,0x30,0x34, - 0x76,0x2d,0x36,0x2e,0x30,0x31,0x4c,0x33,0x2e,0x31, - 0x32,0x35,0x2c,0x31,0x38,0x2e,0x35,0x33,0x7a,0x22, - 0x2f,0x3e,0x0d,0x0a,0x09,0x09,0x3c,0x70,0x61,0x74, + 0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x33,0x2e, + 0x31,0x32,0x35,0x2c,0x31,0x38,0x2e,0x35,0x33,0x6c, + 0x34,0x2e,0x36,0x38,0x34,0x2c,0x33,0x2e,0x30,0x30, + 0x34,0x76,0x2d,0x36,0x2e,0x30,0x31,0x4c,0x33,0x2e, + 0x31,0x32,0x35,0x2c,0x31,0x38,0x2e,0x35,0x33,0x7a, + 0x22,0x2f,0x3e,0x0a,0x09,0x09,0x3c,0x70,0x61,0x74, 0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46, 0x46,0x46,0x46,0x46,0x46,0x22,0x20,0x64,0x3d,0x22, 0x4d,0x37,0x2e,0x38,0x30,0x39,0x2c,0x32,0x32,0x2e, @@ -223,107 +220,106 @@ const unsigned char help_dpad_left_svg_data[3212] = { 0x2e,0x32,0x31,0x35,0x2d,0x30,0x2e,0x31,0x33,0x38, 0x2d,0x30,0x2e,0x33,0x34,0x35,0x2d,0x30,0x2e,0x33, 0x37,0x36,0x2d,0x30,0x2e,0x33,0x34,0x35,0x2d,0x30, - 0x2e,0x36,0x33,0x31,0x0d,0x0a,0x09,0x09,0x09,0x73, - 0x30,0x2e,0x31,0x33,0x2d,0x30,0x2e,0x34,0x39,0x33, - 0x2c,0x30,0x2e,0x33,0x34,0x35,0x2d,0x30,0x2e,0x36, - 0x33,0x31,0x6c,0x34,0x2e,0x36,0x38,0x34,0x2d,0x33, - 0x2e,0x30,0x30,0x36,0x63,0x30,0x2e,0x32,0x33,0x2d, - 0x30,0x2e,0x31,0x34,0x38,0x2c,0x30,0x2e,0x35,0x32, - 0x34,0x2d,0x30,0x2e,0x31,0x35,0x38,0x2c,0x30,0x2e, - 0x37,0x36,0x36,0x2d,0x30,0x2e,0x30,0x32,0x37,0x63, - 0x30,0x2e,0x32,0x34,0x2c,0x30,0x2e,0x31,0x33,0x31, - 0x2c,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2e,0x33,0x38, - 0x34,0x2c,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2e,0x36, - 0x35,0x38,0x76,0x36,0x2e,0x30,0x31,0x0d,0x0a,0x09, - 0x09,0x09,0x63,0x30,0x2c,0x30,0x2e,0x32,0x37,0x34, - 0x2d,0x30,0x2e,0x31,0x34,0x38,0x2c,0x30,0x2e,0x35, - 0x32,0x36,0x2d,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2e, - 0x36,0x35,0x38,0x43,0x38,0x2e,0x30,0x35,0x36,0x2c, - 0x32,0x32,0x2e,0x32,0x35,0x34,0x2c,0x37,0x2e,0x39, - 0x33,0x32,0x2c,0x32,0x32,0x2e,0x32,0x38,0x34,0x2c, - 0x37,0x2e,0x38,0x30,0x39,0x2c,0x32,0x32,0x2e,0x32, - 0x38,0x34,0x7a,0x20,0x4d,0x34,0x2e,0x35,0x31,0x34, - 0x2c,0x31,0x38,0x2e,0x35,0x33,0x6c,0x32,0x2e,0x35, - 0x34,0x35,0x2c,0x31,0x2e,0x36,0x33,0x32,0x76,0x2d, - 0x33,0x2e,0x32,0x36,0x35,0x4c,0x34,0x2e,0x35,0x31, - 0x34,0x2c,0x31,0x38,0x2e,0x35,0x33,0x7a,0x22,0x2f, - 0x3e,0x0d,0x0a,0x09,0x3c,0x2f,0x67,0x3e,0x0d,0x0a, - 0x09,0x3c,0x67,0x3e,0x0d,0x0a,0x09,0x09,0x3c,0x70, - 0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22, - 0x23,0x46,0x46,0x46,0x46,0x46,0x46,0x22,0x20,0x64, - 0x3d,0x22,0x4d,0x32,0x39,0x2e,0x31,0x39,0x35,0x2c, - 0x32,0x32,0x2e,0x32,0x38,0x34,0x63,0x2d,0x30,0x2e, - 0x31,0x32,0x34,0x2c,0x30,0x2d,0x30,0x2e,0x32,0x34, - 0x36,0x2d,0x30,0x2e,0x30,0x33,0x2d,0x30,0x2e,0x33, - 0x35,0x38,0x2d,0x30,0x2e,0x30,0x39,0x32,0x63,0x2d, - 0x30,0x2e,0x32,0x34,0x31,0x2d,0x30,0x2e,0x31,0x33, - 0x32,0x2d,0x30,0x2e,0x33,0x39,0x32,0x2d,0x30,0x2e, - 0x33,0x38,0x34,0x2d,0x30,0x2e,0x33,0x39,0x32,0x2d, - 0x30,0x2e,0x36,0x35,0x38,0x76,0x2d,0x36,0x2e,0x30, - 0x31,0x0d,0x0a,0x09,0x09,0x09,0x63,0x30,0x2d,0x30, - 0x2e,0x32,0x37,0x34,0x2c,0x30,0x2e,0x31,0x34,0x39, - 0x2d,0x30,0x2e,0x35,0x32,0x36,0x2c,0x30,0x2e,0x33, - 0x39,0x32,0x2d,0x30,0x2e,0x36,0x35,0x38,0x63,0x30, - 0x2e,0x32,0x33,0x39,0x2d,0x30,0x2e,0x31,0x33,0x31, - 0x2c,0x30,0x2e,0x35,0x33,0x33,0x2d,0x30,0x2e,0x31, - 0x32,0x33,0x2c,0x30,0x2e,0x37,0x36,0x35,0x2c,0x30, - 0x2e,0x30,0x32,0x37,0x6c,0x34,0x2e,0x36,0x38,0x35, - 0x2c,0x33,0x2e,0x30,0x30,0x35,0x63,0x30,0x2e,0x32, - 0x31,0x35,0x2c,0x30,0x2e,0x31,0x33,0x38,0x2c,0x30, - 0x2e,0x33,0x34,0x35,0x2c,0x30,0x2e,0x33,0x37,0x36, - 0x2c,0x30,0x2e,0x33,0x34,0x35,0x2c,0x30,0x2e,0x36, - 0x33,0x31,0x0d,0x0a,0x09,0x09,0x09,0x73,0x2d,0x30, - 0x2e,0x31,0x33,0x2c,0x30,0x2e,0x34,0x39,0x33,0x2d, - 0x30,0x2e,0x33,0x34,0x35,0x2c,0x30,0x2e,0x36,0x33, - 0x31,0x6c,0x2d,0x34,0x2e,0x36,0x38,0x35,0x2c,0x33, - 0x2e,0x30,0x30,0x34,0x43,0x32,0x39,0x2e,0x34,0x37, - 0x38,0x2c,0x32,0x32,0x2e,0x32,0x34,0x34,0x2c,0x32, - 0x39,0x2e,0x33,0x33,0x36,0x2c,0x32,0x32,0x2e,0x32, - 0x38,0x34,0x2c,0x32,0x39,0x2e,0x31,0x39,0x35,0x2c, - 0x32,0x32,0x2e,0x32,0x38,0x34,0x7a,0x20,0x4d,0x32, - 0x39,0x2e,0x39,0x34,0x35,0x2c,0x31,0x36,0x2e,0x38, - 0x39,0x36,0x76,0x33,0x2e,0x32,0x36,0x36,0x6c,0x32, - 0x2e,0x35,0x34,0x36,0x2d,0x31,0x2e,0x36,0x33,0x33, - 0x0d,0x0a,0x09,0x09,0x09,0x4c,0x32,0x39,0x2e,0x39, - 0x34,0x35,0x2c,0x31,0x36,0x2e,0x38,0x39,0x36,0x7a, - 0x22,0x2f,0x3e,0x0d,0x0a,0x09,0x3c,0x2f,0x67,0x3e, - 0x0d,0x0a,0x09,0x3c,0x67,0x3e,0x0d,0x0a,0x09,0x09, - 0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c, - 0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46,0x46,0x22, - 0x20,0x64,0x3d,0x22,0x4d,0x31,0x38,0x2e,0x35,0x33, - 0x2c,0x33,0x34,0x2e,0x36,0x32,0x36,0x4c,0x31,0x38, + 0x2e,0x36,0x33,0x31,0x0a,0x09,0x09,0x09,0x73,0x30, + 0x2e,0x31,0x33,0x2d,0x30,0x2e,0x34,0x39,0x33,0x2c, + 0x30,0x2e,0x33,0x34,0x35,0x2d,0x30,0x2e,0x36,0x33, + 0x31,0x6c,0x34,0x2e,0x36,0x38,0x34,0x2d,0x33,0x2e, + 0x30,0x30,0x36,0x63,0x30,0x2e,0x32,0x33,0x2d,0x30, + 0x2e,0x31,0x34,0x38,0x2c,0x30,0x2e,0x35,0x32,0x34, + 0x2d,0x30,0x2e,0x31,0x35,0x38,0x2c,0x30,0x2e,0x37, + 0x36,0x36,0x2d,0x30,0x2e,0x30,0x32,0x37,0x63,0x30, + 0x2e,0x32,0x34,0x2c,0x30,0x2e,0x31,0x33,0x31,0x2c, + 0x30,0x2e,0x33,0x39,0x2c,0x30,0x2e,0x33,0x38,0x34, + 0x2c,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2e,0x36,0x35, + 0x38,0x76,0x36,0x2e,0x30,0x31,0x0a,0x09,0x09,0x09, + 0x63,0x30,0x2c,0x30,0x2e,0x32,0x37,0x34,0x2d,0x30, + 0x2e,0x31,0x34,0x38,0x2c,0x30,0x2e,0x35,0x32,0x36, + 0x2d,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2e,0x36,0x35, + 0x38,0x43,0x38,0x2e,0x30,0x35,0x36,0x2c,0x32,0x32, + 0x2e,0x32,0x35,0x34,0x2c,0x37,0x2e,0x39,0x33,0x32, + 0x2c,0x32,0x32,0x2e,0x32,0x38,0x34,0x2c,0x37,0x2e, + 0x38,0x30,0x39,0x2c,0x32,0x32,0x2e,0x32,0x38,0x34, + 0x7a,0x20,0x4d,0x34,0x2e,0x35,0x31,0x34,0x2c,0x31, + 0x38,0x2e,0x35,0x33,0x6c,0x32,0x2e,0x35,0x34,0x35, + 0x2c,0x31,0x2e,0x36,0x33,0x32,0x76,0x2d,0x33,0x2e, + 0x32,0x36,0x35,0x4c,0x34,0x2e,0x35,0x31,0x34,0x2c, + 0x31,0x38,0x2e,0x35,0x33,0x7a,0x22,0x2f,0x3e,0x0a, + 0x09,0x3c,0x2f,0x67,0x3e,0x0a,0x09,0x3c,0x67,0x3e, + 0x0a,0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66, + 0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46, + 0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x32,0x39, + 0x2e,0x31,0x39,0x35,0x2c,0x32,0x32,0x2e,0x32,0x38, + 0x34,0x63,0x2d,0x30,0x2e,0x31,0x32,0x34,0x2c,0x30, + 0x2d,0x30,0x2e,0x32,0x34,0x36,0x2d,0x30,0x2e,0x30, + 0x33,0x2d,0x30,0x2e,0x33,0x35,0x38,0x2d,0x30,0x2e, + 0x30,0x39,0x32,0x63,0x2d,0x30,0x2e,0x32,0x34,0x31, + 0x2d,0x30,0x2e,0x31,0x33,0x32,0x2d,0x30,0x2e,0x33, + 0x39,0x32,0x2d,0x30,0x2e,0x33,0x38,0x34,0x2d,0x30, + 0x2e,0x33,0x39,0x32,0x2d,0x30,0x2e,0x36,0x35,0x38, + 0x76,0x2d,0x36,0x2e,0x30,0x31,0x0a,0x09,0x09,0x09, + 0x63,0x30,0x2d,0x30,0x2e,0x32,0x37,0x34,0x2c,0x30, + 0x2e,0x31,0x34,0x39,0x2d,0x30,0x2e,0x35,0x32,0x36, + 0x2c,0x30,0x2e,0x33,0x39,0x32,0x2d,0x30,0x2e,0x36, + 0x35,0x38,0x63,0x30,0x2e,0x32,0x33,0x39,0x2d,0x30, + 0x2e,0x31,0x33,0x31,0x2c,0x30,0x2e,0x35,0x33,0x33, + 0x2d,0x30,0x2e,0x31,0x32,0x33,0x2c,0x30,0x2e,0x37, + 0x36,0x35,0x2c,0x30,0x2e,0x30,0x32,0x37,0x6c,0x34, + 0x2e,0x36,0x38,0x35,0x2c,0x33,0x2e,0x30,0x30,0x35, + 0x63,0x30,0x2e,0x32,0x31,0x35,0x2c,0x30,0x2e,0x31, + 0x33,0x38,0x2c,0x30,0x2e,0x33,0x34,0x35,0x2c,0x30, + 0x2e,0x33,0x37,0x36,0x2c,0x30,0x2e,0x33,0x34,0x35, + 0x2c,0x30,0x2e,0x36,0x33,0x31,0x0a,0x09,0x09,0x09, + 0x73,0x2d,0x30,0x2e,0x31,0x33,0x2c,0x30,0x2e,0x34, + 0x39,0x33,0x2d,0x30,0x2e,0x33,0x34,0x35,0x2c,0x30, + 0x2e,0x36,0x33,0x31,0x6c,0x2d,0x34,0x2e,0x36,0x38, + 0x35,0x2c,0x33,0x2e,0x30,0x30,0x34,0x43,0x32,0x39, + 0x2e,0x34,0x37,0x38,0x2c,0x32,0x32,0x2e,0x32,0x34, + 0x34,0x2c,0x32,0x39,0x2e,0x33,0x33,0x36,0x2c,0x32, + 0x32,0x2e,0x32,0x38,0x34,0x2c,0x32,0x39,0x2e,0x31, + 0x39,0x35,0x2c,0x32,0x32,0x2e,0x32,0x38,0x34,0x7a, + 0x20,0x4d,0x32,0x39,0x2e,0x39,0x34,0x35,0x2c,0x31, + 0x36,0x2e,0x38,0x39,0x36,0x76,0x33,0x2e,0x32,0x36, + 0x36,0x6c,0x32,0x2e,0x35,0x34,0x36,0x2d,0x31,0x2e, + 0x36,0x33,0x33,0x0a,0x09,0x09,0x09,0x4c,0x32,0x39, + 0x2e,0x39,0x34,0x35,0x2c,0x31,0x36,0x2e,0x38,0x39, + 0x36,0x7a,0x22,0x2f,0x3e,0x0a,0x09,0x3c,0x2f,0x67, + 0x3e,0x0a,0x09,0x3c,0x67,0x3e,0x0a,0x09,0x09,0x3c, + 0x70,0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d, + 0x22,0x23,0x46,0x46,0x46,0x46,0x46,0x46,0x22,0x20, + 0x64,0x3d,0x22,0x4d,0x31,0x38,0x2e,0x35,0x33,0x2c, + 0x33,0x34,0x2e,0x36,0x32,0x36,0x4c,0x31,0x38,0x2e, + 0x35,0x33,0x2c,0x33,0x34,0x2e,0x36,0x32,0x36,0x63, + 0x2d,0x30,0x2e,0x32,0x35,0x35,0x2c,0x30,0x2d,0x30, + 0x2e,0x34,0x39,0x32,0x2d,0x30,0x2e,0x31,0x33,0x2d, + 0x30,0x2e,0x36,0x33,0x31,0x2d,0x30,0x2e,0x33,0x34, + 0x35,0x6c,0x2d,0x33,0x2e,0x30,0x30,0x35,0x2d,0x34, + 0x2e,0x36,0x38,0x34,0x0a,0x09,0x09,0x09,0x63,0x2d, + 0x30,0x2e,0x31,0x34,0x37,0x2d,0x30,0x2e,0x32,0x33, + 0x31,0x2d,0x30,0x2e,0x31,0x35,0x38,0x2d,0x30,0x2e, + 0x35,0x32,0x34,0x2d,0x30,0x2e,0x30,0x32,0x36,0x2d, + 0x30,0x2e,0x37,0x36,0x36,0x73,0x30,0x2e,0x33,0x38, + 0x34,0x2d,0x30,0x2e,0x33,0x39,0x31,0x2c,0x30,0x2e, + 0x36,0x35,0x37,0x2d,0x30,0x2e,0x33,0x39,0x31,0x68, + 0x36,0x2e,0x30,0x31,0x32,0x63,0x30,0x2e,0x32,0x37, + 0x33,0x2c,0x30,0x2c,0x30,0x2e,0x35,0x32,0x35,0x2c, + 0x30,0x2e,0x31,0x34,0x38,0x2c,0x30,0x2e,0x36,0x35, + 0x37,0x2c,0x30,0x2e,0x33,0x39,0x31,0x0a,0x09,0x09, + 0x09,0x63,0x30,0x2e,0x31,0x33,0x33,0x2c,0x30,0x2e, + 0x32,0x34,0x2c,0x30,0x2e,0x31,0x32,0x31,0x2c,0x30, + 0x2e,0x35,0x33,0x33,0x2d,0x30,0x2e,0x30,0x32,0x36, + 0x2c,0x30,0x2e,0x37,0x36,0x36,0x6c,0x2d,0x33,0x2e, + 0x30,0x30,0x35,0x2c,0x34,0x2e,0x36,0x38,0x34,0x43, + 0x31,0x39,0x2e,0x30,0x32,0x33,0x2c,0x33,0x34,0x2e, + 0x34,0x39,0x36,0x2c,0x31,0x38,0x2e,0x37,0x38,0x36, + 0x2c,0x33,0x34,0x2e,0x36,0x32,0x36,0x2c,0x31,0x38, 0x2e,0x35,0x33,0x2c,0x33,0x34,0x2e,0x36,0x32,0x36, - 0x63,0x2d,0x30,0x2e,0x32,0x35,0x35,0x2c,0x30,0x2d, - 0x30,0x2e,0x34,0x39,0x32,0x2d,0x30,0x2e,0x31,0x33, - 0x2d,0x30,0x2e,0x36,0x33,0x31,0x2d,0x30,0x2e,0x33, - 0x34,0x35,0x6c,0x2d,0x33,0x2e,0x30,0x30,0x35,0x2d, - 0x34,0x2e,0x36,0x38,0x34,0x0d,0x0a,0x09,0x09,0x09, - 0x63,0x2d,0x30,0x2e,0x31,0x34,0x37,0x2d,0x30,0x2e, - 0x32,0x33,0x31,0x2d,0x30,0x2e,0x31,0x35,0x38,0x2d, - 0x30,0x2e,0x35,0x32,0x34,0x2d,0x30,0x2e,0x30,0x32, - 0x36,0x2d,0x30,0x2e,0x37,0x36,0x36,0x73,0x30,0x2e, - 0x33,0x38,0x34,0x2d,0x30,0x2e,0x33,0x39,0x31,0x2c, - 0x30,0x2e,0x36,0x35,0x37,0x2d,0x30,0x2e,0x33,0x39, - 0x31,0x68,0x36,0x2e,0x30,0x31,0x32,0x63,0x30,0x2e, - 0x32,0x37,0x33,0x2c,0x30,0x2c,0x30,0x2e,0x35,0x32, - 0x35,0x2c,0x30,0x2e,0x31,0x34,0x38,0x2c,0x30,0x2e, - 0x36,0x35,0x37,0x2c,0x30,0x2e,0x33,0x39,0x31,0x0d, - 0x0a,0x09,0x09,0x09,0x63,0x30,0x2e,0x31,0x33,0x33, - 0x2c,0x30,0x2e,0x32,0x34,0x2c,0x30,0x2e,0x31,0x32, - 0x31,0x2c,0x30,0x2e,0x35,0x33,0x33,0x2d,0x30,0x2e, - 0x30,0x32,0x36,0x2c,0x30,0x2e,0x37,0x36,0x36,0x6c, - 0x2d,0x33,0x2e,0x30,0x30,0x35,0x2c,0x34,0x2e,0x36, - 0x38,0x34,0x43,0x31,0x39,0x2e,0x30,0x32,0x33,0x2c, - 0x33,0x34,0x2e,0x34,0x39,0x36,0x2c,0x31,0x38,0x2e, - 0x37,0x38,0x36,0x2c,0x33,0x34,0x2e,0x36,0x32,0x36, - 0x2c,0x31,0x38,0x2e,0x35,0x33,0x2c,0x33,0x34,0x2e, - 0x36,0x32,0x36,0x7a,0x20,0x4d,0x31,0x36,0x2e,0x38, - 0x39,0x37,0x2c,0x32,0x39,0x2e,0x39,0x34,0x32,0x6c, - 0x31,0x2e,0x36,0x33,0x33,0x2c,0x32,0x2e,0x35,0x34, - 0x35,0x0d,0x0a,0x09,0x09,0x09,0x6c,0x31,0x2e,0x36, - 0x33,0x35,0x2d,0x32,0x2e,0x35,0x34,0x35,0x48,0x31, - 0x36,0x2e,0x38,0x39,0x37,0x7a,0x22,0x2f,0x3e,0x0d, - 0x0a,0x09,0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x3c,0x2f, - 0x67,0x3e,0x0d,0x0a,0x3c,0x2f,0x73,0x76,0x67,0x3e, - 0x0d,0x0a + 0x7a,0x20,0x4d,0x31,0x36,0x2e,0x38,0x39,0x37,0x2c, + 0x32,0x39,0x2e,0x39,0x34,0x32,0x6c,0x31,0x2e,0x36, + 0x33,0x33,0x2c,0x32,0x2e,0x35,0x34,0x35,0x0a,0x09, + 0x09,0x09,0x6c,0x31,0x2e,0x36,0x33,0x35,0x2d,0x32, + 0x2e,0x35,0x34,0x35,0x48,0x31,0x36,0x2e,0x38,0x39, + 0x37,0x7a,0x22,0x2f,0x3e,0x0a,0x09,0x3c,0x2f,0x67, + 0x3e,0x0a,0x3c,0x2f,0x67,0x3e,0x0a,0x3c,0x2f,0x73, + 0x76,0x67,0x3e,0x0a }; + diff --git a/data/converted/help_dpad_leftright_svg.cpp b/data/converted/help_dpad_leftright_svg.cpp index 0e9f86ce3b..315f94c0de 100644 --- a/data/converted/help_dpad_leftright_svg.cpp +++ b/data/converted/help_dpad_leftright_svg.cpp @@ -2,84 +2,83 @@ #include "../Resources.h" -const size_t help_dpad_leftright_svg_size = 3290; -const unsigned char help_dpad_leftright_svg_data[3290] = { +const size_t help_dpad_leftright_svg_size = 3241; +const unsigned char help_dpad_leftright_svg_data[3241] = { 0x3c,0x3f,0x78,0x6d,0x6c,0x20,0x76,0x65,0x72,0x73, 0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x30,0x22,0x20, 0x65,0x6e,0x63,0x6f,0x64,0x69,0x6e,0x67,0x3d,0x22, - 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0d,0x0a, - 0x3c,0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72, - 0x61,0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62, - 0x65,0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61, - 0x74,0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33, - 0x2c,0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f, - 0x72,0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e, - 0x20,0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72, - 0x73,0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30, - 0x20,0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20, - 0x20,0x2d,0x2d,0x3e,0x0d,0x0a,0x3c,0x21,0x44,0x4f, - 0x43,0x54,0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20, - 0x50,0x55,0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f, - 0x2f,0x57,0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20, - 0x53,0x56,0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45, - 0x4e,0x22,0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, - 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, - 0x67,0x2f,0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73, - 0x2f,0x53,0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44, - 0x54,0x44,0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64, - 0x74,0x64,0x22,0x3e,0x0d,0x0a,0x3c,0x73,0x76,0x67, - 0x20,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22, - 0x31,0x2e,0x31,0x22,0x20,0x69,0x64,0x3d,0x22,0x5f, - 0x78,0x33,0x30,0x5f,0x22,0x20,0x78,0x6d,0x6c,0x6e, - 0x73,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f, - 0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67, - 0x2f,0x32,0x30,0x30,0x30,0x2f,0x73,0x76,0x67,0x22, - 0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78,0x6c,0x69, - 0x6e,0x6b,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, - 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, - 0x67,0x2f,0x31,0x39,0x39,0x39,0x2f,0x78,0x6c,0x69, - 0x6e,0x6b,0x22,0x20,0x78,0x3d,0x22,0x30,0x70,0x78, - 0x22,0x20,0x79,0x3d,0x22,0x30,0x70,0x78,0x22,0x0d, - 0x0a,0x09,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22, - 0x33,0x37,0x2e,0x30,0x36,0x31,0x70,0x78,0x22,0x20, - 0x68,0x65,0x69,0x67,0x68,0x74,0x3d,0x22,0x33,0x37, - 0x2e,0x30,0x36,0x31,0x70,0x78,0x22,0x20,0x76,0x69, - 0x65,0x77,0x42,0x6f,0x78,0x3d,0x22,0x30,0x20,0x30, - 0x20,0x33,0x37,0x2e,0x30,0x36,0x31,0x20,0x33,0x37, - 0x2e,0x30,0x36,0x31,0x22,0x20,0x65,0x6e,0x61,0x62, - 0x6c,0x65,0x2d,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f, - 0x75,0x6e,0x64,0x3d,0x22,0x6e,0x65,0x77,0x20,0x30, - 0x20,0x30,0x20,0x33,0x37,0x2e,0x30,0x36,0x31,0x20, - 0x33,0x37,0x2e,0x30,0x36,0x31,0x22,0x20,0x78,0x6d, - 0x6c,0x3a,0x73,0x70,0x61,0x63,0x65,0x3d,0x22,0x70, - 0x72,0x65,0x73,0x65,0x72,0x76,0x65,0x22,0x3e,0x0d, - 0x0a,0x3c,0x67,0x3e,0x0d,0x0a,0x09,0x3c,0x67,0x3e, - 0x0d,0x0a,0x09,0x09,0x3c,0x67,0x3e,0x0d,0x0a,0x09, - 0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69, - 0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46, - 0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x32,0x32,0x2e, - 0x30,0x38,0x36,0x2c,0x33,0x37,0x2e,0x30,0x36,0x68, - 0x2d,0x37,0x2e,0x31,0x31,0x31,0x63,0x2d,0x32,0x2e, - 0x32,0x38,0x39,0x2c,0x30,0x2d,0x33,0x2e,0x31,0x31, - 0x39,0x2d,0x31,0x2e,0x38,0x36,0x36,0x2d,0x33,0x2e, - 0x31,0x31,0x39,0x2d,0x33,0x2e,0x31,0x32,0x31,0x76, - 0x2d,0x38,0x2e,0x37,0x33,0x32,0x48,0x33,0x2e,0x31, - 0x32,0x31,0x43,0x30,0x2e,0x38,0x33,0x31,0x2c,0x32, - 0x35,0x2e,0x32,0x30,0x36,0x2c,0x30,0x2c,0x32,0x33, - 0x2e,0x33,0x34,0x2c,0x30,0x2c,0x32,0x32,0x2e,0x30, - 0x38,0x35,0x0d,0x0a,0x09,0x09,0x09,0x09,0x76,0x2d, - 0x37,0x2e,0x31,0x31,0x63,0x30,0x2d,0x32,0x2e,0x32, - 0x38,0x39,0x2c,0x31,0x2e,0x38,0x36,0x37,0x2d,0x33, - 0x2e,0x31,0x32,0x2c,0x33,0x2e,0x31,0x32,0x31,0x2d, - 0x33,0x2e,0x31,0x32,0x68,0x38,0x2e,0x37,0x33,0x33, - 0x56,0x33,0x2e,0x31,0x32,0x31,0x43,0x31,0x31,0x2e, - 0x38,0x35,0x35,0x2c,0x30,0x2e,0x38,0x33,0x31,0x2c, - 0x31,0x33,0x2e,0x37,0x32,0x2c,0x30,0x2c,0x31,0x34, - 0x2e,0x39,0x37,0x34,0x2c,0x30,0x68,0x37,0x2e,0x31, - 0x31,0x31,0x63,0x32,0x2e,0x32,0x39,0x2c,0x30,0x2c, - 0x33,0x2e,0x31,0x32,0x31,0x2c,0x31,0x2e,0x38,0x36, - 0x37,0x2c,0x33,0x2e,0x31,0x32,0x31,0x2c,0x33,0x2e, - 0x31,0x32,0x31,0x76,0x38,0x2e,0x37,0x33,0x32,0x0d, + 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0a,0x3c, + 0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72,0x61, + 0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62,0x65, + 0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61,0x74, + 0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33,0x2c, + 0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f,0x72, + 0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e,0x20, + 0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72,0x73, + 0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30,0x20, + 0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20,0x20, + 0x2d,0x2d,0x3e,0x0a,0x3c,0x21,0x44,0x4f,0x43,0x54, + 0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20,0x50,0x55, + 0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f,0x2f,0x57, + 0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20,0x53,0x56, + 0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45,0x4e,0x22, + 0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73,0x2f,0x53, + 0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44,0x54,0x44, + 0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64,0x74,0x64, + 0x22,0x3e,0x0a,0x3c,0x73,0x76,0x67,0x20,0x76,0x65, + 0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x31, + 0x22,0x20,0x69,0x64,0x3d,0x22,0x5f,0x78,0x33,0x30, + 0x5f,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3d,0x22, + 0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77, + 0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f,0x32,0x30, + 0x30,0x30,0x2f,0x73,0x76,0x67,0x22,0x20,0x78,0x6d, + 0x6c,0x6e,0x73,0x3a,0x78,0x6c,0x69,0x6e,0x6b,0x3d, + 0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77, + 0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f,0x31, + 0x39,0x39,0x39,0x2f,0x78,0x6c,0x69,0x6e,0x6b,0x22, + 0x20,0x78,0x3d,0x22,0x30,0x70,0x78,0x22,0x20,0x79, + 0x3d,0x22,0x30,0x70,0x78,0x22,0x0a,0x09,0x20,0x77, + 0x69,0x64,0x74,0x68,0x3d,0x22,0x33,0x37,0x2e,0x30, + 0x36,0x31,0x70,0x78,0x22,0x20,0x68,0x65,0x69,0x67, + 0x68,0x74,0x3d,0x22,0x33,0x37,0x2e,0x30,0x36,0x31, + 0x70,0x78,0x22,0x20,0x76,0x69,0x65,0x77,0x42,0x6f, + 0x78,0x3d,0x22,0x30,0x20,0x30,0x20,0x33,0x37,0x2e, + 0x30,0x36,0x31,0x20,0x33,0x37,0x2e,0x30,0x36,0x31, + 0x22,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0x2d,0x62, + 0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x3d, + 0x22,0x6e,0x65,0x77,0x20,0x30,0x20,0x30,0x20,0x33, + 0x37,0x2e,0x30,0x36,0x31,0x20,0x33,0x37,0x2e,0x30, + 0x36,0x31,0x22,0x20,0x78,0x6d,0x6c,0x3a,0x73,0x70, + 0x61,0x63,0x65,0x3d,0x22,0x70,0x72,0x65,0x73,0x65, + 0x72,0x76,0x65,0x22,0x3e,0x0a,0x3c,0x67,0x3e,0x0a, + 0x09,0x3c,0x67,0x3e,0x0a,0x09,0x09,0x3c,0x67,0x3e, + 0x0a,0x09,0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20, + 0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46, + 0x46,0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x32, + 0x32,0x2e,0x30,0x38,0x36,0x2c,0x33,0x37,0x2e,0x30, + 0x36,0x68,0x2d,0x37,0x2e,0x31,0x31,0x31,0x63,0x2d, + 0x32,0x2e,0x32,0x38,0x39,0x2c,0x30,0x2d,0x33,0x2e, + 0x31,0x31,0x39,0x2d,0x31,0x2e,0x38,0x36,0x36,0x2d, + 0x33,0x2e,0x31,0x31,0x39,0x2d,0x33,0x2e,0x31,0x32, + 0x31,0x76,0x2d,0x38,0x2e,0x37,0x33,0x32,0x48,0x33, + 0x2e,0x31,0x32,0x31,0x43,0x30,0x2e,0x38,0x33,0x31, + 0x2c,0x32,0x35,0x2e,0x32,0x30,0x36,0x2c,0x30,0x2c, + 0x32,0x33,0x2e,0x33,0x34,0x2c,0x30,0x2c,0x32,0x32, + 0x2e,0x30,0x38,0x35,0x0a,0x09,0x09,0x09,0x09,0x76, + 0x2d,0x37,0x2e,0x31,0x31,0x63,0x30,0x2d,0x32,0x2e, + 0x32,0x38,0x39,0x2c,0x31,0x2e,0x38,0x36,0x37,0x2d, + 0x33,0x2e,0x31,0x32,0x2c,0x33,0x2e,0x31,0x32,0x31, + 0x2d,0x33,0x2e,0x31,0x32,0x68,0x38,0x2e,0x37,0x33, + 0x33,0x56,0x33,0x2e,0x31,0x32,0x31,0x43,0x31,0x31, + 0x2e,0x38,0x35,0x35,0x2c,0x30,0x2e,0x38,0x33,0x31, + 0x2c,0x31,0x33,0x2e,0x37,0x32,0x2c,0x30,0x2c,0x31, + 0x34,0x2e,0x39,0x37,0x34,0x2c,0x30,0x68,0x37,0x2e, + 0x31,0x31,0x31,0x63,0x32,0x2e,0x32,0x39,0x2c,0x30, + 0x2c,0x33,0x2e,0x31,0x32,0x31,0x2c,0x31,0x2e,0x38, + 0x36,0x37,0x2c,0x33,0x2e,0x31,0x32,0x31,0x2c,0x33, + 0x2e,0x31,0x32,0x31,0x76,0x38,0x2e,0x37,0x33,0x32, 0x0a,0x09,0x09,0x09,0x09,0x68,0x38,0x2e,0x37,0x33, 0x31,0x63,0x32,0x2e,0x32,0x39,0x2c,0x30,0x2c,0x33, 0x2e,0x31,0x32,0x31,0x2c,0x31,0x2e,0x38,0x36,0x35, @@ -89,68 +88,67 @@ const unsigned char help_dpad_leftright_svg_data[3290] = { 0x33,0x2e,0x31,0x32,0x31,0x2d,0x33,0x2e,0x31,0x32, 0x31,0x2c,0x33,0x2e,0x31,0x32,0x31,0x68,0x2d,0x38, 0x2e,0x37,0x33,0x31,0x76,0x38,0x2e,0x37,0x33,0x32, - 0x0d,0x0a,0x09,0x09,0x09,0x09,0x43,0x32,0x35,0x2e, - 0x32,0x30,0x37,0x2c,0x33,0x36,0x2e,0x32,0x32,0x39, - 0x2c,0x32,0x33,0x2e,0x33,0x34,0x31,0x2c,0x33,0x37, - 0x2e,0x30,0x36,0x2c,0x32,0x32,0x2e,0x30,0x38,0x36, - 0x2c,0x33,0x37,0x2e,0x30,0x36,0x7a,0x20,0x4d,0x33, - 0x2e,0x31,0x32,0x31,0x2c,0x31,0x33,0x2e,0x33,0x35, - 0x34,0x43,0x32,0x2e,0x37,0x34,0x35,0x2c,0x31,0x33, - 0x2e,0x33,0x35,0x39,0x2c,0x31,0x2e,0x35,0x2c,0x31, - 0x33,0x2e,0x34,0x39,0x33,0x2c,0x31,0x2e,0x35,0x2c, - 0x31,0x34,0x2e,0x39,0x37,0x34,0x76,0x37,0x2e,0x31, - 0x31,0x0d,0x0a,0x09,0x09,0x09,0x09,0x63,0x30,0x2e, - 0x30,0x30,0x36,0x2c,0x30,0x2e,0x33,0x37,0x36,0x2c, - 0x30,0x2e,0x31,0x33,0x39,0x2c,0x31,0x2e,0x36,0x32, - 0x31,0x2c,0x31,0x2e,0x36,0x32,0x31,0x2c,0x31,0x2e, - 0x36,0x32,0x31,0x68,0x31,0x30,0x2e,0x32,0x33,0x33, - 0x76,0x31,0x30,0x2e,0x32,0x33,0x32,0x63,0x30,0x2e, - 0x30,0x30,0x35,0x2c,0x30,0x2e,0x33,0x37,0x36,0x2c, + 0x0a,0x09,0x09,0x09,0x09,0x43,0x32,0x35,0x2e,0x32, + 0x30,0x37,0x2c,0x33,0x36,0x2e,0x32,0x32,0x39,0x2c, + 0x32,0x33,0x2e,0x33,0x34,0x31,0x2c,0x33,0x37,0x2e, + 0x30,0x36,0x2c,0x32,0x32,0x2e,0x30,0x38,0x36,0x2c, + 0x33,0x37,0x2e,0x30,0x36,0x7a,0x20,0x4d,0x33,0x2e, + 0x31,0x32,0x31,0x2c,0x31,0x33,0x2e,0x33,0x35,0x34, + 0x43,0x32,0x2e,0x37,0x34,0x35,0x2c,0x31,0x33,0x2e, + 0x33,0x35,0x39,0x2c,0x31,0x2e,0x35,0x2c,0x31,0x33, + 0x2e,0x34,0x39,0x33,0x2c,0x31,0x2e,0x35,0x2c,0x31, + 0x34,0x2e,0x39,0x37,0x34,0x76,0x37,0x2e,0x31,0x31, + 0x0a,0x09,0x09,0x09,0x09,0x63,0x30,0x2e,0x30,0x30, + 0x36,0x2c,0x30,0x2e,0x33,0x37,0x36,0x2c,0x30,0x2e, + 0x31,0x33,0x39,0x2c,0x31,0x2e,0x36,0x32,0x31,0x2c, + 0x31,0x2e,0x36,0x32,0x31,0x2c,0x31,0x2e,0x36,0x32, + 0x31,0x68,0x31,0x30,0x2e,0x32,0x33,0x33,0x76,0x31, + 0x30,0x2e,0x32,0x33,0x32,0x63,0x30,0x2e,0x30,0x30, + 0x35,0x2c,0x30,0x2e,0x33,0x37,0x36,0x2c,0x30,0x2e, + 0x31,0x34,0x2c,0x31,0x2e,0x36,0x32,0x31,0x2c,0x31, + 0x2e,0x36,0x31,0x39,0x2c,0x31,0x2e,0x36,0x32,0x31, + 0x68,0x37,0x2e,0x31,0x30,0x38,0x0a,0x09,0x09,0x09, + 0x09,0x63,0x30,0x2e,0x33,0x38,0x34,0x2d,0x30,0x2e, + 0x30,0x30,0x37,0x2c,0x31,0x2e,0x36,0x32,0x34,0x2d, + 0x30,0x2e,0x31,0x34,0x33,0x2c,0x31,0x2e,0x36,0x32, + 0x34,0x2d,0x31,0x2e,0x36,0x32,0x31,0x56,0x32,0x33, + 0x2e,0x37,0x30,0x36,0x68,0x31,0x30,0x2e,0x32,0x33, + 0x31,0x63,0x30,0x2e,0x33,0x37,0x36,0x2d,0x30,0x2e, + 0x30,0x30,0x36,0x2c,0x31,0x2e,0x36,0x32,0x31,0x2d, 0x30,0x2e,0x31,0x34,0x2c,0x31,0x2e,0x36,0x32,0x31, - 0x2c,0x31,0x2e,0x36,0x31,0x39,0x2c,0x31,0x2e,0x36, - 0x32,0x31,0x68,0x37,0x2e,0x31,0x30,0x38,0x0d,0x0a, - 0x09,0x09,0x09,0x09,0x63,0x30,0x2e,0x33,0x38,0x34, - 0x2d,0x30,0x2e,0x30,0x30,0x37,0x2c,0x31,0x2e,0x36, - 0x32,0x34,0x2d,0x30,0x2e,0x31,0x34,0x33,0x2c,0x31, - 0x2e,0x36,0x32,0x34,0x2d,0x31,0x2e,0x36,0x32,0x31, - 0x56,0x32,0x33,0x2e,0x37,0x30,0x36,0x68,0x31,0x30, - 0x2e,0x32,0x33,0x31,0x63,0x30,0x2e,0x33,0x37,0x36, - 0x2d,0x30,0x2e,0x30,0x30,0x36,0x2c,0x31,0x2e,0x36, - 0x32,0x31,0x2d,0x30,0x2e,0x31,0x34,0x2c,0x31,0x2e, - 0x36,0x32,0x31,0x2d,0x31,0x2e,0x36,0x32,0x31,0x76, - 0x2d,0x37,0x2e,0x31,0x31,0x0d,0x0a,0x09,0x09,0x09, - 0x09,0x63,0x2d,0x30,0x2e,0x30,0x30,0x36,0x2d,0x30, - 0x2e,0x33,0x37,0x36,0x2d,0x30,0x2e,0x31,0x34,0x2d, - 0x31,0x2e,0x36,0x32,0x2d,0x31,0x2e,0x36,0x32,0x31, - 0x2d,0x31,0x2e,0x36,0x32,0x68,0x2d,0x31,0x30,0x2e, - 0x32,0x33,0x56,0x33,0x2e,0x31,0x32,0x31,0x43,0x32, - 0x33,0x2e,0x37,0x30,0x31,0x2c,0x32,0x2e,0x37,0x34, - 0x35,0x2c,0x32,0x33,0x2e,0x35,0x36,0x37,0x2c,0x31, - 0x2e,0x35,0x2c,0x32,0x32,0x2e,0x30,0x38,0x36,0x2c, - 0x31,0x2e,0x35,0x68,0x2d,0x37,0x2e,0x31,0x31,0x31, - 0x0d,0x0a,0x09,0x09,0x09,0x09,0x63,0x2d,0x30,0x2e, - 0x33,0x37,0x36,0x2c,0x30,0x2e,0x30,0x30,0x36,0x2d, - 0x31,0x2e,0x36,0x31,0x39,0x2c,0x30,0x2e,0x31,0x34, - 0x2d,0x31,0x2e,0x36,0x31,0x39,0x2c,0x31,0x2e,0x36, - 0x32,0x31,0x76,0x31,0x30,0x2e,0x32,0x33,0x32,0x4c, - 0x33,0x2e,0x31,0x32,0x31,0x2c,0x31,0x33,0x2e,0x33, - 0x35,0x34,0x4c,0x33,0x2e,0x31,0x32,0x31,0x2c,0x31, - 0x33,0x2e,0x33,0x35,0x34,0x7a,0x22,0x2f,0x3e,0x0d, - 0x0a,0x09,0x09,0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x09, - 0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x09,0x3c,0x67,0x3e, - 0x0d,0x0a,0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20, - 0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46, - 0x46,0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x31, - 0x38,0x2e,0x35,0x33,0x31,0x2c,0x32,0x32,0x2e,0x31, - 0x38,0x31,0x63,0x2d,0x32,0x2e,0x30,0x31,0x33,0x2c, - 0x30,0x2d,0x33,0x2e,0x36,0x34,0x39,0x2d,0x31,0x2e, - 0x36,0x33,0x39,0x2d,0x33,0x2e,0x36,0x34,0x39,0x2d, - 0x33,0x2e,0x36,0x35,0x31,0x73,0x31,0x2e,0x36,0x33, - 0x38,0x2d,0x33,0x2e,0x36,0x35,0x2c,0x33,0x2e,0x36, - 0x34,0x39,0x2d,0x33,0x2e,0x36,0x35,0x63,0x32,0x2e, - 0x30,0x31,0x33,0x2c,0x30,0x2c,0x33,0x2e,0x36,0x35, - 0x2c,0x31,0x2e,0x36,0x33,0x39,0x2c,0x33,0x2e,0x36, - 0x35,0x2c,0x33,0x2e,0x36,0x35,0x0d,0x0a,0x09,0x09, + 0x2d,0x31,0x2e,0x36,0x32,0x31,0x76,0x2d,0x37,0x2e, + 0x31,0x31,0x0a,0x09,0x09,0x09,0x09,0x63,0x2d,0x30, + 0x2e,0x30,0x30,0x36,0x2d,0x30,0x2e,0x33,0x37,0x36, + 0x2d,0x30,0x2e,0x31,0x34,0x2d,0x31,0x2e,0x36,0x32, + 0x2d,0x31,0x2e,0x36,0x32,0x31,0x2d,0x31,0x2e,0x36, + 0x32,0x68,0x2d,0x31,0x30,0x2e,0x32,0x33,0x56,0x33, + 0x2e,0x31,0x32,0x31,0x43,0x32,0x33,0x2e,0x37,0x30, + 0x31,0x2c,0x32,0x2e,0x37,0x34,0x35,0x2c,0x32,0x33, + 0x2e,0x35,0x36,0x37,0x2c,0x31,0x2e,0x35,0x2c,0x32, + 0x32,0x2e,0x30,0x38,0x36,0x2c,0x31,0x2e,0x35,0x68, + 0x2d,0x37,0x2e,0x31,0x31,0x31,0x0a,0x09,0x09,0x09, + 0x09,0x63,0x2d,0x30,0x2e,0x33,0x37,0x36,0x2c,0x30, + 0x2e,0x30,0x30,0x36,0x2d,0x31,0x2e,0x36,0x31,0x39, + 0x2c,0x30,0x2e,0x31,0x34,0x2d,0x31,0x2e,0x36,0x31, + 0x39,0x2c,0x31,0x2e,0x36,0x32,0x31,0x76,0x31,0x30, + 0x2e,0x32,0x33,0x32,0x4c,0x33,0x2e,0x31,0x32,0x31, + 0x2c,0x31,0x33,0x2e,0x33,0x35,0x34,0x4c,0x33,0x2e, + 0x31,0x32,0x31,0x2c,0x31,0x33,0x2e,0x33,0x35,0x34, + 0x7a,0x22,0x2f,0x3e,0x0a,0x09,0x09,0x3c,0x2f,0x67, + 0x3e,0x0a,0x09,0x3c,0x2f,0x67,0x3e,0x0a,0x09,0x3c, + 0x67,0x3e,0x0a,0x09,0x09,0x3c,0x70,0x61,0x74,0x68, + 0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46, + 0x46,0x46,0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d, + 0x31,0x38,0x2e,0x35,0x33,0x31,0x2c,0x32,0x32,0x2e, + 0x31,0x38,0x31,0x63,0x2d,0x32,0x2e,0x30,0x31,0x33, + 0x2c,0x30,0x2d,0x33,0x2e,0x36,0x34,0x39,0x2d,0x31, + 0x2e,0x36,0x33,0x39,0x2d,0x33,0x2e,0x36,0x34,0x39, + 0x2d,0x33,0x2e,0x36,0x35,0x31,0x73,0x31,0x2e,0x36, + 0x33,0x38,0x2d,0x33,0x2e,0x36,0x35,0x2c,0x33,0x2e, + 0x36,0x34,0x39,0x2d,0x33,0x2e,0x36,0x35,0x63,0x32, + 0x2e,0x30,0x31,0x33,0x2c,0x30,0x2c,0x33,0x2e,0x36, + 0x35,0x2c,0x31,0x2e,0x36,0x33,0x39,0x2c,0x33,0x2e, + 0x36,0x35,0x2c,0x33,0x2e,0x36,0x35,0x0a,0x09,0x09, 0x09,0x43,0x32,0x32,0x2e,0x31,0x38,0x32,0x2c,0x32, 0x30,0x2e,0x35,0x34,0x33,0x2c,0x32,0x30,0x2e,0x35, 0x34,0x34,0x2c,0x32,0x32,0x2e,0x31,0x38,0x31,0x2c, @@ -162,56 +160,55 @@ const unsigned char help_dpad_leftright_svg_data[3290] = { 0x2d,0x32,0x2e,0x31,0x34,0x39,0x2c,0x32,0x2e,0x31, 0x35,0x73,0x30,0x2e,0x39,0x36,0x35,0x2c,0x32,0x2e, 0x31,0x35,0x31,0x2c,0x32,0x2e,0x31,0x34,0x39,0x2c, - 0x32,0x2e,0x31,0x35,0x31,0x0d,0x0a,0x09,0x09,0x09, - 0x63,0x31,0x2e,0x31,0x38,0x36,0x2c,0x30,0x2c,0x32, - 0x2e,0x31,0x35,0x2d,0x30,0x2e,0x39,0x36,0x36,0x2c, - 0x32,0x2e,0x31,0x35,0x2d,0x32,0x2e,0x31,0x35,0x31, - 0x43,0x32,0x30,0x2e,0x36,0x38,0x32,0x2c,0x31,0x37, - 0x2e,0x33,0x34,0x34,0x2c,0x31,0x39,0x2e,0x37,0x31, - 0x37,0x2c,0x31,0x36,0x2e,0x33,0x37,0x39,0x2c,0x31, - 0x38,0x2e,0x35,0x33,0x31,0x2c,0x31,0x36,0x2e,0x33, - 0x37,0x39,0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x09,0x3c, - 0x2f,0x67,0x3e,0x0d,0x0a,0x09,0x3c,0x67,0x3e,0x0d, + 0x32,0x2e,0x31,0x35,0x31,0x0a,0x09,0x09,0x09,0x63, + 0x31,0x2e,0x31,0x38,0x36,0x2c,0x30,0x2c,0x32,0x2e, + 0x31,0x35,0x2d,0x30,0x2e,0x39,0x36,0x36,0x2c,0x32, + 0x2e,0x31,0x35,0x2d,0x32,0x2e,0x31,0x35,0x31,0x43, + 0x32,0x30,0x2e,0x36,0x38,0x32,0x2c,0x31,0x37,0x2e, + 0x33,0x34,0x34,0x2c,0x31,0x39,0x2e,0x37,0x31,0x37, + 0x2c,0x31,0x36,0x2e,0x33,0x37,0x39,0x2c,0x31,0x38, + 0x2e,0x35,0x33,0x31,0x2c,0x31,0x36,0x2e,0x33,0x37, + 0x39,0x7a,0x22,0x2f,0x3e,0x0a,0x09,0x3c,0x2f,0x67, + 0x3e,0x0a,0x09,0x3c,0x67,0x3e,0x0a,0x09,0x09,0x3c, + 0x70,0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d, + 0x22,0x23,0x46,0x46,0x46,0x46,0x46,0x46,0x22,0x20, + 0x64,0x3d,0x22,0x4d,0x32,0x31,0x2e,0x35,0x33,0x36, + 0x2c,0x38,0x2e,0x36,0x31,0x36,0x68,0x2d,0x36,0x2e, + 0x30,0x31,0x32,0x63,0x2d,0x30,0x2e,0x32,0x37,0x33, + 0x2c,0x30,0x2d,0x30,0x2e,0x35,0x32,0x35,0x2d,0x30, + 0x2e,0x31,0x35,0x2d,0x30,0x2e,0x36,0x35,0x37,0x2d, + 0x30,0x2e,0x33,0x39,0x63,0x2d,0x30,0x2e,0x31,0x33, + 0x32,0x2d,0x30,0x2e,0x32,0x34,0x31,0x2d,0x30,0x2e, + 0x31,0x32,0x31,0x2d,0x30,0x2e,0x35,0x33,0x34,0x2c, + 0x30,0x2e,0x30,0x32,0x36,0x2d,0x30,0x2e,0x37,0x36, + 0x36,0x6c,0x33,0x2e,0x30,0x30,0x35,0x2d,0x34,0x2e, + 0x36,0x38,0x34,0x0a,0x09,0x09,0x09,0x63,0x30,0x2e, + 0x32,0x37,0x36,0x2d,0x30,0x2e,0x34,0x33,0x31,0x2c, + 0x30,0x2e,0x39,0x38,0x36,0x2d,0x30,0x2e,0x34,0x33, + 0x2c,0x31,0x2e,0x32,0x36,0x34,0x2c,0x30,0x6c,0x33, + 0x2e,0x30,0x30,0x35,0x2c,0x34,0x2e,0x36,0x38,0x34, + 0x63,0x30,0x2e,0x31,0x34,0x37,0x2c,0x30,0x2e,0x32, + 0x33,0x31,0x2c,0x30,0x2e,0x31,0x35,0x39,0x2c,0x30, + 0x2e,0x35,0x32,0x34,0x2c,0x30,0x2e,0x30,0x32,0x36, + 0x2c,0x30,0x2e,0x37,0x36,0x36,0x43,0x32,0x32,0x2e, + 0x30,0x36,0x33,0x2c,0x38,0x2e,0x34,0x36,0x36,0x2c, + 0x32,0x31,0x2e,0x38,0x31,0x31,0x2c,0x38,0x2e,0x36, + 0x31,0x36,0x2c,0x32,0x31,0x2e,0x35,0x33,0x36,0x2c, + 0x38,0x2e,0x36,0x31,0x36,0x7a,0x0a,0x09,0x09,0x09, + 0x20,0x4d,0x31,0x36,0x2e,0x38,0x39,0x37,0x2c,0x37, + 0x2e,0x31,0x31,0x36,0x68,0x33,0x2e,0x32,0x36,0x38, + 0x4c,0x31,0x38,0x2e,0x35,0x33,0x2c,0x34,0x2e,0x35, + 0x37,0x31,0x4c,0x31,0x36,0x2e,0x38,0x39,0x37,0x2c, + 0x37,0x2e,0x31,0x31,0x36,0x7a,0x22,0x2f,0x3e,0x0a, + 0x09,0x3c,0x2f,0x67,0x3e,0x0a,0x09,0x3c,0x67,0x3e, 0x0a,0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66, 0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46, - 0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x32,0x31, - 0x2e,0x35,0x33,0x36,0x2c,0x38,0x2e,0x36,0x31,0x36, - 0x68,0x2d,0x36,0x2e,0x30,0x31,0x32,0x63,0x2d,0x30, - 0x2e,0x32,0x37,0x33,0x2c,0x30,0x2d,0x30,0x2e,0x35, - 0x32,0x35,0x2d,0x30,0x2e,0x31,0x35,0x2d,0x30,0x2e, - 0x36,0x35,0x37,0x2d,0x30,0x2e,0x33,0x39,0x63,0x2d, - 0x30,0x2e,0x31,0x33,0x32,0x2d,0x30,0x2e,0x32,0x34, - 0x31,0x2d,0x30,0x2e,0x31,0x32,0x31,0x2d,0x30,0x2e, - 0x35,0x33,0x34,0x2c,0x30,0x2e,0x30,0x32,0x36,0x2d, - 0x30,0x2e,0x37,0x36,0x36,0x6c,0x33,0x2e,0x30,0x30, - 0x35,0x2d,0x34,0x2e,0x36,0x38,0x34,0x0d,0x0a,0x09, - 0x09,0x09,0x63,0x30,0x2e,0x32,0x37,0x36,0x2d,0x30, - 0x2e,0x34,0x33,0x31,0x2c,0x30,0x2e,0x39,0x38,0x36, - 0x2d,0x30,0x2e,0x34,0x33,0x2c,0x31,0x2e,0x32,0x36, - 0x34,0x2c,0x30,0x6c,0x33,0x2e,0x30,0x30,0x35,0x2c, - 0x34,0x2e,0x36,0x38,0x34,0x63,0x30,0x2e,0x31,0x34, - 0x37,0x2c,0x30,0x2e,0x32,0x33,0x31,0x2c,0x30,0x2e, - 0x31,0x35,0x39,0x2c,0x30,0x2e,0x35,0x32,0x34,0x2c, - 0x30,0x2e,0x30,0x32,0x36,0x2c,0x30,0x2e,0x37,0x36, - 0x36,0x43,0x32,0x32,0x2e,0x30,0x36,0x33,0x2c,0x38, - 0x2e,0x34,0x36,0x36,0x2c,0x32,0x31,0x2e,0x38,0x31, - 0x31,0x2c,0x38,0x2e,0x36,0x31,0x36,0x2c,0x32,0x31, - 0x2e,0x35,0x33,0x36,0x2c,0x38,0x2e,0x36,0x31,0x36, - 0x7a,0x0d,0x0a,0x09,0x09,0x09,0x20,0x4d,0x31,0x36, - 0x2e,0x38,0x39,0x37,0x2c,0x37,0x2e,0x31,0x31,0x36, - 0x68,0x33,0x2e,0x32,0x36,0x38,0x4c,0x31,0x38,0x2e, - 0x35,0x33,0x2c,0x34,0x2e,0x35,0x37,0x31,0x4c,0x31, - 0x36,0x2e,0x38,0x39,0x37,0x2c,0x37,0x2e,0x31,0x31, - 0x36,0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x09,0x3c,0x2f, - 0x67,0x3e,0x0d,0x0a,0x09,0x3c,0x67,0x3e,0x0d,0x0a, - 0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69, - 0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46, - 0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x33,0x2e,0x31, - 0x32,0x35,0x2c,0x31,0x38,0x2e,0x35,0x33,0x6c,0x34, - 0x2e,0x36,0x38,0x34,0x2c,0x33,0x2e,0x30,0x30,0x34, - 0x76,0x2d,0x36,0x2e,0x30,0x31,0x4c,0x33,0x2e,0x31, - 0x32,0x35,0x2c,0x31,0x38,0x2e,0x35,0x33,0x7a,0x22, - 0x2f,0x3e,0x0d,0x0a,0x09,0x09,0x3c,0x70,0x61,0x74, + 0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x33,0x2e, + 0x31,0x32,0x35,0x2c,0x31,0x38,0x2e,0x35,0x33,0x6c, + 0x34,0x2e,0x36,0x38,0x34,0x2c,0x33,0x2e,0x30,0x30, + 0x34,0x76,0x2d,0x36,0x2e,0x30,0x31,0x4c,0x33,0x2e, + 0x31,0x32,0x35,0x2c,0x31,0x38,0x2e,0x35,0x33,0x7a, + 0x22,0x2f,0x3e,0x0a,0x09,0x09,0x3c,0x70,0x61,0x74, 0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46, 0x46,0x46,0x46,0x46,0x46,0x22,0x20,0x64,0x3d,0x22, 0x4d,0x37,0x2e,0x38,0x30,0x39,0x2c,0x32,0x32,0x2e, @@ -223,114 +220,114 @@ const unsigned char help_dpad_leftright_svg_data[3290] = { 0x2e,0x32,0x31,0x35,0x2d,0x30,0x2e,0x31,0x33,0x38, 0x2d,0x30,0x2e,0x33,0x34,0x35,0x2d,0x30,0x2e,0x33, 0x37,0x36,0x2d,0x30,0x2e,0x33,0x34,0x35,0x2d,0x30, - 0x2e,0x36,0x33,0x31,0x0d,0x0a,0x09,0x09,0x09,0x73, - 0x30,0x2e,0x31,0x33,0x2d,0x30,0x2e,0x34,0x39,0x33, - 0x2c,0x30,0x2e,0x33,0x34,0x35,0x2d,0x30,0x2e,0x36, - 0x33,0x31,0x6c,0x34,0x2e,0x36,0x38,0x34,0x2d,0x33, - 0x2e,0x30,0x30,0x36,0x63,0x30,0x2e,0x32,0x33,0x2d, - 0x30,0x2e,0x31,0x34,0x38,0x2c,0x30,0x2e,0x35,0x32, - 0x34,0x2d,0x30,0x2e,0x31,0x35,0x38,0x2c,0x30,0x2e, - 0x37,0x36,0x36,0x2d,0x30,0x2e,0x30,0x32,0x37,0x63, - 0x30,0x2e,0x32,0x34,0x2c,0x30,0x2e,0x31,0x33,0x31, - 0x2c,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2e,0x33,0x38, - 0x34,0x2c,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2e,0x36, - 0x35,0x38,0x76,0x36,0x2e,0x30,0x31,0x0d,0x0a,0x09, - 0x09,0x09,0x63,0x30,0x2c,0x30,0x2e,0x32,0x37,0x34, - 0x2d,0x30,0x2e,0x31,0x34,0x38,0x2c,0x30,0x2e,0x35, - 0x32,0x36,0x2d,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2e, - 0x36,0x35,0x38,0x43,0x38,0x2e,0x30,0x35,0x36,0x2c, - 0x32,0x32,0x2e,0x32,0x35,0x34,0x2c,0x37,0x2e,0x39, - 0x33,0x32,0x2c,0x32,0x32,0x2e,0x32,0x38,0x34,0x2c, - 0x37,0x2e,0x38,0x30,0x39,0x2c,0x32,0x32,0x2e,0x32, - 0x38,0x34,0x7a,0x20,0x4d,0x34,0x2e,0x35,0x31,0x34, - 0x2c,0x31,0x38,0x2e,0x35,0x33,0x6c,0x32,0x2e,0x35, - 0x34,0x35,0x2c,0x31,0x2e,0x36,0x33,0x32,0x76,0x2d, - 0x33,0x2e,0x32,0x36,0x35,0x4c,0x34,0x2e,0x35,0x31, - 0x34,0x2c,0x31,0x38,0x2e,0x35,0x33,0x7a,0x22,0x2f, - 0x3e,0x0d,0x0a,0x09,0x3c,0x2f,0x67,0x3e,0x0d,0x0a, - 0x09,0x3c,0x67,0x3e,0x0d,0x0a,0x09,0x09,0x3c,0x70, - 0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22, - 0x23,0x46,0x46,0x46,0x46,0x46,0x46,0x22,0x20,0x64, - 0x3d,0x22,0x4d,0x33,0x33,0x2e,0x38,0x37,0x39,0x2c, - 0x31,0x38,0x2e,0x35,0x32,0x39,0x6c,0x2d,0x34,0x2e, - 0x36,0x38,0x35,0x2d,0x33,0x2e,0x30,0x30,0x35,0x76, - 0x36,0x2e,0x30,0x31,0x4c,0x33,0x33,0x2e,0x38,0x37, - 0x39,0x2c,0x31,0x38,0x2e,0x35,0x32,0x39,0x7a,0x22, - 0x2f,0x3e,0x0d,0x0a,0x09,0x09,0x3c,0x70,0x61,0x74, + 0x2e,0x36,0x33,0x31,0x0a,0x09,0x09,0x09,0x73,0x30, + 0x2e,0x31,0x33,0x2d,0x30,0x2e,0x34,0x39,0x33,0x2c, + 0x30,0x2e,0x33,0x34,0x35,0x2d,0x30,0x2e,0x36,0x33, + 0x31,0x6c,0x34,0x2e,0x36,0x38,0x34,0x2d,0x33,0x2e, + 0x30,0x30,0x36,0x63,0x30,0x2e,0x32,0x33,0x2d,0x30, + 0x2e,0x31,0x34,0x38,0x2c,0x30,0x2e,0x35,0x32,0x34, + 0x2d,0x30,0x2e,0x31,0x35,0x38,0x2c,0x30,0x2e,0x37, + 0x36,0x36,0x2d,0x30,0x2e,0x30,0x32,0x37,0x63,0x30, + 0x2e,0x32,0x34,0x2c,0x30,0x2e,0x31,0x33,0x31,0x2c, + 0x30,0x2e,0x33,0x39,0x2c,0x30,0x2e,0x33,0x38,0x34, + 0x2c,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2e,0x36,0x35, + 0x38,0x76,0x36,0x2e,0x30,0x31,0x0a,0x09,0x09,0x09, + 0x63,0x30,0x2c,0x30,0x2e,0x32,0x37,0x34,0x2d,0x30, + 0x2e,0x31,0x34,0x38,0x2c,0x30,0x2e,0x35,0x32,0x36, + 0x2d,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2e,0x36,0x35, + 0x38,0x43,0x38,0x2e,0x30,0x35,0x36,0x2c,0x32,0x32, + 0x2e,0x32,0x35,0x34,0x2c,0x37,0x2e,0x39,0x33,0x32, + 0x2c,0x32,0x32,0x2e,0x32,0x38,0x34,0x2c,0x37,0x2e, + 0x38,0x30,0x39,0x2c,0x32,0x32,0x2e,0x32,0x38,0x34, + 0x7a,0x20,0x4d,0x34,0x2e,0x35,0x31,0x34,0x2c,0x31, + 0x38,0x2e,0x35,0x33,0x6c,0x32,0x2e,0x35,0x34,0x35, + 0x2c,0x31,0x2e,0x36,0x33,0x32,0x76,0x2d,0x33,0x2e, + 0x32,0x36,0x35,0x4c,0x34,0x2e,0x35,0x31,0x34,0x2c, + 0x31,0x38,0x2e,0x35,0x33,0x7a,0x22,0x2f,0x3e,0x0a, + 0x09,0x3c,0x2f,0x67,0x3e,0x0a,0x09,0x3c,0x67,0x3e, + 0x0a,0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66, + 0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46, + 0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x33,0x33, + 0x2e,0x38,0x37,0x39,0x2c,0x31,0x38,0x2e,0x35,0x32, + 0x39,0x6c,0x2d,0x34,0x2e,0x36,0x38,0x35,0x2d,0x33, + 0x2e,0x30,0x30,0x35,0x76,0x36,0x2e,0x30,0x31,0x4c, + 0x33,0x33,0x2e,0x38,0x37,0x39,0x2c,0x31,0x38,0x2e, + 0x35,0x32,0x39,0x7a,0x22,0x2f,0x3e,0x0a,0x09,0x09, + 0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c, + 0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46,0x46,0x22, + 0x20,0x64,0x3d,0x22,0x4d,0x32,0x39,0x2e,0x31,0x39, + 0x35,0x2c,0x32,0x32,0x2e,0x32,0x38,0x34,0x63,0x2d, + 0x30,0x2e,0x31,0x32,0x34,0x2c,0x30,0x2d,0x30,0x2e, + 0x32,0x34,0x36,0x2d,0x30,0x2e,0x30,0x33,0x2d,0x30, + 0x2e,0x33,0x35,0x38,0x2d,0x30,0x2e,0x30,0x39,0x32, + 0x63,0x2d,0x30,0x2e,0x32,0x34,0x31,0x2d,0x30,0x2e, + 0x31,0x33,0x32,0x2d,0x30,0x2e,0x33,0x39,0x32,0x2d, + 0x30,0x2e,0x33,0x38,0x34,0x2d,0x30,0x2e,0x33,0x39, + 0x32,0x2d,0x30,0x2e,0x36,0x35,0x38,0x76,0x2d,0x36, + 0x2e,0x30,0x31,0x0a,0x09,0x09,0x09,0x63,0x30,0x2d, + 0x30,0x2e,0x32,0x37,0x34,0x2c,0x30,0x2e,0x31,0x34, + 0x39,0x2d,0x30,0x2e,0x35,0x32,0x36,0x2c,0x30,0x2e, + 0x33,0x39,0x32,0x2d,0x30,0x2e,0x36,0x35,0x38,0x63, + 0x30,0x2e,0x32,0x33,0x39,0x2d,0x30,0x2e,0x31,0x33, + 0x31,0x2c,0x30,0x2e,0x35,0x33,0x33,0x2d,0x30,0x2e, + 0x31,0x32,0x33,0x2c,0x30,0x2e,0x37,0x36,0x35,0x2c, + 0x30,0x2e,0x30,0x32,0x37,0x6c,0x34,0x2e,0x36,0x38, + 0x35,0x2c,0x33,0x2e,0x30,0x30,0x35,0x63,0x30,0x2e, + 0x32,0x31,0x35,0x2c,0x30,0x2e,0x31,0x33,0x38,0x2c, + 0x30,0x2e,0x33,0x34,0x35,0x2c,0x30,0x2e,0x33,0x37, + 0x36,0x2c,0x30,0x2e,0x33,0x34,0x35,0x2c,0x30,0x2e, + 0x36,0x33,0x31,0x0a,0x09,0x09,0x09,0x73,0x2d,0x30, + 0x2e,0x31,0x33,0x2c,0x30,0x2e,0x34,0x39,0x33,0x2d, + 0x30,0x2e,0x33,0x34,0x35,0x2c,0x30,0x2e,0x36,0x33, + 0x31,0x6c,0x2d,0x34,0x2e,0x36,0x38,0x35,0x2c,0x33, + 0x2e,0x30,0x30,0x34,0x43,0x32,0x39,0x2e,0x34,0x37, + 0x38,0x2c,0x32,0x32,0x2e,0x32,0x34,0x34,0x2c,0x32, + 0x39,0x2e,0x33,0x33,0x36,0x2c,0x32,0x32,0x2e,0x32, + 0x38,0x34,0x2c,0x32,0x39,0x2e,0x31,0x39,0x35,0x2c, + 0x32,0x32,0x2e,0x32,0x38,0x34,0x7a,0x20,0x4d,0x32, + 0x39,0x2e,0x39,0x34,0x35,0x2c,0x31,0x36,0x2e,0x38, + 0x39,0x36,0x76,0x33,0x2e,0x32,0x36,0x36,0x6c,0x32, + 0x2e,0x35,0x34,0x36,0x2d,0x31,0x2e,0x36,0x33,0x33, + 0x0a,0x09,0x09,0x09,0x4c,0x32,0x39,0x2e,0x39,0x34, + 0x35,0x2c,0x31,0x36,0x2e,0x38,0x39,0x36,0x7a,0x22, + 0x2f,0x3e,0x0a,0x09,0x3c,0x2f,0x67,0x3e,0x0a,0x09, + 0x3c,0x67,0x3e,0x0a,0x09,0x09,0x3c,0x70,0x61,0x74, 0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46, 0x46,0x46,0x46,0x46,0x46,0x22,0x20,0x64,0x3d,0x22, - 0x4d,0x32,0x39,0x2e,0x31,0x39,0x35,0x2c,0x32,0x32, - 0x2e,0x32,0x38,0x34,0x63,0x2d,0x30,0x2e,0x31,0x32, - 0x34,0x2c,0x30,0x2d,0x30,0x2e,0x32,0x34,0x36,0x2d, - 0x30,0x2e,0x30,0x33,0x2d,0x30,0x2e,0x33,0x35,0x38, - 0x2d,0x30,0x2e,0x30,0x39,0x32,0x63,0x2d,0x30,0x2e, - 0x32,0x34,0x31,0x2d,0x30,0x2e,0x31,0x33,0x32,0x2d, - 0x30,0x2e,0x33,0x39,0x32,0x2d,0x30,0x2e,0x33,0x38, - 0x34,0x2d,0x30,0x2e,0x33,0x39,0x32,0x2d,0x30,0x2e, - 0x36,0x35,0x38,0x76,0x2d,0x36,0x2e,0x30,0x31,0x0d, - 0x0a,0x09,0x09,0x09,0x63,0x30,0x2d,0x30,0x2e,0x32, - 0x37,0x34,0x2c,0x30,0x2e,0x31,0x34,0x39,0x2d,0x30, - 0x2e,0x35,0x32,0x36,0x2c,0x30,0x2e,0x33,0x39,0x32, - 0x2d,0x30,0x2e,0x36,0x35,0x38,0x63,0x30,0x2e,0x32, - 0x33,0x39,0x2d,0x30,0x2e,0x31,0x33,0x31,0x2c,0x30, - 0x2e,0x35,0x33,0x33,0x2d,0x30,0x2e,0x31,0x32,0x33, - 0x2c,0x30,0x2e,0x37,0x36,0x35,0x2c,0x30,0x2e,0x30, - 0x32,0x37,0x6c,0x34,0x2e,0x36,0x38,0x35,0x2c,0x33, - 0x2e,0x30,0x30,0x35,0x63,0x30,0x2e,0x32,0x31,0x35, - 0x2c,0x30,0x2e,0x31,0x33,0x38,0x2c,0x30,0x2e,0x33, - 0x34,0x35,0x2c,0x30,0x2e,0x33,0x37,0x36,0x2c,0x30, - 0x2e,0x33,0x34,0x35,0x2c,0x30,0x2e,0x36,0x33,0x31, - 0x0d,0x0a,0x09,0x09,0x09,0x73,0x2d,0x30,0x2e,0x31, - 0x33,0x2c,0x30,0x2e,0x34,0x39,0x33,0x2d,0x30,0x2e, - 0x33,0x34,0x35,0x2c,0x30,0x2e,0x36,0x33,0x31,0x6c, - 0x2d,0x34,0x2e,0x36,0x38,0x35,0x2c,0x33,0x2e,0x30, - 0x30,0x34,0x43,0x32,0x39,0x2e,0x34,0x37,0x38,0x2c, - 0x32,0x32,0x2e,0x32,0x34,0x34,0x2c,0x32,0x39,0x2e, - 0x33,0x33,0x36,0x2c,0x32,0x32,0x2e,0x32,0x38,0x34, - 0x2c,0x32,0x39,0x2e,0x31,0x39,0x35,0x2c,0x32,0x32, - 0x2e,0x32,0x38,0x34,0x7a,0x20,0x4d,0x32,0x39,0x2e, - 0x39,0x34,0x35,0x2c,0x31,0x36,0x2e,0x38,0x39,0x36, - 0x76,0x33,0x2e,0x32,0x36,0x36,0x6c,0x32,0x2e,0x35, - 0x34,0x36,0x2d,0x31,0x2e,0x36,0x33,0x33,0x0d,0x0a, - 0x09,0x09,0x09,0x4c,0x32,0x39,0x2e,0x39,0x34,0x35, - 0x2c,0x31,0x36,0x2e,0x38,0x39,0x36,0x7a,0x22,0x2f, - 0x3e,0x0d,0x0a,0x09,0x3c,0x2f,0x67,0x3e,0x0d,0x0a, - 0x09,0x3c,0x67,0x3e,0x0d,0x0a,0x09,0x09,0x3c,0x70, - 0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22, - 0x23,0x46,0x46,0x46,0x46,0x46,0x46,0x22,0x20,0x64, - 0x3d,0x22,0x4d,0x31,0x38,0x2e,0x35,0x33,0x2c,0x33, - 0x34,0x2e,0x36,0x32,0x36,0x4c,0x31,0x38,0x2e,0x35, - 0x33,0x2c,0x33,0x34,0x2e,0x36,0x32,0x36,0x63,0x2d, - 0x30,0x2e,0x32,0x35,0x35,0x2c,0x30,0x2d,0x30,0x2e, - 0x34,0x39,0x32,0x2d,0x30,0x2e,0x31,0x33,0x2d,0x30, - 0x2e,0x36,0x33,0x31,0x2d,0x30,0x2e,0x33,0x34,0x35, - 0x6c,0x2d,0x33,0x2e,0x30,0x30,0x35,0x2d,0x34,0x2e, - 0x36,0x38,0x34,0x0d,0x0a,0x09,0x09,0x09,0x63,0x2d, - 0x30,0x2e,0x31,0x34,0x37,0x2d,0x30,0x2e,0x32,0x33, - 0x31,0x2d,0x30,0x2e,0x31,0x35,0x38,0x2d,0x30,0x2e, - 0x35,0x32,0x34,0x2d,0x30,0x2e,0x30,0x32,0x36,0x2d, - 0x30,0x2e,0x37,0x36,0x36,0x73,0x30,0x2e,0x33,0x38, - 0x34,0x2d,0x30,0x2e,0x33,0x39,0x31,0x2c,0x30,0x2e, - 0x36,0x35,0x37,0x2d,0x30,0x2e,0x33,0x39,0x31,0x68, - 0x36,0x2e,0x30,0x31,0x32,0x63,0x30,0x2e,0x32,0x37, - 0x33,0x2c,0x30,0x2c,0x30,0x2e,0x35,0x32,0x35,0x2c, - 0x30,0x2e,0x31,0x34,0x38,0x2c,0x30,0x2e,0x36,0x35, - 0x37,0x2c,0x30,0x2e,0x33,0x39,0x31,0x0d,0x0a,0x09, - 0x09,0x09,0x63,0x30,0x2e,0x31,0x33,0x33,0x2c,0x30, - 0x2e,0x32,0x34,0x2c,0x30,0x2e,0x31,0x32,0x31,0x2c, - 0x30,0x2e,0x35,0x33,0x33,0x2d,0x30,0x2e,0x30,0x32, - 0x36,0x2c,0x30,0x2e,0x37,0x36,0x36,0x6c,0x2d,0x33, - 0x2e,0x30,0x30,0x35,0x2c,0x34,0x2e,0x36,0x38,0x34, - 0x43,0x31,0x39,0x2e,0x30,0x32,0x33,0x2c,0x33,0x34, - 0x2e,0x34,0x39,0x36,0x2c,0x31,0x38,0x2e,0x37,0x38, - 0x36,0x2c,0x33,0x34,0x2e,0x36,0x32,0x36,0x2c,0x31, - 0x38,0x2e,0x35,0x33,0x2c,0x33,0x34,0x2e,0x36,0x32, - 0x36,0x7a,0x20,0x4d,0x31,0x36,0x2e,0x38,0x39,0x37, - 0x2c,0x32,0x39,0x2e,0x39,0x34,0x32,0x6c,0x31,0x2e, - 0x36,0x33,0x33,0x2c,0x32,0x2e,0x35,0x34,0x35,0x0d, - 0x0a,0x09,0x09,0x09,0x6c,0x31,0x2e,0x36,0x33,0x35, - 0x2d,0x32,0x2e,0x35,0x34,0x35,0x48,0x31,0x36,0x2e, - 0x38,0x39,0x37,0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x09, - 0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x3c,0x2f,0x67,0x3e, - 0x0d,0x0a,0x3c,0x2f,0x73,0x76,0x67,0x3e,0x0d,0x0a + 0x4d,0x31,0x38,0x2e,0x35,0x33,0x2c,0x33,0x34,0x2e, + 0x36,0x32,0x36,0x4c,0x31,0x38,0x2e,0x35,0x33,0x2c, + 0x33,0x34,0x2e,0x36,0x32,0x36,0x63,0x2d,0x30,0x2e, + 0x32,0x35,0x35,0x2c,0x30,0x2d,0x30,0x2e,0x34,0x39, + 0x32,0x2d,0x30,0x2e,0x31,0x33,0x2d,0x30,0x2e,0x36, + 0x33,0x31,0x2d,0x30,0x2e,0x33,0x34,0x35,0x6c,0x2d, + 0x33,0x2e,0x30,0x30,0x35,0x2d,0x34,0x2e,0x36,0x38, + 0x34,0x0a,0x09,0x09,0x09,0x63,0x2d,0x30,0x2e,0x31, + 0x34,0x37,0x2d,0x30,0x2e,0x32,0x33,0x31,0x2d,0x30, + 0x2e,0x31,0x35,0x38,0x2d,0x30,0x2e,0x35,0x32,0x34, + 0x2d,0x30,0x2e,0x30,0x32,0x36,0x2d,0x30,0x2e,0x37, + 0x36,0x36,0x73,0x30,0x2e,0x33,0x38,0x34,0x2d,0x30, + 0x2e,0x33,0x39,0x31,0x2c,0x30,0x2e,0x36,0x35,0x37, + 0x2d,0x30,0x2e,0x33,0x39,0x31,0x68,0x36,0x2e,0x30, + 0x31,0x32,0x63,0x30,0x2e,0x32,0x37,0x33,0x2c,0x30, + 0x2c,0x30,0x2e,0x35,0x32,0x35,0x2c,0x30,0x2e,0x31, + 0x34,0x38,0x2c,0x30,0x2e,0x36,0x35,0x37,0x2c,0x30, + 0x2e,0x33,0x39,0x31,0x0a,0x09,0x09,0x09,0x63,0x30, + 0x2e,0x31,0x33,0x33,0x2c,0x30,0x2e,0x32,0x34,0x2c, + 0x30,0x2e,0x31,0x32,0x31,0x2c,0x30,0x2e,0x35,0x33, + 0x33,0x2d,0x30,0x2e,0x30,0x32,0x36,0x2c,0x30,0x2e, + 0x37,0x36,0x36,0x6c,0x2d,0x33,0x2e,0x30,0x30,0x35, + 0x2c,0x34,0x2e,0x36,0x38,0x34,0x43,0x31,0x39,0x2e, + 0x30,0x32,0x33,0x2c,0x33,0x34,0x2e,0x34,0x39,0x36, + 0x2c,0x31,0x38,0x2e,0x37,0x38,0x36,0x2c,0x33,0x34, + 0x2e,0x36,0x32,0x36,0x2c,0x31,0x38,0x2e,0x35,0x33, + 0x2c,0x33,0x34,0x2e,0x36,0x32,0x36,0x7a,0x20,0x4d, + 0x31,0x36,0x2e,0x38,0x39,0x37,0x2c,0x32,0x39,0x2e, + 0x39,0x34,0x32,0x6c,0x31,0x2e,0x36,0x33,0x33,0x2c, + 0x32,0x2e,0x35,0x34,0x35,0x0a,0x09,0x09,0x09,0x6c, + 0x31,0x2e,0x36,0x33,0x35,0x2d,0x32,0x2e,0x35,0x34, + 0x35,0x48,0x31,0x36,0x2e,0x38,0x39,0x37,0x7a,0x22, + 0x2f,0x3e,0x0a,0x09,0x3c,0x2f,0x67,0x3e,0x0a,0x3c, + 0x2f,0x67,0x3e,0x0a,0x3c,0x2f,0x73,0x76,0x67,0x3e, + 0x0a }; + diff --git a/data/converted/help_dpad_right_svg.cpp b/data/converted/help_dpad_right_svg.cpp index 0fb71669ba..214053557c 100644 --- a/data/converted/help_dpad_right_svg.cpp +++ b/data/converted/help_dpad_right_svg.cpp @@ -2,84 +2,83 @@ #include "../Resources.h" -const size_t help_dpad_right_svg_size = 3216; -const unsigned char help_dpad_right_svg_data[3216] = { +const size_t help_dpad_right_svg_size = 3168; +const unsigned char help_dpad_right_svg_data[3168] = { 0x3c,0x3f,0x78,0x6d,0x6c,0x20,0x76,0x65,0x72,0x73, 0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x30,0x22,0x20, 0x65,0x6e,0x63,0x6f,0x64,0x69,0x6e,0x67,0x3d,0x22, - 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0d,0x0a, - 0x3c,0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72, - 0x61,0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62, - 0x65,0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61, - 0x74,0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33, - 0x2c,0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f, - 0x72,0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e, - 0x20,0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72, - 0x73,0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30, - 0x20,0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20, - 0x20,0x2d,0x2d,0x3e,0x0d,0x0a,0x3c,0x21,0x44,0x4f, - 0x43,0x54,0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20, - 0x50,0x55,0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f, - 0x2f,0x57,0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20, - 0x53,0x56,0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45, - 0x4e,0x22,0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, - 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, - 0x67,0x2f,0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73, - 0x2f,0x53,0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44, - 0x54,0x44,0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64, - 0x74,0x64,0x22,0x3e,0x0d,0x0a,0x3c,0x73,0x76,0x67, - 0x20,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22, - 0x31,0x2e,0x31,0x22,0x20,0x69,0x64,0x3d,0x22,0x5f, - 0x78,0x33,0x30,0x5f,0x22,0x20,0x78,0x6d,0x6c,0x6e, - 0x73,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f, - 0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67, - 0x2f,0x32,0x30,0x30,0x30,0x2f,0x73,0x76,0x67,0x22, - 0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78,0x6c,0x69, - 0x6e,0x6b,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, - 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, - 0x67,0x2f,0x31,0x39,0x39,0x39,0x2f,0x78,0x6c,0x69, - 0x6e,0x6b,0x22,0x20,0x78,0x3d,0x22,0x30,0x70,0x78, - 0x22,0x20,0x79,0x3d,0x22,0x30,0x70,0x78,0x22,0x0d, - 0x0a,0x09,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22, - 0x33,0x37,0x2e,0x30,0x36,0x31,0x70,0x78,0x22,0x20, - 0x68,0x65,0x69,0x67,0x68,0x74,0x3d,0x22,0x33,0x37, - 0x2e,0x30,0x36,0x31,0x70,0x78,0x22,0x20,0x76,0x69, - 0x65,0x77,0x42,0x6f,0x78,0x3d,0x22,0x30,0x20,0x30, - 0x20,0x33,0x37,0x2e,0x30,0x36,0x31,0x20,0x33,0x37, - 0x2e,0x30,0x36,0x31,0x22,0x20,0x65,0x6e,0x61,0x62, - 0x6c,0x65,0x2d,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f, - 0x75,0x6e,0x64,0x3d,0x22,0x6e,0x65,0x77,0x20,0x30, - 0x20,0x30,0x20,0x33,0x37,0x2e,0x30,0x36,0x31,0x20, - 0x33,0x37,0x2e,0x30,0x36,0x31,0x22,0x20,0x78,0x6d, - 0x6c,0x3a,0x73,0x70,0x61,0x63,0x65,0x3d,0x22,0x70, - 0x72,0x65,0x73,0x65,0x72,0x76,0x65,0x22,0x3e,0x0d, - 0x0a,0x3c,0x67,0x3e,0x0d,0x0a,0x09,0x3c,0x67,0x3e, - 0x0d,0x0a,0x09,0x09,0x3c,0x67,0x3e,0x0d,0x0a,0x09, - 0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69, - 0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46, - 0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x32,0x32,0x2e, - 0x30,0x38,0x36,0x2c,0x33,0x37,0x2e,0x30,0x36,0x68, - 0x2d,0x37,0x2e,0x31,0x31,0x31,0x63,0x2d,0x32,0x2e, - 0x32,0x38,0x39,0x2c,0x30,0x2d,0x33,0x2e,0x31,0x31, - 0x39,0x2d,0x31,0x2e,0x38,0x36,0x36,0x2d,0x33,0x2e, - 0x31,0x31,0x39,0x2d,0x33,0x2e,0x31,0x32,0x31,0x76, - 0x2d,0x38,0x2e,0x37,0x33,0x32,0x48,0x33,0x2e,0x31, - 0x32,0x31,0x43,0x30,0x2e,0x38,0x33,0x31,0x2c,0x32, - 0x35,0x2e,0x32,0x30,0x36,0x2c,0x30,0x2c,0x32,0x33, - 0x2e,0x33,0x34,0x2c,0x30,0x2c,0x32,0x32,0x2e,0x30, - 0x38,0x35,0x0d,0x0a,0x09,0x09,0x09,0x09,0x76,0x2d, - 0x37,0x2e,0x31,0x31,0x63,0x30,0x2d,0x32,0x2e,0x32, - 0x38,0x39,0x2c,0x31,0x2e,0x38,0x36,0x37,0x2d,0x33, - 0x2e,0x31,0x32,0x2c,0x33,0x2e,0x31,0x32,0x31,0x2d, - 0x33,0x2e,0x31,0x32,0x68,0x38,0x2e,0x37,0x33,0x33, - 0x56,0x33,0x2e,0x31,0x32,0x31,0x43,0x31,0x31,0x2e, - 0x38,0x35,0x35,0x2c,0x30,0x2e,0x38,0x33,0x31,0x2c, - 0x31,0x33,0x2e,0x37,0x32,0x2c,0x30,0x2c,0x31,0x34, - 0x2e,0x39,0x37,0x34,0x2c,0x30,0x68,0x37,0x2e,0x31, - 0x31,0x31,0x63,0x32,0x2e,0x32,0x39,0x2c,0x30,0x2c, - 0x33,0x2e,0x31,0x32,0x31,0x2c,0x31,0x2e,0x38,0x36, - 0x37,0x2c,0x33,0x2e,0x31,0x32,0x31,0x2c,0x33,0x2e, - 0x31,0x32,0x31,0x76,0x38,0x2e,0x37,0x33,0x32,0x0d, + 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0a,0x3c, + 0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72,0x61, + 0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62,0x65, + 0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61,0x74, + 0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33,0x2c, + 0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f,0x72, + 0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e,0x20, + 0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72,0x73, + 0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30,0x20, + 0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20,0x20, + 0x2d,0x2d,0x3e,0x0a,0x3c,0x21,0x44,0x4f,0x43,0x54, + 0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20,0x50,0x55, + 0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f,0x2f,0x57, + 0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20,0x53,0x56, + 0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45,0x4e,0x22, + 0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73,0x2f,0x53, + 0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44,0x54,0x44, + 0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64,0x74,0x64, + 0x22,0x3e,0x0a,0x3c,0x73,0x76,0x67,0x20,0x76,0x65, + 0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x31, + 0x22,0x20,0x69,0x64,0x3d,0x22,0x5f,0x78,0x33,0x30, + 0x5f,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3d,0x22, + 0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77, + 0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f,0x32,0x30, + 0x30,0x30,0x2f,0x73,0x76,0x67,0x22,0x20,0x78,0x6d, + 0x6c,0x6e,0x73,0x3a,0x78,0x6c,0x69,0x6e,0x6b,0x3d, + 0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77, + 0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f,0x31, + 0x39,0x39,0x39,0x2f,0x78,0x6c,0x69,0x6e,0x6b,0x22, + 0x20,0x78,0x3d,0x22,0x30,0x70,0x78,0x22,0x20,0x79, + 0x3d,0x22,0x30,0x70,0x78,0x22,0x0a,0x09,0x20,0x77, + 0x69,0x64,0x74,0x68,0x3d,0x22,0x33,0x37,0x2e,0x30, + 0x36,0x31,0x70,0x78,0x22,0x20,0x68,0x65,0x69,0x67, + 0x68,0x74,0x3d,0x22,0x33,0x37,0x2e,0x30,0x36,0x31, + 0x70,0x78,0x22,0x20,0x76,0x69,0x65,0x77,0x42,0x6f, + 0x78,0x3d,0x22,0x30,0x20,0x30,0x20,0x33,0x37,0x2e, + 0x30,0x36,0x31,0x20,0x33,0x37,0x2e,0x30,0x36,0x31, + 0x22,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0x2d,0x62, + 0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x3d, + 0x22,0x6e,0x65,0x77,0x20,0x30,0x20,0x30,0x20,0x33, + 0x37,0x2e,0x30,0x36,0x31,0x20,0x33,0x37,0x2e,0x30, + 0x36,0x31,0x22,0x20,0x78,0x6d,0x6c,0x3a,0x73,0x70, + 0x61,0x63,0x65,0x3d,0x22,0x70,0x72,0x65,0x73,0x65, + 0x72,0x76,0x65,0x22,0x3e,0x0a,0x3c,0x67,0x3e,0x0a, + 0x09,0x3c,0x67,0x3e,0x0a,0x09,0x09,0x3c,0x67,0x3e, + 0x0a,0x09,0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20, + 0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46, + 0x46,0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x32, + 0x32,0x2e,0x30,0x38,0x36,0x2c,0x33,0x37,0x2e,0x30, + 0x36,0x68,0x2d,0x37,0x2e,0x31,0x31,0x31,0x63,0x2d, + 0x32,0x2e,0x32,0x38,0x39,0x2c,0x30,0x2d,0x33,0x2e, + 0x31,0x31,0x39,0x2d,0x31,0x2e,0x38,0x36,0x36,0x2d, + 0x33,0x2e,0x31,0x31,0x39,0x2d,0x33,0x2e,0x31,0x32, + 0x31,0x76,0x2d,0x38,0x2e,0x37,0x33,0x32,0x48,0x33, + 0x2e,0x31,0x32,0x31,0x43,0x30,0x2e,0x38,0x33,0x31, + 0x2c,0x32,0x35,0x2e,0x32,0x30,0x36,0x2c,0x30,0x2c, + 0x32,0x33,0x2e,0x33,0x34,0x2c,0x30,0x2c,0x32,0x32, + 0x2e,0x30,0x38,0x35,0x0a,0x09,0x09,0x09,0x09,0x76, + 0x2d,0x37,0x2e,0x31,0x31,0x63,0x30,0x2d,0x32,0x2e, + 0x32,0x38,0x39,0x2c,0x31,0x2e,0x38,0x36,0x37,0x2d, + 0x33,0x2e,0x31,0x32,0x2c,0x33,0x2e,0x31,0x32,0x31, + 0x2d,0x33,0x2e,0x31,0x32,0x68,0x38,0x2e,0x37,0x33, + 0x33,0x56,0x33,0x2e,0x31,0x32,0x31,0x43,0x31,0x31, + 0x2e,0x38,0x35,0x35,0x2c,0x30,0x2e,0x38,0x33,0x31, + 0x2c,0x31,0x33,0x2e,0x37,0x32,0x2c,0x30,0x2c,0x31, + 0x34,0x2e,0x39,0x37,0x34,0x2c,0x30,0x68,0x37,0x2e, + 0x31,0x31,0x31,0x63,0x32,0x2e,0x32,0x39,0x2c,0x30, + 0x2c,0x33,0x2e,0x31,0x32,0x31,0x2c,0x31,0x2e,0x38, + 0x36,0x37,0x2c,0x33,0x2e,0x31,0x32,0x31,0x2c,0x33, + 0x2e,0x31,0x32,0x31,0x76,0x38,0x2e,0x37,0x33,0x32, 0x0a,0x09,0x09,0x09,0x09,0x68,0x38,0x2e,0x37,0x33, 0x31,0x63,0x32,0x2e,0x32,0x39,0x2c,0x30,0x2c,0x33, 0x2e,0x31,0x32,0x31,0x2c,0x31,0x2e,0x38,0x36,0x35, @@ -89,68 +88,67 @@ const unsigned char help_dpad_right_svg_data[3216] = { 0x33,0x2e,0x31,0x32,0x31,0x2d,0x33,0x2e,0x31,0x32, 0x31,0x2c,0x33,0x2e,0x31,0x32,0x31,0x68,0x2d,0x38, 0x2e,0x37,0x33,0x31,0x76,0x38,0x2e,0x37,0x33,0x32, - 0x0d,0x0a,0x09,0x09,0x09,0x09,0x43,0x32,0x35,0x2e, - 0x32,0x30,0x37,0x2c,0x33,0x36,0x2e,0x32,0x32,0x39, - 0x2c,0x32,0x33,0x2e,0x33,0x34,0x31,0x2c,0x33,0x37, - 0x2e,0x30,0x36,0x2c,0x32,0x32,0x2e,0x30,0x38,0x36, - 0x2c,0x33,0x37,0x2e,0x30,0x36,0x7a,0x20,0x4d,0x33, - 0x2e,0x31,0x32,0x31,0x2c,0x31,0x33,0x2e,0x33,0x35, - 0x34,0x43,0x32,0x2e,0x37,0x34,0x35,0x2c,0x31,0x33, - 0x2e,0x33,0x35,0x39,0x2c,0x31,0x2e,0x35,0x2c,0x31, - 0x33,0x2e,0x34,0x39,0x33,0x2c,0x31,0x2e,0x35,0x2c, - 0x31,0x34,0x2e,0x39,0x37,0x34,0x76,0x37,0x2e,0x31, - 0x31,0x0d,0x0a,0x09,0x09,0x09,0x09,0x63,0x30,0x2e, - 0x30,0x30,0x36,0x2c,0x30,0x2e,0x33,0x37,0x36,0x2c, - 0x30,0x2e,0x31,0x33,0x39,0x2c,0x31,0x2e,0x36,0x32, - 0x31,0x2c,0x31,0x2e,0x36,0x32,0x31,0x2c,0x31,0x2e, - 0x36,0x32,0x31,0x68,0x31,0x30,0x2e,0x32,0x33,0x33, - 0x76,0x31,0x30,0x2e,0x32,0x33,0x32,0x63,0x30,0x2e, - 0x30,0x30,0x35,0x2c,0x30,0x2e,0x33,0x37,0x36,0x2c, + 0x0a,0x09,0x09,0x09,0x09,0x43,0x32,0x35,0x2e,0x32, + 0x30,0x37,0x2c,0x33,0x36,0x2e,0x32,0x32,0x39,0x2c, + 0x32,0x33,0x2e,0x33,0x34,0x31,0x2c,0x33,0x37,0x2e, + 0x30,0x36,0x2c,0x32,0x32,0x2e,0x30,0x38,0x36,0x2c, + 0x33,0x37,0x2e,0x30,0x36,0x7a,0x20,0x4d,0x33,0x2e, + 0x31,0x32,0x31,0x2c,0x31,0x33,0x2e,0x33,0x35,0x34, + 0x43,0x32,0x2e,0x37,0x34,0x35,0x2c,0x31,0x33,0x2e, + 0x33,0x35,0x39,0x2c,0x31,0x2e,0x35,0x2c,0x31,0x33, + 0x2e,0x34,0x39,0x33,0x2c,0x31,0x2e,0x35,0x2c,0x31, + 0x34,0x2e,0x39,0x37,0x34,0x76,0x37,0x2e,0x31,0x31, + 0x0a,0x09,0x09,0x09,0x09,0x63,0x30,0x2e,0x30,0x30, + 0x36,0x2c,0x30,0x2e,0x33,0x37,0x36,0x2c,0x30,0x2e, + 0x31,0x33,0x39,0x2c,0x31,0x2e,0x36,0x32,0x31,0x2c, + 0x31,0x2e,0x36,0x32,0x31,0x2c,0x31,0x2e,0x36,0x32, + 0x31,0x68,0x31,0x30,0x2e,0x32,0x33,0x33,0x76,0x31, + 0x30,0x2e,0x32,0x33,0x32,0x63,0x30,0x2e,0x30,0x30, + 0x35,0x2c,0x30,0x2e,0x33,0x37,0x36,0x2c,0x30,0x2e, + 0x31,0x34,0x2c,0x31,0x2e,0x36,0x32,0x31,0x2c,0x31, + 0x2e,0x36,0x31,0x39,0x2c,0x31,0x2e,0x36,0x32,0x31, + 0x68,0x37,0x2e,0x31,0x30,0x38,0x0a,0x09,0x09,0x09, + 0x09,0x63,0x30,0x2e,0x33,0x38,0x34,0x2d,0x30,0x2e, + 0x30,0x30,0x37,0x2c,0x31,0x2e,0x36,0x32,0x34,0x2d, + 0x30,0x2e,0x31,0x34,0x33,0x2c,0x31,0x2e,0x36,0x32, + 0x34,0x2d,0x31,0x2e,0x36,0x32,0x31,0x56,0x32,0x33, + 0x2e,0x37,0x30,0x36,0x68,0x31,0x30,0x2e,0x32,0x33, + 0x31,0x63,0x30,0x2e,0x33,0x37,0x36,0x2d,0x30,0x2e, + 0x30,0x30,0x36,0x2c,0x31,0x2e,0x36,0x32,0x31,0x2d, 0x30,0x2e,0x31,0x34,0x2c,0x31,0x2e,0x36,0x32,0x31, - 0x2c,0x31,0x2e,0x36,0x31,0x39,0x2c,0x31,0x2e,0x36, - 0x32,0x31,0x68,0x37,0x2e,0x31,0x30,0x38,0x0d,0x0a, - 0x09,0x09,0x09,0x09,0x63,0x30,0x2e,0x33,0x38,0x34, - 0x2d,0x30,0x2e,0x30,0x30,0x37,0x2c,0x31,0x2e,0x36, - 0x32,0x34,0x2d,0x30,0x2e,0x31,0x34,0x33,0x2c,0x31, - 0x2e,0x36,0x32,0x34,0x2d,0x31,0x2e,0x36,0x32,0x31, - 0x56,0x32,0x33,0x2e,0x37,0x30,0x36,0x68,0x31,0x30, - 0x2e,0x32,0x33,0x31,0x63,0x30,0x2e,0x33,0x37,0x36, - 0x2d,0x30,0x2e,0x30,0x30,0x36,0x2c,0x31,0x2e,0x36, - 0x32,0x31,0x2d,0x30,0x2e,0x31,0x34,0x2c,0x31,0x2e, - 0x36,0x32,0x31,0x2d,0x31,0x2e,0x36,0x32,0x31,0x76, - 0x2d,0x37,0x2e,0x31,0x31,0x0d,0x0a,0x09,0x09,0x09, - 0x09,0x63,0x2d,0x30,0x2e,0x30,0x30,0x36,0x2d,0x30, - 0x2e,0x33,0x37,0x36,0x2d,0x30,0x2e,0x31,0x34,0x2d, - 0x31,0x2e,0x36,0x32,0x2d,0x31,0x2e,0x36,0x32,0x31, - 0x2d,0x31,0x2e,0x36,0x32,0x68,0x2d,0x31,0x30,0x2e, - 0x32,0x33,0x56,0x33,0x2e,0x31,0x32,0x31,0x43,0x32, - 0x33,0x2e,0x37,0x30,0x31,0x2c,0x32,0x2e,0x37,0x34, - 0x35,0x2c,0x32,0x33,0x2e,0x35,0x36,0x37,0x2c,0x31, - 0x2e,0x35,0x2c,0x32,0x32,0x2e,0x30,0x38,0x36,0x2c, - 0x31,0x2e,0x35,0x68,0x2d,0x37,0x2e,0x31,0x31,0x31, - 0x0d,0x0a,0x09,0x09,0x09,0x09,0x63,0x2d,0x30,0x2e, - 0x33,0x37,0x36,0x2c,0x30,0x2e,0x30,0x30,0x36,0x2d, - 0x31,0x2e,0x36,0x31,0x39,0x2c,0x30,0x2e,0x31,0x34, - 0x2d,0x31,0x2e,0x36,0x31,0x39,0x2c,0x31,0x2e,0x36, - 0x32,0x31,0x76,0x31,0x30,0x2e,0x32,0x33,0x32,0x4c, - 0x33,0x2e,0x31,0x32,0x31,0x2c,0x31,0x33,0x2e,0x33, - 0x35,0x34,0x4c,0x33,0x2e,0x31,0x32,0x31,0x2c,0x31, - 0x33,0x2e,0x33,0x35,0x34,0x7a,0x22,0x2f,0x3e,0x0d, - 0x0a,0x09,0x09,0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x09, - 0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x09,0x3c,0x67,0x3e, - 0x0d,0x0a,0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20, - 0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46, - 0x46,0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x31, - 0x38,0x2e,0x35,0x33,0x31,0x2c,0x32,0x32,0x2e,0x31, - 0x38,0x31,0x63,0x2d,0x32,0x2e,0x30,0x31,0x33,0x2c, - 0x30,0x2d,0x33,0x2e,0x36,0x34,0x39,0x2d,0x31,0x2e, - 0x36,0x33,0x39,0x2d,0x33,0x2e,0x36,0x34,0x39,0x2d, - 0x33,0x2e,0x36,0x35,0x31,0x73,0x31,0x2e,0x36,0x33, - 0x38,0x2d,0x33,0x2e,0x36,0x35,0x2c,0x33,0x2e,0x36, - 0x34,0x39,0x2d,0x33,0x2e,0x36,0x35,0x63,0x32,0x2e, - 0x30,0x31,0x33,0x2c,0x30,0x2c,0x33,0x2e,0x36,0x35, - 0x2c,0x31,0x2e,0x36,0x33,0x39,0x2c,0x33,0x2e,0x36, - 0x35,0x2c,0x33,0x2e,0x36,0x35,0x0d,0x0a,0x09,0x09, + 0x2d,0x31,0x2e,0x36,0x32,0x31,0x76,0x2d,0x37,0x2e, + 0x31,0x31,0x0a,0x09,0x09,0x09,0x09,0x63,0x2d,0x30, + 0x2e,0x30,0x30,0x36,0x2d,0x30,0x2e,0x33,0x37,0x36, + 0x2d,0x30,0x2e,0x31,0x34,0x2d,0x31,0x2e,0x36,0x32, + 0x2d,0x31,0x2e,0x36,0x32,0x31,0x2d,0x31,0x2e,0x36, + 0x32,0x68,0x2d,0x31,0x30,0x2e,0x32,0x33,0x56,0x33, + 0x2e,0x31,0x32,0x31,0x43,0x32,0x33,0x2e,0x37,0x30, + 0x31,0x2c,0x32,0x2e,0x37,0x34,0x35,0x2c,0x32,0x33, + 0x2e,0x35,0x36,0x37,0x2c,0x31,0x2e,0x35,0x2c,0x32, + 0x32,0x2e,0x30,0x38,0x36,0x2c,0x31,0x2e,0x35,0x68, + 0x2d,0x37,0x2e,0x31,0x31,0x31,0x0a,0x09,0x09,0x09, + 0x09,0x63,0x2d,0x30,0x2e,0x33,0x37,0x36,0x2c,0x30, + 0x2e,0x30,0x30,0x36,0x2d,0x31,0x2e,0x36,0x31,0x39, + 0x2c,0x30,0x2e,0x31,0x34,0x2d,0x31,0x2e,0x36,0x31, + 0x39,0x2c,0x31,0x2e,0x36,0x32,0x31,0x76,0x31,0x30, + 0x2e,0x32,0x33,0x32,0x4c,0x33,0x2e,0x31,0x32,0x31, + 0x2c,0x31,0x33,0x2e,0x33,0x35,0x34,0x4c,0x33,0x2e, + 0x31,0x32,0x31,0x2c,0x31,0x33,0x2e,0x33,0x35,0x34, + 0x7a,0x22,0x2f,0x3e,0x0a,0x09,0x09,0x3c,0x2f,0x67, + 0x3e,0x0a,0x09,0x3c,0x2f,0x67,0x3e,0x0a,0x09,0x3c, + 0x67,0x3e,0x0a,0x09,0x09,0x3c,0x70,0x61,0x74,0x68, + 0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46, + 0x46,0x46,0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d, + 0x31,0x38,0x2e,0x35,0x33,0x31,0x2c,0x32,0x32,0x2e, + 0x31,0x38,0x31,0x63,0x2d,0x32,0x2e,0x30,0x31,0x33, + 0x2c,0x30,0x2d,0x33,0x2e,0x36,0x34,0x39,0x2d,0x31, + 0x2e,0x36,0x33,0x39,0x2d,0x33,0x2e,0x36,0x34,0x39, + 0x2d,0x33,0x2e,0x36,0x35,0x31,0x73,0x31,0x2e,0x36, + 0x33,0x38,0x2d,0x33,0x2e,0x36,0x35,0x2c,0x33,0x2e, + 0x36,0x34,0x39,0x2d,0x33,0x2e,0x36,0x35,0x63,0x32, + 0x2e,0x30,0x31,0x33,0x2c,0x30,0x2c,0x33,0x2e,0x36, + 0x35,0x2c,0x31,0x2e,0x36,0x33,0x39,0x2c,0x33,0x2e, + 0x36,0x35,0x2c,0x33,0x2e,0x36,0x35,0x0a,0x09,0x09, 0x09,0x43,0x32,0x32,0x2e,0x31,0x38,0x32,0x2c,0x32, 0x30,0x2e,0x35,0x34,0x33,0x2c,0x32,0x30,0x2e,0x35, 0x34,0x34,0x2c,0x32,0x32,0x2e,0x31,0x38,0x31,0x2c, @@ -162,61 +160,60 @@ const unsigned char help_dpad_right_svg_data[3216] = { 0x2d,0x32,0x2e,0x31,0x34,0x39,0x2c,0x32,0x2e,0x31, 0x35,0x73,0x30,0x2e,0x39,0x36,0x35,0x2c,0x32,0x2e, 0x31,0x35,0x31,0x2c,0x32,0x2e,0x31,0x34,0x39,0x2c, - 0x32,0x2e,0x31,0x35,0x31,0x0d,0x0a,0x09,0x09,0x09, - 0x63,0x31,0x2e,0x31,0x38,0x36,0x2c,0x30,0x2c,0x32, - 0x2e,0x31,0x35,0x2d,0x30,0x2e,0x39,0x36,0x36,0x2c, - 0x32,0x2e,0x31,0x35,0x2d,0x32,0x2e,0x31,0x35,0x31, - 0x43,0x32,0x30,0x2e,0x36,0x38,0x32,0x2c,0x31,0x37, - 0x2e,0x33,0x34,0x34,0x2c,0x31,0x39,0x2e,0x37,0x31, - 0x37,0x2c,0x31,0x36,0x2e,0x33,0x37,0x39,0x2c,0x31, - 0x38,0x2e,0x35,0x33,0x31,0x2c,0x31,0x36,0x2e,0x33, - 0x37,0x39,0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x09,0x3c, - 0x2f,0x67,0x3e,0x0d,0x0a,0x09,0x3c,0x67,0x3e,0x0d, + 0x32,0x2e,0x31,0x35,0x31,0x0a,0x09,0x09,0x09,0x63, + 0x31,0x2e,0x31,0x38,0x36,0x2c,0x30,0x2c,0x32,0x2e, + 0x31,0x35,0x2d,0x30,0x2e,0x39,0x36,0x36,0x2c,0x32, + 0x2e,0x31,0x35,0x2d,0x32,0x2e,0x31,0x35,0x31,0x43, + 0x32,0x30,0x2e,0x36,0x38,0x32,0x2c,0x31,0x37,0x2e, + 0x33,0x34,0x34,0x2c,0x31,0x39,0x2e,0x37,0x31,0x37, + 0x2c,0x31,0x36,0x2e,0x33,0x37,0x39,0x2c,0x31,0x38, + 0x2e,0x35,0x33,0x31,0x2c,0x31,0x36,0x2e,0x33,0x37, + 0x39,0x7a,0x22,0x2f,0x3e,0x0a,0x09,0x3c,0x2f,0x67, + 0x3e,0x0a,0x09,0x3c,0x67,0x3e,0x0a,0x09,0x09,0x3c, + 0x70,0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d, + 0x22,0x23,0x46,0x46,0x46,0x46,0x46,0x46,0x22,0x20, + 0x64,0x3d,0x22,0x4d,0x32,0x31,0x2e,0x35,0x33,0x36, + 0x2c,0x38,0x2e,0x36,0x31,0x36,0x68,0x2d,0x36,0x2e, + 0x30,0x31,0x32,0x63,0x2d,0x30,0x2e,0x32,0x37,0x33, + 0x2c,0x30,0x2d,0x30,0x2e,0x35,0x32,0x35,0x2d,0x30, + 0x2e,0x31,0x35,0x2d,0x30,0x2e,0x36,0x35,0x37,0x2d, + 0x30,0x2e,0x33,0x39,0x63,0x2d,0x30,0x2e,0x31,0x33, + 0x32,0x2d,0x30,0x2e,0x32,0x34,0x31,0x2d,0x30,0x2e, + 0x31,0x32,0x31,0x2d,0x30,0x2e,0x35,0x33,0x34,0x2c, + 0x30,0x2e,0x30,0x32,0x36,0x2d,0x30,0x2e,0x37,0x36, + 0x36,0x6c,0x33,0x2e,0x30,0x30,0x35,0x2d,0x34,0x2e, + 0x36,0x38,0x34,0x0a,0x09,0x09,0x09,0x63,0x30,0x2e, + 0x32,0x37,0x36,0x2d,0x30,0x2e,0x34,0x33,0x31,0x2c, + 0x30,0x2e,0x39,0x38,0x36,0x2d,0x30,0x2e,0x34,0x33, + 0x2c,0x31,0x2e,0x32,0x36,0x34,0x2c,0x30,0x6c,0x33, + 0x2e,0x30,0x30,0x35,0x2c,0x34,0x2e,0x36,0x38,0x34, + 0x63,0x30,0x2e,0x31,0x34,0x37,0x2c,0x30,0x2e,0x32, + 0x33,0x31,0x2c,0x30,0x2e,0x31,0x35,0x39,0x2c,0x30, + 0x2e,0x35,0x32,0x34,0x2c,0x30,0x2e,0x30,0x32,0x36, + 0x2c,0x30,0x2e,0x37,0x36,0x36,0x43,0x32,0x32,0x2e, + 0x30,0x36,0x33,0x2c,0x38,0x2e,0x34,0x36,0x36,0x2c, + 0x32,0x31,0x2e,0x38,0x31,0x31,0x2c,0x38,0x2e,0x36, + 0x31,0x36,0x2c,0x32,0x31,0x2e,0x35,0x33,0x36,0x2c, + 0x38,0x2e,0x36,0x31,0x36,0x7a,0x0a,0x09,0x09,0x09, + 0x20,0x4d,0x31,0x36,0x2e,0x38,0x39,0x37,0x2c,0x37, + 0x2e,0x31,0x31,0x36,0x68,0x33,0x2e,0x32,0x36,0x38, + 0x4c,0x31,0x38,0x2e,0x35,0x33,0x2c,0x34,0x2e,0x35, + 0x37,0x31,0x4c,0x31,0x36,0x2e,0x38,0x39,0x37,0x2c, + 0x37,0x2e,0x31,0x31,0x36,0x7a,0x22,0x2f,0x3e,0x0a, + 0x09,0x3c,0x2f,0x67,0x3e,0x0a,0x09,0x3c,0x67,0x3e, 0x0a,0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66, 0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46, - 0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x32,0x31, - 0x2e,0x35,0x33,0x36,0x2c,0x38,0x2e,0x36,0x31,0x36, - 0x68,0x2d,0x36,0x2e,0x30,0x31,0x32,0x63,0x2d,0x30, - 0x2e,0x32,0x37,0x33,0x2c,0x30,0x2d,0x30,0x2e,0x35, - 0x32,0x35,0x2d,0x30,0x2e,0x31,0x35,0x2d,0x30,0x2e, - 0x36,0x35,0x37,0x2d,0x30,0x2e,0x33,0x39,0x63,0x2d, - 0x30,0x2e,0x31,0x33,0x32,0x2d,0x30,0x2e,0x32,0x34, - 0x31,0x2d,0x30,0x2e,0x31,0x32,0x31,0x2d,0x30,0x2e, - 0x35,0x33,0x34,0x2c,0x30,0x2e,0x30,0x32,0x36,0x2d, - 0x30,0x2e,0x37,0x36,0x36,0x6c,0x33,0x2e,0x30,0x30, - 0x35,0x2d,0x34,0x2e,0x36,0x38,0x34,0x0d,0x0a,0x09, - 0x09,0x09,0x63,0x30,0x2e,0x32,0x37,0x36,0x2d,0x30, - 0x2e,0x34,0x33,0x31,0x2c,0x30,0x2e,0x39,0x38,0x36, - 0x2d,0x30,0x2e,0x34,0x33,0x2c,0x31,0x2e,0x32,0x36, - 0x34,0x2c,0x30,0x6c,0x33,0x2e,0x30,0x30,0x35,0x2c, - 0x34,0x2e,0x36,0x38,0x34,0x63,0x30,0x2e,0x31,0x34, - 0x37,0x2c,0x30,0x2e,0x32,0x33,0x31,0x2c,0x30,0x2e, - 0x31,0x35,0x39,0x2c,0x30,0x2e,0x35,0x32,0x34,0x2c, - 0x30,0x2e,0x30,0x32,0x36,0x2c,0x30,0x2e,0x37,0x36, - 0x36,0x43,0x32,0x32,0x2e,0x30,0x36,0x33,0x2c,0x38, - 0x2e,0x34,0x36,0x36,0x2c,0x32,0x31,0x2e,0x38,0x31, - 0x31,0x2c,0x38,0x2e,0x36,0x31,0x36,0x2c,0x32,0x31, - 0x2e,0x35,0x33,0x36,0x2c,0x38,0x2e,0x36,0x31,0x36, - 0x7a,0x0d,0x0a,0x09,0x09,0x09,0x20,0x4d,0x31,0x36, - 0x2e,0x38,0x39,0x37,0x2c,0x37,0x2e,0x31,0x31,0x36, - 0x68,0x33,0x2e,0x32,0x36,0x38,0x4c,0x31,0x38,0x2e, - 0x35,0x33,0x2c,0x34,0x2e,0x35,0x37,0x31,0x4c,0x31, - 0x36,0x2e,0x38,0x39,0x37,0x2c,0x37,0x2e,0x31,0x31, - 0x36,0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x09,0x3c,0x2f, - 0x67,0x3e,0x0d,0x0a,0x09,0x3c,0x67,0x3e,0x0d,0x0a, - 0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69, - 0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46, - 0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x37,0x2e,0x38, - 0x30,0x39,0x2c,0x32,0x32,0x2e,0x32,0x38,0x34,0x63, - 0x2d,0x30,0x2e,0x31,0x34,0x31,0x2c,0x30,0x2d,0x30, - 0x2e,0x32,0x38,0x32,0x2d,0x30,0x2e,0x30,0x34,0x2d, - 0x30,0x2e,0x34,0x30,0x35,0x2d,0x30,0x2e,0x31,0x31, - 0x39,0x4c,0x32,0x2e,0x37,0x32,0x2c,0x31,0x39,0x2e, - 0x31,0x36,0x32,0x63,0x2d,0x30,0x2e,0x32,0x31,0x35, - 0x2d,0x30,0x2e,0x31,0x33,0x38,0x2d,0x30,0x2e,0x33, - 0x34,0x35,0x2d,0x30,0x2e,0x33,0x37,0x36,0x2d,0x30, - 0x2e,0x33,0x34,0x35,0x2d,0x30,0x2e,0x36,0x33,0x31, - 0x0d,0x0a,0x09,0x09,0x09,0x73,0x30,0x2e,0x31,0x33, + 0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x37,0x2e, + 0x38,0x30,0x39,0x2c,0x32,0x32,0x2e,0x32,0x38,0x34, + 0x63,0x2d,0x30,0x2e,0x31,0x34,0x31,0x2c,0x30,0x2d, + 0x30,0x2e,0x32,0x38,0x32,0x2d,0x30,0x2e,0x30,0x34, + 0x2d,0x30,0x2e,0x34,0x30,0x35,0x2d,0x30,0x2e,0x31, + 0x31,0x39,0x4c,0x32,0x2e,0x37,0x32,0x2c,0x31,0x39, + 0x2e,0x31,0x36,0x32,0x63,0x2d,0x30,0x2e,0x32,0x31, + 0x35,0x2d,0x30,0x2e,0x31,0x33,0x38,0x2d,0x30,0x2e, + 0x33,0x34,0x35,0x2d,0x30,0x2e,0x33,0x37,0x36,0x2d, + 0x30,0x2e,0x33,0x34,0x35,0x2d,0x30,0x2e,0x36,0x33, + 0x31,0x0a,0x09,0x09,0x09,0x73,0x30,0x2e,0x31,0x33, 0x2d,0x30,0x2e,0x34,0x39,0x33,0x2c,0x30,0x2e,0x33, 0x34,0x35,0x2d,0x30,0x2e,0x36,0x33,0x31,0x6c,0x34, 0x2e,0x36,0x38,0x34,0x2d,0x33,0x2e,0x30,0x30,0x36, @@ -227,103 +224,102 @@ const unsigned char help_dpad_right_svg_data[3216] = { 0x2c,0x30,0x2e,0x31,0x33,0x31,0x2c,0x30,0x2e,0x33, 0x39,0x2c,0x30,0x2e,0x33,0x38,0x34,0x2c,0x30,0x2e, 0x33,0x39,0x2c,0x30,0x2e,0x36,0x35,0x38,0x76,0x36, - 0x2e,0x30,0x31,0x0d,0x0a,0x09,0x09,0x09,0x63,0x30, - 0x2c,0x30,0x2e,0x32,0x37,0x34,0x2d,0x30,0x2e,0x31, - 0x34,0x38,0x2c,0x30,0x2e,0x35,0x32,0x36,0x2d,0x30, - 0x2e,0x33,0x39,0x2c,0x30,0x2e,0x36,0x35,0x38,0x43, - 0x38,0x2e,0x30,0x35,0x36,0x2c,0x32,0x32,0x2e,0x32, - 0x35,0x34,0x2c,0x37,0x2e,0x39,0x33,0x32,0x2c,0x32, - 0x32,0x2e,0x32,0x38,0x34,0x2c,0x37,0x2e,0x38,0x30, - 0x39,0x2c,0x32,0x32,0x2e,0x32,0x38,0x34,0x7a,0x20, - 0x4d,0x34,0x2e,0x35,0x31,0x34,0x2c,0x31,0x38,0x2e, - 0x35,0x33,0x6c,0x32,0x2e,0x35,0x34,0x35,0x2c,0x31, - 0x2e,0x36,0x33,0x32,0x76,0x2d,0x33,0x2e,0x32,0x36, - 0x35,0x4c,0x34,0x2e,0x35,0x31,0x34,0x2c,0x31,0x38, - 0x2e,0x35,0x33,0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x09, - 0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x09,0x3c,0x67,0x3e, - 0x0d,0x0a,0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20, - 0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46, - 0x46,0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x33, - 0x33,0x2e,0x38,0x37,0x39,0x2c,0x31,0x38,0x2e,0x35, - 0x32,0x39,0x6c,0x2d,0x34,0x2e,0x36,0x38,0x35,0x2d, - 0x33,0x2e,0x30,0x30,0x35,0x76,0x36,0x2e,0x30,0x31, - 0x4c,0x33,0x33,0x2e,0x38,0x37,0x39,0x2c,0x31,0x38, - 0x2e,0x35,0x32,0x39,0x7a,0x22,0x2f,0x3e,0x0d,0x0a, - 0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69, - 0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46, - 0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x32,0x39,0x2e, - 0x31,0x39,0x35,0x2c,0x32,0x32,0x2e,0x32,0x38,0x34, - 0x63,0x2d,0x30,0x2e,0x31,0x32,0x34,0x2c,0x30,0x2d, - 0x30,0x2e,0x32,0x34,0x36,0x2d,0x30,0x2e,0x30,0x33, - 0x2d,0x30,0x2e,0x33,0x35,0x38,0x2d,0x30,0x2e,0x30, - 0x39,0x32,0x63,0x2d,0x30,0x2e,0x32,0x34,0x31,0x2d, - 0x30,0x2e,0x31,0x33,0x32,0x2d,0x30,0x2e,0x33,0x39, - 0x32,0x2d,0x30,0x2e,0x33,0x38,0x34,0x2d,0x30,0x2e, - 0x33,0x39,0x32,0x2d,0x30,0x2e,0x36,0x35,0x38,0x76, - 0x2d,0x36,0x2e,0x30,0x31,0x0d,0x0a,0x09,0x09,0x09, - 0x63,0x30,0x2d,0x30,0x2e,0x32,0x37,0x34,0x2c,0x30, - 0x2e,0x31,0x34,0x39,0x2d,0x30,0x2e,0x35,0x32,0x36, - 0x2c,0x30,0x2e,0x33,0x39,0x32,0x2d,0x30,0x2e,0x36, - 0x35,0x38,0x63,0x30,0x2e,0x32,0x33,0x39,0x2d,0x30, - 0x2e,0x31,0x33,0x31,0x2c,0x30,0x2e,0x35,0x33,0x33, - 0x2d,0x30,0x2e,0x31,0x32,0x33,0x2c,0x30,0x2e,0x37, - 0x36,0x35,0x2c,0x30,0x2e,0x30,0x32,0x37,0x6c,0x34, - 0x2e,0x36,0x38,0x35,0x2c,0x33,0x2e,0x30,0x30,0x35, - 0x63,0x30,0x2e,0x32,0x31,0x35,0x2c,0x30,0x2e,0x31, - 0x33,0x38,0x2c,0x30,0x2e,0x33,0x34,0x35,0x2c,0x30, - 0x2e,0x33,0x37,0x36,0x2c,0x30,0x2e,0x33,0x34,0x35, - 0x2c,0x30,0x2e,0x36,0x33,0x31,0x0d,0x0a,0x09,0x09, - 0x09,0x73,0x2d,0x30,0x2e,0x31,0x33,0x2c,0x30,0x2e, - 0x34,0x39,0x33,0x2d,0x30,0x2e,0x33,0x34,0x35,0x2c, - 0x30,0x2e,0x36,0x33,0x31,0x6c,0x2d,0x34,0x2e,0x36, - 0x38,0x35,0x2c,0x33,0x2e,0x30,0x30,0x34,0x43,0x32, - 0x39,0x2e,0x34,0x37,0x38,0x2c,0x32,0x32,0x2e,0x32, - 0x34,0x34,0x2c,0x32,0x39,0x2e,0x33,0x33,0x36,0x2c, - 0x32,0x32,0x2e,0x32,0x38,0x34,0x2c,0x32,0x39,0x2e, - 0x31,0x39,0x35,0x2c,0x32,0x32,0x2e,0x32,0x38,0x34, - 0x7a,0x20,0x4d,0x32,0x39,0x2e,0x39,0x34,0x35,0x2c, - 0x31,0x36,0x2e,0x38,0x39,0x36,0x76,0x33,0x2e,0x32, - 0x36,0x36,0x6c,0x32,0x2e,0x35,0x34,0x36,0x2d,0x31, - 0x2e,0x36,0x33,0x33,0x0d,0x0a,0x09,0x09,0x09,0x4c, - 0x32,0x39,0x2e,0x39,0x34,0x35,0x2c,0x31,0x36,0x2e, - 0x38,0x39,0x36,0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x09, - 0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x09,0x3c,0x67,0x3e, - 0x0d,0x0a,0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20, - 0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46, - 0x46,0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x31, - 0x38,0x2e,0x35,0x33,0x2c,0x33,0x34,0x2e,0x36,0x32, - 0x36,0x4c,0x31,0x38,0x2e,0x35,0x33,0x2c,0x33,0x34, - 0x2e,0x36,0x32,0x36,0x63,0x2d,0x30,0x2e,0x32,0x35, - 0x35,0x2c,0x30,0x2d,0x30,0x2e,0x34,0x39,0x32,0x2d, - 0x30,0x2e,0x31,0x33,0x2d,0x30,0x2e,0x36,0x33,0x31, - 0x2d,0x30,0x2e,0x33,0x34,0x35,0x6c,0x2d,0x33,0x2e, - 0x30,0x30,0x35,0x2d,0x34,0x2e,0x36,0x38,0x34,0x0d, - 0x0a,0x09,0x09,0x09,0x63,0x2d,0x30,0x2e,0x31,0x34, - 0x37,0x2d,0x30,0x2e,0x32,0x33,0x31,0x2d,0x30,0x2e, - 0x31,0x35,0x38,0x2d,0x30,0x2e,0x35,0x32,0x34,0x2d, - 0x30,0x2e,0x30,0x32,0x36,0x2d,0x30,0x2e,0x37,0x36, - 0x36,0x73,0x30,0x2e,0x33,0x38,0x34,0x2d,0x30,0x2e, - 0x33,0x39,0x31,0x2c,0x30,0x2e,0x36,0x35,0x37,0x2d, - 0x30,0x2e,0x33,0x39,0x31,0x68,0x36,0x2e,0x30,0x31, - 0x32,0x63,0x30,0x2e,0x32,0x37,0x33,0x2c,0x30,0x2c, - 0x30,0x2e,0x35,0x32,0x35,0x2c,0x30,0x2e,0x31,0x34, - 0x38,0x2c,0x30,0x2e,0x36,0x35,0x37,0x2c,0x30,0x2e, - 0x33,0x39,0x31,0x0d,0x0a,0x09,0x09,0x09,0x63,0x30, - 0x2e,0x31,0x33,0x33,0x2c,0x30,0x2e,0x32,0x34,0x2c, - 0x30,0x2e,0x31,0x32,0x31,0x2c,0x30,0x2e,0x35,0x33, - 0x33,0x2d,0x30,0x2e,0x30,0x32,0x36,0x2c,0x30,0x2e, - 0x37,0x36,0x36,0x6c,0x2d,0x33,0x2e,0x30,0x30,0x35, - 0x2c,0x34,0x2e,0x36,0x38,0x34,0x43,0x31,0x39,0x2e, - 0x30,0x32,0x33,0x2c,0x33,0x34,0x2e,0x34,0x39,0x36, - 0x2c,0x31,0x38,0x2e,0x37,0x38,0x36,0x2c,0x33,0x34, - 0x2e,0x36,0x32,0x36,0x2c,0x31,0x38,0x2e,0x35,0x33, - 0x2c,0x33,0x34,0x2e,0x36,0x32,0x36,0x7a,0x20,0x4d, - 0x31,0x36,0x2e,0x38,0x39,0x37,0x2c,0x32,0x39,0x2e, - 0x39,0x34,0x32,0x6c,0x31,0x2e,0x36,0x33,0x33,0x2c, - 0x32,0x2e,0x35,0x34,0x35,0x0d,0x0a,0x09,0x09,0x09, - 0x6c,0x31,0x2e,0x36,0x33,0x35,0x2d,0x32,0x2e,0x35, - 0x34,0x35,0x48,0x31,0x36,0x2e,0x38,0x39,0x37,0x7a, - 0x22,0x2f,0x3e,0x0d,0x0a,0x09,0x3c,0x2f,0x67,0x3e, - 0x0d,0x0a,0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x3c,0x2f, - 0x73,0x76,0x67,0x3e,0x0d,0x0a + 0x2e,0x30,0x31,0x0a,0x09,0x09,0x09,0x63,0x30,0x2c, + 0x30,0x2e,0x32,0x37,0x34,0x2d,0x30,0x2e,0x31,0x34, + 0x38,0x2c,0x30,0x2e,0x35,0x32,0x36,0x2d,0x30,0x2e, + 0x33,0x39,0x2c,0x30,0x2e,0x36,0x35,0x38,0x43,0x38, + 0x2e,0x30,0x35,0x36,0x2c,0x32,0x32,0x2e,0x32,0x35, + 0x34,0x2c,0x37,0x2e,0x39,0x33,0x32,0x2c,0x32,0x32, + 0x2e,0x32,0x38,0x34,0x2c,0x37,0x2e,0x38,0x30,0x39, + 0x2c,0x32,0x32,0x2e,0x32,0x38,0x34,0x7a,0x20,0x4d, + 0x34,0x2e,0x35,0x31,0x34,0x2c,0x31,0x38,0x2e,0x35, + 0x33,0x6c,0x32,0x2e,0x35,0x34,0x35,0x2c,0x31,0x2e, + 0x36,0x33,0x32,0x76,0x2d,0x33,0x2e,0x32,0x36,0x35, + 0x4c,0x34,0x2e,0x35,0x31,0x34,0x2c,0x31,0x38,0x2e, + 0x35,0x33,0x7a,0x22,0x2f,0x3e,0x0a,0x09,0x3c,0x2f, + 0x67,0x3e,0x0a,0x09,0x3c,0x67,0x3e,0x0a,0x09,0x09, + 0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c, + 0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46,0x46,0x22, + 0x20,0x64,0x3d,0x22,0x4d,0x33,0x33,0x2e,0x38,0x37, + 0x39,0x2c,0x31,0x38,0x2e,0x35,0x32,0x39,0x6c,0x2d, + 0x34,0x2e,0x36,0x38,0x35,0x2d,0x33,0x2e,0x30,0x30, + 0x35,0x76,0x36,0x2e,0x30,0x31,0x4c,0x33,0x33,0x2e, + 0x38,0x37,0x39,0x2c,0x31,0x38,0x2e,0x35,0x32,0x39, + 0x7a,0x22,0x2f,0x3e,0x0a,0x09,0x09,0x3c,0x70,0x61, + 0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23, + 0x46,0x46,0x46,0x46,0x46,0x46,0x22,0x20,0x64,0x3d, + 0x22,0x4d,0x32,0x39,0x2e,0x31,0x39,0x35,0x2c,0x32, + 0x32,0x2e,0x32,0x38,0x34,0x63,0x2d,0x30,0x2e,0x31, + 0x32,0x34,0x2c,0x30,0x2d,0x30,0x2e,0x32,0x34,0x36, + 0x2d,0x30,0x2e,0x30,0x33,0x2d,0x30,0x2e,0x33,0x35, + 0x38,0x2d,0x30,0x2e,0x30,0x39,0x32,0x63,0x2d,0x30, + 0x2e,0x32,0x34,0x31,0x2d,0x30,0x2e,0x31,0x33,0x32, + 0x2d,0x30,0x2e,0x33,0x39,0x32,0x2d,0x30,0x2e,0x33, + 0x38,0x34,0x2d,0x30,0x2e,0x33,0x39,0x32,0x2d,0x30, + 0x2e,0x36,0x35,0x38,0x76,0x2d,0x36,0x2e,0x30,0x31, + 0x0a,0x09,0x09,0x09,0x63,0x30,0x2d,0x30,0x2e,0x32, + 0x37,0x34,0x2c,0x30,0x2e,0x31,0x34,0x39,0x2d,0x30, + 0x2e,0x35,0x32,0x36,0x2c,0x30,0x2e,0x33,0x39,0x32, + 0x2d,0x30,0x2e,0x36,0x35,0x38,0x63,0x30,0x2e,0x32, + 0x33,0x39,0x2d,0x30,0x2e,0x31,0x33,0x31,0x2c,0x30, + 0x2e,0x35,0x33,0x33,0x2d,0x30,0x2e,0x31,0x32,0x33, + 0x2c,0x30,0x2e,0x37,0x36,0x35,0x2c,0x30,0x2e,0x30, + 0x32,0x37,0x6c,0x34,0x2e,0x36,0x38,0x35,0x2c,0x33, + 0x2e,0x30,0x30,0x35,0x63,0x30,0x2e,0x32,0x31,0x35, + 0x2c,0x30,0x2e,0x31,0x33,0x38,0x2c,0x30,0x2e,0x33, + 0x34,0x35,0x2c,0x30,0x2e,0x33,0x37,0x36,0x2c,0x30, + 0x2e,0x33,0x34,0x35,0x2c,0x30,0x2e,0x36,0x33,0x31, + 0x0a,0x09,0x09,0x09,0x73,0x2d,0x30,0x2e,0x31,0x33, + 0x2c,0x30,0x2e,0x34,0x39,0x33,0x2d,0x30,0x2e,0x33, + 0x34,0x35,0x2c,0x30,0x2e,0x36,0x33,0x31,0x6c,0x2d, + 0x34,0x2e,0x36,0x38,0x35,0x2c,0x33,0x2e,0x30,0x30, + 0x34,0x43,0x32,0x39,0x2e,0x34,0x37,0x38,0x2c,0x32, + 0x32,0x2e,0x32,0x34,0x34,0x2c,0x32,0x39,0x2e,0x33, + 0x33,0x36,0x2c,0x32,0x32,0x2e,0x32,0x38,0x34,0x2c, + 0x32,0x39,0x2e,0x31,0x39,0x35,0x2c,0x32,0x32,0x2e, + 0x32,0x38,0x34,0x7a,0x20,0x4d,0x32,0x39,0x2e,0x39, + 0x34,0x35,0x2c,0x31,0x36,0x2e,0x38,0x39,0x36,0x76, + 0x33,0x2e,0x32,0x36,0x36,0x6c,0x32,0x2e,0x35,0x34, + 0x36,0x2d,0x31,0x2e,0x36,0x33,0x33,0x0a,0x09,0x09, + 0x09,0x4c,0x32,0x39,0x2e,0x39,0x34,0x35,0x2c,0x31, + 0x36,0x2e,0x38,0x39,0x36,0x7a,0x22,0x2f,0x3e,0x0a, + 0x09,0x3c,0x2f,0x67,0x3e,0x0a,0x09,0x3c,0x67,0x3e, + 0x0a,0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66, + 0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46, + 0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x31,0x38, + 0x2e,0x35,0x33,0x2c,0x33,0x34,0x2e,0x36,0x32,0x36, + 0x4c,0x31,0x38,0x2e,0x35,0x33,0x2c,0x33,0x34,0x2e, + 0x36,0x32,0x36,0x63,0x2d,0x30,0x2e,0x32,0x35,0x35, + 0x2c,0x30,0x2d,0x30,0x2e,0x34,0x39,0x32,0x2d,0x30, + 0x2e,0x31,0x33,0x2d,0x30,0x2e,0x36,0x33,0x31,0x2d, + 0x30,0x2e,0x33,0x34,0x35,0x6c,0x2d,0x33,0x2e,0x30, + 0x30,0x35,0x2d,0x34,0x2e,0x36,0x38,0x34,0x0a,0x09, + 0x09,0x09,0x63,0x2d,0x30,0x2e,0x31,0x34,0x37,0x2d, + 0x30,0x2e,0x32,0x33,0x31,0x2d,0x30,0x2e,0x31,0x35, + 0x38,0x2d,0x30,0x2e,0x35,0x32,0x34,0x2d,0x30,0x2e, + 0x30,0x32,0x36,0x2d,0x30,0x2e,0x37,0x36,0x36,0x73, + 0x30,0x2e,0x33,0x38,0x34,0x2d,0x30,0x2e,0x33,0x39, + 0x31,0x2c,0x30,0x2e,0x36,0x35,0x37,0x2d,0x30,0x2e, + 0x33,0x39,0x31,0x68,0x36,0x2e,0x30,0x31,0x32,0x63, + 0x30,0x2e,0x32,0x37,0x33,0x2c,0x30,0x2c,0x30,0x2e, + 0x35,0x32,0x35,0x2c,0x30,0x2e,0x31,0x34,0x38,0x2c, + 0x30,0x2e,0x36,0x35,0x37,0x2c,0x30,0x2e,0x33,0x39, + 0x31,0x0a,0x09,0x09,0x09,0x63,0x30,0x2e,0x31,0x33, + 0x33,0x2c,0x30,0x2e,0x32,0x34,0x2c,0x30,0x2e,0x31, + 0x32,0x31,0x2c,0x30,0x2e,0x35,0x33,0x33,0x2d,0x30, + 0x2e,0x30,0x32,0x36,0x2c,0x30,0x2e,0x37,0x36,0x36, + 0x6c,0x2d,0x33,0x2e,0x30,0x30,0x35,0x2c,0x34,0x2e, + 0x36,0x38,0x34,0x43,0x31,0x39,0x2e,0x30,0x32,0x33, + 0x2c,0x33,0x34,0x2e,0x34,0x39,0x36,0x2c,0x31,0x38, + 0x2e,0x37,0x38,0x36,0x2c,0x33,0x34,0x2e,0x36,0x32, + 0x36,0x2c,0x31,0x38,0x2e,0x35,0x33,0x2c,0x33,0x34, + 0x2e,0x36,0x32,0x36,0x7a,0x20,0x4d,0x31,0x36,0x2e, + 0x38,0x39,0x37,0x2c,0x32,0x39,0x2e,0x39,0x34,0x32, + 0x6c,0x31,0x2e,0x36,0x33,0x33,0x2c,0x32,0x2e,0x35, + 0x34,0x35,0x0a,0x09,0x09,0x09,0x6c,0x31,0x2e,0x36, + 0x33,0x35,0x2d,0x32,0x2e,0x35,0x34,0x35,0x48,0x31, + 0x36,0x2e,0x38,0x39,0x37,0x7a,0x22,0x2f,0x3e,0x0a, + 0x09,0x3c,0x2f,0x67,0x3e,0x0a,0x3c,0x2f,0x67,0x3e, + 0x0a,0x3c,0x2f,0x73,0x76,0x67,0x3e,0x0a }; + diff --git a/data/converted/help_dpad_up_svg.cpp b/data/converted/help_dpad_up_svg.cpp index 225af33da9..a816609fe3 100644 --- a/data/converted/help_dpad_up_svg.cpp +++ b/data/converted/help_dpad_up_svg.cpp @@ -2,84 +2,83 @@ #include "../Resources.h" -const size_t help_dpad_up_svg_size = 3213; -const unsigned char help_dpad_up_svg_data[3213] = { +const size_t help_dpad_up_svg_size = 3165; +const unsigned char help_dpad_up_svg_data[3165] = { 0x3c,0x3f,0x78,0x6d,0x6c,0x20,0x76,0x65,0x72,0x73, 0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x30,0x22,0x20, 0x65,0x6e,0x63,0x6f,0x64,0x69,0x6e,0x67,0x3d,0x22, - 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0d,0x0a, - 0x3c,0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72, - 0x61,0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62, - 0x65,0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61, - 0x74,0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33, - 0x2c,0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f, - 0x72,0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e, - 0x20,0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72, - 0x73,0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30, - 0x20,0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20, - 0x20,0x2d,0x2d,0x3e,0x0d,0x0a,0x3c,0x21,0x44,0x4f, - 0x43,0x54,0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20, - 0x50,0x55,0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f, - 0x2f,0x57,0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20, - 0x53,0x56,0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45, - 0x4e,0x22,0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, - 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, - 0x67,0x2f,0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73, - 0x2f,0x53,0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44, - 0x54,0x44,0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64, - 0x74,0x64,0x22,0x3e,0x0d,0x0a,0x3c,0x73,0x76,0x67, - 0x20,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22, - 0x31,0x2e,0x31,0x22,0x20,0x69,0x64,0x3d,0x22,0x5f, - 0x78,0x33,0x30,0x5f,0x22,0x20,0x78,0x6d,0x6c,0x6e, - 0x73,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f, - 0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67, - 0x2f,0x32,0x30,0x30,0x30,0x2f,0x73,0x76,0x67,0x22, - 0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78,0x6c,0x69, - 0x6e,0x6b,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, - 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, - 0x67,0x2f,0x31,0x39,0x39,0x39,0x2f,0x78,0x6c,0x69, - 0x6e,0x6b,0x22,0x20,0x78,0x3d,0x22,0x30,0x70,0x78, - 0x22,0x20,0x79,0x3d,0x22,0x30,0x70,0x78,0x22,0x0d, - 0x0a,0x09,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22, - 0x33,0x37,0x2e,0x30,0x36,0x31,0x70,0x78,0x22,0x20, - 0x68,0x65,0x69,0x67,0x68,0x74,0x3d,0x22,0x33,0x37, - 0x2e,0x30,0x36,0x31,0x70,0x78,0x22,0x20,0x76,0x69, - 0x65,0x77,0x42,0x6f,0x78,0x3d,0x22,0x30,0x20,0x30, - 0x20,0x33,0x37,0x2e,0x30,0x36,0x31,0x20,0x33,0x37, - 0x2e,0x30,0x36,0x31,0x22,0x20,0x65,0x6e,0x61,0x62, - 0x6c,0x65,0x2d,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f, - 0x75,0x6e,0x64,0x3d,0x22,0x6e,0x65,0x77,0x20,0x30, - 0x20,0x30,0x20,0x33,0x37,0x2e,0x30,0x36,0x31,0x20, - 0x33,0x37,0x2e,0x30,0x36,0x31,0x22,0x20,0x78,0x6d, - 0x6c,0x3a,0x73,0x70,0x61,0x63,0x65,0x3d,0x22,0x70, - 0x72,0x65,0x73,0x65,0x72,0x76,0x65,0x22,0x3e,0x0d, - 0x0a,0x3c,0x67,0x3e,0x0d,0x0a,0x09,0x3c,0x67,0x3e, - 0x0d,0x0a,0x09,0x09,0x3c,0x67,0x3e,0x0d,0x0a,0x09, - 0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69, - 0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46, - 0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x32,0x32,0x2e, - 0x30,0x38,0x36,0x2c,0x33,0x37,0x2e,0x30,0x36,0x68, - 0x2d,0x37,0x2e,0x31,0x31,0x31,0x63,0x2d,0x32,0x2e, - 0x32,0x38,0x39,0x2c,0x30,0x2d,0x33,0x2e,0x31,0x31, - 0x39,0x2d,0x31,0x2e,0x38,0x36,0x36,0x2d,0x33,0x2e, - 0x31,0x31,0x39,0x2d,0x33,0x2e,0x31,0x32,0x31,0x76, - 0x2d,0x38,0x2e,0x37,0x33,0x32,0x48,0x33,0x2e,0x31, - 0x32,0x31,0x43,0x30,0x2e,0x38,0x33,0x31,0x2c,0x32, - 0x35,0x2e,0x32,0x30,0x36,0x2c,0x30,0x2c,0x32,0x33, - 0x2e,0x33,0x34,0x2c,0x30,0x2c,0x32,0x32,0x2e,0x30, - 0x38,0x35,0x0d,0x0a,0x09,0x09,0x09,0x09,0x76,0x2d, - 0x37,0x2e,0x31,0x31,0x63,0x30,0x2d,0x32,0x2e,0x32, - 0x38,0x39,0x2c,0x31,0x2e,0x38,0x36,0x37,0x2d,0x33, - 0x2e,0x31,0x32,0x2c,0x33,0x2e,0x31,0x32,0x31,0x2d, - 0x33,0x2e,0x31,0x32,0x68,0x38,0x2e,0x37,0x33,0x33, - 0x56,0x33,0x2e,0x31,0x32,0x31,0x43,0x31,0x31,0x2e, - 0x38,0x35,0x35,0x2c,0x30,0x2e,0x38,0x33,0x31,0x2c, - 0x31,0x33,0x2e,0x37,0x32,0x2c,0x30,0x2c,0x31,0x34, - 0x2e,0x39,0x37,0x34,0x2c,0x30,0x68,0x37,0x2e,0x31, - 0x31,0x31,0x63,0x32,0x2e,0x32,0x39,0x2c,0x30,0x2c, - 0x33,0x2e,0x31,0x32,0x31,0x2c,0x31,0x2e,0x38,0x36, - 0x37,0x2c,0x33,0x2e,0x31,0x32,0x31,0x2c,0x33,0x2e, - 0x31,0x32,0x31,0x76,0x38,0x2e,0x37,0x33,0x32,0x0d, + 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0a,0x3c, + 0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72,0x61, + 0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62,0x65, + 0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61,0x74, + 0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33,0x2c, + 0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f,0x72, + 0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e,0x20, + 0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72,0x73, + 0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30,0x20, + 0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20,0x20, + 0x2d,0x2d,0x3e,0x0a,0x3c,0x21,0x44,0x4f,0x43,0x54, + 0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20,0x50,0x55, + 0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f,0x2f,0x57, + 0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20,0x53,0x56, + 0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45,0x4e,0x22, + 0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73,0x2f,0x53, + 0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44,0x54,0x44, + 0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64,0x74,0x64, + 0x22,0x3e,0x0a,0x3c,0x73,0x76,0x67,0x20,0x76,0x65, + 0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x31, + 0x22,0x20,0x69,0x64,0x3d,0x22,0x5f,0x78,0x33,0x30, + 0x5f,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3d,0x22, + 0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77, + 0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f,0x32,0x30, + 0x30,0x30,0x2f,0x73,0x76,0x67,0x22,0x20,0x78,0x6d, + 0x6c,0x6e,0x73,0x3a,0x78,0x6c,0x69,0x6e,0x6b,0x3d, + 0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77, + 0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f,0x31, + 0x39,0x39,0x39,0x2f,0x78,0x6c,0x69,0x6e,0x6b,0x22, + 0x20,0x78,0x3d,0x22,0x30,0x70,0x78,0x22,0x20,0x79, + 0x3d,0x22,0x30,0x70,0x78,0x22,0x0a,0x09,0x20,0x77, + 0x69,0x64,0x74,0x68,0x3d,0x22,0x33,0x37,0x2e,0x30, + 0x36,0x31,0x70,0x78,0x22,0x20,0x68,0x65,0x69,0x67, + 0x68,0x74,0x3d,0x22,0x33,0x37,0x2e,0x30,0x36,0x31, + 0x70,0x78,0x22,0x20,0x76,0x69,0x65,0x77,0x42,0x6f, + 0x78,0x3d,0x22,0x30,0x20,0x30,0x20,0x33,0x37,0x2e, + 0x30,0x36,0x31,0x20,0x33,0x37,0x2e,0x30,0x36,0x31, + 0x22,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0x2d,0x62, + 0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x3d, + 0x22,0x6e,0x65,0x77,0x20,0x30,0x20,0x30,0x20,0x33, + 0x37,0x2e,0x30,0x36,0x31,0x20,0x33,0x37,0x2e,0x30, + 0x36,0x31,0x22,0x20,0x78,0x6d,0x6c,0x3a,0x73,0x70, + 0x61,0x63,0x65,0x3d,0x22,0x70,0x72,0x65,0x73,0x65, + 0x72,0x76,0x65,0x22,0x3e,0x0a,0x3c,0x67,0x3e,0x0a, + 0x09,0x3c,0x67,0x3e,0x0a,0x09,0x09,0x3c,0x67,0x3e, + 0x0a,0x09,0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20, + 0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46, + 0x46,0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x32, + 0x32,0x2e,0x30,0x38,0x36,0x2c,0x33,0x37,0x2e,0x30, + 0x36,0x68,0x2d,0x37,0x2e,0x31,0x31,0x31,0x63,0x2d, + 0x32,0x2e,0x32,0x38,0x39,0x2c,0x30,0x2d,0x33,0x2e, + 0x31,0x31,0x39,0x2d,0x31,0x2e,0x38,0x36,0x36,0x2d, + 0x33,0x2e,0x31,0x31,0x39,0x2d,0x33,0x2e,0x31,0x32, + 0x31,0x76,0x2d,0x38,0x2e,0x37,0x33,0x32,0x48,0x33, + 0x2e,0x31,0x32,0x31,0x43,0x30,0x2e,0x38,0x33,0x31, + 0x2c,0x32,0x35,0x2e,0x32,0x30,0x36,0x2c,0x30,0x2c, + 0x32,0x33,0x2e,0x33,0x34,0x2c,0x30,0x2c,0x32,0x32, + 0x2e,0x30,0x38,0x35,0x0a,0x09,0x09,0x09,0x09,0x76, + 0x2d,0x37,0x2e,0x31,0x31,0x63,0x30,0x2d,0x32,0x2e, + 0x32,0x38,0x39,0x2c,0x31,0x2e,0x38,0x36,0x37,0x2d, + 0x33,0x2e,0x31,0x32,0x2c,0x33,0x2e,0x31,0x32,0x31, + 0x2d,0x33,0x2e,0x31,0x32,0x68,0x38,0x2e,0x37,0x33, + 0x33,0x56,0x33,0x2e,0x31,0x32,0x31,0x43,0x31,0x31, + 0x2e,0x38,0x35,0x35,0x2c,0x30,0x2e,0x38,0x33,0x31, + 0x2c,0x31,0x33,0x2e,0x37,0x32,0x2c,0x30,0x2c,0x31, + 0x34,0x2e,0x39,0x37,0x34,0x2c,0x30,0x68,0x37,0x2e, + 0x31,0x31,0x31,0x63,0x32,0x2e,0x32,0x39,0x2c,0x30, + 0x2c,0x33,0x2e,0x31,0x32,0x31,0x2c,0x31,0x2e,0x38, + 0x36,0x37,0x2c,0x33,0x2e,0x31,0x32,0x31,0x2c,0x33, + 0x2e,0x31,0x32,0x31,0x76,0x38,0x2e,0x37,0x33,0x32, 0x0a,0x09,0x09,0x09,0x09,0x68,0x38,0x2e,0x37,0x33, 0x31,0x63,0x32,0x2e,0x32,0x39,0x2c,0x30,0x2c,0x33, 0x2e,0x31,0x32,0x31,0x2c,0x31,0x2e,0x38,0x36,0x35, @@ -89,68 +88,67 @@ const unsigned char help_dpad_up_svg_data[3213] = { 0x33,0x2e,0x31,0x32,0x31,0x2d,0x33,0x2e,0x31,0x32, 0x31,0x2c,0x33,0x2e,0x31,0x32,0x31,0x68,0x2d,0x38, 0x2e,0x37,0x33,0x31,0x76,0x38,0x2e,0x37,0x33,0x32, - 0x0d,0x0a,0x09,0x09,0x09,0x09,0x43,0x32,0x35,0x2e, - 0x32,0x30,0x37,0x2c,0x33,0x36,0x2e,0x32,0x32,0x39, - 0x2c,0x32,0x33,0x2e,0x33,0x34,0x31,0x2c,0x33,0x37, - 0x2e,0x30,0x36,0x2c,0x32,0x32,0x2e,0x30,0x38,0x36, - 0x2c,0x33,0x37,0x2e,0x30,0x36,0x7a,0x20,0x4d,0x33, - 0x2e,0x31,0x32,0x31,0x2c,0x31,0x33,0x2e,0x33,0x35, - 0x34,0x43,0x32,0x2e,0x37,0x34,0x35,0x2c,0x31,0x33, - 0x2e,0x33,0x35,0x39,0x2c,0x31,0x2e,0x35,0x2c,0x31, - 0x33,0x2e,0x34,0x39,0x33,0x2c,0x31,0x2e,0x35,0x2c, - 0x31,0x34,0x2e,0x39,0x37,0x34,0x76,0x37,0x2e,0x31, - 0x31,0x0d,0x0a,0x09,0x09,0x09,0x09,0x63,0x30,0x2e, - 0x30,0x30,0x36,0x2c,0x30,0x2e,0x33,0x37,0x36,0x2c, - 0x30,0x2e,0x31,0x33,0x39,0x2c,0x31,0x2e,0x36,0x32, - 0x31,0x2c,0x31,0x2e,0x36,0x32,0x31,0x2c,0x31,0x2e, - 0x36,0x32,0x31,0x68,0x31,0x30,0x2e,0x32,0x33,0x33, - 0x76,0x31,0x30,0x2e,0x32,0x33,0x32,0x63,0x30,0x2e, - 0x30,0x30,0x35,0x2c,0x30,0x2e,0x33,0x37,0x36,0x2c, + 0x0a,0x09,0x09,0x09,0x09,0x43,0x32,0x35,0x2e,0x32, + 0x30,0x37,0x2c,0x33,0x36,0x2e,0x32,0x32,0x39,0x2c, + 0x32,0x33,0x2e,0x33,0x34,0x31,0x2c,0x33,0x37,0x2e, + 0x30,0x36,0x2c,0x32,0x32,0x2e,0x30,0x38,0x36,0x2c, + 0x33,0x37,0x2e,0x30,0x36,0x7a,0x20,0x4d,0x33,0x2e, + 0x31,0x32,0x31,0x2c,0x31,0x33,0x2e,0x33,0x35,0x34, + 0x43,0x32,0x2e,0x37,0x34,0x35,0x2c,0x31,0x33,0x2e, + 0x33,0x35,0x39,0x2c,0x31,0x2e,0x35,0x2c,0x31,0x33, + 0x2e,0x34,0x39,0x33,0x2c,0x31,0x2e,0x35,0x2c,0x31, + 0x34,0x2e,0x39,0x37,0x34,0x76,0x37,0x2e,0x31,0x31, + 0x0a,0x09,0x09,0x09,0x09,0x63,0x30,0x2e,0x30,0x30, + 0x36,0x2c,0x30,0x2e,0x33,0x37,0x36,0x2c,0x30,0x2e, + 0x31,0x33,0x39,0x2c,0x31,0x2e,0x36,0x32,0x31,0x2c, + 0x31,0x2e,0x36,0x32,0x31,0x2c,0x31,0x2e,0x36,0x32, + 0x31,0x68,0x31,0x30,0x2e,0x32,0x33,0x33,0x76,0x31, + 0x30,0x2e,0x32,0x33,0x32,0x63,0x30,0x2e,0x30,0x30, + 0x35,0x2c,0x30,0x2e,0x33,0x37,0x36,0x2c,0x30,0x2e, + 0x31,0x34,0x2c,0x31,0x2e,0x36,0x32,0x31,0x2c,0x31, + 0x2e,0x36,0x31,0x39,0x2c,0x31,0x2e,0x36,0x32,0x31, + 0x68,0x37,0x2e,0x31,0x30,0x38,0x0a,0x09,0x09,0x09, + 0x09,0x63,0x30,0x2e,0x33,0x38,0x34,0x2d,0x30,0x2e, + 0x30,0x30,0x37,0x2c,0x31,0x2e,0x36,0x32,0x34,0x2d, + 0x30,0x2e,0x31,0x34,0x33,0x2c,0x31,0x2e,0x36,0x32, + 0x34,0x2d,0x31,0x2e,0x36,0x32,0x31,0x56,0x32,0x33, + 0x2e,0x37,0x30,0x36,0x68,0x31,0x30,0x2e,0x32,0x33, + 0x31,0x63,0x30,0x2e,0x33,0x37,0x36,0x2d,0x30,0x2e, + 0x30,0x30,0x36,0x2c,0x31,0x2e,0x36,0x32,0x31,0x2d, 0x30,0x2e,0x31,0x34,0x2c,0x31,0x2e,0x36,0x32,0x31, - 0x2c,0x31,0x2e,0x36,0x31,0x39,0x2c,0x31,0x2e,0x36, - 0x32,0x31,0x68,0x37,0x2e,0x31,0x30,0x38,0x0d,0x0a, - 0x09,0x09,0x09,0x09,0x63,0x30,0x2e,0x33,0x38,0x34, - 0x2d,0x30,0x2e,0x30,0x30,0x37,0x2c,0x31,0x2e,0x36, - 0x32,0x34,0x2d,0x30,0x2e,0x31,0x34,0x33,0x2c,0x31, - 0x2e,0x36,0x32,0x34,0x2d,0x31,0x2e,0x36,0x32,0x31, - 0x56,0x32,0x33,0x2e,0x37,0x30,0x36,0x68,0x31,0x30, - 0x2e,0x32,0x33,0x31,0x63,0x30,0x2e,0x33,0x37,0x36, - 0x2d,0x30,0x2e,0x30,0x30,0x36,0x2c,0x31,0x2e,0x36, - 0x32,0x31,0x2d,0x30,0x2e,0x31,0x34,0x2c,0x31,0x2e, - 0x36,0x32,0x31,0x2d,0x31,0x2e,0x36,0x32,0x31,0x76, - 0x2d,0x37,0x2e,0x31,0x31,0x0d,0x0a,0x09,0x09,0x09, - 0x09,0x63,0x2d,0x30,0x2e,0x30,0x30,0x36,0x2d,0x30, - 0x2e,0x33,0x37,0x36,0x2d,0x30,0x2e,0x31,0x34,0x2d, - 0x31,0x2e,0x36,0x32,0x2d,0x31,0x2e,0x36,0x32,0x31, - 0x2d,0x31,0x2e,0x36,0x32,0x68,0x2d,0x31,0x30,0x2e, - 0x32,0x33,0x56,0x33,0x2e,0x31,0x32,0x31,0x43,0x32, - 0x33,0x2e,0x37,0x30,0x31,0x2c,0x32,0x2e,0x37,0x34, - 0x35,0x2c,0x32,0x33,0x2e,0x35,0x36,0x37,0x2c,0x31, - 0x2e,0x35,0x2c,0x32,0x32,0x2e,0x30,0x38,0x36,0x2c, - 0x31,0x2e,0x35,0x68,0x2d,0x37,0x2e,0x31,0x31,0x31, - 0x0d,0x0a,0x09,0x09,0x09,0x09,0x63,0x2d,0x30,0x2e, - 0x33,0x37,0x36,0x2c,0x30,0x2e,0x30,0x30,0x36,0x2d, - 0x31,0x2e,0x36,0x31,0x39,0x2c,0x30,0x2e,0x31,0x34, - 0x2d,0x31,0x2e,0x36,0x31,0x39,0x2c,0x31,0x2e,0x36, - 0x32,0x31,0x76,0x31,0x30,0x2e,0x32,0x33,0x32,0x4c, - 0x33,0x2e,0x31,0x32,0x31,0x2c,0x31,0x33,0x2e,0x33, - 0x35,0x34,0x4c,0x33,0x2e,0x31,0x32,0x31,0x2c,0x31, - 0x33,0x2e,0x33,0x35,0x34,0x7a,0x22,0x2f,0x3e,0x0d, - 0x0a,0x09,0x09,0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x09, - 0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x09,0x3c,0x67,0x3e, - 0x0d,0x0a,0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20, - 0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46, - 0x46,0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x31, - 0x38,0x2e,0x35,0x33,0x31,0x2c,0x32,0x32,0x2e,0x31, - 0x38,0x31,0x63,0x2d,0x32,0x2e,0x30,0x31,0x33,0x2c, - 0x30,0x2d,0x33,0x2e,0x36,0x34,0x39,0x2d,0x31,0x2e, - 0x36,0x33,0x39,0x2d,0x33,0x2e,0x36,0x34,0x39,0x2d, - 0x33,0x2e,0x36,0x35,0x31,0x73,0x31,0x2e,0x36,0x33, - 0x38,0x2d,0x33,0x2e,0x36,0x35,0x2c,0x33,0x2e,0x36, - 0x34,0x39,0x2d,0x33,0x2e,0x36,0x35,0x63,0x32,0x2e, - 0x30,0x31,0x33,0x2c,0x30,0x2c,0x33,0x2e,0x36,0x35, - 0x2c,0x31,0x2e,0x36,0x33,0x39,0x2c,0x33,0x2e,0x36, - 0x35,0x2c,0x33,0x2e,0x36,0x35,0x0d,0x0a,0x09,0x09, + 0x2d,0x31,0x2e,0x36,0x32,0x31,0x76,0x2d,0x37,0x2e, + 0x31,0x31,0x0a,0x09,0x09,0x09,0x09,0x63,0x2d,0x30, + 0x2e,0x30,0x30,0x36,0x2d,0x30,0x2e,0x33,0x37,0x36, + 0x2d,0x30,0x2e,0x31,0x34,0x2d,0x31,0x2e,0x36,0x32, + 0x2d,0x31,0x2e,0x36,0x32,0x31,0x2d,0x31,0x2e,0x36, + 0x32,0x68,0x2d,0x31,0x30,0x2e,0x32,0x33,0x56,0x33, + 0x2e,0x31,0x32,0x31,0x43,0x32,0x33,0x2e,0x37,0x30, + 0x31,0x2c,0x32,0x2e,0x37,0x34,0x35,0x2c,0x32,0x33, + 0x2e,0x35,0x36,0x37,0x2c,0x31,0x2e,0x35,0x2c,0x32, + 0x32,0x2e,0x30,0x38,0x36,0x2c,0x31,0x2e,0x35,0x68, + 0x2d,0x37,0x2e,0x31,0x31,0x31,0x0a,0x09,0x09,0x09, + 0x09,0x63,0x2d,0x30,0x2e,0x33,0x37,0x36,0x2c,0x30, + 0x2e,0x30,0x30,0x36,0x2d,0x31,0x2e,0x36,0x31,0x39, + 0x2c,0x30,0x2e,0x31,0x34,0x2d,0x31,0x2e,0x36,0x31, + 0x39,0x2c,0x31,0x2e,0x36,0x32,0x31,0x76,0x31,0x30, + 0x2e,0x32,0x33,0x32,0x4c,0x33,0x2e,0x31,0x32,0x31, + 0x2c,0x31,0x33,0x2e,0x33,0x35,0x34,0x4c,0x33,0x2e, + 0x31,0x32,0x31,0x2c,0x31,0x33,0x2e,0x33,0x35,0x34, + 0x7a,0x22,0x2f,0x3e,0x0a,0x09,0x09,0x3c,0x2f,0x67, + 0x3e,0x0a,0x09,0x3c,0x2f,0x67,0x3e,0x0a,0x09,0x3c, + 0x67,0x3e,0x0a,0x09,0x09,0x3c,0x70,0x61,0x74,0x68, + 0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46, + 0x46,0x46,0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d, + 0x31,0x38,0x2e,0x35,0x33,0x31,0x2c,0x32,0x32,0x2e, + 0x31,0x38,0x31,0x63,0x2d,0x32,0x2e,0x30,0x31,0x33, + 0x2c,0x30,0x2d,0x33,0x2e,0x36,0x34,0x39,0x2d,0x31, + 0x2e,0x36,0x33,0x39,0x2d,0x33,0x2e,0x36,0x34,0x39, + 0x2d,0x33,0x2e,0x36,0x35,0x31,0x73,0x31,0x2e,0x36, + 0x33,0x38,0x2d,0x33,0x2e,0x36,0x35,0x2c,0x33,0x2e, + 0x36,0x34,0x39,0x2d,0x33,0x2e,0x36,0x35,0x63,0x32, + 0x2e,0x30,0x31,0x33,0x2c,0x30,0x2c,0x33,0x2e,0x36, + 0x35,0x2c,0x31,0x2e,0x36,0x33,0x39,0x2c,0x33,0x2e, + 0x36,0x35,0x2c,0x33,0x2e,0x36,0x35,0x0a,0x09,0x09, 0x09,0x43,0x32,0x32,0x2e,0x31,0x38,0x32,0x2c,0x32, 0x30,0x2e,0x35,0x34,0x33,0x2c,0x32,0x30,0x2e,0x35, 0x34,0x34,0x2c,0x32,0x32,0x2e,0x31,0x38,0x31,0x2c, @@ -162,56 +160,55 @@ const unsigned char help_dpad_up_svg_data[3213] = { 0x2d,0x32,0x2e,0x31,0x34,0x39,0x2c,0x32,0x2e,0x31, 0x35,0x73,0x30,0x2e,0x39,0x36,0x35,0x2c,0x32,0x2e, 0x31,0x35,0x31,0x2c,0x32,0x2e,0x31,0x34,0x39,0x2c, - 0x32,0x2e,0x31,0x35,0x31,0x0d,0x0a,0x09,0x09,0x09, - 0x63,0x31,0x2e,0x31,0x38,0x36,0x2c,0x30,0x2c,0x32, - 0x2e,0x31,0x35,0x2d,0x30,0x2e,0x39,0x36,0x36,0x2c, - 0x32,0x2e,0x31,0x35,0x2d,0x32,0x2e,0x31,0x35,0x31, - 0x43,0x32,0x30,0x2e,0x36,0x38,0x32,0x2c,0x31,0x37, - 0x2e,0x33,0x34,0x34,0x2c,0x31,0x39,0x2e,0x37,0x31, - 0x37,0x2c,0x31,0x36,0x2e,0x33,0x37,0x39,0x2c,0x31, - 0x38,0x2e,0x35,0x33,0x31,0x2c,0x31,0x36,0x2e,0x33, - 0x37,0x39,0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x09,0x3c, - 0x2f,0x67,0x3e,0x0d,0x0a,0x09,0x3c,0x67,0x3e,0x0d, + 0x32,0x2e,0x31,0x35,0x31,0x0a,0x09,0x09,0x09,0x63, + 0x31,0x2e,0x31,0x38,0x36,0x2c,0x30,0x2c,0x32,0x2e, + 0x31,0x35,0x2d,0x30,0x2e,0x39,0x36,0x36,0x2c,0x32, + 0x2e,0x31,0x35,0x2d,0x32,0x2e,0x31,0x35,0x31,0x43, + 0x32,0x30,0x2e,0x36,0x38,0x32,0x2c,0x31,0x37,0x2e, + 0x33,0x34,0x34,0x2c,0x31,0x39,0x2e,0x37,0x31,0x37, + 0x2c,0x31,0x36,0x2e,0x33,0x37,0x39,0x2c,0x31,0x38, + 0x2e,0x35,0x33,0x31,0x2c,0x31,0x36,0x2e,0x33,0x37, + 0x39,0x7a,0x22,0x2f,0x3e,0x0a,0x09,0x3c,0x2f,0x67, + 0x3e,0x0a,0x09,0x3c,0x67,0x3e,0x0a,0x09,0x09,0x3c, + 0x70,0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d, + 0x22,0x23,0x46,0x46,0x46,0x46,0x46,0x46,0x22,0x20, + 0x64,0x3d,0x22,0x4d,0x31,0x38,0x2e,0x35,0x33,0x2c, + 0x33,0x2e,0x31,0x38,0x33,0x6c,0x2d,0x33,0x2e,0x30, + 0x30,0x35,0x2c,0x34,0x2e,0x36,0x38,0x34,0x68,0x36, + 0x2e,0x30,0x31,0x32,0x4c,0x31,0x38,0x2e,0x35,0x33, + 0x2c,0x33,0x2e,0x31,0x38,0x33,0x7a,0x22,0x2f,0x3e, 0x0a,0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66, 0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46, - 0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x31,0x38, - 0x2e,0x35,0x33,0x2c,0x33,0x2e,0x31,0x38,0x33,0x6c, - 0x2d,0x33,0x2e,0x30,0x30,0x35,0x2c,0x34,0x2e,0x36, - 0x38,0x34,0x68,0x36,0x2e,0x30,0x31,0x32,0x4c,0x31, - 0x38,0x2e,0x35,0x33,0x2c,0x33,0x2e,0x31,0x38,0x33, - 0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x09,0x09,0x3c,0x70, - 0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22, - 0x23,0x46,0x46,0x46,0x46,0x46,0x46,0x22,0x20,0x64, - 0x3d,0x22,0x4d,0x32,0x31,0x2e,0x35,0x33,0x36,0x2c, - 0x38,0x2e,0x36,0x31,0x36,0x68,0x2d,0x36,0x2e,0x30, - 0x31,0x32,0x63,0x2d,0x30,0x2e,0x32,0x37,0x33,0x2c, - 0x30,0x2d,0x30,0x2e,0x35,0x32,0x35,0x2d,0x30,0x2e, - 0x31,0x35,0x2d,0x30,0x2e,0x36,0x35,0x37,0x2d,0x30, - 0x2e,0x33,0x39,0x63,0x2d,0x30,0x2e,0x31,0x33,0x32, - 0x2d,0x30,0x2e,0x32,0x34,0x31,0x2d,0x30,0x2e,0x31, - 0x32,0x31,0x2d,0x30,0x2e,0x35,0x33,0x34,0x2c,0x30, - 0x2e,0x30,0x32,0x36,0x2d,0x30,0x2e,0x37,0x36,0x36, - 0x6c,0x33,0x2e,0x30,0x30,0x35,0x2d,0x34,0x2e,0x36, - 0x38,0x34,0x0d,0x0a,0x09,0x09,0x09,0x63,0x30,0x2e, - 0x32,0x37,0x36,0x2d,0x30,0x2e,0x34,0x33,0x31,0x2c, - 0x30,0x2e,0x39,0x38,0x36,0x2d,0x30,0x2e,0x34,0x33, - 0x2c,0x31,0x2e,0x32,0x36,0x34,0x2c,0x30,0x6c,0x33, - 0x2e,0x30,0x30,0x35,0x2c,0x34,0x2e,0x36,0x38,0x34, - 0x63,0x30,0x2e,0x31,0x34,0x37,0x2c,0x30,0x2e,0x32, - 0x33,0x31,0x2c,0x30,0x2e,0x31,0x35,0x39,0x2c,0x30, - 0x2e,0x35,0x32,0x34,0x2c,0x30,0x2e,0x30,0x32,0x36, - 0x2c,0x30,0x2e,0x37,0x36,0x36,0x43,0x32,0x32,0x2e, - 0x30,0x36,0x33,0x2c,0x38,0x2e,0x34,0x36,0x36,0x2c, - 0x32,0x31,0x2e,0x38,0x31,0x31,0x2c,0x38,0x2e,0x36, - 0x31,0x36,0x2c,0x32,0x31,0x2e,0x35,0x33,0x36,0x2c, - 0x38,0x2e,0x36,0x31,0x36,0x7a,0x0d,0x0a,0x09,0x09, - 0x09,0x20,0x4d,0x31,0x36,0x2e,0x38,0x39,0x37,0x2c, - 0x37,0x2e,0x31,0x31,0x36,0x68,0x33,0x2e,0x32,0x36, - 0x38,0x4c,0x31,0x38,0x2e,0x35,0x33,0x2c,0x34,0x2e, - 0x35,0x37,0x31,0x4c,0x31,0x36,0x2e,0x38,0x39,0x37, - 0x2c,0x37,0x2e,0x31,0x31,0x36,0x7a,0x22,0x2f,0x3e, - 0x0d,0x0a,0x09,0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x09, - 0x3c,0x67,0x3e,0x0d,0x0a,0x09,0x09,0x3c,0x70,0x61, + 0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x32,0x31, + 0x2e,0x35,0x33,0x36,0x2c,0x38,0x2e,0x36,0x31,0x36, + 0x68,0x2d,0x36,0x2e,0x30,0x31,0x32,0x63,0x2d,0x30, + 0x2e,0x32,0x37,0x33,0x2c,0x30,0x2d,0x30,0x2e,0x35, + 0x32,0x35,0x2d,0x30,0x2e,0x31,0x35,0x2d,0x30,0x2e, + 0x36,0x35,0x37,0x2d,0x30,0x2e,0x33,0x39,0x63,0x2d, + 0x30,0x2e,0x31,0x33,0x32,0x2d,0x30,0x2e,0x32,0x34, + 0x31,0x2d,0x30,0x2e,0x31,0x32,0x31,0x2d,0x30,0x2e, + 0x35,0x33,0x34,0x2c,0x30,0x2e,0x30,0x32,0x36,0x2d, + 0x30,0x2e,0x37,0x36,0x36,0x6c,0x33,0x2e,0x30,0x30, + 0x35,0x2d,0x34,0x2e,0x36,0x38,0x34,0x0a,0x09,0x09, + 0x09,0x63,0x30,0x2e,0x32,0x37,0x36,0x2d,0x30,0x2e, + 0x34,0x33,0x31,0x2c,0x30,0x2e,0x39,0x38,0x36,0x2d, + 0x30,0x2e,0x34,0x33,0x2c,0x31,0x2e,0x32,0x36,0x34, + 0x2c,0x30,0x6c,0x33,0x2e,0x30,0x30,0x35,0x2c,0x34, + 0x2e,0x36,0x38,0x34,0x63,0x30,0x2e,0x31,0x34,0x37, + 0x2c,0x30,0x2e,0x32,0x33,0x31,0x2c,0x30,0x2e,0x31, + 0x35,0x39,0x2c,0x30,0x2e,0x35,0x32,0x34,0x2c,0x30, + 0x2e,0x30,0x32,0x36,0x2c,0x30,0x2e,0x37,0x36,0x36, + 0x43,0x32,0x32,0x2e,0x30,0x36,0x33,0x2c,0x38,0x2e, + 0x34,0x36,0x36,0x2c,0x32,0x31,0x2e,0x38,0x31,0x31, + 0x2c,0x38,0x2e,0x36,0x31,0x36,0x2c,0x32,0x31,0x2e, + 0x35,0x33,0x36,0x2c,0x38,0x2e,0x36,0x31,0x36,0x7a, + 0x0a,0x09,0x09,0x09,0x20,0x4d,0x31,0x36,0x2e,0x38, + 0x39,0x37,0x2c,0x37,0x2e,0x31,0x31,0x36,0x68,0x33, + 0x2e,0x32,0x36,0x38,0x4c,0x31,0x38,0x2e,0x35,0x33, + 0x2c,0x34,0x2e,0x35,0x37,0x31,0x4c,0x31,0x36,0x2e, + 0x38,0x39,0x37,0x2c,0x37,0x2e,0x31,0x31,0x36,0x7a, + 0x22,0x2f,0x3e,0x0a,0x09,0x3c,0x2f,0x67,0x3e,0x0a, + 0x09,0x3c,0x67,0x3e,0x0a,0x09,0x09,0x3c,0x70,0x61, 0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23, 0x46,0x46,0x46,0x46,0x46,0x46,0x22,0x20,0x64,0x3d, 0x22,0x4d,0x37,0x2e,0x38,0x30,0x39,0x2c,0x32,0x32, @@ -223,107 +220,106 @@ const unsigned char help_dpad_up_svg_data[3213] = { 0x30,0x2e,0x32,0x31,0x35,0x2d,0x30,0x2e,0x31,0x33, 0x38,0x2d,0x30,0x2e,0x33,0x34,0x35,0x2d,0x30,0x2e, 0x33,0x37,0x36,0x2d,0x30,0x2e,0x33,0x34,0x35,0x2d, - 0x30,0x2e,0x36,0x33,0x31,0x0d,0x0a,0x09,0x09,0x09, - 0x73,0x30,0x2e,0x31,0x33,0x2d,0x30,0x2e,0x34,0x39, - 0x33,0x2c,0x30,0x2e,0x33,0x34,0x35,0x2d,0x30,0x2e, - 0x36,0x33,0x31,0x6c,0x34,0x2e,0x36,0x38,0x34,0x2d, - 0x33,0x2e,0x30,0x30,0x36,0x63,0x30,0x2e,0x32,0x33, - 0x2d,0x30,0x2e,0x31,0x34,0x38,0x2c,0x30,0x2e,0x35, - 0x32,0x34,0x2d,0x30,0x2e,0x31,0x35,0x38,0x2c,0x30, - 0x2e,0x37,0x36,0x36,0x2d,0x30,0x2e,0x30,0x32,0x37, - 0x63,0x30,0x2e,0x32,0x34,0x2c,0x30,0x2e,0x31,0x33, - 0x31,0x2c,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2e,0x33, - 0x38,0x34,0x2c,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2e, - 0x36,0x35,0x38,0x76,0x36,0x2e,0x30,0x31,0x0d,0x0a, - 0x09,0x09,0x09,0x63,0x30,0x2c,0x30,0x2e,0x32,0x37, - 0x34,0x2d,0x30,0x2e,0x31,0x34,0x38,0x2c,0x30,0x2e, - 0x35,0x32,0x36,0x2d,0x30,0x2e,0x33,0x39,0x2c,0x30, - 0x2e,0x36,0x35,0x38,0x43,0x38,0x2e,0x30,0x35,0x36, - 0x2c,0x32,0x32,0x2e,0x32,0x35,0x34,0x2c,0x37,0x2e, - 0x39,0x33,0x32,0x2c,0x32,0x32,0x2e,0x32,0x38,0x34, - 0x2c,0x37,0x2e,0x38,0x30,0x39,0x2c,0x32,0x32,0x2e, - 0x32,0x38,0x34,0x7a,0x20,0x4d,0x34,0x2e,0x35,0x31, - 0x34,0x2c,0x31,0x38,0x2e,0x35,0x33,0x6c,0x32,0x2e, - 0x35,0x34,0x35,0x2c,0x31,0x2e,0x36,0x33,0x32,0x76, - 0x2d,0x33,0x2e,0x32,0x36,0x35,0x4c,0x34,0x2e,0x35, - 0x31,0x34,0x2c,0x31,0x38,0x2e,0x35,0x33,0x7a,0x22, - 0x2f,0x3e,0x0d,0x0a,0x09,0x3c,0x2f,0x67,0x3e,0x0d, - 0x0a,0x09,0x3c,0x67,0x3e,0x0d,0x0a,0x09,0x09,0x3c, - 0x70,0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d, - 0x22,0x23,0x46,0x46,0x46,0x46,0x46,0x46,0x22,0x20, - 0x64,0x3d,0x22,0x4d,0x32,0x39,0x2e,0x31,0x39,0x35, - 0x2c,0x32,0x32,0x2e,0x32,0x38,0x34,0x63,0x2d,0x30, - 0x2e,0x31,0x32,0x34,0x2c,0x30,0x2d,0x30,0x2e,0x32, - 0x34,0x36,0x2d,0x30,0x2e,0x30,0x33,0x2d,0x30,0x2e, - 0x33,0x35,0x38,0x2d,0x30,0x2e,0x30,0x39,0x32,0x63, - 0x2d,0x30,0x2e,0x32,0x34,0x31,0x2d,0x30,0x2e,0x31, - 0x33,0x32,0x2d,0x30,0x2e,0x33,0x39,0x32,0x2d,0x30, - 0x2e,0x33,0x38,0x34,0x2d,0x30,0x2e,0x33,0x39,0x32, - 0x2d,0x30,0x2e,0x36,0x35,0x38,0x76,0x2d,0x36,0x2e, - 0x30,0x31,0x0d,0x0a,0x09,0x09,0x09,0x63,0x30,0x2d, - 0x30,0x2e,0x32,0x37,0x34,0x2c,0x30,0x2e,0x31,0x34, - 0x39,0x2d,0x30,0x2e,0x35,0x32,0x36,0x2c,0x30,0x2e, - 0x33,0x39,0x32,0x2d,0x30,0x2e,0x36,0x35,0x38,0x63, - 0x30,0x2e,0x32,0x33,0x39,0x2d,0x30,0x2e,0x31,0x33, - 0x31,0x2c,0x30,0x2e,0x35,0x33,0x33,0x2d,0x30,0x2e, - 0x31,0x32,0x33,0x2c,0x30,0x2e,0x37,0x36,0x35,0x2c, - 0x30,0x2e,0x30,0x32,0x37,0x6c,0x34,0x2e,0x36,0x38, - 0x35,0x2c,0x33,0x2e,0x30,0x30,0x35,0x63,0x30,0x2e, - 0x32,0x31,0x35,0x2c,0x30,0x2e,0x31,0x33,0x38,0x2c, - 0x30,0x2e,0x33,0x34,0x35,0x2c,0x30,0x2e,0x33,0x37, - 0x36,0x2c,0x30,0x2e,0x33,0x34,0x35,0x2c,0x30,0x2e, - 0x36,0x33,0x31,0x0d,0x0a,0x09,0x09,0x09,0x73,0x2d, - 0x30,0x2e,0x31,0x33,0x2c,0x30,0x2e,0x34,0x39,0x33, - 0x2d,0x30,0x2e,0x33,0x34,0x35,0x2c,0x30,0x2e,0x36, - 0x33,0x31,0x6c,0x2d,0x34,0x2e,0x36,0x38,0x35,0x2c, - 0x33,0x2e,0x30,0x30,0x34,0x43,0x32,0x39,0x2e,0x34, - 0x37,0x38,0x2c,0x32,0x32,0x2e,0x32,0x34,0x34,0x2c, - 0x32,0x39,0x2e,0x33,0x33,0x36,0x2c,0x32,0x32,0x2e, - 0x32,0x38,0x34,0x2c,0x32,0x39,0x2e,0x31,0x39,0x35, - 0x2c,0x32,0x32,0x2e,0x32,0x38,0x34,0x7a,0x20,0x4d, - 0x32,0x39,0x2e,0x39,0x34,0x35,0x2c,0x31,0x36,0x2e, - 0x38,0x39,0x36,0x76,0x33,0x2e,0x32,0x36,0x36,0x6c, - 0x32,0x2e,0x35,0x34,0x36,0x2d,0x31,0x2e,0x36,0x33, - 0x33,0x0d,0x0a,0x09,0x09,0x09,0x4c,0x32,0x39,0x2e, - 0x39,0x34,0x35,0x2c,0x31,0x36,0x2e,0x38,0x39,0x36, - 0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x09,0x3c,0x2f,0x67, - 0x3e,0x0d,0x0a,0x09,0x3c,0x67,0x3e,0x0d,0x0a,0x09, - 0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69,0x6c, - 0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46,0x46, - 0x22,0x20,0x64,0x3d,0x22,0x4d,0x31,0x38,0x2e,0x35, - 0x33,0x2c,0x33,0x34,0x2e,0x36,0x32,0x36,0x4c,0x31, + 0x30,0x2e,0x36,0x33,0x31,0x0a,0x09,0x09,0x09,0x73, + 0x30,0x2e,0x31,0x33,0x2d,0x30,0x2e,0x34,0x39,0x33, + 0x2c,0x30,0x2e,0x33,0x34,0x35,0x2d,0x30,0x2e,0x36, + 0x33,0x31,0x6c,0x34,0x2e,0x36,0x38,0x34,0x2d,0x33, + 0x2e,0x30,0x30,0x36,0x63,0x30,0x2e,0x32,0x33,0x2d, + 0x30,0x2e,0x31,0x34,0x38,0x2c,0x30,0x2e,0x35,0x32, + 0x34,0x2d,0x30,0x2e,0x31,0x35,0x38,0x2c,0x30,0x2e, + 0x37,0x36,0x36,0x2d,0x30,0x2e,0x30,0x32,0x37,0x63, + 0x30,0x2e,0x32,0x34,0x2c,0x30,0x2e,0x31,0x33,0x31, + 0x2c,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2e,0x33,0x38, + 0x34,0x2c,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2e,0x36, + 0x35,0x38,0x76,0x36,0x2e,0x30,0x31,0x0a,0x09,0x09, + 0x09,0x63,0x30,0x2c,0x30,0x2e,0x32,0x37,0x34,0x2d, + 0x30,0x2e,0x31,0x34,0x38,0x2c,0x30,0x2e,0x35,0x32, + 0x36,0x2d,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2e,0x36, + 0x35,0x38,0x43,0x38,0x2e,0x30,0x35,0x36,0x2c,0x32, + 0x32,0x2e,0x32,0x35,0x34,0x2c,0x37,0x2e,0x39,0x33, + 0x32,0x2c,0x32,0x32,0x2e,0x32,0x38,0x34,0x2c,0x37, + 0x2e,0x38,0x30,0x39,0x2c,0x32,0x32,0x2e,0x32,0x38, + 0x34,0x7a,0x20,0x4d,0x34,0x2e,0x35,0x31,0x34,0x2c, + 0x31,0x38,0x2e,0x35,0x33,0x6c,0x32,0x2e,0x35,0x34, + 0x35,0x2c,0x31,0x2e,0x36,0x33,0x32,0x76,0x2d,0x33, + 0x2e,0x32,0x36,0x35,0x4c,0x34,0x2e,0x35,0x31,0x34, + 0x2c,0x31,0x38,0x2e,0x35,0x33,0x7a,0x22,0x2f,0x3e, + 0x0a,0x09,0x3c,0x2f,0x67,0x3e,0x0a,0x09,0x3c,0x67, + 0x3e,0x0a,0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20, + 0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46, + 0x46,0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x32, + 0x39,0x2e,0x31,0x39,0x35,0x2c,0x32,0x32,0x2e,0x32, + 0x38,0x34,0x63,0x2d,0x30,0x2e,0x31,0x32,0x34,0x2c, + 0x30,0x2d,0x30,0x2e,0x32,0x34,0x36,0x2d,0x30,0x2e, + 0x30,0x33,0x2d,0x30,0x2e,0x33,0x35,0x38,0x2d,0x30, + 0x2e,0x30,0x39,0x32,0x63,0x2d,0x30,0x2e,0x32,0x34, + 0x31,0x2d,0x30,0x2e,0x31,0x33,0x32,0x2d,0x30,0x2e, + 0x33,0x39,0x32,0x2d,0x30,0x2e,0x33,0x38,0x34,0x2d, + 0x30,0x2e,0x33,0x39,0x32,0x2d,0x30,0x2e,0x36,0x35, + 0x38,0x76,0x2d,0x36,0x2e,0x30,0x31,0x0a,0x09,0x09, + 0x09,0x63,0x30,0x2d,0x30,0x2e,0x32,0x37,0x34,0x2c, + 0x30,0x2e,0x31,0x34,0x39,0x2d,0x30,0x2e,0x35,0x32, + 0x36,0x2c,0x30,0x2e,0x33,0x39,0x32,0x2d,0x30,0x2e, + 0x36,0x35,0x38,0x63,0x30,0x2e,0x32,0x33,0x39,0x2d, + 0x30,0x2e,0x31,0x33,0x31,0x2c,0x30,0x2e,0x35,0x33, + 0x33,0x2d,0x30,0x2e,0x31,0x32,0x33,0x2c,0x30,0x2e, + 0x37,0x36,0x35,0x2c,0x30,0x2e,0x30,0x32,0x37,0x6c, + 0x34,0x2e,0x36,0x38,0x35,0x2c,0x33,0x2e,0x30,0x30, + 0x35,0x63,0x30,0x2e,0x32,0x31,0x35,0x2c,0x30,0x2e, + 0x31,0x33,0x38,0x2c,0x30,0x2e,0x33,0x34,0x35,0x2c, + 0x30,0x2e,0x33,0x37,0x36,0x2c,0x30,0x2e,0x33,0x34, + 0x35,0x2c,0x30,0x2e,0x36,0x33,0x31,0x0a,0x09,0x09, + 0x09,0x73,0x2d,0x30,0x2e,0x31,0x33,0x2c,0x30,0x2e, + 0x34,0x39,0x33,0x2d,0x30,0x2e,0x33,0x34,0x35,0x2c, + 0x30,0x2e,0x36,0x33,0x31,0x6c,0x2d,0x34,0x2e,0x36, + 0x38,0x35,0x2c,0x33,0x2e,0x30,0x30,0x34,0x43,0x32, + 0x39,0x2e,0x34,0x37,0x38,0x2c,0x32,0x32,0x2e,0x32, + 0x34,0x34,0x2c,0x32,0x39,0x2e,0x33,0x33,0x36,0x2c, + 0x32,0x32,0x2e,0x32,0x38,0x34,0x2c,0x32,0x39,0x2e, + 0x31,0x39,0x35,0x2c,0x32,0x32,0x2e,0x32,0x38,0x34, + 0x7a,0x20,0x4d,0x32,0x39,0x2e,0x39,0x34,0x35,0x2c, + 0x31,0x36,0x2e,0x38,0x39,0x36,0x76,0x33,0x2e,0x32, + 0x36,0x36,0x6c,0x32,0x2e,0x35,0x34,0x36,0x2d,0x31, + 0x2e,0x36,0x33,0x33,0x0a,0x09,0x09,0x09,0x4c,0x32, + 0x39,0x2e,0x39,0x34,0x35,0x2c,0x31,0x36,0x2e,0x38, + 0x39,0x36,0x7a,0x22,0x2f,0x3e,0x0a,0x09,0x3c,0x2f, + 0x67,0x3e,0x0a,0x09,0x3c,0x67,0x3e,0x0a,0x09,0x09, + 0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c, + 0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46,0x46,0x22, + 0x20,0x64,0x3d,0x22,0x4d,0x31,0x38,0x2e,0x35,0x33, + 0x2c,0x33,0x34,0x2e,0x36,0x32,0x36,0x4c,0x31,0x38, + 0x2e,0x35,0x33,0x2c,0x33,0x34,0x2e,0x36,0x32,0x36, + 0x63,0x2d,0x30,0x2e,0x32,0x35,0x35,0x2c,0x30,0x2d, + 0x30,0x2e,0x34,0x39,0x32,0x2d,0x30,0x2e,0x31,0x33, + 0x2d,0x30,0x2e,0x36,0x33,0x31,0x2d,0x30,0x2e,0x33, + 0x34,0x35,0x6c,0x2d,0x33,0x2e,0x30,0x30,0x35,0x2d, + 0x34,0x2e,0x36,0x38,0x34,0x0a,0x09,0x09,0x09,0x63, + 0x2d,0x30,0x2e,0x31,0x34,0x37,0x2d,0x30,0x2e,0x32, + 0x33,0x31,0x2d,0x30,0x2e,0x31,0x35,0x38,0x2d,0x30, + 0x2e,0x35,0x32,0x34,0x2d,0x30,0x2e,0x30,0x32,0x36, + 0x2d,0x30,0x2e,0x37,0x36,0x36,0x73,0x30,0x2e,0x33, + 0x38,0x34,0x2d,0x30,0x2e,0x33,0x39,0x31,0x2c,0x30, + 0x2e,0x36,0x35,0x37,0x2d,0x30,0x2e,0x33,0x39,0x31, + 0x68,0x36,0x2e,0x30,0x31,0x32,0x63,0x30,0x2e,0x32, + 0x37,0x33,0x2c,0x30,0x2c,0x30,0x2e,0x35,0x32,0x35, + 0x2c,0x30,0x2e,0x31,0x34,0x38,0x2c,0x30,0x2e,0x36, + 0x35,0x37,0x2c,0x30,0x2e,0x33,0x39,0x31,0x0a,0x09, + 0x09,0x09,0x63,0x30,0x2e,0x31,0x33,0x33,0x2c,0x30, + 0x2e,0x32,0x34,0x2c,0x30,0x2e,0x31,0x32,0x31,0x2c, + 0x30,0x2e,0x35,0x33,0x33,0x2d,0x30,0x2e,0x30,0x32, + 0x36,0x2c,0x30,0x2e,0x37,0x36,0x36,0x6c,0x2d,0x33, + 0x2e,0x30,0x30,0x35,0x2c,0x34,0x2e,0x36,0x38,0x34, + 0x43,0x31,0x39,0x2e,0x30,0x32,0x33,0x2c,0x33,0x34, + 0x2e,0x34,0x39,0x36,0x2c,0x31,0x38,0x2e,0x37,0x38, + 0x36,0x2c,0x33,0x34,0x2e,0x36,0x32,0x36,0x2c,0x31, 0x38,0x2e,0x35,0x33,0x2c,0x33,0x34,0x2e,0x36,0x32, - 0x36,0x63,0x2d,0x30,0x2e,0x32,0x35,0x35,0x2c,0x30, - 0x2d,0x30,0x2e,0x34,0x39,0x32,0x2d,0x30,0x2e,0x31, - 0x33,0x2d,0x30,0x2e,0x36,0x33,0x31,0x2d,0x30,0x2e, - 0x33,0x34,0x35,0x6c,0x2d,0x33,0x2e,0x30,0x30,0x35, - 0x2d,0x34,0x2e,0x36,0x38,0x34,0x0d,0x0a,0x09,0x09, - 0x09,0x63,0x2d,0x30,0x2e,0x31,0x34,0x37,0x2d,0x30, - 0x2e,0x32,0x33,0x31,0x2d,0x30,0x2e,0x31,0x35,0x38, - 0x2d,0x30,0x2e,0x35,0x32,0x34,0x2d,0x30,0x2e,0x30, - 0x32,0x36,0x2d,0x30,0x2e,0x37,0x36,0x36,0x73,0x30, - 0x2e,0x33,0x38,0x34,0x2d,0x30,0x2e,0x33,0x39,0x31, - 0x2c,0x30,0x2e,0x36,0x35,0x37,0x2d,0x30,0x2e,0x33, - 0x39,0x31,0x68,0x36,0x2e,0x30,0x31,0x32,0x63,0x30, - 0x2e,0x32,0x37,0x33,0x2c,0x30,0x2c,0x30,0x2e,0x35, - 0x32,0x35,0x2c,0x30,0x2e,0x31,0x34,0x38,0x2c,0x30, - 0x2e,0x36,0x35,0x37,0x2c,0x30,0x2e,0x33,0x39,0x31, - 0x0d,0x0a,0x09,0x09,0x09,0x63,0x30,0x2e,0x31,0x33, - 0x33,0x2c,0x30,0x2e,0x32,0x34,0x2c,0x30,0x2e,0x31, - 0x32,0x31,0x2c,0x30,0x2e,0x35,0x33,0x33,0x2d,0x30, - 0x2e,0x30,0x32,0x36,0x2c,0x30,0x2e,0x37,0x36,0x36, - 0x6c,0x2d,0x33,0x2e,0x30,0x30,0x35,0x2c,0x34,0x2e, - 0x36,0x38,0x34,0x43,0x31,0x39,0x2e,0x30,0x32,0x33, - 0x2c,0x33,0x34,0x2e,0x34,0x39,0x36,0x2c,0x31,0x38, - 0x2e,0x37,0x38,0x36,0x2c,0x33,0x34,0x2e,0x36,0x32, - 0x36,0x2c,0x31,0x38,0x2e,0x35,0x33,0x2c,0x33,0x34, - 0x2e,0x36,0x32,0x36,0x7a,0x20,0x4d,0x31,0x36,0x2e, - 0x38,0x39,0x37,0x2c,0x32,0x39,0x2e,0x39,0x34,0x32, - 0x6c,0x31,0x2e,0x36,0x33,0x33,0x2c,0x32,0x2e,0x35, - 0x34,0x35,0x0d,0x0a,0x09,0x09,0x09,0x6c,0x31,0x2e, - 0x36,0x33,0x35,0x2d,0x32,0x2e,0x35,0x34,0x35,0x48, - 0x31,0x36,0x2e,0x38,0x39,0x37,0x7a,0x22,0x2f,0x3e, - 0x0d,0x0a,0x09,0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x3c, - 0x2f,0x67,0x3e,0x0d,0x0a,0x3c,0x2f,0x73,0x76,0x67, - 0x3e,0x0d,0x0a + 0x36,0x7a,0x20,0x4d,0x31,0x36,0x2e,0x38,0x39,0x37, + 0x2c,0x32,0x39,0x2e,0x39,0x34,0x32,0x6c,0x31,0x2e, + 0x36,0x33,0x33,0x2c,0x32,0x2e,0x35,0x34,0x35,0x0a, + 0x09,0x09,0x09,0x6c,0x31,0x2e,0x36,0x33,0x35,0x2d, + 0x32,0x2e,0x35,0x34,0x35,0x48,0x31,0x36,0x2e,0x38, + 0x39,0x37,0x7a,0x22,0x2f,0x3e,0x0a,0x09,0x3c,0x2f, + 0x67,0x3e,0x0a,0x3c,0x2f,0x67,0x3e,0x0a,0x3c,0x2f, + 0x73,0x76,0x67,0x3e,0x0a }; + diff --git a/data/converted/help_dpad_updown_svg.cpp b/data/converted/help_dpad_updown_svg.cpp index 2853153483..f1612667d0 100644 --- a/data/converted/help_dpad_updown_svg.cpp +++ b/data/converted/help_dpad_updown_svg.cpp @@ -2,84 +2,83 @@ #include "../Resources.h" -const size_t help_dpad_updown_svg_size = 3290; -const unsigned char help_dpad_updown_svg_data[3290] = { +const size_t help_dpad_updown_svg_size = 3241; +const unsigned char help_dpad_updown_svg_data[3241] = { 0x3c,0x3f,0x78,0x6d,0x6c,0x20,0x76,0x65,0x72,0x73, 0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x30,0x22,0x20, 0x65,0x6e,0x63,0x6f,0x64,0x69,0x6e,0x67,0x3d,0x22, - 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0d,0x0a, - 0x3c,0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72, - 0x61,0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62, - 0x65,0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61, - 0x74,0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33, - 0x2c,0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f, - 0x72,0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e, - 0x20,0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72, - 0x73,0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30, - 0x20,0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20, - 0x20,0x2d,0x2d,0x3e,0x0d,0x0a,0x3c,0x21,0x44,0x4f, - 0x43,0x54,0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20, - 0x50,0x55,0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f, - 0x2f,0x57,0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20, - 0x53,0x56,0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45, - 0x4e,0x22,0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, - 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, - 0x67,0x2f,0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73, - 0x2f,0x53,0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44, - 0x54,0x44,0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64, - 0x74,0x64,0x22,0x3e,0x0d,0x0a,0x3c,0x73,0x76,0x67, - 0x20,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22, - 0x31,0x2e,0x31,0x22,0x20,0x69,0x64,0x3d,0x22,0x5f, - 0x78,0x33,0x30,0x5f,0x22,0x20,0x78,0x6d,0x6c,0x6e, - 0x73,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f, - 0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67, - 0x2f,0x32,0x30,0x30,0x30,0x2f,0x73,0x76,0x67,0x22, - 0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78,0x6c,0x69, - 0x6e,0x6b,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, - 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, - 0x67,0x2f,0x31,0x39,0x39,0x39,0x2f,0x78,0x6c,0x69, - 0x6e,0x6b,0x22,0x20,0x78,0x3d,0x22,0x30,0x70,0x78, - 0x22,0x20,0x79,0x3d,0x22,0x30,0x70,0x78,0x22,0x0d, - 0x0a,0x09,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22, - 0x33,0x37,0x2e,0x30,0x36,0x31,0x70,0x78,0x22,0x20, - 0x68,0x65,0x69,0x67,0x68,0x74,0x3d,0x22,0x33,0x37, - 0x2e,0x30,0x36,0x31,0x70,0x78,0x22,0x20,0x76,0x69, - 0x65,0x77,0x42,0x6f,0x78,0x3d,0x22,0x30,0x20,0x30, - 0x20,0x33,0x37,0x2e,0x30,0x36,0x31,0x20,0x33,0x37, - 0x2e,0x30,0x36,0x31,0x22,0x20,0x65,0x6e,0x61,0x62, - 0x6c,0x65,0x2d,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f, - 0x75,0x6e,0x64,0x3d,0x22,0x6e,0x65,0x77,0x20,0x30, - 0x20,0x30,0x20,0x33,0x37,0x2e,0x30,0x36,0x31,0x20, - 0x33,0x37,0x2e,0x30,0x36,0x31,0x22,0x20,0x78,0x6d, - 0x6c,0x3a,0x73,0x70,0x61,0x63,0x65,0x3d,0x22,0x70, - 0x72,0x65,0x73,0x65,0x72,0x76,0x65,0x22,0x3e,0x0d, - 0x0a,0x3c,0x67,0x3e,0x0d,0x0a,0x09,0x3c,0x67,0x3e, - 0x0d,0x0a,0x09,0x09,0x3c,0x67,0x3e,0x0d,0x0a,0x09, - 0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69, - 0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46, - 0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x32,0x32,0x2e, - 0x30,0x38,0x36,0x2c,0x33,0x37,0x2e,0x30,0x36,0x68, - 0x2d,0x37,0x2e,0x31,0x31,0x31,0x63,0x2d,0x32,0x2e, - 0x32,0x38,0x39,0x2c,0x30,0x2d,0x33,0x2e,0x31,0x31, - 0x39,0x2d,0x31,0x2e,0x38,0x36,0x36,0x2d,0x33,0x2e, - 0x31,0x31,0x39,0x2d,0x33,0x2e,0x31,0x32,0x31,0x76, - 0x2d,0x38,0x2e,0x37,0x33,0x32,0x48,0x33,0x2e,0x31, - 0x32,0x31,0x43,0x30,0x2e,0x38,0x33,0x31,0x2c,0x32, - 0x35,0x2e,0x32,0x30,0x36,0x2c,0x30,0x2c,0x32,0x33, - 0x2e,0x33,0x34,0x2c,0x30,0x2c,0x32,0x32,0x2e,0x30, - 0x38,0x35,0x0d,0x0a,0x09,0x09,0x09,0x09,0x76,0x2d, - 0x37,0x2e,0x31,0x31,0x63,0x30,0x2d,0x32,0x2e,0x32, - 0x38,0x39,0x2c,0x31,0x2e,0x38,0x36,0x37,0x2d,0x33, - 0x2e,0x31,0x32,0x2c,0x33,0x2e,0x31,0x32,0x31,0x2d, - 0x33,0x2e,0x31,0x32,0x68,0x38,0x2e,0x37,0x33,0x33, - 0x56,0x33,0x2e,0x31,0x32,0x31,0x43,0x31,0x31,0x2e, - 0x38,0x35,0x35,0x2c,0x30,0x2e,0x38,0x33,0x31,0x2c, - 0x31,0x33,0x2e,0x37,0x32,0x2c,0x30,0x2c,0x31,0x34, - 0x2e,0x39,0x37,0x34,0x2c,0x30,0x68,0x37,0x2e,0x31, - 0x31,0x31,0x63,0x32,0x2e,0x32,0x39,0x2c,0x30,0x2c, - 0x33,0x2e,0x31,0x32,0x31,0x2c,0x31,0x2e,0x38,0x36, - 0x37,0x2c,0x33,0x2e,0x31,0x32,0x31,0x2c,0x33,0x2e, - 0x31,0x32,0x31,0x76,0x38,0x2e,0x37,0x33,0x32,0x0d, + 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0a,0x3c, + 0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72,0x61, + 0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62,0x65, + 0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61,0x74, + 0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33,0x2c, + 0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f,0x72, + 0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e,0x20, + 0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72,0x73, + 0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30,0x20, + 0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20,0x20, + 0x2d,0x2d,0x3e,0x0a,0x3c,0x21,0x44,0x4f,0x43,0x54, + 0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20,0x50,0x55, + 0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f,0x2f,0x57, + 0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20,0x53,0x56, + 0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45,0x4e,0x22, + 0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73,0x2f,0x53, + 0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44,0x54,0x44, + 0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64,0x74,0x64, + 0x22,0x3e,0x0a,0x3c,0x73,0x76,0x67,0x20,0x76,0x65, + 0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x31, + 0x22,0x20,0x69,0x64,0x3d,0x22,0x5f,0x78,0x33,0x30, + 0x5f,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3d,0x22, + 0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77, + 0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f,0x32,0x30, + 0x30,0x30,0x2f,0x73,0x76,0x67,0x22,0x20,0x78,0x6d, + 0x6c,0x6e,0x73,0x3a,0x78,0x6c,0x69,0x6e,0x6b,0x3d, + 0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77, + 0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f,0x31, + 0x39,0x39,0x39,0x2f,0x78,0x6c,0x69,0x6e,0x6b,0x22, + 0x20,0x78,0x3d,0x22,0x30,0x70,0x78,0x22,0x20,0x79, + 0x3d,0x22,0x30,0x70,0x78,0x22,0x0a,0x09,0x20,0x77, + 0x69,0x64,0x74,0x68,0x3d,0x22,0x33,0x37,0x2e,0x30, + 0x36,0x31,0x70,0x78,0x22,0x20,0x68,0x65,0x69,0x67, + 0x68,0x74,0x3d,0x22,0x33,0x37,0x2e,0x30,0x36,0x31, + 0x70,0x78,0x22,0x20,0x76,0x69,0x65,0x77,0x42,0x6f, + 0x78,0x3d,0x22,0x30,0x20,0x30,0x20,0x33,0x37,0x2e, + 0x30,0x36,0x31,0x20,0x33,0x37,0x2e,0x30,0x36,0x31, + 0x22,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0x2d,0x62, + 0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x3d, + 0x22,0x6e,0x65,0x77,0x20,0x30,0x20,0x30,0x20,0x33, + 0x37,0x2e,0x30,0x36,0x31,0x20,0x33,0x37,0x2e,0x30, + 0x36,0x31,0x22,0x20,0x78,0x6d,0x6c,0x3a,0x73,0x70, + 0x61,0x63,0x65,0x3d,0x22,0x70,0x72,0x65,0x73,0x65, + 0x72,0x76,0x65,0x22,0x3e,0x0a,0x3c,0x67,0x3e,0x0a, + 0x09,0x3c,0x67,0x3e,0x0a,0x09,0x09,0x3c,0x67,0x3e, + 0x0a,0x09,0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20, + 0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46, + 0x46,0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x32, + 0x32,0x2e,0x30,0x38,0x36,0x2c,0x33,0x37,0x2e,0x30, + 0x36,0x68,0x2d,0x37,0x2e,0x31,0x31,0x31,0x63,0x2d, + 0x32,0x2e,0x32,0x38,0x39,0x2c,0x30,0x2d,0x33,0x2e, + 0x31,0x31,0x39,0x2d,0x31,0x2e,0x38,0x36,0x36,0x2d, + 0x33,0x2e,0x31,0x31,0x39,0x2d,0x33,0x2e,0x31,0x32, + 0x31,0x76,0x2d,0x38,0x2e,0x37,0x33,0x32,0x48,0x33, + 0x2e,0x31,0x32,0x31,0x43,0x30,0x2e,0x38,0x33,0x31, + 0x2c,0x32,0x35,0x2e,0x32,0x30,0x36,0x2c,0x30,0x2c, + 0x32,0x33,0x2e,0x33,0x34,0x2c,0x30,0x2c,0x32,0x32, + 0x2e,0x30,0x38,0x35,0x0a,0x09,0x09,0x09,0x09,0x76, + 0x2d,0x37,0x2e,0x31,0x31,0x63,0x30,0x2d,0x32,0x2e, + 0x32,0x38,0x39,0x2c,0x31,0x2e,0x38,0x36,0x37,0x2d, + 0x33,0x2e,0x31,0x32,0x2c,0x33,0x2e,0x31,0x32,0x31, + 0x2d,0x33,0x2e,0x31,0x32,0x68,0x38,0x2e,0x37,0x33, + 0x33,0x56,0x33,0x2e,0x31,0x32,0x31,0x43,0x31,0x31, + 0x2e,0x38,0x35,0x35,0x2c,0x30,0x2e,0x38,0x33,0x31, + 0x2c,0x31,0x33,0x2e,0x37,0x32,0x2c,0x30,0x2c,0x31, + 0x34,0x2e,0x39,0x37,0x34,0x2c,0x30,0x68,0x37,0x2e, + 0x31,0x31,0x31,0x63,0x32,0x2e,0x32,0x39,0x2c,0x30, + 0x2c,0x33,0x2e,0x31,0x32,0x31,0x2c,0x31,0x2e,0x38, + 0x36,0x37,0x2c,0x33,0x2e,0x31,0x32,0x31,0x2c,0x33, + 0x2e,0x31,0x32,0x31,0x76,0x38,0x2e,0x37,0x33,0x32, 0x0a,0x09,0x09,0x09,0x09,0x68,0x38,0x2e,0x37,0x33, 0x31,0x63,0x32,0x2e,0x32,0x39,0x2c,0x30,0x2c,0x33, 0x2e,0x31,0x32,0x31,0x2c,0x31,0x2e,0x38,0x36,0x35, @@ -89,68 +88,67 @@ const unsigned char help_dpad_updown_svg_data[3290] = { 0x33,0x2e,0x31,0x32,0x31,0x2d,0x33,0x2e,0x31,0x32, 0x31,0x2c,0x33,0x2e,0x31,0x32,0x31,0x68,0x2d,0x38, 0x2e,0x37,0x33,0x31,0x76,0x38,0x2e,0x37,0x33,0x32, - 0x0d,0x0a,0x09,0x09,0x09,0x09,0x43,0x32,0x35,0x2e, - 0x32,0x30,0x37,0x2c,0x33,0x36,0x2e,0x32,0x32,0x39, - 0x2c,0x32,0x33,0x2e,0x33,0x34,0x31,0x2c,0x33,0x37, - 0x2e,0x30,0x36,0x2c,0x32,0x32,0x2e,0x30,0x38,0x36, - 0x2c,0x33,0x37,0x2e,0x30,0x36,0x7a,0x20,0x4d,0x33, - 0x2e,0x31,0x32,0x31,0x2c,0x31,0x33,0x2e,0x33,0x35, - 0x34,0x43,0x32,0x2e,0x37,0x34,0x35,0x2c,0x31,0x33, - 0x2e,0x33,0x35,0x39,0x2c,0x31,0x2e,0x35,0x2c,0x31, - 0x33,0x2e,0x34,0x39,0x33,0x2c,0x31,0x2e,0x35,0x2c, - 0x31,0x34,0x2e,0x39,0x37,0x34,0x76,0x37,0x2e,0x31, - 0x31,0x0d,0x0a,0x09,0x09,0x09,0x09,0x63,0x30,0x2e, - 0x30,0x30,0x36,0x2c,0x30,0x2e,0x33,0x37,0x36,0x2c, - 0x30,0x2e,0x31,0x33,0x39,0x2c,0x31,0x2e,0x36,0x32, - 0x31,0x2c,0x31,0x2e,0x36,0x32,0x31,0x2c,0x31,0x2e, - 0x36,0x32,0x31,0x68,0x31,0x30,0x2e,0x32,0x33,0x33, - 0x76,0x31,0x30,0x2e,0x32,0x33,0x32,0x63,0x30,0x2e, - 0x30,0x30,0x35,0x2c,0x30,0x2e,0x33,0x37,0x36,0x2c, + 0x0a,0x09,0x09,0x09,0x09,0x43,0x32,0x35,0x2e,0x32, + 0x30,0x37,0x2c,0x33,0x36,0x2e,0x32,0x32,0x39,0x2c, + 0x32,0x33,0x2e,0x33,0x34,0x31,0x2c,0x33,0x37,0x2e, + 0x30,0x36,0x2c,0x32,0x32,0x2e,0x30,0x38,0x36,0x2c, + 0x33,0x37,0x2e,0x30,0x36,0x7a,0x20,0x4d,0x33,0x2e, + 0x31,0x32,0x31,0x2c,0x31,0x33,0x2e,0x33,0x35,0x34, + 0x43,0x32,0x2e,0x37,0x34,0x35,0x2c,0x31,0x33,0x2e, + 0x33,0x35,0x39,0x2c,0x31,0x2e,0x35,0x2c,0x31,0x33, + 0x2e,0x34,0x39,0x33,0x2c,0x31,0x2e,0x35,0x2c,0x31, + 0x34,0x2e,0x39,0x37,0x34,0x76,0x37,0x2e,0x31,0x31, + 0x0a,0x09,0x09,0x09,0x09,0x63,0x30,0x2e,0x30,0x30, + 0x36,0x2c,0x30,0x2e,0x33,0x37,0x36,0x2c,0x30,0x2e, + 0x31,0x33,0x39,0x2c,0x31,0x2e,0x36,0x32,0x31,0x2c, + 0x31,0x2e,0x36,0x32,0x31,0x2c,0x31,0x2e,0x36,0x32, + 0x31,0x68,0x31,0x30,0x2e,0x32,0x33,0x33,0x76,0x31, + 0x30,0x2e,0x32,0x33,0x32,0x63,0x30,0x2e,0x30,0x30, + 0x35,0x2c,0x30,0x2e,0x33,0x37,0x36,0x2c,0x30,0x2e, + 0x31,0x34,0x2c,0x31,0x2e,0x36,0x32,0x31,0x2c,0x31, + 0x2e,0x36,0x31,0x39,0x2c,0x31,0x2e,0x36,0x32,0x31, + 0x68,0x37,0x2e,0x31,0x30,0x38,0x0a,0x09,0x09,0x09, + 0x09,0x63,0x30,0x2e,0x33,0x38,0x34,0x2d,0x30,0x2e, + 0x30,0x30,0x37,0x2c,0x31,0x2e,0x36,0x32,0x34,0x2d, + 0x30,0x2e,0x31,0x34,0x33,0x2c,0x31,0x2e,0x36,0x32, + 0x34,0x2d,0x31,0x2e,0x36,0x32,0x31,0x56,0x32,0x33, + 0x2e,0x37,0x30,0x36,0x68,0x31,0x30,0x2e,0x32,0x33, + 0x31,0x63,0x30,0x2e,0x33,0x37,0x36,0x2d,0x30,0x2e, + 0x30,0x30,0x36,0x2c,0x31,0x2e,0x36,0x32,0x31,0x2d, 0x30,0x2e,0x31,0x34,0x2c,0x31,0x2e,0x36,0x32,0x31, - 0x2c,0x31,0x2e,0x36,0x31,0x39,0x2c,0x31,0x2e,0x36, - 0x32,0x31,0x68,0x37,0x2e,0x31,0x30,0x38,0x0d,0x0a, - 0x09,0x09,0x09,0x09,0x63,0x30,0x2e,0x33,0x38,0x34, - 0x2d,0x30,0x2e,0x30,0x30,0x37,0x2c,0x31,0x2e,0x36, - 0x32,0x34,0x2d,0x30,0x2e,0x31,0x34,0x33,0x2c,0x31, - 0x2e,0x36,0x32,0x34,0x2d,0x31,0x2e,0x36,0x32,0x31, - 0x56,0x32,0x33,0x2e,0x37,0x30,0x36,0x68,0x31,0x30, - 0x2e,0x32,0x33,0x31,0x63,0x30,0x2e,0x33,0x37,0x36, - 0x2d,0x30,0x2e,0x30,0x30,0x36,0x2c,0x31,0x2e,0x36, - 0x32,0x31,0x2d,0x30,0x2e,0x31,0x34,0x2c,0x31,0x2e, - 0x36,0x32,0x31,0x2d,0x31,0x2e,0x36,0x32,0x31,0x76, - 0x2d,0x37,0x2e,0x31,0x31,0x0d,0x0a,0x09,0x09,0x09, - 0x09,0x63,0x2d,0x30,0x2e,0x30,0x30,0x36,0x2d,0x30, - 0x2e,0x33,0x37,0x36,0x2d,0x30,0x2e,0x31,0x34,0x2d, - 0x31,0x2e,0x36,0x32,0x2d,0x31,0x2e,0x36,0x32,0x31, - 0x2d,0x31,0x2e,0x36,0x32,0x68,0x2d,0x31,0x30,0x2e, - 0x32,0x33,0x56,0x33,0x2e,0x31,0x32,0x31,0x43,0x32, - 0x33,0x2e,0x37,0x30,0x31,0x2c,0x32,0x2e,0x37,0x34, - 0x35,0x2c,0x32,0x33,0x2e,0x35,0x36,0x37,0x2c,0x31, - 0x2e,0x35,0x2c,0x32,0x32,0x2e,0x30,0x38,0x36,0x2c, - 0x31,0x2e,0x35,0x68,0x2d,0x37,0x2e,0x31,0x31,0x31, - 0x0d,0x0a,0x09,0x09,0x09,0x09,0x63,0x2d,0x30,0x2e, - 0x33,0x37,0x36,0x2c,0x30,0x2e,0x30,0x30,0x36,0x2d, - 0x31,0x2e,0x36,0x31,0x39,0x2c,0x30,0x2e,0x31,0x34, - 0x2d,0x31,0x2e,0x36,0x31,0x39,0x2c,0x31,0x2e,0x36, - 0x32,0x31,0x76,0x31,0x30,0x2e,0x32,0x33,0x32,0x4c, - 0x33,0x2e,0x31,0x32,0x31,0x2c,0x31,0x33,0x2e,0x33, - 0x35,0x34,0x4c,0x33,0x2e,0x31,0x32,0x31,0x2c,0x31, - 0x33,0x2e,0x33,0x35,0x34,0x7a,0x22,0x2f,0x3e,0x0d, - 0x0a,0x09,0x09,0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x09, - 0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x09,0x3c,0x67,0x3e, - 0x0d,0x0a,0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20, - 0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46, - 0x46,0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x31, - 0x38,0x2e,0x35,0x33,0x31,0x2c,0x32,0x32,0x2e,0x31, - 0x38,0x31,0x63,0x2d,0x32,0x2e,0x30,0x31,0x33,0x2c, - 0x30,0x2d,0x33,0x2e,0x36,0x34,0x39,0x2d,0x31,0x2e, - 0x36,0x33,0x39,0x2d,0x33,0x2e,0x36,0x34,0x39,0x2d, - 0x33,0x2e,0x36,0x35,0x31,0x73,0x31,0x2e,0x36,0x33, - 0x38,0x2d,0x33,0x2e,0x36,0x35,0x2c,0x33,0x2e,0x36, - 0x34,0x39,0x2d,0x33,0x2e,0x36,0x35,0x63,0x32,0x2e, - 0x30,0x31,0x33,0x2c,0x30,0x2c,0x33,0x2e,0x36,0x35, - 0x2c,0x31,0x2e,0x36,0x33,0x39,0x2c,0x33,0x2e,0x36, - 0x35,0x2c,0x33,0x2e,0x36,0x35,0x0d,0x0a,0x09,0x09, + 0x2d,0x31,0x2e,0x36,0x32,0x31,0x76,0x2d,0x37,0x2e, + 0x31,0x31,0x0a,0x09,0x09,0x09,0x09,0x63,0x2d,0x30, + 0x2e,0x30,0x30,0x36,0x2d,0x30,0x2e,0x33,0x37,0x36, + 0x2d,0x30,0x2e,0x31,0x34,0x2d,0x31,0x2e,0x36,0x32, + 0x2d,0x31,0x2e,0x36,0x32,0x31,0x2d,0x31,0x2e,0x36, + 0x32,0x68,0x2d,0x31,0x30,0x2e,0x32,0x33,0x56,0x33, + 0x2e,0x31,0x32,0x31,0x43,0x32,0x33,0x2e,0x37,0x30, + 0x31,0x2c,0x32,0x2e,0x37,0x34,0x35,0x2c,0x32,0x33, + 0x2e,0x35,0x36,0x37,0x2c,0x31,0x2e,0x35,0x2c,0x32, + 0x32,0x2e,0x30,0x38,0x36,0x2c,0x31,0x2e,0x35,0x68, + 0x2d,0x37,0x2e,0x31,0x31,0x31,0x0a,0x09,0x09,0x09, + 0x09,0x63,0x2d,0x30,0x2e,0x33,0x37,0x36,0x2c,0x30, + 0x2e,0x30,0x30,0x36,0x2d,0x31,0x2e,0x36,0x31,0x39, + 0x2c,0x30,0x2e,0x31,0x34,0x2d,0x31,0x2e,0x36,0x31, + 0x39,0x2c,0x31,0x2e,0x36,0x32,0x31,0x76,0x31,0x30, + 0x2e,0x32,0x33,0x32,0x4c,0x33,0x2e,0x31,0x32,0x31, + 0x2c,0x31,0x33,0x2e,0x33,0x35,0x34,0x4c,0x33,0x2e, + 0x31,0x32,0x31,0x2c,0x31,0x33,0x2e,0x33,0x35,0x34, + 0x7a,0x22,0x2f,0x3e,0x0a,0x09,0x09,0x3c,0x2f,0x67, + 0x3e,0x0a,0x09,0x3c,0x2f,0x67,0x3e,0x0a,0x09,0x3c, + 0x67,0x3e,0x0a,0x09,0x09,0x3c,0x70,0x61,0x74,0x68, + 0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46, + 0x46,0x46,0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d, + 0x31,0x38,0x2e,0x35,0x33,0x31,0x2c,0x32,0x32,0x2e, + 0x31,0x38,0x31,0x63,0x2d,0x32,0x2e,0x30,0x31,0x33, + 0x2c,0x30,0x2d,0x33,0x2e,0x36,0x34,0x39,0x2d,0x31, + 0x2e,0x36,0x33,0x39,0x2d,0x33,0x2e,0x36,0x34,0x39, + 0x2d,0x33,0x2e,0x36,0x35,0x31,0x73,0x31,0x2e,0x36, + 0x33,0x38,0x2d,0x33,0x2e,0x36,0x35,0x2c,0x33,0x2e, + 0x36,0x34,0x39,0x2d,0x33,0x2e,0x36,0x35,0x63,0x32, + 0x2e,0x30,0x31,0x33,0x2c,0x30,0x2c,0x33,0x2e,0x36, + 0x35,0x2c,0x31,0x2e,0x36,0x33,0x39,0x2c,0x33,0x2e, + 0x36,0x35,0x2c,0x33,0x2e,0x36,0x35,0x0a,0x09,0x09, 0x09,0x43,0x32,0x32,0x2e,0x31,0x38,0x32,0x2c,0x32, 0x30,0x2e,0x35,0x34,0x33,0x2c,0x32,0x30,0x2e,0x35, 0x34,0x34,0x2c,0x32,0x32,0x2e,0x31,0x38,0x31,0x2c, @@ -162,56 +160,55 @@ const unsigned char help_dpad_updown_svg_data[3290] = { 0x2d,0x32,0x2e,0x31,0x34,0x39,0x2c,0x32,0x2e,0x31, 0x35,0x73,0x30,0x2e,0x39,0x36,0x35,0x2c,0x32,0x2e, 0x31,0x35,0x31,0x2c,0x32,0x2e,0x31,0x34,0x39,0x2c, - 0x32,0x2e,0x31,0x35,0x31,0x0d,0x0a,0x09,0x09,0x09, - 0x63,0x31,0x2e,0x31,0x38,0x36,0x2c,0x30,0x2c,0x32, - 0x2e,0x31,0x35,0x2d,0x30,0x2e,0x39,0x36,0x36,0x2c, - 0x32,0x2e,0x31,0x35,0x2d,0x32,0x2e,0x31,0x35,0x31, - 0x43,0x32,0x30,0x2e,0x36,0x38,0x32,0x2c,0x31,0x37, - 0x2e,0x33,0x34,0x34,0x2c,0x31,0x39,0x2e,0x37,0x31, - 0x37,0x2c,0x31,0x36,0x2e,0x33,0x37,0x39,0x2c,0x31, - 0x38,0x2e,0x35,0x33,0x31,0x2c,0x31,0x36,0x2e,0x33, - 0x37,0x39,0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x09,0x3c, - 0x2f,0x67,0x3e,0x0d,0x0a,0x09,0x3c,0x67,0x3e,0x0d, + 0x32,0x2e,0x31,0x35,0x31,0x0a,0x09,0x09,0x09,0x63, + 0x31,0x2e,0x31,0x38,0x36,0x2c,0x30,0x2c,0x32,0x2e, + 0x31,0x35,0x2d,0x30,0x2e,0x39,0x36,0x36,0x2c,0x32, + 0x2e,0x31,0x35,0x2d,0x32,0x2e,0x31,0x35,0x31,0x43, + 0x32,0x30,0x2e,0x36,0x38,0x32,0x2c,0x31,0x37,0x2e, + 0x33,0x34,0x34,0x2c,0x31,0x39,0x2e,0x37,0x31,0x37, + 0x2c,0x31,0x36,0x2e,0x33,0x37,0x39,0x2c,0x31,0x38, + 0x2e,0x35,0x33,0x31,0x2c,0x31,0x36,0x2e,0x33,0x37, + 0x39,0x7a,0x22,0x2f,0x3e,0x0a,0x09,0x3c,0x2f,0x67, + 0x3e,0x0a,0x09,0x3c,0x67,0x3e,0x0a,0x09,0x09,0x3c, + 0x70,0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d, + 0x22,0x23,0x46,0x46,0x46,0x46,0x46,0x46,0x22,0x20, + 0x64,0x3d,0x22,0x4d,0x31,0x38,0x2e,0x35,0x33,0x2c, + 0x33,0x2e,0x31,0x38,0x33,0x6c,0x2d,0x33,0x2e,0x30, + 0x30,0x35,0x2c,0x34,0x2e,0x36,0x38,0x34,0x68,0x36, + 0x2e,0x30,0x31,0x32,0x4c,0x31,0x38,0x2e,0x35,0x33, + 0x2c,0x33,0x2e,0x31,0x38,0x33,0x7a,0x22,0x2f,0x3e, 0x0a,0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66, 0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46, - 0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x31,0x38, - 0x2e,0x35,0x33,0x2c,0x33,0x2e,0x31,0x38,0x33,0x6c, - 0x2d,0x33,0x2e,0x30,0x30,0x35,0x2c,0x34,0x2e,0x36, - 0x38,0x34,0x68,0x36,0x2e,0x30,0x31,0x32,0x4c,0x31, - 0x38,0x2e,0x35,0x33,0x2c,0x33,0x2e,0x31,0x38,0x33, - 0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x09,0x09,0x3c,0x70, - 0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22, - 0x23,0x46,0x46,0x46,0x46,0x46,0x46,0x22,0x20,0x64, - 0x3d,0x22,0x4d,0x32,0x31,0x2e,0x35,0x33,0x36,0x2c, - 0x38,0x2e,0x36,0x31,0x36,0x68,0x2d,0x36,0x2e,0x30, - 0x31,0x32,0x63,0x2d,0x30,0x2e,0x32,0x37,0x33,0x2c, - 0x30,0x2d,0x30,0x2e,0x35,0x32,0x35,0x2d,0x30,0x2e, - 0x31,0x35,0x2d,0x30,0x2e,0x36,0x35,0x37,0x2d,0x30, - 0x2e,0x33,0x39,0x63,0x2d,0x30,0x2e,0x31,0x33,0x32, - 0x2d,0x30,0x2e,0x32,0x34,0x31,0x2d,0x30,0x2e,0x31, - 0x32,0x31,0x2d,0x30,0x2e,0x35,0x33,0x34,0x2c,0x30, - 0x2e,0x30,0x32,0x36,0x2d,0x30,0x2e,0x37,0x36,0x36, - 0x6c,0x33,0x2e,0x30,0x30,0x35,0x2d,0x34,0x2e,0x36, - 0x38,0x34,0x0d,0x0a,0x09,0x09,0x09,0x63,0x30,0x2e, - 0x32,0x37,0x36,0x2d,0x30,0x2e,0x34,0x33,0x31,0x2c, - 0x30,0x2e,0x39,0x38,0x36,0x2d,0x30,0x2e,0x34,0x33, - 0x2c,0x31,0x2e,0x32,0x36,0x34,0x2c,0x30,0x6c,0x33, - 0x2e,0x30,0x30,0x35,0x2c,0x34,0x2e,0x36,0x38,0x34, - 0x63,0x30,0x2e,0x31,0x34,0x37,0x2c,0x30,0x2e,0x32, - 0x33,0x31,0x2c,0x30,0x2e,0x31,0x35,0x39,0x2c,0x30, - 0x2e,0x35,0x32,0x34,0x2c,0x30,0x2e,0x30,0x32,0x36, - 0x2c,0x30,0x2e,0x37,0x36,0x36,0x43,0x32,0x32,0x2e, - 0x30,0x36,0x33,0x2c,0x38,0x2e,0x34,0x36,0x36,0x2c, - 0x32,0x31,0x2e,0x38,0x31,0x31,0x2c,0x38,0x2e,0x36, - 0x31,0x36,0x2c,0x32,0x31,0x2e,0x35,0x33,0x36,0x2c, - 0x38,0x2e,0x36,0x31,0x36,0x7a,0x0d,0x0a,0x09,0x09, - 0x09,0x20,0x4d,0x31,0x36,0x2e,0x38,0x39,0x37,0x2c, - 0x37,0x2e,0x31,0x31,0x36,0x68,0x33,0x2e,0x32,0x36, - 0x38,0x4c,0x31,0x38,0x2e,0x35,0x33,0x2c,0x34,0x2e, - 0x35,0x37,0x31,0x4c,0x31,0x36,0x2e,0x38,0x39,0x37, - 0x2c,0x37,0x2e,0x31,0x31,0x36,0x7a,0x22,0x2f,0x3e, - 0x0d,0x0a,0x09,0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x09, - 0x3c,0x67,0x3e,0x0d,0x0a,0x09,0x09,0x3c,0x70,0x61, + 0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x32,0x31, + 0x2e,0x35,0x33,0x36,0x2c,0x38,0x2e,0x36,0x31,0x36, + 0x68,0x2d,0x36,0x2e,0x30,0x31,0x32,0x63,0x2d,0x30, + 0x2e,0x32,0x37,0x33,0x2c,0x30,0x2d,0x30,0x2e,0x35, + 0x32,0x35,0x2d,0x30,0x2e,0x31,0x35,0x2d,0x30,0x2e, + 0x36,0x35,0x37,0x2d,0x30,0x2e,0x33,0x39,0x63,0x2d, + 0x30,0x2e,0x31,0x33,0x32,0x2d,0x30,0x2e,0x32,0x34, + 0x31,0x2d,0x30,0x2e,0x31,0x32,0x31,0x2d,0x30,0x2e, + 0x35,0x33,0x34,0x2c,0x30,0x2e,0x30,0x32,0x36,0x2d, + 0x30,0x2e,0x37,0x36,0x36,0x6c,0x33,0x2e,0x30,0x30, + 0x35,0x2d,0x34,0x2e,0x36,0x38,0x34,0x0a,0x09,0x09, + 0x09,0x63,0x30,0x2e,0x32,0x37,0x36,0x2d,0x30,0x2e, + 0x34,0x33,0x31,0x2c,0x30,0x2e,0x39,0x38,0x36,0x2d, + 0x30,0x2e,0x34,0x33,0x2c,0x31,0x2e,0x32,0x36,0x34, + 0x2c,0x30,0x6c,0x33,0x2e,0x30,0x30,0x35,0x2c,0x34, + 0x2e,0x36,0x38,0x34,0x63,0x30,0x2e,0x31,0x34,0x37, + 0x2c,0x30,0x2e,0x32,0x33,0x31,0x2c,0x30,0x2e,0x31, + 0x35,0x39,0x2c,0x30,0x2e,0x35,0x32,0x34,0x2c,0x30, + 0x2e,0x30,0x32,0x36,0x2c,0x30,0x2e,0x37,0x36,0x36, + 0x43,0x32,0x32,0x2e,0x30,0x36,0x33,0x2c,0x38,0x2e, + 0x34,0x36,0x36,0x2c,0x32,0x31,0x2e,0x38,0x31,0x31, + 0x2c,0x38,0x2e,0x36,0x31,0x36,0x2c,0x32,0x31,0x2e, + 0x35,0x33,0x36,0x2c,0x38,0x2e,0x36,0x31,0x36,0x7a, + 0x0a,0x09,0x09,0x09,0x20,0x4d,0x31,0x36,0x2e,0x38, + 0x39,0x37,0x2c,0x37,0x2e,0x31,0x31,0x36,0x68,0x33, + 0x2e,0x32,0x36,0x38,0x4c,0x31,0x38,0x2e,0x35,0x33, + 0x2c,0x34,0x2e,0x35,0x37,0x31,0x4c,0x31,0x36,0x2e, + 0x38,0x39,0x37,0x2c,0x37,0x2e,0x31,0x31,0x36,0x7a, + 0x22,0x2f,0x3e,0x0a,0x09,0x3c,0x2f,0x67,0x3e,0x0a, + 0x09,0x3c,0x67,0x3e,0x0a,0x09,0x09,0x3c,0x70,0x61, 0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23, 0x46,0x46,0x46,0x46,0x46,0x46,0x22,0x20,0x64,0x3d, 0x22,0x4d,0x37,0x2e,0x38,0x30,0x39,0x2c,0x32,0x32, @@ -223,114 +220,114 @@ const unsigned char help_dpad_updown_svg_data[3290] = { 0x30,0x2e,0x32,0x31,0x35,0x2d,0x30,0x2e,0x31,0x33, 0x38,0x2d,0x30,0x2e,0x33,0x34,0x35,0x2d,0x30,0x2e, 0x33,0x37,0x36,0x2d,0x30,0x2e,0x33,0x34,0x35,0x2d, - 0x30,0x2e,0x36,0x33,0x31,0x0d,0x0a,0x09,0x09,0x09, - 0x73,0x30,0x2e,0x31,0x33,0x2d,0x30,0x2e,0x34,0x39, - 0x33,0x2c,0x30,0x2e,0x33,0x34,0x35,0x2d,0x30,0x2e, - 0x36,0x33,0x31,0x6c,0x34,0x2e,0x36,0x38,0x34,0x2d, - 0x33,0x2e,0x30,0x30,0x36,0x63,0x30,0x2e,0x32,0x33, - 0x2d,0x30,0x2e,0x31,0x34,0x38,0x2c,0x30,0x2e,0x35, - 0x32,0x34,0x2d,0x30,0x2e,0x31,0x35,0x38,0x2c,0x30, - 0x2e,0x37,0x36,0x36,0x2d,0x30,0x2e,0x30,0x32,0x37, - 0x63,0x30,0x2e,0x32,0x34,0x2c,0x30,0x2e,0x31,0x33, - 0x31,0x2c,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2e,0x33, - 0x38,0x34,0x2c,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2e, - 0x36,0x35,0x38,0x76,0x36,0x2e,0x30,0x31,0x0d,0x0a, - 0x09,0x09,0x09,0x63,0x30,0x2c,0x30,0x2e,0x32,0x37, - 0x34,0x2d,0x30,0x2e,0x31,0x34,0x38,0x2c,0x30,0x2e, - 0x35,0x32,0x36,0x2d,0x30,0x2e,0x33,0x39,0x2c,0x30, - 0x2e,0x36,0x35,0x38,0x43,0x38,0x2e,0x30,0x35,0x36, - 0x2c,0x32,0x32,0x2e,0x32,0x35,0x34,0x2c,0x37,0x2e, - 0x39,0x33,0x32,0x2c,0x32,0x32,0x2e,0x32,0x38,0x34, - 0x2c,0x37,0x2e,0x38,0x30,0x39,0x2c,0x32,0x32,0x2e, - 0x32,0x38,0x34,0x7a,0x20,0x4d,0x34,0x2e,0x35,0x31, - 0x34,0x2c,0x31,0x38,0x2e,0x35,0x33,0x6c,0x32,0x2e, - 0x35,0x34,0x35,0x2c,0x31,0x2e,0x36,0x33,0x32,0x76, - 0x2d,0x33,0x2e,0x32,0x36,0x35,0x4c,0x34,0x2e,0x35, - 0x31,0x34,0x2c,0x31,0x38,0x2e,0x35,0x33,0x7a,0x22, - 0x2f,0x3e,0x0d,0x0a,0x09,0x3c,0x2f,0x67,0x3e,0x0d, - 0x0a,0x09,0x3c,0x67,0x3e,0x0d,0x0a,0x09,0x09,0x3c, - 0x70,0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d, - 0x22,0x23,0x46,0x46,0x46,0x46,0x46,0x46,0x22,0x20, - 0x64,0x3d,0x22,0x4d,0x32,0x39,0x2e,0x31,0x39,0x35, - 0x2c,0x32,0x32,0x2e,0x32,0x38,0x34,0x63,0x2d,0x30, - 0x2e,0x31,0x32,0x34,0x2c,0x30,0x2d,0x30,0x2e,0x32, - 0x34,0x36,0x2d,0x30,0x2e,0x30,0x33,0x2d,0x30,0x2e, - 0x33,0x35,0x38,0x2d,0x30,0x2e,0x30,0x39,0x32,0x63, - 0x2d,0x30,0x2e,0x32,0x34,0x31,0x2d,0x30,0x2e,0x31, - 0x33,0x32,0x2d,0x30,0x2e,0x33,0x39,0x32,0x2d,0x30, - 0x2e,0x33,0x38,0x34,0x2d,0x30,0x2e,0x33,0x39,0x32, - 0x2d,0x30,0x2e,0x36,0x35,0x38,0x76,0x2d,0x36,0x2e, - 0x30,0x31,0x0d,0x0a,0x09,0x09,0x09,0x63,0x30,0x2d, - 0x30,0x2e,0x32,0x37,0x34,0x2c,0x30,0x2e,0x31,0x34, - 0x39,0x2d,0x30,0x2e,0x35,0x32,0x36,0x2c,0x30,0x2e, - 0x33,0x39,0x32,0x2d,0x30,0x2e,0x36,0x35,0x38,0x63, - 0x30,0x2e,0x32,0x33,0x39,0x2d,0x30,0x2e,0x31,0x33, - 0x31,0x2c,0x30,0x2e,0x35,0x33,0x33,0x2d,0x30,0x2e, - 0x31,0x32,0x33,0x2c,0x30,0x2e,0x37,0x36,0x35,0x2c, - 0x30,0x2e,0x30,0x32,0x37,0x6c,0x34,0x2e,0x36,0x38, - 0x35,0x2c,0x33,0x2e,0x30,0x30,0x35,0x63,0x30,0x2e, - 0x32,0x31,0x35,0x2c,0x30,0x2e,0x31,0x33,0x38,0x2c, - 0x30,0x2e,0x33,0x34,0x35,0x2c,0x30,0x2e,0x33,0x37, - 0x36,0x2c,0x30,0x2e,0x33,0x34,0x35,0x2c,0x30,0x2e, - 0x36,0x33,0x31,0x0d,0x0a,0x09,0x09,0x09,0x73,0x2d, - 0x30,0x2e,0x31,0x33,0x2c,0x30,0x2e,0x34,0x39,0x33, - 0x2d,0x30,0x2e,0x33,0x34,0x35,0x2c,0x30,0x2e,0x36, - 0x33,0x31,0x6c,0x2d,0x34,0x2e,0x36,0x38,0x35,0x2c, - 0x33,0x2e,0x30,0x30,0x34,0x43,0x32,0x39,0x2e,0x34, - 0x37,0x38,0x2c,0x32,0x32,0x2e,0x32,0x34,0x34,0x2c, - 0x32,0x39,0x2e,0x33,0x33,0x36,0x2c,0x32,0x32,0x2e, - 0x32,0x38,0x34,0x2c,0x32,0x39,0x2e,0x31,0x39,0x35, - 0x2c,0x32,0x32,0x2e,0x32,0x38,0x34,0x7a,0x20,0x4d, - 0x32,0x39,0x2e,0x39,0x34,0x35,0x2c,0x31,0x36,0x2e, - 0x38,0x39,0x36,0x76,0x33,0x2e,0x32,0x36,0x36,0x6c, - 0x32,0x2e,0x35,0x34,0x36,0x2d,0x31,0x2e,0x36,0x33, - 0x33,0x0d,0x0a,0x09,0x09,0x09,0x4c,0x32,0x39,0x2e, - 0x39,0x34,0x35,0x2c,0x31,0x36,0x2e,0x38,0x39,0x36, - 0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x09,0x3c,0x2f,0x67, - 0x3e,0x0d,0x0a,0x09,0x3c,0x67,0x3e,0x0d,0x0a,0x09, - 0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69,0x6c, - 0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46,0x46, - 0x22,0x20,0x64,0x3d,0x22,0x4d,0x31,0x38,0x2e,0x35, - 0x33,0x2c,0x33,0x33,0x2e,0x38,0x37,0x36,0x6c,0x33, - 0x2e,0x30,0x30,0x37,0x2d,0x34,0x2e,0x36,0x38,0x34, - 0x68,0x2d,0x36,0x2e,0x30,0x31,0x32,0x4c,0x31,0x38, - 0x2e,0x35,0x33,0x2c,0x33,0x33,0x2e,0x38,0x37,0x36, - 0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x09,0x09,0x3c,0x70, - 0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22, - 0x23,0x46,0x46,0x46,0x46,0x46,0x46,0x22,0x20,0x64, - 0x3d,0x22,0x4d,0x31,0x38,0x2e,0x35,0x33,0x2c,0x33, - 0x34,0x2e,0x36,0x32,0x36,0x4c,0x31,0x38,0x2e,0x35, - 0x33,0x2c,0x33,0x34,0x2e,0x36,0x32,0x36,0x63,0x2d, - 0x30,0x2e,0x32,0x35,0x35,0x2c,0x30,0x2d,0x30,0x2e, - 0x34,0x39,0x32,0x2d,0x30,0x2e,0x31,0x33,0x2d,0x30, - 0x2e,0x36,0x33,0x31,0x2d,0x30,0x2e,0x33,0x34,0x35, - 0x6c,0x2d,0x33,0x2e,0x30,0x30,0x35,0x2d,0x34,0x2e, - 0x36,0x38,0x34,0x0d,0x0a,0x09,0x09,0x09,0x63,0x2d, - 0x30,0x2e,0x31,0x34,0x37,0x2d,0x30,0x2e,0x32,0x33, - 0x31,0x2d,0x30,0x2e,0x31,0x35,0x38,0x2d,0x30,0x2e, - 0x35,0x32,0x34,0x2d,0x30,0x2e,0x30,0x32,0x36,0x2d, - 0x30,0x2e,0x37,0x36,0x36,0x73,0x30,0x2e,0x33,0x38, - 0x34,0x2d,0x30,0x2e,0x33,0x39,0x31,0x2c,0x30,0x2e, - 0x36,0x35,0x37,0x2d,0x30,0x2e,0x33,0x39,0x31,0x68, - 0x36,0x2e,0x30,0x31,0x32,0x63,0x30,0x2e,0x32,0x37, - 0x33,0x2c,0x30,0x2c,0x30,0x2e,0x35,0x32,0x35,0x2c, - 0x30,0x2e,0x31,0x34,0x38,0x2c,0x30,0x2e,0x36,0x35, - 0x37,0x2c,0x30,0x2e,0x33,0x39,0x31,0x0d,0x0a,0x09, - 0x09,0x09,0x63,0x30,0x2e,0x31,0x33,0x33,0x2c,0x30, - 0x2e,0x32,0x34,0x2c,0x30,0x2e,0x31,0x32,0x31,0x2c, - 0x30,0x2e,0x35,0x33,0x33,0x2d,0x30,0x2e,0x30,0x32, - 0x36,0x2c,0x30,0x2e,0x37,0x36,0x36,0x6c,0x2d,0x33, - 0x2e,0x30,0x30,0x35,0x2c,0x34,0x2e,0x36,0x38,0x34, - 0x43,0x31,0x39,0x2e,0x30,0x32,0x33,0x2c,0x33,0x34, - 0x2e,0x34,0x39,0x36,0x2c,0x31,0x38,0x2e,0x37,0x38, - 0x36,0x2c,0x33,0x34,0x2e,0x36,0x32,0x36,0x2c,0x31, - 0x38,0x2e,0x35,0x33,0x2c,0x33,0x34,0x2e,0x36,0x32, - 0x36,0x7a,0x20,0x4d,0x31,0x36,0x2e,0x38,0x39,0x37, - 0x2c,0x32,0x39,0x2e,0x39,0x34,0x32,0x6c,0x31,0x2e, - 0x36,0x33,0x33,0x2c,0x32,0x2e,0x35,0x34,0x35,0x0d, - 0x0a,0x09,0x09,0x09,0x6c,0x31,0x2e,0x36,0x33,0x35, - 0x2d,0x32,0x2e,0x35,0x34,0x35,0x48,0x31,0x36,0x2e, - 0x38,0x39,0x37,0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x09, - 0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x3c,0x2f,0x67,0x3e, - 0x0d,0x0a,0x3c,0x2f,0x73,0x76,0x67,0x3e,0x0d,0x0a + 0x30,0x2e,0x36,0x33,0x31,0x0a,0x09,0x09,0x09,0x73, + 0x30,0x2e,0x31,0x33,0x2d,0x30,0x2e,0x34,0x39,0x33, + 0x2c,0x30,0x2e,0x33,0x34,0x35,0x2d,0x30,0x2e,0x36, + 0x33,0x31,0x6c,0x34,0x2e,0x36,0x38,0x34,0x2d,0x33, + 0x2e,0x30,0x30,0x36,0x63,0x30,0x2e,0x32,0x33,0x2d, + 0x30,0x2e,0x31,0x34,0x38,0x2c,0x30,0x2e,0x35,0x32, + 0x34,0x2d,0x30,0x2e,0x31,0x35,0x38,0x2c,0x30,0x2e, + 0x37,0x36,0x36,0x2d,0x30,0x2e,0x30,0x32,0x37,0x63, + 0x30,0x2e,0x32,0x34,0x2c,0x30,0x2e,0x31,0x33,0x31, + 0x2c,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2e,0x33,0x38, + 0x34,0x2c,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2e,0x36, + 0x35,0x38,0x76,0x36,0x2e,0x30,0x31,0x0a,0x09,0x09, + 0x09,0x63,0x30,0x2c,0x30,0x2e,0x32,0x37,0x34,0x2d, + 0x30,0x2e,0x31,0x34,0x38,0x2c,0x30,0x2e,0x35,0x32, + 0x36,0x2d,0x30,0x2e,0x33,0x39,0x2c,0x30,0x2e,0x36, + 0x35,0x38,0x43,0x38,0x2e,0x30,0x35,0x36,0x2c,0x32, + 0x32,0x2e,0x32,0x35,0x34,0x2c,0x37,0x2e,0x39,0x33, + 0x32,0x2c,0x32,0x32,0x2e,0x32,0x38,0x34,0x2c,0x37, + 0x2e,0x38,0x30,0x39,0x2c,0x32,0x32,0x2e,0x32,0x38, + 0x34,0x7a,0x20,0x4d,0x34,0x2e,0x35,0x31,0x34,0x2c, + 0x31,0x38,0x2e,0x35,0x33,0x6c,0x32,0x2e,0x35,0x34, + 0x35,0x2c,0x31,0x2e,0x36,0x33,0x32,0x76,0x2d,0x33, + 0x2e,0x32,0x36,0x35,0x4c,0x34,0x2e,0x35,0x31,0x34, + 0x2c,0x31,0x38,0x2e,0x35,0x33,0x7a,0x22,0x2f,0x3e, + 0x0a,0x09,0x3c,0x2f,0x67,0x3e,0x0a,0x09,0x3c,0x67, + 0x3e,0x0a,0x09,0x09,0x3c,0x70,0x61,0x74,0x68,0x20, + 0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46,0x46,0x46, + 0x46,0x46,0x46,0x22,0x20,0x64,0x3d,0x22,0x4d,0x32, + 0x39,0x2e,0x31,0x39,0x35,0x2c,0x32,0x32,0x2e,0x32, + 0x38,0x34,0x63,0x2d,0x30,0x2e,0x31,0x32,0x34,0x2c, + 0x30,0x2d,0x30,0x2e,0x32,0x34,0x36,0x2d,0x30,0x2e, + 0x30,0x33,0x2d,0x30,0x2e,0x33,0x35,0x38,0x2d,0x30, + 0x2e,0x30,0x39,0x32,0x63,0x2d,0x30,0x2e,0x32,0x34, + 0x31,0x2d,0x30,0x2e,0x31,0x33,0x32,0x2d,0x30,0x2e, + 0x33,0x39,0x32,0x2d,0x30,0x2e,0x33,0x38,0x34,0x2d, + 0x30,0x2e,0x33,0x39,0x32,0x2d,0x30,0x2e,0x36,0x35, + 0x38,0x76,0x2d,0x36,0x2e,0x30,0x31,0x0a,0x09,0x09, + 0x09,0x63,0x30,0x2d,0x30,0x2e,0x32,0x37,0x34,0x2c, + 0x30,0x2e,0x31,0x34,0x39,0x2d,0x30,0x2e,0x35,0x32, + 0x36,0x2c,0x30,0x2e,0x33,0x39,0x32,0x2d,0x30,0x2e, + 0x36,0x35,0x38,0x63,0x30,0x2e,0x32,0x33,0x39,0x2d, + 0x30,0x2e,0x31,0x33,0x31,0x2c,0x30,0x2e,0x35,0x33, + 0x33,0x2d,0x30,0x2e,0x31,0x32,0x33,0x2c,0x30,0x2e, + 0x37,0x36,0x35,0x2c,0x30,0x2e,0x30,0x32,0x37,0x6c, + 0x34,0x2e,0x36,0x38,0x35,0x2c,0x33,0x2e,0x30,0x30, + 0x35,0x63,0x30,0x2e,0x32,0x31,0x35,0x2c,0x30,0x2e, + 0x31,0x33,0x38,0x2c,0x30,0x2e,0x33,0x34,0x35,0x2c, + 0x30,0x2e,0x33,0x37,0x36,0x2c,0x30,0x2e,0x33,0x34, + 0x35,0x2c,0x30,0x2e,0x36,0x33,0x31,0x0a,0x09,0x09, + 0x09,0x73,0x2d,0x30,0x2e,0x31,0x33,0x2c,0x30,0x2e, + 0x34,0x39,0x33,0x2d,0x30,0x2e,0x33,0x34,0x35,0x2c, + 0x30,0x2e,0x36,0x33,0x31,0x6c,0x2d,0x34,0x2e,0x36, + 0x38,0x35,0x2c,0x33,0x2e,0x30,0x30,0x34,0x43,0x32, + 0x39,0x2e,0x34,0x37,0x38,0x2c,0x32,0x32,0x2e,0x32, + 0x34,0x34,0x2c,0x32,0x39,0x2e,0x33,0x33,0x36,0x2c, + 0x32,0x32,0x2e,0x32,0x38,0x34,0x2c,0x32,0x39,0x2e, + 0x31,0x39,0x35,0x2c,0x32,0x32,0x2e,0x32,0x38,0x34, + 0x7a,0x20,0x4d,0x32,0x39,0x2e,0x39,0x34,0x35,0x2c, + 0x31,0x36,0x2e,0x38,0x39,0x36,0x76,0x33,0x2e,0x32, + 0x36,0x36,0x6c,0x32,0x2e,0x35,0x34,0x36,0x2d,0x31, + 0x2e,0x36,0x33,0x33,0x0a,0x09,0x09,0x09,0x4c,0x32, + 0x39,0x2e,0x39,0x34,0x35,0x2c,0x31,0x36,0x2e,0x38, + 0x39,0x36,0x7a,0x22,0x2f,0x3e,0x0a,0x09,0x3c,0x2f, + 0x67,0x3e,0x0a,0x09,0x3c,0x67,0x3e,0x0a,0x09,0x09, + 0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c, + 0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46,0x46,0x22, + 0x20,0x64,0x3d,0x22,0x4d,0x31,0x38,0x2e,0x35,0x33, + 0x2c,0x33,0x33,0x2e,0x38,0x37,0x36,0x6c,0x33,0x2e, + 0x30,0x30,0x37,0x2d,0x34,0x2e,0x36,0x38,0x34,0x68, + 0x2d,0x36,0x2e,0x30,0x31,0x32,0x4c,0x31,0x38,0x2e, + 0x35,0x33,0x2c,0x33,0x33,0x2e,0x38,0x37,0x36,0x7a, + 0x22,0x2f,0x3e,0x0a,0x09,0x09,0x3c,0x70,0x61,0x74, + 0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x46, + 0x46,0x46,0x46,0x46,0x46,0x22,0x20,0x64,0x3d,0x22, + 0x4d,0x31,0x38,0x2e,0x35,0x33,0x2c,0x33,0x34,0x2e, + 0x36,0x32,0x36,0x4c,0x31,0x38,0x2e,0x35,0x33,0x2c, + 0x33,0x34,0x2e,0x36,0x32,0x36,0x63,0x2d,0x30,0x2e, + 0x32,0x35,0x35,0x2c,0x30,0x2d,0x30,0x2e,0x34,0x39, + 0x32,0x2d,0x30,0x2e,0x31,0x33,0x2d,0x30,0x2e,0x36, + 0x33,0x31,0x2d,0x30,0x2e,0x33,0x34,0x35,0x6c,0x2d, + 0x33,0x2e,0x30,0x30,0x35,0x2d,0x34,0x2e,0x36,0x38, + 0x34,0x0a,0x09,0x09,0x09,0x63,0x2d,0x30,0x2e,0x31, + 0x34,0x37,0x2d,0x30,0x2e,0x32,0x33,0x31,0x2d,0x30, + 0x2e,0x31,0x35,0x38,0x2d,0x30,0x2e,0x35,0x32,0x34, + 0x2d,0x30,0x2e,0x30,0x32,0x36,0x2d,0x30,0x2e,0x37, + 0x36,0x36,0x73,0x30,0x2e,0x33,0x38,0x34,0x2d,0x30, + 0x2e,0x33,0x39,0x31,0x2c,0x30,0x2e,0x36,0x35,0x37, + 0x2d,0x30,0x2e,0x33,0x39,0x31,0x68,0x36,0x2e,0x30, + 0x31,0x32,0x63,0x30,0x2e,0x32,0x37,0x33,0x2c,0x30, + 0x2c,0x30,0x2e,0x35,0x32,0x35,0x2c,0x30,0x2e,0x31, + 0x34,0x38,0x2c,0x30,0x2e,0x36,0x35,0x37,0x2c,0x30, + 0x2e,0x33,0x39,0x31,0x0a,0x09,0x09,0x09,0x63,0x30, + 0x2e,0x31,0x33,0x33,0x2c,0x30,0x2e,0x32,0x34,0x2c, + 0x30,0x2e,0x31,0x32,0x31,0x2c,0x30,0x2e,0x35,0x33, + 0x33,0x2d,0x30,0x2e,0x30,0x32,0x36,0x2c,0x30,0x2e, + 0x37,0x36,0x36,0x6c,0x2d,0x33,0x2e,0x30,0x30,0x35, + 0x2c,0x34,0x2e,0x36,0x38,0x34,0x43,0x31,0x39,0x2e, + 0x30,0x32,0x33,0x2c,0x33,0x34,0x2e,0x34,0x39,0x36, + 0x2c,0x31,0x38,0x2e,0x37,0x38,0x36,0x2c,0x33,0x34, + 0x2e,0x36,0x32,0x36,0x2c,0x31,0x38,0x2e,0x35,0x33, + 0x2c,0x33,0x34,0x2e,0x36,0x32,0x36,0x7a,0x20,0x4d, + 0x31,0x36,0x2e,0x38,0x39,0x37,0x2c,0x32,0x39,0x2e, + 0x39,0x34,0x32,0x6c,0x31,0x2e,0x36,0x33,0x33,0x2c, + 0x32,0x2e,0x35,0x34,0x35,0x0a,0x09,0x09,0x09,0x6c, + 0x31,0x2e,0x36,0x33,0x35,0x2d,0x32,0x2e,0x35,0x34, + 0x35,0x48,0x31,0x36,0x2e,0x38,0x39,0x37,0x7a,0x22, + 0x2f,0x3e,0x0a,0x09,0x3c,0x2f,0x67,0x3e,0x0a,0x3c, + 0x2f,0x67,0x3e,0x0a,0x3c,0x2f,0x73,0x76,0x67,0x3e, + 0x0a }; + diff --git a/data/converted/off_svg.cpp b/data/converted/off_svg.cpp index 91198cf7b6..f89baaee74 100644 --- a/data/converted/off_svg.cpp +++ b/data/converted/off_svg.cpp @@ -2,116 +2,115 @@ #include "../Resources.h" -const size_t off_svg_size = 1338; -const unsigned char off_svg_data[1338] = { +const size_t off_svg_size = 1325; +const unsigned char off_svg_data[1325] = { 0x3c,0x3f,0x78,0x6d,0x6c,0x20,0x76,0x65,0x72,0x73, 0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x30,0x22,0x20, 0x65,0x6e,0x63,0x6f,0x64,0x69,0x6e,0x67,0x3d,0x22, - 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0d,0x0a, - 0x3c,0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72, - 0x61,0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62, - 0x65,0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61, - 0x74,0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33, - 0x2c,0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f, - 0x72,0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e, - 0x20,0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72, - 0x73,0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30, - 0x20,0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20, - 0x20,0x2d,0x2d,0x3e,0x0d,0x0a,0x3c,0x21,0x44,0x4f, - 0x43,0x54,0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20, - 0x50,0x55,0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f, - 0x2f,0x57,0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20, - 0x53,0x56,0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45, - 0x4e,0x22,0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, - 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, - 0x67,0x2f,0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73, - 0x2f,0x53,0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44, - 0x54,0x44,0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64, - 0x74,0x64,0x22,0x3e,0x0d,0x0a,0x3c,0x73,0x76,0x67, - 0x20,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22, - 0x31,0x2e,0x31,0x22,0x20,0x69,0x64,0x3d,0x22,0x45, - 0x62,0x65,0x6e,0x65,0x5f,0x31,0x22,0x20,0x78,0x6d, - 0x6c,0x6e,0x73,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a, - 0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f, - 0x72,0x67,0x2f,0x32,0x30,0x30,0x30,0x2f,0x73,0x76, - 0x67,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78, - 0x6c,0x69,0x6e,0x6b,0x3d,0x22,0x68,0x74,0x74,0x70, - 0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e, - 0x6f,0x72,0x67,0x2f,0x31,0x39,0x39,0x39,0x2f,0x78, - 0x6c,0x69,0x6e,0x6b,0x22,0x20,0x78,0x3d,0x22,0x30, - 0x70,0x78,0x22,0x20,0x79,0x3d,0x22,0x30,0x70,0x78, - 0x22,0x0d,0x0a,0x09,0x20,0x77,0x69,0x64,0x74,0x68, - 0x3d,0x22,0x34,0x33,0x2e,0x39,0x31,0x36,0x70,0x78, - 0x22,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3d,0x22, - 0x32,0x31,0x2e,0x39,0x35,0x39,0x70,0x78,0x22,0x20, - 0x76,0x69,0x65,0x77,0x42,0x6f,0x78,0x3d,0x22,0x30, - 0x20,0x30,0x20,0x34,0x33,0x2e,0x39,0x31,0x36,0x20, - 0x32,0x31,0x2e,0x39,0x35,0x39,0x22,0x20,0x65,0x6e, - 0x61,0x62,0x6c,0x65,0x2d,0x62,0x61,0x63,0x6b,0x67, - 0x72,0x6f,0x75,0x6e,0x64,0x3d,0x22,0x6e,0x65,0x77, - 0x20,0x30,0x20,0x30,0x20,0x34,0x33,0x2e,0x39,0x31, - 0x36,0x20,0x32,0x31,0x2e,0x39,0x35,0x39,0x22,0x20, - 0x78,0x6d,0x6c,0x3a,0x73,0x70,0x61,0x63,0x65,0x3d, - 0x22,0x70,0x72,0x65,0x73,0x65,0x72,0x76,0x65,0x22, - 0x3e,0x0d,0x0a,0x3c,0x70,0x61,0x74,0x68,0x20,0x66, - 0x69,0x6c,0x6c,0x3d,0x22,0x23,0x37,0x37,0x37,0x37, - 0x37,0x37,0x22,0x20,0x64,0x3d,0x22,0x4d,0x32,0x39, - 0x2e,0x32,0x39,0x31,0x2c,0x31,0x35,0x2e,0x36,0x39, - 0x68,0x31,0x2e,0x39,0x33,0x34,0x76,0x2d,0x34,0x2e, - 0x31,0x31,0x33,0x68,0x35,0x2e,0x34,0x32,0x76,0x2d, - 0x31,0x2e,0x34,0x37,0x39,0x68,0x2d,0x35,0x2e,0x34, - 0x32,0x56,0x37,0x2e,0x37,0x30,0x34,0x68,0x35,0x2e, - 0x37,0x32,0x39,0x56,0x36,0x2e,0x32,0x32,0x35,0x68, - 0x2d,0x37,0x2e,0x36,0x36,0x32,0x56,0x31,0x35,0x2e, - 0x36,0x39,0x7a,0x20,0x4d,0x31,0x39,0x2e,0x38,0x31, - 0x2c,0x31,0x35,0x2e,0x36,0x39,0x68,0x31,0x2e,0x39, - 0x33,0x36,0x76,0x2d,0x34,0x2e,0x31,0x31,0x33,0x0d, - 0x0a,0x09,0x68,0x35,0x2e,0x34,0x31,0x36,0x76,0x2d, - 0x31,0x2e,0x34,0x37,0x39,0x68,0x2d,0x35,0x2e,0x34, - 0x31,0x36,0x56,0x37,0x2e,0x37,0x30,0x34,0x68,0x35, - 0x2e,0x37,0x32,0x35,0x56,0x36,0x2e,0x32,0x32,0x35, - 0x68,0x2d,0x37,0x2e,0x36,0x36,0x56,0x31,0x35,0x2e, - 0x36,0x39,0x7a,0x20,0x4d,0x31,0x32,0x2e,0x33,0x37, - 0x38,0x2c,0x31,0x34,0x2e,0x34,0x37,0x33,0x63,0x2d, - 0x32,0x2e,0x31,0x36,0x36,0x2c,0x30,0x2d,0x33,0x2e, - 0x34,0x30,0x34,0x2d,0x31,0x2e,0x34,0x33,0x35,0x2d, - 0x33,0x2e,0x34,0x30,0x34,0x2d,0x33,0x2e,0x35,0x31, - 0x37,0x0d,0x0a,0x09,0x63,0x30,0x2d,0x32,0x2e,0x30, - 0x38,0x33,0x2c,0x31,0x2e,0x32,0x33,0x38,0x2d,0x33, - 0x2e,0x35,0x31,0x38,0x2c,0x33,0x2e,0x34,0x30,0x34, - 0x2d,0x33,0x2e,0x35,0x31,0x38,0x63,0x32,0x2e,0x31, - 0x36,0x37,0x2c,0x30,0x2c,0x33,0x2e,0x34,0x30,0x36, - 0x2c,0x31,0x2e,0x34,0x33,0x35,0x2c,0x33,0x2e,0x34, - 0x30,0x36,0x2c,0x33,0x2e,0x35,0x31,0x38,0x43,0x31, - 0x35,0x2e,0x37,0x38,0x34,0x2c,0x31,0x33,0x2e,0x30, - 0x33,0x38,0x2c,0x31,0x34,0x2e,0x35,0x34,0x35,0x2c, - 0x31,0x34,0x2e,0x34,0x37,0x33,0x2c,0x31,0x32,0x2e, - 0x33,0x37,0x38,0x2c,0x31,0x34,0x2e,0x34,0x37,0x33, - 0x20,0x4d,0x31,0x32,0x2e,0x33,0x37,0x38,0x2c,0x31, - 0x35,0x2e,0x39,0x35,0x36,0x0d,0x0a,0x09,0x63,0x33, - 0x2e,0x38,0x39,0x36,0x2c,0x30,0x2c,0x35,0x2e,0x34, - 0x31,0x39,0x2d,0x32,0x2e,0x33,0x33,0x35,0x2c,0x35, - 0x2e,0x34,0x31,0x39,0x2d,0x35,0x73,0x2d,0x31,0x2e, - 0x35,0x32,0x32,0x2d,0x34,0x2e,0x39,0x39,0x37,0x2d, - 0x35,0x2e,0x34,0x31,0x39,0x2d,0x34,0x2e,0x39,0x39, - 0x37,0x63,0x2d,0x33,0x2e,0x38,0x39,0x36,0x2c,0x30, - 0x2d,0x35,0x2e,0x34,0x31,0x36,0x2c,0x32,0x2e,0x33, - 0x33,0x32,0x2d,0x35,0x2e,0x34,0x31,0x36,0x2c,0x34, - 0x2e,0x39,0x39,0x37,0x53,0x38,0x2e,0x34,0x38,0x32, - 0x2c,0x31,0x35,0x2e,0x39,0x35,0x36,0x2c,0x31,0x32, - 0x2e,0x33,0x37,0x38,0x2c,0x31,0x35,0x2e,0x39,0x35, - 0x36,0x22,0x2f,0x3e,0x0d,0x0a,0x3c,0x70,0x61,0x74, - 0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x37, - 0x37,0x37,0x37,0x37,0x37,0x22,0x20,0x64,0x3d,0x22, - 0x4d,0x33,0x39,0x2e,0x36,0x36,0x34,0x2c,0x31,0x2e, - 0x35,0x63,0x31,0x2e,0x35,0x31,0x38,0x2c,0x30,0x2c, - 0x32,0x2e,0x37,0x35,0x32,0x2c,0x31,0x2e,0x32,0x33, - 0x34,0x2c,0x32,0x2e,0x37,0x35,0x32,0x2c,0x32,0x2e, - 0x37,0x35,0x32,0x76,0x31,0x33,0x2e,0x34,0x35,0x35, - 0x63,0x30,0x2c,0x31,0x2e,0x35,0x31,0x38,0x2d,0x31, - 0x2e,0x32,0x33,0x34,0x2c,0x32,0x2e,0x37,0x35,0x32, - 0x2d,0x32,0x2e,0x37,0x35,0x32,0x2c,0x32,0x2e,0x37, - 0x35,0x32,0x48,0x34,0x2e,0x32,0x35,0x32,0x0d,0x0a, + 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0a,0x3c, + 0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72,0x61, + 0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62,0x65, + 0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61,0x74, + 0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33,0x2c, + 0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f,0x72, + 0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e,0x20, + 0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72,0x73, + 0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30,0x20, + 0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20,0x20, + 0x2d,0x2d,0x3e,0x0a,0x3c,0x21,0x44,0x4f,0x43,0x54, + 0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20,0x50,0x55, + 0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f,0x2f,0x57, + 0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20,0x53,0x56, + 0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45,0x4e,0x22, + 0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73,0x2f,0x53, + 0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44,0x54,0x44, + 0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64,0x74,0x64, + 0x22,0x3e,0x0a,0x3c,0x73,0x76,0x67,0x20,0x76,0x65, + 0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x31, + 0x22,0x20,0x69,0x64,0x3d,0x22,0x45,0x62,0x65,0x6e, + 0x65,0x5f,0x31,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73, + 0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x32,0x30,0x30,0x30,0x2f,0x73,0x76,0x67,0x22,0x20, + 0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78,0x6c,0x69,0x6e, + 0x6b,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f, + 0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67, + 0x2f,0x31,0x39,0x39,0x39,0x2f,0x78,0x6c,0x69,0x6e, + 0x6b,0x22,0x20,0x78,0x3d,0x22,0x30,0x70,0x78,0x22, + 0x20,0x79,0x3d,0x22,0x30,0x70,0x78,0x22,0x0a,0x09, + 0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x34,0x33, + 0x2e,0x39,0x31,0x36,0x70,0x78,0x22,0x20,0x68,0x65, + 0x69,0x67,0x68,0x74,0x3d,0x22,0x32,0x31,0x2e,0x39, + 0x35,0x39,0x70,0x78,0x22,0x20,0x76,0x69,0x65,0x77, + 0x42,0x6f,0x78,0x3d,0x22,0x30,0x20,0x30,0x20,0x34, + 0x33,0x2e,0x39,0x31,0x36,0x20,0x32,0x31,0x2e,0x39, + 0x35,0x39,0x22,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65, + 0x2d,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e, + 0x64,0x3d,0x22,0x6e,0x65,0x77,0x20,0x30,0x20,0x30, + 0x20,0x34,0x33,0x2e,0x39,0x31,0x36,0x20,0x32,0x31, + 0x2e,0x39,0x35,0x39,0x22,0x20,0x78,0x6d,0x6c,0x3a, + 0x73,0x70,0x61,0x63,0x65,0x3d,0x22,0x70,0x72,0x65, + 0x73,0x65,0x72,0x76,0x65,0x22,0x3e,0x0a,0x3c,0x70, + 0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22, + 0x23,0x37,0x37,0x37,0x37,0x37,0x37,0x22,0x20,0x64, + 0x3d,0x22,0x4d,0x32,0x39,0x2e,0x32,0x39,0x31,0x2c, + 0x31,0x35,0x2e,0x36,0x39,0x68,0x31,0x2e,0x39,0x33, + 0x34,0x76,0x2d,0x34,0x2e,0x31,0x31,0x33,0x68,0x35, + 0x2e,0x34,0x32,0x76,0x2d,0x31,0x2e,0x34,0x37,0x39, + 0x68,0x2d,0x35,0x2e,0x34,0x32,0x56,0x37,0x2e,0x37, + 0x30,0x34,0x68,0x35,0x2e,0x37,0x32,0x39,0x56,0x36, + 0x2e,0x32,0x32,0x35,0x68,0x2d,0x37,0x2e,0x36,0x36, + 0x32,0x56,0x31,0x35,0x2e,0x36,0x39,0x7a,0x20,0x4d, + 0x31,0x39,0x2e,0x38,0x31,0x2c,0x31,0x35,0x2e,0x36, + 0x39,0x68,0x31,0x2e,0x39,0x33,0x36,0x76,0x2d,0x34, + 0x2e,0x31,0x31,0x33,0x0a,0x09,0x68,0x35,0x2e,0x34, + 0x31,0x36,0x76,0x2d,0x31,0x2e,0x34,0x37,0x39,0x68, + 0x2d,0x35,0x2e,0x34,0x31,0x36,0x56,0x37,0x2e,0x37, + 0x30,0x34,0x68,0x35,0x2e,0x37,0x32,0x35,0x56,0x36, + 0x2e,0x32,0x32,0x35,0x68,0x2d,0x37,0x2e,0x36,0x36, + 0x56,0x31,0x35,0x2e,0x36,0x39,0x7a,0x20,0x4d,0x31, + 0x32,0x2e,0x33,0x37,0x38,0x2c,0x31,0x34,0x2e,0x34, + 0x37,0x33,0x63,0x2d,0x32,0x2e,0x31,0x36,0x36,0x2c, + 0x30,0x2d,0x33,0x2e,0x34,0x30,0x34,0x2d,0x31,0x2e, + 0x34,0x33,0x35,0x2d,0x33,0x2e,0x34,0x30,0x34,0x2d, + 0x33,0x2e,0x35,0x31,0x37,0x0a,0x09,0x63,0x30,0x2d, + 0x32,0x2e,0x30,0x38,0x33,0x2c,0x31,0x2e,0x32,0x33, + 0x38,0x2d,0x33,0x2e,0x35,0x31,0x38,0x2c,0x33,0x2e, + 0x34,0x30,0x34,0x2d,0x33,0x2e,0x35,0x31,0x38,0x63, + 0x32,0x2e,0x31,0x36,0x37,0x2c,0x30,0x2c,0x33,0x2e, + 0x34,0x30,0x36,0x2c,0x31,0x2e,0x34,0x33,0x35,0x2c, + 0x33,0x2e,0x34,0x30,0x36,0x2c,0x33,0x2e,0x35,0x31, + 0x38,0x43,0x31,0x35,0x2e,0x37,0x38,0x34,0x2c,0x31, + 0x33,0x2e,0x30,0x33,0x38,0x2c,0x31,0x34,0x2e,0x35, + 0x34,0x35,0x2c,0x31,0x34,0x2e,0x34,0x37,0x33,0x2c, + 0x31,0x32,0x2e,0x33,0x37,0x38,0x2c,0x31,0x34,0x2e, + 0x34,0x37,0x33,0x20,0x4d,0x31,0x32,0x2e,0x33,0x37, + 0x38,0x2c,0x31,0x35,0x2e,0x39,0x35,0x36,0x0a,0x09, + 0x63,0x33,0x2e,0x38,0x39,0x36,0x2c,0x30,0x2c,0x35, + 0x2e,0x34,0x31,0x39,0x2d,0x32,0x2e,0x33,0x33,0x35, + 0x2c,0x35,0x2e,0x34,0x31,0x39,0x2d,0x35,0x73,0x2d, + 0x31,0x2e,0x35,0x32,0x32,0x2d,0x34,0x2e,0x39,0x39, + 0x37,0x2d,0x35,0x2e,0x34,0x31,0x39,0x2d,0x34,0x2e, + 0x39,0x39,0x37,0x63,0x2d,0x33,0x2e,0x38,0x39,0x36, + 0x2c,0x30,0x2d,0x35,0x2e,0x34,0x31,0x36,0x2c,0x32, + 0x2e,0x33,0x33,0x32,0x2d,0x35,0x2e,0x34,0x31,0x36, + 0x2c,0x34,0x2e,0x39,0x39,0x37,0x53,0x38,0x2e,0x34, + 0x38,0x32,0x2c,0x31,0x35,0x2e,0x39,0x35,0x36,0x2c, + 0x31,0x32,0x2e,0x33,0x37,0x38,0x2c,0x31,0x35,0x2e, + 0x39,0x35,0x36,0x22,0x2f,0x3e,0x0a,0x3c,0x70,0x61, + 0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23, + 0x37,0x37,0x37,0x37,0x37,0x37,0x22,0x20,0x64,0x3d, + 0x22,0x4d,0x33,0x39,0x2e,0x36,0x36,0x34,0x2c,0x31, + 0x2e,0x35,0x63,0x31,0x2e,0x35,0x31,0x38,0x2c,0x30, + 0x2c,0x32,0x2e,0x37,0x35,0x32,0x2c,0x31,0x2e,0x32, + 0x33,0x34,0x2c,0x32,0x2e,0x37,0x35,0x32,0x2c,0x32, + 0x2e,0x37,0x35,0x32,0x76,0x31,0x33,0x2e,0x34,0x35, + 0x35,0x63,0x30,0x2c,0x31,0x2e,0x35,0x31,0x38,0x2d, + 0x31,0x2e,0x32,0x33,0x34,0x2c,0x32,0x2e,0x37,0x35, + 0x32,0x2d,0x32,0x2e,0x37,0x35,0x32,0x2c,0x32,0x2e, + 0x37,0x35,0x32,0x48,0x34,0x2e,0x32,0x35,0x32,0x0a, 0x09,0x63,0x2d,0x31,0x2e,0x35,0x31,0x38,0x2c,0x30, 0x2d,0x32,0x2e,0x37,0x35,0x32,0x2d,0x31,0x2e,0x32, 0x33,0x34,0x2d,0x32,0x2e,0x37,0x35,0x32,0x2d,0x32, @@ -124,18 +123,19 @@ const unsigned char off_svg_data[1338] = { 0x32,0x35,0x32,0x43,0x31,0x2e,0x39,0x31,0x34,0x2c, 0x30,0x2c,0x30,0x2c,0x31,0x2e,0x39,0x31,0x34,0x2c, 0x30,0x2c,0x34,0x2e,0x32,0x35,0x32,0x76,0x31,0x33, - 0x2e,0x34,0x35,0x35,0x0d,0x0a,0x09,0x63,0x30,0x2c, - 0x32,0x2e,0x33,0x33,0x39,0x2c,0x31,0x2e,0x39,0x31, - 0x34,0x2c,0x34,0x2e,0x32,0x35,0x32,0x2c,0x34,0x2e, - 0x32,0x35,0x32,0x2c,0x34,0x2e,0x32,0x35,0x32,0x68, - 0x33,0x35,0x2e,0x34,0x31,0x32,0x63,0x32,0x2e,0x33, - 0x33,0x39,0x2c,0x30,0x2c,0x34,0x2e,0x32,0x35,0x32, - 0x2d,0x31,0x2e,0x39,0x31,0x33,0x2c,0x34,0x2e,0x32, - 0x35,0x32,0x2d,0x34,0x2e,0x32,0x35,0x32,0x56,0x34, - 0x2e,0x32,0x35,0x32,0x43,0x34,0x33,0x2e,0x39,0x31, - 0x36,0x2c,0x31,0x2e,0x39,0x31,0x34,0x2c,0x34,0x32, - 0x2e,0x30,0x30,0x33,0x2c,0x30,0x2c,0x33,0x39,0x2e, - 0x36,0x36,0x34,0x2c,0x30,0x4c,0x33,0x39,0x2e,0x36, - 0x36,0x34,0x2c,0x30,0x7a,0x22,0x2f,0x3e,0x0d,0x0a, - 0x3c,0x2f,0x73,0x76,0x67,0x3e,0x0d,0x0a + 0x2e,0x34,0x35,0x35,0x0a,0x09,0x63,0x30,0x2c,0x32, + 0x2e,0x33,0x33,0x39,0x2c,0x31,0x2e,0x39,0x31,0x34, + 0x2c,0x34,0x2e,0x32,0x35,0x32,0x2c,0x34,0x2e,0x32, + 0x35,0x32,0x2c,0x34,0x2e,0x32,0x35,0x32,0x68,0x33, + 0x35,0x2e,0x34,0x31,0x32,0x63,0x32,0x2e,0x33,0x33, + 0x39,0x2c,0x30,0x2c,0x34,0x2e,0x32,0x35,0x32,0x2d, + 0x31,0x2e,0x39,0x31,0x33,0x2c,0x34,0x2e,0x32,0x35, + 0x32,0x2d,0x34,0x2e,0x32,0x35,0x32,0x56,0x34,0x2e, + 0x32,0x35,0x32,0x43,0x34,0x33,0x2e,0x39,0x31,0x36, + 0x2c,0x31,0x2e,0x39,0x31,0x34,0x2c,0x34,0x32,0x2e, + 0x30,0x30,0x33,0x2c,0x30,0x2c,0x33,0x39,0x2e,0x36, + 0x36,0x34,0x2c,0x30,0x4c,0x33,0x39,0x2e,0x36,0x36, + 0x34,0x2c,0x30,0x7a,0x22,0x2f,0x3e,0x0a,0x3c,0x2f, + 0x73,0x76,0x67,0x3e,0x0a }; + diff --git a/data/converted/on_svg.cpp b/data/converted/on_svg.cpp index 7e3143077e..afd33eee67 100644 --- a/data/converted/on_svg.cpp +++ b/data/converted/on_svg.cpp @@ -2,99 +2,98 @@ #include "../Resources.h" -const size_t on_svg_size = 1146; -const unsigned char on_svg_data[1146] = { +const size_t on_svg_size = 1132; +const unsigned char on_svg_data[1132] = { 0x3c,0x3f,0x78,0x6d,0x6c,0x20,0x76,0x65,0x72,0x73, 0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x30,0x22,0x20, 0x65,0x6e,0x63,0x6f,0x64,0x69,0x6e,0x67,0x3d,0x22, - 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0d,0x0a, - 0x3c,0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72, - 0x61,0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62, - 0x65,0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61, - 0x74,0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33, - 0x2c,0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f, - 0x72,0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e, - 0x20,0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72, - 0x73,0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30, - 0x20,0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20, - 0x20,0x2d,0x2d,0x3e,0x0d,0x0a,0x3c,0x21,0x44,0x4f, - 0x43,0x54,0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20, - 0x50,0x55,0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f, - 0x2f,0x57,0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20, - 0x53,0x56,0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45, - 0x4e,0x22,0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, - 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, - 0x67,0x2f,0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73, - 0x2f,0x53,0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44, - 0x54,0x44,0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64, - 0x74,0x64,0x22,0x3e,0x0d,0x0a,0x3c,0x73,0x76,0x67, - 0x20,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22, - 0x31,0x2e,0x31,0x22,0x20,0x69,0x64,0x3d,0x22,0x45, - 0x62,0x65,0x6e,0x65,0x5f,0x31,0x22,0x20,0x78,0x6d, - 0x6c,0x6e,0x73,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a, - 0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f, - 0x72,0x67,0x2f,0x32,0x30,0x30,0x30,0x2f,0x73,0x76, - 0x67,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78, - 0x6c,0x69,0x6e,0x6b,0x3d,0x22,0x68,0x74,0x74,0x70, - 0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e, - 0x6f,0x72,0x67,0x2f,0x31,0x39,0x39,0x39,0x2f,0x78, - 0x6c,0x69,0x6e,0x6b,0x22,0x20,0x78,0x3d,0x22,0x30, - 0x70,0x78,0x22,0x20,0x79,0x3d,0x22,0x30,0x70,0x78, - 0x22,0x0d,0x0a,0x09,0x20,0x77,0x69,0x64,0x74,0x68, - 0x3d,0x22,0x34,0x33,0x2e,0x39,0x31,0x36,0x70,0x78, - 0x22,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3d,0x22, - 0x32,0x31,0x2e,0x39,0x35,0x39,0x70,0x78,0x22,0x20, - 0x76,0x69,0x65,0x77,0x42,0x6f,0x78,0x3d,0x22,0x30, - 0x20,0x30,0x20,0x34,0x33,0x2e,0x39,0x31,0x36,0x20, - 0x32,0x31,0x2e,0x39,0x35,0x39,0x22,0x20,0x65,0x6e, - 0x61,0x62,0x6c,0x65,0x2d,0x62,0x61,0x63,0x6b,0x67, - 0x72,0x6f,0x75,0x6e,0x64,0x3d,0x22,0x6e,0x65,0x77, - 0x20,0x30,0x20,0x30,0x20,0x34,0x33,0x2e,0x39,0x31, - 0x36,0x20,0x32,0x31,0x2e,0x39,0x35,0x39,0x22,0x20, - 0x78,0x6d,0x6c,0x3a,0x73,0x70,0x61,0x63,0x65,0x3d, - 0x22,0x70,0x72,0x65,0x73,0x65,0x72,0x76,0x65,0x22, - 0x3e,0x0d,0x0a,0x3c,0x67,0x3e,0x0d,0x0a,0x09,0x3c, - 0x70,0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d, - 0x22,0x23,0x37,0x37,0x37,0x37,0x37,0x37,0x22,0x20, - 0x64,0x3d,0x22,0x4d,0x31,0x35,0x2e,0x37,0x35,0x34, - 0x2c,0x37,0x2e,0x34,0x36,0x31,0x63,0x2d,0x32,0x2e, - 0x33,0x31,0x39,0x2c,0x30,0x2d,0x33,0x2e,0x36,0x34, - 0x33,0x2c,0x31,0x2e,0x34,0x33,0x34,0x2d,0x33,0x2e, - 0x36,0x34,0x33,0x2c,0x33,0x2e,0x35,0x31,0x38,0x63, - 0x30,0x2c,0x32,0x2e,0x30,0x38,0x33,0x2c,0x31,0x2e, - 0x33,0x32,0x35,0x2c,0x33,0x2e,0x35,0x32,0x31,0x2c, - 0x33,0x2e,0x36,0x34,0x33,0x2c,0x33,0x2e,0x35,0x32, - 0x31,0x0d,0x0a,0x09,0x09,0x63,0x32,0x2e,0x33,0x32, - 0x2c,0x30,0x2c,0x33,0x2e,0x36,0x34,0x34,0x2d,0x31, - 0x2e,0x34,0x33,0x37,0x2c,0x33,0x2e,0x36,0x34,0x35, - 0x2d,0x33,0x2e,0x35,0x32,0x31,0x43,0x31,0x39,0x2e, - 0x33,0x39,0x39,0x2c,0x38,0x2e,0x38,0x39,0x35,0x2c, - 0x31,0x38,0x2e,0x30,0x37,0x34,0x2c,0x37,0x2e,0x34, - 0x36,0x31,0x2c,0x31,0x35,0x2e,0x37,0x35,0x34,0x2c, - 0x37,0x2e,0x34,0x36,0x31,0x7a,0x22,0x2f,0x3e,0x0d, - 0x0a,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69, - 0x6c,0x6c,0x3d,0x22,0x23,0x37,0x37,0x37,0x37,0x37, - 0x37,0x22,0x20,0x64,0x3d,0x22,0x4d,0x33,0x39,0x2e, - 0x36,0x36,0x34,0x2c,0x30,0x48,0x34,0x2e,0x32,0x35, - 0x32,0x43,0x31,0x2e,0x39,0x31,0x34,0x2c,0x30,0x2c, - 0x30,0x2c,0x31,0x2e,0x39,0x31,0x34,0x2c,0x30,0x2c, - 0x34,0x2e,0x32,0x35,0x32,0x76,0x31,0x33,0x2e,0x34, - 0x35,0x35,0x63,0x30,0x2c,0x32,0x2e,0x33,0x33,0x39, - 0x2c,0x31,0x2e,0x39,0x31,0x34,0x2c,0x34,0x2e,0x32, - 0x35,0x32,0x2c,0x34,0x2e,0x32,0x35,0x32,0x2c,0x34, - 0x2e,0x32,0x35,0x32,0x68,0x33,0x35,0x2e,0x34,0x31, - 0x32,0x0d,0x0a,0x09,0x09,0x63,0x32,0x2e,0x33,0x33, - 0x39,0x2c,0x30,0x2c,0x34,0x2e,0x32,0x35,0x32,0x2d, - 0x31,0x2e,0x39,0x31,0x33,0x2c,0x34,0x2e,0x32,0x35, - 0x32,0x2d,0x34,0x2e,0x32,0x35,0x32,0x56,0x34,0x2e, - 0x32,0x35,0x32,0x43,0x34,0x33,0x2e,0x39,0x31,0x36, - 0x2c,0x31,0x2e,0x39,0x31,0x34,0x2c,0x34,0x32,0x2e, - 0x30,0x30,0x33,0x2c,0x30,0x2c,0x33,0x39,0x2e,0x36, - 0x36,0x34,0x2c,0x30,0x7a,0x20,0x4d,0x31,0x35,0x2e, - 0x37,0x35,0x34,0x2c,0x31,0x35,0x2e,0x39,0x37,0x39, - 0x63,0x2d,0x34,0x2e,0x31,0x36,0x38,0x2c,0x30,0x2d, - 0x35,0x2e,0x37,0x39,0x36,0x2d,0x32,0x2e,0x33,0x33, - 0x34,0x2d,0x35,0x2e,0x37,0x39,0x36,0x2d,0x35,0x0d, + 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0a,0x3c, + 0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72,0x61, + 0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62,0x65, + 0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61,0x74, + 0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33,0x2c, + 0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f,0x72, + 0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e,0x20, + 0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72,0x73, + 0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30,0x20, + 0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20,0x20, + 0x2d,0x2d,0x3e,0x0a,0x3c,0x21,0x44,0x4f,0x43,0x54, + 0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20,0x50,0x55, + 0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f,0x2f,0x57, + 0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20,0x53,0x56, + 0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45,0x4e,0x22, + 0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73,0x2f,0x53, + 0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44,0x54,0x44, + 0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64,0x74,0x64, + 0x22,0x3e,0x0a,0x3c,0x73,0x76,0x67,0x20,0x76,0x65, + 0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x31, + 0x22,0x20,0x69,0x64,0x3d,0x22,0x45,0x62,0x65,0x6e, + 0x65,0x5f,0x31,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73, + 0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x32,0x30,0x30,0x30,0x2f,0x73,0x76,0x67,0x22,0x20, + 0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78,0x6c,0x69,0x6e, + 0x6b,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f, + 0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67, + 0x2f,0x31,0x39,0x39,0x39,0x2f,0x78,0x6c,0x69,0x6e, + 0x6b,0x22,0x20,0x78,0x3d,0x22,0x30,0x70,0x78,0x22, + 0x20,0x79,0x3d,0x22,0x30,0x70,0x78,0x22,0x0a,0x09, + 0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x34,0x33, + 0x2e,0x39,0x31,0x36,0x70,0x78,0x22,0x20,0x68,0x65, + 0x69,0x67,0x68,0x74,0x3d,0x22,0x32,0x31,0x2e,0x39, + 0x35,0x39,0x70,0x78,0x22,0x20,0x76,0x69,0x65,0x77, + 0x42,0x6f,0x78,0x3d,0x22,0x30,0x20,0x30,0x20,0x34, + 0x33,0x2e,0x39,0x31,0x36,0x20,0x32,0x31,0x2e,0x39, + 0x35,0x39,0x22,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65, + 0x2d,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e, + 0x64,0x3d,0x22,0x6e,0x65,0x77,0x20,0x30,0x20,0x30, + 0x20,0x34,0x33,0x2e,0x39,0x31,0x36,0x20,0x32,0x31, + 0x2e,0x39,0x35,0x39,0x22,0x20,0x78,0x6d,0x6c,0x3a, + 0x73,0x70,0x61,0x63,0x65,0x3d,0x22,0x70,0x72,0x65, + 0x73,0x65,0x72,0x76,0x65,0x22,0x3e,0x0a,0x3c,0x67, + 0x3e,0x0a,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66, + 0x69,0x6c,0x6c,0x3d,0x22,0x23,0x37,0x37,0x37,0x37, + 0x37,0x37,0x22,0x20,0x64,0x3d,0x22,0x4d,0x31,0x35, + 0x2e,0x37,0x35,0x34,0x2c,0x37,0x2e,0x34,0x36,0x31, + 0x63,0x2d,0x32,0x2e,0x33,0x31,0x39,0x2c,0x30,0x2d, + 0x33,0x2e,0x36,0x34,0x33,0x2c,0x31,0x2e,0x34,0x33, + 0x34,0x2d,0x33,0x2e,0x36,0x34,0x33,0x2c,0x33,0x2e, + 0x35,0x31,0x38,0x63,0x30,0x2c,0x32,0x2e,0x30,0x38, + 0x33,0x2c,0x31,0x2e,0x33,0x32,0x35,0x2c,0x33,0x2e, + 0x35,0x32,0x31,0x2c,0x33,0x2e,0x36,0x34,0x33,0x2c, + 0x33,0x2e,0x35,0x32,0x31,0x0a,0x09,0x09,0x63,0x32, + 0x2e,0x33,0x32,0x2c,0x30,0x2c,0x33,0x2e,0x36,0x34, + 0x34,0x2d,0x31,0x2e,0x34,0x33,0x37,0x2c,0x33,0x2e, + 0x36,0x34,0x35,0x2d,0x33,0x2e,0x35,0x32,0x31,0x43, + 0x31,0x39,0x2e,0x33,0x39,0x39,0x2c,0x38,0x2e,0x38, + 0x39,0x35,0x2c,0x31,0x38,0x2e,0x30,0x37,0x34,0x2c, + 0x37,0x2e,0x34,0x36,0x31,0x2c,0x31,0x35,0x2e,0x37, + 0x35,0x34,0x2c,0x37,0x2e,0x34,0x36,0x31,0x7a,0x22, + 0x2f,0x3e,0x0a,0x09,0x3c,0x70,0x61,0x74,0x68,0x20, + 0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x37,0x37,0x37, + 0x37,0x37,0x37,0x22,0x20,0x64,0x3d,0x22,0x4d,0x33, + 0x39,0x2e,0x36,0x36,0x34,0x2c,0x30,0x48,0x34,0x2e, + 0x32,0x35,0x32,0x43,0x31,0x2e,0x39,0x31,0x34,0x2c, + 0x30,0x2c,0x30,0x2c,0x31,0x2e,0x39,0x31,0x34,0x2c, + 0x30,0x2c,0x34,0x2e,0x32,0x35,0x32,0x76,0x31,0x33, + 0x2e,0x34,0x35,0x35,0x63,0x30,0x2c,0x32,0x2e,0x33, + 0x33,0x39,0x2c,0x31,0x2e,0x39,0x31,0x34,0x2c,0x34, + 0x2e,0x32,0x35,0x32,0x2c,0x34,0x2e,0x32,0x35,0x32, + 0x2c,0x34,0x2e,0x32,0x35,0x32,0x68,0x33,0x35,0x2e, + 0x34,0x31,0x32,0x0a,0x09,0x09,0x63,0x32,0x2e,0x33, + 0x33,0x39,0x2c,0x30,0x2c,0x34,0x2e,0x32,0x35,0x32, + 0x2d,0x31,0x2e,0x39,0x31,0x33,0x2c,0x34,0x2e,0x32, + 0x35,0x32,0x2d,0x34,0x2e,0x32,0x35,0x32,0x56,0x34, + 0x2e,0x32,0x35,0x32,0x43,0x34,0x33,0x2e,0x39,0x31, + 0x36,0x2c,0x31,0x2e,0x39,0x31,0x34,0x2c,0x34,0x32, + 0x2e,0x30,0x30,0x33,0x2c,0x30,0x2c,0x33,0x39,0x2e, + 0x36,0x36,0x34,0x2c,0x30,0x7a,0x20,0x4d,0x31,0x35, + 0x2e,0x37,0x35,0x34,0x2c,0x31,0x35,0x2e,0x39,0x37, + 0x39,0x63,0x2d,0x34,0x2e,0x31,0x36,0x38,0x2c,0x30, + 0x2d,0x35,0x2e,0x37,0x39,0x36,0x2d,0x32,0x2e,0x33, + 0x33,0x34,0x2d,0x35,0x2e,0x37,0x39,0x36,0x2d,0x35, 0x0a,0x09,0x09,0x63,0x30,0x2d,0x32,0x2e,0x36,0x36, 0x39,0x2c,0x31,0x2e,0x36,0x32,0x38,0x2d,0x35,0x2e, 0x30,0x30,0x31,0x2c,0x35,0x2e,0x37,0x39,0x36,0x2d, @@ -107,16 +106,17 @@ const unsigned char on_svg_data[1146] = { 0x2e,0x39,0x37,0x39,0x2c,0x31,0x35,0x2e,0x37,0x35, 0x34,0x2c,0x31,0x35,0x2e,0x39,0x37,0x39,0x7a,0x20, 0x4d,0x33,0x33,0x2e,0x39,0x35,0x37,0x2c,0x31,0x35, - 0x2e,0x37,0x31,0x35,0x0d,0x0a,0x09,0x09,0x68,0x2d, - 0x32,0x2e,0x33,0x33,0x32,0x4c,0x32,0x35,0x2e,0x37, - 0x32,0x2c,0x38,0x2e,0x36,0x30,0x32,0x68,0x2d,0x30, - 0x2e,0x30,0x32,0x37,0x76,0x37,0x2e,0x31,0x31,0x33, - 0x68,0x2d,0x31,0x2e,0x39,0x38,0x38,0x56,0x36,0x2e, - 0x32,0x34,0x34,0x68,0x32,0x2e,0x33,0x37,0x33,0x6c, - 0x35,0x2e,0x38,0x36,0x35,0x2c,0x37,0x2e,0x31,0x31, - 0x34,0x68,0x30,0x2e,0x30,0x32,0x37,0x56,0x36,0x2e, - 0x32,0x34,0x34,0x68,0x31,0x2e,0x39,0x38,0x37,0x56, - 0x31,0x35,0x2e,0x37,0x31,0x35,0x7a,0x22,0x2f,0x3e, - 0x0d,0x0a,0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x3c,0x2f, - 0x73,0x76,0x67,0x3e,0x0d,0x0a + 0x2e,0x37,0x31,0x35,0x0a,0x09,0x09,0x68,0x2d,0x32, + 0x2e,0x33,0x33,0x32,0x4c,0x32,0x35,0x2e,0x37,0x32, + 0x2c,0x38,0x2e,0x36,0x30,0x32,0x68,0x2d,0x30,0x2e, + 0x30,0x32,0x37,0x76,0x37,0x2e,0x31,0x31,0x33,0x68, + 0x2d,0x31,0x2e,0x39,0x38,0x38,0x56,0x36,0x2e,0x32, + 0x34,0x34,0x68,0x32,0x2e,0x33,0x37,0x33,0x6c,0x35, + 0x2e,0x38,0x36,0x35,0x2c,0x37,0x2e,0x31,0x31,0x34, + 0x68,0x30,0x2e,0x30,0x32,0x37,0x56,0x36,0x2e,0x32, + 0x34,0x34,0x68,0x31,0x2e,0x39,0x38,0x37,0x56,0x31, + 0x35,0x2e,0x37,0x31,0x35,0x7a,0x22,0x2f,0x3e,0x0a, + 0x3c,0x2f,0x67,0x3e,0x0a,0x3c,0x2f,0x73,0x76,0x67, + 0x3e,0x0a }; + diff --git a/data/converted/opensans_hebrew_condensed_light_ttf.cpp b/data/converted/opensans_hebrew_condensed_light_ttf.cpp index a9a553c350..c40c808a8b 100644 --- a/data/converted/opensans_hebrew_condensed_light_ttf.cpp +++ b/data/converted/opensans_hebrew_condensed_light_ttf.cpp @@ -3292,3 +3292,4 @@ const unsigned char opensans_hebrew_condensed_light_ttf_data[32868] = { 0x62,0x72,0x00,0x08,0x00,0x04,0x00,0x00,0x00,0x00, 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00 }; + diff --git a/data/converted/opensans_hebrew_condensed_regular_ttf.cpp b/data/converted/opensans_hebrew_condensed_regular_ttf.cpp index 0fa9cd5696..5c79a51087 100644 --- a/data/converted/opensans_hebrew_condensed_regular_ttf.cpp +++ b/data/converted/opensans_hebrew_condensed_regular_ttf.cpp @@ -3242,3 +3242,4 @@ const unsigned char opensans_hebrew_condensed_regular_ttf_data[32364] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, 0x00,0x00,0x00,0x00 }; + diff --git a/data/converted/option_arrow_svg.cpp b/data/converted/option_arrow_svg.cpp index c07891afdc..caaaad54ac 100644 --- a/data/converted/option_arrow_svg.cpp +++ b/data/converted/option_arrow_svg.cpp @@ -2,91 +2,91 @@ #include "../Resources.h" -const size_t option_arrow_svg_size = 850; -const unsigned char option_arrow_svg_data[850] = { +const size_t option_arrow_svg_size = 839; +const unsigned char option_arrow_svg_data[839] = { 0x3c,0x3f,0x78,0x6d,0x6c,0x20,0x76,0x65,0x72,0x73, 0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x30,0x22,0x20, 0x65,0x6e,0x63,0x6f,0x64,0x69,0x6e,0x67,0x3d,0x22, - 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0d,0x0a, - 0x3c,0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72, - 0x61,0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62, - 0x65,0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61, - 0x74,0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33, - 0x2c,0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f, - 0x72,0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e, - 0x20,0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72, - 0x73,0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30, - 0x20,0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20, - 0x20,0x2d,0x2d,0x3e,0x0d,0x0a,0x3c,0x21,0x44,0x4f, - 0x43,0x54,0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20, - 0x50,0x55,0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f, - 0x2f,0x57,0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20, - 0x53,0x56,0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45, - 0x4e,0x22,0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, - 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, - 0x67,0x2f,0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73, - 0x2f,0x53,0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44, - 0x54,0x44,0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64, - 0x74,0x64,0x22,0x3e,0x0d,0x0a,0x3c,0x73,0x76,0x67, - 0x20,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22, - 0x31,0x2e,0x31,0x22,0x20,0x69,0x64,0x3d,0x22,0x45, - 0x62,0x65,0x6e,0x65,0x5f,0x31,0x22,0x20,0x78,0x6d, - 0x6c,0x6e,0x73,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a, - 0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f, - 0x72,0x67,0x2f,0x32,0x30,0x30,0x30,0x2f,0x73,0x76, - 0x67,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78, - 0x6c,0x69,0x6e,0x6b,0x3d,0x22,0x68,0x74,0x74,0x70, - 0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e, - 0x6f,0x72,0x67,0x2f,0x31,0x39,0x39,0x39,0x2f,0x78, - 0x6c,0x69,0x6e,0x6b,0x22,0x20,0x78,0x3d,0x22,0x30, - 0x70,0x78,0x22,0x20,0x79,0x3d,0x22,0x30,0x70,0x78, - 0x22,0x0d,0x0a,0x09,0x20,0x77,0x69,0x64,0x74,0x68, - 0x3d,0x22,0x31,0x32,0x2e,0x31,0x35,0x38,0x70,0x78, - 0x22,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3d,0x22, - 0x32,0x31,0x2e,0x39,0x31,0x33,0x70,0x78,0x22,0x20, - 0x76,0x69,0x65,0x77,0x42,0x6f,0x78,0x3d,0x22,0x30, - 0x20,0x30,0x20,0x31,0x32,0x2e,0x31,0x35,0x38,0x20, - 0x32,0x31,0x2e,0x39,0x31,0x33,0x22,0x20,0x65,0x6e, - 0x61,0x62,0x6c,0x65,0x2d,0x62,0x61,0x63,0x6b,0x67, - 0x72,0x6f,0x75,0x6e,0x64,0x3d,0x22,0x6e,0x65,0x77, - 0x20,0x30,0x20,0x30,0x20,0x31,0x32,0x2e,0x31,0x35, - 0x38,0x20,0x32,0x31,0x2e,0x39,0x31,0x33,0x22,0x20, - 0x78,0x6d,0x6c,0x3a,0x73,0x70,0x61,0x63,0x65,0x3d, - 0x22,0x70,0x72,0x65,0x73,0x65,0x72,0x76,0x65,0x22, - 0x3e,0x0d,0x0a,0x3c,0x67,0x3e,0x0d,0x0a,0x09,0x3c, - 0x70,0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d, - 0x22,0x23,0x37,0x37,0x37,0x37,0x37,0x37,0x22,0x20, - 0x64,0x3d,0x22,0x4d,0x30,0x2e,0x37,0x35,0x2c,0x32, - 0x31,0x2e,0x39,0x31,0x33,0x63,0x2d,0x30,0x2e,0x31, - 0x2c,0x30,0x2d,0x30,0x2e,0x32,0x2d,0x30,0x2e,0x30, - 0x32,0x2d,0x30,0x2e,0x32,0x39,0x34,0x2d,0x30,0x2e, - 0x30,0x36,0x31,0x43,0x30,0x2e,0x31,0x37,0x39,0x2c, - 0x32,0x31,0x2e,0x37,0x33,0x35,0x2c,0x30,0x2c,0x32, - 0x31,0x2e,0x34,0x36,0x33,0x2c,0x30,0x2c,0x32,0x31, - 0x2e,0x31,0x36,0x33,0x56,0x30,0x2e,0x37,0x35,0x0d, - 0x0a,0x09,0x09,0x63,0x30,0x2d,0x30,0x2e,0x33,0x2c, - 0x30,0x2e,0x31,0x37,0x39,0x2d,0x30,0x2e,0x35,0x37, - 0x32,0x2c,0x30,0x2e,0x34,0x35,0x36,0x2d,0x30,0x2e, - 0x36,0x39,0x43,0x30,0x2e,0x37,0x33,0x2d,0x30,0x2e, - 0x30,0x35,0x37,0x2c,0x31,0x2e,0x30,0x35,0x32,0x2c, - 0x30,0x2c,0x31,0x2e,0x32,0x36,0x39,0x2c,0x30,0x2e, - 0x32,0x30,0x38,0x6c,0x31,0x30,0x2e,0x36,0x35,0x38, - 0x2c,0x31,0x30,0x2e,0x32,0x30,0x36,0x63,0x30,0x2e, - 0x31,0x34,0x37,0x2c,0x30,0x2e,0x31,0x34,0x31,0x2c, - 0x30,0x2e,0x32,0x33,0x31,0x2c,0x30,0x2e,0x33,0x33, - 0x37,0x2c,0x30,0x2e,0x32,0x33,0x31,0x2c,0x30,0x2e, - 0x35,0x34,0x32,0x0d,0x0a,0x09,0x09,0x73,0x2d,0x30, - 0x2e,0x30,0x38,0x34,0x2c,0x30,0x2e,0x34,0x2d,0x30, - 0x2e,0x32,0x33,0x31,0x2c,0x30,0x2e,0x35,0x34,0x32, - 0x4c,0x31,0x2e,0x32,0x36,0x39,0x2c,0x32,0x31,0x2e, - 0x37,0x30,0x35,0x43,0x31,0x2e,0x31,0x32,0x36,0x2c, - 0x32,0x31,0x2e,0x38,0x34,0x2c,0x30,0x2e,0x39,0x33, - 0x39,0x2c,0x32,0x31,0x2e,0x39,0x31,0x33,0x2c,0x30, - 0x2e,0x37,0x35,0x2c,0x32,0x31,0x2e,0x39,0x31,0x33, - 0x7a,0x20,0x4d,0x31,0x2e,0x35,0x2c,0x32,0x2e,0x35, - 0x30,0x36,0x76,0x31,0x36,0x2e,0x38,0x39,0x39,0x6c, - 0x38,0x2e,0x38,0x32,0x34,0x2d,0x38,0x2e,0x34,0x35, - 0x4c,0x31,0x2e,0x35,0x2c,0x32,0x2e,0x35,0x30,0x36, - 0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x3c,0x2f,0x67,0x3e, - 0x0d,0x0a,0x3c,0x2f,0x73,0x76,0x67,0x3e,0x0d,0x0a + 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0a,0x3c, + 0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72,0x61, + 0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62,0x65, + 0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61,0x74, + 0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33,0x2c, + 0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f,0x72, + 0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e,0x20, + 0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72,0x73, + 0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30,0x20, + 0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20,0x20, + 0x2d,0x2d,0x3e,0x0a,0x3c,0x21,0x44,0x4f,0x43,0x54, + 0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20,0x50,0x55, + 0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f,0x2f,0x57, + 0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20,0x53,0x56, + 0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45,0x4e,0x22, + 0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73,0x2f,0x53, + 0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44,0x54,0x44, + 0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64,0x74,0x64, + 0x22,0x3e,0x0a,0x3c,0x73,0x76,0x67,0x20,0x76,0x65, + 0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x31, + 0x22,0x20,0x69,0x64,0x3d,0x22,0x45,0x62,0x65,0x6e, + 0x65,0x5f,0x31,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73, + 0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x32,0x30,0x30,0x30,0x2f,0x73,0x76,0x67,0x22,0x20, + 0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78,0x6c,0x69,0x6e, + 0x6b,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f, + 0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67, + 0x2f,0x31,0x39,0x39,0x39,0x2f,0x78,0x6c,0x69,0x6e, + 0x6b,0x22,0x20,0x78,0x3d,0x22,0x30,0x70,0x78,0x22, + 0x20,0x79,0x3d,0x22,0x30,0x70,0x78,0x22,0x0a,0x09, + 0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x31,0x32, + 0x2e,0x31,0x35,0x38,0x70,0x78,0x22,0x20,0x68,0x65, + 0x69,0x67,0x68,0x74,0x3d,0x22,0x32,0x31,0x2e,0x39, + 0x31,0x33,0x70,0x78,0x22,0x20,0x76,0x69,0x65,0x77, + 0x42,0x6f,0x78,0x3d,0x22,0x30,0x20,0x30,0x20,0x31, + 0x32,0x2e,0x31,0x35,0x38,0x20,0x32,0x31,0x2e,0x39, + 0x31,0x33,0x22,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65, + 0x2d,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e, + 0x64,0x3d,0x22,0x6e,0x65,0x77,0x20,0x30,0x20,0x30, + 0x20,0x31,0x32,0x2e,0x31,0x35,0x38,0x20,0x32,0x31, + 0x2e,0x39,0x31,0x33,0x22,0x20,0x78,0x6d,0x6c,0x3a, + 0x73,0x70,0x61,0x63,0x65,0x3d,0x22,0x70,0x72,0x65, + 0x73,0x65,0x72,0x76,0x65,0x22,0x3e,0x0a,0x3c,0x67, + 0x3e,0x0a,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x66, + 0x69,0x6c,0x6c,0x3d,0x22,0x23,0x37,0x37,0x37,0x37, + 0x37,0x37,0x22,0x20,0x64,0x3d,0x22,0x4d,0x30,0x2e, + 0x37,0x35,0x2c,0x32,0x31,0x2e,0x39,0x31,0x33,0x63, + 0x2d,0x30,0x2e,0x31,0x2c,0x30,0x2d,0x30,0x2e,0x32, + 0x2d,0x30,0x2e,0x30,0x32,0x2d,0x30,0x2e,0x32,0x39, + 0x34,0x2d,0x30,0x2e,0x30,0x36,0x31,0x43,0x30,0x2e, + 0x31,0x37,0x39,0x2c,0x32,0x31,0x2e,0x37,0x33,0x35, + 0x2c,0x30,0x2c,0x32,0x31,0x2e,0x34,0x36,0x33,0x2c, + 0x30,0x2c,0x32,0x31,0x2e,0x31,0x36,0x33,0x56,0x30, + 0x2e,0x37,0x35,0x0a,0x09,0x09,0x63,0x30,0x2d,0x30, + 0x2e,0x33,0x2c,0x30,0x2e,0x31,0x37,0x39,0x2d,0x30, + 0x2e,0x35,0x37,0x32,0x2c,0x30,0x2e,0x34,0x35,0x36, + 0x2d,0x30,0x2e,0x36,0x39,0x43,0x30,0x2e,0x37,0x33, + 0x2d,0x30,0x2e,0x30,0x35,0x37,0x2c,0x31,0x2e,0x30, + 0x35,0x32,0x2c,0x30,0x2c,0x31,0x2e,0x32,0x36,0x39, + 0x2c,0x30,0x2e,0x32,0x30,0x38,0x6c,0x31,0x30,0x2e, + 0x36,0x35,0x38,0x2c,0x31,0x30,0x2e,0x32,0x30,0x36, + 0x63,0x30,0x2e,0x31,0x34,0x37,0x2c,0x30,0x2e,0x31, + 0x34,0x31,0x2c,0x30,0x2e,0x32,0x33,0x31,0x2c,0x30, + 0x2e,0x33,0x33,0x37,0x2c,0x30,0x2e,0x32,0x33,0x31, + 0x2c,0x30,0x2e,0x35,0x34,0x32,0x0a,0x09,0x09,0x73, + 0x2d,0x30,0x2e,0x30,0x38,0x34,0x2c,0x30,0x2e,0x34, + 0x2d,0x30,0x2e,0x32,0x33,0x31,0x2c,0x30,0x2e,0x35, + 0x34,0x32,0x4c,0x31,0x2e,0x32,0x36,0x39,0x2c,0x32, + 0x31,0x2e,0x37,0x30,0x35,0x43,0x31,0x2e,0x31,0x32, + 0x36,0x2c,0x32,0x31,0x2e,0x38,0x34,0x2c,0x30,0x2e, + 0x39,0x33,0x39,0x2c,0x32,0x31,0x2e,0x39,0x31,0x33, + 0x2c,0x30,0x2e,0x37,0x35,0x2c,0x32,0x31,0x2e,0x39, + 0x31,0x33,0x7a,0x20,0x4d,0x31,0x2e,0x35,0x2c,0x32, + 0x2e,0x35,0x30,0x36,0x76,0x31,0x36,0x2e,0x38,0x39, + 0x39,0x6c,0x38,0x2e,0x38,0x32,0x34,0x2d,0x38,0x2e, + 0x34,0x35,0x4c,0x31,0x2e,0x35,0x2c,0x32,0x2e,0x35, + 0x30,0x36,0x7a,0x22,0x2f,0x3e,0x0a,0x3c,0x2f,0x67, + 0x3e,0x0a,0x3c,0x2f,0x73,0x76,0x67,0x3e,0x0a }; + diff --git a/data/converted/scroll_gradient_png.cpp b/data/converted/scroll_gradient_png.cpp index 53c59587f1..77b84a54e0 100644 --- a/data/converted/scroll_gradient_png.cpp +++ b/data/converted/scroll_gradient_png.cpp @@ -8344,3 +8344,4 @@ const unsigned char scroll_gradient_png_data[83384] = { 0x91,0xf7,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44, 0xae,0x42,0x60,0x82 }; + diff --git a/data/converted/slider_knob_svg.cpp b/data/converted/slider_knob_svg.cpp index ec7122501c..8b99255f25 100644 --- a/data/converted/slider_knob_svg.cpp +++ b/data/converted/slider_knob_svg.cpp @@ -2,69 +2,69 @@ #include "../Resources.h" -const size_t slider_knob_svg_size = 627; -const unsigned char slider_knob_svg_data[627] = { +const size_t slider_knob_svg_size = 619; +const unsigned char slider_knob_svg_data[619] = { 0x3c,0x3f,0x78,0x6d,0x6c,0x20,0x76,0x65,0x72,0x73, 0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x30,0x22,0x20, 0x65,0x6e,0x63,0x6f,0x64,0x69,0x6e,0x67,0x3d,0x22, - 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0d,0x0a, - 0x3c,0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72, - 0x61,0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62, - 0x65,0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61, - 0x74,0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33, - 0x2c,0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f, - 0x72,0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e, - 0x20,0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72, - 0x73,0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30, - 0x20,0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20, - 0x20,0x2d,0x2d,0x3e,0x0d,0x0a,0x3c,0x21,0x44,0x4f, - 0x43,0x54,0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20, - 0x50,0x55,0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f, - 0x2f,0x57,0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20, - 0x53,0x56,0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45, - 0x4e,0x22,0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, - 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, - 0x67,0x2f,0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73, - 0x2f,0x53,0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44, - 0x54,0x44,0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64, - 0x74,0x64,0x22,0x3e,0x0d,0x0a,0x3c,0x73,0x76,0x67, - 0x20,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22, - 0x31,0x2e,0x31,0x22,0x20,0x69,0x64,0x3d,0x22,0x45, - 0x62,0x65,0x6e,0x65,0x5f,0x31,0x22,0x20,0x78,0x6d, - 0x6c,0x6e,0x73,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a, - 0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f, - 0x72,0x67,0x2f,0x32,0x30,0x30,0x30,0x2f,0x73,0x76, - 0x67,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78, - 0x6c,0x69,0x6e,0x6b,0x3d,0x22,0x68,0x74,0x74,0x70, - 0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e, - 0x6f,0x72,0x67,0x2f,0x31,0x39,0x39,0x39,0x2f,0x78, - 0x6c,0x69,0x6e,0x6b,0x22,0x20,0x78,0x3d,0x22,0x30, - 0x70,0x78,0x22,0x20,0x79,0x3d,0x22,0x30,0x70,0x78, - 0x22,0x0d,0x0a,0x09,0x20,0x77,0x69,0x64,0x74,0x68, - 0x3d,0x22,0x31,0x36,0x70,0x78,0x22,0x20,0x68,0x65, - 0x69,0x67,0x68,0x74,0x3d,0x22,0x31,0x36,0x70,0x78, - 0x22,0x20,0x76,0x69,0x65,0x77,0x42,0x6f,0x78,0x3d, - 0x22,0x30,0x20,0x30,0x20,0x31,0x36,0x20,0x31,0x36, - 0x22,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0x2d,0x62, - 0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x3d, - 0x22,0x6e,0x65,0x77,0x20,0x30,0x20,0x30,0x20,0x31, - 0x36,0x20,0x31,0x36,0x22,0x20,0x78,0x6d,0x6c,0x3a, - 0x73,0x70,0x61,0x63,0x65,0x3d,0x22,0x70,0x72,0x65, - 0x73,0x65,0x72,0x76,0x65,0x22,0x3e,0x0d,0x0a,0x3c, - 0x70,0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x2d, - 0x72,0x75,0x6c,0x65,0x3d,0x22,0x65,0x76,0x65,0x6e, - 0x6f,0x64,0x64,0x22,0x20,0x63,0x6c,0x69,0x70,0x2d, - 0x72,0x75,0x6c,0x65,0x3d,0x22,0x65,0x76,0x65,0x6e, - 0x6f,0x64,0x64,0x22,0x20,0x66,0x69,0x6c,0x6c,0x3d, - 0x22,0x23,0x37,0x37,0x37,0x37,0x37,0x37,0x22,0x20, - 0x64,0x3d,0x22,0x4d,0x38,0x2c,0x30,0x63,0x34,0x2e, - 0x34,0x31,0x38,0x2c,0x30,0x2c,0x38,0x2c,0x33,0x2e, - 0x35,0x38,0x32,0x2c,0x38,0x2c,0x38,0x63,0x30,0x2c, - 0x34,0x2e,0x34,0x31,0x38,0x2d,0x33,0x2e,0x35,0x38, - 0x32,0x2c,0x38,0x2d,0x38,0x2c,0x38,0x73,0x2d,0x38, - 0x2d,0x33,0x2e,0x35,0x38,0x32,0x2d,0x38,0x2d,0x38, - 0x0d,0x0a,0x09,0x43,0x30,0x2c,0x33,0x2e,0x35,0x38, - 0x32,0x2c,0x33,0x2e,0x35,0x38,0x33,0x2c,0x30,0x2c, - 0x38,0x2c,0x30,0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x3c, - 0x2f,0x73,0x76,0x67,0x3e,0x0d,0x0a + 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0a,0x3c, + 0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72,0x61, + 0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62,0x65, + 0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61,0x74, + 0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33,0x2c, + 0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f,0x72, + 0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e,0x20, + 0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72,0x73, + 0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30,0x20, + 0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20,0x20, + 0x2d,0x2d,0x3e,0x0a,0x3c,0x21,0x44,0x4f,0x43,0x54, + 0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20,0x50,0x55, + 0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f,0x2f,0x57, + 0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20,0x53,0x56, + 0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45,0x4e,0x22, + 0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73,0x2f,0x53, + 0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44,0x54,0x44, + 0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64,0x74,0x64, + 0x22,0x3e,0x0a,0x3c,0x73,0x76,0x67,0x20,0x76,0x65, + 0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x31, + 0x22,0x20,0x69,0x64,0x3d,0x22,0x45,0x62,0x65,0x6e, + 0x65,0x5f,0x31,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73, + 0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x32,0x30,0x30,0x30,0x2f,0x73,0x76,0x67,0x22,0x20, + 0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78,0x6c,0x69,0x6e, + 0x6b,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f, + 0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67, + 0x2f,0x31,0x39,0x39,0x39,0x2f,0x78,0x6c,0x69,0x6e, + 0x6b,0x22,0x20,0x78,0x3d,0x22,0x30,0x70,0x78,0x22, + 0x20,0x79,0x3d,0x22,0x30,0x70,0x78,0x22,0x0a,0x09, + 0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x31,0x36, + 0x70,0x78,0x22,0x20,0x68,0x65,0x69,0x67,0x68,0x74, + 0x3d,0x22,0x31,0x36,0x70,0x78,0x22,0x20,0x76,0x69, + 0x65,0x77,0x42,0x6f,0x78,0x3d,0x22,0x30,0x20,0x30, + 0x20,0x31,0x36,0x20,0x31,0x36,0x22,0x20,0x65,0x6e, + 0x61,0x62,0x6c,0x65,0x2d,0x62,0x61,0x63,0x6b,0x67, + 0x72,0x6f,0x75,0x6e,0x64,0x3d,0x22,0x6e,0x65,0x77, + 0x20,0x30,0x20,0x30,0x20,0x31,0x36,0x20,0x31,0x36, + 0x22,0x20,0x78,0x6d,0x6c,0x3a,0x73,0x70,0x61,0x63, + 0x65,0x3d,0x22,0x70,0x72,0x65,0x73,0x65,0x72,0x76, + 0x65,0x22,0x3e,0x0a,0x3c,0x70,0x61,0x74,0x68,0x20, + 0x66,0x69,0x6c,0x6c,0x2d,0x72,0x75,0x6c,0x65,0x3d, + 0x22,0x65,0x76,0x65,0x6e,0x6f,0x64,0x64,0x22,0x20, + 0x63,0x6c,0x69,0x70,0x2d,0x72,0x75,0x6c,0x65,0x3d, + 0x22,0x65,0x76,0x65,0x6e,0x6f,0x64,0x64,0x22,0x20, + 0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x37,0x37,0x37, + 0x37,0x37,0x37,0x22,0x20,0x64,0x3d,0x22,0x4d,0x38, + 0x2c,0x30,0x63,0x34,0x2e,0x34,0x31,0x38,0x2c,0x30, + 0x2c,0x38,0x2c,0x33,0x2e,0x35,0x38,0x32,0x2c,0x38, + 0x2c,0x38,0x63,0x30,0x2c,0x34,0x2e,0x34,0x31,0x38, + 0x2d,0x33,0x2e,0x35,0x38,0x32,0x2c,0x38,0x2d,0x38, + 0x2c,0x38,0x73,0x2d,0x38,0x2d,0x33,0x2e,0x35,0x38, + 0x32,0x2d,0x38,0x2d,0x38,0x0a,0x09,0x43,0x30,0x2c, + 0x33,0x2e,0x35,0x38,0x32,0x2c,0x33,0x2e,0x35,0x38, + 0x33,0x2c,0x30,0x2c,0x38,0x2c,0x30,0x7a,0x22,0x2f, + 0x3e,0x0a,0x3c,0x2f,0x73,0x76,0x67,0x3e,0x0a }; + diff --git a/data/converted/splash_svg.cpp b/data/converted/splash_svg.cpp index 2f945f1773..e2e3391b59 100644 --- a/data/converted/splash_svg.cpp +++ b/data/converted/splash_svg.cpp @@ -2,95 +2,94 @@ #include "../Resources.h" -const size_t splash_svg_size = 17935; -const unsigned char splash_svg_data[17935] = { +const size_t splash_svg_size = 17764; +const unsigned char splash_svg_data[17764] = { 0x3c,0x3f,0x78,0x6d,0x6c,0x20,0x76,0x65,0x72,0x73, 0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x30,0x22,0x20, 0x65,0x6e,0x63,0x6f,0x64,0x69,0x6e,0x67,0x3d,0x22, - 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0d,0x0a, - 0x3c,0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72, - 0x61,0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62, - 0x65,0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61, - 0x74,0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x30, - 0x2c,0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f, - 0x72,0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e, - 0x20,0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72, - 0x73,0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30, - 0x20,0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20, - 0x20,0x2d,0x2d,0x3e,0x0d,0x0a,0x3c,0x21,0x44,0x4f, - 0x43,0x54,0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20, - 0x50,0x55,0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f, - 0x2f,0x57,0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20, - 0x53,0x56,0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45, - 0x4e,0x22,0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, - 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, - 0x67,0x2f,0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73, - 0x2f,0x53,0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44, - 0x54,0x44,0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64, - 0x74,0x64,0x22,0x3e,0x0d,0x0a,0x3c,0x73,0x76,0x67, - 0x20,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22, - 0x31,0x2e,0x31,0x22,0x20,0x69,0x64,0x3d,0x22,0x45, - 0x62,0x65,0x6e,0x65,0x5f,0x31,0x22,0x20,0x78,0x6d, - 0x6c,0x6e,0x73,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a, - 0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f, - 0x72,0x67,0x2f,0x32,0x30,0x30,0x30,0x2f,0x73,0x76, - 0x67,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78, - 0x6c,0x69,0x6e,0x6b,0x3d,0x22,0x68,0x74,0x74,0x70, - 0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e, - 0x6f,0x72,0x67,0x2f,0x31,0x39,0x39,0x39,0x2f,0x78, - 0x6c,0x69,0x6e,0x6b,0x22,0x20,0x78,0x3d,0x22,0x30, - 0x70,0x78,0x22,0x20,0x79,0x3d,0x22,0x30,0x70,0x78, - 0x22,0x0d,0x0a,0x09,0x20,0x77,0x69,0x64,0x74,0x68, - 0x3d,0x22,0x31,0x32,0x38,0x30,0x70,0x78,0x22,0x20, - 0x68,0x65,0x69,0x67,0x68,0x74,0x3d,0x22,0x37,0x32, - 0x30,0x70,0x78,0x22,0x20,0x76,0x69,0x65,0x77,0x42, - 0x6f,0x78,0x3d,0x22,0x30,0x20,0x30,0x20,0x31,0x32, - 0x38,0x30,0x20,0x37,0x32,0x30,0x22,0x20,0x65,0x6e, - 0x61,0x62,0x6c,0x65,0x2d,0x62,0x61,0x63,0x6b,0x67, - 0x72,0x6f,0x75,0x6e,0x64,0x3d,0x22,0x6e,0x65,0x77, - 0x20,0x30,0x20,0x30,0x20,0x31,0x32,0x38,0x30,0x20, - 0x37,0x32,0x30,0x22,0x20,0x78,0x6d,0x6c,0x3a,0x73, - 0x70,0x61,0x63,0x65,0x3d,0x22,0x70,0x72,0x65,0x73, - 0x65,0x72,0x76,0x65,0x22,0x3e,0x0d,0x0a,0x3c,0x70, - 0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22, - 0x23,0x43,0x39,0x30,0x30,0x31,0x32,0x22,0x20,0x64, - 0x3d,0x22,0x4d,0x34,0x33,0x31,0x2e,0x35,0x32,0x39, - 0x2c,0x34,0x34,0x32,0x2e,0x30,0x39,0x37,0x4c,0x34, - 0x33,0x31,0x2e,0x35,0x32,0x39,0x2c,0x34,0x34,0x32, - 0x2e,0x30,0x39,0x37,0x4c,0x34,0x33,0x31,0x2e,0x35, - 0x32,0x39,0x2c,0x34,0x34,0x32,0x2e,0x30,0x39,0x37, - 0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x3c,0x70,0x61,0x74, - 0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x43, - 0x39,0x30,0x30,0x31,0x32,0x22,0x20,0x64,0x3d,0x22, - 0x4d,0x34,0x33,0x31,0x2e,0x35,0x32,0x39,0x2c,0x33, + 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0a,0x3c, + 0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72,0x61, + 0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62,0x65, + 0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61,0x74, + 0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x30,0x2c, + 0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f,0x72, + 0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e,0x20, + 0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72,0x73, + 0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30,0x20, + 0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20,0x20, + 0x2d,0x2d,0x3e,0x0a,0x3c,0x21,0x44,0x4f,0x43,0x54, + 0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20,0x50,0x55, + 0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f,0x2f,0x57, + 0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20,0x53,0x56, + 0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45,0x4e,0x22, + 0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73,0x2f,0x53, + 0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44,0x54,0x44, + 0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64,0x74,0x64, + 0x22,0x3e,0x0a,0x3c,0x73,0x76,0x67,0x20,0x76,0x65, + 0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x31, + 0x22,0x20,0x69,0x64,0x3d,0x22,0x45,0x62,0x65,0x6e, + 0x65,0x5f,0x31,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73, + 0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x32,0x30,0x30,0x30,0x2f,0x73,0x76,0x67,0x22,0x20, + 0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78,0x6c,0x69,0x6e, + 0x6b,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f, + 0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67, + 0x2f,0x31,0x39,0x39,0x39,0x2f,0x78,0x6c,0x69,0x6e, + 0x6b,0x22,0x20,0x78,0x3d,0x22,0x30,0x70,0x78,0x22, + 0x20,0x79,0x3d,0x22,0x30,0x70,0x78,0x22,0x0a,0x09, + 0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x31,0x32, + 0x38,0x30,0x70,0x78,0x22,0x20,0x68,0x65,0x69,0x67, + 0x68,0x74,0x3d,0x22,0x37,0x32,0x30,0x70,0x78,0x22, + 0x20,0x76,0x69,0x65,0x77,0x42,0x6f,0x78,0x3d,0x22, + 0x30,0x20,0x30,0x20,0x31,0x32,0x38,0x30,0x20,0x37, + 0x32,0x30,0x22,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65, + 0x2d,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e, + 0x64,0x3d,0x22,0x6e,0x65,0x77,0x20,0x30,0x20,0x30, + 0x20,0x31,0x32,0x38,0x30,0x20,0x37,0x32,0x30,0x22, + 0x20,0x78,0x6d,0x6c,0x3a,0x73,0x70,0x61,0x63,0x65, + 0x3d,0x22,0x70,0x72,0x65,0x73,0x65,0x72,0x76,0x65, + 0x22,0x3e,0x0a,0x3c,0x70,0x61,0x74,0x68,0x20,0x66, + 0x69,0x6c,0x6c,0x3d,0x22,0x23,0x43,0x39,0x30,0x30, + 0x31,0x32,0x22,0x20,0x64,0x3d,0x22,0x4d,0x34,0x33, + 0x31,0x2e,0x35,0x32,0x39,0x2c,0x34,0x34,0x32,0x2e, + 0x30,0x39,0x37,0x4c,0x34,0x33,0x31,0x2e,0x35,0x32, + 0x39,0x2c,0x34,0x34,0x32,0x2e,0x30,0x39,0x37,0x4c, + 0x34,0x33,0x31,0x2e,0x35,0x32,0x39,0x2c,0x34,0x34, + 0x32,0x2e,0x30,0x39,0x37,0x7a,0x22,0x2f,0x3e,0x0a, + 0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c, + 0x3d,0x22,0x23,0x43,0x39,0x30,0x30,0x31,0x32,0x22, + 0x20,0x64,0x3d,0x22,0x4d,0x34,0x33,0x31,0x2e,0x35, + 0x32,0x39,0x2c,0x33,0x35,0x39,0x2e,0x32,0x31,0x36, + 0x4c,0x34,0x33,0x31,0x2e,0x35,0x32,0x39,0x2c,0x33, 0x35,0x39,0x2e,0x32,0x31,0x36,0x4c,0x34,0x33,0x31, 0x2e,0x35,0x32,0x39,0x2c,0x33,0x35,0x39,0x2e,0x32, - 0x31,0x36,0x4c,0x34,0x33,0x31,0x2e,0x35,0x32,0x39, - 0x2c,0x33,0x35,0x39,0x2e,0x32,0x31,0x36,0x7a,0x22, - 0x2f,0x3e,0x0d,0x0a,0x3c,0x70,0x61,0x74,0x68,0x20, + 0x31,0x36,0x7a,0x22,0x2f,0x3e,0x0a,0x3c,0x70,0x61, + 0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23, + 0x43,0x39,0x30,0x30,0x31,0x32,0x22,0x20,0x64,0x3d, + 0x22,0x4d,0x34,0x33,0x31,0x2e,0x35,0x32,0x39,0x2c, + 0x32,0x37,0x36,0x2e,0x33,0x30,0x36,0x4c,0x34,0x33, + 0x31,0x2e,0x35,0x32,0x39,0x2c,0x32,0x37,0x36,0x2e, + 0x33,0x30,0x36,0x4c,0x34,0x33,0x31,0x2e,0x35,0x32, + 0x39,0x2c,0x32,0x37,0x36,0x2e,0x33,0x30,0x36,0x7a, + 0x22,0x2f,0x3e,0x0a,0x3c,0x70,0x61,0x74,0x68,0x20, 0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x43,0x39,0x30, 0x30,0x31,0x32,0x22,0x20,0x64,0x3d,0x22,0x4d,0x34, - 0x33,0x31,0x2e,0x35,0x32,0x39,0x2c,0x32,0x37,0x36, - 0x2e,0x33,0x30,0x36,0x4c,0x34,0x33,0x31,0x2e,0x35, - 0x32,0x39,0x2c,0x32,0x37,0x36,0x2e,0x33,0x30,0x36, - 0x4c,0x34,0x33,0x31,0x2e,0x35,0x32,0x39,0x2c,0x32, - 0x37,0x36,0x2e,0x33,0x30,0x36,0x7a,0x22,0x2f,0x3e, - 0x0d,0x0a,0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69, - 0x6c,0x6c,0x3d,0x22,0x23,0x43,0x39,0x30,0x30,0x31, - 0x32,0x22,0x20,0x64,0x3d,0x22,0x4d,0x34,0x33,0x31, - 0x2e,0x35,0x32,0x39,0x2c,0x33,0x31,0x37,0x2e,0x37, - 0x35,0x33,0x4c,0x34,0x33,0x31,0x2e,0x35,0x32,0x39, - 0x2c,0x33,0x31,0x37,0x2e,0x37,0x35,0x33,0x4c,0x34, 0x33,0x31,0x2e,0x35,0x32,0x39,0x2c,0x33,0x31,0x37, - 0x2e,0x37,0x35,0x33,0x7a,0x22,0x2f,0x3e,0x0d,0x0a, - 0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c, - 0x3d,0x22,0x23,0x43,0x39,0x30,0x30,0x31,0x32,0x22, - 0x20,0x64,0x3d,0x22,0x4d,0x34,0x33,0x31,0x2e,0x35, - 0x32,0x39,0x2c,0x34,0x38,0x33,0x2e,0x35,0x34,0x34, - 0x4c,0x34,0x33,0x31,0x2e,0x35,0x32,0x39,0x2c,0x34, - 0x38,0x33,0x2e,0x35,0x34,0x34,0x4c,0x34,0x33,0x31, - 0x2e,0x35,0x32,0x39,0x2c,0x34,0x38,0x33,0x2e,0x35, - 0x34,0x34,0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x3c,0x70, + 0x2e,0x37,0x35,0x33,0x4c,0x34,0x33,0x31,0x2e,0x35, + 0x32,0x39,0x2c,0x33,0x31,0x37,0x2e,0x37,0x35,0x33, + 0x4c,0x34,0x33,0x31,0x2e,0x35,0x32,0x39,0x2c,0x33, + 0x31,0x37,0x2e,0x37,0x35,0x33,0x7a,0x22,0x2f,0x3e, + 0x0a,0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69,0x6c, + 0x6c,0x3d,0x22,0x23,0x43,0x39,0x30,0x30,0x31,0x32, + 0x22,0x20,0x64,0x3d,0x22,0x4d,0x34,0x33,0x31,0x2e, + 0x35,0x32,0x39,0x2c,0x34,0x38,0x33,0x2e,0x35,0x34, + 0x34,0x4c,0x34,0x33,0x31,0x2e,0x35,0x32,0x39,0x2c, + 0x34,0x38,0x33,0x2e,0x35,0x34,0x34,0x4c,0x34,0x33, + 0x31,0x2e,0x35,0x32,0x39,0x2c,0x34,0x38,0x33,0x2e, + 0x35,0x34,0x34,0x7a,0x22,0x2f,0x3e,0x0a,0x3c,0x70, 0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22, 0x23,0x43,0x39,0x30,0x30,0x31,0x32,0x22,0x20,0x64, 0x3d,0x22,0x4d,0x34,0x33,0x31,0x2e,0x35,0x32,0x39, @@ -98,107 +97,106 @@ const unsigned char splash_svg_data[17935] = { 0x33,0x31,0x2e,0x35,0x32,0x39,0x2c,0x34,0x30,0x30, 0x2e,0x36,0x34,0x32,0x4c,0x34,0x33,0x31,0x2e,0x35, 0x32,0x39,0x2c,0x34,0x30,0x30,0x2e,0x36,0x34,0x32, - 0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x3c,0x70,0x61,0x74, - 0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x43, - 0x39,0x30,0x30,0x31,0x32,0x22,0x20,0x64,0x3d,0x22, - 0x4d,0x34,0x33,0x31,0x2e,0x35,0x32,0x39,0x2c,0x32, - 0x33,0x34,0x2e,0x38,0x34,0x32,0x4c,0x34,0x33,0x31, - 0x2e,0x35,0x32,0x39,0x2c,0x32,0x33,0x34,0x2e,0x38, - 0x34,0x32,0x4c,0x34,0x33,0x31,0x2e,0x35,0x32,0x39, - 0x2c,0x32,0x33,0x34,0x2e,0x38,0x34,0x32,0x7a,0x22, - 0x2f,0x3e,0x0d,0x0a,0x3c,0x70,0x61,0x74,0x68,0x20, - 0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x30,0x30,0x34, - 0x45,0x37,0x33,0x22,0x20,0x64,0x3d,0x22,0x4d,0x34, - 0x33,0x31,0x2e,0x35,0x32,0x39,0x2c,0x32,0x34,0x35, - 0x2e,0x39,0x35,0x31,0x63,0x30,0x2d,0x36,0x2e,0x31, - 0x31,0x2d,0x34,0x2e,0x39,0x39,0x39,0x2d,0x31,0x31, - 0x2e,0x31,0x30,0x38,0x2d,0x31,0x31,0x2e,0x31,0x30, - 0x35,0x2d,0x31,0x31,0x2e,0x31,0x30,0x38,0x48,0x36, - 0x39,0x2e,0x35,0x36,0x33,0x63,0x2d,0x36,0x2e,0x31, - 0x31,0x32,0x2c,0x30,0x2d,0x31,0x34,0x2e,0x36,0x34, - 0x34,0x2c,0x33,0x2e,0x35,0x33,0x34,0x2d,0x31,0x38, - 0x2e,0x39,0x36,0x33,0x2c,0x37,0x2e,0x38,0x35,0x35, - 0x0d,0x0a,0x09,0x6c,0x2d,0x32,0x35,0x2e,0x37,0x34, - 0x35,0x2c,0x32,0x35,0x2e,0x37,0x34,0x35,0x43,0x32, - 0x30,0x2e,0x35,0x33,0x33,0x2c,0x32,0x37,0x32,0x2e, - 0x37,0x36,0x34,0x2c,0x31,0x37,0x2c,0x32,0x38,0x31, - 0x2e,0x32,0x39,0x36,0x2c,0x31,0x37,0x2c,0x32,0x38, - 0x37,0x2e,0x34,0x30,0x36,0x76,0x32,0x32,0x36,0x2e, - 0x34,0x36,0x38,0x63,0x30,0x2c,0x36,0x2e,0x31,0x31, - 0x31,0x2c,0x34,0x2e,0x39,0x39,0x39,0x2c,0x31,0x31, - 0x2e,0x31,0x30,0x39,0x2c,0x31,0x31,0x2e,0x31,0x30, - 0x36,0x2c,0x31,0x31,0x2e,0x31,0x30,0x39,0x68,0x33, - 0x35,0x30,0x2e,0x38,0x36,0x0d,0x0a,0x09,0x63,0x36, - 0x2e,0x31,0x30,0x37,0x2c,0x30,0x2c,0x31,0x34,0x2e, - 0x36,0x34,0x33,0x2d,0x33,0x2e,0x35,0x33,0x35,0x2c, - 0x31,0x38,0x2e,0x39,0x36,0x33,0x2d,0x37,0x2e,0x38, - 0x35,0x34,0x6c,0x32,0x35,0x2e,0x37,0x34,0x31,0x2d, - 0x32,0x35,0x2e,0x37,0x33,0x36,0x63,0x34,0x2e,0x33, - 0x32,0x2d,0x34,0x2e,0x33,0x31,0x37,0x2c,0x37,0x2e, - 0x38,0x35,0x34,0x2d,0x31,0x32,0x2e,0x38,0x35,0x33, - 0x2c,0x37,0x2e,0x38,0x35,0x34,0x2d,0x31,0x38,0x2e, - 0x39,0x36,0x35,0x4c,0x34,0x33,0x31,0x2e,0x35,0x32, - 0x39,0x2c,0x32,0x34,0x35,0x2e,0x39,0x35,0x31,0x7a, - 0x22,0x2f,0x3e,0x0d,0x0a,0x3c,0x70,0x61,0x74,0x68, - 0x20,0x6f,0x70,0x61,0x63,0x69,0x74,0x79,0x3d,0x22, - 0x30,0x2e,0x32,0x22,0x20,0x65,0x6e,0x61,0x62,0x6c, - 0x65,0x2d,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75, - 0x6e,0x64,0x3d,0x22,0x6e,0x65,0x77,0x20,0x20,0x20, - 0x20,0x22,0x20,0x64,0x3d,0x22,0x4d,0x33,0x38,0x32, - 0x2e,0x32,0x32,0x2c,0x33,0x39,0x32,0x2e,0x37,0x38, - 0x39,0x6c,0x2d,0x32,0x35,0x2e,0x37,0x33,0x2d,0x32, - 0x35,0x2e,0x37,0x32,0x39,0x63,0x2d,0x34,0x2e,0x33, - 0x31,0x39,0x2d,0x34,0x2e,0x33,0x31,0x38,0x2d,0x31, - 0x32,0x2e,0x38,0x35,0x34,0x2d,0x37,0x2e,0x38,0x35, - 0x34,0x2d,0x31,0x38,0x2e,0x39,0x36,0x33,0x2d,0x37, - 0x2e,0x38,0x35,0x32,0x48,0x33,0x31,0x38,0x2e,0x32, - 0x38,0x0d,0x0a,0x09,0x63,0x2d,0x36,0x2e,0x31,0x31, - 0x32,0x2c,0x30,0x2e,0x30,0x30,0x31,0x2d,0x31,0x31, - 0x2e,0x31,0x31,0x2c,0x30,0x2e,0x30,0x30,0x31,0x2d, - 0x31,0x31,0x2e,0x31,0x31,0x2c,0x30,0x2e,0x30,0x30, - 0x31,0x73,0x33,0x2e,0x35,0x33,0x32,0x2d,0x33,0x2e, - 0x35,0x33,0x34,0x2c,0x37,0x2e,0x38,0x35,0x34,0x2d, - 0x37,0x2e,0x38,0x35,0x35,0x6c,0x36,0x37,0x2e,0x31, - 0x39,0x37,0x2d,0x36,0x37,0x2e,0x31,0x39,0x33,0x63, - 0x34,0x2e,0x33,0x32,0x2d,0x34,0x2e,0x33,0x32,0x31, - 0x2c,0x32,0x2e,0x38,0x35,0x34,0x2d,0x37,0x2e,0x38, - 0x35,0x35,0x2d,0x33,0x2e,0x32,0x35,0x33,0x2d,0x37, - 0x2e,0x38,0x35,0x35,0x48,0x32,0x37,0x36,0x2e,0x38, - 0x33,0x32,0x0d,0x0a,0x09,0x63,0x2d,0x36,0x2e,0x31, - 0x31,0x31,0x2c,0x30,0x2d,0x31,0x34,0x2e,0x36,0x34, - 0x33,0x2c,0x33,0x2e,0x35,0x33,0x34,0x2d,0x31,0x38, - 0x2e,0x39,0x36,0x33,0x2c,0x37,0x2e,0x38,0x35,0x35, - 0x4c,0x32,0x35,0x2e,0x31,0x34,0x32,0x2c,0x35,0x31, - 0x36,0x2e,0x38,0x36,0x63,0x2d,0x31,0x2e,0x38,0x32, - 0x35,0x2c,0x31,0x2e,0x38,0x32,0x32,0x2d,0x33,0x2e, - 0x35,0x31,0x37,0x2c,0x33,0x2e,0x35,0x31,0x34,0x2d, - 0x34,0x2e,0x38,0x37,0x31,0x2c,0x34,0x2e,0x38,0x36, - 0x37,0x63,0x32,0x2e,0x30,0x31,0x32,0x2c,0x32,0x2e, - 0x30,0x31,0x2c,0x34,0x2e,0x37,0x38,0x36,0x2c,0x33, - 0x2e,0x32,0x35,0x38,0x2c,0x37,0x2e,0x38,0x33,0x36, - 0x2c,0x33,0x2e,0x32,0x35,0x38,0x0d,0x0a,0x09,0x63, - 0x30,0x2e,0x30,0x30,0x35,0x2c,0x30,0x2c,0x30,0x2e, - 0x30,0x31,0x2c,0x30,0x2c,0x30,0x2e,0x30,0x31,0x36, - 0x2c,0x30,0x68,0x39,0x39,0x2e,0x39,0x35,0x33,0x68, - 0x31,0x36,0x37,0x2e,0x39,0x38,0x38,0x63,0x36,0x2e, - 0x31,0x31,0x31,0x2c,0x30,0x2c,0x31,0x31,0x2e,0x31, - 0x32,0x32,0x2d,0x30,0x2e,0x30,0x31,0x32,0x2c,0x31, - 0x31,0x2e,0x31,0x33,0x33,0x2d,0x30,0x2e,0x30,0x32, - 0x33,0x63,0x30,0x2e,0x30,0x31,0x35,0x2d,0x30,0x2e, - 0x30,0x31,0x36,0x2c,0x33,0x2e,0x35,0x35,0x39,0x2d, - 0x33,0x2e,0x35,0x36,0x32,0x2c,0x37,0x2e,0x38,0x38, - 0x2d,0x37,0x2e,0x38,0x38,0x6c,0x36,0x37,0x2e,0x31, - 0x34,0x34,0x2d,0x36,0x37,0x2e,0x31,0x33,0x32,0x0d, - 0x0a,0x09,0x63,0x34,0x2e,0x33,0x32,0x2d,0x34,0x2e, - 0x33,0x31,0x36,0x2c,0x37,0x2e,0x38,0x35,0x33,0x2d, - 0x31,0x32,0x2e,0x38,0x35,0x32,0x2c,0x37,0x2e,0x38, - 0x35,0x33,0x2d,0x31,0x38,0x2e,0x39,0x36,0x33,0x76, - 0x2d,0x31,0x39,0x2e,0x32,0x33,0x35,0x43,0x33,0x39, - 0x30,0x2e,0x30,0x37,0x33,0x2c,0x34,0x30,0x35,0x2e, - 0x36,0x34,0x2c,0x33,0x38,0x36,0x2e,0x35,0x34,0x2c, - 0x33,0x39,0x37,0x2e,0x31,0x30,0x34,0x2c,0x33,0x38, - 0x32,0x2e,0x32,0x32,0x2c,0x33,0x39,0x32,0x2e,0x37, - 0x38,0x39,0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x3c,0x70, + 0x7a,0x22,0x2f,0x3e,0x0a,0x3c,0x70,0x61,0x74,0x68, + 0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x43,0x39, + 0x30,0x30,0x31,0x32,0x22,0x20,0x64,0x3d,0x22,0x4d, + 0x34,0x33,0x31,0x2e,0x35,0x32,0x39,0x2c,0x32,0x33, + 0x34,0x2e,0x38,0x34,0x32,0x4c,0x34,0x33,0x31,0x2e, + 0x35,0x32,0x39,0x2c,0x32,0x33,0x34,0x2e,0x38,0x34, + 0x32,0x4c,0x34,0x33,0x31,0x2e,0x35,0x32,0x39,0x2c, + 0x32,0x33,0x34,0x2e,0x38,0x34,0x32,0x7a,0x22,0x2f, + 0x3e,0x0a,0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69, + 0x6c,0x6c,0x3d,0x22,0x23,0x30,0x30,0x34,0x45,0x37, + 0x33,0x22,0x20,0x64,0x3d,0x22,0x4d,0x34,0x33,0x31, + 0x2e,0x35,0x32,0x39,0x2c,0x32,0x34,0x35,0x2e,0x39, + 0x35,0x31,0x63,0x30,0x2d,0x36,0x2e,0x31,0x31,0x2d, + 0x34,0x2e,0x39,0x39,0x39,0x2d,0x31,0x31,0x2e,0x31, + 0x30,0x38,0x2d,0x31,0x31,0x2e,0x31,0x30,0x35,0x2d, + 0x31,0x31,0x2e,0x31,0x30,0x38,0x48,0x36,0x39,0x2e, + 0x35,0x36,0x33,0x63,0x2d,0x36,0x2e,0x31,0x31,0x32, + 0x2c,0x30,0x2d,0x31,0x34,0x2e,0x36,0x34,0x34,0x2c, + 0x33,0x2e,0x35,0x33,0x34,0x2d,0x31,0x38,0x2e,0x39, + 0x36,0x33,0x2c,0x37,0x2e,0x38,0x35,0x35,0x0a,0x09, + 0x6c,0x2d,0x32,0x35,0x2e,0x37,0x34,0x35,0x2c,0x32, + 0x35,0x2e,0x37,0x34,0x35,0x43,0x32,0x30,0x2e,0x35, + 0x33,0x33,0x2c,0x32,0x37,0x32,0x2e,0x37,0x36,0x34, + 0x2c,0x31,0x37,0x2c,0x32,0x38,0x31,0x2e,0x32,0x39, + 0x36,0x2c,0x31,0x37,0x2c,0x32,0x38,0x37,0x2e,0x34, + 0x30,0x36,0x76,0x32,0x32,0x36,0x2e,0x34,0x36,0x38, + 0x63,0x30,0x2c,0x36,0x2e,0x31,0x31,0x31,0x2c,0x34, + 0x2e,0x39,0x39,0x39,0x2c,0x31,0x31,0x2e,0x31,0x30, + 0x39,0x2c,0x31,0x31,0x2e,0x31,0x30,0x36,0x2c,0x31, + 0x31,0x2e,0x31,0x30,0x39,0x68,0x33,0x35,0x30,0x2e, + 0x38,0x36,0x0a,0x09,0x63,0x36,0x2e,0x31,0x30,0x37, + 0x2c,0x30,0x2c,0x31,0x34,0x2e,0x36,0x34,0x33,0x2d, + 0x33,0x2e,0x35,0x33,0x35,0x2c,0x31,0x38,0x2e,0x39, + 0x36,0x33,0x2d,0x37,0x2e,0x38,0x35,0x34,0x6c,0x32, + 0x35,0x2e,0x37,0x34,0x31,0x2d,0x32,0x35,0x2e,0x37, + 0x33,0x36,0x63,0x34,0x2e,0x33,0x32,0x2d,0x34,0x2e, + 0x33,0x31,0x37,0x2c,0x37,0x2e,0x38,0x35,0x34,0x2d, + 0x31,0x32,0x2e,0x38,0x35,0x33,0x2c,0x37,0x2e,0x38, + 0x35,0x34,0x2d,0x31,0x38,0x2e,0x39,0x36,0x35,0x4c, + 0x34,0x33,0x31,0x2e,0x35,0x32,0x39,0x2c,0x32,0x34, + 0x35,0x2e,0x39,0x35,0x31,0x7a,0x22,0x2f,0x3e,0x0a, + 0x3c,0x70,0x61,0x74,0x68,0x20,0x6f,0x70,0x61,0x63, + 0x69,0x74,0x79,0x3d,0x22,0x30,0x2e,0x32,0x22,0x20, + 0x65,0x6e,0x61,0x62,0x6c,0x65,0x2d,0x62,0x61,0x63, + 0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x3d,0x22,0x6e, + 0x65,0x77,0x20,0x20,0x20,0x20,0x22,0x20,0x64,0x3d, + 0x22,0x4d,0x33,0x38,0x32,0x2e,0x32,0x32,0x2c,0x33, + 0x39,0x32,0x2e,0x37,0x38,0x39,0x6c,0x2d,0x32,0x35, + 0x2e,0x37,0x33,0x2d,0x32,0x35,0x2e,0x37,0x32,0x39, + 0x63,0x2d,0x34,0x2e,0x33,0x31,0x39,0x2d,0x34,0x2e, + 0x33,0x31,0x38,0x2d,0x31,0x32,0x2e,0x38,0x35,0x34, + 0x2d,0x37,0x2e,0x38,0x35,0x34,0x2d,0x31,0x38,0x2e, + 0x39,0x36,0x33,0x2d,0x37,0x2e,0x38,0x35,0x32,0x48, + 0x33,0x31,0x38,0x2e,0x32,0x38,0x0a,0x09,0x63,0x2d, + 0x36,0x2e,0x31,0x31,0x32,0x2c,0x30,0x2e,0x30,0x30, + 0x31,0x2d,0x31,0x31,0x2e,0x31,0x31,0x2c,0x30,0x2e, + 0x30,0x30,0x31,0x2d,0x31,0x31,0x2e,0x31,0x31,0x2c, + 0x30,0x2e,0x30,0x30,0x31,0x73,0x33,0x2e,0x35,0x33, + 0x32,0x2d,0x33,0x2e,0x35,0x33,0x34,0x2c,0x37,0x2e, + 0x38,0x35,0x34,0x2d,0x37,0x2e,0x38,0x35,0x35,0x6c, + 0x36,0x37,0x2e,0x31,0x39,0x37,0x2d,0x36,0x37,0x2e, + 0x31,0x39,0x33,0x63,0x34,0x2e,0x33,0x32,0x2d,0x34, + 0x2e,0x33,0x32,0x31,0x2c,0x32,0x2e,0x38,0x35,0x34, + 0x2d,0x37,0x2e,0x38,0x35,0x35,0x2d,0x33,0x2e,0x32, + 0x35,0x33,0x2d,0x37,0x2e,0x38,0x35,0x35,0x48,0x32, + 0x37,0x36,0x2e,0x38,0x33,0x32,0x0a,0x09,0x63,0x2d, + 0x36,0x2e,0x31,0x31,0x31,0x2c,0x30,0x2d,0x31,0x34, + 0x2e,0x36,0x34,0x33,0x2c,0x33,0x2e,0x35,0x33,0x34, + 0x2d,0x31,0x38,0x2e,0x39,0x36,0x33,0x2c,0x37,0x2e, + 0x38,0x35,0x35,0x4c,0x32,0x35,0x2e,0x31,0x34,0x32, + 0x2c,0x35,0x31,0x36,0x2e,0x38,0x36,0x63,0x2d,0x31, + 0x2e,0x38,0x32,0x35,0x2c,0x31,0x2e,0x38,0x32,0x32, + 0x2d,0x33,0x2e,0x35,0x31,0x37,0x2c,0x33,0x2e,0x35, + 0x31,0x34,0x2d,0x34,0x2e,0x38,0x37,0x31,0x2c,0x34, + 0x2e,0x38,0x36,0x37,0x63,0x32,0x2e,0x30,0x31,0x32, + 0x2c,0x32,0x2e,0x30,0x31,0x2c,0x34,0x2e,0x37,0x38, + 0x36,0x2c,0x33,0x2e,0x32,0x35,0x38,0x2c,0x37,0x2e, + 0x38,0x33,0x36,0x2c,0x33,0x2e,0x32,0x35,0x38,0x0a, + 0x09,0x63,0x30,0x2e,0x30,0x30,0x35,0x2c,0x30,0x2c, + 0x30,0x2e,0x30,0x31,0x2c,0x30,0x2c,0x30,0x2e,0x30, + 0x31,0x36,0x2c,0x30,0x68,0x39,0x39,0x2e,0x39,0x35, + 0x33,0x68,0x31,0x36,0x37,0x2e,0x39,0x38,0x38,0x63, + 0x36,0x2e,0x31,0x31,0x31,0x2c,0x30,0x2c,0x31,0x31, + 0x2e,0x31,0x32,0x32,0x2d,0x30,0x2e,0x30,0x31,0x32, + 0x2c,0x31,0x31,0x2e,0x31,0x33,0x33,0x2d,0x30,0x2e, + 0x30,0x32,0x33,0x63,0x30,0x2e,0x30,0x31,0x35,0x2d, + 0x30,0x2e,0x30,0x31,0x36,0x2c,0x33,0x2e,0x35,0x35, + 0x39,0x2d,0x33,0x2e,0x35,0x36,0x32,0x2c,0x37,0x2e, + 0x38,0x38,0x2d,0x37,0x2e,0x38,0x38,0x6c,0x36,0x37, + 0x2e,0x31,0x34,0x34,0x2d,0x36,0x37,0x2e,0x31,0x33, + 0x32,0x0a,0x09,0x63,0x34,0x2e,0x33,0x32,0x2d,0x34, + 0x2e,0x33,0x31,0x36,0x2c,0x37,0x2e,0x38,0x35,0x33, + 0x2d,0x31,0x32,0x2e,0x38,0x35,0x32,0x2c,0x37,0x2e, + 0x38,0x35,0x33,0x2d,0x31,0x38,0x2e,0x39,0x36,0x33, + 0x76,0x2d,0x31,0x39,0x2e,0x32,0x33,0x35,0x43,0x33, + 0x39,0x30,0x2e,0x30,0x37,0x33,0x2c,0x34,0x30,0x35, + 0x2e,0x36,0x34,0x2c,0x33,0x38,0x36,0x2e,0x35,0x34, + 0x2c,0x33,0x39,0x37,0x2e,0x31,0x30,0x34,0x2c,0x33, + 0x38,0x32,0x2e,0x32,0x32,0x2c,0x33,0x39,0x32,0x2e, + 0x37,0x38,0x39,0x7a,0x22,0x2f,0x3e,0x0a,0x3c,0x70, 0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22, 0x23,0x46,0x46,0x46,0x46,0x46,0x46,0x22,0x20,0x64, 0x3d,0x22,0x4d,0x32,0x37,0x36,0x2e,0x38,0x32,0x34, @@ -211,90 +209,89 @@ const unsigned char splash_svg_data[17935] = { 0x33,0x32,0x31,0x2d,0x34,0x2e,0x33,0x32,0x31,0x2d, 0x37,0x2e,0x38,0x35,0x37,0x2d,0x31,0x32,0x2e,0x38, 0x35,0x35,0x2d,0x37,0x2e,0x38,0x36,0x35,0x2d,0x31, - 0x38,0x2e,0x39,0x36,0x36,0x0d,0x0a,0x09,0x6c,0x2d, - 0x30,0x2e,0x30,0x31,0x32,0x2d,0x31,0x39,0x2e,0x32, - 0x34,0x36,0x63,0x2d,0x30,0x2e,0x30,0x30,0x38,0x2d, - 0x36,0x2e,0x31,0x31,0x2c,0x33,0x2e,0x35,0x32,0x35, - 0x2d,0x31,0x34,0x2e,0x36,0x34,0x33,0x2c,0x37,0x2e, - 0x38,0x34,0x36,0x2d,0x31,0x38,0x2e,0x39,0x36,0x34, - 0x6c,0x32,0x35,0x2e,0x37,0x34,0x31,0x2d,0x32,0x35, - 0x2e,0x37,0x33,0x37,0x63,0x34,0x2e,0x33,0x32,0x31, - 0x2d,0x34,0x2e,0x33,0x32,0x31,0x2c,0x31,0x32,0x2e, - 0x38,0x35,0x32,0x2d,0x37,0x2e,0x38,0x35,0x35,0x2c, + 0x38,0x2e,0x39,0x36,0x36,0x0a,0x09,0x6c,0x2d,0x30, + 0x2e,0x30,0x31,0x32,0x2d,0x31,0x39,0x2e,0x32,0x34, + 0x36,0x63,0x2d,0x30,0x2e,0x30,0x30,0x38,0x2d,0x36, + 0x2e,0x31,0x31,0x2c,0x33,0x2e,0x35,0x32,0x35,0x2d, + 0x31,0x34,0x2e,0x36,0x34,0x33,0x2c,0x37,0x2e,0x38, + 0x34,0x36,0x2d,0x31,0x38,0x2e,0x39,0x36,0x34,0x6c, + 0x32,0x35,0x2e,0x37,0x34,0x31,0x2d,0x32,0x35,0x2e, + 0x37,0x33,0x37,0x63,0x34,0x2e,0x33,0x32,0x31,0x2d, + 0x34,0x2e,0x33,0x32,0x31,0x2c,0x31,0x32,0x2e,0x38, + 0x35,0x32,0x2d,0x37,0x2e,0x38,0x35,0x35,0x2c,0x31, + 0x38,0x2e,0x39,0x36,0x33,0x2d,0x37,0x2e,0x38,0x35, + 0x35,0x68,0x31,0x30,0x32,0x2e,0x31,0x34,0x0a,0x09, + 0x63,0x36,0x2e,0x31,0x30,0x37,0x2c,0x30,0x2c,0x37, + 0x2e,0x35,0x37,0x33,0x2c,0x33,0x2e,0x35,0x33,0x34, + 0x2c,0x33,0x2e,0x32,0x35,0x33,0x2c,0x37,0x2e,0x38, + 0x35,0x35,0x6c,0x2d,0x32,0x35,0x2e,0x37,0x34,0x31, + 0x2c,0x32,0x35,0x2e,0x37,0x33,0x37,0x63,0x2d,0x34, + 0x2e,0x33,0x32,0x31,0x2c,0x34,0x2e,0x33,0x32,0x31, + 0x2d,0x31,0x32,0x2e,0x38,0x35,0x32,0x2c,0x37,0x2e, + 0x38,0x35,0x35,0x2d,0x31,0x38,0x2e,0x39,0x36,0x33, + 0x2c,0x37,0x2e,0x38,0x35,0x35,0x68,0x2d,0x36,0x30, + 0x2e,0x36,0x38,0x38,0x0a,0x09,0x63,0x2d,0x36,0x2e, + 0x31,0x31,0x32,0x2c,0x30,0x2d,0x31,0x31,0x2e,0x31, + 0x31,0x2c,0x34,0x2e,0x39,0x39,0x38,0x2d,0x31,0x31, + 0x2e,0x31,0x31,0x2c,0x31,0x31,0x2e,0x31,0x30,0x38, + 0x76,0x31,0x39,0x2e,0x32,0x34,0x36,0x63,0x30,0x2c, + 0x36,0x2e,0x31,0x31,0x2c,0x34,0x2e,0x39,0x39,0x38, + 0x2c,0x31,0x31,0x2e,0x31,0x30,0x38,0x2c,0x31,0x31, + 0x2e,0x31,0x30,0x36,0x2c,0x31,0x31,0x2e,0x31,0x30, + 0x36,0x6c,0x36,0x30,0x2e,0x37,0x30,0x32,0x2d,0x30, + 0x2e,0x30,0x30,0x37,0x63,0x36,0x2e,0x31,0x30,0x38, + 0x2d,0x30,0x2e,0x30,0x30,0x32,0x2c,0x31,0x34,0x2e, + 0x36,0x34,0x34,0x2c,0x33,0x2e,0x35,0x33,0x33,0x2c, + 0x31,0x38,0x2e,0x39,0x36,0x33,0x2c,0x37,0x2e,0x38, + 0x35,0x32,0x0a,0x09,0x6c,0x32,0x35,0x2e,0x37,0x33, + 0x2c,0x32,0x35,0x2e,0x37,0x32,0x39,0x63,0x34,0x2e, + 0x33,0x32,0x2c,0x34,0x2e,0x33,0x31,0x35,0x2c,0x37, + 0x2e,0x38,0x35,0x33,0x2c,0x31,0x32,0x2e,0x38,0x35, + 0x31,0x2c,0x37,0x2e,0x38,0x35,0x33,0x2c,0x31,0x38, + 0x2e,0x39,0x36,0x33,0x76,0x31,0x39,0x2e,0x32,0x33, + 0x35,0x63,0x30,0x2c,0x36,0x2e,0x31,0x31,0x2d,0x33, + 0x2e,0x35,0x33,0x32,0x2c,0x31,0x34,0x2e,0x36,0x34, + 0x36,0x2d,0x37,0x2e,0x38,0x35,0x33,0x2c,0x31,0x38, + 0x2e,0x39,0x36,0x33,0x6c,0x2d,0x32,0x35,0x2e,0x37, + 0x34,0x31,0x2c,0x32,0x35,0x2e,0x37,0x34,0x0a,0x09, + 0x63,0x2d,0x34,0x2e,0x33,0x32,0x31,0x2c,0x34,0x2e, + 0x33,0x31,0x37,0x2d,0x31,0x32,0x2e,0x38,0x35,0x32, + 0x2c,0x37,0x2e,0x38,0x35,0x34,0x2d,0x31,0x38,0x2e, + 0x39,0x36,0x33,0x2c,0x37,0x2e,0x38,0x35,0x34,0x68, + 0x2d,0x36,0x30,0x2e,0x36,0x38,0x38,0x63,0x2d,0x36, + 0x2e,0x31,0x31,0x32,0x2c,0x30,0x2d,0x31,0x34,0x2e, + 0x36,0x34,0x33,0x2d,0x33,0x2e,0x35,0x33,0x36,0x2d, 0x31,0x38,0x2e,0x39,0x36,0x33,0x2d,0x37,0x2e,0x38, - 0x35,0x35,0x68,0x31,0x30,0x32,0x2e,0x31,0x34,0x0d, - 0x0a,0x09,0x63,0x36,0x2e,0x31,0x30,0x37,0x2c,0x30, - 0x2c,0x37,0x2e,0x35,0x37,0x33,0x2c,0x33,0x2e,0x35, - 0x33,0x34,0x2c,0x33,0x2e,0x32,0x35,0x33,0x2c,0x37, - 0x2e,0x38,0x35,0x35,0x6c,0x2d,0x32,0x35,0x2e,0x37, - 0x34,0x31,0x2c,0x32,0x35,0x2e,0x37,0x33,0x37,0x63, - 0x2d,0x34,0x2e,0x33,0x32,0x31,0x2c,0x34,0x2e,0x33, - 0x32,0x31,0x2d,0x31,0x32,0x2e,0x38,0x35,0x32,0x2c, - 0x37,0x2e,0x38,0x35,0x35,0x2d,0x31,0x38,0x2e,0x39, - 0x36,0x33,0x2c,0x37,0x2e,0x38,0x35,0x35,0x68,0x2d, - 0x36,0x30,0x2e,0x36,0x38,0x38,0x0d,0x0a,0x09,0x63, - 0x2d,0x36,0x2e,0x31,0x31,0x32,0x2c,0x30,0x2d,0x31, - 0x31,0x2e,0x31,0x31,0x2c,0x34,0x2e,0x39,0x39,0x38, - 0x2d,0x31,0x31,0x2e,0x31,0x31,0x2c,0x31,0x31,0x2e, - 0x31,0x30,0x38,0x76,0x31,0x39,0x2e,0x32,0x34,0x36, - 0x63,0x30,0x2c,0x36,0x2e,0x31,0x31,0x2c,0x34,0x2e, - 0x39,0x39,0x38,0x2c,0x31,0x31,0x2e,0x31,0x30,0x38, - 0x2c,0x31,0x31,0x2e,0x31,0x30,0x36,0x2c,0x31,0x31, - 0x2e,0x31,0x30,0x36,0x6c,0x36,0x30,0x2e,0x37,0x30, - 0x32,0x2d,0x30,0x2e,0x30,0x30,0x37,0x63,0x36,0x2e, - 0x31,0x30,0x38,0x2d,0x30,0x2e,0x30,0x30,0x32,0x2c, - 0x31,0x34,0x2e,0x36,0x34,0x34,0x2c,0x33,0x2e,0x35, - 0x33,0x33,0x2c,0x31,0x38,0x2e,0x39,0x36,0x33,0x2c, - 0x37,0x2e,0x38,0x35,0x32,0x0d,0x0a,0x09,0x6c,0x32, - 0x35,0x2e,0x37,0x33,0x2c,0x32,0x35,0x2e,0x37,0x32, - 0x39,0x63,0x34,0x2e,0x33,0x32,0x2c,0x34,0x2e,0x33, - 0x31,0x35,0x2c,0x37,0x2e,0x38,0x35,0x33,0x2c,0x31, - 0x32,0x2e,0x38,0x35,0x31,0x2c,0x37,0x2e,0x38,0x35, - 0x33,0x2c,0x31,0x38,0x2e,0x39,0x36,0x33,0x76,0x31, - 0x39,0x2e,0x32,0x33,0x35,0x63,0x30,0x2c,0x36,0x2e, - 0x31,0x31,0x2d,0x33,0x2e,0x35,0x33,0x32,0x2c,0x31, - 0x34,0x2e,0x36,0x34,0x36,0x2d,0x37,0x2e,0x38,0x35, - 0x33,0x2c,0x31,0x38,0x2e,0x39,0x36,0x33,0x6c,0x2d, - 0x32,0x35,0x2e,0x37,0x34,0x31,0x2c,0x32,0x35,0x2e, - 0x37,0x34,0x0d,0x0a,0x09,0x63,0x2d,0x34,0x2e,0x33, - 0x32,0x31,0x2c,0x34,0x2e,0x33,0x31,0x37,0x2d,0x31, - 0x32,0x2e,0x38,0x35,0x32,0x2c,0x37,0x2e,0x38,0x35, - 0x34,0x2d,0x31,0x38,0x2e,0x39,0x36,0x33,0x2c,0x37, - 0x2e,0x38,0x35,0x34,0x68,0x2d,0x36,0x30,0x2e,0x36, - 0x38,0x38,0x63,0x2d,0x36,0x2e,0x31,0x31,0x32,0x2c, - 0x30,0x2d,0x31,0x34,0x2e,0x36,0x34,0x33,0x2d,0x33, - 0x2e,0x35,0x33,0x36,0x2d,0x31,0x38,0x2e,0x39,0x36, - 0x33,0x2d,0x37,0x2e,0x38,0x35,0x34,0x6c,0x2d,0x32, - 0x35,0x2e,0x37,0x34,0x31,0x2d,0x32,0x35,0x2e,0x37, - 0x34,0x0d,0x0a,0x09,0x63,0x2d,0x34,0x2e,0x33,0x32, - 0x2d,0x34,0x2e,0x33,0x31,0x36,0x2d,0x32,0x2e,0x38, - 0x35,0x38,0x2d,0x37,0x2e,0x38,0x35,0x34,0x2c,0x33, - 0x2e,0x32,0x35,0x33,0x2d,0x37,0x2e,0x38,0x35,0x34, - 0x68,0x31,0x30,0x32,0x2e,0x31,0x34,0x63,0x36,0x2e, - 0x31,0x31,0x32,0x2c,0x30,0x2c,0x31,0x31,0x2e,0x31, - 0x31,0x2d,0x34,0x2e,0x39,0x39,0x38,0x2c,0x31,0x31, - 0x2e,0x31,0x31,0x2d,0x31,0x31,0x2e,0x31,0x30,0x39, - 0x56,0x34,0x31,0x31,0x2e,0x37,0x35,0x63,0x30,0x2d, - 0x36,0x2e,0x31,0x31,0x32,0x2c,0x30,0x2d,0x31,0x31, - 0x2e,0x31,0x31,0x2c,0x30,0x2e,0x30,0x30,0x33,0x2d, - 0x31,0x31,0x2e,0x31,0x31,0x0d,0x0a,0x09,0x63,0x30, - 0x2e,0x30,0x30,0x34,0x2c,0x30,0x2d,0x34,0x2e,0x39, - 0x39,0x34,0x2c,0x30,0x2d,0x31,0x31,0x2e,0x31,0x30, - 0x33,0x2c,0x30,0x4c,0x32,0x37,0x36,0x2e,0x38,0x32, - 0x34,0x2c,0x34,0x30,0x30,0x2e,0x36,0x34,0x39,0x7a, - 0x22,0x2f,0x3e,0x0d,0x0a,0x3c,0x67,0x20,0x6f,0x70, - 0x61,0x63,0x69,0x74,0x79,0x3d,0x22,0x30,0x2e,0x32, - 0x22,0x3e,0x0d,0x0a,0x09,0x3c,0x70,0x61,0x74,0x68, - 0x20,0x64,0x3d,0x22,0x4d,0x31,0x37,0x2e,0x30,0x30, - 0x38,0x2c,0x33,0x37,0x30,0x2e,0x38,0x37,0x37,0x63, - 0x30,0x2d,0x36,0x2e,0x31,0x31,0x2c,0x30,0x2d,0x31, - 0x31,0x2e,0x32,0x33,0x38,0x2c,0x30,0x2d,0x31,0x31, - 0x2e,0x33,0x39,0x33,0x63,0x30,0x2d,0x30,0x2e,0x31, - 0x35,0x35,0x2c,0x33,0x2e,0x35,0x33,0x32,0x2d,0x33, - 0x2e,0x38,0x31,0x38,0x2c,0x37,0x2e,0x38,0x35,0x34, - 0x2d,0x38,0x2e,0x31,0x33,0x38,0x6c,0x36,0x37,0x2e, - 0x31,0x38,0x35,0x2d,0x36,0x37,0x2e,0x31,0x38,0x36, - 0x0d,0x0a,0x09,0x09,0x63,0x34,0x2e,0x33,0x32,0x31, + 0x35,0x34,0x6c,0x2d,0x32,0x35,0x2e,0x37,0x34,0x31, + 0x2d,0x32,0x35,0x2e,0x37,0x34,0x0a,0x09,0x63,0x2d, + 0x34,0x2e,0x33,0x32,0x2d,0x34,0x2e,0x33,0x31,0x36, + 0x2d,0x32,0x2e,0x38,0x35,0x38,0x2d,0x37,0x2e,0x38, + 0x35,0x34,0x2c,0x33,0x2e,0x32,0x35,0x33,0x2d,0x37, + 0x2e,0x38,0x35,0x34,0x68,0x31,0x30,0x32,0x2e,0x31, + 0x34,0x63,0x36,0x2e,0x31,0x31,0x32,0x2c,0x30,0x2c, + 0x31,0x31,0x2e,0x31,0x31,0x2d,0x34,0x2e,0x39,0x39, + 0x38,0x2c,0x31,0x31,0x2e,0x31,0x31,0x2d,0x31,0x31, + 0x2e,0x31,0x30,0x39,0x56,0x34,0x31,0x31,0x2e,0x37, + 0x35,0x63,0x30,0x2d,0x36,0x2e,0x31,0x31,0x32,0x2c, + 0x30,0x2d,0x31,0x31,0x2e,0x31,0x31,0x2c,0x30,0x2e, + 0x30,0x30,0x33,0x2d,0x31,0x31,0x2e,0x31,0x31,0x0a, + 0x09,0x63,0x30,0x2e,0x30,0x30,0x34,0x2c,0x30,0x2d, + 0x34,0x2e,0x39,0x39,0x34,0x2c,0x30,0x2d,0x31,0x31, + 0x2e,0x31,0x30,0x33,0x2c,0x30,0x4c,0x32,0x37,0x36, + 0x2e,0x38,0x32,0x34,0x2c,0x34,0x30,0x30,0x2e,0x36, + 0x34,0x39,0x7a,0x22,0x2f,0x3e,0x0a,0x3c,0x67,0x20, + 0x6f,0x70,0x61,0x63,0x69,0x74,0x79,0x3d,0x22,0x30, + 0x2e,0x32,0x22,0x3e,0x0a,0x09,0x3c,0x70,0x61,0x74, + 0x68,0x20,0x64,0x3d,0x22,0x4d,0x31,0x37,0x2e,0x30, + 0x30,0x38,0x2c,0x33,0x37,0x30,0x2e,0x38,0x37,0x37, + 0x63,0x30,0x2d,0x36,0x2e,0x31,0x31,0x2c,0x30,0x2d, + 0x31,0x31,0x2e,0x32,0x33,0x38,0x2c,0x30,0x2d,0x31, + 0x31,0x2e,0x33,0x39,0x33,0x63,0x30,0x2d,0x30,0x2e, + 0x31,0x35,0x35,0x2c,0x33,0x2e,0x35,0x33,0x32,0x2d, + 0x33,0x2e,0x38,0x31,0x38,0x2c,0x37,0x2e,0x38,0x35, + 0x34,0x2d,0x38,0x2e,0x31,0x33,0x38,0x6c,0x36,0x37, + 0x2e,0x31,0x38,0x35,0x2d,0x36,0x37,0x2e,0x31,0x38, + 0x36,0x0a,0x09,0x09,0x63,0x34,0x2e,0x33,0x32,0x31, 0x2d,0x34,0x2e,0x33,0x32,0x31,0x2c,0x31,0x32,0x2e, 0x38,0x35,0x35,0x2d,0x37,0x2e,0x38,0x35,0x35,0x2c, 0x31,0x38,0x2e,0x39,0x36,0x33,0x2d,0x37,0x2e,0x38, @@ -303,98 +300,97 @@ const unsigned char splash_svg_data[17935] = { 0x35,0x37,0x34,0x2c,0x33,0x2e,0x35,0x33,0x34,0x2c, 0x33,0x2e,0x32,0x35,0x33,0x2c,0x37,0x2e,0x38,0x35, 0x35,0x6c,0x2d,0x36,0x37,0x2e,0x31,0x39,0x37,0x2c, - 0x36,0x37,0x2e,0x31,0x38,0x32,0x0d,0x0a,0x09,0x09, - 0x63,0x2d,0x34,0x2e,0x33,0x32,0x2c,0x34,0x2e,0x33, - 0x32,0x31,0x2d,0x37,0x2e,0x38,0x35,0x33,0x2c,0x37, - 0x2e,0x38,0x35,0x35,0x2d,0x37,0x2e,0x38,0x35,0x33, - 0x2c,0x37,0x2e,0x38,0x35,0x35,0x73,0x34,0x2e,0x39, - 0x39,0x38,0x2c,0x30,0x2e,0x30,0x30,0x32,0x2c,0x31, - 0x31,0x2e,0x31,0x31,0x2c,0x30,0x2e,0x30,0x30,0x36, - 0x6c,0x31,0x39,0x2e,0x32,0x32,0x38,0x2c,0x30,0x2e, - 0x30,0x30,0x37,0x63,0x36,0x2e,0x31,0x30,0x38,0x2c, - 0x30,0x2e,0x30,0x30,0x34,0x2c,0x31,0x30,0x2e,0x37, - 0x35,0x2c,0x34,0x2e,0x39,0x39,0x33,0x2c,0x31,0x30, - 0x2e,0x33,0x31,0x38,0x2c,0x31,0x31,0x2e,0x30,0x38, - 0x36,0x6c,0x2d,0x31,0x2e,0x31,0x31,0x34,0x2c,0x31, - 0x35,0x2e,0x35,0x39,0x32,0x0d,0x0a,0x09,0x09,0x63, - 0x2d,0x30,0x2e,0x34,0x33,0x33,0x2c,0x36,0x2e,0x30, - 0x39,0x32,0x2d,0x31,0x2e,0x37,0x30,0x37,0x2c,0x31, - 0x31,0x2e,0x39,0x39,0x38,0x2d,0x32,0x2e,0x38,0x33, - 0x33,0x2c,0x31,0x33,0x2e,0x31,0x32,0x33,0x63,0x2d, - 0x31,0x2e,0x31,0x32,0x35,0x2c,0x31,0x2e,0x31,0x32, - 0x35,0x2d,0x35,0x2e,0x35,0x37,0x36,0x2c,0x35,0x2e, - 0x35,0x38,0x2d,0x39,0x2e,0x38,0x39,0x36,0x2c,0x39, - 0x2e,0x38,0x39,0x36,0x6c,0x2d,0x32,0x35,0x2e,0x32, - 0x30,0x31,0x2c,0x32,0x35,0x2e,0x32,0x30,0x31,0x63, - 0x2d,0x34,0x2e,0x33,0x32,0x2c,0x34,0x2e,0x33,0x31, - 0x36,0x2d,0x37,0x2e,0x38,0x38,0x35,0x2c,0x37,0x2e, - 0x38,0x38,0x35,0x2d,0x37,0x2e,0x39,0x32,0x32,0x2c, - 0x37,0x2e,0x39,0x31,0x38,0x0d,0x0a,0x09,0x09,0x63, - 0x2d,0x30,0x2e,0x30,0x33,0x34,0x2c,0x30,0x2e,0x30, - 0x33,0x35,0x2c,0x34,0x2e,0x39,0x33,0x33,0x2c,0x30, - 0x2e,0x30,0x36,0x35,0x2c,0x31,0x31,0x2e,0x30,0x34, - 0x31,0x2c,0x30,0x2e,0x30,0x36,0x32,0x68,0x31,0x37, - 0x2e,0x39,0x37,0x39,0x63,0x36,0x2e,0x31,0x30,0x38, - 0x2d,0x30,0x2e,0x30,0x30,0x34,0x2c,0x31,0x34,0x2e, - 0x37,0x38,0x34,0x2c,0x33,0x2e,0x33,0x37,0x39,0x2c, - 0x31,0x39,0x2e,0x32,0x38,0x31,0x2c,0x37,0x2e,0x35, - 0x31,0x38,0x6c,0x32,0x36,0x2e,0x38,0x33,0x36,0x2c, - 0x32,0x34,0x2e,0x36,0x39,0x35,0x0d,0x0a,0x09,0x09, - 0x63,0x34,0x2e,0x34,0x39,0x37,0x2c,0x34,0x2e,0x31, - 0x33,0x37,0x2c,0x38,0x2e,0x31,0x38,0x31,0x2c,0x37, - 0x2e,0x36,0x32,0x33,0x2c,0x38,0x2e,0x30,0x35,0x38, - 0x2c,0x37,0x2e,0x37,0x35,0x63,0x2d,0x30,0x2e,0x31, - 0x32,0x36,0x2c,0x30,0x2e,0x31,0x32,0x36,0x2d,0x33, - 0x2e,0x37,0x36,0x36,0x2c,0x33,0x2e,0x37,0x36,0x32, - 0x2d,0x38,0x2e,0x30,0x38,0x37,0x2c,0x38,0x2e,0x30, - 0x38,0x33,0x6c,0x2d,0x33,0x34,0x2e,0x38,0x32,0x37, - 0x2c,0x33,0x34,0x2e,0x38,0x34,0x39,0x6c,0x2d,0x31, - 0x34,0x37,0x2e,0x32,0x31,0x32,0x2c,0x30,0x2e,0x30, - 0x30,0x32,0x0d,0x0a,0x09,0x09,0x63,0x2d,0x36,0x2e, - 0x31,0x30,0x37,0x2c,0x30,0x2d,0x31,0x31,0x2e,0x31, - 0x30,0x35,0x2d,0x34,0x2e,0x39,0x39,0x38,0x2d,0x31, - 0x31,0x2e,0x31,0x30,0x35,0x2d,0x31,0x31,0x2e,0x31, - 0x31,0x4c,0x31,0x37,0x2e,0x30,0x30,0x38,0x2c,0x33, - 0x37,0x30,0x2e,0x38,0x37,0x37,0x7a,0x22,0x2f,0x3e, - 0x0d,0x0a,0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x3c,0x70, - 0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22, - 0x23,0x46,0x46,0x46,0x46,0x46,0x46,0x22,0x20,0x64, - 0x3d,0x22,0x4d,0x31,0x31,0x31,0x2e,0x30,0x31,0x2c, - 0x34,0x34,0x32,0x2e,0x30,0x39,0x37,0x63,0x2d,0x36, - 0x2e,0x31,0x30,0x37,0x2c,0x30,0x2d,0x31,0x31,0x2e, - 0x31,0x30,0x35,0x2d,0x34,0x2e,0x39,0x39,0x38,0x2d, - 0x31,0x31,0x2e,0x31,0x30,0x35,0x2d,0x31,0x31,0x2e, - 0x31,0x30,0x39,0x76,0x2d,0x31,0x39,0x2e,0x32,0x33, - 0x35,0x63,0x30,0x2d,0x36,0x2e,0x31,0x31,0x32,0x2c, - 0x34,0x2e,0x39,0x39,0x38,0x2d,0x31,0x31,0x2e,0x31, - 0x31,0x2c,0x31,0x31,0x2e,0x31,0x30,0x35,0x2d,0x31, - 0x31,0x2e,0x31,0x31,0x68,0x36,0x30,0x2e,0x36,0x39, - 0x0d,0x0a,0x09,0x63,0x36,0x2e,0x31,0x30,0x38,0x2c, - 0x30,0x2c,0x31,0x31,0x2e,0x31,0x30,0x36,0x2d,0x34, - 0x2e,0x39,0x39,0x38,0x2c,0x31,0x31,0x2e,0x31,0x30, - 0x36,0x2d,0x31,0x31,0x2e,0x31,0x30,0x39,0x76,0x2d, - 0x31,0x39,0x2e,0x32,0x30,0x34,0x63,0x30,0x2d,0x36, - 0x2e,0x31,0x31,0x32,0x2d,0x34,0x2e,0x39,0x39,0x38, - 0x2d,0x31,0x31,0x2e,0x31,0x31,0x2d,0x31,0x31,0x2e, - 0x31,0x30,0x36,0x2d,0x31,0x31,0x2e,0x31,0x31,0x68, - 0x2d,0x36,0x30,0x2e,0x36,0x39,0x63,0x2d,0x36,0x2e, - 0x31,0x30,0x37,0x2c,0x30,0x2d,0x31,0x31,0x2e,0x31, - 0x30,0x35,0x2d,0x34,0x2e,0x39,0x39,0x38,0x2d,0x31, - 0x31,0x2e,0x31,0x30,0x35,0x2d,0x31,0x31,0x2e,0x31, - 0x30,0x38,0x76,0x2d,0x31,0x39,0x2e,0x32,0x34,0x36, - 0x0d,0x0a,0x09,0x63,0x30,0x2d,0x36,0x2e,0x31,0x31, - 0x2c,0x34,0x2e,0x39,0x39,0x38,0x2d,0x31,0x31,0x2e, - 0x31,0x30,0x38,0x2c,0x31,0x31,0x2e,0x31,0x30,0x35, - 0x2d,0x31,0x31,0x2e,0x31,0x30,0x38,0x68,0x36,0x30, - 0x2e,0x36,0x39,0x63,0x36,0x2e,0x31,0x30,0x38,0x2c, - 0x30,0x2c,0x31,0x34,0x2e,0x36,0x34,0x33,0x2d,0x33, - 0x2e,0x35,0x33,0x34,0x2c,0x31,0x38,0x2e,0x39,0x36, - 0x34,0x2d,0x37,0x2e,0x38,0x35,0x34,0x6c,0x32,0x35, - 0x2e,0x37,0x34,0x39,0x2d,0x32,0x35,0x2e,0x37,0x34, - 0x31,0x63,0x34,0x2e,0x33,0x32,0x31,0x2d,0x34,0x2e, - 0x33,0x31,0x39,0x2c,0x32,0x2e,0x38,0x35,0x35,0x2d, - 0x37,0x2e,0x38,0x35,0x33,0x2d,0x33,0x2e,0x32,0x35, - 0x33,0x2d,0x37,0x2e,0x38,0x35,0x33,0x0d,0x0a,0x09, + 0x36,0x37,0x2e,0x31,0x38,0x32,0x0a,0x09,0x09,0x63, + 0x2d,0x34,0x2e,0x33,0x32,0x2c,0x34,0x2e,0x33,0x32, + 0x31,0x2d,0x37,0x2e,0x38,0x35,0x33,0x2c,0x37,0x2e, + 0x38,0x35,0x35,0x2d,0x37,0x2e,0x38,0x35,0x33,0x2c, + 0x37,0x2e,0x38,0x35,0x35,0x73,0x34,0x2e,0x39,0x39, + 0x38,0x2c,0x30,0x2e,0x30,0x30,0x32,0x2c,0x31,0x31, + 0x2e,0x31,0x31,0x2c,0x30,0x2e,0x30,0x30,0x36,0x6c, + 0x31,0x39,0x2e,0x32,0x32,0x38,0x2c,0x30,0x2e,0x30, + 0x30,0x37,0x63,0x36,0x2e,0x31,0x30,0x38,0x2c,0x30, + 0x2e,0x30,0x30,0x34,0x2c,0x31,0x30,0x2e,0x37,0x35, + 0x2c,0x34,0x2e,0x39,0x39,0x33,0x2c,0x31,0x30,0x2e, + 0x33,0x31,0x38,0x2c,0x31,0x31,0x2e,0x30,0x38,0x36, + 0x6c,0x2d,0x31,0x2e,0x31,0x31,0x34,0x2c,0x31,0x35, + 0x2e,0x35,0x39,0x32,0x0a,0x09,0x09,0x63,0x2d,0x30, + 0x2e,0x34,0x33,0x33,0x2c,0x36,0x2e,0x30,0x39,0x32, + 0x2d,0x31,0x2e,0x37,0x30,0x37,0x2c,0x31,0x31,0x2e, + 0x39,0x39,0x38,0x2d,0x32,0x2e,0x38,0x33,0x33,0x2c, + 0x31,0x33,0x2e,0x31,0x32,0x33,0x63,0x2d,0x31,0x2e, + 0x31,0x32,0x35,0x2c,0x31,0x2e,0x31,0x32,0x35,0x2d, + 0x35,0x2e,0x35,0x37,0x36,0x2c,0x35,0x2e,0x35,0x38, + 0x2d,0x39,0x2e,0x38,0x39,0x36,0x2c,0x39,0x2e,0x38, + 0x39,0x36,0x6c,0x2d,0x32,0x35,0x2e,0x32,0x30,0x31, + 0x2c,0x32,0x35,0x2e,0x32,0x30,0x31,0x63,0x2d,0x34, + 0x2e,0x33,0x32,0x2c,0x34,0x2e,0x33,0x31,0x36,0x2d, + 0x37,0x2e,0x38,0x38,0x35,0x2c,0x37,0x2e,0x38,0x38, + 0x35,0x2d,0x37,0x2e,0x39,0x32,0x32,0x2c,0x37,0x2e, + 0x39,0x31,0x38,0x0a,0x09,0x09,0x63,0x2d,0x30,0x2e, + 0x30,0x33,0x34,0x2c,0x30,0x2e,0x30,0x33,0x35,0x2c, + 0x34,0x2e,0x39,0x33,0x33,0x2c,0x30,0x2e,0x30,0x36, + 0x35,0x2c,0x31,0x31,0x2e,0x30,0x34,0x31,0x2c,0x30, + 0x2e,0x30,0x36,0x32,0x68,0x31,0x37,0x2e,0x39,0x37, + 0x39,0x63,0x36,0x2e,0x31,0x30,0x38,0x2d,0x30,0x2e, + 0x30,0x30,0x34,0x2c,0x31,0x34,0x2e,0x37,0x38,0x34, + 0x2c,0x33,0x2e,0x33,0x37,0x39,0x2c,0x31,0x39,0x2e, + 0x32,0x38,0x31,0x2c,0x37,0x2e,0x35,0x31,0x38,0x6c, + 0x32,0x36,0x2e,0x38,0x33,0x36,0x2c,0x32,0x34,0x2e, + 0x36,0x39,0x35,0x0a,0x09,0x09,0x63,0x34,0x2e,0x34, + 0x39,0x37,0x2c,0x34,0x2e,0x31,0x33,0x37,0x2c,0x38, + 0x2e,0x31,0x38,0x31,0x2c,0x37,0x2e,0x36,0x32,0x33, + 0x2c,0x38,0x2e,0x30,0x35,0x38,0x2c,0x37,0x2e,0x37, + 0x35,0x63,0x2d,0x30,0x2e,0x31,0x32,0x36,0x2c,0x30, + 0x2e,0x31,0x32,0x36,0x2d,0x33,0x2e,0x37,0x36,0x36, + 0x2c,0x33,0x2e,0x37,0x36,0x32,0x2d,0x38,0x2e,0x30, + 0x38,0x37,0x2c,0x38,0x2e,0x30,0x38,0x33,0x6c,0x2d, + 0x33,0x34,0x2e,0x38,0x32,0x37,0x2c,0x33,0x34,0x2e, + 0x38,0x34,0x39,0x6c,0x2d,0x31,0x34,0x37,0x2e,0x32, + 0x31,0x32,0x2c,0x30,0x2e,0x30,0x30,0x32,0x0a,0x09, + 0x09,0x63,0x2d,0x36,0x2e,0x31,0x30,0x37,0x2c,0x30, + 0x2d,0x31,0x31,0x2e,0x31,0x30,0x35,0x2d,0x34,0x2e, + 0x39,0x39,0x38,0x2d,0x31,0x31,0x2e,0x31,0x30,0x35, + 0x2d,0x31,0x31,0x2e,0x31,0x31,0x4c,0x31,0x37,0x2e, + 0x30,0x30,0x38,0x2c,0x33,0x37,0x30,0x2e,0x38,0x37, + 0x37,0x7a,0x22,0x2f,0x3e,0x0a,0x3c,0x2f,0x67,0x3e, + 0x0a,0x3c,0x70,0x61,0x74,0x68,0x20,0x66,0x69,0x6c, + 0x6c,0x3d,0x22,0x23,0x46,0x46,0x46,0x46,0x46,0x46, + 0x22,0x20,0x64,0x3d,0x22,0x4d,0x31,0x31,0x31,0x2e, + 0x30,0x31,0x2c,0x34,0x34,0x32,0x2e,0x30,0x39,0x37, + 0x63,0x2d,0x36,0x2e,0x31,0x30,0x37,0x2c,0x30,0x2d, + 0x31,0x31,0x2e,0x31,0x30,0x35,0x2d,0x34,0x2e,0x39, + 0x39,0x38,0x2d,0x31,0x31,0x2e,0x31,0x30,0x35,0x2d, + 0x31,0x31,0x2e,0x31,0x30,0x39,0x76,0x2d,0x31,0x39, + 0x2e,0x32,0x33,0x35,0x63,0x30,0x2d,0x36,0x2e,0x31, + 0x31,0x32,0x2c,0x34,0x2e,0x39,0x39,0x38,0x2d,0x31, + 0x31,0x2e,0x31,0x31,0x2c,0x31,0x31,0x2e,0x31,0x30, + 0x35,0x2d,0x31,0x31,0x2e,0x31,0x31,0x68,0x36,0x30, + 0x2e,0x36,0x39,0x0a,0x09,0x63,0x36,0x2e,0x31,0x30, + 0x38,0x2c,0x30,0x2c,0x31,0x31,0x2e,0x31,0x30,0x36, + 0x2d,0x34,0x2e,0x39,0x39,0x38,0x2c,0x31,0x31,0x2e, + 0x31,0x30,0x36,0x2d,0x31,0x31,0x2e,0x31,0x30,0x39, + 0x76,0x2d,0x31,0x39,0x2e,0x32,0x30,0x34,0x63,0x30, + 0x2d,0x36,0x2e,0x31,0x31,0x32,0x2d,0x34,0x2e,0x39, + 0x39,0x38,0x2d,0x31,0x31,0x2e,0x31,0x31,0x2d,0x31, + 0x31,0x2e,0x31,0x30,0x36,0x2d,0x31,0x31,0x2e,0x31, + 0x31,0x68,0x2d,0x36,0x30,0x2e,0x36,0x39,0x63,0x2d, + 0x36,0x2e,0x31,0x30,0x37,0x2c,0x30,0x2d,0x31,0x31, + 0x2e,0x31,0x30,0x35,0x2d,0x34,0x2e,0x39,0x39,0x38, + 0x2d,0x31,0x31,0x2e,0x31,0x30,0x35,0x2d,0x31,0x31, + 0x2e,0x31,0x30,0x38,0x76,0x2d,0x31,0x39,0x2e,0x32, + 0x34,0x36,0x0a,0x09,0x63,0x30,0x2d,0x36,0x2e,0x31, + 0x31,0x2c,0x34,0x2e,0x39,0x39,0x38,0x2d,0x31,0x31, + 0x2e,0x31,0x30,0x38,0x2c,0x31,0x31,0x2e,0x31,0x30, + 0x35,0x2d,0x31,0x31,0x2e,0x31,0x30,0x38,0x68,0x36, + 0x30,0x2e,0x36,0x39,0x63,0x36,0x2e,0x31,0x30,0x38, + 0x2c,0x30,0x2c,0x31,0x34,0x2e,0x36,0x34,0x33,0x2d, + 0x33,0x2e,0x35,0x33,0x34,0x2c,0x31,0x38,0x2e,0x39, + 0x36,0x34,0x2d,0x37,0x2e,0x38,0x35,0x34,0x6c,0x32, + 0x35,0x2e,0x37,0x34,0x39,0x2d,0x32,0x35,0x2e,0x37, + 0x34,0x31,0x63,0x34,0x2e,0x33,0x32,0x31,0x2d,0x34, + 0x2e,0x33,0x31,0x39,0x2c,0x32,0x2e,0x38,0x35,0x35, + 0x2d,0x37,0x2e,0x38,0x35,0x33,0x2d,0x33,0x2e,0x32, + 0x35,0x33,0x2d,0x37,0x2e,0x38,0x35,0x33,0x0a,0x09, 0x48,0x31,0x31,0x31,0x2e,0x30,0x31,0x63,0x2d,0x36, 0x2e,0x31,0x30,0x37,0x2c,0x30,0x2d,0x31,0x34,0x2e, 0x36,0x34,0x33,0x2c,0x33,0x2e,0x35,0x33,0x34,0x2d, @@ -405,98 +401,97 @@ const unsigned char splash_svg_data[17935] = { 0x35,0x37,0x2c,0x31,0x32,0x2e,0x38,0x35,0x34,0x2d, 0x37,0x2e,0x38,0x35,0x37,0x2c,0x31,0x38,0x2e,0x39, 0x36,0x34,0x76,0x31,0x30,0x32,0x2e,0x31,0x32,0x35, - 0x0d,0x0a,0x09,0x63,0x30,0x2c,0x36,0x2e,0x31,0x31, - 0x31,0x2c,0x33,0x2e,0x35,0x33,0x37,0x2c,0x31,0x34, - 0x2e,0x36,0x34,0x36,0x2c,0x37,0x2e,0x38,0x35,0x37, - 0x2c,0x31,0x38,0x2e,0x39,0x36,0x33,0x6c,0x32,0x35, - 0x2e,0x37,0x33,0x37,0x2c,0x32,0x35,0x2e,0x37,0x34, - 0x63,0x34,0x2e,0x33,0x32,0x31,0x2c,0x34,0x2e,0x33, - 0x31,0x37,0x2c,0x31,0x32,0x2e,0x38,0x35,0x35,0x2c, - 0x37,0x2e,0x38,0x35,0x34,0x2c,0x31,0x38,0x2e,0x39, - 0x36,0x33,0x2c,0x37,0x2e,0x38,0x35,0x34,0x68,0x31, - 0x30,0x32,0x2e,0x31,0x34,0x33,0x63,0x36,0x2e,0x31, - 0x31,0x32,0x2c,0x30,0x2c,0x37,0x2e,0x35,0x37,0x34, - 0x2d,0x33,0x2e,0x35,0x33,0x36,0x2c,0x33,0x2e,0x32, - 0x35,0x33,0x2d,0x37,0x2e,0x38,0x35,0x36,0x0d,0x0a, - 0x09,0x6c,0x2d,0x32,0x35,0x2e,0x37,0x34,0x31,0x2d, - 0x32,0x35,0x2e,0x37,0x34,0x34,0x63,0x2d,0x34,0x2e, - 0x33,0x32,0x2d,0x34,0x2e,0x33,0x32,0x31,0x2d,0x31, - 0x32,0x2e,0x38,0x35,0x34,0x2d,0x37,0x2e,0x38,0x35, - 0x37,0x2d,0x31,0x38,0x2e,0x39,0x36,0x34,0x2d,0x37, - 0x2e,0x38,0x35,0x37,0x4c,0x31,0x31,0x31,0x2e,0x30, - 0x31,0x2c,0x34,0x34,0x32,0x2e,0x30,0x39,0x37,0x7a, - 0x22,0x2f,0x3e,0x0d,0x0a,0x3c,0x67,0x3e,0x0d,0x0a, - 0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x64,0x3d,0x22, - 0x4d,0x35,0x35,0x38,0x2e,0x36,0x30,0x35,0x2c,0x33, - 0x32,0x36,0x2e,0x35,0x36,0x32,0x63,0x2d,0x31,0x2e, - 0x36,0x32,0x33,0x2c,0x33,0x2e,0x38,0x2d,0x33,0x2e, - 0x38,0x35,0x2c,0x37,0x2e,0x31,0x31,0x35,0x2d,0x36, - 0x2e,0x36,0x38,0x32,0x2c,0x39,0x2e,0x39,0x34,0x33, - 0x63,0x2d,0x32,0x2e,0x38,0x33,0x32,0x2c,0x32,0x2e, - 0x38,0x33,0x36,0x2d,0x36,0x2e,0x31,0x34,0x36,0x2c, - 0x35,0x2e,0x30,0x36,0x2d,0x39,0x2e,0x39,0x34,0x37, - 0x2c,0x36,0x2e,0x36,0x38,0x32,0x0d,0x0a,0x09,0x09, - 0x63,0x2d,0x33,0x2e,0x37,0x39,0x36,0x2c,0x31,0x2e, - 0x36,0x32,0x33,0x2d,0x37,0x2e,0x38,0x33,0x38,0x2c, - 0x32,0x2e,0x34,0x33,0x34,0x2d,0x31,0x32,0x2e,0x31, - 0x31,0x37,0x2c,0x32,0x2e,0x34,0x33,0x34,0x68,0x2d, - 0x38,0x2e,0x34,0x39,0x36,0x63,0x2d,0x34,0x2e,0x32, - 0x38,0x33,0x2c,0x30,0x2d,0x38,0x2e,0x33,0x32,0x34, - 0x2d,0x30,0x2e,0x38,0x31,0x32,0x2d,0x31,0x32,0x2e, - 0x31,0x32,0x31,0x2d,0x32,0x2e,0x34,0x33,0x34,0x63, - 0x2d,0x33,0x2e,0x38,0x2d,0x31,0x2e,0x36,0x32,0x33, - 0x2d,0x37,0x2e,0x31,0x31,0x35,0x2d,0x33,0x2e,0x38, - 0x34,0x36,0x2d,0x39,0x2e,0x39,0x34,0x32,0x2d,0x36, - 0x2e,0x36,0x38,0x32,0x0d,0x0a,0x09,0x09,0x63,0x2d, - 0x32,0x2e,0x38,0x33,0x36,0x2d,0x32,0x2e,0x38,0x32, - 0x38,0x2d,0x35,0x2e,0x30,0x36,0x33,0x2d,0x36,0x2e, - 0x31,0x34,0x33,0x2d,0x36,0x2e,0x36,0x38,0x33,0x2d, - 0x39,0x2e,0x39,0x34,0x33,0x63,0x2d,0x31,0x2e,0x36, - 0x32,0x36,0x2d,0x33,0x2e,0x37,0x39,0x36,0x2d,0x32, - 0x2e,0x34,0x33,0x34,0x2d,0x37,0x2e,0x38,0x33,0x38, - 0x2d,0x32,0x2e,0x34,0x33,0x34,0x2d,0x31,0x32,0x2e, - 0x31,0x32,0x31,0x76,0x2d,0x34,0x37,0x2e,0x38,0x35, - 0x38,0x63,0x30,0x2d,0x34,0x2e,0x32,0x38,0x32,0x2c, - 0x30,0x2e,0x38,0x30,0x38,0x2d,0x38,0x2e,0x33,0x32, - 0x34,0x2c,0x32,0x2e,0x34,0x33,0x34,0x2d,0x31,0x32, - 0x2e,0x31,0x32,0x0d,0x0a,0x09,0x09,0x63,0x31,0x2e, - 0x36,0x31,0x39,0x2d,0x33,0x2e,0x38,0x30,0x31,0x2c, - 0x33,0x2e,0x38,0x34,0x37,0x2d,0x37,0x2e,0x31,0x31, - 0x35,0x2c,0x36,0x2e,0x36,0x38,0x33,0x2d,0x39,0x2e, - 0x39,0x34,0x37,0x63,0x32,0x2e,0x38,0x32,0x37,0x2d, - 0x32,0x2e,0x38,0x33,0x33,0x2c,0x36,0x2e,0x31,0x34, - 0x33,0x2d,0x35,0x2e,0x30,0x35,0x36,0x2c,0x39,0x2e, - 0x39,0x34,0x32,0x2d,0x36,0x2e,0x36,0x38,0x32,0x63, - 0x33,0x2e,0x37,0x39,0x36,0x2d,0x31,0x2e,0x36,0x31, - 0x39,0x2c,0x37,0x2e,0x38,0x33,0x38,0x2d,0x32,0x2e, - 0x34,0x33,0x34,0x2c,0x31,0x32,0x2e,0x31,0x32,0x31, - 0x2d,0x32,0x2e,0x34,0x33,0x34,0x68,0x38,0x2e,0x34, - 0x39,0x36,0x0d,0x0a,0x09,0x09,0x63,0x34,0x2e,0x32, - 0x37,0x39,0x2c,0x30,0x2c,0x38,0x2e,0x33,0x32,0x2c, - 0x30,0x2e,0x38,0x31,0x35,0x2c,0x31,0x32,0x2e,0x31, - 0x31,0x37,0x2c,0x32,0x2e,0x34,0x33,0x34,0x63,0x33, - 0x2e,0x38,0x2c,0x31,0x2e,0x36,0x32,0x36,0x2c,0x37, - 0x2e,0x31,0x31,0x35,0x2c,0x33,0x2e,0x38,0x35,0x2c, - 0x39,0x2e,0x39,0x34,0x37,0x2c,0x36,0x2e,0x36,0x38, - 0x32,0x73,0x35,0x2e,0x30,0x36,0x2c,0x36,0x2e,0x31, - 0x34,0x36,0x2c,0x36,0x2e,0x36,0x38,0x32,0x2c,0x39, - 0x2e,0x39,0x34,0x37,0x63,0x31,0x2e,0x36,0x32,0x33, - 0x2c,0x33,0x2e,0x37,0x39,0x36,0x2c,0x32,0x2e,0x34, - 0x33,0x34,0x2c,0x37,0x2e,0x38,0x33,0x38,0x2c,0x32, - 0x2e,0x34,0x33,0x34,0x2c,0x31,0x32,0x2e,0x31,0x32, - 0x0d,0x0a,0x09,0x09,0x76,0x32,0x34,0x2e,0x39,0x36, - 0x34,0x68,0x2d,0x35,0x38,0x2e,0x31,0x31,0x34,0x76, - 0x32,0x33,0x2e,0x36,0x31,0x38,0x63,0x30,0x2c,0x32, - 0x2e,0x35,0x35,0x36,0x2c,0x30,0x2e,0x34,0x38,0x31, - 0x2c,0x34,0x2e,0x39,0x35,0x36,0x2c,0x31,0x2e,0x34, - 0x35,0x2c,0x37,0x2e,0x32,0x30,0x32,0x63,0x30,0x2e, - 0x39,0x36,0x35,0x2c,0x32,0x2e,0x32,0x34,0x33,0x2c, - 0x32,0x2e,0x32,0x37,0x37,0x2c,0x34,0x2e,0x31,0x39, - 0x35,0x2c,0x33,0x2e,0x39,0x33,0x35,0x2c,0x35,0x2e, - 0x38,0x35,0x32,0x63,0x31,0x2e,0x36,0x36,0x31,0x2c, - 0x31,0x2e,0x36,0x35,0x37,0x2c,0x33,0x2e,0x36,0x30, - 0x39,0x2c,0x32,0x2e,0x39,0x37,0x2c,0x35,0x2e,0x38, - 0x35,0x35,0x2c,0x33,0x2e,0x39,0x33,0x38,0x0d,0x0a, + 0x0a,0x09,0x63,0x30,0x2c,0x36,0x2e,0x31,0x31,0x31, + 0x2c,0x33,0x2e,0x35,0x33,0x37,0x2c,0x31,0x34,0x2e, + 0x36,0x34,0x36,0x2c,0x37,0x2e,0x38,0x35,0x37,0x2c, + 0x31,0x38,0x2e,0x39,0x36,0x33,0x6c,0x32,0x35,0x2e, + 0x37,0x33,0x37,0x2c,0x32,0x35,0x2e,0x37,0x34,0x63, + 0x34,0x2e,0x33,0x32,0x31,0x2c,0x34,0x2e,0x33,0x31, + 0x37,0x2c,0x31,0x32,0x2e,0x38,0x35,0x35,0x2c,0x37, + 0x2e,0x38,0x35,0x34,0x2c,0x31,0x38,0x2e,0x39,0x36, + 0x33,0x2c,0x37,0x2e,0x38,0x35,0x34,0x68,0x31,0x30, + 0x32,0x2e,0x31,0x34,0x33,0x63,0x36,0x2e,0x31,0x31, + 0x32,0x2c,0x30,0x2c,0x37,0x2e,0x35,0x37,0x34,0x2d, + 0x33,0x2e,0x35,0x33,0x36,0x2c,0x33,0x2e,0x32,0x35, + 0x33,0x2d,0x37,0x2e,0x38,0x35,0x36,0x0a,0x09,0x6c, + 0x2d,0x32,0x35,0x2e,0x37,0x34,0x31,0x2d,0x32,0x35, + 0x2e,0x37,0x34,0x34,0x63,0x2d,0x34,0x2e,0x33,0x32, + 0x2d,0x34,0x2e,0x33,0x32,0x31,0x2d,0x31,0x32,0x2e, + 0x38,0x35,0x34,0x2d,0x37,0x2e,0x38,0x35,0x37,0x2d, + 0x31,0x38,0x2e,0x39,0x36,0x34,0x2d,0x37,0x2e,0x38, + 0x35,0x37,0x4c,0x31,0x31,0x31,0x2e,0x30,0x31,0x2c, + 0x34,0x34,0x32,0x2e,0x30,0x39,0x37,0x7a,0x22,0x2f, + 0x3e,0x0a,0x3c,0x67,0x3e,0x0a,0x09,0x3c,0x70,0x61, + 0x74,0x68,0x20,0x64,0x3d,0x22,0x4d,0x35,0x35,0x38, + 0x2e,0x36,0x30,0x35,0x2c,0x33,0x32,0x36,0x2e,0x35, + 0x36,0x32,0x63,0x2d,0x31,0x2e,0x36,0x32,0x33,0x2c, + 0x33,0x2e,0x38,0x2d,0x33,0x2e,0x38,0x35,0x2c,0x37, + 0x2e,0x31,0x31,0x35,0x2d,0x36,0x2e,0x36,0x38,0x32, + 0x2c,0x39,0x2e,0x39,0x34,0x33,0x63,0x2d,0x32,0x2e, + 0x38,0x33,0x32,0x2c,0x32,0x2e,0x38,0x33,0x36,0x2d, + 0x36,0x2e,0x31,0x34,0x36,0x2c,0x35,0x2e,0x30,0x36, + 0x2d,0x39,0x2e,0x39,0x34,0x37,0x2c,0x36,0x2e,0x36, + 0x38,0x32,0x0a,0x09,0x09,0x63,0x2d,0x33,0x2e,0x37, + 0x39,0x36,0x2c,0x31,0x2e,0x36,0x32,0x33,0x2d,0x37, + 0x2e,0x38,0x33,0x38,0x2c,0x32,0x2e,0x34,0x33,0x34, + 0x2d,0x31,0x32,0x2e,0x31,0x31,0x37,0x2c,0x32,0x2e, + 0x34,0x33,0x34,0x68,0x2d,0x38,0x2e,0x34,0x39,0x36, + 0x63,0x2d,0x34,0x2e,0x32,0x38,0x33,0x2c,0x30,0x2d, + 0x38,0x2e,0x33,0x32,0x34,0x2d,0x30,0x2e,0x38,0x31, + 0x32,0x2d,0x31,0x32,0x2e,0x31,0x32,0x31,0x2d,0x32, + 0x2e,0x34,0x33,0x34,0x63,0x2d,0x33,0x2e,0x38,0x2d, + 0x31,0x2e,0x36,0x32,0x33,0x2d,0x37,0x2e,0x31,0x31, + 0x35,0x2d,0x33,0x2e,0x38,0x34,0x36,0x2d,0x39,0x2e, + 0x39,0x34,0x32,0x2d,0x36,0x2e,0x36,0x38,0x32,0x0a, + 0x09,0x09,0x63,0x2d,0x32,0x2e,0x38,0x33,0x36,0x2d, + 0x32,0x2e,0x38,0x32,0x38,0x2d,0x35,0x2e,0x30,0x36, + 0x33,0x2d,0x36,0x2e,0x31,0x34,0x33,0x2d,0x36,0x2e, + 0x36,0x38,0x33,0x2d,0x39,0x2e,0x39,0x34,0x33,0x63, + 0x2d,0x31,0x2e,0x36,0x32,0x36,0x2d,0x33,0x2e,0x37, + 0x39,0x36,0x2d,0x32,0x2e,0x34,0x33,0x34,0x2d,0x37, + 0x2e,0x38,0x33,0x38,0x2d,0x32,0x2e,0x34,0x33,0x34, + 0x2d,0x31,0x32,0x2e,0x31,0x32,0x31,0x76,0x2d,0x34, + 0x37,0x2e,0x38,0x35,0x38,0x63,0x30,0x2d,0x34,0x2e, + 0x32,0x38,0x32,0x2c,0x30,0x2e,0x38,0x30,0x38,0x2d, + 0x38,0x2e,0x33,0x32,0x34,0x2c,0x32,0x2e,0x34,0x33, + 0x34,0x2d,0x31,0x32,0x2e,0x31,0x32,0x0a,0x09,0x09, + 0x63,0x31,0x2e,0x36,0x31,0x39,0x2d,0x33,0x2e,0x38, + 0x30,0x31,0x2c,0x33,0x2e,0x38,0x34,0x37,0x2d,0x37, + 0x2e,0x31,0x31,0x35,0x2c,0x36,0x2e,0x36,0x38,0x33, + 0x2d,0x39,0x2e,0x39,0x34,0x37,0x63,0x32,0x2e,0x38, + 0x32,0x37,0x2d,0x32,0x2e,0x38,0x33,0x33,0x2c,0x36, + 0x2e,0x31,0x34,0x33,0x2d,0x35,0x2e,0x30,0x35,0x36, + 0x2c,0x39,0x2e,0x39,0x34,0x32,0x2d,0x36,0x2e,0x36, + 0x38,0x32,0x63,0x33,0x2e,0x37,0x39,0x36,0x2d,0x31, + 0x2e,0x36,0x31,0x39,0x2c,0x37,0x2e,0x38,0x33,0x38, + 0x2d,0x32,0x2e,0x34,0x33,0x34,0x2c,0x31,0x32,0x2e, + 0x31,0x32,0x31,0x2d,0x32,0x2e,0x34,0x33,0x34,0x68, + 0x38,0x2e,0x34,0x39,0x36,0x0a,0x09,0x09,0x63,0x34, + 0x2e,0x32,0x37,0x39,0x2c,0x30,0x2c,0x38,0x2e,0x33, + 0x32,0x2c,0x30,0x2e,0x38,0x31,0x35,0x2c,0x31,0x32, + 0x2e,0x31,0x31,0x37,0x2c,0x32,0x2e,0x34,0x33,0x34, + 0x63,0x33,0x2e,0x38,0x2c,0x31,0x2e,0x36,0x32,0x36, + 0x2c,0x37,0x2e,0x31,0x31,0x35,0x2c,0x33,0x2e,0x38, + 0x35,0x2c,0x39,0x2e,0x39,0x34,0x37,0x2c,0x36,0x2e, + 0x36,0x38,0x32,0x73,0x35,0x2e,0x30,0x36,0x2c,0x36, + 0x2e,0x31,0x34,0x36,0x2c,0x36,0x2e,0x36,0x38,0x32, + 0x2c,0x39,0x2e,0x39,0x34,0x37,0x63,0x31,0x2e,0x36, + 0x32,0x33,0x2c,0x33,0x2e,0x37,0x39,0x36,0x2c,0x32, + 0x2e,0x34,0x33,0x34,0x2c,0x37,0x2e,0x38,0x33,0x38, + 0x2c,0x32,0x2e,0x34,0x33,0x34,0x2c,0x31,0x32,0x2e, + 0x31,0x32,0x0a,0x09,0x09,0x76,0x32,0x34,0x2e,0x39, + 0x36,0x34,0x68,0x2d,0x35,0x38,0x2e,0x31,0x31,0x34, + 0x76,0x32,0x33,0x2e,0x36,0x31,0x38,0x63,0x30,0x2c, + 0x32,0x2e,0x35,0x35,0x36,0x2c,0x30,0x2e,0x34,0x38, + 0x31,0x2c,0x34,0x2e,0x39,0x35,0x36,0x2c,0x31,0x2e, + 0x34,0x35,0x2c,0x37,0x2e,0x32,0x30,0x32,0x63,0x30, + 0x2e,0x39,0x36,0x35,0x2c,0x32,0x2e,0x32,0x34,0x33, + 0x2c,0x32,0x2e,0x32,0x37,0x37,0x2c,0x34,0x2e,0x31, + 0x39,0x35,0x2c,0x33,0x2e,0x39,0x33,0x35,0x2c,0x35, + 0x2e,0x38,0x35,0x32,0x63,0x31,0x2e,0x36,0x36,0x31, + 0x2c,0x31,0x2e,0x36,0x35,0x37,0x2c,0x33,0x2e,0x36, + 0x30,0x39,0x2c,0x32,0x2e,0x39,0x37,0x2c,0x35,0x2e, + 0x38,0x35,0x35,0x2c,0x33,0x2e,0x39,0x33,0x38,0x0a, 0x09,0x09,0x63,0x32,0x2e,0x32,0x34,0x33,0x2c,0x30, 0x2e,0x39,0x36,0x34,0x2c,0x34,0x2e,0x36,0x34,0x33, 0x2c,0x31,0x2e,0x34,0x34,0x37,0x2c,0x37,0x2e,0x31, @@ -508,105 +503,104 @@ const unsigned char splash_svg_data[17935] = { 0x34,0x33,0x2d,0x30,0x2e,0x39,0x36,0x38,0x2c,0x34, 0x2e,0x31,0x39,0x35,0x2d,0x32,0x2e,0x32,0x38,0x31, 0x2c,0x35,0x2e,0x38,0x35,0x32,0x2d,0x33,0x2e,0x39, - 0x33,0x38,0x0d,0x0a,0x09,0x09,0x63,0x31,0x2e,0x36, - 0x35,0x37,0x2d,0x31,0x2e,0x36,0x35,0x37,0x2c,0x32, - 0x2e,0x39,0x37,0x31,0x2d,0x33,0x2e,0x36,0x30,0x39, - 0x2c,0x33,0x2e,0x39,0x33,0x38,0x2d,0x35,0x2e,0x38, - 0x35,0x32,0x63,0x30,0x2e,0x39,0x36,0x34,0x2d,0x32, - 0x2e,0x32,0x34,0x36,0x2c,0x31,0x2e,0x34,0x35,0x31, - 0x2d,0x34,0x2e,0x36,0x34,0x36,0x2c,0x31,0x2e,0x34, - 0x35,0x31,0x2d,0x37,0x2e,0x32,0x30,0x32,0x76,0x2d, - 0x37,0x2e,0x30,0x34,0x32,0x6c,0x31,0x32,0x2e,0x37, - 0x33,0x39,0x2c,0x32,0x2e,0x30,0x37,0x76,0x34,0x2e, - 0x32,0x34,0x38,0x0d,0x0a,0x09,0x09,0x43,0x35,0x36, - 0x31,0x2e,0x30,0x33,0x38,0x2c,0x33,0x31,0x38,0x2e, - 0x37,0x32,0x34,0x2c,0x35,0x36,0x30,0x2e,0x32,0x32, - 0x38,0x2c,0x33,0x32,0x32,0x2e,0x37,0x36,0x35,0x2c, - 0x35,0x35,0x38,0x2e,0x36,0x30,0x35,0x2c,0x33,0x32, - 0x36,0x2e,0x35,0x36,0x32,0x7a,0x20,0x4d,0x35,0x34, - 0x38,0x2e,0x32,0x39,0x39,0x2c,0x32,0x36,0x35,0x2e, - 0x38,0x35,0x35,0x63,0x30,0x2d,0x32,0x2e,0x35,0x35, - 0x33,0x2d,0x30,0x2e,0x34,0x38,0x36,0x2d,0x34,0x2e, - 0x39,0x35,0x32,0x2d,0x31,0x2e,0x34,0x35,0x31,0x2d, - 0x37,0x2e,0x31,0x39,0x39,0x0d,0x0a,0x09,0x09,0x63, - 0x2d,0x30,0x2e,0x39,0x36,0x38,0x2d,0x32,0x2e,0x32, - 0x34,0x33,0x2d,0x32,0x2e,0x32,0x38,0x31,0x2d,0x34, - 0x2e,0x31,0x39,0x34,0x2d,0x33,0x2e,0x39,0x33,0x38, - 0x2d,0x35,0x2e,0x38,0x35,0x32,0x63,0x2d,0x31,0x2e, - 0x36,0x35,0x36,0x2d,0x31,0x2e,0x36,0x35,0x38,0x2d, - 0x33,0x2e,0x36,0x30,0x38,0x2d,0x32,0x2e,0x39,0x37, - 0x2d,0x35,0x2e,0x38,0x35,0x32,0x2d,0x33,0x2e,0x39, - 0x33,0x38,0x63,0x2d,0x32,0x2e,0x32,0x34,0x37,0x2d, - 0x30,0x2e,0x39,0x36,0x34,0x2d,0x34,0x2e,0x36,0x34, - 0x36,0x2d,0x31,0x2e,0x34,0x35,0x2d,0x37,0x2e,0x31, - 0x39,0x39,0x2d,0x31,0x2e,0x34,0x35,0x68,0x2d,0x38, - 0x2e,0x34,0x39,0x36,0x0d,0x0a,0x09,0x09,0x63,0x2d, - 0x32,0x2e,0x35,0x35,0x37,0x2c,0x30,0x2d,0x34,0x2e, - 0x39,0x35,0x36,0x2c,0x30,0x2e,0x34,0x38,0x36,0x2d, - 0x37,0x2e,0x31,0x39,0x39,0x2c,0x31,0x2e,0x34,0x35, - 0x63,0x2d,0x32,0x2e,0x32,0x34,0x36,0x2c,0x30,0x2e, - 0x39,0x36,0x39,0x2d,0x34,0x2e,0x31,0x39,0x34,0x2c, - 0x32,0x2e,0x32,0x38,0x31,0x2d,0x35,0x2e,0x38,0x35, - 0x35,0x2c,0x33,0x2e,0x39,0x33,0x38,0x63,0x2d,0x31, - 0x2e,0x36,0x35,0x37,0x2c,0x31,0x2e,0x36,0x35,0x37, - 0x2d,0x32,0x2e,0x39,0x37,0x2c,0x33,0x2e,0x36,0x30, - 0x39,0x2d,0x33,0x2e,0x39,0x33,0x34,0x2c,0x35,0x2e, - 0x38,0x35,0x32,0x0d,0x0a,0x09,0x09,0x63,0x2d,0x30, - 0x2e,0x39,0x36,0x39,0x2c,0x32,0x2e,0x32,0x34,0x37, - 0x2d,0x31,0x2e,0x34,0x35,0x31,0x2c,0x34,0x2e,0x36, - 0x34,0x36,0x2d,0x31,0x2e,0x34,0x35,0x31,0x2c,0x37, - 0x2e,0x31,0x39,0x39,0x56,0x32,0x38,0x31,0x2e,0x36, - 0x68,0x34,0x35,0x2e,0x33,0x37,0x35,0x4c,0x35,0x34, - 0x38,0x2e,0x32,0x39,0x39,0x2c,0x32,0x36,0x35,0x2e, - 0x38,0x35,0x35,0x4c,0x35,0x34,0x38,0x2e,0x32,0x39, - 0x39,0x2c,0x32,0x36,0x35,0x2e,0x38,0x35,0x35,0x7a, - 0x22,0x2f,0x3e,0x0d,0x0a,0x09,0x3c,0x70,0x61,0x74, - 0x68,0x20,0x64,0x3d,0x22,0x4d,0x36,0x39,0x38,0x2e, - 0x35,0x30,0x36,0x2c,0x33,0x34,0x33,0x2e,0x35,0x35, - 0x76,0x2d,0x37,0x37,0x2e,0x36,0x39,0x35,0x63,0x30, - 0x2d,0x32,0x2e,0x35,0x35,0x33,0x2d,0x30,0x2e,0x34, - 0x38,0x32,0x2d,0x34,0x2e,0x39,0x35,0x32,0x2d,0x31, - 0x2e,0x34,0x35,0x2d,0x37,0x2e,0x31,0x39,0x39,0x63, - 0x2d,0x30,0x2e,0x39,0x36,0x39,0x2d,0x32,0x2e,0x32, - 0x34,0x33,0x2d,0x32,0x2e,0x32,0x37,0x37,0x2d,0x34, - 0x2e,0x31,0x39,0x34,0x2d,0x33,0x2e,0x39,0x33,0x38, - 0x2d,0x35,0x2e,0x38,0x35,0x32,0x0d,0x0a,0x09,0x09, - 0x63,0x2d,0x31,0x2e,0x36,0x35,0x32,0x2d,0x31,0x2e, - 0x36,0x35,0x37,0x2d,0x33,0x2e,0x36,0x30,0x38,0x2d, - 0x32,0x2e,0x39,0x37,0x2d,0x35,0x2e,0x38,0x35,0x32, - 0x2d,0x33,0x2e,0x39,0x33,0x38,0x63,0x2d,0x32,0x2e, - 0x32,0x34,0x37,0x2d,0x30,0x2e,0x39,0x36,0x34,0x2d, - 0x34,0x2e,0x36,0x34,0x36,0x2d,0x31,0x2e,0x34,0x35, - 0x2d,0x37,0x2e,0x31,0x39,0x39,0x2d,0x31,0x2e,0x34, - 0x35,0x68,0x2d,0x36,0x2e,0x33,0x31,0x37,0x63,0x2d, - 0x32,0x2e,0x35,0x35,0x38,0x2c,0x30,0x2d,0x34,0x2e, - 0x39,0x35,0x36,0x2c,0x30,0x2e,0x34,0x38,0x36,0x2d, - 0x37,0x2e,0x32,0x30,0x32,0x2c,0x31,0x2e,0x34,0x35, - 0x0d,0x0a,0x09,0x09,0x63,0x2d,0x32,0x2e,0x32,0x34, - 0x33,0x2c,0x30,0x2e,0x39,0x36,0x39,0x2d,0x34,0x2e, - 0x32,0x31,0x2c,0x32,0x2e,0x32,0x38,0x31,0x2d,0x35, - 0x2e,0x39,0x30,0x32,0x2c,0x33,0x2e,0x39,0x33,0x38, - 0x63,0x2d,0x31,0x2e,0x36,0x39,0x35,0x2c,0x31,0x2e, - 0x36,0x35,0x37,0x2d,0x33,0x2e,0x30,0x32,0x33,0x2c, - 0x33,0x2e,0x36,0x30,0x39,0x2d,0x33,0x2e,0x39,0x39, - 0x31,0x2c,0x35,0x2e,0x38,0x35,0x32,0x63,0x2d,0x30, - 0x2e,0x39,0x36,0x35,0x2c,0x32,0x2e,0x32,0x34,0x37, - 0x2d,0x31,0x2e,0x34,0x34,0x35,0x2c,0x34,0x2e,0x36, - 0x34,0x36,0x2d,0x31,0x2e,0x34,0x34,0x35,0x2c,0x37, - 0x2e,0x31,0x39,0x39,0x76,0x37,0x37,0x2e,0x36,0x39, - 0x35,0x68,0x2d,0x31,0x32,0x2e,0x36,0x34,0x33,0x0d, - 0x0a,0x09,0x09,0x76,0x2d,0x37,0x37,0x2e,0x36,0x39, + 0x33,0x38,0x0a,0x09,0x09,0x63,0x31,0x2e,0x36,0x35, + 0x37,0x2d,0x31,0x2e,0x36,0x35,0x37,0x2c,0x32,0x2e, + 0x39,0x37,0x31,0x2d,0x33,0x2e,0x36,0x30,0x39,0x2c, + 0x33,0x2e,0x39,0x33,0x38,0x2d,0x35,0x2e,0x38,0x35, + 0x32,0x63,0x30,0x2e,0x39,0x36,0x34,0x2d,0x32,0x2e, + 0x32,0x34,0x36,0x2c,0x31,0x2e,0x34,0x35,0x31,0x2d, + 0x34,0x2e,0x36,0x34,0x36,0x2c,0x31,0x2e,0x34,0x35, + 0x31,0x2d,0x37,0x2e,0x32,0x30,0x32,0x76,0x2d,0x37, + 0x2e,0x30,0x34,0x32,0x6c,0x31,0x32,0x2e,0x37,0x33, + 0x39,0x2c,0x32,0x2e,0x30,0x37,0x76,0x34,0x2e,0x32, + 0x34,0x38,0x0a,0x09,0x09,0x43,0x35,0x36,0x31,0x2e, + 0x30,0x33,0x38,0x2c,0x33,0x31,0x38,0x2e,0x37,0x32, + 0x34,0x2c,0x35,0x36,0x30,0x2e,0x32,0x32,0x38,0x2c, + 0x33,0x32,0x32,0x2e,0x37,0x36,0x35,0x2c,0x35,0x35, + 0x38,0x2e,0x36,0x30,0x35,0x2c,0x33,0x32,0x36,0x2e, + 0x35,0x36,0x32,0x7a,0x20,0x4d,0x35,0x34,0x38,0x2e, + 0x32,0x39,0x39,0x2c,0x32,0x36,0x35,0x2e,0x38,0x35, 0x35,0x63,0x30,0x2d,0x32,0x2e,0x35,0x35,0x33,0x2d, - 0x30,0x2e,0x34,0x38,0x32,0x2d,0x34,0x2e,0x39,0x35, - 0x32,0x2d,0x31,0x2e,0x34,0x35,0x2d,0x37,0x2e,0x31, - 0x39,0x39,0x63,0x2d,0x30,0x2e,0x39,0x36,0x38,0x2d, - 0x32,0x2e,0x32,0x34,0x33,0x2d,0x32,0x2e,0x32,0x39, - 0x36,0x2d,0x34,0x2e,0x31,0x39,0x34,0x2d,0x33,0x2e, - 0x39,0x38,0x37,0x2d,0x35,0x2e,0x38,0x35,0x32,0x63, - 0x2d,0x31,0x2e,0x36,0x39,0x31,0x2d,0x31,0x2e,0x36, - 0x35,0x37,0x2d,0x33,0x2e,0x36,0x35,0x38,0x2d,0x32, - 0x2e,0x39,0x37,0x2d,0x35,0x2e,0x39,0x30,0x35,0x2d, - 0x33,0x2e,0x39,0x33,0x38,0x0d,0x0a,0x09,0x09,0x63, + 0x30,0x2e,0x34,0x38,0x36,0x2d,0x34,0x2e,0x39,0x35, + 0x32,0x2d,0x31,0x2e,0x34,0x35,0x31,0x2d,0x37,0x2e, + 0x31,0x39,0x39,0x0a,0x09,0x09,0x63,0x2d,0x30,0x2e, + 0x39,0x36,0x38,0x2d,0x32,0x2e,0x32,0x34,0x33,0x2d, + 0x32,0x2e,0x32,0x38,0x31,0x2d,0x34,0x2e,0x31,0x39, + 0x34,0x2d,0x33,0x2e,0x39,0x33,0x38,0x2d,0x35,0x2e, + 0x38,0x35,0x32,0x63,0x2d,0x31,0x2e,0x36,0x35,0x36, + 0x2d,0x31,0x2e,0x36,0x35,0x38,0x2d,0x33,0x2e,0x36, + 0x30,0x38,0x2d,0x32,0x2e,0x39,0x37,0x2d,0x35,0x2e, + 0x38,0x35,0x32,0x2d,0x33,0x2e,0x39,0x33,0x38,0x63, + 0x2d,0x32,0x2e,0x32,0x34,0x37,0x2d,0x30,0x2e,0x39, + 0x36,0x34,0x2d,0x34,0x2e,0x36,0x34,0x36,0x2d,0x31, + 0x2e,0x34,0x35,0x2d,0x37,0x2e,0x31,0x39,0x39,0x2d, + 0x31,0x2e,0x34,0x35,0x68,0x2d,0x38,0x2e,0x34,0x39, + 0x36,0x0a,0x09,0x09,0x63,0x2d,0x32,0x2e,0x35,0x35, + 0x37,0x2c,0x30,0x2d,0x34,0x2e,0x39,0x35,0x36,0x2c, + 0x30,0x2e,0x34,0x38,0x36,0x2d,0x37,0x2e,0x31,0x39, + 0x39,0x2c,0x31,0x2e,0x34,0x35,0x63,0x2d,0x32,0x2e, + 0x32,0x34,0x36,0x2c,0x30,0x2e,0x39,0x36,0x39,0x2d, + 0x34,0x2e,0x31,0x39,0x34,0x2c,0x32,0x2e,0x32,0x38, + 0x31,0x2d,0x35,0x2e,0x38,0x35,0x35,0x2c,0x33,0x2e, + 0x39,0x33,0x38,0x63,0x2d,0x31,0x2e,0x36,0x35,0x37, + 0x2c,0x31,0x2e,0x36,0x35,0x37,0x2d,0x32,0x2e,0x39, + 0x37,0x2c,0x33,0x2e,0x36,0x30,0x39,0x2d,0x33,0x2e, + 0x39,0x33,0x34,0x2c,0x35,0x2e,0x38,0x35,0x32,0x0a, + 0x09,0x09,0x63,0x2d,0x30,0x2e,0x39,0x36,0x39,0x2c, + 0x32,0x2e,0x32,0x34,0x37,0x2d,0x31,0x2e,0x34,0x35, + 0x31,0x2c,0x34,0x2e,0x36,0x34,0x36,0x2d,0x31,0x2e, + 0x34,0x35,0x31,0x2c,0x37,0x2e,0x31,0x39,0x39,0x56, + 0x32,0x38,0x31,0x2e,0x36,0x68,0x34,0x35,0x2e,0x33, + 0x37,0x35,0x4c,0x35,0x34,0x38,0x2e,0x32,0x39,0x39, + 0x2c,0x32,0x36,0x35,0x2e,0x38,0x35,0x35,0x4c,0x35, + 0x34,0x38,0x2e,0x32,0x39,0x39,0x2c,0x32,0x36,0x35, + 0x2e,0x38,0x35,0x35,0x7a,0x22,0x2f,0x3e,0x0a,0x09, + 0x3c,0x70,0x61,0x74,0x68,0x20,0x64,0x3d,0x22,0x4d, + 0x36,0x39,0x38,0x2e,0x35,0x30,0x36,0x2c,0x33,0x34, + 0x33,0x2e,0x35,0x35,0x76,0x2d,0x37,0x37,0x2e,0x36, + 0x39,0x35,0x63,0x30,0x2d,0x32,0x2e,0x35,0x35,0x33, + 0x2d,0x30,0x2e,0x34,0x38,0x32,0x2d,0x34,0x2e,0x39, + 0x35,0x32,0x2d,0x31,0x2e,0x34,0x35,0x2d,0x37,0x2e, + 0x31,0x39,0x39,0x63,0x2d,0x30,0x2e,0x39,0x36,0x39, + 0x2d,0x32,0x2e,0x32,0x34,0x33,0x2d,0x32,0x2e,0x32, + 0x37,0x37,0x2d,0x34,0x2e,0x31,0x39,0x34,0x2d,0x33, + 0x2e,0x39,0x33,0x38,0x2d,0x35,0x2e,0x38,0x35,0x32, + 0x0a,0x09,0x09,0x63,0x2d,0x31,0x2e,0x36,0x35,0x32, + 0x2d,0x31,0x2e,0x36,0x35,0x37,0x2d,0x33,0x2e,0x36, + 0x30,0x38,0x2d,0x32,0x2e,0x39,0x37,0x2d,0x35,0x2e, + 0x38,0x35,0x32,0x2d,0x33,0x2e,0x39,0x33,0x38,0x63, + 0x2d,0x32,0x2e,0x32,0x34,0x37,0x2d,0x30,0x2e,0x39, + 0x36,0x34,0x2d,0x34,0x2e,0x36,0x34,0x36,0x2d,0x31, + 0x2e,0x34,0x35,0x2d,0x37,0x2e,0x31,0x39,0x39,0x2d, + 0x31,0x2e,0x34,0x35,0x68,0x2d,0x36,0x2e,0x33,0x31, + 0x37,0x63,0x2d,0x32,0x2e,0x35,0x35,0x38,0x2c,0x30, + 0x2d,0x34,0x2e,0x39,0x35,0x36,0x2c,0x30,0x2e,0x34, + 0x38,0x36,0x2d,0x37,0x2e,0x32,0x30,0x32,0x2c,0x31, + 0x2e,0x34,0x35,0x0a,0x09,0x09,0x63,0x2d,0x32,0x2e, + 0x32,0x34,0x33,0x2c,0x30,0x2e,0x39,0x36,0x39,0x2d, + 0x34,0x2e,0x32,0x31,0x2c,0x32,0x2e,0x32,0x38,0x31, + 0x2d,0x35,0x2e,0x39,0x30,0x32,0x2c,0x33,0x2e,0x39, + 0x33,0x38,0x63,0x2d,0x31,0x2e,0x36,0x39,0x35,0x2c, + 0x31,0x2e,0x36,0x35,0x37,0x2d,0x33,0x2e,0x30,0x32, + 0x33,0x2c,0x33,0x2e,0x36,0x30,0x39,0x2d,0x33,0x2e, + 0x39,0x39,0x31,0x2c,0x35,0x2e,0x38,0x35,0x32,0x63, + 0x2d,0x30,0x2e,0x39,0x36,0x35,0x2c,0x32,0x2e,0x32, + 0x34,0x37,0x2d,0x31,0x2e,0x34,0x34,0x35,0x2c,0x34, + 0x2e,0x36,0x34,0x36,0x2d,0x31,0x2e,0x34,0x34,0x35, + 0x2c,0x37,0x2e,0x31,0x39,0x39,0x76,0x37,0x37,0x2e, + 0x36,0x39,0x35,0x68,0x2d,0x31,0x32,0x2e,0x36,0x34, + 0x33,0x0a,0x09,0x09,0x76,0x2d,0x37,0x37,0x2e,0x36, + 0x39,0x35,0x63,0x30,0x2d,0x32,0x2e,0x35,0x35,0x33, + 0x2d,0x30,0x2e,0x34,0x38,0x32,0x2d,0x34,0x2e,0x39, + 0x35,0x32,0x2d,0x31,0x2e,0x34,0x35,0x2d,0x37,0x2e, + 0x31,0x39,0x39,0x63,0x2d,0x30,0x2e,0x39,0x36,0x38, + 0x2d,0x32,0x2e,0x32,0x34,0x33,0x2d,0x32,0x2e,0x32, + 0x39,0x36,0x2d,0x34,0x2e,0x31,0x39,0x34,0x2d,0x33, + 0x2e,0x39,0x38,0x37,0x2d,0x35,0x2e,0x38,0x35,0x32, + 0x63,0x2d,0x31,0x2e,0x36,0x39,0x31,0x2d,0x31,0x2e, + 0x36,0x35,0x37,0x2d,0x33,0x2e,0x36,0x35,0x38,0x2d, + 0x32,0x2e,0x39,0x37,0x2d,0x35,0x2e,0x39,0x30,0x35, + 0x2d,0x33,0x2e,0x39,0x33,0x38,0x0a,0x09,0x09,0x63, 0x2d,0x32,0x2e,0x32,0x34,0x32,0x2d,0x30,0x2e,0x39, 0x36,0x34,0x2d,0x34,0x2e,0x36,0x34,0x33,0x2d,0x31, 0x2e,0x34,0x35,0x2d,0x37,0x2e,0x31,0x39,0x39,0x2d, @@ -618,99 +612,98 @@ const unsigned char splash_svg_data[17935] = { 0x2c,0x30,0x2e,0x39,0x36,0x39,0x2d,0x34,0x2e,0x31, 0x39,0x35,0x2c,0x32,0x2e,0x32,0x38,0x31,0x2d,0x35, 0x2e,0x38,0x35,0x35,0x2c,0x33,0x2e,0x39,0x33,0x38, - 0x0d,0x0a,0x09,0x09,0x63,0x2d,0x31,0x2e,0x36,0x35, - 0x37,0x2c,0x31,0x2e,0x36,0x35,0x37,0x2d,0x32,0x2e, - 0x39,0x37,0x2c,0x33,0x2e,0x36,0x30,0x39,0x2d,0x33, - 0x2e,0x39,0x33,0x35,0x2c,0x35,0x2e,0x38,0x35,0x32, - 0x63,0x2d,0x30,0x2e,0x39,0x36,0x38,0x2c,0x32,0x2e, - 0x32,0x34,0x37,0x2d,0x31,0x2e,0x34,0x35,0x2c,0x34, - 0x2e,0x36,0x34,0x36,0x2d,0x31,0x2e,0x34,0x35,0x2c, - 0x37,0x2e,0x31,0x39,0x39,0x76,0x37,0x37,0x2e,0x36, - 0x39,0x35,0x68,0x2d,0x31,0x32,0x2e,0x37,0x34,0x31, - 0x56,0x32,0x33,0x37,0x2e,0x34,0x37,0x34,0x68,0x34, - 0x2e,0x32,0x34,0x34,0x6c,0x36,0x2e,0x39,0x34,0x33, - 0x2c,0x31,0x30,0x2e,0x37,0x37,0x33,0x0d,0x0a,0x09, - 0x09,0x63,0x32,0x2e,0x38,0x39,0x39,0x2d,0x33,0x2e, - 0x39,0x33,0x38,0x2c,0x36,0x2e,0x35,0x34,0x2d,0x37, - 0x2e,0x30,0x36,0x31,0x2c,0x31,0x30,0x2e,0x39,0x33, - 0x2d,0x39,0x2e,0x33,0x37,0x36,0x63,0x34,0x2e,0x33, - 0x38,0x32,0x2d,0x32,0x2e,0x33,0x31,0x32,0x2c,0x39, - 0x2e,0x31,0x36,0x36,0x2d,0x33,0x2e,0x34,0x37,0x31, - 0x2c,0x31,0x34,0x2e,0x33,0x34,0x34,0x2d,0x33,0x2e, - 0x34,0x37,0x31,0x68,0x31,0x2e,0x30,0x33,0x37,0x63, - 0x36,0x2e,0x30,0x30,0x39,0x2c,0x30,0x2c,0x31,0x31, - 0x2e,0x34,0x32,0x38,0x2c,0x31,0x2e,0x34,0x38,0x35, - 0x2c,0x31,0x36,0x2e,0x32,0x36,0x36,0x2c,0x34,0x2e, - 0x34,0x35,0x35,0x0d,0x0a,0x09,0x09,0x63,0x34,0x2e, - 0x38,0x33,0x33,0x2c,0x32,0x2e,0x39,0x37,0x2c,0x38, - 0x2e,0x35,0x36,0x32,0x2c,0x36,0x2e,0x39,0x30,0x38, - 0x2c,0x31,0x31,0x2e,0x31,0x38,0x37,0x2c,0x31,0x31, - 0x2e,0x38,0x31,0x31,0x63,0x31,0x2e,0x33,0x31,0x32, - 0x2d,0x32,0x2e,0x34,0x31,0x39,0x2c,0x32,0x2e,0x39, - 0x33,0x36,0x2d,0x34,0x2e,0x36,0x32,0x37,0x2c,0x34, - 0x2e,0x38,0x36,0x39,0x2d,0x36,0x2e,0x36,0x32,0x39, - 0x63,0x31,0x2e,0x39,0x33,0x33,0x2d,0x32,0x2e,0x30, - 0x30,0x35,0x2c,0x34,0x2e,0x30,0x37,0x35,0x2d,0x33, - 0x2e,0x37,0x31,0x32,0x2c,0x36,0x2e,0x34,0x32,0x32, - 0x2d,0x35,0x2e,0x31,0x32,0x38,0x0d,0x0a,0x09,0x09, - 0x63,0x32,0x2e,0x33,0x35,0x2d,0x31,0x2e,0x34,0x31, - 0x36,0x2c,0x34,0x2e,0x39,0x30,0x36,0x2d,0x32,0x2e, - 0x35,0x32,0x32,0x2c,0x37,0x2e,0x36,0x36,0x39,0x2d, - 0x33,0x2e,0x33,0x31,0x38,0x63,0x32,0x2e,0x37,0x36, - 0x2d,0x30,0x2e,0x37,0x39,0x32,0x2c,0x35,0x2e,0x36, - 0x32,0x36,0x2d,0x31,0x2e,0x31,0x39,0x2c,0x38,0x2e, - 0x35,0x39,0x36,0x2d,0x31,0x2e,0x31,0x39,0x68,0x31, - 0x2e,0x30,0x33,0x37,0x63,0x34,0x2e,0x32,0x37,0x39, - 0x2c,0x30,0x2c,0x38,0x2e,0x33,0x32,0x2c,0x30,0x2e, - 0x38,0x31,0x35,0x2c,0x31,0x32,0x2e,0x31,0x32,0x31, - 0x2c,0x32,0x2e,0x34,0x33,0x34,0x0d,0x0a,0x09,0x09, - 0x63,0x33,0x2e,0x37,0x39,0x36,0x2c,0x31,0x2e,0x36, - 0x32,0x36,0x2c,0x37,0x2e,0x31,0x31,0x34,0x2c,0x33, - 0x2e,0x38,0x35,0x2c,0x39,0x2e,0x39,0x34,0x36,0x2c, - 0x36,0x2e,0x36,0x38,0x32,0x63,0x32,0x2e,0x38,0x32, - 0x38,0x2c,0x32,0x2e,0x38,0x33,0x32,0x2c,0x35,0x2e, - 0x30,0x35,0x36,0x2c,0x36,0x2e,0x31,0x34,0x36,0x2c, - 0x36,0x2e,0x36,0x38,0x33,0x2c,0x39,0x2e,0x39,0x34, - 0x37,0x63,0x31,0x2e,0x36,0x31,0x38,0x2c,0x33,0x2e, - 0x37,0x39,0x36,0x2c,0x32,0x2e,0x34,0x33,0x35,0x2c, - 0x37,0x2e,0x38,0x33,0x38,0x2c,0x32,0x2e,0x34,0x33, - 0x35,0x2c,0x31,0x32,0x2e,0x31,0x32,0x76,0x37,0x36, - 0x2e,0x39,0x36,0x38,0x68,0x2d,0x31,0x32,0x2e,0x37, - 0x34,0x37,0x0d,0x0a,0x09,0x09,0x56,0x33,0x34,0x33, - 0x2e,0x35,0x35,0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x09, - 0x3c,0x70,0x61,0x74,0x68,0x20,0x64,0x3d,0x22,0x4d, - 0x38,0x30,0x33,0x2e,0x33,0x34,0x33,0x2c,0x33,0x34, - 0x33,0x2e,0x35,0x35,0x6c,0x2d,0x37,0x2e,0x30,0x34, - 0x36,0x2d,0x31,0x30,0x2e,0x37,0x37,0x33,0x63,0x2d, - 0x32,0x2e,0x39,0x30,0x31,0x2c,0x33,0x2e,0x39,0x33, - 0x38,0x2d,0x36,0x2e,0x35,0x32,0x35,0x2c,0x37,0x2e, - 0x30,0x36,0x31,0x2d,0x31,0x30,0x2e,0x38,0x37,0x38, - 0x2c,0x39,0x2e,0x33,0x37,0x36,0x63,0x2d,0x34,0x2e, - 0x33,0x34,0x38,0x2c,0x32,0x2e,0x33,0x31,0x32,0x2d, - 0x39,0x2e,0x31,0x31,0x35,0x2c,0x33,0x2e,0x34,0x36, - 0x37,0x2d,0x31,0x34,0x2e,0x32,0x39,0x34,0x2c,0x33, - 0x2e,0x34,0x36,0x37,0x68,0x2d,0x33,0x2e,0x32,0x31, - 0x31,0x0d,0x0a,0x09,0x09,0x63,0x2d,0x34,0x2e,0x32, - 0x38,0x36,0x2c,0x30,0x2d,0x38,0x2e,0x33,0x32,0x33, - 0x2d,0x30,0x2e,0x38,0x31,0x32,0x2d,0x31,0x32,0x2e, - 0x31,0x32,0x2d,0x32,0x2e,0x34,0x33,0x34,0x63,0x2d, - 0x33,0x2e,0x38,0x30,0x31,0x2d,0x31,0x2e,0x36,0x32, - 0x33,0x2d,0x37,0x2e,0x31,0x31,0x34,0x2d,0x33,0x2e, - 0x38,0x34,0x36,0x2d,0x39,0x2e,0x39,0x34,0x36,0x2d, - 0x36,0x2e,0x36,0x38,0x32,0x63,0x2d,0x32,0x2e,0x38, - 0x33,0x32,0x2d,0x32,0x2e,0x38,0x32,0x38,0x2d,0x35, - 0x2e,0x30,0x36,0x31,0x2d,0x36,0x2e,0x31,0x34,0x33, - 0x2d,0x36,0x2e,0x36,0x38,0x34,0x2d,0x39,0x2e,0x39, - 0x34,0x33,0x0d,0x0a,0x09,0x09,0x63,0x2d,0x31,0x2e, - 0x36,0x32,0x32,0x2d,0x33,0x2e,0x37,0x39,0x36,0x2d, - 0x32,0x2e,0x34,0x33,0x34,0x2d,0x37,0x2e,0x38,0x33, - 0x38,0x2d,0x32,0x2e,0x34,0x33,0x34,0x2d,0x31,0x32, - 0x2e,0x31,0x32,0x31,0x76,0x2d,0x37,0x36,0x2e,0x39, - 0x36,0x36,0x68,0x31,0x32,0x2e,0x37,0x34,0x34,0x76, - 0x37,0x37,0x2e,0x36,0x39,0x31,0x63,0x30,0x2c,0x32, - 0x2e,0x35,0x35,0x36,0x2c,0x30,0x2e,0x34,0x38,0x31, - 0x2c,0x34,0x2e,0x39,0x35,0x36,0x2c,0x31,0x2e,0x34, - 0x34,0x36,0x2c,0x37,0x2e,0x32,0x30,0x32,0x0d,0x0a, + 0x0a,0x09,0x09,0x63,0x2d,0x31,0x2e,0x36,0x35,0x37, + 0x2c,0x31,0x2e,0x36,0x35,0x37,0x2d,0x32,0x2e,0x39, + 0x37,0x2c,0x33,0x2e,0x36,0x30,0x39,0x2d,0x33,0x2e, + 0x39,0x33,0x35,0x2c,0x35,0x2e,0x38,0x35,0x32,0x63, + 0x2d,0x30,0x2e,0x39,0x36,0x38,0x2c,0x32,0x2e,0x32, + 0x34,0x37,0x2d,0x31,0x2e,0x34,0x35,0x2c,0x34,0x2e, + 0x36,0x34,0x36,0x2d,0x31,0x2e,0x34,0x35,0x2c,0x37, + 0x2e,0x31,0x39,0x39,0x76,0x37,0x37,0x2e,0x36,0x39, + 0x35,0x68,0x2d,0x31,0x32,0x2e,0x37,0x34,0x31,0x56, + 0x32,0x33,0x37,0x2e,0x34,0x37,0x34,0x68,0x34,0x2e, + 0x32,0x34,0x34,0x6c,0x36,0x2e,0x39,0x34,0x33,0x2c, + 0x31,0x30,0x2e,0x37,0x37,0x33,0x0a,0x09,0x09,0x63, + 0x32,0x2e,0x38,0x39,0x39,0x2d,0x33,0x2e,0x39,0x33, + 0x38,0x2c,0x36,0x2e,0x35,0x34,0x2d,0x37,0x2e,0x30, + 0x36,0x31,0x2c,0x31,0x30,0x2e,0x39,0x33,0x2d,0x39, + 0x2e,0x33,0x37,0x36,0x63,0x34,0x2e,0x33,0x38,0x32, + 0x2d,0x32,0x2e,0x33,0x31,0x32,0x2c,0x39,0x2e,0x31, + 0x36,0x36,0x2d,0x33,0x2e,0x34,0x37,0x31,0x2c,0x31, + 0x34,0x2e,0x33,0x34,0x34,0x2d,0x33,0x2e,0x34,0x37, + 0x31,0x68,0x31,0x2e,0x30,0x33,0x37,0x63,0x36,0x2e, + 0x30,0x30,0x39,0x2c,0x30,0x2c,0x31,0x31,0x2e,0x34, + 0x32,0x38,0x2c,0x31,0x2e,0x34,0x38,0x35,0x2c,0x31, + 0x36,0x2e,0x32,0x36,0x36,0x2c,0x34,0x2e,0x34,0x35, + 0x35,0x0a,0x09,0x09,0x63,0x34,0x2e,0x38,0x33,0x33, + 0x2c,0x32,0x2e,0x39,0x37,0x2c,0x38,0x2e,0x35,0x36, + 0x32,0x2c,0x36,0x2e,0x39,0x30,0x38,0x2c,0x31,0x31, + 0x2e,0x31,0x38,0x37,0x2c,0x31,0x31,0x2e,0x38,0x31, + 0x31,0x63,0x31,0x2e,0x33,0x31,0x32,0x2d,0x32,0x2e, + 0x34,0x31,0x39,0x2c,0x32,0x2e,0x39,0x33,0x36,0x2d, + 0x34,0x2e,0x36,0x32,0x37,0x2c,0x34,0x2e,0x38,0x36, + 0x39,0x2d,0x36,0x2e,0x36,0x32,0x39,0x63,0x31,0x2e, + 0x39,0x33,0x33,0x2d,0x32,0x2e,0x30,0x30,0x35,0x2c, + 0x34,0x2e,0x30,0x37,0x35,0x2d,0x33,0x2e,0x37,0x31, + 0x32,0x2c,0x36,0x2e,0x34,0x32,0x32,0x2d,0x35,0x2e, + 0x31,0x32,0x38,0x0a,0x09,0x09,0x63,0x32,0x2e,0x33, + 0x35,0x2d,0x31,0x2e,0x34,0x31,0x36,0x2c,0x34,0x2e, + 0x39,0x30,0x36,0x2d,0x32,0x2e,0x35,0x32,0x32,0x2c, + 0x37,0x2e,0x36,0x36,0x39,0x2d,0x33,0x2e,0x33,0x31, + 0x38,0x63,0x32,0x2e,0x37,0x36,0x2d,0x30,0x2e,0x37, + 0x39,0x32,0x2c,0x35,0x2e,0x36,0x32,0x36,0x2d,0x31, + 0x2e,0x31,0x39,0x2c,0x38,0x2e,0x35,0x39,0x36,0x2d, + 0x31,0x2e,0x31,0x39,0x68,0x31,0x2e,0x30,0x33,0x37, + 0x63,0x34,0x2e,0x32,0x37,0x39,0x2c,0x30,0x2c,0x38, + 0x2e,0x33,0x32,0x2c,0x30,0x2e,0x38,0x31,0x35,0x2c, + 0x31,0x32,0x2e,0x31,0x32,0x31,0x2c,0x32,0x2e,0x34, + 0x33,0x34,0x0a,0x09,0x09,0x63,0x33,0x2e,0x37,0x39, + 0x36,0x2c,0x31,0x2e,0x36,0x32,0x36,0x2c,0x37,0x2e, + 0x31,0x31,0x34,0x2c,0x33,0x2e,0x38,0x35,0x2c,0x39, + 0x2e,0x39,0x34,0x36,0x2c,0x36,0x2e,0x36,0x38,0x32, + 0x63,0x32,0x2e,0x38,0x32,0x38,0x2c,0x32,0x2e,0x38, + 0x33,0x32,0x2c,0x35,0x2e,0x30,0x35,0x36,0x2c,0x36, + 0x2e,0x31,0x34,0x36,0x2c,0x36,0x2e,0x36,0x38,0x33, + 0x2c,0x39,0x2e,0x39,0x34,0x37,0x63,0x31,0x2e,0x36, + 0x31,0x38,0x2c,0x33,0x2e,0x37,0x39,0x36,0x2c,0x32, + 0x2e,0x34,0x33,0x35,0x2c,0x37,0x2e,0x38,0x33,0x38, + 0x2c,0x32,0x2e,0x34,0x33,0x35,0x2c,0x31,0x32,0x2e, + 0x31,0x32,0x76,0x37,0x36,0x2e,0x39,0x36,0x38,0x68, + 0x2d,0x31,0x32,0x2e,0x37,0x34,0x37,0x0a,0x09,0x09, + 0x56,0x33,0x34,0x33,0x2e,0x35,0x35,0x7a,0x22,0x2f, + 0x3e,0x0a,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x64, + 0x3d,0x22,0x4d,0x38,0x30,0x33,0x2e,0x33,0x34,0x33, + 0x2c,0x33,0x34,0x33,0x2e,0x35,0x35,0x6c,0x2d,0x37, + 0x2e,0x30,0x34,0x36,0x2d,0x31,0x30,0x2e,0x37,0x37, + 0x33,0x63,0x2d,0x32,0x2e,0x39,0x30,0x31,0x2c,0x33, + 0x2e,0x39,0x33,0x38,0x2d,0x36,0x2e,0x35,0x32,0x35, + 0x2c,0x37,0x2e,0x30,0x36,0x31,0x2d,0x31,0x30,0x2e, + 0x38,0x37,0x38,0x2c,0x39,0x2e,0x33,0x37,0x36,0x63, + 0x2d,0x34,0x2e,0x33,0x34,0x38,0x2c,0x32,0x2e,0x33, + 0x31,0x32,0x2d,0x39,0x2e,0x31,0x31,0x35,0x2c,0x33, + 0x2e,0x34,0x36,0x37,0x2d,0x31,0x34,0x2e,0x32,0x39, + 0x34,0x2c,0x33,0x2e,0x34,0x36,0x37,0x68,0x2d,0x33, + 0x2e,0x32,0x31,0x31,0x0a,0x09,0x09,0x63,0x2d,0x34, + 0x2e,0x32,0x38,0x36,0x2c,0x30,0x2d,0x38,0x2e,0x33, + 0x32,0x33,0x2d,0x30,0x2e,0x38,0x31,0x32,0x2d,0x31, + 0x32,0x2e,0x31,0x32,0x2d,0x32,0x2e,0x34,0x33,0x34, + 0x63,0x2d,0x33,0x2e,0x38,0x30,0x31,0x2d,0x31,0x2e, + 0x36,0x32,0x33,0x2d,0x37,0x2e,0x31,0x31,0x34,0x2d, + 0x33,0x2e,0x38,0x34,0x36,0x2d,0x39,0x2e,0x39,0x34, + 0x36,0x2d,0x36,0x2e,0x36,0x38,0x32,0x63,0x2d,0x32, + 0x2e,0x38,0x33,0x32,0x2d,0x32,0x2e,0x38,0x32,0x38, + 0x2d,0x35,0x2e,0x30,0x36,0x31,0x2d,0x36,0x2e,0x31, + 0x34,0x33,0x2d,0x36,0x2e,0x36,0x38,0x34,0x2d,0x39, + 0x2e,0x39,0x34,0x33,0x0a,0x09,0x09,0x63,0x2d,0x31, + 0x2e,0x36,0x32,0x32,0x2d,0x33,0x2e,0x37,0x39,0x36, + 0x2d,0x32,0x2e,0x34,0x33,0x34,0x2d,0x37,0x2e,0x38, + 0x33,0x38,0x2d,0x32,0x2e,0x34,0x33,0x34,0x2d,0x31, + 0x32,0x2e,0x31,0x32,0x31,0x76,0x2d,0x37,0x36,0x2e, + 0x39,0x36,0x36,0x68,0x31,0x32,0x2e,0x37,0x34,0x34, + 0x76,0x37,0x37,0x2e,0x36,0x39,0x31,0x63,0x30,0x2c, + 0x32,0x2e,0x35,0x35,0x36,0x2c,0x30,0x2e,0x34,0x38, + 0x31,0x2c,0x34,0x2e,0x39,0x35,0x36,0x2c,0x31,0x2e, + 0x34,0x34,0x36,0x2c,0x37,0x2e,0x32,0x30,0x32,0x0a, 0x09,0x09,0x63,0x30,0x2e,0x39,0x36,0x39,0x2c,0x32, 0x2e,0x32,0x34,0x33,0x2c,0x32,0x2e,0x32,0x38,0x2c, 0x34,0x2e,0x31,0x39,0x35,0x2c,0x33,0x2e,0x39,0x33, @@ -722,100 +715,99 @@ const unsigned char splash_svg_data[17935] = { 0x2e,0x39,0x36,0x34,0x2c,0x34,0x2e,0x36,0x34,0x36, 0x2c,0x31,0x2e,0x34,0x34,0x37,0x2c,0x37,0x2e,0x32, 0x30,0x33,0x2c,0x31,0x2e,0x34,0x34,0x37,0x68,0x38, - 0x2e,0x34,0x39,0x36,0x0d,0x0a,0x09,0x09,0x63,0x32, - 0x2e,0x35,0x34,0x39,0x2c,0x30,0x2c,0x34,0x2e,0x39, - 0x35,0x32,0x2d,0x30,0x2e,0x34,0x38,0x32,0x2c,0x37, - 0x2e,0x31,0x39,0x34,0x2d,0x31,0x2e,0x34,0x34,0x37, - 0x63,0x32,0x2e,0x32,0x34,0x33,0x2d,0x30,0x2e,0x39, - 0x36,0x38,0x2c,0x34,0x2e,0x31,0x39,0x38,0x2d,0x32, - 0x2e,0x32,0x38,0x31,0x2c,0x35,0x2e,0x38,0x35,0x34, - 0x2d,0x33,0x2e,0x39,0x33,0x38,0x63,0x31,0x2e,0x36, - 0x35,0x37,0x2d,0x31,0x2e,0x36,0x35,0x37,0x2c,0x32, - 0x2e,0x39,0x37,0x31,0x2d,0x33,0x2e,0x36,0x30,0x39, - 0x2c,0x33,0x2e,0x39,0x33,0x36,0x2d,0x35,0x2e,0x38, - 0x35,0x32,0x0d,0x0a,0x09,0x09,0x63,0x30,0x2e,0x39, - 0x36,0x39,0x2d,0x32,0x2e,0x32,0x34,0x36,0x2c,0x31, - 0x2e,0x34,0x35,0x34,0x2d,0x34,0x2e,0x36,0x34,0x36, - 0x2c,0x31,0x2e,0x34,0x35,0x34,0x2d,0x37,0x2e,0x32, - 0x30,0x32,0x76,0x2d,0x37,0x37,0x2e,0x36,0x39,0x31, - 0x68,0x31,0x32,0x2e,0x37,0x33,0x36,0x56,0x33,0x34, - 0x33,0x2e,0x35,0x35,0x48,0x38,0x30,0x33,0x2e,0x33, - 0x34,0x33,0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x09,0x3c, - 0x70,0x61,0x74,0x68,0x20,0x64,0x3d,0x22,0x4d,0x38, - 0x33,0x37,0x2e,0x33,0x31,0x39,0x2c,0x33,0x34,0x33, - 0x2e,0x35,0x35,0x56,0x31,0x39,0x35,0x68,0x31,0x32, - 0x2e,0x37,0x34,0x76,0x31,0x34,0x38,0x2e,0x35,0x35, - 0x48,0x38,0x33,0x37,0x2e,0x33,0x31,0x39,0x7a,0x22, - 0x2f,0x3e,0x0d,0x0a,0x09,0x3c,0x70,0x61,0x74,0x68, - 0x20,0x64,0x3d,0x22,0x4d,0x39,0x34,0x36,0x2e,0x34, - 0x30,0x34,0x2c,0x33,0x34,0x33,0x2e,0x35,0x35,0x6c, - 0x2d,0x37,0x2e,0x30,0x34,0x36,0x2d,0x31,0x30,0x2e, - 0x35,0x36,0x37,0x63,0x2d,0x32,0x2e,0x39,0x2c,0x33, - 0x2e,0x38,0x2d,0x36,0x2e,0x35,0x32,0x35,0x2c,0x36, - 0x2e,0x38,0x35,0x34,0x2d,0x31,0x30,0x2e,0x38,0x38, - 0x31,0x2c,0x39,0x2e,0x31,0x37,0x63,0x2d,0x34,0x2e, - 0x33,0x34,0x38,0x2c,0x32,0x2e,0x33,0x31,0x32,0x2d, - 0x39,0x2e,0x31,0x31,0x36,0x2c,0x33,0x2e,0x34,0x36, - 0x37,0x2d,0x31,0x34,0x2e,0x32,0x39,0x2c,0x33,0x2e, - 0x34,0x36,0x37,0x68,0x2d,0x33,0x2e,0x32,0x31,0x35, - 0x0d,0x0a,0x09,0x09,0x63,0x2d,0x34,0x2e,0x32,0x38, - 0x32,0x2c,0x30,0x2d,0x38,0x2e,0x33,0x32,0x2d,0x30, - 0x2e,0x38,0x31,0x32,0x2d,0x31,0x32,0x2e,0x31,0x31, - 0x36,0x2d,0x32,0x2e,0x34,0x33,0x34,0x63,0x2d,0x33, - 0x2e,0x38,0x30,0x35,0x2d,0x31,0x2e,0x36,0x32,0x33, - 0x2d,0x37,0x2e,0x31,0x31,0x39,0x2d,0x33,0x2e,0x38, - 0x34,0x36,0x2d,0x39,0x2e,0x39,0x34,0x37,0x2d,0x36, - 0x2e,0x36,0x38,0x32,0x63,0x2d,0x32,0x2e,0x38,0x33, - 0x36,0x2d,0x32,0x2e,0x38,0x32,0x38,0x2d,0x35,0x2e, - 0x30,0x36,0x32,0x2d,0x36,0x2e,0x31,0x34,0x33,0x2d, - 0x36,0x2e,0x36,0x38,0x32,0x2d,0x39,0x2e,0x39,0x34, - 0x33,0x0d,0x0a,0x09,0x09,0x63,0x2d,0x31,0x2e,0x36, - 0x32,0x37,0x2d,0x33,0x2e,0x37,0x39,0x36,0x2d,0x32, - 0x2e,0x34,0x33,0x36,0x2d,0x37,0x2e,0x38,0x33,0x38, - 0x2d,0x32,0x2e,0x34,0x33,0x36,0x2d,0x31,0x32,0x2e, - 0x31,0x32,0x31,0x76,0x2d,0x31,0x2e,0x30,0x33,0x37, - 0x63,0x30,0x2d,0x34,0x2e,0x32,0x37,0x39,0x2c,0x30, - 0x2e,0x38,0x30,0x39,0x2d,0x38,0x2e,0x33,0x32,0x2c, - 0x32,0x2e,0x34,0x33,0x36,0x2d,0x31,0x32,0x2e,0x31, - 0x32,0x31,0x63,0x31,0x2e,0x36,0x31,0x38,0x2d,0x33, - 0x2e,0x37,0x39,0x36,0x2c,0x33,0x2e,0x38,0x34,0x36, - 0x2d,0x37,0x2e,0x31,0x31,0x31,0x2c,0x36,0x2e,0x36, - 0x38,0x32,0x2d,0x39,0x2e,0x39,0x34,0x33,0x0d,0x0a, - 0x09,0x09,0x63,0x32,0x2e,0x38,0x32,0x38,0x2d,0x32, - 0x2e,0x38,0x33,0x32,0x2c,0x36,0x2e,0x31,0x34,0x34, - 0x2d,0x35,0x2e,0x30,0x36,0x2c,0x39,0x2e,0x39,0x34, - 0x37,0x2d,0x36,0x2e,0x36,0x38,0x32,0x63,0x33,0x2e, - 0x37,0x39,0x36,0x2d,0x31,0x2e,0x36,0x32,0x33,0x2c, - 0x37,0x2e,0x38,0x33,0x34,0x2d,0x32,0x2e,0x34,0x33, - 0x34,0x2c,0x31,0x32,0x2e,0x31,0x31,0x36,0x2d,0x32, - 0x2e,0x34,0x33,0x34,0x68,0x32,0x36,0x2e,0x39,0x33, - 0x36,0x76,0x2d,0x31,0x36,0x2e,0x33,0x36,0x38,0x63, - 0x30,0x2d,0x32,0x2e,0x35,0x35,0x33,0x2d,0x30,0x2e, - 0x34,0x38,0x31,0x2d,0x34,0x2e,0x39,0x35,0x32,0x2d, - 0x31,0x2e,0x34,0x35,0x2d,0x37,0x2e,0x31,0x39,0x39, - 0x0d,0x0a,0x09,0x09,0x63,0x2d,0x30,0x2e,0x39,0x36, - 0x39,0x2d,0x32,0x2e,0x32,0x34,0x33,0x2d,0x32,0x2e, - 0x32,0x37,0x36,0x2d,0x34,0x2e,0x31,0x39,0x34,0x2d, - 0x33,0x2e,0x39,0x33,0x38,0x2d,0x35,0x2e,0x38,0x35, - 0x32,0x63,0x2d,0x31,0x2e,0x36,0x35,0x33,0x2d,0x31, - 0x2e,0x36,0x35,0x37,0x2d,0x33,0x2e,0x36,0x30,0x39, - 0x2d,0x32,0x2e,0x39,0x37,0x2d,0x35,0x2e,0x38,0x35, - 0x33,0x2d,0x33,0x2e,0x39,0x33,0x38,0x63,0x2d,0x32, - 0x2e,0x32,0x34,0x36,0x2d,0x30,0x2e,0x39,0x36,0x34, - 0x2d,0x34,0x2e,0x36,0x34,0x36,0x2d,0x31,0x2e,0x34, - 0x35,0x2d,0x37,0x2e,0x31,0x39,0x38,0x2d,0x31,0x2e, - 0x34,0x35,0x68,0x2d,0x37,0x2e,0x34,0x35,0x39,0x0d, - 0x0a,0x09,0x09,0x63,0x2d,0x32,0x2e,0x35,0x35,0x38, - 0x2c,0x30,0x2d,0x34,0x2e,0x39,0x35,0x36,0x2c,0x30, - 0x2e,0x34,0x38,0x36,0x2d,0x37,0x2e,0x31,0x39,0x38, - 0x2c,0x31,0x2e,0x34,0x35,0x63,0x2d,0x32,0x2e,0x32, - 0x34,0x37,0x2c,0x30,0x2e,0x39,0x36,0x39,0x2d,0x34, - 0x2e,0x31,0x39,0x35,0x2c,0x32,0x2e,0x32,0x38,0x31, - 0x2d,0x35,0x2e,0x38,0x35,0x36,0x2c,0x33,0x2e,0x39, - 0x33,0x38,0x63,0x2d,0x31,0x2e,0x36,0x35,0x32,0x2c, - 0x31,0x2e,0x36,0x35,0x37,0x2d,0x32,0x2e,0x39,0x37, - 0x2c,0x33,0x2e,0x36,0x30,0x39,0x2d,0x33,0x2e,0x39, - 0x33,0x34,0x2c,0x35,0x2e,0x38,0x35,0x32,0x0d,0x0a, + 0x2e,0x34,0x39,0x36,0x0a,0x09,0x09,0x63,0x32,0x2e, + 0x35,0x34,0x39,0x2c,0x30,0x2c,0x34,0x2e,0x39,0x35, + 0x32,0x2d,0x30,0x2e,0x34,0x38,0x32,0x2c,0x37,0x2e, + 0x31,0x39,0x34,0x2d,0x31,0x2e,0x34,0x34,0x37,0x63, + 0x32,0x2e,0x32,0x34,0x33,0x2d,0x30,0x2e,0x39,0x36, + 0x38,0x2c,0x34,0x2e,0x31,0x39,0x38,0x2d,0x32,0x2e, + 0x32,0x38,0x31,0x2c,0x35,0x2e,0x38,0x35,0x34,0x2d, + 0x33,0x2e,0x39,0x33,0x38,0x63,0x31,0x2e,0x36,0x35, + 0x37,0x2d,0x31,0x2e,0x36,0x35,0x37,0x2c,0x32,0x2e, + 0x39,0x37,0x31,0x2d,0x33,0x2e,0x36,0x30,0x39,0x2c, + 0x33,0x2e,0x39,0x33,0x36,0x2d,0x35,0x2e,0x38,0x35, + 0x32,0x0a,0x09,0x09,0x63,0x30,0x2e,0x39,0x36,0x39, + 0x2d,0x32,0x2e,0x32,0x34,0x36,0x2c,0x31,0x2e,0x34, + 0x35,0x34,0x2d,0x34,0x2e,0x36,0x34,0x36,0x2c,0x31, + 0x2e,0x34,0x35,0x34,0x2d,0x37,0x2e,0x32,0x30,0x32, + 0x76,0x2d,0x37,0x37,0x2e,0x36,0x39,0x31,0x68,0x31, + 0x32,0x2e,0x37,0x33,0x36,0x56,0x33,0x34,0x33,0x2e, + 0x35,0x35,0x48,0x38,0x30,0x33,0x2e,0x33,0x34,0x33, + 0x7a,0x22,0x2f,0x3e,0x0a,0x09,0x3c,0x70,0x61,0x74, + 0x68,0x20,0x64,0x3d,0x22,0x4d,0x38,0x33,0x37,0x2e, + 0x33,0x31,0x39,0x2c,0x33,0x34,0x33,0x2e,0x35,0x35, + 0x56,0x31,0x39,0x35,0x68,0x31,0x32,0x2e,0x37,0x34, + 0x76,0x31,0x34,0x38,0x2e,0x35,0x35,0x48,0x38,0x33, + 0x37,0x2e,0x33,0x31,0x39,0x7a,0x22,0x2f,0x3e,0x0a, + 0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x64,0x3d,0x22, + 0x4d,0x39,0x34,0x36,0x2e,0x34,0x30,0x34,0x2c,0x33, + 0x34,0x33,0x2e,0x35,0x35,0x6c,0x2d,0x37,0x2e,0x30, + 0x34,0x36,0x2d,0x31,0x30,0x2e,0x35,0x36,0x37,0x63, + 0x2d,0x32,0x2e,0x39,0x2c,0x33,0x2e,0x38,0x2d,0x36, + 0x2e,0x35,0x32,0x35,0x2c,0x36,0x2e,0x38,0x35,0x34, + 0x2d,0x31,0x30,0x2e,0x38,0x38,0x31,0x2c,0x39,0x2e, + 0x31,0x37,0x63,0x2d,0x34,0x2e,0x33,0x34,0x38,0x2c, + 0x32,0x2e,0x33,0x31,0x32,0x2d,0x39,0x2e,0x31,0x31, + 0x36,0x2c,0x33,0x2e,0x34,0x36,0x37,0x2d,0x31,0x34, + 0x2e,0x32,0x39,0x2c,0x33,0x2e,0x34,0x36,0x37,0x68, + 0x2d,0x33,0x2e,0x32,0x31,0x35,0x0a,0x09,0x09,0x63, + 0x2d,0x34,0x2e,0x32,0x38,0x32,0x2c,0x30,0x2d,0x38, + 0x2e,0x33,0x32,0x2d,0x30,0x2e,0x38,0x31,0x32,0x2d, + 0x31,0x32,0x2e,0x31,0x31,0x36,0x2d,0x32,0x2e,0x34, + 0x33,0x34,0x63,0x2d,0x33,0x2e,0x38,0x30,0x35,0x2d, + 0x31,0x2e,0x36,0x32,0x33,0x2d,0x37,0x2e,0x31,0x31, + 0x39,0x2d,0x33,0x2e,0x38,0x34,0x36,0x2d,0x39,0x2e, + 0x39,0x34,0x37,0x2d,0x36,0x2e,0x36,0x38,0x32,0x63, + 0x2d,0x32,0x2e,0x38,0x33,0x36,0x2d,0x32,0x2e,0x38, + 0x32,0x38,0x2d,0x35,0x2e,0x30,0x36,0x32,0x2d,0x36, + 0x2e,0x31,0x34,0x33,0x2d,0x36,0x2e,0x36,0x38,0x32, + 0x2d,0x39,0x2e,0x39,0x34,0x33,0x0a,0x09,0x09,0x63, + 0x2d,0x31,0x2e,0x36,0x32,0x37,0x2d,0x33,0x2e,0x37, + 0x39,0x36,0x2d,0x32,0x2e,0x34,0x33,0x36,0x2d,0x37, + 0x2e,0x38,0x33,0x38,0x2d,0x32,0x2e,0x34,0x33,0x36, + 0x2d,0x31,0x32,0x2e,0x31,0x32,0x31,0x76,0x2d,0x31, + 0x2e,0x30,0x33,0x37,0x63,0x30,0x2d,0x34,0x2e,0x32, + 0x37,0x39,0x2c,0x30,0x2e,0x38,0x30,0x39,0x2d,0x38, + 0x2e,0x33,0x32,0x2c,0x32,0x2e,0x34,0x33,0x36,0x2d, + 0x31,0x32,0x2e,0x31,0x32,0x31,0x63,0x31,0x2e,0x36, + 0x31,0x38,0x2d,0x33,0x2e,0x37,0x39,0x36,0x2c,0x33, + 0x2e,0x38,0x34,0x36,0x2d,0x37,0x2e,0x31,0x31,0x31, + 0x2c,0x36,0x2e,0x36,0x38,0x32,0x2d,0x39,0x2e,0x39, + 0x34,0x33,0x0a,0x09,0x09,0x63,0x32,0x2e,0x38,0x32, + 0x38,0x2d,0x32,0x2e,0x38,0x33,0x32,0x2c,0x36,0x2e, + 0x31,0x34,0x34,0x2d,0x35,0x2e,0x30,0x36,0x2c,0x39, + 0x2e,0x39,0x34,0x37,0x2d,0x36,0x2e,0x36,0x38,0x32, + 0x63,0x33,0x2e,0x37,0x39,0x36,0x2d,0x31,0x2e,0x36, + 0x32,0x33,0x2c,0x37,0x2e,0x38,0x33,0x34,0x2d,0x32, + 0x2e,0x34,0x33,0x34,0x2c,0x31,0x32,0x2e,0x31,0x31, + 0x36,0x2d,0x32,0x2e,0x34,0x33,0x34,0x68,0x32,0x36, + 0x2e,0x39,0x33,0x36,0x76,0x2d,0x31,0x36,0x2e,0x33, + 0x36,0x38,0x63,0x30,0x2d,0x32,0x2e,0x35,0x35,0x33, + 0x2d,0x30,0x2e,0x34,0x38,0x31,0x2d,0x34,0x2e,0x39, + 0x35,0x32,0x2d,0x31,0x2e,0x34,0x35,0x2d,0x37,0x2e, + 0x31,0x39,0x39,0x0a,0x09,0x09,0x63,0x2d,0x30,0x2e, + 0x39,0x36,0x39,0x2d,0x32,0x2e,0x32,0x34,0x33,0x2d, + 0x32,0x2e,0x32,0x37,0x36,0x2d,0x34,0x2e,0x31,0x39, + 0x34,0x2d,0x33,0x2e,0x39,0x33,0x38,0x2d,0x35,0x2e, + 0x38,0x35,0x32,0x63,0x2d,0x31,0x2e,0x36,0x35,0x33, + 0x2d,0x31,0x2e,0x36,0x35,0x37,0x2d,0x33,0x2e,0x36, + 0x30,0x39,0x2d,0x32,0x2e,0x39,0x37,0x2d,0x35,0x2e, + 0x38,0x35,0x33,0x2d,0x33,0x2e,0x39,0x33,0x38,0x63, + 0x2d,0x32,0x2e,0x32,0x34,0x36,0x2d,0x30,0x2e,0x39, + 0x36,0x34,0x2d,0x34,0x2e,0x36,0x34,0x36,0x2d,0x31, + 0x2e,0x34,0x35,0x2d,0x37,0x2e,0x31,0x39,0x38,0x2d, + 0x31,0x2e,0x34,0x35,0x68,0x2d,0x37,0x2e,0x34,0x35, + 0x39,0x0a,0x09,0x09,0x63,0x2d,0x32,0x2e,0x35,0x35, + 0x38,0x2c,0x30,0x2d,0x34,0x2e,0x39,0x35,0x36,0x2c, + 0x30,0x2e,0x34,0x38,0x36,0x2d,0x37,0x2e,0x31,0x39, + 0x38,0x2c,0x31,0x2e,0x34,0x35,0x63,0x2d,0x32,0x2e, + 0x32,0x34,0x37,0x2c,0x30,0x2e,0x39,0x36,0x39,0x2d, + 0x34,0x2e,0x31,0x39,0x35,0x2c,0x32,0x2e,0x32,0x38, + 0x31,0x2d,0x35,0x2e,0x38,0x35,0x36,0x2c,0x33,0x2e, + 0x39,0x33,0x38,0x63,0x2d,0x31,0x2e,0x36,0x35,0x32, + 0x2c,0x31,0x2e,0x36,0x35,0x37,0x2d,0x32,0x2e,0x39, + 0x37,0x2c,0x33,0x2e,0x36,0x30,0x39,0x2d,0x33,0x2e, + 0x39,0x33,0x34,0x2c,0x35,0x2e,0x38,0x35,0x32,0x0a, 0x09,0x09,0x63,0x2d,0x30,0x2e,0x39,0x36,0x39,0x2c, 0x32,0x2e,0x32,0x34,0x37,0x2d,0x31,0x2e,0x34,0x35, 0x31,0x2c,0x34,0x2e,0x36,0x34,0x36,0x2d,0x31,0x2e, @@ -825,110 +817,109 @@ const unsigned char splash_svg_data[17935] = { 0x31,0x2e,0x30,0x33,0x33,0x63,0x30,0x2d,0x34,0x2e, 0x32,0x38,0x32,0x2c,0x30,0x2e,0x38,0x31,0x32,0x2d, 0x38,0x2e,0x33,0x32,0x34,0x2c,0x32,0x2e,0x34,0x33, - 0x36,0x2d,0x31,0x32,0x2e,0x31,0x32,0x0d,0x0a,0x09, - 0x09,0x63,0x31,0x2e,0x36,0x32,0x32,0x2d,0x33,0x2e, - 0x38,0x30,0x31,0x2c,0x33,0x2e,0x38,0x35,0x2d,0x37, - 0x2e,0x31,0x31,0x35,0x2c,0x36,0x2e,0x36,0x38,0x32, - 0x2d,0x39,0x2e,0x39,0x34,0x37,0x63,0x32,0x2e,0x38, - 0x32,0x38,0x2d,0x32,0x2e,0x38,0x33,0x33,0x2c,0x36, - 0x2e,0x31,0x34,0x36,0x2d,0x35,0x2e,0x30,0x35,0x36, - 0x2c,0x39,0x2e,0x39,0x34,0x33,0x2d,0x36,0x2e,0x36, - 0x38,0x32,0x63,0x33,0x2e,0x37,0x39,0x36,0x2d,0x31, - 0x2e,0x36,0x31,0x39,0x2c,0x37,0x2e,0x38,0x33,0x38, - 0x2d,0x32,0x2e,0x34,0x33,0x34,0x2c,0x31,0x32,0x2e, - 0x31,0x32,0x2d,0x32,0x2e,0x34,0x33,0x34,0x68,0x37, - 0x2e,0x34,0x35,0x39,0x0d,0x0a,0x09,0x09,0x63,0x34, - 0x2e,0x32,0x37,0x38,0x2c,0x30,0x2c,0x38,0x2e,0x33, - 0x31,0x39,0x2c,0x30,0x2e,0x38,0x31,0x35,0x2c,0x31, - 0x32,0x2e,0x31,0x31,0x37,0x2c,0x32,0x2e,0x34,0x33, - 0x34,0x63,0x33,0x2e,0x38,0x2c,0x31,0x2e,0x36,0x32, - 0x36,0x2c,0x37,0x2e,0x31,0x31,0x33,0x2c,0x33,0x2e, - 0x38,0x35,0x2c,0x39,0x2e,0x39,0x34,0x39,0x2c,0x36, - 0x2e,0x36,0x38,0x32,0x63,0x32,0x2e,0x38,0x32,0x38, - 0x2c,0x32,0x2e,0x38,0x33,0x32,0x2c,0x35,0x2e,0x30, - 0x35,0x37,0x2c,0x36,0x2e,0x31,0x34,0x36,0x2c,0x36, - 0x2e,0x36,0x38,0x2c,0x39,0x2e,0x39,0x34,0x37,0x0d, - 0x0a,0x09,0x09,0x63,0x31,0x2e,0x36,0x32,0x32,0x2c, - 0x33,0x2e,0x37,0x39,0x36,0x2c,0x32,0x2e,0x34,0x33, - 0x34,0x2c,0x37,0x2e,0x38,0x33,0x38,0x2c,0x32,0x2e, - 0x34,0x33,0x34,0x2c,0x31,0x32,0x2e,0x31,0x32,0x76, - 0x37,0x36,0x2e,0x39,0x36,0x38,0x48,0x39,0x34,0x36, - 0x2e,0x34,0x30,0x34,0x4c,0x39,0x34,0x36,0x2e,0x34, - 0x30,0x34,0x2c,0x33,0x34,0x33,0x2e,0x35,0x35,0x7a, - 0x20,0x4d,0x39,0x33,0x37,0x2e,0x39,0x30,0x37,0x2c, - 0x32,0x39,0x32,0x2e,0x31,0x36,0x37,0x68,0x2d,0x32, - 0x36,0x2e,0x39,0x33,0x36,0x63,0x2d,0x32,0x2e,0x35, - 0x35,0x38,0x2c,0x30,0x2d,0x34,0x2e,0x39,0x35,0x36, - 0x2c,0x30,0x2e,0x34,0x38,0x36,0x2d,0x37,0x2e,0x31, - 0x39,0x39,0x2c,0x31,0x2e,0x34,0x35,0x31,0x0d,0x0a, - 0x09,0x09,0x63,0x2d,0x32,0x2e,0x32,0x34,0x36,0x2c, - 0x30,0x2e,0x39,0x36,0x38,0x2d,0x34,0x2e,0x31,0x39, - 0x34,0x2c,0x32,0x2e,0x32,0x39,0x36,0x2d,0x35,0x2e, - 0x38,0x35,0x32,0x2c,0x33,0x2e,0x39,0x38,0x38,0x63, - 0x2d,0x31,0x2e,0x36,0x36,0x31,0x2c,0x31,0x2e,0x36, - 0x39,0x35,0x2d,0x32,0x2e,0x39,0x37,0x31,0x2c,0x33, - 0x2e,0x36,0x36,0x33,0x2d,0x33,0x2e,0x39,0x33,0x38, - 0x2c,0x35,0x2e,0x39,0x30,0x35,0x63,0x2d,0x30,0x2e, - 0x39,0x36,0x39,0x2c,0x32,0x2e,0x32,0x34,0x37,0x2d, - 0x31,0x2e,0x34,0x35,0x31,0x2c,0x34,0x2e,0x36,0x34, - 0x36,0x2d,0x31,0x2e,0x34,0x35,0x31,0x2c,0x37,0x2e, - 0x32,0x30,0x33,0x76,0x34,0x2e,0x34,0x35,0x31,0x0d, - 0x0a,0x09,0x09,0x63,0x30,0x2c,0x32,0x2e,0x35,0x35, - 0x36,0x2c,0x30,0x2e,0x34,0x38,0x32,0x2c,0x34,0x2e, - 0x39,0x35,0x36,0x2c,0x31,0x2e,0x34,0x35,0x31,0x2c, - 0x37,0x2e,0x32,0x30,0x32,0x63,0x30,0x2e,0x39,0x36, - 0x38,0x2c,0x32,0x2e,0x32,0x34,0x33,0x2c,0x32,0x2e, - 0x32,0x37,0x36,0x2c,0x34,0x2e,0x31,0x39,0x35,0x2c, - 0x33,0x2e,0x39,0x33,0x38,0x2c,0x35,0x2e,0x38,0x35, - 0x32,0x63,0x31,0x2e,0x36,0x35,0x36,0x2c,0x31,0x2e, - 0x36,0x35,0x37,0x2c,0x33,0x2e,0x36,0x30,0x34,0x2c, - 0x32,0x2e,0x39,0x37,0x2c,0x35,0x2e,0x38,0x35,0x32, - 0x2c,0x33,0x2e,0x39,0x33,0x38,0x0d,0x0a,0x09,0x09, - 0x63,0x32,0x2e,0x32,0x34,0x33,0x2c,0x30,0x2e,0x39, - 0x36,0x34,0x2c,0x34,0x2e,0x36,0x34,0x33,0x2c,0x31, - 0x2e,0x34,0x34,0x37,0x2c,0x37,0x2e,0x31,0x39,0x39, - 0x2c,0x31,0x2e,0x34,0x34,0x37,0x68,0x38,0x2e,0x34, - 0x39,0x36,0x63,0x32,0x2e,0x35,0x35,0x33,0x2c,0x30, - 0x2c,0x34,0x2e,0x39,0x35,0x32,0x2d,0x30,0x2e,0x34, - 0x38,0x32,0x2c,0x37,0x2e,0x31,0x39,0x38,0x2d,0x31, - 0x2e,0x34,0x34,0x37,0x63,0x32,0x2e,0x32,0x34,0x32, - 0x2d,0x30,0x2e,0x39,0x36,0x38,0x2c,0x34,0x2e,0x31, - 0x39,0x38,0x2d,0x32,0x2e,0x32,0x38,0x31,0x2c,0x35, - 0x2e,0x38,0x35,0x33,0x2d,0x33,0x2e,0x39,0x33,0x38, - 0x0d,0x0a,0x09,0x09,0x63,0x31,0x2e,0x36,0x36,0x31, - 0x2d,0x31,0x2e,0x36,0x35,0x37,0x2c,0x32,0x2e,0x39, - 0x37,0x2d,0x33,0x2e,0x36,0x30,0x39,0x2c,0x33,0x2e, - 0x39,0x33,0x38,0x2d,0x35,0x2e,0x38,0x35,0x32,0x63, - 0x30,0x2e,0x39,0x36,0x39,0x2d,0x32,0x2e,0x32,0x34, - 0x36,0x2c,0x31,0x2e,0x34,0x35,0x2d,0x34,0x2e,0x36, - 0x34,0x36,0x2c,0x31,0x2e,0x34,0x35,0x2d,0x37,0x2e, - 0x32,0x30,0x32,0x4c,0x39,0x33,0x37,0x2e,0x39,0x30, - 0x37,0x2c,0x32,0x39,0x32,0x2e,0x31,0x36,0x37,0x4c, - 0x39,0x33,0x37,0x2e,0x39,0x30,0x37,0x2c,0x32,0x39, - 0x32,0x2e,0x31,0x36,0x37,0x7a,0x22,0x2f,0x3e,0x0d, - 0x0a,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x64,0x3d, - 0x22,0x4d,0x31,0x30,0x31,0x34,0x2e,0x37,0x37,0x32, - 0x2c,0x33,0x34,0x33,0x2e,0x35,0x35,0x63,0x2d,0x33, - 0x2e,0x38,0x36,0x35,0x2c,0x30,0x2d,0x37,0x2e,0x35, - 0x30,0x39,0x2d,0x30,0x2e,0x37,0x32,0x34,0x2d,0x31, - 0x30,0x2e,0x39,0x33,0x31,0x2d,0x32,0x2e,0x31,0x37, - 0x34,0x63,0x2d,0x33,0x2e,0x34,0x31,0x38,0x2d,0x31, - 0x2e,0x34,0x35,0x31,0x2d,0x36,0x2e,0x33,0x38,0x39, - 0x2d,0x33,0x2e,0x34,0x35,0x36,0x2d,0x38,0x2e,0x39, - 0x30,0x39,0x2d,0x36,0x2e,0x30,0x30,0x39,0x0d,0x0a, - 0x09,0x09,0x63,0x2d,0x32,0x2e,0x35,0x32,0x2d,0x32, - 0x2e,0x35,0x35,0x37,0x2d,0x34,0x2e,0x35,0x32,0x34, - 0x2d,0x35,0x2e,0x35,0x32,0x36,0x2d,0x36,0x2e,0x30, - 0x30,0x39,0x2d,0x38,0x2e,0x39,0x31,0x63,0x2d,0x31, - 0x2e,0x34,0x38,0x35,0x2d,0x33,0x2e,0x33,0x38,0x33, - 0x2d,0x32,0x2e,0x32,0x32,0x35,0x2d,0x37,0x2e,0x30, - 0x30,0x37,0x2d,0x32,0x2e,0x32,0x32,0x35,0x2d,0x31, - 0x30,0x2e,0x38,0x37,0x36,0x56,0x32,0x34,0x39,0x2e, - 0x35,0x39,0x68,0x2d,0x31,0x39,0x2e,0x30,0x36,0x32, - 0x76,0x2d,0x31,0x32,0x2e,0x31,0x31,0x36,0x68,0x31, - 0x39,0x2e,0x30,0x36,0x32,0x76,0x2d,0x32,0x35,0x2e, - 0x34,0x38,0x35,0x6c,0x31,0x32,0x2e,0x37,0x34,0x2d, - 0x32,0x2e,0x30,0x37,0x0d,0x0a,0x09,0x09,0x76,0x32, + 0x36,0x2d,0x31,0x32,0x2e,0x31,0x32,0x0a,0x09,0x09, + 0x63,0x31,0x2e,0x36,0x32,0x32,0x2d,0x33,0x2e,0x38, + 0x30,0x31,0x2c,0x33,0x2e,0x38,0x35,0x2d,0x37,0x2e, + 0x31,0x31,0x35,0x2c,0x36,0x2e,0x36,0x38,0x32,0x2d, + 0x39,0x2e,0x39,0x34,0x37,0x63,0x32,0x2e,0x38,0x32, + 0x38,0x2d,0x32,0x2e,0x38,0x33,0x33,0x2c,0x36,0x2e, + 0x31,0x34,0x36,0x2d,0x35,0x2e,0x30,0x35,0x36,0x2c, + 0x39,0x2e,0x39,0x34,0x33,0x2d,0x36,0x2e,0x36,0x38, + 0x32,0x63,0x33,0x2e,0x37,0x39,0x36,0x2d,0x31,0x2e, + 0x36,0x31,0x39,0x2c,0x37,0x2e,0x38,0x33,0x38,0x2d, + 0x32,0x2e,0x34,0x33,0x34,0x2c,0x31,0x32,0x2e,0x31, + 0x32,0x2d,0x32,0x2e,0x34,0x33,0x34,0x68,0x37,0x2e, + 0x34,0x35,0x39,0x0a,0x09,0x09,0x63,0x34,0x2e,0x32, + 0x37,0x38,0x2c,0x30,0x2c,0x38,0x2e,0x33,0x31,0x39, + 0x2c,0x30,0x2e,0x38,0x31,0x35,0x2c,0x31,0x32,0x2e, + 0x31,0x31,0x37,0x2c,0x32,0x2e,0x34,0x33,0x34,0x63, + 0x33,0x2e,0x38,0x2c,0x31,0x2e,0x36,0x32,0x36,0x2c, + 0x37,0x2e,0x31,0x31,0x33,0x2c,0x33,0x2e,0x38,0x35, + 0x2c,0x39,0x2e,0x39,0x34,0x39,0x2c,0x36,0x2e,0x36, + 0x38,0x32,0x63,0x32,0x2e,0x38,0x32,0x38,0x2c,0x32, + 0x2e,0x38,0x33,0x32,0x2c,0x35,0x2e,0x30,0x35,0x37, + 0x2c,0x36,0x2e,0x31,0x34,0x36,0x2c,0x36,0x2e,0x36, + 0x38,0x2c,0x39,0x2e,0x39,0x34,0x37,0x0a,0x09,0x09, + 0x63,0x31,0x2e,0x36,0x32,0x32,0x2c,0x33,0x2e,0x37, + 0x39,0x36,0x2c,0x32,0x2e,0x34,0x33,0x34,0x2c,0x37, + 0x2e,0x38,0x33,0x38,0x2c,0x32,0x2e,0x34,0x33,0x34, + 0x2c,0x31,0x32,0x2e,0x31,0x32,0x76,0x37,0x36,0x2e, + 0x39,0x36,0x38,0x48,0x39,0x34,0x36,0x2e,0x34,0x30, + 0x34,0x4c,0x39,0x34,0x36,0x2e,0x34,0x30,0x34,0x2c, + 0x33,0x34,0x33,0x2e,0x35,0x35,0x7a,0x20,0x4d,0x39, + 0x33,0x37,0x2e,0x39,0x30,0x37,0x2c,0x32,0x39,0x32, + 0x2e,0x31,0x36,0x37,0x68,0x2d,0x32,0x36,0x2e,0x39, + 0x33,0x36,0x63,0x2d,0x32,0x2e,0x35,0x35,0x38,0x2c, + 0x30,0x2d,0x34,0x2e,0x39,0x35,0x36,0x2c,0x30,0x2e, + 0x34,0x38,0x36,0x2d,0x37,0x2e,0x31,0x39,0x39,0x2c, + 0x31,0x2e,0x34,0x35,0x31,0x0a,0x09,0x09,0x63,0x2d, + 0x32,0x2e,0x32,0x34,0x36,0x2c,0x30,0x2e,0x39,0x36, + 0x38,0x2d,0x34,0x2e,0x31,0x39,0x34,0x2c,0x32,0x2e, + 0x32,0x39,0x36,0x2d,0x35,0x2e,0x38,0x35,0x32,0x2c, + 0x33,0x2e,0x39,0x38,0x38,0x63,0x2d,0x31,0x2e,0x36, + 0x36,0x31,0x2c,0x31,0x2e,0x36,0x39,0x35,0x2d,0x32, + 0x2e,0x39,0x37,0x31,0x2c,0x33,0x2e,0x36,0x36,0x33, + 0x2d,0x33,0x2e,0x39,0x33,0x38,0x2c,0x35,0x2e,0x39, + 0x30,0x35,0x63,0x2d,0x30,0x2e,0x39,0x36,0x39,0x2c, + 0x32,0x2e,0x32,0x34,0x37,0x2d,0x31,0x2e,0x34,0x35, + 0x31,0x2c,0x34,0x2e,0x36,0x34,0x36,0x2d,0x31,0x2e, + 0x34,0x35,0x31,0x2c,0x37,0x2e,0x32,0x30,0x33,0x76, + 0x34,0x2e,0x34,0x35,0x31,0x0a,0x09,0x09,0x63,0x30, + 0x2c,0x32,0x2e,0x35,0x35,0x36,0x2c,0x30,0x2e,0x34, + 0x38,0x32,0x2c,0x34,0x2e,0x39,0x35,0x36,0x2c,0x31, + 0x2e,0x34,0x35,0x31,0x2c,0x37,0x2e,0x32,0x30,0x32, + 0x63,0x30,0x2e,0x39,0x36,0x38,0x2c,0x32,0x2e,0x32, + 0x34,0x33,0x2c,0x32,0x2e,0x32,0x37,0x36,0x2c,0x34, + 0x2e,0x31,0x39,0x35,0x2c,0x33,0x2e,0x39,0x33,0x38, + 0x2c,0x35,0x2e,0x38,0x35,0x32,0x63,0x31,0x2e,0x36, + 0x35,0x36,0x2c,0x31,0x2e,0x36,0x35,0x37,0x2c,0x33, + 0x2e,0x36,0x30,0x34,0x2c,0x32,0x2e,0x39,0x37,0x2c, + 0x35,0x2e,0x38,0x35,0x32,0x2c,0x33,0x2e,0x39,0x33, + 0x38,0x0a,0x09,0x09,0x63,0x32,0x2e,0x32,0x34,0x33, + 0x2c,0x30,0x2e,0x39,0x36,0x34,0x2c,0x34,0x2e,0x36, + 0x34,0x33,0x2c,0x31,0x2e,0x34,0x34,0x37,0x2c,0x37, + 0x2e,0x31,0x39,0x39,0x2c,0x31,0x2e,0x34,0x34,0x37, + 0x68,0x38,0x2e,0x34,0x39,0x36,0x63,0x32,0x2e,0x35, + 0x35,0x33,0x2c,0x30,0x2c,0x34,0x2e,0x39,0x35,0x32, + 0x2d,0x30,0x2e,0x34,0x38,0x32,0x2c,0x37,0x2e,0x31, + 0x39,0x38,0x2d,0x31,0x2e,0x34,0x34,0x37,0x63,0x32, + 0x2e,0x32,0x34,0x32,0x2d,0x30,0x2e,0x39,0x36,0x38, + 0x2c,0x34,0x2e,0x31,0x39,0x38,0x2d,0x32,0x2e,0x32, + 0x38,0x31,0x2c,0x35,0x2e,0x38,0x35,0x33,0x2d,0x33, + 0x2e,0x39,0x33,0x38,0x0a,0x09,0x09,0x63,0x31,0x2e, + 0x36,0x36,0x31,0x2d,0x31,0x2e,0x36,0x35,0x37,0x2c, + 0x32,0x2e,0x39,0x37,0x2d,0x33,0x2e,0x36,0x30,0x39, + 0x2c,0x33,0x2e,0x39,0x33,0x38,0x2d,0x35,0x2e,0x38, + 0x35,0x32,0x63,0x30,0x2e,0x39,0x36,0x39,0x2d,0x32, + 0x2e,0x32,0x34,0x36,0x2c,0x31,0x2e,0x34,0x35,0x2d, + 0x34,0x2e,0x36,0x34,0x36,0x2c,0x31,0x2e,0x34,0x35, + 0x2d,0x37,0x2e,0x32,0x30,0x32,0x4c,0x39,0x33,0x37, + 0x2e,0x39,0x30,0x37,0x2c,0x32,0x39,0x32,0x2e,0x31, + 0x36,0x37,0x4c,0x39,0x33,0x37,0x2e,0x39,0x30,0x37, + 0x2c,0x32,0x39,0x32,0x2e,0x31,0x36,0x37,0x7a,0x22, + 0x2f,0x3e,0x0a,0x09,0x3c,0x70,0x61,0x74,0x68,0x20, + 0x64,0x3d,0x22,0x4d,0x31,0x30,0x31,0x34,0x2e,0x37, + 0x37,0x32,0x2c,0x33,0x34,0x33,0x2e,0x35,0x35,0x63, + 0x2d,0x33,0x2e,0x38,0x36,0x35,0x2c,0x30,0x2d,0x37, + 0x2e,0x35,0x30,0x39,0x2d,0x30,0x2e,0x37,0x32,0x34, + 0x2d,0x31,0x30,0x2e,0x39,0x33,0x31,0x2d,0x32,0x2e, + 0x31,0x37,0x34,0x63,0x2d,0x33,0x2e,0x34,0x31,0x38, + 0x2d,0x31,0x2e,0x34,0x35,0x31,0x2d,0x36,0x2e,0x33, + 0x38,0x39,0x2d,0x33,0x2e,0x34,0x35,0x36,0x2d,0x38, + 0x2e,0x39,0x30,0x39,0x2d,0x36,0x2e,0x30,0x30,0x39, + 0x0a,0x09,0x09,0x63,0x2d,0x32,0x2e,0x35,0x32,0x2d, + 0x32,0x2e,0x35,0x35,0x37,0x2d,0x34,0x2e,0x35,0x32, + 0x34,0x2d,0x35,0x2e,0x35,0x32,0x36,0x2d,0x36,0x2e, + 0x30,0x30,0x39,0x2d,0x38,0x2e,0x39,0x31,0x63,0x2d, + 0x31,0x2e,0x34,0x38,0x35,0x2d,0x33,0x2e,0x33,0x38, + 0x33,0x2d,0x32,0x2e,0x32,0x32,0x35,0x2d,0x37,0x2e, + 0x30,0x30,0x37,0x2d,0x32,0x2e,0x32,0x32,0x35,0x2d, + 0x31,0x30,0x2e,0x38,0x37,0x36,0x56,0x32,0x34,0x39, + 0x2e,0x35,0x39,0x68,0x2d,0x31,0x39,0x2e,0x30,0x36, + 0x32,0x76,0x2d,0x31,0x32,0x2e,0x31,0x31,0x36,0x68, + 0x31,0x39,0x2e,0x30,0x36,0x32,0x76,0x2d,0x32,0x35, + 0x2e,0x34,0x38,0x35,0x6c,0x31,0x32,0x2e,0x37,0x34, + 0x2d,0x32,0x2e,0x30,0x37,0x0a,0x09,0x09,0x76,0x32, 0x37,0x2e,0x35,0x35,0x35,0x68,0x32,0x36,0x2e,0x39, 0x33,0x36,0x76,0x31,0x32,0x2e,0x31,0x31,0x36,0x68, 0x2d,0x32,0x36,0x2e,0x39,0x33,0x36,0x76,0x36,0x36, @@ -939,109 +930,108 @@ const unsigned char splash_svg_data[17935] = { 0x38,0x38,0x2c,0x31,0x2e,0x38,0x33,0x33,0x2c,0x31, 0x2e,0x38,0x37,0x39,0x2c,0x33,0x2e,0x34,0x33,0x37, 0x2c,0x33,0x2e,0x32,0x36,0x31,0x2c,0x34,0x2e,0x38, - 0x31,0x38,0x0d,0x0a,0x09,0x09,0x63,0x31,0x2e,0x33, - 0x38,0x32,0x2c,0x31,0x2e,0x33,0x38,0x31,0x2c,0x33, - 0x2e,0x30,0x30,0x34,0x2c,0x32,0x2e,0x34,0x37,0x32, - 0x2c,0x34,0x2e,0x38,0x36,0x38,0x2c,0x33,0x2e,0x32, - 0x36,0x34,0x63,0x31,0x2e,0x38,0x36,0x36,0x2c,0x30, - 0x2e,0x37,0x39,0x32,0x2c,0x33,0x2e,0x38,0x36,0x34, - 0x2c,0x31,0x2e,0x31,0x38,0x39,0x2c,0x36,0x2e,0x30, - 0x30,0x39,0x2c,0x31,0x2e,0x31,0x38,0x39,0x68,0x31, - 0x31,0x2e,0x36,0x30,0x34,0x76,0x31,0x32,0x2e,0x31, - 0x32,0x31,0x4c,0x31,0x30,0x31,0x34,0x2e,0x37,0x37, - 0x32,0x2c,0x33,0x34,0x33,0x2e,0x35,0x35,0x4c,0x31, - 0x30,0x31,0x34,0x2e,0x37,0x37,0x32,0x2c,0x33,0x34, - 0x33,0x2e,0x35,0x35,0x7a,0x22,0x2f,0x3e,0x0d,0x0a, - 0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x64,0x3d,0x22, - 0x4d,0x31,0x30,0x35,0x32,0x2e,0x39,0x39,0x36,0x2c, - 0x32,0x31,0x31,0x2e,0x39,0x38,0x39,0x56,0x31,0x39, - 0x35,0x68,0x31,0x34,0x2e,0x38,0x31,0x35,0x76,0x31, - 0x36,0x2e,0x39,0x38,0x39,0x48,0x31,0x30,0x35,0x32, - 0x2e,0x39,0x39,0x36,0x7a,0x20,0x4d,0x31,0x30,0x35, - 0x34,0x2e,0x30,0x33,0x33,0x2c,0x33,0x34,0x33,0x2e, - 0x35,0x35,0x56,0x32,0x33,0x37,0x2e,0x34,0x37,0x34, - 0x68,0x31,0x32,0x2e,0x37,0x34,0x31,0x56,0x33,0x34, - 0x33,0x2e,0x35,0x35,0x48,0x31,0x30,0x35,0x34,0x2e, - 0x30,0x33,0x33,0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x09, - 0x3c,0x70,0x61,0x74,0x68,0x20,0x64,0x3d,0x22,0x4d, + 0x31,0x38,0x0a,0x09,0x09,0x63,0x31,0x2e,0x33,0x38, + 0x32,0x2c,0x31,0x2e,0x33,0x38,0x31,0x2c,0x33,0x2e, + 0x30,0x30,0x34,0x2c,0x32,0x2e,0x34,0x37,0x32,0x2c, + 0x34,0x2e,0x38,0x36,0x38,0x2c,0x33,0x2e,0x32,0x36, + 0x34,0x63,0x31,0x2e,0x38,0x36,0x36,0x2c,0x30,0x2e, + 0x37,0x39,0x32,0x2c,0x33,0x2e,0x38,0x36,0x34,0x2c, + 0x31,0x2e,0x31,0x38,0x39,0x2c,0x36,0x2e,0x30,0x30, + 0x39,0x2c,0x31,0x2e,0x31,0x38,0x39,0x68,0x31,0x31, + 0x2e,0x36,0x30,0x34,0x76,0x31,0x32,0x2e,0x31,0x32, + 0x31,0x4c,0x31,0x30,0x31,0x34,0x2e,0x37,0x37,0x32, + 0x2c,0x33,0x34,0x33,0x2e,0x35,0x35,0x4c,0x31,0x30, + 0x31,0x34,0x2e,0x37,0x37,0x32,0x2c,0x33,0x34,0x33, + 0x2e,0x35,0x35,0x7a,0x22,0x2f,0x3e,0x0a,0x09,0x3c, + 0x70,0x61,0x74,0x68,0x20,0x64,0x3d,0x22,0x4d,0x31, + 0x30,0x35,0x32,0x2e,0x39,0x39,0x36,0x2c,0x32,0x31, + 0x31,0x2e,0x39,0x38,0x39,0x56,0x31,0x39,0x35,0x68, + 0x31,0x34,0x2e,0x38,0x31,0x35,0x76,0x31,0x36,0x2e, + 0x39,0x38,0x39,0x48,0x31,0x30,0x35,0x32,0x2e,0x39, + 0x39,0x36,0x7a,0x20,0x4d,0x31,0x30,0x35,0x34,0x2e, + 0x30,0x33,0x33,0x2c,0x33,0x34,0x33,0x2e,0x35,0x35, + 0x56,0x32,0x33,0x37,0x2e,0x34,0x37,0x34,0x68,0x31, + 0x32,0x2e,0x37,0x34,0x31,0x56,0x33,0x34,0x33,0x2e, + 0x35,0x35,0x48,0x31,0x30,0x35,0x34,0x2e,0x30,0x33, + 0x33,0x7a,0x22,0x2f,0x3e,0x0a,0x09,0x3c,0x70,0x61, + 0x74,0x68,0x20,0x64,0x3d,0x22,0x4d,0x31,0x31,0x36, + 0x34,0x2e,0x39,0x33,0x2c,0x33,0x32,0x36,0x2e,0x35, + 0x36,0x32,0x63,0x2d,0x31,0x2e,0x36,0x32,0x33,0x2c, + 0x33,0x2e,0x38,0x2d,0x33,0x2e,0x38,0x35,0x32,0x2c, + 0x37,0x2e,0x31,0x31,0x35,0x2d,0x36,0x2e,0x36,0x37, + 0x39,0x2c,0x39,0x2e,0x39,0x34,0x33,0x63,0x2d,0x32, + 0x2e,0x38,0x33,0x37,0x2c,0x32,0x2e,0x38,0x33,0x36, + 0x2d,0x36,0x2e,0x31,0x35,0x2c,0x35,0x2e,0x30,0x36, + 0x2d,0x39,0x2e,0x39,0x35,0x2c,0x36,0x2e,0x36,0x38, + 0x32,0x0a,0x09,0x09,0x63,0x2d,0x33,0x2e,0x37,0x39, + 0x37,0x2c,0x31,0x2e,0x36,0x32,0x33,0x2d,0x37,0x2e, + 0x38,0x33,0x38,0x2c,0x32,0x2e,0x34,0x33,0x34,0x2d, + 0x31,0x32,0x2e,0x31,0x31,0x37,0x2c,0x32,0x2e,0x34, + 0x33,0x34,0x68,0x2d,0x38,0x2e,0x34,0x39,0x36,0x63, + 0x2d,0x34,0x2e,0x32,0x38,0x32,0x2c,0x30,0x2d,0x38, + 0x2e,0x33,0x31,0x39,0x2d,0x30,0x2e,0x38,0x31,0x32, + 0x2d,0x31,0x32,0x2e,0x31,0x31,0x36,0x2d,0x32,0x2e, + 0x34,0x33,0x34,0x63,0x2d,0x33,0x2e,0x38,0x30,0x35, + 0x2d,0x31,0x2e,0x36,0x32,0x33,0x2d,0x37,0x2e,0x31, + 0x31,0x39,0x2d,0x33,0x2e,0x38,0x34,0x36,0x2d,0x39, + 0x2e,0x39,0x34,0x36,0x2d,0x36,0x2e,0x36,0x38,0x32, + 0x0a,0x09,0x09,0x63,0x2d,0x32,0x2e,0x38,0x33,0x37, + 0x2d,0x32,0x2e,0x38,0x32,0x38,0x2d,0x35,0x2e,0x30, + 0x36,0x32,0x2d,0x36,0x2e,0x31,0x34,0x33,0x2d,0x36, + 0x2e,0x36,0x38,0x33,0x2d,0x39,0x2e,0x39,0x34,0x33, + 0x63,0x2d,0x31,0x2e,0x36,0x32,0x37,0x2d,0x33,0x2e, + 0x37,0x39,0x36,0x2d,0x32,0x2e,0x34,0x33,0x35,0x2d, + 0x37,0x2e,0x38,0x33,0x38,0x2d,0x32,0x2e,0x34,0x33, + 0x35,0x2d,0x31,0x32,0x2e,0x31,0x32,0x31,0x76,0x2d, + 0x34,0x37,0x2e,0x38,0x35,0x38,0x63,0x30,0x2d,0x34, + 0x2e,0x32,0x38,0x32,0x2c,0x30,0x2e,0x38,0x30,0x38, + 0x2d,0x38,0x2e,0x33,0x32,0x34,0x2c,0x32,0x2e,0x34, + 0x33,0x35,0x2d,0x31,0x32,0x2e,0x31,0x32,0x0a,0x09, + 0x09,0x63,0x31,0x2e,0x36,0x31,0x39,0x2d,0x33,0x2e, + 0x38,0x30,0x31,0x2c,0x33,0x2e,0x38,0x34,0x36,0x2d, + 0x37,0x2e,0x31,0x31,0x35,0x2c,0x36,0x2e,0x36,0x38, + 0x33,0x2d,0x39,0x2e,0x39,0x34,0x37,0x63,0x32,0x2e, + 0x38,0x32,0x37,0x2d,0x32,0x2e,0x38,0x33,0x33,0x2c, + 0x36,0x2e,0x31,0x34,0x33,0x2d,0x35,0x2e,0x30,0x35, + 0x36,0x2c,0x39,0x2e,0x39,0x34,0x36,0x2d,0x36,0x2e, + 0x36,0x38,0x32,0x63,0x33,0x2e,0x37,0x39,0x37,0x2d, + 0x31,0x2e,0x36,0x31,0x39,0x2c,0x37,0x2e,0x38,0x33, + 0x34,0x2d,0x32,0x2e,0x34,0x33,0x34,0x2c,0x31,0x32, + 0x2e,0x31,0x31,0x36,0x2d,0x32,0x2e,0x34,0x33,0x34, + 0x68,0x38,0x2e,0x34,0x39,0x36,0x0a,0x09,0x09,0x63, + 0x34,0x2e,0x32,0x37,0x39,0x2c,0x30,0x2c,0x38,0x2e, + 0x33,0x32,0x2c,0x30,0x2e,0x38,0x31,0x35,0x2c,0x31, + 0x32,0x2e,0x31,0x31,0x37,0x2c,0x32,0x2e,0x34,0x33, + 0x34,0x63,0x33,0x2e,0x38,0x2c,0x31,0x2e,0x36,0x32, + 0x36,0x2c,0x37,0x2e,0x31,0x31,0x34,0x2c,0x33,0x2e, + 0x38,0x35,0x2c,0x39,0x2e,0x39,0x35,0x2c,0x36,0x2e, + 0x36,0x38,0x32,0x63,0x32,0x2e,0x38,0x32,0x37,0x2c, + 0x32,0x2e,0x38,0x33,0x32,0x2c,0x35,0x2e,0x30,0x35, + 0x36,0x2c,0x36,0x2e,0x31,0x34,0x36,0x2c,0x36,0x2e, + 0x36,0x37,0x39,0x2c,0x39,0x2e,0x39,0x34,0x37,0x0a, + 0x09,0x09,0x63,0x31,0x2e,0x36,0x32,0x32,0x2c,0x33, + 0x2e,0x37,0x39,0x36,0x2c,0x32,0x2e,0x34,0x33,0x34, + 0x2c,0x37,0x2e,0x38,0x33,0x38,0x2c,0x32,0x2e,0x34, + 0x33,0x34,0x2c,0x31,0x32,0x2e,0x31,0x32,0x76,0x34, + 0x37,0x2e,0x38,0x35,0x38,0x43,0x31,0x31,0x36,0x37, + 0x2e,0x33,0x36,0x33,0x2c,0x33,0x31,0x38,0x2e,0x37, + 0x32,0x34,0x2c,0x31,0x31,0x36,0x36,0x2e,0x35,0x35, + 0x32,0x2c,0x33,0x32,0x32,0x2e,0x37,0x36,0x35,0x2c, 0x31,0x31,0x36,0x34,0x2e,0x39,0x33,0x2c,0x33,0x32, - 0x36,0x2e,0x35,0x36,0x32,0x63,0x2d,0x31,0x2e,0x36, - 0x32,0x33,0x2c,0x33,0x2e,0x38,0x2d,0x33,0x2e,0x38, - 0x35,0x32,0x2c,0x37,0x2e,0x31,0x31,0x35,0x2d,0x36, - 0x2e,0x36,0x37,0x39,0x2c,0x39,0x2e,0x39,0x34,0x33, - 0x63,0x2d,0x32,0x2e,0x38,0x33,0x37,0x2c,0x32,0x2e, - 0x38,0x33,0x36,0x2d,0x36,0x2e,0x31,0x35,0x2c,0x35, - 0x2e,0x30,0x36,0x2d,0x39,0x2e,0x39,0x35,0x2c,0x36, - 0x2e,0x36,0x38,0x32,0x0d,0x0a,0x09,0x09,0x63,0x2d, - 0x33,0x2e,0x37,0x39,0x37,0x2c,0x31,0x2e,0x36,0x32, - 0x33,0x2d,0x37,0x2e,0x38,0x33,0x38,0x2c,0x32,0x2e, - 0x34,0x33,0x34,0x2d,0x31,0x32,0x2e,0x31,0x31,0x37, - 0x2c,0x32,0x2e,0x34,0x33,0x34,0x68,0x2d,0x38,0x2e, - 0x34,0x39,0x36,0x63,0x2d,0x34,0x2e,0x32,0x38,0x32, - 0x2c,0x30,0x2d,0x38,0x2e,0x33,0x31,0x39,0x2d,0x30, - 0x2e,0x38,0x31,0x32,0x2d,0x31,0x32,0x2e,0x31,0x31, - 0x36,0x2d,0x32,0x2e,0x34,0x33,0x34,0x63,0x2d,0x33, - 0x2e,0x38,0x30,0x35,0x2d,0x31,0x2e,0x36,0x32,0x33, - 0x2d,0x37,0x2e,0x31,0x31,0x39,0x2d,0x33,0x2e,0x38, - 0x34,0x36,0x2d,0x39,0x2e,0x39,0x34,0x36,0x2d,0x36, - 0x2e,0x36,0x38,0x32,0x0d,0x0a,0x09,0x09,0x63,0x2d, - 0x32,0x2e,0x38,0x33,0x37,0x2d,0x32,0x2e,0x38,0x32, - 0x38,0x2d,0x35,0x2e,0x30,0x36,0x32,0x2d,0x36,0x2e, - 0x31,0x34,0x33,0x2d,0x36,0x2e,0x36,0x38,0x33,0x2d, - 0x39,0x2e,0x39,0x34,0x33,0x63,0x2d,0x31,0x2e,0x36, - 0x32,0x37,0x2d,0x33,0x2e,0x37,0x39,0x36,0x2d,0x32, - 0x2e,0x34,0x33,0x35,0x2d,0x37,0x2e,0x38,0x33,0x38, - 0x2d,0x32,0x2e,0x34,0x33,0x35,0x2d,0x31,0x32,0x2e, - 0x31,0x32,0x31,0x76,0x2d,0x34,0x37,0x2e,0x38,0x35, - 0x38,0x63,0x30,0x2d,0x34,0x2e,0x32,0x38,0x32,0x2c, - 0x30,0x2e,0x38,0x30,0x38,0x2d,0x38,0x2e,0x33,0x32, - 0x34,0x2c,0x32,0x2e,0x34,0x33,0x35,0x2d,0x31,0x32, - 0x2e,0x31,0x32,0x0d,0x0a,0x09,0x09,0x63,0x31,0x2e, - 0x36,0x31,0x39,0x2d,0x33,0x2e,0x38,0x30,0x31,0x2c, - 0x33,0x2e,0x38,0x34,0x36,0x2d,0x37,0x2e,0x31,0x31, - 0x35,0x2c,0x36,0x2e,0x36,0x38,0x33,0x2d,0x39,0x2e, - 0x39,0x34,0x37,0x63,0x32,0x2e,0x38,0x32,0x37,0x2d, - 0x32,0x2e,0x38,0x33,0x33,0x2c,0x36,0x2e,0x31,0x34, - 0x33,0x2d,0x35,0x2e,0x30,0x35,0x36,0x2c,0x39,0x2e, - 0x39,0x34,0x36,0x2d,0x36,0x2e,0x36,0x38,0x32,0x63, - 0x33,0x2e,0x37,0x39,0x37,0x2d,0x31,0x2e,0x36,0x31, - 0x39,0x2c,0x37,0x2e,0x38,0x33,0x34,0x2d,0x32,0x2e, - 0x34,0x33,0x34,0x2c,0x31,0x32,0x2e,0x31,0x31,0x36, - 0x2d,0x32,0x2e,0x34,0x33,0x34,0x68,0x38,0x2e,0x34, - 0x39,0x36,0x0d,0x0a,0x09,0x09,0x63,0x34,0x2e,0x32, - 0x37,0x39,0x2c,0x30,0x2c,0x38,0x2e,0x33,0x32,0x2c, - 0x30,0x2e,0x38,0x31,0x35,0x2c,0x31,0x32,0x2e,0x31, - 0x31,0x37,0x2c,0x32,0x2e,0x34,0x33,0x34,0x63,0x33, - 0x2e,0x38,0x2c,0x31,0x2e,0x36,0x32,0x36,0x2c,0x37, - 0x2e,0x31,0x31,0x34,0x2c,0x33,0x2e,0x38,0x35,0x2c, - 0x39,0x2e,0x39,0x35,0x2c,0x36,0x2e,0x36,0x38,0x32, - 0x63,0x32,0x2e,0x38,0x32,0x37,0x2c,0x32,0x2e,0x38, - 0x33,0x32,0x2c,0x35,0x2e,0x30,0x35,0x36,0x2c,0x36, - 0x2e,0x31,0x34,0x36,0x2c,0x36,0x2e,0x36,0x37,0x39, - 0x2c,0x39,0x2e,0x39,0x34,0x37,0x0d,0x0a,0x09,0x09, - 0x63,0x31,0x2e,0x36,0x32,0x32,0x2c,0x33,0x2e,0x37, - 0x39,0x36,0x2c,0x32,0x2e,0x34,0x33,0x34,0x2c,0x37, - 0x2e,0x38,0x33,0x38,0x2c,0x32,0x2e,0x34,0x33,0x34, - 0x2c,0x31,0x32,0x2e,0x31,0x32,0x76,0x34,0x37,0x2e, - 0x38,0x35,0x38,0x43,0x31,0x31,0x36,0x37,0x2e,0x33, - 0x36,0x33,0x2c,0x33,0x31,0x38,0x2e,0x37,0x32,0x34, - 0x2c,0x31,0x31,0x36,0x36,0x2e,0x35,0x35,0x32,0x2c, - 0x33,0x32,0x32,0x2e,0x37,0x36,0x35,0x2c,0x31,0x31, - 0x36,0x34,0x2e,0x39,0x33,0x2c,0x33,0x32,0x36,0x2e, - 0x35,0x36,0x32,0x7a,0x20,0x4d,0x31,0x31,0x35,0x34, - 0x2e,0x36,0x32,0x32,0x2c,0x32,0x36,0x35,0x2e,0x38, - 0x35,0x35,0x0d,0x0a,0x09,0x09,0x63,0x30,0x2d,0x32, - 0x2e,0x35,0x35,0x33,0x2d,0x30,0x2e,0x34,0x38,0x31, - 0x2d,0x34,0x2e,0x39,0x35,0x32,0x2d,0x31,0x2e,0x34, - 0x34,0x39,0x2d,0x37,0x2e,0x31,0x39,0x39,0x63,0x2d, - 0x30,0x2e,0x39,0x37,0x2d,0x32,0x2e,0x32,0x34,0x33, - 0x2d,0x32,0x2e,0x32,0x37,0x37,0x2d,0x34,0x2e,0x31, - 0x39,0x34,0x2d,0x33,0x2e,0x39,0x33,0x38,0x2d,0x35, - 0x2e,0x38,0x35,0x32,0x63,0x2d,0x31,0x2e,0x36,0x35, - 0x33,0x2d,0x31,0x2e,0x36,0x35,0x37,0x2d,0x33,0x2e, - 0x36,0x30,0x38,0x2d,0x32,0x2e,0x39,0x37,0x2d,0x35, - 0x2e,0x38,0x35,0x32,0x2d,0x33,0x2e,0x39,0x33,0x38, - 0x0d,0x0a,0x09,0x09,0x63,0x2d,0x32,0x2e,0x32,0x34, + 0x36,0x2e,0x35,0x36,0x32,0x7a,0x20,0x4d,0x31,0x31, + 0x35,0x34,0x2e,0x36,0x32,0x32,0x2c,0x32,0x36,0x35, + 0x2e,0x38,0x35,0x35,0x0a,0x09,0x09,0x63,0x30,0x2d, + 0x32,0x2e,0x35,0x35,0x33,0x2d,0x30,0x2e,0x34,0x38, + 0x31,0x2d,0x34,0x2e,0x39,0x35,0x32,0x2d,0x31,0x2e, + 0x34,0x34,0x39,0x2d,0x37,0x2e,0x31,0x39,0x39,0x63, + 0x2d,0x30,0x2e,0x39,0x37,0x2d,0x32,0x2e,0x32,0x34, + 0x33,0x2d,0x32,0x2e,0x32,0x37,0x37,0x2d,0x34,0x2e, + 0x31,0x39,0x34,0x2d,0x33,0x2e,0x39,0x33,0x38,0x2d, + 0x35,0x2e,0x38,0x35,0x32,0x63,0x2d,0x31,0x2e,0x36, + 0x35,0x33,0x2d,0x31,0x2e,0x36,0x35,0x37,0x2d,0x33, + 0x2e,0x36,0x30,0x38,0x2d,0x32,0x2e,0x39,0x37,0x2d, + 0x35,0x2e,0x38,0x35,0x32,0x2d,0x33,0x2e,0x39,0x33, + 0x38,0x0a,0x09,0x09,0x63,0x2d,0x32,0x2e,0x32,0x34, 0x36,0x2d,0x30,0x2e,0x39,0x36,0x34,0x2d,0x34,0x2e, 0x36,0x34,0x36,0x2d,0x31,0x2e,0x34,0x35,0x2d,0x37, 0x2e,0x31,0x39,0x39,0x2d,0x31,0x2e,0x34,0x35,0x68, @@ -1052,210 +1042,208 @@ const unsigned char splash_svg_data[17935] = { 0x32,0x2e,0x32,0x34,0x37,0x2c,0x30,0x2e,0x39,0x36, 0x39,0x2d,0x34,0x2e,0x31,0x39,0x34,0x2c,0x32,0x2e, 0x32,0x38,0x31,0x2d,0x35,0x2e,0x38,0x35,0x32,0x2c, - 0x33,0x2e,0x39,0x33,0x38,0x0d,0x0a,0x09,0x09,0x63, - 0x2d,0x31,0x2e,0x36,0x36,0x31,0x2c,0x31,0x2e,0x36, - 0x35,0x37,0x2d,0x32,0x2e,0x39,0x37,0x31,0x2c,0x33, - 0x2e,0x36,0x30,0x39,0x2d,0x33,0x2e,0x39,0x33,0x38, - 0x2c,0x35,0x2e,0x38,0x35,0x32,0x63,0x2d,0x30,0x2e, - 0x39,0x36,0x39,0x2c,0x32,0x2e,0x32,0x34,0x37,0x2d, - 0x31,0x2e,0x34,0x35,0x2c,0x34,0x2e,0x36,0x34,0x36, - 0x2d,0x31,0x2e,0x34,0x35,0x2c,0x37,0x2e,0x31,0x39, - 0x39,0x76,0x34,0x39,0x2e,0x33,0x30,0x39,0x63,0x30, - 0x2c,0x32,0x2e,0x35,0x35,0x36,0x2c,0x30,0x2e,0x34, - 0x38,0x31,0x2c,0x34,0x2e,0x39,0x35,0x36,0x2c,0x31, - 0x2e,0x34,0x35,0x2c,0x37,0x2e,0x32,0x30,0x32,0x0d, - 0x0a,0x09,0x09,0x63,0x30,0x2e,0x39,0x36,0x38,0x2c, - 0x32,0x2e,0x32,0x34,0x33,0x2c,0x32,0x2e,0x32,0x37, - 0x37,0x2c,0x34,0x2e,0x31,0x39,0x35,0x2c,0x33,0x2e, - 0x39,0x33,0x38,0x2c,0x35,0x2e,0x38,0x35,0x32,0x63, - 0x31,0x2e,0x36,0x35,0x36,0x2c,0x31,0x2e,0x36,0x35, - 0x37,0x2c,0x33,0x2e,0x36,0x30,0x34,0x2c,0x32,0x2e, - 0x39,0x37,0x2c,0x35,0x2e,0x38,0x35,0x32,0x2c,0x33, - 0x2e,0x39,0x33,0x38,0x63,0x32,0x2e,0x32,0x34,0x32, - 0x2c,0x30,0x2e,0x39,0x36,0x34,0x2c,0x34,0x2e,0x36, - 0x34,0x33,0x2c,0x31,0x2e,0x34,0x34,0x37,0x2c,0x37, - 0x2e,0x31,0x39,0x38,0x2c,0x31,0x2e,0x34,0x34,0x37, - 0x68,0x38,0x2e,0x34,0x39,0x36,0x0d,0x0a,0x09,0x09, - 0x63,0x32,0x2e,0x35,0x35,0x33,0x2c,0x30,0x2c,0x34, - 0x2e,0x39,0x35,0x33,0x2d,0x30,0x2e,0x34,0x38,0x32, - 0x2c,0x37,0x2e,0x31,0x39,0x39,0x2d,0x31,0x2e,0x34, - 0x34,0x37,0x63,0x32,0x2e,0x32,0x34,0x33,0x2d,0x30, - 0x2e,0x39,0x36,0x38,0x2c,0x34,0x2e,0x31,0x39,0x37, - 0x2d,0x32,0x2e,0x32,0x38,0x31,0x2c,0x35,0x2e,0x38, - 0x35,0x32,0x2d,0x33,0x2e,0x39,0x33,0x38,0x63,0x31, + 0x33,0x2e,0x39,0x33,0x38,0x0a,0x09,0x09,0x63,0x2d, + 0x31,0x2e,0x36,0x36,0x31,0x2c,0x31,0x2e,0x36,0x35, + 0x37,0x2d,0x32,0x2e,0x39,0x37,0x31,0x2c,0x33,0x2e, + 0x36,0x30,0x39,0x2d,0x33,0x2e,0x39,0x33,0x38,0x2c, + 0x35,0x2e,0x38,0x35,0x32,0x63,0x2d,0x30,0x2e,0x39, + 0x36,0x39,0x2c,0x32,0x2e,0x32,0x34,0x37,0x2d,0x31, + 0x2e,0x34,0x35,0x2c,0x34,0x2e,0x36,0x34,0x36,0x2d, + 0x31,0x2e,0x34,0x35,0x2c,0x37,0x2e,0x31,0x39,0x39, + 0x76,0x34,0x39,0x2e,0x33,0x30,0x39,0x63,0x30,0x2c, + 0x32,0x2e,0x35,0x35,0x36,0x2c,0x30,0x2e,0x34,0x38, + 0x31,0x2c,0x34,0x2e,0x39,0x35,0x36,0x2c,0x31,0x2e, + 0x34,0x35,0x2c,0x37,0x2e,0x32,0x30,0x32,0x0a,0x09, + 0x09,0x63,0x30,0x2e,0x39,0x36,0x38,0x2c,0x32,0x2e, + 0x32,0x34,0x33,0x2c,0x32,0x2e,0x32,0x37,0x37,0x2c, + 0x34,0x2e,0x31,0x39,0x35,0x2c,0x33,0x2e,0x39,0x33, + 0x38,0x2c,0x35,0x2e,0x38,0x35,0x32,0x63,0x31,0x2e, + 0x36,0x35,0x36,0x2c,0x31,0x2e,0x36,0x35,0x37,0x2c, + 0x33,0x2e,0x36,0x30,0x34,0x2c,0x32,0x2e,0x39,0x37, + 0x2c,0x35,0x2e,0x38,0x35,0x32,0x2c,0x33,0x2e,0x39, + 0x33,0x38,0x63,0x32,0x2e,0x32,0x34,0x32,0x2c,0x30, + 0x2e,0x39,0x36,0x34,0x2c,0x34,0x2e,0x36,0x34,0x33, + 0x2c,0x31,0x2e,0x34,0x34,0x37,0x2c,0x37,0x2e,0x31, + 0x39,0x38,0x2c,0x31,0x2e,0x34,0x34,0x37,0x68,0x38, + 0x2e,0x34,0x39,0x36,0x0a,0x09,0x09,0x63,0x32,0x2e, + 0x35,0x35,0x33,0x2c,0x30,0x2c,0x34,0x2e,0x39,0x35, + 0x33,0x2d,0x30,0x2e,0x34,0x38,0x32,0x2c,0x37,0x2e, + 0x31,0x39,0x39,0x2d,0x31,0x2e,0x34,0x34,0x37,0x63, + 0x32,0x2e,0x32,0x34,0x33,0x2d,0x30,0x2e,0x39,0x36, + 0x38,0x2c,0x34,0x2e,0x31,0x39,0x37,0x2d,0x32,0x2e, + 0x32,0x38,0x31,0x2c,0x35,0x2e,0x38,0x35,0x32,0x2d, + 0x33,0x2e,0x39,0x33,0x38,0x63,0x31,0x2e,0x36,0x36, + 0x31,0x2d,0x31,0x2e,0x36,0x35,0x37,0x2c,0x32,0x2e, + 0x39,0x37,0x2d,0x33,0x2e,0x36,0x30,0x39,0x2c,0x33, + 0x2e,0x39,0x33,0x38,0x2d,0x35,0x2e,0x38,0x35,0x32, + 0x0a,0x09,0x09,0x63,0x30,0x2e,0x39,0x36,0x38,0x2d, + 0x32,0x2e,0x32,0x34,0x36,0x2c,0x31,0x2e,0x34,0x34, + 0x39,0x2d,0x34,0x2e,0x36,0x34,0x36,0x2c,0x31,0x2e, + 0x34,0x34,0x39,0x2d,0x37,0x2e,0x32,0x30,0x32,0x56, + 0x32,0x36,0x35,0x2e,0x38,0x35,0x35,0x7a,0x22,0x2f, + 0x3e,0x0a,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x64, + 0x3d,0x22,0x4d,0x31,0x32,0x35,0x30,0x2e,0x39,0x36, + 0x34,0x2c,0x33,0x34,0x33,0x2e,0x35,0x35,0x76,0x2d, + 0x37,0x37,0x2e,0x36,0x39,0x35,0x63,0x30,0x2d,0x32, + 0x2e,0x35,0x35,0x33,0x2d,0x30,0x2e,0x34,0x38,0x36, + 0x2d,0x34,0x2e,0x39,0x35,0x32,0x2d,0x31,0x2e,0x34, + 0x35,0x31,0x2d,0x37,0x2e,0x31,0x39,0x39,0x63,0x2d, + 0x30,0x2e,0x39,0x36,0x39,0x2d,0x32,0x2e,0x32,0x34, + 0x33,0x2d,0x32,0x2e,0x32,0x38,0x2d,0x34,0x2e,0x31, + 0x39,0x34,0x2d,0x33,0x2e,0x39,0x33,0x35,0x2d,0x35, + 0x2e,0x38,0x35,0x32,0x0a,0x09,0x09,0x63,0x2d,0x31, 0x2e,0x36,0x36,0x31,0x2d,0x31,0x2e,0x36,0x35,0x37, - 0x2c,0x32,0x2e,0x39,0x37,0x2d,0x33,0x2e,0x36,0x30, - 0x39,0x2c,0x33,0x2e,0x39,0x33,0x38,0x2d,0x35,0x2e, - 0x38,0x35,0x32,0x0d,0x0a,0x09,0x09,0x63,0x30,0x2e, - 0x39,0x36,0x38,0x2d,0x32,0x2e,0x32,0x34,0x36,0x2c, - 0x31,0x2e,0x34,0x34,0x39,0x2d,0x34,0x2e,0x36,0x34, - 0x36,0x2c,0x31,0x2e,0x34,0x34,0x39,0x2d,0x37,0x2e, - 0x32,0x30,0x32,0x56,0x32,0x36,0x35,0x2e,0x38,0x35, - 0x35,0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x09,0x3c,0x70, - 0x61,0x74,0x68,0x20,0x64,0x3d,0x22,0x4d,0x31,0x32, - 0x35,0x30,0x2e,0x39,0x36,0x34,0x2c,0x33,0x34,0x33, - 0x2e,0x35,0x35,0x76,0x2d,0x37,0x37,0x2e,0x36,0x39, - 0x35,0x63,0x30,0x2d,0x32,0x2e,0x35,0x35,0x33,0x2d, - 0x30,0x2e,0x34,0x38,0x36,0x2d,0x34,0x2e,0x39,0x35, - 0x32,0x2d,0x31,0x2e,0x34,0x35,0x31,0x2d,0x37,0x2e, - 0x31,0x39,0x39,0x63,0x2d,0x30,0x2e,0x39,0x36,0x39, - 0x2d,0x32,0x2e,0x32,0x34,0x33,0x2d,0x32,0x2e,0x32, - 0x38,0x2d,0x34,0x2e,0x31,0x39,0x34,0x2d,0x33,0x2e, - 0x39,0x33,0x35,0x2d,0x35,0x2e,0x38,0x35,0x32,0x0d, - 0x0a,0x09,0x09,0x63,0x2d,0x31,0x2e,0x36,0x36,0x31, - 0x2d,0x31,0x2e,0x36,0x35,0x37,0x2d,0x33,0x2e,0x36, - 0x31,0x32,0x2d,0x32,0x2e,0x39,0x37,0x2d,0x35,0x2e, - 0x38,0x35,0x35,0x2d,0x33,0x2e,0x39,0x33,0x38,0x63, - 0x2d,0x32,0x2e,0x32,0x34,0x32,0x2d,0x30,0x2e,0x39, - 0x36,0x34,0x2d,0x34,0x2e,0x36,0x34,0x36,0x2d,0x31, - 0x2e,0x34,0x35,0x2d,0x37,0x2e,0x31,0x39,0x38,0x2d, - 0x31,0x2e,0x34,0x35,0x68,0x2d,0x38,0x2e,0x34,0x39, - 0x32,0x63,0x2d,0x32,0x2e,0x35,0x35,0x37,0x2c,0x30, - 0x2d,0x34,0x2e,0x39,0x36,0x2c,0x30,0x2e,0x34,0x38, - 0x36,0x2d,0x37,0x2e,0x32,0x30,0x33,0x2c,0x31,0x2e, - 0x34,0x35,0x0d,0x0a,0x09,0x09,0x63,0x2d,0x32,0x2e, - 0x32,0x34,0x31,0x2c,0x30,0x2e,0x39,0x36,0x39,0x2d, - 0x34,0x2e,0x31,0x39,0x33,0x2c,0x32,0x2e,0x32,0x38, - 0x31,0x2d,0x35,0x2e,0x38,0x35,0x34,0x2c,0x33,0x2e, - 0x39,0x33,0x38,0x63,0x2d,0x31,0x2e,0x36,0x35,0x33, - 0x2c,0x31,0x2e,0x36,0x35,0x37,0x2d,0x32,0x2e,0x39, - 0x37,0x2c,0x33,0x2e,0x36,0x30,0x39,0x2d,0x33,0x2e, - 0x39,0x33,0x35,0x2c,0x35,0x2e,0x38,0x35,0x32,0x63, - 0x2d,0x30,0x2e,0x39,0x36,0x39,0x2c,0x32,0x2e,0x32, - 0x34,0x37,0x2d,0x31,0x2e,0x34,0x35,0x2c,0x34,0x2e, - 0x36,0x34,0x36,0x2d,0x31,0x2e,0x34,0x35,0x2c,0x37, - 0x2e,0x31,0x39,0x39,0x76,0x37,0x37,0x2e,0x36,0x39, - 0x35,0x68,0x2d,0x31,0x32,0x2e,0x37,0x34,0x0d,0x0a, - 0x09,0x09,0x56,0x32,0x33,0x37,0x2e,0x34,0x37,0x34, - 0x68,0x34,0x2e,0x32,0x34,0x38,0x6c,0x36,0x2e,0x39, - 0x33,0x38,0x2c,0x31,0x30,0x2e,0x37,0x37,0x33,0x63, - 0x32,0x2e,0x39,0x2d,0x33,0x2e,0x39,0x33,0x38,0x2c, - 0x36,0x2e,0x35,0x34,0x31,0x2d,0x37,0x2e,0x30,0x36, - 0x31,0x2c,0x31,0x30,0x2e,0x39,0x33,0x31,0x2d,0x39, - 0x2e,0x33,0x37,0x36,0x63,0x34,0x2e,0x33,0x38,0x32, - 0x2d,0x32,0x2e,0x33,0x31,0x32,0x2c,0x39,0x2e,0x31, - 0x36,0x36,0x2d,0x33,0x2e,0x34,0x37,0x31,0x2c,0x31, - 0x34,0x2e,0x33,0x34,0x38,0x2d,0x33,0x2e,0x34,0x37, - 0x31,0x68,0x33,0x2e,0x32,0x31,0x31,0x0d,0x0a,0x09, - 0x09,0x63,0x34,0x2e,0x32,0x38,0x32,0x2c,0x30,0x2c, - 0x38,0x2e,0x33,0x32,0x2c,0x30,0x2e,0x38,0x31,0x35, - 0x2c,0x31,0x32,0x2e,0x31,0x32,0x2c,0x32,0x2e,0x34, - 0x33,0x34,0x63,0x33,0x2e,0x37,0x39,0x37,0x2c,0x31, - 0x2e,0x36,0x32,0x36,0x2c,0x37,0x2e,0x31,0x31,0x31, - 0x2c,0x33,0x2e,0x38,0x35,0x2c,0x39,0x2e,0x39,0x34, - 0x33,0x2c,0x36,0x2e,0x36,0x38,0x32,0x73,0x35,0x2e, - 0x30,0x36,0x2c,0x36,0x2e,0x31,0x34,0x36,0x2c,0x36, - 0x2e,0x36,0x38,0x32,0x2c,0x39,0x2e,0x39,0x34,0x37, - 0x63,0x31,0x2e,0x36,0x32,0x33,0x2c,0x33,0x2e,0x37, - 0x39,0x36,0x2c,0x32,0x2e,0x34,0x33,0x36,0x2c,0x37, - 0x2e,0x38,0x33,0x38,0x2c,0x32,0x2e,0x34,0x33,0x36, - 0x2c,0x31,0x32,0x2e,0x31,0x32,0x0d,0x0a,0x09,0x09, + 0x2d,0x33,0x2e,0x36,0x31,0x32,0x2d,0x32,0x2e,0x39, + 0x37,0x2d,0x35,0x2e,0x38,0x35,0x35,0x2d,0x33,0x2e, + 0x39,0x33,0x38,0x63,0x2d,0x32,0x2e,0x32,0x34,0x32, + 0x2d,0x30,0x2e,0x39,0x36,0x34,0x2d,0x34,0x2e,0x36, + 0x34,0x36,0x2d,0x31,0x2e,0x34,0x35,0x2d,0x37,0x2e, + 0x31,0x39,0x38,0x2d,0x31,0x2e,0x34,0x35,0x68,0x2d, + 0x38,0x2e,0x34,0x39,0x32,0x63,0x2d,0x32,0x2e,0x35, + 0x35,0x37,0x2c,0x30,0x2d,0x34,0x2e,0x39,0x36,0x2c, + 0x30,0x2e,0x34,0x38,0x36,0x2d,0x37,0x2e,0x32,0x30, + 0x33,0x2c,0x31,0x2e,0x34,0x35,0x0a,0x09,0x09,0x63, + 0x2d,0x32,0x2e,0x32,0x34,0x31,0x2c,0x30,0x2e,0x39, + 0x36,0x39,0x2d,0x34,0x2e,0x31,0x39,0x33,0x2c,0x32, + 0x2e,0x32,0x38,0x31,0x2d,0x35,0x2e,0x38,0x35,0x34, + 0x2c,0x33,0x2e,0x39,0x33,0x38,0x63,0x2d,0x31,0x2e, + 0x36,0x35,0x33,0x2c,0x31,0x2e,0x36,0x35,0x37,0x2d, + 0x32,0x2e,0x39,0x37,0x2c,0x33,0x2e,0x36,0x30,0x39, + 0x2d,0x33,0x2e,0x39,0x33,0x35,0x2c,0x35,0x2e,0x38, + 0x35,0x32,0x63,0x2d,0x30,0x2e,0x39,0x36,0x39,0x2c, + 0x32,0x2e,0x32,0x34,0x37,0x2d,0x31,0x2e,0x34,0x35, + 0x2c,0x34,0x2e,0x36,0x34,0x36,0x2d,0x31,0x2e,0x34, + 0x35,0x2c,0x37,0x2e,0x31,0x39,0x39,0x76,0x37,0x37, + 0x2e,0x36,0x39,0x35,0x68,0x2d,0x31,0x32,0x2e,0x37, + 0x34,0x0a,0x09,0x09,0x56,0x32,0x33,0x37,0x2e,0x34, + 0x37,0x34,0x68,0x34,0x2e,0x32,0x34,0x38,0x6c,0x36, + 0x2e,0x39,0x33,0x38,0x2c,0x31,0x30,0x2e,0x37,0x37, + 0x33,0x63,0x32,0x2e,0x39,0x2d,0x33,0x2e,0x39,0x33, + 0x38,0x2c,0x36,0x2e,0x35,0x34,0x31,0x2d,0x37,0x2e, + 0x30,0x36,0x31,0x2c,0x31,0x30,0x2e,0x39,0x33,0x31, + 0x2d,0x39,0x2e,0x33,0x37,0x36,0x63,0x34,0x2e,0x33, + 0x38,0x32,0x2d,0x32,0x2e,0x33,0x31,0x32,0x2c,0x39, + 0x2e,0x31,0x36,0x36,0x2d,0x33,0x2e,0x34,0x37,0x31, + 0x2c,0x31,0x34,0x2e,0x33,0x34,0x38,0x2d,0x33,0x2e, + 0x34,0x37,0x31,0x68,0x33,0x2e,0x32,0x31,0x31,0x0a, + 0x09,0x09,0x63,0x34,0x2e,0x32,0x38,0x32,0x2c,0x30, + 0x2c,0x38,0x2e,0x33,0x32,0x2c,0x30,0x2e,0x38,0x31, + 0x35,0x2c,0x31,0x32,0x2e,0x31,0x32,0x2c,0x32,0x2e, + 0x34,0x33,0x34,0x63,0x33,0x2e,0x37,0x39,0x37,0x2c, + 0x31,0x2e,0x36,0x32,0x36,0x2c,0x37,0x2e,0x31,0x31, + 0x31,0x2c,0x33,0x2e,0x38,0x35,0x2c,0x39,0x2e,0x39, + 0x34,0x33,0x2c,0x36,0x2e,0x36,0x38,0x32,0x73,0x35, + 0x2e,0x30,0x36,0x2c,0x36,0x2e,0x31,0x34,0x36,0x2c, + 0x36,0x2e,0x36,0x38,0x32,0x2c,0x39,0x2e,0x39,0x34, + 0x37,0x63,0x31,0x2e,0x36,0x32,0x33,0x2c,0x33,0x2e, + 0x37,0x39,0x36,0x2c,0x32,0x2e,0x34,0x33,0x36,0x2c, + 0x37,0x2e,0x38,0x33,0x38,0x2c,0x32,0x2e,0x34,0x33, + 0x36,0x2c,0x31,0x32,0x2e,0x31,0x32,0x0a,0x09,0x09, 0x76,0x37,0x36,0x2e,0x39,0x36,0x38,0x4c,0x31,0x32, 0x35,0x30,0x2e,0x39,0x36,0x34,0x2c,0x33,0x34,0x33, 0x2e,0x35,0x35,0x4c,0x31,0x32,0x35,0x30,0x2e,0x39, 0x36,0x34,0x2c,0x33,0x34,0x33,0x2e,0x35,0x35,0x7a, - 0x22,0x2f,0x3e,0x0d,0x0a,0x09,0x3c,0x70,0x61,0x74, - 0x68,0x20,0x64,0x3d,0x22,0x4d,0x35,0x36,0x33,0x2e, - 0x31,0x30,0x39,0x2c,0x34,0x39,0x36,0x2e,0x32,0x35, - 0x38,0x63,0x30,0x2c,0x34,0x2e,0x32,0x37,0x38,0x2d, - 0x30,0x2e,0x38,0x36,0x35,0x2c,0x38,0x2e,0x31,0x39, - 0x38,0x2d,0x32,0x2e,0x35,0x38,0x37,0x2c,0x31,0x31, - 0x2e,0x37,0x35,0x37,0x63,0x2d,0x31,0x2e,0x37,0x32, - 0x39,0x2c,0x33,0x2e,0x35,0x36,0x31,0x2d,0x34,0x2e, - 0x30,0x37,0x36,0x2c,0x36,0x2e,0x36,0x31,0x33,0x2d, - 0x37,0x2e,0x30,0x34,0x36,0x2c,0x39,0x2e,0x31,0x37, - 0x0d,0x0a,0x09,0x09,0x63,0x2d,0x32,0x2e,0x39,0x37, - 0x2c,0x32,0x2e,0x35,0x35,0x38,0x2d,0x36,0x2e,0x34, - 0x30,0x36,0x2c,0x34,0x2e,0x35,0x33,0x39,0x2d,0x31, - 0x30,0x2e,0x33,0x30,0x37,0x2c,0x35,0x2e,0x39,0x35, - 0x35,0x63,0x2d,0x33,0x2e,0x39,0x30,0x33,0x2c,0x31, - 0x2e,0x34,0x31,0x36,0x2d,0x37,0x2e,0x39,0x39,0x35, - 0x2c,0x32,0x2e,0x31,0x32,0x2d,0x31,0x32,0x2e,0x32, - 0x37,0x37,0x2c,0x32,0x2e,0x31,0x32,0x48,0x35,0x32, - 0x32,0x2e,0x34,0x63,0x2d,0x34,0x2e,0x32,0x38,0x33, - 0x2c,0x30,0x2d,0x38,0x2e,0x33,0x37,0x37,0x2d,0x30, - 0x2e,0x38,0x31,0x32,0x2d,0x31,0x32,0x2e,0x32,0x37, - 0x37,0x2d,0x32,0x2e,0x34,0x33,0x34,0x0d,0x0a,0x09, - 0x09,0x63,0x2d,0x33,0x2e,0x39,0x30,0x33,0x2d,0x31, - 0x2e,0x36,0x32,0x33,0x2d,0x37,0x2e,0x33,0x32,0x2d, - 0x33,0x2e,0x38,0x34,0x33,0x2d,0x31,0x30,0x2e,0x32, - 0x35,0x37,0x2d,0x36,0x2e,0x36,0x38,0x33,0x63,0x2d, - 0x32,0x2e,0x39,0x33,0x36,0x2d,0x32,0x2e,0x38,0x32, - 0x34,0x2d,0x35,0x2e,0x32,0x38,0x2d,0x36,0x2e,0x31, - 0x34,0x2d,0x37,0x2e,0x30,0x34,0x32,0x2d,0x39,0x2e, - 0x39,0x34,0x33,0x63,0x2d,0x31,0x2e,0x37,0x36,0x2d, - 0x33,0x2e,0x37,0x39,0x37,0x2d,0x32,0x2e,0x36,0x34, - 0x31,0x2d,0x37,0x2e,0x38,0x33,0x38,0x2d,0x32,0x2e, - 0x36,0x34,0x31,0x2d,0x31,0x32,0x2e,0x31,0x31,0x36, - 0x76,0x2d,0x34,0x2e,0x32,0x34,0x38,0x0d,0x0a,0x09, - 0x09,0x6c,0x31,0x32,0x2e,0x37,0x34,0x2d,0x32,0x2e, - 0x30,0x37,0x34,0x76,0x37,0x2e,0x30,0x34,0x32,0x63, - 0x30,0x2c,0x32,0x2e,0x35,0x35,0x37,0x2c,0x30,0x2e, - 0x35,0x33,0x31,0x2c,0x34,0x2e,0x39,0x36,0x31,0x2c, - 0x31,0x2e,0x36,0x30,0x34,0x2c,0x37,0x2e,0x32,0x30, - 0x32,0x63,0x31,0x2e,0x30,0x37,0x31,0x2c,0x32,0x2e, - 0x32,0x34,0x33,0x2c,0x32,0x2e,0x35,0x30,0x33,0x2c, - 0x34,0x2e,0x31,0x39,0x34,0x2c,0x34,0x2e,0x33,0x30, - 0x31,0x2c,0x35,0x2e,0x38,0x35,0x34,0x63,0x31,0x2e, - 0x37,0x39,0x35,0x2c,0x31,0x2e,0x36,0x35,0x34,0x2c, - 0x33,0x2e,0x38,0x36,0x36,0x2c,0x32,0x2e,0x39,0x37, - 0x31,0x2c,0x36,0x2e,0x32,0x31,0x37,0x2c,0x33,0x2e, - 0x39,0x33,0x36,0x0d,0x0a,0x09,0x09,0x63,0x32,0x2e, - 0x33,0x34,0x36,0x2c,0x30,0x2e,0x39,0x36,0x35,0x2c, - 0x34,0x2e,0x37,0x39,0x39,0x2c,0x31,0x2e,0x34,0x34, - 0x37,0x2c,0x37,0x2e,0x33,0x35,0x34,0x2c,0x31,0x2e, - 0x34,0x34,0x37,0x68,0x38,0x2e,0x34,0x39,0x32,0x63, - 0x32,0x2e,0x35,0x35,0x37,0x2c,0x30,0x2c,0x35,0x2e, - 0x30,0x30,0x36,0x2d,0x30,0x2e,0x33,0x37,0x36,0x2c, - 0x37,0x2e,0x33,0x35,0x35,0x2d,0x31,0x2e,0x31,0x33, - 0x35,0x63,0x32,0x2e,0x33,0x34,0x37,0x2d,0x30,0x2e, - 0x37,0x36,0x35,0x2c,0x34,0x2e,0x34,0x33,0x37,0x2d, - 0x31,0x2e,0x38,0x35,0x32,0x2c,0x36,0x2e,0x32,0x37, - 0x2d,0x33,0x2e,0x32,0x36,0x38,0x0d,0x0a,0x09,0x09, - 0x63,0x31,0x2e,0x38,0x32,0x39,0x2d,0x31,0x2e,0x34, - 0x31,0x36,0x2c,0x33,0x2e,0x32,0x38,0x2d,0x33,0x2e, - 0x31,0x32,0x33,0x2c,0x34,0x2e,0x33,0x35,0x31,0x2d, - 0x35,0x2e,0x31,0x32,0x39,0x63,0x31,0x2e,0x30,0x36, - 0x38,0x2d,0x31,0x2e,0x39,0x39,0x37,0x2c,0x31,0x2e, - 0x36,0x30,0x34,0x2d,0x34,0x2e,0x32,0x37,0x37,0x2c, - 0x31,0x2e,0x36,0x30,0x34,0x2d,0x36,0x2e,0x38,0x33, - 0x35,0x63,0x30,0x2d,0x33,0x2e,0x37,0x39,0x37,0x2d, - 0x30,0x2e,0x38,0x32,0x37,0x2d,0x36,0x2e,0x39,0x30, - 0x33,0x2d,0x32,0x2e,0x34,0x38,0x38,0x2d,0x39,0x2e, - 0x33,0x32,0x33,0x0d,0x0a,0x09,0x09,0x63,0x2d,0x31, - 0x2e,0x36,0x35,0x37,0x2d,0x32,0x2e,0x34,0x31,0x39, - 0x2d,0x33,0x2e,0x38,0x35,0x2d,0x34,0x2e,0x34,0x33, - 0x38,0x2d,0x36,0x2e,0x35,0x37,0x35,0x2d,0x36,0x2e, - 0x30,0x36,0x32,0x63,0x2d,0x32,0x2e,0x37,0x32,0x39, - 0x2d,0x31,0x2e,0x36,0x32,0x33,0x2d,0x35,0x2e,0x38, - 0x33,0x36,0x2d,0x32,0x2e,0x39,0x36,0x34,0x2d,0x39, - 0x2e,0x33,0x32,0x32,0x2d,0x34,0x2e,0x30,0x33,0x34, - 0x63,0x2d,0x33,0x2e,0x34,0x39,0x2d,0x31,0x2e,0x30, - 0x37,0x31,0x2d,0x37,0x2e,0x30,0x36,0x35,0x2d,0x32, - 0x2e,0x31,0x34,0x35,0x2d,0x31,0x30,0x2e,0x37,0x32, - 0x35,0x2d,0x33,0x2e,0x32,0x31,0x35,0x0d,0x0a,0x09, - 0x09,0x63,0x2d,0x33,0x2e,0x36,0x36,0x33,0x2d,0x31, - 0x2e,0x30,0x37,0x31,0x2d,0x37,0x2e,0x32,0x33,0x36, - 0x2d,0x32,0x2e,0x32,0x39,0x36,0x2d,0x31,0x30,0x2e, - 0x37,0x32,0x34,0x2d,0x33,0x2e,0x36,0x37,0x34,0x63, - 0x2d,0x33,0x2e,0x34,0x38,0x36,0x2d,0x31,0x2e,0x33, - 0x38,0x37,0x2d,0x36,0x2e,0x35,0x39,0x34,0x2d,0x33, - 0x2e,0x32,0x2d,0x39,0x2e,0x33,0x32,0x33,0x2d,0x35, - 0x2e,0x34,0x34,0x32,0x63,0x2d,0x32,0x2e,0x37,0x32, - 0x39,0x2d,0x32,0x2e,0x32,0x34,0x32,0x2d,0x34,0x2e, - 0x39,0x31,0x38,0x2d,0x35,0x2e,0x30,0x36,0x2d,0x36, - 0x2e,0x35,0x37,0x35,0x2d,0x38,0x2e,0x34,0x34,0x32, - 0x0d,0x0a,0x09,0x09,0x63,0x2d,0x31,0x2e,0x36,0x36, - 0x31,0x2d,0x33,0x2e,0x33,0x38,0x34,0x2d,0x32,0x2e, - 0x34,0x38,0x37,0x2d,0x37,0x2e,0x35,0x39,0x33,0x2d, - 0x32,0x2e,0x34,0x38,0x37,0x2d,0x31,0x32,0x2e,0x36, - 0x33,0x38,0x63,0x30,0x2d,0x34,0x2e,0x32,0x37,0x38, - 0x2c,0x30,0x2e,0x38,0x32,0x36,0x2d,0x38,0x2e,0x31, - 0x39,0x36,0x2c,0x32,0x2e,0x34,0x38,0x37,0x2d,0x31, - 0x31,0x2e,0x37,0x35,0x37,0x63,0x31,0x2e,0x36,0x35, - 0x37,0x2d,0x33,0x2e,0x35,0x36,0x31,0x2c,0x33,0x2e, - 0x39,0x2d,0x36,0x2e,0x36,0x31,0x33,0x2c,0x36,0x2e, - 0x37,0x33,0x32,0x2d,0x39,0x2e,0x31,0x37,0x0d,0x0a, + 0x22,0x2f,0x3e,0x0a,0x09,0x3c,0x70,0x61,0x74,0x68, + 0x20,0x64,0x3d,0x22,0x4d,0x35,0x36,0x33,0x2e,0x31, + 0x30,0x39,0x2c,0x34,0x39,0x36,0x2e,0x32,0x35,0x38, + 0x63,0x30,0x2c,0x34,0x2e,0x32,0x37,0x38,0x2d,0x30, + 0x2e,0x38,0x36,0x35,0x2c,0x38,0x2e,0x31,0x39,0x38, + 0x2d,0x32,0x2e,0x35,0x38,0x37,0x2c,0x31,0x31,0x2e, + 0x37,0x35,0x37,0x63,0x2d,0x31,0x2e,0x37,0x32,0x39, + 0x2c,0x33,0x2e,0x35,0x36,0x31,0x2d,0x34,0x2e,0x30, + 0x37,0x36,0x2c,0x36,0x2e,0x36,0x31,0x33,0x2d,0x37, + 0x2e,0x30,0x34,0x36,0x2c,0x39,0x2e,0x31,0x37,0x0a, + 0x09,0x09,0x63,0x2d,0x32,0x2e,0x39,0x37,0x2c,0x32, + 0x2e,0x35,0x35,0x38,0x2d,0x36,0x2e,0x34,0x30,0x36, + 0x2c,0x34,0x2e,0x35,0x33,0x39,0x2d,0x31,0x30,0x2e, + 0x33,0x30,0x37,0x2c,0x35,0x2e,0x39,0x35,0x35,0x63, + 0x2d,0x33,0x2e,0x39,0x30,0x33,0x2c,0x31,0x2e,0x34, + 0x31,0x36,0x2d,0x37,0x2e,0x39,0x39,0x35,0x2c,0x32, + 0x2e,0x31,0x32,0x2d,0x31,0x32,0x2e,0x32,0x37,0x37, + 0x2c,0x32,0x2e,0x31,0x32,0x48,0x35,0x32,0x32,0x2e, + 0x34,0x63,0x2d,0x34,0x2e,0x32,0x38,0x33,0x2c,0x30, + 0x2d,0x38,0x2e,0x33,0x37,0x37,0x2d,0x30,0x2e,0x38, + 0x31,0x32,0x2d,0x31,0x32,0x2e,0x32,0x37,0x37,0x2d, + 0x32,0x2e,0x34,0x33,0x34,0x0a,0x09,0x09,0x63,0x2d, + 0x33,0x2e,0x39,0x30,0x33,0x2d,0x31,0x2e,0x36,0x32, + 0x33,0x2d,0x37,0x2e,0x33,0x32,0x2d,0x33,0x2e,0x38, + 0x34,0x33,0x2d,0x31,0x30,0x2e,0x32,0x35,0x37,0x2d, + 0x36,0x2e,0x36,0x38,0x33,0x63,0x2d,0x32,0x2e,0x39, + 0x33,0x36,0x2d,0x32,0x2e,0x38,0x32,0x34,0x2d,0x35, + 0x2e,0x32,0x38,0x2d,0x36,0x2e,0x31,0x34,0x2d,0x37, + 0x2e,0x30,0x34,0x32,0x2d,0x39,0x2e,0x39,0x34,0x33, + 0x63,0x2d,0x31,0x2e,0x37,0x36,0x2d,0x33,0x2e,0x37, + 0x39,0x37,0x2d,0x32,0x2e,0x36,0x34,0x31,0x2d,0x37, + 0x2e,0x38,0x33,0x38,0x2d,0x32,0x2e,0x36,0x34,0x31, + 0x2d,0x31,0x32,0x2e,0x31,0x31,0x36,0x76,0x2d,0x34, + 0x2e,0x32,0x34,0x38,0x0a,0x09,0x09,0x6c,0x31,0x32, + 0x2e,0x37,0x34,0x2d,0x32,0x2e,0x30,0x37,0x34,0x76, + 0x37,0x2e,0x30,0x34,0x32,0x63,0x30,0x2c,0x32,0x2e, + 0x35,0x35,0x37,0x2c,0x30,0x2e,0x35,0x33,0x31,0x2c, + 0x34,0x2e,0x39,0x36,0x31,0x2c,0x31,0x2e,0x36,0x30, + 0x34,0x2c,0x37,0x2e,0x32,0x30,0x32,0x63,0x31,0x2e, + 0x30,0x37,0x31,0x2c,0x32,0x2e,0x32,0x34,0x33,0x2c, + 0x32,0x2e,0x35,0x30,0x33,0x2c,0x34,0x2e,0x31,0x39, + 0x34,0x2c,0x34,0x2e,0x33,0x30,0x31,0x2c,0x35,0x2e, + 0x38,0x35,0x34,0x63,0x31,0x2e,0x37,0x39,0x35,0x2c, + 0x31,0x2e,0x36,0x35,0x34,0x2c,0x33,0x2e,0x38,0x36, + 0x36,0x2c,0x32,0x2e,0x39,0x37,0x31,0x2c,0x36,0x2e, + 0x32,0x31,0x37,0x2c,0x33,0x2e,0x39,0x33,0x36,0x0a, + 0x09,0x09,0x63,0x32,0x2e,0x33,0x34,0x36,0x2c,0x30, + 0x2e,0x39,0x36,0x35,0x2c,0x34,0x2e,0x37,0x39,0x39, + 0x2c,0x31,0x2e,0x34,0x34,0x37,0x2c,0x37,0x2e,0x33, + 0x35,0x34,0x2c,0x31,0x2e,0x34,0x34,0x37,0x68,0x38, + 0x2e,0x34,0x39,0x32,0x63,0x32,0x2e,0x35,0x35,0x37, + 0x2c,0x30,0x2c,0x35,0x2e,0x30,0x30,0x36,0x2d,0x30, + 0x2e,0x33,0x37,0x36,0x2c,0x37,0x2e,0x33,0x35,0x35, + 0x2d,0x31,0x2e,0x31,0x33,0x35,0x63,0x32,0x2e,0x33, + 0x34,0x37,0x2d,0x30,0x2e,0x37,0x36,0x35,0x2c,0x34, + 0x2e,0x34,0x33,0x37,0x2d,0x31,0x2e,0x38,0x35,0x32, + 0x2c,0x36,0x2e,0x32,0x37,0x2d,0x33,0x2e,0x32,0x36, + 0x38,0x0a,0x09,0x09,0x63,0x31,0x2e,0x38,0x32,0x39, + 0x2d,0x31,0x2e,0x34,0x31,0x36,0x2c,0x33,0x2e,0x32, + 0x38,0x2d,0x33,0x2e,0x31,0x32,0x33,0x2c,0x34,0x2e, + 0x33,0x35,0x31,0x2d,0x35,0x2e,0x31,0x32,0x39,0x63, + 0x31,0x2e,0x30,0x36,0x38,0x2d,0x31,0x2e,0x39,0x39, + 0x37,0x2c,0x31,0x2e,0x36,0x30,0x34,0x2d,0x34,0x2e, + 0x32,0x37,0x37,0x2c,0x31,0x2e,0x36,0x30,0x34,0x2d, + 0x36,0x2e,0x38,0x33,0x35,0x63,0x30,0x2d,0x33,0x2e, + 0x37,0x39,0x37,0x2d,0x30,0x2e,0x38,0x32,0x37,0x2d, + 0x36,0x2e,0x39,0x30,0x33,0x2d,0x32,0x2e,0x34,0x38, + 0x38,0x2d,0x39,0x2e,0x33,0x32,0x33,0x0a,0x09,0x09, + 0x63,0x2d,0x31,0x2e,0x36,0x35,0x37,0x2d,0x32,0x2e, + 0x34,0x31,0x39,0x2d,0x33,0x2e,0x38,0x35,0x2d,0x34, + 0x2e,0x34,0x33,0x38,0x2d,0x36,0x2e,0x35,0x37,0x35, + 0x2d,0x36,0x2e,0x30,0x36,0x32,0x63,0x2d,0x32,0x2e, + 0x37,0x32,0x39,0x2d,0x31,0x2e,0x36,0x32,0x33,0x2d, + 0x35,0x2e,0x38,0x33,0x36,0x2d,0x32,0x2e,0x39,0x36, + 0x34,0x2d,0x39,0x2e,0x33,0x32,0x32,0x2d,0x34,0x2e, + 0x30,0x33,0x34,0x63,0x2d,0x33,0x2e,0x34,0x39,0x2d, + 0x31,0x2e,0x30,0x37,0x31,0x2d,0x37,0x2e,0x30,0x36, + 0x35,0x2d,0x32,0x2e,0x31,0x34,0x35,0x2d,0x31,0x30, + 0x2e,0x37,0x32,0x35,0x2d,0x33,0x2e,0x32,0x31,0x35, + 0x0a,0x09,0x09,0x63,0x2d,0x33,0x2e,0x36,0x36,0x33, + 0x2d,0x31,0x2e,0x30,0x37,0x31,0x2d,0x37,0x2e,0x32, + 0x33,0x36,0x2d,0x32,0x2e,0x32,0x39,0x36,0x2d,0x31, + 0x30,0x2e,0x37,0x32,0x34,0x2d,0x33,0x2e,0x36,0x37, + 0x34,0x63,0x2d,0x33,0x2e,0x34,0x38,0x36,0x2d,0x31, + 0x2e,0x33,0x38,0x37,0x2d,0x36,0x2e,0x35,0x39,0x34, + 0x2d,0x33,0x2e,0x32,0x2d,0x39,0x2e,0x33,0x32,0x33, + 0x2d,0x35,0x2e,0x34,0x34,0x32,0x63,0x2d,0x32,0x2e, + 0x37,0x32,0x39,0x2d,0x32,0x2e,0x32,0x34,0x32,0x2d, + 0x34,0x2e,0x39,0x31,0x38,0x2d,0x35,0x2e,0x30,0x36, + 0x2d,0x36,0x2e,0x35,0x37,0x35,0x2d,0x38,0x2e,0x34, + 0x34,0x32,0x0a,0x09,0x09,0x63,0x2d,0x31,0x2e,0x36, + 0x36,0x31,0x2d,0x33,0x2e,0x33,0x38,0x34,0x2d,0x32, + 0x2e,0x34,0x38,0x37,0x2d,0x37,0x2e,0x35,0x39,0x33, + 0x2d,0x32,0x2e,0x34,0x38,0x37,0x2d,0x31,0x32,0x2e, + 0x36,0x33,0x38,0x63,0x30,0x2d,0x34,0x2e,0x32,0x37, + 0x38,0x2c,0x30,0x2e,0x38,0x32,0x36,0x2d,0x38,0x2e, + 0x31,0x39,0x36,0x2c,0x32,0x2e,0x34,0x38,0x37,0x2d, + 0x31,0x31,0x2e,0x37,0x35,0x37,0x63,0x31,0x2e,0x36, + 0x35,0x37,0x2d,0x33,0x2e,0x35,0x36,0x31,0x2c,0x33, + 0x2e,0x39,0x2d,0x36,0x2e,0x36,0x31,0x33,0x2c,0x36, + 0x2e,0x37,0x33,0x32,0x2d,0x39,0x2e,0x31,0x37,0x0a, 0x09,0x09,0x73,0x36,0x2e,0x31,0x32,0x37,0x2d,0x34, 0x2e,0x35,0x33,0x39,0x2c,0x39,0x2e,0x38,0x39,0x33, 0x2d,0x35,0x2e,0x39,0x35,0x35,0x63,0x33,0x2e,0x37, @@ -1266,105 +1254,104 @@ const unsigned char splash_svg_data[17935] = { 0x34,0x2e,0x32,0x38,0x33,0x2c,0x30,0x2c,0x38,0x2e, 0x33,0x32,0x34,0x2c,0x30,0x2e,0x38,0x31,0x39,0x2c, 0x31,0x32,0x2e,0x31,0x32,0x31,0x2c,0x32,0x2e,0x34, - 0x33,0x35,0x0d,0x0a,0x09,0x09,0x63,0x33,0x2e,0x37, - 0x39,0x36,0x2c,0x31,0x2e,0x36,0x33,0x31,0x2c,0x37, - 0x2e,0x31,0x31,0x35,0x2c,0x33,0x2e,0x38,0x35,0x31, - 0x2c,0x39,0x2e,0x39,0x34,0x37,0x2c,0x36,0x2e,0x36, - 0x38,0x32,0x63,0x32,0x2e,0x38,0x32,0x37,0x2c,0x32, - 0x2e,0x38,0x33,0x34,0x2c,0x35,0x2e,0x30,0x35,0x36, - 0x2c,0x36,0x2e,0x31,0x34,0x36,0x2c,0x36,0x2e,0x36, - 0x38,0x32,0x2c,0x39,0x2e,0x39,0x35,0x31,0x63,0x31, - 0x2e,0x36,0x31,0x39,0x2c,0x33,0x2e,0x37,0x39,0x37, - 0x2c,0x32,0x2e,0x34,0x33,0x34,0x2c,0x37,0x2e,0x38, - 0x33,0x38,0x2c,0x32,0x2e,0x34,0x33,0x34,0x2c,0x31, - 0x32,0x2e,0x31,0x31,0x37,0x76,0x30,0x2e,0x34,0x31, - 0x33,0x0d,0x0a,0x09,0x09,0x6c,0x2d,0x31,0x32,0x2e, - 0x37,0x34,0x34,0x2c,0x32,0x2e,0x30,0x37,0x34,0x76, - 0x2d,0x33,0x2e,0x32,0x31,0x35,0x63,0x30,0x2d,0x32, - 0x2e,0x35,0x35,0x2d,0x30,0x2e,0x34,0x38,0x31,0x2d, - 0x34,0x2e,0x39,0x35,0x33,0x2d,0x31,0x2e,0x34,0x35, - 0x2d,0x37,0x2e,0x31,0x39,0x35,0x63,0x2d,0x30,0x2e, - 0x39,0x37,0x2d,0x32,0x2e,0x32,0x34,0x31,0x2d,0x32, - 0x2e,0x32,0x37,0x37,0x2d,0x34,0x2e,0x31,0x39,0x34, - 0x2d,0x33,0x2e,0x39,0x33,0x35,0x2d,0x35,0x2e,0x38, - 0x35,0x34,0x63,0x2d,0x31,0x2e,0x36,0x35,0x37,0x2d, - 0x31,0x2e,0x36,0x35,0x33,0x2d,0x33,0x2e,0x36,0x30, - 0x38,0x2d,0x32,0x2e,0x39,0x37,0x31,0x2d,0x35,0x2e, - 0x38,0x35,0x34,0x2d,0x33,0x2e,0x39,0x33,0x36,0x0d, - 0x0a,0x09,0x09,0x63,0x2d,0x32,0x2e,0x32,0x34,0x33, - 0x2d,0x30,0x2e,0x39,0x36,0x34,0x2d,0x34,0x2e,0x36, - 0x34,0x34,0x2d,0x31,0x2e,0x34,0x35,0x33,0x2d,0x37, - 0x2e,0x31,0x39,0x39,0x2d,0x31,0x2e,0x34,0x35,0x33, - 0x68,0x2d,0x37,0x2e,0x34,0x35,0x39,0x63,0x2d,0x32, - 0x2e,0x35,0x35,0x33,0x2c,0x30,0x2d,0x34,0x2e,0x39, - 0x35,0x36,0x2c,0x30,0x2e,0x33,0x38,0x33,0x2d,0x37, - 0x2e,0x31,0x39,0x39,0x2c,0x31,0x2e,0x31,0x34,0x31, - 0x63,0x2d,0x32,0x2e,0x32,0x34,0x33,0x2c,0x30,0x2e, - 0x37,0x36,0x36,0x2d,0x34,0x2e,0x31,0x39,0x35,0x2c, - 0x31,0x2e,0x38,0x35,0x33,0x2d,0x35,0x2e,0x38,0x35, - 0x32,0x2c,0x33,0x2e,0x32,0x36,0x31,0x0d,0x0a,0x09, - 0x09,0x63,0x2d,0x31,0x2e,0x36,0x35,0x37,0x2c,0x31, - 0x2e,0x34,0x32,0x34,0x2d,0x32,0x2e,0x39,0x37,0x31, - 0x2c,0x33,0x2e,0x31,0x33,0x2d,0x33,0x2e,0x39,0x33, - 0x38,0x2c,0x35,0x2e,0x31,0x32,0x38,0x63,0x2d,0x30, - 0x2e,0x39,0x36,0x39,0x2c,0x32,0x2e,0x30,0x30,0x36, - 0x2d,0x31,0x2e,0x34,0x35,0x31,0x2c,0x34,0x2e,0x32, - 0x38,0x37,0x2d,0x31,0x2e,0x34,0x35,0x31,0x2c,0x36, - 0x2e,0x38,0x34,0x34,0x63,0x30,0x2c,0x33,0x2e,0x36, - 0x35,0x38,0x2c,0x30,0x2e,0x38,0x33,0x31,0x2c,0x36, - 0x2e,0x36,0x34,0x35,0x2c,0x32,0x2e,0x34,0x38,0x38, - 0x2c,0x38,0x2e,0x39,0x35,0x35,0x0d,0x0a,0x09,0x09, - 0x63,0x31,0x2e,0x36,0x35,0x37,0x2c,0x32,0x2e,0x33, - 0x31,0x39,0x2c,0x33,0x2e,0x38,0x35,0x2c,0x34,0x2e, - 0x32,0x37,0x31,0x2c,0x36,0x2e,0x35,0x37,0x39,0x2c, - 0x35,0x2e,0x38,0x35,0x35,0x63,0x32,0x2e,0x37,0x32, - 0x35,0x2c,0x31,0x2e,0x35,0x39,0x32,0x2c,0x35,0x2e, - 0x38,0x33,0x33,0x2c,0x32,0x2e,0x39,0x31,0x36,0x2c, - 0x39,0x2e,0x33,0x32,0x33,0x2c,0x33,0x2e,0x39,0x38, - 0x36,0x63,0x33,0x2e,0x34,0x38,0x36,0x2c,0x31,0x2e, - 0x30,0x37,0x32,0x2c,0x37,0x2e,0x30,0x34,0x32,0x2c, - 0x32,0x2e,0x31,0x37,0x34,0x2c,0x31,0x30,0x2e,0x36, - 0x37,0x2c,0x33,0x2e,0x33,0x31,0x34,0x0d,0x0a,0x09, - 0x09,0x63,0x33,0x2e,0x36,0x32,0x35,0x2c,0x31,0x2e, - 0x31,0x34,0x31,0x2c,0x37,0x2e,0x31,0x38,0x2c,0x32, - 0x2e,0x34,0x33,0x36,0x2c,0x31,0x30,0x2e,0x36,0x37, - 0x2c,0x33,0x2e,0x38,0x38,0x39,0x63,0x33,0x2e,0x34, - 0x38,0x36,0x2c,0x31,0x2e,0x34,0x34,0x36,0x2c,0x36, - 0x2e,0x35,0x39,0x34,0x2c,0x33,0x2e,0x33,0x31,0x34, - 0x2c,0x39,0x2e,0x33,0x32,0x33,0x2c,0x35,0x2e,0x35, - 0x38,0x38,0x63,0x32,0x2e,0x37,0x32,0x39,0x2c,0x32, - 0x2e,0x32,0x38,0x2c,0x34,0x2e,0x39,0x32,0x32,0x2c, - 0x35,0x2e,0x31,0x32,0x39,0x2c,0x36,0x2e,0x35,0x37, - 0x39,0x2c,0x38,0x2e,0x35,0x35,0x31,0x0d,0x0a,0x09, - 0x09,0x43,0x35,0x36,0x32,0x2e,0x32,0x38,0x32,0x2c, - 0x34,0x38,0x36,0x2e,0x39,0x38,0x39,0x2c,0x35,0x36, - 0x33,0x2e,0x31,0x30,0x39,0x2c,0x34,0x39,0x31,0x2e, - 0x32,0x31,0x34,0x2c,0x35,0x36,0x33,0x2e,0x31,0x30, - 0x39,0x2c,0x34,0x39,0x36,0x2e,0x32,0x35,0x38,0x7a, - 0x22,0x2f,0x3e,0x0d,0x0a,0x09,0x3c,0x70,0x61,0x74, - 0x68,0x20,0x64,0x3d,0x22,0x4d,0x36,0x32,0x36,0x2e, - 0x31,0x39,0x36,0x2c,0x35,0x32,0x33,0x2e,0x31,0x39, - 0x34,0x63,0x2d,0x33,0x2e,0x38,0x36,0x35,0x2c,0x30, - 0x2d,0x37,0x2e,0x35,0x30,0x39,0x2d,0x30,0x2e,0x37, - 0x32,0x39,0x2d,0x31,0x30,0x2e,0x39,0x32,0x36,0x2d, - 0x32,0x2e,0x31,0x37,0x34,0x63,0x2d,0x33,0x2e,0x34, - 0x32,0x31,0x2d,0x31,0x2e,0x34,0x35,0x35,0x2d,0x36, - 0x2e,0x33,0x39,0x32,0x2d,0x33,0x2e,0x34,0x36,0x31, - 0x2d,0x38,0x2e,0x39,0x31,0x2d,0x36,0x2e,0x30,0x31, - 0x0d,0x0a,0x09,0x09,0x63,0x2d,0x32,0x2e,0x35,0x32, - 0x31,0x2d,0x32,0x2e,0x35,0x35,0x37,0x2d,0x34,0x2e, - 0x35,0x32,0x32,0x2d,0x35,0x2e,0x35,0x32,0x35,0x2d, - 0x36,0x2e,0x30,0x30,0x38,0x2d,0x38,0x2e,0x39,0x30, - 0x38,0x63,0x2d,0x31,0x2e,0x34,0x38,0x35,0x2d,0x33, - 0x2e,0x33,0x38,0x35,0x2d,0x32,0x2e,0x32,0x32,0x39, - 0x2d,0x37,0x2e,0x30,0x31,0x33,0x2d,0x32,0x2e,0x32, - 0x32,0x39,0x2d,0x31,0x30,0x2e,0x38,0x37,0x37,0x76, - 0x2d,0x36,0x35,0x2e,0x39,0x39,0x36,0x68,0x2d,0x31, - 0x39,0x2e,0x30,0x35,0x39,0x76,0x2d,0x31,0x32,0x2e, - 0x31,0x31,0x37,0x68,0x31,0x39,0x2e,0x30,0x35,0x39, - 0x76,0x2d,0x32,0x35,0x2e,0x34,0x37,0x39,0x6c,0x31, - 0x32,0x2e,0x37,0x34,0x2d,0x32,0x2e,0x30,0x37,0x33, - 0x0d,0x0a,0x09,0x09,0x76,0x32,0x37,0x2e,0x35,0x35, + 0x33,0x35,0x0a,0x09,0x09,0x63,0x33,0x2e,0x37,0x39, + 0x36,0x2c,0x31,0x2e,0x36,0x33,0x31,0x2c,0x37,0x2e, + 0x31,0x31,0x35,0x2c,0x33,0x2e,0x38,0x35,0x31,0x2c, + 0x39,0x2e,0x39,0x34,0x37,0x2c,0x36,0x2e,0x36,0x38, + 0x32,0x63,0x32,0x2e,0x38,0x32,0x37,0x2c,0x32,0x2e, + 0x38,0x33,0x34,0x2c,0x35,0x2e,0x30,0x35,0x36,0x2c, + 0x36,0x2e,0x31,0x34,0x36,0x2c,0x36,0x2e,0x36,0x38, + 0x32,0x2c,0x39,0x2e,0x39,0x35,0x31,0x63,0x31,0x2e, + 0x36,0x31,0x39,0x2c,0x33,0x2e,0x37,0x39,0x37,0x2c, + 0x32,0x2e,0x34,0x33,0x34,0x2c,0x37,0x2e,0x38,0x33, + 0x38,0x2c,0x32,0x2e,0x34,0x33,0x34,0x2c,0x31,0x32, + 0x2e,0x31,0x31,0x37,0x76,0x30,0x2e,0x34,0x31,0x33, + 0x0a,0x09,0x09,0x6c,0x2d,0x31,0x32,0x2e,0x37,0x34, + 0x34,0x2c,0x32,0x2e,0x30,0x37,0x34,0x76,0x2d,0x33, + 0x2e,0x32,0x31,0x35,0x63,0x30,0x2d,0x32,0x2e,0x35, + 0x35,0x2d,0x30,0x2e,0x34,0x38,0x31,0x2d,0x34,0x2e, + 0x39,0x35,0x33,0x2d,0x31,0x2e,0x34,0x35,0x2d,0x37, + 0x2e,0x31,0x39,0x35,0x63,0x2d,0x30,0x2e,0x39,0x37, + 0x2d,0x32,0x2e,0x32,0x34,0x31,0x2d,0x32,0x2e,0x32, + 0x37,0x37,0x2d,0x34,0x2e,0x31,0x39,0x34,0x2d,0x33, + 0x2e,0x39,0x33,0x35,0x2d,0x35,0x2e,0x38,0x35,0x34, + 0x63,0x2d,0x31,0x2e,0x36,0x35,0x37,0x2d,0x31,0x2e, + 0x36,0x35,0x33,0x2d,0x33,0x2e,0x36,0x30,0x38,0x2d, + 0x32,0x2e,0x39,0x37,0x31,0x2d,0x35,0x2e,0x38,0x35, + 0x34,0x2d,0x33,0x2e,0x39,0x33,0x36,0x0a,0x09,0x09, + 0x63,0x2d,0x32,0x2e,0x32,0x34,0x33,0x2d,0x30,0x2e, + 0x39,0x36,0x34,0x2d,0x34,0x2e,0x36,0x34,0x34,0x2d, + 0x31,0x2e,0x34,0x35,0x33,0x2d,0x37,0x2e,0x31,0x39, + 0x39,0x2d,0x31,0x2e,0x34,0x35,0x33,0x68,0x2d,0x37, + 0x2e,0x34,0x35,0x39,0x63,0x2d,0x32,0x2e,0x35,0x35, + 0x33,0x2c,0x30,0x2d,0x34,0x2e,0x39,0x35,0x36,0x2c, + 0x30,0x2e,0x33,0x38,0x33,0x2d,0x37,0x2e,0x31,0x39, + 0x39,0x2c,0x31,0x2e,0x31,0x34,0x31,0x63,0x2d,0x32, + 0x2e,0x32,0x34,0x33,0x2c,0x30,0x2e,0x37,0x36,0x36, + 0x2d,0x34,0x2e,0x31,0x39,0x35,0x2c,0x31,0x2e,0x38, + 0x35,0x33,0x2d,0x35,0x2e,0x38,0x35,0x32,0x2c,0x33, + 0x2e,0x32,0x36,0x31,0x0a,0x09,0x09,0x63,0x2d,0x31, + 0x2e,0x36,0x35,0x37,0x2c,0x31,0x2e,0x34,0x32,0x34, + 0x2d,0x32,0x2e,0x39,0x37,0x31,0x2c,0x33,0x2e,0x31, + 0x33,0x2d,0x33,0x2e,0x39,0x33,0x38,0x2c,0x35,0x2e, + 0x31,0x32,0x38,0x63,0x2d,0x30,0x2e,0x39,0x36,0x39, + 0x2c,0x32,0x2e,0x30,0x30,0x36,0x2d,0x31,0x2e,0x34, + 0x35,0x31,0x2c,0x34,0x2e,0x32,0x38,0x37,0x2d,0x31, + 0x2e,0x34,0x35,0x31,0x2c,0x36,0x2e,0x38,0x34,0x34, + 0x63,0x30,0x2c,0x33,0x2e,0x36,0x35,0x38,0x2c,0x30, + 0x2e,0x38,0x33,0x31,0x2c,0x36,0x2e,0x36,0x34,0x35, + 0x2c,0x32,0x2e,0x34,0x38,0x38,0x2c,0x38,0x2e,0x39, + 0x35,0x35,0x0a,0x09,0x09,0x63,0x31,0x2e,0x36,0x35, + 0x37,0x2c,0x32,0x2e,0x33,0x31,0x39,0x2c,0x33,0x2e, + 0x38,0x35,0x2c,0x34,0x2e,0x32,0x37,0x31,0x2c,0x36, + 0x2e,0x35,0x37,0x39,0x2c,0x35,0x2e,0x38,0x35,0x35, + 0x63,0x32,0x2e,0x37,0x32,0x35,0x2c,0x31,0x2e,0x35, + 0x39,0x32,0x2c,0x35,0x2e,0x38,0x33,0x33,0x2c,0x32, + 0x2e,0x39,0x31,0x36,0x2c,0x39,0x2e,0x33,0x32,0x33, + 0x2c,0x33,0x2e,0x39,0x38,0x36,0x63,0x33,0x2e,0x34, + 0x38,0x36,0x2c,0x31,0x2e,0x30,0x37,0x32,0x2c,0x37, + 0x2e,0x30,0x34,0x32,0x2c,0x32,0x2e,0x31,0x37,0x34, + 0x2c,0x31,0x30,0x2e,0x36,0x37,0x2c,0x33,0x2e,0x33, + 0x31,0x34,0x0a,0x09,0x09,0x63,0x33,0x2e,0x36,0x32, + 0x35,0x2c,0x31,0x2e,0x31,0x34,0x31,0x2c,0x37,0x2e, + 0x31,0x38,0x2c,0x32,0x2e,0x34,0x33,0x36,0x2c,0x31, + 0x30,0x2e,0x36,0x37,0x2c,0x33,0x2e,0x38,0x38,0x39, + 0x63,0x33,0x2e,0x34,0x38,0x36,0x2c,0x31,0x2e,0x34, + 0x34,0x36,0x2c,0x36,0x2e,0x35,0x39,0x34,0x2c,0x33, + 0x2e,0x33,0x31,0x34,0x2c,0x39,0x2e,0x33,0x32,0x33, + 0x2c,0x35,0x2e,0x35,0x38,0x38,0x63,0x32,0x2e,0x37, + 0x32,0x39,0x2c,0x32,0x2e,0x32,0x38,0x2c,0x34,0x2e, + 0x39,0x32,0x32,0x2c,0x35,0x2e,0x31,0x32,0x39,0x2c, + 0x36,0x2e,0x35,0x37,0x39,0x2c,0x38,0x2e,0x35,0x35, + 0x31,0x0a,0x09,0x09,0x43,0x35,0x36,0x32,0x2e,0x32, + 0x38,0x32,0x2c,0x34,0x38,0x36,0x2e,0x39,0x38,0x39, + 0x2c,0x35,0x36,0x33,0x2e,0x31,0x30,0x39,0x2c,0x34, + 0x39,0x31,0x2e,0x32,0x31,0x34,0x2c,0x35,0x36,0x33, + 0x2e,0x31,0x30,0x39,0x2c,0x34,0x39,0x36,0x2e,0x32, + 0x35,0x38,0x7a,0x22,0x2f,0x3e,0x0a,0x09,0x3c,0x70, + 0x61,0x74,0x68,0x20,0x64,0x3d,0x22,0x4d,0x36,0x32, + 0x36,0x2e,0x31,0x39,0x36,0x2c,0x35,0x32,0x33,0x2e, + 0x31,0x39,0x34,0x63,0x2d,0x33,0x2e,0x38,0x36,0x35, + 0x2c,0x30,0x2d,0x37,0x2e,0x35,0x30,0x39,0x2d,0x30, + 0x2e,0x37,0x32,0x39,0x2d,0x31,0x30,0x2e,0x39,0x32, + 0x36,0x2d,0x32,0x2e,0x31,0x37,0x34,0x63,0x2d,0x33, + 0x2e,0x34,0x32,0x31,0x2d,0x31,0x2e,0x34,0x35,0x35, + 0x2d,0x36,0x2e,0x33,0x39,0x32,0x2d,0x33,0x2e,0x34, + 0x36,0x31,0x2d,0x38,0x2e,0x39,0x31,0x2d,0x36,0x2e, + 0x30,0x31,0x0a,0x09,0x09,0x63,0x2d,0x32,0x2e,0x35, + 0x32,0x31,0x2d,0x32,0x2e,0x35,0x35,0x37,0x2d,0x34, + 0x2e,0x35,0x32,0x32,0x2d,0x35,0x2e,0x35,0x32,0x35, + 0x2d,0x36,0x2e,0x30,0x30,0x38,0x2d,0x38,0x2e,0x39, + 0x30,0x38,0x63,0x2d,0x31,0x2e,0x34,0x38,0x35,0x2d, + 0x33,0x2e,0x33,0x38,0x35,0x2d,0x32,0x2e,0x32,0x32, + 0x39,0x2d,0x37,0x2e,0x30,0x31,0x33,0x2d,0x32,0x2e, + 0x32,0x32,0x39,0x2d,0x31,0x30,0x2e,0x38,0x37,0x37, + 0x76,0x2d,0x36,0x35,0x2e,0x39,0x39,0x36,0x68,0x2d, + 0x31,0x39,0x2e,0x30,0x35,0x39,0x76,0x2d,0x31,0x32, + 0x2e,0x31,0x31,0x37,0x68,0x31,0x39,0x2e,0x30,0x35, + 0x39,0x76,0x2d,0x32,0x35,0x2e,0x34,0x37,0x39,0x6c, + 0x31,0x32,0x2e,0x37,0x34,0x2d,0x32,0x2e,0x30,0x37, + 0x33,0x0a,0x09,0x09,0x76,0x32,0x37,0x2e,0x35,0x35, 0x35,0x48,0x36,0x33,0x37,0x2e,0x38,0x76,0x31,0x32, 0x2e,0x31,0x31,0x37,0x68,0x2d,0x32,0x36,0x2e,0x39, 0x33,0x37,0x76,0x36,0x36,0x2e,0x36,0x31,0x34,0x63, @@ -1374,111 +1361,110 @@ const unsigned char splash_svg_data[17935] = { 0x35,0x63,0x30,0x2e,0x37,0x39,0x32,0x2c,0x31,0x2e, 0x38,0x32,0x39,0x2c,0x31,0x2e,0x38,0x37,0x39,0x2c, 0x33,0x2e,0x34,0x33,0x37,0x2c,0x33,0x2e,0x32,0x36, - 0x31,0x2c,0x34,0x2e,0x38,0x31,0x33,0x0d,0x0a,0x09, - 0x09,0x63,0x31,0x2e,0x33,0x38,0x31,0x2c,0x31,0x2e, - 0x33,0x38,0x36,0x2c,0x33,0x2e,0x30,0x30,0x34,0x2c, - 0x32,0x2e,0x34,0x37,0x33,0x2c,0x34,0x2e,0x38,0x36, - 0x38,0x2c,0x33,0x2e,0x32,0x37,0x63,0x31,0x2e,0x38, - 0x36,0x38,0x2c,0x30,0x2e,0x37,0x38,0x38,0x2c,0x33, - 0x2e,0x38,0x36,0x39,0x2c,0x31,0x2e,0x31,0x38,0x38, - 0x2c,0x36,0x2e,0x30,0x30,0x38,0x2c,0x31,0x2e,0x31, - 0x38,0x38,0x68,0x31,0x31,0x2e,0x36,0x30,0x34,0x76, - 0x31,0x32,0x2e,0x31,0x32,0x33,0x48,0x36,0x32,0x36, - 0x2e,0x31,0x39,0x36,0x4c,0x36,0x32,0x36,0x2e,0x31, - 0x39,0x36,0x2c,0x35,0x32,0x33,0x2e,0x31,0x39,0x34, - 0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x09,0x3c,0x70,0x61, - 0x74,0x68,0x20,0x64,0x3d,0x22,0x4d,0x37,0x32,0x37, - 0x2e,0x38,0x32,0x31,0x2c,0x35,0x32,0x33,0x2e,0x31, - 0x39,0x34,0x6c,0x2d,0x37,0x2e,0x30,0x34,0x32,0x2d, - 0x31,0x30,0x2e,0x35,0x37,0x63,0x2d,0x32,0x2e,0x38, - 0x39,0x39,0x2c,0x33,0x2e,0x38,0x30,0x34,0x2d,0x36, - 0x2e,0x35,0x32,0x37,0x2c,0x36,0x2e,0x38,0x35,0x37, - 0x2d,0x31,0x30,0x2e,0x38,0x37,0x36,0x2c,0x39,0x2e, - 0x31,0x36,0x39,0x63,0x2d,0x34,0x2e,0x33,0x35,0x32, - 0x2c,0x32,0x2e,0x33,0x31,0x32,0x2d,0x39,0x2e,0x31, - 0x31,0x36,0x2c,0x33,0x2e,0x34,0x36,0x38,0x2d,0x31, - 0x34,0x2e,0x32,0x39,0x39,0x2c,0x33,0x2e,0x34,0x36, - 0x38,0x68,0x2d,0x33,0x2e,0x32,0x30,0x37,0x0d,0x0a, - 0x09,0x09,0x63,0x2d,0x34,0x2e,0x32,0x38,0x36,0x2c, - 0x30,0x2d,0x38,0x2e,0x33,0x32,0x38,0x2d,0x30,0x2e, - 0x38,0x31,0x32,0x2d,0x31,0x32,0x2e,0x31,0x32,0x34, - 0x2d,0x32,0x2e,0x34,0x33,0x34,0x63,0x2d,0x33,0x2e, - 0x38,0x30,0x31,0x2d,0x31,0x2e,0x36,0x32,0x33,0x2d, - 0x37,0x2e,0x31,0x31,0x34,0x2d,0x33,0x2e,0x38,0x34, - 0x34,0x2d,0x39,0x2e,0x39,0x34,0x33,0x2d,0x36,0x2e, - 0x36,0x38,0x34,0x63,0x2d,0x32,0x2e,0x38,0x33,0x36, - 0x2d,0x32,0x2e,0x38,0x32,0x34,0x2d,0x35,0x2e,0x30, - 0x36,0x32,0x2d,0x36,0x2e,0x31,0x33,0x39,0x2d,0x36, - 0x2e,0x36,0x38,0x32,0x2d,0x39,0x2e,0x39,0x34,0x32, - 0x0d,0x0a,0x09,0x09,0x63,0x2d,0x31,0x2e,0x36,0x32, - 0x37,0x2d,0x33,0x2e,0x37,0x39,0x36,0x2d,0x32,0x2e, - 0x34,0x33,0x35,0x2d,0x37,0x2e,0x38,0x33,0x39,0x2d, - 0x32,0x2e,0x34,0x33,0x35,0x2d,0x31,0x32,0x2e,0x31, - 0x31,0x36,0x76,0x2d,0x31,0x2e,0x30,0x34,0x31,0x63, - 0x30,0x2d,0x34,0x2e,0x32,0x37,0x37,0x2c,0x30,0x2e, - 0x38,0x30,0x38,0x2d,0x38,0x2e,0x33,0x32,0x2c,0x32, + 0x31,0x2c,0x34,0x2e,0x38,0x31,0x33,0x0a,0x09,0x09, + 0x63,0x31,0x2e,0x33,0x38,0x31,0x2c,0x31,0x2e,0x33, + 0x38,0x36,0x2c,0x33,0x2e,0x30,0x30,0x34,0x2c,0x32, + 0x2e,0x34,0x37,0x33,0x2c,0x34,0x2e,0x38,0x36,0x38, + 0x2c,0x33,0x2e,0x32,0x37,0x63,0x31,0x2e,0x38,0x36, + 0x38,0x2c,0x30,0x2e,0x37,0x38,0x38,0x2c,0x33,0x2e, + 0x38,0x36,0x39,0x2c,0x31,0x2e,0x31,0x38,0x38,0x2c, + 0x36,0x2e,0x30,0x30,0x38,0x2c,0x31,0x2e,0x31,0x38, + 0x38,0x68,0x31,0x31,0x2e,0x36,0x30,0x34,0x76,0x31, + 0x32,0x2e,0x31,0x32,0x33,0x48,0x36,0x32,0x36,0x2e, + 0x31,0x39,0x36,0x4c,0x36,0x32,0x36,0x2e,0x31,0x39, + 0x36,0x2c,0x35,0x32,0x33,0x2e,0x31,0x39,0x34,0x7a, + 0x22,0x2f,0x3e,0x0a,0x09,0x3c,0x70,0x61,0x74,0x68, + 0x20,0x64,0x3d,0x22,0x4d,0x37,0x32,0x37,0x2e,0x38, + 0x32,0x31,0x2c,0x35,0x32,0x33,0x2e,0x31,0x39,0x34, + 0x6c,0x2d,0x37,0x2e,0x30,0x34,0x32,0x2d,0x31,0x30, + 0x2e,0x35,0x37,0x63,0x2d,0x32,0x2e,0x38,0x39,0x39, + 0x2c,0x33,0x2e,0x38,0x30,0x34,0x2d,0x36,0x2e,0x35, + 0x32,0x37,0x2c,0x36,0x2e,0x38,0x35,0x37,0x2d,0x31, + 0x30,0x2e,0x38,0x37,0x36,0x2c,0x39,0x2e,0x31,0x36, + 0x39,0x63,0x2d,0x34,0x2e,0x33,0x35,0x32,0x2c,0x32, + 0x2e,0x33,0x31,0x32,0x2d,0x39,0x2e,0x31,0x31,0x36, + 0x2c,0x33,0x2e,0x34,0x36,0x38,0x2d,0x31,0x34,0x2e, + 0x32,0x39,0x39,0x2c,0x33,0x2e,0x34,0x36,0x38,0x68, + 0x2d,0x33,0x2e,0x32,0x30,0x37,0x0a,0x09,0x09,0x63, + 0x2d,0x34,0x2e,0x32,0x38,0x36,0x2c,0x30,0x2d,0x38, + 0x2e,0x33,0x32,0x38,0x2d,0x30,0x2e,0x38,0x31,0x32, + 0x2d,0x31,0x32,0x2e,0x31,0x32,0x34,0x2d,0x32,0x2e, + 0x34,0x33,0x34,0x63,0x2d,0x33,0x2e,0x38,0x30,0x31, + 0x2d,0x31,0x2e,0x36,0x32,0x33,0x2d,0x37,0x2e,0x31, + 0x31,0x34,0x2d,0x33,0x2e,0x38,0x34,0x34,0x2d,0x39, + 0x2e,0x39,0x34,0x33,0x2d,0x36,0x2e,0x36,0x38,0x34, + 0x63,0x2d,0x32,0x2e,0x38,0x33,0x36,0x2d,0x32,0x2e, + 0x38,0x32,0x34,0x2d,0x35,0x2e,0x30,0x36,0x32,0x2d, + 0x36,0x2e,0x31,0x33,0x39,0x2d,0x36,0x2e,0x36,0x38, + 0x32,0x2d,0x39,0x2e,0x39,0x34,0x32,0x0a,0x09,0x09, + 0x63,0x2d,0x31,0x2e,0x36,0x32,0x37,0x2d,0x33,0x2e, + 0x37,0x39,0x36,0x2d,0x32,0x2e,0x34,0x33,0x35,0x2d, + 0x37,0x2e,0x38,0x33,0x39,0x2d,0x32,0x2e,0x34,0x33, + 0x35,0x2d,0x31,0x32,0x2e,0x31,0x31,0x36,0x76,0x2d, + 0x31,0x2e,0x30,0x34,0x31,0x63,0x30,0x2d,0x34,0x2e, + 0x32,0x37,0x37,0x2c,0x30,0x2e,0x38,0x30,0x38,0x2d, + 0x38,0x2e,0x33,0x32,0x2c,0x32,0x2e,0x34,0x33,0x35, + 0x2d,0x31,0x32,0x2e,0x31,0x31,0x36,0x63,0x31,0x2e, + 0x36,0x31,0x38,0x2d,0x33,0x2e,0x37,0x39,0x37,0x2c, + 0x33,0x2e,0x38,0x34,0x36,0x2d,0x37,0x2e,0x31,0x31, + 0x2c,0x36,0x2e,0x36,0x38,0x32,0x2d,0x39,0x2e,0x39, + 0x34,0x32,0x0a,0x09,0x09,0x63,0x32,0x2e,0x38,0x32, + 0x39,0x2d,0x32,0x2e,0x38,0x33,0x32,0x2c,0x36,0x2e, + 0x31,0x34,0x34,0x2d,0x35,0x2e,0x30,0x36,0x31,0x2c, + 0x39,0x2e,0x39,0x34,0x33,0x2d,0x36,0x2e,0x36,0x38, + 0x33,0x63,0x33,0x2e,0x37,0x39,0x36,0x2d,0x31,0x2e, + 0x36,0x32,0x32,0x2c,0x37,0x2e,0x38,0x33,0x38,0x2d, + 0x32,0x2e,0x34,0x33,0x35,0x2c,0x31,0x32,0x2e,0x31, + 0x32,0x34,0x2d,0x32,0x2e,0x34,0x33,0x35,0x68,0x32, + 0x36,0x2e,0x39,0x33,0x32,0x76,0x2d,0x31,0x36,0x2e, + 0x33,0x37,0x32,0x63,0x30,0x2d,0x32,0x2e,0x35,0x34, + 0x39,0x2d,0x30,0x2e,0x34,0x38,0x35,0x2d,0x34,0x2e, + 0x39,0x35,0x33,0x2d,0x31,0x2e,0x34,0x34,0x39,0x2d, + 0x37,0x2e,0x31,0x39,0x35,0x0a,0x09,0x09,0x63,0x2d, + 0x30,0x2e,0x39,0x37,0x2d,0x32,0x2e,0x32,0x34,0x31, + 0x2d,0x32,0x2e,0x32,0x38,0x31,0x2d,0x34,0x2e,0x31, + 0x39,0x34,0x2d,0x33,0x2e,0x39,0x33,0x36,0x2d,0x35, + 0x2e,0x38,0x35,0x34,0x63,0x2d,0x31,0x2e,0x36,0x36, + 0x31,0x2d,0x31,0x2e,0x36,0x35,0x33,0x2d,0x33,0x2e, + 0x36,0x31,0x32,0x2d,0x32,0x2e,0x39,0x37,0x31,0x2d, + 0x35,0x2e,0x38,0x35,0x34,0x2d,0x33,0x2e,0x39,0x33, + 0x36,0x63,0x2d,0x32,0x2e,0x32,0x34,0x32,0x2d,0x30, + 0x2e,0x39,0x36,0x34,0x2d,0x34,0x2e,0x36,0x34,0x36, + 0x2d,0x31,0x2e,0x34,0x35,0x33,0x2d,0x37,0x2e,0x31, + 0x39,0x39,0x2d,0x31,0x2e,0x34,0x35,0x33,0x68,0x2d, + 0x37,0x2e,0x34,0x35,0x39,0x0a,0x09,0x09,0x63,0x2d, + 0x32,0x2e,0x35,0x35,0x37,0x2c,0x30,0x2d,0x34,0x2e, + 0x39,0x35,0x36,0x2c,0x30,0x2e,0x34,0x38,0x39,0x2d, + 0x37,0x2e,0x32,0x30,0x32,0x2c,0x31,0x2e,0x34,0x35, + 0x33,0x63,0x2d,0x32,0x2e,0x32,0x34,0x33,0x2c,0x30, + 0x2e,0x39,0x36,0x35,0x2d,0x34,0x2e,0x31,0x39,0x34, + 0x2c,0x32,0x2e,0x32,0x38,0x31,0x2d,0x35,0x2e,0x38, + 0x35,0x32,0x2c,0x33,0x2e,0x39,0x33,0x36,0x63,0x2d, + 0x31,0x2e,0x36,0x35,0x37,0x2c,0x31,0x2e,0x36,0x36, + 0x2d,0x32,0x2e,0x39,0x37,0x31,0x2c,0x33,0x2e,0x36, + 0x31,0x33,0x2d,0x33,0x2e,0x39,0x33,0x36,0x2c,0x35, + 0x2e,0x38,0x35,0x34,0x0a,0x09,0x09,0x63,0x2d,0x30, + 0x2e,0x39,0x36,0x39,0x2c,0x32,0x2e,0x32,0x34,0x32, + 0x2d,0x31,0x2e,0x34,0x35,0x2c,0x34,0x2e,0x36,0x34, + 0x36,0x2d,0x31,0x2e,0x34,0x35,0x2c,0x37,0x2e,0x31, + 0x39,0x35,0x76,0x33,0x2e,0x38,0x33,0x34,0x6c,0x2d, + 0x31,0x32,0x2e,0x37,0x34,0x34,0x2d,0x32,0x2e,0x30, + 0x37,0x34,0x76,0x2d,0x31,0x2e,0x30,0x33,0x32,0x63, + 0x30,0x2d,0x34,0x2e,0x32,0x37,0x39,0x2c,0x30,0x2e, + 0x38,0x31,0x32,0x2d,0x38,0x2e,0x33,0x32,0x2c,0x32, 0x2e,0x34,0x33,0x35,0x2d,0x31,0x32,0x2e,0x31,0x31, - 0x36,0x63,0x31,0x2e,0x36,0x31,0x38,0x2d,0x33,0x2e, - 0x37,0x39,0x37,0x2c,0x33,0x2e,0x38,0x34,0x36,0x2d, - 0x37,0x2e,0x31,0x31,0x2c,0x36,0x2e,0x36,0x38,0x32, - 0x2d,0x39,0x2e,0x39,0x34,0x32,0x0d,0x0a,0x09,0x09, - 0x63,0x32,0x2e,0x38,0x32,0x39,0x2d,0x32,0x2e,0x38, - 0x33,0x32,0x2c,0x36,0x2e,0x31,0x34,0x34,0x2d,0x35, - 0x2e,0x30,0x36,0x31,0x2c,0x39,0x2e,0x39,0x34,0x33, - 0x2d,0x36,0x2e,0x36,0x38,0x33,0x63,0x33,0x2e,0x37, - 0x39,0x36,0x2d,0x31,0x2e,0x36,0x32,0x32,0x2c,0x37, - 0x2e,0x38,0x33,0x38,0x2d,0x32,0x2e,0x34,0x33,0x35, - 0x2c,0x31,0x32,0x2e,0x31,0x32,0x34,0x2d,0x32,0x2e, - 0x34,0x33,0x35,0x68,0x32,0x36,0x2e,0x39,0x33,0x32, - 0x76,0x2d,0x31,0x36,0x2e,0x33,0x37,0x32,0x63,0x30, - 0x2d,0x32,0x2e,0x35,0x34,0x39,0x2d,0x30,0x2e,0x34, - 0x38,0x35,0x2d,0x34,0x2e,0x39,0x35,0x33,0x2d,0x31, - 0x2e,0x34,0x34,0x39,0x2d,0x37,0x2e,0x31,0x39,0x35, - 0x0d,0x0a,0x09,0x09,0x63,0x2d,0x30,0x2e,0x39,0x37, - 0x2d,0x32,0x2e,0x32,0x34,0x31,0x2d,0x32,0x2e,0x32, - 0x38,0x31,0x2d,0x34,0x2e,0x31,0x39,0x34,0x2d,0x33, - 0x2e,0x39,0x33,0x36,0x2d,0x35,0x2e,0x38,0x35,0x34, - 0x63,0x2d,0x31,0x2e,0x36,0x36,0x31,0x2d,0x31,0x2e, - 0x36,0x35,0x33,0x2d,0x33,0x2e,0x36,0x31,0x32,0x2d, - 0x32,0x2e,0x39,0x37,0x31,0x2d,0x35,0x2e,0x38,0x35, - 0x34,0x2d,0x33,0x2e,0x39,0x33,0x36,0x63,0x2d,0x32, - 0x2e,0x32,0x34,0x32,0x2d,0x30,0x2e,0x39,0x36,0x34, - 0x2d,0x34,0x2e,0x36,0x34,0x36,0x2d,0x31,0x2e,0x34, - 0x35,0x33,0x2d,0x37,0x2e,0x31,0x39,0x39,0x2d,0x31, - 0x2e,0x34,0x35,0x33,0x68,0x2d,0x37,0x2e,0x34,0x35, - 0x39,0x0d,0x0a,0x09,0x09,0x63,0x2d,0x32,0x2e,0x35, - 0x35,0x37,0x2c,0x30,0x2d,0x34,0x2e,0x39,0x35,0x36, - 0x2c,0x30,0x2e,0x34,0x38,0x39,0x2d,0x37,0x2e,0x32, - 0x30,0x32,0x2c,0x31,0x2e,0x34,0x35,0x33,0x63,0x2d, - 0x32,0x2e,0x32,0x34,0x33,0x2c,0x30,0x2e,0x39,0x36, - 0x35,0x2d,0x34,0x2e,0x31,0x39,0x34,0x2c,0x32,0x2e, - 0x32,0x38,0x31,0x2d,0x35,0x2e,0x38,0x35,0x32,0x2c, - 0x33,0x2e,0x39,0x33,0x36,0x63,0x2d,0x31,0x2e,0x36, - 0x35,0x37,0x2c,0x31,0x2e,0x36,0x36,0x2d,0x32,0x2e, - 0x39,0x37,0x31,0x2c,0x33,0x2e,0x36,0x31,0x33,0x2d, - 0x33,0x2e,0x39,0x33,0x36,0x2c,0x35,0x2e,0x38,0x35, - 0x34,0x0d,0x0a,0x09,0x09,0x63,0x2d,0x30,0x2e,0x39, - 0x36,0x39,0x2c,0x32,0x2e,0x32,0x34,0x32,0x2d,0x31, - 0x2e,0x34,0x35,0x2c,0x34,0x2e,0x36,0x34,0x36,0x2d, - 0x31,0x2e,0x34,0x35,0x2c,0x37,0x2e,0x31,0x39,0x35, - 0x76,0x33,0x2e,0x38,0x33,0x34,0x6c,0x2d,0x31,0x32, - 0x2e,0x37,0x34,0x34,0x2d,0x32,0x2e,0x30,0x37,0x34, - 0x76,0x2d,0x31,0x2e,0x30,0x33,0x32,0x63,0x30,0x2d, - 0x34,0x2e,0x32,0x37,0x39,0x2c,0x30,0x2e,0x38,0x31, - 0x32,0x2d,0x38,0x2e,0x33,0x32,0x2c,0x32,0x2e,0x34, - 0x33,0x35,0x2d,0x31,0x32,0x2e,0x31,0x31,0x37,0x0d, - 0x0a,0x09,0x09,0x63,0x31,0x2e,0x36,0x32,0x33,0x2d, - 0x33,0x2e,0x38,0x30,0x35,0x2c,0x33,0x2e,0x38,0x35, - 0x2d,0x37,0x2e,0x31,0x31,0x37,0x2c,0x36,0x2e,0x36, - 0x38,0x33,0x2d,0x39,0x2e,0x39,0x35,0x63,0x32,0x2e, - 0x38,0x33,0x32,0x2d,0x32,0x2e,0x38,0x33,0x32,0x2c, - 0x36,0x2e,0x31,0x34,0x36,0x2d,0x35,0x2e,0x30,0x35, - 0x32,0x2c,0x39,0x2e,0x39,0x34,0x36,0x2d,0x36,0x2e, - 0x36,0x38,0x33,0x63,0x33,0x2e,0x37,0x39,0x36,0x2d, - 0x31,0x2e,0x36,0x31,0x35,0x2c,0x37,0x2e,0x38,0x33, - 0x38,0x2d,0x32,0x2e,0x34,0x33,0x35,0x2c,0x31,0x32, - 0x2e,0x31,0x32,0x2d,0x32,0x2e,0x34,0x33,0x35,0x68, - 0x37,0x2e,0x34,0x35,0x39,0x0d,0x0a,0x09,0x09,0x63, + 0x37,0x0a,0x09,0x09,0x63,0x31,0x2e,0x36,0x32,0x33, + 0x2d,0x33,0x2e,0x38,0x30,0x35,0x2c,0x33,0x2e,0x38, + 0x35,0x2d,0x37,0x2e,0x31,0x31,0x37,0x2c,0x36,0x2e, + 0x36,0x38,0x33,0x2d,0x39,0x2e,0x39,0x35,0x63,0x32, + 0x2e,0x38,0x33,0x32,0x2d,0x32,0x2e,0x38,0x33,0x32, + 0x2c,0x36,0x2e,0x31,0x34,0x36,0x2d,0x35,0x2e,0x30, + 0x35,0x32,0x2c,0x39,0x2e,0x39,0x34,0x36,0x2d,0x36, + 0x2e,0x36,0x38,0x33,0x63,0x33,0x2e,0x37,0x39,0x36, + 0x2d,0x31,0x2e,0x36,0x31,0x35,0x2c,0x37,0x2e,0x38, + 0x33,0x38,0x2d,0x32,0x2e,0x34,0x33,0x35,0x2c,0x31, + 0x32,0x2e,0x31,0x32,0x2d,0x32,0x2e,0x34,0x33,0x35, + 0x68,0x37,0x2e,0x34,0x35,0x39,0x0a,0x09,0x09,0x63, 0x34,0x2e,0x32,0x38,0x33,0x2c,0x30,0x2c,0x38,0x2e, 0x33,0x32,0x2c,0x30,0x2e,0x38,0x31,0x39,0x2c,0x31, 0x32,0x2e,0x31,0x32,0x31,0x2c,0x32,0x2e,0x34,0x33, @@ -1489,110 +1475,109 @@ const unsigned char splash_svg_data[17935] = { 0x38,0x33,0x32,0x2c,0x32,0x2e,0x38,0x33,0x33,0x2c, 0x35,0x2e,0x30,0x36,0x31,0x2c,0x36,0x2e,0x31,0x34, 0x36,0x2c,0x36,0x2e,0x36,0x38,0x34,0x2c,0x39,0x2e, - 0x39,0x35,0x0d,0x0a,0x09,0x09,0x63,0x31,0x2e,0x36, - 0x32,0x33,0x2c,0x33,0x2e,0x37,0x39,0x37,0x2c,0x32, - 0x2e,0x34,0x33,0x34,0x2c,0x37,0x2e,0x38,0x33,0x38, - 0x2c,0x32,0x2e,0x34,0x33,0x34,0x2c,0x31,0x32,0x2e, - 0x31,0x31,0x37,0x76,0x37,0x36,0x2e,0x39,0x37,0x31, - 0x48,0x37,0x32,0x37,0x2e,0x38,0x32,0x31,0x4c,0x37, - 0x32,0x37,0x2e,0x38,0x32,0x31,0x2c,0x35,0x32,0x33, - 0x2e,0x31,0x39,0x34,0x7a,0x20,0x4d,0x37,0x31,0x39, - 0x2e,0x33,0x32,0x38,0x2c,0x34,0x37,0x31,0x2e,0x38, - 0x31,0x68,0x2d,0x32,0x36,0x2e,0x39,0x33,0x32,0x63, - 0x2d,0x32,0x2e,0x35,0x36,0x31,0x2c,0x30,0x2d,0x34, - 0x2e,0x39,0x36,0x2c,0x30,0x2e,0x34,0x38,0x32,0x2d, + 0x39,0x35,0x0a,0x09,0x09,0x63,0x31,0x2e,0x36,0x32, + 0x33,0x2c,0x33,0x2e,0x37,0x39,0x37,0x2c,0x32,0x2e, + 0x34,0x33,0x34,0x2c,0x37,0x2e,0x38,0x33,0x38,0x2c, + 0x32,0x2e,0x34,0x33,0x34,0x2c,0x31,0x32,0x2e,0x31, + 0x31,0x37,0x76,0x37,0x36,0x2e,0x39,0x37,0x31,0x48, + 0x37,0x32,0x37,0x2e,0x38,0x32,0x31,0x4c,0x37,0x32, + 0x37,0x2e,0x38,0x32,0x31,0x2c,0x35,0x32,0x33,0x2e, + 0x31,0x39,0x34,0x7a,0x20,0x4d,0x37,0x31,0x39,0x2e, + 0x33,0x32,0x38,0x2c,0x34,0x37,0x31,0x2e,0x38,0x31, + 0x68,0x2d,0x32,0x36,0x2e,0x39,0x33,0x32,0x63,0x2d, + 0x32,0x2e,0x35,0x36,0x31,0x2c,0x30,0x2d,0x34,0x2e, + 0x39,0x36,0x2c,0x30,0x2e,0x34,0x38,0x32,0x2d,0x37, + 0x2e,0x32,0x30,0x32,0x2c,0x31,0x2e,0x34,0x34,0x37, + 0x0a,0x09,0x09,0x63,0x2d,0x32,0x2e,0x32,0x34,0x37, + 0x2c,0x30,0x2e,0x39,0x37,0x33,0x2d,0x34,0x2e,0x31, + 0x39,0x33,0x2c,0x32,0x2e,0x32,0x39,0x36,0x2d,0x35, + 0x2e,0x38,0x35,0x34,0x2c,0x33,0x2e,0x39,0x38,0x38, + 0x63,0x2d,0x31,0x2e,0x36,0x35,0x37,0x2c,0x31,0x2e, + 0x36,0x39,0x39,0x2d,0x32,0x2e,0x39,0x37,0x31,0x2c, + 0x33,0x2e,0x36,0x36,0x36,0x2d,0x33,0x2e,0x39,0x33, + 0x36,0x2c,0x35,0x2e,0x39,0x30,0x38,0x63,0x2d,0x30, + 0x2e,0x39,0x36,0x39,0x2c,0x32,0x2e,0x32,0x34,0x32, + 0x2d,0x31,0x2e,0x34,0x35,0x2c,0x34,0x2e,0x36,0x34, + 0x36,0x2d,0x31,0x2e,0x34,0x35,0x2c,0x37,0x2e,0x32, + 0x30,0x33,0x76,0x34,0x2e,0x34,0x34,0x36,0x0a,0x09, + 0x09,0x63,0x30,0x2c,0x32,0x2e,0x35,0x35,0x38,0x2c, + 0x30,0x2e,0x34,0x38,0x31,0x2c,0x34,0x2e,0x39,0x36, + 0x2c,0x31,0x2e,0x34,0x35,0x2c,0x37,0x2e,0x32,0x30, + 0x32,0x63,0x30,0x2e,0x39,0x36,0x35,0x2c,0x32,0x2e, + 0x32,0x34,0x33,0x2c,0x32,0x2e,0x32,0x37,0x37,0x2c, + 0x34,0x2e,0x31,0x39,0x34,0x2c,0x33,0x2e,0x39,0x33, + 0x36,0x2c,0x35,0x2e,0x38,0x35,0x35,0x63,0x31,0x2e, + 0x36,0x36,0x31,0x2c,0x31,0x2e,0x36,0x35,0x32,0x2c, + 0x33,0x2e,0x36,0x30,0x37,0x2c,0x32,0x2e,0x39,0x37, + 0x2c,0x35,0x2e,0x38,0x35,0x34,0x2c,0x33,0x2e,0x39, + 0x33,0x35,0x0a,0x09,0x09,0x63,0x32,0x2e,0x32,0x34, + 0x32,0x2c,0x30,0x2e,0x39,0x36,0x35,0x2c,0x34,0x2e, + 0x36,0x34,0x33,0x2c,0x31,0x2e,0x34,0x34,0x37,0x2c, 0x37,0x2e,0x32,0x30,0x32,0x2c,0x31,0x2e,0x34,0x34, - 0x37,0x0d,0x0a,0x09,0x09,0x63,0x2d,0x32,0x2e,0x32, - 0x34,0x37,0x2c,0x30,0x2e,0x39,0x37,0x33,0x2d,0x34, - 0x2e,0x31,0x39,0x33,0x2c,0x32,0x2e,0x32,0x39,0x36, - 0x2d,0x35,0x2e,0x38,0x35,0x34,0x2c,0x33,0x2e,0x39, - 0x38,0x38,0x63,0x2d,0x31,0x2e,0x36,0x35,0x37,0x2c, - 0x31,0x2e,0x36,0x39,0x39,0x2d,0x32,0x2e,0x39,0x37, - 0x31,0x2c,0x33,0x2e,0x36,0x36,0x36,0x2d,0x33,0x2e, - 0x39,0x33,0x36,0x2c,0x35,0x2e,0x39,0x30,0x38,0x63, - 0x2d,0x30,0x2e,0x39,0x36,0x39,0x2c,0x32,0x2e,0x32, - 0x34,0x32,0x2d,0x31,0x2e,0x34,0x35,0x2c,0x34,0x2e, - 0x36,0x34,0x36,0x2d,0x31,0x2e,0x34,0x35,0x2c,0x37, - 0x2e,0x32,0x30,0x33,0x76,0x34,0x2e,0x34,0x34,0x36, - 0x0d,0x0a,0x09,0x09,0x63,0x30,0x2c,0x32,0x2e,0x35, - 0x35,0x38,0x2c,0x30,0x2e,0x34,0x38,0x31,0x2c,0x34, - 0x2e,0x39,0x36,0x2c,0x31,0x2e,0x34,0x35,0x2c,0x37, - 0x2e,0x32,0x30,0x32,0x63,0x30,0x2e,0x39,0x36,0x35, - 0x2c,0x32,0x2e,0x32,0x34,0x33,0x2c,0x32,0x2e,0x32, - 0x37,0x37,0x2c,0x34,0x2e,0x31,0x39,0x34,0x2c,0x33, - 0x2e,0x39,0x33,0x36,0x2c,0x35,0x2e,0x38,0x35,0x35, - 0x63,0x31,0x2e,0x36,0x36,0x31,0x2c,0x31,0x2e,0x36, - 0x35,0x32,0x2c,0x33,0x2e,0x36,0x30,0x37,0x2c,0x32, - 0x2e,0x39,0x37,0x2c,0x35,0x2e,0x38,0x35,0x34,0x2c, - 0x33,0x2e,0x39,0x33,0x35,0x0d,0x0a,0x09,0x09,0x63, - 0x32,0x2e,0x32,0x34,0x32,0x2c,0x30,0x2e,0x39,0x36, - 0x35,0x2c,0x34,0x2e,0x36,0x34,0x33,0x2c,0x31,0x2e, - 0x34,0x34,0x37,0x2c,0x37,0x2e,0x32,0x30,0x32,0x2c, - 0x31,0x2e,0x34,0x34,0x37,0x68,0x38,0x2e,0x34,0x39, - 0x32,0x63,0x32,0x2e,0x35,0x35,0x33,0x2c,0x30,0x2c, - 0x34,0x2e,0x39,0x35,0x37,0x2d,0x30,0x2e,0x34,0x38, - 0x32,0x2c,0x37,0x2e,0x31,0x39,0x39,0x2d,0x31,0x2e, - 0x34,0x34,0x37,0x63,0x32,0x2e,0x32,0x34,0x31,0x2d, - 0x30,0x2e,0x39,0x36,0x35,0x2c,0x34,0x2e,0x31,0x39, - 0x33,0x2d,0x32,0x2e,0x32,0x38,0x2c,0x35,0x2e,0x38, - 0x35,0x34,0x2d,0x33,0x2e,0x39,0x33,0x35,0x0d,0x0a, - 0x09,0x09,0x63,0x31,0x2e,0x36,0x35,0x33,0x2d,0x31, - 0x2e,0x36,0x36,0x31,0x2c,0x32,0x2e,0x39,0x36,0x36, - 0x2d,0x33,0x2e,0x36,0x31,0x32,0x2c,0x33,0x2e,0x39, - 0x33,0x36,0x2d,0x35,0x2e,0x38,0x35,0x35,0x63,0x30, - 0x2e,0x39,0x36,0x34,0x2d,0x32,0x2e,0x32,0x34,0x32, - 0x2c,0x31,0x2e,0x34,0x34,0x39,0x2d,0x34,0x2e,0x36, - 0x34,0x36,0x2c,0x31,0x2e,0x34,0x34,0x39,0x2d,0x37, - 0x2e,0x32,0x30,0x32,0x4c,0x37,0x31,0x39,0x2e,0x33, - 0x32,0x38,0x2c,0x34,0x37,0x31,0x2e,0x38,0x31,0x4c, + 0x37,0x68,0x38,0x2e,0x34,0x39,0x32,0x63,0x32,0x2e, + 0x35,0x35,0x33,0x2c,0x30,0x2c,0x34,0x2e,0x39,0x35, + 0x37,0x2d,0x30,0x2e,0x34,0x38,0x32,0x2c,0x37,0x2e, + 0x31,0x39,0x39,0x2d,0x31,0x2e,0x34,0x34,0x37,0x63, + 0x32,0x2e,0x32,0x34,0x31,0x2d,0x30,0x2e,0x39,0x36, + 0x35,0x2c,0x34,0x2e,0x31,0x39,0x33,0x2d,0x32,0x2e, + 0x32,0x38,0x2c,0x35,0x2e,0x38,0x35,0x34,0x2d,0x33, + 0x2e,0x39,0x33,0x35,0x0a,0x09,0x09,0x63,0x31,0x2e, + 0x36,0x35,0x33,0x2d,0x31,0x2e,0x36,0x36,0x31,0x2c, + 0x32,0x2e,0x39,0x36,0x36,0x2d,0x33,0x2e,0x36,0x31, + 0x32,0x2c,0x33,0x2e,0x39,0x33,0x36,0x2d,0x35,0x2e, + 0x38,0x35,0x35,0x63,0x30,0x2e,0x39,0x36,0x34,0x2d, + 0x32,0x2e,0x32,0x34,0x32,0x2c,0x31,0x2e,0x34,0x34, + 0x39,0x2d,0x34,0x2e,0x36,0x34,0x36,0x2c,0x31,0x2e, + 0x34,0x34,0x39,0x2d,0x37,0x2e,0x32,0x30,0x32,0x4c, 0x37,0x31,0x39,0x2e,0x33,0x32,0x38,0x2c,0x34,0x37, - 0x31,0x2e,0x38,0x31,0x7a,0x22,0x2f,0x3e,0x0d,0x0a, - 0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x64,0x3d,0x22, - 0x4d,0x37,0x39,0x36,0x2e,0x31,0x39,0x33,0x2c,0x35, - 0x32,0x33,0x2e,0x31,0x39,0x34,0x63,0x2d,0x33,0x2e, - 0x38,0x36,0x39,0x2c,0x30,0x2d,0x37,0x2e,0x35,0x31, - 0x33,0x2d,0x30,0x2e,0x37,0x32,0x39,0x2d,0x31,0x30, - 0x2e,0x39,0x32,0x37,0x2d,0x32,0x2e,0x31,0x37,0x34, - 0x63,0x2d,0x33,0x2e,0x34,0x32,0x31,0x2d,0x31,0x2e, - 0x34,0x35,0x35,0x2d,0x36,0x2e,0x33,0x39,0x32,0x2d, - 0x33,0x2e,0x34,0x36,0x31,0x2d,0x38,0x2e,0x39,0x30, - 0x39,0x2d,0x36,0x2e,0x30,0x31,0x0d,0x0a,0x09,0x09, - 0x63,0x2d,0x32,0x2e,0x35,0x32,0x36,0x2d,0x32,0x2e, - 0x35,0x35,0x37,0x2d,0x34,0x2e,0x35,0x32,0x33,0x2d, - 0x35,0x2e,0x35,0x32,0x35,0x2d,0x36,0x2e,0x30,0x30, - 0x39,0x2d,0x38,0x2e,0x39,0x30,0x38,0x63,0x2d,0x31, - 0x2e,0x34,0x38,0x35,0x2d,0x33,0x2e,0x33,0x38,0x35, - 0x2d,0x32,0x2e,0x32,0x32,0x39,0x2d,0x37,0x2e,0x30, - 0x31,0x33,0x2d,0x32,0x2e,0x32,0x32,0x39,0x2d,0x31, - 0x30,0x2e,0x38,0x37,0x37,0x76,0x2d,0x36,0x35,0x2e, - 0x39,0x39,0x36,0x68,0x2d,0x31,0x39,0x2e,0x30,0x35, - 0x39,0x76,0x2d,0x31,0x32,0x2e,0x31,0x31,0x37,0x68, - 0x31,0x39,0x2e,0x30,0x35,0x39,0x76,0x2d,0x32,0x35, - 0x2e,0x34,0x37,0x39,0x0d,0x0a,0x09,0x09,0x6c,0x31, - 0x32,0x2e,0x37,0x34,0x31,0x2d,0x32,0x2e,0x30,0x37, - 0x33,0x76,0x32,0x37,0x2e,0x35,0x35,0x35,0x68,0x32, - 0x36,0x2e,0x39,0x33,0x32,0x76,0x31,0x32,0x2e,0x31, - 0x31,0x37,0x68,0x2d,0x32,0x36,0x2e,0x39,0x33,0x32, - 0x76,0x36,0x36,0x2e,0x36,0x31,0x34,0x63,0x30,0x2c, - 0x32,0x2e,0x31,0x34,0x34,0x2c,0x30,0x2e,0x33,0x39, - 0x35,0x2c,0x34,0x2e,0x31,0x32,0x36,0x2c,0x31,0x2e, - 0x31,0x38,0x39,0x2c,0x35,0x2e,0x39,0x35,0x35,0x63, - 0x30,0x2e,0x37,0x39,0x36,0x2c,0x31,0x2e,0x38,0x32, - 0x39,0x2c,0x31,0x2e,0x38,0x38,0x33,0x2c,0x33,0x2e, - 0x34,0x33,0x37,0x2c,0x33,0x2e,0x32,0x36,0x35,0x2c, - 0x34,0x2e,0x38,0x31,0x33,0x0d,0x0a,0x09,0x09,0x63, - 0x31,0x2e,0x33,0x38,0x32,0x2c,0x31,0x2e,0x33,0x38, - 0x36,0x2c,0x33,0x2e,0x30,0x30,0x35,0x2c,0x32,0x2e, - 0x34,0x37,0x33,0x2c,0x34,0x2e,0x38,0x36,0x38,0x2c, - 0x33,0x2e,0x32,0x37,0x63,0x31,0x2e,0x38,0x36,0x34, - 0x2c,0x30,0x2e,0x37,0x38,0x38,0x2c,0x33,0x2e,0x38, - 0x36,0x39,0x2c,0x31,0x2e,0x31,0x38,0x38,0x2c,0x36, - 0x2e,0x30,0x30,0x39,0x2c,0x31,0x2e,0x31,0x38,0x38, - 0x68,0x31,0x31,0x2e,0x36,0x76,0x31,0x32,0x2e,0x31, - 0x32,0x33,0x48,0x37,0x39,0x36,0x2e,0x31,0x39,0x33, - 0x4c,0x37,0x39,0x36,0x2e,0x31,0x39,0x33,0x2c,0x35, - 0x32,0x33,0x2e,0x31,0x39,0x34,0x7a,0x22,0x2f,0x3e, - 0x0d,0x0a,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x64, + 0x31,0x2e,0x38,0x31,0x4c,0x37,0x31,0x39,0x2e,0x33, + 0x32,0x38,0x2c,0x34,0x37,0x31,0x2e,0x38,0x31,0x7a, + 0x22,0x2f,0x3e,0x0a,0x09,0x3c,0x70,0x61,0x74,0x68, + 0x20,0x64,0x3d,0x22,0x4d,0x37,0x39,0x36,0x2e,0x31, + 0x39,0x33,0x2c,0x35,0x32,0x33,0x2e,0x31,0x39,0x34, + 0x63,0x2d,0x33,0x2e,0x38,0x36,0x39,0x2c,0x30,0x2d, + 0x37,0x2e,0x35,0x31,0x33,0x2d,0x30,0x2e,0x37,0x32, + 0x39,0x2d,0x31,0x30,0x2e,0x39,0x32,0x37,0x2d,0x32, + 0x2e,0x31,0x37,0x34,0x63,0x2d,0x33,0x2e,0x34,0x32, + 0x31,0x2d,0x31,0x2e,0x34,0x35,0x35,0x2d,0x36,0x2e, + 0x33,0x39,0x32,0x2d,0x33,0x2e,0x34,0x36,0x31,0x2d, + 0x38,0x2e,0x39,0x30,0x39,0x2d,0x36,0x2e,0x30,0x31, + 0x0a,0x09,0x09,0x63,0x2d,0x32,0x2e,0x35,0x32,0x36, + 0x2d,0x32,0x2e,0x35,0x35,0x37,0x2d,0x34,0x2e,0x35, + 0x32,0x33,0x2d,0x35,0x2e,0x35,0x32,0x35,0x2d,0x36, + 0x2e,0x30,0x30,0x39,0x2d,0x38,0x2e,0x39,0x30,0x38, + 0x63,0x2d,0x31,0x2e,0x34,0x38,0x35,0x2d,0x33,0x2e, + 0x33,0x38,0x35,0x2d,0x32,0x2e,0x32,0x32,0x39,0x2d, + 0x37,0x2e,0x30,0x31,0x33,0x2d,0x32,0x2e,0x32,0x32, + 0x39,0x2d,0x31,0x30,0x2e,0x38,0x37,0x37,0x76,0x2d, + 0x36,0x35,0x2e,0x39,0x39,0x36,0x68,0x2d,0x31,0x39, + 0x2e,0x30,0x35,0x39,0x76,0x2d,0x31,0x32,0x2e,0x31, + 0x31,0x37,0x68,0x31,0x39,0x2e,0x30,0x35,0x39,0x76, + 0x2d,0x32,0x35,0x2e,0x34,0x37,0x39,0x0a,0x09,0x09, + 0x6c,0x31,0x32,0x2e,0x37,0x34,0x31,0x2d,0x32,0x2e, + 0x30,0x37,0x33,0x76,0x32,0x37,0x2e,0x35,0x35,0x35, + 0x68,0x32,0x36,0x2e,0x39,0x33,0x32,0x76,0x31,0x32, + 0x2e,0x31,0x31,0x37,0x68,0x2d,0x32,0x36,0x2e,0x39, + 0x33,0x32,0x76,0x36,0x36,0x2e,0x36,0x31,0x34,0x63, + 0x30,0x2c,0x32,0x2e,0x31,0x34,0x34,0x2c,0x30,0x2e, + 0x33,0x39,0x35,0x2c,0x34,0x2e,0x31,0x32,0x36,0x2c, + 0x31,0x2e,0x31,0x38,0x39,0x2c,0x35,0x2e,0x39,0x35, + 0x35,0x63,0x30,0x2e,0x37,0x39,0x36,0x2c,0x31,0x2e, + 0x38,0x32,0x39,0x2c,0x31,0x2e,0x38,0x38,0x33,0x2c, + 0x33,0x2e,0x34,0x33,0x37,0x2c,0x33,0x2e,0x32,0x36, + 0x35,0x2c,0x34,0x2e,0x38,0x31,0x33,0x0a,0x09,0x09, + 0x63,0x31,0x2e,0x33,0x38,0x32,0x2c,0x31,0x2e,0x33, + 0x38,0x36,0x2c,0x33,0x2e,0x30,0x30,0x35,0x2c,0x32, + 0x2e,0x34,0x37,0x33,0x2c,0x34,0x2e,0x38,0x36,0x38, + 0x2c,0x33,0x2e,0x32,0x37,0x63,0x31,0x2e,0x38,0x36, + 0x34,0x2c,0x30,0x2e,0x37,0x38,0x38,0x2c,0x33,0x2e, + 0x38,0x36,0x39,0x2c,0x31,0x2e,0x31,0x38,0x38,0x2c, + 0x36,0x2e,0x30,0x30,0x39,0x2c,0x31,0x2e,0x31,0x38, + 0x38,0x68,0x31,0x31,0x2e,0x36,0x76,0x31,0x32,0x2e, + 0x31,0x32,0x33,0x48,0x37,0x39,0x36,0x2e,0x31,0x39, + 0x33,0x4c,0x37,0x39,0x36,0x2e,0x31,0x39,0x33,0x2c, + 0x35,0x32,0x33,0x2e,0x31,0x39,0x34,0x7a,0x22,0x2f, + 0x3e,0x0a,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x64, 0x3d,0x22,0x4d,0x38,0x33,0x34,0x2e,0x34,0x31,0x39, 0x2c,0x33,0x39,0x31,0x2e,0x36,0x33,0x32,0x76,0x2d, 0x31,0x36,0x2e,0x39,0x38,0x38,0x68,0x31,0x34,0x2e, @@ -1603,108 +1588,107 @@ const unsigned char splash_svg_data[17935] = { 0x2e,0x31,0x31,0x33,0x68,0x31,0x32,0x2e,0x37,0x34, 0x76,0x31,0x30,0x36,0x2e,0x30,0x38,0x31,0x48,0x38, 0x33,0x35,0x2e,0x34,0x35,0x35,0x7a,0x22,0x2f,0x3e, - 0x0d,0x0a,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x64, - 0x3d,0x22,0x4d,0x39,0x34,0x36,0x2e,0x33,0x35,0x31, - 0x2c,0x35,0x30,0x36,0x2e,0x32,0x30,0x31,0x63,0x2d, - 0x31,0x2e,0x36,0x32,0x33,0x2c,0x33,0x2e,0x38,0x30, - 0x35,0x2d,0x33,0x2e,0x38,0x35,0x2c,0x37,0x2e,0x31, - 0x31,0x38,0x2d,0x36,0x2e,0x36,0x38,0x32,0x2c,0x39, - 0x2e,0x39,0x34,0x32,0x63,0x2d,0x32,0x2e,0x38,0x33, - 0x32,0x2c,0x32,0x2e,0x38,0x34,0x2d,0x36,0x2e,0x31, - 0x34,0x36,0x2c,0x35,0x2e,0x30,0x36,0x31,0x2d,0x39, - 0x2e,0x39,0x34,0x33,0x2c,0x36,0x2e,0x36,0x38,0x34, - 0x0d,0x0a,0x09,0x09,0x63,0x2d,0x33,0x2e,0x38,0x30, - 0x31,0x2c,0x31,0x2e,0x36,0x32,0x32,0x2d,0x37,0x2e, - 0x38,0x33,0x38,0x2c,0x32,0x2e,0x34,0x33,0x34,0x2d, - 0x31,0x32,0x2e,0x31,0x32,0x2c,0x32,0x2e,0x34,0x33, - 0x34,0x68,0x2d,0x38,0x2e,0x34,0x39,0x33,0x63,0x2d, - 0x34,0x2e,0x32,0x38,0x36,0x2c,0x30,0x2d,0x38,0x2e, - 0x33,0x32,0x37,0x2d,0x30,0x2e,0x38,0x31,0x32,0x2d, - 0x31,0x32,0x2e,0x31,0x32,0x34,0x2d,0x32,0x2e,0x34, - 0x33,0x34,0x63,0x2d,0x33,0x2e,0x37,0x39,0x36,0x2d, - 0x31,0x2e,0x36,0x32,0x33,0x2d,0x37,0x2e,0x31,0x30, - 0x39,0x2d,0x33,0x2e,0x38,0x34,0x34,0x2d,0x39,0x2e, - 0x39,0x34,0x31,0x2d,0x36,0x2e,0x36,0x38,0x34,0x0d, - 0x0a,0x09,0x09,0x63,0x2d,0x32,0x2e,0x38,0x33,0x32, - 0x2d,0x32,0x2e,0x38,0x32,0x34,0x2d,0x35,0x2e,0x30, - 0x36,0x31,0x2d,0x36,0x2e,0x31,0x33,0x39,0x2d,0x36, - 0x2e,0x36,0x38,0x34,0x2d,0x39,0x2e,0x39,0x34,0x32, - 0x63,0x2d,0x31,0x2e,0x36,0x32,0x33,0x2d,0x33,0x2e, - 0x37,0x39,0x36,0x2d,0x32,0x2e,0x34,0x33,0x35,0x2d, - 0x37,0x2e,0x38,0x33,0x39,0x2d,0x32,0x2e,0x34,0x33, - 0x35,0x2d,0x31,0x32,0x2e,0x31,0x31,0x36,0x76,0x2d, - 0x34,0x37,0x2e,0x38,0x36,0x31,0x63,0x30,0x2d,0x34, - 0x2e,0x32,0x37,0x39,0x2c,0x30,0x2e,0x38,0x31,0x32, - 0x2d,0x38,0x2e,0x33,0x32,0x2c,0x32,0x2e,0x34,0x33, - 0x35,0x2d,0x31,0x32,0x2e,0x31,0x31,0x37,0x0d,0x0a, - 0x09,0x09,0x63,0x31,0x2e,0x36,0x32,0x33,0x2d,0x33, - 0x2e,0x38,0x30,0x35,0x2c,0x33,0x2e,0x38,0x35,0x32, - 0x2d,0x37,0x2e,0x31,0x31,0x37,0x2c,0x36,0x2e,0x36, - 0x38,0x34,0x2d,0x39,0x2e,0x39,0x35,0x63,0x32,0x2e, - 0x38,0x33,0x31,0x2d,0x32,0x2e,0x38,0x33,0x32,0x2c, - 0x36,0x2e,0x31,0x34,0x36,0x2d,0x35,0x2e,0x30,0x35, - 0x32,0x2c,0x39,0x2e,0x39,0x34,0x31,0x2d,0x36,0x2e, - 0x36,0x38,0x33,0x63,0x33,0x2e,0x37,0x39,0x37,0x2d, - 0x31,0x2e,0x36,0x31,0x35,0x2c,0x37,0x2e,0x38,0x33, - 0x38,0x2d,0x32,0x2e,0x34,0x33,0x35,0x2c,0x31,0x32, - 0x2e,0x31,0x32,0x34,0x2d,0x32,0x2e,0x34,0x33,0x35, - 0x68,0x38,0x2e,0x34,0x39,0x33,0x0d,0x0a,0x09,0x09, - 0x63,0x34,0x2e,0x32,0x38,0x32,0x2c,0x30,0x2c,0x38, - 0x2e,0x33,0x31,0x39,0x2c,0x30,0x2e,0x38,0x31,0x39, - 0x2c,0x31,0x32,0x2e,0x31,0x32,0x2c,0x32,0x2e,0x34, - 0x33,0x35,0x63,0x33,0x2e,0x37,0x39,0x37,0x2c,0x31, - 0x2e,0x36,0x33,0x31,0x2c,0x37,0x2e,0x31,0x31,0x31, - 0x2c,0x33,0x2e,0x38,0x35,0x31,0x2c,0x39,0x2e,0x39, - 0x34,0x33,0x2c,0x36,0x2e,0x36,0x38,0x33,0x63,0x32, - 0x2e,0x38,0x33,0x31,0x2c,0x32,0x2e,0x38,0x33,0x33, - 0x2c,0x35,0x2e,0x30,0x35,0x39,0x2c,0x36,0x2e,0x31, - 0x34,0x36,0x2c,0x36,0x2e,0x36,0x38,0x32,0x2c,0x39, - 0x2e,0x39,0x35,0x0d,0x0a,0x09,0x09,0x63,0x31,0x2e, - 0x36,0x32,0x33,0x2c,0x33,0x2e,0x37,0x39,0x37,0x2c, - 0x32,0x2e,0x34,0x33,0x34,0x2c,0x37,0x2e,0x38,0x33, - 0x38,0x2c,0x32,0x2e,0x34,0x33,0x34,0x2c,0x31,0x32, - 0x2e,0x31,0x31,0x37,0x76,0x34,0x37,0x2e,0x38,0x36, - 0x31,0x43,0x39,0x34,0x38,0x2e,0x37,0x38,0x33,0x2c, - 0x34,0x39,0x38,0x2e,0x33,0x36,0x33,0x2c,0x39,0x34, - 0x37,0x2e,0x39,0x37,0x34,0x2c,0x35,0x30,0x32,0x2e, - 0x34,0x30,0x35,0x2c,0x39,0x34,0x36,0x2e,0x33,0x35, - 0x31,0x2c,0x35,0x30,0x36,0x2e,0x32,0x30,0x31,0x7a, - 0x20,0x4d,0x39,0x33,0x36,0x2e,0x30,0x34,0x34,0x2c, - 0x34,0x34,0x35,0x2e,0x34,0x39,0x36,0x0d,0x0a,0x09, - 0x09,0x63,0x30,0x2d,0x32,0x2e,0x35,0x34,0x39,0x2d, - 0x30,0x2e,0x34,0x38,0x35,0x2d,0x34,0x2e,0x39,0x35, - 0x33,0x2d,0x31,0x2e,0x34,0x35,0x2d,0x37,0x2e,0x31, - 0x39,0x35,0x63,0x2d,0x30,0x2e,0x39,0x36,0x38,0x2d, - 0x32,0x2e,0x32,0x34,0x31,0x2d,0x32,0x2e,0x32,0x38, - 0x31,0x2d,0x34,0x2e,0x31,0x39,0x34,0x2d,0x33,0x2e, - 0x39,0x33,0x36,0x2d,0x35,0x2e,0x38,0x35,0x34,0x63, - 0x2d,0x31,0x2e,0x36,0x36,0x31,0x2d,0x31,0x2e,0x36, - 0x35,0x33,0x2d,0x33,0x2e,0x36,0x31,0x31,0x2d,0x32, - 0x2e,0x39,0x37,0x31,0x2d,0x35,0x2e,0x38,0x35,0x34, - 0x2d,0x33,0x2e,0x39,0x33,0x36,0x0d,0x0a,0x09,0x09, - 0x63,0x2d,0x32,0x2e,0x32,0x34,0x32,0x2d,0x30,0x2e, - 0x39,0x36,0x34,0x2d,0x34,0x2e,0x36,0x34,0x36,0x2d, - 0x31,0x2e,0x34,0x35,0x33,0x2d,0x37,0x2e,0x31,0x39, - 0x38,0x2d,0x31,0x2e,0x34,0x35,0x33,0x68,0x2d,0x38, - 0x2e,0x34,0x39,0x33,0x63,0x2d,0x32,0x2e,0x35,0x35, - 0x37,0x2c,0x30,0x2d,0x34,0x2e,0x39,0x36,0x2c,0x30, - 0x2e,0x34,0x38,0x39,0x2d,0x37,0x2e,0x32,0x30,0x32, - 0x2c,0x31,0x2e,0x34,0x35,0x33,0x63,0x2d,0x32,0x2e, - 0x32,0x34,0x32,0x2c,0x30,0x2e,0x39,0x36,0x35,0x2d, - 0x34,0x2e,0x31,0x39,0x33,0x2c,0x32,0x2e,0x32,0x38, - 0x31,0x2d,0x35,0x2e,0x38,0x35,0x34,0x2c,0x33,0x2e, - 0x39,0x33,0x36,0x0d,0x0a,0x09,0x09,0x63,0x2d,0x31, - 0x2e,0x36,0x35,0x33,0x2c,0x31,0x2e,0x36,0x36,0x2d, - 0x32,0x2e,0x39,0x37,0x2c,0x33,0x2e,0x36,0x31,0x33, - 0x2d,0x33,0x2e,0x39,0x33,0x36,0x2c,0x35,0x2e,0x38, - 0x35,0x34,0x63,0x2d,0x30,0x2e,0x39,0x36,0x38,0x2c, - 0x32,0x2e,0x32,0x34,0x32,0x2d,0x31,0x2e,0x34,0x34, - 0x39,0x2c,0x34,0x2e,0x36,0x34,0x36,0x2d,0x31,0x2e, - 0x34,0x34,0x39,0x2c,0x37,0x2e,0x31,0x39,0x35,0x76, - 0x34,0x39,0x2e,0x33,0x31,0x63,0x30,0x2c,0x32,0x2e, - 0x35,0x35,0x37,0x2c,0x30,0x2e,0x34,0x38,0x31,0x2c, - 0x34,0x2e,0x39,0x35,0x39,0x2c,0x31,0x2e,0x34,0x34, - 0x39,0x2c,0x37,0x2e,0x32,0x30,0x31,0x0d,0x0a,0x09, + 0x0a,0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x64,0x3d, + 0x22,0x4d,0x39,0x34,0x36,0x2e,0x33,0x35,0x31,0x2c, + 0x35,0x30,0x36,0x2e,0x32,0x30,0x31,0x63,0x2d,0x31, + 0x2e,0x36,0x32,0x33,0x2c,0x33,0x2e,0x38,0x30,0x35, + 0x2d,0x33,0x2e,0x38,0x35,0x2c,0x37,0x2e,0x31,0x31, + 0x38,0x2d,0x36,0x2e,0x36,0x38,0x32,0x2c,0x39,0x2e, + 0x39,0x34,0x32,0x63,0x2d,0x32,0x2e,0x38,0x33,0x32, + 0x2c,0x32,0x2e,0x38,0x34,0x2d,0x36,0x2e,0x31,0x34, + 0x36,0x2c,0x35,0x2e,0x30,0x36,0x31,0x2d,0x39,0x2e, + 0x39,0x34,0x33,0x2c,0x36,0x2e,0x36,0x38,0x34,0x0a, + 0x09,0x09,0x63,0x2d,0x33,0x2e,0x38,0x30,0x31,0x2c, + 0x31,0x2e,0x36,0x32,0x32,0x2d,0x37,0x2e,0x38,0x33, + 0x38,0x2c,0x32,0x2e,0x34,0x33,0x34,0x2d,0x31,0x32, + 0x2e,0x31,0x32,0x2c,0x32,0x2e,0x34,0x33,0x34,0x68, + 0x2d,0x38,0x2e,0x34,0x39,0x33,0x63,0x2d,0x34,0x2e, + 0x32,0x38,0x36,0x2c,0x30,0x2d,0x38,0x2e,0x33,0x32, + 0x37,0x2d,0x30,0x2e,0x38,0x31,0x32,0x2d,0x31,0x32, + 0x2e,0x31,0x32,0x34,0x2d,0x32,0x2e,0x34,0x33,0x34, + 0x63,0x2d,0x33,0x2e,0x37,0x39,0x36,0x2d,0x31,0x2e, + 0x36,0x32,0x33,0x2d,0x37,0x2e,0x31,0x30,0x39,0x2d, + 0x33,0x2e,0x38,0x34,0x34,0x2d,0x39,0x2e,0x39,0x34, + 0x31,0x2d,0x36,0x2e,0x36,0x38,0x34,0x0a,0x09,0x09, + 0x63,0x2d,0x32,0x2e,0x38,0x33,0x32,0x2d,0x32,0x2e, + 0x38,0x32,0x34,0x2d,0x35,0x2e,0x30,0x36,0x31,0x2d, + 0x36,0x2e,0x31,0x33,0x39,0x2d,0x36,0x2e,0x36,0x38, + 0x34,0x2d,0x39,0x2e,0x39,0x34,0x32,0x63,0x2d,0x31, + 0x2e,0x36,0x32,0x33,0x2d,0x33,0x2e,0x37,0x39,0x36, + 0x2d,0x32,0x2e,0x34,0x33,0x35,0x2d,0x37,0x2e,0x38, + 0x33,0x39,0x2d,0x32,0x2e,0x34,0x33,0x35,0x2d,0x31, + 0x32,0x2e,0x31,0x31,0x36,0x76,0x2d,0x34,0x37,0x2e, + 0x38,0x36,0x31,0x63,0x30,0x2d,0x34,0x2e,0x32,0x37, + 0x39,0x2c,0x30,0x2e,0x38,0x31,0x32,0x2d,0x38,0x2e, + 0x33,0x32,0x2c,0x32,0x2e,0x34,0x33,0x35,0x2d,0x31, + 0x32,0x2e,0x31,0x31,0x37,0x0a,0x09,0x09,0x63,0x31, + 0x2e,0x36,0x32,0x33,0x2d,0x33,0x2e,0x38,0x30,0x35, + 0x2c,0x33,0x2e,0x38,0x35,0x32,0x2d,0x37,0x2e,0x31, + 0x31,0x37,0x2c,0x36,0x2e,0x36,0x38,0x34,0x2d,0x39, + 0x2e,0x39,0x35,0x63,0x32,0x2e,0x38,0x33,0x31,0x2d, + 0x32,0x2e,0x38,0x33,0x32,0x2c,0x36,0x2e,0x31,0x34, + 0x36,0x2d,0x35,0x2e,0x30,0x35,0x32,0x2c,0x39,0x2e, + 0x39,0x34,0x31,0x2d,0x36,0x2e,0x36,0x38,0x33,0x63, + 0x33,0x2e,0x37,0x39,0x37,0x2d,0x31,0x2e,0x36,0x31, + 0x35,0x2c,0x37,0x2e,0x38,0x33,0x38,0x2d,0x32,0x2e, + 0x34,0x33,0x35,0x2c,0x31,0x32,0x2e,0x31,0x32,0x34, + 0x2d,0x32,0x2e,0x34,0x33,0x35,0x68,0x38,0x2e,0x34, + 0x39,0x33,0x0a,0x09,0x09,0x63,0x34,0x2e,0x32,0x38, + 0x32,0x2c,0x30,0x2c,0x38,0x2e,0x33,0x31,0x39,0x2c, + 0x30,0x2e,0x38,0x31,0x39,0x2c,0x31,0x32,0x2e,0x31, + 0x32,0x2c,0x32,0x2e,0x34,0x33,0x35,0x63,0x33,0x2e, + 0x37,0x39,0x37,0x2c,0x31,0x2e,0x36,0x33,0x31,0x2c, + 0x37,0x2e,0x31,0x31,0x31,0x2c,0x33,0x2e,0x38,0x35, + 0x31,0x2c,0x39,0x2e,0x39,0x34,0x33,0x2c,0x36,0x2e, + 0x36,0x38,0x33,0x63,0x32,0x2e,0x38,0x33,0x31,0x2c, + 0x32,0x2e,0x38,0x33,0x33,0x2c,0x35,0x2e,0x30,0x35, + 0x39,0x2c,0x36,0x2e,0x31,0x34,0x36,0x2c,0x36,0x2e, + 0x36,0x38,0x32,0x2c,0x39,0x2e,0x39,0x35,0x0a,0x09, + 0x09,0x63,0x31,0x2e,0x36,0x32,0x33,0x2c,0x33,0x2e, + 0x37,0x39,0x37,0x2c,0x32,0x2e,0x34,0x33,0x34,0x2c, + 0x37,0x2e,0x38,0x33,0x38,0x2c,0x32,0x2e,0x34,0x33, + 0x34,0x2c,0x31,0x32,0x2e,0x31,0x31,0x37,0x76,0x34, + 0x37,0x2e,0x38,0x36,0x31,0x43,0x39,0x34,0x38,0x2e, + 0x37,0x38,0x33,0x2c,0x34,0x39,0x38,0x2e,0x33,0x36, + 0x33,0x2c,0x39,0x34,0x37,0x2e,0x39,0x37,0x34,0x2c, + 0x35,0x30,0x32,0x2e,0x34,0x30,0x35,0x2c,0x39,0x34, + 0x36,0x2e,0x33,0x35,0x31,0x2c,0x35,0x30,0x36,0x2e, + 0x32,0x30,0x31,0x7a,0x20,0x4d,0x39,0x33,0x36,0x2e, + 0x30,0x34,0x34,0x2c,0x34,0x34,0x35,0x2e,0x34,0x39, + 0x36,0x0a,0x09,0x09,0x63,0x30,0x2d,0x32,0x2e,0x35, + 0x34,0x39,0x2d,0x30,0x2e,0x34,0x38,0x35,0x2d,0x34, + 0x2e,0x39,0x35,0x33,0x2d,0x31,0x2e,0x34,0x35,0x2d, + 0x37,0x2e,0x31,0x39,0x35,0x63,0x2d,0x30,0x2e,0x39, + 0x36,0x38,0x2d,0x32,0x2e,0x32,0x34,0x31,0x2d,0x32, + 0x2e,0x32,0x38,0x31,0x2d,0x34,0x2e,0x31,0x39,0x34, + 0x2d,0x33,0x2e,0x39,0x33,0x36,0x2d,0x35,0x2e,0x38, + 0x35,0x34,0x63,0x2d,0x31,0x2e,0x36,0x36,0x31,0x2d, + 0x31,0x2e,0x36,0x35,0x33,0x2d,0x33,0x2e,0x36,0x31, + 0x31,0x2d,0x32,0x2e,0x39,0x37,0x31,0x2d,0x35,0x2e, + 0x38,0x35,0x34,0x2d,0x33,0x2e,0x39,0x33,0x36,0x0a, + 0x09,0x09,0x63,0x2d,0x32,0x2e,0x32,0x34,0x32,0x2d, + 0x30,0x2e,0x39,0x36,0x34,0x2d,0x34,0x2e,0x36,0x34, + 0x36,0x2d,0x31,0x2e,0x34,0x35,0x33,0x2d,0x37,0x2e, + 0x31,0x39,0x38,0x2d,0x31,0x2e,0x34,0x35,0x33,0x68, + 0x2d,0x38,0x2e,0x34,0x39,0x33,0x63,0x2d,0x32,0x2e, + 0x35,0x35,0x37,0x2c,0x30,0x2d,0x34,0x2e,0x39,0x36, + 0x2c,0x30,0x2e,0x34,0x38,0x39,0x2d,0x37,0x2e,0x32, + 0x30,0x32,0x2c,0x31,0x2e,0x34,0x35,0x33,0x63,0x2d, + 0x32,0x2e,0x32,0x34,0x32,0x2c,0x30,0x2e,0x39,0x36, + 0x35,0x2d,0x34,0x2e,0x31,0x39,0x33,0x2c,0x32,0x2e, + 0x32,0x38,0x31,0x2d,0x35,0x2e,0x38,0x35,0x34,0x2c, + 0x33,0x2e,0x39,0x33,0x36,0x0a,0x09,0x09,0x63,0x2d, + 0x31,0x2e,0x36,0x35,0x33,0x2c,0x31,0x2e,0x36,0x36, + 0x2d,0x32,0x2e,0x39,0x37,0x2c,0x33,0x2e,0x36,0x31, + 0x33,0x2d,0x33,0x2e,0x39,0x33,0x36,0x2c,0x35,0x2e, + 0x38,0x35,0x34,0x63,0x2d,0x30,0x2e,0x39,0x36,0x38, + 0x2c,0x32,0x2e,0x32,0x34,0x32,0x2d,0x31,0x2e,0x34, + 0x34,0x39,0x2c,0x34,0x2e,0x36,0x34,0x36,0x2d,0x31, + 0x2e,0x34,0x34,0x39,0x2c,0x37,0x2e,0x31,0x39,0x35, + 0x76,0x34,0x39,0x2e,0x33,0x31,0x63,0x30,0x2c,0x32, + 0x2e,0x35,0x35,0x37,0x2c,0x30,0x2e,0x34,0x38,0x31, + 0x2c,0x34,0x2e,0x39,0x35,0x39,0x2c,0x31,0x2e,0x34, + 0x34,0x39,0x2c,0x37,0x2e,0x32,0x30,0x31,0x0a,0x09, 0x09,0x63,0x30,0x2e,0x39,0x36,0x36,0x2c,0x32,0x2e, 0x32,0x34,0x33,0x2c,0x32,0x2e,0x32,0x38,0x31,0x2c, 0x34,0x2e,0x31,0x39,0x34,0x2c,0x33,0x2e,0x39,0x33, @@ -1716,86 +1700,86 @@ const unsigned char splash_svg_data[17935] = { 0x2e,0x39,0x36,0x36,0x2c,0x34,0x2e,0x36,0x34,0x36, 0x2c,0x31,0x2e,0x34,0x34,0x37,0x2c,0x37,0x2e,0x32, 0x30,0x32,0x2c,0x31,0x2e,0x34,0x34,0x37,0x68,0x38, - 0x2e,0x34,0x39,0x33,0x0d,0x0a,0x09,0x09,0x63,0x32, - 0x2e,0x35,0x35,0x33,0x2c,0x30,0x2c,0x34,0x2e,0x39, - 0x35,0x36,0x2d,0x30,0x2e,0x34,0x38,0x31,0x2c,0x37, - 0x2e,0x31,0x39,0x38,0x2d,0x31,0x2e,0x34,0x34,0x37, - 0x63,0x32,0x2e,0x32,0x34,0x33,0x2d,0x30,0x2e,0x39, - 0x36,0x35,0x2c,0x34,0x2e,0x31,0x39,0x33,0x2d,0x32, - 0x2e,0x32,0x38,0x2c,0x35,0x2e,0x38,0x35,0x34,0x2d, - 0x33,0x2e,0x39,0x33,0x35,0x63,0x31,0x2e,0x36,0x35, - 0x33,0x2d,0x31,0x2e,0x36,0x36,0x31,0x2c,0x32,0x2e, - 0x39,0x36,0x38,0x2d,0x33,0x2e,0x36,0x31,0x32,0x2c, - 0x33,0x2e,0x39,0x33,0x36,0x2d,0x35,0x2e,0x38,0x35, - 0x35,0x0d,0x0a,0x09,0x09,0x63,0x30,0x2e,0x39,0x36, - 0x35,0x2d,0x32,0x2e,0x32,0x34,0x32,0x2c,0x31,0x2e, - 0x34,0x35,0x2d,0x34,0x2e,0x36,0x34,0x36,0x2c,0x31, - 0x2e,0x34,0x35,0x2d,0x37,0x2e,0x32,0x30,0x31,0x56, - 0x34,0x34,0x35,0x2e,0x34,0x39,0x36,0x7a,0x22,0x2f, - 0x3e,0x0d,0x0a,0x09,0x3c,0x70,0x61,0x74,0x68,0x20, - 0x64,0x3d,0x22,0x4d,0x31,0x30,0x33,0x32,0x2e,0x33, - 0x38,0x35,0x2c,0x35,0x32,0x33,0x2e,0x31,0x39,0x34, - 0x76,0x2d,0x37,0x37,0x2e,0x36,0x39,0x38,0x63,0x30, - 0x2d,0x32,0x2e,0x35,0x34,0x39,0x2d,0x30,0x2e,0x34, - 0x38,0x32,0x2d,0x34,0x2e,0x39,0x35,0x33,0x2d,0x31, - 0x2e,0x34,0x35,0x2d,0x37,0x2e,0x31,0x39,0x35,0x63, - 0x2d,0x30,0x2e,0x39,0x36,0x39,0x2d,0x32,0x2e,0x32, - 0x34,0x31,0x2d,0x32,0x2e,0x32,0x37,0x37,0x2d,0x34, - 0x2e,0x31,0x39,0x34,0x2d,0x33,0x2e,0x39,0x33,0x38, - 0x2d,0x35,0x2e,0x38,0x35,0x34,0x0d,0x0a,0x09,0x09, - 0x63,0x2d,0x31,0x2e,0x36,0x35,0x32,0x2d,0x31,0x2e, - 0x36,0x35,0x33,0x2d,0x33,0x2e,0x36,0x30,0x38,0x2d, - 0x32,0x2e,0x39,0x37,0x31,0x2d,0x35,0x2e,0x38,0x35, - 0x32,0x2d,0x33,0x2e,0x39,0x33,0x36,0x63,0x2d,0x32, - 0x2e,0x32,0x34,0x37,0x2d,0x30,0x2e,0x39,0x36,0x34, - 0x2d,0x34,0x2e,0x36,0x34,0x36,0x2d,0x31,0x2e,0x34, - 0x35,0x33,0x2d,0x37,0x2e,0x31,0x39,0x39,0x2d,0x31, - 0x2e,0x34,0x35,0x33,0x68,0x2d,0x38,0x2e,0x34,0x39, - 0x36,0x63,0x2d,0x32,0x2e,0x35,0x35,0x37,0x2c,0x30, - 0x2d,0x34,0x2e,0x39,0x35,0x36,0x2c,0x30,0x2e,0x34, - 0x38,0x39,0x2d,0x37,0x2e,0x31,0x39,0x38,0x2c,0x31, - 0x2e,0x34,0x35,0x33,0x0d,0x0a,0x09,0x09,0x63,0x2d, - 0x32,0x2e,0x32,0x34,0x36,0x2c,0x30,0x2e,0x39,0x36, - 0x35,0x2d,0x34,0x2e,0x31,0x39,0x34,0x2c,0x32,0x2e, - 0x32,0x38,0x31,0x2d,0x35,0x2e,0x38,0x35,0x33,0x2c, - 0x33,0x2e,0x39,0x33,0x36,0x63,0x2d,0x31,0x2e,0x36, - 0x36,0x31,0x2c,0x31,0x2e,0x36,0x36,0x2d,0x32,0x2e, - 0x39,0x37,0x2c,0x33,0x2e,0x36,0x31,0x33,0x2d,0x33, - 0x2e,0x39,0x33,0x38,0x2c,0x35,0x2e,0x38,0x35,0x34, - 0x63,0x2d,0x30,0x2e,0x39,0x37,0x2c,0x32,0x2e,0x32, - 0x34,0x32,0x2d,0x31,0x2e,0x34,0x35,0x31,0x2c,0x34, - 0x2e,0x36,0x34,0x36,0x2d,0x31,0x2e,0x34,0x35,0x31, - 0x2c,0x37,0x2e,0x31,0x39,0x35,0x76,0x37,0x37,0x2e, - 0x36,0x39,0x38,0x68,0x2d,0x31,0x32,0x2e,0x37,0x34, - 0x0d,0x0a,0x09,0x09,0x56,0x34,0x31,0x37,0x2e,0x31, - 0x31,0x33,0x68,0x34,0x2e,0x32,0x34,0x34,0x6c,0x36, - 0x2e,0x39,0x34,0x32,0x2c,0x31,0x30,0x2e,0x37,0x37, - 0x36,0x63,0x32,0x2e,0x39,0x2d,0x33,0x2e,0x39,0x34, - 0x2c,0x36,0x2e,0x35,0x34,0x35,0x2d,0x37,0x2e,0x30, - 0x36,0x33,0x2c,0x31,0x30,0x2e,0x39,0x33,0x31,0x2d, - 0x39,0x2e,0x33,0x37,0x35,0x63,0x34,0x2e,0x33,0x38, - 0x36,0x2d,0x32,0x2e,0x33,0x31,0x32,0x2c,0x39,0x2e, - 0x31,0x37,0x2d,0x33,0x2e,0x34,0x37,0x37,0x2c,0x31, - 0x34,0x2e,0x33,0x34,0x34,0x2d,0x33,0x2e,0x34,0x37, - 0x37,0x68,0x33,0x2e,0x32,0x31,0x35,0x0d,0x0a,0x09, - 0x09,0x63,0x34,0x2e,0x32,0x37,0x38,0x2c,0x30,0x2c, - 0x38,0x2e,0x33,0x32,0x2c,0x30,0x2e,0x38,0x31,0x38, - 0x2c,0x31,0x32,0x2e,0x31,0x31,0x37,0x2c,0x32,0x2e, - 0x34,0x33,0x36,0x63,0x33,0x2e,0x38,0x2c,0x31,0x2e, - 0x36,0x32,0x39,0x2c,0x37,0x2e,0x31,0x31,0x34,0x2c, - 0x33,0x2e,0x38,0x35,0x2c,0x39,0x2e,0x39,0x35,0x2c, - 0x36,0x2e,0x36,0x38,0x32,0x63,0x32,0x2e,0x38,0x32, - 0x38,0x2c,0x32,0x2e,0x38,0x33,0x33,0x2c,0x35,0x2e, - 0x30,0x35,0x36,0x2c,0x36,0x2e,0x31,0x34,0x36,0x2c, - 0x36,0x2e,0x36,0x37,0x39,0x2c,0x39,0x2e,0x39,0x35, - 0x31,0x0d,0x0a,0x09,0x09,0x63,0x31,0x2e,0x36,0x32, - 0x32,0x2c,0x33,0x2e,0x37,0x39,0x35,0x2c,0x32,0x2e, - 0x34,0x33,0x35,0x2c,0x37,0x2e,0x38,0x33,0x38,0x2c, - 0x32,0x2e,0x34,0x33,0x35,0x2c,0x31,0x32,0x2e,0x31, - 0x31,0x35,0x76,0x37,0x36,0x2e,0x39,0x37,0x33,0x48, - 0x31,0x30,0x33,0x32,0x2e,0x33,0x38,0x35,0x4c,0x31, - 0x30,0x33,0x32,0x2e,0x33,0x38,0x35,0x2c,0x35,0x32, - 0x33,0x2e,0x31,0x39,0x34,0x7a,0x22,0x2f,0x3e,0x0d, - 0x0a,0x3c,0x2f,0x67,0x3e,0x0d,0x0a,0x3c,0x2f,0x73, - 0x76,0x67,0x3e,0x0d,0x0a + 0x2e,0x34,0x39,0x33,0x0a,0x09,0x09,0x63,0x32,0x2e, + 0x35,0x35,0x33,0x2c,0x30,0x2c,0x34,0x2e,0x39,0x35, + 0x36,0x2d,0x30,0x2e,0x34,0x38,0x31,0x2c,0x37,0x2e, + 0x31,0x39,0x38,0x2d,0x31,0x2e,0x34,0x34,0x37,0x63, + 0x32,0x2e,0x32,0x34,0x33,0x2d,0x30,0x2e,0x39,0x36, + 0x35,0x2c,0x34,0x2e,0x31,0x39,0x33,0x2d,0x32,0x2e, + 0x32,0x38,0x2c,0x35,0x2e,0x38,0x35,0x34,0x2d,0x33, + 0x2e,0x39,0x33,0x35,0x63,0x31,0x2e,0x36,0x35,0x33, + 0x2d,0x31,0x2e,0x36,0x36,0x31,0x2c,0x32,0x2e,0x39, + 0x36,0x38,0x2d,0x33,0x2e,0x36,0x31,0x32,0x2c,0x33, + 0x2e,0x39,0x33,0x36,0x2d,0x35,0x2e,0x38,0x35,0x35, + 0x0a,0x09,0x09,0x63,0x30,0x2e,0x39,0x36,0x35,0x2d, + 0x32,0x2e,0x32,0x34,0x32,0x2c,0x31,0x2e,0x34,0x35, + 0x2d,0x34,0x2e,0x36,0x34,0x36,0x2c,0x31,0x2e,0x34, + 0x35,0x2d,0x37,0x2e,0x32,0x30,0x31,0x56,0x34,0x34, + 0x35,0x2e,0x34,0x39,0x36,0x7a,0x22,0x2f,0x3e,0x0a, + 0x09,0x3c,0x70,0x61,0x74,0x68,0x20,0x64,0x3d,0x22, + 0x4d,0x31,0x30,0x33,0x32,0x2e,0x33,0x38,0x35,0x2c, + 0x35,0x32,0x33,0x2e,0x31,0x39,0x34,0x76,0x2d,0x37, + 0x37,0x2e,0x36,0x39,0x38,0x63,0x30,0x2d,0x32,0x2e, + 0x35,0x34,0x39,0x2d,0x30,0x2e,0x34,0x38,0x32,0x2d, + 0x34,0x2e,0x39,0x35,0x33,0x2d,0x31,0x2e,0x34,0x35, + 0x2d,0x37,0x2e,0x31,0x39,0x35,0x63,0x2d,0x30,0x2e, + 0x39,0x36,0x39,0x2d,0x32,0x2e,0x32,0x34,0x31,0x2d, + 0x32,0x2e,0x32,0x37,0x37,0x2d,0x34,0x2e,0x31,0x39, + 0x34,0x2d,0x33,0x2e,0x39,0x33,0x38,0x2d,0x35,0x2e, + 0x38,0x35,0x34,0x0a,0x09,0x09,0x63,0x2d,0x31,0x2e, + 0x36,0x35,0x32,0x2d,0x31,0x2e,0x36,0x35,0x33,0x2d, + 0x33,0x2e,0x36,0x30,0x38,0x2d,0x32,0x2e,0x39,0x37, + 0x31,0x2d,0x35,0x2e,0x38,0x35,0x32,0x2d,0x33,0x2e, + 0x39,0x33,0x36,0x63,0x2d,0x32,0x2e,0x32,0x34,0x37, + 0x2d,0x30,0x2e,0x39,0x36,0x34,0x2d,0x34,0x2e,0x36, + 0x34,0x36,0x2d,0x31,0x2e,0x34,0x35,0x33,0x2d,0x37, + 0x2e,0x31,0x39,0x39,0x2d,0x31,0x2e,0x34,0x35,0x33, + 0x68,0x2d,0x38,0x2e,0x34,0x39,0x36,0x63,0x2d,0x32, + 0x2e,0x35,0x35,0x37,0x2c,0x30,0x2d,0x34,0x2e,0x39, + 0x35,0x36,0x2c,0x30,0x2e,0x34,0x38,0x39,0x2d,0x37, + 0x2e,0x31,0x39,0x38,0x2c,0x31,0x2e,0x34,0x35,0x33, + 0x0a,0x09,0x09,0x63,0x2d,0x32,0x2e,0x32,0x34,0x36, + 0x2c,0x30,0x2e,0x39,0x36,0x35,0x2d,0x34,0x2e,0x31, + 0x39,0x34,0x2c,0x32,0x2e,0x32,0x38,0x31,0x2d,0x35, + 0x2e,0x38,0x35,0x33,0x2c,0x33,0x2e,0x39,0x33,0x36, + 0x63,0x2d,0x31,0x2e,0x36,0x36,0x31,0x2c,0x31,0x2e, + 0x36,0x36,0x2d,0x32,0x2e,0x39,0x37,0x2c,0x33,0x2e, + 0x36,0x31,0x33,0x2d,0x33,0x2e,0x39,0x33,0x38,0x2c, + 0x35,0x2e,0x38,0x35,0x34,0x63,0x2d,0x30,0x2e,0x39, + 0x37,0x2c,0x32,0x2e,0x32,0x34,0x32,0x2d,0x31,0x2e, + 0x34,0x35,0x31,0x2c,0x34,0x2e,0x36,0x34,0x36,0x2d, + 0x31,0x2e,0x34,0x35,0x31,0x2c,0x37,0x2e,0x31,0x39, + 0x35,0x76,0x37,0x37,0x2e,0x36,0x39,0x38,0x68,0x2d, + 0x31,0x32,0x2e,0x37,0x34,0x0a,0x09,0x09,0x56,0x34, + 0x31,0x37,0x2e,0x31,0x31,0x33,0x68,0x34,0x2e,0x32, + 0x34,0x34,0x6c,0x36,0x2e,0x39,0x34,0x32,0x2c,0x31, + 0x30,0x2e,0x37,0x37,0x36,0x63,0x32,0x2e,0x39,0x2d, + 0x33,0x2e,0x39,0x34,0x2c,0x36,0x2e,0x35,0x34,0x35, + 0x2d,0x37,0x2e,0x30,0x36,0x33,0x2c,0x31,0x30,0x2e, + 0x39,0x33,0x31,0x2d,0x39,0x2e,0x33,0x37,0x35,0x63, + 0x34,0x2e,0x33,0x38,0x36,0x2d,0x32,0x2e,0x33,0x31, + 0x32,0x2c,0x39,0x2e,0x31,0x37,0x2d,0x33,0x2e,0x34, + 0x37,0x37,0x2c,0x31,0x34,0x2e,0x33,0x34,0x34,0x2d, + 0x33,0x2e,0x34,0x37,0x37,0x68,0x33,0x2e,0x32,0x31, + 0x35,0x0a,0x09,0x09,0x63,0x34,0x2e,0x32,0x37,0x38, + 0x2c,0x30,0x2c,0x38,0x2e,0x33,0x32,0x2c,0x30,0x2e, + 0x38,0x31,0x38,0x2c,0x31,0x32,0x2e,0x31,0x31,0x37, + 0x2c,0x32,0x2e,0x34,0x33,0x36,0x63,0x33,0x2e,0x38, + 0x2c,0x31,0x2e,0x36,0x32,0x39,0x2c,0x37,0x2e,0x31, + 0x31,0x34,0x2c,0x33,0x2e,0x38,0x35,0x2c,0x39,0x2e, + 0x39,0x35,0x2c,0x36,0x2e,0x36,0x38,0x32,0x63,0x32, + 0x2e,0x38,0x32,0x38,0x2c,0x32,0x2e,0x38,0x33,0x33, + 0x2c,0x35,0x2e,0x30,0x35,0x36,0x2c,0x36,0x2e,0x31, + 0x34,0x36,0x2c,0x36,0x2e,0x36,0x37,0x39,0x2c,0x39, + 0x2e,0x39,0x35,0x31,0x0a,0x09,0x09,0x63,0x31,0x2e, + 0x36,0x32,0x32,0x2c,0x33,0x2e,0x37,0x39,0x35,0x2c, + 0x32,0x2e,0x34,0x33,0x35,0x2c,0x37,0x2e,0x38,0x33, + 0x38,0x2c,0x32,0x2e,0x34,0x33,0x35,0x2c,0x31,0x32, + 0x2e,0x31,0x31,0x35,0x76,0x37,0x36,0x2e,0x39,0x37, + 0x33,0x48,0x31,0x30,0x33,0x32,0x2e,0x33,0x38,0x35, + 0x4c,0x31,0x30,0x33,0x32,0x2e,0x33,0x38,0x35,0x2c, + 0x35,0x32,0x33,0x2e,0x31,0x39,0x34,0x7a,0x22,0x2f, + 0x3e,0x0a,0x3c,0x2f,0x67,0x3e,0x0a,0x3c,0x2f,0x73, + 0x76,0x67,0x3e,0x0a }; + diff --git a/data/converted/star_filled_svg.cpp b/data/converted/star_filled_svg.cpp index 3cec60910a..0778724565 100644 --- a/data/converted/star_filled_svg.cpp +++ b/data/converted/star_filled_svg.cpp @@ -2,114 +2,113 @@ #include "../Resources.h" -const size_t star_filled_svg_size = 1164; -const unsigned char star_filled_svg_data[1164] = { +const size_t star_filled_svg_size = 1152; +const unsigned char star_filled_svg_data[1152] = { 0x3c,0x3f,0x78,0x6d,0x6c,0x20,0x76,0x65,0x72,0x73, 0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x30,0x22,0x20, 0x65,0x6e,0x63,0x6f,0x64,0x69,0x6e,0x67,0x3d,0x22, - 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0d,0x0a, - 0x3c,0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72, - 0x61,0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62, - 0x65,0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61, - 0x74,0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33, - 0x2c,0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f, - 0x72,0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e, - 0x20,0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72, - 0x73,0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30, - 0x20,0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20, - 0x20,0x2d,0x2d,0x3e,0x0d,0x0a,0x3c,0x21,0x44,0x4f, - 0x43,0x54,0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20, - 0x50,0x55,0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f, - 0x2f,0x57,0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20, - 0x53,0x56,0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45, - 0x4e,0x22,0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, - 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, - 0x67,0x2f,0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73, - 0x2f,0x53,0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44, - 0x54,0x44,0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64, - 0x74,0x64,0x22,0x3e,0x0d,0x0a,0x3c,0x73,0x76,0x67, - 0x20,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22, - 0x31,0x2e,0x31,0x22,0x20,0x69,0x64,0x3d,0x22,0x45, - 0x62,0x65,0x6e,0x65,0x5f,0x31,0x22,0x20,0x78,0x6d, - 0x6c,0x6e,0x73,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a, - 0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f, - 0x72,0x67,0x2f,0x32,0x30,0x30,0x30,0x2f,0x73,0x76, - 0x67,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78, - 0x6c,0x69,0x6e,0x6b,0x3d,0x22,0x68,0x74,0x74,0x70, - 0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e, - 0x6f,0x72,0x67,0x2f,0x31,0x39,0x39,0x39,0x2f,0x78, - 0x6c,0x69,0x6e,0x6b,0x22,0x20,0x78,0x3d,0x22,0x30, - 0x70,0x78,0x22,0x20,0x79,0x3d,0x22,0x30,0x70,0x78, - 0x22,0x0d,0x0a,0x09,0x20,0x77,0x69,0x64,0x74,0x68, - 0x3d,0x22,0x32,0x31,0x2e,0x37,0x37,0x35,0x70,0x78, - 0x22,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3d,0x22, - 0x32,0x30,0x2e,0x37,0x36,0x32,0x70,0x78,0x22,0x20, - 0x76,0x69,0x65,0x77,0x42,0x6f,0x78,0x3d,0x22,0x30, - 0x20,0x30,0x20,0x32,0x31,0x2e,0x37,0x37,0x35,0x20, - 0x32,0x30,0x2e,0x37,0x36,0x32,0x22,0x20,0x65,0x6e, - 0x61,0x62,0x6c,0x65,0x2d,0x62,0x61,0x63,0x6b,0x67, - 0x72,0x6f,0x75,0x6e,0x64,0x3d,0x22,0x6e,0x65,0x77, - 0x20,0x30,0x20,0x30,0x20,0x32,0x31,0x2e,0x37,0x37, - 0x35,0x20,0x32,0x30,0x2e,0x37,0x36,0x32,0x22,0x20, - 0x78,0x6d,0x6c,0x3a,0x73,0x70,0x61,0x63,0x65,0x3d, - 0x22,0x70,0x72,0x65,0x73,0x65,0x72,0x76,0x65,0x22, - 0x3e,0x0d,0x0a,0x3c,0x70,0x61,0x74,0x68,0x20,0x66, - 0x69,0x6c,0x6c,0x3d,0x22,0x23,0x37,0x37,0x37,0x37, - 0x37,0x37,0x22,0x20,0x64,0x3d,0x22,0x4d,0x38,0x2e, - 0x37,0x31,0x2c,0x32,0x2e,0x30,0x37,0x36,0x63,0x2d, - 0x30,0x2e,0x31,0x38,0x32,0x2c,0x30,0x2d,0x30,0x2e, - 0x33,0x36,0x34,0x2c,0x30,0x2e,0x31,0x34,0x2d,0x30, - 0x2e,0x35,0x30,0x31,0x2c,0x30,0x2e,0x34,0x31,0x39, - 0x4c,0x36,0x2e,0x33,0x35,0x2c,0x36,0x2e,0x32,0x36, - 0x31,0x63,0x2d,0x30,0x2e,0x32,0x37,0x36,0x2c,0x30, - 0x2e,0x35,0x36,0x2d,0x31,0x2e,0x30,0x30,0x37,0x2c, - 0x31,0x2e,0x30,0x39,0x31,0x2d,0x31,0x2e,0x36,0x32, - 0x34,0x2c,0x31,0x2e,0x31,0x38,0x4c,0x30,0x2e,0x35, - 0x37,0x32,0x2c,0x38,0x2e,0x30,0x34,0x35,0x0d,0x0a, - 0x09,0x43,0x2d,0x30,0x2e,0x30,0x34,0x36,0x2c,0x38, - 0x2e,0x31,0x33,0x35,0x2d,0x30,0x2e,0x31,0x38,0x35, - 0x2c,0x38,0x2e,0x35,0x36,0x34,0x2c,0x30,0x2e,0x32, - 0x36,0x32,0x2c,0x39,0x6c,0x33,0x2e,0x30,0x30,0x37, - 0x2c,0x32,0x2e,0x39,0x33,0x31,0x63,0x30,0x2e,0x34, - 0x34,0x37,0x2c,0x30,0x2e,0x34,0x33,0x36,0x2c,0x30, - 0x2e,0x37,0x32,0x36,0x2c,0x31,0x2e,0x32,0x39,0x35, - 0x2c,0x30,0x2e,0x36,0x32,0x2c,0x31,0x2e,0x39,0x30, - 0x39,0x6c,0x2d,0x30,0x2e,0x37,0x31,0x2c,0x34,0x2e, - 0x31,0x34,0x0d,0x0a,0x09,0x63,0x2d,0x30,0x2e,0x30, - 0x37,0x37,0x2c,0x30,0x2e,0x34,0x34,0x36,0x2c,0x30, - 0x2e,0x30,0x39,0x34,0x2c,0x30,0x2e,0x37,0x30,0x38, - 0x2c,0x30,0x2e,0x34,0x30,0x35,0x2c,0x30,0x2e,0x37, - 0x30,0x38,0x63,0x30,0x2e,0x31,0x31,0x38,0x2c,0x30, - 0x2c,0x30,0x2e,0x32,0x35,0x35,0x2d,0x30,0x2e,0x30, - 0x33,0x38,0x2c,0x30,0x2e,0x34,0x30,0x37,0x2d,0x30, - 0x2e,0x31,0x31,0x37,0x6c,0x33,0x2e,0x37,0x31,0x37, - 0x2d,0x31,0x2e,0x39,0x35,0x36,0x63,0x30,0x2e,0x32, - 0x37,0x36,0x2d,0x30,0x2e,0x31,0x34,0x35,0x2c,0x30, - 0x2e,0x36,0x34,0x2d,0x30,0x2e,0x32,0x31,0x36,0x2c, - 0x31,0x2e,0x30,0x30,0x33,0x2d,0x30,0x2e,0x32,0x31, - 0x36,0x0d,0x0a,0x09,0x63,0x30,0x2e,0x33,0x36,0x34, - 0x2c,0x30,0x2c,0x30,0x2e,0x37,0x32,0x39,0x2c,0x30, - 0x2e,0x30,0x37,0x32,0x2c,0x31,0x2e,0x30,0x30,0x34, - 0x2c,0x30,0x2e,0x32,0x31,0x36,0x6c,0x33,0x2e,0x37, - 0x31,0x37,0x2c,0x31,0x2e,0x39,0x35,0x36,0x63,0x30, - 0x2e,0x31,0x35,0x2c,0x30,0x2e,0x30,0x37,0x39,0x2c, - 0x30,0x2e,0x32,0x38,0x39,0x2c,0x30,0x2e,0x31,0x31, - 0x37,0x2c,0x30,0x2e,0x34,0x30,0x37,0x2c,0x30,0x2e, - 0x31,0x31,0x37,0x63,0x30,0x2e,0x33,0x31,0x31,0x2c, - 0x30,0x2c,0x30,0x2e,0x34,0x38,0x31,0x2d,0x30,0x2e, - 0x32,0x36,0x32,0x2c,0x30,0x2e,0x34,0x30,0x35,0x2d, - 0x30,0x2e,0x37,0x30,0x38,0x6c,0x2d,0x30,0x2e,0x37, - 0x31,0x31,0x2d,0x34,0x2e,0x31,0x34,0x0d,0x0a,0x09, - 0x63,0x2d,0x30,0x2e,0x31,0x30,0x35,0x2d,0x30,0x2e, - 0x36,0x31,0x34,0x2c,0x30,0x2e,0x31,0x37,0x34,0x2d, - 0x31,0x2e,0x34,0x37,0x34,0x2c,0x30,0x2e,0x36,0x31, - 0x39,0x2d,0x31,0x2e,0x39,0x30,0x39,0x4c,0x31,0x37, - 0x2e,0x31,0x36,0x2c,0x39,0x63,0x30,0x2e,0x34,0x34, - 0x36,0x2d,0x30,0x2e,0x34,0x33,0x36,0x2c,0x30,0x2e, - 0x33,0x30,0x37,0x2d,0x30,0x2e,0x38,0x36,0x35,0x2d, - 0x30,0x2e,0x33,0x31,0x31,0x2d,0x30,0x2e,0x39,0x35, - 0x35,0x6c,0x2d,0x34,0x2e,0x31,0x35,0x34,0x2d,0x30, - 0x2e,0x36,0x30,0x33,0x0d,0x0a,0x09,0x63,0x2d,0x30, + 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0a,0x3c, + 0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72,0x61, + 0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62,0x65, + 0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61,0x74, + 0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33,0x2c, + 0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f,0x72, + 0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e,0x20, + 0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72,0x73, + 0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30,0x20, + 0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20,0x20, + 0x2d,0x2d,0x3e,0x0a,0x3c,0x21,0x44,0x4f,0x43,0x54, + 0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20,0x50,0x55, + 0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f,0x2f,0x57, + 0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20,0x53,0x56, + 0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45,0x4e,0x22, + 0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73,0x2f,0x53, + 0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44,0x54,0x44, + 0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64,0x74,0x64, + 0x22,0x3e,0x0a,0x3c,0x73,0x76,0x67,0x20,0x76,0x65, + 0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x31, + 0x22,0x20,0x69,0x64,0x3d,0x22,0x45,0x62,0x65,0x6e, + 0x65,0x5f,0x31,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73, + 0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x32,0x30,0x30,0x30,0x2f,0x73,0x76,0x67,0x22,0x20, + 0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78,0x6c,0x69,0x6e, + 0x6b,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f, + 0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67, + 0x2f,0x31,0x39,0x39,0x39,0x2f,0x78,0x6c,0x69,0x6e, + 0x6b,0x22,0x20,0x78,0x3d,0x22,0x30,0x70,0x78,0x22, + 0x20,0x79,0x3d,0x22,0x30,0x70,0x78,0x22,0x0a,0x09, + 0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x32,0x31, + 0x2e,0x37,0x37,0x35,0x70,0x78,0x22,0x20,0x68,0x65, + 0x69,0x67,0x68,0x74,0x3d,0x22,0x32,0x30,0x2e,0x37, + 0x36,0x32,0x70,0x78,0x22,0x20,0x76,0x69,0x65,0x77, + 0x42,0x6f,0x78,0x3d,0x22,0x30,0x20,0x30,0x20,0x32, + 0x31,0x2e,0x37,0x37,0x35,0x20,0x32,0x30,0x2e,0x37, + 0x36,0x32,0x22,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65, + 0x2d,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e, + 0x64,0x3d,0x22,0x6e,0x65,0x77,0x20,0x30,0x20,0x30, + 0x20,0x32,0x31,0x2e,0x37,0x37,0x35,0x20,0x32,0x30, + 0x2e,0x37,0x36,0x32,0x22,0x20,0x78,0x6d,0x6c,0x3a, + 0x73,0x70,0x61,0x63,0x65,0x3d,0x22,0x70,0x72,0x65, + 0x73,0x65,0x72,0x76,0x65,0x22,0x3e,0x0a,0x3c,0x70, + 0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22, + 0x23,0x37,0x37,0x37,0x37,0x37,0x37,0x22,0x20,0x64, + 0x3d,0x22,0x4d,0x38,0x2e,0x37,0x31,0x2c,0x32,0x2e, + 0x30,0x37,0x36,0x63,0x2d,0x30,0x2e,0x31,0x38,0x32, + 0x2c,0x30,0x2d,0x30,0x2e,0x33,0x36,0x34,0x2c,0x30, + 0x2e,0x31,0x34,0x2d,0x30,0x2e,0x35,0x30,0x31,0x2c, + 0x30,0x2e,0x34,0x31,0x39,0x4c,0x36,0x2e,0x33,0x35, + 0x2c,0x36,0x2e,0x32,0x36,0x31,0x63,0x2d,0x30,0x2e, + 0x32,0x37,0x36,0x2c,0x30,0x2e,0x35,0x36,0x2d,0x31, + 0x2e,0x30,0x30,0x37,0x2c,0x31,0x2e,0x30,0x39,0x31, + 0x2d,0x31,0x2e,0x36,0x32,0x34,0x2c,0x31,0x2e,0x31, + 0x38,0x4c,0x30,0x2e,0x35,0x37,0x32,0x2c,0x38,0x2e, + 0x30,0x34,0x35,0x0a,0x09,0x43,0x2d,0x30,0x2e,0x30, + 0x34,0x36,0x2c,0x38,0x2e,0x31,0x33,0x35,0x2d,0x30, + 0x2e,0x31,0x38,0x35,0x2c,0x38,0x2e,0x35,0x36,0x34, + 0x2c,0x30,0x2e,0x32,0x36,0x32,0x2c,0x39,0x6c,0x33, + 0x2e,0x30,0x30,0x37,0x2c,0x32,0x2e,0x39,0x33,0x31, + 0x63,0x30,0x2e,0x34,0x34,0x37,0x2c,0x30,0x2e,0x34, + 0x33,0x36,0x2c,0x30,0x2e,0x37,0x32,0x36,0x2c,0x31, + 0x2e,0x32,0x39,0x35,0x2c,0x30,0x2e,0x36,0x32,0x2c, + 0x31,0x2e,0x39,0x30,0x39,0x6c,0x2d,0x30,0x2e,0x37, + 0x31,0x2c,0x34,0x2e,0x31,0x34,0x0a,0x09,0x63,0x2d, + 0x30,0x2e,0x30,0x37,0x37,0x2c,0x30,0x2e,0x34,0x34, + 0x36,0x2c,0x30,0x2e,0x30,0x39,0x34,0x2c,0x30,0x2e, + 0x37,0x30,0x38,0x2c,0x30,0x2e,0x34,0x30,0x35,0x2c, + 0x30,0x2e,0x37,0x30,0x38,0x63,0x30,0x2e,0x31,0x31, + 0x38,0x2c,0x30,0x2c,0x30,0x2e,0x32,0x35,0x35,0x2d, + 0x30,0x2e,0x30,0x33,0x38,0x2c,0x30,0x2e,0x34,0x30, + 0x37,0x2d,0x30,0x2e,0x31,0x31,0x37,0x6c,0x33,0x2e, + 0x37,0x31,0x37,0x2d,0x31,0x2e,0x39,0x35,0x36,0x63, + 0x30,0x2e,0x32,0x37,0x36,0x2d,0x30,0x2e,0x31,0x34, + 0x35,0x2c,0x30,0x2e,0x36,0x34,0x2d,0x30,0x2e,0x32, + 0x31,0x36,0x2c,0x31,0x2e,0x30,0x30,0x33,0x2d,0x30, + 0x2e,0x32,0x31,0x36,0x0a,0x09,0x63,0x30,0x2e,0x33, + 0x36,0x34,0x2c,0x30,0x2c,0x30,0x2e,0x37,0x32,0x39, + 0x2c,0x30,0x2e,0x30,0x37,0x32,0x2c,0x31,0x2e,0x30, + 0x30,0x34,0x2c,0x30,0x2e,0x32,0x31,0x36,0x6c,0x33, + 0x2e,0x37,0x31,0x37,0x2c,0x31,0x2e,0x39,0x35,0x36, + 0x63,0x30,0x2e,0x31,0x35,0x2c,0x30,0x2e,0x30,0x37, + 0x39,0x2c,0x30,0x2e,0x32,0x38,0x39,0x2c,0x30,0x2e, + 0x31,0x31,0x37,0x2c,0x30,0x2e,0x34,0x30,0x37,0x2c, + 0x30,0x2e,0x31,0x31,0x37,0x63,0x30,0x2e,0x33,0x31, + 0x31,0x2c,0x30,0x2c,0x30,0x2e,0x34,0x38,0x31,0x2d, + 0x30,0x2e,0x32,0x36,0x32,0x2c,0x30,0x2e,0x34,0x30, + 0x35,0x2d,0x30,0x2e,0x37,0x30,0x38,0x6c,0x2d,0x30, + 0x2e,0x37,0x31,0x31,0x2d,0x34,0x2e,0x31,0x34,0x0a, + 0x09,0x63,0x2d,0x30,0x2e,0x31,0x30,0x35,0x2d,0x30, + 0x2e,0x36,0x31,0x34,0x2c,0x30,0x2e,0x31,0x37,0x34, + 0x2d,0x31,0x2e,0x34,0x37,0x34,0x2c,0x30,0x2e,0x36, + 0x31,0x39,0x2d,0x31,0x2e,0x39,0x30,0x39,0x4c,0x31, + 0x37,0x2e,0x31,0x36,0x2c,0x39,0x63,0x30,0x2e,0x34, + 0x34,0x36,0x2d,0x30,0x2e,0x34,0x33,0x36,0x2c,0x30, + 0x2e,0x33,0x30,0x37,0x2d,0x30,0x2e,0x38,0x36,0x35, + 0x2d,0x30,0x2e,0x33,0x31,0x31,0x2d,0x30,0x2e,0x39, + 0x35,0x35,0x6c,0x2d,0x34,0x2e,0x31,0x35,0x34,0x2d, + 0x30,0x2e,0x36,0x30,0x33,0x0a,0x09,0x63,0x2d,0x30, 0x2e,0x36,0x31,0x37,0x2d,0x30,0x2e,0x30,0x38,0x39, 0x2d,0x31,0x2e,0x33,0x34,0x39,0x2d,0x30,0x2e,0x36, 0x32,0x2d,0x31,0x2e,0x36,0x32,0x34,0x2d,0x31,0x2e, @@ -119,6 +118,7 @@ const unsigned char star_filled_svg_data[1164] = { 0x39,0x33,0x2c,0x32,0x2e,0x30,0x37,0x36,0x2c,0x38, 0x2e,0x37,0x31,0x2c,0x32,0x2e,0x30,0x37,0x36,0x4c, 0x38,0x2e,0x37,0x31,0x2c,0x32,0x2e,0x30,0x37,0x36, - 0x7a,0x22,0x2f,0x3e,0x0d,0x0a,0x3c,0x2f,0x73,0x76, - 0x67,0x3e,0x0d,0x0a + 0x7a,0x22,0x2f,0x3e,0x0a,0x3c,0x2f,0x73,0x76,0x67, + 0x3e,0x0a }; + diff --git a/data/converted/star_unfilled_svg.cpp b/data/converted/star_unfilled_svg.cpp index 5d6b43bda3..aae8f75a1d 100644 --- a/data/converted/star_unfilled_svg.cpp +++ b/data/converted/star_unfilled_svg.cpp @@ -2,118 +2,117 @@ #include "../Resources.h" -const size_t star_unfilled_svg_size = 1889; -const unsigned char star_unfilled_svg_data[1889] = { +const size_t star_unfilled_svg_size = 1871; +const unsigned char star_unfilled_svg_data[1871] = { 0x3c,0x3f,0x78,0x6d,0x6c,0x20,0x76,0x65,0x72,0x73, 0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x30,0x22,0x20, 0x65,0x6e,0x63,0x6f,0x64,0x69,0x6e,0x67,0x3d,0x22, - 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0d,0x0a, - 0x3c,0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72, - 0x61,0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62, - 0x65,0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61, - 0x74,0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33, - 0x2c,0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f, - 0x72,0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e, - 0x20,0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72, - 0x73,0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30, - 0x20,0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20, - 0x20,0x2d,0x2d,0x3e,0x0d,0x0a,0x3c,0x21,0x44,0x4f, - 0x43,0x54,0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20, - 0x50,0x55,0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f, - 0x2f,0x57,0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20, - 0x53,0x56,0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45, - 0x4e,0x22,0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, - 0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72, - 0x67,0x2f,0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73, - 0x2f,0x53,0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44, - 0x54,0x44,0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64, - 0x74,0x64,0x22,0x3e,0x0d,0x0a,0x3c,0x73,0x76,0x67, - 0x20,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22, - 0x31,0x2e,0x31,0x22,0x20,0x69,0x64,0x3d,0x22,0x45, - 0x62,0x65,0x6e,0x65,0x5f,0x31,0x22,0x20,0x78,0x6d, - 0x6c,0x6e,0x73,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a, - 0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f, - 0x72,0x67,0x2f,0x32,0x30,0x30,0x30,0x2f,0x73,0x76, - 0x67,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78, - 0x6c,0x69,0x6e,0x6b,0x3d,0x22,0x68,0x74,0x74,0x70, - 0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e, - 0x6f,0x72,0x67,0x2f,0x31,0x39,0x39,0x39,0x2f,0x78, - 0x6c,0x69,0x6e,0x6b,0x22,0x20,0x78,0x3d,0x22,0x30, - 0x70,0x78,0x22,0x20,0x79,0x3d,0x22,0x30,0x70,0x78, - 0x22,0x0d,0x0a,0x09,0x20,0x77,0x69,0x64,0x74,0x68, - 0x3d,0x22,0x32,0x31,0x2e,0x37,0x37,0x35,0x70,0x78, - 0x22,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3d,0x22, - 0x32,0x30,0x2e,0x37,0x36,0x32,0x70,0x78,0x22,0x20, - 0x76,0x69,0x65,0x77,0x42,0x6f,0x78,0x3d,0x22,0x30, - 0x20,0x30,0x20,0x32,0x31,0x2e,0x37,0x37,0x35,0x20, - 0x32,0x30,0x2e,0x37,0x36,0x32,0x22,0x20,0x65,0x6e, - 0x61,0x62,0x6c,0x65,0x2d,0x62,0x61,0x63,0x6b,0x67, - 0x72,0x6f,0x75,0x6e,0x64,0x3d,0x22,0x6e,0x65,0x77, - 0x20,0x30,0x20,0x30,0x20,0x32,0x31,0x2e,0x37,0x37, - 0x35,0x20,0x32,0x30,0x2e,0x37,0x36,0x32,0x22,0x20, - 0x78,0x6d,0x6c,0x3a,0x73,0x70,0x61,0x63,0x65,0x3d, - 0x22,0x70,0x72,0x65,0x73,0x65,0x72,0x76,0x65,0x22, - 0x3e,0x0d,0x0a,0x3c,0x70,0x61,0x74,0x68,0x20,0x66, - 0x69,0x6c,0x6c,0x3d,0x22,0x23,0x37,0x37,0x37,0x37, - 0x37,0x37,0x22,0x20,0x64,0x3d,0x22,0x4d,0x38,0x2e, - 0x37,0x31,0x2c,0x32,0x2e,0x34,0x38,0x63,0x30,0x2e, - 0x30,0x32,0x36,0x2c,0x30,0x2e,0x30,0x31,0x38,0x2c, - 0x30,0x2e,0x30,0x38,0x33,0x2c,0x30,0x2e,0x30,0x37, - 0x2c,0x30,0x2e,0x31,0x34,0x33,0x2c,0x30,0x2e,0x31, - 0x39,0x33,0x6c,0x31,0x2e,0x38,0x35,0x39,0x2c,0x33, - 0x2e,0x37,0x36,0x36,0x63,0x30,0x2e,0x33,0x33,0x33, - 0x2c,0x30,0x2e,0x36,0x37,0x36,0x2c,0x31,0x2e,0x31, - 0x38,0x2c,0x31,0x2e,0x32,0x39,0x31,0x2c,0x31,0x2e, - 0x39,0x32,0x34,0x2c,0x31,0x2e,0x33,0x39,0x38,0x6c, - 0x34,0x2e,0x31,0x35,0x35,0x2c,0x30,0x2e,0x36,0x30, - 0x33,0x0d,0x0a,0x09,0x63,0x30,0x2e,0x31,0x35,0x2c, - 0x30,0x2e,0x30,0x32,0x32,0x2c,0x30,0x2e,0x32,0x31, - 0x38,0x2c,0x30,0x2e,0x30,0x36,0x36,0x2c,0x30,0x2e, - 0x32,0x32,0x37,0x2c,0x30,0x2e,0x30,0x36,0x36,0x63, - 0x30,0x2e,0x30,0x30,0x31,0x2c,0x30,0x2c,0x30,0x2e, - 0x30,0x30,0x31,0x2c,0x30,0x2c,0x30,0x2e,0x30,0x30, - 0x31,0x2c,0x30,0x63,0x30,0x2c,0x30,0x2e,0x30,0x31, - 0x39,0x2d,0x30,0x2e,0x30,0x32,0x35,0x2c,0x30,0x2e, - 0x30,0x39,0x36,0x2d,0x30,0x2e,0x31,0x34,0x2c,0x30, - 0x2e,0x32,0x30,0x37,0x6c,0x2d,0x33,0x2e,0x30,0x30, - 0x39,0x2c,0x32,0x2e,0x39,0x33,0x31,0x0d,0x0a,0x09, - 0x63,0x2d,0x30,0x2e,0x35,0x33,0x39,0x2c,0x30,0x2e, - 0x35,0x32,0x36,0x2d,0x30,0x2e,0x38,0x36,0x32,0x2c, - 0x31,0x2e,0x35,0x32,0x31,0x2d,0x30,0x2e,0x37,0x33, - 0x35,0x2c,0x32,0x2e,0x32,0x36,0x33,0x6c,0x30,0x2e, - 0x37,0x31,0x31,0x2c,0x34,0x2e,0x31,0x34,0x63,0x30, - 0x2e,0x30,0x32,0x37,0x2c,0x30,0x2e,0x31,0x35,0x36, - 0x2c,0x30,0x2e,0x30,0x30,0x33,0x2c,0x30,0x2e,0x32, - 0x33,0x34,0x2d,0x30,0x2e,0x30,0x31,0x31,0x2c,0x30, - 0x2e,0x32,0x33,0x39,0x63,0x2d,0x30,0x2e,0x30,0x32, - 0x35,0x2c,0x30,0x2d,0x30,0x2e,0x30,0x39,0x38,0x2d, - 0x30,0x2e,0x30,0x30,0x38,0x2d,0x30,0x2e,0x32,0x32, - 0x31,0x2d,0x30,0x2e,0x30,0x37,0x31,0x4c,0x39,0x2e, - 0x39,0x2c,0x31,0x36,0x2e,0x32,0x36,0x0d,0x0a,0x09, - 0x63,0x2d,0x30,0x2e,0x33,0x32,0x34,0x2d,0x30,0x2e, - 0x31,0x37,0x31,0x2d,0x30,0x2e,0x37,0x34,0x37,0x2d, - 0x30,0x2e,0x32,0x36,0x34,0x2d,0x31,0x2e,0x31,0x39, - 0x2d,0x30,0x2e,0x32,0x36,0x34,0x53,0x37,0x2e,0x38, - 0x34,0x33,0x2c,0x31,0x36,0x2e,0x30,0x39,0x2c,0x37, - 0x2e,0x35,0x32,0x2c,0x31,0x36,0x2e,0x32,0x36,0x6c, - 0x2d,0x33,0x2e,0x37,0x31,0x36,0x2c,0x31,0x2e,0x39, - 0x35,0x34,0x63,0x2d,0x30,0x2e,0x31,0x32,0x33,0x2c, - 0x30,0x2e,0x30,0x36,0x33,0x2d,0x30,0x2e,0x31,0x39, - 0x36,0x2c,0x30,0x2e,0x30,0x37,0x31,0x2d,0x30,0x2e, - 0x32,0x32,0x34,0x2c,0x30,0x2e,0x30,0x38,0x32,0x0d, - 0x0a,0x09,0x63,0x2d,0x30,0x2e,0x30,0x31,0x2d,0x30, - 0x2e,0x30,0x31,0x36,0x2d,0x30,0x2e,0x30,0x33,0x34, - 0x2d,0x30,0x2e,0x30,0x39,0x34,0x2d,0x30,0x2e,0x30, - 0x30,0x38,0x2d,0x30,0x2e,0x32,0x35,0x6c,0x30,0x2e, - 0x37,0x31,0x2d,0x34,0x2e,0x31,0x34,0x63,0x30,0x2e, - 0x31,0x32,0x38,0x2d,0x30,0x2e,0x37,0x34,0x33,0x2d, - 0x30,0x2e,0x31,0x39,0x35,0x2d,0x31,0x2e,0x37,0x33, - 0x37,0x2d,0x30,0x2e,0x37,0x33,0x35,0x2d,0x32,0x2e, - 0x32,0x36,0x33,0x4c,0x30,0x2e,0x35,0x34,0x31,0x2c, - 0x38,0x2e,0x37,0x31,0x32,0x43,0x30,0x2e,0x34,0x32, - 0x37,0x2c,0x38,0x2e,0x36,0x30,0x32,0x2c,0x30,0x2e, - 0x34,0x2c,0x38,0x2e,0x35,0x32,0x35,0x2c,0x30,0x2e, - 0x33,0x39,0x35,0x2c,0x38,0x2e,0x35,0x32,0x35,0x0d, + 0x75,0x74,0x66,0x2d,0x38,0x22,0x3f,0x3e,0x0a,0x3c, + 0x21,0x2d,0x2d,0x20,0x47,0x65,0x6e,0x65,0x72,0x61, + 0x74,0x6f,0x72,0x3a,0x20,0x41,0x64,0x6f,0x62,0x65, + 0x20,0x49,0x6c,0x6c,0x75,0x73,0x74,0x72,0x61,0x74, + 0x6f,0x72,0x20,0x31,0x36,0x2e,0x30,0x2e,0x33,0x2c, + 0x20,0x53,0x56,0x47,0x20,0x45,0x78,0x70,0x6f,0x72, + 0x74,0x20,0x50,0x6c,0x75,0x67,0x2d,0x49,0x6e,0x20, + 0x2e,0x20,0x53,0x56,0x47,0x20,0x56,0x65,0x72,0x73, + 0x69,0x6f,0x6e,0x3a,0x20,0x36,0x2e,0x30,0x30,0x20, + 0x42,0x75,0x69,0x6c,0x64,0x20,0x30,0x29,0x20,0x20, + 0x2d,0x2d,0x3e,0x0a,0x3c,0x21,0x44,0x4f,0x43,0x54, + 0x59,0x50,0x45,0x20,0x73,0x76,0x67,0x20,0x50,0x55, + 0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f,0x2f,0x57, + 0x33,0x43,0x2f,0x2f,0x44,0x54,0x44,0x20,0x53,0x56, + 0x47,0x20,0x31,0x2e,0x31,0x2f,0x2f,0x45,0x4e,0x22, + 0x20,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x47,0x72,0x61,0x70,0x68,0x69,0x63,0x73,0x2f,0x53, + 0x56,0x47,0x2f,0x31,0x2e,0x31,0x2f,0x44,0x54,0x44, + 0x2f,0x73,0x76,0x67,0x31,0x31,0x2e,0x64,0x74,0x64, + 0x22,0x3e,0x0a,0x3c,0x73,0x76,0x67,0x20,0x76,0x65, + 0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22,0x31,0x2e,0x31, + 0x22,0x20,0x69,0x64,0x3d,0x22,0x45,0x62,0x65,0x6e, + 0x65,0x5f,0x31,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73, + 0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, + 0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, + 0x32,0x30,0x30,0x30,0x2f,0x73,0x76,0x67,0x22,0x20, + 0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78,0x6c,0x69,0x6e, + 0x6b,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f, + 0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67, + 0x2f,0x31,0x39,0x39,0x39,0x2f,0x78,0x6c,0x69,0x6e, + 0x6b,0x22,0x20,0x78,0x3d,0x22,0x30,0x70,0x78,0x22, + 0x20,0x79,0x3d,0x22,0x30,0x70,0x78,0x22,0x0a,0x09, + 0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x32,0x31, + 0x2e,0x37,0x37,0x35,0x70,0x78,0x22,0x20,0x68,0x65, + 0x69,0x67,0x68,0x74,0x3d,0x22,0x32,0x30,0x2e,0x37, + 0x36,0x32,0x70,0x78,0x22,0x20,0x76,0x69,0x65,0x77, + 0x42,0x6f,0x78,0x3d,0x22,0x30,0x20,0x30,0x20,0x32, + 0x31,0x2e,0x37,0x37,0x35,0x20,0x32,0x30,0x2e,0x37, + 0x36,0x32,0x22,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65, + 0x2d,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e, + 0x64,0x3d,0x22,0x6e,0x65,0x77,0x20,0x30,0x20,0x30, + 0x20,0x32,0x31,0x2e,0x37,0x37,0x35,0x20,0x32,0x30, + 0x2e,0x37,0x36,0x32,0x22,0x20,0x78,0x6d,0x6c,0x3a, + 0x73,0x70,0x61,0x63,0x65,0x3d,0x22,0x70,0x72,0x65, + 0x73,0x65,0x72,0x76,0x65,0x22,0x3e,0x0a,0x3c,0x70, + 0x61,0x74,0x68,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22, + 0x23,0x37,0x37,0x37,0x37,0x37,0x37,0x22,0x20,0x64, + 0x3d,0x22,0x4d,0x38,0x2e,0x37,0x31,0x2c,0x32,0x2e, + 0x34,0x38,0x63,0x30,0x2e,0x30,0x32,0x36,0x2c,0x30, + 0x2e,0x30,0x31,0x38,0x2c,0x30,0x2e,0x30,0x38,0x33, + 0x2c,0x30,0x2e,0x30,0x37,0x2c,0x30,0x2e,0x31,0x34, + 0x33,0x2c,0x30,0x2e,0x31,0x39,0x33,0x6c,0x31,0x2e, + 0x38,0x35,0x39,0x2c,0x33,0x2e,0x37,0x36,0x36,0x63, + 0x30,0x2e,0x33,0x33,0x33,0x2c,0x30,0x2e,0x36,0x37, + 0x36,0x2c,0x31,0x2e,0x31,0x38,0x2c,0x31,0x2e,0x32, + 0x39,0x31,0x2c,0x31,0x2e,0x39,0x32,0x34,0x2c,0x31, + 0x2e,0x33,0x39,0x38,0x6c,0x34,0x2e,0x31,0x35,0x35, + 0x2c,0x30,0x2e,0x36,0x30,0x33,0x0a,0x09,0x63,0x30, + 0x2e,0x31,0x35,0x2c,0x30,0x2e,0x30,0x32,0x32,0x2c, + 0x30,0x2e,0x32,0x31,0x38,0x2c,0x30,0x2e,0x30,0x36, + 0x36,0x2c,0x30,0x2e,0x32,0x32,0x37,0x2c,0x30,0x2e, + 0x30,0x36,0x36,0x63,0x30,0x2e,0x30,0x30,0x31,0x2c, + 0x30,0x2c,0x30,0x2e,0x30,0x30,0x31,0x2c,0x30,0x2c, + 0x30,0x2e,0x30,0x30,0x31,0x2c,0x30,0x63,0x30,0x2c, + 0x30,0x2e,0x30,0x31,0x39,0x2d,0x30,0x2e,0x30,0x32, + 0x35,0x2c,0x30,0x2e,0x30,0x39,0x36,0x2d,0x30,0x2e, + 0x31,0x34,0x2c,0x30,0x2e,0x32,0x30,0x37,0x6c,0x2d, + 0x33,0x2e,0x30,0x30,0x39,0x2c,0x32,0x2e,0x39,0x33, + 0x31,0x0a,0x09,0x63,0x2d,0x30,0x2e,0x35,0x33,0x39, + 0x2c,0x30,0x2e,0x35,0x32,0x36,0x2d,0x30,0x2e,0x38, + 0x36,0x32,0x2c,0x31,0x2e,0x35,0x32,0x31,0x2d,0x30, + 0x2e,0x37,0x33,0x35,0x2c,0x32,0x2e,0x32,0x36,0x33, + 0x6c,0x30,0x2e,0x37,0x31,0x31,0x2c,0x34,0x2e,0x31, + 0x34,0x63,0x30,0x2e,0x30,0x32,0x37,0x2c,0x30,0x2e, + 0x31,0x35,0x36,0x2c,0x30,0x2e,0x30,0x30,0x33,0x2c, + 0x30,0x2e,0x32,0x33,0x34,0x2d,0x30,0x2e,0x30,0x31, + 0x31,0x2c,0x30,0x2e,0x32,0x33,0x39,0x63,0x2d,0x30, + 0x2e,0x30,0x32,0x35,0x2c,0x30,0x2d,0x30,0x2e,0x30, + 0x39,0x38,0x2d,0x30,0x2e,0x30,0x30,0x38,0x2d,0x30, + 0x2e,0x32,0x32,0x31,0x2d,0x30,0x2e,0x30,0x37,0x31, + 0x4c,0x39,0x2e,0x39,0x2c,0x31,0x36,0x2e,0x32,0x36, + 0x0a,0x09,0x63,0x2d,0x30,0x2e,0x33,0x32,0x34,0x2d, + 0x30,0x2e,0x31,0x37,0x31,0x2d,0x30,0x2e,0x37,0x34, + 0x37,0x2d,0x30,0x2e,0x32,0x36,0x34,0x2d,0x31,0x2e, + 0x31,0x39,0x2d,0x30,0x2e,0x32,0x36,0x34,0x53,0x37, + 0x2e,0x38,0x34,0x33,0x2c,0x31,0x36,0x2e,0x30,0x39, + 0x2c,0x37,0x2e,0x35,0x32,0x2c,0x31,0x36,0x2e,0x32, + 0x36,0x6c,0x2d,0x33,0x2e,0x37,0x31,0x36,0x2c,0x31, + 0x2e,0x39,0x35,0x34,0x63,0x2d,0x30,0x2e,0x31,0x32, + 0x33,0x2c,0x30,0x2e,0x30,0x36,0x33,0x2d,0x30,0x2e, + 0x31,0x39,0x36,0x2c,0x30,0x2e,0x30,0x37,0x31,0x2d, + 0x30,0x2e,0x32,0x32,0x34,0x2c,0x30,0x2e,0x30,0x38, + 0x32,0x0a,0x09,0x63,0x2d,0x30,0x2e,0x30,0x31,0x2d, + 0x30,0x2e,0x30,0x31,0x36,0x2d,0x30,0x2e,0x30,0x33, + 0x34,0x2d,0x30,0x2e,0x30,0x39,0x34,0x2d,0x30,0x2e, + 0x30,0x30,0x38,0x2d,0x30,0x2e,0x32,0x35,0x6c,0x30, + 0x2e,0x37,0x31,0x2d,0x34,0x2e,0x31,0x34,0x63,0x30, + 0x2e,0x31,0x32,0x38,0x2d,0x30,0x2e,0x37,0x34,0x33, + 0x2d,0x30,0x2e,0x31,0x39,0x35,0x2d,0x31,0x2e,0x37, + 0x33,0x37,0x2d,0x30,0x2e,0x37,0x33,0x35,0x2d,0x32, + 0x2e,0x32,0x36,0x33,0x4c,0x30,0x2e,0x35,0x34,0x31, + 0x2c,0x38,0x2e,0x37,0x31,0x32,0x43,0x30,0x2e,0x34, + 0x32,0x37,0x2c,0x38,0x2e,0x36,0x30,0x32,0x2c,0x30, + 0x2e,0x34,0x2c,0x38,0x2e,0x35,0x32,0x35,0x2c,0x30, + 0x2e,0x33,0x39,0x35,0x2c,0x38,0x2e,0x35,0x32,0x35, 0x0a,0x09,0x6c,0x30,0x2c,0x30,0x43,0x30,0x2e,0x34, 0x30,0x35,0x2c,0x38,0x2e,0x35,0x31,0x2c,0x30,0x2e, 0x34,0x37,0x32,0x2c,0x38,0x2e,0x34,0x36,0x34,0x2c, @@ -123,74 +122,75 @@ const unsigned char star_unfilled_svg_data[1889] = { 0x37,0x33,0x2c,0x36,0x2e,0x33,0x37,0x35,0x2c,0x37, 0x2e,0x31,0x31,0x35,0x2c,0x36,0x2e,0x37,0x30,0x39, 0x2c,0x36,0x2e,0x34,0x33,0x39,0x6c,0x31,0x2e,0x38, - 0x35,0x39,0x2d,0x33,0x2e,0x37,0x36,0x36,0x0d,0x0a, - 0x09,0x43,0x38,0x2e,0x36,0x32,0x38,0x2c,0x32,0x2e, - 0x35,0x35,0x2c,0x38,0x2e,0x36,0x38,0x35,0x2c,0x32, - 0x2e,0x34,0x39,0x36,0x2c,0x38,0x2e,0x37,0x31,0x2c, - 0x32,0x2e,0x34,0x38,0x20,0x4d,0x38,0x2e,0x37,0x31, - 0x2c,0x32,0x2e,0x30,0x37,0x36,0x63,0x2d,0x30,0x2e, - 0x31,0x38,0x32,0x2c,0x30,0x2d,0x30,0x2e,0x33,0x36, - 0x34,0x2c,0x30,0x2e,0x31,0x34,0x2d,0x30,0x2e,0x35, - 0x30,0x31,0x2c,0x30,0x2e,0x34,0x31,0x39,0x4c,0x36, - 0x2e,0x33,0x35,0x2c,0x36,0x2e,0x32,0x36,0x32,0x63, - 0x2d,0x30,0x2e,0x32,0x37,0x36,0x2c,0x30,0x2e,0x35, - 0x36,0x2d,0x31,0x2e,0x30,0x30,0x37,0x2c,0x31,0x2e, - 0x30,0x39,0x31,0x2d,0x31,0x2e,0x36,0x32,0x34,0x2c, - 0x31,0x2e,0x31,0x38,0x0d,0x0a,0x09,0x4c,0x30,0x2e, - 0x35,0x37,0x32,0x2c,0x38,0x2e,0x30,0x34,0x35,0x63, - 0x2d,0x30,0x2e,0x36,0x31,0x38,0x2c,0x30,0x2e,0x30, - 0x39,0x2d,0x30,0x2e,0x37,0x35,0x37,0x2c,0x30,0x2e, - 0x35,0x32,0x2d,0x30,0x2e,0x33,0x31,0x2c,0x30,0x2e, - 0x39,0x35,0x35,0x6c,0x33,0x2e,0x30,0x30,0x37,0x2c, + 0x35,0x39,0x2d,0x33,0x2e,0x37,0x36,0x36,0x0a,0x09, + 0x43,0x38,0x2e,0x36,0x32,0x38,0x2c,0x32,0x2e,0x35, + 0x35,0x2c,0x38,0x2e,0x36,0x38,0x35,0x2c,0x32,0x2e, + 0x34,0x39,0x36,0x2c,0x38,0x2e,0x37,0x31,0x2c,0x32, + 0x2e,0x34,0x38,0x20,0x4d,0x38,0x2e,0x37,0x31,0x2c, + 0x32,0x2e,0x30,0x37,0x36,0x63,0x2d,0x30,0x2e,0x31, + 0x38,0x32,0x2c,0x30,0x2d,0x30,0x2e,0x33,0x36,0x34, + 0x2c,0x30,0x2e,0x31,0x34,0x2d,0x30,0x2e,0x35,0x30, + 0x31,0x2c,0x30,0x2e,0x34,0x31,0x39,0x4c,0x36,0x2e, + 0x33,0x35,0x2c,0x36,0x2e,0x32,0x36,0x32,0x63,0x2d, + 0x30,0x2e,0x32,0x37,0x36,0x2c,0x30,0x2e,0x35,0x36, + 0x2d,0x31,0x2e,0x30,0x30,0x37,0x2c,0x31,0x2e,0x30, + 0x39,0x31,0x2d,0x31,0x2e,0x36,0x32,0x34,0x2c,0x31, + 0x2e,0x31,0x38,0x0a,0x09,0x4c,0x30,0x2e,0x35,0x37, + 0x32,0x2c,0x38,0x2e,0x30,0x34,0x35,0x63,0x2d,0x30, + 0x2e,0x36,0x31,0x38,0x2c,0x30,0x2e,0x30,0x39,0x2d, + 0x30,0x2e,0x37,0x35,0x37,0x2c,0x30,0x2e,0x35,0x32, + 0x2d,0x30,0x2e,0x33,0x31,0x2c,0x30,0x2e,0x39,0x35, + 0x35,0x6c,0x33,0x2e,0x30,0x30,0x37,0x2c,0x32,0x2e, + 0x39,0x33,0x31,0x63,0x30,0x2e,0x34,0x34,0x37,0x2c, + 0x30,0x2e,0x34,0x33,0x36,0x2c,0x30,0x2e,0x37,0x32, + 0x36,0x2c,0x31,0x2e,0x32,0x39,0x35,0x2c,0x30,0x2e, + 0x36,0x32,0x2c,0x31,0x2e,0x39,0x30,0x39,0x6c,0x2d, + 0x30,0x2e,0x37,0x31,0x2c,0x34,0x2e,0x31,0x33,0x39, + 0x0a,0x09,0x63,0x2d,0x30,0x2e,0x30,0x37,0x37,0x2c, + 0x30,0x2e,0x34,0x34,0x36,0x2c,0x30,0x2e,0x30,0x39, + 0x34,0x2c,0x30,0x2e,0x37,0x30,0x38,0x2c,0x30,0x2e, + 0x34,0x30,0x35,0x2c,0x30,0x2e,0x37,0x30,0x38,0x63, + 0x30,0x2e,0x31,0x31,0x38,0x2c,0x30,0x2c,0x30,0x2e, + 0x32,0x35,0x35,0x2d,0x30,0x2e,0x30,0x33,0x38,0x2c, + 0x30,0x2e,0x34,0x30,0x37,0x2d,0x30,0x2e,0x31,0x31, + 0x37,0x6c,0x33,0x2e,0x37,0x31,0x37,0x2d,0x31,0x2e, + 0x39,0x35,0x35,0x63,0x30,0x2e,0x32,0x37,0x36,0x2d, + 0x30,0x2e,0x31,0x34,0x35,0x2c,0x30,0x2e,0x36,0x34, + 0x2d,0x30,0x2e,0x32,0x31,0x36,0x2c,0x31,0x2e,0x30, + 0x30,0x33,0x2d,0x30,0x2e,0x32,0x31,0x36,0x0a,0x09, + 0x63,0x30,0x2e,0x33,0x36,0x34,0x2c,0x30,0x2c,0x30, + 0x2e,0x37,0x32,0x39,0x2c,0x30,0x2e,0x30,0x37,0x32, + 0x2c,0x31,0x2e,0x30,0x30,0x34,0x2c,0x30,0x2e,0x32, + 0x31,0x36,0x6c,0x33,0x2e,0x37,0x31,0x37,0x2c,0x31, + 0x2e,0x39,0x35,0x35,0x63,0x30,0x2e,0x31,0x35,0x2c, + 0x30,0x2e,0x30,0x37,0x39,0x2c,0x30,0x2e,0x32,0x38, + 0x39,0x2c,0x30,0x2e,0x31,0x31,0x37,0x2c,0x30,0x2e, + 0x34,0x30,0x37,0x2c,0x30,0x2e,0x31,0x31,0x37,0x63, + 0x30,0x2e,0x33,0x31,0x31,0x2c,0x30,0x2c,0x30,0x2e, + 0x34,0x38,0x31,0x2d,0x30,0x2e,0x32,0x36,0x32,0x2c, + 0x30,0x2e,0x34,0x30,0x35,0x2d,0x30,0x2e,0x37,0x30, + 0x38,0x6c,0x2d,0x30,0x2e,0x37,0x31,0x31,0x2d,0x34, + 0x2e,0x31,0x33,0x39,0x0a,0x09,0x63,0x2d,0x30,0x2e, + 0x31,0x30,0x35,0x2d,0x30,0x2e,0x36,0x31,0x34,0x2c, + 0x30,0x2e,0x31,0x37,0x34,0x2d,0x31,0x2e,0x34,0x37, + 0x34,0x2c,0x30,0x2e,0x36,0x31,0x39,0x2d,0x31,0x2e, + 0x39,0x30,0x39,0x6c,0x33,0x2e,0x30,0x30,0x39,0x2d, 0x32,0x2e,0x39,0x33,0x31,0x63,0x30,0x2e,0x34,0x34, - 0x37,0x2c,0x30,0x2e,0x34,0x33,0x36,0x2c,0x30,0x2e, - 0x37,0x32,0x36,0x2c,0x31,0x2e,0x32,0x39,0x35,0x2c, - 0x30,0x2e,0x36,0x32,0x2c,0x31,0x2e,0x39,0x30,0x39, - 0x6c,0x2d,0x30,0x2e,0x37,0x31,0x2c,0x34,0x2e,0x31, - 0x33,0x39,0x0d,0x0a,0x09,0x63,0x2d,0x30,0x2e,0x30, - 0x37,0x37,0x2c,0x30,0x2e,0x34,0x34,0x36,0x2c,0x30, - 0x2e,0x30,0x39,0x34,0x2c,0x30,0x2e,0x37,0x30,0x38, - 0x2c,0x30,0x2e,0x34,0x30,0x35,0x2c,0x30,0x2e,0x37, - 0x30,0x38,0x63,0x30,0x2e,0x31,0x31,0x38,0x2c,0x30, - 0x2c,0x30,0x2e,0x32,0x35,0x35,0x2d,0x30,0x2e,0x30, - 0x33,0x38,0x2c,0x30,0x2e,0x34,0x30,0x37,0x2d,0x30, - 0x2e,0x31,0x31,0x37,0x6c,0x33,0x2e,0x37,0x31,0x37, - 0x2d,0x31,0x2e,0x39,0x35,0x35,0x63,0x30,0x2e,0x32, - 0x37,0x36,0x2d,0x30,0x2e,0x31,0x34,0x35,0x2c,0x30, - 0x2e,0x36,0x34,0x2d,0x30,0x2e,0x32,0x31,0x36,0x2c, - 0x31,0x2e,0x30,0x30,0x33,0x2d,0x30,0x2e,0x32,0x31, - 0x36,0x0d,0x0a,0x09,0x63,0x30,0x2e,0x33,0x36,0x34, - 0x2c,0x30,0x2c,0x30,0x2e,0x37,0x32,0x39,0x2c,0x30, - 0x2e,0x30,0x37,0x32,0x2c,0x31,0x2e,0x30,0x30,0x34, - 0x2c,0x30,0x2e,0x32,0x31,0x36,0x6c,0x33,0x2e,0x37, - 0x31,0x37,0x2c,0x31,0x2e,0x39,0x35,0x35,0x63,0x30, - 0x2e,0x31,0x35,0x2c,0x30,0x2e,0x30,0x37,0x39,0x2c, - 0x30,0x2e,0x32,0x38,0x39,0x2c,0x30,0x2e,0x31,0x31, - 0x37,0x2c,0x30,0x2e,0x34,0x30,0x37,0x2c,0x30,0x2e, - 0x31,0x31,0x37,0x63,0x30,0x2e,0x33,0x31,0x31,0x2c, - 0x30,0x2c,0x30,0x2e,0x34,0x38,0x31,0x2d,0x30,0x2e, - 0x32,0x36,0x32,0x2c,0x30,0x2e,0x34,0x30,0x35,0x2d, - 0x30,0x2e,0x37,0x30,0x38,0x6c,0x2d,0x30,0x2e,0x37, - 0x31,0x31,0x2d,0x34,0x2e,0x31,0x33,0x39,0x0d,0x0a, - 0x09,0x63,0x2d,0x30,0x2e,0x31,0x30,0x35,0x2d,0x30, - 0x2e,0x36,0x31,0x34,0x2c,0x30,0x2e,0x31,0x37,0x34, - 0x2d,0x31,0x2e,0x34,0x37,0x34,0x2c,0x30,0x2e,0x36, - 0x31,0x39,0x2d,0x31,0x2e,0x39,0x30,0x39,0x6c,0x33, - 0x2e,0x30,0x30,0x39,0x2d,0x32,0x2e,0x39,0x33,0x31, - 0x63,0x30,0x2e,0x34,0x34,0x36,0x2d,0x30,0x2e,0x34, - 0x33,0x35,0x2c,0x30,0x2e,0x33,0x30,0x37,0x2d,0x30, - 0x2e,0x38,0x36,0x35,0x2d,0x30,0x2e,0x33,0x31,0x31, - 0x2d,0x30,0x2e,0x39,0x35,0x35,0x6c,0x2d,0x34,0x2e, - 0x31,0x35,0x34,0x2d,0x30,0x2e,0x36,0x30,0x33,0x0d, - 0x0a,0x09,0x63,0x2d,0x30,0x2e,0x36,0x31,0x37,0x2d, - 0x30,0x2e,0x30,0x38,0x39,0x2d,0x31,0x2e,0x33,0x34, - 0x39,0x2d,0x30,0x2e,0x36,0x32,0x2d,0x31,0x2e,0x36, - 0x32,0x34,0x2d,0x31,0x2e,0x31,0x38,0x4c,0x39,0x2e, - 0x32,0x31,0x33,0x2c,0x32,0x2e,0x34,0x39,0x35,0x43, - 0x39,0x2e,0x30,0x37,0x34,0x2c,0x32,0x2e,0x32,0x31, - 0x36,0x2c,0x38,0x2e,0x38,0x39,0x33,0x2c,0x32,0x2e, - 0x30,0x37,0x36,0x2c,0x38,0x2e,0x37,0x31,0x2c,0x32, - 0x2e,0x30,0x37,0x36,0x4c,0x38,0x2e,0x37,0x31,0x2c, - 0x32,0x2e,0x30,0x37,0x36,0x7a,0x22,0x2f,0x3e,0x0d, - 0x0a,0x3c,0x2f,0x73,0x76,0x67,0x3e,0x0d,0x0a + 0x36,0x2d,0x30,0x2e,0x34,0x33,0x35,0x2c,0x30,0x2e, + 0x33,0x30,0x37,0x2d,0x30,0x2e,0x38,0x36,0x35,0x2d, + 0x30,0x2e,0x33,0x31,0x31,0x2d,0x30,0x2e,0x39,0x35, + 0x35,0x6c,0x2d,0x34,0x2e,0x31,0x35,0x34,0x2d,0x30, + 0x2e,0x36,0x30,0x33,0x0a,0x09,0x63,0x2d,0x30,0x2e, + 0x36,0x31,0x37,0x2d,0x30,0x2e,0x30,0x38,0x39,0x2d, + 0x31,0x2e,0x33,0x34,0x39,0x2d,0x30,0x2e,0x36,0x32, + 0x2d,0x31,0x2e,0x36,0x32,0x34,0x2d,0x31,0x2e,0x31, + 0x38,0x4c,0x39,0x2e,0x32,0x31,0x33,0x2c,0x32,0x2e, + 0x34,0x39,0x35,0x43,0x39,0x2e,0x30,0x37,0x34,0x2c, + 0x32,0x2e,0x32,0x31,0x36,0x2c,0x38,0x2e,0x38,0x39, + 0x33,0x2c,0x32,0x2e,0x30,0x37,0x36,0x2c,0x38,0x2e, + 0x37,0x31,0x2c,0x32,0x2e,0x30,0x37,0x36,0x4c,0x38, + 0x2e,0x37,0x31,0x2c,0x32,0x2e,0x30,0x37,0x36,0x7a, + 0x22,0x2f,0x3e,0x0a,0x3c,0x2f,0x73,0x76,0x67,0x3e, + 0x0a }; + diff --git a/data/converted/textinput_ninepatch_active_png.cpp b/data/converted/textinput_ninepatch_active_png.cpp index aae67003b5..664b3f79ef 100644 --- a/data/converted/textinput_ninepatch_active_png.cpp +++ b/data/converted/textinput_ninepatch_active_png.cpp @@ -314,3 +314,4 @@ const unsigned char textinput_ninepatch_active_png_data[3084] = { 0x50,0x30,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44, 0xae,0x42,0x60,0x82 }; + diff --git a/data/converted/textinput_ninepatch_png.cpp b/data/converted/textinput_ninepatch_png.cpp index 21387e40d3..6d1fb2de9c 100644 --- a/data/converted/textinput_ninepatch_png.cpp +++ b/data/converted/textinput_ninepatch_png.cpp @@ -133,3 +133,4 @@ const unsigned char textinput_ninepatch_png_data[1275] = { 0xeb,0x7d,0x04,0x00,0x00,0x00,0x00,0x49,0x45,0x4e, 0x44,0xae,0x42,0x60,0x82 }; + diff --git a/data/converted/window_icon_256_png.cpp b/data/converted/window_icon_256_png.cpp index e88c4c9f7a..20c5839c63 100644 --- a/data/converted/window_icon_256_png.cpp +++ b/data/converted/window_icon_256_png.cpp @@ -492,3 +492,4 @@ const unsigned char window_icon_256_png_data[4870] = { 0x21,0xc5,0x64,0xe3,0xe4,0x8c,0x4c,0xec,0x00,0x00, 0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82 }; + diff --git a/data/resources/help/analog_down.svg b/data/resources/help/analog_down.svg new file mode 100644 index 0000000000..e129aef1e5 --- /dev/null +++ b/data/resources/help/analog_down.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/data/resources/help/analog_left.svg b/data/resources/help/analog_left.svg new file mode 100644 index 0000000000..852fa81951 --- /dev/null +++ b/data/resources/help/analog_left.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/data/resources/help/analog_right.svg b/data/resources/help/analog_right.svg new file mode 100644 index 0000000000..6e08065d29 --- /dev/null +++ b/data/resources/help/analog_right.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/data/resources/help/analog_thumb.svg b/data/resources/help/analog_thumb.svg new file mode 100644 index 0000000000..4cbd0ef5cc --- /dev/null +++ b/data/resources/help/analog_thumb.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/data/resources/help/analog_up.svg b/data/resources/help/analog_up.svg new file mode 100644 index 0000000000..61d32dbf6f --- /dev/null +++ b/data/resources/help/analog_up.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/es-core/CMakeLists.txt b/es-core/CMakeLists.txt index 5a13b6e8df..09219d6739 100644 --- a/es-core/CMakeLists.txt +++ b/es-core/CMakeLists.txt @@ -121,6 +121,11 @@ set(EMBEDDED_ASSET_SOURCES ${emulationstation-all_SOURCE_DIR}/data/converted/frame_png.cpp ${emulationstation-all_SOURCE_DIR}/data/converted/scroll_gradient_png.cpp + ${emulationstation-all_SOURCE_DIR}/data/converted/help_analog_left_svg.cpp + ${emulationstation-all_SOURCE_DIR}/data/converted/help_analog_right_svg.cpp + ${emulationstation-all_SOURCE_DIR}/data/converted/help_analog_up_svg.cpp + ${emulationstation-all_SOURCE_DIR}/data/converted/help_analog_down_svg.cpp + ${emulationstation-all_SOURCE_DIR}/data/converted/help_analog_thumb_svg.cpp ${emulationstation-all_SOURCE_DIR}/data/converted/help_button_a_svg.cpp ${emulationstation-all_SOURCE_DIR}/data/converted/help_button_b_svg.cpp ${emulationstation-all_SOURCE_DIR}/data/converted/help_button_x_svg.cpp diff --git a/es-core/src/InputManager.cpp b/es-core/src/InputManager.cpp index 3bd26b8975..81bbb57704 100644 --- a/es-core/src/InputManager.cpp +++ b/es-core/src/InputManager.cpp @@ -287,39 +287,60 @@ void InputManager::loadDefaultKBConfig() cfg->mapInput("start", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_F1, 1, true)); cfg->mapInput("select", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_F2, 1, true)); - cfg->mapInput("pageup", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_RIGHTBRACKET, 1, true)); - cfg->mapInput("pagedown", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_LEFTBRACKET, 1, true)); + cfg->mapInput("leftbottom", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_RIGHTBRACKET, 1, true)); + cfg->mapInput("rightbottom", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_LEFTBRACKET, 1, true)); } void InputManager::writeDeviceConfig(InputConfig* config) { - assert(initialized()); - - std::string path = getConfigPath(); - - pugi::xml_document doc; - - if(fs::exists(path)) - { - // merge files - pugi::xml_parse_result result = doc.load_file(path.c_str()); - if(!result) - { - LOG(LogError) << "Error parsing input config: " << result.description(); - }else{ - // successfully loaded, delete the old entry if it exists - pugi::xml_node root = doc.child("inputList"); - if(root) - { - pugi::xml_node oldEntry = root.find_child_by_attribute("inputConfig", "deviceGUID", config->getDeviceGUIDString().c_str()); - if(oldEntry) - root.remove_child(oldEntry); - oldEntry = root.find_child_by_attribute("inputConfig", "deviceName", config->getDeviceName().c_str()); - if(oldEntry) - root.remove_child(oldEntry); - } - } - } + assert(initialized()); + + std::string path = getConfigPath(); + + pugi::xml_document doc; + + if(fs::exists(path)) + { + // merge files + pugi::xml_parse_result result = doc.load_file(path.c_str()); + if(!result) + { + LOG(LogError) << "Error parsing input config: " << result.description(); + } + else + { + // successfully loaded, delete the old entry if it exists + pugi::xml_node root = doc.child("inputList"); + if(root) + { + // if inputAction @type=onfinish is set, let onfinish command take care for creating input configuration. + // we just put the input configuration into a temporary input config file. + pugi::xml_node actionnode = root.find_child_by_attribute("inputAction", "type", "onfinish"); + if(actionnode) + { + path = getTemporaryConfigPath(); + doc.reset(); + root = doc.append_child("inputList"); + root.append_copy(actionnode); + } + else + { + pugi::xml_node oldEntry = root.find_child_by_attribute("inputConfig", "deviceGUID", + config->getDeviceGUIDString().c_str()); + if(oldEntry) + { + root.remove_child(oldEntry); + } + oldEntry = root.find_child_by_attribute("inputConfig", "deviceName", + config->getDeviceName().c_str()); + if(oldEntry) + { + root.remove_child(oldEntry); + } + } + } + } + } pugi::xml_node root = doc.child("inputList"); if(!root) @@ -329,6 +350,48 @@ void InputManager::writeDeviceConfig(InputConfig* config) doc.save_file(path.c_str()); } +void InputManager::doOnFinish() +{ + assert(initialized()); + std::string path = getConfigPath(); + pugi::xml_document doc; + + if(fs::exists(path)) + { + pugi::xml_parse_result result = doc.load_file(path.c_str()); + if(!result) + { + LOG(LogError) << "Error parsing input config: " << result.description(); + } + else + { + pugi::xml_node root = doc.child("inputList"); + if(root) + { + root = root.find_child_by_attribute("inputAction", "type", "onfinish"); + if(root) + { + for(pugi::xml_node command = root.child("command"); command; + command = command.next_sibling("command")) + { + std::string tocall = command.text().get(); + + LOG(LogInfo) << " " << tocall; + std::cout << "==============================================\ninput config finish command:\n"; + int exitCode = runSystemCommand(tocall); + std::cout << "==============================================\n"; + + if(exitCode != 0) + { + LOG(LogWarning) << "...launch terminated with nonzero exit code " << exitCode << "!"; + } + } + } + } + } + } +} + std::string InputManager::getConfigPath() { std::string path = getHomePath(); @@ -336,6 +399,13 @@ std::string InputManager::getConfigPath() return path; } +std::string InputManager::getTemporaryConfigPath() +{ + std::string path = getHomePath(); + path += "/.emulationstation/es_temporaryinput.cfg"; + return path; +} + bool InputManager::initialized() const { return mKeyboardInputConfig != NULL; diff --git a/es-core/src/InputManager.h b/es-core/src/InputManager.h index 5ec8d8848a..7408356342 100644 --- a/es-core/src/InputManager.h +++ b/es-core/src/InputManager.h @@ -39,7 +39,9 @@ class InputManager static InputManager* getInstance(); void writeDeviceConfig(InputConfig* config); + void doOnFinish(); static std::string getConfigPath(); + static std::string getTemporaryConfigPath(); void init(); void deinit(); diff --git a/es-core/src/components/ComponentList.cpp b/es-core/src/components/ComponentList.cpp index a16bcb0975..77b9ae83bc 100644 --- a/es-core/src/components/ComponentList.cpp +++ b/es-core/src/components/ComponentList.cpp @@ -81,10 +81,10 @@ bool ComponentList::input(InputConfig* config, Input input) }else if(config->isMappedTo("down", input)) { return listInput(input.value != 0 ? 1 : 0); - }else if(config->isMappedTo("pageup", input)) + }else if(config->isMappedTo("leftbottom", input)) { return listInput(input.value != 0 ? -7 : 0); - }else if(config->isMappedTo("pagedown", input)){ + }else if(config->isMappedTo("rightbottom", input)){ return listInput(input.value != 0 ? 7 : 0); } diff --git a/es-core/src/components/DateTimeComponent.cpp b/es-core/src/components/DateTimeComponent.cpp index 7113ec4950..a360be44f3 100644 --- a/es-core/src/components/DateTimeComponent.cpp +++ b/es-core/src/components/DateTimeComponent.cpp @@ -54,9 +54,9 @@ bool DateTimeComponent::input(InputConfig* config, Input input) } int incDir = 0; - if(config->isMappedTo("up", input) || config->isMappedTo("pageup", input)) + if(config->isMappedTo("up", input) || config->isMappedTo("leftbottom", input)) incDir = 1; - else if(config->isMappedTo("down", input) || config->isMappedTo("pagedown", input)) + else if(config->isMappedTo("down", input) || config->isMappedTo("rightbottom", input)) incDir = -1; if(incDir != 0) diff --git a/es-core/src/guis/GuiInputConfig.cpp b/es-core/src/guis/GuiInputConfig.cpp index b4522709f4..d0f311a254 100644 --- a/es-core/src/guis/GuiInputConfig.cpp +++ b/es-core/src/guis/GuiInputConfig.cpp @@ -7,24 +7,134 @@ #include "components/ButtonComponent.h" #include "Util.h" -static const int inputCount = 10; -static const char* inputName[inputCount] = { "Up", "Down", "Left", "Right", "A", "B", "Start", "Select", "PageUp", "PageDown" }; -static const bool inputSkippable[inputCount] = { false, false, false, false, false, false, false, false, true, true }; -static const char* inputDispName[inputCount] = { "UP", "DOWN", "LEFT", "RIGHT", "A", "B", "START", "SELECT", "PAGE UP", "PAGE DOWN" }; -static const char* inputIcon[inputCount] = { ":/help/dpad_up.svg", ":/help/dpad_down.svg", ":/help/dpad_left.svg", ":/help/dpad_right.svg", - ":/help/button_a.svg", ":/help/button_b.svg", ":/help/button_start.svg", ":/help/button_select.svg", - ":/help/button_l.svg", ":/help/button_r.svg" }; +// static const int inputCount = 10; +// static const char* inputName[inputCount] = { "Up", "Down", "Left", "Right", "A", "B", "Start", "Select", "PageUp", "PageDown" }; +// static const bool inputSkippable[inputCount] = { false, false, false, false, false, false, false, false, true, true }; +// static const char* inputDispName[inputCount] = { "UP", "DOWN", "LEFT", "RIGHT", "A", "B", "START", "SELECT", "PAGE UP", "PAGE DOWN" }; +// static const char* inputIcon[inputCount] = { ":/help/dpad_up.svg", ":/help/dpad_down.svg", ":/help/dpad_left.svg", ":/help/dpad_right.svg", +// ":/help/button_a.svg", ":/help/button_b.svg", ":/help/button_start.svg", ":/help/button_select.svg", +// ":/help/button_l.svg", ":/help/button_r.svg" }; + +static const int inputCount = 24; +static const char* inputName[inputCount] = +{ + "Up", + "Down", + "Left", + "Right", + "Start", + "Select", + "A", + "B", + "X", + "Y", + "LeftBottom", + "RightBottom", + "LeftTop", + "RightTop", + "LeftThumb", + "RightThumb", + "LeftAnalogUp", + "LeftAnalogDown", + "LeftAnalogLeft", + "LeftAnalogRight", + "RightAnalogUp", + "RightAnalogDown", + "RightAnalogLeft", + "RightAnalogRight" +}; +static const bool inputSkippable[inputCount] = +{ + false, + false, + false, + false, + true, + true, + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true +}; +static const char* inputDispName[inputCount] = +{ + "D-PAD UP", + "D-PAD DOWN", + "D-PAD LEFT", + "D-PAD RIGHT", + "START", + "SELECT", + "A", + "B", + "X", + "Y", + "LEFT BOTTOM", + "RIGHT BOTTOM", + "LEFT TOP", + "RIGHT TOP", + "LEFT THUMB", + "RIGHT THUMB", + "LEFT ANALOG UP", + "LEFT ANALOG DOWN", + "LEFT ANALOG LEFT", + "LEFT ANALOG RIGHT", + "RIGHT ANALOG UP", + "RIGHT ANALOG DOWN", + "RIGHT ANALOG LEFT", + "RIGHT ANALOG RIGHT" +}; +static const char* inputIcon[inputCount] = +{ + ":/help/dpad_up.svg", + ":/help/dpad_down.svg", + ":/help/dpad_left.svg", + ":/help/dpad_right.svg", + ":/help/button_start.svg", + ":/help/button_select.svg", + ":/help/button_a.svg", + ":/help/button_b.svg", + ":/help/button_x.svg", + ":/help/button_y.svg", + ":/help/button_l.svg", + ":/help/button_r.svg", + ":/help/button_l.svg", + ":/help/button_r.svg", + ":/help/analog_thumb.svg", + ":/help/analog_thumb.svg", + ":/help/analog_up.svg", + ":/help/analog_down.svg", + ":/help/analog_left.svg", + ":/help/analog_right.svg", + ":/help/analog_up.svg", + ":/help/analog_down.svg", + ":/help/analog_left.svg", + ":/help/analog_right.svg" +}; //MasterVolUp and MasterVolDown are also hooked up, but do not appear on this screen. //If you want, you can manually add them to es_input.cfg. using namespace Eigen; -#define HOLD_TO_SKIP_MS 5000 +#define HOLD_TO_SKIP_MS 2500 GuiInputConfig::GuiInputConfig(Window* window, InputConfig* target, bool reconfigureAll, const std::function& okCallback) : GuiComponent(window), mBackground(window, ":/frame.png"), mGrid(window, Vector2i(1, 7)), - mTargetConfig(target), mHoldingInput(false) + mTargetConfig(target), mHoldingInput(false), mBusyAnim(window) { LOG(LogInfo) << "Configuring device " << target->getDeviceId() << " (" << target->getDeviceName() << ")."; @@ -149,6 +259,7 @@ GuiInputConfig::GuiInputConfig(Window* window, InputConfig* target, bool reconfi std::vector< std::shared_ptr > buttons; buttons.push_back(std::make_shared(mWindow, "OK", "ok", [this, okCallback] { InputManager::getInstance()->writeDeviceConfig(mTargetConfig); // save + InputManager::getInstance()->doOnFinish(); // execute possible onFinish commands if(okCallback) okCallback(); delete this; @@ -174,6 +285,8 @@ void GuiInputConfig::onSizeChanged() //mGrid.setRowHeightPerc(4, 0.03f); mGrid.setRowHeightPerc(5, (mList->getRowHeight(0) * 5 + 2) / mSize.y()); mGrid.setRowHeightPerc(6, mButtonGrid->getSize().y() / mSize.y()); + + mBusyAnim.setSize(mSize); } void GuiInputConfig::update(int deltaTime) diff --git a/es-core/src/guis/GuiInputConfig.h b/es-core/src/guis/GuiInputConfig.h index 20af11df86..0c93cb3667 100644 --- a/es-core/src/guis/GuiInputConfig.h +++ b/es-core/src/guis/GuiInputConfig.h @@ -4,6 +4,7 @@ #include "components/NinePatchComponent.h" #include "components/ComponentGrid.h" #include "components/ComponentList.h" +#include "components/BusyComponent.h" class TextComponent; @@ -46,4 +47,6 @@ class GuiInputConfig : public GuiComponent Input mHeldInput; int mHeldTime; int mHeldInputId; + + BusyComponent mBusyAnim; }; From 5be78e9c532d4c400c190f7f9c966b85aa19463e Mon Sep 17 00:00:00 2001 From: taalas Date: Sun, 7 Jun 2015 18:56:02 +0200 Subject: [PATCH 03/74] add direct launch tag and corresponding data structures --- es-app/src/SystemData.cpp | 60 +++++++++++++++++++++++---------- es-app/src/SystemData.h | 4 ++- es-app/src/views/SystemView.cpp | 11 +++++- 3 files changed, 56 insertions(+), 19 deletions(-) diff --git a/es-app/src/SystemData.cpp b/es-app/src/SystemData.cpp index 5e2b9b4c2e..3b6ad218dc 100644 --- a/es-app/src/SystemData.cpp +++ b/es-app/src/SystemData.cpp @@ -18,7 +18,7 @@ std::vector SystemData::sSystemVector; namespace fs = boost::filesystem; SystemData::SystemData(const std::string& name, const std::string& fullName, const std::string& startPath, const std::vector& extensions, - const std::string& command, const std::vector& platformIds, const std::string& themeFolder) + const std::string& command, const std::vector& platformIds, const std::string& themeFolder, bool directLaunch) { mName = name; mFullName = fullName; @@ -36,6 +36,8 @@ SystemData::SystemData(const std::string& name, const std::string& fullName, con mPlatformIds = platformIds; mThemeFolder = themeFolder; + mDirectLaunch = directLaunch; + mRootFolder = new FileData(FOLDER, mStartPath, this); mRootFolder->metadata.set("name", mFullName); @@ -106,7 +108,12 @@ std::string escapePath(const boost::filesystem::path& path) void SystemData::launchGame(Window* window, FileData* game) { - LOG(LogInfo) << "Attempting to launch game..."; + if ( game ) + { + LOG(LogInfo) << "Attempting to launch game..."; + }else{ + LOG(LogInfo) << "Attempting to launch command..."; + } AudioManager::getInstance()->deinit(); VolumeControl::getInstance()->deinit(); @@ -114,13 +121,16 @@ void SystemData::launchGame(Window* window, FileData* game) std::string command = mLaunchCommand; - const std::string rom = escapePath(game->getPath()); - const std::string basename = game->getPath().stem().string(); - const std::string rom_raw = fs::path(game->getPath()).make_preferred().string(); + if ( game ) + { + const std::string rom = escapePath(game->getPath()); + const std::string basename = game->getPath().stem().string(); + const std::string rom_raw = fs::path(game->getPath()).make_preferred().string(); - command = strreplace(command, "%ROM%", rom); - command = strreplace(command, "%BASENAME%", basename); - command = strreplace(command, "%ROM_RAW%", rom_raw); + command = strreplace(command, "%ROM%", rom); + command = strreplace(command, "%BASENAME%", basename); + command = strreplace(command, "%ROM_RAW%", rom_raw); + } LOG(LogInfo) << " " << command; std::cout << "==============================================\n"; @@ -137,13 +147,16 @@ void SystemData::launchGame(Window* window, FileData* game) AudioManager::getInstance()->init(); window->normalizeNextUpdate(); - //update number of times the game has been launched - int timesPlayed = game->metadata.getInt("playcount") + 1; - game->metadata.set("playcount", std::to_string(static_cast(timesPlayed))); + if ( game ) + { + //update number of times the game has been launched + int timesPlayed = game->metadata.getInt("playcount") + 1; + game->metadata.set("playcount", std::to_string(static_cast(timesPlayed))); - //update last played time - boost::posix_time::ptime time = boost::posix_time::second_clock::universal_time(); - game->metadata.setTime("lastplayed", time); + //update last played time + boost::posix_time::ptime time = boost::posix_time::second_clock::universal_time(); + game->metadata.setTime("lastplayed", time); + } } void SystemData::populateFolder(FileData* folder) @@ -263,11 +276,13 @@ bool SystemData::loadConfig() for(pugi::xml_node system = systemList.child("system"); system; system = system.next_sibling("system")) { std::string name, fullname, path, cmd, themeFolder; + bool directLaunch; PlatformIds::PlatformId platformId = PlatformIds::PLATFORM_UNKNOWN; name = system.child("name").text().get(); fullname = system.child("fullname").text().get(); path = system.child("path").text().get(); + directLaunch = ( strcmp( system.child("directlaunch").text().get(), "true" ) == 0); // convert extensions list from a string into a vector of strings std::vector extensions = readList(system.child("extension").text().get()); @@ -301,18 +316,25 @@ bool SystemData::loadConfig() // theme folder themeFolder = system.child("theme").text().as_string(name.c_str()); - //validate - if(name.empty() || path.empty() || extensions.empty() || cmd.empty()) + //validate game system + if( (name.empty() || path.empty() || extensions.empty() || cmd.empty() ) && directLaunch == false ) { LOG(LogError) << "System \"" << name << "\" is missing name, path, extension, or command!"; continue; } + + //validate direct launch item + if( (name.empty() || cmd.empty() ) && directLaunch == true ) + { + LOG(LogError) << "Direct Launch item \"" << name << "\" is missing name or command!"; + continue; + } //convert path to generic directory seperators boost::filesystem::path genericPath(path); path = genericPath.generic_string(); - SystemData* newSys = new SystemData(name, fullname, path, extensions, cmd, platformIds, themeFolder); + SystemData* newSys = new SystemData(name, fullname, path, extensions, cmd, platformIds, themeFolder, directLaunch); if(newSys->getRootFolder()->getChildren().size() == 0) { LOG(LogWarning) << "System \"" << name << "\" has no games! Ignoring it."; @@ -363,6 +385,10 @@ void SystemData::writeExampleConfig(const std::string& path) " \n" " nes\n" + "\n" + " \n" + " false\n" " \n" "\n"; diff --git a/es-app/src/SystemData.h b/es-app/src/SystemData.h index 2a0ac81886..6629d9f7ee 100644 --- a/es-app/src/SystemData.h +++ b/es-app/src/SystemData.h @@ -12,7 +12,7 @@ class SystemData { public: SystemData(const std::string& name, const std::string& fullName, const std::string& startPath, const std::vector& extensions, - const std::string& command, const std::vector& platformIds, const std::string& themeFolder); + const std::string& command, const std::vector& platformIds, const std::string& themeFolder, bool directLaunch=false); ~SystemData(); inline FileData* getRootFolder() const { return mRootFolder; }; @@ -21,6 +21,7 @@ class SystemData inline const std::string& getStartPath() const { return mStartPath; } inline const std::vector& getExtensions() const { return mSearchExtensions; } inline const std::string& getThemeFolder() const { return mThemeFolder; } + inline const bool getDirectLaunch() const { return mDirectLaunch; } inline const std::vector& getPlatformIds() const { return mPlatformIds; } inline bool hasPlatformId(PlatformIds::PlatformId id) { return std::find(mPlatformIds.begin(), mPlatformIds.end(), id) != mPlatformIds.end(); } @@ -73,6 +74,7 @@ class SystemData std::vector mPlatformIds; std::string mThemeFolder; std::shared_ptr mTheme; + bool mDirectLaunch; void populateFolder(FileData* folder); diff --git a/es-app/src/views/SystemView.cpp b/es-app/src/views/SystemView.cpp index 54987fdf87..9810cd316d 100644 --- a/es-app/src/views/SystemView.cpp +++ b/es-app/src/views/SystemView.cpp @@ -119,7 +119,16 @@ bool SystemView::input(InputConfig* config, Input input) if(config->isMappedTo("a", input)) { stopScrolling(); - ViewController::get()->goToGameList(getSelected()); + + SystemData *systemData = getSelected(); + + // decide whether to show game list or launch the command directly + if ( !systemData->getDirectLaunch() ) + { + ViewController::get()->goToGameList(getSelected()); + }else{ + systemData->launchGame( mWindow, nullptr ); + } return true; } }else{ From d2d448ee1c68d577a0983447201e02a04d3e27e9 Mon Sep 17 00:00:00 2001 From: taalas Date: Tue, 9 Jun 2015 14:27:27 +0200 Subject: [PATCH 04/74] fix indentation --- es-app/src/SystemData.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/es-app/src/SystemData.cpp b/es-app/src/SystemData.cpp index 3b6ad218dc..8a05d5f1ed 100644 --- a/es-app/src/SystemData.cpp +++ b/es-app/src/SystemData.cpp @@ -387,8 +387,8 @@ void SystemData::writeExampleConfig(const std::string& path) " nes\n" "\n" " \n" - " false\n" + " will launch the command given. If set to true, every tag except for name and command is optional -->\n" + " false\n" " \n" "\n"; From 6f602a22c9c15f33e64def21e1426522ab8d5766 Mon Sep 17 00:00:00 2001 From: taalas Date: Tue, 9 Jun 2015 15:13:29 +0200 Subject: [PATCH 05/74] skip game lists without games when quick selecting, handle empty game lists --- es-app/src/SystemData.cpp | 17 ++++++++++++---- es-app/src/views/ViewController.cpp | 20 +++++++++++++++++-- .../src/views/gamelist/BasicGameListView.cpp | 6 ++++++ 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/es-app/src/SystemData.cpp b/es-app/src/SystemData.cpp index 8a05d5f1ed..39b63825f6 100644 --- a/es-app/src/SystemData.cpp +++ b/es-app/src/SystemData.cpp @@ -161,6 +161,12 @@ void SystemData::launchGame(Window* window, FileData* game) void SystemData::populateFolder(FileData* folder) { + if (mDirectLaunch) + { + LOG(LogInfo) << "System " << mName << " is a direct launch item, not building game lists."; + return; + } + const fs::path& folderPath = folder->getPath(); if(!fs::is_directory(folderPath)) { @@ -330,12 +336,15 @@ bool SystemData::loadConfig() continue; } - //convert path to generic directory seperators - boost::filesystem::path genericPath(path); - path = genericPath.generic_string(); + if (!directLaunch) + { + //convert path to generic directory seperators + boost::filesystem::path genericPath(path); + path = genericPath.generic_string(); + } SystemData* newSys = new SystemData(name, fullname, path, extensions, cmd, platformIds, themeFolder, directLaunch); - if(newSys->getRootFolder()->getChildren().size() == 0) + if(newSys->getRootFolder()->getChildren().size() == 0 && !directLaunch) { LOG(LogWarning) << "System \"" << name << "\" has no games! Ignoring it."; delete newSys; diff --git a/es-app/src/views/ViewController.cpp b/es-app/src/views/ViewController.cpp index 5a94d97c2b..9716cfd8bf 100644 --- a/es-app/src/views/ViewController.cpp +++ b/es-app/src/views/ViewController.cpp @@ -72,7 +72,15 @@ void ViewController::goToNextGameList() assert(mState.viewing == GAME_LIST); SystemData* system = getState().getSystem(); assert(system); - goToGameList(system->getNext()); + + // skip systems that don't have a game list, this will always end since it is called + // from a system with a game list and the iterator is cyclic + do + { + system = system->getNext(); + } while ( system->getDirectLaunch() ); + + goToGameList(system); } void ViewController::goToPrevGameList() @@ -80,7 +88,15 @@ void ViewController::goToPrevGameList() assert(mState.viewing == GAME_LIST); SystemData* system = getState().getSystem(); assert(system); - goToGameList(system->getPrev()); + + // skip systems that don't have a game list, this will always end since it is called + // from a system with a game list and the iterator is cyclic + do + { + system = system->getPrev(); + } while ( system->getDirectLaunch() ); + + goToGameList(system); } void ViewController::goToGameList(SystemData* system) diff --git a/es-app/src/views/gamelist/BasicGameListView.cpp b/es-app/src/views/gamelist/BasicGameListView.cpp index af4ccbfe4d..e0facdd207 100644 --- a/es-app/src/views/gamelist/BasicGameListView.cpp +++ b/es-app/src/views/gamelist/BasicGameListView.cpp @@ -38,6 +38,12 @@ void BasicGameListView::onFileChanged(FileData* file, FileChangeType change) void BasicGameListView::populateList(const std::vector& files) { mList.clear(); + + // file list can be empty if direct launch item + if (files.size()==0) + { + return; + } mHeaderText.setText(files.at(0)->getSystem()->getFullName()); From b3c38b97825d9182bcbe49547a12d5e9dc04b930 Mon Sep 17 00:00:00 2001 From: Jools Wills Date: Sat, 19 Sep 2015 02:25:31 +0100 Subject: [PATCH 06/74] don't strip info from the parentheses in the gameslists - it's useful! --- es-app/src/FileData.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/es-app/src/FileData.cpp b/es-app/src/FileData.cpp index a1b625d8a5..d4279105bd 100644 --- a/es-app/src/FileData.cpp +++ b/es-app/src/FileData.cpp @@ -66,7 +66,7 @@ std::string FileData::getCleanName() const if(mSystem && mSystem->hasPlatformId(PlatformIds::ARCADE) || mSystem->hasPlatformId(PlatformIds::NEOGEO)) stem = PlatformIds::getCleanMameName(stem.c_str()); - return removeParenthesis(stem); + return stem; } const std::string& FileData::getThumbnailPath() const From cdda6f6dc1c443dff1345d32e3f1ca3ded130cb5 Mon Sep 17 00:00:00 2001 From: gizmo98 Date: Mon, 28 Sep 2015 19:25:15 +0200 Subject: [PATCH 07/74] Skip controller config if known device is added after startup Fix for problems like this: http://blog.petrockblock.com/forums/topic/retropie-wont-recognize-ps3-controller-unless-ps-button-is-hit-before-es-start/ http://blog.petrockblock.com/forums/topic/elegent-method-of-detecting-wireless-controller-before-starting-es/ No controller found message pops up if no controller is connected. If a known controller is connected and any button is pressed system selection menu will show up instantly. --- es-core/src/guis/GuiDetectDevice.cpp | 31 +++++++++++++++++++++------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/es-core/src/guis/GuiDetectDevice.cpp b/es-core/src/guis/GuiDetectDevice.cpp index 95deea1ea8..d185183d8f 100644 --- a/es-core/src/guis/GuiDetectDevice.cpp +++ b/es-core/src/guis/GuiDetectDevice.cpp @@ -8,11 +8,15 @@ #include #include #include "Util.h" +#include +#include #define HOLD_TIME 1000 using namespace Eigen; +namespace fs = boost::filesystem; + GuiDetectDevice::GuiDetectDevice(Window* window, bool firstRun, const std::function& doneCallback) : GuiComponent(window), mFirstRun(firstRun), mBackground(window, ":/frame.png"), mGrid(window, Vector2i(1, 5)) { @@ -100,15 +104,26 @@ void GuiDetectDevice::update(int deltaTime) { if(mHoldingConfig) { - mHoldTime -= deltaTime; - const float t = (float)mHoldTime / HOLD_TIME; - unsigned int c = (unsigned char)(t * 255); - mDeviceHeld->setColor((c << 24) | (c << 16) | (c << 8) | 0xFF); - if(mHoldTime <= 0) + // If ES starts and if a known device is connected after startup skip controller configuration + if(mFirstRun && fs::exists(InputManager::getConfigPath()) && InputManager::getInstance()->getNumConfiguredDevices() > 0) + { + InputManager::getInstance()->doOnFinish(); // execute possible onFinish commands + if(mDoneCallback) + mDoneCallback(); + delete this; // delete GUI element + } + else { - // picked one! - mWindow->pushGui(new GuiInputConfig(mWindow, mHoldingConfig, true, mDoneCallback)); - delete this; + mHoldTime -= deltaTime; + const float t = (float)mHoldTime / HOLD_TIME; + unsigned int c = (unsigned char)(t * 255); + mDeviceHeld->setColor((c << 24) | (c << 16) | (c << 8) | 0xFF); + if(mHoldTime <= 0) + { + // picked one! + mWindow->pushGui(new GuiInputConfig(mWindow, mHoldingConfig, true, mDoneCallback)); + delete this; + } } } } From 7bffae0812bfb1963fa14b8a80cd1126800711bd Mon Sep 17 00:00:00 2001 From: Jools Wills Date: Sat, 3 Oct 2015 20:20:33 +0100 Subject: [PATCH 08/74] change hold to skip timer to 1 second. This means the countdown message never shows, but it says at the top to hold to skip and this makes it a lot more convenient to set up snes style controllers. Has been tested by herbfaargus also, who agreed it's an improvement. #6 --- es-core/src/guis/GuiInputConfig.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/es-core/src/guis/GuiInputConfig.cpp b/es-core/src/guis/GuiInputConfig.cpp index d0f311a254..78f598ff10 100644 --- a/es-core/src/guis/GuiInputConfig.cpp +++ b/es-core/src/guis/GuiInputConfig.cpp @@ -130,7 +130,7 @@ static const char* inputIcon[inputCount] = using namespace Eigen; -#define HOLD_TO_SKIP_MS 2500 +#define HOLD_TO_SKIP_MS 1000 GuiInputConfig::GuiInputConfig(Window* window, InputConfig* target, bool reconfigureAll, const std::function& okCallback) : GuiComponent(window), mBackground(window, ":/frame.png"), mGrid(window, Vector2i(1, 7)), From 6f0b63b1bb14398f30a0d3d09e4cf9e5b3d21db8 Mon Sep 17 00:00:00 2001 From: Jools Wills Date: Sat, 3 Oct 2015 20:41:44 +0100 Subject: [PATCH 09/74] trailing whitespace introduced by #9 --- es-core/src/guis/GuiDetectDevice.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/es-core/src/guis/GuiDetectDevice.cpp b/es-core/src/guis/GuiDetectDevice.cpp index d185183d8f..b7fae13654 100644 --- a/es-core/src/guis/GuiDetectDevice.cpp +++ b/es-core/src/guis/GuiDetectDevice.cpp @@ -107,10 +107,10 @@ void GuiDetectDevice::update(int deltaTime) // If ES starts and if a known device is connected after startup skip controller configuration if(mFirstRun && fs::exists(InputManager::getConfigPath()) && InputManager::getInstance()->getNumConfiguredDevices() > 0) { - InputManager::getInstance()->doOnFinish(); // execute possible onFinish commands - if(mDoneCallback) + InputManager::getInstance()->doOnFinish(); // execute possible onFinish commands + if(mDoneCallback) mDoneCallback(); - delete this; // delete GUI element + delete this; // delete GUI element } else { From 43c5e0911fa4a6de474ead25ff208821c8cc0b3a Mon Sep 17 00:00:00 2001 From: Phil Eichinger Date: Wed, 2 Dec 2015 20:24:36 +0100 Subject: [PATCH 10/74] Make libboost dependencies for Debian dependent on the found version Makes it installable on Debian Jessie (libboost 1.55.0) --- es-app/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/es-app/CMakeLists.txt b/es-app/CMakeLists.txt index ee7f829909..6f1de88be4 100644 --- a/es-app/CMakeLists.txt +++ b/es-app/CMakeLists.txt @@ -133,7 +133,7 @@ SET(CPACK_RESOURCE_FILE README "${CMAKE_CURRENT_SOURCE_DIR}/README.md") SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "Alec Lofquist ") SET(CPACK_DEBIAN_PACKAGE_SECTION "misc") SET(CPACK_DEBIAN_PACKAGE_PRIORITY "extra") -SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6, libsdl2-2.0-0, libboost-system1.54.0, libboost-filesystem1.54.0, libfreeimage3, libfreetype6, libcurl3, libasound2") +SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6, libsdl2-2.0-0, libboost-system${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}, libboost-filesystem${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}, libfreeimage3, libfreetype6, libcurl3, libasound2") SET(CPACK_DEBIAN_PACKAGE_BUILDS_DEPENDS "debhelper (>= 8.0.0), cmake, g++ (>= 4.8), libsdl2-dev, libboost-system-dev, libboost-filesystem-dev, libboost-date-time-dev, libfreeimage-dev, libfreetype6-dev, libeigen3-dev, libcurl4-openssl-dev, libasound2-dev, libgl1-mesa-dev") SET(CPACK_PACKAGE_VENDOR "emulationstation.org") From fe86459f9919fbc53dcad313a7c470b675eea1cb Mon Sep 17 00:00:00 2001 From: Jools Wills Date: Sun, 17 Jan 2016 04:24:28 +0000 Subject: [PATCH 11/74] don't call shutdown from ES directly - which causes it to not save the gameslists on exit. Instead create files /tmp/es-restart /tmp/es-sysrestart /tmp/es-shutdown to decide what we want to do. there is an emulationstation.sh launch script to handle this --- emulationstation.sh | 18 ++++++++++++++++++ es-app/src/guis/GuiMenu.cpp | 15 +++++++++++++-- es-core/src/platform.cpp | 18 ++++++++++++++++++ es-core/src/platform.h | 4 +++- 4 files changed, 52 insertions(+), 3 deletions(-) create mode 100755 emulationstation.sh diff --git a/emulationstation.sh b/emulationstation.sh new file mode 100755 index 0000000000..cc48aed670 --- /dev/null +++ b/emulationstation.sh @@ -0,0 +1,18 @@ +#!/bin/sh + +while true; do + rm -f /tmp/es-restart /tmp/es-sysrestart /tmp/es-shutdown + ./emulationstation "$@" + [ -f /tmp/es-restart ] && continue + if [ -f /tmp/es-sysrestart ]; then + rm -f /tmp/es-sysrestart + sudo reboot + break + fi + if [ -f /tmp/es-shutdown ]; then + rm -f /tmp/es-shutdown + sudo poweroff + break + fi + break +done diff --git a/es-app/src/guis/GuiMenu.cpp b/es-app/src/guis/GuiMenu.cpp index 417d38224c..8478d98eb0 100644 --- a/es-app/src/guis/GuiMenu.cpp +++ b/es-app/src/guis/GuiMenu.cpp @@ -177,10 +177,21 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MEN Window* window = mWindow; ComponentListRow row; + row.makeAcceptInputHandler([window] { + window->pushGui(new GuiMsgBox(window, "REALLY RESTART?", "YES", + [] { + if(quitES("/tmp/es-restart") != 0) + LOG(LogWarning) << "Restart terminated with non-zero result!"; + }, "NO", nullptr)); + }); + row.addElement(std::make_shared(window, "RESTART EMULATIONSTATION", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true); + s->addRow(row); + + row.elements.clear(); row.makeAcceptInputHandler([window] { window->pushGui(new GuiMsgBox(window, "REALLY RESTART?", "YES", [] { - if(runRestartCommand() != 0) + if(quitES("/tmp/es-sysrestart") != 0) LOG(LogWarning) << "Restart terminated with non-zero result!"; }, "NO", nullptr)); }); @@ -191,7 +202,7 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MEN row.makeAcceptInputHandler([window] { window->pushGui(new GuiMsgBox(window, "REALLY SHUTDOWN?", "YES", [] { - if(runShutdownCommand() != 0) + if(quitES("/tmp/es-shutdown") != 0) LOG(LogWarning) << "Shutdown terminated with non-zero result!"; }, "NO", nullptr)); }); diff --git a/es-core/src/platform.cpp b/es-core/src/platform.cpp index e1663a5f97..31127a9cab 100644 --- a/es-core/src/platform.cpp +++ b/es-core/src/platform.cpp @@ -1,7 +1,9 @@ #include "platform.h" #include #include +#include #include +#include #ifdef WIN32 #include @@ -69,4 +71,20 @@ int runSystemCommand(const std::string& cmd_utf8) #else return system(cmd_utf8.c_str()); #endif +} + +int quitES(const std::string& filename) +{ + touch(filename); + SDL_Event* quit = new SDL_Event(); + quit->type = SDL_QUIT; + SDL_PushEvent(quit); + return 0; +} + +void touch(const std::string& filename) +{ + int fd = open(filename.c_str(), O_CREAT|O_WRONLY, 0644); + if (fd >= 0) + close(fd); } \ No newline at end of file diff --git a/es-core/src/platform.h b/es-core/src/platform.h index a0571b32ae..0760b565c1 100644 --- a/es-core/src/platform.h +++ b/es-core/src/platform.h @@ -21,4 +21,6 @@ std::string getHomePath(); int runShutdownCommand(); // shut down the system (returns 0 if successful) int runRestartCommand(); // restart the system (returns 0 if successful) -int runSystemCommand(const std::string& cmd_utf8); // run a utf-8 encoded in the shell (requires wstring conversion on Windows) \ No newline at end of file +int runSystemCommand(const std::string& cmd_utf8); // run a utf-8 encoded in the shell (requires wstring conversion on Windows) +int quitES(const std::string& filename); +void touch(const std::string& filename); From f0d3bae673ddf3e7946e88054e219fc591ff3a8d Mon Sep 17 00:00:00 2001 From: HerbFargus Date: Mon, 25 Jan 2016 19:28:59 -0700 Subject: [PATCH 12/74] Cosmetic nits --- es-app/src/SystemData.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/es-app/src/SystemData.cpp b/es-app/src/SystemData.cpp index 5e2b9b4c2e..60e5975b17 100644 --- a/es-app/src/SystemData.cpp +++ b/es-app/src/SystemData.cpp @@ -123,9 +123,7 @@ void SystemData::launchGame(Window* window, FileData* game) command = strreplace(command, "%ROM_RAW%", rom_raw); LOG(LogInfo) << " " << command; - std::cout << "==============================================\n"; int exitCode = runSystemCommand(command); - std::cout << "==============================================\n"; if(exitCode != 0) { From 9b78834b42a9ef98229d51e5385695d96d95677a Mon Sep 17 00:00:00 2001 From: Devenor Date: Wed, 25 Mar 2015 21:52:27 +0100 Subject: [PATCH 13/74] Added symlink support on removeCommonPath --- es-core/src/Util.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/es-core/src/Util.cpp b/es-core/src/Util.cpp index 198e10a820..8c7dc0c921 100644 --- a/es-core/src/Util.cpp +++ b/es-core/src/Util.cpp @@ -110,7 +110,8 @@ fs::path removeCommonPath(const fs::path& path, const fs::path& relativeTo, bool return path; } - fs::path p = fs::canonical(path); + // if it's a symlink we don't want to apply fs::canonical on it, otherwise we'll lose the current parent_path + fs::path p = (fs::is_symlink(path) ? fs::canonical(path.parent_path()) / path.filename() : fs::canonical(path)); fs::path r = fs::canonical(relativeTo); if(p.root_path() != r.root_path()) From 15fdbb2a8344c38e06a1754bfc05eaa3948fa065 Mon Sep 17 00:00:00 2001 From: Christian Uhsat Date: Sun, 27 Sep 2015 20:38:32 +0200 Subject: [PATCH 14/74] Hide mouse cursor early --- es-core/src/Renderer_init_sdlgl.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/es-core/src/Renderer_init_sdlgl.cpp b/es-core/src/Renderer_init_sdlgl.cpp index 00175f3fc8..ab0bfb56a4 100644 --- a/es-core/src/Renderer_init_sdlgl.cpp +++ b/es-core/src/Renderer_init_sdlgl.cpp @@ -36,6 +36,9 @@ namespace Renderer return false; } + //hide mouse cursor early + initialCursorState = SDL_ShowCursor(0) == 1; + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); @@ -108,9 +111,6 @@ namespace Renderer LOG(LogWarning) << "Tried to enable vsync, but failed! (" << SDL_GetError() << ")"; } - //hide mouse cursor - initialCursorState = SDL_ShowCursor(0) == 1; - return true; } From 26f4850eaf471155eeac5b74ae2d31909bcb634e Mon Sep 17 00:00:00 2001 From: Jools Wills Date: Sat, 26 Mar 2016 01:57:05 +0000 Subject: [PATCH 15/74] add configuration menu "other settings" and add "save metadata on exit" option, which users can use to speed up exit - fixes #35 --- es-app/src/SystemData.cpp | 2 +- es-app/src/guis/GuiMenu.cpp | 13 +++++++++++++ es-core/src/Settings.cpp | 1 + 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/es-app/src/SystemData.cpp b/es-app/src/SystemData.cpp index 29157cae54..51c779f5e2 100644 --- a/es-app/src/SystemData.cpp +++ b/es-app/src/SystemData.cpp @@ -55,7 +55,7 @@ SystemData::SystemData(const std::string& name, const std::string& fullName, con SystemData::~SystemData() { //save changed game data back to xml - if(!Settings::getInstance()->getBool("IgnoreGamelist")) + if(!Settings::getInstance()->getBool("IgnoreGamelist") && Settings::getInstance()->getBool("SaveGamelistsOnExit")) { updateGamelist(this); } diff --git a/es-app/src/guis/GuiMenu.cpp b/es-app/src/guis/GuiMenu.cpp index 8478d98eb0..95061e599f 100644 --- a/es-app/src/guis/GuiMenu.cpp +++ b/es-app/src/guis/GuiMenu.cpp @@ -165,6 +165,19 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MEN mWindow->pushGui(s); }); + addEntry("OTHER SETTINGS", 0x777777FF, true, + [this] { + auto s = new GuiSettings(mWindow, "OTHER SETTINGS"); + + // gamelists + auto save_gamelists = std::make_shared(mWindow); + save_gamelists->setState(Settings::getInstance()->getBool("SaveGamelistsOnExit")); + s->addWithLabel("SAVE METADATA ON EXIT", save_gamelists); + s->addSaveFunc([save_gamelists] { Settings::getInstance()->setBool("SaveGamelistsOnExit", save_gamelists->getState()); }); + + mWindow->pushGui(s); + }); + addEntry("CONFIGURE INPUT", 0x777777FF, true, [this] { mWindow->pushGui(new GuiDetectDevice(mWindow, false, nullptr)); diff --git a/es-core/src/Settings.cpp b/es-core/src/Settings.cpp index 779ee71420..859f07b9d8 100644 --- a/es-core/src/Settings.cpp +++ b/es-core/src/Settings.cpp @@ -59,6 +59,7 @@ void Settings::setDefaults() mBoolMap["IgnoreGamelist"] = false; mBoolMap["HideConsole"] = true; mBoolMap["QuickSystemSelect"] = true; + mBoolMap["SaveGamelistsOnExit"] = true; mBoolMap["Debug"] = false; mBoolMap["DebugGrid"] = false; From 267b43fa05f066ee894d08593e62b5d6e31d44d1 Mon Sep 17 00:00:00 2001 From: Jools Wills Date: Sat, 26 Mar 2016 03:31:13 +0000 Subject: [PATCH 16/74] move ParseGamelistOnly option to the gui so people can easily enable it for faster startup --- es-app/src/guis/GuiMenu.cpp | 5 +++++ es-core/src/Settings.cpp | 1 - 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/es-app/src/guis/GuiMenu.cpp b/es-app/src/guis/GuiMenu.cpp index 95061e599f..032706b939 100644 --- a/es-app/src/guis/GuiMenu.cpp +++ b/es-app/src/guis/GuiMenu.cpp @@ -175,6 +175,11 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MEN s->addWithLabel("SAVE METADATA ON EXIT", save_gamelists); s->addSaveFunc([save_gamelists] { Settings::getInstance()->setBool("SaveGamelistsOnExit", save_gamelists->getState()); }); + auto parse_gamelists = std::make_shared(mWindow); + parse_gamelists->setState(Settings::getInstance()->getBool("ParseGamelistOnly")); + s->addWithLabel("PARSE GAMESLISTS ONLY", parse_gamelists); + s->addSaveFunc([parse_gamelists] { Settings::getInstance()->setBool("ParseGamelistOnly", parse_gamelists->getState()); }); + mWindow->pushGui(s); }); diff --git a/es-core/src/Settings.cpp b/es-core/src/Settings.cpp index 859f07b9d8..67f12150df 100644 --- a/es-core/src/Settings.cpp +++ b/es-core/src/Settings.cpp @@ -13,7 +13,6 @@ std::vector settings_dont_save = boost::assign::list_of ("Debug") ("DebugGrid") ("DebugText") - ("ParseGamelistOnly") ("ShowExit") ("Windowed") ("VSync") From 1becb4150855e487e94e1e2e761ebb64dffb8f1c Mon Sep 17 00:00:00 2001 From: Jools Wills Date: Tue, 29 Mar 2016 05:03:39 +0100 Subject: [PATCH 17/74] Revert "Add direct launch option for systems that don't need a game list" --- es-app/src/SystemData.cpp | 77 +++++-------------- es-app/src/SystemData.h | 4 +- es-app/src/views/SystemView.cpp | 11 +-- es-app/src/views/ViewController.cpp | 20 +---- .../src/views/gamelist/BasicGameListView.cpp | 6 -- 5 files changed, 25 insertions(+), 93 deletions(-) diff --git a/es-app/src/SystemData.cpp b/es-app/src/SystemData.cpp index 51c779f5e2..95345ed636 100644 --- a/es-app/src/SystemData.cpp +++ b/es-app/src/SystemData.cpp @@ -18,7 +18,7 @@ std::vector SystemData::sSystemVector; namespace fs = boost::filesystem; SystemData::SystemData(const std::string& name, const std::string& fullName, const std::string& startPath, const std::vector& extensions, - const std::string& command, const std::vector& platformIds, const std::string& themeFolder, bool directLaunch) + const std::string& command, const std::vector& platformIds, const std::string& themeFolder) { mName = name; mFullName = fullName; @@ -36,8 +36,6 @@ SystemData::SystemData(const std::string& name, const std::string& fullName, con mPlatformIds = platformIds; mThemeFolder = themeFolder; - mDirectLaunch = directLaunch; - mRootFolder = new FileData(FOLDER, mStartPath, this); mRootFolder->metadata.set("name", mFullName); @@ -108,12 +106,7 @@ std::string escapePath(const boost::filesystem::path& path) void SystemData::launchGame(Window* window, FileData* game) { - if ( game ) - { - LOG(LogInfo) << "Attempting to launch game..."; - }else{ - LOG(LogInfo) << "Attempting to launch command..."; - } + LOG(LogInfo) << "Attempting to launch game..."; AudioManager::getInstance()->deinit(); VolumeControl::getInstance()->deinit(); @@ -121,16 +114,13 @@ void SystemData::launchGame(Window* window, FileData* game) std::string command = mLaunchCommand; - if ( game ) - { - const std::string rom = escapePath(game->getPath()); - const std::string basename = game->getPath().stem().string(); - const std::string rom_raw = fs::path(game->getPath()).make_preferred().string(); + const std::string rom = escapePath(game->getPath()); + const std::string basename = game->getPath().stem().string(); + const std::string rom_raw = fs::path(game->getPath()).make_preferred().string(); - command = strreplace(command, "%ROM%", rom); - command = strreplace(command, "%BASENAME%", basename); - command = strreplace(command, "%ROM_RAW%", rom_raw); - } + command = strreplace(command, "%ROM%", rom); + command = strreplace(command, "%BASENAME%", basename); + command = strreplace(command, "%ROM_RAW%", rom_raw); LOG(LogInfo) << " " << command; int exitCode = runSystemCommand(command); @@ -145,26 +135,17 @@ void SystemData::launchGame(Window* window, FileData* game) AudioManager::getInstance()->init(); window->normalizeNextUpdate(); - if ( game ) - { - //update number of times the game has been launched - int timesPlayed = game->metadata.getInt("playcount") + 1; - game->metadata.set("playcount", std::to_string(static_cast(timesPlayed))); + //update number of times the game has been launched + int timesPlayed = game->metadata.getInt("playcount") + 1; + game->metadata.set("playcount", std::to_string(static_cast(timesPlayed))); - //update last played time - boost::posix_time::ptime time = boost::posix_time::second_clock::universal_time(); - game->metadata.setTime("lastplayed", time); - } + //update last played time + boost::posix_time::ptime time = boost::posix_time::second_clock::universal_time(); + game->metadata.setTime("lastplayed", time); } void SystemData::populateFolder(FileData* folder) { - if (mDirectLaunch) - { - LOG(LogInfo) << "System " << mName << " is a direct launch item, not building game lists."; - return; - } - const fs::path& folderPath = folder->getPath(); if(!fs::is_directory(folderPath)) { @@ -280,13 +261,11 @@ bool SystemData::loadConfig() for(pugi::xml_node system = systemList.child("system"); system; system = system.next_sibling("system")) { std::string name, fullname, path, cmd, themeFolder; - bool directLaunch; PlatformIds::PlatformId platformId = PlatformIds::PLATFORM_UNKNOWN; name = system.child("name").text().get(); fullname = system.child("fullname").text().get(); path = system.child("path").text().get(); - directLaunch = ( strcmp( system.child("directlaunch").text().get(), "true" ) == 0); // convert extensions list from a string into a vector of strings std::vector extensions = readList(system.child("extension").text().get()); @@ -320,29 +299,19 @@ bool SystemData::loadConfig() // theme folder themeFolder = system.child("theme").text().as_string(name.c_str()); - //validate game system - if( (name.empty() || path.empty() || extensions.empty() || cmd.empty() ) && directLaunch == false ) + //validate + if(name.empty() || path.empty() || extensions.empty() || cmd.empty()) { LOG(LogError) << "System \"" << name << "\" is missing name, path, extension, or command!"; continue; } - - //validate direct launch item - if( (name.empty() || cmd.empty() ) && directLaunch == true ) - { - LOG(LogError) << "Direct Launch item \"" << name << "\" is missing name or command!"; - continue; - } - if (!directLaunch) - { - //convert path to generic directory seperators - boost::filesystem::path genericPath(path); - path = genericPath.generic_string(); - } + //convert path to generic directory seperators + boost::filesystem::path genericPath(path); + path = genericPath.generic_string(); - SystemData* newSys = new SystemData(name, fullname, path, extensions, cmd, platformIds, themeFolder, directLaunch); - if(newSys->getRootFolder()->getChildren().size() == 0 && !directLaunch) + SystemData* newSys = new SystemData(name, fullname, path, extensions, cmd, platformIds, themeFolder); + if(newSys->getRootFolder()->getChildren().size() == 0) { LOG(LogWarning) << "System \"" << name << "\" has no games! Ignoring it."; delete newSys; @@ -392,10 +361,6 @@ void SystemData::writeExampleConfig(const std::string& path) " \n" " nes\n" - "\n" - " \n" - " false\n" " \n" "\n"; diff --git a/es-app/src/SystemData.h b/es-app/src/SystemData.h index 6629d9f7ee..2a0ac81886 100644 --- a/es-app/src/SystemData.h +++ b/es-app/src/SystemData.h @@ -12,7 +12,7 @@ class SystemData { public: SystemData(const std::string& name, const std::string& fullName, const std::string& startPath, const std::vector& extensions, - const std::string& command, const std::vector& platformIds, const std::string& themeFolder, bool directLaunch=false); + const std::string& command, const std::vector& platformIds, const std::string& themeFolder); ~SystemData(); inline FileData* getRootFolder() const { return mRootFolder; }; @@ -21,7 +21,6 @@ class SystemData inline const std::string& getStartPath() const { return mStartPath; } inline const std::vector& getExtensions() const { return mSearchExtensions; } inline const std::string& getThemeFolder() const { return mThemeFolder; } - inline const bool getDirectLaunch() const { return mDirectLaunch; } inline const std::vector& getPlatformIds() const { return mPlatformIds; } inline bool hasPlatformId(PlatformIds::PlatformId id) { return std::find(mPlatformIds.begin(), mPlatformIds.end(), id) != mPlatformIds.end(); } @@ -74,7 +73,6 @@ class SystemData std::vector mPlatformIds; std::string mThemeFolder; std::shared_ptr mTheme; - bool mDirectLaunch; void populateFolder(FileData* folder); diff --git a/es-app/src/views/SystemView.cpp b/es-app/src/views/SystemView.cpp index 9810cd316d..54987fdf87 100644 --- a/es-app/src/views/SystemView.cpp +++ b/es-app/src/views/SystemView.cpp @@ -119,16 +119,7 @@ bool SystemView::input(InputConfig* config, Input input) if(config->isMappedTo("a", input)) { stopScrolling(); - - SystemData *systemData = getSelected(); - - // decide whether to show game list or launch the command directly - if ( !systemData->getDirectLaunch() ) - { - ViewController::get()->goToGameList(getSelected()); - }else{ - systemData->launchGame( mWindow, nullptr ); - } + ViewController::get()->goToGameList(getSelected()); return true; } }else{ diff --git a/es-app/src/views/ViewController.cpp b/es-app/src/views/ViewController.cpp index 9716cfd8bf..5a94d97c2b 100644 --- a/es-app/src/views/ViewController.cpp +++ b/es-app/src/views/ViewController.cpp @@ -72,15 +72,7 @@ void ViewController::goToNextGameList() assert(mState.viewing == GAME_LIST); SystemData* system = getState().getSystem(); assert(system); - - // skip systems that don't have a game list, this will always end since it is called - // from a system with a game list and the iterator is cyclic - do - { - system = system->getNext(); - } while ( system->getDirectLaunch() ); - - goToGameList(system); + goToGameList(system->getNext()); } void ViewController::goToPrevGameList() @@ -88,15 +80,7 @@ void ViewController::goToPrevGameList() assert(mState.viewing == GAME_LIST); SystemData* system = getState().getSystem(); assert(system); - - // skip systems that don't have a game list, this will always end since it is called - // from a system with a game list and the iterator is cyclic - do - { - system = system->getPrev(); - } while ( system->getDirectLaunch() ); - - goToGameList(system); + goToGameList(system->getPrev()); } void ViewController::goToGameList(SystemData* system) diff --git a/es-app/src/views/gamelist/BasicGameListView.cpp b/es-app/src/views/gamelist/BasicGameListView.cpp index 5438c889fc..d3cbc017a1 100644 --- a/es-app/src/views/gamelist/BasicGameListView.cpp +++ b/es-app/src/views/gamelist/BasicGameListView.cpp @@ -38,12 +38,6 @@ void BasicGameListView::onFileChanged(FileData* file, FileChangeType change) void BasicGameListView::populateList(const std::vector& files) { mList.clear(); - - // file list can be empty if direct launch item - if (files.size()==0) - { - return; - } mHeaderText.setText(files.at(0)->getSystem()->getFullName()); From 53f69bf61b2a2287d36d2c3c5cd26838c2ae9c5c Mon Sep 17 00:00:00 2001 From: Jools Wills Date: Tue, 29 Mar 2016 16:33:19 +0100 Subject: [PATCH 18/74] add a getDisplayName function, which is used for rom display, and make getCleanName again strip paratheses, which is used in the scraper backends. --- es-app/src/FileData.cpp | 9 +++++++-- es-app/src/FileData.h | 5 ++++- es-app/src/Gamelist.cpp | 2 +- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/es-app/src/FileData.cpp b/es-app/src/FileData.cpp index d4279105bd..f9f28185b8 100644 --- a/es-app/src/FileData.cpp +++ b/es-app/src/FileData.cpp @@ -48,7 +48,7 @@ FileData::FileData(FileType type, const fs::path& path, SystemData* system) { // metadata needs at least a name field (since that's what getName() will return) if(metadata.get("name").empty()) - metadata.set("name", getCleanName()); + metadata.set("name", getDisplayName()); } FileData::~FileData() @@ -60,7 +60,7 @@ FileData::~FileData() delete mChildren.back(); } -std::string FileData::getCleanName() const +std::string FileData::getDisplayName() const { std::string stem = mPath.stem().generic_string(); if(mSystem && mSystem->hasPlatformId(PlatformIds::ARCADE) || mSystem->hasPlatformId(PlatformIds::NEOGEO)) @@ -69,6 +69,11 @@ std::string FileData::getCleanName() const return stem; } +std::string FileData::getCleanName() const +{ + return removeParenthesis(this->getDisplayName()); +} + const std::string& FileData::getThumbnailPath() const { if(!metadata.get("thumbnail").empty()) diff --git a/es-app/src/FileData.h b/es-app/src/FileData.h index add6345f4c..99fba06710 100644 --- a/es-app/src/FileData.h +++ b/es-app/src/FileData.h @@ -49,7 +49,10 @@ class FileData void addChild(FileData* file); // Error if mType != FOLDER void removeChild(FileData* file); //Error if mType != FOLDER - // Returns our best guess at the "real" name for this file (will strip parenthesis and attempt to perform MAME name translation) + // Returns our best guess at the "real" name for this file (will attempt to perform MAME name translation) + std::string getDisplayName() const; + + // As above, but also remove parenthesis std::string getCleanName() const; typedef bool ComparisonFunction(const FileData* a, const FileData* b); diff --git a/es-app/src/Gamelist.cpp b/es-app/src/Gamelist.cpp index 8c647fc4d0..9caeda354e 100644 --- a/es-app/src/Gamelist.cpp +++ b/es-app/src/Gamelist.cpp @@ -148,7 +148,7 @@ void addFileDataNode(pugi::xml_node& parent, const FileData* file, const char* t if(newNode.children().begin() == newNode.child("name") //first element is name && ++newNode.children().begin() == newNode.children().end() //theres only one element - && newNode.child("name").text().get() == file->getCleanName()) //the name is the default + && newNode.child("name").text().get() == file->getDisplayName()) //the name is the default { //if the only info is the default name, don't bother with this node //delete it and ultimately do nothing From dbc2ab6110c4c1f6cc4a8faaf668a35ac6da8975 Mon Sep 17 00:00:00 2001 From: "D. Polders" Date: Sun, 17 Apr 2016 22:03:11 +0200 Subject: [PATCH 19/74] SVG update Updated the svg library from https://github.com/memononen/nanosvg --- external/nanosvg/nanosvg.h | 1151 ++++++++++++++++++++------------ external/nanosvg/nanosvgrast.h | 998 ++++++++++++++++++++++----- 2 files changed, 1549 insertions(+), 600 deletions(-) diff --git a/external/nanosvg/nanosvg.h b/external/nanosvg/nanosvg.h index ad2ee52601..a6c60155ea 100644 --- a/external/nanosvg/nanosvg.h +++ b/external/nanosvg/nanosvg.h @@ -1,14 +1,14 @@ /* * Copyright (c) 2013-14 Mikko Mononen memon@inside.org - * + * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. - * + * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: - * + * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be @@ -17,7 +17,7 @@ * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. * - * The SVG parser is based on Anti-Graim Geometry 2.4 SVG example + * The SVG parser is based on Anti-Grain Geometry 2.4 SVG example * Copyright (C) 2002-2004 Maxim Shemanarev (McSeem) (http://www.antigrain.com/) * * Arc calculation code based on canvg (https://code.google.com/p/canvg/) @@ -43,7 +43,7 @@ extern "C" { // That is, you should get the same looking data as your designed in your favorite app. // // NanoSVG can return the paths in few different units. For example if you want to render an image, you may choose -// to get the paths in pixels, or if you are feeding the data into a CNC-cutter, you may want to use millimeters. +// to get the paths in pixels, or if you are feeding the data into a CNC-cutter, you may want to use millimeters. // // The units passed to NanoVG should be one of: 'px', 'pt', 'pc' 'mm', 'cm', or 'in'. // DPI (dots-per-inch) controls how the unit conversion is done. @@ -53,13 +53,13 @@ extern "C" { /* Example Usage: // Load - struct SNVGImage* image; + NSVGImage* image; image = nsvgParseFromFile("test.svg", "px", 96); printf("size: %f x %f\n", image->width, image->height); // Use... - for (shape = image->shapes; shape != NULL; shape = shape->next) { - for (path = shape->paths; path != NULL; path = path->next) { - for (i = 0; i < path->npts-1; i += 3) { + for (NSVGshape *shape = image->shapes; shape != NULL; shape = shape->next) { + for (NSVGpath *path = shape->paths; path != NULL; path = path->next) { + for (int i = 0; i < path->npts-1; i += 3) { float* p = &path->pts[i*2]; drawCubicBez(p[0],p[1], p[2],p[3], p[4],p[5], p[6],p[7]); } @@ -69,71 +69,105 @@ extern "C" { nsvgDelete(image); */ -#define NSVG_PAINT_NONE 0 -#define NSVG_PAINT_COLOR 1 -#define NSVG_PAINT_LINEAR_GRADIENT 2 -#define NSVG_PAINT_RADIAL_GRADIENT 3 +enum NSVGpaintType { + NSVG_PAINT_NONE = 0, + NSVG_PAINT_COLOR = 1, + NSVG_PAINT_LINEAR_GRADIENT = 2, + NSVG_PAINT_RADIAL_GRADIENT = 3, +}; + +enum NSVGspreadType { + NSVG_SPREAD_PAD = 0, + NSVG_SPREAD_REFLECT = 1, + NSVG_SPREAD_REPEAT = 2, +}; + +enum NSVGlineJoin { + NSVG_JOIN_MITER = 0, + NSVG_JOIN_ROUND = 1, + NSVG_JOIN_BEVEL = 2, +}; + +enum NSVGlineCap { + NSVG_CAP_BUTT = 0, + NSVG_CAP_ROUND = 1, + NSVG_CAP_SQUARE = 2, +}; + +enum NSVGfillRule { + NSVG_FILLRULE_NONZERO = 0, + NSVG_FILLRULE_EVENODD = 1, +}; -#define NSVG_SPREAD_PAD 0 -#define NSVG_SPREAD_REFLECT 1 -#define NSVG_SPREAD_REPEAT 2 +enum NSVGflags { + NSVG_FLAGS_VISIBLE = 0x01 +}; -struct NSVGgradientStop { +typedef struct NSVGgradientStop { unsigned int color; float offset; -}; +} NSVGgradientStop; -struct NSVGgradient { +typedef struct NSVGgradient { float xform[6]; char spread; float fx, fy; int nstops; - struct NSVGgradientStop stops[1]; -}; + NSVGgradientStop stops[1]; +} NSVGgradient; -struct NSVGpaint { +typedef struct NSVGpaint { char type; union { unsigned int color; - struct NSVGgradient* gradient; + NSVGgradient* gradient; }; -}; +} NSVGpaint; -struct NSVGpath +typedef struct NSVGpath { float* pts; // Cubic bezier points: x0,y0, [cpx1,cpx1,cpx2,cpy2,x1,y1], ... int npts; // Total number of bezier points. char closed; // Flag indicating if shapes should be treated as closed. float bounds[4]; // Tight bounding box of the shape [minx,miny,maxx,maxy]. struct NSVGpath* next; // Pointer to next path, or NULL if last element. -}; +} NSVGpath; -struct NSVGshape +typedef struct NSVGshape { - struct NSVGpaint fill; // Fill paint - struct NSVGpaint stroke; // Stroke paint + char id[64]; // Optional 'id' attr of the shape or its group + NSVGpaint fill; // Fill paint + NSVGpaint stroke; // Stroke paint float opacity; // Opacity of the shape. - float strokeWidth; // Stroke width (scaled) + float strokeWidth; // Stroke width (scaled). + float strokeDashOffset; // Stroke dash offset (scaled). + float strokeDashArray[8]; // Stroke dash array (scaled). + char strokeDashCount; // Number of dash values in dash array. + char strokeLineJoin; // Stroke join type. + char strokeLineCap; // Stroke cap type. + char fillRule; // Fill rule, see NSVGfillRule. + unsigned char flags; // Logical or of NSVG_FLAGS_* flags float bounds[4]; // Tight bounding box of the shape [minx,miny,maxx,maxy]. - struct NSVGpath* paths; // Linked list of paths in the image. + NSVGpath* paths; // Linked list of paths in the image. struct NSVGshape* next; // Pointer to next shape, or NULL if last element. -}; +} NSVGshape; -struct NSVGimage +typedef struct NSVGimage { float width; // Width of the image. float height; // Height of the image. - struct NSVGshape* shapes; // Linked list of shapes in the image. -}; + NSVGshape* shapes; // Linked list of shapes in the image. +} NSVGimage; // Parses SVG file from a file, returns SVG image as paths. -struct NSVGimage* nsvgParseFromFile(const char* filename, const char* units, float dpi); +NSVGimage* nsvgParseFromFile(const char* filename, const char* units, float dpi); // Parses SVG file from a null terminated string, returns SVG image as paths. -struct NSVGimage* nsvgParse(char* input, const char* units, float dpi); +// Important note: changes the string. +NSVGimage* nsvgParse(char* input, const char* units, float dpi); // Deletes list of paths. -void nsvgDelete(struct NSVGimage* image); +void nsvgDelete(NSVGimage* image); #ifdef __cplusplus }; @@ -157,6 +191,7 @@ void nsvgDelete(struct NSVGimage* image); #define NSVG_ALIGN_MEET 1 #define NSVG_ALIGN_SLICE 2 +#define NSVG_NOTUSED(v) do { (void)(1 ? (void)0 : ( (void)(v) ) ); } while(0) #define NSVG_RGB(r, g, b) (((unsigned int)r) | ((unsigned int)g << 8) | ((unsigned int)b << 16)) #ifdef _MSC_VER @@ -204,7 +239,7 @@ static void nsvg__parseContent(char* s, // Trim start white spaces while (*s && nsvg__isspace(*s)) s++; if (!*s) return; - + if (contentCb) (*contentCb)(ud, s); } @@ -219,7 +254,8 @@ static void nsvg__parseElement(char* s, char* name; int start = 0; int end = 0; - + char quote; + // Skip white space after the '<' while (*s && nsvg__isspace(*s)) s++; @@ -254,15 +290,16 @@ static void nsvg__parseElement(char* s, while (*s && !nsvg__isspace(*s) && *s != '=') s++; if (*s) { *s++ = '\0'; } // Skip until the beginning of the value. - while (*s && *s != '\"') s++; + while (*s && *s != '\"' && *s != '\'') s++; if (!*s) break; + quote = *s; s++; // Store value and find the end of it. attr[nattr++] = s; - while (*s && *s != '\"') s++; + while (*s && *s != quote) s++; if (*s) { *s++ = '\0'; } } - + // List terminator attr[nattr++] = 0; attr[nattr++] = 0; @@ -300,7 +337,7 @@ int nsvg__parseXML(char* input, s++; } } - + return 1; } @@ -309,32 +346,59 @@ int nsvg__parseXML(char* input, #define NSVG_MAX_ATTR 128 -#define NSVG_USER_SPACE 0 -#define NSVG_OBJECT_SPACE 1 +enum NSVGgradientUnits { + NSVG_USER_SPACE = 0, + NSVG_OBJECT_SPACE = 1, +}; + +#define NSVG_MAX_DASHES 8 + +enum NSVGunits { + NSVG_UNITS_USER, + NSVG_UNITS_PX, + NSVG_UNITS_PT, + NSVG_UNITS_PC, + NSVG_UNITS_MM, + NSVG_UNITS_CM, + NSVG_UNITS_IN, + NSVG_UNITS_PERCENT, + NSVG_UNITS_EM, + NSVG_UNITS_EX, +}; + +typedef struct NSVGcoordinate { + float value; + int units; +} NSVGcoordinate; -struct NSVGgradientData +typedef struct NSVGlinearData { + NSVGcoordinate x1, y1, x2, y2; +} NSVGlinearData; + +typedef struct NSVGradialData { + NSVGcoordinate cx, cy, r, fx, fy; +} NSVGradialData; + +typedef struct NSVGgradientData { char id[64]; char ref[64]; char type; union { - struct { - float x1, y1, x2, y2; - } linear; - struct { - float cx, cy, r, fx, fy; - } radial; + NSVGlinearData linear; + NSVGradialData radial; }; char spread; char units; float xform[6]; int nstops; - struct NSVGgradientStop* stops; + NSVGgradientStop* stops; struct NSVGgradientData* next; -}; +} NSVGgradientData; -struct NSVGattrib +typedef struct NSVGattrib { + char id[64]; float xform[6]; unsigned int fillColor; unsigned int strokeColor; @@ -344,6 +408,12 @@ struct NSVGattrib char fillGradient[64]; char strokeGradient[64]; float strokeWidth; + float strokeDashOffset; + float strokeDashArray[NSVG_MAX_DASHES]; + int strokeDashCount; + char strokeLineJoin; + char strokeLineCap; + char fillRule; float fontSize; unsigned int stopColor; float stopOpacity; @@ -351,24 +421,24 @@ struct NSVGattrib char hasFill; char hasStroke; char visible; -}; +} NSVGattrib; -struct NSVGparser +typedef struct NSVGparser { - struct NSVGattrib attr[NSVG_MAX_ATTR]; + NSVGattrib attr[NSVG_MAX_ATTR]; int attrHead; float* pts; int npts; int cpts; - struct NSVGpath* plist; - struct NSVGimage* image; - struct NSVGgradientData* gradients; + NSVGpath* plist; + NSVGimage* image; + NSVGgradientData* gradients; float viewMinx, viewMiny, viewWidth, viewHeight; int alignX, alignY, alignType; float dpi; char pathFlag; - char defsFlag; -}; + char defsFlag; +} NSVGparser; static void nsvg__xformIdentity(float* t) { @@ -428,12 +498,12 @@ static void nsvg__xformMultiply(float* t, float* s) static void nsvg__xformInverse(float* inv, float* t) { - double det = (double)t[0] * t[3] - (double)t[2] * t[1]; - if (det > -1e-6 && det < -1e-6) { + double invdet, det = (double)t[0] * t[3] - (double)t[2] * t[1]; + if (det > -1e-6 && det < 1e-6) { nsvg__xformIdentity(t); return; } - double invdet = 1.0 / det; + invdet = 1.0 / det; inv[0] = (float)(t[3] * invdet); inv[2] = (float)(-t[2] * invdet); inv[4] = (float)(((double)t[2] * t[5] - (double)t[3] * t[4]) * invdet); @@ -472,7 +542,7 @@ static int nsvg__ptInBounds(float* pt, float* bounds) static double nsvg__evalBezier(double t, double p0, double p1, double p2, double p3) { - float it = 1.0-t; + double it = 1.0-t; return it*it*it*p0 + 3.0*it*it*t*p1 + 3.0*it*t*t*p2 + t*t*t*p3; } @@ -527,19 +597,20 @@ static void nsvg__curveBounds(float* bounds, float* curve) } } -static struct NSVGparser* nsvg__createParser() +static NSVGparser* nsvg__createParser() { - struct NSVGparser* p; - p = (struct NSVGparser*)malloc(sizeof(struct NSVGparser)); + NSVGparser* p; + p = (NSVGparser*)malloc(sizeof(NSVGparser)); if (p == NULL) goto error; - memset(p, 0, sizeof(struct NSVGparser)); + memset(p, 0, sizeof(NSVGparser)); - p->image = (struct NSVGimage*)malloc(sizeof(struct NSVGimage)); + p->image = (NSVGimage*)malloc(sizeof(NSVGimage)); if (p->image == NULL) goto error; - memset(p->image, 0, sizeof(struct NSVGimage)); + memset(p->image, 0, sizeof(NSVGimage)); // Init style nsvg__xformIdentity(p->attr[0].xform); + memset(p->attr[0].id, 0, sizeof p->attr[0].id); p->attr[0].fillColor = NSVG_RGB(0,0,0); p->attr[0].strokeColor = NSVG_RGB(0,0,0); p->attr[0].opacity = 1; @@ -547,8 +618,10 @@ static struct NSVGparser* nsvg__createParser() p->attr[0].strokeOpacity = 1; p->attr[0].stopOpacity = 1; p->attr[0].strokeWidth = 1; + p->attr[0].strokeLineJoin = NSVG_JOIN_MITER; + p->attr[0].strokeLineCap = NSVG_CAP_BUTT; + p->attr[0].fillRule = NSVG_FILLRULE_NONZERO; p->attr[0].hasFill = 1; - p->attr[0].hasStroke = 0; p->attr[0].visible = 1; return p; @@ -561,10 +634,10 @@ static struct NSVGparser* nsvg__createParser() return NULL; } -static void nsvg__deletePaths(struct NSVGpath* path) +static void nsvg__deletePaths(NSVGpath* path) { while (path) { - struct NSVGpath *next = path->next; + NSVGpath *next = path->next; if (path->pts != NULL) free(path->pts); free(path); @@ -572,15 +645,15 @@ static void nsvg__deletePaths(struct NSVGpath* path) } } -static void nsvg__deletePaint(struct NSVGpaint* paint) +static void nsvg__deletePaint(NSVGpaint* paint) { - if (paint->type == NSVG_PAINT_LINEAR_GRADIENT || paint->type == NSVG_PAINT_LINEAR_GRADIENT) + if (paint->type == NSVG_PAINT_LINEAR_GRADIENT || paint->type == NSVG_PAINT_RADIAL_GRADIENT) free(paint->gradient); } -static void nsvg__deleteGradientData(struct NSVGgradientData* grad) +static void nsvg__deleteGradientData(NSVGgradientData* grad) { - struct NSVGgradientData* next; + NSVGgradientData* next; while (grad != NULL) { next = grad->next; free(grad->stops); @@ -589,7 +662,7 @@ static void nsvg__deleteGradientData(struct NSVGgradientData* grad) } } -static void nsvg__deleteParser(struct NSVGparser* p) +static void nsvg__deleteParser(NSVGparser* p) { if (p != NULL) { nsvg__deletePaths(p->plist); @@ -600,12 +673,12 @@ static void nsvg__deleteParser(struct NSVGparser* p) } } -static void nsvg__resetPath(struct NSVGparser* p) +static void nsvg__resetPath(NSVGparser* p) { p->npts = 0; } -static void nsvg__addPoint(struct NSVGparser* p, float x, float y) +static void nsvg__addPoint(NSVGparser* p, float x, float y) { if (p->npts+1 > p->cpts) { p->cpts = p->cpts ? p->cpts*2 : 8; @@ -617,12 +690,17 @@ static void nsvg__addPoint(struct NSVGparser* p, float x, float y) p->npts++; } -static void nsvg__moveTo(struct NSVGparser* p, float x, float y) +static void nsvg__moveTo(NSVGparser* p, float x, float y) { - nsvg__addPoint(p, x, y); + if (p->npts > 0) { + p->pts[(p->npts-1)*2+0] = x; + p->pts[(p->npts-1)*2+1] = y; + } else { + nsvg__addPoint(p, x, y); + } } -static void nsvg__lineTo(struct NSVGparser* p, float x, float y) +static void nsvg__lineTo(NSVGparser* p, float x, float y) { float px,py, dx,dy; if (p->npts > 0) { @@ -636,35 +714,80 @@ static void nsvg__lineTo(struct NSVGparser* p, float x, float y) } } -static void nsvg__cubicBezTo(struct NSVGparser* p, float cpx1, float cpy1, float cpx2, float cpy2, float x, float y) +static void nsvg__cubicBezTo(NSVGparser* p, float cpx1, float cpy1, float cpx2, float cpy2, float x, float y) { nsvg__addPoint(p, cpx1, cpy1); nsvg__addPoint(p, cpx2, cpy2); nsvg__addPoint(p, x, y); } -static struct NSVGattrib* nsvg__getAttr(struct NSVGparser* p) +static NSVGattrib* nsvg__getAttr(NSVGparser* p) { return &p->attr[p->attrHead]; } -static void nsvg__pushAttr(struct NSVGparser* p) +static void nsvg__pushAttr(NSVGparser* p) { if (p->attrHead < NSVG_MAX_ATTR-1) { p->attrHead++; - memcpy(&p->attr[p->attrHead], &p->attr[p->attrHead-1], sizeof(struct NSVGattrib)); + memcpy(&p->attr[p->attrHead], &p->attr[p->attrHead-1], sizeof(NSVGattrib)); } } -static void nsvg__popAttr(struct NSVGparser* p) +static void nsvg__popAttr(NSVGparser* p) { if (p->attrHead > 0) p->attrHead--; } -static struct NSVGgradientData* nsvg__findGradientData(struct NSVGparser* p, const char* id) +static float nsvg__actualOrigX(NSVGparser* p) +{ + return p->viewMinx; +} + +static float nsvg__actualOrigY(NSVGparser* p) +{ + return p->viewMiny; +} + +static float nsvg__actualWidth(NSVGparser* p) +{ + return p->viewWidth; +} + +static float nsvg__actualHeight(NSVGparser* p) +{ + return p->viewHeight; +} + +static float nsvg__actualLength(NSVGparser* p) +{ + float w = nsvg__actualWidth(p), h = nsvg__actualHeight(p); + return sqrtf(w*w + h*h) / sqrtf(2.0f); +} + +static float nsvg__convertToPixels(NSVGparser* p, NSVGcoordinate c, float orig, float length) +{ + NSVGattrib* attr = nsvg__getAttr(p); + switch (c.units) { + case NSVG_UNITS_USER: return c.value; + case NSVG_UNITS_PX: return c.value; + case NSVG_UNITS_PT: return c.value / 72.0f * p->dpi; + case NSVG_UNITS_PC: return c.value / 6.0f * p->dpi; + case NSVG_UNITS_MM: return c.value / 25.4f * p->dpi; + case NSVG_UNITS_CM: return c.value / 2.54f * p->dpi; + case NSVG_UNITS_IN: return c.value * p->dpi; + case NSVG_UNITS_EM: return c.value * attr->fontSize; + case NSVG_UNITS_EX: return c.value * attr->fontSize * 0.52f; // x-height of Helvetica. + case NSVG_UNITS_PERCENT: return orig + c.value / 100.0f * length; + default: return c.value; + } + return c.value; +} + +static NSVGgradientData* nsvg__findGradientData(NSVGparser* p, const char* id) { - struct NSVGgradientData* grad = p->gradients; + NSVGgradientData* grad = p->gradients; while (grad) { if (strcmp(grad->id, id) == 0) return grad; @@ -673,14 +796,14 @@ static struct NSVGgradientData* nsvg__findGradientData(struct NSVGparser* p, con return NULL; } -static struct NSVGgradient* nsvg__createGradient(struct NSVGparser* p, const char* id, const float* bounds, char* paintType) +static NSVGgradient* nsvg__createGradient(NSVGparser* p, const char* id, const float* localBounds, char* paintType) { - struct NSVGattrib* attr = nsvg__getAttr(p); - struct NSVGgradientData* data = NULL; - struct NSVGgradientData* ref = NULL; - struct NSVGgradientStop* stops = NULL; - struct NSVGgradient* grad; - float dx, dy, d; + NSVGattrib* attr = nsvg__getAttr(p); + NSVGgradientData* data = NULL; + NSVGgradientData* ref = NULL; + NSVGgradientStop* stops = NULL; + NSVGgradient* grad; + float ox, oy, sw, sh, sl; int nstops = 0; data = nsvg__findGradientData(p, id); @@ -689,7 +812,7 @@ static struct NSVGgradient* nsvg__createGradient(struct NSVGparser* p, const cha // TODO: use ref to fill in all unset values too. ref = data; while (ref != NULL) { - if (ref->stops != NULL) { + if (stops == NULL && ref->stops != NULL) { stops = ref->stops; nstops = ref->nstops; break; @@ -698,33 +821,55 @@ static struct NSVGgradient* nsvg__createGradient(struct NSVGparser* p, const cha } if (stops == NULL) return NULL; - grad = (struct NSVGgradient*)malloc(sizeof(struct NSVGgradient) + sizeof(struct NSVGgradientStop)*(nstops-1)); + grad = (NSVGgradient*)malloc(sizeof(NSVGgradient) + sizeof(NSVGgradientStop)*(nstops-1)); if (grad == NULL) return NULL; - // TODO: handle data->units == NSVG_OBJECT_SPACE. + // The shape width and height. + if (data->units == NSVG_OBJECT_SPACE) { + ox = localBounds[0]; + oy = localBounds[1]; + sw = localBounds[2] - localBounds[0]; + sh = localBounds[3] - localBounds[1]; + } else { + ox = nsvg__actualOrigX(p); + oy = nsvg__actualOrigY(p); + sw = nsvg__actualWidth(p); + sh = nsvg__actualHeight(p); + } + sl = sqrtf(sw*sw + sh*sh) / sqrtf(2.0f); if (data->type == NSVG_PAINT_LINEAR_GRADIENT) { + float x1, y1, x2, y2, dx, dy; + x1 = nsvg__convertToPixels(p, data->linear.x1, ox, sw); + y1 = nsvg__convertToPixels(p, data->linear.y1, oy, sh); + x2 = nsvg__convertToPixels(p, data->linear.x2, ox, sw); + y2 = nsvg__convertToPixels(p, data->linear.y2, oy, sh); // Calculate transform aligned to the line - dx = data->linear.x2 - data->linear.x1; - dy = data->linear.y2 - data->linear.y1; - d = sqrtf(dx*dx + dy*dy); + dx = x2 - x1; + dy = y2 - y1; grad->xform[0] = dy; grad->xform[1] = -dx; grad->xform[2] = dx; grad->xform[3] = dy; - grad->xform[4] = data->linear.x1; grad->xform[5] = data->linear.y1; + grad->xform[4] = x1; grad->xform[5] = y1; } else { + float cx, cy, fx, fy, r; + cx = nsvg__convertToPixels(p, data->radial.cx, ox, sw); + cy = nsvg__convertToPixels(p, data->radial.cy, oy, sh); + fx = nsvg__convertToPixels(p, data->radial.fx, ox, sw); + fy = nsvg__convertToPixels(p, data->radial.fy, oy, sh); + r = nsvg__convertToPixels(p, data->radial.r, 0, sl); // Calculate transform aligned to the circle - grad->xform[0] = data->radial.r; grad->xform[1] = 0; - grad->xform[2] = 0; grad->xform[3] = data->radial.r; - grad->xform[4] = data->radial.cx; grad->xform[5] = data->radial.cy; - grad->fx = data->radial.fx / data->radial.r; - grad->fy = data->radial.fy / data->radial.r; + grad->xform[0] = r; grad->xform[1] = 0; + grad->xform[2] = 0; grad->xform[3] = r; + grad->xform[4] = cx; grad->xform[5] = cy; + grad->fx = fx / r; + grad->fy = fy / r; } - nsvg__xformMultiply(grad->xform, attr->xform); nsvg__xformMultiply(grad->xform, data->xform); + nsvg__xformMultiply(grad->xform, attr->xform); grad->spread = data->spread; - memcpy(grad->stops, stops, nstops*sizeof(struct NSVGgradientStop)); + memcpy(grad->stops, stops, nstops*sizeof(NSVGgradientStop)); grad->nstops = nstops; *paintType = data->type; @@ -732,22 +877,68 @@ static struct NSVGgradient* nsvg__createGradient(struct NSVGparser* p, const cha return grad; } -static void nsvg__addShape(struct NSVGparser* p) +static float nsvg__getAverageScale(float* t) +{ + float sx = sqrtf(t[0]*t[0] + t[2]*t[2]); + float sy = sqrtf(t[1]*t[1] + t[3]*t[3]); + return (sx + sy) * 0.5f; +} + +static void nsvg__getLocalBounds(float* bounds, NSVGshape *shape, float* xform) +{ + NSVGpath* path; + float curve[4*2], curveBounds[4]; + int i, first = 1; + for (path = shape->paths; path != NULL; path = path->next) { + nsvg__xformPoint(&curve[0], &curve[1], path->pts[0], path->pts[1], xform); + for (i = 0; i < path->npts-1; i += 3) { + nsvg__xformPoint(&curve[2], &curve[3], path->pts[(i+1)*2], path->pts[(i+1)*2+1], xform); + nsvg__xformPoint(&curve[4], &curve[5], path->pts[(i+2)*2], path->pts[(i+2)*2+1], xform); + nsvg__xformPoint(&curve[6], &curve[7], path->pts[(i+3)*2], path->pts[(i+3)*2+1], xform); + nsvg__curveBounds(curveBounds, curve); + if (first) { + bounds[0] = curveBounds[0]; + bounds[1] = curveBounds[1]; + bounds[2] = curveBounds[2]; + bounds[3] = curveBounds[3]; + first = 0; + } else { + bounds[0] = nsvg__minf(bounds[0], curveBounds[0]); + bounds[1] = nsvg__minf(bounds[1], curveBounds[1]); + bounds[2] = nsvg__maxf(bounds[2], curveBounds[2]); + bounds[3] = nsvg__maxf(bounds[3], curveBounds[3]); + } + curve[0] = curve[6]; + curve[1] = curve[7]; + } + } +} + +static void nsvg__addShape(NSVGparser* p) { - struct NSVGattrib* attr = nsvg__getAttr(p); + NSVGattrib* attr = nsvg__getAttr(p); float scale = 1.0f; - struct NSVGshape *shape, *cur, *prev; - struct NSVGpath* path; + NSVGshape *shape, *cur, *prev; + NSVGpath* path; + int i; if (p->plist == NULL) return; - shape = (struct NSVGshape*)malloc(sizeof(struct NSVGshape)); + shape = (NSVGshape*)malloc(sizeof(NSVGshape)); if (shape == NULL) goto error; - memset(shape, 0, sizeof(struct NSVGshape)); + memset(shape, 0, sizeof(NSVGshape)); - scale = nsvg__maxf(fabsf(attr->xform[0]), fabsf(attr->xform[3])); + memcpy(shape->id, attr->id, sizeof shape->id); + scale = nsvg__getAverageScale(attr->xform); shape->strokeWidth = attr->strokeWidth * scale; + shape->strokeDashOffset = attr->strokeDashOffset * scale; + shape->strokeDashCount = attr->strokeDashCount; + for (i = 0; i < attr->strokeDashCount; i++) + shape->strokeDashArray[i] = attr->strokeDashArray[i] * scale; + shape->strokeLineJoin = attr->strokeLineJoin; + shape->strokeLineCap = attr->strokeLineCap; + shape->fillRule = attr->fillRule; shape->opacity = attr->opacity; shape->paths = p->plist; @@ -773,7 +964,10 @@ static void nsvg__addShape(struct NSVGparser* p) shape->fill.color = attr->fillColor; shape->fill.color |= (unsigned int)(attr->fillOpacity*255) << 24; } else if (attr->hasFill == 2) { - shape->fill.gradient = nsvg__createGradient(p, attr->fillGradient, shape->bounds, &shape->fill.type); + float inv[6], localBounds[4]; + nsvg__xformInverse(inv, attr->xform); + nsvg__getLocalBounds(localBounds, shape, inv); + shape->fill.gradient = nsvg__createGradient(p, attr->fillGradient, localBounds, &shape->fill.type); if (shape->fill.gradient == NULL) { shape->fill.type = NSVG_PAINT_NONE; } @@ -787,11 +981,17 @@ static void nsvg__addShape(struct NSVGparser* p) shape->stroke.color = attr->strokeColor; shape->stroke.color |= (unsigned int)(attr->strokeOpacity*255) << 24; } else if (attr->hasStroke == 2) { - shape->stroke.gradient = nsvg__createGradient(p, attr->strokeGradient, shape->bounds, &shape->stroke.type); + float inv[6], localBounds[4]; + nsvg__xformInverse(inv, attr->xform); + nsvg__getLocalBounds(localBounds, shape, inv); + shape->stroke.gradient = nsvg__createGradient(p, attr->strokeGradient, localBounds, &shape->stroke.type); if (shape->stroke.gradient == NULL) shape->stroke.type = NSVG_PAINT_NONE; } + // Set flags + shape->flags = (attr->visible ? NSVG_FLAGS_VISIBLE : 0x00); + // Add to tail prev = NULL; cur = p->image->shapes; @@ -810,33 +1010,33 @@ static void nsvg__addShape(struct NSVGparser* p) if (shape) free(shape); } -static void nsvg__addPath(struct NSVGparser* p, char closed) +static void nsvg__addPath(NSVGparser* p, char closed) { - struct NSVGattrib* attr = nsvg__getAttr(p); - struct NSVGpath* path = NULL; + NSVGattrib* attr = nsvg__getAttr(p); + NSVGpath* path = NULL; float bounds[4]; float* curve; int i; - - if (p->npts == 0) + + if (p->npts < 4) return; if (closed) nsvg__lineTo(p, p->pts[0], p->pts[1]); - path = (struct NSVGpath*)malloc(sizeof(struct NSVGpath)); + path = (NSVGpath*)malloc(sizeof(NSVGpath)); if (path == NULL) goto error; - memset(path, 0, sizeof(struct NSVGpath)); + memset(path, 0, sizeof(NSVGpath)); path->pts = (float*)malloc(p->npts*2*sizeof(float)); if (path->pts == NULL) goto error; path->closed = closed; path->npts = p->npts; - + // Transform path. for (i = 0; i < p->npts; ++i) nsvg__xformPoint(&path->pts[i*2], &path->pts[i*2+1], p->pts[i*2], p->pts[i*2+1], attr->xform); - + // Find bounds for (i = 0; i < path->npts-1; i += 3) { curve = &path->pts[i*2]; @@ -866,48 +1066,57 @@ static void nsvg__addPath(struct NSVGparser* p, char closed) } } -static const char* nsvg__getNextPathItem(const char* s, char* it) +static const char* nsvg__parseNumber(const char* s, char* it, const int size) { + const int last = size-1; int i = 0; - it[0] = '\0'; - // Skip white spaces and commas - while (*s && (nsvg__isspace(*s) || *s == ',')) s++; - if (!*s) return s; - if (*s == '-' || *s == '+' || nsvg__isdigit(*s)) { - // sign - if (*s == '-' || *s == '+') { - if (i < 63) it[i++] = *s; - s++; - } - // integer part + + // sign + if (*s == '-' || *s == '+') { + if (i < last) it[i++] = *s; + s++; + } + // integer part + while (*s && nsvg__isdigit(*s)) { + if (i < last) it[i++] = *s; + s++; + } + if (*s == '.') { + // decimal point + if (i < last) it[i++] = *s; + s++; + // fraction part while (*s && nsvg__isdigit(*s)) { - if (i < 63) it[i++] = *s; + if (i < last) it[i++] = *s; s++; } - if (*s == '.') { - // decimal point - if (i < 63) it[i++] = *s; + } + // exponent + if (*s == 'e' || *s == 'E') { + if (i < last) it[i++] = *s; + s++; + if (*s == '-' || *s == '+') { + if (i < last) it[i++] = *s; s++; - // fraction part - while (*s && nsvg__isdigit(*s)) { - if (i < 63) it[i++] = *s; - s++; - } } - // exponent - if (*s == 'e' || *s == 'E') { - if (i < 63) it[i++] = *s; + while (*s && nsvg__isdigit(*s)) { + if (i < last) it[i++] = *s; s++; - if (*s == '-' || *s == '+') { - if (i < 63) it[i++] = *s; - s++; - } - while (*s && nsvg__isdigit(*s)) { - if (i < 63) it[i++] = *s; - s++; - } } - it[i] = '\0'; + } + it[i] = '\0'; + + return s; +} + +static const char* nsvg__getNextPathItem(const char* s, char* it) +{ + it[0] = '\0'; + // Skip white spaces and commas + while (*s && (nsvg__isspace(*s) || *s == ',')) s++; + if (!*s) return s; + if (*s == '-' || *s == '+' || *s == '.' || nsvg__isdigit(*s)) { + s = nsvg__parseNumber(s, it, 64); } else { // Parse command it[0] = *s++; @@ -918,23 +1127,6 @@ static const char* nsvg__getNextPathItem(const char* s, char* it) return s; } -static float nsvg__actualWidth(struct NSVGparser* p) -{ - return p->viewWidth; -} - -static float nsvg__actualHeight(struct NSVGparser* p) -{ - return p->viewHeight; -} - -static float nsvg__actualLength(struct NSVGparser* p) -{ - float w = nsvg__actualWidth(p), h = nsvg__actualHeight(p); - return sqrtf(w*w + h*h) / sqrtf(2.0f); -} - - static unsigned int nsvg__parseColorHex(const char* str) { unsigned int c = 0, r = 0, g = 0, b = 0; @@ -968,12 +1160,12 @@ static unsigned int nsvg__parseColorRGB(const char* str) } } -struct NSVGNamedColor { +typedef struct NSVGNamedColor { const char* name; unsigned int color; -}; +} NSVGNamedColor; -struct NSVGNamedColor nsvg__colors[] = { +NSVGNamedColor nsvg__colors[] = { { "red", NSVG_RGB(255, 0, 0) }, { "green", NSVG_RGB( 0, 128, 0) }, @@ -1129,8 +1321,8 @@ struct NSVGNamedColor nsvg__colors[] = { static unsigned int nsvg__parseColorName(const char* str) { - int i, ncolors = sizeof(nsvg__colors) / sizeof(struct NSVGNamedColor); - + int i, ncolors = sizeof(nsvg__colors) / sizeof(NSVGNamedColor); + for (i = 0; i < ncolors; i++) { if (strcmp(nsvg__colors[i].name, str) == 0) { return nsvg__colors[i].color; @@ -1142,7 +1334,7 @@ static unsigned int nsvg__parseColorName(const char* str) static unsigned int nsvg__parseColor(const char* str) { - int len = 0; + size_t len = 0; while(*str == ' ') ++str; len = strlen(str); if (len >= 1 && *str == '#') @@ -1152,75 +1344,65 @@ static unsigned int nsvg__parseColor(const char* str) return nsvg__parseColorName(str); } -static float nsvg__convertToPixels(struct NSVGparser* p, float val, const char* units, int dir) +static float nsvg__parseOpacity(const char* str) { - struct NSVGattrib* attr; - - if (p != NULL) { - // Convert units to pixels. - if (units[0] == '\0') { - return val; - } else if (units[0] == 'p' && units[1] == 'x') { - return val; - } else if (units[0] == 'p' && units[1] == 't') { - return val / 72.0f * p->dpi; - } else if (units[0] == 'p' && units[1] == 'c') { - return val / 6.0f * p->dpi; - } else if (units[0] == 'm' && units[1] == 'm') { - return val / 25.4f * p->dpi; - } else if (units[0] == 'c' && units[1] == 'm') { - return val / 2.54f * p->dpi; - } else if (units[0] == 'i' && units[1] == 'n') { - return val * p->dpi; - } else if (units[0] == '%') { - if (p != NULL) { - attr = nsvg__getAttr(p); - if (dir == 0) - return (val/100.0f) * nsvg__actualWidth(p); - else if (dir == 1) - return (val/100.0f) * nsvg__actualHeight(p); - else if (dir == 2) - return (val/100.0f) * nsvg__actualLength(p); - } else { - return (val/100.0f); - } - } else if (units[0] == 'e' && units[1] == 'm') { - if (p != NULL) { - attr = nsvg__getAttr(p); - return val * attr->fontSize; - } - } else if (units[0] == 'e' && units[1] == 'x') { - if (p != NULL) { - attr = nsvg__getAttr(p); - return val * attr->fontSize * 0.52f; // x-height of Helvetica. - } - } - } else { - // Convert units to pixels. - if (units[0] == '\0') { - return val; - } else if (units[0] == 'p' && units[1] == 'x') { - return val; - } else if (units[0] == '%') { - return (val/100.0f); - } - } + float val = 0; + sscanf(str, "%f", &val); + if (val < 0.0f) val = 0.0f; + if (val > 1.0f) val = 1.0f; return val; } -static float nsvg__parseFloat(struct NSVGparser* p, const char* str, int dir) -{ - float val = 0; +static int nsvg__parseUnits(const char* units) +{ + if (units[0] == 'p' && units[1] == 'x') + return NSVG_UNITS_PX; + else if (units[0] == 'p' && units[1] == 't') + return NSVG_UNITS_PT; + else if (units[0] == 'p' && units[1] == 'c') + return NSVG_UNITS_PC; + else if (units[0] == 'm' && units[1] == 'm') + return NSVG_UNITS_MM; + else if (units[0] == 'c' && units[1] == 'm') + return NSVG_UNITS_CM; + else if (units[0] == 'i' && units[1] == 'n') + return NSVG_UNITS_IN; + else if (units[0] == '%') + return NSVG_UNITS_PERCENT; + else if (units[0] == 'e' && units[1] == 'm') + return NSVG_UNITS_EM; + else if (units[0] == 'e' && units[1] == 'x') + return NSVG_UNITS_EX; + return NSVG_UNITS_USER; +} + +static NSVGcoordinate nsvg__parseCoordinateRaw(const char* str) +{ + NSVGcoordinate coord = {0, NSVG_UNITS_USER}; char units[32]=""; - sscanf(str, "%f%s", &val, units); - return nsvg__convertToPixels(p, val, units, dir); + sscanf(str, "%f%s", &coord.value, units); + coord.units = nsvg__parseUnits(units); + return coord; +} + +static NSVGcoordinate nsvg__coord(float v, int units) +{ + NSVGcoordinate coord = {v, units}; + return coord; +} + +static float nsvg__parseCoordinate(NSVGparser* p, const char* str, float orig, float length) +{ + NSVGcoordinate coord = nsvg__parseCoordinateRaw(str); + return nsvg__convertToPixels(p, coord, orig, length); } static int nsvg__parseTransformArgs(const char* str, float* args, int maxNa, int* na) { const char* end; const char* ptr; - + char it[64]; + *na = 0; ptr = str; while (*ptr && *ptr != '(') ++ptr; @@ -1230,12 +1412,12 @@ static int nsvg__parseTransformArgs(const char* str, float* args, int maxNa, int while (*end && *end != ')') ++end; if (*end == 0) return 1; - + while (ptr < end) { - if (nsvg__isnum(*ptr)) { + if (*ptr == '-' || *ptr == '+' || *ptr == '.' || nsvg__isdigit(*ptr)) { if (*na >= maxNa) return 0; - args[(*na)++] = (float)atof(ptr); - while (ptr < end && nsvg__isnum(*ptr)) ++ptr; + ptr = nsvg__parseNumber(ptr, it, 64); + args[(*na)++] = (float)atof(it); } else { ++ptr; } @@ -1243,6 +1425,7 @@ static int nsvg__parseTransformArgs(const char* str, float* args, int maxNa, int return (int)(end - str); } + static int nsvg__parseMatrix(float* xform, const char* str) { float t[6]; @@ -1260,6 +1443,7 @@ static int nsvg__parseTranslate(float* xform, const char* str) int na = 0; int len = nsvg__parseTransformArgs(str, args, 2, &na); if (na == 1) args[1] = 0.0; + nsvg__xformSetTranslation(t, args[0], args[1]); memcpy(xform, t, sizeof(float)*6); return len; @@ -1312,15 +1496,15 @@ static int nsvg__parseRotate(float* xform, const char* str) if (na > 1) { nsvg__xformSetTranslation(t, -args[1], -args[2]); - nsvg__xformPremultiply(m, t); + nsvg__xformMultiply(m, t); } - + nsvg__xformSetRotation(t, args[0]/180.0f*NSVG_PI); - nsvg__xformPremultiply(m, t); + nsvg__xformMultiply(m, t); if (na > 1) { nsvg__xformSetTranslation(t, args[1], args[2]); - nsvg__xformPremultiply(m, t); + nsvg__xformMultiply(m, t); } memcpy(xform, m, sizeof(float)*6); @@ -1350,7 +1534,7 @@ static void nsvg__parseTransform(float* xform, const char* str) ++str; continue; } - + nsvg__xformPremultiply(xform, t); } } @@ -1368,21 +1552,97 @@ static void nsvg__parseUrl(char* id, const char* str) id[i] = '\0'; } -static void nsvg__parseStyle(struct NSVGparser* p, const char* str); +static char nsvg__parseLineCap(const char* str) +{ + if (strcmp(str, "butt") == 0) + return NSVG_CAP_BUTT; + else if (strcmp(str, "round") == 0) + return NSVG_CAP_ROUND; + else if (strcmp(str, "square") == 0) + return NSVG_CAP_SQUARE; + // TODO: handle inherit. + return NSVG_CAP_BUTT; +} + +static char nsvg__parseLineJoin(const char* str) +{ + if (strcmp(str, "miter") == 0) + return NSVG_JOIN_MITER; + else if (strcmp(str, "round") == 0) + return NSVG_JOIN_ROUND; + else if (strcmp(str, "bevel") == 0) + return NSVG_JOIN_BEVEL; + // TODO: handle inherit. + return NSVG_CAP_BUTT; +} + +static char nsvg__parseFillRule(const char* str) +{ + if (strcmp(str, "nonzero") == 0) + return NSVG_FILLRULE_NONZERO; + else if (strcmp(str, "evenodd") == 0) + return NSVG_FILLRULE_EVENODD; + // TODO: handle inherit. + return NSVG_FILLRULE_NONZERO; +} + +static const char* nsvg__getNextDashItem(const char* s, char* it) +{ + int n = 0; + it[0] = '\0'; + // Skip white spaces and commas + while (*s && (nsvg__isspace(*s) || *s == ',')) s++; + // Advance until whitespace, comma or end. + while (*s && (!nsvg__isspace(*s) && *s != ',')) { + if (n < 63) + it[n++] = *s; + s++; + } + it[n++] = '\0'; + return s; +} + +static int nsvg__parseStrokeDashArray(NSVGparser* p, const char* str, float* strokeDashArray) +{ + char item[64]; + int count = 0, i; + float sum = 0.0f; + + // Handle "none" + if (str[0] == 'n') + return 0; + + // Parse dashes + while (*str) { + str = nsvg__getNextDashItem(str, item); + if (!*item) break; + if (count < NSVG_MAX_DASHES) + strokeDashArray[count++] = fabsf(nsvg__parseCoordinate(p, item, 0.0f, nsvg__actualLength(p))); + } + + for (i = 0; i < count; i++) + sum += strokeDashArray[i]; + if (sum <= 1e-6f) + count = 0; + + return count; +} -static int nsvg__parseAttr(struct NSVGparser* p, const char* name, const char* value) +static void nsvg__parseStyle(NSVGparser* p, const char* str); + +static int nsvg__parseAttr(NSVGparser* p, const char* name, const char* value) { float xform[6]; - struct NSVGattrib* attr = nsvg__getAttr(p); + NSVGattrib* attr = nsvg__getAttr(p); if (!attr) return 0; - + if (strcmp(name, "style") == 0) { nsvg__parseStyle(p, value); } else if (strcmp(name, "display") == 0) { if (strcmp(value, "none") == 0) attr->visible = 0; - else - attr->visible = 1; + // Don't reset ->visible on display:inline, one display:none hides the whole subtree + } else if (strcmp(name, "fill") == 0) { if (strcmp(value, "none") == 0) { attr->hasFill = 0; @@ -1394,9 +1654,9 @@ static int nsvg__parseAttr(struct NSVGparser* p, const char* name, const char* v attr->fillColor = nsvg__parseColor(value); } } else if (strcmp(name, "opacity") == 0) { - attr->opacity = nsvg__parseFloat(p, value, 2); + attr->opacity = nsvg__parseOpacity(value); } else if (strcmp(name, "fill-opacity") == 0) { - attr->fillOpacity = nsvg__parseFloat(p, value, 2); + attr->fillOpacity = nsvg__parseOpacity(value); } else if (strcmp(name, "stroke") == 0) { if (strcmp(value, "none") == 0) { attr->hasStroke = 0; @@ -1408,80 +1668,93 @@ static int nsvg__parseAttr(struct NSVGparser* p, const char* name, const char* v attr->strokeColor = nsvg__parseColor(value); } } else if (strcmp(name, "stroke-width") == 0) { - attr->strokeWidth = nsvg__parseFloat(p, value, 2); + attr->strokeWidth = nsvg__parseCoordinate(p, value, 0.0f, nsvg__actualLength(p)); + } else if (strcmp(name, "stroke-dasharray") == 0) { + attr->strokeDashCount = nsvg__parseStrokeDashArray(p, value, attr->strokeDashArray); + } else if (strcmp(name, "stroke-dashoffset") == 0) { + attr->strokeDashOffset = nsvg__parseCoordinate(p, value, 0.0f, nsvg__actualLength(p)); } else if (strcmp(name, "stroke-opacity") == 0) { - attr->strokeOpacity = nsvg__parseFloat(NULL, value, 2); + attr->strokeOpacity = nsvg__parseOpacity(value); + } else if (strcmp(name, "stroke-linecap") == 0) { + attr->strokeLineCap = nsvg__parseLineCap(value); + } else if (strcmp(name, "stroke-linejoin") == 0) { + attr->strokeLineJoin = nsvg__parseLineJoin(value); + } else if (strcmp(name, "fill-rule") == 0) { + attr->fillRule = nsvg__parseFillRule(value); } else if (strcmp(name, "font-size") == 0) { - attr->fontSize = nsvg__parseFloat(p, value, 2); + attr->fontSize = nsvg__parseCoordinate(p, value, 0.0f, nsvg__actualLength(p)); } else if (strcmp(name, "transform") == 0) { nsvg__parseTransform(xform, value); nsvg__xformPremultiply(attr->xform, xform); } else if (strcmp(name, "stop-color") == 0) { attr->stopColor = nsvg__parseColor(value); } else if (strcmp(name, "stop-opacity") == 0) { - attr->stopOpacity = nsvg__parseFloat(NULL, value, 2); + attr->stopOpacity = nsvg__parseOpacity(value); } else if (strcmp(name, "offset") == 0) { - attr->stopOffset = nsvg__parseFloat(NULL, value, 2); + attr->stopOffset = nsvg__parseCoordinate(p, value, 0.0f, 1.0f); + } else if (strcmp(name, "id") == 0) { + strncpy(attr->id, value, 63); + attr->id[63] = '\0'; } else { return 0; } return 1; } -static int nsvg__parseNameValue(struct NSVGparser* p, const char* start, const char* end) +static int nsvg__parseNameValue(NSVGparser* p, const char* start, const char* end) { const char* str; const char* val; char name[512]; char value[512]; int n; - + str = start; while (str < end && *str != ':') ++str; - + val = str; - + // Right Trim while (str > start && (*str == ':' || nsvg__isspace(*str))) --str; ++str; - + n = (int)(str - start); if (n > 511) n = 511; if (n) memcpy(name, start, n); name[n] = 0; - + while (val < end && (*val == ':' || nsvg__isspace(*val))) ++val; - + n = (int)(end - val); if (n > 511) n = 511; if (n) memcpy(value, val, n); value[n] = 0; - + return nsvg__parseAttr(p, name, value); } -static void nsvg__parseStyle(struct NSVGparser* p, const char* str) +static void nsvg__parseStyle(NSVGparser* p, const char* str) { const char* start; const char* end; - + while (*str) { // Left Trim while(*str && nsvg__isspace(*str)) ++str; start = str; while(*str && *str != ';') ++str; end = str; - + // Right Trim while (end > start && (*end == ';' || nsvg__isspace(*end))) --end; ++end; - + nsvg__parseNameValue(p, start, end); if (*str) ++str; } } -static void nsvg__parseAttribs(struct NSVGparser* p, const char** attr) +static void nsvg__parseAttribs(NSVGparser* p, const char** attr) { int i; for (i = 0; attr[i]; i += 2) @@ -1523,7 +1796,7 @@ static int nsvg__getArgsPerElement(char cmd) return 0; } -static void nsvg__pathMoveTo(struct NSVGparser* p, float* cpx, float* cpy, float* args, int rel) +static void nsvg__pathMoveTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel) { if (rel) { *cpx += args[0]; @@ -1535,7 +1808,7 @@ static void nsvg__pathMoveTo(struct NSVGparser* p, float* cpx, float* cpy, float nsvg__moveTo(p, *cpx, *cpy); } -static void nsvg__pathLineTo(struct NSVGparser* p, float* cpx, float* cpy, float* args, int rel) +static void nsvg__pathLineTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel) { if (rel) { *cpx += args[0]; @@ -1547,7 +1820,7 @@ static void nsvg__pathLineTo(struct NSVGparser* p, float* cpx, float* cpy, float nsvg__lineTo(p, *cpx, *cpy); } -static void nsvg__pathHLineTo(struct NSVGparser* p, float* cpx, float* cpy, float* args, int rel) +static void nsvg__pathHLineTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel) { if (rel) *cpx += args[0]; @@ -1556,7 +1829,7 @@ static void nsvg__pathHLineTo(struct NSVGparser* p, float* cpx, float* cpy, floa nsvg__lineTo(p, *cpx, *cpy); } -static void nsvg__pathVLineTo(struct NSVGparser* p, float* cpx, float* cpy, float* args, int rel) +static void nsvg__pathVLineTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel) { if (rel) *cpy += args[0]; @@ -1565,13 +1838,11 @@ static void nsvg__pathVLineTo(struct NSVGparser* p, float* cpx, float* cpy, floa nsvg__lineTo(p, *cpx, *cpy); } -static void nsvg__pathCubicBezTo(struct NSVGparser* p, float* cpx, float* cpy, +static void nsvg__pathCubicBezTo(NSVGparser* p, float* cpx, float* cpy, float* cpx2, float* cpy2, float* args, int rel) { - float x1, y1, x2, y2, cx1, cy1, cx2, cy2; - - x1 = *cpx; - y1 = *cpy; + float x2, y2, cx1, cy1, cx2, cy2; + if (rel) { cx1 = *cpx + args[0]; cy1 = *cpy + args[1]; @@ -1589,18 +1860,18 @@ static void nsvg__pathCubicBezTo(struct NSVGparser* p, float* cpx, float* cpy, } nsvg__cubicBezTo(p, cx1,cy1, cx2,cy2, x2,y2); - + *cpx2 = cx2; *cpy2 = cy2; *cpx = x2; *cpy = y2; } -static void nsvg__pathCubicBezShortTo(struct NSVGparser* p, float* cpx, float* cpy, +static void nsvg__pathCubicBezShortTo(NSVGparser* p, float* cpx, float* cpy, float* cpx2, float* cpy2, float* args, int rel) { float x1, y1, x2, y2, cx1, cy1, cx2, cy2; - + x1 = *cpx; y1 = *cpy; if (rel) { @@ -1614,24 +1885,24 @@ static void nsvg__pathCubicBezShortTo(struct NSVGparser* p, float* cpx, float* c x2 = args[2]; y2 = args[3]; } - + cx1 = 2*x1 - *cpx2; cy1 = 2*y1 - *cpy2; - + nsvg__cubicBezTo(p, cx1,cy1, cx2,cy2, x2,y2); - + *cpx2 = cx2; *cpy2 = cy2; *cpx = x2; *cpy = y2; } -static void nsvg__pathQuadBezTo(struct NSVGparser* p, float* cpx, float* cpy, +static void nsvg__pathQuadBezTo(NSVGparser* p, float* cpx, float* cpy, float* cpx2, float* cpy2, float* args, int rel) { float x1, y1, x2, y2, cx, cy; float cx1, cy1, cx2, cy2; - + x1 = *cpx; y1 = *cpy; if (rel) { @@ -1646,25 +1917,26 @@ static void nsvg__pathQuadBezTo(struct NSVGparser* p, float* cpx, float* cpy, y2 = args[3]; } - // Convert to cubix bezier + // Convert to cubic bezier cx1 = x1 + 2.0f/3.0f*(cx - x1); cy1 = y1 + 2.0f/3.0f*(cy - y1); cx2 = x2 + 2.0f/3.0f*(cx - x2); cy2 = y2 + 2.0f/3.0f*(cy - y2); + nsvg__cubicBezTo(p, cx1,cy1, cx2,cy2, x2,y2); - + *cpx2 = cx; *cpy2 = cy; *cpx = x2; *cpy = y2; } -static void nsvg__pathQuadBezShortTo(struct NSVGparser* p, float* cpx, float* cpy, +static void nsvg__pathQuadBezShortTo(NSVGparser* p, float* cpx, float* cpy, float* cpx2, float* cpy2, float* args, int rel) { float x1, y1, x2, y2, cx, cy; float cx1, cy1, cx2, cy2; - + x1 = *cpx; y1 = *cpy; if (rel) { @@ -1683,8 +1955,9 @@ static void nsvg__pathQuadBezShortTo(struct NSVGparser* p, float* cpx, float* cp cy1 = y1 + 2.0f/3.0f*(cy - y1); cx2 = x2 + 2.0f/3.0f*(cx - x2); cy2 = y2 + 2.0f/3.0f*(cy - y2); + nsvg__cubicBezTo(p, cx1,cy1, cx2,cy2, x2,y2); - + *cpx2 = cx; *cpy2 = cy; *cpx = x2; @@ -1704,17 +1977,17 @@ static float nsvg__vecang(float ux, float uy, float vx, float vy) float r = nsvg__vecrat(ux,uy, vx,vy); if (r < -1.0f) r = -1.0f; if (r > 1.0f) r = 1.0f; - return ((ux*vy < uy*vx) ? -1.0f : 1.0f) * acosf(r); + return ((ux*vy < uy*vx) ? -1.0f : 1.0f) * acosf(r); } -static void nsvg__pathArcTo(struct NSVGparser* p, float* cpx, float* cpy, float* args, int rel) +static void nsvg__pathArcTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel) { // Ported from canvg (https://code.google.com/p/canvg/) float rx, ry, rotx; float x1, y1, x2, y2, cx, cy, dx, dy, d; float x1p, y1p, cxp, cyp, s, sa, sb; float ux, uy, vx, vy, a1, da; - float x, y, tanx, tany, a, px, py, ptanx, ptany, t[6]; + float x, y, tanx, tany, a, px = 0, py = 0, ptanx = 0, ptany = 0, t[6]; float sinrx, cosrx; int fa, fs; int i, ndivs; @@ -1749,7 +2022,7 @@ static void nsvg__pathArcTo(struct NSVGparser* p, float* cpx, float* cpy, float* sinrx = sinf(rotx); cosrx = cosf(rotx); - // Convert to center point parameterization. + // Convert to center point parameterization. // http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes // 1) Compute x1', y1' x1p = cosrx * dx / 2.0f + sinrx * dy / 2.0f; @@ -1761,7 +2034,7 @@ static void nsvg__pathArcTo(struct NSVGparser* p, float* cpx, float* cpy, float* ry *= d; } // 2) Compute cx', cy' - s = 0.0f; + s = 0.0f; sa = nsvg__sqr(rx)*nsvg__sqr(ry) - nsvg__sqr(rx)*nsvg__sqr(y1p) - nsvg__sqr(ry)*nsvg__sqr(x1p); sb = nsvg__sqr(rx)*nsvg__sqr(y1p) + nsvg__sqr(ry)*nsvg__sqr(x1p); if (sa < 0.0f) sa = 0.0f; @@ -1801,7 +2074,8 @@ static void nsvg__pathArcTo(struct NSVGparser* p, float* cpx, float* cpy, float* t[4] = cx; t[5] = cy; // Split arc into max 90 degree segments. - ndivs = (int)(fabsf(da) / (NSVG_PI*0.5f) + 0.5f); + // The loop assumes an iteration per end point (including start and end), this +1. + ndivs = (int)(fabsf(da) / (NSVG_PI*0.5f) + 1.0f); hda = (da / (float)ndivs) / 2.0f; kappa = fabsf(4.0f / 3.0f * (1.0f - cosf(hda)) / sinf(hda)); if (da < 0.0f) @@ -1825,19 +2099,19 @@ static void nsvg__pathArcTo(struct NSVGparser* p, float* cpx, float* cpy, float* *cpy = y2; } -static void nsvg__parsePath(struct NSVGparser* p, const char** attr) +static void nsvg__parsePath(NSVGparser* p, const char** attr) { const char* s = NULL; - char cmd; + char cmd = '\0'; float args[10]; int nargs; - int rargs; + int rargs = 0; float cpx, cpy, cpx2, cpy2; const char* tmp[4]; char closedFlag; int i; char item[64]; - + for (i = 0; attr[i]; i += 2) { if (strcmp(attr[i], "d") == 0) { s = attr[i + 1]; @@ -1850,13 +2124,13 @@ static void nsvg__parsePath(struct NSVGparser* p, const char** attr) } } - if(s) - { + if (s) { nsvg__resetPath(p); cpx = 0; cpy = 0; + cpx2 = 0; cpy2 = 0; closedFlag = 0; nargs = 0; - + while (*s) { s = nsvg__getNextPathItem(s, item); if (!*item) break; @@ -1870,20 +2144,24 @@ static void nsvg__parsePath(struct NSVGparser* p, const char** attr) nsvg__pathMoveTo(p, &cpx, &cpy, args, cmd == 'm' ? 1 : 0); // Moveto can be followed by multiple coordinate pairs, // which should be treated as linetos. - cmd = (cmd =='m') ? 'l' : 'L'; + cmd = (cmd == 'm') ? 'l' : 'L'; rargs = nsvg__getArgsPerElement(cmd); + cpx2 = cpx; cpy2 = cpy; break; case 'l': case 'L': nsvg__pathLineTo(p, &cpx, &cpy, args, cmd == 'l' ? 1 : 0); + cpx2 = cpx; cpy2 = cpy; break; case 'H': case 'h': nsvg__pathHLineTo(p, &cpx, &cpy, args, cmd == 'h' ? 1 : 0); + cpx2 = cpx; cpy2 = cpy; break; case 'V': case 'v': nsvg__pathVLineTo(p, &cpx, &cpy, args, cmd == 'v' ? 1 : 0); + cpx2 = cpx; cpy2 = cpy; break; case 'C': case 'c': @@ -1899,16 +2177,18 @@ static void nsvg__parsePath(struct NSVGparser* p, const char** attr) break; case 'T': case 't': - nsvg__pathQuadBezShortTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd == 's' ? 1 : 0); + nsvg__pathQuadBezShortTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd == 't' ? 1 : 0); break; case 'A': case 'a': nsvg__pathArcTo(p, &cpx, &cpy, args, cmd == 'a' ? 1 : 0); + cpx2 = cpx; cpy2 = cpy; break; default: if (nargs >= 2) { cpx = args[nargs-2]; cpy = args[nargs-1]; + cpx2 = cpx; cpy2 = cpy; } break; } @@ -1928,10 +2208,16 @@ static void nsvg__parsePath(struct NSVGparser* p, const char** attr) } else if (cmd == 'Z' || cmd == 'z') { closedFlag = 1; // Commit path. - if (p->npts > 0) + if (p->npts > 0) { + // Move current point to first point + cpx = p->pts[0]; + cpy = p->pts[1]; + cpx2 = cpx; cpy2 = cpy; nsvg__addPath(p, closedFlag); + } // Start new subpath. nsvg__resetPath(p); + nsvg__moveTo(p, cpx, cpy); closedFlag = 0; nargs = 0; } @@ -1939,13 +2225,13 @@ static void nsvg__parsePath(struct NSVGparser* p, const char** attr) } // Commit path. if (p->npts) - nsvg__addPath(p, closedFlag); + nsvg__addPath(p, closedFlag); } nsvg__addShape(p); } -static void nsvg__parseRect(struct NSVGparser* p, const char** attr) +static void nsvg__parseRect(NSVGparser* p, const char** attr) { float x = 0.0f; float y = 0.0f; @@ -1954,15 +2240,15 @@ static void nsvg__parseRect(struct NSVGparser* p, const char** attr) float rx = -1.0f; // marks not set float ry = -1.0f; int i; - + for (i = 0; attr[i]; i += 2) { if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) { - if (strcmp(attr[i], "x") == 0) x = nsvg__parseFloat(p, attr[i+1], 0); - if (strcmp(attr[i], "y") == 0) y = nsvg__parseFloat(p, attr[i+1], 1); - if (strcmp(attr[i], "width") == 0) w = nsvg__parseFloat(p, attr[i+1], 0); - if (strcmp(attr[i], "height") == 0) h = nsvg__parseFloat(p, attr[i+1], 1); - if (strcmp(attr[i], "rx") == 0) rx = fabsf(nsvg__parseFloat(p, attr[i+1], 0)); - if (strcmp(attr[i], "ry") == 0) ry = fabsf(nsvg__parseFloat(p, attr[i+1], 1)); + if (strcmp(attr[i], "x") == 0) x = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigX(p), nsvg__actualWidth(p)); + if (strcmp(attr[i], "y") == 0) y = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigY(p), nsvg__actualHeight(p)); + if (strcmp(attr[i], "width") == 0) w = nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualWidth(p)); + if (strcmp(attr[i], "height") == 0) h = nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualHeight(p)); + if (strcmp(attr[i], "rx") == 0) rx = fabsf(nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualWidth(p))); + if (strcmp(attr[i], "ry") == 0) ry = fabsf(nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualHeight(p))); } } @@ -1972,7 +2258,7 @@ static void nsvg__parseRect(struct NSVGparser* p, const char** attr) if (ry < 0.0f) ry = 0.0f; if (rx > w/2.0f) rx = w/2.0f; if (ry > h/2.0f) ry = h/2.0f; - + if (w != 0.0f && h != 0.0f) { nsvg__resetPath(p); @@ -1993,28 +2279,28 @@ static void nsvg__parseRect(struct NSVGparser* p, const char** attr) nsvg__lineTo(p, x, y+ry); nsvg__cubicBezTo(p, x, y+ry*(1-NSVG_KAPPA90), x+rx*(1-NSVG_KAPPA90), y, x+rx, y); } - + nsvg__addPath(p, 1); nsvg__addShape(p); } } -static void nsvg__parseCircle(struct NSVGparser* p, const char** attr) +static void nsvg__parseCircle(NSVGparser* p, const char** attr) { float cx = 0.0f; float cy = 0.0f; float r = 0.0f; int i; - + for (i = 0; attr[i]; i += 2) { if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) { - if (strcmp(attr[i], "cx") == 0) cx = nsvg__parseFloat(p, attr[i+1], 0); - if (strcmp(attr[i], "cy") == 0) cy = nsvg__parseFloat(p, attr[i+1], 1); - if (strcmp(attr[i], "r") == 0) r = fabsf(nsvg__parseFloat(p, attr[i+1], 2)); + if (strcmp(attr[i], "cx") == 0) cx = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigX(p), nsvg__actualWidth(p)); + if (strcmp(attr[i], "cy") == 0) cy = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigY(p), nsvg__actualHeight(p)); + if (strcmp(attr[i], "r") == 0) r = fabsf(nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualLength(p))); } } - + if (r > 0.0f) { nsvg__resetPath(p); @@ -2023,30 +2309,30 @@ static void nsvg__parseCircle(struct NSVGparser* p, const char** attr) nsvg__cubicBezTo(p, cx-r*NSVG_KAPPA90, cy+r, cx-r, cy+r*NSVG_KAPPA90, cx-r, cy); nsvg__cubicBezTo(p, cx-r, cy-r*NSVG_KAPPA90, cx-r*NSVG_KAPPA90, cy-r, cx, cy-r); nsvg__cubicBezTo(p, cx+r*NSVG_KAPPA90, cy-r, cx+r, cy-r*NSVG_KAPPA90, cx+r, cy); - + nsvg__addPath(p, 1); nsvg__addShape(p); } } -static void nsvg__parseEllipse(struct NSVGparser* p, const char** attr) +static void nsvg__parseEllipse(NSVGparser* p, const char** attr) { float cx = 0.0f; float cy = 0.0f; float rx = 0.0f; float ry = 0.0f; int i; - + for (i = 0; attr[i]; i += 2) { if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) { - if (strcmp(attr[i], "cx") == 0) cx = nsvg__parseFloat(p, attr[i+1], 0); - if (strcmp(attr[i], "cy") == 0) cy = nsvg__parseFloat(p, attr[i+1], 1); - if (strcmp(attr[i], "rx") == 0) rx = fabsf(nsvg__parseFloat(p, attr[i+1], 0)); - if (strcmp(attr[i], "ry") == 0) ry = fabsf(nsvg__parseFloat(p, attr[i+1], 1)); + if (strcmp(attr[i], "cx") == 0) cx = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigX(p), nsvg__actualWidth(p)); + if (strcmp(attr[i], "cy") == 0) cy = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigY(p), nsvg__actualHeight(p)); + if (strcmp(attr[i], "rx") == 0) rx = fabsf(nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualWidth(p))); + if (strcmp(attr[i], "ry") == 0) ry = fabsf(nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualHeight(p))); } } - + if (rx > 0.0f && ry > 0.0f) { nsvg__resetPath(p); @@ -2056,50 +2342,50 @@ static void nsvg__parseEllipse(struct NSVGparser* p, const char** attr) nsvg__cubicBezTo(p, cx-rx*NSVG_KAPPA90, cy+ry, cx-rx, cy+ry*NSVG_KAPPA90, cx-rx, cy); nsvg__cubicBezTo(p, cx-rx, cy-ry*NSVG_KAPPA90, cx-rx*NSVG_KAPPA90, cy-ry, cx, cy-ry); nsvg__cubicBezTo(p, cx+rx*NSVG_KAPPA90, cy-ry, cx+rx, cy-ry*NSVG_KAPPA90, cx+rx, cy); - + nsvg__addPath(p, 1); nsvg__addShape(p); } } -static void nsvg__parseLine(struct NSVGparser* p, const char** attr) +static void nsvg__parseLine(NSVGparser* p, const char** attr) { float x1 = 0.0; float y1 = 0.0; float x2 = 0.0; float y2 = 0.0; int i; - + for (i = 0; attr[i]; i += 2) { if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) { - if (strcmp(attr[i], "x1") == 0) x1 = nsvg__parseFloat(p, attr[i + 1], 0); - if (strcmp(attr[i], "y1") == 0) y1 = nsvg__parseFloat(p, attr[i + 1], 1); - if (strcmp(attr[i], "x2") == 0) x2 = nsvg__parseFloat(p, attr[i + 1], 0); - if (strcmp(attr[i], "y2") == 0) y2 = nsvg__parseFloat(p, attr[i + 1], 1); + if (strcmp(attr[i], "x1") == 0) x1 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigX(p), nsvg__actualWidth(p)); + if (strcmp(attr[i], "y1") == 0) y1 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigY(p), nsvg__actualHeight(p)); + if (strcmp(attr[i], "x2") == 0) x2 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigX(p), nsvg__actualWidth(p)); + if (strcmp(attr[i], "y2") == 0) y2 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigY(p), nsvg__actualHeight(p)); } } - + nsvg__resetPath(p); - + nsvg__moveTo(p, x1, y1); nsvg__lineTo(p, x2, y2); - + nsvg__addPath(p, 0); nsvg__addShape(p); } -static void nsvg__parsePoly(struct NSVGparser* p, const char** attr, int closeFlag) +static void nsvg__parsePoly(NSVGparser* p, const char** attr, int closeFlag) { int i; const char* s; float args[2]; int nargs, npts = 0; char item[64]; - + nsvg__resetPath(p); - + for (i = 0; attr[i]; i += 2) { if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) { if (strcmp(attr[i], "points") == 0) { @@ -2120,21 +2406,21 @@ static void nsvg__parsePoly(struct NSVGparser* p, const char** attr, int closeFl } } } - + nsvg__addPath(p, (char)closeFlag); nsvg__addShape(p); } -static void nsvg__parseSVG(struct NSVGparser* p, const char** attr) +static void nsvg__parseSVG(NSVGparser* p, const char** attr) { int i; for (i = 0; attr[i]; i += 2) { if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) { if (strcmp(attr[i], "width") == 0) { - p->image->width = nsvg__parseFloat(p, attr[i + 1], 0); + p->image->width = nsvg__parseCoordinate(p, attr[i + 1], 0.0f, 1.0f); } else if (strcmp(attr[i], "height") == 0) { - p->image->height = nsvg__parseFloat(p, attr[i + 1], 1); + p->image->height = nsvg__parseCoordinate(p, attr[i + 1], 0.0f, 1.0f); } else if (strcmp(attr[i], "viewBox") == 0) { sscanf(attr[i + 1], "%f%*[%%, \t]%f%*[%%, \t]%f%*[%%, \t]%f", &p->viewMinx, &p->viewMiny, &p->viewWidth, &p->viewHeight); } else if (strcmp(attr[i], "preserveAspectRatio") == 0) { @@ -2166,19 +2452,32 @@ static void nsvg__parseSVG(struct NSVGparser* p, const char** attr) } } -static void nsvg__parseGradient(struct NSVGparser* p, const char** attr, char type) +static void nsvg__parseGradient(NSVGparser* p, const char** attr, char type) { int i; - struct NSVGgradientData* grad = (struct NSVGgradientData*)malloc(sizeof(struct NSVGgradientData)); + NSVGgradientData* grad = (NSVGgradientData*)malloc(sizeof(NSVGgradientData)); if (grad == NULL) return; - memset(grad, 0, sizeof(struct NSVGgradientData)); - + memset(grad, 0, sizeof(NSVGgradientData)); + grad->units = NSVG_OBJECT_SPACE; grad->type = type; + if (grad->type == NSVG_PAINT_LINEAR_GRADIENT) { + grad->linear.x1 = nsvg__coord(0.0f, NSVG_UNITS_PERCENT); + grad->linear.y1 = nsvg__coord(0.0f, NSVG_UNITS_PERCENT); + grad->linear.x2 = nsvg__coord(100.0f, NSVG_UNITS_PERCENT); + grad->linear.y2 = nsvg__coord(0.0f, NSVG_UNITS_PERCENT); + } else if (grad->type == NSVG_PAINT_RADIAL_GRADIENT) { + grad->radial.cx = nsvg__coord(50.0f, NSVG_UNITS_PERCENT); + grad->radial.cy = nsvg__coord(50.0f, NSVG_UNITS_PERCENT); + grad->radial.r = nsvg__coord(50.0f, NSVG_UNITS_PERCENT); + } + nsvg__xformIdentity(grad->xform); - // TODO: does not handle percent and objectBoundingBox correctly yet. for (i = 0; attr[i]; i += 2) { - if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) { + if (strcmp(attr[i], "id") == 0) { + strncpy(grad->id, attr[i+1], 63); + grad->id[63] = '\0'; + } else if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) { if (strcmp(attr[i], "gradientUnits") == 0) { if (strcmp(attr[i+1], "objectBoundingBox") == 0) grad->units = NSVG_OBJECT_SPACE; @@ -2187,23 +2486,23 @@ static void nsvg__parseGradient(struct NSVGparser* p, const char** attr, char ty } else if (strcmp(attr[i], "gradientTransform") == 0) { nsvg__parseTransform(grad->xform, attr[i + 1]); } else if (strcmp(attr[i], "cx") == 0) { - grad->radial.cx = nsvg__parseFloat(p, attr[i + 1], 0); + grad->radial.cx = nsvg__parseCoordinateRaw(attr[i + 1]); } else if (strcmp(attr[i], "cy") == 0) { - grad->radial.cy = nsvg__parseFloat(p, attr[i + 1], 1); + grad->radial.cy = nsvg__parseCoordinateRaw(attr[i + 1]); } else if (strcmp(attr[i], "r") == 0) { - grad->radial.r = nsvg__parseFloat(p, attr[i + 1], 2); + grad->radial.r = nsvg__parseCoordinateRaw(attr[i + 1]); } else if (strcmp(attr[i], "fx") == 0) { - grad->radial.fx = nsvg__parseFloat(p, attr[i + 1], 0); + grad->radial.fx = nsvg__parseCoordinateRaw(attr[i + 1]); } else if (strcmp(attr[i], "fy") == 0) { - grad->radial.fy = nsvg__parseFloat(p, attr[i + 1], 1); + grad->radial.fy = nsvg__parseCoordinateRaw(attr[i + 1]); } else if (strcmp(attr[i], "x1") == 0) { - grad->linear.x1 = nsvg__parseFloat(p, attr[i + 1], 0); + grad->linear.x1 = nsvg__parseCoordinateRaw(attr[i + 1]); } else if (strcmp(attr[i], "y1") == 0) { - grad->linear.y1 = nsvg__parseFloat(p, attr[i + 1], 1); + grad->linear.y1 = nsvg__parseCoordinateRaw(attr[i + 1]); } else if (strcmp(attr[i], "x2") == 0) { - grad->linear.x2 = nsvg__parseFloat(p, attr[i + 1], 0); + grad->linear.x2 = nsvg__parseCoordinateRaw(attr[i + 1]); } else if (strcmp(attr[i], "y2") == 0) { - grad->linear.y2 = nsvg__parseFloat(p, attr[i + 1], 1); + grad->linear.y2 = nsvg__parseCoordinateRaw(attr[i + 1]); } else if (strcmp(attr[i], "spreadMethod") == 0) { if (strcmp(attr[i+1], "pad") == 0) grad->spread = NSVG_SPREAD_PAD; @@ -2212,11 +2511,9 @@ static void nsvg__parseGradient(struct NSVGparser* p, const char** attr, char ty else if (strcmp(attr[i+1], "repeat") == 0) grad->spread = NSVG_SPREAD_REPEAT; } else if (strcmp(attr[i], "xlink:href") == 0) { - strncpy(grad->ref, attr[i+1], 63); - grad->ref[63] = '\0'; - } else if (strcmp(attr[i], "id") == 0) { - strncpy(grad->id, attr[i+1], 63); - grad->id[63] = '\0'; + const char *href = attr[i+1]; + strncpy(grad->ref, href+1, 62); + grad->ref[62] = '\0'; } } } @@ -2225,11 +2522,11 @@ static void nsvg__parseGradient(struct NSVGparser* p, const char** attr, char ty p->gradients = grad; } -static void nsvg__parseGradientStop(struct NSVGparser* p, const char** attr) +static void nsvg__parseGradientStop(NSVGparser* p, const char** attr) { - struct NSVGattrib* curAttr = nsvg__getAttr(p); - struct NSVGgradientData* grad; - struct NSVGgradientStop* stop; + NSVGattrib* curAttr = nsvg__getAttr(p); + NSVGgradientData* grad; + NSVGgradientStop* stop; int i, idx; curAttr->stopOffset = 0; @@ -2245,7 +2542,7 @@ static void nsvg__parseGradientStop(struct NSVGparser* p, const char** attr) if (grad == NULL) return; grad->nstops++; - grad->stops = (struct NSVGgradientStop*)realloc(grad->stops, sizeof(struct NSVGgradientStop)*grad->nstops); + grad->stops = (NSVGgradientStop*)realloc(grad->stops, sizeof(NSVGgradientStop)*grad->nstops); if (grad->stops == NULL) return; // Insert @@ -2269,8 +2566,8 @@ static void nsvg__parseGradientStop(struct NSVGparser* p, const char** attr) static void nsvg__startElement(void* ud, const char* el, const char** attr) { - struct NSVGparser* p = (struct NSVGparser*)ud; - + NSVGparser* p = (NSVGparser*)ud; + if (p->defsFlag) { // Skip everything but gradients in defs if (strcmp(el, "linearGradient") == 0) { @@ -2282,7 +2579,7 @@ static void nsvg__startElement(void* ud, const char* el, const char** attr) } return; } - + if (strcmp(el, "g") == 0) { nsvg__pushAttr(p); nsvg__parseAttribs(p, attr); @@ -2331,8 +2628,8 @@ static void nsvg__startElement(void* ud, const char* el, const char** attr) static void nsvg__endElement(void* ud, const char* el) { - struct NSVGparser* p = (struct NSVGparser*)ud; - + NSVGparser* p = (NSVGparser*)ud; + if (strcmp(el, "g") == 0) { nsvg__popAttr(p); } else if (strcmp(el, "path") == 0) { @@ -2344,13 +2641,19 @@ static void nsvg__endElement(void* ud, const char* el) static void nsvg__content(void* ud, const char* s) { + NSVG_NOTUSED(ud); + NSVG_NOTUSED(s); // empty } -static void nsvg__imageBounds(struct NSVGparser* p, float* bounds) +static void nsvg__imageBounds(NSVGparser* p, float* bounds) { - struct NSVGshape* shape; + NSVGshape* shape; shape = p->image->shapes; + if (shape == NULL) { + bounds[0] = bounds[1] = bounds[2] = bounds[3] = 0.0; + return; + } bounds[0] = shape->bounds[0]; bounds[1] = shape->bounds[1]; bounds[2] = shape->bounds[2]; @@ -2373,7 +2676,7 @@ static float nsvg__viewAlign(float content, float container, int type) return (container - content) * 0.5f; } -static void nsvg__scaleGradient(struct NSVGgradient* grad, float tx, float ty, float sx, float sy) +static void nsvg__scaleGradient(NSVGgradient* grad, float tx, float ty, float sx, float sy) { grad->xform[0] *= sx; grad->xform[1] *= sx; @@ -2383,38 +2686,44 @@ static void nsvg__scaleGradient(struct NSVGgradient* grad, float tx, float ty, f grad->xform[5] += ty*sx; } -static void nsvg__scaleToViewbox(struct NSVGparser* p, const char* units) +static void nsvg__scaleToViewbox(NSVGparser* p, const char* units) { - struct NSVGshape* shape; - struct NSVGpath* path; - float tx, ty, sx, sy, us, bounds[4], t[6]; + NSVGshape* shape; + NSVGpath* path; + float tx, ty, sx, sy, us, bounds[4], t[6], avgs; int i; float* pt; // Guess image size if not set completely. nsvg__imageBounds(p, bounds); + if (p->viewWidth == 0) { - if (p->image->width > 0) + if (p->image->width > 0) { p->viewWidth = p->image->width; - else - p->viewWidth = bounds[2]; + } else { + p->viewMinx = bounds[0]; + p->viewWidth = bounds[2] - bounds[0]; + } } if (p->viewHeight == 0) { - if (p->image->height > 0) + if (p->image->height > 0) { p->viewHeight = p->image->height; - else - p->viewHeight = bounds[3]; + } else { + p->viewMiny = bounds[1]; + p->viewHeight = bounds[3] - bounds[1]; + } } if (p->image->width == 0) p->image->width = p->viewWidth; if (p->image->height == 0) p->image->height = p->viewHeight; - tx = -p->viewMinx; + tx = -p->viewMinx; ty = -p->viewMiny; sx = p->viewWidth > 0 ? p->image->width / p->viewWidth : 0; sy = p->viewHeight > 0 ? p->image->height / p->viewHeight : 0; - us = 1.0f / nsvg__convertToPixels(p, 1.0f, units, 0); + // Unit scaling + us = 1.0f / nsvg__convertToPixels(p, nsvg__coord(1.0f, nsvg__parseUnits(units)), 0.0f, 1.0f); // Fix aspect ratio if (p->alignType == NSVG_ALIGN_MEET) { @@ -2432,6 +2741,7 @@ static void nsvg__scaleToViewbox(struct NSVGparser* p, const char* units) // Transform sx *= us; sy *= us; + avgs = (sx+sy) / 2.0f; for (shape = p->image->shapes; shape != NULL; shape = shape->next) { shape->bounds[0] = (shape->bounds[0] + tx) * sx; shape->bounds[1] = (shape->bounds[1] + ty) * sy; @@ -2460,17 +2770,18 @@ static void nsvg__scaleToViewbox(struct NSVGparser* p, const char* units) nsvg__xformInverse(shape->stroke.gradient->xform, t); } + shape->strokeWidth *= avgs; + shape->strokeDashOffset *= avgs; + for (i = 0; i < shape->strokeDashCount; i++) + shape->strokeDashArray[i] *= avgs; } - - sx *= us; - sy *= us; } -struct NSVGimage* nsvgParse(char* input, const char* units, float dpi) +NSVGimage* nsvgParse(char* input, const char* units, float dpi) { - struct NSVGparser* p; - struct NSVGimage* ret = 0; - + NSVGparser* p; + NSVGimage* ret = 0; + p = nsvg__createParser(); if (p == NULL) { return NULL; @@ -2490,12 +2801,12 @@ struct NSVGimage* nsvgParse(char* input, const char* units, float dpi) return ret; } -struct NSVGimage* nsvgParseFromFile(const char* filename, const char* units, float dpi) +NSVGimage* nsvgParseFromFile(const char* filename, const char* units, float dpi) { FILE* fp = NULL; - int size; + size_t size; char* data = NULL; - struct NSVGimage* image = NULL; + NSVGimage* image = NULL; fp = fopen(filename, "rb"); if (!fp) goto error; @@ -2504,7 +2815,7 @@ struct NSVGimage* nsvgParseFromFile(const char* filename, const char* units, flo fseek(fp, 0, SEEK_SET); data = (char*)malloc(size+1); if (data == NULL) goto error; - fread(data, size, 1, fp); + if (fread(data, 1, size, fp) != size) goto error; data[size] = '\0'; // Must be null terminated. fclose(fp); image = nsvgParse(data, units, dpi); @@ -2519,9 +2830,9 @@ struct NSVGimage* nsvgParseFromFile(const char* filename, const char* units, flo return NULL; } -void nsvgDelete(struct NSVGimage* image) +void nsvgDelete(NSVGimage* image) { - struct NSVGshape *snext, *shape; + NSVGshape *snext, *shape; if (image == NULL) return; shape = image->shapes; while (shape != NULL) { diff --git a/external/nanosvg/nanosvgrast.h b/external/nanosvg/nanosvgrast.h index 60eac66ea5..2ec6502888 100644 --- a/external/nanosvg/nanosvgrast.h +++ b/external/nanosvg/nanosvgrast.h @@ -1,14 +1,14 @@ /* * Copyright (c) 2013-14 Mikko Mononen memon@inside.org - * + * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. - * + * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: - * + * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be @@ -29,10 +29,11 @@ extern "C" { #endif +typedef struct NSVGrasterizer NSVGrasterizer; + /* Example Usage: // Load SVG struct SNVGImage* image = nsvgParseFromFile("test.svg."); - // Create rasterizer (can be used to render multiple images). struct NSVGrasterizer* rast = nsvgCreateRasterizer(); // Allocate memory for image @@ -42,7 +43,7 @@ extern "C" { */ // Allocated rasterizer context. -struct NSVGrasterizer* nsvgCreateRasterizer(); +NSVGrasterizer* nsvgCreateRasterizer(); // Rasterizes SVG image, returns RGBA image (non-premultiplied alpha) // r - pointer to rasterizer context @@ -53,12 +54,12 @@ struct NSVGrasterizer* nsvgCreateRasterizer(); // w - width of the image to render // h - height of the image to render // stride - number of bytes per scaleline in the destination buffer -void nsvgRasterize(struct NSVGrasterizer* r, - struct NSVGimage* image, float tx, float ty, float scale, +void nsvgRasterize(NSVGrasterizer* r, + NSVGimage* image, float tx, float ty, float scale, unsigned char* dst, int w, int h, int stride); // Deletes rasterizer context. -void nsvgDeleteRasterizer(struct NSVGrasterizer*); +void nsvgDeleteRasterizer(NSVGrasterizer*); #ifdef __cplusplus @@ -77,43 +78,62 @@ void nsvgDeleteRasterizer(struct NSVGrasterizer*); #define NSVG__FIXMASK (NSVG__FIX-1) #define NSVG__MEMPAGE_SIZE 1024 -struct NSVGedge { - float x0,y0, x1,y1; - int dir; - struct NSVGedge* next; -}; - -struct NSVGactiveEdge { +typedef struct NSVGedge { + float x0,y0, x1,y1; + int dir; + struct NSVGedge* next; +} NSVGedge; + +typedef struct NSVGpoint { + float x, y; + float dx, dy; + float len; + float dmx, dmy; + unsigned char flags; +} NSVGpoint; + +typedef struct NSVGactiveEdge { int x,dx; float ey; int dir; struct NSVGactiveEdge *next; -}; +} NSVGactiveEdge; -struct NSVGmemPage { +typedef struct NSVGmemPage { unsigned char mem[NSVG__MEMPAGE_SIZE]; int size; struct NSVGmemPage* next; -}; +} NSVGmemPage; -struct NSVGcachedPaint { +typedef struct NSVGcachedPaint { char type; char spread; float xform[6]; unsigned int colors[256]; -}; +} NSVGcachedPaint; struct NSVGrasterizer { float px, py; - struct NSVGedge* edges; + float tessTol; + float distTol; + + NSVGedge* edges; int nedges; int cedges; - struct NSVGactiveEdge* freelist; - struct NSVGmemPage* pages; - struct NSVGmemPage* curpage; + NSVGpoint* points; + int npoints; + int cpoints; + + NSVGpoint* points2; + int npoints2; + int cpoints2; + + NSVGactiveEdge* freelist; + NSVGmemPage* pages; + NSVGmemPage* curpage; unsigned char* scanline; int cscanline; @@ -122,11 +142,14 @@ struct NSVGrasterizer int width, height, stride; }; -struct NSVGrasterizer* nsvgCreateRasterizer() +NSVGrasterizer* nsvgCreateRasterizer() { - struct NSVGrasterizer* r = (struct NSVGrasterizer*)malloc(sizeof(struct NSVGrasterizer)); + NSVGrasterizer* r = (NSVGrasterizer*)malloc(sizeof(NSVGrasterizer)); if (r == NULL) goto error; - memset(r, 0, sizeof(struct NSVGrasterizer)); + memset(r, 0, sizeof(NSVGrasterizer)); + + r->tessTol = 0.25f; + r->distTol = 0.01f; return r; @@ -135,39 +158,41 @@ struct NSVGrasterizer* nsvgCreateRasterizer() return NULL; } -void nsvgDeleteRasterizer(struct NSVGrasterizer* r) +void nsvgDeleteRasterizer(NSVGrasterizer* r) { - struct NSVGmemPage* p; + NSVGmemPage* p; if (r == NULL) return; p = r->pages; while (p != NULL) { - struct NSVGmemPage* next = p->next; + NSVGmemPage* next = p->next; free(p); p = next; } if (r->edges) free(r->edges); + if (r->points) free(r->points); + if (r->points2) free(r->points2); if (r->scanline) free(r->scanline); free(r); } -static struct NSVGmemPage* nsvg__nextPage(struct NSVGrasterizer* r, struct NSVGmemPage* cur) +static NSVGmemPage* nsvg__nextPage(NSVGrasterizer* r, NSVGmemPage* cur) { - struct NSVGmemPage *newp; + NSVGmemPage *newp; // If using existing chain, return the next page in chain if (cur != NULL && cur->next != NULL) { return cur->next; } - + // Alloc new page - newp = (struct NSVGmemPage*)malloc(sizeof(struct NSVGmemPage)); + newp = (NSVGmemPage*)malloc(sizeof(NSVGmemPage)); if (newp == NULL) return NULL; - memset(newp, 0, sizeof(struct NSVGmemPage)); - + memset(newp, 0, sizeof(NSVGmemPage)); + // Add to linked list if (cur != NULL) cur->next = newp; @@ -177,9 +202,9 @@ static struct NSVGmemPage* nsvg__nextPage(struct NSVGrasterizer* r, struct NSVGm return newp; } -static void nsvg__resetPool(struct NSVGrasterizer* r) +static void nsvg__resetPool(NSVGrasterizer* r) { - struct NSVGmemPage* p = r->pages; + NSVGmemPage* p = r->pages; while (p != NULL) { p->size = 0; p = p->next; @@ -187,7 +212,7 @@ static void nsvg__resetPool(struct NSVGrasterizer* r) r->curpage = r->pages; } -static unsigned char* nsvg__alloc(struct NSVGrasterizer* r, int size) +static unsigned char* nsvg__alloc(NSVGrasterizer* r, int size) { unsigned char* buf; if (size > NSVG__MEMPAGE_SIZE) return NULL; @@ -199,9 +224,64 @@ static unsigned char* nsvg__alloc(struct NSVGrasterizer* r, int size) return buf; } -static void nsvg__addEdge(struct NSVGrasterizer* r, float x0, float y0, float x1, float y1) +static int nsvg__ptEquals(float x1, float y1, float x2, float y2, float tol) +{ + float dx = x2 - x1; + float dy = y2 - y1; + return dx*dx + dy*dy < tol*tol; +} + +static void nsvg__addPathPoint(NSVGrasterizer* r, float x, float y, int flags) +{ + NSVGpoint* pt; + + if (r->npoints > 0) { + pt = &r->points[r->npoints-1]; + if (nsvg__ptEquals(pt->x,pt->y, x,y, r->distTol)) { + pt->flags |= flags; + return; + } + } + + if (r->npoints+1 > r->cpoints) { + r->cpoints = r->cpoints > 0 ? r->cpoints * 2 : 64; + r->points = (NSVGpoint*)realloc(r->points, sizeof(NSVGpoint) * r->cpoints); + if (r->points == NULL) return; + } + + pt = &r->points[r->npoints]; + pt->x = x; + pt->y = y; + pt->flags = (unsigned char)flags; + r->npoints++; +} + +static void nsvg__appendPathPoint(NSVGrasterizer* r, NSVGpoint pt) +{ + if (r->npoints+1 > r->cpoints) { + r->cpoints = r->cpoints > 0 ? r->cpoints * 2 : 64; + r->points = (NSVGpoint*)realloc(r->points, sizeof(NSVGpoint) * r->cpoints); + if (r->points == NULL) return; + } + r->points[r->npoints] = pt; + r->npoints++; +} + +static void nsvg__duplicatePoints(NSVGrasterizer* r) +{ + if (r->npoints > r->cpoints2) { + r->cpoints2 = r->npoints; + r->points2 = (NSVGpoint*)realloc(r->points2, sizeof(NSVGpoint) * r->cpoints2); + if (r->points2 == NULL) return; + } + + memcpy(r->points2, r->points, sizeof(NSVGpoint) * r->npoints); + r->npoints2 = r->npoints; +} + +static void nsvg__addEdge(NSVGrasterizer* r, float x0, float y0, float x1, float y1) { - struct NSVGedge* e; + NSVGedge* e; // Skip horizontal edges if (y0 == y1) @@ -209,7 +289,7 @@ static void nsvg__addEdge(struct NSVGrasterizer* r, float x0, float y0, float x1 if (r->nedges+1 > r->cedges) { r->cedges = r->cedges > 0 ? r->cedges * 2 : 64; - r->edges = (struct NSVGedge*)realloc(r->edges, sizeof(struct NSVGedge) * r->cedges); + r->edges = (NSVGedge*)realloc(r->edges, sizeof(NSVGedge) * r->cedges); if (r->edges == NULL) return; } @@ -231,23 +311,28 @@ static void nsvg__addEdge(struct NSVGrasterizer* r, float x0, float y0, float x1 } } +static float nsvg__normalize(float *x, float* y) +{ + float d = sqrtf((*x)*(*x) + (*y)*(*y)); + if (d > 1e-6f) { + float id = 1.0f / d; + *x *= id; + *y *= id; + } + return d; +} + static float nsvg__absf(float x) { return x < 0 ? -x : x; } -static void nsvg__flattenCubicBez(struct NSVGrasterizer* r, +static void nsvg__flattenCubicBez(NSVGrasterizer* r, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, - float tol, int level) + int level, int type) { float x12,y12,x23,y23,x34,y34,x123,y123,x234,y234,x1234,y1234; - - if (level > 10) return; + float dx,dy,d2,d3; - if (nsvg__absf(x1+x3-x2-x2) + nsvg__absf(y1+y3-y2-y2) + nsvg__absf(x2+x4-x3-x3) + nsvg__absf(y2+y4-y3-y3) < tol) { - nsvg__addEdge(r, r->px, r->py, x4, y4); - r->px = x4; - r->py = y4; - return; - } + if (level > 10) return; x12 = (x1+x2)*0.5f; y12 = (y1+y2)*0.5f; @@ -257,38 +342,503 @@ static void nsvg__flattenCubicBez(struct NSVGrasterizer* r, y34 = (y3+y4)*0.5f; x123 = (x12+x23)*0.5f; y123 = (y12+y23)*0.5f; + + dx = x4 - x1; + dy = y4 - y1; + d2 = nsvg__absf(((x2 - x4) * dy - (y2 - y4) * dx)); + d3 = nsvg__absf(((x3 - x4) * dy - (y3 - y4) * dx)); + + if ((d2 + d3)*(d2 + d3) < r->tessTol * (dx*dx + dy*dy)) { + nsvg__addPathPoint(r, x4, y4, type); + return; + } + x234 = (x23+x34)*0.5f; y234 = (y23+y34)*0.5f; x1234 = (x123+x234)*0.5f; y1234 = (y123+y234)*0.5f; - nsvg__flattenCubicBez(r, x1,y1, x12,y12, x123,y123, x1234,y1234, tol, level+1); - nsvg__flattenCubicBez(r, x1234,y1234, x234,y234, x34,y34, x4,y4, tol, level+1); + nsvg__flattenCubicBez(r, x1,y1, x12,y12, x123,y123, x1234,y1234, level+1, 0); + nsvg__flattenCubicBez(r, x1234,y1234, x234,y234, x34,y34, x4,y4, level+1, type); } -static void nsvg__flattenShape(struct NSVGrasterizer* r, struct NSVGshape* shape, float scale) +static void nsvg__flattenShape(NSVGrasterizer* r, NSVGshape* shape, float scale) { - struct NSVGpath* path; - float tol = 0.25f * 4.0f / scale; - int i; + int i, j; + NSVGpath* path; for (path = shape->paths; path != NULL; path = path->next) { + r->npoints = 0; // Flatten path - r->px = path->pts[0]; - r->py = path->pts[1]; + nsvg__addPathPoint(r, path->pts[0]*scale, path->pts[1]*scale, 0); for (i = 0; i < path->npts-1; i += 3) { float* p = &path->pts[i*2]; - nsvg__flattenCubicBez(r, p[0],p[1], p[2],p[3], p[4],p[5], p[6],p[7], tol, 0); + nsvg__flattenCubicBez(r, p[0]*scale,p[1]*scale, p[2]*scale,p[3]*scale, p[4]*scale,p[5]*scale, p[6]*scale,p[7]*scale, 0, 0); } // Close path - nsvg__addEdge(r, r->px,r->py, path->pts[0],path->pts[1]); + nsvg__addPathPoint(r, path->pts[0]*scale, path->pts[1]*scale, 0); + // Build edges + for (i = 0, j = r->npoints-1; i < r->npoints; j = i++) + nsvg__addEdge(r, r->points[j].x, r->points[j].y, r->points[i].x, r->points[i].y); + } +} + +enum NSVGpointFlags +{ + NSVG_PT_CORNER = 0x01, + NSVG_PT_BEVEL = 0x02, + NSVG_PT_LEFT = 0x04, +}; + +static void nsvg__initClosed(NSVGpoint* left, NSVGpoint* right, NSVGpoint* p0, NSVGpoint* p1, float lineWidth) +{ + float w = lineWidth * 0.5f; + float dx = p1->x - p0->x; + float dy = p1->y - p0->y; + float len = nsvg__normalize(&dx, &dy); + float px = p0->x + dx*len*0.5f, py = p0->y + dy*len*0.5f; + float dlx = dy, dly = -dx; + float lx = px - dlx*w, ly = py - dly*w; + float rx = px + dlx*w, ry = py + dly*w; + left->x = lx; left->y = ly; + right->x = rx; right->y = ry; +} + +static void nsvg__buttCap(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p, float dx, float dy, float lineWidth, int connect) +{ + float w = lineWidth * 0.5f; + float px = p->x, py = p->y; + float dlx = dy, dly = -dx; + float lx = px - dlx*w, ly = py - dly*w; + float rx = px + dlx*w, ry = py + dly*w; + + nsvg__addEdge(r, lx, ly, rx, ry); + + if (connect) { + nsvg__addEdge(r, left->x, left->y, lx, ly); + nsvg__addEdge(r, rx, ry, right->x, right->y); + } + left->x = lx; left->y = ly; + right->x = rx; right->y = ry; +} + +static void nsvg__squareCap(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p, float dx, float dy, float lineWidth, int connect) +{ + float w = lineWidth * 0.5f; + float px = p->x - dx*w, py = p->y - dy*w; + float dlx = dy, dly = -dx; + float lx = px - dlx*w, ly = py - dly*w; + float rx = px + dlx*w, ry = py + dly*w; + + nsvg__addEdge(r, lx, ly, rx, ry); + + if (connect) { + nsvg__addEdge(r, left->x, left->y, lx, ly); + nsvg__addEdge(r, rx, ry, right->x, right->y); + } + left->x = lx; left->y = ly; + right->x = rx; right->y = ry; +} + +#ifndef NSVG_PI +#define NSVG_PI (3.14159265358979323846264338327f) +#endif + +static void nsvg__roundCap(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p, float dx, float dy, float lineWidth, int ncap, int connect) +{ + int i; + float w = lineWidth * 0.5f; + float px = p->x, py = p->y; + float dlx = dy, dly = -dx; + float lx = 0, ly = 0, rx = 0, ry = 0, prevx = 0, prevy = 0; + + for (i = 0; i < ncap; i++) { + float a = i/(float)(ncap-1)*NSVG_PI; + float ax = cosf(a) * w, ay = sinf(a) * w; + float x = px - dlx*ax - dx*ay; + float y = py - dly*ax - dy*ay; + + if (i > 0) + nsvg__addEdge(r, prevx, prevy, x, y); + + prevx = x; + prevy = y; + + if (i == 0) { + lx = x; ly = y; + } else if (i == ncap-1) { + rx = x; ry = y; + } + } + + if (connect) { + nsvg__addEdge(r, left->x, left->y, lx, ly); + nsvg__addEdge(r, rx, ry, right->x, right->y); + } + + left->x = lx; left->y = ly; + right->x = rx; right->y = ry; +} + +static void nsvg__bevelJoin(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p0, NSVGpoint* p1, float lineWidth) +{ + float w = lineWidth * 0.5f; + float dlx0 = p0->dy, dly0 = -p0->dx; + float dlx1 = p1->dy, dly1 = -p1->dx; + float lx0 = p1->x - (dlx0 * w), ly0 = p1->y - (dly0 * w); + float rx0 = p1->x + (dlx0 * w), ry0 = p1->y + (dly0 * w); + float lx1 = p1->x - (dlx1 * w), ly1 = p1->y - (dly1 * w); + float rx1 = p1->x + (dlx1 * w), ry1 = p1->y + (dly1 * w); + + nsvg__addEdge(r, lx0, ly0, left->x, left->y); + nsvg__addEdge(r, lx1, ly1, lx0, ly0); + + nsvg__addEdge(r, right->x, right->y, rx0, ry0); + nsvg__addEdge(r, rx0, ry0, rx1, ry1); + + left->x = lx1; left->y = ly1; + right->x = rx1; right->y = ry1; +} + +static void nsvg__miterJoin(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p0, NSVGpoint* p1, float lineWidth) +{ + float w = lineWidth * 0.5f; + float dlx0 = p0->dy, dly0 = -p0->dx; + float dlx1 = p1->dy, dly1 = -p1->dx; + float lx0, rx0, lx1, rx1; + float ly0, ry0, ly1, ry1; + + if (p1->flags & NSVG_PT_LEFT) { + lx0 = lx1 = p1->x - p1->dmx * w; + ly0 = ly1 = p1->y - p1->dmy * w; + nsvg__addEdge(r, lx1, ly1, left->x, left->y); + + rx0 = p1->x + (dlx0 * w); + ry0 = p1->y + (dly0 * w); + rx1 = p1->x + (dlx1 * w); + ry1 = p1->y + (dly1 * w); + nsvg__addEdge(r, right->x, right->y, rx0, ry0); + nsvg__addEdge(r, rx0, ry0, rx1, ry1); + } else { + lx0 = p1->x - (dlx0 * w); + ly0 = p1->y - (dly0 * w); + lx1 = p1->x - (dlx1 * w); + ly1 = p1->y - (dly1 * w); + nsvg__addEdge(r, lx0, ly0, left->x, left->y); + nsvg__addEdge(r, lx1, ly1, lx0, ly0); + + rx0 = rx1 = p1->x + p1->dmx * w; + ry0 = ry1 = p1->y + p1->dmy * w; + nsvg__addEdge(r, right->x, right->y, rx1, ry1); + } + + left->x = lx1; left->y = ly1; + right->x = rx1; right->y = ry1; +} + +static void nsvg__roundJoin(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p0, NSVGpoint* p1, float lineWidth, int ncap) +{ + int i, n; + float w = lineWidth * 0.5f; + float dlx0 = p0->dy, dly0 = -p0->dx; + float dlx1 = p1->dy, dly1 = -p1->dx; + float a0 = atan2f(dly0, dlx0); + float a1 = atan2f(dly1, dlx1); + float da = a1 - a0; + float lx, ly, rx, ry; + + if (da < NSVG_PI) da += NSVG_PI*2; + if (da > NSVG_PI) da -= NSVG_PI*2; + + n = (int)ceilf((nsvg__absf(da) / NSVG_PI) * ncap); + if (n < 2) n = 2; + if (n > ncap) n = ncap; + + lx = left->x; + ly = left->y; + rx = right->x; + ry = right->y; + + for (i = 0; i < n; i++) { + float u = i/(float)(n-1); + float a = a0 + u*da; + float ax = cosf(a) * w, ay = sinf(a) * w; + float lx1 = p1->x - ax, ly1 = p1->y - ay; + float rx1 = p1->x + ax, ry1 = p1->y + ay; + + nsvg__addEdge(r, lx1, ly1, lx, ly); + nsvg__addEdge(r, rx, ry, rx1, ry1); + + lx = lx1; ly = ly1; + rx = rx1; ry = ry1; + } + + left->x = lx; left->y = ly; + right->x = rx; right->y = ry; +} + +static void nsvg__straightJoin(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p1, float lineWidth) +{ + float w = lineWidth * 0.5f; + float lx = p1->x - (p1->dmx * w), ly = p1->y - (p1->dmy * w); + float rx = p1->x + (p1->dmx * w), ry = p1->y + (p1->dmy * w); + + nsvg__addEdge(r, lx, ly, left->x, left->y); + nsvg__addEdge(r, right->x, right->y, rx, ry); + + left->x = lx; left->y = ly; + right->x = rx; right->y = ry; +} + +static int nsvg__curveDivs(float r, float arc, float tol) +{ + float da = acosf(r / (r + tol)) * 2.0f; + int divs = (int)ceilf(arc / da); + if (divs < 2) divs = 2; + return divs; +} + +static void nsvg__expandStroke(NSVGrasterizer* r, NSVGpoint* points, int npoints, int closed, int lineJoin, int lineCap, float lineWidth) +{ + int ncap = nsvg__curveDivs(lineWidth*0.5f, NSVG_PI, r->tessTol); // Calculate divisions per half circle. + NSVGpoint left = {0,0,0,0,0,0,0,0}, right = {0,0,0,0,0,0,0,0}, firstLeft = {0,0,0,0,0,0,0,0}, firstRight = {0,0,0,0,0,0,0,0}; + NSVGpoint* p0, *p1; + int j, s, e; + + // Build stroke edges + if (closed) { + // Looping + p0 = &points[npoints-1]; + p1 = &points[0]; + s = 0; + e = npoints; + } else { + // Add cap + p0 = &points[0]; + p1 = &points[1]; + s = 1; + e = npoints-1; + } + + if (closed) { + nsvg__initClosed(&left, &right, p0, p1, lineWidth); + firstLeft = left; + firstRight = right; + } else { + // Add cap + float dx = p1->x - p0->x; + float dy = p1->y - p0->y; + nsvg__normalize(&dx, &dy); + if (lineCap == NSVG_CAP_BUTT) + nsvg__buttCap(r, &left, &right, p0, dx, dy, lineWidth, 0); + else if (lineCap == NSVG_CAP_SQUARE) + nsvg__squareCap(r, &left, &right, p0, dx, dy, lineWidth, 0); + else if (lineCap == NSVG_CAP_ROUND) + nsvg__roundCap(r, &left, &right, p0, dx, dy, lineWidth, ncap, 0); + } + + for (j = s; j < e; ++j) { + if (p1->flags & NSVG_PT_CORNER) { + if (lineJoin == NSVG_JOIN_ROUND) + nsvg__roundJoin(r, &left, &right, p0, p1, lineWidth, ncap); + else if (lineJoin == NSVG_JOIN_BEVEL || (p1->flags & NSVG_PT_BEVEL)) + nsvg__bevelJoin(r, &left, &right, p0, p1, lineWidth); + else + nsvg__miterJoin(r, &left, &right, p0, p1, lineWidth); + } else { + nsvg__straightJoin(r, &left, &right, p1, lineWidth); + } + p0 = p1++; + } + + if (closed) { + // Loop it + nsvg__addEdge(r, firstLeft.x, firstLeft.y, left.x, left.y); + nsvg__addEdge(r, right.x, right.y, firstRight.x, firstRight.y); + } else { + // Add cap + float dx = p1->x - p0->x; + float dy = p1->y - p0->y; + nsvg__normalize(&dx, &dy); + if (lineCap == NSVG_CAP_BUTT) + nsvg__buttCap(r, &right, &left, p1, -dx, -dy, lineWidth, 1); + else if (lineCap == NSVG_CAP_SQUARE) + nsvg__squareCap(r, &right, &left, p1, -dx, -dy, lineWidth, 1); + else if (lineCap == NSVG_CAP_ROUND) + nsvg__roundCap(r, &right, &left, p1, -dx, -dy, lineWidth, ncap, 1); + } +} + +static void nsvg__prepareStroke(NSVGrasterizer* r, float miterLimit, int lineJoin) +{ + int i, j; + NSVGpoint* p0, *p1; + + p0 = &r->points[r->npoints-1]; + p1 = &r->points[0]; + for (i = 0; i < r->npoints; i++) { + // Calculate segment direction and length + p0->dx = p1->x - p0->x; + p0->dy = p1->y - p0->y; + p0->len = nsvg__normalize(&p0->dx, &p0->dy); + // Advance + p0 = p1++; + } + + // calculate joins + p0 = &r->points[r->npoints-1]; + p1 = &r->points[0]; + for (j = 0; j < r->npoints; j++) { + float dlx0, dly0, dlx1, dly1, dmr2, cross; + dlx0 = p0->dy; + dly0 = -p0->dx; + dlx1 = p1->dy; + dly1 = -p1->dx; + // Calculate extrusions + p1->dmx = (dlx0 + dlx1) * 0.5f; + p1->dmy = (dly0 + dly1) * 0.5f; + dmr2 = p1->dmx*p1->dmx + p1->dmy*p1->dmy; + if (dmr2 > 0.000001f) { + float s2 = 1.0f / dmr2; + if (s2 > 600.0f) { + s2 = 600.0f; + } + p1->dmx *= s2; + p1->dmy *= s2; + } + + // Clear flags, but keep the corner. + p1->flags = (p1->flags & NSVG_PT_CORNER) ? NSVG_PT_CORNER : 0; + + // Keep track of left turns. + cross = p1->dx * p0->dy - p0->dx * p1->dy; + if (cross > 0.0f) + p1->flags |= NSVG_PT_LEFT; + + // Check to see if the corner needs to be beveled. + if (p1->flags & NSVG_PT_CORNER) { + if ((dmr2 * miterLimit*miterLimit) < 1.0f || lineJoin == NSVG_JOIN_BEVEL || lineJoin == NSVG_JOIN_ROUND) { + p1->flags |= NSVG_PT_BEVEL; + } + } + + p0 = p1++; + } +} + +static void nsvg__flattenShapeStroke(NSVGrasterizer* r, NSVGshape* shape, float scale) +{ + int i, j, closed; + NSVGpath* path; + NSVGpoint* p0, *p1; + float miterLimit = 4; + int lineJoin = shape->strokeLineJoin; + int lineCap = shape->strokeLineCap; + float lineWidth = shape->strokeWidth * scale; + + for (path = shape->paths; path != NULL; path = path->next) { + // Flatten path + r->npoints = 0; + nsvg__addPathPoint(r, path->pts[0]*scale, path->pts[1]*scale, NSVG_PT_CORNER); + for (i = 0; i < path->npts-1; i += 3) { + float* p = &path->pts[i*2]; + nsvg__flattenCubicBez(r, p[0]*scale,p[1]*scale, p[2]*scale,p[3]*scale, p[4]*scale,p[5]*scale, p[6]*scale,p[7]*scale, 0, NSVG_PT_CORNER); + } + if (r->npoints < 2) + continue; + + closed = path->closed; + + // If the first and last points are the same, remove the last, mark as closed path. + p0 = &r->points[r->npoints-1]; + p1 = &r->points[0]; + if (nsvg__ptEquals(p0->x,p0->y, p1->x,p1->y, r->distTol)) { + r->npoints--; + p0 = &r->points[r->npoints-1]; + closed = 1; + } + + if (shape->strokeDashCount > 0) { + int idash = 0, dashState = 1; + float totalDist = 0, dashLen, allDashLen, dashOffset; + NSVGpoint cur; + + if (closed) + nsvg__appendPathPoint(r, r->points[0]); + + // Duplicate points -> points2. + nsvg__duplicatePoints(r); + + r->npoints = 0; + cur = r->points2[0]; + nsvg__appendPathPoint(r, cur); + + // Figure out dash offset. + allDashLen = 0; + for (j = 0; j < shape->strokeDashCount; j++) + allDashLen += shape->strokeDashArray[j]; + if (shape->strokeDashCount & 1) + allDashLen *= 2.0f; + // Find location inside pattern + dashOffset = fmodf(shape->strokeDashOffset, allDashLen); + if (dashOffset < 0.0f) + dashOffset += allDashLen; + + while (dashOffset > shape->strokeDashArray[idash]) { + dashOffset -= shape->strokeDashArray[idash]; + idash = (idash + 1) % shape->strokeDashCount; + } + dashLen = (shape->strokeDashArray[idash] - dashOffset) * scale; + + for (j = 1; j < r->npoints2; ) { + float dx = r->points2[j].x - cur.x; + float dy = r->points2[j].y - cur.y; + float dist = sqrtf(dx*dx + dy*dy); + + if ((totalDist + dist) > dashLen) { + // Calculate intermediate point + float d = (dashLen - totalDist) / dist; + float x = cur.x + dx * d; + float y = cur.y + dy * d; + nsvg__addPathPoint(r, x, y, NSVG_PT_CORNER); + + // Stroke + if (r->npoints > 1 && dashState) { + nsvg__prepareStroke(r, miterLimit, lineJoin); + nsvg__expandStroke(r, r->points, r->npoints, 0, lineJoin, lineCap, lineWidth); + } + // Advance dash pattern + dashState = !dashState; + idash = (idash+1) % shape->strokeDashCount; + dashLen = shape->strokeDashArray[idash] * scale; + // Restart + cur.x = x; + cur.y = y; + cur.flags = NSVG_PT_CORNER; + totalDist = 0.0f; + r->npoints = 0; + nsvg__appendPathPoint(r, cur); + } else { + totalDist += dist; + cur = r->points2[j]; + nsvg__appendPathPoint(r, cur); + j++; + } + } + // Stroke any leftover path + if (r->npoints > 1 && dashState) + nsvg__expandStroke(r, r->points, r->npoints, 0, lineJoin, lineCap, lineWidth); + } else { + nsvg__prepareStroke(r, miterLimit, lineJoin); + nsvg__expandStroke(r, r->points, r->npoints, closed, lineJoin, lineCap, lineWidth); + } } } static int nsvg__cmpEdge(const void *p, const void *q) { - struct NSVGedge* a = (struct NSVGedge*)p; - struct NSVGedge* b = (struct NSVGedge*)q; + NSVGedge* a = (NSVGedge*)p; + NSVGedge* b = (NSVGedge*)q; if (a->y0 < b->y0) return -1; if (a->y0 > b->y0) return 1; @@ -296,9 +846,9 @@ static int nsvg__cmpEdge(const void *p, const void *q) } -static struct NSVGactiveEdge* nsvg__addActive(struct NSVGrasterizer* r, struct NSVGedge* e, float startPoint) +static NSVGactiveEdge* nsvg__addActive(NSVGrasterizer* r, NSVGedge* e, float startPoint) { - struct NSVGactiveEdge* z; + NSVGactiveEdge* z; if (r->freelist != NULL) { // Restore from freelist. @@ -306,7 +856,7 @@ static struct NSVGactiveEdge* nsvg__addActive(struct NSVGrasterizer* r, struct N r->freelist = z->next; } else { // Alloc new edge. - z = (struct NSVGactiveEdge*)nsvg__alloc(r, sizeof(struct NSVGactiveEdge)); + z = (NSVGactiveEdge*)nsvg__alloc(r, sizeof(NSVGactiveEdge)); if (z == NULL) return NULL; } @@ -314,10 +864,10 @@ static struct NSVGactiveEdge* nsvg__addActive(struct NSVGrasterizer* r, struct N // STBTT_assert(e->y0 <= start_point); // round dx down to avoid going too far if (dxdy < 0) - z->dx = -floorf(NSVG__FIX * -dxdy); + z->dx = (int)(-floorf(NSVG__FIX * -dxdy)); else - z->dx = floorf(NSVG__FIX * dxdy); - z->x = floorf(NSVG__FIX * (e->x0 + dxdy * (startPoint - e->y0))); + z->dx = (int)floorf(NSVG__FIX * dxdy); + z->x = (int)floorf(NSVG__FIX * (e->x0 + dxdy * (startPoint - e->y0))); // z->x -= off_x * FIX; z->ey = e->y1; z->next = 0; @@ -326,54 +876,73 @@ static struct NSVGactiveEdge* nsvg__addActive(struct NSVGrasterizer* r, struct N return z; } -static void nsvg__freeActive(struct NSVGrasterizer* r, struct NSVGactiveEdge* z) +static void nsvg__freeActive(NSVGrasterizer* r, NSVGactiveEdge* z) { z->next = r->freelist; r->freelist = z; } +static void nsvg__fillScanline(unsigned char* scanline, int len, int x0, int x1, int maxWeight, int* xmin, int* xmax) +{ + int i = x0 >> NSVG__FIXSHIFT; + int j = x1 >> NSVG__FIXSHIFT; + if (i < *xmin) *xmin = i; + if (j > *xmax) *xmax = j; + if (i < len && j >= 0) { + if (i == j) { + // x0,x1 are the same pixel, so compute combined coverage + scanline[i] += (unsigned char)((x1 - x0) * maxWeight >> NSVG__FIXSHIFT); + } else { + if (i >= 0) // add antialiasing for x0 + scanline[i] += (unsigned char)(((NSVG__FIX - (x0 & NSVG__FIXMASK)) * maxWeight) >> NSVG__FIXSHIFT); + else + i = -1; // clip + + if (j < len) // add antialiasing for x1 + scanline[j] += (unsigned char)(((x1 & NSVG__FIXMASK) * maxWeight) >> NSVG__FIXSHIFT); + else + j = len; // clip + + for (++i; i < j; ++i) // fill pixels between x0 and x1 + scanline[i] += (unsigned char)maxWeight; + } + } +} + // note: this routine clips fills that extend off the edges... ideally this // wouldn't happen, but it could happen if the truetype glyph bounding boxes // are wrong, or if the user supplies a too-small bitmap -static void nsvg__fillActiveEdges(unsigned char* scanline, int len, struct NSVGactiveEdge* e, int maxWeight, int* xmin, int* xmax) +static void nsvg__fillActiveEdges(unsigned char* scanline, int len, NSVGactiveEdge* e, int maxWeight, int* xmin, int* xmax, char fillRule) { // non-zero winding fill int x0 = 0, w = 0; - while (e != NULL) { - if (w == 0) { - // if we're currently at zero, we need to record the edge start point - x0 = e->x; w += e->dir; - } else { - int x1 = e->x; w += e->dir; - // if we went to zero, we need to draw + if (fillRule == NSVG_FILLRULE_NONZERO) { + // Non-zero + while (e != NULL) { if (w == 0) { - int i = x0 >> NSVG__FIXSHIFT; - int j = x1 >> NSVG__FIXSHIFT; - if (i < *xmin) *xmin = i; - if (j > *xmax) *xmax = j; - if (i < len && j >= 0) { - if (i == j) { - // x0,x1 are the same pixel, so compute combined coverage - scanline[i] += (unsigned char)((x1 - x0) * maxWeight >> NSVG__FIXSHIFT); - } else { - if (i >= 0) // add antialiasing for x0 - scanline[i] += (unsigned char)(((NSVG__FIX - (x0 & NSVG__FIXMASK)) * maxWeight) >> NSVG__FIXSHIFT); - else - i = -1; // clip - - if (j < len) // add antialiasing for x1 - scanline[j] += (unsigned char)(((x1 & NSVG__FIXMASK) * maxWeight) >> NSVG__FIXSHIFT); - else - j = len; // clip - - for (++i; i < j; ++i) // fill pixels between x0 and x1 - scanline[i] += (unsigned char)maxWeight; - } - } + // if we're currently at zero, we need to record the edge start point + x0 = e->x; w += e->dir; + } else { + int x1 = e->x; w += e->dir; + // if we went to zero, we need to draw + if (w == 0) + nsvg__fillScanline(scanline, len, x0, x1, maxWeight, xmin, xmax); } + e = e->next; + } + } else if (fillRule == NSVG_FILLRULE_EVENODD) { + // Even-odd + while (e != NULL) { + if (w == 0) { + // if we're currently at zero, we need to record the edge start point + x0 = e->x; w = 1; + } else { + int x1 = e->x; w = 0; + nsvg__fillScanline(scanline, len, x0, x1, maxWeight, xmin, xmax); + } + e = e->next; } - e = e->next; } } @@ -386,26 +955,31 @@ static unsigned int nsvg__RGBA(unsigned char r, unsigned char g, unsigned char b static unsigned int nsvg__lerpRGBA(unsigned int c0, unsigned int c1, float u) { - int iu = (float)(nsvg__clampf(u, 0.0f, 1.0f) * 256.0f); + int iu = (int)(nsvg__clampf(u, 0.0f, 1.0f) * 256.0f); int r = (((c0) & 0xff)*(256-iu) + (((c1) & 0xff)*iu)) >> 8; int g = (((c0>>8) & 0xff)*(256-iu) + (((c1>>8) & 0xff)*iu)) >> 8; int b = (((c0>>16) & 0xff)*(256-iu) + (((c1>>16) & 0xff)*iu)) >> 8; int a = (((c0>>24) & 0xff)*(256-iu) + (((c1>>24) & 0xff)*iu)) >> 8; - return nsvg__RGBA(r,g,b,a); + return nsvg__RGBA((unsigned char)r, (unsigned char)g, (unsigned char)b, (unsigned char)a); } static unsigned int nsvg__applyOpacity(unsigned int c, float u) { - int iu = (float)(nsvg__clampf(u, 0.0f, 1.0f) * 256.0f); + int iu = (int)(nsvg__clampf(u, 0.0f, 1.0f) * 256.0f); int r = (c) & 0xff; int g = (c>>8) & 0xff; int b = (c>>16) & 0xff; int a = (((c>>24) & 0xff)*iu) >> 8; - return nsvg__RGBA(r,g,b,a); + return nsvg__RGBA((unsigned char)r, (unsigned char)g, (unsigned char)b, (unsigned char)a); +} + +static inline int nsvg__div255(int x) +{ + return ((x+1) * 257) >> 16; } static void nsvg__scanlineSolid(unsigned char* dst, int count, unsigned char* cover, int x, int y, - float tx, float ty, float scale, struct NSVGcachedPaint* cache) + float tx, float ty, float scale, NSVGcachedPaint* cache) { if (cache->type == NSVG_PAINT_COLOR) { @@ -417,18 +991,18 @@ static void nsvg__scanlineSolid(unsigned char* dst, int count, unsigned char* co for (i = 0; i < count; i++) { int r,g,b; - int a = ((int)cover[0] * ca) >> 8; + int a = nsvg__div255((int)cover[0] * ca); int ia = 255 - a; // Premultiply - r = (cr * a) >> 8; - g = (cg * a) >> 8; - b = (cb * a) >> 8; + r = nsvg__div255(cr * a); + g = nsvg__div255(cg * a); + b = nsvg__div255(cb * a); // Blend over - r += ((ia * (int)dst[0]) >> 8); - g += ((ia * (int)dst[1]) >> 8); - b += ((ia * (int)dst[2]) >> 8); - a += ((ia * (int)dst[3]) >> 8); + r += nsvg__div255(ia * (int)dst[0]); + g += nsvg__div255(ia * (int)dst[1]); + b += nsvg__div255(ia * (int)dst[2]); + a += nsvg__div255(ia * (int)dst[3]); dst[0] = (unsigned char)r; dst[1] = (unsigned char)g; @@ -459,19 +1033,19 @@ static void nsvg__scanlineSolid(unsigned char* dst, int count, unsigned char* co cb = (c >> 16) & 0xff; ca = (c >> 24) & 0xff; - a = ((int)cover[0] * ca) >> 8; + a = nsvg__div255((int)cover[0] * ca); ia = 255 - a; // Premultiply - r = (cr * a) >> 8; - g = (cg * a) >> 8; - b = (cb * a) >> 8; + r = nsvg__div255(cr * a); + g = nsvg__div255(cg * a); + b = nsvg__div255(cb * a); // Blend over - r += ((ia * (int)dst[0]) >> 8); - g += ((ia * (int)dst[1]) >> 8); - b += ((ia * (int)dst[2]) >> 8); - a += ((ia * (int)dst[3]) >> 8); + r += nsvg__div255(ia * (int)dst[0]); + g += nsvg__div255(ia * (int)dst[1]); + b += nsvg__div255(ia * (int)dst[2]); + a += nsvg__div255(ia * (int)dst[3]); dst[0] = (unsigned char)r; dst[1] = (unsigned char)g; @@ -506,19 +1080,19 @@ static void nsvg__scanlineSolid(unsigned char* dst, int count, unsigned char* co cb = (c >> 16) & 0xff; ca = (c >> 24) & 0xff; - a = ((int)cover[0] * ca) >> 8; + a = nsvg__div255((int)cover[0] * ca); ia = 255 - a; // Premultiply - r = (cr * a) >> 8; - g = (cg * a) >> 8; - b = (cb * a) >> 8; + r = nsvg__div255(cr * a); + g = nsvg__div255(cg * a); + b = nsvg__div255(cb * a); // Blend over - r += ((ia * (int)dst[0]) >> 8); - g += ((ia * (int)dst[1]) >> 8); - b += ((ia * (int)dst[2]) >> 8); - a += ((ia * (int)dst[3]) >> 8); + r += nsvg__div255(ia * (int)dst[0]); + g += nsvg__div255(ia * (int)dst[1]); + b += nsvg__div255(ia * (int)dst[2]); + a += nsvg__div255(ia * (int)dst[3]); dst[0] = (unsigned char)r; dst[1] = (unsigned char)g; @@ -532,9 +1106,9 @@ static void nsvg__scanlineSolid(unsigned char* dst, int count, unsigned char* co } } -static void nsvg__rasterizeSortedEdges(struct NSVGrasterizer *r, float tx, float ty, float scale, struct NSVGcachedPaint* cache) +static void nsvg__rasterizeSortedEdges(NSVGrasterizer *r, float tx, float ty, float scale, NSVGcachedPaint* cache, char fillRule) { - struct NSVGactiveEdge *active = NULL; + NSVGactiveEdge *active = NULL; int y, s; int e = 0; int maxWeight = (255 / NSVG__SUBSAMPLES); // weight per vertical scanline @@ -547,12 +1121,12 @@ static void nsvg__rasterizeSortedEdges(struct NSVGrasterizer *r, float tx, float for (s = 0; s < NSVG__SUBSAMPLES; ++s) { // find center of pixel for this scanline float scany = y*NSVG__SUBSAMPLES + s + 0.5f; - struct NSVGactiveEdge **step = &active; + NSVGactiveEdge **step = &active; // update all active edges; // remove all active edges that terminate before the center of this scanline while (*step) { - struct NSVGactiveEdge *z = *step; + NSVGactiveEdge *z = *step; if (z->ey <= scany) { *step = z->next; // delete from list // NSVG__assert(z->valid); @@ -569,8 +1143,8 @@ static void nsvg__rasterizeSortedEdges(struct NSVGrasterizer *r, float tx, float step = &active; while (*step && (*step)->next) { if ((*step)->x > (*step)->next->x) { - struct NSVGactiveEdge* t = *step; - struct NSVGactiveEdge* q = t->next; + NSVGactiveEdge* t = *step; + NSVGactiveEdge* q = t->next; t->next = q->next; q->next = t; *step = q; @@ -584,7 +1158,7 @@ static void nsvg__rasterizeSortedEdges(struct NSVGrasterizer *r, float tx, float // insert all edges that start before the center of this scanline -- omit ones that also end on this scanline while (e < r->nedges && r->edges[e].y0 <= scany) { if (r->edges[e].y1 > scany) { - struct NSVGactiveEdge* z = nsvg__addActive(r, &r->edges[e], scany); + NSVGactiveEdge* z = nsvg__addActive(r, &r->edges[e], scany); if (z == NULL) break; // find insertion point if (active == NULL) { @@ -595,7 +1169,7 @@ static void nsvg__rasterizeSortedEdges(struct NSVGrasterizer *r, float tx, float active = z; } else { // find thing to insert AFTER - struct NSVGactiveEdge* p = active; + NSVGactiveEdge* p = active; while (p->next && p->next->x < z->x) p = p->next; // at this point, p->next->x is NOT < z->x @@ -608,13 +1182,13 @@ static void nsvg__rasterizeSortedEdges(struct NSVGrasterizer *r, float tx, float // now process all active edges in non-zero fashion if (active != NULL) - nsvg__fillActiveEdges(r->scanline, r->width, active, maxWeight, &xmin, &xmax); + nsvg__fillActiveEdges(r->scanline, r->width, active, maxWeight, &xmin, &xmax, fillRule); } // Blit if (xmin < 0) xmin = 0; if (xmax > r->width-1) xmax = r->width-1; if (xmin <= xmax) { - nsvg__scanlineSolid(&r->bitmap[y * r->stride] + xmin*4, xmax-xmin+1, &r->scanline[xmin], xmin, y, tx,ty,scale,cache); + nsvg__scanlineSolid(&r->bitmap[y * r->stride] + xmin*4, xmax-xmin+1, &r->scanline[xmin], xmin, y, tx,ty, scale, cache); } } @@ -630,9 +1204,9 @@ static void nsvg__unpremultiplyAlpha(unsigned char* image, int w, int h, int str for (x = 0; x < w; x++) { int r = row[0], g = row[1], b = row[2], a = row[3]; if (a != 0) { - row[0] = (int)(r*255/a); - row[1] = (int)(g*255/a); - row[2] = (int)(b*255/a); + row[0] = (unsigned char)(r*255/a); + row[1] = (unsigned char)(g*255/a); + row[2] = (unsigned char)(b*255/a); } row += 4; } @@ -669,9 +1243,9 @@ static void nsvg__unpremultiplyAlpha(unsigned char* image, int w, int h, int str n++; } if (n > 0) { - row[0] = r/n; - row[1] = g/n; - row[2] = b/n; + row[0] = (unsigned char)(r/n); + row[1] = (unsigned char)(g/n); + row[2] = (unsigned char)(b/n); } } row += 4; @@ -680,10 +1254,10 @@ static void nsvg__unpremultiplyAlpha(unsigned char* image, int w, int h, int str } -static void nsvg__initPaint(struct NSVGcachedPaint* cache, struct NSVGpaint* paint, float opacity) +static void nsvg__initPaint(NSVGcachedPaint* cache, NSVGpaint* paint, float opacity) { int i, j; - struct NSVGgradient* grad; + NSVGgradient* grad; cache->type = paint->type; @@ -704,15 +1278,15 @@ static void nsvg__initPaint(struct NSVGcachedPaint* cache, struct NSVGpaint* pai for (i = 0; i < 256; i++) cache->colors[i] = nsvg__applyOpacity(grad->stops[i].color, opacity); } else { - unsigned int ca, cb; + unsigned int ca, cb = 0; float ua, ub, du, u; int ia, ib, count; ca = nsvg__applyOpacity(grad->stops[0].color, opacity); ua = nsvg__clampf(grad->stops[0].offset, 0, 1); ub = nsvg__clampf(grad->stops[grad->nstops-1].offset, ua, 1); - ia = ua * 255.0f; - ib = ub * 255.0f; + ia = (int)(ua * 255.0f); + ib = (int)(ub * 255.0f); for (i = 0; i < ia; i++) { cache->colors[i] = ca; } @@ -722,8 +1296,8 @@ static void nsvg__initPaint(struct NSVGcachedPaint* cache, struct NSVGpaint* pai cb = nsvg__applyOpacity(grad->stops[i+1].color, opacity); ua = nsvg__clampf(grad->stops[i].offset, 0, 1); ub = nsvg__clampf(grad->stops[i+1].offset, 0, 1); - ia = ua * 255.0f; - ib = ub * 255.0f; + ia = (int)(ua * 255.0f); + ib = (int)(ub * 255.0f); count = ib - ia; if (count <= 0) continue; u = 0; @@ -740,15 +1314,52 @@ static void nsvg__initPaint(struct NSVGcachedPaint* cache, struct NSVGpaint* pai } -void nsvgRasterize(struct NSVGrasterizer* r, - struct NSVGimage* image, float tx, float ty, float scale, +/* +static void dumpEdges(NSVGrasterizer* r, const char* name) +{ + float xmin = 0, xmax = 0, ymin = 0, ymax = 0; + NSVGedge *e = NULL; + int i; + if (r->nedges == 0) return; + FILE* fp = fopen(name, "w"); + if (fp == NULL) return; + xmin = xmax = r->edges[0].x0; + ymin = ymax = r->edges[0].y0; + for (i = 0; i < r->nedges; i++) { + e = &r->edges[i]; + xmin = nsvg__minf(xmin, e->x0); + xmin = nsvg__minf(xmin, e->x1); + xmax = nsvg__maxf(xmax, e->x0); + xmax = nsvg__maxf(xmax, e->x1); + ymin = nsvg__minf(ymin, e->y0); + ymin = nsvg__minf(ymin, e->y1); + ymax = nsvg__maxf(ymax, e->y0); + ymax = nsvg__maxf(ymax, e->y1); + } + fprintf(fp, "", xmin, ymin, (xmax - xmin), (ymax - ymin)); + for (i = 0; i < r->nedges; i++) { + e = &r->edges[i]; + fprintf(fp ,"", e->x0,e->y0, e->x1,e->y1); + } + for (i = 0; i < r->npoints; i++) { + if (i+1 < r->npoints) + fprintf(fp ,"", r->points[i].x, r->points[i].y, r->points[i+1].x, r->points[i+1].y); + fprintf(fp ,"", r->points[i].x, r->points[i].y, r->points[i].flags == 0 ? "#f00" : "#0f0"); + } + fprintf(fp, ""); + fclose(fp); +} +*/ + +void nsvgRasterize(NSVGrasterizer* r, + NSVGimage* image, float tx, float ty, float scale, unsigned char* dst, int w, int h, int stride) { - struct NSVGshape *shape = NULL; - struct NSVGedge *e = NULL; - struct NSVGcachedPaint cache; + NSVGshape *shape = NULL; + NSVGedge *e = NULL; + NSVGcachedPaint cache; int i; - + r->bitmap = dst; r->width = w; r->height = h; @@ -764,32 +1375,59 @@ void nsvgRasterize(struct NSVGrasterizer* r, memset(&dst[i*stride], 0, w*4); for (shape = image->shapes; shape != NULL; shape = shape->next) { - - if (shape->fill.type == NSVG_PAINT_NONE) + if (!(shape->flags & NSVG_FLAGS_VISIBLE)) continue; - nsvg__resetPool(r); - r->freelist = NULL; - r->nedges = 0; + if (shape->fill.type != NSVG_PAINT_NONE) { + nsvg__resetPool(r); + r->freelist = NULL; + r->nedges = 0; + + nsvg__flattenShape(r, shape, scale); - nsvg__flattenShape(r, shape, scale); + // Scale and translate edges + for (i = 0; i < r->nedges; i++) { + e = &r->edges[i]; + e->x0 = tx + e->x0; + e->y0 = (ty + e->y0) * NSVG__SUBSAMPLES; + e->x1 = tx + e->x1; + e->y1 = (ty + e->y1) * NSVG__SUBSAMPLES; + } - // Scale and translate edges - for (i = 0; i < r->nedges; i++) { - e = &r->edges[i]; - e->x0 = tx + e->x0 * scale; - e->y0 = (ty + e->y0 * scale) * NSVG__SUBSAMPLES; - e->x1 = tx + e->x1 * scale; - e->y1 = (ty + e->y1 * scale) * NSVG__SUBSAMPLES; + // Rasterize edges + qsort(r->edges, r->nedges, sizeof(NSVGedge), nsvg__cmpEdge); + + // now, traverse the scanlines and find the intersections on each scanline, use non-zero rule + nsvg__initPaint(&cache, &shape->fill, shape->opacity); + + nsvg__rasterizeSortedEdges(r, tx,ty,scale, &cache, shape->fillRule); } + if (shape->stroke.type != NSVG_PAINT_NONE && (shape->strokeWidth * scale) > 0.01f) { + nsvg__resetPool(r); + r->freelist = NULL; + r->nedges = 0; + + nsvg__flattenShapeStroke(r, shape, scale); + +// dumpEdges(r, "edge.svg"); + + // Scale and translate edges + for (i = 0; i < r->nedges; i++) { + e = &r->edges[i]; + e->x0 = tx + e->x0; + e->y0 = (ty + e->y0) * NSVG__SUBSAMPLES; + e->x1 = tx + e->x1; + e->y1 = (ty + e->y1) * NSVG__SUBSAMPLES; + } - // Rasterize edges - qsort(r->edges, r->nedges, sizeof(struct NSVGedge), nsvg__cmpEdge); + // Rasterize edges + qsort(r->edges, r->nedges, sizeof(NSVGedge), nsvg__cmpEdge); - // now, traverse the scanlines and find the intersections on each scanline, use non-zero rule - nsvg__initPaint(&cache, &shape->fill, shape->opacity); - - nsvg__rasterizeSortedEdges(r, tx,ty,scale, &cache); + // now, traverse the scanlines and find the intersections on each scanline, use non-zero rule + nsvg__initPaint(&cache, &shape->stroke, shape->opacity); + + nsvg__rasterizeSortedEdges(r, tx,ty,scale, &cache, NSVG_FILLRULE_NONZERO); + } } nsvg__unpremultiplyAlpha(dst, w, h, stride); From 23d96b6a5667c6db1c1876b99841161f8478729a Mon Sep 17 00:00:00 2001 From: Jools Wills Date: Wed, 20 Apr 2016 23:22:10 +0100 Subject: [PATCH 20/74] allow emulationstation.sh to be called from any location (gets basename from $0) --- emulationstation.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/emulationstation.sh b/emulationstation.sh index cc48aed670..227078f06d 100755 --- a/emulationstation.sh +++ b/emulationstation.sh @@ -1,8 +1,9 @@ #!/bin/sh +esdir="$(dirname $0)" while true; do rm -f /tmp/es-restart /tmp/es-sysrestart /tmp/es-shutdown - ./emulationstation "$@" + "$esdir/emulationstation" "$@" [ -f /tmp/es-restart ] && continue if [ -f /tmp/es-sysrestart ]; then rm -f /tmp/es-sysrestart From ab8409da4137c5a328419c3cfed6a691aa395e5e Mon Sep 17 00:00:00 2001 From: Ken Taylor Date: Fri, 1 Jul 2016 22:14:41 -0700 Subject: [PATCH 21/74] Always reload input config after running onfinish script --- es-core/src/InputManager.cpp | 4 ++++ es-core/src/guis/GuiDetectDevice.cpp | 1 - es-core/src/guis/GuiInputConfig.cpp | 3 +-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/es-core/src/InputManager.cpp b/es-core/src/InputManager.cpp index 81bbb57704..04ca793647 100644 --- a/es-core/src/InputManager.cpp +++ b/es-core/src/InputManager.cpp @@ -348,6 +348,10 @@ void InputManager::writeDeviceConfig(InputConfig* config) config->writeToXML(root); doc.save_file(path.c_str()); + + // execute any onFinish commands and re-load the config for changes + doOnFinish(); + loadInputConfig(config); } void InputManager::doOnFinish() diff --git a/es-core/src/guis/GuiDetectDevice.cpp b/es-core/src/guis/GuiDetectDevice.cpp index b7fae13654..bf8e8e4cbe 100644 --- a/es-core/src/guis/GuiDetectDevice.cpp +++ b/es-core/src/guis/GuiDetectDevice.cpp @@ -107,7 +107,6 @@ void GuiDetectDevice::update(int deltaTime) // If ES starts and if a known device is connected after startup skip controller configuration if(mFirstRun && fs::exists(InputManager::getConfigPath()) && InputManager::getInstance()->getNumConfiguredDevices() > 0) { - InputManager::getInstance()->doOnFinish(); // execute possible onFinish commands if(mDoneCallback) mDoneCallback(); delete this; // delete GUI element diff --git a/es-core/src/guis/GuiInputConfig.cpp b/es-core/src/guis/GuiInputConfig.cpp index 78f598ff10..f03144e11e 100644 --- a/es-core/src/guis/GuiInputConfig.cpp +++ b/es-core/src/guis/GuiInputConfig.cpp @@ -259,7 +259,6 @@ GuiInputConfig::GuiInputConfig(Window* window, InputConfig* target, bool reconfi std::vector< std::shared_ptr > buttons; buttons.push_back(std::make_shared(mWindow, "OK", "ok", [this, okCallback] { InputManager::getInstance()->writeDeviceConfig(mTargetConfig); // save - InputManager::getInstance()->doOnFinish(); // execute possible onFinish commands if(okCallback) okCallback(); delete this; @@ -388,4 +387,4 @@ bool GuiInputConfig::assign(Input input, int inputId) void GuiInputConfig::clearAssignment(int inputId) { mTargetConfig->unmapInput(inputName[inputId]); -} \ No newline at end of file +} From a78c9721be5fd3f535b21a78e73d337174955d4d Mon Sep 17 00:00:00 2001 From: Jools Wills Date: Mon, 4 Jul 2016 00:29:53 +0100 Subject: [PATCH 22/74] rename buttons to avoid confusion (bottom -> shoulder / top -> trigger). --- es-core/src/guis/GuiInputConfig.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/es-core/src/guis/GuiInputConfig.cpp b/es-core/src/guis/GuiInputConfig.cpp index 78f598ff10..c28bfee05f 100644 --- a/es-core/src/guis/GuiInputConfig.cpp +++ b/es-core/src/guis/GuiInputConfig.cpp @@ -28,10 +28,10 @@ static const char* inputName[inputCount] = "B", "X", "Y", - "LeftBottom", - "RightBottom", - "LeftTop", - "RightTop", + "LeftShoulder", + "RightShoulder", + "LeftTrigger", + "RightTrigger", "LeftThumb", "RightThumb", "LeftAnalogUp", @@ -82,10 +82,10 @@ static const char* inputDispName[inputCount] = "B", "X", "Y", - "LEFT BOTTOM", - "RIGHT BOTTOM", - "LEFT TOP", - "RIGHT TOP", + "LEFT SHOULDER", + "RIGHT SHOULDER", + "LEFT TRIGGER", + "RIGHT TRIGGER", "LEFT THUMB", "RIGHT THUMB", "LEFT ANALOG UP", From f3cf36fd94aa57e577d5c44ae0fa5c9bd011df52 Mon Sep 17 00:00:00 2001 From: "M. Broncano" Date: Sat, 23 Jul 2016 04:11:44 +0000 Subject: [PATCH 23/74] Fixes libGL problem --- es-core/src/Window.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/es-core/src/Window.cpp b/es-core/src/Window.cpp index 76bb1754e3..d9dea20508 100644 --- a/es-core/src/Window.cpp +++ b/es-core/src/Window.cpp @@ -13,7 +13,6 @@ Window::Window() : mNormalizeNextUpdate(false), mFrameTimeElapsed(0), mFrameCoun { mHelp = new HelpComponent(this); mBackgroundOverlay = new ImageComponent(this); - mBackgroundOverlay->setImage(":/scroll_gradient.png"); } Window::~Window() @@ -65,6 +64,8 @@ bool Window::init(unsigned int width, unsigned int height) return false; } + mBackgroundOverlay->setImage(":/scroll_gradient.png"); + InputManager::getInstance()->init(); ResourceManager::getInstance()->reloadAll(); From 0ab75f8996c01d27972a2cac4e86d72fa6939f3e Mon Sep 17 00:00:00 2001 From: Alex Jones Date: Wed, 3 Aug 2016 19:09:59 +0100 Subject: [PATCH 24/74] Add eclipse files to .gitignore --- .gitignore | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.gitignore b/.gitignore index 063da9dcf9..0686c4180e 100644 --- a/.gitignore +++ b/.gitignore @@ -29,3 +29,8 @@ CMakeCache.txt CMakeFiles cmake_install.cmake Makefile + +# Eclipse +.cproject +.project +.settings/ From fa513e4c2de1897484a4f64981938ca6f80033b7 Mon Sep 17 00:00:00 2001 From: Jools Wills Date: Wed, 10 Aug 2016 02:48:04 +0100 Subject: [PATCH 25/74] cosmetic - spaces -> tabs to match rest of file --- es-core/src/InputManager.cpp | 172 ++++++++++++------------ es-core/src/guis/GuiInputConfig.cpp | 194 ++++++++++++++-------------- 2 files changed, 183 insertions(+), 183 deletions(-) diff --git a/es-core/src/InputManager.cpp b/es-core/src/InputManager.cpp index 04ca793647..f03fbc14ec 100644 --- a/es-core/src/InputManager.cpp +++ b/es-core/src/InputManager.cpp @@ -293,54 +293,54 @@ void InputManager::loadDefaultKBConfig() void InputManager::writeDeviceConfig(InputConfig* config) { - assert(initialized()); - - std::string path = getConfigPath(); - - pugi::xml_document doc; - - if(fs::exists(path)) - { - // merge files - pugi::xml_parse_result result = doc.load_file(path.c_str()); - if(!result) - { - LOG(LogError) << "Error parsing input config: " << result.description(); - } - else - { - // successfully loaded, delete the old entry if it exists - pugi::xml_node root = doc.child("inputList"); - if(root) - { - // if inputAction @type=onfinish is set, let onfinish command take care for creating input configuration. - // we just put the input configuration into a temporary input config file. - pugi::xml_node actionnode = root.find_child_by_attribute("inputAction", "type", "onfinish"); - if(actionnode) - { - path = getTemporaryConfigPath(); - doc.reset(); - root = doc.append_child("inputList"); - root.append_copy(actionnode); - } - else - { - pugi::xml_node oldEntry = root.find_child_by_attribute("inputConfig", "deviceGUID", - config->getDeviceGUIDString().c_str()); - if(oldEntry) - { - root.remove_child(oldEntry); - } - oldEntry = root.find_child_by_attribute("inputConfig", "deviceName", - config->getDeviceName().c_str()); - if(oldEntry) - { - root.remove_child(oldEntry); - } - } - } - } - } + assert(initialized()); + + std::string path = getConfigPath(); + + pugi::xml_document doc; + + if(fs::exists(path)) + { + // merge files + pugi::xml_parse_result result = doc.load_file(path.c_str()); + if(!result) + { + LOG(LogError) << "Error parsing input config: " << result.description(); + } + else + { + // successfully loaded, delete the old entry if it exists + pugi::xml_node root = doc.child("inputList"); + if(root) + { + // if inputAction @type=onfinish is set, let onfinish command take care for creating input configuration. + // we just put the input configuration into a temporary input config file. + pugi::xml_node actionnode = root.find_child_by_attribute("inputAction", "type", "onfinish"); + if(actionnode) + { + path = getTemporaryConfigPath(); + doc.reset(); + root = doc.append_child("inputList"); + root.append_copy(actionnode); + } + else + { + pugi::xml_node oldEntry = root.find_child_by_attribute("inputConfig", "deviceGUID", + config->getDeviceGUIDString().c_str()); + if(oldEntry) + { + root.remove_child(oldEntry); + } + oldEntry = root.find_child_by_attribute("inputConfig", "deviceName", + config->getDeviceName().c_str()); + if(oldEntry) + { + root.remove_child(oldEntry); + } + } + } + } + } pugi::xml_node root = doc.child("inputList"); if(!root) @@ -356,44 +356,44 @@ void InputManager::writeDeviceConfig(InputConfig* config) void InputManager::doOnFinish() { - assert(initialized()); - std::string path = getConfigPath(); - pugi::xml_document doc; - - if(fs::exists(path)) - { - pugi::xml_parse_result result = doc.load_file(path.c_str()); - if(!result) - { - LOG(LogError) << "Error parsing input config: " << result.description(); - } - else - { - pugi::xml_node root = doc.child("inputList"); - if(root) - { - root = root.find_child_by_attribute("inputAction", "type", "onfinish"); - if(root) - { - for(pugi::xml_node command = root.child("command"); command; - command = command.next_sibling("command")) - { - std::string tocall = command.text().get(); - - LOG(LogInfo) << " " << tocall; - std::cout << "==============================================\ninput config finish command:\n"; - int exitCode = runSystemCommand(tocall); - std::cout << "==============================================\n"; - - if(exitCode != 0) - { - LOG(LogWarning) << "...launch terminated with nonzero exit code " << exitCode << "!"; - } - } - } - } - } - } + assert(initialized()); + std::string path = getConfigPath(); + pugi::xml_document doc; + + if(fs::exists(path)) + { + pugi::xml_parse_result result = doc.load_file(path.c_str()); + if(!result) + { + LOG(LogError) << "Error parsing input config: " << result.description(); + } + else + { + pugi::xml_node root = doc.child("inputList"); + if(root) + { + root = root.find_child_by_attribute("inputAction", "type", "onfinish"); + if(root) + { + for(pugi::xml_node command = root.child("command"); command; + command = command.next_sibling("command")) + { + std::string tocall = command.text().get(); + + LOG(LogInfo) << " " << tocall; + std::cout << "==============================================\ninput config finish command:\n"; + int exitCode = runSystemCommand(tocall); + std::cout << "==============================================\n"; + + if(exitCode != 0) + { + LOG(LogWarning) << "...launch terminated with nonzero exit code " << exitCode << "!"; + } + } + } + } + } + } } std::string InputManager::getConfigPath() diff --git a/es-core/src/guis/GuiInputConfig.cpp b/es-core/src/guis/GuiInputConfig.cpp index d0238ebe8c..996133596b 100644 --- a/es-core/src/guis/GuiInputConfig.cpp +++ b/es-core/src/guis/GuiInputConfig.cpp @@ -18,111 +18,111 @@ static const int inputCount = 24; static const char* inputName[inputCount] = { - "Up", - "Down", - "Left", - "Right", - "Start", - "Select", - "A", - "B", - "X", - "Y", - "LeftShoulder", - "RightShoulder", - "LeftTrigger", - "RightTrigger", - "LeftThumb", - "RightThumb", - "LeftAnalogUp", - "LeftAnalogDown", - "LeftAnalogLeft", - "LeftAnalogRight", - "RightAnalogUp", - "RightAnalogDown", - "RightAnalogLeft", - "RightAnalogRight" + "Up", + "Down", + "Left", + "Right", + "Start", + "Select", + "A", + "B", + "X", + "Y", + "LeftShoulder", + "RightShoulder", + "LeftTrigger", + "RightTrigger", + "LeftThumb", + "RightThumb", + "LeftAnalogUp", + "LeftAnalogDown", + "LeftAnalogLeft", + "LeftAnalogRight", + "RightAnalogUp", + "RightAnalogDown", + "RightAnalogLeft", + "RightAnalogRight" }; static const bool inputSkippable[inputCount] = { - false, - false, - false, - false, - true, - true, - false, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true + false, + false, + false, + false, + true, + true, + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true }; static const char* inputDispName[inputCount] = { - "D-PAD UP", - "D-PAD DOWN", - "D-PAD LEFT", - "D-PAD RIGHT", - "START", - "SELECT", - "A", - "B", - "X", - "Y", - "LEFT SHOULDER", - "RIGHT SHOULDER", - "LEFT TRIGGER", - "RIGHT TRIGGER", - "LEFT THUMB", - "RIGHT THUMB", - "LEFT ANALOG UP", - "LEFT ANALOG DOWN", - "LEFT ANALOG LEFT", - "LEFT ANALOG RIGHT", - "RIGHT ANALOG UP", - "RIGHT ANALOG DOWN", - "RIGHT ANALOG LEFT", - "RIGHT ANALOG RIGHT" + "D-PAD UP", + "D-PAD DOWN", + "D-PAD LEFT", + "D-PAD RIGHT", + "START", + "SELECT", + "A", + "B", + "X", + "Y", + "LEFT SHOULDER", + "RIGHT SHOULDER", + "LEFT TRIGGER", + "RIGHT TRIGGER", + "LEFT THUMB", + "RIGHT THUMB", + "LEFT ANALOG UP", + "LEFT ANALOG DOWN", + "LEFT ANALOG LEFT", + "LEFT ANALOG RIGHT", + "RIGHT ANALOG UP", + "RIGHT ANALOG DOWN", + "RIGHT ANALOG LEFT", + "RIGHT ANALOG RIGHT" }; static const char* inputIcon[inputCount] = { - ":/help/dpad_up.svg", - ":/help/dpad_down.svg", - ":/help/dpad_left.svg", - ":/help/dpad_right.svg", - ":/help/button_start.svg", - ":/help/button_select.svg", - ":/help/button_a.svg", - ":/help/button_b.svg", - ":/help/button_x.svg", - ":/help/button_y.svg", - ":/help/button_l.svg", - ":/help/button_r.svg", - ":/help/button_l.svg", - ":/help/button_r.svg", - ":/help/analog_thumb.svg", - ":/help/analog_thumb.svg", - ":/help/analog_up.svg", - ":/help/analog_down.svg", - ":/help/analog_left.svg", - ":/help/analog_right.svg", - ":/help/analog_up.svg", - ":/help/analog_down.svg", - ":/help/analog_left.svg", - ":/help/analog_right.svg" + ":/help/dpad_up.svg", + ":/help/dpad_down.svg", + ":/help/dpad_left.svg", + ":/help/dpad_right.svg", + ":/help/button_start.svg", + ":/help/button_select.svg", + ":/help/button_a.svg", + ":/help/button_b.svg", + ":/help/button_x.svg", + ":/help/button_y.svg", + ":/help/button_l.svg", + ":/help/button_r.svg", + ":/help/button_l.svg", + ":/help/button_r.svg", + ":/help/analog_thumb.svg", + ":/help/analog_thumb.svg", + ":/help/analog_up.svg", + ":/help/analog_down.svg", + ":/help/analog_left.svg", + ":/help/analog_right.svg", + ":/help/analog_up.svg", + ":/help/analog_down.svg", + ":/help/analog_left.svg", + ":/help/analog_right.svg" }; //MasterVolUp and MasterVolDown are also hooked up, but do not appear on this screen. @@ -285,7 +285,7 @@ void GuiInputConfig::onSizeChanged() mGrid.setRowHeightPerc(5, (mList->getRowHeight(0) * 5 + 2) / mSize.y()); mGrid.setRowHeightPerc(6, mButtonGrid->getSize().y() / mSize.y()); - mBusyAnim.setSize(mSize); + mBusyAnim.setSize(mSize); } void GuiInputConfig::update(int deltaTime) From 454a18f9ec0ba6ff83d565914d1c87c03dd0f5be Mon Sep 17 00:00:00 2001 From: Alex Jones Date: Tue, 9 Aug 2016 21:26:30 +0100 Subject: [PATCH 26/74] Trust the gamelist by not checking whether files exist and also improve the algorithm for parsing the gamelist. --- es-app/src/FileData.cpp | 15 ++++++++++----- es-app/src/FileData.h | 5 ++++- es-app/src/Gamelist.cpp | 35 ++++++++++++++++++++--------------- es-app/src/SystemData.cpp | 4 ++-- es-core/src/Util.cpp | 14 ++++++++++++++ es-core/src/Util.h | 1 + 6 files changed, 51 insertions(+), 23 deletions(-) diff --git a/es-app/src/FileData.cpp b/es-app/src/FileData.cpp index f9f28185b8..0b151b6e20 100644 --- a/es-app/src/FileData.cpp +++ b/es-app/src/FileData.cpp @@ -56,8 +56,7 @@ FileData::~FileData() if(mParent) mParent->removeChild(this); - while(mChildren.size()) - delete mChildren.back(); + mChildren.clear(); } std::string FileData::getDisplayName() const @@ -107,15 +106,20 @@ void FileData::addChild(FileData* file) assert(mType == FOLDER); assert(file->getParent() == NULL); - mChildren.push_back(file); - file->mParent = this; + const std::string key = file->getPath().filename().string(); + if (mChildrenByFilename.find(key) == mChildrenByFilename.end()) + { + mChildrenByFilename[key] = file; + mChildren.push_back(file); + file->mParent = this; + } } void FileData::removeChild(FileData* file) { assert(mType == FOLDER); assert(file->getParent() == this); - + mChildrenByFilename.erase(file->getPath().filename().string()); for(auto it = mChildren.begin(); it != mChildren.end(); it++) { if(*it == file) @@ -127,6 +131,7 @@ void FileData::removeChild(FileData* file) // File somehow wasn't in our children. assert(false); + } void FileData::sort(ComparisonFunction& comparator, bool ascending) diff --git a/es-app/src/FileData.h b/es-app/src/FileData.h index 99fba06710..f21ca8f9dc 100644 --- a/es-app/src/FileData.h +++ b/es-app/src/FileData.h @@ -1,7 +1,8 @@ #pragma once -#include +#include #include +#include #include #include "MetaData.h" @@ -39,6 +40,7 @@ class FileData inline FileType getType() const { return mType; } inline const boost::filesystem::path& getPath() const { return mPath; } inline FileData* getParent() const { return mParent; } + inline const std::unordered_map& getChildrenByFilename() const { return mChildrenByFilename; } inline const std::vector& getChildren() const { return mChildren; } inline SystemData* getSystem() const { return mSystem; } @@ -76,5 +78,6 @@ class FileData boost::filesystem::path mPath; SystemData* mSystem; FileData* mParent; + std::unordered_map mChildrenByFilename; std::vector mChildren; }; diff --git a/es-app/src/Gamelist.cpp b/es-app/src/Gamelist.cpp index 9caeda354e..8f3db352d0 100644 --- a/es-app/src/Gamelist.cpp +++ b/es-app/src/Gamelist.cpp @@ -8,13 +8,21 @@ namespace fs = boost::filesystem; -FileData* findOrCreateFile(SystemData* system, const boost::filesystem::path& path, FileType type) +FileData* findOrCreateFile(SystemData* system, const boost::filesystem::path& path, FileType type, bool trustGamelist) { // first, verify that path is within the system's root folder FileData* root = system->getRootFolder(); - + + fs::path relative; bool contains = false; - fs::path relative = removeCommonPath(path, root->getPath(), contains); + if (trustGamelist) + { + relative = removeCommonPathUsingStrings(path, root->getPath(), contains); + } + else + { + relative = removeCommonPath(path, root->getPath(), contains); + } if(!contains) { LOG(LogError) << "File path \"" << path << "\" is outside system path \"" << system->getStartPath() << "\""; @@ -26,16 +34,12 @@ FileData* findOrCreateFile(SystemData* system, const boost::filesystem::path& pa bool found = false; while(path_it != relative.end()) { - const std::vector& children = treeNode->getChildren(); - found = false; - for(auto child_it = children.begin(); child_it != children.end(); child_it++) - { - if((*child_it)->getPath().filename() == *path_it) - { - treeNode = *child_it; - found = true; - break; - } + const std::unordered_map& children = treeNode->getChildrenByFilename(); + + std::string key = path_it->string(); + found = children.find(key) != children.end(); + if (found) { + treeNode = children.at(key); } // this is the end @@ -79,6 +83,7 @@ FileData* findOrCreateFile(SystemData* system, const boost::filesystem::path& pa void parseGamelist(SystemData* system) { + bool trustGamelist = Settings::getInstance()->getBool("ParseGamelistOnly"); std::string xmlpath = system->getGamelistPath(false); if(!boost::filesystem::exists(xmlpath)) @@ -114,13 +119,13 @@ void parseGamelist(SystemData* system) { fs::path path = resolvePath(fileNode.child("path").text().get(), relativeTo, false); - if(!boost::filesystem::exists(path)) + if(!trustGamelist && !boost::filesystem::exists(path)) { LOG(LogWarning) << "File \"" << path << "\" does not exist! Ignoring."; continue; } - FileData* file = findOrCreateFile(system, path, type); + FileData* file = findOrCreateFile(system, path, type, trustGamelist); if(!file) { LOG(LogError) << "Error finding/creating FileData for \"" << path << "\", skipping."; diff --git a/es-app/src/SystemData.cpp b/es-app/src/SystemData.cpp index 95345ed636..cb46f1c47c 100644 --- a/es-app/src/SystemData.cpp +++ b/es-app/src/SystemData.cpp @@ -198,7 +198,7 @@ void SystemData::populateFolder(FileData* folder) populateFolder(newFolder); //ignore folders that do not contain games - if(newFolder->getChildren().size() == 0) + if(newFolder->getChildrenByFilename().size() == 0) delete newFolder; else folder->addChild(newFolder); @@ -311,7 +311,7 @@ bool SystemData::loadConfig() path = genericPath.generic_string(); SystemData* newSys = new SystemData(name, fullname, path, extensions, cmd, platformIds, themeFolder); - if(newSys->getRootFolder()->getChildren().size() == 0) + if(newSys->getRootFolder()->getChildrenByFilename().size() == 0) { LOG(LogWarning) << "System \"" << name << "\" has no games! Ignoring it."; delete newSys; diff --git a/es-core/src/Util.cpp b/es-core/src/Util.cpp index 8c7dc0c921..80560a2baa 100644 --- a/es-core/src/Util.cpp +++ b/es-core/src/Util.cpp @@ -100,6 +100,20 @@ fs::path resolvePath(const fs::path& path, const fs::path& relativeTo, bool allo return path; } +fs::path removeCommonPathUsingStrings(const fs::path& path, const fs::path& relativeTo, bool& contains) +{ + std::string pathStr = path.c_str(); + std::string relativeToStr = relativeTo.c_str(); + if (pathStr.find_first_of(relativeToStr) == 0) { + contains = true; + return pathStr.substr(relativeToStr.size() + 1); + } + else { + contains = false; + return path; + } +} + // example: removeCommonPath("/home/pi/roms/nes/foo/bar.nes", "/home/pi/roms/nes/") returns "foo/bar.nes" fs::path removeCommonPath(const fs::path& path, const fs::path& relativeTo, bool& contains) { diff --git a/es-core/src/Util.h b/es-core/src/Util.h index 5bf2a12752..507ceecfd6 100644 --- a/es-core/src/Util.h +++ b/es-core/src/Util.h @@ -19,6 +19,7 @@ float round(float num); std::string getCanonicalPath(const std::string& str); +boost::filesystem::path removeCommonPathUsingStrings(const boost::filesystem::path& path, const boost::filesystem::path& relativeTo, bool& contains); // example: removeCommonPath("/home/pi/roms/nes/foo/bar.nes", "/home/pi/roms/nes/") returns "foo/bar.nes" boost::filesystem::path removeCommonPath(const boost::filesystem::path& path, const boost::filesystem::path& relativeTo, bool& contains); From c5b74947a0f85c2cababf790e02ed781eb48e557 Mon Sep 17 00:00:00 2001 From: Jools Wills Date: Sat, 13 Aug 2016 01:40:50 +0100 Subject: [PATCH 27/74] workaround for analogue trigger configuration - eg with xpad. Unlike other axis, they don't default to 0, but instead start at -32768 and go to +32767 when pressed. This confuses the current ES code axis code. As a workaround, we get the initial value and if it is -32767, we add 32767 and divide by two. This gives it a range that can be handled with the current code (from 0 to 32767). Note on my X11 machine, I had to plug the joystick in after ES was loaded or it get 0 as the initial axis value for the triggers. This seems ok on the RPI though, so possible some SDL issue. With this change on a 360 controller the triggers should be correctly detected as +2 and +5 without seeing two presses for each trigger press. --- es-core/src/InputManager.cpp | 24 +++++++++++++++++++----- es-core/src/InputManager.h | 1 + 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/es-core/src/InputManager.cpp b/es-core/src/InputManager.cpp index f03fbc14ec..c1d2db5a97 100644 --- a/es-core/src/InputManager.cpp +++ b/es-core/src/InputManager.cpp @@ -89,7 +89,14 @@ void InputManager::addJoystickByDeviceIndex(int id) // set up the prevAxisValues int numAxes = SDL_JoystickNumAxes(joy); mPrevAxisValues[joyId] = new int[numAxes]; - std::fill(mPrevAxisValues[joyId], mPrevAxisValues[joyId] + numAxes, 0); //initialize array to 0 + mInitAxisValues[joyId] = new int[numAxes]; + + int axis; + for (int i = 0; i< numAxes; i++) { + axis = SDL_JoystickGetAxis(joy, i); + mInitAxisValues[joyId][i] = axis; + mPrevAxisValues[joyId][i] = axis; + } } void InputManager::removeJoystickByJoystickID(SDL_JoystickID joyId) @@ -170,21 +177,28 @@ InputConfig* InputManager::getInputConfigByDevice(int device) bool InputManager::parseEvent(const SDL_Event& ev, Window* window) { bool causedEvent = false; + int axis; + int deadzone = DEADZONE; switch(ev.type) { case SDL_JOYAXISMOTION: + axis = ev.jaxis.value; + if (mInitAxisValues[ev.jaxis.which][ev.jaxis.axis] == -32768) + { + deadzone /= 2; + axis = (axis + 32767) / 2; + } //if it switched boundaries - if((abs(ev.jaxis.value) > DEADZONE) != (abs(mPrevAxisValues[ev.jaxis.which][ev.jaxis.axis]) > DEADZONE)) + if((abs(axis) > deadzone) != (abs(mPrevAxisValues[ev.jaxis.which][ev.jaxis.axis]) > deadzone)) { int normValue; - if(abs(ev.jaxis.value) <= DEADZONE) + if(abs(axis) <= deadzone) normValue = 0; else - if(ev.jaxis.value > 0) + if(axis > 0) normValue = 1; else normValue = -1; - window->input(getInputConfigByDevice(ev.jaxis.which), Input(ev.jaxis.which, TYPE_AXIS, ev.jaxis.axis, normValue, false)); causedEvent = true; } diff --git a/es-core/src/InputManager.h b/es-core/src/InputManager.h index 7408356342..295fa87f74 100644 --- a/es-core/src/InputManager.h +++ b/es-core/src/InputManager.h @@ -26,6 +26,7 @@ class InputManager InputConfig* mKeyboardInputConfig; std::map mPrevAxisValues; + std::map mInitAxisValues; bool initialized() const; From 3eba889bdf4466bb6f39c144ef58959033907dbe Mon Sep 17 00:00:00 2001 From: Jools Wills Date: Sun, 14 Aug 2016 20:24:39 +0100 Subject: [PATCH 28/74] Revert "workaround for analogue trigger configuration - eg with xpad." --- es-core/src/InputManager.cpp | 24 +++++------------------- es-core/src/InputManager.h | 1 - 2 files changed, 5 insertions(+), 20 deletions(-) diff --git a/es-core/src/InputManager.cpp b/es-core/src/InputManager.cpp index c1d2db5a97..f03fbc14ec 100644 --- a/es-core/src/InputManager.cpp +++ b/es-core/src/InputManager.cpp @@ -89,14 +89,7 @@ void InputManager::addJoystickByDeviceIndex(int id) // set up the prevAxisValues int numAxes = SDL_JoystickNumAxes(joy); mPrevAxisValues[joyId] = new int[numAxes]; - mInitAxisValues[joyId] = new int[numAxes]; - - int axis; - for (int i = 0; i< numAxes; i++) { - axis = SDL_JoystickGetAxis(joy, i); - mInitAxisValues[joyId][i] = axis; - mPrevAxisValues[joyId][i] = axis; - } + std::fill(mPrevAxisValues[joyId], mPrevAxisValues[joyId] + numAxes, 0); //initialize array to 0 } void InputManager::removeJoystickByJoystickID(SDL_JoystickID joyId) @@ -177,28 +170,21 @@ InputConfig* InputManager::getInputConfigByDevice(int device) bool InputManager::parseEvent(const SDL_Event& ev, Window* window) { bool causedEvent = false; - int axis; - int deadzone = DEADZONE; switch(ev.type) { case SDL_JOYAXISMOTION: - axis = ev.jaxis.value; - if (mInitAxisValues[ev.jaxis.which][ev.jaxis.axis] == -32768) - { - deadzone /= 2; - axis = (axis + 32767) / 2; - } //if it switched boundaries - if((abs(axis) > deadzone) != (abs(mPrevAxisValues[ev.jaxis.which][ev.jaxis.axis]) > deadzone)) + if((abs(ev.jaxis.value) > DEADZONE) != (abs(mPrevAxisValues[ev.jaxis.which][ev.jaxis.axis]) > DEADZONE)) { int normValue; - if(abs(axis) <= deadzone) + if(abs(ev.jaxis.value) <= DEADZONE) normValue = 0; else - if(axis > 0) + if(ev.jaxis.value > 0) normValue = 1; else normValue = -1; + window->input(getInputConfigByDevice(ev.jaxis.which), Input(ev.jaxis.which, TYPE_AXIS, ev.jaxis.axis, normValue, false)); causedEvent = true; } diff --git a/es-core/src/InputManager.h b/es-core/src/InputManager.h index 295fa87f74..7408356342 100644 --- a/es-core/src/InputManager.h +++ b/es-core/src/InputManager.h @@ -26,7 +26,6 @@ class InputManager InputConfig* mKeyboardInputConfig; std::map mPrevAxisValues; - std::map mInitAxisValues; bool initialized() const; From cdd819e041104a78dd072b637d5adc8a36390ae9 Mon Sep 17 00:00:00 2001 From: Joseph Mann Date: Thu, 30 Jun 2016 12:05:50 -0600 Subject: [PATCH 29/74] Fix linux (fedora) compilation issues --- es-core/src/Util.cpp | 2 +- es-core/src/Util.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/es-core/src/Util.cpp b/es-core/src/Util.cpp index 80560a2baa..34be52494c 100644 --- a/es-core/src/Util.cpp +++ b/es-core/src/Util.cpp @@ -26,7 +26,7 @@ std::string strToUpper(const std::string& str) } -#if _MSC_VER < 1800 +#if defined(_WIN32) && _MSC_VER < 1800 float round(float num) { return (float)((int)(num + 0.5f)); diff --git a/es-core/src/Util.h b/es-core/src/Util.h index 507ceecfd6..d26aee08bb 100644 --- a/es-core/src/Util.h +++ b/es-core/src/Util.h @@ -15,7 +15,9 @@ Eigen::Affine3f roundMatrix(const Eigen::Affine3f& mat); Eigen::Vector3f roundVector(const Eigen::Vector3f& vec); Eigen::Vector2f roundVector(const Eigen::Vector2f& vec); +#if defined(_WIN32) && _MSC_VER < 1800 float round(float num); +#endif std::string getCanonicalPath(const std::string& str); From 0213bef499dd9e67286c33b56dcf1145cb54e132 Mon Sep 17 00:00:00 2001 From: Jacob Karleskint Date: Sat, 3 Sep 2016 15:45:52 -0500 Subject: [PATCH 30/74] Checks if game has metadata Adds a function to metadata "isDefault()" which will return true if all metadata is still set to default values and false if any values are not set to default When saving, a game that has no metadata would also not be saved in the gamelist xml. so now it will just ignore looking for that game instead of looping through every node until it reaches the end of the tree. --- es-app/src/Gamelist.cpp | 6 ++++++ es-app/src/MetaData.cpp | 9 +++++++++ es-app/src/MetaData.h | 2 ++ 3 files changed, 17 insertions(+) diff --git a/es-app/src/Gamelist.cpp b/es-app/src/Gamelist.cpp index 8f3db352d0..aeb8d0580f 100644 --- a/es-app/src/Gamelist.cpp +++ b/es-app/src/Gamelist.cpp @@ -215,6 +215,12 @@ void updateGamelist(SystemData* system) { const char* tag = ((*fit)->getType() == GAME) ? "game" : "folder"; + // check if current file has metadata, if no, skip it as it wont be in the gamelist anyway. + if ((*fit)->metadata.isDefault()) { + ++fit; + continue; + } + // check if the file already exists in the XML // if it does, remove it before adding for(pugi::xml_node fileNode = root.child(tag); fileNode; fileNode = fileNode.next_sibling(tag)) diff --git a/es-app/src/MetaData.cpp b/es-app/src/MetaData.cpp index 2d5340bd24..76c82b9d69 100644 --- a/es-app/src/MetaData.cpp +++ b/es-app/src/MetaData.cpp @@ -133,3 +133,12 @@ boost::posix_time::ptime MetaDataList::getTime(const std::string& key) const { return string_to_ptime(get(key), "%Y%m%dT%H%M%S%F%q"); } + +bool MetaDataList::isDefault() +{ + for (int i = 1; i < mMap.size(); i++) { + if (mMap.at(gameDecls[i].key) != gameDecls[i].defaultValue) return false; + } + + return true; +} diff --git a/es-app/src/MetaData.h b/es-app/src/MetaData.h index 1143d9204b..d111cec786 100644 --- a/es-app/src/MetaData.h +++ b/es-app/src/MetaData.h @@ -56,6 +56,8 @@ class MetaDataList float getFloat(const std::string& key) const; boost::posix_time::ptime getTime(const std::string& key) const; + bool isDefault(); + inline MetaDataListType getType() const { return mType; } inline const std::vector& getMDD() const { return getMDDByType(getType()); } From 8fe0202c2e06e961de1687ccc1f772b9aeaf23a8 Mon Sep 17 00:00:00 2001 From: Jools Wills Date: Mon, 12 Sep 2016 19:04:39 +0100 Subject: [PATCH 31/74] restore cursor on exit --- emulationstation.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/emulationstation.sh b/emulationstation.sh index 227078f06d..42df2e7acc 100755 --- a/emulationstation.sh +++ b/emulationstation.sh @@ -15,5 +15,6 @@ while true; do sudo poweroff break fi + tput cnorm break done From 5b74b877ef734a027b0b1fed74a75091bfbf8ab4 Mon Sep 17 00:00:00 2001 From: Jools Wills Date: Mon, 12 Sep 2016 19:11:25 +0100 Subject: [PATCH 32/74] Revert "restore cursor on exit" This reverts commit 8fe0202c2e06e961de1687ccc1f772b9aeaf23a8. Better to do this in the RP ES launch script --- emulationstation.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/emulationstation.sh b/emulationstation.sh index 42df2e7acc..227078f06d 100755 --- a/emulationstation.sh +++ b/emulationstation.sh @@ -15,6 +15,5 @@ while true; do sudo poweroff break fi - tput cnorm break done From b1daeafe24bfb93f75f4c7e63f52f8dcc09cdc2b Mon Sep 17 00:00:00 2001 From: vbs Date: Mon, 12 Sep 2016 13:31:44 +0200 Subject: [PATCH 33/74] Added flag for GUI components to indicate activate background processing. ES won't enter sleep mode if any component has the processing flag set. (In sleep mode no more calls to update() on any components are invoked) --- es-app/src/guis/GuiScraperMulti.cpp | 4 ++++ es-core/src/GuiComponent.cpp | 8 +++++++- es-core/src/GuiComponent.h | 5 +++++ es-core/src/Window.cpp | 8 +++++++- es-core/src/Window.h | 3 +++ 5 files changed, 26 insertions(+), 2 deletions(-) diff --git a/es-app/src/guis/GuiScraperMulti.cpp b/es-app/src/guis/GuiScraperMulti.cpp index afbfe0a3d1..8da0377dfe 100644 --- a/es-app/src/guis/GuiScraperMulti.cpp +++ b/es-app/src/guis/GuiScraperMulti.cpp @@ -21,6 +21,8 @@ GuiScraperMulti::GuiScraperMulti(Window* window, const std::queuepushGui(new GuiMsgBox(mWindow, ss.str(), "OK", [&] { delete this; })); + + mIsProcessing = false; } std::vector GuiScraperMulti::getHelpPrompts() diff --git a/es-core/src/GuiComponent.cpp b/es-core/src/GuiComponent.cpp index 2b4fbe3c13..d079930ded 100644 --- a/es-core/src/GuiComponent.cpp +++ b/es-core/src/GuiComponent.cpp @@ -6,7 +6,8 @@ #include "ThemeData.h" GuiComponent::GuiComponent(Window* window) : mWindow(window), mParent(NULL), mOpacity(255), - mPosition(Eigen::Vector3f::Zero()), mSize(Eigen::Vector2f::Zero()), mTransform(Eigen::Affine3f::Identity()) + mPosition(Eigen::Vector3f::Zero()), mSize(Eigen::Vector2f::Zero()), mTransform(Eigen::Affine3f::Identity()), + mIsProcessing(false) { for(unsigned char i = 0; i < MAX_ANIMATIONS; i++) mAnimationMap[i] = NULL; @@ -339,3 +340,8 @@ HelpStyle GuiComponent::getHelpStyle() { return HelpStyle(); } + +bool GuiComponent::isProcessing() const +{ + return mIsProcessing; +} diff --git a/es-core/src/GuiComponent.h b/es-core/src/GuiComponent.h index 0b8734a2f2..566b2a615f 100644 --- a/es-core/src/GuiComponent.h +++ b/es-core/src/GuiComponent.h @@ -90,6 +90,9 @@ class GuiComponent virtual HelpStyle getHelpStyle(); + // Returns true if the component is busy doing background processing (e.g. HTTP downloads) + bool isProcessing() const; + protected: void renderChildren(const Eigen::Affine3f& transform) const; void updateSelf(int deltaTime); // updates animations @@ -104,6 +107,8 @@ class GuiComponent Eigen::Vector3f mPosition; Eigen::Vector2f mSize; + bool mIsProcessing; + public: const static unsigned char MAX_ANIMATIONS = 4; diff --git a/es-core/src/Window.cpp b/es-core/src/Window.cpp index d9dea20508..c8db08089c 100644 --- a/es-core/src/Window.cpp +++ b/es-core/src/Window.cpp @@ -4,6 +4,7 @@ #include "AudioManager.h" #include "Log.h" #include "Settings.h" +#include #include #include "components/HelpComponent.h" #include "components/ImageComponent.h" @@ -202,7 +203,7 @@ void Window::render() } unsigned int screensaverTime = (unsigned int)Settings::getInstance()->getInt("ScreenSaverTime"); - if(mTimeSinceLastInput >= screensaverTime && screensaverTime != 0 && mAllowSleep) + if(mTimeSinceLastInput >= screensaverTime && screensaverTime != 0 && !isProcessing() && mAllowSleep) { // go to sleep mSleeping = true; @@ -335,3 +336,8 @@ void Window::onWake() { } + +bool Window::isProcessing() +{ + return count_if(mGuiStack.begin(), mGuiStack.end(), [](GuiComponent* c) { return c->isProcessing(); }) > 0; +} diff --git a/es-core/src/Window.h b/es-core/src/Window.h index 6576cb04a3..54e014c762 100644 --- a/es-core/src/Window.h +++ b/es-core/src/Window.h @@ -41,6 +41,9 @@ class Window void onSleep(); void onWake(); + // Returns true if at least one component on the stack is processing + bool isProcessing(); + HelpComponent* mHelp; ImageComponent* mBackgroundOverlay; From 329730cc3eac734f4fda4e317e9378db098d9768 Mon Sep 17 00:00:00 2001 From: verybadsoldier Date: Sat, 17 Sep 2016 15:21:24 +0200 Subject: [PATCH 34/74] Decoupled screensaver and sleep mode: background jobs will only prevent sleep mode but screen saver (dimming) will still be active. --- es-core/src/Window.cpp | 23 ++++++++++++++++------- es-core/src/Window.h | 1 + 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/es-core/src/Window.cpp b/es-core/src/Window.cpp index c8db08089c..e5622e8ca5 100644 --- a/es-core/src/Window.cpp +++ b/es-core/src/Window.cpp @@ -203,11 +203,16 @@ void Window::render() } unsigned int screensaverTime = (unsigned int)Settings::getInstance()->getInt("ScreenSaverTime"); - if(mTimeSinceLastInput >= screensaverTime && screensaverTime != 0 && !isProcessing() && mAllowSleep) + if(mTimeSinceLastInput >= screensaverTime && screensaverTime != 0) { - // go to sleep - mSleeping = true; - onSleep(); + renderScreenSaver(); + + if (!isProcessing() && mAllowSleep) + { + // go to sleep + mSleeping = true; + onSleep(); + } } } @@ -327,9 +332,6 @@ void Window::setHelpPrompts(const std::vector& prompts, const HelpSt void Window::onSleep() { - Renderer::setMatrix(Eigen::Affine3f::Identity()); - unsigned char opacity = Settings::getInstance()->getString("ScreenSaverBehavior") == "dim" ? 0xA0 : 0xFF; - Renderer::drawRect(0, 0, Renderer::getScreenWidth(), Renderer::getScreenHeight(), 0x00000000 | opacity); } void Window::onWake() @@ -341,3 +343,10 @@ bool Window::isProcessing() { return count_if(mGuiStack.begin(), mGuiStack.end(), [](GuiComponent* c) { return c->isProcessing(); }) > 0; } + +void Window::renderScreenSaver() +{ + Renderer::setMatrix(Eigen::Affine3f::Identity()); + unsigned char opacity = Settings::getInstance()->getString("ScreenSaverBehavior") == "dim" ? 0xA0 : 0xFF; + Renderer::drawRect(0, 0, Renderer::getScreenWidth(), Renderer::getScreenHeight(), 0x00000000 | opacity); +} diff --git a/es-core/src/Window.h b/es-core/src/Window.h index 54e014c762..5eee873a2c 100644 --- a/es-core/src/Window.h +++ b/es-core/src/Window.h @@ -43,6 +43,7 @@ class Window // Returns true if at least one component on the stack is processing bool isProcessing(); + void renderScreenSaver(); HelpComponent* mHelp; ImageComponent* mBackgroundOverlay; From 1c343c999b1a1a4e1405f2a5926b8b9e3d7c1b68 Mon Sep 17 00:00:00 2001 From: Jools Wills Date: Tue, 8 Nov 2016 19:38:10 +0000 Subject: [PATCH 35/74] show "CONFIGURATION" instead of "X GAMES AVAILABLE" for the retropie menu --- es-app/src/views/SystemView.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/es-app/src/views/SystemView.cpp b/es-app/src/views/SystemView.cpp index 54987fdf87..013490aca9 100644 --- a/es-app/src/views/SystemView.cpp +++ b/es-app/src/views/SystemView.cpp @@ -177,8 +177,10 @@ void SystemView::onCursorChanged(const CursorState& state) setAnimation(infoFadeOut, 0, [this, gameCount] { std::stringstream ss; + if (getSelected()->getName() == "retropie") + ss << "CONFIGURATION"; // only display a game count if there are at least 2 games - if(gameCount > 1) + else if(gameCount > 1) ss << gameCount << " GAMES AVAILABLE"; mSystemInfo.setText(ss.str()); From 4d27443f335ef2ab22d5f6ba670e9ec879bff3f2 Mon Sep 17 00:00:00 2001 From: Jools Wills Date: Wed, 30 Nov 2016 18:15:13 +0000 Subject: [PATCH 36/74] emulationstation - add additional scroll speed tier, and slow down fastest speed --- es-core/src/components/IList.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/es-core/src/components/IList.h b/es-core/src/components/IList.h index 85d8064961..ede3360a9d 100644 --- a/es-core/src/components/IList.h +++ b/es-core/src/components/IList.h @@ -36,10 +36,11 @@ struct ScrollTierList // default scroll tiers const ScrollTier QUICK_SCROLL_TIERS[] = { {500, 500}, - {5000, 114}, - {0, 8} + {2000, 114}, + {4000, 32}, + {0, 16} }; -const ScrollTierList LIST_SCROLL_STYLE_QUICK = { 3, QUICK_SCROLL_TIERS }; +const ScrollTierList LIST_SCROLL_STYLE_QUICK = { 4, QUICK_SCROLL_TIERS }; const ScrollTier SLOW_SCROLL_TIERS[] = { {500, 500}, From 3ccc380c2b56747cf579947ade02f888723222d3 Mon Sep 17 00:00:00 2001 From: Jools Wills Date: Sat, 3 Dec 2016 02:22:59 +0000 Subject: [PATCH 37/74] added confirmation to "CONFIGURE INPUT". fixes #75 --- es-app/src/guis/GuiMenu.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/es-app/src/guis/GuiMenu.cpp b/es-app/src/guis/GuiMenu.cpp index 032706b939..d005fc04ec 100644 --- a/es-app/src/guis/GuiMenu.cpp +++ b/es-app/src/guis/GuiMenu.cpp @@ -184,8 +184,13 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MEN }); addEntry("CONFIGURE INPUT", 0x777777FF, true, - [this] { - mWindow->pushGui(new GuiDetectDevice(mWindow, false, nullptr)); + [this] { + Window* window = mWindow; + window->pushGui(new GuiMsgBox(window, "ARE YOU SURE YOU WANT TO CONFIGURE INPUT?", "YES", + [window] { + window->pushGui(new GuiDetectDevice(window, false, nullptr)); + }, "NO", nullptr) + ); }); addEntry("QUIT", 0x777777FF, true, From 25e1067794760523a331c07c1c0b23922b9644f2 Mon Sep 17 00:00:00 2001 From: fieldofcows Date: Sun, 4 Dec 2016 23:47:34 +0000 Subject: [PATCH 38/74] Add video view that is based on detail view but allows themes to include a video preview of the selected game along with a marquee image --- CMake/Packages/FindVLC.cmake | 55 ++ CMake/Packages/MacroEnsureVersion.cmake | 117 ++++ CMakeLists.txt | 3 + README.md | 5 +- es-app/CMakeLists.txt | 2 + es-app/src/FileData.cpp | 26 + es-app/src/FileData.h | 2 + es-app/src/MetaData.cpp | 17 +- es-app/src/MetaData.h | 2 +- es-app/src/views/ViewController.cpp | 39 +- .../src/views/gamelist/VideoGameListView.cpp | 345 ++++++++++++ es-app/src/views/gamelist/VideoGameListView.h | 53 ++ es-core/CMakeLists.txt | 2 + es-core/src/GuiComponent.cpp | 14 + es-core/src/GuiComponent.h | 3 + es-core/src/ThemeData.cpp | 10 +- es-core/src/ThemeData.h | 1 + es-core/src/Window.cpp | 5 + es-core/src/components/VideoComponent.cpp | 518 ++++++++++++++++++ es-core/src/components/VideoComponent.h | 112 ++++ 20 files changed, 1318 insertions(+), 13 deletions(-) create mode 100644 CMake/Packages/FindVLC.cmake create mode 100644 CMake/Packages/MacroEnsureVersion.cmake create mode 100644 es-app/src/views/gamelist/VideoGameListView.cpp create mode 100644 es-app/src/views/gamelist/VideoGameListView.h create mode 100644 es-core/src/components/VideoComponent.cpp create mode 100644 es-core/src/components/VideoComponent.h diff --git a/CMake/Packages/FindVLC.cmake b/CMake/Packages/FindVLC.cmake new file mode 100644 index 0000000000..eec5c57092 --- /dev/null +++ b/CMake/Packages/FindVLC.cmake @@ -0,0 +1,55 @@ +# - Try to find VLC library +# Once done this will define +# +# VLC_FOUND - system has VLC +# VLC_INCLUDE_DIR - The VLC include directory +# VLC_LIBRARIES - The libraries needed to use VLC +# VLC_DEFINITIONS - Compiler switches required for using VLC +# +# Copyright (C) 2008, Tanguy Krotoff +# Copyright (C) 2008, Lukas Durfina +# Copyright (c) 2009, Fathi Boudra +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. +# + +if(VLC_INCLUDE_DIR AND VLC_LIBRARIES) + # in cache already + set(VLC_FIND_QUIETLY TRUE) +endif(VLC_INCLUDE_DIR AND VLC_LIBRARIES) + +# use pkg-config to get the directories and then use these values +# in the FIND_PATH() and FIND_LIBRARY() calls +if(NOT WIN32) + find_package(PkgConfig) + pkg_check_modules(VLC libvlc>=1.0.0) + set(VLC_DEFINITIONS ${VLC_CFLAGS}) + set(VLC_LIBRARIES ${VLC_LDFLAGS}) +endif(NOT WIN32) + +# TODO add argument support to pass version on find_package +include(MacroEnsureVersion) +macro_ensure_version(1.0.0 ${VLC_VERSION} VLC_VERSION_OK) +if(VLC_VERSION_OK) + set(VLC_FOUND TRUE) + message(STATUS "VLC library found") +else(VLC_VERSION_OK) + set(VLC_FOUND FALSE) + message(FATAL_ERROR "VLC library not found") +endif(VLC_VERSION_OK) + +find_path(VLC_INCLUDE_DIR + NAMES vlc.h + PATHS ${VLC_INCLUDE_DIRS} + PATH_SUFFIXES vlc) + +find_library(VLC_LIBRARIES + NAMES vlc + PATHS ${VLC_LIBRARY_DIRS}) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(VLC DEFAULT_MSG VLC_INCLUDE_DIR VLC_LIBRARIES) + +# show the VLC_INCLUDE_DIR and VLC_LIBRARIES variables only in the advanced view +mark_as_advanced(VLC_INCLUDE_DIR VLC_LIBRARIES) diff --git a/CMake/Packages/MacroEnsureVersion.cmake b/CMake/Packages/MacroEnsureVersion.cmake new file mode 100644 index 0000000000..6797e5b7db --- /dev/null +++ b/CMake/Packages/MacroEnsureVersion.cmake @@ -0,0 +1,117 @@ +# This file defines the following macros for developers to use in ensuring +# that installed software is of the right version: +# +# MACRO_ENSURE_VERSION - test that a version number is greater than +# or equal to some minimum +# MACRO_ENSURE_VERSION_RANGE - test that a version number is greater than +# or equal to some minimum and less than some +# maximum +# MACRO_ENSURE_VERSION2 - deprecated, do not use in new code +# + +# MACRO_ENSURE_VERSION +# This macro compares version numbers of the form "x.y.z" or "x.y" +# MACRO_ENSURE_VERSION( FOO_MIN_VERSION FOO_VERSION_FOUND FOO_VERSION_OK) +# will set FOO_VERSION_OK to true if FOO_VERSION_FOUND >= FOO_MIN_VERSION +# Leading and trailing text is ok, e.g. +# MACRO_ENSURE_VERSION( "2.5.31" "flex 2.5.4a" VERSION_OK) +# which means 2.5.31 is required and "flex 2.5.4a" is what was found on the system + +# Copyright (c) 2006, David Faure, +# Copyright (c) 2007, Will Stephenson +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +# MACRO_ENSURE_VERSION_RANGE +# This macro ensures that a version number of the form +# "x.y.z" or "x.y" falls within a range defined by +# min_version <= found_version < max_version. +# If this expression holds, FOO_VERSION_OK will be set TRUE +# +# Example: MACRO_ENSURE_VERSION_RANGE3( "0.1.0" ${FOOCODE_VERSION} "0.7.0" FOO_VERSION_OK ) +# +# This macro will break silently if any of x,y,z are greater than 100. +# +# Copyright (c) 2007, Will Stephenson +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +# NORMALIZE_VERSION +# Helper macro to convert version numbers of the form "x.y.z" +# to an integer equal to 10^4 * x + 10^2 * y + z +# +# This macro will break silently if any of x,y,z are greater than 100. +# +# Copyright (c) 2006, David Faure, +# Copyright (c) 2007, Will Stephenson +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +# CHECK_RANGE_INCLUSIVE_LOWER +# Helper macro to check whether x <= y < z +# +# Copyright (c) 2007, Will Stephenson +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + + +MACRO(NORMALIZE_VERSION _requested_version _normalized_version) + STRING(REGEX MATCH "[^0-9]*[0-9]+\\.[0-9]+\\.[0-9]+.*" _threePartMatch "${_requested_version}") + if (_threePartMatch) + # parse the parts of the version string + STRING(REGEX REPLACE "[^0-9]*([0-9]+)\\.[0-9]+\\.[0-9]+.*" "\\1" _major_vers "${_requested_version}") + STRING(REGEX REPLACE "[^0-9]*[0-9]+\\.([0-9]+)\\.[0-9]+.*" "\\1" _minor_vers "${_requested_version}") + STRING(REGEX REPLACE "[^0-9]*[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" _patch_vers "${_requested_version}") + else (_threePartMatch) + STRING(REGEX REPLACE "([0-9]+)\\.[0-9]+" "\\1" _major_vers "${_requested_version}") + STRING(REGEX REPLACE "[0-9]+\\.([0-9]+)" "\\1" _minor_vers "${_requested_version}") + set(_patch_vers "0") + endif (_threePartMatch) + + # compute an overall version number which can be compared at once + MATH(EXPR ${_normalized_version} "${_major_vers}*10000 + ${_minor_vers}*100 + ${_patch_vers}") +ENDMACRO(NORMALIZE_VERSION) + +MACRO(MACRO_CHECK_RANGE_INCLUSIVE_LOWER _lower_limit _value _upper_limit _ok) + if (${_value} LESS ${_lower_limit}) + set( ${_ok} FALSE ) + elseif (${_value} EQUAL ${_lower_limit}) + set( ${_ok} TRUE ) + elseif (${_value} EQUAL ${_upper_limit}) + set( ${_ok} FALSE ) + elseif (${_value} GREATER ${_upper_limit}) + set( ${_ok} FALSE ) + else (${_value} LESS ${_lower_limit}) + set( ${_ok} TRUE ) + endif (${_value} LESS ${_lower_limit}) +ENDMACRO(MACRO_CHECK_RANGE_INCLUSIVE_LOWER) + +MACRO(MACRO_ENSURE_VERSION requested_version found_version var_too_old) + NORMALIZE_VERSION( ${requested_version} req_vers_num ) + NORMALIZE_VERSION( ${found_version} found_vers_num ) + + if (found_vers_num LESS req_vers_num) + set( ${var_too_old} FALSE ) + else (found_vers_num LESS req_vers_num) + set( ${var_too_old} TRUE ) + endif (found_vers_num LESS req_vers_num) + +ENDMACRO(MACRO_ENSURE_VERSION) + +MACRO(MACRO_ENSURE_VERSION2 requested_version2 found_version2 var_too_old2) + MACRO_ENSURE_VERSION( ${requested_version2} ${found_version2} ${var_too_old2}) +ENDMACRO(MACRO_ENSURE_VERSION2) + +MACRO(MACRO_ENSURE_VERSION_RANGE min_version found_version max_version var_ok) + NORMALIZE_VERSION( ${min_version} req_vers_num ) + NORMALIZE_VERSION( ${found_version} found_vers_num ) + NORMALIZE_VERSION( ${max_version} max_vers_num ) + + MACRO_CHECK_RANGE_INCLUSIVE_LOWER( ${req_vers_num} ${found_vers_num} ${max_vers_num} ${var_ok}) +ENDMACRO(MACRO_ENSURE_VERSION_RANGE) + + diff --git a/CMakeLists.txt b/CMakeLists.txt index 784c2d0ac0..48143a5230 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,6 +48,7 @@ find_package(SDL2 REQUIRED) find_package(Boost REQUIRED COMPONENTS system filesystem date_time locale) find_package(Eigen3 REQUIRED) find_package(CURL REQUIRED) +find_package(VLC REQUIRED) #add ALSA for Linux if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") @@ -99,6 +100,7 @@ set(COMMON_INCLUDE_DIRS ${Boost_INCLUDE_DIRS} ${EIGEN3_INCLUDE_DIR} ${CURL_INCLUDE_DIR} + ${VLC_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/external ${CMAKE_CURRENT_SOURCE_DIR}/es-core/src ) @@ -148,6 +150,7 @@ set(COMMON_LIBRARIES ${FreeImage_LIBRARIES} ${SDL2_LIBRARY} ${CURL_LIBRARIES} + ${VLC_LIBRARIES} pugixml nanosvg ) diff --git a/README.md b/README.md index ff02eae137..1113c6d03f 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,10 @@ EmulationStation has a few dependencies. For building, you'll need CMake, SDL2, **On Debian/Ubuntu:** All of this be easily installed with apt-get: ```bash -sudo apt-get install libsdl2-dev libboost-system-dev libboost-filesystem-dev libboost-date-time-dev libboost-locale-dev libfreeimage-dev libfreetype6-dev libeigen3-dev libcurl4-openssl-dev libasound2-dev libgl1-mesa-dev build-essential cmake fonts-droid +sudo apt-get install libsdl2-dev libboost-system-dev libboost-filesystem-dev libboost-date-time-dev \ + libboost-locale-dev libfreeimage-dev libfreetype6-dev libeigen3-dev libcurl4-openssl-dev \ + libasound2-dev libgl1-mesa-dev build-essential cmake fonts-droid \ + libvlc-dev libvlccore-dev vlc-nox ``` Then, generate and build the Makefile with CMake: diff --git a/es-app/CMakeLists.txt b/es-app/CMakeLists.txt index 6f1de88be4..47dfd131c5 100644 --- a/es-app/CMakeLists.txt +++ b/es-app/CMakeLists.txt @@ -38,6 +38,7 @@ set(ES_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/src/views/gamelist/IGameListView.h ${CMAKE_CURRENT_SOURCE_DIR}/src/views/gamelist/ISimpleGameListView.h ${CMAKE_CURRENT_SOURCE_DIR}/src/views/gamelist/GridGameListView.h + ${CMAKE_CURRENT_SOURCE_DIR}/src/views/gamelist/VideoGameListView.h ${CMAKE_CURRENT_SOURCE_DIR}/src/views/SystemView.h ${CMAKE_CURRENT_SOURCE_DIR}/src/views/ViewController.h @@ -84,6 +85,7 @@ set(ES_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/views/gamelist/IGameListView.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/views/gamelist/ISimpleGameListView.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/views/gamelist/GridGameListView.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/views/gamelist/VideoGameListView.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/views/SystemView.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/views/ViewController.cpp ) diff --git a/es-app/src/FileData.cpp b/es-app/src/FileData.cpp index 0b151b6e20..c8409d4d59 100644 --- a/es-app/src/FileData.cpp +++ b/es-app/src/FileData.cpp @@ -81,6 +81,32 @@ const std::string& FileData::getThumbnailPath() const return metadata.get("image"); } +const std::string& FileData::getVideoPath() const +{ + if (mType == GAME) + { + return metadata.get("video"); + } + else + { + static std::string empty; + return empty; + } +} + +const std::string& FileData::getMarqueePath() const +{ + if (mType == GAME) + { + return metadata.get("marquee"); + } + else + { + static std::string empty; + return empty; + } +} + std::vector FileData::getFilesRecursive(unsigned int typeMask) const { diff --git a/es-app/src/FileData.h b/es-app/src/FileData.h index f21ca8f9dc..bd59ac0710 100644 --- a/es-app/src/FileData.h +++ b/es-app/src/FileData.h @@ -45,6 +45,8 @@ class FileData inline SystemData* getSystem() const { return mSystem; } virtual const std::string& getThumbnailPath() const; + virtual const std::string& getVideoPath() const; + virtual const std::string& getMarqueePath() const; std::vector getFilesRecursive(unsigned int typeMask) const; diff --git a/es-app/src/MetaData.cpp b/es-app/src/MetaData.cpp index 76c82b9d69..3f5da45c67 100644 --- a/es-app/src/MetaData.cpp +++ b/es-app/src/MetaData.cpp @@ -9,8 +9,10 @@ MetaDataDecl gameDecls[] = { // key, type, default, statistic, name in GuiMetaDataEd, prompt in GuiMetaDataEd {"name", MD_STRING, "", false, "name", "enter game name"}, {"desc", MD_MULTILINE_STRING, "", false, "description", "enter description"}, - {"image", MD_IMAGE_PATH, "", false, "image", "enter path to image"}, - {"thumbnail", MD_IMAGE_PATH, "", false, "thumbnail", "enter path to thumbnail"}, + {"image", MD_PATH, "", false, "image", "enter path to image"}, + {"video", MD_PATH , "", false, "video", "enter path to video"}, + {"marquee", MD_PATH, "", false, "marquee", "enter path to marquee"}, + {"thumbnail", MD_PATH, "", false, "thumbnail", "enter path to thumbnail"}, {"rating", MD_RATING, "0.000000", false, "rating", "enter rating"}, {"releasedate", MD_DATE, "not-a-date-time", false, "release date", "enter release date"}, {"developer", MD_STRING, "unknown", false, "developer", "enter game developer"}, @@ -25,8 +27,8 @@ const std::vector gameMDD(gameDecls, gameDecls + sizeof(gameDecls) MetaDataDecl folderDecls[] = { {"name", MD_STRING, "", false}, {"desc", MD_MULTILINE_STRING, "", false}, - {"image", MD_IMAGE_PATH, "", false}, - {"thumbnail", MD_IMAGE_PATH, "", false}, + {"image", MD_PATH, "", false}, + {"thumbnail", MD_PATH, "", false}, }; const std::vector folderMDD(folderDecls, folderDecls + sizeof(folderDecls) / sizeof(folderDecls[0])); @@ -68,9 +70,10 @@ MetaDataList MetaDataList::createFromXML(MetaDataListType type, pugi::xml_node n { // if it's a path, resolve relative paths std::string value = md.text().get(); - if(iter->type == MD_IMAGE_PATH) + if (iter->type == MD_PATH) + { value = resolvePath(value, relativeTo, true).generic_string(); - + } mdl.set(iter->key, value); }else{ mdl.set(iter->key, iter->defaultValue); @@ -96,7 +99,7 @@ void MetaDataList::appendToXML(pugi::xml_node parent, bool ignoreDefaults, const // try and make paths relative if we can std::string value = mapIter->second; - if(mddIter->type == MD_IMAGE_PATH) + if (mddIter->type == MD_PATH) value = makeRelativePath(value, relativeTo, true).generic_string(); parent.append_child(mapIter->first.c_str()).text().set(value.c_str()); diff --git a/es-app/src/MetaData.h b/es-app/src/MetaData.h index d111cec786..136a8b2f6a 100644 --- a/es-app/src/MetaData.h +++ b/es-app/src/MetaData.h @@ -16,7 +16,7 @@ enum MetaDataType //specialized types MD_MULTILINE_STRING, - MD_IMAGE_PATH, + MD_PATH, MD_RATING, MD_DATE, MD_TIME //used for lastplayed diff --git a/es-app/src/views/ViewController.cpp b/es-app/src/views/ViewController.cpp index 5a94d97c2b..1e10c91753 100644 --- a/es-app/src/views/ViewController.cpp +++ b/es-app/src/views/ViewController.cpp @@ -5,12 +5,14 @@ #include "views/gamelist/BasicGameListView.h" #include "views/gamelist/DetailedGameListView.h" +#include "views/gamelist/VideoGameListView.h" #include "views/gamelist/GridGameListView.h" #include "guis/GuiMenu.h" #include "guis/GuiMsgBox.h" #include "animations/LaunchAnimation.h" #include "animations/MoveCameraAnimation.h" #include "animations/LambdaAnimation.h" +#include ViewController* ViewController::sInstance = NULL; @@ -55,6 +57,12 @@ int ViewController::getSystemId(SystemData* system) void ViewController::goToSystemView(SystemData* system) { + // Tell any current view it's about to be hidden + if (mCurrentView) + { + mCurrentView->onHide(); + } + mState.viewing = SYSTEM_SELECT; mState.system = system; @@ -99,7 +107,15 @@ void ViewController::goToGameList(SystemData* system) mState.viewing = GAME_LIST; mState.system = system; + if (mCurrentView) + { + mCurrentView->onHide(); + } mCurrentView = getGameListView(system); + if (mCurrentView) + { + mCurrentView->onShow(); + } playViewTransition(); } @@ -163,6 +179,10 @@ void ViewController::launch(FileData* game, Eigen::Vector3f center) return; } + // Hide the current view + if (mCurrentView) + mCurrentView->onHide(); + Eigen::Affine3f origCamera = mCamera; origCamera.translation() = -mCurrentView->getPosition(); @@ -210,17 +230,26 @@ std::shared_ptr ViewController::getGameListView(SystemData* syste //decide type bool detailed = false; + bool video = false; std::vector files = system->getRootFolder()->getFilesRecursive(GAME | FOLDER); for(auto it = files.begin(); it != files.end(); it++) { - if(!(*it)->getThumbnailPath().empty()) + if(!(*it)->getVideoPath().empty()) { - detailed = true; + video = true; break; } + else if(!(*it)->getThumbnailPath().empty()) + { + detailed = true; + // Don't break out in case any subsequent files have video + } } - if(detailed) + if (video) + // Create the view + view = std::shared_ptr(new VideoGameListView(mWindow, system->getRootFolder())); + else if(detailed) view = std::shared_ptr(new DetailedGameListView(mWindow, system->getRootFolder())); else view = std::shared_ptr(new BasicGameListView(mWindow, system->getRootFolder())); @@ -347,6 +376,10 @@ void ViewController::reloadGameListView(IGameListView* view, bool reloadTheme) break; } } + // Redisplay the current view + if (mCurrentView) + mCurrentView->onShow(); + } void ViewController::reloadAll() diff --git a/es-app/src/views/gamelist/VideoGameListView.cpp b/es-app/src/views/gamelist/VideoGameListView.cpp new file mode 100644 index 0000000000..2a270be028 --- /dev/null +++ b/es-app/src/views/gamelist/VideoGameListView.cpp @@ -0,0 +1,345 @@ +#include "views/gamelist/VideoGameListView.h" +#include "views/ViewController.h" +#include "Window.h" +#include "animations/LambdaAnimation.h" +#include +#include + +VideoGameListView::VideoGameListView(Window* window, FileData* root) : + BasicGameListView(window, root), + mDescContainer(window), mDescription(window), + mMarquee(window), + mImage(window), + mVideo(window), + mVideoPlaying(false), + + mLblRating(window), mLblReleaseDate(window), mLblDeveloper(window), mLblPublisher(window), + mLblGenre(window), mLblPlayers(window), mLblLastPlayed(window), mLblPlayCount(window), + + mRating(window), mReleaseDate(window), mDeveloper(window), mPublisher(window), + mGenre(window), mPlayers(window), mLastPlayed(window), mPlayCount(window) +{ + const float padding = 0.01f; + + mList.setPosition(mSize.x() * (0.50f + padding), mList.getPosition().y()); + mList.setSize(mSize.x() * (0.50f - padding), mList.getSize().y()); + mList.setAlignment(TextListComponent::ALIGN_LEFT); + mList.setCursorChangedCallback([&](const CursorState& state) { updateInfoPanel(); }); + + // Marquee + mMarquee.setOrigin(0.5f, 0.5f); + mMarquee.setPosition(mSize.x() * 0.25f, mSize.y() * 0.10f); + mMarquee.setMaxSize(mSize.x() * (0.5f - 2*padding), mSize.y() * 0.18f); + addChild(&mMarquee); + + // Image + mImage.setOrigin(0.5f, 0.5f); + // Default to off the screen + mImage.setPosition(2.0f, 2.0f); + mImage.setMaxSize(1.0f, 1.0f); + addChild(&mImage); + + // video + mVideo.setOrigin(0.5f, 0.5f); + mVideo.setPosition(mSize.x() * 0.25f, mSize.y() * 0.4f); + mVideo.setSize(mSize.x() * (0.5f - 2*padding), mSize.y() * 0.4f); + addChild(&mVideo); + + // We want the video to be in front of the background but behind any 'extra' images + for (std::vector::iterator it = mChildren.begin(); it != mChildren.end(); ++it) + { + if (*it == &mThemeExtras) + { + mChildren.insert(it, &mVideo); + mChildren.pop_back(); + break; + } + } + + // metadata labels + values + mLblRating.setText("Rating: "); + addChild(&mLblRating); + addChild(&mRating); + mLblReleaseDate.setText("Released: "); + addChild(&mLblReleaseDate); + addChild(&mReleaseDate); + mLblDeveloper.setText("Developer: "); + addChild(&mLblDeveloper); + addChild(&mDeveloper); + mLblPublisher.setText("Publisher: "); + addChild(&mLblPublisher); + addChild(&mPublisher); + mLblGenre.setText("Genre: "); + addChild(&mLblGenre); + addChild(&mGenre); + mLblPlayers.setText("Players: "); + addChild(&mLblPlayers); + addChild(&mPlayers); + mLblLastPlayed.setText("Last played: "); + addChild(&mLblLastPlayed); + mLastPlayed.setDisplayMode(DateTimeComponent::DISP_RELATIVE_TO_NOW); + addChild(&mLastPlayed); + mLblPlayCount.setText("Times played: "); + addChild(&mLblPlayCount); + addChild(&mPlayCount); + + mDescContainer.setPosition(mSize.x() * padding, mSize.y() * 0.65f); + mDescContainer.setSize(mSize.x() * (0.50f - 2*padding), mSize.y() - mDescContainer.getPosition().y()); + mDescContainer.setAutoScroll(true); + addChild(&mDescContainer); + + mDescription.setFont(Font::get(FONT_SIZE_SMALL)); + mDescription.setSize(mDescContainer.getSize().x(), 0); + mDescContainer.addChild(&mDescription); + + initMDLabels(); + initMDValues(); + updateInfoPanel(); +} + +VideoGameListView::~VideoGameListView() +{ +} + +void VideoGameListView::onThemeChanged(const std::shared_ptr& theme) +{ + BasicGameListView::onThemeChanged(theme); + + using namespace ThemeFlags; + mMarquee.applyTheme(theme, getName(), "md_marquee", POSITION | ThemeFlags::SIZE); + mImage.applyTheme(theme, getName(), "md_image", POSITION | ThemeFlags::SIZE); + mVideo.applyTheme(theme, getName(), "md_video", POSITION | ThemeFlags::SIZE | ThemeFlags::DELAY); + + initMDLabels(); + std::vector labels = getMDLabels(); + assert(labels.size() == 8); + const char* lblElements[8] = { + "md_lbl_rating", "md_lbl_releasedate", "md_lbl_developer", "md_lbl_publisher", + "md_lbl_genre", "md_lbl_players", "md_lbl_lastplayed", "md_lbl_playcount" + }; + + for(unsigned int i = 0; i < labels.size(); i++) + { + labels[i]->applyTheme(theme, getName(), lblElements[i], ALL); + } + + + initMDValues(); + std::vector values = getMDValues(); + assert(values.size() == 8); + const char* valElements[8] = { + "md_rating", "md_releasedate", "md_developer", "md_publisher", + "md_genre", "md_players", "md_lastplayed", "md_playcount" + }; + + for(unsigned int i = 0; i < values.size(); i++) + { + values[i]->applyTheme(theme, getName(), valElements[i], ALL ^ ThemeFlags::TEXT); + } + + mDescContainer.applyTheme(theme, getName(), "md_description", POSITION | ThemeFlags::SIZE); + mDescription.setSize(mDescContainer.getSize().x(), 0); + mDescription.applyTheme(theme, getName(), "md_description", ALL ^ (POSITION | ThemeFlags::SIZE | TEXT)); +} + +void VideoGameListView::initMDLabels() +{ + using namespace Eigen; + + std::vector components = getMDLabels(); + + const unsigned int colCount = 2; + const unsigned int rowCount = components.size() / 2; + + Vector3f start(mSize.x() * 0.01f, mSize.y() * 0.625f, 0.0f); + + const float colSize = (mSize.x() * 0.48f) / colCount; + const float rowPadding = 0.01f * mSize.y(); + + for(unsigned int i = 0; i < components.size(); i++) + { + const unsigned int row = i % rowCount; + Vector3f pos(0.0f, 0.0f, 0.0f); + if(row == 0) + { + pos = start + Vector3f(colSize * (i / rowCount), 0, 0); + }else{ + // work from the last component + GuiComponent* lc = components[i-1]; + pos = lc->getPosition() + Vector3f(0, lc->getSize().y() + rowPadding, 0); + } + + components[i]->setFont(Font::get(FONT_SIZE_SMALL)); + components[i]->setPosition(pos); + } +} + +void VideoGameListView::initMDValues() +{ + using namespace Eigen; + + std::vector labels = getMDLabels(); + std::vector values = getMDValues(); + + std::shared_ptr defaultFont = Font::get(FONT_SIZE_SMALL); + mRating.setSize(defaultFont->getHeight() * 5.0f, (float)defaultFont->getHeight()); + mReleaseDate.setFont(defaultFont); + mDeveloper.setFont(defaultFont); + mPublisher.setFont(defaultFont); + mGenre.setFont(defaultFont); + mPlayers.setFont(defaultFont); + mLastPlayed.setFont(defaultFont); + mPlayCount.setFont(defaultFont); + + float bottom = 0.0f; + + const float colSize = (mSize.x() * 0.48f) / 2; + for(unsigned int i = 0; i < labels.size(); i++) + { + const float heightDiff = (labels[i]->getSize().y() - values[i]->getSize().y()) / 2; + values[i]->setPosition(labels[i]->getPosition() + Vector3f(labels[i]->getSize().x(), heightDiff, 0)); + values[i]->setSize(colSize - labels[i]->getSize().x(), values[i]->getSize().y()); + + float testBot = values[i]->getPosition().y() + values[i]->getSize().y(); + if(testBot > bottom) + bottom = testBot; + } + + mDescContainer.setPosition(mDescContainer.getPosition().x(), bottom + mSize.y() * 0.01f); + mDescContainer.setSize(mDescContainer.getSize().x(), mSize.y() - mDescContainer.getPosition().y()); +} + + + +void VideoGameListView::updateInfoPanel() +{ + FileData* file = (mList.size() == 0 || mList.isScrolling()) ? NULL : mList.getSelected(); + + bool fadingOut; + if(file == NULL) + { + mVideo.setVideo(""); + mVideo.setImage(""); + mVideoPlaying = false; + //mMarquee.setImage(""); + //mDescription.setText(""); + fadingOut = true; + + }else{ + std::string video_path; + std::string marquee_path; + std::string thumbnail_path; + video_path = file->getVideoPath(); + marquee_path = file->getMarqueePath(); + thumbnail_path = file->getThumbnailPath(); + + if (!video_path.empty() && (video_path[0] == '~')) + { + video_path.erase(0, 1); + video_path.insert(0, getHomePath()); + } + if (!marquee_path.empty() && (marquee_path[0] == '~')) + { + marquee_path.erase(0, 1); + marquee_path.insert(0, getHomePath()); + } + if (!thumbnail_path.empty() && (thumbnail_path[0] == '~')) + { + thumbnail_path.erase(0, 1); + thumbnail_path.insert(0, getHomePath()); + } + if (!mVideo.setVideo(video_path)) + mVideo.setDefaultVideo(); + mVideoPlaying = true; + + mVideo.setImage(thumbnail_path); + mMarquee.setImage(marquee_path); + mImage.setImage(thumbnail_path); + + mDescription.setText(file->metadata.get("desc")); + mDescContainer.reset(); + + if(file->getType() == GAME) + { + mRating.setValue(file->metadata.get("rating")); + mReleaseDate.setValue(file->metadata.get("releasedate")); + mDeveloper.setValue(file->metadata.get("developer")); + mPublisher.setValue(file->metadata.get("publisher")); + mGenre.setValue(file->metadata.get("genre")); + mPlayers.setValue(file->metadata.get("players")); + mLastPlayed.setValue(file->metadata.get("lastplayed")); + mPlayCount.setValue(file->metadata.get("playcount")); + } + + fadingOut = false; + } + + std::vector comps = getMDValues(); + comps.push_back(&mMarquee); + comps.push_back(&mVideo); + comps.push_back(&mDescription); + comps.push_back(&mImage); + std::vector labels = getMDLabels(); + comps.insert(comps.end(), labels.begin(), labels.end()); + + for(auto it = comps.begin(); it != comps.end(); it++) + { + GuiComponent* comp = *it; + // an animation is playing + // then animate if reverse != fadingOut + // an animation is not playing + // then animate if opacity != our target opacity + if((comp->isAnimationPlaying(0) && comp->isAnimationReversed(0) != fadingOut) || + (!comp->isAnimationPlaying(0) && comp->getOpacity() != (fadingOut ? 0 : 255))) + { + auto func = [comp](float t) + { + comp->setOpacity((unsigned char)(lerp(0.0f, 1.0f, t)*255)); + }; + comp->setAnimation(new LambdaAnimation(func, 150), 0, nullptr, fadingOut); + } + } +} + +void VideoGameListView::launch(FileData* game) +{ + Eigen::Vector3f target(Renderer::getScreenWidth() / 2.0f, Renderer::getScreenHeight() / 2.0f, 0); + if(mMarquee.hasImage()) + target << mVideo.getCenter().x(), mVideo.getCenter().y(), 0; + + ViewController::get()->launch(game, target); +} + +std::vector VideoGameListView::getMDLabels() +{ + std::vector ret; + ret.push_back(&mLblRating); + ret.push_back(&mLblReleaseDate); + ret.push_back(&mLblDeveloper); + ret.push_back(&mLblPublisher); + ret.push_back(&mLblGenre); + ret.push_back(&mLblPlayers); + ret.push_back(&mLblLastPlayed); + ret.push_back(&mLblPlayCount); + return ret; +} + +std::vector VideoGameListView::getMDValues() +{ + std::vector ret; + ret.push_back(&mRating); + ret.push_back(&mReleaseDate); + ret.push_back(&mDeveloper); + ret.push_back(&mPublisher); + ret.push_back(&mGenre); + ret.push_back(&mPlayers); + ret.push_back(&mLastPlayed); + ret.push_back(&mPlayCount); + return ret; +} + +void VideoGameListView::update(int deltaTime) +{ + BasicGameListView::update(deltaTime); + mVideo.update(deltaTime); +} diff --git a/es-app/src/views/gamelist/VideoGameListView.h b/es-app/src/views/gamelist/VideoGameListView.h new file mode 100644 index 0000000000..b0673d396d --- /dev/null +++ b/es-app/src/views/gamelist/VideoGameListView.h @@ -0,0 +1,53 @@ +#pragma once + +#include "views/gamelist/BasicGameListView.h" +#include "components/ScrollableContainer.h" +#include "components/RatingComponent.h" +#include "components/DateTimeComponent.h" +#include "components/VideoComponent.h" + +class VideoGameListView : public BasicGameListView +{ +public: + VideoGameListView(Window* window, FileData* root); + virtual ~VideoGameListView(); + + virtual void onThemeChanged(const std::shared_ptr& theme) override; + + virtual const char* getName() const override { return "video"; } + +protected: + virtual void launch(FileData* game) override; + + virtual void update(int deltaTime) override; + +private: + void updateInfoPanel(); + + void initMDLabels(); + void initMDValues(); + + ImageComponent mMarquee; + VideoComponent mVideo; + ImageComponent mImage; + + TextComponent mLblRating, mLblReleaseDate, mLblDeveloper, mLblPublisher, mLblGenre, mLblPlayers, mLblLastPlayed, mLblPlayCount; + + RatingComponent mRating; + DateTimeComponent mReleaseDate; + TextComponent mDeveloper; + TextComponent mPublisher; + TextComponent mGenre; + TextComponent mPlayers; + DateTimeComponent mLastPlayed; + TextComponent mPlayCount; + + std::vector getMDLabels(); + std::vector getMDValues(); + + ScrollableContainer mDescContainer; + TextComponent mDescription; + + bool mVideoPlaying; + +}; diff --git a/es-core/CMakeLists.txt b/es-core/CMakeLists.txt index 09219d6739..cf0cfb3ea3 100644 --- a/es-core/CMakeLists.txt +++ b/es-core/CMakeLists.txt @@ -42,6 +42,7 @@ set(CORE_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/src/components/SwitchComponent.h ${CMAKE_CURRENT_SOURCE_DIR}/src/components/TextComponent.h ${CMAKE_CURRENT_SOURCE_DIR}/src/components/TextEditComponent.h + ${CMAKE_CURRENT_SOURCE_DIR}/src/components/VideoComponent.h # Guis ${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiDetectDevice.h @@ -96,6 +97,7 @@ set(CORE_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/components/SwitchComponent.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/components/TextComponent.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/components/TextEditComponent.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/components/VideoComponent.cpp # Guis ${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiDetectDevice.cpp diff --git a/es-core/src/GuiComponent.cpp b/es-core/src/GuiComponent.cpp index d079930ded..6ba531f2bf 100644 --- a/es-core/src/GuiComponent.cpp +++ b/es-core/src/GuiComponent.cpp @@ -345,3 +345,17 @@ bool GuiComponent::isProcessing() const { return mIsProcessing; } + +void GuiComponent::onShow() +{ + for(unsigned int i = 0; i < getChildCount(); i++) + getChild(i)->onShow(); +} + +void GuiComponent::onHide() +{ + for(unsigned int i = 0; i < getChildCount(); i++) + getChild(i)->onHide(); +} + + diff --git a/es-core/src/GuiComponent.h b/es-core/src/GuiComponent.h index 566b2a615f..e37abe69f0 100644 --- a/es-core/src/GuiComponent.h +++ b/es-core/src/GuiComponent.h @@ -77,6 +77,9 @@ class GuiComponent virtual void onFocusGained() {}; virtual void onFocusLost() {}; + + virtual void onShow(); + virtual void onHide(); // Default implementation just handles and tags as normalized float pairs. // You probably want to keep this behavior for any derived classes as well as add your own. diff --git a/es-core/src/ThemeData.cpp b/es-core/src/ThemeData.cpp index fce86628f3..871e7dead0 100644 --- a/es-core/src/ThemeData.cpp +++ b/es-core/src/ThemeData.cpp @@ -82,7 +82,15 @@ std::map< std::string, ElementMapType > ThemeData::sElementMap = boost::assign:: ("textColor", COLOR) ("iconColor", COLOR) ("fontPath", PATH) - ("fontSize", FLOAT))); + ("fontSize", FLOAT))) + ("video", makeMap(boost::assign::map_list_of + ("pos", NORMALIZED_PAIR) + ("size", NORMALIZED_PAIR) + ("origin", NORMALIZED_PAIR) + ("default", PATH) + ("delay", FLOAT) + ("showSnapshotNoVideo", BOOLEAN) + ("showSnapshotDelay", BOOLEAN))); namespace fs = boost::filesystem; diff --git a/es-core/src/ThemeData.h b/es-core/src/ThemeData.h index 268f0753f1..32702a15c8 100644 --- a/es-core/src/ThemeData.h +++ b/es-core/src/ThemeData.h @@ -37,6 +37,7 @@ namespace ThemeFlags TEXT = 512, FORCE_UPPERCASE = 1024, LINE_SPACING = 2048, + DELAY = 4096, ALL = 0xFFFFFFFF }; diff --git a/es-core/src/Window.cpp b/es-core/src/Window.cpp index e5622e8ca5..761df4abc4 100644 --- a/es-core/src/Window.cpp +++ b/es-core/src/Window.cpp @@ -90,6 +90,11 @@ bool Window::init(unsigned int width, unsigned int height) void Window::deinit() { + // Hide all GUI elements on uninitialisation - this disable + for(auto i = mGuiStack.begin(); i != mGuiStack.end(); i++) + { + (*i)->onHide(); + } InputManager::getInstance()->deinit(); ResourceManager::getInstance()->unloadAll(); Renderer::deinit(); diff --git a/es-core/src/components/VideoComponent.cpp b/es-core/src/components/VideoComponent.cpp new file mode 100644 index 0000000000..6f41ffd786 --- /dev/null +++ b/es-core/src/components/VideoComponent.cpp @@ -0,0 +1,518 @@ +#include "components/VideoComponent.h" +#include "Renderer.h" +#include "ThemeData.h" +#include "Util.h" +#ifdef WIN32 +#include +#endif + +#define FADE_TIME_MS 200 + +libvlc_instance_t* VideoComponent::mVLC = NULL; + +// VLC prepares to render a video frame. +static void *lock(void *data, void **p_pixels) { + struct VideoContext *c = (struct VideoContext *)data; + SDL_LockMutex(c->mutex); + SDL_LockSurface(c->surface); + *p_pixels = c->surface->pixels; + return NULL; // Picture identifier, not needed here. +} + +// VLC just rendered a video frame. +static void unlock(void *data, void *id, void *const *p_pixels) { + struct VideoContext *c = (struct VideoContext *)data; + SDL_UnlockSurface(c->surface); + SDL_UnlockMutex(c->mutex); +} + +// VLC wants to display a video frame. +static void display(void *data, void *id) { + //Data to be displayed +} + +VideoComponent::VideoComponent(Window* window) : + GuiComponent(window), + mStaticImage(window), + mMediaPlayer(nullptr), + mVideoHeight(0), + mVideoWidth(0), + mStartDelayed(false), + mIsPlaying(false), + mShowing(false) +{ + memset(&mContext, 0, sizeof(mContext)); + + // Setup the default configuration + mConfig.showSnapshotDelay = false; + mConfig.showSnapshotNoVideo = false; + mConfig.startDelay = 0; + + // Get an empty texture for rendering the video + mTexture = TextureResource::get(""); + + // Make sure VLC has been initialised + setupVLC(); +} + +VideoComponent::~VideoComponent() +{ + // Stop any currently running video + stopVideo(); +} + +void VideoComponent::setOrigin(float originX, float originY) +{ + mOrigin << originX, originY; + + // Update the embeded static image + mStaticImage.setOrigin(originX, originY); +} + +Eigen::Vector2f VideoComponent::getCenter() const +{ + return Eigen::Vector2f(mPosition.x() - (getSize().x() * mOrigin.x()) + getSize().x() / 2, + mPosition.y() - (getSize().y() * mOrigin.y()) + getSize().y() / 2); +} + +void VideoComponent::onSizeChanged() +{ + // Update the embeded static image + mStaticImage.onSizeChanged(); +} + +bool VideoComponent::setVideo(std::string path) +{ + // Convert the path into a format VLC can understand + boost::filesystem::path fullPath = getCanonicalPath(path); + fullPath.make_preferred().native(); + + // Check that it's changed + if (fullPath == mVideoPath) + return !path.empty(); + + // Store the path + mVideoPath = fullPath; + + // If the file exists then set the new video + if (!fullPath.empty() && ResourceManager::getInstance()->fileExists(fullPath.generic_string())) + { + // Return true to show that we are going to attempt to play a video + return true; + } + // Return false to show that no video will be displayed + return false; +} + +void VideoComponent::setImage(std::string path) +{ + // Check that the image has changed + if (path == mStaticImagePath) + return; + + mStaticImage.setImage(path); + // Make the image stretch to fill the video region + mStaticImage.setSize(getSize()); + mFadeIn = 0.0f; + mStaticImagePath = path; +} + +void VideoComponent::setDefaultVideo() +{ + setVideo(mConfig.defaultVideoPath); +} + +void VideoComponent::setOpacity(unsigned char opacity) +{ + mOpacity = opacity; + // Update the embeded static image + mStaticImage.setOpacity(opacity); +} + +void VideoComponent::render(const Eigen::Affine3f& parentTrans) +{ + float x, y; + + Eigen::Affine3f trans = parentTrans * getTransform(); + GuiComponent::renderChildren(trans); + + Renderer::setMatrix(trans); + + // Handle the case where the video is delayed + handleStartDelay(); + + // Handle looping of the video + handleLooping(); + + if (mIsPlaying && mContext.valid) + { + float tex_offs_x = 0.0f; + float tex_offs_y = 0.0f; + float x2; + float y2; + + x = -(float)mSize.x() * mOrigin.x(); + y = -(float)mSize.y() * mOrigin.y(); + x2 = x+mSize.x(); + y2 = y+mSize.y(); + + // Define a structure to contain the data for each vertex + struct Vertex + { + Eigen::Vector2f pos; + Eigen::Vector2f tex; + Eigen::Vector4f colour; + } vertices[6]; + + // We need two triangles to cover the rectangular area + vertices[0].pos[0] = x; vertices[0].pos[1] = y; + vertices[1].pos[0] = x; vertices[1].pos[1] = y2; + vertices[2].pos[0] = x2; vertices[2].pos[1] = y; + + vertices[3].pos[0] = x2; vertices[3].pos[1] = y; + vertices[4].pos[0] = x; vertices[4].pos[1] = y2; + vertices[5].pos[0] = x2; vertices[5].pos[1] = y2; + + // Texture coordinates + vertices[0].tex[0] = -tex_offs_x; vertices[0].tex[1] = -tex_offs_y; + vertices[1].tex[0] = -tex_offs_x; vertices[1].tex[1] = 1.0f + tex_offs_y; + vertices[2].tex[0] = 1.0f + tex_offs_x; vertices[2].tex[1] = -tex_offs_y; + + vertices[3].tex[0] = 1.0f + tex_offs_x; vertices[3].tex[1] = -tex_offs_y; + vertices[4].tex[0] = -tex_offs_x; vertices[4].tex[1] = 1.0f + tex_offs_y; + vertices[5].tex[0] = 1.0f + tex_offs_x; vertices[5].tex[1] = 1.0f + tex_offs_y; + + // Colours - use this to fade the video in and out + for (int i = 0; i < (4 * 6); ++i) { + if ((i%4) < 3) + vertices[i / 4].colour[i % 4] = mFadeIn; + else + vertices[i / 4].colour[i % 4] = 1.0f; + } + + glEnable(GL_TEXTURE_2D); + + // Build a texture for the video frame + mTexture->initFromPixels((unsigned char*)mContext.surface->pixels, mContext.surface->w, mContext.surface->h); + mTexture->bind(); + + // Render it + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glColorPointer(4, GL_FLOAT, sizeof(Vertex), &vertices[0].colour); + glVertexPointer(2, GL_FLOAT, sizeof(Vertex), &vertices[0].pos); + glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &vertices[0].tex); + + glDrawArrays(GL_TRIANGLES, 0, 6); + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + + glDisable(GL_TEXTURE_2D); + } + else + { + // This is the case where the video is not currently being displayed. Work out + // if we need to display a static image + if ((mConfig.showSnapshotNoVideo && mVideoPath.empty()) || (mStartDelayed && mConfig.showSnapshotDelay)) + { + // Display the static image instead + mStaticImage.setOpacity((unsigned char)(mFadeIn * 255.0f)); + mStaticImage.render(parentTrans); + } + } + +} + +void VideoComponent::applyTheme(const std::shared_ptr& theme, const std::string& view, const std::string& element, unsigned int properties) +{ + using namespace ThemeFlags; + + const ThemeData::ThemeElement* elem = theme->getElement(view, element, "video"); + if(!elem) + { + return; + } + + Eigen::Vector2f scale = getParent() ? getParent()->getSize() : Eigen::Vector2f((float)Renderer::getScreenWidth(), (float)Renderer::getScreenHeight()); + + if ((properties & POSITION) && elem->has("pos")) + { + Eigen::Vector2f denormalized = elem->get("pos").cwiseProduct(scale); + setPosition(Eigen::Vector3f(denormalized.x(), denormalized.y(), 0)); + } + + if ((properties & ThemeFlags::SIZE) && elem->has("size")) + { + setSize(elem->get("size").cwiseProduct(scale)); + } + + // position + size also implies origin + if (((properties & ORIGIN) || ((properties & POSITION) && (properties & ThemeFlags::SIZE))) && elem->has("origin")) + setOrigin(elem->get("origin")); + + if(elem->has("default")) + mConfig.defaultVideoPath = elem->get("default"); + + if((properties & ThemeFlags::DELAY) && elem->has("delay")) + mConfig.startDelay = (unsigned)(elem->get("delay") * 1000.0f); + + if (elem->has("showSnapshotNoVideo")) + mConfig.showSnapshotNoVideo = elem->get("showSnapshotNoVideo"); + + if (elem->has("showSnapshotDelay")) + mConfig.showSnapshotDelay = elem->get("showSnapshotDelay"); + + // Update the embeded static image + mStaticImage.setPosition(getPosition()); + mStaticImage.setMaxSize(getSize()); + mStaticImage.setSize(getSize()); +} + +std::vector VideoComponent::getHelpPrompts() +{ + std::vector ret; + ret.push_back(HelpPrompt("a", "select")); + return ret; +} + +void VideoComponent::setupContext() +{ + if (!mContext.valid) + { + // Create an RGBA surface to render the video into + mContext.surface = SDL_CreateRGBSurface(SDL_SWSURFACE, (int)mVideoWidth, (int)mVideoHeight, 32, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff); + mContext.mutex = SDL_CreateMutex(); + mContext.valid = true; + } +} + +void VideoComponent::freeContext() +{ + if (mContext.valid) + { + SDL_FreeSurface(mContext.surface); + SDL_DestroyMutex(mContext.mutex); + mContext.valid = false; + } +} + +void VideoComponent::setupVLC() +{ + // If VLC hasn't been initialised yet then do it now + if (!mVLC) + { + const char* args[] = { "--quiet" }; + mVLC = libvlc_new(sizeof(args) / sizeof(args[0]), args); + } +} + +void VideoComponent::handleStartDelay() +{ + // Only play if any delay has timed out + if (mStartDelayed) + { + if (mStartTime > SDL_GetTicks()) + { + // Timeout not yet completed + return; + } + // Completed + mStartDelayed = false; + // Clear the playing flag so startVideo works + mIsPlaying = false; + startVideo(); + } +} + +void VideoComponent::handleLooping() +{ + if (mIsPlaying && mMediaPlayer) + { + libvlc_state_t state = libvlc_media_player_get_state(mMediaPlayer); + if (state == libvlc_Ended) + { + //libvlc_media_player_set_position(mMediaPlayer, 0.0f); + libvlc_media_player_set_media(mMediaPlayer, mMedia); + libvlc_media_player_play(mMediaPlayer); + } + } +} + +void VideoComponent::startVideo() +{ + if (!mIsPlaying) { + mVideoWidth = 0; + mVideoHeight = 0; + +#ifdef WIN32 + std::wstring_convert, wchar_t> wton; + std::string path = wton.to_bytes(mVideoPath.c_str()); +#else + std::string path(mVideoPath.c_str()); +#endif + // Make sure we have a video path + if (mVLC && (path.size() > 0)) + { + // Set the video that we are going to be playing so we don't attempt to restart it + mPlayingVideoPath = mVideoPath; + + // Open the media + mMedia = libvlc_media_new_path(mVLC, path.c_str()); + if (mMedia) + { + unsigned track_count; + // Get the media metadata so we can find the aspect ratio + libvlc_media_parse(mMedia); + libvlc_media_track_t** tracks; + track_count = libvlc_media_tracks_get(mMedia, &tracks); + for (unsigned track = 0; track < track_count; ++track) + { + if (tracks[track]->i_type == libvlc_track_video) + { + mVideoWidth = tracks[track]->video->i_width; + mVideoHeight = tracks[track]->video->i_height; + break; + } + } + libvlc_media_tracks_release(tracks, track_count); + + // Make sure we found a valid video track + if ((mVideoWidth > 0) && (mVideoHeight > 0)) + { + setupContext(); + + // Setup the media player + mMediaPlayer = libvlc_media_player_new_from_media(mMedia); + libvlc_media_player_play(mMediaPlayer); + libvlc_video_set_callbacks(mMediaPlayer, lock, unlock, display, (void*)&mContext); + libvlc_video_set_format(mMediaPlayer, "RGBA", (int)mVideoWidth, (int)mVideoHeight, (int)mVideoWidth * 4); + + // Update the playing state + mIsPlaying = true; + mFadeIn = 0.0f; + } + } + } + } +} + +void VideoComponent::startVideoWithDelay() +{ + // If not playing then either start the video or initiate the delay + if (!mIsPlaying) + { + // Set the video that we are going to be playing so we don't attempt to restart it + mPlayingVideoPath = mVideoPath; + + if (mConfig.startDelay == 0) + { + // No delay. Just start the video + mStartDelayed = false; + startVideo(); + } + else + { + // Configure the start delay + mStartDelayed = true; + mFadeIn = 0.0f; + mStartTime = SDL_GetTicks() + mConfig.startDelay; + } + mIsPlaying = true; + } +} + +void VideoComponent::stopVideo() +{ + mIsPlaying = false; + mStartDelayed = false; + // Release the media player so it stops calling back to us + if (mMediaPlayer) + { + libvlc_media_player_stop(mMediaPlayer); + libvlc_media_player_release(mMediaPlayer); + libvlc_media_release(mMedia); + mMediaPlayer = NULL; + freeContext(); + } +} + +void VideoComponent::update(int deltaTime) +{ + manageState(); + + // If the video start is delayed and there is less than the fade time then set the image fade + // accordingly + if (mStartDelayed) + { + Uint32 ticks = SDL_GetTicks(); + if (mStartTime > ticks) + { + Uint32 diff = mStartTime - ticks; + if (diff < FADE_TIME_MS) + { + mFadeIn = (float)diff / (float)FADE_TIME_MS; + return; + } + } + } + // If the fade in is less than 1 then increment it + if (mFadeIn < 1.0f) + { + mFadeIn += deltaTime / (float)FADE_TIME_MS; + if (mFadeIn > 1.0f) + mFadeIn = 1.0f; + } + GuiComponent::update(deltaTime); +} + +void VideoComponent::manageState() +{ + // We will only show if the component is on display + bool show = mShowing; + + // See if we're already playing + if (mIsPlaying) + { + // If we are not on display then stop the video from playing + if (!show) + { + stopVideo(); + } + else + { + if (mVideoPath != mPlayingVideoPath) + { + // Path changed. Stop the video. We will start it again below because + // mIsPlaying will be modified by stopVideo to be false + stopVideo(); + } + } + } + // Need to recheck variable rather than 'else' because it may be modified above + if (!mIsPlaying) + { + // If we are on display then see if we should start the video + if (show && !mVideoPath.empty()) + { + startVideoWithDelay(); + } + } +} + +void VideoComponent::onShow() +{ + mShowing = true; + manageState(); +} + +void VideoComponent::onHide() +{ + mShowing = false; + manageState(); +} + + diff --git a/es-core/src/components/VideoComponent.h b/es-core/src/components/VideoComponent.h new file mode 100644 index 0000000000..f8376cfe90 --- /dev/null +++ b/es-core/src/components/VideoComponent.h @@ -0,0 +1,112 @@ +#ifndef _VIDEOCOMPONENT_H_ +#define _VIDEOCOMPONENT_H_ + +#include "platform.h" +#include GLHEADER + +#include "GuiComponent.h" +#include "ImageComponent.h" +#include +#include +#include "resources/TextureResource.h" +#include +#include +#include +#include + +struct VideoContext { + SDL_Surface* surface; + SDL_mutex* mutex; + bool valid; +}; + +class VideoComponent : public GuiComponent +{ + // Structure that groups together the configuration of the video component + struct Configuration + { + unsigned startDelay; + bool showSnapshotNoVideo; + bool showSnapshotDelay; + std::string defaultVideoPath; + }; + +public: + static void setupVLC(); + + VideoComponent(Window* window); + virtual ~VideoComponent(); + + // Loads the video at the given filepath + bool setVideo(std::string path); + // Loads a static image that is displayed if the video cannot be played + void setImage(std::string path); + + // Configures the component to show the default video + void setDefaultVideo(); + + virtual void onShow() override; + virtual void onHide() override; + + //Sets the origin as a percentage of this image (e.g. (0, 0) is top left, (0.5, 0.5) is the center) + void setOrigin(float originX, float originY); + inline void setOrigin(Eigen::Vector2f origin) { setOrigin(origin.x(), origin.y()); } + + void onSizeChanged() override; + void setOpacity(unsigned char opacity) override; + + void render(const Eigen::Affine3f& parentTrans) override; + + virtual void applyTheme(const std::shared_ptr& theme, const std::string& view, const std::string& element, unsigned int properties) override; + + virtual std::vector getHelpPrompts() override; + + // Returns the center point of the video (takes origin into account). + Eigen::Vector2f getCenter() const; + + virtual void update(int deltaTime); + +private: + // Start the video Immediately + void startVideo(); + // Start the video after any configured delay + void startVideoWithDelay(); + // Stop the video + void stopVideo(); + + void setupContext(); + void freeContext(); + + // Handle any delay to the start of playing the video clip. Must be called periodically + void handleStartDelay(); + + // Handle looping the video. Must be called periodically + void handleLooping(); + + // Manage the playing state of the component + void manageState(); + +private: + static libvlc_instance_t* mVLC; + libvlc_media_t* mMedia; + libvlc_media_player_t* mMediaPlayer; + VideoContext mContext; + unsigned mVideoWidth; + unsigned mVideoHeight; + Eigen::Vector2f mOrigin; + std::shared_ptr mTexture; + float mFadeIn; + std::string mStaticImagePath; + ImageComponent mStaticImage; + + boost::filesystem::path mVideoPath; + boost::filesystem::path mPlayingVideoPath; + bool mStartDelayed; + unsigned mStartTime; + bool mIsPlaying; + bool mShowing; + + Configuration mConfig; +}; + +#endif From e2bb889d016a15e9313dadb2b910db3e9852be04 Mon Sep 17 00:00:00 2001 From: Jools Wills Date: Mon, 12 Dec 2016 17:04:20 +0000 Subject: [PATCH 39/74] bumped version number to 2.1.0rp --- es-app/src/EmulationStation.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/es-app/src/EmulationStation.h b/es-app/src/EmulationStation.h index 3fbb279050..99cdb39a70 100644 --- a/es-app/src/EmulationStation.h +++ b/es-app/src/EmulationStation.h @@ -3,11 +3,11 @@ // These numbers and strings need to be manually updated for a new version. // Do this version number update as the very last commit for the new release version. #define PROGRAM_VERSION_MAJOR 2 -#define PROGRAM_VERSION_MINOR 0 -#define PROGRAM_VERSION_MAINTENANCE 1 -#define PROGRAM_VERSION_STRING "2.0.1a" +#define PROGRAM_VERSION_MINOR 1 +#define PROGRAM_VERSION_MAINTENANCE 0 +#define PROGRAM_VERSION_STRING "2.1.0rp" #define PROGRAM_BUILT_STRING __DATE__ " - " __TIME__ -#define RESOURCE_VERSION_STRING "2,0,1\0" +#define RESOURCE_VERSION_STRING "2,1,0\0" #define RESOURCE_VERSION PROGRAM_VERSION_MAJOR,PROGRAM_VERSION_MINOR,PROGRAM_VERSION_MAINTENANCE From a97a8a30901d8e0b025f283a44b99b2fd4411755 Mon Sep 17 00:00:00 2001 From: Jools Wills Date: Thu, 15 Dec 2016 17:57:20 +0000 Subject: [PATCH 40/74] check for libMali.so in additional locations --- CMakeLists.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 48143a5230..261215014f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,9 +26,11 @@ else() endif() #------------------------------------------------------------------------------- -#check if we're running on olinuxino +#check if we're running on olinuxino / odroid / etc MESSAGE("Looking for libMali.so") -if(EXISTS "/usr/lib/libMali.so") +if(EXISTS "/usr/lib/libMali.so" OR + EXISTS "/usr/lib/arm-linux-gnueabihf/libMali.so" OR + EXISTS "/usr/lib/aarch64-linux-gnu/libMali.so") MESSAGE("libMali.so found") set(GLSystem "OpenGL ES") else() From 44ea23ae6ae8ace74193ebdc0a6e70f7f43b8e10 Mon Sep 17 00:00:00 2001 From: verybadsoldier Date: Mon, 19 Dec 2016 16:59:40 +0100 Subject: [PATCH 41/74] when saving gamelist.xml only save metadata that has been changed (to speed things up) --- es-app/src/Gamelist.cpp | 29 +++++++++++++++++++---------- es-app/src/MetaData.cpp | 15 +++++++++++++-- es-app/src/MetaData.h | 4 ++++ 3 files changed, 36 insertions(+), 12 deletions(-) diff --git a/es-app/src/Gamelist.cpp b/es-app/src/Gamelist.cpp index aeb8d0580f..dacf88fd4f 100644 --- a/es-app/src/Gamelist.cpp +++ b/es-app/src/Gamelist.cpp @@ -139,6 +139,8 @@ void parseGamelist(SystemData* system) //make sure name gets set if one didn't exist if(file->metadata.get("name").empty()) file->metadata.set("name", defaultName); + + file->metadata.resetChangedFlag(); } } } @@ -207,20 +209,24 @@ void updateGamelist(SystemData* system) FileData* rootFolder = system->getRootFolder(); if (rootFolder != nullptr) { + int numUpdated = 0; + //get only files, no folders std::vector files = rootFolder->getFilesRecursive(GAME | FOLDER); //iterate through all files, checking if they're already in the XML - std::vector::const_iterator fit = files.cbegin(); - while(fit != files.cend()) + for(std::vector::const_iterator fit = files.cbegin(); fit != files.cend(); ++fit) { const char* tag = ((*fit)->getType() == GAME) ? "game" : "folder"; // check if current file has metadata, if no, skip it as it wont be in the gamelist anyway. if ((*fit)->metadata.isDefault()) { - ++fit; continue; } + // do not touch if it wasn't changed anyway + if (!(*fit)->metadata.wasChanged()) + continue; + // check if the file already exists in the XML // if it does, remove it before adding for(pugi::xml_node fileNode = root.child(tag); fileNode; fileNode = fileNode.next_sibling(tag)) @@ -244,18 +250,21 @@ void updateGamelist(SystemData* system) // it was either removed or never existed to begin with; either way, we can add it now addFileDataNode(root, *fit, tag, system); - - ++fit; + ++numUpdated; } //now write the file - //make sure the folders leading up to this path exist (or the write will fail) - boost::filesystem::path xmlWritePath(system->getGamelistPath(true)); - boost::filesystem::create_directories(xmlWritePath.parent_path()); + if (numUpdated > 0) { + //make sure the folders leading up to this path exist (or the write will fail) + boost::filesystem::path xmlWritePath(system->getGamelistPath(true)); + boost::filesystem::create_directories(xmlWritePath.parent_path()); + + LOG(LogInfo) << "Added/Updated " << numUpdated << " entities in '" << xmlReadPath << "'"; - if (!doc.save_file(xmlWritePath.c_str())) { - LOG(LogError) << "Error saving gamelist.xml to \"" << xmlWritePath << "\" (for system " << system->getName() << ")!"; + if (!doc.save_file(xmlWritePath.c_str())) { + LOG(LogError) << "Error saving gamelist.xml to \"" << xmlWritePath << "\" (for system " << system->getName() << ")!"; + } } }else{ LOG(LogError) << "Found no root folder for system \"" << system->getName() << "\"!"; diff --git a/es-app/src/MetaData.cpp b/es-app/src/MetaData.cpp index 3f5da45c67..390ed4efb9 100644 --- a/es-app/src/MetaData.cpp +++ b/es-app/src/MetaData.cpp @@ -49,7 +49,7 @@ const std::vector& getMDDByType(MetaDataListType type) MetaDataList::MetaDataList(MetaDataListType type) - : mType(type) + : mType(type), mWasChanged(false) { const std::vector& mdd = getMDD(); for(auto iter = mdd.begin(); iter != mdd.end(); iter++) @@ -110,11 +110,12 @@ void MetaDataList::appendToXML(pugi::xml_node parent, bool ignoreDefaults, const void MetaDataList::set(const std::string& key, const std::string& value) { mMap[key] = value; + mWasChanged = true; } void MetaDataList::setTime(const std::string& key, const boost::posix_time::ptime& time) { - mMap[key] = boost::posix_time::to_iso_string(time); + set(key, boost::posix_time::to_iso_string(time)); } const std::string& MetaDataList::get(const std::string& key) const @@ -145,3 +146,13 @@ bool MetaDataList::isDefault() return true; } + +bool MetaDataList::wasChanged() const +{ + return mWasChanged; +} + +void MetaDataList::resetChangedFlag() +{ + mWasChanged = false; +} diff --git a/es-app/src/MetaData.h b/es-app/src/MetaData.h index 136a8b2f6a..df444e9d4c 100644 --- a/es-app/src/MetaData.h +++ b/es-app/src/MetaData.h @@ -58,10 +58,14 @@ class MetaDataList bool isDefault(); + bool wasChanged() const; + void resetChangedFlag(); + inline MetaDataListType getType() const { return mType; } inline const std::vector& getMDD() const { return getMDDByType(getType()); } private: MetaDataListType mType; std::map mMap; + bool mWasChanged; }; From 9ad911c18d8b7e9a769c0f7b09013c63d6202d2e Mon Sep 17 00:00:00 2001 From: Jools Wills Date: Tue, 20 Dec 2016 14:46:55 +0000 Subject: [PATCH 42/74] fixes crash when saving meta data - #79 --- es-app/src/MetaData.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/es-app/src/MetaData.cpp b/es-app/src/MetaData.cpp index 3f5da45c67..09305a0c46 100644 --- a/es-app/src/MetaData.cpp +++ b/es-app/src/MetaData.cpp @@ -139,8 +139,10 @@ boost::posix_time::ptime MetaDataList::getTime(const std::string& key) const bool MetaDataList::isDefault() { + const std::vector& mdd = getMDD(); + for (int i = 1; i < mMap.size(); i++) { - if (mMap.at(gameDecls[i].key) != gameDecls[i].defaultValue) return false; + if (mMap.at(mdd[i].key) != mdd[i].defaultValue) return false; } return true; From 747a78bd456c763feab17a71f308aad80dc7e3ed Mon Sep 17 00:00:00 2001 From: Jools Wills Date: Tue, 20 Dec 2016 14:49:43 +0000 Subject: [PATCH 43/74] bump version number to 2.1.1rp --- es-app/src/EmulationStation.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/es-app/src/EmulationStation.h b/es-app/src/EmulationStation.h index 99cdb39a70..12cfb2e678 100644 --- a/es-app/src/EmulationStation.h +++ b/es-app/src/EmulationStation.h @@ -4,10 +4,10 @@ // Do this version number update as the very last commit for the new release version. #define PROGRAM_VERSION_MAJOR 2 #define PROGRAM_VERSION_MINOR 1 -#define PROGRAM_VERSION_MAINTENANCE 0 -#define PROGRAM_VERSION_STRING "2.1.0rp" +#define PROGRAM_VERSION_MAINTENANCE 1 +#define PROGRAM_VERSION_STRING "2.1.1rp" #define PROGRAM_BUILT_STRING __DATE__ " - " __TIME__ -#define RESOURCE_VERSION_STRING "2,1,0\0" +#define RESOURCE_VERSION_STRING "2,1,1\0" #define RESOURCE_VERSION PROGRAM_VERSION_MAJOR,PROGRAM_VERSION_MINOR,PROGRAM_VERSION_MAINTENANCE From 56971d54a54f5670e8178c9e92491eaed328e6b8 Mon Sep 17 00:00:00 2001 From: Jools Wills Date: Tue, 20 Dec 2016 18:01:07 +0000 Subject: [PATCH 44/74] bump version to 2.1.2 --- es-app/src/EmulationStation.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/es-app/src/EmulationStation.h b/es-app/src/EmulationStation.h index 12cfb2e678..da8d26ed7d 100644 --- a/es-app/src/EmulationStation.h +++ b/es-app/src/EmulationStation.h @@ -4,10 +4,10 @@ // Do this version number update as the very last commit for the new release version. #define PROGRAM_VERSION_MAJOR 2 #define PROGRAM_VERSION_MINOR 1 -#define PROGRAM_VERSION_MAINTENANCE 1 -#define PROGRAM_VERSION_STRING "2.1.1rp" +#define PROGRAM_VERSION_MAINTENANCE 2 +#define PROGRAM_VERSION_STRING "2.1.2rp" #define PROGRAM_BUILT_STRING __DATE__ " - " __TIME__ -#define RESOURCE_VERSION_STRING "2,1,1\0" +#define RESOURCE_VERSION_STRING "2,1,2\0" #define RESOURCE_VERSION PROGRAM_VERSION_MAJOR,PROGRAM_VERSION_MINOR,PROGRAM_VERSION_MAINTENANCE From d6b726cc34a84d21ec4fafb6c25bb73c76adfaa9 Mon Sep 17 00:00:00 2001 From: Jools Wills Date: Fri, 30 Dec 2016 21:35:10 +0000 Subject: [PATCH 45/74] return es error code --- emulationstation.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/emulationstation.sh b/emulationstation.sh index 227078f06d..c6915bafdf 100755 --- a/emulationstation.sh +++ b/emulationstation.sh @@ -4,6 +4,7 @@ esdir="$(dirname $0)" while true; do rm -f /tmp/es-restart /tmp/es-sysrestart /tmp/es-shutdown "$esdir/emulationstation" "$@" + ret=$? [ -f /tmp/es-restart ] && continue if [ -f /tmp/es-sysrestart ]; then rm -f /tmp/es-sysrestart @@ -17,3 +18,4 @@ while true; do fi break done +exit $ret From e974cd9d43d1f86677e5cd7b261eefc92a9b4b83 Mon Sep 17 00:00:00 2001 From: John Rassa Date: Thu, 12 Jan 2017 19:17:53 +0000 Subject: [PATCH 46/74] Added a --no-splash option for disableing the ES logo fix indentation --- es-app/src/main.cpp | 8 ++++++-- es-core/src/Settings.cpp | 4 +++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/es-app/src/main.cpp b/es-app/src/main.cpp index 393f199fd3..6753b9ae31 100644 --- a/es-app/src/main.cpp +++ b/es-app/src/main.cpp @@ -55,6 +55,9 @@ bool parseArgs(int argc, char* argv[], unsigned int* width, unsigned int* height }else if(strcmp(argv[i], "--no-exit") == 0) { Settings::getInstance()->setBool("ShowExit", false); + }else if(strcmp(argv[i], "--no-splash") == 0) + { + Settings::getInstance()->setBool("SplashScreen", false); }else if(strcmp(argv[i], "--debug") == 0) { Settings::getInstance()->setBool("Debug", true); @@ -91,6 +94,7 @@ bool parseArgs(int argc, char* argv[], unsigned int* width, unsigned int* height "--ignore-gamelist ignore the gamelist (useful for troubleshooting)\n" "--draw-framerate display the framerate\n" "--no-exit don't show the exit option in the menu\n" + "--no-splash don't show the splash screen\n" "--debug more logging, show console on Windows\n" "--scrape scrape using command line interface\n" "--windowed not fullscreen, should be used with --resolution\n" @@ -225,8 +229,8 @@ int main(int argc, char* argv[]) std::string glExts = (const char*)glGetString(GL_EXTENSIONS); LOG(LogInfo) << "Checking available OpenGL extensions..."; LOG(LogInfo) << " ARB_texture_non_power_of_two: " << (glExts.find("ARB_texture_non_power_of_two") != std::string::npos ? "ok" : "MISSING"); - - window.renderLoadingScreen(); + if(Settings::getInstance()->getBool("SplashScreen")) + window.renderLoadingScreen(); } const char* errorMsg = NULL; diff --git a/es-core/src/Settings.cpp b/es-core/src/Settings.cpp index 67f12150df..337dcaac13 100644 --- a/es-core/src/Settings.cpp +++ b/es-core/src/Settings.cpp @@ -17,7 +17,8 @@ std::vector settings_dont_save = boost::assign::list_of ("Windowed") ("VSync") ("HideConsole") - ("IgnoreGamelist"); + ("IgnoreGamelist") + ("SplashScreen"); Settings::Settings() { @@ -43,6 +44,7 @@ void Settings::setDefaults() mBoolMap["DrawFramerate"] = false; mBoolMap["ShowExit"] = true; mBoolMap["Windowed"] = false; + mBoolMap["SplashScreen"] = true; #ifdef _RPI_ // don't enable VSync by default on the Pi, since it already From df9f5b8c3f34e682ba0e395b20cf3ab28b0fa043 Mon Sep 17 00:00:00 2001 From: Steven Selph Date: Wed, 18 Jan 2017 21:43:50 -0500 Subject: [PATCH 47/74] Remove TheArchive scraper --- es-app/CMakeLists.txt | 2 - es-app/src/guis/GuiMenu.cpp | 2 - es-app/src/scrapers/Scraper.cpp | 4 +- es-app/src/scrapers/TheArchiveScraper.cpp | 66 ----------------------- es-app/src/scrapers/TheArchiveScraper.h | 16 ------ 5 files changed, 1 insertion(+), 89 deletions(-) delete mode 100644 es-app/src/scrapers/TheArchiveScraper.cpp delete mode 100644 es-app/src/scrapers/TheArchiveScraper.h diff --git a/es-app/CMakeLists.txt b/es-app/CMakeLists.txt index 47dfd131c5..04cbf509c0 100644 --- a/es-app/CMakeLists.txt +++ b/es-app/CMakeLists.txt @@ -30,7 +30,6 @@ set(ES_HEADERS # Scrapers ${CMAKE_CURRENT_SOURCE_DIR}/src/scrapers/Scraper.h ${CMAKE_CURRENT_SOURCE_DIR}/src/scrapers/GamesDBScraper.h - ${CMAKE_CURRENT_SOURCE_DIR}/src/scrapers/TheArchiveScraper.h # Views ${CMAKE_CURRENT_SOURCE_DIR}/src/views/gamelist/BasicGameListView.h @@ -77,7 +76,6 @@ set(ES_SOURCES # Scrapers ${CMAKE_CURRENT_SOURCE_DIR}/src/scrapers/Scraper.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/scrapers/GamesDBScraper.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/src/scrapers/TheArchiveScraper.cpp # Views ${CMAKE_CURRENT_SOURCE_DIR}/src/views/gamelist/BasicGameListView.cpp diff --git a/es-app/src/guis/GuiMenu.cpp b/es-app/src/guis/GuiMenu.cpp index d005fc04ec..71ac7272bc 100644 --- a/es-app/src/guis/GuiMenu.cpp +++ b/es-app/src/guis/GuiMenu.cpp @@ -17,8 +17,6 @@ #include "components/OptionListComponent.h" #include "components/MenuComponent.h" #include "VolumeControl.h" -#include "scrapers/GamesDBScraper.h" -#include "scrapers/TheArchiveScraper.h" GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MENU"), mVersion(window) { diff --git a/es-app/src/scrapers/Scraper.cpp b/es-app/src/scrapers/Scraper.cpp index c827a4755f..ff4ba88db1 100644 --- a/es-app/src/scrapers/Scraper.cpp +++ b/es-app/src/scrapers/Scraper.cpp @@ -6,11 +6,9 @@ #include #include "GamesDBScraper.h" -#include "TheArchiveScraper.h" const std::map scraper_request_funcs = boost::assign::map_list_of - ("TheGamesDB", &thegamesdb_generate_scraper_requests) - ("TheArchive", &thearchive_generate_scraper_requests); + ("TheGamesDB", &thegamesdb_generate_scraper_requests); std::unique_ptr startScraperSearch(const ScraperSearchParams& params) { diff --git a/es-app/src/scrapers/TheArchiveScraper.cpp b/es-app/src/scrapers/TheArchiveScraper.cpp deleted file mode 100644 index fe490ca555..0000000000 --- a/es-app/src/scrapers/TheArchiveScraper.cpp +++ /dev/null @@ -1,66 +0,0 @@ -#include "TheArchiveScraper.h" -#include "Log.h" -#include "pugixml/pugixml.hpp" - -void thearchive_generate_scraper_requests(const ScraperSearchParams& params, std::queue< std::unique_ptr >& requests, - std::vector& results) -{ - std::string path = "api.archive.vg/2.0/Archive.search/xml/7TTRM4MNTIKR2NNAGASURHJOZJ3QXQC5/"; - - std::string cleanName = params.nameOverride; - if(cleanName.empty()) - cleanName = params.game->getCleanName(); - - path += HttpReq::urlEncode(cleanName); - //platform TODO, should use some params.system get method - - requests.push(std::unique_ptr(new TheArchiveRequest(results, path))); -} - -void TheArchiveRequest::process(const std::unique_ptr& req, std::vector& results) -{ - assert(req->status() == HttpReq::REQ_SUCCESS); - - pugi::xml_document doc; - pugi::xml_parse_result parseResult = doc.load(req->getContent().c_str()); - if(!parseResult) - { - std::stringstream ss; - ss << "TheArchiveRequest - error parsing XML.\n\t" << parseResult.description(); - std::string err = ss.str(); - setError(err); - LOG(LogError) << err; - return; - } - - pugi::xml_node data = doc.child("OpenSearchDescription").child("games"); - - pugi::xml_node game = data.child("game"); - while(game && results.size() < MAX_SCRAPER_RESULTS) - { - ScraperSearchResult result; - - result.mdl.set("name", game.child("title").text().get()); - result.mdl.set("desc", game.child("description").text().get()); - - //Archive.search does not return ratings - - result.mdl.set("developer", game.child("developer").text().get()); - - std::string genre = game.child("genre").text().get(); - size_t search = genre.find_last_of(" > "); - genre = genre.substr(search == std::string::npos ? 0 : search, std::string::npos); - result.mdl.set("genre", genre); - - pugi::xml_node image = game.child("box_front"); - pugi::xml_node thumbnail = game.child("box_front_small"); - - if(image) - result.imageUrl = image.text().get(); - if(thumbnail) - result.thumbnailUrl = thumbnail.text().get(); - - results.push_back(result); - game = game.next_sibling("game"); - } -} diff --git a/es-app/src/scrapers/TheArchiveScraper.h b/es-app/src/scrapers/TheArchiveScraper.h deleted file mode 100644 index 9837539a4e..0000000000 --- a/es-app/src/scrapers/TheArchiveScraper.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include "scrapers/Scraper.h" - -void thearchive_generate_scraper_requests(const ScraperSearchParams& params, std::queue< std::unique_ptr >& requests, - std::vector& results); - -void thearchive_process_httpreq(const std::unique_ptr& req, std::vector& results); - -class TheArchiveRequest : public ScraperHttpRequest -{ -public: - TheArchiveRequest(std::vector& resultsWrite, const std::string& url) : ScraperHttpRequest(resultsWrite, url) {} -protected: - void process(const std::unique_ptr& req, std::vector& results) override; -}; \ No newline at end of file From 454473224240b3106d7f14fcff9f2d30e2e771b3 Mon Sep 17 00:00:00 2001 From: fieldofcows Date: Sun, 22 Jan 2017 23:28:06 +0000 Subject: [PATCH 48/74] Fix WSOD by loading textures on demand in a separate thread when a user configurable texture memory threshold is reached --- es-app/src/components/RatingComponent.cpp | 12 +- es-app/src/guis/GuiMenu.cpp | 6 + es-app/src/main.cpp | 5 + es-app/src/views/SystemView.cpp | 4 +- es-app/src/views/ViewController.cpp | 4 +- es-core/CMakeLists.txt | 6 +- es-core/src/Settings.cpp | 3 +- es-core/src/Window.cpp | 9 +- es-core/src/components/ImageComponent.cpp | 66 ++++- es-core/src/components/ImageComponent.h | 7 +- es-core/src/resources/SVGResource.cpp | 101 -------- es-core/src/resources/SVGResource.h | 27 -- es-core/src/resources/TextureData.cpp | 259 +++++++++++++++++++ es-core/src/resources/TextureData.h | 63 +++++ es-core/src/resources/TextureDataManager.cpp | 226 ++++++++++++++++ es-core/src/resources/TextureDataManager.h | 86 ++++++ es-core/src/resources/TextureResource.cpp | 245 +++++++++++------- es-core/src/resources/TextureResource.h | 49 ++-- 18 files changed, 897 insertions(+), 281 deletions(-) delete mode 100644 es-core/src/resources/SVGResource.cpp delete mode 100644 es-core/src/resources/SVGResource.h create mode 100644 es-core/src/resources/TextureData.cpp create mode 100644 es-core/src/resources/TextureData.h create mode 100644 es-core/src/resources/TextureDataManager.cpp create mode 100644 es-core/src/resources/TextureDataManager.h diff --git a/es-app/src/components/RatingComponent.cpp b/es-app/src/components/RatingComponent.cpp index 12f39a3090..3dbc36a0a4 100644 --- a/es-app/src/components/RatingComponent.cpp +++ b/es-app/src/components/RatingComponent.cpp @@ -2,7 +2,6 @@ #include "Renderer.h" #include "Window.h" #include "Util.h" -#include "resources/SVGResource.h" RatingComponent::RatingComponent(Window* window) : GuiComponent(window) { @@ -45,16 +44,13 @@ void RatingComponent::onSizeChanged() else if(mSize.x() == 0) mSize[0] = mSize.y() * NUM_RATING_STARS; - auto filledSVG = dynamic_cast(mFilledTexture.get()); - auto unfilledSVG = dynamic_cast(mUnfilledTexture.get()); - if(mSize.y() > 0) { size_t heightPx = (size_t)round(mSize.y()); - if(filledSVG) - filledSVG->rasterizeAt(heightPx, heightPx); - if(unfilledSVG) - unfilledSVG->rasterizeAt(heightPx, heightPx); + if (mFilledTexture) + mFilledTexture->rasterizeAt(heightPx, heightPx); + if(mUnfilledTexture) + mUnfilledTexture->rasterizeAt(heightPx, heightPx); } updateVertices(); diff --git a/es-app/src/guis/GuiMenu.cpp b/es-app/src/guis/GuiMenu.cpp index 71ac7272bc..68b1a355d1 100644 --- a/es-app/src/guis/GuiMenu.cpp +++ b/es-app/src/guis/GuiMenu.cpp @@ -178,6 +178,12 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MEN s->addWithLabel("PARSE GAMESLISTS ONLY", parse_gamelists); s->addSaveFunc([parse_gamelists] { Settings::getInstance()->setBool("ParseGamelistOnly", parse_gamelists->getState()); }); + // maximum vram + auto max_vram = std::make_shared(mWindow, 0.f, 1000.f, 10.f, "Mb"); + max_vram->setValue((float)(Settings::getInstance()->getInt("MaxVRAM"))); + s->addWithLabel("VRAM LIMIT", max_vram); + s->addSaveFunc([max_vram] { Settings::getInstance()->setInt("MaxVRAM", (int)round(max_vram->getValue())); }); + mWindow->pushGui(s); }); diff --git a/es-app/src/main.cpp b/es-app/src/main.cpp index 6753b9ae31..c3d030ec4b 100644 --- a/es-app/src/main.cpp +++ b/es-app/src/main.cpp @@ -74,6 +74,10 @@ bool parseArgs(int argc, char* argv[], unsigned int* width, unsigned int* height }else if(strcmp(argv[i], "--scrape") == 0) { scrape_cmdline = true; + }else if(strcmp(argv[i], "--max-vram") == 0) + { + int maxVRAM = atoi(argv[i + 1]); + Settings::getInstance()->setInt("MaxVRAM", maxVRAM); }else if(strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) { #ifdef WIN32 @@ -99,6 +103,7 @@ bool parseArgs(int argc, char* argv[], unsigned int* width, unsigned int* height "--scrape scrape using command line interface\n" "--windowed not fullscreen, should be used with --resolution\n" "--vsync [1/on or 0/off] turn vsync on or off (default is on)\n" + "--max-vram [size] Max VRAM to use in Mb before swapping. 0 for unlimited\n" "--help, -h summon a sentient, angry tuba\n\n" "More information available in README.md.\n"; return false; //exit after printing help diff --git a/es-app/src/views/SystemView.cpp b/es-app/src/views/SystemView.cpp index 013490aca9..c760125b97 100644 --- a/es-app/src/views/SystemView.cpp +++ b/es-app/src/views/SystemView.cpp @@ -43,13 +43,13 @@ void SystemView::populate() // make logo if(theme->getElement("system", "logo", "image")) { - ImageComponent* logo = new ImageComponent(mWindow); + ImageComponent* logo = new ImageComponent(mWindow, false, false); logo->setMaxSize(Eigen::Vector2f(logoSize().x(), logoSize().y())); logo->applyTheme((*it)->getTheme(), "system", "logo", ThemeFlags::PATH); logo->setPosition((logoSize().x() - logo->getSize().x()) / 2, (logoSize().y() - logo->getSize().y()) / 2); // center e.data.logo = std::shared_ptr(logo); - ImageComponent* logoSelected = new ImageComponent(mWindow); + ImageComponent* logoSelected = new ImageComponent(mWindow, false, false); logoSelected->setMaxSize(Eigen::Vector2f(logoSize().x() * SELECTED_SCALE, logoSize().y() * SELECTED_SCALE * 0.70f)); logoSelected->applyTheme((*it)->getTheme(), "system", "logo", ThemeFlags::PATH); logoSelected->setPosition((logoSize().x() - logoSelected->getSize().x()) / 2, diff --git a/es-app/src/views/ViewController.cpp b/es-app/src/views/ViewController.cpp index 1e10c91753..d9093e8e10 100644 --- a/es-app/src/views/ViewController.cpp +++ b/es-app/src/views/ViewController.cpp @@ -406,7 +406,9 @@ void ViewController::reloadAll() mCurrentView = getGameListView(mState.getSystem()); }else if(mState.viewing == SYSTEM_SELECT) { - mSystemListView->goToSystem(mState.getSystem(), false); + SystemData* system = mState.getSystem(); + goToSystemView(SystemData::sSystemVector.front()); + mSystemListView->goToSystem(system, false); mCurrentView = mSystemListView; }else{ goToSystemView(SystemData::sSystemVector.front()); diff --git a/es-core/CMakeLists.txt b/es-core/CMakeLists.txt index cf0cfb3ea3..f05aec77c3 100644 --- a/es-core/CMakeLists.txt +++ b/es-core/CMakeLists.txt @@ -53,8 +53,9 @@ set(CORE_HEADERS # Resources ${CMAKE_CURRENT_SOURCE_DIR}/src/resources/Font.h ${CMAKE_CURRENT_SOURCE_DIR}/src/resources/ResourceManager.h - ${CMAKE_CURRENT_SOURCE_DIR}/src/resources/SVGResource.h ${CMAKE_CURRENT_SOURCE_DIR}/src/resources/TextureResource.h + ${CMAKE_CURRENT_SOURCE_DIR}/src/resources/TextureData.h + ${CMAKE_CURRENT_SOURCE_DIR}/src/resources/TextureDataManager.h # Embedded assets (needed by ResourceManager) ${emulationstation-all_SOURCE_DIR}/data/Resources.h @@ -108,8 +109,9 @@ set(CORE_SOURCES # Resources ${CMAKE_CURRENT_SOURCE_DIR}/src/resources/Font.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/resources/ResourceManager.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/src/resources/SVGResource.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/resources/TextureResource.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/resources/TextureData.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/resources/TextureDataManager.cpp ) set(EMBEDDED_ASSET_SOURCES diff --git a/es-core/src/Settings.cpp b/es-core/src/Settings.cpp index 337dcaac13..df90ba7b65 100644 --- a/es-core/src/Settings.cpp +++ b/es-core/src/Settings.cpp @@ -69,6 +69,7 @@ void Settings::setDefaults() mIntMap["ScreenSaverTime"] = 5*60*1000; // 5 minutes mIntMap["ScraperResizeWidth"] = 400; mIntMap["ScraperResizeHeight"] = 0; + mIntMap["MaxVRAM"] = 100; mStringMap["TransitionStyle"] = "fade"; mStringMap["ThemeSet"] = ""; @@ -154,4 +155,4 @@ void Settings::setMethodName(const std::string& name, type value) \ SETTINGS_GETSET(bool, mBoolMap, getBool, setBool); SETTINGS_GETSET(int, mIntMap, getInt, setInt); SETTINGS_GETSET(float, mFloatMap, getFloat, setFloat); -SETTINGS_GETSET(const std::string&, mStringMap, getString, setString); \ No newline at end of file +SETTINGS_GETSET(const std::string&, mStringMap, getString, setString); diff --git a/es-core/src/Window.cpp b/es-core/src/Window.cpp index 761df4abc4..e402162c3d 100644 --- a/es-core/src/Window.cpp +++ b/es-core/src/Window.cpp @@ -160,11 +160,12 @@ void Window::update(int deltaTime) ss << std::fixed << std::setprecision(2) << ((float)mFrameTimeElapsed / (float)mFrameCountElapsed) << "ms"; // vram - float textureVramUsageMb = TextureResource::getTotalMemUsage() / 1000.0f / 1000.0f;; + float textureVramUsageMb = TextureResource::getTotalMemUsage() / 1000.0f / 1000.0f; + float textureTotalUsageMb = TextureResource::getTotalTextureSize() / 1000.0f / 1000.0f; float fontVramUsageMb = Font::getTotalMemUsage() / 1000.0f / 1000.0f;; - float totalVramUsageMb = textureVramUsageMb + fontVramUsageMb; - ss << "\nVRAM: " << totalVramUsageMb << "mb (texs: " << textureVramUsageMb << "mb, fonts: " << fontVramUsageMb << "mb)"; + ss << "\nFont VRAM: " << fontVramUsageMb << " Tex VRAM: " << textureVramUsageMb << + " Tex Max: " << textureTotalUsageMb; mFrameDataText = std::unique_ptr(mDefaultFonts.at(1)->buildTextCache(ss.str(), 50.f, 50.f, 0xFF00FFFF)); } @@ -242,7 +243,7 @@ void Window::renderLoadingScreen() Renderer::setMatrix(trans); Renderer::drawRect(0, 0, Renderer::getScreenWidth(), Renderer::getScreenHeight(), 0xFFFFFFFF); - ImageComponent splash(this); + ImageComponent splash(this, true); splash.setResize(Renderer::getScreenWidth() * 0.6f, 0.0f); splash.setImage(":/splash.svg"); splash.setPosition((Renderer::getScreenWidth() - splash.getSize().x()) / 2, (Renderer::getScreenHeight() - splash.getSize().y()) / 2 * 0.6f); diff --git a/es-core/src/components/ImageComponent.cpp b/es-core/src/components/ImageComponent.cpp index 2898c6f732..1ae62314d8 100644 --- a/es-core/src/components/ImageComponent.cpp +++ b/es-core/src/components/ImageComponent.cpp @@ -6,7 +6,6 @@ #include "Renderer.h" #include "ThemeData.h" #include "Util.h" -#include "resources/SVGResource.h" Eigen::Vector2i ImageComponent::getTextureSize() const { @@ -22,8 +21,9 @@ Eigen::Vector2f ImageComponent::getCenter() const mPosition.y() - (getSize().y() * mOrigin.y()) + getSize().y() / 2); } -ImageComponent::ImageComponent(Window* window) : GuiComponent(window), - mTargetIsMax(false), mFlipX(false), mFlipY(false), mOrigin(0.0, 0.0), mTargetSize(0, 0), mColorShift(0xFFFFFFFF) +ImageComponent::ImageComponent(Window* window, bool forceLoad, bool dynamic) : GuiComponent(window), + mTargetIsMax(false), mFlipX(false), mFlipY(false), mOrigin(0.0, 0.0), mTargetSize(0, 0), mColorShift(0xFFFFFFFF), + mForceLoad(forceLoad), mDynamic(dynamic) { updateColors(); } @@ -37,9 +37,7 @@ void ImageComponent::resize() if(!mTexture) return; - SVGResource* svg = dynamic_cast(mTexture.get()); - - const Eigen::Vector2f textureSize = svg ? svg->getSourceImageSize() : Eigen::Vector2f((float)mTexture->getSize().x(), (float)mTexture->getSize().y()); + const Eigen::Vector2f textureSize = mTexture->getSourceImageSize(); if(textureSize.isZero()) return; @@ -90,12 +88,8 @@ void ImageComponent::resize() } } } - - if(svg) - { - // mSize.y() should already be rounded - svg->rasterizeAt((int)round(mSize.x()), (int)round(mSize.y())); - } + // mSize.y() should already be rounded + mTexture->rasterizeAt((int)round(mSize.x()), (int)round(mSize.y())); onSizeChanged(); } @@ -110,7 +104,7 @@ void ImageComponent::setImage(std::string path, bool tile) if(path.empty() || !ResourceManager::getInstance()->fileExists(path)) mTexture.reset(); else - mTexture = TextureResource::get(path, tile); + mTexture = TextureResource::get(path, tile, mForceLoad, mDynamic); resize(); } @@ -247,7 +241,10 @@ void ImageComponent::render(const Eigen::Affine3f& parentTrans) if(mTexture->isInitialized()) { // actually draw the image - mTexture->bind(); + // The bind() function returns false if the texture is not currently loaded. A blank + // texture is bound in this case but we want to handle a fade so it doesn't just 'jump' in + // when it finally loads + fadeIn(mTexture->bind()); glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); @@ -278,6 +275,47 @@ void ImageComponent::render(const Eigen::Affine3f& parentTrans) GuiComponent::renderChildren(trans); } +void ImageComponent::fadeIn(bool textureLoaded) +{ + if (!mForceLoad) + { + if (!textureLoaded) + { + // Start the fade if this is the first time we've encountered the unloaded texture + if (!mFading) + { + // Start with a zero opacity and flag it as fading + mFadeOpacity = 0; + mFading = true; + // Set the colours to be translucent + mColorShift = (mColorShift >> 8 << 8) | 0; + updateColors(); + } + } + else if (mFading) + { + // The texture is loaded and we need to fade it in. The fade is based on the frame rate + // and is 1/4 second if running at 60 frames per second although the actual value is not + // that important + int opacity = mFadeOpacity + 255 / 15; + // See if we've finished fading + if (opacity >= 255) + { + mFadeOpacity = 255; + mFading = false; + } + else + { + mFadeOpacity = (unsigned char)opacity; + } + // Apply the combination of the target opacity and current fade + float newOpacity = (float)mOpacity * ((float)mFadeOpacity / 255.0f); + mColorShift = (mColorShift >> 8 << 8) | (unsigned char)newOpacity; + updateColors(); + } + } +} + bool ImageComponent::hasImage() { return (bool)mTexture; diff --git a/es-core/src/components/ImageComponent.h b/es-core/src/components/ImageComponent.h index 939c6c7cd2..3ff1ffbb27 100644 --- a/es-core/src/components/ImageComponent.h +++ b/es-core/src/components/ImageComponent.h @@ -12,7 +12,7 @@ class ImageComponent : public GuiComponent { public: - ImageComponent(Window* window); + ImageComponent(Window* window, bool forceLoad = false, bool dynamic = true); virtual ~ImageComponent(); //Loads the image at the given filepath. Will tile if tile is true (retrieves texture as tiling, creates vertices accordingly). @@ -81,10 +81,15 @@ class ImageComponent : public GuiComponent void updateVertices(); void updateColors(); + void fadeIn(bool textureLoaded); unsigned int mColorShift; std::shared_ptr mTexture; + unsigned char mFadeOpacity; + bool mFading; + bool mForceLoad; + bool mDynamic; }; #endif diff --git a/es-core/src/resources/SVGResource.cpp b/es-core/src/resources/SVGResource.cpp deleted file mode 100644 index 1a4ea16fca..0000000000 --- a/es-core/src/resources/SVGResource.cpp +++ /dev/null @@ -1,101 +0,0 @@ -#include "SVGResource.h" -#include "nanosvg/nanosvg.h" -#include "nanosvg/nanosvgrast.h" -#include "Log.h" -#include "Util.h" -#include "ImageIO.h" - -#define DPI 96 - -SVGResource::SVGResource(const std::string& path, bool tile) : TextureResource(path, tile), mSVGImage(NULL) -{ - mLastWidth = 0; - mLastHeight = 0; -} - -SVGResource::~SVGResource() -{ - deinitSVG(); -} - -void SVGResource::unload(std::shared_ptr& rm) -{ - deinitSVG(); - TextureResource::unload(rm); -} - -void SVGResource::initFromMemory(const char* file, size_t length) -{ - deinit(); - deinitSVG(); - - // nsvgParse excepts a modifiable, null-terminated string - char* copy = (char*)malloc(length + 1); - assert(copy != NULL); - memcpy(copy, file, length); - copy[length] = '\0'; - - mSVGImage = nsvgParse(copy, "px", DPI); - free(copy); - - if(!mSVGImage) - { - LOG(LogError) << "Error parsing SVG image."; - return; - } - - if(mLastWidth && mLastHeight) - rasterizeAt(mLastWidth, mLastHeight); - else - rasterizeAt((size_t)round(mSVGImage->width), (size_t)round(mSVGImage->height)); -} - -void SVGResource::rasterizeAt(size_t width, size_t height) -{ - if(!mSVGImage || (width == 0 && height == 0)) - return; - - if(width == 0) - { - // auto scale width to keep aspect - width = (size_t)round((height / mSVGImage->height) * mSVGImage->width); - }else if(height == 0) - { - // auto scale height to keep aspect - height = (size_t)round((width / mSVGImage->width) * mSVGImage->height); - } - - if(width != (size_t)round(mSVGImage->width) && height != (size_t)round(mSVGImage->height)) - { - mLastWidth = width; - mLastHeight = height; - } - - unsigned char* imagePx = (unsigned char*)malloc(width * height * 4); - assert(imagePx != NULL); - - NSVGrasterizer* rast = nsvgCreateRasterizer(); - nsvgRasterize(rast, mSVGImage, 0, 0, height / mSVGImage->height, imagePx, width, height, width * 4); - nsvgDeleteRasterizer(rast); - - ImageIO::flipPixelsVert(imagePx, width, height); - - initFromPixels(imagePx, width, height); - free(imagePx); -} - -Eigen::Vector2f SVGResource::getSourceImageSize() const -{ - if(mSVGImage) - return Eigen::Vector2f(mSVGImage->width, mSVGImage->height); - - return Eigen::Vector2f::Zero(); -} - -void SVGResource::deinitSVG() -{ - if(mSVGImage) - nsvgDelete(mSVGImage); - - mSVGImage = NULL; -} diff --git a/es-core/src/resources/SVGResource.h b/es-core/src/resources/SVGResource.h deleted file mode 100644 index 87479c0cf1..0000000000 --- a/es-core/src/resources/SVGResource.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include "resources/TextureResource.h" - -struct NSVGimage; - -class SVGResource : public TextureResource -{ -public: - virtual ~SVGResource(); - - virtual void unload(std::shared_ptr& rm) override; - - virtual void initFromMemory(const char* image, size_t length) override; - - void rasterizeAt(size_t width, size_t height); - Eigen::Vector2f getSourceImageSize() const; - -protected: - friend TextureResource; - SVGResource(const std::string& path, bool tile); - void deinitSVG(); - - NSVGimage* mSVGImage; - size_t mLastWidth; - size_t mLastHeight; -}; diff --git a/es-core/src/resources/TextureData.cpp b/es-core/src/resources/TextureData.cpp new file mode 100644 index 0000000000..15a3da116e --- /dev/null +++ b/es-core/src/resources/TextureData.cpp @@ -0,0 +1,259 @@ +#include "resources/TextureData.h" +#include "resources/ResourceManager.h" +#include "Log.h" +#include "ImageIO.h" +#include "string.h" +#include "Util.h" +#include "nanosvg/nanosvg.h" +#include "nanosvg/nanosvgrast.h" +#include + +#define DPI 96 + +TextureData::TextureData(bool tile) : mTile(tile), mTextureID(0), mDataRGBA(nullptr), mScalable(false), + mWidth(0), mHeight(0), mSourceWidth(0.0f), mSourceHeight(0.0f) +{ +} + +TextureData::~TextureData() +{ + releaseVRAM(); + releaseRAM(); +} + +void TextureData::initFromPath(const std::string& path) +{ + // Just set the path. It will be loaded later + mPath = path; + // Only textures with paths are reloadable + mReloadable = true; +} + +bool TextureData::initSVGFromMemory(const unsigned char* fileData, size_t length) +{ + // If already initialised then don't read again + { + std::unique_lock lock(mMutex); + if (mDataRGBA) + return true; + } + + // nsvgParse excepts a modifiable, null-terminated string + char* copy = (char*)malloc(length + 1); + assert(copy != NULL); + memcpy(copy, fileData, length); + copy[length] = '\0'; + + NSVGimage* svgImage = nsvgParse(copy, "px", DPI); + free(copy); + if (!svgImage) + { + LOG(LogError) << "Error parsing SVG image."; + return false; + } + + // We want to rasterise this texture at a specific resolution. If the source size + // variables are set then use them otherwise set them from the parsed file + if ((mSourceWidth == 0.0f) && (mSourceHeight == 0.0f)) + { + mSourceWidth = svgImage->width; + mSourceHeight = svgImage->height; + } + mWidth = (size_t)round(mSourceWidth); + mHeight = (size_t)round(mSourceHeight); + + if (mWidth == 0) + { + // auto scale width to keep aspect + mWidth = (size_t)round(((float)mHeight / svgImage->height) * svgImage->width); + } + else if (mHeight == 0) + { + // auto scale height to keep aspect + mHeight = (size_t)round(((float)mWidth / svgImage->width) * svgImage->height); + } + + unsigned char* dataRGBA = new unsigned char[mWidth * mHeight * 4]; + + NSVGrasterizer* rast = nsvgCreateRasterizer(); + nsvgRasterize(rast, svgImage, 0, 0, mHeight / svgImage->height, dataRGBA, mWidth, mHeight, mWidth * 4); + nsvgDeleteRasterizer(rast); + + ImageIO::flipPixelsVert(dataRGBA, mWidth, mHeight); + + std::unique_lock lock(mMutex); + mDataRGBA = dataRGBA; + + return true; +} + +bool TextureData::initImageFromMemory(const unsigned char* fileData, size_t length) +{ + size_t width, height; + + // If already initialised then don't read again + { + std::unique_lock lock(mMutex); + if (mDataRGBA) + return true; + } + + std::vector imageRGBA = ImageIO::loadFromMemoryRGBA32((const unsigned char*)(fileData), length, width, height); + if (imageRGBA.size() == 0) + { + LOG(LogError) << "Could not initialize texture from memory, invalid data! (file path: " << mPath << ", data ptr: " << (size_t)fileData << ", reported size: " << length << ")"; + return false; + } + + mSourceWidth = width; + mSourceHeight = height; + mScalable = false; + + return initFromRGBA(imageRGBA.data(), width, height); +} + +bool TextureData::initFromRGBA(const unsigned char* dataRGBA, size_t width, size_t height) +{ + // If already initialised then don't read again + std::unique_lock lock(mMutex); + if (mDataRGBA) + return true; + + // Take a copy + mDataRGBA = new unsigned char[width * height * 4]; + memcpy(mDataRGBA, dataRGBA, width * height * 4); + mWidth = width; + mHeight = height; + return true; +} + +bool TextureData::load() +{ + bool retval = false; + + // Need to load. See if there is a file + if (!mPath.empty()) + { + std::shared_ptr& rm = ResourceManager::getInstance(); + const ResourceData& data = rm->getFileData(mPath); + // is it an SVG? + if (mPath.substr(mPath.size() - 4, std::string::npos) == ".svg") + { + mScalable = true; + retval = initSVGFromMemory((const unsigned char*)data.ptr.get(), data.length); + } + else + retval = initImageFromMemory((const unsigned char*)data.ptr.get(), data.length); + } + return retval; +} + +bool TextureData::isLoaded() +{ + std::unique_lock lock(mMutex); + if (mDataRGBA || (mTextureID != 0)) + return true; + return false; +} + +bool TextureData::uploadAndBind() +{ + // See if it's already been uploaded + std::unique_lock lock(mMutex); + if (mTextureID != 0) + { + glBindTexture(GL_TEXTURE_2D, mTextureID); + } + else + { + // Load it if necessary + if (!mDataRGBA) + { + return false; + } + // Make sure we're ready to upload + if ((mWidth == 0) || (mHeight == 0) || (mDataRGBA == nullptr)) + return false; + glGetError(); + //now for the openGL texture stuff + glGenTextures(1, &mTextureID); + glBindTexture(GL_TEXTURE_2D, mTextureID); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, mWidth, mHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, mDataRGBA); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + const GLint wrapMode = mTile ? GL_REPEAT : GL_CLAMP_TO_EDGE; + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapMode); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapMode); + } + return true; +} + +void TextureData::releaseVRAM() +{ + std::unique_lock lock(mMutex); + if (mTextureID != 0) + { + glDeleteTextures(1, &mTextureID); + mTextureID = 0; + } +} + +void TextureData::releaseRAM() +{ + std::unique_lock lock(mMutex); + delete[] mDataRGBA; + mDataRGBA = 0; +} + +size_t TextureData::width() +{ + if (mWidth == 0) + load(); + return mWidth; +} + +size_t TextureData::height() +{ + if (mHeight == 0) + load(); + return mHeight; +} + +float TextureData::sourceWidth() +{ + if (mSourceWidth == 0) + load(); + return mSourceWidth; +} + +float TextureData::sourceHeight() +{ + if (mSourceHeight == 0) + load(); + return mSourceHeight; +} + +void TextureData::setSourceSize(float width, float height) +{ + if (mScalable) + { + if ((mSourceWidth != width) || (mSourceHeight != height)) + { + mSourceWidth = width; + mSourceHeight = height; + releaseVRAM(); + releaseRAM(); + } + } +} + +size_t TextureData::getVRAMUsage() +{ + if ((mTextureID != 0) || (mDataRGBA != nullptr)) + return mWidth * mHeight * 4; + else + return 0; +} diff --git a/es-core/src/resources/TextureData.h b/es-core/src/resources/TextureData.h new file mode 100644 index 0000000000..76ca6a0b4d --- /dev/null +++ b/es-core/src/resources/TextureData.h @@ -0,0 +1,63 @@ +#pragma once + +#include +#include +#include "platform.h" +#include +#include GLHEADER + +class TextureResource; + +class TextureData +{ +public: + TextureData(bool tile); + ~TextureData(); + + // These functions populate mDataRGBA but do not upload the texture to VRAM + + //!!!! Needs to be canonical path. Caller should check for duplicates before calling this + void initFromPath(const std::string& path); + bool initSVGFromMemory(const unsigned char* fileData, size_t length); + bool initImageFromMemory(const unsigned char* fileData, size_t length); + bool initFromRGBA(const unsigned char* dataRGBA, size_t width, size_t height); + + // Read the data into memory if necessary + bool load(); + + bool isLoaded(); + + // Upload the texture to VRAM if necessary and bind. Returns true if bound ok or + // false if either not loaded + bool uploadAndBind(); + + // Release the texture from VRAM + void releaseVRAM(); + + // Release the texture from conventional RAM + void releaseRAM(); + + // Get the amount of VRAM currenty used by this texture + size_t getVRAMUsage(); + + size_t width(); + size_t height(); + float sourceWidth(); + float sourceHeight(); + void setSourceSize(float width, float height); + + bool tiled() { return mTile; } + +private: + std::mutex mMutex; + bool mTile; + std::string mPath; + GLuint mTextureID; + unsigned char* mDataRGBA; + size_t mWidth; + size_t mHeight; + float mSourceWidth; + float mSourceHeight; + bool mScalable; + bool mReloadable; +}; diff --git a/es-core/src/resources/TextureDataManager.cpp b/es-core/src/resources/TextureDataManager.cpp new file mode 100644 index 0000000000..55720d14ac --- /dev/null +++ b/es-core/src/resources/TextureDataManager.cpp @@ -0,0 +1,226 @@ +#include "resources/TextureDataManager.h" +#include "resources/TextureResource.h" +#include "Settings.h" + +TextureDataManager::TextureDataManager() +{ + unsigned char data[5 * 5 * 4]; + mBlank = std::shared_ptr(new TextureData(false)); + for (int i = 0; i < (5 * 5); ++i) + { + data[i*4] = (i % 2) * 255; + data[i*4+1] = (i % 2) * 255; + data[i*4+2] = (i % 2) * 255; + data[i*4+3] = 0; + } + mBlank->initFromRGBA(data, 5, 5); + mLoader = new TextureLoader; +} + +TextureDataManager::~TextureDataManager() +{ + delete mLoader; +} + +std::shared_ptr TextureDataManager::add(const TextureResource* key, bool tiled) +{ + remove(key); + std::shared_ptr data(new TextureData(tiled)); + mTextures.push_front(data); + mTextureLookup[key] = mTextures.begin(); + return data; +} + +void TextureDataManager::remove(const TextureResource* key) +{ + // Find the entry in the list + auto it = mTextureLookup.find(key); + if (it != mTextureLookup.end()) + { + // Remove the list entry + mTextures.erase((*it).second); + // And the lookup + mTextureLookup.erase(it); + } +} + +std::shared_ptr TextureDataManager::get(const TextureResource* key) +{ + // If it's in the cache then we want to remove it from it's current location and + // move it to the top + std::shared_ptr tex; + auto it = mTextureLookup.find(key); + if (it != mTextureLookup.end()) + { + tex = *(*it).second; + // Remove the list entry + mTextures.erase((*it).second); + // Put it at the top + mTextures.push_front(tex); + // Store it back in the lookup + mTextureLookup[key] = mTextures.begin(); + + // Make sure it's loaded or queued for loading + load(tex); + } + return tex; +} + +bool TextureDataManager::bind(const TextureResource* key) +{ + std::shared_ptr tex = get(key); + bool bound = false; + if (tex != nullptr) + bound = tex->uploadAndBind(); + if (!bound) + mBlank->uploadAndBind(); + return bound; +} + +size_t TextureDataManager::getTotalSize() +{ + size_t total = 0; + for (auto tex : mTextures) + total += tex->width() * tex->height() * 4; + return total; +} + +size_t TextureDataManager::getCommittedSize() +{ + size_t total = 0; + for (auto tex : mTextures) + total += tex->getVRAMUsage(); + return total; +} + +size_t TextureDataManager::getQueueSize() +{ + return mLoader->getQueueSize(); +} + +void TextureDataManager::load(std::shared_ptr tex, bool block) +{ + // See if it's already loaded + if (tex->isLoaded()) + return; + // Not loaded. Make sure there is room + size_t size = TextureResource::getTotalMemUsage(); + size_t max_texture = (size_t)Settings::getInstance()->getInt("MaxVRAM") * 1024 * 1024; + + size_t in = size; + + for (auto it = mTextures.rbegin(); it != mTextures.rend(); ++it) + { + if (size < max_texture) + break; + //size -= (*it)->getVRAMUsage(); + (*it)->releaseVRAM(); + (*it)->releaseRAM(); + // It may be already in the loader queue. In this case it wouldn't have been using + // any VRAM yet but it will be. Remove it from the loader queue + mLoader->remove(*it); + size = TextureResource::getTotalMemUsage(); + } + if (!block) + mLoader->load(tex); + else + tex->load(); +} + +TextureLoader::TextureLoader() : mExit(false) +{ + mThread = new std::thread(&TextureLoader::threadProc, this); +} + +TextureLoader::~TextureLoader() +{ + // Just abort any waiting texture + mTextureDataQ.clear(); + mTextureDataLookup.clear(); + + // Exit the thread + mExit = true; + mEvent.notify_one(); + mThread->join(); + delete mThread; +} + +void TextureLoader::threadProc() +{ + while (!mExit) + { + std::shared_ptr textureData; + { + // Wait for an event to say there is something in the queue + std::unique_lock lock(mMutex); + mEvent.wait(lock); + if (!mTextureDataQ.empty()) + { + textureData = mTextureDataQ.front(); + mTextureDataQ.pop_front(); + mTextureDataLookup.erase(mTextureDataLookup.find(textureData.get())); + } + } + // Queue has been released here but we might have a texture to process + while (textureData) + { + textureData->load(); + + // See if there is another item in the queue + textureData = nullptr; + std::unique_lock lock(mMutex); + if (!mTextureDataQ.empty()) + { + textureData = mTextureDataQ.front(); + mTextureDataQ.pop_front(); + mTextureDataLookup.erase(mTextureDataLookup.find(textureData.get())); + } + } + } +} + +void TextureLoader::load(std::shared_ptr textureData) +{ + // Make sure it's not already loaded + if (!textureData->isLoaded()) + { + std::unique_lock lock(mMutex); + // Remove it from the queue if it is already there + auto td = mTextureDataLookup.find(textureData.get()); + if (td != mTextureDataLookup.end()) + { + mTextureDataQ.erase((*td).second); + mTextureDataLookup.erase(td); + } + + // Put it on the start of the queue as we want the newly requested textures to load first + mTextureDataQ.push_front(textureData); + mTextureDataLookup[textureData.get()] = mTextureDataQ.begin(); + mEvent.notify_one(); + } +} + +void TextureLoader::remove(std::shared_ptr textureData) +{ + // Just remove it from the queue so we don't attempt to load it + std::unique_lock lock(mMutex); + auto td = mTextureDataLookup.find(textureData.get()); + if (td != mTextureDataLookup.end()) + { + mTextureDataQ.erase((*td).second); + mTextureDataLookup.erase(td); + } +} + +size_t TextureLoader::getQueueSize() +{ + // Gets the amount of video memory that will be used once all textures in + // the queue are loaded + size_t mem = 0; + std::unique_lock lock(mMutex); + for (auto tex : mTextureDataQ) + { + mem += tex->width() * tex->height() * 4; + } + return mem; +} diff --git a/es-core/src/resources/TextureDataManager.h b/es-core/src/resources/TextureDataManager.h new file mode 100644 index 0000000000..414804aba9 --- /dev/null +++ b/es-core/src/resources/TextureDataManager.h @@ -0,0 +1,86 @@ +#pragma once + +#include "resources/ResourceManager.h" +#include "platform.h" +#include "resources/TextureData.h" +#include +#include +#include +#include +#include +#include + +class TextureResource; + +class TextureLoader +{ +public: + TextureLoader(); + ~TextureLoader(); + + void load(std::shared_ptr textureData); + void remove(std::shared_ptr textureData); + + size_t getQueueSize(); + +private: + void processQueue(); + void threadProc(); + + std::list > mTextureDataQ; + std::map >::iterator > mTextureDataLookup; + + std::thread* mThread; + std::mutex mMutex; + std::condition_variable mEvent; + bool mExit; +}; + +// +// This class manages the loading and unloading of textures +// +// When textures are added, the texture data is just stored as-is. The texture +// data should only have been constructed and not loaded for this to work correctly. +// When the get() function is called it indicates that a texture wants to be used so +// at this point the texture data is loaded (via a call to load()). +// +// Once the load is complete (which may not be on the first call to get() if the +// data is loaded in a background thread) then the get() function call uploadAndBind() +// to upload to VRAM if necessary and bind the texture. This is followed by a call +// to releaseRAM() which frees the memory buffer if the texture can be reloaded from +// disk if needed again +// +class TextureDataManager +{ +public: + TextureDataManager(); + ~TextureDataManager(); + + std::shared_ptr add(const TextureResource* key, bool tiled); + + // The texturedata being removed may be loading in a different thread. However it will + // be referenced by a smart point so we only need to remove it from our array and it + // will be deleted when the other thread has finished with it + void remove(const TextureResource* key); + + std::shared_ptr get(const TextureResource* key); + bool bind(const TextureResource* key); + + // Get the total size of all textures managed by this object, loaded and unloaded in bytes + size_t getTotalSize(); + // Get the total size of all committed textures (in VRAM) in bytes + size_t getCommittedSize(); + // Get the total size of all load-pending textures in the queue - these will + // be committed to VRAM as the queue is processed + size_t getQueueSize(); + // Load a texture, freeing resources as necessary to make space + void load(std::shared_ptr tex, bool block = false); + +private: + + std::list > mTextures; + std::map >::iterator > mTextureLookup; + std::shared_ptr mBlank; + TextureLoader* mLoader; +}; + diff --git a/es-core/src/resources/TextureResource.cpp b/es-core/src/resources/TextureResource.cpp index e6657dcc20..6400d74b9b 100644 --- a/es-core/src/resources/TextureResource.cpp +++ b/es-core/src/resources/TextureResource.cpp @@ -5,108 +5,113 @@ #include "ImageIO.h" #include "Renderer.h" #include "Util.h" -#include "resources/SVGResource.h" +#include "Settings.h" +TextureDataManager TextureResource::sTextureDataManager; std::map< TextureResource::TextureKeyType, std::weak_ptr > TextureResource::sTextureMap; -std::list< std::weak_ptr > TextureResource::sTextureList; +std::set TextureResource::sAllTextures; -TextureResource::TextureResource(const std::string& path, bool tile) : - mTextureID(0), mPath(path), mTextureSize(Eigen::Vector2i::Zero()), mTile(tile) +TextureResource::TextureResource(const std::string& path, bool tile, bool dynamic) : mTextureData(nullptr), mForceLoad(false) { -} - -TextureResource::~TextureResource() -{ - deinit(); -} - -void TextureResource::unload(std::shared_ptr& rm) -{ - deinit(); -} + // Create a texture data object for this texture + if (!path.empty()) + { + // If there is a path then the 'dynamic' flag tells us whether to use the texture + // data manager to manage loading/unloading of this texture + std::shared_ptr data; + if (dynamic) + { + data = sTextureDataManager.add(this, tile); + data->initFromPath(path); + // Force the texture manager to load it using a blocking load + sTextureDataManager.load(data, true); + } + else + { + mTextureData = std::shared_ptr(new TextureData(tile)); + data = mTextureData; + data->initFromPath(path); + // Load it so we can read the width/height + data->load(); + } -void TextureResource::reload(std::shared_ptr& rm) -{ - if(!mPath.empty()) + mSize << data->width(), data->height(); + mSourceSize << data->sourceWidth(), data->sourceHeight(); + } + else { - const ResourceData& data = rm->getFileData(mPath); - initFromMemory((const char*)data.ptr.get(), data.length); + // Create a texture managed by this class because it cannot be dynamically loaded and unloaded + mTextureData = std::shared_ptr(new TextureData(tile)); } + sAllTextures.insert(this); } -void TextureResource::initFromPixels(const unsigned char* dataRGBA, size_t width, size_t height) +TextureResource::~TextureResource() { - deinit(); - - assert(width > 0 && height > 0); - - //now for the openGL texture stuff - glGenTextures(1, &mTextureID); - glBindTexture(GL_TEXTURE_2D, mTextureID); - - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, dataRGBA); + if (mTextureData == nullptr) + sTextureDataManager.remove(this); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - const GLint wrapMode = mTile ? GL_REPEAT : GL_CLAMP_TO_EDGE; - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapMode); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapMode); - - mTextureSize << width, height; + sAllTextures.erase(sAllTextures.find(this)); } -void TextureResource::initFromMemory(const char* data, size_t length) +void TextureResource::initFromPixels(const unsigned char* dataRGBA, size_t width, size_t height) { - size_t width, height; - std::vector imageRGBA = ImageIO::loadFromMemoryRGBA32((const unsigned char*)(data), length, width, height); - - if(imageRGBA.size() == 0) - { - LOG(LogError) << "Could not initialize texture from memory, invalid data! (file path: " << mPath << ", data ptr: " << (size_t)data << ", reported size: " << length << ")"; - return; - } - - initFromPixels(imageRGBA.data(), width, height); + // This is only valid if we have a local texture data object + assert(mTextureData != nullptr); + mTextureData->releaseVRAM(); + mTextureData->releaseRAM(); + mTextureData->initFromRGBA(dataRGBA, width, height); + // Cache the image dimensions + mSize << width, height; + mSourceSize << mTextureData->sourceWidth(), mTextureData->sourceHeight(); } -void TextureResource::deinit() +void TextureResource::initFromMemory(const char* data, size_t length) { - if(mTextureID != 0) - { - glDeleteTextures(1, &mTextureID); - mTextureID = 0; - } + // This is only valid if we have a local texture data object + assert(mTextureData != nullptr); + mTextureData->releaseVRAM(); + mTextureData->releaseRAM(); + mTextureData->initImageFromMemory((const unsigned char*)data, length); + // Get the size from the texture data + mSize << mTextureData->width(), mTextureData->height(); + mSourceSize << mTextureData->sourceWidth(), mTextureData->sourceHeight(); } -const Eigen::Vector2i& TextureResource::getSize() const +const Eigen::Vector2i TextureResource::getSize() const { - return mTextureSize; + return mSize; } bool TextureResource::isTiled() const { - return mTile; + if (mTextureData != nullptr) + return mTextureData->tiled(); + std::shared_ptr data = sTextureDataManager.get(this); + return data->tiled(); } -void TextureResource::bind() const +bool TextureResource::bind() { - if(mTextureID != 0) - glBindTexture(GL_TEXTURE_2D, mTextureID); + if (mTextureData != nullptr) + { + mTextureData->uploadAndBind(); + return true; + } else - LOG(LogError) << "Tried to bind uninitialized texture!"; + { + return sTextureDataManager.bind(this); + } } - -std::shared_ptr TextureResource::get(const std::string& path, bool tile) +std::shared_ptr TextureResource::get(const std::string& path, bool tile, bool forceLoad, bool dynamic) { std::shared_ptr& rm = ResourceManager::getInstance(); const std::string canonicalPath = getCanonicalPath(path); - if(canonicalPath.empty()) { - std::shared_ptr tex(new TextureResource("", tile)); + std::shared_ptr tex(new TextureResource("", tile, false)); rm->addReloadable(tex); //make sure we get properly deinitialized even though we do nothing on reinitialization return tex; } @@ -121,58 +126,100 @@ std::shared_ptr TextureResource::get(const std::string& path, b // need to create it std::shared_ptr tex; + tex = std::shared_ptr(new TextureResource(key.first, tile, dynamic)); + std::shared_ptr data = sTextureDataManager.get(tex.get()); // is it an SVG? - if(key.first.substr(key.first.size() - 4, std::string::npos) == ".svg") + if(key.first.substr(key.first.size() - 4, std::string::npos) != ".svg") { - // probably - // don't add it to our map because 2 svgs might be rasterized at different sizes - tex = std::shared_ptr(new SVGResource(key.first, tile)); - sTextureList.push_back(tex); // add it to our list though - rm->addReloadable(tex); - tex->reload(rm); - return tex; - }else{ - // normal texture - tex = std::shared_ptr(new TextureResource(key.first, tile)); + // Probably not. Add it to our map. We don't add SVGs because 2 svgs might be rasterized at different sizes sTextureMap[key] = std::weak_ptr(tex); - sTextureList.push_back(tex); - rm->addReloadable(tex); - tex->reload(ResourceManager::getInstance()); - return tex; } + + // Add it to the reloadable list + rm->addReloadable(tex); + + // Force load it if necessary. Note that it may get dumped from VRAM if we run low + if (forceLoad) + { + tex->mForceLoad = forceLoad; + data->load(); + } + + return tex; } -bool TextureResource::isInitialized() const +// For scalable source images in textures we want to set the resolution to rasterize at +void TextureResource::rasterizeAt(size_t width, size_t height) { - return mTextureID != 0; + std::shared_ptr data; + if (mTextureData != nullptr) + data = mTextureData; + else + data = sTextureDataManager.get(this); + mSourceSize << (float)width, (float)height; + data->setSourceSize((float)width, (float)height); + if (mForceLoad || (mTextureData != nullptr)) + data->load(); } -size_t TextureResource::getMemUsage() const +Eigen::Vector2f TextureResource::getSourceImageSize() const { - if(!mTextureID || mTextureSize.x() == 0 || mTextureSize.y() == 0) - return 0; + return mSourceSize; +} - return mTextureSize.x() * mTextureSize.y() * 4; +bool TextureResource::isInitialized() const +{ + return true; } size_t TextureResource::getTotalMemUsage() { size_t total = 0; - - auto it = sTextureList.begin(); - while(it != sTextureList.end()) + // Count up all textures that manage their own texture data + for (auto tex : sAllTextures) { - if((*it).expired()) - { - // remove expired textures from the list - it = sTextureList.erase(it); - continue; - } - - total += (*it).lock()->getMemUsage(); - it++; + if (tex->mTextureData != nullptr) + total += tex->mTextureData->getVRAMUsage(); } + // Now get the committed memory from the manager + total += sTextureDataManager.getCommittedSize(); + // And the size of the loading queue + total += sTextureDataManager.getQueueSize(); + return total; +} +size_t TextureResource::getTotalTextureSize() +{ + size_t total = 0; + // Count up all textures that manage their own texture data + for (auto tex : sAllTextures) + { + if (tex->mTextureData != nullptr) + total += tex->getSize().x() * tex->getSize().y() * 4; + } + // Now get the total memory from the manager + total += sTextureDataManager.getTotalSize(); return total; } + +void TextureResource::unload(std::shared_ptr& rm) +{ + // Release the texture's resources + std::shared_ptr data; + if (mTextureData == nullptr) + data = sTextureDataManager.get(this); + else + data = mTextureData; + + data->releaseVRAM(); + data->releaseRAM(); +} + +void TextureResource::reload(std::shared_ptr& rm) +{ + // For dynamically loaded textures the texture manager will load them on demand. + // For manually loaded textures we have to reload them here + if (mTextureData) + mTextureData->load(); +} diff --git a/es-core/src/resources/TextureResource.h b/es-core/src/resources/TextureResource.h index 811e71de37..7623e8b1c2 100644 --- a/es-core/src/resources/TextureResource.h +++ b/es-core/src/resources/TextureResource.h @@ -3,8 +3,12 @@ #include "resources/ResourceManager.h" #include +#include +#include #include #include "platform.h" +#include "resources/TextureData.h" +#include "resources/TextureDataManager.h" #include GLHEADER // An OpenGL texture. @@ -12,40 +16,43 @@ class TextureResource : public IReloadable { public: - static std::shared_ptr get(const std::string& path, bool tile = false); + static std::shared_ptr get(const std::string& path, bool tile = false, bool forceLoad = false, bool dynamic = true); + void initFromPixels(const unsigned char* dataRGBA, size_t width, size_t height); + virtual void initFromMemory(const char* file, size_t length); + + // For scalable source images in textures we want to set the resolution to rasterize at + void rasterizeAt(size_t width, size_t height); + Eigen::Vector2f getSourceImageSize() const; virtual ~TextureResource(); - virtual void unload(std::shared_ptr& rm) override; - virtual void reload(std::shared_ptr& rm) override; - bool isInitialized() const; bool isTiled() const; - const Eigen::Vector2i& getSize() const; - void bind() const; - - // Warning: will NOT correctly reinitialize when this texture is reloaded (e.g. ES starts/stops playing a game). - virtual void initFromMemory(const char* file, size_t length); - // Warning: will NOT correctly reinitialize when this texture is reloaded (e.g. ES starts/stops playing a game). - void initFromPixels(const unsigned char* dataRGBA, size_t width, size_t height); + const Eigen::Vector2i getSize() const; + bool bind(); - size_t getMemUsage() const; // returns an approximation of the VRAM used by this texture (in bytes) static size_t getTotalMemUsage(); // returns an approximation of total VRAM used by textures (in bytes) + static size_t getTotalTextureSize(); // returns the number of bytes that would be used if all textures were in memory protected: - TextureResource(const std::string& path, bool tile); - void deinit(); - - Eigen::Vector2i mTextureSize; - const std::string mPath; - const bool mTile; + TextureResource(const std::string& path, bool tile, bool dynamic); + virtual void unload(std::shared_ptr& rm); + virtual void reload(std::shared_ptr& rm); private: - GLuint mTextureID; + // mTextureData is used for textures that are not loaded from a file - these ones + // are permanently allocated and cannot be loaded and unloaded based on resources + std::shared_ptr mTextureData; + + // The texture data manager manages loading and unloading of filesystem based textures + static TextureDataManager sTextureDataManager; + + Eigen::Vector2i mSize; + Eigen::Vector2f mSourceSize; + bool mForceLoad; typedef std::pair TextureKeyType; static std::map< TextureKeyType, std::weak_ptr > sTextureMap; // map of textures, used to prevent duplicate textures - - static std::list< std::weak_ptr > sTextureList; // list of all textures, used for memory approximations + static std::set sAllTextures; // Set of all textures, used for memory management }; From c02900cfd7b7d7d2885501bace6e6f0e900acfc8 Mon Sep 17 00:00:00 2001 From: Jools Wills Date: Sat, 28 Jan 2017 00:31:34 +0000 Subject: [PATCH 49/74] bumped version to 2.1.3 --- es-app/src/EmulationStation.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/es-app/src/EmulationStation.h b/es-app/src/EmulationStation.h index da8d26ed7d..632d9917e3 100644 --- a/es-app/src/EmulationStation.h +++ b/es-app/src/EmulationStation.h @@ -4,10 +4,10 @@ // Do this version number update as the very last commit for the new release version. #define PROGRAM_VERSION_MAJOR 2 #define PROGRAM_VERSION_MINOR 1 -#define PROGRAM_VERSION_MAINTENANCE 2 -#define PROGRAM_VERSION_STRING "2.1.2rp" +#define PROGRAM_VERSION_MAINTENANCE 3 +#define PROGRAM_VERSION_STRING "2.1.3rp" #define PROGRAM_BUILT_STRING __DATE__ " - " __TIME__ -#define RESOURCE_VERSION_STRING "2,1,2\0" +#define RESOURCE_VERSION_STRING "2,1,3\0" #define RESOURCE_VERSION PROGRAM_VERSION_MAJOR,PROGRAM_VERSION_MINOR,PROGRAM_VERSION_MAINTENANCE From 03687180cb4458906477b541f04ed757f36d529f Mon Sep 17 00:00:00 2001 From: Jools Wills Date: Sat, 28 Jan 2017 02:24:40 +0000 Subject: [PATCH 50/74] =?UTF-8?q?Revert=20"Fix=20WSOD=20by=20loading=20tex?= =?UTF-8?q?tures=20on=20demand=20in=20a=20separate=20thread=20when=20a=20u?= =?UTF-8?q?s=E2=80=A6"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- es-app/src/components/RatingComponent.cpp | 12 +- es-app/src/guis/GuiMenu.cpp | 6 - es-app/src/main.cpp | 5 - es-app/src/views/SystemView.cpp | 4 +- es-app/src/views/ViewController.cpp | 4 +- es-core/CMakeLists.txt | 6 +- es-core/src/Settings.cpp | 3 +- es-core/src/Window.cpp | 9 +- es-core/src/components/ImageComponent.cpp | 66 +---- es-core/src/components/ImageComponent.h | 7 +- es-core/src/resources/SVGResource.cpp | 101 ++++++++ es-core/src/resources/SVGResource.h | 27 ++ es-core/src/resources/TextureData.cpp | 259 ------------------- es-core/src/resources/TextureData.h | 63 ----- es-core/src/resources/TextureDataManager.cpp | 226 ---------------- es-core/src/resources/TextureDataManager.h | 86 ------ es-core/src/resources/TextureResource.cpp | 245 +++++++----------- es-core/src/resources/TextureResource.h | 49 ++-- 18 files changed, 281 insertions(+), 897 deletions(-) create mode 100644 es-core/src/resources/SVGResource.cpp create mode 100644 es-core/src/resources/SVGResource.h delete mode 100644 es-core/src/resources/TextureData.cpp delete mode 100644 es-core/src/resources/TextureData.h delete mode 100644 es-core/src/resources/TextureDataManager.cpp delete mode 100644 es-core/src/resources/TextureDataManager.h diff --git a/es-app/src/components/RatingComponent.cpp b/es-app/src/components/RatingComponent.cpp index 3dbc36a0a4..12f39a3090 100644 --- a/es-app/src/components/RatingComponent.cpp +++ b/es-app/src/components/RatingComponent.cpp @@ -2,6 +2,7 @@ #include "Renderer.h" #include "Window.h" #include "Util.h" +#include "resources/SVGResource.h" RatingComponent::RatingComponent(Window* window) : GuiComponent(window) { @@ -44,13 +45,16 @@ void RatingComponent::onSizeChanged() else if(mSize.x() == 0) mSize[0] = mSize.y() * NUM_RATING_STARS; + auto filledSVG = dynamic_cast(mFilledTexture.get()); + auto unfilledSVG = dynamic_cast(mUnfilledTexture.get()); + if(mSize.y() > 0) { size_t heightPx = (size_t)round(mSize.y()); - if (mFilledTexture) - mFilledTexture->rasterizeAt(heightPx, heightPx); - if(mUnfilledTexture) - mUnfilledTexture->rasterizeAt(heightPx, heightPx); + if(filledSVG) + filledSVG->rasterizeAt(heightPx, heightPx); + if(unfilledSVG) + unfilledSVG->rasterizeAt(heightPx, heightPx); } updateVertices(); diff --git a/es-app/src/guis/GuiMenu.cpp b/es-app/src/guis/GuiMenu.cpp index 68b1a355d1..71ac7272bc 100644 --- a/es-app/src/guis/GuiMenu.cpp +++ b/es-app/src/guis/GuiMenu.cpp @@ -178,12 +178,6 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MEN s->addWithLabel("PARSE GAMESLISTS ONLY", parse_gamelists); s->addSaveFunc([parse_gamelists] { Settings::getInstance()->setBool("ParseGamelistOnly", parse_gamelists->getState()); }); - // maximum vram - auto max_vram = std::make_shared(mWindow, 0.f, 1000.f, 10.f, "Mb"); - max_vram->setValue((float)(Settings::getInstance()->getInt("MaxVRAM"))); - s->addWithLabel("VRAM LIMIT", max_vram); - s->addSaveFunc([max_vram] { Settings::getInstance()->setInt("MaxVRAM", (int)round(max_vram->getValue())); }); - mWindow->pushGui(s); }); diff --git a/es-app/src/main.cpp b/es-app/src/main.cpp index c3d030ec4b..6753b9ae31 100644 --- a/es-app/src/main.cpp +++ b/es-app/src/main.cpp @@ -74,10 +74,6 @@ bool parseArgs(int argc, char* argv[], unsigned int* width, unsigned int* height }else if(strcmp(argv[i], "--scrape") == 0) { scrape_cmdline = true; - }else if(strcmp(argv[i], "--max-vram") == 0) - { - int maxVRAM = atoi(argv[i + 1]); - Settings::getInstance()->setInt("MaxVRAM", maxVRAM); }else if(strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) { #ifdef WIN32 @@ -103,7 +99,6 @@ bool parseArgs(int argc, char* argv[], unsigned int* width, unsigned int* height "--scrape scrape using command line interface\n" "--windowed not fullscreen, should be used with --resolution\n" "--vsync [1/on or 0/off] turn vsync on or off (default is on)\n" - "--max-vram [size] Max VRAM to use in Mb before swapping. 0 for unlimited\n" "--help, -h summon a sentient, angry tuba\n\n" "More information available in README.md.\n"; return false; //exit after printing help diff --git a/es-app/src/views/SystemView.cpp b/es-app/src/views/SystemView.cpp index c760125b97..013490aca9 100644 --- a/es-app/src/views/SystemView.cpp +++ b/es-app/src/views/SystemView.cpp @@ -43,13 +43,13 @@ void SystemView::populate() // make logo if(theme->getElement("system", "logo", "image")) { - ImageComponent* logo = new ImageComponent(mWindow, false, false); + ImageComponent* logo = new ImageComponent(mWindow); logo->setMaxSize(Eigen::Vector2f(logoSize().x(), logoSize().y())); logo->applyTheme((*it)->getTheme(), "system", "logo", ThemeFlags::PATH); logo->setPosition((logoSize().x() - logo->getSize().x()) / 2, (logoSize().y() - logo->getSize().y()) / 2); // center e.data.logo = std::shared_ptr(logo); - ImageComponent* logoSelected = new ImageComponent(mWindow, false, false); + ImageComponent* logoSelected = new ImageComponent(mWindow); logoSelected->setMaxSize(Eigen::Vector2f(logoSize().x() * SELECTED_SCALE, logoSize().y() * SELECTED_SCALE * 0.70f)); logoSelected->applyTheme((*it)->getTheme(), "system", "logo", ThemeFlags::PATH); logoSelected->setPosition((logoSize().x() - logoSelected->getSize().x()) / 2, diff --git a/es-app/src/views/ViewController.cpp b/es-app/src/views/ViewController.cpp index d9093e8e10..1e10c91753 100644 --- a/es-app/src/views/ViewController.cpp +++ b/es-app/src/views/ViewController.cpp @@ -406,9 +406,7 @@ void ViewController::reloadAll() mCurrentView = getGameListView(mState.getSystem()); }else if(mState.viewing == SYSTEM_SELECT) { - SystemData* system = mState.getSystem(); - goToSystemView(SystemData::sSystemVector.front()); - mSystemListView->goToSystem(system, false); + mSystemListView->goToSystem(mState.getSystem(), false); mCurrentView = mSystemListView; }else{ goToSystemView(SystemData::sSystemVector.front()); diff --git a/es-core/CMakeLists.txt b/es-core/CMakeLists.txt index f05aec77c3..cf0cfb3ea3 100644 --- a/es-core/CMakeLists.txt +++ b/es-core/CMakeLists.txt @@ -53,9 +53,8 @@ set(CORE_HEADERS # Resources ${CMAKE_CURRENT_SOURCE_DIR}/src/resources/Font.h ${CMAKE_CURRENT_SOURCE_DIR}/src/resources/ResourceManager.h + ${CMAKE_CURRENT_SOURCE_DIR}/src/resources/SVGResource.h ${CMAKE_CURRENT_SOURCE_DIR}/src/resources/TextureResource.h - ${CMAKE_CURRENT_SOURCE_DIR}/src/resources/TextureData.h - ${CMAKE_CURRENT_SOURCE_DIR}/src/resources/TextureDataManager.h # Embedded assets (needed by ResourceManager) ${emulationstation-all_SOURCE_DIR}/data/Resources.h @@ -109,9 +108,8 @@ set(CORE_SOURCES # Resources ${CMAKE_CURRENT_SOURCE_DIR}/src/resources/Font.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/resources/ResourceManager.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/resources/SVGResource.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/resources/TextureResource.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/src/resources/TextureData.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/src/resources/TextureDataManager.cpp ) set(EMBEDDED_ASSET_SOURCES diff --git a/es-core/src/Settings.cpp b/es-core/src/Settings.cpp index df90ba7b65..337dcaac13 100644 --- a/es-core/src/Settings.cpp +++ b/es-core/src/Settings.cpp @@ -69,7 +69,6 @@ void Settings::setDefaults() mIntMap["ScreenSaverTime"] = 5*60*1000; // 5 minutes mIntMap["ScraperResizeWidth"] = 400; mIntMap["ScraperResizeHeight"] = 0; - mIntMap["MaxVRAM"] = 100; mStringMap["TransitionStyle"] = "fade"; mStringMap["ThemeSet"] = ""; @@ -155,4 +154,4 @@ void Settings::setMethodName(const std::string& name, type value) \ SETTINGS_GETSET(bool, mBoolMap, getBool, setBool); SETTINGS_GETSET(int, mIntMap, getInt, setInt); SETTINGS_GETSET(float, mFloatMap, getFloat, setFloat); -SETTINGS_GETSET(const std::string&, mStringMap, getString, setString); +SETTINGS_GETSET(const std::string&, mStringMap, getString, setString); \ No newline at end of file diff --git a/es-core/src/Window.cpp b/es-core/src/Window.cpp index e402162c3d..761df4abc4 100644 --- a/es-core/src/Window.cpp +++ b/es-core/src/Window.cpp @@ -160,12 +160,11 @@ void Window::update(int deltaTime) ss << std::fixed << std::setprecision(2) << ((float)mFrameTimeElapsed / (float)mFrameCountElapsed) << "ms"; // vram - float textureVramUsageMb = TextureResource::getTotalMemUsage() / 1000.0f / 1000.0f; - float textureTotalUsageMb = TextureResource::getTotalTextureSize() / 1000.0f / 1000.0f; + float textureVramUsageMb = TextureResource::getTotalMemUsage() / 1000.0f / 1000.0f;; float fontVramUsageMb = Font::getTotalMemUsage() / 1000.0f / 1000.0f;; + float totalVramUsageMb = textureVramUsageMb + fontVramUsageMb; + ss << "\nVRAM: " << totalVramUsageMb << "mb (texs: " << textureVramUsageMb << "mb, fonts: " << fontVramUsageMb << "mb)"; - ss << "\nFont VRAM: " << fontVramUsageMb << " Tex VRAM: " << textureVramUsageMb << - " Tex Max: " << textureTotalUsageMb; mFrameDataText = std::unique_ptr(mDefaultFonts.at(1)->buildTextCache(ss.str(), 50.f, 50.f, 0xFF00FFFF)); } @@ -243,7 +242,7 @@ void Window::renderLoadingScreen() Renderer::setMatrix(trans); Renderer::drawRect(0, 0, Renderer::getScreenWidth(), Renderer::getScreenHeight(), 0xFFFFFFFF); - ImageComponent splash(this, true); + ImageComponent splash(this); splash.setResize(Renderer::getScreenWidth() * 0.6f, 0.0f); splash.setImage(":/splash.svg"); splash.setPosition((Renderer::getScreenWidth() - splash.getSize().x()) / 2, (Renderer::getScreenHeight() - splash.getSize().y()) / 2 * 0.6f); diff --git a/es-core/src/components/ImageComponent.cpp b/es-core/src/components/ImageComponent.cpp index 1ae62314d8..2898c6f732 100644 --- a/es-core/src/components/ImageComponent.cpp +++ b/es-core/src/components/ImageComponent.cpp @@ -6,6 +6,7 @@ #include "Renderer.h" #include "ThemeData.h" #include "Util.h" +#include "resources/SVGResource.h" Eigen::Vector2i ImageComponent::getTextureSize() const { @@ -21,9 +22,8 @@ Eigen::Vector2f ImageComponent::getCenter() const mPosition.y() - (getSize().y() * mOrigin.y()) + getSize().y() / 2); } -ImageComponent::ImageComponent(Window* window, bool forceLoad, bool dynamic) : GuiComponent(window), - mTargetIsMax(false), mFlipX(false), mFlipY(false), mOrigin(0.0, 0.0), mTargetSize(0, 0), mColorShift(0xFFFFFFFF), - mForceLoad(forceLoad), mDynamic(dynamic) +ImageComponent::ImageComponent(Window* window) : GuiComponent(window), + mTargetIsMax(false), mFlipX(false), mFlipY(false), mOrigin(0.0, 0.0), mTargetSize(0, 0), mColorShift(0xFFFFFFFF) { updateColors(); } @@ -37,7 +37,9 @@ void ImageComponent::resize() if(!mTexture) return; - const Eigen::Vector2f textureSize = mTexture->getSourceImageSize(); + SVGResource* svg = dynamic_cast(mTexture.get()); + + const Eigen::Vector2f textureSize = svg ? svg->getSourceImageSize() : Eigen::Vector2f((float)mTexture->getSize().x(), (float)mTexture->getSize().y()); if(textureSize.isZero()) return; @@ -88,8 +90,12 @@ void ImageComponent::resize() } } } - // mSize.y() should already be rounded - mTexture->rasterizeAt((int)round(mSize.x()), (int)round(mSize.y())); + + if(svg) + { + // mSize.y() should already be rounded + svg->rasterizeAt((int)round(mSize.x()), (int)round(mSize.y())); + } onSizeChanged(); } @@ -104,7 +110,7 @@ void ImageComponent::setImage(std::string path, bool tile) if(path.empty() || !ResourceManager::getInstance()->fileExists(path)) mTexture.reset(); else - mTexture = TextureResource::get(path, tile, mForceLoad, mDynamic); + mTexture = TextureResource::get(path, tile); resize(); } @@ -241,10 +247,7 @@ void ImageComponent::render(const Eigen::Affine3f& parentTrans) if(mTexture->isInitialized()) { // actually draw the image - // The bind() function returns false if the texture is not currently loaded. A blank - // texture is bound in this case but we want to handle a fade so it doesn't just 'jump' in - // when it finally loads - fadeIn(mTexture->bind()); + mTexture->bind(); glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); @@ -275,47 +278,6 @@ void ImageComponent::render(const Eigen::Affine3f& parentTrans) GuiComponent::renderChildren(trans); } -void ImageComponent::fadeIn(bool textureLoaded) -{ - if (!mForceLoad) - { - if (!textureLoaded) - { - // Start the fade if this is the first time we've encountered the unloaded texture - if (!mFading) - { - // Start with a zero opacity and flag it as fading - mFadeOpacity = 0; - mFading = true; - // Set the colours to be translucent - mColorShift = (mColorShift >> 8 << 8) | 0; - updateColors(); - } - } - else if (mFading) - { - // The texture is loaded and we need to fade it in. The fade is based on the frame rate - // and is 1/4 second if running at 60 frames per second although the actual value is not - // that important - int opacity = mFadeOpacity + 255 / 15; - // See if we've finished fading - if (opacity >= 255) - { - mFadeOpacity = 255; - mFading = false; - } - else - { - mFadeOpacity = (unsigned char)opacity; - } - // Apply the combination of the target opacity and current fade - float newOpacity = (float)mOpacity * ((float)mFadeOpacity / 255.0f); - mColorShift = (mColorShift >> 8 << 8) | (unsigned char)newOpacity; - updateColors(); - } - } -} - bool ImageComponent::hasImage() { return (bool)mTexture; diff --git a/es-core/src/components/ImageComponent.h b/es-core/src/components/ImageComponent.h index 3ff1ffbb27..939c6c7cd2 100644 --- a/es-core/src/components/ImageComponent.h +++ b/es-core/src/components/ImageComponent.h @@ -12,7 +12,7 @@ class ImageComponent : public GuiComponent { public: - ImageComponent(Window* window, bool forceLoad = false, bool dynamic = true); + ImageComponent(Window* window); virtual ~ImageComponent(); //Loads the image at the given filepath. Will tile if tile is true (retrieves texture as tiling, creates vertices accordingly). @@ -81,15 +81,10 @@ class ImageComponent : public GuiComponent void updateVertices(); void updateColors(); - void fadeIn(bool textureLoaded); unsigned int mColorShift; std::shared_ptr mTexture; - unsigned char mFadeOpacity; - bool mFading; - bool mForceLoad; - bool mDynamic; }; #endif diff --git a/es-core/src/resources/SVGResource.cpp b/es-core/src/resources/SVGResource.cpp new file mode 100644 index 0000000000..1a4ea16fca --- /dev/null +++ b/es-core/src/resources/SVGResource.cpp @@ -0,0 +1,101 @@ +#include "SVGResource.h" +#include "nanosvg/nanosvg.h" +#include "nanosvg/nanosvgrast.h" +#include "Log.h" +#include "Util.h" +#include "ImageIO.h" + +#define DPI 96 + +SVGResource::SVGResource(const std::string& path, bool tile) : TextureResource(path, tile), mSVGImage(NULL) +{ + mLastWidth = 0; + mLastHeight = 0; +} + +SVGResource::~SVGResource() +{ + deinitSVG(); +} + +void SVGResource::unload(std::shared_ptr& rm) +{ + deinitSVG(); + TextureResource::unload(rm); +} + +void SVGResource::initFromMemory(const char* file, size_t length) +{ + deinit(); + deinitSVG(); + + // nsvgParse excepts a modifiable, null-terminated string + char* copy = (char*)malloc(length + 1); + assert(copy != NULL); + memcpy(copy, file, length); + copy[length] = '\0'; + + mSVGImage = nsvgParse(copy, "px", DPI); + free(copy); + + if(!mSVGImage) + { + LOG(LogError) << "Error parsing SVG image."; + return; + } + + if(mLastWidth && mLastHeight) + rasterizeAt(mLastWidth, mLastHeight); + else + rasterizeAt((size_t)round(mSVGImage->width), (size_t)round(mSVGImage->height)); +} + +void SVGResource::rasterizeAt(size_t width, size_t height) +{ + if(!mSVGImage || (width == 0 && height == 0)) + return; + + if(width == 0) + { + // auto scale width to keep aspect + width = (size_t)round((height / mSVGImage->height) * mSVGImage->width); + }else if(height == 0) + { + // auto scale height to keep aspect + height = (size_t)round((width / mSVGImage->width) * mSVGImage->height); + } + + if(width != (size_t)round(mSVGImage->width) && height != (size_t)round(mSVGImage->height)) + { + mLastWidth = width; + mLastHeight = height; + } + + unsigned char* imagePx = (unsigned char*)malloc(width * height * 4); + assert(imagePx != NULL); + + NSVGrasterizer* rast = nsvgCreateRasterizer(); + nsvgRasterize(rast, mSVGImage, 0, 0, height / mSVGImage->height, imagePx, width, height, width * 4); + nsvgDeleteRasterizer(rast); + + ImageIO::flipPixelsVert(imagePx, width, height); + + initFromPixels(imagePx, width, height); + free(imagePx); +} + +Eigen::Vector2f SVGResource::getSourceImageSize() const +{ + if(mSVGImage) + return Eigen::Vector2f(mSVGImage->width, mSVGImage->height); + + return Eigen::Vector2f::Zero(); +} + +void SVGResource::deinitSVG() +{ + if(mSVGImage) + nsvgDelete(mSVGImage); + + mSVGImage = NULL; +} diff --git a/es-core/src/resources/SVGResource.h b/es-core/src/resources/SVGResource.h new file mode 100644 index 0000000000..87479c0cf1 --- /dev/null +++ b/es-core/src/resources/SVGResource.h @@ -0,0 +1,27 @@ +#pragma once + +#include "resources/TextureResource.h" + +struct NSVGimage; + +class SVGResource : public TextureResource +{ +public: + virtual ~SVGResource(); + + virtual void unload(std::shared_ptr& rm) override; + + virtual void initFromMemory(const char* image, size_t length) override; + + void rasterizeAt(size_t width, size_t height); + Eigen::Vector2f getSourceImageSize() const; + +protected: + friend TextureResource; + SVGResource(const std::string& path, bool tile); + void deinitSVG(); + + NSVGimage* mSVGImage; + size_t mLastWidth; + size_t mLastHeight; +}; diff --git a/es-core/src/resources/TextureData.cpp b/es-core/src/resources/TextureData.cpp deleted file mode 100644 index 15a3da116e..0000000000 --- a/es-core/src/resources/TextureData.cpp +++ /dev/null @@ -1,259 +0,0 @@ -#include "resources/TextureData.h" -#include "resources/ResourceManager.h" -#include "Log.h" -#include "ImageIO.h" -#include "string.h" -#include "Util.h" -#include "nanosvg/nanosvg.h" -#include "nanosvg/nanosvgrast.h" -#include - -#define DPI 96 - -TextureData::TextureData(bool tile) : mTile(tile), mTextureID(0), mDataRGBA(nullptr), mScalable(false), - mWidth(0), mHeight(0), mSourceWidth(0.0f), mSourceHeight(0.0f) -{ -} - -TextureData::~TextureData() -{ - releaseVRAM(); - releaseRAM(); -} - -void TextureData::initFromPath(const std::string& path) -{ - // Just set the path. It will be loaded later - mPath = path; - // Only textures with paths are reloadable - mReloadable = true; -} - -bool TextureData::initSVGFromMemory(const unsigned char* fileData, size_t length) -{ - // If already initialised then don't read again - { - std::unique_lock lock(mMutex); - if (mDataRGBA) - return true; - } - - // nsvgParse excepts a modifiable, null-terminated string - char* copy = (char*)malloc(length + 1); - assert(copy != NULL); - memcpy(copy, fileData, length); - copy[length] = '\0'; - - NSVGimage* svgImage = nsvgParse(copy, "px", DPI); - free(copy); - if (!svgImage) - { - LOG(LogError) << "Error parsing SVG image."; - return false; - } - - // We want to rasterise this texture at a specific resolution. If the source size - // variables are set then use them otherwise set them from the parsed file - if ((mSourceWidth == 0.0f) && (mSourceHeight == 0.0f)) - { - mSourceWidth = svgImage->width; - mSourceHeight = svgImage->height; - } - mWidth = (size_t)round(mSourceWidth); - mHeight = (size_t)round(mSourceHeight); - - if (mWidth == 0) - { - // auto scale width to keep aspect - mWidth = (size_t)round(((float)mHeight / svgImage->height) * svgImage->width); - } - else if (mHeight == 0) - { - // auto scale height to keep aspect - mHeight = (size_t)round(((float)mWidth / svgImage->width) * svgImage->height); - } - - unsigned char* dataRGBA = new unsigned char[mWidth * mHeight * 4]; - - NSVGrasterizer* rast = nsvgCreateRasterizer(); - nsvgRasterize(rast, svgImage, 0, 0, mHeight / svgImage->height, dataRGBA, mWidth, mHeight, mWidth * 4); - nsvgDeleteRasterizer(rast); - - ImageIO::flipPixelsVert(dataRGBA, mWidth, mHeight); - - std::unique_lock lock(mMutex); - mDataRGBA = dataRGBA; - - return true; -} - -bool TextureData::initImageFromMemory(const unsigned char* fileData, size_t length) -{ - size_t width, height; - - // If already initialised then don't read again - { - std::unique_lock lock(mMutex); - if (mDataRGBA) - return true; - } - - std::vector imageRGBA = ImageIO::loadFromMemoryRGBA32((const unsigned char*)(fileData), length, width, height); - if (imageRGBA.size() == 0) - { - LOG(LogError) << "Could not initialize texture from memory, invalid data! (file path: " << mPath << ", data ptr: " << (size_t)fileData << ", reported size: " << length << ")"; - return false; - } - - mSourceWidth = width; - mSourceHeight = height; - mScalable = false; - - return initFromRGBA(imageRGBA.data(), width, height); -} - -bool TextureData::initFromRGBA(const unsigned char* dataRGBA, size_t width, size_t height) -{ - // If already initialised then don't read again - std::unique_lock lock(mMutex); - if (mDataRGBA) - return true; - - // Take a copy - mDataRGBA = new unsigned char[width * height * 4]; - memcpy(mDataRGBA, dataRGBA, width * height * 4); - mWidth = width; - mHeight = height; - return true; -} - -bool TextureData::load() -{ - bool retval = false; - - // Need to load. See if there is a file - if (!mPath.empty()) - { - std::shared_ptr& rm = ResourceManager::getInstance(); - const ResourceData& data = rm->getFileData(mPath); - // is it an SVG? - if (mPath.substr(mPath.size() - 4, std::string::npos) == ".svg") - { - mScalable = true; - retval = initSVGFromMemory((const unsigned char*)data.ptr.get(), data.length); - } - else - retval = initImageFromMemory((const unsigned char*)data.ptr.get(), data.length); - } - return retval; -} - -bool TextureData::isLoaded() -{ - std::unique_lock lock(mMutex); - if (mDataRGBA || (mTextureID != 0)) - return true; - return false; -} - -bool TextureData::uploadAndBind() -{ - // See if it's already been uploaded - std::unique_lock lock(mMutex); - if (mTextureID != 0) - { - glBindTexture(GL_TEXTURE_2D, mTextureID); - } - else - { - // Load it if necessary - if (!mDataRGBA) - { - return false; - } - // Make sure we're ready to upload - if ((mWidth == 0) || (mHeight == 0) || (mDataRGBA == nullptr)) - return false; - glGetError(); - //now for the openGL texture stuff - glGenTextures(1, &mTextureID); - glBindTexture(GL_TEXTURE_2D, mTextureID); - - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, mWidth, mHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, mDataRGBA); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - const GLint wrapMode = mTile ? GL_REPEAT : GL_CLAMP_TO_EDGE; - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapMode); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapMode); - } - return true; -} - -void TextureData::releaseVRAM() -{ - std::unique_lock lock(mMutex); - if (mTextureID != 0) - { - glDeleteTextures(1, &mTextureID); - mTextureID = 0; - } -} - -void TextureData::releaseRAM() -{ - std::unique_lock lock(mMutex); - delete[] mDataRGBA; - mDataRGBA = 0; -} - -size_t TextureData::width() -{ - if (mWidth == 0) - load(); - return mWidth; -} - -size_t TextureData::height() -{ - if (mHeight == 0) - load(); - return mHeight; -} - -float TextureData::sourceWidth() -{ - if (mSourceWidth == 0) - load(); - return mSourceWidth; -} - -float TextureData::sourceHeight() -{ - if (mSourceHeight == 0) - load(); - return mSourceHeight; -} - -void TextureData::setSourceSize(float width, float height) -{ - if (mScalable) - { - if ((mSourceWidth != width) || (mSourceHeight != height)) - { - mSourceWidth = width; - mSourceHeight = height; - releaseVRAM(); - releaseRAM(); - } - } -} - -size_t TextureData::getVRAMUsage() -{ - if ((mTextureID != 0) || (mDataRGBA != nullptr)) - return mWidth * mHeight * 4; - else - return 0; -} diff --git a/es-core/src/resources/TextureData.h b/es-core/src/resources/TextureData.h deleted file mode 100644 index 76ca6a0b4d..0000000000 --- a/es-core/src/resources/TextureData.h +++ /dev/null @@ -1,63 +0,0 @@ -#pragma once - -#include -#include -#include "platform.h" -#include -#include GLHEADER - -class TextureResource; - -class TextureData -{ -public: - TextureData(bool tile); - ~TextureData(); - - // These functions populate mDataRGBA but do not upload the texture to VRAM - - //!!!! Needs to be canonical path. Caller should check for duplicates before calling this - void initFromPath(const std::string& path); - bool initSVGFromMemory(const unsigned char* fileData, size_t length); - bool initImageFromMemory(const unsigned char* fileData, size_t length); - bool initFromRGBA(const unsigned char* dataRGBA, size_t width, size_t height); - - // Read the data into memory if necessary - bool load(); - - bool isLoaded(); - - // Upload the texture to VRAM if necessary and bind. Returns true if bound ok or - // false if either not loaded - bool uploadAndBind(); - - // Release the texture from VRAM - void releaseVRAM(); - - // Release the texture from conventional RAM - void releaseRAM(); - - // Get the amount of VRAM currenty used by this texture - size_t getVRAMUsage(); - - size_t width(); - size_t height(); - float sourceWidth(); - float sourceHeight(); - void setSourceSize(float width, float height); - - bool tiled() { return mTile; } - -private: - std::mutex mMutex; - bool mTile; - std::string mPath; - GLuint mTextureID; - unsigned char* mDataRGBA; - size_t mWidth; - size_t mHeight; - float mSourceWidth; - float mSourceHeight; - bool mScalable; - bool mReloadable; -}; diff --git a/es-core/src/resources/TextureDataManager.cpp b/es-core/src/resources/TextureDataManager.cpp deleted file mode 100644 index 55720d14ac..0000000000 --- a/es-core/src/resources/TextureDataManager.cpp +++ /dev/null @@ -1,226 +0,0 @@ -#include "resources/TextureDataManager.h" -#include "resources/TextureResource.h" -#include "Settings.h" - -TextureDataManager::TextureDataManager() -{ - unsigned char data[5 * 5 * 4]; - mBlank = std::shared_ptr(new TextureData(false)); - for (int i = 0; i < (5 * 5); ++i) - { - data[i*4] = (i % 2) * 255; - data[i*4+1] = (i % 2) * 255; - data[i*4+2] = (i % 2) * 255; - data[i*4+3] = 0; - } - mBlank->initFromRGBA(data, 5, 5); - mLoader = new TextureLoader; -} - -TextureDataManager::~TextureDataManager() -{ - delete mLoader; -} - -std::shared_ptr TextureDataManager::add(const TextureResource* key, bool tiled) -{ - remove(key); - std::shared_ptr data(new TextureData(tiled)); - mTextures.push_front(data); - mTextureLookup[key] = mTextures.begin(); - return data; -} - -void TextureDataManager::remove(const TextureResource* key) -{ - // Find the entry in the list - auto it = mTextureLookup.find(key); - if (it != mTextureLookup.end()) - { - // Remove the list entry - mTextures.erase((*it).second); - // And the lookup - mTextureLookup.erase(it); - } -} - -std::shared_ptr TextureDataManager::get(const TextureResource* key) -{ - // If it's in the cache then we want to remove it from it's current location and - // move it to the top - std::shared_ptr tex; - auto it = mTextureLookup.find(key); - if (it != mTextureLookup.end()) - { - tex = *(*it).second; - // Remove the list entry - mTextures.erase((*it).second); - // Put it at the top - mTextures.push_front(tex); - // Store it back in the lookup - mTextureLookup[key] = mTextures.begin(); - - // Make sure it's loaded or queued for loading - load(tex); - } - return tex; -} - -bool TextureDataManager::bind(const TextureResource* key) -{ - std::shared_ptr tex = get(key); - bool bound = false; - if (tex != nullptr) - bound = tex->uploadAndBind(); - if (!bound) - mBlank->uploadAndBind(); - return bound; -} - -size_t TextureDataManager::getTotalSize() -{ - size_t total = 0; - for (auto tex : mTextures) - total += tex->width() * tex->height() * 4; - return total; -} - -size_t TextureDataManager::getCommittedSize() -{ - size_t total = 0; - for (auto tex : mTextures) - total += tex->getVRAMUsage(); - return total; -} - -size_t TextureDataManager::getQueueSize() -{ - return mLoader->getQueueSize(); -} - -void TextureDataManager::load(std::shared_ptr tex, bool block) -{ - // See if it's already loaded - if (tex->isLoaded()) - return; - // Not loaded. Make sure there is room - size_t size = TextureResource::getTotalMemUsage(); - size_t max_texture = (size_t)Settings::getInstance()->getInt("MaxVRAM") * 1024 * 1024; - - size_t in = size; - - for (auto it = mTextures.rbegin(); it != mTextures.rend(); ++it) - { - if (size < max_texture) - break; - //size -= (*it)->getVRAMUsage(); - (*it)->releaseVRAM(); - (*it)->releaseRAM(); - // It may be already in the loader queue. In this case it wouldn't have been using - // any VRAM yet but it will be. Remove it from the loader queue - mLoader->remove(*it); - size = TextureResource::getTotalMemUsage(); - } - if (!block) - mLoader->load(tex); - else - tex->load(); -} - -TextureLoader::TextureLoader() : mExit(false) -{ - mThread = new std::thread(&TextureLoader::threadProc, this); -} - -TextureLoader::~TextureLoader() -{ - // Just abort any waiting texture - mTextureDataQ.clear(); - mTextureDataLookup.clear(); - - // Exit the thread - mExit = true; - mEvent.notify_one(); - mThread->join(); - delete mThread; -} - -void TextureLoader::threadProc() -{ - while (!mExit) - { - std::shared_ptr textureData; - { - // Wait for an event to say there is something in the queue - std::unique_lock lock(mMutex); - mEvent.wait(lock); - if (!mTextureDataQ.empty()) - { - textureData = mTextureDataQ.front(); - mTextureDataQ.pop_front(); - mTextureDataLookup.erase(mTextureDataLookup.find(textureData.get())); - } - } - // Queue has been released here but we might have a texture to process - while (textureData) - { - textureData->load(); - - // See if there is another item in the queue - textureData = nullptr; - std::unique_lock lock(mMutex); - if (!mTextureDataQ.empty()) - { - textureData = mTextureDataQ.front(); - mTextureDataQ.pop_front(); - mTextureDataLookup.erase(mTextureDataLookup.find(textureData.get())); - } - } - } -} - -void TextureLoader::load(std::shared_ptr textureData) -{ - // Make sure it's not already loaded - if (!textureData->isLoaded()) - { - std::unique_lock lock(mMutex); - // Remove it from the queue if it is already there - auto td = mTextureDataLookup.find(textureData.get()); - if (td != mTextureDataLookup.end()) - { - mTextureDataQ.erase((*td).second); - mTextureDataLookup.erase(td); - } - - // Put it on the start of the queue as we want the newly requested textures to load first - mTextureDataQ.push_front(textureData); - mTextureDataLookup[textureData.get()] = mTextureDataQ.begin(); - mEvent.notify_one(); - } -} - -void TextureLoader::remove(std::shared_ptr textureData) -{ - // Just remove it from the queue so we don't attempt to load it - std::unique_lock lock(mMutex); - auto td = mTextureDataLookup.find(textureData.get()); - if (td != mTextureDataLookup.end()) - { - mTextureDataQ.erase((*td).second); - mTextureDataLookup.erase(td); - } -} - -size_t TextureLoader::getQueueSize() -{ - // Gets the amount of video memory that will be used once all textures in - // the queue are loaded - size_t mem = 0; - std::unique_lock lock(mMutex); - for (auto tex : mTextureDataQ) - { - mem += tex->width() * tex->height() * 4; - } - return mem; -} diff --git a/es-core/src/resources/TextureDataManager.h b/es-core/src/resources/TextureDataManager.h deleted file mode 100644 index 414804aba9..0000000000 --- a/es-core/src/resources/TextureDataManager.h +++ /dev/null @@ -1,86 +0,0 @@ -#pragma once - -#include "resources/ResourceManager.h" -#include "platform.h" -#include "resources/TextureData.h" -#include -#include -#include -#include -#include -#include - -class TextureResource; - -class TextureLoader -{ -public: - TextureLoader(); - ~TextureLoader(); - - void load(std::shared_ptr textureData); - void remove(std::shared_ptr textureData); - - size_t getQueueSize(); - -private: - void processQueue(); - void threadProc(); - - std::list > mTextureDataQ; - std::map >::iterator > mTextureDataLookup; - - std::thread* mThread; - std::mutex mMutex; - std::condition_variable mEvent; - bool mExit; -}; - -// -// This class manages the loading and unloading of textures -// -// When textures are added, the texture data is just stored as-is. The texture -// data should only have been constructed and not loaded for this to work correctly. -// When the get() function is called it indicates that a texture wants to be used so -// at this point the texture data is loaded (via a call to load()). -// -// Once the load is complete (which may not be on the first call to get() if the -// data is loaded in a background thread) then the get() function call uploadAndBind() -// to upload to VRAM if necessary and bind the texture. This is followed by a call -// to releaseRAM() which frees the memory buffer if the texture can be reloaded from -// disk if needed again -// -class TextureDataManager -{ -public: - TextureDataManager(); - ~TextureDataManager(); - - std::shared_ptr add(const TextureResource* key, bool tiled); - - // The texturedata being removed may be loading in a different thread. However it will - // be referenced by a smart point so we only need to remove it from our array and it - // will be deleted when the other thread has finished with it - void remove(const TextureResource* key); - - std::shared_ptr get(const TextureResource* key); - bool bind(const TextureResource* key); - - // Get the total size of all textures managed by this object, loaded and unloaded in bytes - size_t getTotalSize(); - // Get the total size of all committed textures (in VRAM) in bytes - size_t getCommittedSize(); - // Get the total size of all load-pending textures in the queue - these will - // be committed to VRAM as the queue is processed - size_t getQueueSize(); - // Load a texture, freeing resources as necessary to make space - void load(std::shared_ptr tex, bool block = false); - -private: - - std::list > mTextures; - std::map >::iterator > mTextureLookup; - std::shared_ptr mBlank; - TextureLoader* mLoader; -}; - diff --git a/es-core/src/resources/TextureResource.cpp b/es-core/src/resources/TextureResource.cpp index 6400d74b9b..e6657dcc20 100644 --- a/es-core/src/resources/TextureResource.cpp +++ b/es-core/src/resources/TextureResource.cpp @@ -5,113 +5,108 @@ #include "ImageIO.h" #include "Renderer.h" #include "Util.h" -#include "Settings.h" +#include "resources/SVGResource.h" -TextureDataManager TextureResource::sTextureDataManager; std::map< TextureResource::TextureKeyType, std::weak_ptr > TextureResource::sTextureMap; -std::set TextureResource::sAllTextures; +std::list< std::weak_ptr > TextureResource::sTextureList; -TextureResource::TextureResource(const std::string& path, bool tile, bool dynamic) : mTextureData(nullptr), mForceLoad(false) +TextureResource::TextureResource(const std::string& path, bool tile) : + mTextureID(0), mPath(path), mTextureSize(Eigen::Vector2i::Zero()), mTile(tile) { - // Create a texture data object for this texture - if (!path.empty()) - { - // If there is a path then the 'dynamic' flag tells us whether to use the texture - // data manager to manage loading/unloading of this texture - std::shared_ptr data; - if (dynamic) - { - data = sTextureDataManager.add(this, tile); - data->initFromPath(path); - // Force the texture manager to load it using a blocking load - sTextureDataManager.load(data, true); - } - else - { - mTextureData = std::shared_ptr(new TextureData(tile)); - data = mTextureData; - data->initFromPath(path); - // Load it so we can read the width/height - data->load(); - } - - mSize << data->width(), data->height(); - mSourceSize << data->sourceWidth(), data->sourceHeight(); - } - else - { - // Create a texture managed by this class because it cannot be dynamically loaded and unloaded - mTextureData = std::shared_ptr(new TextureData(tile)); - } - sAllTextures.insert(this); } TextureResource::~TextureResource() { - if (mTextureData == nullptr) - sTextureDataManager.remove(this); + deinit(); +} - sAllTextures.erase(sAllTextures.find(this)); +void TextureResource::unload(std::shared_ptr& rm) +{ + deinit(); +} + +void TextureResource::reload(std::shared_ptr& rm) +{ + if(!mPath.empty()) + { + const ResourceData& data = rm->getFileData(mPath); + initFromMemory((const char*)data.ptr.get(), data.length); + } } void TextureResource::initFromPixels(const unsigned char* dataRGBA, size_t width, size_t height) { - // This is only valid if we have a local texture data object - assert(mTextureData != nullptr); - mTextureData->releaseVRAM(); - mTextureData->releaseRAM(); - mTextureData->initFromRGBA(dataRGBA, width, height); - // Cache the image dimensions - mSize << width, height; - mSourceSize << mTextureData->sourceWidth(), mTextureData->sourceHeight(); + deinit(); + + assert(width > 0 && height > 0); + + //now for the openGL texture stuff + glGenTextures(1, &mTextureID); + glBindTexture(GL_TEXTURE_2D, mTextureID); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, dataRGBA); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + const GLint wrapMode = mTile ? GL_REPEAT : GL_CLAMP_TO_EDGE; + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapMode); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapMode); + + mTextureSize << width, height; } void TextureResource::initFromMemory(const char* data, size_t length) { - // This is only valid if we have a local texture data object - assert(mTextureData != nullptr); - mTextureData->releaseVRAM(); - mTextureData->releaseRAM(); - mTextureData->initImageFromMemory((const unsigned char*)data, length); - // Get the size from the texture data - mSize << mTextureData->width(), mTextureData->height(); - mSourceSize << mTextureData->sourceWidth(), mTextureData->sourceHeight(); + size_t width, height; + std::vector imageRGBA = ImageIO::loadFromMemoryRGBA32((const unsigned char*)(data), length, width, height); + + if(imageRGBA.size() == 0) + { + LOG(LogError) << "Could not initialize texture from memory, invalid data! (file path: " << mPath << ", data ptr: " << (size_t)data << ", reported size: " << length << ")"; + return; + } + + initFromPixels(imageRGBA.data(), width, height); +} + +void TextureResource::deinit() +{ + if(mTextureID != 0) + { + glDeleteTextures(1, &mTextureID); + mTextureID = 0; + } } -const Eigen::Vector2i TextureResource::getSize() const +const Eigen::Vector2i& TextureResource::getSize() const { - return mSize; + return mTextureSize; } bool TextureResource::isTiled() const { - if (mTextureData != nullptr) - return mTextureData->tiled(); - std::shared_ptr data = sTextureDataManager.get(this); - return data->tiled(); + return mTile; } -bool TextureResource::bind() +void TextureResource::bind() const { - if (mTextureData != nullptr) - { - mTextureData->uploadAndBind(); - return true; - } + if(mTextureID != 0) + glBindTexture(GL_TEXTURE_2D, mTextureID); else - { - return sTextureDataManager.bind(this); - } + LOG(LogError) << "Tried to bind uninitialized texture!"; } -std::shared_ptr TextureResource::get(const std::string& path, bool tile, bool forceLoad, bool dynamic) + +std::shared_ptr TextureResource::get(const std::string& path, bool tile) { std::shared_ptr& rm = ResourceManager::getInstance(); const std::string canonicalPath = getCanonicalPath(path); + if(canonicalPath.empty()) { - std::shared_ptr tex(new TextureResource("", tile, false)); + std::shared_ptr tex(new TextureResource("", tile)); rm->addReloadable(tex); //make sure we get properly deinitialized even though we do nothing on reinitialization return tex; } @@ -126,100 +121,58 @@ std::shared_ptr TextureResource::get(const std::string& path, b // need to create it std::shared_ptr tex; - tex = std::shared_ptr(new TextureResource(key.first, tile, dynamic)); - std::shared_ptr data = sTextureDataManager.get(tex.get()); // is it an SVG? - if(key.first.substr(key.first.size() - 4, std::string::npos) != ".svg") + if(key.first.substr(key.first.size() - 4, std::string::npos) == ".svg") { - // Probably not. Add it to our map. We don't add SVGs because 2 svgs might be rasterized at different sizes + // probably + // don't add it to our map because 2 svgs might be rasterized at different sizes + tex = std::shared_ptr(new SVGResource(key.first, tile)); + sTextureList.push_back(tex); // add it to our list though + rm->addReloadable(tex); + tex->reload(rm); + return tex; + }else{ + // normal texture + tex = std::shared_ptr(new TextureResource(key.first, tile)); sTextureMap[key] = std::weak_ptr(tex); + sTextureList.push_back(tex); + rm->addReloadable(tex); + tex->reload(ResourceManager::getInstance()); + return tex; } - - // Add it to the reloadable list - rm->addReloadable(tex); - - // Force load it if necessary. Note that it may get dumped from VRAM if we run low - if (forceLoad) - { - tex->mForceLoad = forceLoad; - data->load(); - } - - return tex; } -// For scalable source images in textures we want to set the resolution to rasterize at -void TextureResource::rasterizeAt(size_t width, size_t height) +bool TextureResource::isInitialized() const { - std::shared_ptr data; - if (mTextureData != nullptr) - data = mTextureData; - else - data = sTextureDataManager.get(this); - mSourceSize << (float)width, (float)height; - data->setSourceSize((float)width, (float)height); - if (mForceLoad || (mTextureData != nullptr)) - data->load(); + return mTextureID != 0; } -Eigen::Vector2f TextureResource::getSourceImageSize() const +size_t TextureResource::getMemUsage() const { - return mSourceSize; -} + if(!mTextureID || mTextureSize.x() == 0 || mTextureSize.y() == 0) + return 0; -bool TextureResource::isInitialized() const -{ - return true; + return mTextureSize.x() * mTextureSize.y() * 4; } size_t TextureResource::getTotalMemUsage() { size_t total = 0; - // Count up all textures that manage their own texture data - for (auto tex : sAllTextures) - { - if (tex->mTextureData != nullptr) - total += tex->mTextureData->getVRAMUsage(); - } - // Now get the committed memory from the manager - total += sTextureDataManager.getCommittedSize(); - // And the size of the loading queue - total += sTextureDataManager.getQueueSize(); - return total; -} -size_t TextureResource::getTotalTextureSize() -{ - size_t total = 0; - // Count up all textures that manage their own texture data - for (auto tex : sAllTextures) + auto it = sTextureList.begin(); + while(it != sTextureList.end()) { - if (tex->mTextureData != nullptr) - total += tex->getSize().x() * tex->getSize().y() * 4; - } - // Now get the total memory from the manager - total += sTextureDataManager.getTotalSize(); - return total; -} - -void TextureResource::unload(std::shared_ptr& rm) -{ - // Release the texture's resources - std::shared_ptr data; - if (mTextureData == nullptr) - data = sTextureDataManager.get(this); - else - data = mTextureData; + if((*it).expired()) + { + // remove expired textures from the list + it = sTextureList.erase(it); + continue; + } - data->releaseVRAM(); - data->releaseRAM(); -} + total += (*it).lock()->getMemUsage(); + it++; + } -void TextureResource::reload(std::shared_ptr& rm) -{ - // For dynamically loaded textures the texture manager will load them on demand. - // For manually loaded textures we have to reload them here - if (mTextureData) - mTextureData->load(); + return total; } diff --git a/es-core/src/resources/TextureResource.h b/es-core/src/resources/TextureResource.h index 7623e8b1c2..811e71de37 100644 --- a/es-core/src/resources/TextureResource.h +++ b/es-core/src/resources/TextureResource.h @@ -3,12 +3,8 @@ #include "resources/ResourceManager.h" #include -#include -#include #include #include "platform.h" -#include "resources/TextureData.h" -#include "resources/TextureDataManager.h" #include GLHEADER // An OpenGL texture. @@ -16,43 +12,40 @@ class TextureResource : public IReloadable { public: - static std::shared_ptr get(const std::string& path, bool tile = false, bool forceLoad = false, bool dynamic = true); - void initFromPixels(const unsigned char* dataRGBA, size_t width, size_t height); - virtual void initFromMemory(const char* file, size_t length); - - // For scalable source images in textures we want to set the resolution to rasterize at - void rasterizeAt(size_t width, size_t height); - Eigen::Vector2f getSourceImageSize() const; + static std::shared_ptr get(const std::string& path, bool tile = false); virtual ~TextureResource(); + virtual void unload(std::shared_ptr& rm) override; + virtual void reload(std::shared_ptr& rm) override; + bool isInitialized() const; bool isTiled() const; + const Eigen::Vector2i& getSize() const; + void bind() const; + + // Warning: will NOT correctly reinitialize when this texture is reloaded (e.g. ES starts/stops playing a game). + virtual void initFromMemory(const char* file, size_t length); - const Eigen::Vector2i getSize() const; - bool bind(); + // Warning: will NOT correctly reinitialize when this texture is reloaded (e.g. ES starts/stops playing a game). + void initFromPixels(const unsigned char* dataRGBA, size_t width, size_t height); + size_t getMemUsage() const; // returns an approximation of the VRAM used by this texture (in bytes) static size_t getTotalMemUsage(); // returns an approximation of total VRAM used by textures (in bytes) - static size_t getTotalTextureSize(); // returns the number of bytes that would be used if all textures were in memory protected: - TextureResource(const std::string& path, bool tile, bool dynamic); - virtual void unload(std::shared_ptr& rm); - virtual void reload(std::shared_ptr& rm); + TextureResource(const std::string& path, bool tile); + void deinit(); -private: - // mTextureData is used for textures that are not loaded from a file - these ones - // are permanently allocated and cannot be loaded and unloaded based on resources - std::shared_ptr mTextureData; - - // The texture data manager manages loading and unloading of filesystem based textures - static TextureDataManager sTextureDataManager; + Eigen::Vector2i mTextureSize; + const std::string mPath; + const bool mTile; - Eigen::Vector2i mSize; - Eigen::Vector2f mSourceSize; - bool mForceLoad; +private: + GLuint mTextureID; typedef std::pair TextureKeyType; static std::map< TextureKeyType, std::weak_ptr > sTextureMap; // map of textures, used to prevent duplicate textures - static std::set sAllTextures; // Set of all textures, used for memory management + + static std::list< std::weak_ptr > sTextureList; // list of all textures, used for memory approximations }; From 6872f472772f2d6a2ae5b3971a4434330b5b9ca3 Mon Sep 17 00:00:00 2001 From: fieldofcows Date: Sun, 22 Jan 2017 23:28:06 +0000 Subject: [PATCH 51/74] Fix WSOD by loading textures on demand in a separate thread when a user configurable texture memory threshold is reached --- es-app/src/components/RatingComponent.cpp | 12 +- es-app/src/guis/GuiMenu.cpp | 6 + es-app/src/main.cpp | 5 + es-app/src/views/SystemView.cpp | 4 +- es-app/src/views/ViewController.cpp | 4 +- es-core/CMakeLists.txt | 6 +- es-core/src/Settings.cpp | 3 +- es-core/src/Window.cpp | 9 +- es-core/src/components/ImageComponent.cpp | 69 ++++- es-core/src/components/ImageComponent.h | 7 +- es-core/src/resources/SVGResource.cpp | 101 -------- es-core/src/resources/SVGResource.h | 27 -- es-core/src/resources/TextureData.cpp | 259 +++++++++++++++++++ es-core/src/resources/TextureData.h | 63 +++++ es-core/src/resources/TextureDataManager.cpp | 226 ++++++++++++++++ es-core/src/resources/TextureDataManager.h | 86 ++++++ es-core/src/resources/TextureResource.cpp | 245 +++++++++++------- es-core/src/resources/TextureResource.h | 49 ++-- 18 files changed, 900 insertions(+), 281 deletions(-) delete mode 100644 es-core/src/resources/SVGResource.cpp delete mode 100644 es-core/src/resources/SVGResource.h create mode 100644 es-core/src/resources/TextureData.cpp create mode 100644 es-core/src/resources/TextureData.h create mode 100644 es-core/src/resources/TextureDataManager.cpp create mode 100644 es-core/src/resources/TextureDataManager.h diff --git a/es-app/src/components/RatingComponent.cpp b/es-app/src/components/RatingComponent.cpp index 12f39a3090..3dbc36a0a4 100644 --- a/es-app/src/components/RatingComponent.cpp +++ b/es-app/src/components/RatingComponent.cpp @@ -2,7 +2,6 @@ #include "Renderer.h" #include "Window.h" #include "Util.h" -#include "resources/SVGResource.h" RatingComponent::RatingComponent(Window* window) : GuiComponent(window) { @@ -45,16 +44,13 @@ void RatingComponent::onSizeChanged() else if(mSize.x() == 0) mSize[0] = mSize.y() * NUM_RATING_STARS; - auto filledSVG = dynamic_cast(mFilledTexture.get()); - auto unfilledSVG = dynamic_cast(mUnfilledTexture.get()); - if(mSize.y() > 0) { size_t heightPx = (size_t)round(mSize.y()); - if(filledSVG) - filledSVG->rasterizeAt(heightPx, heightPx); - if(unfilledSVG) - unfilledSVG->rasterizeAt(heightPx, heightPx); + if (mFilledTexture) + mFilledTexture->rasterizeAt(heightPx, heightPx); + if(mUnfilledTexture) + mUnfilledTexture->rasterizeAt(heightPx, heightPx); } updateVertices(); diff --git a/es-app/src/guis/GuiMenu.cpp b/es-app/src/guis/GuiMenu.cpp index 71ac7272bc..68b1a355d1 100644 --- a/es-app/src/guis/GuiMenu.cpp +++ b/es-app/src/guis/GuiMenu.cpp @@ -178,6 +178,12 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MEN s->addWithLabel("PARSE GAMESLISTS ONLY", parse_gamelists); s->addSaveFunc([parse_gamelists] { Settings::getInstance()->setBool("ParseGamelistOnly", parse_gamelists->getState()); }); + // maximum vram + auto max_vram = std::make_shared(mWindow, 0.f, 1000.f, 10.f, "Mb"); + max_vram->setValue((float)(Settings::getInstance()->getInt("MaxVRAM"))); + s->addWithLabel("VRAM LIMIT", max_vram); + s->addSaveFunc([max_vram] { Settings::getInstance()->setInt("MaxVRAM", (int)round(max_vram->getValue())); }); + mWindow->pushGui(s); }); diff --git a/es-app/src/main.cpp b/es-app/src/main.cpp index 6753b9ae31..c3d030ec4b 100644 --- a/es-app/src/main.cpp +++ b/es-app/src/main.cpp @@ -74,6 +74,10 @@ bool parseArgs(int argc, char* argv[], unsigned int* width, unsigned int* height }else if(strcmp(argv[i], "--scrape") == 0) { scrape_cmdline = true; + }else if(strcmp(argv[i], "--max-vram") == 0) + { + int maxVRAM = atoi(argv[i + 1]); + Settings::getInstance()->setInt("MaxVRAM", maxVRAM); }else if(strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) { #ifdef WIN32 @@ -99,6 +103,7 @@ bool parseArgs(int argc, char* argv[], unsigned int* width, unsigned int* height "--scrape scrape using command line interface\n" "--windowed not fullscreen, should be used with --resolution\n" "--vsync [1/on or 0/off] turn vsync on or off (default is on)\n" + "--max-vram [size] Max VRAM to use in Mb before swapping. 0 for unlimited\n" "--help, -h summon a sentient, angry tuba\n\n" "More information available in README.md.\n"; return false; //exit after printing help diff --git a/es-app/src/views/SystemView.cpp b/es-app/src/views/SystemView.cpp index 013490aca9..c760125b97 100644 --- a/es-app/src/views/SystemView.cpp +++ b/es-app/src/views/SystemView.cpp @@ -43,13 +43,13 @@ void SystemView::populate() // make logo if(theme->getElement("system", "logo", "image")) { - ImageComponent* logo = new ImageComponent(mWindow); + ImageComponent* logo = new ImageComponent(mWindow, false, false); logo->setMaxSize(Eigen::Vector2f(logoSize().x(), logoSize().y())); logo->applyTheme((*it)->getTheme(), "system", "logo", ThemeFlags::PATH); logo->setPosition((logoSize().x() - logo->getSize().x()) / 2, (logoSize().y() - logo->getSize().y()) / 2); // center e.data.logo = std::shared_ptr(logo); - ImageComponent* logoSelected = new ImageComponent(mWindow); + ImageComponent* logoSelected = new ImageComponent(mWindow, false, false); logoSelected->setMaxSize(Eigen::Vector2f(logoSize().x() * SELECTED_SCALE, logoSize().y() * SELECTED_SCALE * 0.70f)); logoSelected->applyTheme((*it)->getTheme(), "system", "logo", ThemeFlags::PATH); logoSelected->setPosition((logoSize().x() - logoSelected->getSize().x()) / 2, diff --git a/es-app/src/views/ViewController.cpp b/es-app/src/views/ViewController.cpp index 1e10c91753..d9093e8e10 100644 --- a/es-app/src/views/ViewController.cpp +++ b/es-app/src/views/ViewController.cpp @@ -406,7 +406,9 @@ void ViewController::reloadAll() mCurrentView = getGameListView(mState.getSystem()); }else if(mState.viewing == SYSTEM_SELECT) { - mSystemListView->goToSystem(mState.getSystem(), false); + SystemData* system = mState.getSystem(); + goToSystemView(SystemData::sSystemVector.front()); + mSystemListView->goToSystem(system, false); mCurrentView = mSystemListView; }else{ goToSystemView(SystemData::sSystemVector.front()); diff --git a/es-core/CMakeLists.txt b/es-core/CMakeLists.txt index cf0cfb3ea3..f05aec77c3 100644 --- a/es-core/CMakeLists.txt +++ b/es-core/CMakeLists.txt @@ -53,8 +53,9 @@ set(CORE_HEADERS # Resources ${CMAKE_CURRENT_SOURCE_DIR}/src/resources/Font.h ${CMAKE_CURRENT_SOURCE_DIR}/src/resources/ResourceManager.h - ${CMAKE_CURRENT_SOURCE_DIR}/src/resources/SVGResource.h ${CMAKE_CURRENT_SOURCE_DIR}/src/resources/TextureResource.h + ${CMAKE_CURRENT_SOURCE_DIR}/src/resources/TextureData.h + ${CMAKE_CURRENT_SOURCE_DIR}/src/resources/TextureDataManager.h # Embedded assets (needed by ResourceManager) ${emulationstation-all_SOURCE_DIR}/data/Resources.h @@ -108,8 +109,9 @@ set(CORE_SOURCES # Resources ${CMAKE_CURRENT_SOURCE_DIR}/src/resources/Font.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/resources/ResourceManager.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/src/resources/SVGResource.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/resources/TextureResource.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/resources/TextureData.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/resources/TextureDataManager.cpp ) set(EMBEDDED_ASSET_SOURCES diff --git a/es-core/src/Settings.cpp b/es-core/src/Settings.cpp index 337dcaac13..df90ba7b65 100644 --- a/es-core/src/Settings.cpp +++ b/es-core/src/Settings.cpp @@ -69,6 +69,7 @@ void Settings::setDefaults() mIntMap["ScreenSaverTime"] = 5*60*1000; // 5 minutes mIntMap["ScraperResizeWidth"] = 400; mIntMap["ScraperResizeHeight"] = 0; + mIntMap["MaxVRAM"] = 100; mStringMap["TransitionStyle"] = "fade"; mStringMap["ThemeSet"] = ""; @@ -154,4 +155,4 @@ void Settings::setMethodName(const std::string& name, type value) \ SETTINGS_GETSET(bool, mBoolMap, getBool, setBool); SETTINGS_GETSET(int, mIntMap, getInt, setInt); SETTINGS_GETSET(float, mFloatMap, getFloat, setFloat); -SETTINGS_GETSET(const std::string&, mStringMap, getString, setString); \ No newline at end of file +SETTINGS_GETSET(const std::string&, mStringMap, getString, setString); diff --git a/es-core/src/Window.cpp b/es-core/src/Window.cpp index 761df4abc4..e402162c3d 100644 --- a/es-core/src/Window.cpp +++ b/es-core/src/Window.cpp @@ -160,11 +160,12 @@ void Window::update(int deltaTime) ss << std::fixed << std::setprecision(2) << ((float)mFrameTimeElapsed / (float)mFrameCountElapsed) << "ms"; // vram - float textureVramUsageMb = TextureResource::getTotalMemUsage() / 1000.0f / 1000.0f;; + float textureVramUsageMb = TextureResource::getTotalMemUsage() / 1000.0f / 1000.0f; + float textureTotalUsageMb = TextureResource::getTotalTextureSize() / 1000.0f / 1000.0f; float fontVramUsageMb = Font::getTotalMemUsage() / 1000.0f / 1000.0f;; - float totalVramUsageMb = textureVramUsageMb + fontVramUsageMb; - ss << "\nVRAM: " << totalVramUsageMb << "mb (texs: " << textureVramUsageMb << "mb, fonts: " << fontVramUsageMb << "mb)"; + ss << "\nFont VRAM: " << fontVramUsageMb << " Tex VRAM: " << textureVramUsageMb << + " Tex Max: " << textureTotalUsageMb; mFrameDataText = std::unique_ptr(mDefaultFonts.at(1)->buildTextCache(ss.str(), 50.f, 50.f, 0xFF00FFFF)); } @@ -242,7 +243,7 @@ void Window::renderLoadingScreen() Renderer::setMatrix(trans); Renderer::drawRect(0, 0, Renderer::getScreenWidth(), Renderer::getScreenHeight(), 0xFFFFFFFF); - ImageComponent splash(this); + ImageComponent splash(this, true); splash.setResize(Renderer::getScreenWidth() * 0.6f, 0.0f); splash.setImage(":/splash.svg"); splash.setPosition((Renderer::getScreenWidth() - splash.getSize().x()) / 2, (Renderer::getScreenHeight() - splash.getSize().y()) / 2 * 0.6f); diff --git a/es-core/src/components/ImageComponent.cpp b/es-core/src/components/ImageComponent.cpp index 2898c6f732..0705e0c28f 100644 --- a/es-core/src/components/ImageComponent.cpp +++ b/es-core/src/components/ImageComponent.cpp @@ -6,7 +6,6 @@ #include "Renderer.h" #include "ThemeData.h" #include "Util.h" -#include "resources/SVGResource.h" Eigen::Vector2i ImageComponent::getTextureSize() const { @@ -22,8 +21,9 @@ Eigen::Vector2f ImageComponent::getCenter() const mPosition.y() - (getSize().y() * mOrigin.y()) + getSize().y() / 2); } -ImageComponent::ImageComponent(Window* window) : GuiComponent(window), - mTargetIsMax(false), mFlipX(false), mFlipY(false), mOrigin(0.0, 0.0), mTargetSize(0, 0), mColorShift(0xFFFFFFFF) +ImageComponent::ImageComponent(Window* window, bool forceLoad, bool dynamic) : GuiComponent(window), + mTargetIsMax(false), mFlipX(false), mFlipY(false), mOrigin(0.0, 0.0), mTargetSize(0, 0), mColorShift(0xFFFFFFFF), + mForceLoad(forceLoad), mDynamic(dynamic), mFadeOpacity(0.0f), mFading(false) { updateColors(); } @@ -37,9 +37,7 @@ void ImageComponent::resize() if(!mTexture) return; - SVGResource* svg = dynamic_cast(mTexture.get()); - - const Eigen::Vector2f textureSize = svg ? svg->getSourceImageSize() : Eigen::Vector2f((float)mTexture->getSize().x(), (float)mTexture->getSize().y()); + const Eigen::Vector2f textureSize = mTexture->getSourceImageSize(); if(textureSize.isZero()) return; @@ -90,12 +88,8 @@ void ImageComponent::resize() } } } - - if(svg) - { - // mSize.y() should already be rounded - svg->rasterizeAt((int)round(mSize.x()), (int)round(mSize.y())); - } + // mSize.y() should already be rounded + mTexture->rasterizeAt((int)round(mSize.x()), (int)round(mSize.y())); onSizeChanged(); } @@ -110,7 +104,7 @@ void ImageComponent::setImage(std::string path, bool tile) if(path.empty() || !ResourceManager::getInstance()->fileExists(path)) mTexture.reset(); else - mTexture = TextureResource::get(path, tile); + mTexture = TextureResource::get(path, tile, mForceLoad, mDynamic); resize(); } @@ -166,6 +160,9 @@ void ImageComponent::setFlipY(bool flip) void ImageComponent::setColorShift(unsigned int color) { mColorShift = color; + // Grab the opacity from the color shift because we may need to apply it if + // fading textures in + mOpacity = color & 0xff; updateColors(); } @@ -247,7 +244,10 @@ void ImageComponent::render(const Eigen::Affine3f& parentTrans) if(mTexture->isInitialized()) { // actually draw the image - mTexture->bind(); + // The bind() function returns false if the texture is not currently loaded. A blank + // texture is bound in this case but we want to handle a fade so it doesn't just 'jump' in + // when it finally loads + fadeIn(mTexture->bind()); glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); @@ -278,6 +278,47 @@ void ImageComponent::render(const Eigen::Affine3f& parentTrans) GuiComponent::renderChildren(trans); } +void ImageComponent::fadeIn(bool textureLoaded) +{ + if (!mForceLoad) + { + if (!textureLoaded) + { + // Start the fade if this is the first time we've encountered the unloaded texture + if (!mFading) + { + // Start with a zero opacity and flag it as fading + mFadeOpacity = 0; + mFading = true; + // Set the colours to be translucent + mColorShift = (mColorShift >> 8 << 8) | 0; + updateColors(); + } + } + else if (mFading) + { + // The texture is loaded and we need to fade it in. The fade is based on the frame rate + // and is 1/4 second if running at 60 frames per second although the actual value is not + // that important + int opacity = mFadeOpacity + 255 / 15; + // See if we've finished fading + if (opacity >= 255) + { + mFadeOpacity = 255; + mFading = false; + } + else + { + mFadeOpacity = (unsigned char)opacity; + } + // Apply the combination of the target opacity and current fade + float newOpacity = (float)mOpacity * ((float)mFadeOpacity / 255.0f); + mColorShift = (mColorShift >> 8 << 8) | (unsigned char)newOpacity; + updateColors(); + } + } +} + bool ImageComponent::hasImage() { return (bool)mTexture; diff --git a/es-core/src/components/ImageComponent.h b/es-core/src/components/ImageComponent.h index 939c6c7cd2..3ff1ffbb27 100644 --- a/es-core/src/components/ImageComponent.h +++ b/es-core/src/components/ImageComponent.h @@ -12,7 +12,7 @@ class ImageComponent : public GuiComponent { public: - ImageComponent(Window* window); + ImageComponent(Window* window, bool forceLoad = false, bool dynamic = true); virtual ~ImageComponent(); //Loads the image at the given filepath. Will tile if tile is true (retrieves texture as tiling, creates vertices accordingly). @@ -81,10 +81,15 @@ class ImageComponent : public GuiComponent void updateVertices(); void updateColors(); + void fadeIn(bool textureLoaded); unsigned int mColorShift; std::shared_ptr mTexture; + unsigned char mFadeOpacity; + bool mFading; + bool mForceLoad; + bool mDynamic; }; #endif diff --git a/es-core/src/resources/SVGResource.cpp b/es-core/src/resources/SVGResource.cpp deleted file mode 100644 index 1a4ea16fca..0000000000 --- a/es-core/src/resources/SVGResource.cpp +++ /dev/null @@ -1,101 +0,0 @@ -#include "SVGResource.h" -#include "nanosvg/nanosvg.h" -#include "nanosvg/nanosvgrast.h" -#include "Log.h" -#include "Util.h" -#include "ImageIO.h" - -#define DPI 96 - -SVGResource::SVGResource(const std::string& path, bool tile) : TextureResource(path, tile), mSVGImage(NULL) -{ - mLastWidth = 0; - mLastHeight = 0; -} - -SVGResource::~SVGResource() -{ - deinitSVG(); -} - -void SVGResource::unload(std::shared_ptr& rm) -{ - deinitSVG(); - TextureResource::unload(rm); -} - -void SVGResource::initFromMemory(const char* file, size_t length) -{ - deinit(); - deinitSVG(); - - // nsvgParse excepts a modifiable, null-terminated string - char* copy = (char*)malloc(length + 1); - assert(copy != NULL); - memcpy(copy, file, length); - copy[length] = '\0'; - - mSVGImage = nsvgParse(copy, "px", DPI); - free(copy); - - if(!mSVGImage) - { - LOG(LogError) << "Error parsing SVG image."; - return; - } - - if(mLastWidth && mLastHeight) - rasterizeAt(mLastWidth, mLastHeight); - else - rasterizeAt((size_t)round(mSVGImage->width), (size_t)round(mSVGImage->height)); -} - -void SVGResource::rasterizeAt(size_t width, size_t height) -{ - if(!mSVGImage || (width == 0 && height == 0)) - return; - - if(width == 0) - { - // auto scale width to keep aspect - width = (size_t)round((height / mSVGImage->height) * mSVGImage->width); - }else if(height == 0) - { - // auto scale height to keep aspect - height = (size_t)round((width / mSVGImage->width) * mSVGImage->height); - } - - if(width != (size_t)round(mSVGImage->width) && height != (size_t)round(mSVGImage->height)) - { - mLastWidth = width; - mLastHeight = height; - } - - unsigned char* imagePx = (unsigned char*)malloc(width * height * 4); - assert(imagePx != NULL); - - NSVGrasterizer* rast = nsvgCreateRasterizer(); - nsvgRasterize(rast, mSVGImage, 0, 0, height / mSVGImage->height, imagePx, width, height, width * 4); - nsvgDeleteRasterizer(rast); - - ImageIO::flipPixelsVert(imagePx, width, height); - - initFromPixels(imagePx, width, height); - free(imagePx); -} - -Eigen::Vector2f SVGResource::getSourceImageSize() const -{ - if(mSVGImage) - return Eigen::Vector2f(mSVGImage->width, mSVGImage->height); - - return Eigen::Vector2f::Zero(); -} - -void SVGResource::deinitSVG() -{ - if(mSVGImage) - nsvgDelete(mSVGImage); - - mSVGImage = NULL; -} diff --git a/es-core/src/resources/SVGResource.h b/es-core/src/resources/SVGResource.h deleted file mode 100644 index 87479c0cf1..0000000000 --- a/es-core/src/resources/SVGResource.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include "resources/TextureResource.h" - -struct NSVGimage; - -class SVGResource : public TextureResource -{ -public: - virtual ~SVGResource(); - - virtual void unload(std::shared_ptr& rm) override; - - virtual void initFromMemory(const char* image, size_t length) override; - - void rasterizeAt(size_t width, size_t height); - Eigen::Vector2f getSourceImageSize() const; - -protected: - friend TextureResource; - SVGResource(const std::string& path, bool tile); - void deinitSVG(); - - NSVGimage* mSVGImage; - size_t mLastWidth; - size_t mLastHeight; -}; diff --git a/es-core/src/resources/TextureData.cpp b/es-core/src/resources/TextureData.cpp new file mode 100644 index 0000000000..15a3da116e --- /dev/null +++ b/es-core/src/resources/TextureData.cpp @@ -0,0 +1,259 @@ +#include "resources/TextureData.h" +#include "resources/ResourceManager.h" +#include "Log.h" +#include "ImageIO.h" +#include "string.h" +#include "Util.h" +#include "nanosvg/nanosvg.h" +#include "nanosvg/nanosvgrast.h" +#include + +#define DPI 96 + +TextureData::TextureData(bool tile) : mTile(tile), mTextureID(0), mDataRGBA(nullptr), mScalable(false), + mWidth(0), mHeight(0), mSourceWidth(0.0f), mSourceHeight(0.0f) +{ +} + +TextureData::~TextureData() +{ + releaseVRAM(); + releaseRAM(); +} + +void TextureData::initFromPath(const std::string& path) +{ + // Just set the path. It will be loaded later + mPath = path; + // Only textures with paths are reloadable + mReloadable = true; +} + +bool TextureData::initSVGFromMemory(const unsigned char* fileData, size_t length) +{ + // If already initialised then don't read again + { + std::unique_lock lock(mMutex); + if (mDataRGBA) + return true; + } + + // nsvgParse excepts a modifiable, null-terminated string + char* copy = (char*)malloc(length + 1); + assert(copy != NULL); + memcpy(copy, fileData, length); + copy[length] = '\0'; + + NSVGimage* svgImage = nsvgParse(copy, "px", DPI); + free(copy); + if (!svgImage) + { + LOG(LogError) << "Error parsing SVG image."; + return false; + } + + // We want to rasterise this texture at a specific resolution. If the source size + // variables are set then use them otherwise set them from the parsed file + if ((mSourceWidth == 0.0f) && (mSourceHeight == 0.0f)) + { + mSourceWidth = svgImage->width; + mSourceHeight = svgImage->height; + } + mWidth = (size_t)round(mSourceWidth); + mHeight = (size_t)round(mSourceHeight); + + if (mWidth == 0) + { + // auto scale width to keep aspect + mWidth = (size_t)round(((float)mHeight / svgImage->height) * svgImage->width); + } + else if (mHeight == 0) + { + // auto scale height to keep aspect + mHeight = (size_t)round(((float)mWidth / svgImage->width) * svgImage->height); + } + + unsigned char* dataRGBA = new unsigned char[mWidth * mHeight * 4]; + + NSVGrasterizer* rast = nsvgCreateRasterizer(); + nsvgRasterize(rast, svgImage, 0, 0, mHeight / svgImage->height, dataRGBA, mWidth, mHeight, mWidth * 4); + nsvgDeleteRasterizer(rast); + + ImageIO::flipPixelsVert(dataRGBA, mWidth, mHeight); + + std::unique_lock lock(mMutex); + mDataRGBA = dataRGBA; + + return true; +} + +bool TextureData::initImageFromMemory(const unsigned char* fileData, size_t length) +{ + size_t width, height; + + // If already initialised then don't read again + { + std::unique_lock lock(mMutex); + if (mDataRGBA) + return true; + } + + std::vector imageRGBA = ImageIO::loadFromMemoryRGBA32((const unsigned char*)(fileData), length, width, height); + if (imageRGBA.size() == 0) + { + LOG(LogError) << "Could not initialize texture from memory, invalid data! (file path: " << mPath << ", data ptr: " << (size_t)fileData << ", reported size: " << length << ")"; + return false; + } + + mSourceWidth = width; + mSourceHeight = height; + mScalable = false; + + return initFromRGBA(imageRGBA.data(), width, height); +} + +bool TextureData::initFromRGBA(const unsigned char* dataRGBA, size_t width, size_t height) +{ + // If already initialised then don't read again + std::unique_lock lock(mMutex); + if (mDataRGBA) + return true; + + // Take a copy + mDataRGBA = new unsigned char[width * height * 4]; + memcpy(mDataRGBA, dataRGBA, width * height * 4); + mWidth = width; + mHeight = height; + return true; +} + +bool TextureData::load() +{ + bool retval = false; + + // Need to load. See if there is a file + if (!mPath.empty()) + { + std::shared_ptr& rm = ResourceManager::getInstance(); + const ResourceData& data = rm->getFileData(mPath); + // is it an SVG? + if (mPath.substr(mPath.size() - 4, std::string::npos) == ".svg") + { + mScalable = true; + retval = initSVGFromMemory((const unsigned char*)data.ptr.get(), data.length); + } + else + retval = initImageFromMemory((const unsigned char*)data.ptr.get(), data.length); + } + return retval; +} + +bool TextureData::isLoaded() +{ + std::unique_lock lock(mMutex); + if (mDataRGBA || (mTextureID != 0)) + return true; + return false; +} + +bool TextureData::uploadAndBind() +{ + // See if it's already been uploaded + std::unique_lock lock(mMutex); + if (mTextureID != 0) + { + glBindTexture(GL_TEXTURE_2D, mTextureID); + } + else + { + // Load it if necessary + if (!mDataRGBA) + { + return false; + } + // Make sure we're ready to upload + if ((mWidth == 0) || (mHeight == 0) || (mDataRGBA == nullptr)) + return false; + glGetError(); + //now for the openGL texture stuff + glGenTextures(1, &mTextureID); + glBindTexture(GL_TEXTURE_2D, mTextureID); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, mWidth, mHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, mDataRGBA); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + const GLint wrapMode = mTile ? GL_REPEAT : GL_CLAMP_TO_EDGE; + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapMode); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapMode); + } + return true; +} + +void TextureData::releaseVRAM() +{ + std::unique_lock lock(mMutex); + if (mTextureID != 0) + { + glDeleteTextures(1, &mTextureID); + mTextureID = 0; + } +} + +void TextureData::releaseRAM() +{ + std::unique_lock lock(mMutex); + delete[] mDataRGBA; + mDataRGBA = 0; +} + +size_t TextureData::width() +{ + if (mWidth == 0) + load(); + return mWidth; +} + +size_t TextureData::height() +{ + if (mHeight == 0) + load(); + return mHeight; +} + +float TextureData::sourceWidth() +{ + if (mSourceWidth == 0) + load(); + return mSourceWidth; +} + +float TextureData::sourceHeight() +{ + if (mSourceHeight == 0) + load(); + return mSourceHeight; +} + +void TextureData::setSourceSize(float width, float height) +{ + if (mScalable) + { + if ((mSourceWidth != width) || (mSourceHeight != height)) + { + mSourceWidth = width; + mSourceHeight = height; + releaseVRAM(); + releaseRAM(); + } + } +} + +size_t TextureData::getVRAMUsage() +{ + if ((mTextureID != 0) || (mDataRGBA != nullptr)) + return mWidth * mHeight * 4; + else + return 0; +} diff --git a/es-core/src/resources/TextureData.h b/es-core/src/resources/TextureData.h new file mode 100644 index 0000000000..76ca6a0b4d --- /dev/null +++ b/es-core/src/resources/TextureData.h @@ -0,0 +1,63 @@ +#pragma once + +#include +#include +#include "platform.h" +#include +#include GLHEADER + +class TextureResource; + +class TextureData +{ +public: + TextureData(bool tile); + ~TextureData(); + + // These functions populate mDataRGBA but do not upload the texture to VRAM + + //!!!! Needs to be canonical path. Caller should check for duplicates before calling this + void initFromPath(const std::string& path); + bool initSVGFromMemory(const unsigned char* fileData, size_t length); + bool initImageFromMemory(const unsigned char* fileData, size_t length); + bool initFromRGBA(const unsigned char* dataRGBA, size_t width, size_t height); + + // Read the data into memory if necessary + bool load(); + + bool isLoaded(); + + // Upload the texture to VRAM if necessary and bind. Returns true if bound ok or + // false if either not loaded + bool uploadAndBind(); + + // Release the texture from VRAM + void releaseVRAM(); + + // Release the texture from conventional RAM + void releaseRAM(); + + // Get the amount of VRAM currenty used by this texture + size_t getVRAMUsage(); + + size_t width(); + size_t height(); + float sourceWidth(); + float sourceHeight(); + void setSourceSize(float width, float height); + + bool tiled() { return mTile; } + +private: + std::mutex mMutex; + bool mTile; + std::string mPath; + GLuint mTextureID; + unsigned char* mDataRGBA; + size_t mWidth; + size_t mHeight; + float mSourceWidth; + float mSourceHeight; + bool mScalable; + bool mReloadable; +}; diff --git a/es-core/src/resources/TextureDataManager.cpp b/es-core/src/resources/TextureDataManager.cpp new file mode 100644 index 0000000000..55720d14ac --- /dev/null +++ b/es-core/src/resources/TextureDataManager.cpp @@ -0,0 +1,226 @@ +#include "resources/TextureDataManager.h" +#include "resources/TextureResource.h" +#include "Settings.h" + +TextureDataManager::TextureDataManager() +{ + unsigned char data[5 * 5 * 4]; + mBlank = std::shared_ptr(new TextureData(false)); + for (int i = 0; i < (5 * 5); ++i) + { + data[i*4] = (i % 2) * 255; + data[i*4+1] = (i % 2) * 255; + data[i*4+2] = (i % 2) * 255; + data[i*4+3] = 0; + } + mBlank->initFromRGBA(data, 5, 5); + mLoader = new TextureLoader; +} + +TextureDataManager::~TextureDataManager() +{ + delete mLoader; +} + +std::shared_ptr TextureDataManager::add(const TextureResource* key, bool tiled) +{ + remove(key); + std::shared_ptr data(new TextureData(tiled)); + mTextures.push_front(data); + mTextureLookup[key] = mTextures.begin(); + return data; +} + +void TextureDataManager::remove(const TextureResource* key) +{ + // Find the entry in the list + auto it = mTextureLookup.find(key); + if (it != mTextureLookup.end()) + { + // Remove the list entry + mTextures.erase((*it).second); + // And the lookup + mTextureLookup.erase(it); + } +} + +std::shared_ptr TextureDataManager::get(const TextureResource* key) +{ + // If it's in the cache then we want to remove it from it's current location and + // move it to the top + std::shared_ptr tex; + auto it = mTextureLookup.find(key); + if (it != mTextureLookup.end()) + { + tex = *(*it).second; + // Remove the list entry + mTextures.erase((*it).second); + // Put it at the top + mTextures.push_front(tex); + // Store it back in the lookup + mTextureLookup[key] = mTextures.begin(); + + // Make sure it's loaded or queued for loading + load(tex); + } + return tex; +} + +bool TextureDataManager::bind(const TextureResource* key) +{ + std::shared_ptr tex = get(key); + bool bound = false; + if (tex != nullptr) + bound = tex->uploadAndBind(); + if (!bound) + mBlank->uploadAndBind(); + return bound; +} + +size_t TextureDataManager::getTotalSize() +{ + size_t total = 0; + for (auto tex : mTextures) + total += tex->width() * tex->height() * 4; + return total; +} + +size_t TextureDataManager::getCommittedSize() +{ + size_t total = 0; + for (auto tex : mTextures) + total += tex->getVRAMUsage(); + return total; +} + +size_t TextureDataManager::getQueueSize() +{ + return mLoader->getQueueSize(); +} + +void TextureDataManager::load(std::shared_ptr tex, bool block) +{ + // See if it's already loaded + if (tex->isLoaded()) + return; + // Not loaded. Make sure there is room + size_t size = TextureResource::getTotalMemUsage(); + size_t max_texture = (size_t)Settings::getInstance()->getInt("MaxVRAM") * 1024 * 1024; + + size_t in = size; + + for (auto it = mTextures.rbegin(); it != mTextures.rend(); ++it) + { + if (size < max_texture) + break; + //size -= (*it)->getVRAMUsage(); + (*it)->releaseVRAM(); + (*it)->releaseRAM(); + // It may be already in the loader queue. In this case it wouldn't have been using + // any VRAM yet but it will be. Remove it from the loader queue + mLoader->remove(*it); + size = TextureResource::getTotalMemUsage(); + } + if (!block) + mLoader->load(tex); + else + tex->load(); +} + +TextureLoader::TextureLoader() : mExit(false) +{ + mThread = new std::thread(&TextureLoader::threadProc, this); +} + +TextureLoader::~TextureLoader() +{ + // Just abort any waiting texture + mTextureDataQ.clear(); + mTextureDataLookup.clear(); + + // Exit the thread + mExit = true; + mEvent.notify_one(); + mThread->join(); + delete mThread; +} + +void TextureLoader::threadProc() +{ + while (!mExit) + { + std::shared_ptr textureData; + { + // Wait for an event to say there is something in the queue + std::unique_lock lock(mMutex); + mEvent.wait(lock); + if (!mTextureDataQ.empty()) + { + textureData = mTextureDataQ.front(); + mTextureDataQ.pop_front(); + mTextureDataLookup.erase(mTextureDataLookup.find(textureData.get())); + } + } + // Queue has been released here but we might have a texture to process + while (textureData) + { + textureData->load(); + + // See if there is another item in the queue + textureData = nullptr; + std::unique_lock lock(mMutex); + if (!mTextureDataQ.empty()) + { + textureData = mTextureDataQ.front(); + mTextureDataQ.pop_front(); + mTextureDataLookup.erase(mTextureDataLookup.find(textureData.get())); + } + } + } +} + +void TextureLoader::load(std::shared_ptr textureData) +{ + // Make sure it's not already loaded + if (!textureData->isLoaded()) + { + std::unique_lock lock(mMutex); + // Remove it from the queue if it is already there + auto td = mTextureDataLookup.find(textureData.get()); + if (td != mTextureDataLookup.end()) + { + mTextureDataQ.erase((*td).second); + mTextureDataLookup.erase(td); + } + + // Put it on the start of the queue as we want the newly requested textures to load first + mTextureDataQ.push_front(textureData); + mTextureDataLookup[textureData.get()] = mTextureDataQ.begin(); + mEvent.notify_one(); + } +} + +void TextureLoader::remove(std::shared_ptr textureData) +{ + // Just remove it from the queue so we don't attempt to load it + std::unique_lock lock(mMutex); + auto td = mTextureDataLookup.find(textureData.get()); + if (td != mTextureDataLookup.end()) + { + mTextureDataQ.erase((*td).second); + mTextureDataLookup.erase(td); + } +} + +size_t TextureLoader::getQueueSize() +{ + // Gets the amount of video memory that will be used once all textures in + // the queue are loaded + size_t mem = 0; + std::unique_lock lock(mMutex); + for (auto tex : mTextureDataQ) + { + mem += tex->width() * tex->height() * 4; + } + return mem; +} diff --git a/es-core/src/resources/TextureDataManager.h b/es-core/src/resources/TextureDataManager.h new file mode 100644 index 0000000000..414804aba9 --- /dev/null +++ b/es-core/src/resources/TextureDataManager.h @@ -0,0 +1,86 @@ +#pragma once + +#include "resources/ResourceManager.h" +#include "platform.h" +#include "resources/TextureData.h" +#include +#include +#include +#include +#include +#include + +class TextureResource; + +class TextureLoader +{ +public: + TextureLoader(); + ~TextureLoader(); + + void load(std::shared_ptr textureData); + void remove(std::shared_ptr textureData); + + size_t getQueueSize(); + +private: + void processQueue(); + void threadProc(); + + std::list > mTextureDataQ; + std::map >::iterator > mTextureDataLookup; + + std::thread* mThread; + std::mutex mMutex; + std::condition_variable mEvent; + bool mExit; +}; + +// +// This class manages the loading and unloading of textures +// +// When textures are added, the texture data is just stored as-is. The texture +// data should only have been constructed and not loaded for this to work correctly. +// When the get() function is called it indicates that a texture wants to be used so +// at this point the texture data is loaded (via a call to load()). +// +// Once the load is complete (which may not be on the first call to get() if the +// data is loaded in a background thread) then the get() function call uploadAndBind() +// to upload to VRAM if necessary and bind the texture. This is followed by a call +// to releaseRAM() which frees the memory buffer if the texture can be reloaded from +// disk if needed again +// +class TextureDataManager +{ +public: + TextureDataManager(); + ~TextureDataManager(); + + std::shared_ptr add(const TextureResource* key, bool tiled); + + // The texturedata being removed may be loading in a different thread. However it will + // be referenced by a smart point so we only need to remove it from our array and it + // will be deleted when the other thread has finished with it + void remove(const TextureResource* key); + + std::shared_ptr get(const TextureResource* key); + bool bind(const TextureResource* key); + + // Get the total size of all textures managed by this object, loaded and unloaded in bytes + size_t getTotalSize(); + // Get the total size of all committed textures (in VRAM) in bytes + size_t getCommittedSize(); + // Get the total size of all load-pending textures in the queue - these will + // be committed to VRAM as the queue is processed + size_t getQueueSize(); + // Load a texture, freeing resources as necessary to make space + void load(std::shared_ptr tex, bool block = false); + +private: + + std::list > mTextures; + std::map >::iterator > mTextureLookup; + std::shared_ptr mBlank; + TextureLoader* mLoader; +}; + diff --git a/es-core/src/resources/TextureResource.cpp b/es-core/src/resources/TextureResource.cpp index e6657dcc20..6400d74b9b 100644 --- a/es-core/src/resources/TextureResource.cpp +++ b/es-core/src/resources/TextureResource.cpp @@ -5,108 +5,113 @@ #include "ImageIO.h" #include "Renderer.h" #include "Util.h" -#include "resources/SVGResource.h" +#include "Settings.h" +TextureDataManager TextureResource::sTextureDataManager; std::map< TextureResource::TextureKeyType, std::weak_ptr > TextureResource::sTextureMap; -std::list< std::weak_ptr > TextureResource::sTextureList; +std::set TextureResource::sAllTextures; -TextureResource::TextureResource(const std::string& path, bool tile) : - mTextureID(0), mPath(path), mTextureSize(Eigen::Vector2i::Zero()), mTile(tile) +TextureResource::TextureResource(const std::string& path, bool tile, bool dynamic) : mTextureData(nullptr), mForceLoad(false) { -} - -TextureResource::~TextureResource() -{ - deinit(); -} - -void TextureResource::unload(std::shared_ptr& rm) -{ - deinit(); -} + // Create a texture data object for this texture + if (!path.empty()) + { + // If there is a path then the 'dynamic' flag tells us whether to use the texture + // data manager to manage loading/unloading of this texture + std::shared_ptr data; + if (dynamic) + { + data = sTextureDataManager.add(this, tile); + data->initFromPath(path); + // Force the texture manager to load it using a blocking load + sTextureDataManager.load(data, true); + } + else + { + mTextureData = std::shared_ptr(new TextureData(tile)); + data = mTextureData; + data->initFromPath(path); + // Load it so we can read the width/height + data->load(); + } -void TextureResource::reload(std::shared_ptr& rm) -{ - if(!mPath.empty()) + mSize << data->width(), data->height(); + mSourceSize << data->sourceWidth(), data->sourceHeight(); + } + else { - const ResourceData& data = rm->getFileData(mPath); - initFromMemory((const char*)data.ptr.get(), data.length); + // Create a texture managed by this class because it cannot be dynamically loaded and unloaded + mTextureData = std::shared_ptr(new TextureData(tile)); } + sAllTextures.insert(this); } -void TextureResource::initFromPixels(const unsigned char* dataRGBA, size_t width, size_t height) +TextureResource::~TextureResource() { - deinit(); - - assert(width > 0 && height > 0); - - //now for the openGL texture stuff - glGenTextures(1, &mTextureID); - glBindTexture(GL_TEXTURE_2D, mTextureID); - - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, dataRGBA); + if (mTextureData == nullptr) + sTextureDataManager.remove(this); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - const GLint wrapMode = mTile ? GL_REPEAT : GL_CLAMP_TO_EDGE; - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapMode); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapMode); - - mTextureSize << width, height; + sAllTextures.erase(sAllTextures.find(this)); } -void TextureResource::initFromMemory(const char* data, size_t length) +void TextureResource::initFromPixels(const unsigned char* dataRGBA, size_t width, size_t height) { - size_t width, height; - std::vector imageRGBA = ImageIO::loadFromMemoryRGBA32((const unsigned char*)(data), length, width, height); - - if(imageRGBA.size() == 0) - { - LOG(LogError) << "Could not initialize texture from memory, invalid data! (file path: " << mPath << ", data ptr: " << (size_t)data << ", reported size: " << length << ")"; - return; - } - - initFromPixels(imageRGBA.data(), width, height); + // This is only valid if we have a local texture data object + assert(mTextureData != nullptr); + mTextureData->releaseVRAM(); + mTextureData->releaseRAM(); + mTextureData->initFromRGBA(dataRGBA, width, height); + // Cache the image dimensions + mSize << width, height; + mSourceSize << mTextureData->sourceWidth(), mTextureData->sourceHeight(); } -void TextureResource::deinit() +void TextureResource::initFromMemory(const char* data, size_t length) { - if(mTextureID != 0) - { - glDeleteTextures(1, &mTextureID); - mTextureID = 0; - } + // This is only valid if we have a local texture data object + assert(mTextureData != nullptr); + mTextureData->releaseVRAM(); + mTextureData->releaseRAM(); + mTextureData->initImageFromMemory((const unsigned char*)data, length); + // Get the size from the texture data + mSize << mTextureData->width(), mTextureData->height(); + mSourceSize << mTextureData->sourceWidth(), mTextureData->sourceHeight(); } -const Eigen::Vector2i& TextureResource::getSize() const +const Eigen::Vector2i TextureResource::getSize() const { - return mTextureSize; + return mSize; } bool TextureResource::isTiled() const { - return mTile; + if (mTextureData != nullptr) + return mTextureData->tiled(); + std::shared_ptr data = sTextureDataManager.get(this); + return data->tiled(); } -void TextureResource::bind() const +bool TextureResource::bind() { - if(mTextureID != 0) - glBindTexture(GL_TEXTURE_2D, mTextureID); + if (mTextureData != nullptr) + { + mTextureData->uploadAndBind(); + return true; + } else - LOG(LogError) << "Tried to bind uninitialized texture!"; + { + return sTextureDataManager.bind(this); + } } - -std::shared_ptr TextureResource::get(const std::string& path, bool tile) +std::shared_ptr TextureResource::get(const std::string& path, bool tile, bool forceLoad, bool dynamic) { std::shared_ptr& rm = ResourceManager::getInstance(); const std::string canonicalPath = getCanonicalPath(path); - if(canonicalPath.empty()) { - std::shared_ptr tex(new TextureResource("", tile)); + std::shared_ptr tex(new TextureResource("", tile, false)); rm->addReloadable(tex); //make sure we get properly deinitialized even though we do nothing on reinitialization return tex; } @@ -121,58 +126,100 @@ std::shared_ptr TextureResource::get(const std::string& path, b // need to create it std::shared_ptr tex; + tex = std::shared_ptr(new TextureResource(key.first, tile, dynamic)); + std::shared_ptr data = sTextureDataManager.get(tex.get()); // is it an SVG? - if(key.first.substr(key.first.size() - 4, std::string::npos) == ".svg") + if(key.first.substr(key.first.size() - 4, std::string::npos) != ".svg") { - // probably - // don't add it to our map because 2 svgs might be rasterized at different sizes - tex = std::shared_ptr(new SVGResource(key.first, tile)); - sTextureList.push_back(tex); // add it to our list though - rm->addReloadable(tex); - tex->reload(rm); - return tex; - }else{ - // normal texture - tex = std::shared_ptr(new TextureResource(key.first, tile)); + // Probably not. Add it to our map. We don't add SVGs because 2 svgs might be rasterized at different sizes sTextureMap[key] = std::weak_ptr(tex); - sTextureList.push_back(tex); - rm->addReloadable(tex); - tex->reload(ResourceManager::getInstance()); - return tex; } + + // Add it to the reloadable list + rm->addReloadable(tex); + + // Force load it if necessary. Note that it may get dumped from VRAM if we run low + if (forceLoad) + { + tex->mForceLoad = forceLoad; + data->load(); + } + + return tex; } -bool TextureResource::isInitialized() const +// For scalable source images in textures we want to set the resolution to rasterize at +void TextureResource::rasterizeAt(size_t width, size_t height) { - return mTextureID != 0; + std::shared_ptr data; + if (mTextureData != nullptr) + data = mTextureData; + else + data = sTextureDataManager.get(this); + mSourceSize << (float)width, (float)height; + data->setSourceSize((float)width, (float)height); + if (mForceLoad || (mTextureData != nullptr)) + data->load(); } -size_t TextureResource::getMemUsage() const +Eigen::Vector2f TextureResource::getSourceImageSize() const { - if(!mTextureID || mTextureSize.x() == 0 || mTextureSize.y() == 0) - return 0; + return mSourceSize; +} - return mTextureSize.x() * mTextureSize.y() * 4; +bool TextureResource::isInitialized() const +{ + return true; } size_t TextureResource::getTotalMemUsage() { size_t total = 0; - - auto it = sTextureList.begin(); - while(it != sTextureList.end()) + // Count up all textures that manage their own texture data + for (auto tex : sAllTextures) { - if((*it).expired()) - { - // remove expired textures from the list - it = sTextureList.erase(it); - continue; - } - - total += (*it).lock()->getMemUsage(); - it++; + if (tex->mTextureData != nullptr) + total += tex->mTextureData->getVRAMUsage(); } + // Now get the committed memory from the manager + total += sTextureDataManager.getCommittedSize(); + // And the size of the loading queue + total += sTextureDataManager.getQueueSize(); + return total; +} +size_t TextureResource::getTotalTextureSize() +{ + size_t total = 0; + // Count up all textures that manage their own texture data + for (auto tex : sAllTextures) + { + if (tex->mTextureData != nullptr) + total += tex->getSize().x() * tex->getSize().y() * 4; + } + // Now get the total memory from the manager + total += sTextureDataManager.getTotalSize(); return total; } + +void TextureResource::unload(std::shared_ptr& rm) +{ + // Release the texture's resources + std::shared_ptr data; + if (mTextureData == nullptr) + data = sTextureDataManager.get(this); + else + data = mTextureData; + + data->releaseVRAM(); + data->releaseRAM(); +} + +void TextureResource::reload(std::shared_ptr& rm) +{ + // For dynamically loaded textures the texture manager will load them on demand. + // For manually loaded textures we have to reload them here + if (mTextureData) + mTextureData->load(); +} diff --git a/es-core/src/resources/TextureResource.h b/es-core/src/resources/TextureResource.h index 811e71de37..7623e8b1c2 100644 --- a/es-core/src/resources/TextureResource.h +++ b/es-core/src/resources/TextureResource.h @@ -3,8 +3,12 @@ #include "resources/ResourceManager.h" #include +#include +#include #include #include "platform.h" +#include "resources/TextureData.h" +#include "resources/TextureDataManager.h" #include GLHEADER // An OpenGL texture. @@ -12,40 +16,43 @@ class TextureResource : public IReloadable { public: - static std::shared_ptr get(const std::string& path, bool tile = false); + static std::shared_ptr get(const std::string& path, bool tile = false, bool forceLoad = false, bool dynamic = true); + void initFromPixels(const unsigned char* dataRGBA, size_t width, size_t height); + virtual void initFromMemory(const char* file, size_t length); + + // For scalable source images in textures we want to set the resolution to rasterize at + void rasterizeAt(size_t width, size_t height); + Eigen::Vector2f getSourceImageSize() const; virtual ~TextureResource(); - virtual void unload(std::shared_ptr& rm) override; - virtual void reload(std::shared_ptr& rm) override; - bool isInitialized() const; bool isTiled() const; - const Eigen::Vector2i& getSize() const; - void bind() const; - - // Warning: will NOT correctly reinitialize when this texture is reloaded (e.g. ES starts/stops playing a game). - virtual void initFromMemory(const char* file, size_t length); - // Warning: will NOT correctly reinitialize when this texture is reloaded (e.g. ES starts/stops playing a game). - void initFromPixels(const unsigned char* dataRGBA, size_t width, size_t height); + const Eigen::Vector2i getSize() const; + bool bind(); - size_t getMemUsage() const; // returns an approximation of the VRAM used by this texture (in bytes) static size_t getTotalMemUsage(); // returns an approximation of total VRAM used by textures (in bytes) + static size_t getTotalTextureSize(); // returns the number of bytes that would be used if all textures were in memory protected: - TextureResource(const std::string& path, bool tile); - void deinit(); - - Eigen::Vector2i mTextureSize; - const std::string mPath; - const bool mTile; + TextureResource(const std::string& path, bool tile, bool dynamic); + virtual void unload(std::shared_ptr& rm); + virtual void reload(std::shared_ptr& rm); private: - GLuint mTextureID; + // mTextureData is used for textures that are not loaded from a file - these ones + // are permanently allocated and cannot be loaded and unloaded based on resources + std::shared_ptr mTextureData; + + // The texture data manager manages loading and unloading of filesystem based textures + static TextureDataManager sTextureDataManager; + + Eigen::Vector2i mSize; + Eigen::Vector2f mSourceSize; + bool mForceLoad; typedef std::pair TextureKeyType; static std::map< TextureKeyType, std::weak_ptr > sTextureMap; // map of textures, used to prevent duplicate textures - - static std::list< std::weak_ptr > sTextureList; // list of all textures, used for memory approximations + static std::set sAllTextures; // Set of all textures, used for memory management }; From e95eb4eea6fbe9b2357963a7a7d33eba275ab41d Mon Sep 17 00:00:00 2001 From: Jools Wills Date: Thu, 2 Feb 2017 00:20:17 +0000 Subject: [PATCH 52/74] bump version to 2.1.4rp --- es-app/src/EmulationStation.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/es-app/src/EmulationStation.h b/es-app/src/EmulationStation.h index 632d9917e3..213832cc82 100644 --- a/es-app/src/EmulationStation.h +++ b/es-app/src/EmulationStation.h @@ -4,10 +4,10 @@ // Do this version number update as the very last commit for the new release version. #define PROGRAM_VERSION_MAJOR 2 #define PROGRAM_VERSION_MINOR 1 -#define PROGRAM_VERSION_MAINTENANCE 3 -#define PROGRAM_VERSION_STRING "2.1.3rp" +#define PROGRAM_VERSION_MAINTENANCE 4 +#define PROGRAM_VERSION_STRING "2.1.4rp" #define PROGRAM_BUILT_STRING __DATE__ " - " __TIME__ -#define RESOURCE_VERSION_STRING "2,1,3\0" +#define RESOURCE_VERSION_STRING "2,1,4\0" #define RESOURCE_VERSION PROGRAM_VERSION_MAJOR,PROGRAM_VERSION_MINOR,PROGRAM_VERSION_MAINTENANCE From b851f91bd37859b66eba30e0ccf0af562bc82342 Mon Sep 17 00:00:00 2001 From: dirk-de-bugger Date: Sat, 18 Feb 2017 23:35:12 +0100 Subject: [PATCH 53/74] Fix initial text positioning and improve keyboard handling in TextEditComponent --- es-core/src/components/TextEditComponent.cpp | 40 ++++++++++++++++---- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/es-core/src/components/TextEditComponent.cpp b/es-core/src/components/TextEditComponent.cpp index af57991924..c5ff4f75ea 100644 --- a/es-core/src/components/TextEditComponent.cpp +++ b/es-core/src/components/TextEditComponent.cpp @@ -20,7 +20,7 @@ TextEditComponent::TextEditComponent(Window* window) : GuiComponent(window), onFocusLost(); - setSize(256, mFont->getHeight() + TEXT_PADDING_VERT); + setSize(4096, mFont->getHeight() + TEXT_PADDING_VERT); } void TextEditComponent::onFocusGained() @@ -91,15 +91,20 @@ void TextEditComponent::stopEditing() bool TextEditComponent::input(InputConfig* config, Input input) { + bool const cursor_left = (config->getDeviceId() != DEVICE_KEYBOARD && config->isMappedTo("left", input)) || + (config->getDeviceId() == DEVICE_KEYBOARD && input.id == SDLK_LEFT); + bool const cursor_right = (config->getDeviceId() != DEVICE_KEYBOARD && config->isMappedTo("right", input)) || + (config->getDeviceId() == DEVICE_KEYBOARD && input.id == SDLK_RIGHT); + if(input.value == 0) { - if(config->isMappedTo("left", input) || config->isMappedTo("right", input)) + if(cursor_left || cursor_right) mCursorRepeatDir = 0; return false; } - if(config->isMappedTo("a", input) && mFocused && !mEditing) + if((config->isMappedTo("a", input) || (config->getDeviceId() == DEVICE_KEYBOARD && input.id == SDLK_RETURN)) && mFocused && !mEditing) { startEditing(); return true; @@ -125,17 +130,38 @@ bool TextEditComponent::input(InputConfig* config, Input input) return true; } - if(config->isMappedTo("up", input)) + if(config->getDeviceId() != DEVICE_KEYBOARD && config->isMappedTo("up", input)) { // TODO - }else if(config->isMappedTo("down", input)) + }else if(config->getDeviceId() != DEVICE_KEYBOARD && config->isMappedTo("down", input)) { // TODO - }else if(config->isMappedTo("left", input) || config->isMappedTo("right", input)) + }else if(cursor_left || cursor_right) { - mCursorRepeatDir = config->isMappedTo("left", input) ? -1 : 1; + mCursorRepeatDir = cursor_left ? -1 : 1; mCursorRepeatTimer = -(CURSOR_REPEAT_START_DELAY - CURSOR_REPEAT_SPEED); moveCursor(mCursorRepeatDir); + } else if(config->getDeviceId() == DEVICE_KEYBOARD) + { + switch(input.id) + { + case SDLK_HOME: + setCursor(0); + break; + + case SDLK_END: + setCursor(std::string::npos); + break; + + case SDLK_DELETE: + if(mCursor < mText.length()) + { + // Fake as Backspace one char to the right + moveCursor(1); + textInput("\b"); + } + break; + } } //consume all input when editing text From 44f886c961bd32e9a5c75e84a7fdf0945a73a468 Mon Sep 17 00:00:00 2001 From: jrassa Date: Thu, 23 Feb 2017 20:42:35 -0500 Subject: [PATCH 54/74] implement maxSize for videos implement maxSize for videos --- es-core/src/ThemeData.cpp | 1 + es-core/src/components/VideoComponent.cpp | 98 ++++++++++++++++++++--- es-core/src/components/VideoComponent.h | 19 +++++ 3 files changed, 108 insertions(+), 10 deletions(-) diff --git a/es-core/src/ThemeData.cpp b/es-core/src/ThemeData.cpp index 871e7dead0..cd35d06a66 100644 --- a/es-core/src/ThemeData.cpp +++ b/es-core/src/ThemeData.cpp @@ -86,6 +86,7 @@ std::map< std::string, ElementMapType > ThemeData::sElementMap = boost::assign:: ("video", makeMap(boost::assign::map_list_of ("pos", NORMALIZED_PAIR) ("size", NORMALIZED_PAIR) + ("maxSize", NORMALIZED_PAIR) ("origin", NORMALIZED_PAIR) ("default", PATH) ("delay", FLOAT) diff --git a/es-core/src/components/VideoComponent.cpp b/es-core/src/components/VideoComponent.cpp index 6f41ffd786..268a45316d 100644 --- a/es-core/src/components/VideoComponent.cpp +++ b/es-core/src/components/VideoComponent.cpp @@ -39,7 +39,10 @@ VideoComponent::VideoComponent(Window* window) : mVideoWidth(0), mStartDelayed(false), mIsPlaying(false), - mShowing(false) + mShowing(false), + mTargetIsMax(false), + mOrigin(0, 0), + mTargetSize(0, 0) { memset(&mContext, 0, sizeof(mContext)); @@ -69,12 +72,89 @@ void VideoComponent::setOrigin(float originX, float originY) mStaticImage.setOrigin(originX, originY); } +void VideoComponent::setResize(float width, float height) +{ + mTargetSize << width, height; + mTargetIsMax = false; + mStaticImage.setResize(width, height); + resize(); +} + +void VideoComponent::setMaxSize(float width, float height) +{ + mTargetSize << width, height; + mTargetIsMax = true; + mStaticImage.setMaxSize(width, height); + resize(); +} + Eigen::Vector2f VideoComponent::getCenter() const { return Eigen::Vector2f(mPosition.x() - (getSize().x() * mOrigin.x()) + getSize().x() / 2, mPosition.y() - (getSize().y() * mOrigin.y()) + getSize().y() / 2); } +void VideoComponent::resize() +{ + if(!mTexture) + return; + + const Eigen::Vector2f textureSize(mVideoWidth, mVideoHeight); + + if(textureSize.isZero()) + return; + + // SVG rasterization is determined by height (see SVGResource.cpp), and rasterization is done in terms of pixels + // if rounding is off enough in the rasterization step (for images with extreme aspect ratios), it can cause cutoff when the aspect ratio breaks + // so, we always make sure the resultant height is an integer to make sure cutoff doesn't happen, and scale width from that + // (you'll see this scattered throughout the function) + // this is probably not the best way, so if you're familiar with this problem and have a better solution, please make a pull request! + + if(mTargetIsMax) + { + + mSize = textureSize; + + Eigen::Vector2f resizeScale((mTargetSize.x() / mSize.x()), (mTargetSize.y() / mSize.y())); + + if(resizeScale.x() < resizeScale.y()) + { + mSize[0] *= resizeScale.x(); + mSize[1] *= resizeScale.x(); + }else{ + mSize[0] *= resizeScale.y(); + mSize[1] *= resizeScale.y(); + } + + // for SVG rasterization, always calculate width from rounded height (see comment above) + mSize[1] = round(mSize[1]); + mSize[0] = (mSize[1] / textureSize.y()) * textureSize.x(); + + }else{ + // if both components are set, we just stretch + // if no components are set, we don't resize at all + mSize = mTargetSize.isZero() ? textureSize : mTargetSize; + + // if only one component is set, we resize in a way that maintains aspect ratio + // for SVG rasterization, we always calculate width from rounded height (see comment above) + if(!mTargetSize.x() && mTargetSize.y()) + { + mSize[1] = round(mTargetSize.y()); + mSize[0] = (mSize.y() / textureSize.y()) * textureSize.x(); + }else if(mTargetSize.x() && !mTargetSize.y()) + { + mSize[1] = round((mTargetSize.x() / textureSize.x()) * textureSize.y()); + mSize[0] = (mSize.y() / textureSize.y()) * textureSize.x(); + } + } + + // mSize.y() should already be rounded + mTexture->rasterizeAt((int)round(mSize.x()), (int)round(mSize.y())); + + onSizeChanged(); +} + + void VideoComponent::onSizeChanged() { // Update the embeded static image @@ -111,8 +191,6 @@ void VideoComponent::setImage(std::string path) return; mStaticImage.setImage(path); - // Make the image stretch to fill the video region - mStaticImage.setSize(getSize()); mFadeIn = 0.0f; mStaticImagePath = path; } @@ -243,11 +321,15 @@ void VideoComponent::applyTheme(const std::shared_ptr& theme, const s { Eigen::Vector2f denormalized = elem->get("pos").cwiseProduct(scale); setPosition(Eigen::Vector3f(denormalized.x(), denormalized.y(), 0)); + mStaticImage.setPosition(Eigen::Vector3f(denormalized.x(), denormalized.y(), 0)); } - if ((properties & ThemeFlags::SIZE) && elem->has("size")) + if(properties & ThemeFlags::SIZE) { - setSize(elem->get("size").cwiseProduct(scale)); + if(elem->has("size")) + setResize(elem->get("size").cwiseProduct(scale)); + else if(elem->has("maxSize")) + setMaxSize(elem->get("maxSize").cwiseProduct(scale)); } // position + size also implies origin @@ -265,11 +347,6 @@ void VideoComponent::applyTheme(const std::shared_ptr& theme, const s if (elem->has("showSnapshotDelay")) mConfig.showSnapshotDelay = elem->get("showSnapshotDelay"); - - // Update the embeded static image - mStaticImage.setPosition(getPosition()); - mStaticImage.setMaxSize(getSize()); - mStaticImage.setSize(getSize()); } std::vector VideoComponent::getHelpPrompts() @@ -287,6 +364,7 @@ void VideoComponent::setupContext() mContext.surface = SDL_CreateRGBSurface(SDL_SWSURFACE, (int)mVideoWidth, (int)mVideoHeight, 32, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff); mContext.mutex = SDL_CreateMutex(); mContext.valid = true; + resize(); } } diff --git a/es-core/src/components/VideoComponent.h b/es-core/src/components/VideoComponent.h index f8376cfe90..14179defa3 100644 --- a/es-core/src/components/VideoComponent.h +++ b/es-core/src/components/VideoComponent.h @@ -55,6 +55,19 @@ class VideoComponent : public GuiComponent void onSizeChanged() override; void setOpacity(unsigned char opacity) override; + // Resize the video to fit this size. If one axis is zero, scale that axis to maintain aspect ratio. + // If both are non-zero, potentially break the aspect ratio. If both are zero, no resizing. + // Can be set before or after a video is loaded. + // setMaxSize() and setResize() are mutually exclusive. + void setResize(float width, float height); + inline void setResize(const Eigen::Vector2f& size) { setResize(size.x(), size.y()); } + + // Resize the video to be as large as possible but fit within a box of this size. + // Can be set before or after a video is loaded. + // Never breaks the aspect ratio. setMaxSize() and setResize() are mutually exclusive. + void setMaxSize(float width, float height); + inline void setMaxSize(const Eigen::Vector2f& size) { setMaxSize(size.x(), size.y()); } + void render(const Eigen::Affine3f& parentTrans) override; virtual void applyTheme(const std::shared_ptr& theme, const std::string& view, const std::string& element, unsigned int properties) override; @@ -67,6 +80,10 @@ class VideoComponent : public GuiComponent virtual void update(int deltaTime); private: + // Calculates the correct mSize from our resizing information (set by setResize/setMaxSize). + // Used internally whenever the resizing parameters or texture change. + void resize(); + // Start the video Immediately void startVideo(); // Start the video after any configured delay @@ -94,6 +111,7 @@ class VideoComponent : public GuiComponent unsigned mVideoWidth; unsigned mVideoHeight; Eigen::Vector2f mOrigin; + Eigen::Vector2f mTargetSize; std::shared_ptr mTexture; float mFadeIn; std::string mStaticImagePath; @@ -105,6 +123,7 @@ class VideoComponent : public GuiComponent unsigned mStartTime; bool mIsPlaying; bool mShowing; + bool mTargetIsMax; Configuration mConfig; }; From e2374271f2919b77cb04c0d15569e5e47529d8e4 Mon Sep 17 00:00:00 2001 From: jrassa Date: Fri, 24 Feb 2017 23:19:29 -0500 Subject: [PATCH 55/74] don't enable video view if current theme doesn't support it --- es-app/src/views/ViewController.cpp | 4 +++- es-core/src/ThemeData.cpp | 5 +++++ es-core/src/ThemeData.h | 2 ++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/es-app/src/views/ViewController.cpp b/es-app/src/views/ViewController.cpp index d9093e8e10..ce29025e05 100644 --- a/es-app/src/views/ViewController.cpp +++ b/es-app/src/views/ViewController.cpp @@ -228,13 +228,15 @@ std::shared_ptr ViewController::getGameListView(SystemData* syste //if we didn't, make it, remember it, and return it std::shared_ptr view; + bool themeHasVideoView = system->getTheme()->hasView("video"); + //decide type bool detailed = false; bool video = false; std::vector files = system->getRootFolder()->getFilesRecursive(GAME | FOLDER); for(auto it = files.begin(); it != files.end(); it++) { - if(!(*it)->getVideoPath().empty()) + if(themeHasVideoView && !(*it)->getVideoPath().empty()) { video = true; break; diff --git a/es-core/src/ThemeData.cpp b/es-core/src/ThemeData.cpp index 871e7dead0..9ed9e093e5 100644 --- a/es-core/src/ThemeData.cpp +++ b/es-core/src/ThemeData.cpp @@ -343,6 +343,11 @@ void ThemeData::parseElement(const pugi::xml_node& root, const std::map Date: Fri, 3 Mar 2017 21:34:57 +0000 Subject: [PATCH 56/74] Update GamesDBScraper.cpp Fixes platform name for Neo Geo so that the scraper works --- es-app/src/scrapers/GamesDBScraper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/es-app/src/scrapers/GamesDBScraper.cpp b/es-app/src/scrapers/GamesDBScraper.cpp index ea78e374e1..74ecc37b75 100644 --- a/es-app/src/scrapers/GamesDBScraper.cpp +++ b/es-app/src/scrapers/GamesDBScraper.cpp @@ -29,7 +29,7 @@ const std::map gamesdb_platformid_map = boost::assign:: (XBOX, "Microsoft Xbox") (XBOX_360, "Microsoft Xbox 360") // missing MSX - (NEOGEO, "NeoGeo") + (NEOGEO, "Neo Geo") (NEOGEO_POCKET, "Neo Geo Pocket") (NEOGEO_POCKET_COLOR, "Neo Geo Pocket Color") (NINTENDO_3DS, "Nintendo 3DS") From 25960c4505251e2dfd36088db13f8b66ad9a242c Mon Sep 17 00:00:00 2001 From: John Rassa Date: Tue, 7 Mar 2017 15:01:30 -0500 Subject: [PATCH 57/74] add video documentation add documentation for video view and video element. --- THEMES.md | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/THEMES.md b/THEMES.md index d4a2bdd63f..a8a111fa13 100644 --- a/THEMES.md +++ b/THEMES.md @@ -332,6 +332,57 @@ Reference * `text name="md_description"` - POSITION | SIZE | FONT_PATH | FONT_SIZE | COLOR - Text is the "desc" metadata. If no `pos`/`size` is specified, will move and resize to fit under the lowest label and reach to the bottom of the screen. +#### video +* `helpsystem name="help"` - ALL + - The help system style for this view. +* `image name="background"` - ALL + - This is a background image that exists for convenience. It goes from (0, 0) to (1, 1). +* `text name="logoText"` - ALL + - Displays the name of the system. Only present if no "logo" image is specified. Displayed at the top of the screen, centered by default. +* `image name="logo"` - ALL + - A header image. If a non-empty `path` is specified, `text name="headerText"` will be hidden and this image will be, by default, displayed roughly in its place. +* `textlist name="gamelist"` - ALL + - The gamelist. `primaryColor` is for games, `secondaryColor` is for folders. Left aligned by default. + +* Metadata + * Labels + * `text name="md_lbl_rating"` - ALL + * `text name="md_lbl_releasedate"` - ALL + * `text name="md_lbl_developer"` - ALL + * `text name="md_lbl_publisher"` - ALL + * `text name="md_lbl_genre"` - ALL + * `text name="md_lbl_players"` - ALL + * `text name="md_lbl_lastplayed"` - ALL + * `text name="md_lbl_playcount"` - ALL + + * Values + * All values will follow to the right of their labels if a position isn't specified. + + * `image name="md_image"` - POSITION | SIZE + - Path is the "image" metadata for the currently selected game. + * `image name="md_marquee"` - POSITION | SIZE + - Path is the "marquee" metadata for the currently selected game. + * `video name="md_video"` - POSITION | SIZE + - Path is the "video" metadata for the currently selected game. + * `rating name="md_rating"` - ALL + - The "rating" metadata. + * `datetime name="md_releasedate"` - ALL + - The "releasedate" metadata. + * `text name="md_developer"` - ALL + - The "developer" metadata. + * `text name="md_publisher"` - ALL + - The "publisher" metadata. + * `text name="md_genre"` - ALL + - The "genre" metadata. + * `text name="md_players"` - ALL + - The "players" metadata (number of players the game supports). + * `datetime name="md_lastplayed"` - ALL + - The "lastplayed" metadata. Displayed as a string representing the time relative to "now" (e.g. "3 hours ago"). + * `text name="md_playcount"` - ALL + - The "playcount" metadata (number of times the game has been played). + * `text name="md_description"` - POSITION | SIZE | FONT_PATH | FONT_SIZE | COLOR + - Text is the "desc" metadata. If no `pos`/`size` is specified, will move and resize to fit under the lowest label and reach to the bottom of the screen. + --- #### grid @@ -389,6 +440,21 @@ Can be created as an extra. - If true, the image will be tiled instead of stretched to fit its size. Useful for backgrounds. * `color` - type: COLOR. - Multiply each pixel's color by this color. For example, an all-white image with `FF0000` would become completely red. You can also control the transparency of an image with `FFFFFFAA` - keeping all the pixels their normal color and only affecting the alpha channel. + +#### video + +* `pos` - type: NORMALIZED_PAIR. +* `size` - type: NORMALIZED_PAIR. +* `origin` - type: NORMALIZED_PAIR. + - Where on the image `pos` refers to. For example, an origin of `0.5 0.5` and a `pos` of `0.5 0.5` would place the image exactly in the middle of the screen. If the "POSITION" and "SIZE" attributes are themable, "ORIGIN" is implied. +* `delay` - type: FLOAT. Default is false. + - Delay in seconds before video will start playing. +* `default` - type: PATH. + - Path to default video file. Default video will be played when selected game does not have a video. +* `showSnapshotNoVideo` - type: BOOLEAN + - If true, image will be shown when selected game does not have a video and no `default` video is configured. +* `showSnapshotDelay` - type: BOOLEAN + - If true, playing of video will be delayed for `delayed` seconds, when game is selected. #### text From 49940d62d78b2b9601402b22107f9ab79176f70b Mon Sep 17 00:00:00 2001 From: John Rassa Date: Fri, 10 Mar 2017 13:49:15 -0500 Subject: [PATCH 58/74] =?UTF-8?q?implemented=20feature=20element=20to=20al?= =?UTF-8?q?low=20themes=20to=20support=20new=20features=20w=E2=80=A6=20(#9?= =?UTF-8?q?6)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * implemented feature element to allow themes to support new features without breaking older versions of ES * supported attribute should only allow one value --- es-core/src/ThemeData.cpp | 31 +++++++++++++++++++++++++++++-- es-core/src/ThemeData.h | 3 +++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/es-core/src/ThemeData.cpp b/es-core/src/ThemeData.cpp index 9ed9e093e5..e216633e4b 100644 --- a/es-core/src/ThemeData.cpp +++ b/es-core/src/ThemeData.cpp @@ -23,6 +23,9 @@ ElementMapType makeMap(const T& mapInit) return m; } +std::vector ThemeData::sSupportedViews = boost::assign::list_of("system")("basic")("detailed")("video"); +std::vector ThemeData::sSupportedFeatures = boost::assign::list_of("video"); + std::map< std::string, ElementMapType > ThemeData::sElementMap = boost::assign::map_list_of ("image", makeMap(boost::assign::map_list_of ("pos", NORMALIZED_PAIR) @@ -181,6 +184,7 @@ void ThemeData::loadFile(const std::string& path) parseIncludes(root); parseViews(root); + parseFeatures(root); } @@ -211,11 +215,31 @@ void ThemeData::parseIncludes(const pugi::xml_node& root) parseIncludes(root); parseViews(root); + parseFeatures(root); mPaths.pop_back(); } } +void ThemeData::parseFeatures(const pugi::xml_node& root) +{ + ThemeException error; + error.setFiles(mPaths); + + for(pugi::xml_node node = root.child("feature"); node; node = node.next_sibling("feature")) + { + if(!node.attribute("supported")) + throw error << "Feature missing \"supported\" attribute!"; + + const std::string supportedAttr = node.attribute("supported").as_string(); + + if (std::find(sSupportedFeatures.begin(), sSupportedFeatures.end(), supportedAttr) != sSupportedFeatures.end()) + { + parseViews(node); + } + } +} + void ThemeData::parseViews(const pugi::xml_node& root) { ThemeException error; @@ -238,8 +262,11 @@ void ThemeData::parseViews(const pugi::xml_node& root) prevOff = nameAttr.find_first_not_of(delim, off); off = nameAttr.find_first_of(delim, prevOff); - ThemeView& view = mViews.insert(std::pair(viewKey, ThemeView())).first->second; - parseView(node, view); + if (std::find(sSupportedViews.begin(), sSupportedViews.end(), viewKey) != sSupportedViews.end()) + { + ThemeView& view = mViews.insert(std::pair(viewKey, ThemeView())).first->second; + parseView(node, view); + } } } } diff --git a/es-core/src/ThemeData.h b/es-core/src/ThemeData.h index 408d0c52c3..082b736849 100644 --- a/es-core/src/ThemeData.h +++ b/es-core/src/ThemeData.h @@ -149,10 +149,13 @@ class ThemeData private: static std::map< std::string, std::map > sElementMap; + static std::vector sSupportedFeatures; + static std::vector sSupportedViews; std::deque mPaths; float mVersion; + void parseFeatures(const pugi::xml_node& themeRoot); void parseIncludes(const pugi::xml_node& themeRoot); void parseViews(const pugi::xml_node& themeRoot); void parseView(const pugi::xml_node& viewNode, ThemeView& view); From baa4e2590db418c345e53a42e70be24a29805104 Mon Sep 17 00:00:00 2001 From: Jools Wills Date: Mon, 13 Mar 2017 18:16:57 +0000 Subject: [PATCH 59/74] make jump to letter move to first occurrence of the letter --- es-app/src/guis/GuiGamelistOptions.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/es-app/src/guis/GuiGamelistOptions.cpp b/es-app/src/guis/GuiGamelistOptions.cpp index 1c8948cc5b..cb8f45d68b 100644 --- a/es-app/src/guis/GuiGamelistOptions.cpp +++ b/es-app/src/guis/GuiGamelistOptions.cpp @@ -104,7 +104,7 @@ void GuiGamelistOptions::jumpToLetter() if(checkLetter < letter) min = mid + 1; - else if(checkLetter > letter) + else if(checkLetter > letter || (mid > 0 && (letter == toupper(files.at(mid - 1)->getName()[0])))) max = mid - 1; else break; //exact match found From cdc189021210aa62b1f656c2f5bf5991e684e693 Mon Sep 17 00:00:00 2001 From: Jools Wills Date: Mon, 13 Mar 2017 18:19:51 +0000 Subject: [PATCH 60/74] bump to version 2.1.5 --- es-app/src/EmulationStation.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/es-app/src/EmulationStation.h b/es-app/src/EmulationStation.h index 213832cc82..0c6b1dddc4 100644 --- a/es-app/src/EmulationStation.h +++ b/es-app/src/EmulationStation.h @@ -4,10 +4,10 @@ // Do this version number update as the very last commit for the new release version. #define PROGRAM_VERSION_MAJOR 2 #define PROGRAM_VERSION_MINOR 1 -#define PROGRAM_VERSION_MAINTENANCE 4 -#define PROGRAM_VERSION_STRING "2.1.4rp" +#define PROGRAM_VERSION_MAINTENANCE 5 +#define PROGRAM_VERSION_STRING "2.1.5rp" #define PROGRAM_BUILT_STRING __DATE__ " - " __TIME__ -#define RESOURCE_VERSION_STRING "2,1,4\0" +#define RESOURCE_VERSION_STRING "2,1,5\0" #define RESOURCE_VERSION PROGRAM_VERSION_MAJOR,PROGRAM_VERSION_MINOR,PROGRAM_VERSION_MAINTENANCE From 867db8ac9cb1d9611300b038f4a07b616cd0042a Mon Sep 17 00:00:00 2001 From: John Rassa Date: Tue, 14 Mar 2017 10:01:39 -0400 Subject: [PATCH 61/74] add maxSize documentation for video --- THEMES.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/THEMES.md b/THEMES.md index a8a111fa13..a321229fa5 100644 --- a/THEMES.md +++ b/THEMES.md @@ -445,6 +445,9 @@ Can be created as an extra. * `pos` - type: NORMALIZED_PAIR. * `size` - type: NORMALIZED_PAIR. + - If only one axis is specified (and the other is zero), the other will be automatically calculated in accordance with the video's aspect ratio. +* `maxSize` - type: NORMALIZED_PAIR. + - The video will be resized as large as possible so that it fits within this size and maintains its aspect ratio. Use this instead of `size` when you don't know what kind of video you're using so it doesn't get grossly oversized on one axis (e.g. with a game's video metadata). * `origin` - type: NORMALIZED_PAIR. - Where on the image `pos` refers to. For example, an origin of `0.5 0.5` and a `pos` of `0.5 0.5` would place the image exactly in the middle of the screen. If the "POSITION" and "SIZE" attributes are themable, "ORIGIN" is implied. * `delay` - type: FLOAT. Default is false. From 6cb81ab1af8889c965dafc21ba9cef7c39ac20fb Mon Sep 17 00:00:00 2001 From: "D. Polders" Date: Thu, 17 Nov 2016 21:37:44 +0100 Subject: [PATCH 62/74] Small changes to facilitate building on Windows platform using VS2015 --- .gitignore | 3 +++ CMakeLists.txt | 9 +++++++++ es-core/src/Util.cpp | 5 +++++ es-core/src/platform.cpp | 6 ++++++ 4 files changed, 23 insertions(+) diff --git a/.gitignore b/.gitignore index 0686c4180e..685ee8c426 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,6 @@ Makefile .cproject .project .settings/ + +# WinMerge +.bak \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 261215014f..d15b4303eb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -47,7 +47,11 @@ endif() find_package(Freetype REQUIRED) find_package(FreeImage REQUIRED) find_package(SDL2 REQUIRED) +if(MSVC) +find_package(Boost REQUIRED COMPONENTS system date_time locale) +else() find_package(Boost REQUIRED COMPONENTS system filesystem date_time locale) +endif() find_package(Eigen3 REQUIRED) find_package(CURL REQUIRED) find_package(VLC REQUIRED) @@ -81,9 +85,14 @@ if(CMAKE_COMPILER_IS_GNUCXX) endif() #set up compiler flags for GCC +if (CMAKE_BUILD_TYPE MATCHES Debug) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wno-attributes -O0") #support C++11 for std::, optimize + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -O0") +else() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wno-attributes -O3") #support C++11 for std::, optimize set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -O3") #-s = strip binary endif() +endif() if(${GLSystem} MATCHES "Desktop OpenGL") add_definitions(-DUSE_OPENGL_DESKTOP) diff --git a/es-core/src/Util.cpp b/es-core/src/Util.cpp index 34be52494c..8d88104252 100644 --- a/es-core/src/Util.cpp +++ b/es-core/src/Util.cpp @@ -102,8 +102,13 @@ fs::path resolvePath(const fs::path& path, const fs::path& relativeTo, bool allo fs::path removeCommonPathUsingStrings(const fs::path& path, const fs::path& relativeTo, bool& contains) { +#ifdef WIN32 + std::wstring pathStr = path.c_str(); + std::wstring relativeToStr = relativeTo.c_str(); +#else std::string pathStr = path.c_str(); std::string relativeToStr = relativeTo.c_str(); +#endif if (pathStr.find_first_of(relativeToStr) == 0) { contains = true; return pathStr.substr(relativeToStr.size() + 1); diff --git a/es-core/src/platform.cpp b/es-core/src/platform.cpp index 31127a9cab..04d02b98f6 100644 --- a/es-core/src/platform.cpp +++ b/es-core/src/platform.cpp @@ -84,7 +84,13 @@ int quitES(const std::string& filename) void touch(const std::string& filename) { +#ifdef WIN32 + FILE* fp = fopen(filename.c_str(), "ab+"); + if (fp != NULL) + fclose(fp); +#else int fd = open(filename.c_str(), O_CREAT|O_WRONLY, 0644); if (fd >= 0) close(fd); +#endif } \ No newline at end of file From ac5e3ad95f34ac52bc925d618f37fe9b1717b42b Mon Sep 17 00:00:00 2001 From: "D. Polders" Date: Mon, 13 Mar 2017 22:11:07 +0100 Subject: [PATCH 63/74] System Carousel feature, now with only a single commit! --- .gitignore | 3 - CMakeLists.txt | 2 +- THEMES.md | 23 ++ es-app/src/views/SystemView.cpp | 294 ++++++++++++++++------- es-app/src/views/SystemView.h | 32 ++- es-app/src/views/ViewController.cpp | 2 +- es-core/src/ThemeData.cpp | 20 +- es-core/src/components/TextComponent.cpp | 55 +++-- es-core/src/components/TextComponent.h | 7 +- 9 files changed, 315 insertions(+), 123 deletions(-) diff --git a/.gitignore b/.gitignore index 685ee8c426..0686c4180e 100644 --- a/.gitignore +++ b/.gitignore @@ -34,6 +34,3 @@ Makefile .cproject .project .settings/ - -# WinMerge -.bak \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index d15b4303eb..1b98f16216 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -86,7 +86,7 @@ if(CMAKE_COMPILER_IS_GNUCXX) #set up compiler flags for GCC if (CMAKE_BUILD_TYPE MATCHES Debug) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wno-attributes -O0") #support C++11 for std::, optimize + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wno-attributes -O0") #support C++11 for std::, optimize set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -O0") else() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wno-attributes -O3") #support C++11 for std::, optimize diff --git a/THEMES.md b/THEMES.md index a8a111fa13..1c518dafd5 100644 --- a/THEMES.md +++ b/THEMES.md @@ -400,8 +400,12 @@ Reference #### system * `helpsystem name="help"` - ALL - The help system style for this view. +* `carousel name="systemcarousel"` -ALL + - The system logo carousel * `image name="logo"` - PATH - A logo image, to be displayed in the system logo carousel. +* `text name="systemInfo"` - ALL + - Displays details of the system currently selected in the carousel. * You can use extra elements (elements with `extra="true"`) to add your own backgrounds, etc. They will be displayed behind the carousel, and scroll relative to the carousel. @@ -468,6 +472,7 @@ Can be created as an extra. - `w h` - works like a "text box." If `h` is non-zero and `h` <= `fontSize` (implying it should be a single line of text), text that goes beyond `w` will be truncated with an elipses (...). * `text` - type: STRING. * `color` - type: COLOR. +* `backgroundColor` - type: COLOR; * `fontPath` - type: PATH. - Path to a truetype font (.ttf). * `fontSize` - type: FLOAT. @@ -541,6 +546,24 @@ EmulationStation borrows the concept of "nine patches" from Android (or "9-Slice * `fontPath` - type: PATH. * `fontSize` - type: FLOAT. +#### carousel + +* `type` - type: STRING. + * Accepted values are "HORIZONTAL" or "VERTICAL". Sets the scoll direction of the carousel. + * Default is "HORIZONTAL". +* `size` - type: NORMALIZED_PAIR. Default is "1 0.2325" +* `pos` - type: NORMALIZED_PAIR. Default is "0 0.38375". +* `color` - type: COLOR. + * Controls the color of the carousel background. + * Default is FFFFFFD8 +* `logoSize` - type: NORMALIZED_PAIR. Default is "0.25 0.155" +* `logoScale` - type: FLOAT. + * Selected logo is increased in size by this scale + * Default is 1.5 +* `maxLogoCount` - type: FLOAT. + * Sets the number of logos to display in the carousel. + * Default is 3 + The help system is a special element that displays a context-sensitive list of actions the user can take at any time. You should try and keep the position constant throughout every screen. Keep in mind the "default" settings (including position) are used whenever the user opens a menu. [*Check out the "official" themes for some more examples!*](http://aloshi.com/emulationstation#themes) diff --git a/es-app/src/views/SystemView.cpp b/es-app/src/views/SystemView.cpp index c760125b97..272d4c6342 100644 --- a/es-app/src/views/SystemView.cpp +++ b/es-app/src/views/SystemView.cpp @@ -9,22 +9,15 @@ #include "Settings.h" #include "Util.h" -#define SELECTED_SCALE 1.5f -#define LOGO_PADDING ((logoSize().x() * (SELECTED_SCALE - 1)/2) + (mSize.x() * 0.06f)) -#define BAND_HEIGHT (logoSize().y() * SELECTED_SCALE) - SystemView::SystemView(Window* window) : IList(window, LIST_SCROLL_STYLE_SLOW, LIST_ALWAYS_LOOP), - mSystemInfo(window, "SYSTEM INFO", Font::get(FONT_SIZE_SMALL), 0x33333300, ALIGN_CENTER) + mViewNeedsReload(true), + mSystemInfo(window, "SYSTEM INFO", Font::get(FONT_SIZE_SMALL), 0x33333300, ALIGN_CENTER) { mCamOffset = 0; mExtrasCamOffset = 0; mExtrasFadeOpacity = 0.0f; setSize((float)Renderer::getScreenWidth(), (float)Renderer::getScreenHeight()); - - mSystemInfo.setSize(mSize.x(), mSystemInfo.getSize().y() * 1.333f); - mSystemInfo.setPosition(0, (mSize.y() + BAND_HEIGHT) / 2); - populate(); } @@ -36,6 +29,9 @@ void SystemView::populate() { const std::shared_ptr& theme = (*it)->getTheme(); + if(mViewNeedsReload) + getViewElements(theme); + Entry e; e.name = (*it)->getName(); e.object = *it; @@ -43,18 +39,20 @@ void SystemView::populate() // make logo if(theme->getElement("system", "logo", "image")) { - ImageComponent* logo = new ImageComponent(mWindow, false, false); - logo->setMaxSize(Eigen::Vector2f(logoSize().x(), logoSize().y())); + ImageComponent* logo = new ImageComponent(mWindow); + logo->setMaxSize(Eigen::Vector2f(mCarousel.logoSize.x(), mCarousel.logoSize.y())); logo->applyTheme((*it)->getTheme(), "system", "logo", ThemeFlags::PATH); - logo->setPosition((logoSize().x() - logo->getSize().x()) / 2, (logoSize().y() - logo->getSize().y()) / 2); // center + logo->setPosition((mCarousel.logoSize.x() - logo->getSize().x()) / 2, + (mCarousel.logoSize.y() - logo->getSize().y()) / 2); // center e.data.logo = std::shared_ptr(logo); - ImageComponent* logoSelected = new ImageComponent(mWindow, false, false); - logoSelected->setMaxSize(Eigen::Vector2f(logoSize().x() * SELECTED_SCALE, logoSize().y() * SELECTED_SCALE * 0.70f)); - logoSelected->applyTheme((*it)->getTheme(), "system", "logo", ThemeFlags::PATH); - logoSelected->setPosition((logoSize().x() - logoSelected->getSize().x()) / 2, - (logoSize().y() - logoSelected->getSize().y()) / 2); // center + ImageComponent* logoSelected = new ImageComponent(mWindow); + logoSelected->setMaxSize(Eigen::Vector2f(mCarousel.logoSize.x() * mCarousel.logoScale, mCarousel.logoSize.y() * mCarousel.logoScale)); + logoSelected->applyTheme((*it)->getTheme(), "system", "logo", ThemeFlags::PATH | ThemeFlags::COLOR); + logoSelected->setPosition((mCarousel.logoSize.x() - logoSelected->getSize().x()) / 2, + (mCarousel.logoSize.y() - logoSelected->getSize().y()) / 2); // center e.data.logoSelected = std::shared_ptr(logoSelected); + }else{ // no logo in theme; use text TextComponent* text = new TextComponent(mWindow, @@ -62,15 +60,15 @@ void SystemView::populate() Font::get(FONT_SIZE_LARGE), 0x000000FF, ALIGN_CENTER); - text->setSize(logoSize()); + text->setSize(mCarousel.logoSize); e.data.logo = std::shared_ptr(text); TextComponent* textSelected = new TextComponent(mWindow, (*it)->getName(), - Font::get((int)(FONT_SIZE_LARGE * SELECTED_SCALE)), + Font::get((int)(FONT_SIZE_LARGE * 1.5)), 0x000000FF, ALIGN_CENTER); - textSelected->setSize(logoSize()); + textSelected->setSize(mCarousel.logoSize); e.data.logoSelected = std::shared_ptr(textSelected); } @@ -96,26 +94,40 @@ bool SystemView::input(InputConfig* config, Input input) { if(config->getDeviceId() == DEVICE_KEYBOARD && input.value && input.id == SDLK_r && SDL_GetModState() & KMOD_LCTRL && Settings::getInstance()->getBool("Debug")) { - LOG(LogInfo) << " Reloading SystemList view"; - - // reload themes - for(auto it = mEntries.begin(); it != mEntries.end(); it++) - it->object->loadTheme(); - - populate(); - updateHelpPrompts(); + LOG(LogInfo) << " Reloading all"; + ViewController::get()->reloadAll(); return true; } - if(config->isMappedTo("left", input)) - { - listInput(-1); - return true; - } - if(config->isMappedTo("right", input)) + + switch (mCarousel.type) { - listInput(1); - return true; + case VERTICAL: + if (config->isMappedTo("up", input)) + { + listInput(-1); + return true; + } + if (config->isMappedTo("down", input)) + { + listInput(1); + return true; + } + break; + case HORIZONTAL: + default: + if (config->isMappedTo("left", input)) + { + listInput(-1); + return true; + } + if (config->isMappedTo("right", input)) + { + listInput(1); + return true; + } + break; } + if(config->isMappedTo("a", input)) { stopScrolling(); @@ -123,7 +135,10 @@ bool SystemView::input(InputConfig* config, Input input) return true; } }else{ - if(config->isMappedTo("left", input) || config->isMappedTo("right", input)) + if(config->isMappedTo("left", input) || + config->isMappedTo("right", input) || + config->isMappedTo("up", input) || + config->isMappedTo("down", input)) listInput(0); } @@ -254,94 +269,191 @@ void SystemView::onCursorChanged(const CursorState& state) void SystemView::render(const Eigen::Affine3f& parentTrans) { if(size() == 0) - return; - - Eigen::Affine3f trans = getTransform() * parentTrans; + return; // nothing to render - // draw the list elements (titles, backgrounds, logos) - const float logoSizeX = logoSize().x() + LOGO_PADDING; + Eigen::Affine3f trans = getTransform() * parentTrans; - int logoCount = (int)(mSize.x() / logoSizeX) + 2; // how many logos we need to draw - int center = (int)(mCamOffset); + renderExtras(trans); + renderCarousel(trans); + renderInfoBar(trans); +} - if(mEntries.size() == 1) - logoCount = 1; +std::vector SystemView::getHelpPrompts() +{ + std::vector prompts; + if (mCarousel.type == VERTICAL) + prompts.push_back(HelpPrompt("up/down", "choose")); + else + prompts.push_back(HelpPrompt("left/right", "choose")); + prompts.push_back(HelpPrompt("a", "select")); + return prompts; +} - // draw background extras - Eigen::Affine3f extrasTrans = trans; - int extrasCenter = (int)mExtrasCamOffset; - for(int i = extrasCenter - 1; i < extrasCenter + 2; i++) - { - int index = i; - while(index < 0) - index += mEntries.size(); - while(index >= (int)mEntries.size()) - index -= mEntries.size(); +HelpStyle SystemView::getHelpStyle() +{ + HelpStyle style; + style.applyTheme(mEntries.at(mCursor).object->getTheme(), "system"); + return style; +} - extrasTrans.translation() = trans.translation() + Eigen::Vector3f((i - mExtrasCamOffset) * mSize.x(), 0, 0); +void SystemView::onThemeChanged(const std::shared_ptr& theme) +{ + LOG(LogDebug) << "SystemView::onThemeChanged()"; + mViewNeedsReload = true; + populate(); +} - Eigen::Vector2i clipRect = Eigen::Vector2i((int)((i - mExtrasCamOffset) * mSize.x()), 0); - Renderer::pushClipRect(clipRect, mSize.cast()); - mEntries.at(index).data.backgroundExtras->render(extrasTrans); - Renderer::popClipRect(); - } +// Get the ThemeElements that make up the SystemView. +void SystemView::getViewElements(const std::shared_ptr& theme) +{ + LOG(LogDebug) << "SystemView::getViewElements()"; - // fade extras if necessary - if(mExtrasFadeOpacity) - { - Renderer::setMatrix(trans); - Renderer::drawRect(0.0f, 0.0f, mSize.x(), mSize.y(), 0x00000000 | (unsigned char)(mExtrasFadeOpacity * 255)); - } + getDefaultElements(); - // draw logos - float xOff = (mSize.x() - logoSize().x())/2 - (mCamOffset * logoSizeX); - float yOff = (mSize.y() - logoSize().y())/2; + const ThemeData::ThemeElement* carouselElem = theme->getElement("system", "systemcarousel", "carousel"); + if (carouselElem) + getCarouselFromTheme(carouselElem); + + const ThemeData::ThemeElement* sysInfoElem = theme->getElement("system", "systemInfo", "text"); + if (sysInfoElem) + mSystemInfo.applyTheme(theme, "system", "systemInfo", ThemeFlags::ALL); + + mViewNeedsReload = false; +} + +// Render system carousel +void SystemView::renderCarousel(const Eigen::Affine3f& trans) +{ + Eigen::Vector2i clipPos((int)mCarousel.pos.x(), (int)mCarousel.pos.y()); + Eigen::Vector2i clipSize((int)mCarousel.size.x(), (int)mCarousel.size.y()); - // background behind the logos + Renderer::pushClipRect(clipPos, clipSize); + + // background box behind logos Renderer::setMatrix(trans); - Renderer::drawRect(0.f, (mSize.y() - BAND_HEIGHT) / 2, mSize.x(), BAND_HEIGHT, 0xFFFFFFD8); + Renderer::drawRect(mCarousel.pos.x(), mCarousel.pos.y(), mCarousel.size.x(), mCarousel.size.y(), mCarousel.color); + + // draw logos + Eigen::Vector2f logoSpacing(0.0, 0.0); // NB: logoSpacing will include the size of the logo itself as well! + float xOff = 0.0; + float yOff = 0.0; + + switch (mCarousel.type) + { + case VERTICAL: + logoSpacing[1] = ((mCarousel.size.y() - (mCarousel.logoSize.y() * mCarousel.maxLogoCount)) / (mCarousel.maxLogoCount)) + mCarousel.logoSize.y(); + xOff = mCarousel.pos.x() + (mCarousel.size.x() / 2) - (mCarousel.logoSize.x() / 2); + yOff = mCarousel.pos.y() + (mCarousel.size.y() - mCarousel.logoSize.y()) / 2 - (mCamOffset * logoSpacing[1]); + break; + case HORIZONTAL: + default: + logoSpacing[0] = ((mCarousel.size.x() - (mCarousel.logoSize.x() * mCarousel.maxLogoCount)) / (mCarousel.maxLogoCount)) + mCarousel.logoSize.x(); + xOff = mCarousel.pos.x() + (mCarousel.size.x() - mCarousel.logoSize.x()) / 2 - (mCamOffset * logoSpacing[0]); + yOff = mCarousel.pos.y() + (mCarousel.size.y() / 2) - (mCarousel.logoSize.y() / 2); + break; + } Eigen::Affine3f logoTrans = trans; - for(int i = center - logoCount/2; i < center + logoCount/2 + 1; i++) + int center = (int)(mCamOffset); + int logoCount = std::min(mCarousel.maxLogoCount, (int)mEntries.size()) + 2; + + for (int i = center - logoCount / 2; i < center + logoCount / 2 + 1; i++) { int index = i; - while(index < 0) + while (index < 0) index += mEntries.size(); - while(index >= (int)mEntries.size()) + while (index >= (int)mEntries.size()) index -= mEntries.size(); - logoTrans.translation() = trans.translation() + Eigen::Vector3f(i * logoSizeX + xOff, yOff, 0); + logoTrans.translation() = trans.translation() + Eigen::Vector3f(i * logoSpacing[0] + xOff, i * logoSpacing [1] + yOff, 0); - if(index == mCursor) //scale our selection up + if (index == mCursor) //Selected System { - // selected const std::shared_ptr& comp = mEntries.at(index).data.logoSelected; comp->setOpacity(0xFF); comp->render(logoTrans); - }else{ - // not selected + } + else { // not selected systems const std::shared_ptr& comp = mEntries.at(index).data.logo; comp->setOpacity(0x80); comp->render(logoTrans); } } + Renderer::popClipRect(); +} +void SystemView::renderInfoBar(const Eigen::Affine3f& trans) +{ Renderer::setMatrix(trans); - Renderer::drawRect(mSystemInfo.getPosition().x(), mSystemInfo.getPosition().y() - 1, mSize.x(), mSystemInfo.getSize().y(), 0xDDDDDD00 | (unsigned char)(mSystemInfo.getOpacity() / 255.f * 0xD8)); mSystemInfo.render(trans); } -std::vector SystemView::getHelpPrompts() +// Draw background extras +void SystemView::renderExtras(const Eigen::Affine3f& trans) { - std::vector prompts; - prompts.push_back(HelpPrompt("left/right", "choose")); - prompts.push_back(HelpPrompt("a", "select")); - return prompts; + Eigen::Affine3f extrasTrans = trans; + int extrasCenter = (int)mExtrasCamOffset; + for (int i = extrasCenter - 1; i < extrasCenter + 2; i++) + { + int index = i; + while (index < 0) + index += mEntries.size(); + while (index >= (int)mEntries.size()) + index -= mEntries.size(); + + extrasTrans.translation() = trans.translation() + Eigen::Vector3f((i - mExtrasCamOffset) * mSize.x(), 0, 0); + + Eigen::Vector2i clipRect = Eigen::Vector2i((int)((i - mExtrasCamOffset) * mSize.x()), 0); + Renderer::pushClipRect(clipRect, mSize.cast()); + mEntries.at(index).data.backgroundExtras->render(extrasTrans); + Renderer::popClipRect(); + } + + // fade extras if necessary + if (mExtrasFadeOpacity) + { + Renderer::setMatrix(trans); + Renderer::drawRect(0.0f, 0.0f, mSize.x(), mSize.y(), 0x00000000 | (unsigned char)(mExtrasFadeOpacity * 255)); + } } -HelpStyle SystemView::getHelpStyle() +// Populate the system carousel with the legacy values +void SystemView::getDefaultElements(void) { - HelpStyle style; - style.applyTheme(mEntries.at(mCursor).object->getTheme(), "system"); - return style; + // Carousel + mCarousel.type = HORIZONTAL; + mCarousel.size.x() = mSize.x(); + mCarousel.size.y() = 0.2325f * mSize.y(); + mCarousel.pos.x() = 0.0f; + mCarousel.pos.y() = 0.5f * (mSize.y() - mCarousel.size.y()); + mCarousel.color = 0xFFFFFFD8; + mCarousel.logoScale = 1.5f; + mCarousel.logoSize.x() = 0.25f * mSize.x(); + mCarousel.logoSize.y() = 0.155f * mSize.y(); + mCarousel.maxLogoCount = 3; + + // System Info Bar + mSystemInfo.setSize(mSize.x(), mSystemInfo.getFont()->getLetterHeight()*2.2f); + mSystemInfo.setPosition(0, (mCarousel.pos.y() + mCarousel.size.y())); + mSystemInfo.setBackgroundColor(0xDDDDDDD8); + mSystemInfo.setFont(Font::get((int)(0.035f * mSize.y()), Font::getDefaultPath())); + mSystemInfo.setColor(0x000000FF); +} + +void SystemView::getCarouselFromTheme(const ThemeData::ThemeElement* elem) +{ + if (elem->has("type")) + mCarousel.type = !(elem->get("type").compare("vertical")) ? VERTICAL : HORIZONTAL; + if (elem->has("size")) + mCarousel.size = elem->get("size").cwiseProduct(mSize); + if (elem->has("pos")) + mCarousel.pos = elem->get("pos").cwiseProduct(mSize); + if (elem->has("color")) + mCarousel.color = elem->get("color"); + if (elem->has("logoScale")) + mCarousel.logoScale = elem->get("logoScale"); + if (elem->has("logoSize")) + mCarousel.logoSize = elem->get("logoSize").cwiseProduct(mSize); + if (elem->has("maxLogoCount")) + mCarousel.maxLogoCount = std::round(elem->get("maxLogoCount")); } diff --git a/es-app/src/views/SystemView.h b/es-app/src/views/SystemView.h index 15200b9038..209c4b0e95 100644 --- a/es-app/src/views/SystemView.h +++ b/es-app/src/views/SystemView.h @@ -10,6 +10,12 @@ class SystemData; class AnimatedImageComponent; +enum CarouselType : unsigned int +{ + HORIZONTAL = 0, + VERTICAL = 1 +}; + struct SystemViewData { std::shared_ptr logo; @@ -17,6 +23,18 @@ struct SystemViewData std::shared_ptr backgroundExtras; }; +struct SystemViewCarousel +{ + CarouselType type; + Eigen::Vector2f pos; + Eigen::Vector2f size; + float logoScale; + Eigen::Vector2f logoSpacing; + unsigned int color; + int maxLogoCount; // number of logos shown on the carousel + Eigen::Vector2f logoSize; +}; + class SystemView : public IList { public: @@ -28,6 +46,8 @@ class SystemView : public IList void update(int deltaTime) override; void render(const Eigen::Affine3f& parentTrans) override; + void onThemeChanged(const std::shared_ptr& theme); + std::vector getHelpPrompts() override; virtual HelpStyle getHelpStyle() override; @@ -35,14 +55,22 @@ class SystemView : public IList void onCursorChanged(const CursorState& state) override; private: - inline Eigen::Vector2f logoSize() const { return Eigen::Vector2f(mSize.x() * 0.25f, mSize.y() * 0.155f); } - void populate(); + void getViewElements(const std::shared_ptr& theme); + void getDefaultElements(void); + void getCarouselFromTheme(const ThemeData::ThemeElement* elem); + void renderCarousel(const Eigen::Affine3f& parentTrans); + void renderExtras(const Eigen::Affine3f& parentTrans); + void renderInfoBar(const Eigen::Affine3f& trans); + + SystemViewCarousel mCarousel; TextComponent mSystemInfo; // unit is list index float mCamOffset; float mExtrasCamOffset; float mExtrasFadeOpacity; + + bool mViewNeedsReload; }; diff --git a/es-app/src/views/ViewController.cpp b/es-app/src/views/ViewController.cpp index ce29025e05..cc83eece51 100644 --- a/es-app/src/views/ViewController.cpp +++ b/es-app/src/views/ViewController.cpp @@ -12,7 +12,7 @@ #include "animations/LaunchAnimation.h" #include "animations/MoveCameraAnimation.h" #include "animations/LambdaAnimation.h" -#include +#include ViewController* ViewController::sInstance = NULL; diff --git a/es-core/src/ThemeData.cpp b/es-core/src/ThemeData.cpp index 2b38ce817c..ae00a0b205 100644 --- a/es-core/src/ThemeData.cpp +++ b/es-core/src/ThemeData.cpp @@ -24,7 +24,7 @@ ElementMapType makeMap(const T& mapInit) } std::vector ThemeData::sSupportedViews = boost::assign::list_of("system")("basic")("detailed")("video"); -std::vector ThemeData::sSupportedFeatures = boost::assign::list_of("video"); +std::vector ThemeData::sSupportedFeatures = boost::assign::list_of("video")("carousel"); std::map< std::string, ElementMapType > ThemeData::sElementMap = boost::assign::map_list_of ("image", makeMap(boost::assign::map_list_of @@ -39,12 +39,14 @@ std::map< std::string, ElementMapType > ThemeData::sElementMap = boost::assign:: ("pos", NORMALIZED_PAIR) ("size", NORMALIZED_PAIR) ("text", STRING) - ("color", COLOR) + ("backgroundColor", COLOR) ("fontPath", PATH) ("fontSize", FLOAT) + ("color", COLOR) ("alignment", STRING) ("forceUppercase", BOOLEAN) - ("lineSpacing", FLOAT))) + ("lineSpacing", FLOAT) + ("value", STRING))) ("textlist", makeMap(boost::assign::map_list_of ("pos", NORMALIZED_PAIR) ("size", NORMALIZED_PAIR) @@ -94,12 +96,20 @@ std::map< std::string, ElementMapType > ThemeData::sElementMap = boost::assign:: ("default", PATH) ("delay", FLOAT) ("showSnapshotNoVideo", BOOLEAN) - ("showSnapshotDelay", BOOLEAN))); + ("showSnapshotDelay", BOOLEAN))) + ("carousel", makeMap(boost::assign::map_list_of + ("type", STRING) + ("size", NORMALIZED_PAIR) + ("pos", NORMALIZED_PAIR) + ("color", COLOR) + ("logoScale", FLOAT) + ("logoSize", NORMALIZED_PAIR) + ("maxLogoCount", FLOAT))); namespace fs = boost::filesystem; #define MINIMUM_THEME_FORMAT_VERSION 3 -#define CURRENT_THEME_FORMAT_VERSION 3 +#define CURRENT_THEME_FORMAT_VERSION 4 // helper unsigned int getHexColor(const char* str) diff --git a/es-core/src/components/TextComponent.cpp b/es-core/src/components/TextComponent.cpp index bce50da12c..9ab5effa54 100644 --- a/es-core/src/components/TextComponent.cpp +++ b/es-core/src/components/TextComponent.cpp @@ -1,4 +1,5 @@ #include "components/TextComponent.h" + #include "Renderer.h" #include "Log.h" #include "Window.h" @@ -7,16 +8,17 @@ #include "Settings.h" TextComponent::TextComponent(Window* window) : GuiComponent(window), - mFont(Font::get(FONT_SIZE_MEDIUM)), mUppercase(false), mColor(0x000000FF), mAutoCalcExtent(true, true), mAlignment(ALIGN_LEFT), mLineSpacing(1.5f) + mFont(Font::get(FONT_SIZE_MEDIUM)), mUppercase(false), mColor(0x000000FF), mAutoCalcExtent(true, true), mAlignment(ALIGN_LEFT), mLineSpacing(1.5f), mBgColor(NULL) { } TextComponent::TextComponent(Window* window, const std::string& text, const std::shared_ptr& font, unsigned int color, Alignment align, - Eigen::Vector3f pos, Eigen::Vector2f size) : GuiComponent(window), - mFont(NULL), mUppercase(false), mColor(0x000000FF), mAutoCalcExtent(true, true), mAlignment(align), mLineSpacing(1.5f) + Eigen::Vector3f pos, Eigen::Vector2f size, unsigned int bgcolor) : GuiComponent(window), + mFont(NULL), mUppercase(false), mColor(0x000000FF), mAutoCalcExtent(true, true), mAlignment(align), mLineSpacing(1.5f), mBgColor(NULL) { setFont(font); setColor(color); + setBackgroundColor(bgcolor); setText(text); setPosition(pos); setSize(size); @@ -34,19 +36,34 @@ void TextComponent::setFont(const std::shared_ptr& font) onTextChanged(); } +// Set the color of the font/text void TextComponent::setColor(unsigned int color) { mColor = color; - - unsigned char opacity = mColor & 0x000000FF; - GuiComponent::setOpacity(opacity); - + mColorOpacity = mColor & 0x000000FF; onColorChanged(); } +// Set the color of the background box +void TextComponent::setBackgroundColor(unsigned int color) +{ + mBgColor = color; + mBgColorOpacity = mBgColor & 0x000000FF; +} + +// Scale the opacity void TextComponent::setOpacity(unsigned char opacity) { - mColor = (mColor & 0xFFFFFF00) | opacity; + // This method is mostly called to do fading in-out of the Text component element. + // Therefore, we assume here that opacity is a fractional value (expressed as an int 0-255), + // of the opacity originally set with setColor() or setBackgroundColor(). + + unsigned char o = (unsigned char)((float)opacity / 255.f * (float) mColorOpacity); + mColor = (mColor & 0xFFFFFF00) | (unsigned char) o; + + unsigned char bgo = (unsigned char)((float)opacity / 255.f * (float)mBgColorOpacity); + mBgColor = (mBgColor & 0xFFFFFF00) | (unsigned char)bgo; + onColorChanged(); GuiComponent::setOpacity(opacity); @@ -73,11 +90,11 @@ void TextComponent::render(const Eigen::Affine3f& parentTrans) { Eigen::Affine3f trans = parentTrans * getTransform(); - /*Eigen::Vector3f dim(mSize.x(), mSize.y(), 0); - dim = trans * dim - trans.translation(); - Renderer::pushClipRect(Eigen::Vector2i((int)trans.translation().x(), (int)trans.translation().y()), - Eigen::Vector2i((int)(dim.x() + 0.5f), (int)(dim.y() + 0.5f))); - */ + if (mBgColor) + { + Renderer::drawRect(getPosition().x(), getPosition().y() - 1, + getSize().x(), getSize().y(), mBgColor); + } if(mTextCache) { @@ -90,7 +107,7 @@ void TextComponent::render(const Eigen::Affine3f& parentTrans) Renderer::setMatrix(trans); Renderer::drawRect(0.f, 0.f, mSize.x(), mSize.y(), 0xFF000033); } - + trans.translate(off); trans = roundMatrix(trans); Renderer::setMatrix(trans); @@ -111,11 +128,8 @@ void TextComponent::render(const Eigen::Affine3f& parentTrans) break; } } - mFont->renderTextCache(mTextCache.get()); } - - //Renderer::popClipRect(); } void TextComponent::calculateExtent() @@ -216,8 +230,11 @@ void TextComponent::applyTheme(const std::shared_ptr& theme, const st if(!elem) return; - if(properties & COLOR && elem->has("color")) - setColor(elem->get("color")); + if (properties & COLOR && elem->has("color")) + setColor(elem->get("color")); + + if (properties & COLOR && elem->has("backgroundColor")) + setBackgroundColor(elem->get("backgroundColor")); if(properties & ALIGNMENT && elem->has("alignment")) { diff --git a/es-core/src/components/TextComponent.h b/es-core/src/components/TextComponent.h index 4a4a33fcde..a0dc4a5543 100644 --- a/es-core/src/components/TextComponent.h +++ b/es-core/src/components/TextComponent.h @@ -16,7 +16,7 @@ class TextComponent : public GuiComponent public: TextComponent(Window* window); TextComponent(Window* window, const std::string& text, const std::shared_ptr& font, unsigned int color = 0x000000FF, Alignment align = ALIGN_LEFT, - Eigen::Vector3f pos = Eigen::Vector3f::Zero(), Eigen::Vector2f size = Eigen::Vector2f::Zero()); + Eigen::Vector3f pos = Eigen::Vector3f::Zero(), Eigen::Vector2f size = Eigen::Vector2f::Zero(), unsigned int bgcolor = 0x00000000); void setFont(const std::shared_ptr& font); void setUppercase(bool uppercase); @@ -25,6 +25,7 @@ class TextComponent : public GuiComponent void setColor(unsigned int color); void setAlignment(Alignment align); void setLineSpacing(float spacing); + void setBackgroundColor(unsigned int color); void render(const Eigen::Affine3f& parentTrans) override; @@ -45,6 +46,10 @@ class TextComponent : public GuiComponent void onColorChanged(); unsigned int mColor; + unsigned int mBgColor; + unsigned char mColorOpacity; + unsigned char mBgColorOpacity; + std::shared_ptr mFont; bool mUppercase; Eigen::Matrix mAutoCalcExtent; From 82ddaa1813420491a26fafbdf691ab0de06f4501 Mon Sep 17 00:00:00 2001 From: Jools Wills Date: Thu, 30 Mar 2017 21:47:11 +0100 Subject: [PATCH 64/74] added additional search path for libmali.so (needed on Ubuntu 16.04 / Odroid XU4) --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1b98f16216..5961fff7bc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,7 +30,8 @@ endif() MESSAGE("Looking for libMali.so") if(EXISTS "/usr/lib/libMali.so" OR EXISTS "/usr/lib/arm-linux-gnueabihf/libMali.so" OR - EXISTS "/usr/lib/aarch64-linux-gnu/libMali.so") + EXISTS "/usr/lib/aarch64-linux-gnu/libMali.so" OR + EXISTS "/usr/lib/arm-linux-gnueabihf/mali-egl/libmali.so") MESSAGE("libMali.so found") set(GLSystem "OpenGL ES") else() From 61a493c38a4804903a3d61e41dc39e972e5508f1 Mon Sep 17 00:00:00 2001 From: Jools Wills Date: Mon, 3 Apr 2017 19:41:21 +0100 Subject: [PATCH 65/74] fix warning --- es-core/src/components/TextComponent.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/es-core/src/components/TextComponent.cpp b/es-core/src/components/TextComponent.cpp index 9ab5effa54..c7b7a490d6 100644 --- a/es-core/src/components/TextComponent.cpp +++ b/es-core/src/components/TextComponent.cpp @@ -8,13 +8,13 @@ #include "Settings.h" TextComponent::TextComponent(Window* window) : GuiComponent(window), - mFont(Font::get(FONT_SIZE_MEDIUM)), mUppercase(false), mColor(0x000000FF), mAutoCalcExtent(true, true), mAlignment(ALIGN_LEFT), mLineSpacing(1.5f), mBgColor(NULL) + mFont(Font::get(FONT_SIZE_MEDIUM)), mUppercase(false), mColor(0x000000FF), mAutoCalcExtent(true, true), mAlignment(ALIGN_LEFT), mLineSpacing(1.5f), mBgColor(0) { } TextComponent::TextComponent(Window* window, const std::string& text, const std::shared_ptr& font, unsigned int color, Alignment align, Eigen::Vector3f pos, Eigen::Vector2f size, unsigned int bgcolor) : GuiComponent(window), - mFont(NULL), mUppercase(false), mColor(0x000000FF), mAutoCalcExtent(true, true), mAlignment(align), mLineSpacing(1.5f), mBgColor(NULL) + mFont(NULL), mUppercase(false), mColor(0x000000FF), mAutoCalcExtent(true, true), mAlignment(align), mLineSpacing(1.5f), mBgColor(0) { setFont(font); setColor(color); From 752472355a073853abf4f1b8b7609a27d3d1bd83 Mon Sep 17 00:00:00 2001 From: Jools Wills Date: Mon, 3 Apr 2017 19:45:28 +0100 Subject: [PATCH 66/74] convert pugixml to git submodule and update to v1.8.1 --- .gitmodules | 3 + es-app/src/Gamelist.cpp | 2 +- es-app/src/MetaData.h | 2 +- es-app/src/scrapers/GamesDBScraper.cpp | 2 +- es-core/src/InputConfig.h | 2 +- es-core/src/InputManager.cpp | 2 +- es-core/src/Settings.cpp | 2 +- es-core/src/ThemeData.cpp | 2 +- es-core/src/ThemeData.h | 2 +- external/pugixml | 1 + external/pugixml/CMakeLists.txt | 13 - external/pugixml/pugiconfig.hpp | 69 - external/pugixml/pugixml.hpp | 1265 --- external/pugixml/pugixml_license.txt | 27 - external/pugixml/src/pugixml.cpp | 10250 ----------------------- 15 files changed, 12 insertions(+), 11632 deletions(-) create mode 100644 .gitmodules create mode 160000 external/pugixml delete mode 100644 external/pugixml/CMakeLists.txt delete mode 100644 external/pugixml/pugiconfig.hpp delete mode 100644 external/pugixml/pugixml.hpp delete mode 100644 external/pugixml/pugixml_license.txt delete mode 100644 external/pugixml/src/pugixml.cpp diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000..ab38f31f31 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "external/pugixml"] + path = external/pugixml + url = https://github.com/zeux/pugixml.git diff --git a/es-app/src/Gamelist.cpp b/es-app/src/Gamelist.cpp index dacf88fd4f..e5bc7da3bc 100644 --- a/es-app/src/Gamelist.cpp +++ b/es-app/src/Gamelist.cpp @@ -1,6 +1,6 @@ #include "Gamelist.h" #include "SystemData.h" -#include "pugixml/pugixml.hpp" +#include "pugixml/src/pugixml.hpp" #include #include "Log.h" #include "Settings.h" diff --git a/es-app/src/MetaData.h b/es-app/src/MetaData.h index df444e9d4c..f9b867450d 100644 --- a/es-app/src/MetaData.h +++ b/es-app/src/MetaData.h @@ -1,6 +1,6 @@ #pragma once -#include "pugixml/pugixml.hpp" +#include "pugixml/src/pugixml.hpp" #include #include #include "GuiComponent.h" diff --git a/es-app/src/scrapers/GamesDBScraper.cpp b/es-app/src/scrapers/GamesDBScraper.cpp index 74ecc37b75..80a679e982 100644 --- a/es-app/src/scrapers/GamesDBScraper.cpp +++ b/es-app/src/scrapers/GamesDBScraper.cpp @@ -1,6 +1,6 @@ #include "scrapers/GamesDBScraper.h" #include "Log.h" -#include "pugixml/pugixml.hpp" +#include "pugixml/src/pugixml.hpp" #include "MetaData.h" #include "Settings.h" #include "Util.h" diff --git a/es-core/src/InputConfig.h b/es-core/src/InputConfig.h index 4fa3980ac6..ca2b9ece85 100644 --- a/es-core/src/InputConfig.h +++ b/es-core/src/InputConfig.h @@ -6,7 +6,7 @@ #include #include #include -#include "pugixml/pugixml.hpp" +#include "pugixml/src/pugixml.hpp" #define DEVICE_KEYBOARD -1 diff --git a/es-core/src/InputManager.cpp b/es-core/src/InputManager.cpp index f03fbc14ec..3bc7574166 100644 --- a/es-core/src/InputManager.cpp +++ b/es-core/src/InputManager.cpp @@ -3,7 +3,7 @@ #include "Settings.h" #include "Window.h" #include "Log.h" -#include "pugixml/pugixml.hpp" +#include "pugixml/src/pugixml.hpp" #include #include "platform.h" diff --git a/es-core/src/Settings.cpp b/es-core/src/Settings.cpp index df90ba7b65..05c286dba3 100644 --- a/es-core/src/Settings.cpp +++ b/es-core/src/Settings.cpp @@ -1,6 +1,6 @@ #include "Settings.h" #include "Log.h" -#include "pugixml/pugixml.hpp" +#include "pugixml/src/pugixml.hpp" #include "platform.h" #include #include diff --git a/es-core/src/ThemeData.cpp b/es-core/src/ThemeData.cpp index ae00a0b205..50958b11f8 100644 --- a/es-core/src/ThemeData.cpp +++ b/es-core/src/ThemeData.cpp @@ -5,7 +5,7 @@ #include "resources/TextureResource.h" #include "Log.h" #include "Settings.h" -#include "pugixml/pugixml.hpp" +#include "pugixml/src/pugixml.hpp" #include #include "components/ImageComponent.h" diff --git a/es-core/src/ThemeData.h b/es-core/src/ThemeData.h index 082b736849..8231e07ede 100644 --- a/es-core/src/ThemeData.h +++ b/es-core/src/ThemeData.h @@ -9,7 +9,7 @@ #include #include #include -#include "pugixml/pugixml.hpp" +#include "pugixml/src/pugixml.hpp" #include "GuiComponent.h" template diff --git a/external/pugixml b/external/pugixml new file mode 160000 index 0000000000..d2deb420bc --- /dev/null +++ b/external/pugixml @@ -0,0 +1 @@ +Subproject commit d2deb420bc70369faa12785df2b5dd4d390e523d diff --git a/external/pugixml/CMakeLists.txt b/external/pugixml/CMakeLists.txt deleted file mode 100644 index fb01783b12..0000000000 --- a/external/pugixml/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -project("pugixml") - -set(PUGI_HEADERS - ${CMAKE_CURRENT_SOURCE_DIR}/pugiconfig.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/pugixml.hpp -) - -set(PUGI_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/src/pugixml.cpp -) - -include_directories(${CMAKE_CURRENT_SOURCE_DIR}) -add_library(pugixml STATIC ${PUGI_SOURCES} ${PUG_HEADERS}) diff --git a/external/pugixml/pugiconfig.hpp b/external/pugixml/pugiconfig.hpp deleted file mode 100644 index c2196715cd..0000000000 --- a/external/pugixml/pugiconfig.hpp +++ /dev/null @@ -1,69 +0,0 @@ -/** - * pugixml parser - version 1.2 - * -------------------------------------------------------- - * Copyright (C) 2006-2012, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) - * Report bugs and download new versions at http://pugixml.org/ - * - * This library is distributed under the MIT License. See notice at the end - * of this file. - * - * This work is based on the pugxml parser, which is: - * Copyright (C) 2003, by Kristen Wegner (kristen@tima.net) - */ - -#ifndef HEADER_PUGICONFIG_HPP -#define HEADER_PUGICONFIG_HPP - -// Uncomment this to enable wchar_t mode -// #define PUGIXML_WCHAR_MODE - -// Uncomment this to disable XPath -// #define PUGIXML_NO_XPATH - -// Uncomment this to disable STL -// #define PUGIXML_NO_STL - -// Uncomment this to disable exceptions -// #define PUGIXML_NO_EXCEPTIONS - -// Set this to control attributes for public classes/functions, i.e.: -// #define PUGIXML_API __declspec(dllexport) // to export all public symbols from DLL -// #define PUGIXML_CLASS __declspec(dllimport) // to import all classes from DLL -// #define PUGIXML_FUNCTION __fastcall // to set calling conventions to all public functions to fastcall -// In absence of PUGIXML_CLASS/PUGIXML_FUNCTION definitions PUGIXML_API is used instead - -// Uncomment this to switch to header-only version -// #define PUGIXML_HEADER_ONLY -// #include "pugixml.cpp" - -// Tune these constants to adjust memory-related behavior -// #define PUGIXML_MEMORY_PAGE_SIZE 32768 -// #define PUGIXML_MEMORY_OUTPUT_STACK 10240 -// #define PUGIXML_MEMORY_XPATH_PAGE_SIZE 4096 - -#endif - -/** - * Copyright (c) 2006-2012 Arseny Kapoulkine - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ diff --git a/external/pugixml/pugixml.hpp b/external/pugixml/pugixml.hpp deleted file mode 100644 index 77b4dcf474..0000000000 --- a/external/pugixml/pugixml.hpp +++ /dev/null @@ -1,1265 +0,0 @@ -/** - * pugixml parser - version 1.2 - * -------------------------------------------------------- - * Copyright (C) 2006-2012, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) - * Report bugs and download new versions at http://pugixml.org/ - * - * This library is distributed under the MIT License. See notice at the end - * of this file. - * - * This work is based on the pugxml parser, which is: - * Copyright (C) 2003, by Kristen Wegner (kristen@tima.net) - */ - -#ifndef PUGIXML_VERSION -// Define version macro; evaluates to major * 100 + minor so that it's safe to use in less-than comparisons -# define PUGIXML_VERSION 120 -#endif - -// Include user configuration file (this can define various configuration macros) -#include "pugiconfig.hpp" - -#ifndef HEADER_PUGIXML_HPP -#define HEADER_PUGIXML_HPP - -// Include stddef.h for size_t and ptrdiff_t -#include - -// Include exception header for XPath -#if !defined(PUGIXML_NO_XPATH) && !defined(PUGIXML_NO_EXCEPTIONS) -# include -#endif - -// Include STL headers -#ifndef PUGIXML_NO_STL -# include -# include -# include -#endif - -// Macro for deprecated features -#ifndef PUGIXML_DEPRECATED -# if defined(__GNUC__) -# define PUGIXML_DEPRECATED __attribute__((deprecated)) -# elif defined(_MSC_VER) && _MSC_VER >= 1300 -# define PUGIXML_DEPRECATED __declspec(deprecated) -# else -# define PUGIXML_DEPRECATED -# endif -#endif - -// If no API is defined, assume default -#ifndef PUGIXML_API -# define PUGIXML_API -#endif - -// If no API for classes is defined, assume default -#ifndef PUGIXML_CLASS -# define PUGIXML_CLASS PUGIXML_API -#endif - -// If no API for functions is defined, assume default -#ifndef PUGIXML_FUNCTION -# define PUGIXML_FUNCTION PUGIXML_API -#endif - -// Character interface macros -#ifdef PUGIXML_WCHAR_MODE -# define PUGIXML_TEXT(t) L ## t -# define PUGIXML_CHAR wchar_t -#else -# define PUGIXML_TEXT(t) t -# define PUGIXML_CHAR char -#endif - -namespace pugi -{ - // Character type used for all internal storage and operations; depends on PUGIXML_WCHAR_MODE - typedef PUGIXML_CHAR char_t; - -#ifndef PUGIXML_NO_STL - // String type used for operations that work with STL string; depends on PUGIXML_WCHAR_MODE - typedef std::basic_string, std::allocator > string_t; -#endif -} - -// The PugiXML namespace -namespace pugi -{ - // Tree node types - enum xml_node_type - { - node_null, // Empty (null) node handle - node_document, // A document tree's absolute root - node_element, // Element tag, i.e. '' - node_pcdata, // Plain character data, i.e. 'text' - node_cdata, // Character data, i.e. '' - node_comment, // Comment tag, i.e. '' - node_pi, // Processing instruction, i.e. '' - node_declaration, // Document declaration, i.e. '' - node_doctype // Document type declaration, i.e. '' - }; - - // Parsing options - - // Minimal parsing mode (equivalent to turning all other flags off). - // Only elements and PCDATA sections are added to the DOM tree, no text conversions are performed. - const unsigned int parse_minimal = 0x0000; - - // This flag determines if processing instructions (node_pi) are added to the DOM tree. This flag is off by default. - const unsigned int parse_pi = 0x0001; - - // This flag determines if comments (node_comment) are added to the DOM tree. This flag is off by default. - const unsigned int parse_comments = 0x0002; - - // This flag determines if CDATA sections (node_cdata) are added to the DOM tree. This flag is on by default. - const unsigned int parse_cdata = 0x0004; - - // This flag determines if plain character data (node_pcdata) that consist only of whitespace are added to the DOM tree. - // This flag is off by default; turning it on usually results in slower parsing and more memory consumption. - const unsigned int parse_ws_pcdata = 0x0008; - - // This flag determines if character and entity references are expanded during parsing. This flag is on by default. - const unsigned int parse_escapes = 0x0010; - - // This flag determines if EOL characters are normalized (converted to #xA) during parsing. This flag is on by default. - const unsigned int parse_eol = 0x0020; - - // This flag determines if attribute values are normalized using CDATA normalization rules during parsing. This flag is on by default. - const unsigned int parse_wconv_attribute = 0x0040; - - // This flag determines if attribute values are normalized using NMTOKENS normalization rules during parsing. This flag is off by default. - const unsigned int parse_wnorm_attribute = 0x0080; - - // This flag determines if document declaration (node_declaration) is added to the DOM tree. This flag is off by default. - const unsigned int parse_declaration = 0x0100; - - // This flag determines if document type declaration (node_doctype) is added to the DOM tree. This flag is off by default. - const unsigned int parse_doctype = 0x0200; - - // This flag determines if plain character data (node_pcdata) that is the only child of the parent node and that consists only - // of whitespace is added to the DOM tree. - // This flag is off by default; turning it on may result in slower parsing and more memory consumption. - const unsigned int parse_ws_pcdata_single = 0x0400; - - // The default parsing mode. - // Elements, PCDATA and CDATA sections are added to the DOM tree, character/reference entities are expanded, - // End-of-Line characters are normalized, attribute values are normalized using CDATA normalization rules. - const unsigned int parse_default = parse_cdata | parse_escapes | parse_wconv_attribute | parse_eol; - - // The full parsing mode. - // Nodes of all types are added to the DOM tree, character/reference entities are expanded, - // End-of-Line characters are normalized, attribute values are normalized using CDATA normalization rules. - const unsigned int parse_full = parse_default | parse_pi | parse_comments | parse_declaration | parse_doctype; - - // These flags determine the encoding of input data for XML document - enum xml_encoding - { - encoding_auto, // Auto-detect input encoding using BOM or < / class xml_object_range - { - public: - typedef It const_iterator; - - xml_object_range(It b, It e): _begin(b), _end(e) - { - } - - It begin() const { return _begin; } - It end() const { return _end; } - - private: - It _begin, _end; - }; - - // Writer interface for node printing (see xml_node::print) - class PUGIXML_CLASS xml_writer - { - public: - virtual ~xml_writer() {} - - // Write memory chunk into stream/file/whatever - virtual void write(const void* data, size_t size) = 0; - }; - - // xml_writer implementation for FILE* - class PUGIXML_CLASS xml_writer_file: public xml_writer - { - public: - // Construct writer from a FILE* object; void* is used to avoid header dependencies on stdio - xml_writer_file(void* file); - - virtual void write(const void* data, size_t size); - - private: - void* file; - }; - - #ifndef PUGIXML_NO_STL - // xml_writer implementation for streams - class PUGIXML_CLASS xml_writer_stream: public xml_writer - { - public: - // Construct writer from an output stream object - xml_writer_stream(std::basic_ostream >& stream); - xml_writer_stream(std::basic_ostream >& stream); - - virtual void write(const void* data, size_t size); - - private: - std::basic_ostream >* narrow_stream; - std::basic_ostream >* wide_stream; - }; - #endif - - // A light-weight handle for manipulating attributes in DOM tree - class PUGIXML_CLASS xml_attribute - { - friend class xml_attribute_iterator; - friend class xml_node; - - private: - xml_attribute_struct* _attr; - - typedef void (*unspecified_bool_type)(xml_attribute***); - - public: - // Default constructor. Constructs an empty attribute. - xml_attribute(); - - // Constructs attribute from internal pointer - explicit xml_attribute(xml_attribute_struct* attr); - - // Safe bool conversion operator - operator unspecified_bool_type() const; - - // Borland C++ workaround - bool operator!() const; - - // Comparison operators (compares wrapped attribute pointers) - bool operator==(const xml_attribute& r) const; - bool operator!=(const xml_attribute& r) const; - bool operator<(const xml_attribute& r) const; - bool operator>(const xml_attribute& r) const; - bool operator<=(const xml_attribute& r) const; - bool operator>=(const xml_attribute& r) const; - - // Check if attribute is empty - bool empty() const; - - // Get attribute name/value, or "" if attribute is empty - const char_t* name() const; - const char_t* value() const; - - // Get attribute value, or the default value if attribute is empty - const char_t* as_string(const char_t* def = PUGIXML_TEXT("")) const; - - // Get attribute value as a number, or the default value if conversion did not succeed or attribute is empty - int as_int(int def = 0) const; - unsigned int as_uint(unsigned int def = 0) const; - double as_double(double def = 0) const; - float as_float(float def = 0) const; - - // Get attribute value as bool (returns true if first character is in '1tTyY' set), or the default value if attribute is empty - bool as_bool(bool def = false) const; - - // Set attribute name/value (returns false if attribute is empty or there is not enough memory) - bool set_name(const char_t* rhs); - bool set_value(const char_t* rhs); - - // Set attribute value with type conversion (numbers are converted to strings, boolean is converted to "true"/"false") - bool set_value(int rhs); - bool set_value(unsigned int rhs); - bool set_value(double rhs); - bool set_value(bool rhs); - - // Set attribute value (equivalent to set_value without error checking) - xml_attribute& operator=(const char_t* rhs); - xml_attribute& operator=(int rhs); - xml_attribute& operator=(unsigned int rhs); - xml_attribute& operator=(double rhs); - xml_attribute& operator=(bool rhs); - - // Get next/previous attribute in the attribute list of the parent node - xml_attribute next_attribute() const; - xml_attribute previous_attribute() const; - - // Get hash value (unique for handles to the same object) - size_t hash_value() const; - - // Get internal pointer - xml_attribute_struct* internal_object() const; - }; - -#ifdef __BORLANDC__ - // Borland C++ workaround - bool PUGIXML_FUNCTION operator&&(const xml_attribute& lhs, bool rhs); - bool PUGIXML_FUNCTION operator||(const xml_attribute& lhs, bool rhs); -#endif - - // A light-weight handle for manipulating nodes in DOM tree - class PUGIXML_CLASS xml_node - { - friend class xml_attribute_iterator; - friend class xml_node_iterator; - friend class xml_named_node_iterator; - - protected: - xml_node_struct* _root; - - typedef void (*unspecified_bool_type)(xml_node***); - - public: - // Default constructor. Constructs an empty node. - xml_node(); - - // Constructs node from internal pointer - explicit xml_node(xml_node_struct* p); - - // Safe bool conversion operator - operator unspecified_bool_type() const; - - // Borland C++ workaround - bool operator!() const; - - // Comparison operators (compares wrapped node pointers) - bool operator==(const xml_node& r) const; - bool operator!=(const xml_node& r) const; - bool operator<(const xml_node& r) const; - bool operator>(const xml_node& r) const; - bool operator<=(const xml_node& r) const; - bool operator>=(const xml_node& r) const; - - // Check if node is empty. - bool empty() const; - - // Get node type - xml_node_type type() const; - - // Get node name/value, or "" if node is empty or it has no name/value - const char_t* name() const; - const char_t* value() const; - - // Get attribute list - xml_attribute first_attribute() const; - xml_attribute last_attribute() const; - - // Get children list - xml_node first_child() const; - xml_node last_child() const; - - // Get next/previous sibling in the children list of the parent node - xml_node next_sibling() const; - xml_node previous_sibling() const; - - // Get parent node - xml_node parent() const; - - // Get root of DOM tree this node belongs to - xml_node root() const; - - // Get text object for the current node - xml_text text() const; - - // Get child, attribute or next/previous sibling with the specified name - xml_node child(const char_t* name) const; - xml_attribute attribute(const char_t* name) const; - xml_node next_sibling(const char_t* name) const; - xml_node previous_sibling(const char_t* name) const; - - // Get child value of current node; that is, value of the first child node of type PCDATA/CDATA - const char_t* child_value() const; - - // Get child value of child with specified name. Equivalent to child(name).child_value(). - const char_t* child_value(const char_t* name) const; - - // Set node name/value (returns false if node is empty, there is not enough memory, or node can not have name/value) - bool set_name(const char_t* rhs); - bool set_value(const char_t* rhs); - - // Add attribute with specified name. Returns added attribute, or empty attribute on errors. - xml_attribute append_attribute(const char_t* name); - xml_attribute prepend_attribute(const char_t* name); - xml_attribute insert_attribute_after(const char_t* name, const xml_attribute& attr); - xml_attribute insert_attribute_before(const char_t* name, const xml_attribute& attr); - - // Add a copy of the specified attribute. Returns added attribute, or empty attribute on errors. - xml_attribute append_copy(const xml_attribute& proto); - xml_attribute prepend_copy(const xml_attribute& proto); - xml_attribute insert_copy_after(const xml_attribute& proto, const xml_attribute& attr); - xml_attribute insert_copy_before(const xml_attribute& proto, const xml_attribute& attr); - - // Add child node with specified type. Returns added node, or empty node on errors. - xml_node append_child(xml_node_type type = node_element); - xml_node prepend_child(xml_node_type type = node_element); - xml_node insert_child_after(xml_node_type type, const xml_node& node); - xml_node insert_child_before(xml_node_type type, const xml_node& node); - - // Add child element with specified name. Returns added node, or empty node on errors. - xml_node append_child(const char_t* name); - xml_node prepend_child(const char_t* name); - xml_node insert_child_after(const char_t* name, const xml_node& node); - xml_node insert_child_before(const char_t* name, const xml_node& node); - - // Add a copy of the specified node as a child. Returns added node, or empty node on errors. - xml_node append_copy(const xml_node& proto); - xml_node prepend_copy(const xml_node& proto); - xml_node insert_copy_after(const xml_node& proto, const xml_node& node); - xml_node insert_copy_before(const xml_node& proto, const xml_node& node); - - // Remove specified attribute - bool remove_attribute(const xml_attribute& a); - bool remove_attribute(const char_t* name); - - // Remove specified child - bool remove_child(const xml_node& n); - bool remove_child(const char_t* name); - - // Find attribute using predicate. Returns first attribute for which predicate returned true. - template xml_attribute find_attribute(Predicate pred) const - { - if (!_root) return xml_attribute(); - - for (xml_attribute attrib = first_attribute(); attrib; attrib = attrib.next_attribute()) - if (pred(attrib)) - return attrib; - - return xml_attribute(); - } - - // Find child node using predicate. Returns first child for which predicate returned true. - template xml_node find_child(Predicate pred) const - { - if (!_root) return xml_node(); - - for (xml_node node = first_child(); node; node = node.next_sibling()) - if (pred(node)) - return node; - - return xml_node(); - } - - // Find node from subtree using predicate. Returns first node from subtree (depth-first), for which predicate returned true. - template xml_node find_node(Predicate pred) const - { - if (!_root) return xml_node(); - - xml_node cur = first_child(); - - while (cur._root && cur._root != _root) - { - if (pred(cur)) return cur; - - if (cur.first_child()) cur = cur.first_child(); - else if (cur.next_sibling()) cur = cur.next_sibling(); - else - { - while (!cur.next_sibling() && cur._root != _root) cur = cur.parent(); - - if (cur._root != _root) cur = cur.next_sibling(); - } - } - - return xml_node(); - } - - // Find child node by attribute name/value - xml_node find_child_by_attribute(const char_t* name, const char_t* attr_name, const char_t* attr_value) const; - xml_node find_child_by_attribute(const char_t* attr_name, const char_t* attr_value) const; - - #ifndef PUGIXML_NO_STL - // Get the absolute node path from root as a text string. - string_t path(char_t delimiter = '/') const; - #endif - - // Search for a node by path consisting of node names and . or .. elements. - xml_node first_element_by_path(const char_t* path, char_t delimiter = '/') const; - - // Recursively traverse subtree with xml_tree_walker - bool traverse(xml_tree_walker& walker); - - #ifndef PUGIXML_NO_XPATH - // Select single node by evaluating XPath query. Returns first node from the resulting node set. - xpath_node select_single_node(const char_t* query, xpath_variable_set* variables = 0) const; - xpath_node select_single_node(const xpath_query& query) const; - - // Select node set by evaluating XPath query - xpath_node_set select_nodes(const char_t* query, xpath_variable_set* variables = 0) const; - xpath_node_set select_nodes(const xpath_query& query) const; - #endif - - // Print subtree using a writer object - void print(xml_writer& writer, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto, unsigned int depth = 0) const; - - #ifndef PUGIXML_NO_STL - // Print subtree to stream - void print(std::basic_ostream >& os, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto, unsigned int depth = 0) const; - void print(std::basic_ostream >& os, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, unsigned int depth = 0) const; - #endif - - // Child nodes iterators - typedef xml_node_iterator iterator; - - iterator begin() const; - iterator end() const; - - // Attribute iterators - typedef xml_attribute_iterator attribute_iterator; - - attribute_iterator attributes_begin() const; - attribute_iterator attributes_end() const; - - // Range-based for support - xml_object_range children() const; - xml_object_range children(const char_t* name) const; - xml_object_range attributes() const; - - // Get node offset in parsed file/string (in char_t units) for debugging purposes - ptrdiff_t offset_debug() const; - - // Get hash value (unique for handles to the same object) - size_t hash_value() const; - - // Get internal pointer - xml_node_struct* internal_object() const; - }; - -#ifdef __BORLANDC__ - // Borland C++ workaround - bool PUGIXML_FUNCTION operator&&(const xml_node& lhs, bool rhs); - bool PUGIXML_FUNCTION operator||(const xml_node& lhs, bool rhs); -#endif - - // A helper for working with text inside PCDATA nodes - class PUGIXML_CLASS xml_text - { - friend class xml_node; - - xml_node_struct* _root; - - typedef void (*unspecified_bool_type)(xml_text***); - - explicit xml_text(xml_node_struct* root); - - xml_node_struct* _data_new(); - xml_node_struct* _data() const; - - public: - // Default constructor. Constructs an empty object. - xml_text(); - - // Safe bool conversion operator - operator unspecified_bool_type() const; - - // Borland C++ workaround - bool operator!() const; - - // Check if text object is empty - bool empty() const; - - // Get text, or "" if object is empty - const char_t* get() const; - - // Get text, or the default value if object is empty - const char_t* as_string(const char_t* def = PUGIXML_TEXT("")) const; - - // Get text as a number, or the default value if conversion did not succeed or object is empty - int as_int(int def = 0) const; - unsigned int as_uint(unsigned int def = 0) const; - double as_double(double def = 0) const; - float as_float(float def = 0) const; - - // Get text as bool (returns true if first character is in '1tTyY' set), or the default value if object is empty - bool as_bool(bool def = false) const; - - // Set text (returns false if object is empty or there is not enough memory) - bool set(const char_t* rhs); - - // Set text with type conversion (numbers are converted to strings, boolean is converted to "true"/"false") - bool set(int rhs); - bool set(unsigned int rhs); - bool set(double rhs); - bool set(bool rhs); - - // Set text (equivalent to set without error checking) - xml_text& operator=(const char_t* rhs); - xml_text& operator=(int rhs); - xml_text& operator=(unsigned int rhs); - xml_text& operator=(double rhs); - xml_text& operator=(bool rhs); - - // Get the data node (node_pcdata or node_cdata) for this object - xml_node data() const; - }; - -#ifdef __BORLANDC__ - // Borland C++ workaround - bool PUGIXML_FUNCTION operator&&(const xml_text& lhs, bool rhs); - bool PUGIXML_FUNCTION operator||(const xml_text& lhs, bool rhs); -#endif - - // Child node iterator (a bidirectional iterator over a collection of xml_node) - class PUGIXML_CLASS xml_node_iterator - { - friend class xml_node; - - private: - mutable xml_node _wrap; - xml_node _parent; - - xml_node_iterator(xml_node_struct* ref, xml_node_struct* parent); - - public: - // Iterator traits - typedef ptrdiff_t difference_type; - typedef xml_node value_type; - typedef xml_node* pointer; - typedef xml_node& reference; - - #ifndef PUGIXML_NO_STL - typedef std::bidirectional_iterator_tag iterator_category; - #endif - - // Default constructor - xml_node_iterator(); - - // Construct an iterator which points to the specified node - xml_node_iterator(const xml_node& node); - - // Iterator operators - bool operator==(const xml_node_iterator& rhs) const; - bool operator!=(const xml_node_iterator& rhs) const; - - xml_node& operator*() const; - xml_node* operator->() const; - - const xml_node_iterator& operator++(); - xml_node_iterator operator++(int); - - const xml_node_iterator& operator--(); - xml_node_iterator operator--(int); - }; - - // Attribute iterator (a bidirectional iterator over a collection of xml_attribute) - class PUGIXML_CLASS xml_attribute_iterator - { - friend class xml_node; - - private: - mutable xml_attribute _wrap; - xml_node _parent; - - xml_attribute_iterator(xml_attribute_struct* ref, xml_node_struct* parent); - - public: - // Iterator traits - typedef ptrdiff_t difference_type; - typedef xml_attribute value_type; - typedef xml_attribute* pointer; - typedef xml_attribute& reference; - - #ifndef PUGIXML_NO_STL - typedef std::bidirectional_iterator_tag iterator_category; - #endif - - // Default constructor - xml_attribute_iterator(); - - // Construct an iterator which points to the specified attribute - xml_attribute_iterator(const xml_attribute& attr, const xml_node& parent); - - // Iterator operators - bool operator==(const xml_attribute_iterator& rhs) const; - bool operator!=(const xml_attribute_iterator& rhs) const; - - xml_attribute& operator*() const; - xml_attribute* operator->() const; - - const xml_attribute_iterator& operator++(); - xml_attribute_iterator operator++(int); - - const xml_attribute_iterator& operator--(); - xml_attribute_iterator operator--(int); - }; - - // Named node range helper - class xml_named_node_iterator - { - public: - // Iterator traits - typedef ptrdiff_t difference_type; - typedef xml_node value_type; - typedef xml_node* pointer; - typedef xml_node& reference; - - #ifndef PUGIXML_NO_STL - typedef std::forward_iterator_tag iterator_category; - #endif - - // Default constructor - xml_named_node_iterator(); - - // Construct an iterator which points to the specified node - xml_named_node_iterator(const xml_node& node, const char_t* name); - - // Iterator operators - bool operator==(const xml_named_node_iterator& rhs) const; - bool operator!=(const xml_named_node_iterator& rhs) const; - - xml_node& operator*() const; - xml_node* operator->() const; - - const xml_named_node_iterator& operator++(); - xml_named_node_iterator operator++(int); - - private: - mutable xml_node _node; - const char_t* _name; - }; - - // Abstract tree walker class (see xml_node::traverse) - class PUGIXML_CLASS xml_tree_walker - { - friend class xml_node; - - private: - int _depth; - - protected: - // Get current traversal depth - int depth() const; - - public: - xml_tree_walker(); - virtual ~xml_tree_walker(); - - // Callback that is called when traversal begins - virtual bool begin(xml_node& node); - - // Callback that is called for each node traversed - virtual bool for_each(xml_node& node) = 0; - - // Callback that is called when traversal ends - virtual bool end(xml_node& node); - }; - - // Parsing status, returned as part of xml_parse_result object - enum xml_parse_status - { - status_ok = 0, // No error - - status_file_not_found, // File was not found during load_file() - status_io_error, // Error reading from file/stream - status_out_of_memory, // Could not allocate memory - status_internal_error, // Internal error occurred - - status_unrecognized_tag, // Parser could not determine tag type - - status_bad_pi, // Parsing error occurred while parsing document declaration/processing instruction - status_bad_comment, // Parsing error occurred while parsing comment - status_bad_cdata, // Parsing error occurred while parsing CDATA section - status_bad_doctype, // Parsing error occurred while parsing document type declaration - status_bad_pcdata, // Parsing error occurred while parsing PCDATA section - status_bad_start_element, // Parsing error occurred while parsing start element tag - status_bad_attribute, // Parsing error occurred while parsing element attribute - status_bad_end_element, // Parsing error occurred while parsing end element tag - status_end_element_mismatch // There was a mismatch of start-end tags (closing tag had incorrect name, some tag was not closed or there was an excessive closing tag) - }; - - // Parsing result - struct PUGIXML_CLASS xml_parse_result - { - // Parsing status (see xml_parse_status) - xml_parse_status status; - - // Last parsed offset (in char_t units from start of input data) - ptrdiff_t offset; - - // Source document encoding - xml_encoding encoding; - - // Default constructor, initializes object to failed state - xml_parse_result(); - - // Cast to bool operator - operator bool() const; - - // Get error description - const char* description() const; - }; - - // Document class (DOM tree root) - class PUGIXML_CLASS xml_document: public xml_node - { - private: - char_t* _buffer; - - char _memory[192]; - - // Non-copyable semantics - xml_document(const xml_document&); - const xml_document& operator=(const xml_document&); - - void create(); - void destroy(); - - xml_parse_result load_buffer_impl(void* contents, size_t size, unsigned int options, xml_encoding encoding, bool is_mutable, bool own); - - public: - // Default constructor, makes empty document - xml_document(); - - // Destructor, invalidates all node/attribute handles to this document - ~xml_document(); - - // Removes all nodes, leaving the empty document - void reset(); - - // Removes all nodes, then copies the entire contents of the specified document - void reset(const xml_document& proto); - - #ifndef PUGIXML_NO_STL - // Load document from stream. - xml_parse_result load(std::basic_istream >& stream, unsigned int options = parse_default, xml_encoding encoding = encoding_auto); - xml_parse_result load(std::basic_istream >& stream, unsigned int options = parse_default); - #endif - - // Load document from zero-terminated string. No encoding conversions are applied. - xml_parse_result load(const char_t* contents, unsigned int options = parse_default); - - // Load document from file - xml_parse_result load_file(const char* path, unsigned int options = parse_default, xml_encoding encoding = encoding_auto); - xml_parse_result load_file(const wchar_t* path, unsigned int options = parse_default, xml_encoding encoding = encoding_auto); - - // Load document from buffer. Copies/converts the buffer, so it may be deleted or changed after the function returns. - xml_parse_result load_buffer(const void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto); - - // Load document from buffer, using the buffer for in-place parsing (the buffer is modified and used for storage of document data). - // You should ensure that buffer data will persist throughout the document's lifetime, and free the buffer memory manually once document is destroyed. - xml_parse_result load_buffer_inplace(void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto); - - // Load document from buffer, using the buffer for in-place parsing (the buffer is modified and used for storage of document data). - // You should allocate the buffer with pugixml allocation function; document will free the buffer when it is no longer needed (you can't use it anymore). - xml_parse_result load_buffer_inplace_own(void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto); - - // Save XML document to writer (semantics is slightly different from xml_node::print, see documentation for details). - void save(xml_writer& writer, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const; - - #ifndef PUGIXML_NO_STL - // Save XML document to stream (semantics is slightly different from xml_node::print, see documentation for details). - void save(std::basic_ostream >& stream, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const; - void save(std::basic_ostream >& stream, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default) const; - #endif - - // Save XML to file - bool save_file(const char* path, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const; - bool save_file(const wchar_t* path, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const; - - // Get document element - xml_node document_element() const; - }; - -#ifndef PUGIXML_NO_XPATH - // XPath query return type - enum xpath_value_type - { - xpath_type_none, // Unknown type (query failed to compile) - xpath_type_node_set, // Node set (xpath_node_set) - xpath_type_number, // Number - xpath_type_string, // String - xpath_type_boolean // Boolean - }; - - // XPath parsing result - struct PUGIXML_CLASS xpath_parse_result - { - // Error message (0 if no error) - const char* error; - - // Last parsed offset (in char_t units from string start) - ptrdiff_t offset; - - // Default constructor, initializes object to failed state - xpath_parse_result(); - - // Cast to bool operator - operator bool() const; - - // Get error description - const char* description() const; - }; - - // A single XPath variable - class PUGIXML_CLASS xpath_variable - { - friend class xpath_variable_set; - - protected: - xpath_value_type _type; - xpath_variable* _next; - - xpath_variable(); - - // Non-copyable semantics - xpath_variable(const xpath_variable&); - xpath_variable& operator=(const xpath_variable&); - - public: - // Get variable name - const char_t* name() const; - - // Get variable type - xpath_value_type type() const; - - // Get variable value; no type conversion is performed, default value (false, NaN, empty string, empty node set) is returned on type mismatch error - bool get_boolean() const; - double get_number() const; - const char_t* get_string() const; - const xpath_node_set& get_node_set() const; - - // Set variable value; no type conversion is performed, false is returned on type mismatch error - bool set(bool value); - bool set(double value); - bool set(const char_t* value); - bool set(const xpath_node_set& value); - }; - - // A set of XPath variables - class PUGIXML_CLASS xpath_variable_set - { - private: - xpath_variable* _data[64]; - - // Non-copyable semantics - xpath_variable_set(const xpath_variable_set&); - xpath_variable_set& operator=(const xpath_variable_set&); - - xpath_variable* find(const char_t* name) const; - - public: - // Default constructor/destructor - xpath_variable_set(); - ~xpath_variable_set(); - - // Add a new variable or get the existing one, if the types match - xpath_variable* add(const char_t* name, xpath_value_type type); - - // Set value of an existing variable; no type conversion is performed, false is returned if there is no such variable or if types mismatch - bool set(const char_t* name, bool value); - bool set(const char_t* name, double value); - bool set(const char_t* name, const char_t* value); - bool set(const char_t* name, const xpath_node_set& value); - - // Get existing variable by name - xpath_variable* get(const char_t* name); - const xpath_variable* get(const char_t* name) const; - }; - - // A compiled XPath query object - class PUGIXML_CLASS xpath_query - { - private: - void* _impl; - xpath_parse_result _result; - - typedef void (*unspecified_bool_type)(xpath_query***); - - // Non-copyable semantics - xpath_query(const xpath_query&); - xpath_query& operator=(const xpath_query&); - - public: - // Construct a compiled object from XPath expression. - // If PUGIXML_NO_EXCEPTIONS is not defined, throws xpath_exception on compilation errors. - explicit xpath_query(const char_t* query, xpath_variable_set* variables = 0); - - // Destructor - ~xpath_query(); - - // Get query expression return type - xpath_value_type return_type() const; - - // Evaluate expression as boolean value in the specified context; performs type conversion if necessary. - // If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors. - bool evaluate_boolean(const xpath_node& n) const; - - // Evaluate expression as double value in the specified context; performs type conversion if necessary. - // If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors. - double evaluate_number(const xpath_node& n) const; - - #ifndef PUGIXML_NO_STL - // Evaluate expression as string value in the specified context; performs type conversion if necessary. - // If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors. - string_t evaluate_string(const xpath_node& n) const; - #endif - - // Evaluate expression as string value in the specified context; performs type conversion if necessary. - // At most capacity characters are written to the destination buffer, full result size is returned (includes terminating zero). - // If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors. - // If PUGIXML_NO_EXCEPTIONS is defined, returns empty set instead. - size_t evaluate_string(char_t* buffer, size_t capacity, const xpath_node& n) const; - - // Evaluate expression as node set in the specified context. - // If PUGIXML_NO_EXCEPTIONS is not defined, throws xpath_exception on type mismatch and std::bad_alloc on out of memory errors. - // If PUGIXML_NO_EXCEPTIONS is defined, returns empty node set instead. - xpath_node_set evaluate_node_set(const xpath_node& n) const; - - // Get parsing result (used to get compilation errors in PUGIXML_NO_EXCEPTIONS mode) - const xpath_parse_result& result() const; - - // Safe bool conversion operator - operator unspecified_bool_type() const; - - // Borland C++ workaround - bool operator!() const; - }; - - #ifndef PUGIXML_NO_EXCEPTIONS - // XPath exception class - class PUGIXML_CLASS xpath_exception: public std::exception - { - private: - xpath_parse_result _result; - - public: - // Construct exception from parse result - explicit xpath_exception(const xpath_parse_result& result); - - // Get error message - virtual const char* what() const throw(); - - // Get parse result - const xpath_parse_result& result() const; - }; - #endif - - // XPath node class (either xml_node or xml_attribute) - class PUGIXML_CLASS xpath_node - { - private: - xml_node _node; - xml_attribute _attribute; - - typedef void (*unspecified_bool_type)(xpath_node***); - - public: - // Default constructor; constructs empty XPath node - xpath_node(); - - // Construct XPath node from XML node/attribute - xpath_node(const xml_node& node); - xpath_node(const xml_attribute& attribute, const xml_node& parent); - - // Get node/attribute, if any - xml_node node() const; - xml_attribute attribute() const; - - // Get parent of contained node/attribute - xml_node parent() const; - - // Safe bool conversion operator - operator unspecified_bool_type() const; - - // Borland C++ workaround - bool operator!() const; - - // Comparison operators - bool operator==(const xpath_node& n) const; - bool operator!=(const xpath_node& n) const; - }; - -#ifdef __BORLANDC__ - // Borland C++ workaround - bool PUGIXML_FUNCTION operator&&(const xpath_node& lhs, bool rhs); - bool PUGIXML_FUNCTION operator||(const xpath_node& lhs, bool rhs); -#endif - - // A fixed-size collection of XPath nodes - class PUGIXML_CLASS xpath_node_set - { - public: - // Collection type - enum type_t - { - type_unsorted, // Not ordered - type_sorted, // Sorted by document order (ascending) - type_sorted_reverse // Sorted by document order (descending) - }; - - // Constant iterator type - typedef const xpath_node* const_iterator; - - // Default constructor. Constructs empty set. - xpath_node_set(); - - // Constructs a set from iterator range; data is not checked for duplicates and is not sorted according to provided type, so be careful - xpath_node_set(const_iterator begin, const_iterator end, type_t type = type_unsorted); - - // Destructor - ~xpath_node_set(); - - // Copy constructor/assignment operator - xpath_node_set(const xpath_node_set& ns); - xpath_node_set& operator=(const xpath_node_set& ns); - - // Get collection type - type_t type() const; - - // Get collection size - size_t size() const; - - // Indexing operator - const xpath_node& operator[](size_t index) const; - - // Collection iterators - const_iterator begin() const; - const_iterator end() const; - - // Sort the collection in ascending/descending order by document order - void sort(bool reverse = false); - - // Get first node in the collection by document order - xpath_node first() const; - - // Check if collection is empty - bool empty() const; - - private: - type_t _type; - - xpath_node _storage; - - xpath_node* _begin; - xpath_node* _end; - - void _assign(const_iterator begin, const_iterator end); - }; -#endif - -#ifndef PUGIXML_NO_STL - // Convert wide string to UTF8 - std::basic_string, std::allocator > PUGIXML_FUNCTION as_utf8(const wchar_t* str); - std::basic_string, std::allocator > PUGIXML_FUNCTION as_utf8(const std::basic_string, std::allocator >& str); - - // Convert UTF8 to wide string - std::basic_string, std::allocator > PUGIXML_FUNCTION as_wide(const char* str); - std::basic_string, std::allocator > PUGIXML_FUNCTION as_wide(const std::basic_string, std::allocator >& str); -#endif - - // Memory allocation function interface; returns pointer to allocated memory or NULL on failure - typedef void* (*allocation_function)(size_t size); - - // Memory deallocation function interface - typedef void (*deallocation_function)(void* ptr); - - // Override default memory management functions. All subsequent allocations/deallocations will be performed via supplied functions. - void PUGIXML_FUNCTION set_memory_management_functions(allocation_function allocate, deallocation_function deallocate); - - // Get current memory management functions - allocation_function PUGIXML_FUNCTION get_memory_allocation_function(); - deallocation_function PUGIXML_FUNCTION get_memory_deallocation_function(); -} - -#if !defined(PUGIXML_NO_STL) && (defined(_MSC_VER) || defined(__ICC)) -namespace std -{ - // Workarounds for (non-standard) iterator category detection for older versions (MSVC7/IC8 and earlier) - std::bidirectional_iterator_tag PUGIXML_FUNCTION _Iter_cat(const pugi::xml_node_iterator&); - std::bidirectional_iterator_tag PUGIXML_FUNCTION _Iter_cat(const pugi::xml_attribute_iterator&); - std::forward_iterator_tag PUGIXML_FUNCTION _Iter_cat(const pugi::xml_named_node_iterator&); -} -#endif - -#if !defined(PUGIXML_NO_STL) && defined(__SUNPRO_CC) -namespace std -{ - // Workarounds for (non-standard) iterator category detection - std::bidirectional_iterator_tag PUGIXML_FUNCTION __iterator_category(const pugi::xml_node_iterator&); - std::bidirectional_iterator_tag PUGIXML_FUNCTION __iterator_category(const pugi::xml_attribute_iterator&); - std::forward_iterator_tag PUGIXML_FUNCTION __iterator_category(const pugi::xml_named_node_iterator&); -} -#endif - -#endif - -/** - * Copyright (c) 2006-2012 Arseny Kapoulkine - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ diff --git a/external/pugixml/pugixml_license.txt b/external/pugixml/pugixml_license.txt deleted file mode 100644 index ad0bc4607e..0000000000 --- a/external/pugixml/pugixml_license.txt +++ /dev/null @@ -1,27 +0,0 @@ -pugixml 1.2 - an XML processing library - - -This library is distributed under the MIT License: - -Copyright (c) 2006-2012 Arseny Kapoulkine - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. diff --git a/external/pugixml/src/pugixml.cpp b/external/pugixml/src/pugixml.cpp deleted file mode 100644 index 4035ab1cfd..0000000000 --- a/external/pugixml/src/pugixml.cpp +++ /dev/null @@ -1,10250 +0,0 @@ -/** - * pugixml parser - version 1.2 - * -------------------------------------------------------- - * Copyright (C) 2006-2012, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) - * Report bugs and download new versions at http://pugixml.org/ - * - * This library is distributed under the MIT License. See notice at the end - * of this file. - * - * This work is based on the pugxml parser, which is: - * Copyright (C) 2003, by Kristen Wegner (kristen@tima.net) - */ - -#ifndef SOURCE_PUGIXML_CPP -#define SOURCE_PUGIXML_CPP - -#include "pugixml.hpp" - -#include -#include -#include -#include -#include - -#ifndef PUGIXML_NO_XPATH -# include -# include -# ifdef PUGIXML_NO_EXCEPTIONS -# include -# endif -#endif - -#ifndef PUGIXML_NO_STL -# include -# include -# include -#endif - -// For placement new -#include - -#ifdef _MSC_VER -# pragma warning(push) -# pragma warning(disable: 4127) // conditional expression is constant -# pragma warning(disable: 4324) // structure was padded due to __declspec(align()) -# pragma warning(disable: 4611) // interaction between '_setjmp' and C++ object destruction is non-portable -# pragma warning(disable: 4702) // unreachable code -# pragma warning(disable: 4996) // this function or variable may be unsafe -# pragma warning(disable: 4793) // function compiled as native: presence of '_setjmp' makes a function unmanaged -#endif - -#ifdef __INTEL_COMPILER -# pragma warning(disable: 177) // function was declared but never referenced -# pragma warning(disable: 279) // controlling expression is constant -# pragma warning(disable: 1478 1786) // function was declared "deprecated" -# pragma warning(disable: 1684) // conversion from pointer to same-sized integral type -#endif - -#if defined(__BORLANDC__) && defined(PUGIXML_HEADER_ONLY) -# pragma warn -8080 // symbol is declared but never used; disabling this inside push/pop bracket does not make the warning go away -#endif - -#ifdef __BORLANDC__ -# pragma option push -# pragma warn -8008 // condition is always false -# pragma warn -8066 // unreachable code -#endif - -#ifdef __SNC__ -// Using diag_push/diag_pop does not disable the warnings inside templates due to a compiler bug -# pragma diag_suppress=178 // function was declared but never referenced -# pragma diag_suppress=237 // controlling expression is constant -#endif - -// Inlining controls -#if defined(_MSC_VER) && _MSC_VER >= 1300 -# define PUGI__NO_INLINE __declspec(noinline) -#elif defined(__GNUC__) -# define PUGI__NO_INLINE __attribute__((noinline)) -#else -# define PUGI__NO_INLINE -#endif - -// Simple static assertion -#define PUGI__STATIC_ASSERT(cond) { static const char condition_failed[(cond) ? 1 : -1] = {0}; (void)condition_failed[0]; } - -// Digital Mars C++ bug workaround for passing char loaded from memory via stack -#ifdef __DMC__ -# define PUGI__DMC_VOLATILE volatile -#else -# define PUGI__DMC_VOLATILE -#endif - -// Borland C++ bug workaround for not defining ::memcpy depending on header include order (can't always use std::memcpy because some compilers don't have it at all) -#if defined(__BORLANDC__) && !defined(__MEM_H_USING_LIST) -using std::memcpy; -using std::memmove; -#endif - -// In some environments MSVC is a compiler but the CRT lacks certain MSVC-specific features -#if defined(_MSC_VER) && !defined(__S3E__) -# define PUGI__MSVC_CRT_VERSION _MSC_VER -#endif - -#ifdef PUGIXML_HEADER_ONLY -# define PUGI__NS_BEGIN namespace pugi { namespace impl { -# define PUGI__NS_END } } -# define PUGI__FN inline -# define PUGI__FN_NO_INLINE inline -#else -# if defined(_MSC_VER) && _MSC_VER < 1300 // MSVC6 seems to have an amusing bug with anonymous namespaces inside namespaces -# define PUGI__NS_BEGIN namespace pugi { namespace impl { -# define PUGI__NS_END } } -# else -# define PUGI__NS_BEGIN namespace pugi { namespace impl { namespace { -# define PUGI__NS_END } } } -# endif -# define PUGI__FN -# define PUGI__FN_NO_INLINE PUGI__NO_INLINE -#endif - -// uintptr_t -#if !defined(_MSC_VER) || _MSC_VER >= 1600 -# include -#else -# ifndef _UINTPTR_T_DEFINED -// No native uintptr_t in MSVC6 and in some WinCE versions -typedef size_t uintptr_t; -#define _UINTPTR_T_DEFINED -# endif -PUGI__NS_BEGIN - typedef unsigned __int8 uint8_t; - typedef unsigned __int16 uint16_t; - typedef unsigned __int32 uint32_t; -PUGI__NS_END -#endif - -// Memory allocation -PUGI__NS_BEGIN - PUGI__FN void* default_allocate(size_t size) - { - return malloc(size); - } - - PUGI__FN void default_deallocate(void* ptr) - { - free(ptr); - } - - template - struct xml_memory_management_function_storage - { - static allocation_function allocate; - static deallocation_function deallocate; - }; - - template allocation_function xml_memory_management_function_storage::allocate = default_allocate; - template deallocation_function xml_memory_management_function_storage::deallocate = default_deallocate; - - typedef xml_memory_management_function_storage xml_memory; -PUGI__NS_END - -// String utilities -PUGI__NS_BEGIN - // Get string length - PUGI__FN size_t strlength(const char_t* s) - { - assert(s); - - #ifdef PUGIXML_WCHAR_MODE - return wcslen(s); - #else - return strlen(s); - #endif - } - - // Compare two strings - PUGI__FN bool strequal(const char_t* src, const char_t* dst) - { - assert(src && dst); - - #ifdef PUGIXML_WCHAR_MODE - return wcscmp(src, dst) == 0; - #else - return strcmp(src, dst) == 0; - #endif - } - - // Compare lhs with [rhs_begin, rhs_end) - PUGI__FN bool strequalrange(const char_t* lhs, const char_t* rhs, size_t count) - { - for (size_t i = 0; i < count; ++i) - if (lhs[i] != rhs[i]) - return false; - - return lhs[count] == 0; - } - -#ifdef PUGIXML_WCHAR_MODE - // Convert string to wide string, assuming all symbols are ASCII - PUGI__FN void widen_ascii(wchar_t* dest, const char* source) - { - for (const char* i = source; *i; ++i) *dest++ = *i; - *dest = 0; - } -#endif -PUGI__NS_END - -#if !defined(PUGIXML_NO_STL) || !defined(PUGIXML_NO_XPATH) -// auto_ptr-like buffer holder for exception recovery -PUGI__NS_BEGIN - struct buffer_holder - { - void* data; - void (*deleter)(void*); - - buffer_holder(void* data_, void (*deleter_)(void*)): data(data_), deleter(deleter_) - { - } - - ~buffer_holder() - { - if (data) deleter(data); - } - - void* release() - { - void* result = data; - data = 0; - return result; - } - }; -PUGI__NS_END -#endif - -PUGI__NS_BEGIN - static const size_t xml_memory_page_size = - #ifdef PUGIXML_MEMORY_PAGE_SIZE - PUGIXML_MEMORY_PAGE_SIZE - #else - 32768 - #endif - ; - - static const uintptr_t xml_memory_page_alignment = 32; - static const uintptr_t xml_memory_page_pointer_mask = ~(xml_memory_page_alignment - 1); - static const uintptr_t xml_memory_page_name_allocated_mask = 16; - static const uintptr_t xml_memory_page_value_allocated_mask = 8; - static const uintptr_t xml_memory_page_type_mask = 7; - - struct xml_allocator; - - struct xml_memory_page - { - static xml_memory_page* construct(void* memory) - { - if (!memory) return 0; //$ redundant, left for performance - - xml_memory_page* result = static_cast(memory); - - result->allocator = 0; - result->memory = 0; - result->prev = 0; - result->next = 0; - result->busy_size = 0; - result->freed_size = 0; - - return result; - } - - xml_allocator* allocator; - - void* memory; - - xml_memory_page* prev; - xml_memory_page* next; - - size_t busy_size; - size_t freed_size; - - char data[1]; - }; - - struct xml_memory_string_header - { - uint16_t page_offset; // offset from page->data - uint16_t full_size; // 0 if string occupies whole page - }; - - struct xml_allocator - { - xml_allocator(xml_memory_page* root): _root(root), _busy_size(root->busy_size) - { - } - - xml_memory_page* allocate_page(size_t data_size) - { - size_t size = offsetof(xml_memory_page, data) + data_size; - - // allocate block with some alignment, leaving memory for worst-case padding - void* memory = xml_memory::allocate(size + xml_memory_page_alignment); - if (!memory) return 0; - - // align upwards to page boundary - void* page_memory = reinterpret_cast((reinterpret_cast(memory) + (xml_memory_page_alignment - 1)) & ~(xml_memory_page_alignment - 1)); - - // prepare page structure - xml_memory_page* page = xml_memory_page::construct(page_memory); - - page->memory = memory; - page->allocator = _root->allocator; - - return page; - } - - static void deallocate_page(xml_memory_page* page) - { - xml_memory::deallocate(page->memory); - } - - void* allocate_memory_oob(size_t size, xml_memory_page*& out_page); - - void* allocate_memory(size_t size, xml_memory_page*& out_page) - { - if (_busy_size + size > xml_memory_page_size) return allocate_memory_oob(size, out_page); - - void* buf = _root->data + _busy_size; - - _busy_size += size; - - out_page = _root; - - return buf; - } - - void deallocate_memory(void* ptr, size_t size, xml_memory_page* page) - { - if (page == _root) page->busy_size = _busy_size; - - assert(ptr >= page->data && ptr < page->data + page->busy_size); - (void)!ptr; - - page->freed_size += size; - assert(page->freed_size <= page->busy_size); - - if (page->freed_size == page->busy_size) - { - if (page->next == 0) - { - assert(_root == page); - - // top page freed, just reset sizes - page->busy_size = page->freed_size = 0; - _busy_size = 0; - } - else - { - assert(_root != page); - assert(page->prev); - - // remove from the list - page->prev->next = page->next; - page->next->prev = page->prev; - - // deallocate - deallocate_page(page); - } - } - } - - char_t* allocate_string(size_t length) - { - // allocate memory for string and header block - size_t size = sizeof(xml_memory_string_header) + length * sizeof(char_t); - - // round size up to pointer alignment boundary - size_t full_size = (size + (sizeof(void*) - 1)) & ~(sizeof(void*) - 1); - - xml_memory_page* page; - xml_memory_string_header* header = static_cast(allocate_memory(full_size, page)); - - if (!header) return 0; - - // setup header - ptrdiff_t page_offset = reinterpret_cast(header) - page->data; - - assert(page_offset >= 0 && page_offset < (1 << 16)); - header->page_offset = static_cast(page_offset); - - // full_size == 0 for large strings that occupy the whole page - assert(full_size < (1 << 16) || (page->busy_size == full_size && page_offset == 0)); - header->full_size = static_cast(full_size < (1 << 16) ? full_size : 0); - - // round-trip through void* to avoid 'cast increases required alignment of target type' warning - // header is guaranteed a pointer-sized alignment, which should be enough for char_t - return static_cast(static_cast(header + 1)); - } - - void deallocate_string(char_t* string) - { - // this function casts pointers through void* to avoid 'cast increases required alignment of target type' warnings - // we're guaranteed the proper (pointer-sized) alignment on the input string if it was allocated via allocate_string - - // get header - xml_memory_string_header* header = static_cast(static_cast(string)) - 1; - - // deallocate - size_t page_offset = offsetof(xml_memory_page, data) + header->page_offset; - xml_memory_page* page = reinterpret_cast(static_cast(reinterpret_cast(header) - page_offset)); - - // if full_size == 0 then this string occupies the whole page - size_t full_size = header->full_size == 0 ? page->busy_size : header->full_size; - - deallocate_memory(header, full_size, page); - } - - xml_memory_page* _root; - size_t _busy_size; - }; - - PUGI__FN_NO_INLINE void* xml_allocator::allocate_memory_oob(size_t size, xml_memory_page*& out_page) - { - const size_t large_allocation_threshold = xml_memory_page_size / 4; - - xml_memory_page* page = allocate_page(size <= large_allocation_threshold ? xml_memory_page_size : size); - out_page = page; - - if (!page) return 0; - - if (size <= large_allocation_threshold) - { - _root->busy_size = _busy_size; - - // insert page at the end of linked list - page->prev = _root; - _root->next = page; - _root = page; - - _busy_size = size; - } - else - { - // insert page before the end of linked list, so that it is deleted as soon as possible - // the last page is not deleted even if it's empty (see deallocate_memory) - assert(_root->prev); - - page->prev = _root->prev; - page->next = _root; - - _root->prev->next = page; - _root->prev = page; - } - - // allocate inside page - page->busy_size = size; - - return page->data; - } -PUGI__NS_END - -namespace pugi -{ - /// A 'name=value' XML attribute structure. - struct xml_attribute_struct - { - /// Default ctor - xml_attribute_struct(impl::xml_memory_page* page): header(reinterpret_cast(page)), name(0), value(0), prev_attribute_c(0), next_attribute(0) - { - } - - uintptr_t header; - - char_t* name; ///< Pointer to attribute name. - char_t* value; ///< Pointer to attribute value. - - xml_attribute_struct* prev_attribute_c; ///< Previous attribute (cyclic list) - xml_attribute_struct* next_attribute; ///< Next attribute - }; - - /// An XML document tree node. - struct xml_node_struct - { - /// Default ctor - /// \param type - node type - xml_node_struct(impl::xml_memory_page* page, xml_node_type type): header(reinterpret_cast(page) | (type - 1)), parent(0), name(0), value(0), first_child(0), prev_sibling_c(0), next_sibling(0), first_attribute(0) - { - } - - uintptr_t header; - - xml_node_struct* parent; ///< Pointer to parent - - char_t* name; ///< Pointer to element name. - char_t* value; ///< Pointer to any associated string data. - - xml_node_struct* first_child; ///< First child - - xml_node_struct* prev_sibling_c; ///< Left brother (cyclic list) - xml_node_struct* next_sibling; ///< Right brother - - xml_attribute_struct* first_attribute; ///< First attribute - }; -} - -PUGI__NS_BEGIN - struct xml_document_struct: public xml_node_struct, public xml_allocator - { - xml_document_struct(xml_memory_page* page): xml_node_struct(page, node_document), xml_allocator(page), buffer(0) - { - } - - const char_t* buffer; - }; - - inline xml_allocator& get_allocator(const xml_node_struct* node) - { - assert(node); - - return *reinterpret_cast(node->header & xml_memory_page_pointer_mask)->allocator; - } -PUGI__NS_END - -// Low-level DOM operations -PUGI__NS_BEGIN - inline xml_attribute_struct* allocate_attribute(xml_allocator& alloc) - { - xml_memory_page* page; - void* memory = alloc.allocate_memory(sizeof(xml_attribute_struct), page); - - return new (memory) xml_attribute_struct(page); - } - - inline xml_node_struct* allocate_node(xml_allocator& alloc, xml_node_type type) - { - xml_memory_page* page; - void* memory = alloc.allocate_memory(sizeof(xml_node_struct), page); - - return new (memory) xml_node_struct(page, type); - } - - inline void destroy_attribute(xml_attribute_struct* a, xml_allocator& alloc) - { - uintptr_t header = a->header; - - if (header & impl::xml_memory_page_name_allocated_mask) alloc.deallocate_string(a->name); - if (header & impl::xml_memory_page_value_allocated_mask) alloc.deallocate_string(a->value); - - alloc.deallocate_memory(a, sizeof(xml_attribute_struct), reinterpret_cast(header & xml_memory_page_pointer_mask)); - } - - inline void destroy_node(xml_node_struct* n, xml_allocator& alloc) - { - uintptr_t header = n->header; - - if (header & impl::xml_memory_page_name_allocated_mask) alloc.deallocate_string(n->name); - if (header & impl::xml_memory_page_value_allocated_mask) alloc.deallocate_string(n->value); - - for (xml_attribute_struct* attr = n->first_attribute; attr; ) - { - xml_attribute_struct* next = attr->next_attribute; - - destroy_attribute(attr, alloc); - - attr = next; - } - - for (xml_node_struct* child = n->first_child; child; ) - { - xml_node_struct* next = child->next_sibling; - - destroy_node(child, alloc); - - child = next; - } - - alloc.deallocate_memory(n, sizeof(xml_node_struct), reinterpret_cast(header & xml_memory_page_pointer_mask)); - } - - PUGI__FN_NO_INLINE xml_node_struct* append_node(xml_node_struct* node, xml_allocator& alloc, xml_node_type type = node_element) - { - xml_node_struct* child = allocate_node(alloc, type); - if (!child) return 0; - - child->parent = node; - - xml_node_struct* first_child = node->first_child; - - if (first_child) - { - xml_node_struct* last_child = first_child->prev_sibling_c; - - last_child->next_sibling = child; - child->prev_sibling_c = last_child; - first_child->prev_sibling_c = child; - } - else - { - node->first_child = child; - child->prev_sibling_c = child; - } - - return child; - } - - PUGI__FN_NO_INLINE xml_attribute_struct* append_attribute_ll(xml_node_struct* node, xml_allocator& alloc) - { - xml_attribute_struct* a = allocate_attribute(alloc); - if (!a) return 0; - - xml_attribute_struct* first_attribute = node->first_attribute; - - if (first_attribute) - { - xml_attribute_struct* last_attribute = first_attribute->prev_attribute_c; - - last_attribute->next_attribute = a; - a->prev_attribute_c = last_attribute; - first_attribute->prev_attribute_c = a; - } - else - { - node->first_attribute = a; - a->prev_attribute_c = a; - } - - return a; - } -PUGI__NS_END - -// Helper classes for code generation -PUGI__NS_BEGIN - struct opt_false - { - enum { value = 0 }; - }; - - struct opt_true - { - enum { value = 1 }; - }; -PUGI__NS_END - -// Unicode utilities -PUGI__NS_BEGIN - inline uint16_t endian_swap(uint16_t value) - { - return static_cast(((value & 0xff) << 8) | (value >> 8)); - } - - inline uint32_t endian_swap(uint32_t value) - { - return ((value & 0xff) << 24) | ((value & 0xff00) << 8) | ((value & 0xff0000) >> 8) | (value >> 24); - } - - struct utf8_counter - { - typedef size_t value_type; - - static value_type low(value_type result, uint32_t ch) - { - // U+0000..U+007F - if (ch < 0x80) return result + 1; - // U+0080..U+07FF - else if (ch < 0x800) return result + 2; - // U+0800..U+FFFF - else return result + 3; - } - - static value_type high(value_type result, uint32_t) - { - // U+10000..U+10FFFF - return result + 4; - } - }; - - struct utf8_writer - { - typedef uint8_t* value_type; - - static value_type low(value_type result, uint32_t ch) - { - // U+0000..U+007F - if (ch < 0x80) - { - *result = static_cast(ch); - return result + 1; - } - // U+0080..U+07FF - else if (ch < 0x800) - { - result[0] = static_cast(0xC0 | (ch >> 6)); - result[1] = static_cast(0x80 | (ch & 0x3F)); - return result + 2; - } - // U+0800..U+FFFF - else - { - result[0] = static_cast(0xE0 | (ch >> 12)); - result[1] = static_cast(0x80 | ((ch >> 6) & 0x3F)); - result[2] = static_cast(0x80 | (ch & 0x3F)); - return result + 3; - } - } - - static value_type high(value_type result, uint32_t ch) - { - // U+10000..U+10FFFF - result[0] = static_cast(0xF0 | (ch >> 18)); - result[1] = static_cast(0x80 | ((ch >> 12) & 0x3F)); - result[2] = static_cast(0x80 | ((ch >> 6) & 0x3F)); - result[3] = static_cast(0x80 | (ch & 0x3F)); - return result + 4; - } - - static value_type any(value_type result, uint32_t ch) - { - return (ch < 0x10000) ? low(result, ch) : high(result, ch); - } - }; - - struct utf16_counter - { - typedef size_t value_type; - - static value_type low(value_type result, uint32_t) - { - return result + 1; - } - - static value_type high(value_type result, uint32_t) - { - return result + 2; - } - }; - - struct utf16_writer - { - typedef uint16_t* value_type; - - static value_type low(value_type result, uint32_t ch) - { - *result = static_cast(ch); - - return result + 1; - } - - static value_type high(value_type result, uint32_t ch) - { - uint32_t msh = static_cast(ch - 0x10000) >> 10; - uint32_t lsh = static_cast(ch - 0x10000) & 0x3ff; - - result[0] = static_cast(0xD800 + msh); - result[1] = static_cast(0xDC00 + lsh); - - return result + 2; - } - - static value_type any(value_type result, uint32_t ch) - { - return (ch < 0x10000) ? low(result, ch) : high(result, ch); - } - }; - - struct utf32_counter - { - typedef size_t value_type; - - static value_type low(value_type result, uint32_t) - { - return result + 1; - } - - static value_type high(value_type result, uint32_t) - { - return result + 1; - } - }; - - struct utf32_writer - { - typedef uint32_t* value_type; - - static value_type low(value_type result, uint32_t ch) - { - *result = ch; - - return result + 1; - } - - static value_type high(value_type result, uint32_t ch) - { - *result = ch; - - return result + 1; - } - - static value_type any(value_type result, uint32_t ch) - { - *result = ch; - - return result + 1; - } - }; - - struct latin1_writer - { - typedef uint8_t* value_type; - - static value_type low(value_type result, uint32_t ch) - { - *result = static_cast(ch > 255 ? '?' : ch); - - return result + 1; - } - - static value_type high(value_type result, uint32_t ch) - { - (void)ch; - - *result = '?'; - - return result + 1; - } - }; - - template struct wchar_selector; - - template <> struct wchar_selector<2> - { - typedef uint16_t type; - typedef utf16_counter counter; - typedef utf16_writer writer; - }; - - template <> struct wchar_selector<4> - { - typedef uint32_t type; - typedef utf32_counter counter; - typedef utf32_writer writer; - }; - - typedef wchar_selector::counter wchar_counter; - typedef wchar_selector::writer wchar_writer; - - template struct utf_decoder - { - static inline typename Traits::value_type decode_utf8_block(const uint8_t* data, size_t size, typename Traits::value_type result) - { - const uint8_t utf8_byte_mask = 0x3f; - - while (size) - { - uint8_t lead = *data; - - // 0xxxxxxx -> U+0000..U+007F - if (lead < 0x80) - { - result = Traits::low(result, lead); - data += 1; - size -= 1; - - // process aligned single-byte (ascii) blocks - if ((reinterpret_cast(data) & 3) == 0) - { - // round-trip through void* to silence 'cast increases required alignment of target type' warnings - while (size >= 4 && (*static_cast(static_cast(data)) & 0x80808080) == 0) - { - result = Traits::low(result, data[0]); - result = Traits::low(result, data[1]); - result = Traits::low(result, data[2]); - result = Traits::low(result, data[3]); - data += 4; - size -= 4; - } - } - } - // 110xxxxx -> U+0080..U+07FF - else if (static_cast(lead - 0xC0) < 0x20 && size >= 2 && (data[1] & 0xc0) == 0x80) - { - result = Traits::low(result, ((lead & ~0xC0) << 6) | (data[1] & utf8_byte_mask)); - data += 2; - size -= 2; - } - // 1110xxxx -> U+0800-U+FFFF - else if (static_cast(lead - 0xE0) < 0x10 && size >= 3 && (data[1] & 0xc0) == 0x80 && (data[2] & 0xc0) == 0x80) - { - result = Traits::low(result, ((lead & ~0xE0) << 12) | ((data[1] & utf8_byte_mask) << 6) | (data[2] & utf8_byte_mask)); - data += 3; - size -= 3; - } - // 11110xxx -> U+10000..U+10FFFF - else if (static_cast(lead - 0xF0) < 0x08 && size >= 4 && (data[1] & 0xc0) == 0x80 && (data[2] & 0xc0) == 0x80 && (data[3] & 0xc0) == 0x80) - { - result = Traits::high(result, ((lead & ~0xF0) << 18) | ((data[1] & utf8_byte_mask) << 12) | ((data[2] & utf8_byte_mask) << 6) | (data[3] & utf8_byte_mask)); - data += 4; - size -= 4; - } - // 10xxxxxx or 11111xxx -> invalid - else - { - data += 1; - size -= 1; - } - } - - return result; - } - - static inline typename Traits::value_type decode_utf16_block(const uint16_t* data, size_t size, typename Traits::value_type result) - { - const uint16_t* end = data + size; - - while (data < end) - { - uint16_t lead = opt_swap::value ? endian_swap(*data) : *data; - - // U+0000..U+D7FF - if (lead < 0xD800) - { - result = Traits::low(result, lead); - data += 1; - } - // U+E000..U+FFFF - else if (static_cast(lead - 0xE000) < 0x2000) - { - result = Traits::low(result, lead); - data += 1; - } - // surrogate pair lead - else if (static_cast(lead - 0xD800) < 0x400 && data + 1 < end) - { - uint16_t next = opt_swap::value ? endian_swap(data[1]) : data[1]; - - if (static_cast(next - 0xDC00) < 0x400) - { - result = Traits::high(result, 0x10000 + ((lead & 0x3ff) << 10) + (next & 0x3ff)); - data += 2; - } - else - { - data += 1; - } - } - else - { - data += 1; - } - } - - return result; - } - - static inline typename Traits::value_type decode_utf32_block(const uint32_t* data, size_t size, typename Traits::value_type result) - { - const uint32_t* end = data + size; - - while (data < end) - { - uint32_t lead = opt_swap::value ? endian_swap(*data) : *data; - - // U+0000..U+FFFF - if (lead < 0x10000) - { - result = Traits::low(result, lead); - data += 1; - } - // U+10000..U+10FFFF - else - { - result = Traits::high(result, lead); - data += 1; - } - } - - return result; - } - - static inline typename Traits::value_type decode_latin1_block(const uint8_t* data, size_t size, typename Traits::value_type result) - { - for (size_t i = 0; i < size; ++i) - { - result = Traits::low(result, data[i]); - } - - return result; - } - - static inline typename Traits::value_type decode_wchar_block_impl(const uint16_t* data, size_t size, typename Traits::value_type result) - { - return decode_utf16_block(data, size, result); - } - - static inline typename Traits::value_type decode_wchar_block_impl(const uint32_t* data, size_t size, typename Traits::value_type result) - { - return decode_utf32_block(data, size, result); - } - - static inline typename Traits::value_type decode_wchar_block(const wchar_t* data, size_t size, typename Traits::value_type result) - { - return decode_wchar_block_impl(reinterpret_cast::type*>(data), size, result); - } - }; - - template PUGI__FN void convert_utf_endian_swap(T* result, const T* data, size_t length) - { - for (size_t i = 0; i < length; ++i) result[i] = endian_swap(data[i]); - } - -#ifdef PUGIXML_WCHAR_MODE - PUGI__FN void convert_wchar_endian_swap(wchar_t* result, const wchar_t* data, size_t length) - { - for (size_t i = 0; i < length; ++i) result[i] = static_cast(endian_swap(static_cast::type>(data[i]))); - } -#endif -PUGI__NS_END - -PUGI__NS_BEGIN - enum chartype_t - { - ct_parse_pcdata = 1, // \0, &, \r, < - ct_parse_attr = 2, // \0, &, \r, ', " - ct_parse_attr_ws = 4, // \0, &, \r, ', ", \n, tab - ct_space = 8, // \r, \n, space, tab - ct_parse_cdata = 16, // \0, ], >, \r - ct_parse_comment = 32, // \0, -, >, \r - ct_symbol = 64, // Any symbol > 127, a-z, A-Z, 0-9, _, :, -, . - ct_start_symbol = 128 // Any symbol > 127, a-z, A-Z, _, : - }; - - static const unsigned char chartype_table[256] = - { - 55, 0, 0, 0, 0, 0, 0, 0, 0, 12, 12, 0, 0, 63, 0, 0, // 0-15 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16-31 - 8, 0, 6, 0, 0, 0, 7, 6, 0, 0, 0, 0, 0, 96, 64, 0, // 32-47 - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 192, 0, 1, 0, 48, 0, // 48-63 - 0, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, // 64-79 - 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 0, 0, 16, 0, 192, // 80-95 - 0, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, // 96-111 - 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 0, 0, 0, 0, 0, // 112-127 - - 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, // 128+ - 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192 - }; - - enum chartypex_t - { - ctx_special_pcdata = 1, // Any symbol >= 0 and < 32 (except \t, \r, \n), &, <, > - ctx_special_attr = 2, // Any symbol >= 0 and < 32 (except \t), &, <, >, " - ctx_start_symbol = 4, // Any symbol > 127, a-z, A-Z, _ - ctx_digit = 8, // 0-9 - ctx_symbol = 16 // Any symbol > 127, a-z, A-Z, 0-9, _, -, . - }; - - static const unsigned char chartypex_table[256] = - { - 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 2, 3, 3, 2, 3, 3, // 0-15 - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 16-31 - 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 16, 16, 0, // 32-47 - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 3, 0, 3, 0, // 48-63 - - 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, // 64-79 - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 20, // 80-95 - 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, // 96-111 - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, // 112-127 - - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, // 128+ - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20 - }; - -#ifdef PUGIXML_WCHAR_MODE - #define PUGI__IS_CHARTYPE_IMPL(c, ct, table) ((static_cast(c) < 128 ? table[static_cast(c)] : table[128]) & (ct)) -#else - #define PUGI__IS_CHARTYPE_IMPL(c, ct, table) (table[static_cast(c)] & (ct)) -#endif - - #define PUGI__IS_CHARTYPE(c, ct) PUGI__IS_CHARTYPE_IMPL(c, ct, chartype_table) - #define PUGI__IS_CHARTYPEX(c, ct) PUGI__IS_CHARTYPE_IMPL(c, ct, chartypex_table) - - PUGI__FN bool is_little_endian() - { - unsigned int ui = 1; - - return *reinterpret_cast(&ui) == 1; - } - - PUGI__FN xml_encoding get_wchar_encoding() - { - PUGI__STATIC_ASSERT(sizeof(wchar_t) == 2 || sizeof(wchar_t) == 4); - - if (sizeof(wchar_t) == 2) - return is_little_endian() ? encoding_utf16_le : encoding_utf16_be; - else - return is_little_endian() ? encoding_utf32_le : encoding_utf32_be; - } - - PUGI__FN xml_encoding guess_buffer_encoding(uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3) - { - // look for BOM in first few bytes - if (d0 == 0 && d1 == 0 && d2 == 0xfe && d3 == 0xff) return encoding_utf32_be; - if (d0 == 0xff && d1 == 0xfe && d2 == 0 && d3 == 0) return encoding_utf32_le; - if (d0 == 0xfe && d1 == 0xff) return encoding_utf16_be; - if (d0 == 0xff && d1 == 0xfe) return encoding_utf16_le; - if (d0 == 0xef && d1 == 0xbb && d2 == 0xbf) return encoding_utf8; - - // look for <, (contents); - - PUGI__DMC_VOLATILE uint8_t d0 = data[0], d1 = data[1], d2 = data[2], d3 = data[3]; - - return guess_buffer_encoding(d0, d1, d2, d3); - } - - PUGI__FN bool get_mutable_buffer(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, bool is_mutable) - { - if (is_mutable) - { - out_buffer = static_cast(const_cast(contents)); - } - else - { - void* buffer = xml_memory::allocate(size > 0 ? size : 1); - if (!buffer) return false; - - memcpy(buffer, contents, size); - - out_buffer = static_cast(buffer); - } - - out_length = size / sizeof(char_t); - - return true; - } - -#ifdef PUGIXML_WCHAR_MODE - PUGI__FN bool need_endian_swap_utf(xml_encoding le, xml_encoding re) - { - return (le == encoding_utf16_be && re == encoding_utf16_le) || (le == encoding_utf16_le && re == encoding_utf16_be) || - (le == encoding_utf32_be && re == encoding_utf32_le) || (le == encoding_utf32_le && re == encoding_utf32_be); - } - - PUGI__FN bool convert_buffer_endian_swap(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, bool is_mutable) - { - const char_t* data = static_cast(contents); - - if (is_mutable) - { - out_buffer = const_cast(data); - } - else - { - out_buffer = static_cast(xml_memory::allocate(size > 0 ? size : 1)); - if (!out_buffer) return false; - } - - out_length = size / sizeof(char_t); - - convert_wchar_endian_swap(out_buffer, data, out_length); - - return true; - } - - PUGI__FN bool convert_buffer_utf8(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size) - { - const uint8_t* data = static_cast(contents); - - // first pass: get length in wchar_t units - out_length = utf_decoder::decode_utf8_block(data, size, 0); - - // allocate buffer of suitable length - out_buffer = static_cast(xml_memory::allocate((out_length > 0 ? out_length : 1) * sizeof(char_t))); - if (!out_buffer) return false; - - // second pass: convert utf8 input to wchar_t - wchar_writer::value_type out_begin = reinterpret_cast(out_buffer); - wchar_writer::value_type out_end = utf_decoder::decode_utf8_block(data, size, out_begin); - - assert(out_end == out_begin + out_length); - (void)!out_end; - - return true; - } - - template PUGI__FN bool convert_buffer_utf16(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, opt_swap) - { - const uint16_t* data = static_cast(contents); - size_t length = size / sizeof(uint16_t); - - // first pass: get length in wchar_t units - out_length = utf_decoder::decode_utf16_block(data, length, 0); - - // allocate buffer of suitable length - out_buffer = static_cast(xml_memory::allocate((out_length > 0 ? out_length : 1) * sizeof(char_t))); - if (!out_buffer) return false; - - // second pass: convert utf16 input to wchar_t - wchar_writer::value_type out_begin = reinterpret_cast(out_buffer); - wchar_writer::value_type out_end = utf_decoder::decode_utf16_block(data, length, out_begin); - - assert(out_end == out_begin + out_length); - (void)!out_end; - - return true; - } - - template PUGI__FN bool convert_buffer_utf32(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, opt_swap) - { - const uint32_t* data = static_cast(contents); - size_t length = size / sizeof(uint32_t); - - // first pass: get length in wchar_t units - out_length = utf_decoder::decode_utf32_block(data, length, 0); - - // allocate buffer of suitable length - out_buffer = static_cast(xml_memory::allocate((out_length > 0 ? out_length : 1) * sizeof(char_t))); - if (!out_buffer) return false; - - // second pass: convert utf32 input to wchar_t - wchar_writer::value_type out_begin = reinterpret_cast(out_buffer); - wchar_writer::value_type out_end = utf_decoder::decode_utf32_block(data, length, out_begin); - - assert(out_end == out_begin + out_length); - (void)!out_end; - - return true; - } - - PUGI__FN bool convert_buffer_latin1(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size) - { - const uint8_t* data = static_cast(contents); - - // get length in wchar_t units - out_length = size; - - // allocate buffer of suitable length - out_buffer = static_cast(xml_memory::allocate((out_length > 0 ? out_length : 1) * sizeof(char_t))); - if (!out_buffer) return false; - - // convert latin1 input to wchar_t - wchar_writer::value_type out_begin = reinterpret_cast(out_buffer); - wchar_writer::value_type out_end = utf_decoder::decode_latin1_block(data, size, out_begin); - - assert(out_end == out_begin + out_length); - (void)!out_end; - - return true; - } - - PUGI__FN bool convert_buffer(char_t*& out_buffer, size_t& out_length, xml_encoding encoding, const void* contents, size_t size, bool is_mutable) - { - // get native encoding - xml_encoding wchar_encoding = get_wchar_encoding(); - - // fast path: no conversion required - if (encoding == wchar_encoding) return get_mutable_buffer(out_buffer, out_length, contents, size, is_mutable); - - // only endian-swapping is required - if (need_endian_swap_utf(encoding, wchar_encoding)) return convert_buffer_endian_swap(out_buffer, out_length, contents, size, is_mutable); - - // source encoding is utf8 - if (encoding == encoding_utf8) return convert_buffer_utf8(out_buffer, out_length, contents, size); - - // source encoding is utf16 - if (encoding == encoding_utf16_be || encoding == encoding_utf16_le) - { - xml_encoding native_encoding = is_little_endian() ? encoding_utf16_le : encoding_utf16_be; - - return (native_encoding == encoding) ? - convert_buffer_utf16(out_buffer, out_length, contents, size, opt_false()) : - convert_buffer_utf16(out_buffer, out_length, contents, size, opt_true()); - } - - // source encoding is utf32 - if (encoding == encoding_utf32_be || encoding == encoding_utf32_le) - { - xml_encoding native_encoding = is_little_endian() ? encoding_utf32_le : encoding_utf32_be; - - return (native_encoding == encoding) ? - convert_buffer_utf32(out_buffer, out_length, contents, size, opt_false()) : - convert_buffer_utf32(out_buffer, out_length, contents, size, opt_true()); - } - - // source encoding is latin1 - if (encoding == encoding_latin1) return convert_buffer_latin1(out_buffer, out_length, contents, size); - - assert(!"Invalid encoding"); - return false; - } -#else - template PUGI__FN bool convert_buffer_utf16(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, opt_swap) - { - const uint16_t* data = static_cast(contents); - size_t length = size / sizeof(uint16_t); - - // first pass: get length in utf8 units - out_length = utf_decoder::decode_utf16_block(data, length, 0); - - // allocate buffer of suitable length - out_buffer = static_cast(xml_memory::allocate((out_length > 0 ? out_length : 1) * sizeof(char_t))); - if (!out_buffer) return false; - - // second pass: convert utf16 input to utf8 - uint8_t* out_begin = reinterpret_cast(out_buffer); - uint8_t* out_end = utf_decoder::decode_utf16_block(data, length, out_begin); - - assert(out_end == out_begin + out_length); - (void)!out_end; - - return true; - } - - template PUGI__FN bool convert_buffer_utf32(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, opt_swap) - { - const uint32_t* data = static_cast(contents); - size_t length = size / sizeof(uint32_t); - - // first pass: get length in utf8 units - out_length = utf_decoder::decode_utf32_block(data, length, 0); - - // allocate buffer of suitable length - out_buffer = static_cast(xml_memory::allocate((out_length > 0 ? out_length : 1) * sizeof(char_t))); - if (!out_buffer) return false; - - // second pass: convert utf32 input to utf8 - uint8_t* out_begin = reinterpret_cast(out_buffer); - uint8_t* out_end = utf_decoder::decode_utf32_block(data, length, out_begin); - - assert(out_end == out_begin + out_length); - (void)!out_end; - - return true; - } - - PUGI__FN size_t get_latin1_7bit_prefix_length(const uint8_t* data, size_t size) - { - for (size_t i = 0; i < size; ++i) - if (data[i] > 127) - return i; - - return size; - } - - PUGI__FN bool convert_buffer_latin1(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, bool is_mutable) - { - const uint8_t* data = static_cast(contents); - - // get size of prefix that does not need utf8 conversion - size_t prefix_length = get_latin1_7bit_prefix_length(data, size); - assert(prefix_length <= size); - - const uint8_t* postfix = data + prefix_length; - size_t postfix_length = size - prefix_length; - - // if no conversion is needed, just return the original buffer - if (postfix_length == 0) return get_mutable_buffer(out_buffer, out_length, contents, size, is_mutable); - - // first pass: get length in utf8 units - out_length = prefix_length + utf_decoder::decode_latin1_block(postfix, postfix_length, 0); - - // allocate buffer of suitable length - out_buffer = static_cast(xml_memory::allocate((out_length > 0 ? out_length : 1) * sizeof(char_t))); - if (!out_buffer) return false; - - // second pass: convert latin1 input to utf8 - memcpy(out_buffer, data, prefix_length); - - uint8_t* out_begin = reinterpret_cast(out_buffer); - uint8_t* out_end = utf_decoder::decode_latin1_block(postfix, postfix_length, out_begin + prefix_length); - - assert(out_end == out_begin + out_length); - (void)!out_end; - - return true; - } - - PUGI__FN bool convert_buffer(char_t*& out_buffer, size_t& out_length, xml_encoding encoding, const void* contents, size_t size, bool is_mutable) - { - // fast path: no conversion required - if (encoding == encoding_utf8) return get_mutable_buffer(out_buffer, out_length, contents, size, is_mutable); - - // source encoding is utf16 - if (encoding == encoding_utf16_be || encoding == encoding_utf16_le) - { - xml_encoding native_encoding = is_little_endian() ? encoding_utf16_le : encoding_utf16_be; - - return (native_encoding == encoding) ? - convert_buffer_utf16(out_buffer, out_length, contents, size, opt_false()) : - convert_buffer_utf16(out_buffer, out_length, contents, size, opt_true()); - } - - // source encoding is utf32 - if (encoding == encoding_utf32_be || encoding == encoding_utf32_le) - { - xml_encoding native_encoding = is_little_endian() ? encoding_utf32_le : encoding_utf32_be; - - return (native_encoding == encoding) ? - convert_buffer_utf32(out_buffer, out_length, contents, size, opt_false()) : - convert_buffer_utf32(out_buffer, out_length, contents, size, opt_true()); - } - - // source encoding is latin1 - if (encoding == encoding_latin1) return convert_buffer_latin1(out_buffer, out_length, contents, size, is_mutable); - - assert(!"Invalid encoding"); - return false; - } -#endif - - PUGI__FN size_t as_utf8_begin(const wchar_t* str, size_t length) - { - // get length in utf8 characters - return utf_decoder::decode_wchar_block(str, length, 0); - } - - PUGI__FN void as_utf8_end(char* buffer, size_t size, const wchar_t* str, size_t length) - { - // convert to utf8 - uint8_t* begin = reinterpret_cast(buffer); - uint8_t* end = utf_decoder::decode_wchar_block(str, length, begin); - - assert(begin + size == end); - (void)!end; - - // zero-terminate - buffer[size] = 0; - } - -#ifndef PUGIXML_NO_STL - PUGI__FN std::string as_utf8_impl(const wchar_t* str, size_t length) - { - // first pass: get length in utf8 characters - size_t size = as_utf8_begin(str, length); - - // allocate resulting string - std::string result; - result.resize(size); - - // second pass: convert to utf8 - if (size > 0) as_utf8_end(&result[0], size, str, length); - - return result; - } - - PUGI__FN std::basic_string as_wide_impl(const char* str, size_t size) - { - const uint8_t* data = reinterpret_cast(str); - - // first pass: get length in wchar_t units - size_t length = utf_decoder::decode_utf8_block(data, size, 0); - - // allocate resulting string - std::basic_string result; - result.resize(length); - - // second pass: convert to wchar_t - if (length > 0) - { - wchar_writer::value_type begin = reinterpret_cast(&result[0]); - wchar_writer::value_type end = utf_decoder::decode_utf8_block(data, size, begin); - - assert(begin + length == end); - (void)!end; - } - - return result; - } -#endif - - inline bool strcpy_insitu_allow(size_t length, uintptr_t allocated, char_t* target) - { - assert(target); - size_t target_length = strlength(target); - - // always reuse document buffer memory if possible - if (!allocated) return target_length >= length; - - // reuse heap memory if waste is not too great - const size_t reuse_threshold = 32; - - return target_length >= length && (target_length < reuse_threshold || target_length - length < target_length / 2); - } - - PUGI__FN bool strcpy_insitu(char_t*& dest, uintptr_t& header, uintptr_t header_mask, const char_t* source) - { - size_t source_length = strlength(source); - - if (source_length == 0) - { - // empty string and null pointer are equivalent, so just deallocate old memory - xml_allocator* alloc = reinterpret_cast(header & xml_memory_page_pointer_mask)->allocator; - - if (header & header_mask) alloc->deallocate_string(dest); - - // mark the string as not allocated - dest = 0; - header &= ~header_mask; - - return true; - } - else if (dest && strcpy_insitu_allow(source_length, header & header_mask, dest)) - { - // we can reuse old buffer, so just copy the new data (including zero terminator) - memcpy(dest, source, (source_length + 1) * sizeof(char_t)); - - return true; - } - else - { - xml_allocator* alloc = reinterpret_cast(header & xml_memory_page_pointer_mask)->allocator; - - // allocate new buffer - char_t* buf = alloc->allocate_string(source_length + 1); - if (!buf) return false; - - // copy the string (including zero terminator) - memcpy(buf, source, (source_length + 1) * sizeof(char_t)); - - // deallocate old buffer (*after* the above to protect against overlapping memory and/or allocation failures) - if (header & header_mask) alloc->deallocate_string(dest); - - // the string is now allocated, so set the flag - dest = buf; - header |= header_mask; - - return true; - } - } - - struct gap - { - char_t* end; - size_t size; - - gap(): end(0), size(0) - { - } - - // Push new gap, move s count bytes further (skipping the gap). - // Collapse previous gap. - void push(char_t*& s, size_t count) - { - if (end) // there was a gap already; collapse it - { - // Move [old_gap_end, new_gap_start) to [old_gap_start, ...) - assert(s >= end); - memmove(end - size, end, reinterpret_cast(s) - reinterpret_cast(end)); - } - - s += count; // end of current gap - - // "merge" two gaps - end = s; - size += count; - } - - // Collapse all gaps, return past-the-end pointer - char_t* flush(char_t* s) - { - if (end) - { - // Move [old_gap_end, current_pos) to [old_gap_start, ...) - assert(s >= end); - memmove(end - size, end, reinterpret_cast(s) - reinterpret_cast(end)); - - return s - size; - } - else return s; - } - }; - - PUGI__FN char_t* strconv_escape(char_t* s, gap& g) - { - char_t* stre = s + 1; - - switch (*stre) - { - case '#': // &#... - { - unsigned int ucsc = 0; - - if (stre[1] == 'x') // &#x... (hex code) - { - stre += 2; - - char_t ch = *stre; - - if (ch == ';') return stre; - - for (;;) - { - if (static_cast(ch - '0') <= 9) - ucsc = 16 * ucsc + (ch - '0'); - else if (static_cast((ch | ' ') - 'a') <= 5) - ucsc = 16 * ucsc + ((ch | ' ') - 'a' + 10); - else if (ch == ';') - break; - else // cancel - return stre; - - ch = *++stre; - } - - ++stre; - } - else // &#... (dec code) - { - char_t ch = *++stre; - - if (ch == ';') return stre; - - for (;;) - { - if (static_cast(ch - '0') <= 9) - ucsc = 10 * ucsc + (ch - '0'); - else if (ch == ';') - break; - else // cancel - return stre; - - ch = *++stre; - } - - ++stre; - } - - #ifdef PUGIXML_WCHAR_MODE - s = reinterpret_cast(wchar_writer::any(reinterpret_cast(s), ucsc)); - #else - s = reinterpret_cast(utf8_writer::any(reinterpret_cast(s), ucsc)); - #endif - - g.push(s, stre - s); - return stre; - } - - case 'a': // &a - { - ++stre; - - if (*stre == 'm') // &am - { - if (*++stre == 'p' && *++stre == ';') // & - { - *s++ = '&'; - ++stre; - - g.push(s, stre - s); - return stre; - } - } - else if (*stre == 'p') // &ap - { - if (*++stre == 'o' && *++stre == 's' && *++stre == ';') // ' - { - *s++ = '\''; - ++stre; - - g.push(s, stre - s); - return stre; - } - } - break; - } - - case 'g': // &g - { - if (*++stre == 't' && *++stre == ';') // > - { - *s++ = '>'; - ++stre; - - g.push(s, stre - s); - return stre; - } - break; - } - - case 'l': // &l - { - if (*++stre == 't' && *++stre == ';') // < - { - *s++ = '<'; - ++stre; - - g.push(s, stre - s); - return stre; - } - break; - } - - case 'q': // &q - { - if (*++stre == 'u' && *++stre == 'o' && *++stre == 't' && *++stre == ';') // " - { - *s++ = '"'; - ++stre; - - g.push(s, stre - s); - return stre; - } - break; - } - - default: - break; - } - - return stre; - } - - // Utility macro for last character handling - #define ENDSWITH(c, e) ((c) == (e) || ((c) == 0 && endch == (e))) - - PUGI__FN char_t* strconv_comment(char_t* s, char_t endch) - { - gap g; - - while (true) - { - while (!PUGI__IS_CHARTYPE(*s, ct_parse_comment)) ++s; - - if (*s == '\r') // Either a single 0x0d or 0x0d 0x0a pair - { - *s++ = '\n'; // replace first one with 0x0a - - if (*s == '\n') g.push(s, 1); - } - else if (s[0] == '-' && s[1] == '-' && ENDSWITH(s[2], '>')) // comment ends here - { - *g.flush(s) = 0; - - return s + (s[2] == '>' ? 3 : 2); - } - else if (*s == 0) - { - return 0; - } - else ++s; - } - } - - PUGI__FN char_t* strconv_cdata(char_t* s, char_t endch) - { - gap g; - - while (true) - { - while (!PUGI__IS_CHARTYPE(*s, ct_parse_cdata)) ++s; - - if (*s == '\r') // Either a single 0x0d or 0x0d 0x0a pair - { - *s++ = '\n'; // replace first one with 0x0a - - if (*s == '\n') g.push(s, 1); - } - else if (s[0] == ']' && s[1] == ']' && ENDSWITH(s[2], '>')) // CDATA ends here - { - *g.flush(s) = 0; - - return s + 1; - } - else if (*s == 0) - { - return 0; - } - else ++s; - } - } - - typedef char_t* (*strconv_pcdata_t)(char_t*); - - template struct strconv_pcdata_impl - { - static char_t* parse(char_t* s) - { - gap g; - - while (true) - { - while (!PUGI__IS_CHARTYPE(*s, ct_parse_pcdata)) ++s; - - if (*s == '<') // PCDATA ends here - { - *g.flush(s) = 0; - - return s + 1; - } - else if (opt_eol::value && *s == '\r') // Either a single 0x0d or 0x0d 0x0a pair - { - *s++ = '\n'; // replace first one with 0x0a - - if (*s == '\n') g.push(s, 1); - } - else if (opt_escape::value && *s == '&') - { - s = strconv_escape(s, g); - } - else if (*s == 0) - { - return s; - } - else ++s; - } - } - }; - - PUGI__FN strconv_pcdata_t get_strconv_pcdata(unsigned int optmask) - { - PUGI__STATIC_ASSERT(parse_escapes == 0x10 && parse_eol == 0x20); - - switch ((optmask >> 4) & 3) // get bitmask for flags (eol escapes) - { - case 0: return strconv_pcdata_impl::parse; - case 1: return strconv_pcdata_impl::parse; - case 2: return strconv_pcdata_impl::parse; - case 3: return strconv_pcdata_impl::parse; - default: return 0; // should not get here - } - } - - typedef char_t* (*strconv_attribute_t)(char_t*, char_t); - - template struct strconv_attribute_impl - { - static char_t* parse_wnorm(char_t* s, char_t end_quote) - { - gap g; - - // trim leading whitespaces - if (PUGI__IS_CHARTYPE(*s, ct_space)) - { - char_t* str = s; - - do ++str; - while (PUGI__IS_CHARTYPE(*str, ct_space)); - - g.push(s, str - s); - } - - while (true) - { - while (!PUGI__IS_CHARTYPE(*s, ct_parse_attr_ws | ct_space)) ++s; - - if (*s == end_quote) - { - char_t* str = g.flush(s); - - do *str-- = 0; - while (PUGI__IS_CHARTYPE(*str, ct_space)); - - return s + 1; - } - else if (PUGI__IS_CHARTYPE(*s, ct_space)) - { - *s++ = ' '; - - if (PUGI__IS_CHARTYPE(*s, ct_space)) - { - char_t* str = s + 1; - while (PUGI__IS_CHARTYPE(*str, ct_space)) ++str; - - g.push(s, str - s); - } - } - else if (opt_escape::value && *s == '&') - { - s = strconv_escape(s, g); - } - else if (!*s) - { - return 0; - } - else ++s; - } - } - - static char_t* parse_wconv(char_t* s, char_t end_quote) - { - gap g; - - while (true) - { - while (!PUGI__IS_CHARTYPE(*s, ct_parse_attr_ws)) ++s; - - if (*s == end_quote) - { - *g.flush(s) = 0; - - return s + 1; - } - else if (PUGI__IS_CHARTYPE(*s, ct_space)) - { - if (*s == '\r') - { - *s++ = ' '; - - if (*s == '\n') g.push(s, 1); - } - else *s++ = ' '; - } - else if (opt_escape::value && *s == '&') - { - s = strconv_escape(s, g); - } - else if (!*s) - { - return 0; - } - else ++s; - } - } - - static char_t* parse_eol(char_t* s, char_t end_quote) - { - gap g; - - while (true) - { - while (!PUGI__IS_CHARTYPE(*s, ct_parse_attr)) ++s; - - if (*s == end_quote) - { - *g.flush(s) = 0; - - return s + 1; - } - else if (*s == '\r') - { - *s++ = '\n'; - - if (*s == '\n') g.push(s, 1); - } - else if (opt_escape::value && *s == '&') - { - s = strconv_escape(s, g); - } - else if (!*s) - { - return 0; - } - else ++s; - } - } - - static char_t* parse_simple(char_t* s, char_t end_quote) - { - gap g; - - while (true) - { - while (!PUGI__IS_CHARTYPE(*s, ct_parse_attr)) ++s; - - if (*s == end_quote) - { - *g.flush(s) = 0; - - return s + 1; - } - else if (opt_escape::value && *s == '&') - { - s = strconv_escape(s, g); - } - else if (!*s) - { - return 0; - } - else ++s; - } - } - }; - - PUGI__FN strconv_attribute_t get_strconv_attribute(unsigned int optmask) - { - PUGI__STATIC_ASSERT(parse_escapes == 0x10 && parse_eol == 0x20 && parse_wconv_attribute == 0x40 && parse_wnorm_attribute == 0x80); - - switch ((optmask >> 4) & 15) // get bitmask for flags (wconv wnorm eol escapes) - { - case 0: return strconv_attribute_impl::parse_simple; - case 1: return strconv_attribute_impl::parse_simple; - case 2: return strconv_attribute_impl::parse_eol; - case 3: return strconv_attribute_impl::parse_eol; - case 4: return strconv_attribute_impl::parse_wconv; - case 5: return strconv_attribute_impl::parse_wconv; - case 6: return strconv_attribute_impl::parse_wconv; - case 7: return strconv_attribute_impl::parse_wconv; - case 8: return strconv_attribute_impl::parse_wnorm; - case 9: return strconv_attribute_impl::parse_wnorm; - case 10: return strconv_attribute_impl::parse_wnorm; - case 11: return strconv_attribute_impl::parse_wnorm; - case 12: return strconv_attribute_impl::parse_wnorm; - case 13: return strconv_attribute_impl::parse_wnorm; - case 14: return strconv_attribute_impl::parse_wnorm; - case 15: return strconv_attribute_impl::parse_wnorm; - default: return 0; // should not get here - } - } - - inline xml_parse_result make_parse_result(xml_parse_status status, ptrdiff_t offset = 0) - { - xml_parse_result result; - result.status = status; - result.offset = offset; - - return result; - } - - struct xml_parser - { - xml_allocator alloc; - char_t* error_offset; - xml_parse_status error_status; - - // Parser utilities. - #define PUGI__SKIPWS() { while (PUGI__IS_CHARTYPE(*s, ct_space)) ++s; } - #define PUGI__OPTSET(OPT) ( optmsk & (OPT) ) - #define PUGI__PUSHNODE(TYPE) { cursor = append_node(cursor, alloc, TYPE); if (!cursor) PUGI__THROW_ERROR(status_out_of_memory, s); } - #define PUGI__POPNODE() { cursor = cursor->parent; } - #define PUGI__SCANFOR(X) { while (*s != 0 && !(X)) ++s; } - #define PUGI__SCANWHILE(X) { while ((X)) ++s; } - #define PUGI__ENDSEG() { ch = *s; *s = 0; ++s; } - #define PUGI__THROW_ERROR(err, m) return error_offset = m, error_status = err, static_cast(0) - #define PUGI__CHECK_ERROR(err, m) { if (*s == 0) PUGI__THROW_ERROR(err, m); } - - xml_parser(const xml_allocator& alloc_): alloc(alloc_), error_offset(0), error_status(status_ok) - { - } - - // DOCTYPE consists of nested sections of the following possible types: - // , , "...", '...' - // - // - // First group can not contain nested groups - // Second group can contain nested groups of the same type - // Third group can contain all other groups - char_t* parse_doctype_primitive(char_t* s) - { - if (*s == '"' || *s == '\'') - { - // quoted string - char_t ch = *s++; - PUGI__SCANFOR(*s == ch); - if (!*s) PUGI__THROW_ERROR(status_bad_doctype, s); - - s++; - } - else if (s[0] == '<' && s[1] == '?') - { - // - s += 2; - PUGI__SCANFOR(s[0] == '?' && s[1] == '>'); // no need for ENDSWITH because ?> can't terminate proper doctype - if (!*s) PUGI__THROW_ERROR(status_bad_doctype, s); - - s += 2; - } - else if (s[0] == '<' && s[1] == '!' && s[2] == '-' && s[3] == '-') - { - s += 4; - PUGI__SCANFOR(s[0] == '-' && s[1] == '-' && s[2] == '>'); // no need for ENDSWITH because --> can't terminate proper doctype - if (!*s) PUGI__THROW_ERROR(status_bad_doctype, s); - - s += 4; - } - else PUGI__THROW_ERROR(status_bad_doctype, s); - - return s; - } - - char_t* parse_doctype_ignore(char_t* s) - { - assert(s[0] == '<' && s[1] == '!' && s[2] == '['); - s++; - - while (*s) - { - if (s[0] == '<' && s[1] == '!' && s[2] == '[') - { - // nested ignore section - s = parse_doctype_ignore(s); - if (!s) return s; - } - else if (s[0] == ']' && s[1] == ']' && s[2] == '>') - { - // ignore section end - s += 3; - - return s; - } - else s++; - } - - PUGI__THROW_ERROR(status_bad_doctype, s); - } - - char_t* parse_doctype_group(char_t* s, char_t endch, bool toplevel) - { - assert(s[0] == '<' && s[1] == '!'); - s++; - - while (*s) - { - if (s[0] == '<' && s[1] == '!' && s[2] != '-') - { - if (s[2] == '[') - { - // ignore - s = parse_doctype_ignore(s); - if (!s) return s; - } - else - { - // some control group - s = parse_doctype_group(s, endch, false); - if (!s) return s; - } - } - else if (s[0] == '<' || s[0] == '"' || s[0] == '\'') - { - // unknown tag (forbidden), or some primitive group - s = parse_doctype_primitive(s); - if (!s) return s; - } - else if (*s == '>') - { - s++; - - return s; - } - else s++; - } - - if (!toplevel || endch != '>') PUGI__THROW_ERROR(status_bad_doctype, s); - - return s; - } - - char_t* parse_exclamation(char_t* s, xml_node_struct* cursor, unsigned int optmsk, char_t endch) - { - // parse node contents, starting with exclamation mark - ++s; - - if (*s == '-') // 'value = s; // Save the offset. - } - - if (PUGI__OPTSET(parse_eol) && PUGI__OPTSET(parse_comments)) - { - s = strconv_comment(s, endch); - - if (!s) PUGI__THROW_ERROR(status_bad_comment, cursor->value); - } - else - { - // Scan for terminating '-->'. - PUGI__SCANFOR(s[0] == '-' && s[1] == '-' && ENDSWITH(s[2], '>')); - PUGI__CHECK_ERROR(status_bad_comment, s); - - if (PUGI__OPTSET(parse_comments)) - *s = 0; // Zero-terminate this segment at the first terminating '-'. - - s += (s[2] == '>' ? 3 : 2); // Step over the '\0->'. - } - } - else PUGI__THROW_ERROR(status_bad_comment, s); - } - else if (*s == '[') - { - // 'value = s; // Save the offset. - - if (PUGI__OPTSET(parse_eol)) - { - s = strconv_cdata(s, endch); - - if (!s) PUGI__THROW_ERROR(status_bad_cdata, cursor->value); - } - else - { - // Scan for terminating ']]>'. - PUGI__SCANFOR(s[0] == ']' && s[1] == ']' && ENDSWITH(s[2], '>')); - PUGI__CHECK_ERROR(status_bad_cdata, s); - - *s++ = 0; // Zero-terminate this segment. - } - } - else // Flagged for discard, but we still have to scan for the terminator. - { - // Scan for terminating ']]>'. - PUGI__SCANFOR(s[0] == ']' && s[1] == ']' && ENDSWITH(s[2], '>')); - PUGI__CHECK_ERROR(status_bad_cdata, s); - - ++s; - } - - s += (s[1] == '>' ? 2 : 1); // Step over the last ']>'. - } - else PUGI__THROW_ERROR(status_bad_cdata, s); - } - else if (s[0] == 'D' && s[1] == 'O' && s[2] == 'C' && s[3] == 'T' && s[4] == 'Y' && s[5] == 'P' && ENDSWITH(s[6], 'E')) - { - s -= 2; - - if (cursor->parent) PUGI__THROW_ERROR(status_bad_doctype, s); - - char_t* mark = s + 9; - - s = parse_doctype_group(s, endch, true); - if (!s) return s; - - if (PUGI__OPTSET(parse_doctype)) - { - while (PUGI__IS_CHARTYPE(*mark, ct_space)) ++mark; - - PUGI__PUSHNODE(node_doctype); - - cursor->value = mark; - - assert((s[0] == 0 && endch == '>') || s[-1] == '>'); - s[*s == 0 ? 0 : -1] = 0; - - PUGI__POPNODE(); - } - } - else if (*s == 0 && endch == '-') PUGI__THROW_ERROR(status_bad_comment, s); - else if (*s == 0 && endch == '[') PUGI__THROW_ERROR(status_bad_cdata, s); - else PUGI__THROW_ERROR(status_unrecognized_tag, s); - - return s; - } - - char_t* parse_question(char_t* s, xml_node_struct*& ref_cursor, unsigned int optmsk, char_t endch) - { - // load into registers - xml_node_struct* cursor = ref_cursor; - char_t ch = 0; - - // parse node contents, starting with question mark - ++s; - - // read PI target - char_t* target = s; - - if (!PUGI__IS_CHARTYPE(*s, ct_start_symbol)) PUGI__THROW_ERROR(status_bad_pi, s); - - PUGI__SCANWHILE(PUGI__IS_CHARTYPE(*s, ct_symbol)); - PUGI__CHECK_ERROR(status_bad_pi, s); - - // determine node type; stricmp / strcasecmp is not portable - bool declaration = (target[0] | ' ') == 'x' && (target[1] | ' ') == 'm' && (target[2] | ' ') == 'l' && target + 3 == s; - - if (declaration ? PUGI__OPTSET(parse_declaration) : PUGI__OPTSET(parse_pi)) - { - if (declaration) - { - // disallow non top-level declarations - if (cursor->parent) PUGI__THROW_ERROR(status_bad_pi, s); - - PUGI__PUSHNODE(node_declaration); - } - else - { - PUGI__PUSHNODE(node_pi); - } - - cursor->name = target; - - PUGI__ENDSEG(); - - // parse value/attributes - if (ch == '?') - { - // empty node - if (!ENDSWITH(*s, '>')) PUGI__THROW_ERROR(status_bad_pi, s); - s += (*s == '>'); - - PUGI__POPNODE(); - } - else if (PUGI__IS_CHARTYPE(ch, ct_space)) - { - PUGI__SKIPWS(); - - // scan for tag end - char_t* value = s; - - PUGI__SCANFOR(s[0] == '?' && ENDSWITH(s[1], '>')); - PUGI__CHECK_ERROR(status_bad_pi, s); - - if (declaration) - { - // replace ending ? with / so that 'element' terminates properly - *s = '/'; - - // we exit from this function with cursor at node_declaration, which is a signal to parse() to go to LOC_ATTRIBUTES - s = value; - } - else - { - // store value and step over > - cursor->value = value; - PUGI__POPNODE(); - - PUGI__ENDSEG(); - - s += (*s == '>'); - } - } - else PUGI__THROW_ERROR(status_bad_pi, s); - } - else - { - // scan for tag end - PUGI__SCANFOR(s[0] == '?' && ENDSWITH(s[1], '>')); - PUGI__CHECK_ERROR(status_bad_pi, s); - - s += (s[1] == '>' ? 2 : 1); - } - - // store from registers - ref_cursor = cursor; - - return s; - } - - char_t* parse(char_t* s, xml_node_struct* xmldoc, unsigned int optmsk, char_t endch) - { - strconv_attribute_t strconv_attribute = get_strconv_attribute(optmsk); - strconv_pcdata_t strconv_pcdata = get_strconv_pcdata(optmsk); - - char_t ch = 0; - xml_node_struct* cursor = xmldoc; - char_t* mark = s; - - while (*s != 0) - { - if (*s == '<') - { - ++s; - - LOC_TAG: - if (PUGI__IS_CHARTYPE(*s, ct_start_symbol)) // '<#...' - { - PUGI__PUSHNODE(node_element); // Append a new node to the tree. - - cursor->name = s; - - PUGI__SCANWHILE(PUGI__IS_CHARTYPE(*s, ct_symbol)); // Scan for a terminator. - PUGI__ENDSEG(); // Save char in 'ch', terminate & step over. - - if (ch == '>') - { - // end of tag - } - else if (PUGI__IS_CHARTYPE(ch, ct_space)) - { - LOC_ATTRIBUTES: - while (true) - { - PUGI__SKIPWS(); // Eat any whitespace. - - if (PUGI__IS_CHARTYPE(*s, ct_start_symbol)) // <... #... - { - xml_attribute_struct* a = append_attribute_ll(cursor, alloc); // Make space for this attribute. - if (!a) PUGI__THROW_ERROR(status_out_of_memory, s); - - a->name = s; // Save the offset. - - PUGI__SCANWHILE(PUGI__IS_CHARTYPE(*s, ct_symbol)); // Scan for a terminator. - PUGI__CHECK_ERROR(status_bad_attribute, s); //$ redundant, left for performance - - PUGI__ENDSEG(); // Save char in 'ch', terminate & step over. - PUGI__CHECK_ERROR(status_bad_attribute, s); //$ redundant, left for performance - - if (PUGI__IS_CHARTYPE(ch, ct_space)) - { - PUGI__SKIPWS(); // Eat any whitespace. - PUGI__CHECK_ERROR(status_bad_attribute, s); //$ redundant, left for performance - - ch = *s; - ++s; - } - - if (ch == '=') // '<... #=...' - { - PUGI__SKIPWS(); // Eat any whitespace. - - if (*s == '"' || *s == '\'') // '<... #="...' - { - ch = *s; // Save quote char to avoid breaking on "''" -or- '""'. - ++s; // Step over the quote. - a->value = s; // Save the offset. - - s = strconv_attribute(s, ch); - - if (!s) PUGI__THROW_ERROR(status_bad_attribute, a->value); - - // After this line the loop continues from the start; - // Whitespaces, / and > are ok, symbols and EOF are wrong, - // everything else will be detected - if (PUGI__IS_CHARTYPE(*s, ct_start_symbol)) PUGI__THROW_ERROR(status_bad_attribute, s); - } - else PUGI__THROW_ERROR(status_bad_attribute, s); - } - else PUGI__THROW_ERROR(status_bad_attribute, s); - } - else if (*s == '/') - { - ++s; - - if (*s == '>') - { - PUGI__POPNODE(); - s++; - break; - } - else if (*s == 0 && endch == '>') - { - PUGI__POPNODE(); - break; - } - else PUGI__THROW_ERROR(status_bad_start_element, s); - } - else if (*s == '>') - { - ++s; - - break; - } - else if (*s == 0 && endch == '>') - { - break; - } - else PUGI__THROW_ERROR(status_bad_start_element, s); - } - - // !!! - } - else if (ch == '/') // '<#.../' - { - if (!ENDSWITH(*s, '>')) PUGI__THROW_ERROR(status_bad_start_element, s); - - PUGI__POPNODE(); // Pop. - - s += (*s == '>'); - } - else if (ch == 0) - { - // we stepped over null terminator, backtrack & handle closing tag - --s; - - if (endch != '>') PUGI__THROW_ERROR(status_bad_start_element, s); - } - else PUGI__THROW_ERROR(status_bad_start_element, s); - } - else if (*s == '/') - { - ++s; - - char_t* name = cursor->name; - if (!name) PUGI__THROW_ERROR(status_end_element_mismatch, s); - - while (PUGI__IS_CHARTYPE(*s, ct_symbol)) - { - if (*s++ != *name++) PUGI__THROW_ERROR(status_end_element_mismatch, s); - } - - if (*name) - { - if (*s == 0 && name[0] == endch && name[1] == 0) PUGI__THROW_ERROR(status_bad_end_element, s); - else PUGI__THROW_ERROR(status_end_element_mismatch, s); - } - - PUGI__POPNODE(); // Pop. - - PUGI__SKIPWS(); - - if (*s == 0) - { - if (endch != '>') PUGI__THROW_ERROR(status_bad_end_element, s); - } - else - { - if (*s != '>') PUGI__THROW_ERROR(status_bad_end_element, s); - ++s; - } - } - else if (*s == '?') // 'header & xml_memory_page_type_mask) + 1 == node_declaration) goto LOC_ATTRIBUTES; - } - else if (*s == '!') // 'first_child) continue; - } - } - - s = mark; - - if (cursor->parent) - { - PUGI__PUSHNODE(node_pcdata); // Append a new node on the tree. - cursor->value = s; // Save the offset. - - s = strconv_pcdata(s); - - PUGI__POPNODE(); // Pop since this is a standalone. - - if (!*s) break; - } - else - { - PUGI__SCANFOR(*s == '<'); // '...<' - if (!*s) break; - - ++s; - } - - // We're after '<' - goto LOC_TAG; - } - } - - // check that last tag is closed - if (cursor != xmldoc) PUGI__THROW_ERROR(status_end_element_mismatch, s); - - return s; - } - - static xml_parse_result parse(char_t* buffer, size_t length, xml_node_struct* root, unsigned int optmsk) - { - xml_document_struct* xmldoc = static_cast(root); - - // store buffer for offset_debug - xmldoc->buffer = buffer; - - // early-out for empty documents - if (length == 0) return make_parse_result(status_ok); - - // create parser on stack - xml_parser parser(*xmldoc); - - // save last character and make buffer zero-terminated (speeds up parsing) - char_t endch = buffer[length - 1]; - buffer[length - 1] = 0; - - // perform actual parsing - parser.parse(buffer, xmldoc, optmsk, endch); - - xml_parse_result result = make_parse_result(parser.error_status, parser.error_offset ? parser.error_offset - buffer : 0); - assert(result.offset >= 0 && static_cast(result.offset) <= length); - - // update allocator state - *static_cast(xmldoc) = parser.alloc; - - // since we removed last character, we have to handle the only possible false positive - if (result && endch == '<') - { - // there's no possible well-formed document with < at the end - return make_parse_result(status_unrecognized_tag, length); - } - - return result; - } - }; - - // Output facilities - PUGI__FN xml_encoding get_write_native_encoding() - { - #ifdef PUGIXML_WCHAR_MODE - return get_wchar_encoding(); - #else - return encoding_utf8; - #endif - } - - PUGI__FN xml_encoding get_write_encoding(xml_encoding encoding) - { - // replace wchar encoding with utf implementation - if (encoding == encoding_wchar) return get_wchar_encoding(); - - // replace utf16 encoding with utf16 with specific endianness - if (encoding == encoding_utf16) return is_little_endian() ? encoding_utf16_le : encoding_utf16_be; - - // replace utf32 encoding with utf32 with specific endianness - if (encoding == encoding_utf32) return is_little_endian() ? encoding_utf32_le : encoding_utf32_be; - - // only do autodetection if no explicit encoding is requested - if (encoding != encoding_auto) return encoding; - - // assume utf8 encoding - return encoding_utf8; - } - -#ifdef PUGIXML_WCHAR_MODE - PUGI__FN size_t get_valid_length(const char_t* data, size_t length) - { - assert(length > 0); - - // discard last character if it's the lead of a surrogate pair - return (sizeof(wchar_t) == 2 && static_cast(static_cast(data[length - 1]) - 0xD800) < 0x400) ? length - 1 : length; - } - - PUGI__FN size_t convert_buffer(char_t* r_char, uint8_t* r_u8, uint16_t* r_u16, uint32_t* r_u32, const char_t* data, size_t length, xml_encoding encoding) - { - // only endian-swapping is required - if (need_endian_swap_utf(encoding, get_wchar_encoding())) - { - convert_wchar_endian_swap(r_char, data, length); - - return length * sizeof(char_t); - } - - // convert to utf8 - if (encoding == encoding_utf8) - { - uint8_t* dest = r_u8; - uint8_t* end = utf_decoder::decode_wchar_block(data, length, dest); - - return static_cast(end - dest); - } - - // convert to utf16 - if (encoding == encoding_utf16_be || encoding == encoding_utf16_le) - { - uint16_t* dest = r_u16; - - // convert to native utf16 - uint16_t* end = utf_decoder::decode_wchar_block(data, length, dest); - - // swap if necessary - xml_encoding native_encoding = is_little_endian() ? encoding_utf16_le : encoding_utf16_be; - - if (native_encoding != encoding) convert_utf_endian_swap(dest, dest, static_cast(end - dest)); - - return static_cast(end - dest) * sizeof(uint16_t); - } - - // convert to utf32 - if (encoding == encoding_utf32_be || encoding == encoding_utf32_le) - { - uint32_t* dest = r_u32; - - // convert to native utf32 - uint32_t* end = utf_decoder::decode_wchar_block(data, length, dest); - - // swap if necessary - xml_encoding native_encoding = is_little_endian() ? encoding_utf32_le : encoding_utf32_be; - - if (native_encoding != encoding) convert_utf_endian_swap(dest, dest, static_cast(end - dest)); - - return static_cast(end - dest) * sizeof(uint32_t); - } - - // convert to latin1 - if (encoding == encoding_latin1) - { - uint8_t* dest = r_u8; - uint8_t* end = utf_decoder::decode_wchar_block(data, length, dest); - - return static_cast(end - dest); - } - - assert(!"Invalid encoding"); - return 0; - } -#else - PUGI__FN size_t get_valid_length(const char_t* data, size_t length) - { - assert(length > 4); - - for (size_t i = 1; i <= 4; ++i) - { - uint8_t ch = static_cast(data[length - i]); - - // either a standalone character or a leading one - if ((ch & 0xc0) != 0x80) return length - i; - } - - // there are four non-leading characters at the end, sequence tail is broken so might as well process the whole chunk - return length; - } - - PUGI__FN size_t convert_buffer(char_t* /* r_char */, uint8_t* r_u8, uint16_t* r_u16, uint32_t* r_u32, const char_t* data, size_t length, xml_encoding encoding) - { - if (encoding == encoding_utf16_be || encoding == encoding_utf16_le) - { - uint16_t* dest = r_u16; - - // convert to native utf16 - uint16_t* end = utf_decoder::decode_utf8_block(reinterpret_cast(data), length, dest); - - // swap if necessary - xml_encoding native_encoding = is_little_endian() ? encoding_utf16_le : encoding_utf16_be; - - if (native_encoding != encoding) convert_utf_endian_swap(dest, dest, static_cast(end - dest)); - - return static_cast(end - dest) * sizeof(uint16_t); - } - - if (encoding == encoding_utf32_be || encoding == encoding_utf32_le) - { - uint32_t* dest = r_u32; - - // convert to native utf32 - uint32_t* end = utf_decoder::decode_utf8_block(reinterpret_cast(data), length, dest); - - // swap if necessary - xml_encoding native_encoding = is_little_endian() ? encoding_utf32_le : encoding_utf32_be; - - if (native_encoding != encoding) convert_utf_endian_swap(dest, dest, static_cast(end - dest)); - - return static_cast(end - dest) * sizeof(uint32_t); - } - - if (encoding == encoding_latin1) - { - uint8_t* dest = r_u8; - uint8_t* end = utf_decoder::decode_utf8_block(reinterpret_cast(data), length, dest); - - return static_cast(end - dest); - } - - assert(!"Invalid encoding"); - return 0; - } -#endif - - class xml_buffered_writer - { - xml_buffered_writer(const xml_buffered_writer&); - xml_buffered_writer& operator=(const xml_buffered_writer&); - - public: - xml_buffered_writer(xml_writer& writer_, xml_encoding user_encoding): writer(writer_), bufsize(0), encoding(get_write_encoding(user_encoding)) - { - PUGI__STATIC_ASSERT(bufcapacity >= 8); - } - - ~xml_buffered_writer() - { - flush(); - } - - void flush() - { - flush(buffer, bufsize); - bufsize = 0; - } - - void flush(const char_t* data, size_t size) - { - if (size == 0) return; - - // fast path, just write data - if (encoding == get_write_native_encoding()) - writer.write(data, size * sizeof(char_t)); - else - { - // convert chunk - size_t result = convert_buffer(scratch.data_char, scratch.data_u8, scratch.data_u16, scratch.data_u32, data, size, encoding); - assert(result <= sizeof(scratch)); - - // write data - writer.write(scratch.data_u8, result); - } - } - - void write(const char_t* data, size_t length) - { - if (bufsize + length > bufcapacity) - { - // flush the remaining buffer contents - flush(); - - // handle large chunks - if (length > bufcapacity) - { - if (encoding == get_write_native_encoding()) - { - // fast path, can just write data chunk - writer.write(data, length * sizeof(char_t)); - return; - } - - // need to convert in suitable chunks - while (length > bufcapacity) - { - // get chunk size by selecting such number of characters that are guaranteed to fit into scratch buffer - // and form a complete codepoint sequence (i.e. discard start of last codepoint if necessary) - size_t chunk_size = get_valid_length(data, bufcapacity); - - // convert chunk and write - flush(data, chunk_size); - - // iterate - data += chunk_size; - length -= chunk_size; - } - - // small tail is copied below - bufsize = 0; - } - } - - memcpy(buffer + bufsize, data, length * sizeof(char_t)); - bufsize += length; - } - - void write(const char_t* data) - { - write(data, strlength(data)); - } - - void write(char_t d0) - { - if (bufsize + 1 > bufcapacity) flush(); - - buffer[bufsize + 0] = d0; - bufsize += 1; - } - - void write(char_t d0, char_t d1) - { - if (bufsize + 2 > bufcapacity) flush(); - - buffer[bufsize + 0] = d0; - buffer[bufsize + 1] = d1; - bufsize += 2; - } - - void write(char_t d0, char_t d1, char_t d2) - { - if (bufsize + 3 > bufcapacity) flush(); - - buffer[bufsize + 0] = d0; - buffer[bufsize + 1] = d1; - buffer[bufsize + 2] = d2; - bufsize += 3; - } - - void write(char_t d0, char_t d1, char_t d2, char_t d3) - { - if (bufsize + 4 > bufcapacity) flush(); - - buffer[bufsize + 0] = d0; - buffer[bufsize + 1] = d1; - buffer[bufsize + 2] = d2; - buffer[bufsize + 3] = d3; - bufsize += 4; - } - - void write(char_t d0, char_t d1, char_t d2, char_t d3, char_t d4) - { - if (bufsize + 5 > bufcapacity) flush(); - - buffer[bufsize + 0] = d0; - buffer[bufsize + 1] = d1; - buffer[bufsize + 2] = d2; - buffer[bufsize + 3] = d3; - buffer[bufsize + 4] = d4; - bufsize += 5; - } - - void write(char_t d0, char_t d1, char_t d2, char_t d3, char_t d4, char_t d5) - { - if (bufsize + 6 > bufcapacity) flush(); - - buffer[bufsize + 0] = d0; - buffer[bufsize + 1] = d1; - buffer[bufsize + 2] = d2; - buffer[bufsize + 3] = d3; - buffer[bufsize + 4] = d4; - buffer[bufsize + 5] = d5; - bufsize += 6; - } - - // utf8 maximum expansion: x4 (-> utf32) - // utf16 maximum expansion: x2 (-> utf32) - // utf32 maximum expansion: x1 - enum - { - bufcapacitybytes = - #ifdef PUGIXML_MEMORY_OUTPUT_STACK - PUGIXML_MEMORY_OUTPUT_STACK - #else - 10240 - #endif - , - bufcapacity = bufcapacitybytes / (sizeof(char_t) + 4) - }; - - char_t buffer[bufcapacity]; - - union - { - uint8_t data_u8[4 * bufcapacity]; - uint16_t data_u16[2 * bufcapacity]; - uint32_t data_u32[bufcapacity]; - char_t data_char[bufcapacity]; - } scratch; - - xml_writer& writer; - size_t bufsize; - xml_encoding encoding; - }; - - PUGI__FN void text_output_escaped(xml_buffered_writer& writer, const char_t* s, chartypex_t type) - { - while (*s) - { - const char_t* prev = s; - - // While *s is a usual symbol - while (!PUGI__IS_CHARTYPEX(*s, type)) ++s; - - writer.write(prev, static_cast(s - prev)); - - switch (*s) - { - case 0: break; - case '&': - writer.write('&', 'a', 'm', 'p', ';'); - ++s; - break; - case '<': - writer.write('&', 'l', 't', ';'); - ++s; - break; - case '>': - writer.write('&', 'g', 't', ';'); - ++s; - break; - case '"': - writer.write('&', 'q', 'u', 'o', 't', ';'); - ++s; - break; - default: // s is not a usual symbol - { - unsigned int ch = static_cast(*s++); - assert(ch < 32); - - writer.write('&', '#', static_cast((ch / 10) + '0'), static_cast((ch % 10) + '0'), ';'); - } - } - } - } - - PUGI__FN void text_output(xml_buffered_writer& writer, const char_t* s, chartypex_t type, unsigned int flags) - { - if (flags & format_no_escapes) - writer.write(s); - else - text_output_escaped(writer, s, type); - } - - PUGI__FN void text_output_cdata(xml_buffered_writer& writer, const char_t* s) - { - do - { - writer.write('<', '!', '[', 'C', 'D'); - writer.write('A', 'T', 'A', '['); - - const char_t* prev = s; - - // look for ]]> sequence - we can't output it as is since it terminates CDATA - while (*s && !(s[0] == ']' && s[1] == ']' && s[2] == '>')) ++s; - - // skip ]] if we stopped at ]]>, > will go to the next CDATA section - if (*s) s += 2; - - writer.write(prev, static_cast(s - prev)); - - writer.write(']', ']', '>'); - } - while (*s); - } - - PUGI__FN void node_output_attributes(xml_buffered_writer& writer, const xml_node& node, unsigned int flags) - { - const char_t* default_name = PUGIXML_TEXT(":anonymous"); - - for (xml_attribute a = node.first_attribute(); a; a = a.next_attribute()) - { - writer.write(' '); - writer.write(a.name()[0] ? a.name() : default_name); - writer.write('=', '"'); - - text_output(writer, a.value(), ctx_special_attr, flags); - - writer.write('"'); - } - } - - PUGI__FN void node_output(xml_buffered_writer& writer, const xml_node& node, const char_t* indent, unsigned int flags, unsigned int depth) - { - const char_t* default_name = PUGIXML_TEXT(":anonymous"); - - if ((flags & format_indent) != 0 && (flags & format_raw) == 0) - for (unsigned int i = 0; i < depth; ++i) writer.write(indent); - - switch (node.type()) - { - case node_document: - { - for (xml_node n = node.first_child(); n; n = n.next_sibling()) - node_output(writer, n, indent, flags, depth); - break; - } - - case node_element: - { - const char_t* name = node.name()[0] ? node.name() : default_name; - - writer.write('<'); - writer.write(name); - - node_output_attributes(writer, node, flags); - - if (flags & format_raw) - { - if (!node.first_child()) - writer.write(' ', '/', '>'); - else - { - writer.write('>'); - - for (xml_node n = node.first_child(); n; n = n.next_sibling()) - node_output(writer, n, indent, flags, depth + 1); - - writer.write('<', '/'); - writer.write(name); - writer.write('>'); - } - } - else if (!node.first_child()) - writer.write(' ', '/', '>', '\n'); - else if (node.first_child() == node.last_child() && (node.first_child().type() == node_pcdata || node.first_child().type() == node_cdata)) - { - writer.write('>'); - - if (node.first_child().type() == node_pcdata) - text_output(writer, node.first_child().value(), ctx_special_pcdata, flags); - else - text_output_cdata(writer, node.first_child().value()); - - writer.write('<', '/'); - writer.write(name); - writer.write('>', '\n'); - } - else - { - writer.write('>', '\n'); - - for (xml_node n = node.first_child(); n; n = n.next_sibling()) - node_output(writer, n, indent, flags, depth + 1); - - if ((flags & format_indent) != 0 && (flags & format_raw) == 0) - for (unsigned int i = 0; i < depth; ++i) writer.write(indent); - - writer.write('<', '/'); - writer.write(name); - writer.write('>', '\n'); - } - - break; - } - - case node_pcdata: - text_output(writer, node.value(), ctx_special_pcdata, flags); - if ((flags & format_raw) == 0) writer.write('\n'); - break; - - case node_cdata: - text_output_cdata(writer, node.value()); - if ((flags & format_raw) == 0) writer.write('\n'); - break; - - case node_comment: - writer.write('<', '!', '-', '-'); - writer.write(node.value()); - writer.write('-', '-', '>'); - if ((flags & format_raw) == 0) writer.write('\n'); - break; - - case node_pi: - case node_declaration: - writer.write('<', '?'); - writer.write(node.name()[0] ? node.name() : default_name); - - if (node.type() == node_declaration) - { - node_output_attributes(writer, node, flags); - } - else if (node.value()[0]) - { - writer.write(' '); - writer.write(node.value()); - } - - writer.write('?', '>'); - if ((flags & format_raw) == 0) writer.write('\n'); - break; - - case node_doctype: - writer.write('<', '!', 'D', 'O', 'C'); - writer.write('T', 'Y', 'P', 'E'); - - if (node.value()[0]) - { - writer.write(' '); - writer.write(node.value()); - } - - writer.write('>'); - if ((flags & format_raw) == 0) writer.write('\n'); - break; - - default: - assert(!"Invalid node type"); - } - } - - inline bool has_declaration(const xml_node& node) - { - for (xml_node child = node.first_child(); child; child = child.next_sibling()) - { - xml_node_type type = child.type(); - - if (type == node_declaration) return true; - if (type == node_element) return false; - } - - return false; - } - - inline bool allow_insert_child(xml_node_type parent, xml_node_type child) - { - if (parent != node_document && parent != node_element) return false; - if (child == node_document || child == node_null) return false; - if (parent != node_document && (child == node_declaration || child == node_doctype)) return false; - - return true; - } - - PUGI__FN void recursive_copy_skip(xml_node& dest, const xml_node& source, const xml_node& skip) - { - assert(dest.type() == source.type()); - - switch (source.type()) - { - case node_element: - { - dest.set_name(source.name()); - - for (xml_attribute a = source.first_attribute(); a; a = a.next_attribute()) - dest.append_attribute(a.name()).set_value(a.value()); - - for (xml_node c = source.first_child(); c; c = c.next_sibling()) - { - if (c == skip) continue; - - xml_node cc = dest.append_child(c.type()); - assert(cc); - - recursive_copy_skip(cc, c, skip); - } - - break; - } - - case node_pcdata: - case node_cdata: - case node_comment: - case node_doctype: - dest.set_value(source.value()); - break; - - case node_pi: - dest.set_name(source.name()); - dest.set_value(source.value()); - break; - - case node_declaration: - { - dest.set_name(source.name()); - - for (xml_attribute a = source.first_attribute(); a; a = a.next_attribute()) - dest.append_attribute(a.name()).set_value(a.value()); - - break; - } - - default: - assert(!"Invalid node type"); - } - } - - inline bool is_text_node(xml_node_struct* node) - { - xml_node_type type = static_cast((node->header & impl::xml_memory_page_type_mask) + 1); - - return type == node_pcdata || type == node_cdata; - } - - // get value with conversion functions - PUGI__FN int get_value_int(const char_t* value, int def) - { - if (!value) return def; - - #ifdef PUGIXML_WCHAR_MODE - return static_cast(wcstol(value, 0, 10)); - #else - return static_cast(strtol(value, 0, 10)); - #endif - } - - PUGI__FN unsigned int get_value_uint(const char_t* value, unsigned int def) - { - if (!value) return def; - - #ifdef PUGIXML_WCHAR_MODE - return static_cast(wcstoul(value, 0, 10)); - #else - return static_cast(strtoul(value, 0, 10)); - #endif - } - - PUGI__FN double get_value_double(const char_t* value, double def) - { - if (!value) return def; - - #ifdef PUGIXML_WCHAR_MODE - return wcstod(value, 0); - #else - return strtod(value, 0); - #endif - } - - PUGI__FN float get_value_float(const char_t* value, float def) - { - if (!value) return def; - - #ifdef PUGIXML_WCHAR_MODE - return static_cast(wcstod(value, 0)); - #else - return static_cast(strtod(value, 0)); - #endif - } - - PUGI__FN bool get_value_bool(const char_t* value, bool def) - { - if (!value) return def; - - // only look at first char - char_t first = *value; - - // 1*, t* (true), T* (True), y* (yes), Y* (YES) - return (first == '1' || first == 't' || first == 'T' || first == 'y' || first == 'Y'); - } - - // set value with conversion functions - PUGI__FN bool set_value_buffer(char_t*& dest, uintptr_t& header, uintptr_t header_mask, char (&buf)[128]) - { - #ifdef PUGIXML_WCHAR_MODE - char_t wbuf[128]; - impl::widen_ascii(wbuf, buf); - - return strcpy_insitu(dest, header, header_mask, wbuf); - #else - return strcpy_insitu(dest, header, header_mask, buf); - #endif - } - - PUGI__FN bool set_value_convert(char_t*& dest, uintptr_t& header, uintptr_t header_mask, int value) - { - char buf[128]; - sprintf(buf, "%d", value); - - return set_value_buffer(dest, header, header_mask, buf); - } - - PUGI__FN bool set_value_convert(char_t*& dest, uintptr_t& header, uintptr_t header_mask, unsigned int value) - { - char buf[128]; - sprintf(buf, "%u", value); - - return set_value_buffer(dest, header, header_mask, buf); - } - - PUGI__FN bool set_value_convert(char_t*& dest, uintptr_t& header, uintptr_t header_mask, double value) - { - char buf[128]; - sprintf(buf, "%g", value); - - return set_value_buffer(dest, header, header_mask, buf); - } - - PUGI__FN bool set_value_convert(char_t*& dest, uintptr_t& header, uintptr_t header_mask, bool value) - { - return strcpy_insitu(dest, header, header_mask, value ? PUGIXML_TEXT("true") : PUGIXML_TEXT("false")); - } - - // we need to get length of entire file to load it in memory; the only (relatively) sane way to do it is via seek/tell trick - PUGI__FN xml_parse_status get_file_size(FILE* file, size_t& out_result) - { - #if defined(PUGI__MSVC_CRT_VERSION) && PUGI__MSVC_CRT_VERSION >= 1400 && !defined(_WIN32_WCE) - // there are 64-bit versions of fseek/ftell, let's use them - typedef __int64 length_type; - - _fseeki64(file, 0, SEEK_END); - length_type length = _ftelli64(file); - _fseeki64(file, 0, SEEK_SET); - #elif defined(__MINGW32__) && !defined(__NO_MINGW_LFS) && !defined(__STRICT_ANSI__) - // there are 64-bit versions of fseek/ftell, let's use them - typedef off64_t length_type; - - fseeko64(file, 0, SEEK_END); - length_type length = ftello64(file); - fseeko64(file, 0, SEEK_SET); - #else - // if this is a 32-bit OS, long is enough; if this is a unix system, long is 64-bit, which is enough; otherwise we can't do anything anyway. - typedef long length_type; - - fseek(file, 0, SEEK_END); - length_type length = ftell(file); - fseek(file, 0, SEEK_SET); - #endif - - // check for I/O errors - if (length < 0) return status_io_error; - - // check for overflow - size_t result = static_cast(length); - - if (static_cast(result) != length) return status_out_of_memory; - - // finalize - out_result = result; - - return status_ok; - } - - PUGI__FN xml_parse_result load_file_impl(xml_document& doc, FILE* file, unsigned int options, xml_encoding encoding) - { - if (!file) return make_parse_result(status_file_not_found); - - // get file size (can result in I/O errors) - size_t size = 0; - xml_parse_status size_status = get_file_size(file, size); - - if (size_status != status_ok) - { - fclose(file); - return make_parse_result(size_status); - } - - // allocate buffer for the whole file - char* contents = static_cast(xml_memory::allocate(size > 0 ? size : 1)); - - if (!contents) - { - fclose(file); - return make_parse_result(status_out_of_memory); - } - - // read file in memory - size_t read_size = fread(contents, 1, size, file); - fclose(file); - - if (read_size != size) - { - xml_memory::deallocate(contents); - return make_parse_result(status_io_error); - } - - return doc.load_buffer_inplace_own(contents, size, options, encoding); - } - -#ifndef PUGIXML_NO_STL - template struct xml_stream_chunk - { - static xml_stream_chunk* create() - { - void* memory = xml_memory::allocate(sizeof(xml_stream_chunk)); - - return new (memory) xml_stream_chunk(); - } - - static void destroy(void* ptr) - { - xml_stream_chunk* chunk = static_cast(ptr); - - // free chunk chain - while (chunk) - { - xml_stream_chunk* next = chunk->next; - xml_memory::deallocate(chunk); - chunk = next; - } - } - - xml_stream_chunk(): next(0), size(0) - { - } - - xml_stream_chunk* next; - size_t size; - - T data[xml_memory_page_size / sizeof(T)]; - }; - - template PUGI__FN xml_parse_status load_stream_data_noseek(std::basic_istream& stream, void** out_buffer, size_t* out_size) - { - buffer_holder chunks(0, xml_stream_chunk::destroy); - - // read file to a chunk list - size_t total = 0; - xml_stream_chunk* last = 0; - - while (!stream.eof()) - { - // allocate new chunk - xml_stream_chunk* chunk = xml_stream_chunk::create(); - if (!chunk) return status_out_of_memory; - - // append chunk to list - if (last) last = last->next = chunk; - else chunks.data = last = chunk; - - // read data to chunk - stream.read(chunk->data, static_cast(sizeof(chunk->data) / sizeof(T))); - chunk->size = static_cast(stream.gcount()) * sizeof(T); - - // read may set failbit | eofbit in case gcount() is less than read length, so check for other I/O errors - if (stream.bad() || (!stream.eof() && stream.fail())) return status_io_error; - - // guard against huge files (chunk size is small enough to make this overflow check work) - if (total + chunk->size < total) return status_out_of_memory; - total += chunk->size; - } - - // copy chunk list to a contiguous buffer - char* buffer = static_cast(xml_memory::allocate(total)); - if (!buffer) return status_out_of_memory; - - char* write = buffer; - - for (xml_stream_chunk* chunk = static_cast*>(chunks.data); chunk; chunk = chunk->next) - { - assert(write + chunk->size <= buffer + total); - memcpy(write, chunk->data, chunk->size); - write += chunk->size; - } - - assert(write == buffer + total); - - // return buffer - *out_buffer = buffer; - *out_size = total; - - return status_ok; - } - - template PUGI__FN xml_parse_status load_stream_data_seek(std::basic_istream& stream, void** out_buffer, size_t* out_size) - { - // get length of remaining data in stream - typename std::basic_istream::pos_type pos = stream.tellg(); - stream.seekg(0, std::ios::end); - std::streamoff length = stream.tellg() - pos; - stream.seekg(pos); - - if (stream.fail() || pos < 0) return status_io_error; - - // guard against huge files - size_t read_length = static_cast(length); - - if (static_cast(read_length) != length || length < 0) return status_out_of_memory; - - // read stream data into memory (guard against stream exceptions with buffer holder) - buffer_holder buffer(xml_memory::allocate((read_length > 0 ? read_length : 1) * sizeof(T)), xml_memory::deallocate); - if (!buffer.data) return status_out_of_memory; - - stream.read(static_cast(buffer.data), static_cast(read_length)); - - // read may set failbit | eofbit in case gcount() is less than read_length (i.e. line ending conversion), so check for other I/O errors - if (stream.bad() || (!stream.eof() && stream.fail())) return status_io_error; - - // return buffer - size_t actual_length = static_cast(stream.gcount()); - assert(actual_length <= read_length); - - *out_buffer = buffer.release(); - *out_size = actual_length * sizeof(T); - - return status_ok; - } - - template PUGI__FN xml_parse_result load_stream_impl(xml_document& doc, std::basic_istream& stream, unsigned int options, xml_encoding encoding) - { - void* buffer = 0; - size_t size = 0; - - // load stream to memory (using seek-based implementation if possible, since it's faster and takes less memory) - xml_parse_status status = (stream.tellg() < 0) ? load_stream_data_noseek(stream, &buffer, &size) : load_stream_data_seek(stream, &buffer, &size); - if (status != status_ok) return make_parse_result(status); - - return doc.load_buffer_inplace_own(buffer, size, options, encoding); - } -#endif - -#if defined(PUGI__MSVC_CRT_VERSION) || defined(__BORLANDC__) || (defined(__MINGW32__) && !defined(__STRICT_ANSI__)) - PUGI__FN FILE* open_file_wide(const wchar_t* path, const wchar_t* mode) - { - return _wfopen(path, mode); - } -#else - PUGI__FN char* convert_path_heap(const wchar_t* str) - { - assert(str); - - // first pass: get length in utf8 characters - size_t length = wcslen(str); - size_t size = as_utf8_begin(str, length); - - // allocate resulting string - char* result = static_cast(xml_memory::allocate(size + 1)); - if (!result) return 0; - - // second pass: convert to utf8 - as_utf8_end(result, size, str, length); - - return result; - } - - PUGI__FN FILE* open_file_wide(const wchar_t* path, const wchar_t* mode) - { - // there is no standard function to open wide paths, so our best bet is to try utf8 path - char* path_utf8 = convert_path_heap(path); - if (!path_utf8) return 0; - - // convert mode to ASCII (we mirror _wfopen interface) - char mode_ascii[4] = {0}; - for (size_t i = 0; mode[i]; ++i) mode_ascii[i] = static_cast(mode[i]); - - // try to open the utf8 path - FILE* result = fopen(path_utf8, mode_ascii); - - // free dummy buffer - xml_memory::deallocate(path_utf8); - - return result; - } -#endif - - PUGI__FN bool save_file_impl(const xml_document& doc, FILE* file, const char_t* indent, unsigned int flags, xml_encoding encoding) - { - if (!file) return false; - - xml_writer_file writer(file); - doc.save(writer, indent, flags, encoding); - - int result = ferror(file); - - fclose(file); - - return result == 0; - } -PUGI__NS_END - -namespace pugi -{ - PUGI__FN xml_writer_file::xml_writer_file(void* file_): file(file_) - { - } - - PUGI__FN void xml_writer_file::write(const void* data, size_t size) - { - size_t result = fwrite(data, 1, size, static_cast(file)); - (void)!result; // unfortunately we can't do proper error handling here - } - -#ifndef PUGIXML_NO_STL - PUGI__FN xml_writer_stream::xml_writer_stream(std::basic_ostream >& stream): narrow_stream(&stream), wide_stream(0) - { - } - - PUGI__FN xml_writer_stream::xml_writer_stream(std::basic_ostream >& stream): narrow_stream(0), wide_stream(&stream) - { - } - - PUGI__FN void xml_writer_stream::write(const void* data, size_t size) - { - if (narrow_stream) - { - assert(!wide_stream); - narrow_stream->write(reinterpret_cast(data), static_cast(size)); - } - else - { - assert(wide_stream); - assert(size % sizeof(wchar_t) == 0); - - wide_stream->write(reinterpret_cast(data), static_cast(size / sizeof(wchar_t))); - } - } -#endif - - PUGI__FN xml_tree_walker::xml_tree_walker(): _depth(0) - { - } - - PUGI__FN xml_tree_walker::~xml_tree_walker() - { - } - - PUGI__FN int xml_tree_walker::depth() const - { - return _depth; - } - - PUGI__FN bool xml_tree_walker::begin(xml_node&) - { - return true; - } - - PUGI__FN bool xml_tree_walker::end(xml_node&) - { - return true; - } - - PUGI__FN xml_attribute::xml_attribute(): _attr(0) - { - } - - PUGI__FN xml_attribute::xml_attribute(xml_attribute_struct* attr): _attr(attr) - { - } - - PUGI__FN static void unspecified_bool_xml_attribute(xml_attribute***) - { - } - - PUGI__FN xml_attribute::operator xml_attribute::unspecified_bool_type() const - { - return _attr ? unspecified_bool_xml_attribute : 0; - } - - PUGI__FN bool xml_attribute::operator!() const - { - return !_attr; - } - - PUGI__FN bool xml_attribute::operator==(const xml_attribute& r) const - { - return (_attr == r._attr); - } - - PUGI__FN bool xml_attribute::operator!=(const xml_attribute& r) const - { - return (_attr != r._attr); - } - - PUGI__FN bool xml_attribute::operator<(const xml_attribute& r) const - { - return (_attr < r._attr); - } - - PUGI__FN bool xml_attribute::operator>(const xml_attribute& r) const - { - return (_attr > r._attr); - } - - PUGI__FN bool xml_attribute::operator<=(const xml_attribute& r) const - { - return (_attr <= r._attr); - } - - PUGI__FN bool xml_attribute::operator>=(const xml_attribute& r) const - { - return (_attr >= r._attr); - } - - PUGI__FN xml_attribute xml_attribute::next_attribute() const - { - return _attr ? xml_attribute(_attr->next_attribute) : xml_attribute(); - } - - PUGI__FN xml_attribute xml_attribute::previous_attribute() const - { - return _attr && _attr->prev_attribute_c->next_attribute ? xml_attribute(_attr->prev_attribute_c) : xml_attribute(); - } - - PUGI__FN const char_t* xml_attribute::as_string(const char_t* def) const - { - return (_attr && _attr->value) ? _attr->value : def; - } - - PUGI__FN int xml_attribute::as_int(int def) const - { - return impl::get_value_int(_attr ? _attr->value : 0, def); - } - - PUGI__FN unsigned int xml_attribute::as_uint(unsigned int def) const - { - return impl::get_value_uint(_attr ? _attr->value : 0, def); - } - - PUGI__FN double xml_attribute::as_double(double def) const - { - return impl::get_value_double(_attr ? _attr->value : 0, def); - } - - PUGI__FN float xml_attribute::as_float(float def) const - { - return impl::get_value_float(_attr ? _attr->value : 0, def); - } - - PUGI__FN bool xml_attribute::as_bool(bool def) const - { - return impl::get_value_bool(_attr ? _attr->value : 0, def); - } - - PUGI__FN bool xml_attribute::empty() const - { - return !_attr; - } - - PUGI__FN const char_t* xml_attribute::name() const - { - return (_attr && _attr->name) ? _attr->name : PUGIXML_TEXT(""); - } - - PUGI__FN const char_t* xml_attribute::value() const - { - return (_attr && _attr->value) ? _attr->value : PUGIXML_TEXT(""); - } - - PUGI__FN size_t xml_attribute::hash_value() const - { - return static_cast(reinterpret_cast(_attr) / sizeof(xml_attribute_struct)); - } - - PUGI__FN xml_attribute_struct* xml_attribute::internal_object() const - { - return _attr; - } - - PUGI__FN xml_attribute& xml_attribute::operator=(const char_t* rhs) - { - set_value(rhs); - return *this; - } - - PUGI__FN xml_attribute& xml_attribute::operator=(int rhs) - { - set_value(rhs); - return *this; - } - - PUGI__FN xml_attribute& xml_attribute::operator=(unsigned int rhs) - { - set_value(rhs); - return *this; - } - - PUGI__FN xml_attribute& xml_attribute::operator=(double rhs) - { - set_value(rhs); - return *this; - } - - PUGI__FN xml_attribute& xml_attribute::operator=(bool rhs) - { - set_value(rhs); - return *this; - } - - PUGI__FN bool xml_attribute::set_name(const char_t* rhs) - { - if (!_attr) return false; - - return impl::strcpy_insitu(_attr->name, _attr->header, impl::xml_memory_page_name_allocated_mask, rhs); - } - - PUGI__FN bool xml_attribute::set_value(const char_t* rhs) - { - if (!_attr) return false; - - return impl::strcpy_insitu(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); - } - - PUGI__FN bool xml_attribute::set_value(int rhs) - { - if (!_attr) return false; - - return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); - } - - PUGI__FN bool xml_attribute::set_value(unsigned int rhs) - { - if (!_attr) return false; - - return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); - } - - PUGI__FN bool xml_attribute::set_value(double rhs) - { - if (!_attr) return false; - - return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); - } - - PUGI__FN bool xml_attribute::set_value(bool rhs) - { - if (!_attr) return false; - - return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); - } - -#ifdef __BORLANDC__ - PUGI__FN bool operator&&(const xml_attribute& lhs, bool rhs) - { - return (bool)lhs && rhs; - } - - PUGI__FN bool operator||(const xml_attribute& lhs, bool rhs) - { - return (bool)lhs || rhs; - } -#endif - - PUGI__FN xml_node::xml_node(): _root(0) - { - } - - PUGI__FN xml_node::xml_node(xml_node_struct* p): _root(p) - { - } - - PUGI__FN static void unspecified_bool_xml_node(xml_node***) - { - } - - PUGI__FN xml_node::operator xml_node::unspecified_bool_type() const - { - return _root ? unspecified_bool_xml_node : 0; - } - - PUGI__FN bool xml_node::operator!() const - { - return !_root; - } - - PUGI__FN xml_node::iterator xml_node::begin() const - { - return iterator(_root ? _root->first_child : 0, _root); - } - - PUGI__FN xml_node::iterator xml_node::end() const - { - return iterator(0, _root); - } - - PUGI__FN xml_node::attribute_iterator xml_node::attributes_begin() const - { - return attribute_iterator(_root ? _root->first_attribute : 0, _root); - } - - PUGI__FN xml_node::attribute_iterator xml_node::attributes_end() const - { - return attribute_iterator(0, _root); - } - - PUGI__FN xml_object_range xml_node::children() const - { - return xml_object_range(begin(), end()); - } - - PUGI__FN xml_object_range xml_node::children(const char_t* name_) const - { - return xml_object_range(xml_named_node_iterator(child(name_), name_), xml_named_node_iterator()); - } - - PUGI__FN xml_object_range xml_node::attributes() const - { - return xml_object_range(attributes_begin(), attributes_end()); - } - - PUGI__FN bool xml_node::operator==(const xml_node& r) const - { - return (_root == r._root); - } - - PUGI__FN bool xml_node::operator!=(const xml_node& r) const - { - return (_root != r._root); - } - - PUGI__FN bool xml_node::operator<(const xml_node& r) const - { - return (_root < r._root); - } - - PUGI__FN bool xml_node::operator>(const xml_node& r) const - { - return (_root > r._root); - } - - PUGI__FN bool xml_node::operator<=(const xml_node& r) const - { - return (_root <= r._root); - } - - PUGI__FN bool xml_node::operator>=(const xml_node& r) const - { - return (_root >= r._root); - } - - PUGI__FN bool xml_node::empty() const - { - return !_root; - } - - PUGI__FN const char_t* xml_node::name() const - { - return (_root && _root->name) ? _root->name : PUGIXML_TEXT(""); - } - - PUGI__FN xml_node_type xml_node::type() const - { - return _root ? static_cast((_root->header & impl::xml_memory_page_type_mask) + 1) : node_null; - } - - PUGI__FN const char_t* xml_node::value() const - { - return (_root && _root->value) ? _root->value : PUGIXML_TEXT(""); - } - - PUGI__FN xml_node xml_node::child(const char_t* name_) const - { - if (!_root) return xml_node(); - - for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling) - if (i->name && impl::strequal(name_, i->name)) return xml_node(i); - - return xml_node(); - } - - PUGI__FN xml_attribute xml_node::attribute(const char_t* name_) const - { - if (!_root) return xml_attribute(); - - for (xml_attribute_struct* i = _root->first_attribute; i; i = i->next_attribute) - if (i->name && impl::strequal(name_, i->name)) - return xml_attribute(i); - - return xml_attribute(); - } - - PUGI__FN xml_node xml_node::next_sibling(const char_t* name_) const - { - if (!_root) return xml_node(); - - for (xml_node_struct* i = _root->next_sibling; i; i = i->next_sibling) - if (i->name && impl::strequal(name_, i->name)) return xml_node(i); - - return xml_node(); - } - - PUGI__FN xml_node xml_node::next_sibling() const - { - if (!_root) return xml_node(); - - if (_root->next_sibling) return xml_node(_root->next_sibling); - else return xml_node(); - } - - PUGI__FN xml_node xml_node::previous_sibling(const char_t* name_) const - { - if (!_root) return xml_node(); - - for (xml_node_struct* i = _root->prev_sibling_c; i->next_sibling; i = i->prev_sibling_c) - if (i->name && impl::strequal(name_, i->name)) return xml_node(i); - - return xml_node(); - } - - PUGI__FN xml_node xml_node::previous_sibling() const - { - if (!_root) return xml_node(); - - if (_root->prev_sibling_c->next_sibling) return xml_node(_root->prev_sibling_c); - else return xml_node(); - } - - PUGI__FN xml_node xml_node::parent() const - { - return _root ? xml_node(_root->parent) : xml_node(); - } - - PUGI__FN xml_node xml_node::root() const - { - if (!_root) return xml_node(); - - impl::xml_memory_page* page = reinterpret_cast(_root->header & impl::xml_memory_page_pointer_mask); - - return xml_node(static_cast(page->allocator)); - } - - PUGI__FN xml_text xml_node::text() const - { - return xml_text(_root); - } - - PUGI__FN const char_t* xml_node::child_value() const - { - if (!_root) return PUGIXML_TEXT(""); - - for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling) - if (i->value && impl::is_text_node(i)) - return i->value; - - return PUGIXML_TEXT(""); - } - - PUGI__FN const char_t* xml_node::child_value(const char_t* name_) const - { - return child(name_).child_value(); - } - - PUGI__FN xml_attribute xml_node::first_attribute() const - { - return _root ? xml_attribute(_root->first_attribute) : xml_attribute(); - } - - PUGI__FN xml_attribute xml_node::last_attribute() const - { - return _root && _root->first_attribute ? xml_attribute(_root->first_attribute->prev_attribute_c) : xml_attribute(); - } - - PUGI__FN xml_node xml_node::first_child() const - { - return _root ? xml_node(_root->first_child) : xml_node(); - } - - PUGI__FN xml_node xml_node::last_child() const - { - return _root && _root->first_child ? xml_node(_root->first_child->prev_sibling_c) : xml_node(); - } - - PUGI__FN bool xml_node::set_name(const char_t* rhs) - { - switch (type()) - { - case node_pi: - case node_declaration: - case node_element: - return impl::strcpy_insitu(_root->name, _root->header, impl::xml_memory_page_name_allocated_mask, rhs); - - default: - return false; - } - } - - PUGI__FN bool xml_node::set_value(const char_t* rhs) - { - switch (type()) - { - case node_pi: - case node_cdata: - case node_pcdata: - case node_comment: - case node_doctype: - return impl::strcpy_insitu(_root->value, _root->header, impl::xml_memory_page_value_allocated_mask, rhs); - - default: - return false; - } - } - - PUGI__FN xml_attribute xml_node::append_attribute(const char_t* name_) - { - if (type() != node_element && type() != node_declaration) return xml_attribute(); - - xml_attribute a(impl::append_attribute_ll(_root, impl::get_allocator(_root))); - a.set_name(name_); - - return a; - } - - PUGI__FN xml_attribute xml_node::prepend_attribute(const char_t* name_) - { - if (type() != node_element && type() != node_declaration) return xml_attribute(); - - xml_attribute a(impl::allocate_attribute(impl::get_allocator(_root))); - if (!a) return xml_attribute(); - - a.set_name(name_); - - xml_attribute_struct* head = _root->first_attribute; - - if (head) - { - a._attr->prev_attribute_c = head->prev_attribute_c; - head->prev_attribute_c = a._attr; - } - else - a._attr->prev_attribute_c = a._attr; - - a._attr->next_attribute = head; - _root->first_attribute = a._attr; - - return a; - } - - PUGI__FN xml_attribute xml_node::insert_attribute_before(const char_t* name_, const xml_attribute& attr) - { - if ((type() != node_element && type() != node_declaration) || attr.empty()) return xml_attribute(); - - // check that attribute belongs to *this - xml_attribute_struct* cur = attr._attr; - - while (cur->prev_attribute_c->next_attribute) cur = cur->prev_attribute_c; - - if (cur != _root->first_attribute) return xml_attribute(); - - xml_attribute a(impl::allocate_attribute(impl::get_allocator(_root))); - if (!a) return xml_attribute(); - - a.set_name(name_); - - if (attr._attr->prev_attribute_c->next_attribute) - attr._attr->prev_attribute_c->next_attribute = a._attr; - else - _root->first_attribute = a._attr; - - a._attr->prev_attribute_c = attr._attr->prev_attribute_c; - a._attr->next_attribute = attr._attr; - attr._attr->prev_attribute_c = a._attr; - - return a; - } - - PUGI__FN xml_attribute xml_node::insert_attribute_after(const char_t* name_, const xml_attribute& attr) - { - if ((type() != node_element && type() != node_declaration) || attr.empty()) return xml_attribute(); - - // check that attribute belongs to *this - xml_attribute_struct* cur = attr._attr; - - while (cur->prev_attribute_c->next_attribute) cur = cur->prev_attribute_c; - - if (cur != _root->first_attribute) return xml_attribute(); - - xml_attribute a(impl::allocate_attribute(impl::get_allocator(_root))); - if (!a) return xml_attribute(); - - a.set_name(name_); - - if (attr._attr->next_attribute) - attr._attr->next_attribute->prev_attribute_c = a._attr; - else - _root->first_attribute->prev_attribute_c = a._attr; - - a._attr->next_attribute = attr._attr->next_attribute; - a._attr->prev_attribute_c = attr._attr; - attr._attr->next_attribute = a._attr; - - return a; - } - - PUGI__FN xml_attribute xml_node::append_copy(const xml_attribute& proto) - { - if (!proto) return xml_attribute(); - - xml_attribute result = append_attribute(proto.name()); - result.set_value(proto.value()); - - return result; - } - - PUGI__FN xml_attribute xml_node::prepend_copy(const xml_attribute& proto) - { - if (!proto) return xml_attribute(); - - xml_attribute result = prepend_attribute(proto.name()); - result.set_value(proto.value()); - - return result; - } - - PUGI__FN xml_attribute xml_node::insert_copy_after(const xml_attribute& proto, const xml_attribute& attr) - { - if (!proto) return xml_attribute(); - - xml_attribute result = insert_attribute_after(proto.name(), attr); - result.set_value(proto.value()); - - return result; - } - - PUGI__FN xml_attribute xml_node::insert_copy_before(const xml_attribute& proto, const xml_attribute& attr) - { - if (!proto) return xml_attribute(); - - xml_attribute result = insert_attribute_before(proto.name(), attr); - result.set_value(proto.value()); - - return result; - } - - PUGI__FN xml_node xml_node::append_child(xml_node_type type_) - { - if (!impl::allow_insert_child(this->type(), type_)) return xml_node(); - - xml_node n(impl::append_node(_root, impl::get_allocator(_root), type_)); - - if (type_ == node_declaration) n.set_name(PUGIXML_TEXT("xml")); - - return n; - } - - PUGI__FN xml_node xml_node::prepend_child(xml_node_type type_) - { - if (!impl::allow_insert_child(this->type(), type_)) return xml_node(); - - xml_node n(impl::allocate_node(impl::get_allocator(_root), type_)); - if (!n) return xml_node(); - - n._root->parent = _root; - - xml_node_struct* head = _root->first_child; - - if (head) - { - n._root->prev_sibling_c = head->prev_sibling_c; - head->prev_sibling_c = n._root; - } - else - n._root->prev_sibling_c = n._root; - - n._root->next_sibling = head; - _root->first_child = n._root; - - if (type_ == node_declaration) n.set_name(PUGIXML_TEXT("xml")); - - return n; - } - - PUGI__FN xml_node xml_node::insert_child_before(xml_node_type type_, const xml_node& node) - { - if (!impl::allow_insert_child(this->type(), type_)) return xml_node(); - if (!node._root || node._root->parent != _root) return xml_node(); - - xml_node n(impl::allocate_node(impl::get_allocator(_root), type_)); - if (!n) return xml_node(); - - n._root->parent = _root; - - if (node._root->prev_sibling_c->next_sibling) - node._root->prev_sibling_c->next_sibling = n._root; - else - _root->first_child = n._root; - - n._root->prev_sibling_c = node._root->prev_sibling_c; - n._root->next_sibling = node._root; - node._root->prev_sibling_c = n._root; - - if (type_ == node_declaration) n.set_name(PUGIXML_TEXT("xml")); - - return n; - } - - PUGI__FN xml_node xml_node::insert_child_after(xml_node_type type_, const xml_node& node) - { - if (!impl::allow_insert_child(this->type(), type_)) return xml_node(); - if (!node._root || node._root->parent != _root) return xml_node(); - - xml_node n(impl::allocate_node(impl::get_allocator(_root), type_)); - if (!n) return xml_node(); - - n._root->parent = _root; - - if (node._root->next_sibling) - node._root->next_sibling->prev_sibling_c = n._root; - else - _root->first_child->prev_sibling_c = n._root; - - n._root->next_sibling = node._root->next_sibling; - n._root->prev_sibling_c = node._root; - node._root->next_sibling = n._root; - - if (type_ == node_declaration) n.set_name(PUGIXML_TEXT("xml")); - - return n; - } - - PUGI__FN xml_node xml_node::append_child(const char_t* name_) - { - xml_node result = append_child(node_element); - - result.set_name(name_); - - return result; - } - - PUGI__FN xml_node xml_node::prepend_child(const char_t* name_) - { - xml_node result = prepend_child(node_element); - - result.set_name(name_); - - return result; - } - - PUGI__FN xml_node xml_node::insert_child_after(const char_t* name_, const xml_node& node) - { - xml_node result = insert_child_after(node_element, node); - - result.set_name(name_); - - return result; - } - - PUGI__FN xml_node xml_node::insert_child_before(const char_t* name_, const xml_node& node) - { - xml_node result = insert_child_before(node_element, node); - - result.set_name(name_); - - return result; - } - - PUGI__FN xml_node xml_node::append_copy(const xml_node& proto) - { - xml_node result = append_child(proto.type()); - - if (result) impl::recursive_copy_skip(result, proto, result); - - return result; - } - - PUGI__FN xml_node xml_node::prepend_copy(const xml_node& proto) - { - xml_node result = prepend_child(proto.type()); - - if (result) impl::recursive_copy_skip(result, proto, result); - - return result; - } - - PUGI__FN xml_node xml_node::insert_copy_after(const xml_node& proto, const xml_node& node) - { - xml_node result = insert_child_after(proto.type(), node); - - if (result) impl::recursive_copy_skip(result, proto, result); - - return result; - } - - PUGI__FN xml_node xml_node::insert_copy_before(const xml_node& proto, const xml_node& node) - { - xml_node result = insert_child_before(proto.type(), node); - - if (result) impl::recursive_copy_skip(result, proto, result); - - return result; - } - - PUGI__FN bool xml_node::remove_attribute(const char_t* name_) - { - return remove_attribute(attribute(name_)); - } - - PUGI__FN bool xml_node::remove_attribute(const xml_attribute& a) - { - if (!_root || !a._attr) return false; - - // check that attribute belongs to *this - xml_attribute_struct* attr = a._attr; - - while (attr->prev_attribute_c->next_attribute) attr = attr->prev_attribute_c; - - if (attr != _root->first_attribute) return false; - - if (a._attr->next_attribute) a._attr->next_attribute->prev_attribute_c = a._attr->prev_attribute_c; - else if (_root->first_attribute) _root->first_attribute->prev_attribute_c = a._attr->prev_attribute_c; - - if (a._attr->prev_attribute_c->next_attribute) a._attr->prev_attribute_c->next_attribute = a._attr->next_attribute; - else _root->first_attribute = a._attr->next_attribute; - - impl::destroy_attribute(a._attr, impl::get_allocator(_root)); - - return true; - } - - PUGI__FN bool xml_node::remove_child(const char_t* name_) - { - return remove_child(child(name_)); - } - - PUGI__FN bool xml_node::remove_child(const xml_node& n) - { - if (!_root || !n._root || n._root->parent != _root) return false; - - if (n._root->next_sibling) n._root->next_sibling->prev_sibling_c = n._root->prev_sibling_c; - else if (_root->first_child) _root->first_child->prev_sibling_c = n._root->prev_sibling_c; - - if (n._root->prev_sibling_c->next_sibling) n._root->prev_sibling_c->next_sibling = n._root->next_sibling; - else _root->first_child = n._root->next_sibling; - - impl::destroy_node(n._root, impl::get_allocator(_root)); - - return true; - } - - PUGI__FN xml_node xml_node::find_child_by_attribute(const char_t* name_, const char_t* attr_name, const char_t* attr_value) const - { - if (!_root) return xml_node(); - - for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling) - if (i->name && impl::strequal(name_, i->name)) - { - for (xml_attribute_struct* a = i->first_attribute; a; a = a->next_attribute) - if (impl::strequal(attr_name, a->name) && impl::strequal(attr_value, a->value)) - return xml_node(i); - } - - return xml_node(); - } - - PUGI__FN xml_node xml_node::find_child_by_attribute(const char_t* attr_name, const char_t* attr_value) const - { - if (!_root) return xml_node(); - - for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling) - for (xml_attribute_struct* a = i->first_attribute; a; a = a->next_attribute) - if (impl::strequal(attr_name, a->name) && impl::strequal(attr_value, a->value)) - return xml_node(i); - - return xml_node(); - } - -#ifndef PUGIXML_NO_STL - PUGI__FN string_t xml_node::path(char_t delimiter) const - { - xml_node cursor = *this; // Make a copy. - - string_t result = cursor.name(); - - while (cursor.parent()) - { - cursor = cursor.parent(); - - string_t temp = cursor.name(); - temp += delimiter; - temp += result; - result.swap(temp); - } - - return result; - } -#endif - - PUGI__FN xml_node xml_node::first_element_by_path(const char_t* path_, char_t delimiter) const - { - xml_node found = *this; // Current search context. - - if (!_root || !path_ || !path_[0]) return found; - - if (path_[0] == delimiter) - { - // Absolute path; e.g. '/foo/bar' - found = found.root(); - ++path_; - } - - const char_t* path_segment = path_; - - while (*path_segment == delimiter) ++path_segment; - - const char_t* path_segment_end = path_segment; - - while (*path_segment_end && *path_segment_end != delimiter) ++path_segment_end; - - if (path_segment == path_segment_end) return found; - - const char_t* next_segment = path_segment_end; - - while (*next_segment == delimiter) ++next_segment; - - if (*path_segment == '.' && path_segment + 1 == path_segment_end) - return found.first_element_by_path(next_segment, delimiter); - else if (*path_segment == '.' && *(path_segment+1) == '.' && path_segment + 2 == path_segment_end) - return found.parent().first_element_by_path(next_segment, delimiter); - else - { - for (xml_node_struct* j = found._root->first_child; j; j = j->next_sibling) - { - if (j->name && impl::strequalrange(j->name, path_segment, static_cast(path_segment_end - path_segment))) - { - xml_node subsearch = xml_node(j).first_element_by_path(next_segment, delimiter); - - if (subsearch) return subsearch; - } - } - - return xml_node(); - } - } - - PUGI__FN bool xml_node::traverse(xml_tree_walker& walker) - { - walker._depth = -1; - - xml_node arg_begin = *this; - if (!walker.begin(arg_begin)) return false; - - xml_node cur = first_child(); - - if (cur) - { - ++walker._depth; - - do - { - xml_node arg_for_each = cur; - if (!walker.for_each(arg_for_each)) - return false; - - if (cur.first_child()) - { - ++walker._depth; - cur = cur.first_child(); - } - else if (cur.next_sibling()) - cur = cur.next_sibling(); - else - { - // Borland C++ workaround - while (!cur.next_sibling() && cur != *this && !cur.parent().empty()) - { - --walker._depth; - cur = cur.parent(); - } - - if (cur != *this) - cur = cur.next_sibling(); - } - } - while (cur && cur != *this); - } - - assert(walker._depth == -1); - - xml_node arg_end = *this; - return walker.end(arg_end); - } - - PUGI__FN size_t xml_node::hash_value() const - { - return static_cast(reinterpret_cast(_root) / sizeof(xml_node_struct)); - } - - PUGI__FN xml_node_struct* xml_node::internal_object() const - { - return _root; - } - - PUGI__FN void xml_node::print(xml_writer& writer, const char_t* indent, unsigned int flags, xml_encoding encoding, unsigned int depth) const - { - if (!_root) return; - - impl::xml_buffered_writer buffered_writer(writer, encoding); - - impl::node_output(buffered_writer, *this, indent, flags, depth); - } - -#ifndef PUGIXML_NO_STL - PUGI__FN void xml_node::print(std::basic_ostream >& stream, const char_t* indent, unsigned int flags, xml_encoding encoding, unsigned int depth) const - { - xml_writer_stream writer(stream); - - print(writer, indent, flags, encoding, depth); - } - - PUGI__FN void xml_node::print(std::basic_ostream >& stream, const char_t* indent, unsigned int flags, unsigned int depth) const - { - xml_writer_stream writer(stream); - - print(writer, indent, flags, encoding_wchar, depth); - } -#endif - - PUGI__FN ptrdiff_t xml_node::offset_debug() const - { - xml_node_struct* r = root()._root; - - if (!r) return -1; - - const char_t* buffer = static_cast(r)->buffer; - - if (!buffer) return -1; - - switch (type()) - { - case node_document: - return 0; - - case node_element: - case node_declaration: - case node_pi: - return (_root->header & impl::xml_memory_page_name_allocated_mask) ? -1 : _root->name - buffer; - - case node_pcdata: - case node_cdata: - case node_comment: - case node_doctype: - return (_root->header & impl::xml_memory_page_value_allocated_mask) ? -1 : _root->value - buffer; - - default: - return -1; - } - } - -#ifdef __BORLANDC__ - PUGI__FN bool operator&&(const xml_node& lhs, bool rhs) - { - return (bool)lhs && rhs; - } - - PUGI__FN bool operator||(const xml_node& lhs, bool rhs) - { - return (bool)lhs || rhs; - } -#endif - - PUGI__FN xml_text::xml_text(xml_node_struct* root): _root(root) - { - } - - PUGI__FN xml_node_struct* xml_text::_data() const - { - if (!_root || impl::is_text_node(_root)) return _root; - - for (xml_node_struct* node = _root->first_child; node; node = node->next_sibling) - if (impl::is_text_node(node)) - return node; - - return 0; - } - - PUGI__FN xml_node_struct* xml_text::_data_new() - { - xml_node_struct* d = _data(); - if (d) return d; - - return xml_node(_root).append_child(node_pcdata).internal_object(); - } - - PUGI__FN xml_text::xml_text(): _root(0) - { - } - - PUGI__FN static void unspecified_bool_xml_text(xml_text***) - { - } - - PUGI__FN xml_text::operator xml_text::unspecified_bool_type() const - { - return _data() ? unspecified_bool_xml_text : 0; - } - - PUGI__FN bool xml_text::operator!() const - { - return !_data(); - } - - PUGI__FN bool xml_text::empty() const - { - return _data() == 0; - } - - PUGI__FN const char_t* xml_text::get() const - { - xml_node_struct* d = _data(); - - return (d && d->value) ? d->value : PUGIXML_TEXT(""); - } - - PUGI__FN const char_t* xml_text::as_string(const char_t* def) const - { - xml_node_struct* d = _data(); - - return (d && d->value) ? d->value : def; - } - - PUGI__FN int xml_text::as_int(int def) const - { - xml_node_struct* d = _data(); - - return impl::get_value_int(d ? d->value : 0, def); - } - - PUGI__FN unsigned int xml_text::as_uint(unsigned int def) const - { - xml_node_struct* d = _data(); - - return impl::get_value_uint(d ? d->value : 0, def); - } - - PUGI__FN double xml_text::as_double(double def) const - { - xml_node_struct* d = _data(); - - return impl::get_value_double(d ? d->value : 0, def); - } - - PUGI__FN float xml_text::as_float(float def) const - { - xml_node_struct* d = _data(); - - return impl::get_value_float(d ? d->value : 0, def); - } - - PUGI__FN bool xml_text::as_bool(bool def) const - { - xml_node_struct* d = _data(); - - return impl::get_value_bool(d ? d->value : 0, def); - } - - PUGI__FN bool xml_text::set(const char_t* rhs) - { - xml_node_struct* dn = _data_new(); - - return dn ? impl::strcpy_insitu(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; - } - - PUGI__FN bool xml_text::set(int rhs) - { - xml_node_struct* dn = _data_new(); - - return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; - } - - PUGI__FN bool xml_text::set(unsigned int rhs) - { - xml_node_struct* dn = _data_new(); - - return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; - } - - PUGI__FN bool xml_text::set(double rhs) - { - xml_node_struct* dn = _data_new(); - - return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; - } - - PUGI__FN bool xml_text::set(bool rhs) - { - xml_node_struct* dn = _data_new(); - - return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; - } - - PUGI__FN xml_text& xml_text::operator=(const char_t* rhs) - { - set(rhs); - return *this; - } - - PUGI__FN xml_text& xml_text::operator=(int rhs) - { - set(rhs); - return *this; - } - - PUGI__FN xml_text& xml_text::operator=(unsigned int rhs) - { - set(rhs); - return *this; - } - - PUGI__FN xml_text& xml_text::operator=(double rhs) - { - set(rhs); - return *this; - } - - PUGI__FN xml_text& xml_text::operator=(bool rhs) - { - set(rhs); - return *this; - } - - PUGI__FN xml_node xml_text::data() const - { - return xml_node(_data()); - } - -#ifdef __BORLANDC__ - PUGI__FN bool operator&&(const xml_text& lhs, bool rhs) - { - return (bool)lhs && rhs; - } - - PUGI__FN bool operator||(const xml_text& lhs, bool rhs) - { - return (bool)lhs || rhs; - } -#endif - - PUGI__FN xml_node_iterator::xml_node_iterator() - { - } - - PUGI__FN xml_node_iterator::xml_node_iterator(const xml_node& node): _wrap(node), _parent(node.parent()) - { - } - - PUGI__FN xml_node_iterator::xml_node_iterator(xml_node_struct* ref, xml_node_struct* parent): _wrap(ref), _parent(parent) - { - } - - PUGI__FN bool xml_node_iterator::operator==(const xml_node_iterator& rhs) const - { - return _wrap._root == rhs._wrap._root && _parent._root == rhs._parent._root; - } - - PUGI__FN bool xml_node_iterator::operator!=(const xml_node_iterator& rhs) const - { - return _wrap._root != rhs._wrap._root || _parent._root != rhs._parent._root; - } - - PUGI__FN xml_node& xml_node_iterator::operator*() const - { - assert(_wrap._root); - return _wrap; - } - - PUGI__FN xml_node* xml_node_iterator::operator->() const - { - assert(_wrap._root); - return const_cast(&_wrap); // BCC32 workaround - } - - PUGI__FN const xml_node_iterator& xml_node_iterator::operator++() - { - assert(_wrap._root); - _wrap._root = _wrap._root->next_sibling; - return *this; - } - - PUGI__FN xml_node_iterator xml_node_iterator::operator++(int) - { - xml_node_iterator temp = *this; - ++*this; - return temp; - } - - PUGI__FN const xml_node_iterator& xml_node_iterator::operator--() - { - _wrap = _wrap._root ? _wrap.previous_sibling() : _parent.last_child(); - return *this; - } - - PUGI__FN xml_node_iterator xml_node_iterator::operator--(int) - { - xml_node_iterator temp = *this; - --*this; - return temp; - } - - PUGI__FN xml_attribute_iterator::xml_attribute_iterator() - { - } - - PUGI__FN xml_attribute_iterator::xml_attribute_iterator(const xml_attribute& attr, const xml_node& parent): _wrap(attr), _parent(parent) - { - } - - PUGI__FN xml_attribute_iterator::xml_attribute_iterator(xml_attribute_struct* ref, xml_node_struct* parent): _wrap(ref), _parent(parent) - { - } - - PUGI__FN bool xml_attribute_iterator::operator==(const xml_attribute_iterator& rhs) const - { - return _wrap._attr == rhs._wrap._attr && _parent._root == rhs._parent._root; - } - - PUGI__FN bool xml_attribute_iterator::operator!=(const xml_attribute_iterator& rhs) const - { - return _wrap._attr != rhs._wrap._attr || _parent._root != rhs._parent._root; - } - - PUGI__FN xml_attribute& xml_attribute_iterator::operator*() const - { - assert(_wrap._attr); - return _wrap; - } - - PUGI__FN xml_attribute* xml_attribute_iterator::operator->() const - { - assert(_wrap._attr); - return const_cast(&_wrap); // BCC32 workaround - } - - PUGI__FN const xml_attribute_iterator& xml_attribute_iterator::operator++() - { - assert(_wrap._attr); - _wrap._attr = _wrap._attr->next_attribute; - return *this; - } - - PUGI__FN xml_attribute_iterator xml_attribute_iterator::operator++(int) - { - xml_attribute_iterator temp = *this; - ++*this; - return temp; - } - - PUGI__FN const xml_attribute_iterator& xml_attribute_iterator::operator--() - { - _wrap = _wrap._attr ? _wrap.previous_attribute() : _parent.last_attribute(); - return *this; - } - - PUGI__FN xml_attribute_iterator xml_attribute_iterator::operator--(int) - { - xml_attribute_iterator temp = *this; - --*this; - return temp; - } - - PUGI__FN xml_named_node_iterator::xml_named_node_iterator(): _name(0) - { - } - - PUGI__FN xml_named_node_iterator::xml_named_node_iterator(const xml_node& node, const char_t* name): _node(node), _name(name) - { - } - - PUGI__FN bool xml_named_node_iterator::operator==(const xml_named_node_iterator& rhs) const - { - return _node == rhs._node; - } - - PUGI__FN bool xml_named_node_iterator::operator!=(const xml_named_node_iterator& rhs) const - { - return _node != rhs._node; - } - - PUGI__FN xml_node& xml_named_node_iterator::operator*() const - { - assert(_node._root); - return _node; - } - - PUGI__FN xml_node* xml_named_node_iterator::operator->() const - { - assert(_node._root); - return const_cast(&_node); // BCC32 workaround - } - - PUGI__FN const xml_named_node_iterator& xml_named_node_iterator::operator++() - { - assert(_node._root); - _node = _node.next_sibling(_name); - return *this; - } - - PUGI__FN xml_named_node_iterator xml_named_node_iterator::operator++(int) - { - xml_named_node_iterator temp = *this; - ++*this; - return temp; - } - - PUGI__FN xml_parse_result::xml_parse_result(): status(status_internal_error), offset(0), encoding(encoding_auto) - { - } - - PUGI__FN xml_parse_result::operator bool() const - { - return status == status_ok; - } - - PUGI__FN const char* xml_parse_result::description() const - { - switch (status) - { - case status_ok: return "No error"; - - case status_file_not_found: return "File was not found"; - case status_io_error: return "Error reading from file/stream"; - case status_out_of_memory: return "Could not allocate memory"; - case status_internal_error: return "Internal error occurred"; - - case status_unrecognized_tag: return "Could not determine tag type"; - - case status_bad_pi: return "Error parsing document declaration/processing instruction"; - case status_bad_comment: return "Error parsing comment"; - case status_bad_cdata: return "Error parsing CDATA section"; - case status_bad_doctype: return "Error parsing document type declaration"; - case status_bad_pcdata: return "Error parsing PCDATA section"; - case status_bad_start_element: return "Error parsing start element tag"; - case status_bad_attribute: return "Error parsing element attribute"; - case status_bad_end_element: return "Error parsing end element tag"; - case status_end_element_mismatch: return "Start-end tags mismatch"; - - default: return "Unknown error"; - } - } - - PUGI__FN xml_document::xml_document(): _buffer(0) - { - create(); - } - - PUGI__FN xml_document::~xml_document() - { - destroy(); - } - - PUGI__FN void xml_document::reset() - { - destroy(); - create(); - } - - PUGI__FN void xml_document::reset(const xml_document& proto) - { - reset(); - - for (xml_node cur = proto.first_child(); cur; cur = cur.next_sibling()) - append_copy(cur); - } - - PUGI__FN void xml_document::create() - { - // initialize sentinel page - PUGI__STATIC_ASSERT(offsetof(impl::xml_memory_page, data) + sizeof(impl::xml_document_struct) + impl::xml_memory_page_alignment <= sizeof(_memory)); - - // align upwards to page boundary - void* page_memory = reinterpret_cast((reinterpret_cast(_memory) + (impl::xml_memory_page_alignment - 1)) & ~(impl::xml_memory_page_alignment - 1)); - - // prepare page structure - impl::xml_memory_page* page = impl::xml_memory_page::construct(page_memory); - - page->busy_size = impl::xml_memory_page_size; - - // allocate new root - _root = new (page->data) impl::xml_document_struct(page); - _root->prev_sibling_c = _root; - - // setup sentinel page - page->allocator = static_cast(_root); - } - - PUGI__FN void xml_document::destroy() - { - // destroy static storage - if (_buffer) - { - impl::xml_memory::deallocate(_buffer); - _buffer = 0; - } - - // destroy dynamic storage, leave sentinel page (it's in static memory) - if (_root) - { - impl::xml_memory_page* root_page = reinterpret_cast(_root->header & impl::xml_memory_page_pointer_mask); - assert(root_page && !root_page->prev && !root_page->memory); - - // destroy all pages - for (impl::xml_memory_page* page = root_page->next; page; ) - { - impl::xml_memory_page* next = page->next; - - impl::xml_allocator::deallocate_page(page); - - page = next; - } - - // cleanup root page - root_page->allocator = 0; - root_page->next = 0; - root_page->busy_size = root_page->freed_size = 0; - - _root = 0; - } - } - -#ifndef PUGIXML_NO_STL - PUGI__FN xml_parse_result xml_document::load(std::basic_istream >& stream, unsigned int options, xml_encoding encoding) - { - reset(); - - return impl::load_stream_impl(*this, stream, options, encoding); - } - - PUGI__FN xml_parse_result xml_document::load(std::basic_istream >& stream, unsigned int options) - { - reset(); - - return impl::load_stream_impl(*this, stream, options, encoding_wchar); - } -#endif - - PUGI__FN xml_parse_result xml_document::load(const char_t* contents, unsigned int options) - { - // Force native encoding (skip autodetection) - #ifdef PUGIXML_WCHAR_MODE - xml_encoding encoding = encoding_wchar; - #else - xml_encoding encoding = encoding_utf8; - #endif - - return load_buffer(contents, impl::strlength(contents) * sizeof(char_t), options, encoding); - } - - PUGI__FN xml_parse_result xml_document::load_file(const char* path_, unsigned int options, xml_encoding encoding) - { - reset(); - - FILE* file = fopen(path_, "rb"); - - return impl::load_file_impl(*this, file, options, encoding); - } - - PUGI__FN xml_parse_result xml_document::load_file(const wchar_t* path_, unsigned int options, xml_encoding encoding) - { - reset(); - - FILE* file = impl::open_file_wide(path_, L"rb"); - - return impl::load_file_impl(*this, file, options, encoding); - } - - PUGI__FN xml_parse_result xml_document::load_buffer_impl(void* contents, size_t size, unsigned int options, xml_encoding encoding, bool is_mutable, bool own) - { - reset(); - - // check input buffer - assert(contents || size == 0); - - // get actual encoding - xml_encoding buffer_encoding = impl::get_buffer_encoding(encoding, contents, size); - - // get private buffer - char_t* buffer = 0; - size_t length = 0; - - if (!impl::convert_buffer(buffer, length, buffer_encoding, contents, size, is_mutable)) return impl::make_parse_result(status_out_of_memory); - - // delete original buffer if we performed a conversion - if (own && buffer != contents && contents) impl::xml_memory::deallocate(contents); - - // parse - xml_parse_result res = impl::xml_parser::parse(buffer, length, _root, options); - - // remember encoding - res.encoding = buffer_encoding; - - // grab onto buffer if it's our buffer, user is responsible for deallocating contens himself - if (own || buffer != contents) _buffer = buffer; - - return res; - } - - PUGI__FN xml_parse_result xml_document::load_buffer(const void* contents, size_t size, unsigned int options, xml_encoding encoding) - { - return load_buffer_impl(const_cast(contents), size, options, encoding, false, false); - } - - PUGI__FN xml_parse_result xml_document::load_buffer_inplace(void* contents, size_t size, unsigned int options, xml_encoding encoding) - { - return load_buffer_impl(contents, size, options, encoding, true, false); - } - - PUGI__FN xml_parse_result xml_document::load_buffer_inplace_own(void* contents, size_t size, unsigned int options, xml_encoding encoding) - { - return load_buffer_impl(contents, size, options, encoding, true, true); - } - - PUGI__FN void xml_document::save(xml_writer& writer, const char_t* indent, unsigned int flags, xml_encoding encoding) const - { - impl::xml_buffered_writer buffered_writer(writer, encoding); - - if ((flags & format_write_bom) && encoding != encoding_latin1) - { - // BOM always represents the codepoint U+FEFF, so just write it in native encoding - #ifdef PUGIXML_WCHAR_MODE - unsigned int bom = 0xfeff; - buffered_writer.write(static_cast(bom)); - #else - buffered_writer.write('\xef', '\xbb', '\xbf'); - #endif - } - - if (!(flags & format_no_declaration) && !impl::has_declaration(*this)) - { - buffered_writer.write(PUGIXML_TEXT("'); - if (!(flags & format_raw)) buffered_writer.write('\n'); - } - - impl::node_output(buffered_writer, *this, indent, flags, 0); - } - -#ifndef PUGIXML_NO_STL - PUGI__FN void xml_document::save(std::basic_ostream >& stream, const char_t* indent, unsigned int flags, xml_encoding encoding) const - { - xml_writer_stream writer(stream); - - save(writer, indent, flags, encoding); - } - - PUGI__FN void xml_document::save(std::basic_ostream >& stream, const char_t* indent, unsigned int flags) const - { - xml_writer_stream writer(stream); - - save(writer, indent, flags, encoding_wchar); - } -#endif - - PUGI__FN bool xml_document::save_file(const char* path_, const char_t* indent, unsigned int flags, xml_encoding encoding) const - { - FILE* file = fopen(path_, (flags & format_save_file_text) ? "w" : "wb"); - return impl::save_file_impl(*this, file, indent, flags, encoding); - } - - PUGI__FN bool xml_document::save_file(const wchar_t* path_, const char_t* indent, unsigned int flags, xml_encoding encoding) const - { - FILE* file = impl::open_file_wide(path_, (flags & format_save_file_text) ? L"w" : L"wb"); - return impl::save_file_impl(*this, file, indent, flags, encoding); - } - - PUGI__FN xml_node xml_document::document_element() const - { - for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling) - if ((i->header & impl::xml_memory_page_type_mask) + 1 == node_element) - return xml_node(i); - - return xml_node(); - } - -#ifndef PUGIXML_NO_STL - PUGI__FN std::string PUGIXML_FUNCTION as_utf8(const wchar_t* str) - { - assert(str); - - return impl::as_utf8_impl(str, wcslen(str)); - } - - PUGI__FN std::string PUGIXML_FUNCTION as_utf8(const std::basic_string& str) - { - return impl::as_utf8_impl(str.c_str(), str.size()); - } - - PUGI__FN std::basic_string PUGIXML_FUNCTION as_wide(const char* str) - { - assert(str); - - return impl::as_wide_impl(str, strlen(str)); - } - - PUGI__FN std::basic_string PUGIXML_FUNCTION as_wide(const std::string& str) - { - return impl::as_wide_impl(str.c_str(), str.size()); - } -#endif - - PUGI__FN void PUGIXML_FUNCTION set_memory_management_functions(allocation_function allocate, deallocation_function deallocate) - { - impl::xml_memory::allocate = allocate; - impl::xml_memory::deallocate = deallocate; - } - - PUGI__FN allocation_function PUGIXML_FUNCTION get_memory_allocation_function() - { - return impl::xml_memory::allocate; - } - - PUGI__FN deallocation_function PUGIXML_FUNCTION get_memory_deallocation_function() - { - return impl::xml_memory::deallocate; - } -} - -#if !defined(PUGIXML_NO_STL) && (defined(_MSC_VER) || defined(__ICC)) -namespace std -{ - // Workarounds for (non-standard) iterator category detection for older versions (MSVC7/IC8 and earlier) - PUGI__FN std::bidirectional_iterator_tag _Iter_cat(const pugi::xml_node_iterator&) - { - return std::bidirectional_iterator_tag(); - } - - PUGI__FN std::bidirectional_iterator_tag _Iter_cat(const pugi::xml_attribute_iterator&) - { - return std::bidirectional_iterator_tag(); - } - - PUGI__FN std::forward_iterator_tag _Iter_cat(const pugi::xml_named_node_iterator&) - { - return std::forward_iterator_tag(); - } -} -#endif - -#if !defined(PUGIXML_NO_STL) && defined(__SUNPRO_CC) -namespace std -{ - // Workarounds for (non-standard) iterator category detection - PUGI__FN std::bidirectional_iterator_tag __iterator_category(const pugi::xml_node_iterator&) - { - return std::bidirectional_iterator_tag(); - } - - PUGI__FN std::bidirectional_iterator_tag __iterator_category(const pugi::xml_attribute_iterator&) - { - return std::bidirectional_iterator_tag(); - } - - PUGI__FN std::forward_iterator_tag __iterator_category(const pugi::xml_named_node_iterator&) - { - return std::forward_iterator_tag(); - } -} -#endif - -#ifndef PUGIXML_NO_XPATH - -// STL replacements -PUGI__NS_BEGIN - struct equal_to - { - template bool operator()(const T& lhs, const T& rhs) const - { - return lhs == rhs; - } - }; - - struct not_equal_to - { - template bool operator()(const T& lhs, const T& rhs) const - { - return lhs != rhs; - } - }; - - struct less - { - template bool operator()(const T& lhs, const T& rhs) const - { - return lhs < rhs; - } - }; - - struct less_equal - { - template bool operator()(const T& lhs, const T& rhs) const - { - return lhs <= rhs; - } - }; - - template void swap(T& lhs, T& rhs) - { - T temp = lhs; - lhs = rhs; - rhs = temp; - } - - template I min_element(I begin, I end, const Pred& pred) - { - I result = begin; - - for (I it = begin + 1; it != end; ++it) - if (pred(*it, *result)) - result = it; - - return result; - } - - template void reverse(I begin, I end) - { - while (begin + 1 < end) swap(*begin++, *--end); - } - - template I unique(I begin, I end) - { - // fast skip head - while (begin + 1 < end && *begin != *(begin + 1)) begin++; - - if (begin == end) return begin; - - // last written element - I write = begin++; - - // merge unique elements - while (begin != end) - { - if (*begin != *write) - *++write = *begin++; - else - begin++; - } - - // past-the-end (write points to live element) - return write + 1; - } - - template void copy_backwards(I begin, I end, I target) - { - while (begin != end) *--target = *--end; - } - - template void insertion_sort(I begin, I end, const Pred& pred, T*) - { - assert(begin != end); - - for (I it = begin + 1; it != end; ++it) - { - T val = *it; - - if (pred(val, *begin)) - { - // move to front - copy_backwards(begin, it, it + 1); - *begin = val; - } - else - { - I hole = it; - - // move hole backwards - while (pred(val, *(hole - 1))) - { - *hole = *(hole - 1); - hole--; - } - - // fill hole with element - *hole = val; - } - } - } - - // std variant for elements with == - template void partition(I begin, I middle, I end, const Pred& pred, I* out_eqbeg, I* out_eqend) - { - I eqbeg = middle, eqend = middle + 1; - - // expand equal range - while (eqbeg != begin && *(eqbeg - 1) == *eqbeg) --eqbeg; - while (eqend != end && *eqend == *eqbeg) ++eqend; - - // process outer elements - I ltend = eqbeg, gtbeg = eqend; - - for (;;) - { - // find the element from the right side that belongs to the left one - for (; gtbeg != end; ++gtbeg) - if (!pred(*eqbeg, *gtbeg)) - { - if (*gtbeg == *eqbeg) swap(*gtbeg, *eqend++); - else break; - } - - // find the element from the left side that belongs to the right one - for (; ltend != begin; --ltend) - if (!pred(*(ltend - 1), *eqbeg)) - { - if (*eqbeg == *(ltend - 1)) swap(*(ltend - 1), *--eqbeg); - else break; - } - - // scanned all elements - if (gtbeg == end && ltend == begin) - { - *out_eqbeg = eqbeg; - *out_eqend = eqend; - return; - } - - // make room for elements by moving equal area - if (gtbeg == end) - { - if (--ltend != --eqbeg) swap(*ltend, *eqbeg); - swap(*eqbeg, *--eqend); - } - else if (ltend == begin) - { - if (eqend != gtbeg) swap(*eqbeg, *eqend); - ++eqend; - swap(*gtbeg++, *eqbeg++); - } - else swap(*gtbeg++, *--ltend); - } - } - - template void median3(I first, I middle, I last, const Pred& pred) - { - if (pred(*middle, *first)) swap(*middle, *first); - if (pred(*last, *middle)) swap(*last, *middle); - if (pred(*middle, *first)) swap(*middle, *first); - } - - template void median(I first, I middle, I last, const Pred& pred) - { - if (last - first <= 40) - { - // median of three for small chunks - median3(first, middle, last, pred); - } - else - { - // median of nine - size_t step = (last - first + 1) / 8; - - median3(first, first + step, first + 2 * step, pred); - median3(middle - step, middle, middle + step, pred); - median3(last - 2 * step, last - step, last, pred); - median3(first + step, middle, last - step, pred); - } - } - - template void sort(I begin, I end, const Pred& pred) - { - // sort large chunks - while (end - begin > 32) - { - // find median element - I middle = begin + (end - begin) / 2; - median(begin, middle, end - 1, pred); - - // partition in three chunks (< = >) - I eqbeg, eqend; - partition(begin, middle, end, pred, &eqbeg, &eqend); - - // loop on larger half - if (eqbeg - begin > end - eqend) - { - sort(eqend, end, pred); - end = eqbeg; - } - else - { - sort(begin, eqbeg, pred); - begin = eqend; - } - } - - // insertion sort small chunk - if (begin != end) insertion_sort(begin, end, pred, &*begin); - } -PUGI__NS_END - -// Allocator used for AST and evaluation stacks -PUGI__NS_BEGIN - struct xpath_memory_block - { - xpath_memory_block* next; - - char data[ - #ifdef PUGIXML_MEMORY_XPATH_PAGE_SIZE - PUGIXML_MEMORY_XPATH_PAGE_SIZE - #else - 4096 - #endif - ]; - }; - - class xpath_allocator - { - xpath_memory_block* _root; - size_t _root_size; - - public: - #ifdef PUGIXML_NO_EXCEPTIONS - jmp_buf* error_handler; - #endif - - xpath_allocator(xpath_memory_block* root, size_t root_size = 0): _root(root), _root_size(root_size) - { - #ifdef PUGIXML_NO_EXCEPTIONS - error_handler = 0; - #endif - } - - void* allocate_nothrow(size_t size) - { - const size_t block_capacity = sizeof(_root->data); - - // align size so that we're able to store pointers in subsequent blocks - size = (size + sizeof(void*) - 1) & ~(sizeof(void*) - 1); - - if (_root_size + size <= block_capacity) - { - void* buf = _root->data + _root_size; - _root_size += size; - return buf; - } - else - { - size_t block_data_size = (size > block_capacity) ? size : block_capacity; - size_t block_size = block_data_size + offsetof(xpath_memory_block, data); - - xpath_memory_block* block = static_cast(xml_memory::allocate(block_size)); - if (!block) return 0; - - block->next = _root; - - _root = block; - _root_size = size; - - return block->data; - } - } - - void* allocate(size_t size) - { - void* result = allocate_nothrow(size); - - if (!result) - { - #ifdef PUGIXML_NO_EXCEPTIONS - assert(error_handler); - longjmp(*error_handler, 1); - #else - throw std::bad_alloc(); - #endif - } - - return result; - } - - void* reallocate(void* ptr, size_t old_size, size_t new_size) - { - // align size so that we're able to store pointers in subsequent blocks - old_size = (old_size + sizeof(void*) - 1) & ~(sizeof(void*) - 1); - new_size = (new_size + sizeof(void*) - 1) & ~(sizeof(void*) - 1); - - // we can only reallocate the last object - assert(ptr == 0 || static_cast(ptr) + old_size == _root->data + _root_size); - - // adjust root size so that we have not allocated the object at all - bool only_object = (_root_size == old_size); - - if (ptr) _root_size -= old_size; - - // allocate a new version (this will obviously reuse the memory if possible) - void* result = allocate(new_size); - assert(result); - - // we have a new block - if (result != ptr && ptr) - { - // copy old data - assert(new_size > old_size); - memcpy(result, ptr, old_size); - - // free the previous page if it had no other objects - if (only_object) - { - assert(_root->data == result); - assert(_root->next); - - xpath_memory_block* next = _root->next->next; - - if (next) - { - // deallocate the whole page, unless it was the first one - xml_memory::deallocate(_root->next); - _root->next = next; - } - } - } - - return result; - } - - void revert(const xpath_allocator& state) - { - // free all new pages - xpath_memory_block* cur = _root; - - while (cur != state._root) - { - xpath_memory_block* next = cur->next; - - xml_memory::deallocate(cur); - - cur = next; - } - - // restore state - _root = state._root; - _root_size = state._root_size; - } - - void release() - { - xpath_memory_block* cur = _root; - assert(cur); - - while (cur->next) - { - xpath_memory_block* next = cur->next; - - xml_memory::deallocate(cur); - - cur = next; - } - } - }; - - struct xpath_allocator_capture - { - xpath_allocator_capture(xpath_allocator* alloc): _target(alloc), _state(*alloc) - { - } - - ~xpath_allocator_capture() - { - _target->revert(_state); - } - - xpath_allocator* _target; - xpath_allocator _state; - }; - - struct xpath_stack - { - xpath_allocator* result; - xpath_allocator* temp; - }; - - struct xpath_stack_data - { - xpath_memory_block blocks[2]; - xpath_allocator result; - xpath_allocator temp; - xpath_stack stack; - - #ifdef PUGIXML_NO_EXCEPTIONS - jmp_buf error_handler; - #endif - - xpath_stack_data(): result(blocks + 0), temp(blocks + 1) - { - blocks[0].next = blocks[1].next = 0; - - stack.result = &result; - stack.temp = &temp; - - #ifdef PUGIXML_NO_EXCEPTIONS - result.error_handler = temp.error_handler = &error_handler; - #endif - } - - ~xpath_stack_data() - { - result.release(); - temp.release(); - } - }; -PUGI__NS_END - -// String class -PUGI__NS_BEGIN - class xpath_string - { - const char_t* _buffer; - bool _uses_heap; - - static char_t* duplicate_string(const char_t* string, size_t length, xpath_allocator* alloc) - { - char_t* result = static_cast(alloc->allocate((length + 1) * sizeof(char_t))); - assert(result); - - memcpy(result, string, length * sizeof(char_t)); - result[length] = 0; - - return result; - } - - static char_t* duplicate_string(const char_t* string, xpath_allocator* alloc) - { - return duplicate_string(string, strlength(string), alloc); - } - - public: - xpath_string(): _buffer(PUGIXML_TEXT("")), _uses_heap(false) - { - } - - explicit xpath_string(const char_t* str, xpath_allocator* alloc) - { - bool empty_ = (*str == 0); - - _buffer = empty_ ? PUGIXML_TEXT("") : duplicate_string(str, alloc); - _uses_heap = !empty_; - } - - explicit xpath_string(const char_t* str, bool use_heap): _buffer(str), _uses_heap(use_heap) - { - } - - xpath_string(const char_t* begin, const char_t* end, xpath_allocator* alloc) - { - assert(begin <= end); - - bool empty_ = (begin == end); - - _buffer = empty_ ? PUGIXML_TEXT("") : duplicate_string(begin, static_cast(end - begin), alloc); - _uses_heap = !empty_; - } - - void append(const xpath_string& o, xpath_allocator* alloc) - { - // skip empty sources - if (!*o._buffer) return; - - // fast append for constant empty target and constant source - if (!*_buffer && !_uses_heap && !o._uses_heap) - { - _buffer = o._buffer; - } - else - { - // need to make heap copy - size_t target_length = strlength(_buffer); - size_t source_length = strlength(o._buffer); - size_t result_length = target_length + source_length; - - // allocate new buffer - char_t* result = static_cast(alloc->reallocate(_uses_heap ? const_cast(_buffer) : 0, (target_length + 1) * sizeof(char_t), (result_length + 1) * sizeof(char_t))); - assert(result); - - // append first string to the new buffer in case there was no reallocation - if (!_uses_heap) memcpy(result, _buffer, target_length * sizeof(char_t)); - - // append second string to the new buffer - memcpy(result + target_length, o._buffer, source_length * sizeof(char_t)); - result[result_length] = 0; - - // finalize - _buffer = result; - _uses_heap = true; - } - } - - const char_t* c_str() const - { - return _buffer; - } - - size_t length() const - { - return strlength(_buffer); - } - - char_t* data(xpath_allocator* alloc) - { - // make private heap copy - if (!_uses_heap) - { - _buffer = duplicate_string(_buffer, alloc); - _uses_heap = true; - } - - return const_cast(_buffer); - } - - bool empty() const - { - return *_buffer == 0; - } - - bool operator==(const xpath_string& o) const - { - return strequal(_buffer, o._buffer); - } - - bool operator!=(const xpath_string& o) const - { - return !strequal(_buffer, o._buffer); - } - - bool uses_heap() const - { - return _uses_heap; - } - }; - - PUGI__FN xpath_string xpath_string_const(const char_t* str) - { - return xpath_string(str, false); - } -PUGI__NS_END - -PUGI__NS_BEGIN - PUGI__FN bool starts_with(const char_t* string, const char_t* pattern) - { - while (*pattern && *string == *pattern) - { - string++; - pattern++; - } - - return *pattern == 0; - } - - PUGI__FN const char_t* find_char(const char_t* s, char_t c) - { - #ifdef PUGIXML_WCHAR_MODE - return wcschr(s, c); - #else - return strchr(s, c); - #endif - } - - PUGI__FN const char_t* find_substring(const char_t* s, const char_t* p) - { - #ifdef PUGIXML_WCHAR_MODE - // MSVC6 wcsstr bug workaround (if s is empty it always returns 0) - return (*p == 0) ? s : wcsstr(s, p); - #else - return strstr(s, p); - #endif - } - - // Converts symbol to lower case, if it is an ASCII one - PUGI__FN char_t tolower_ascii(char_t ch) - { - return static_cast(ch - 'A') < 26 ? static_cast(ch | ' ') : ch; - } - - PUGI__FN xpath_string string_value(const xpath_node& na, xpath_allocator* alloc) - { - if (na.attribute()) - return xpath_string_const(na.attribute().value()); - else - { - const xml_node& n = na.node(); - - switch (n.type()) - { - case node_pcdata: - case node_cdata: - case node_comment: - case node_pi: - return xpath_string_const(n.value()); - - case node_document: - case node_element: - { - xpath_string result; - - xml_node cur = n.first_child(); - - while (cur && cur != n) - { - if (cur.type() == node_pcdata || cur.type() == node_cdata) - result.append(xpath_string_const(cur.value()), alloc); - - if (cur.first_child()) - cur = cur.first_child(); - else if (cur.next_sibling()) - cur = cur.next_sibling(); - else - { - while (!cur.next_sibling() && cur != n) - cur = cur.parent(); - - if (cur != n) cur = cur.next_sibling(); - } - } - - return result; - } - - default: - return xpath_string(); - } - } - } - - PUGI__FN unsigned int node_height(xml_node n) - { - unsigned int result = 0; - - while (n) - { - ++result; - n = n.parent(); - } - - return result; - } - - PUGI__FN bool node_is_before(xml_node ln, unsigned int lh, xml_node rn, unsigned int rh) - { - // normalize heights - for (unsigned int i = rh; i < lh; i++) ln = ln.parent(); - for (unsigned int j = lh; j < rh; j++) rn = rn.parent(); - - // one node is the ancestor of the other - if (ln == rn) return lh < rh; - - // find common ancestor - while (ln.parent() != rn.parent()) - { - ln = ln.parent(); - rn = rn.parent(); - } - - // there is no common ancestor (the shared parent is null), nodes are from different documents - if (!ln.parent()) return ln < rn; - - // determine sibling order - for (; ln; ln = ln.next_sibling()) - if (ln == rn) - return true; - - return false; - } - - PUGI__FN bool node_is_ancestor(xml_node parent, xml_node node) - { - while (node && node != parent) node = node.parent(); - - return parent && node == parent; - } - - PUGI__FN const void* document_order(const xpath_node& xnode) - { - xml_node_struct* node = xnode.node().internal_object(); - - if (node) - { - if (node->name && (node->header & xml_memory_page_name_allocated_mask) == 0) return node->name; - if (node->value && (node->header & xml_memory_page_value_allocated_mask) == 0) return node->value; - return 0; - } - - xml_attribute_struct* attr = xnode.attribute().internal_object(); - - if (attr) - { - if ((attr->header & xml_memory_page_name_allocated_mask) == 0) return attr->name; - if ((attr->header & xml_memory_page_value_allocated_mask) == 0) return attr->value; - return 0; - } - - return 0; - } - - struct document_order_comparator - { - bool operator()(const xpath_node& lhs, const xpath_node& rhs) const - { - // optimized document order based check - const void* lo = document_order(lhs); - const void* ro = document_order(rhs); - - if (lo && ro) return lo < ro; - - // slow comparison - xml_node ln = lhs.node(), rn = rhs.node(); - - // compare attributes - if (lhs.attribute() && rhs.attribute()) - { - // shared parent - if (lhs.parent() == rhs.parent()) - { - // determine sibling order - for (xml_attribute a = lhs.attribute(); a; a = a.next_attribute()) - if (a == rhs.attribute()) - return true; - - return false; - } - - // compare attribute parents - ln = lhs.parent(); - rn = rhs.parent(); - } - else if (lhs.attribute()) - { - // attributes go after the parent element - if (lhs.parent() == rhs.node()) return false; - - ln = lhs.parent(); - } - else if (rhs.attribute()) - { - // attributes go after the parent element - if (rhs.parent() == lhs.node()) return true; - - rn = rhs.parent(); - } - - if (ln == rn) return false; - - unsigned int lh = node_height(ln); - unsigned int rh = node_height(rn); - - return node_is_before(ln, lh, rn, rh); - } - }; - - struct duplicate_comparator - { - bool operator()(const xpath_node& lhs, const xpath_node& rhs) const - { - if (lhs.attribute()) return rhs.attribute() ? lhs.attribute() < rhs.attribute() : true; - else return rhs.attribute() ? false : lhs.node() < rhs.node(); - } - }; - - PUGI__FN double gen_nan() - { - #if defined(__STDC_IEC_559__) || ((FLT_RADIX - 0 == 2) && (FLT_MAX_EXP - 0 == 128) && (FLT_MANT_DIG - 0 == 24)) - union { float f; uint32_t i; } u[sizeof(float) == sizeof(uint32_t) ? 1 : -1]; - u[0].i = 0x7fc00000; - return u[0].f; - #else - // fallback - const volatile double zero = 0.0; - return zero / zero; - #endif - } - - PUGI__FN bool is_nan(double value) - { - #if defined(PUGI__MSVC_CRT_VERSION) || defined(__BORLANDC__) - return !!_isnan(value); - #elif defined(fpclassify) && defined(FP_NAN) - return fpclassify(value) == FP_NAN; - #else - // fallback - const volatile double v = value; - return v != v; - #endif - } - - PUGI__FN const char_t* convert_number_to_string_special(double value) - { - #if defined(PUGI__MSVC_CRT_VERSION) || defined(__BORLANDC__) - if (_finite(value)) return (value == 0) ? PUGIXML_TEXT("0") : 0; - if (_isnan(value)) return PUGIXML_TEXT("NaN"); - return value > 0 ? PUGIXML_TEXT("Infinity") : PUGIXML_TEXT("-Infinity"); - #elif defined(fpclassify) && defined(FP_NAN) && defined(FP_INFINITE) && defined(FP_ZERO) - switch (fpclassify(value)) - { - case FP_NAN: - return PUGIXML_TEXT("NaN"); - - case FP_INFINITE: - return value > 0 ? PUGIXML_TEXT("Infinity") : PUGIXML_TEXT("-Infinity"); - - case FP_ZERO: - return PUGIXML_TEXT("0"); - - default: - return 0; - } - #else - // fallback - const volatile double v = value; - - if (v == 0) return PUGIXML_TEXT("0"); - if (v != v) return PUGIXML_TEXT("NaN"); - if (v * 2 == v) return value > 0 ? PUGIXML_TEXT("Infinity") : PUGIXML_TEXT("-Infinity"); - return 0; - #endif - } - - PUGI__FN bool convert_number_to_boolean(double value) - { - return (value != 0 && !is_nan(value)); - } - - PUGI__FN void truncate_zeros(char* begin, char* end) - { - while (begin != end && end[-1] == '0') end--; - - *end = 0; - } - - // gets mantissa digits in the form of 0.xxxxx with 0. implied and the exponent -#if defined(PUGI__MSVC_CRT_VERSION) && PUGI__MSVC_CRT_VERSION >= 1400 && !defined(_WIN32_WCE) - PUGI__FN void convert_number_to_mantissa_exponent(double value, char* buffer, size_t buffer_size, char** out_mantissa, int* out_exponent) - { - // get base values - int sign, exponent; - _ecvt_s(buffer, buffer_size, value, DBL_DIG + 1, &exponent, &sign); - - // truncate redundant zeros - truncate_zeros(buffer, buffer + strlen(buffer)); - - // fill results - *out_mantissa = buffer; - *out_exponent = exponent; - } -#else - PUGI__FN void convert_number_to_mantissa_exponent(double value, char* buffer, size_t buffer_size, char** out_mantissa, int* out_exponent) - { - // get a scientific notation value with IEEE DBL_DIG decimals - sprintf(buffer, "%.*e", DBL_DIG, value); - assert(strlen(buffer) < buffer_size); - (void)!buffer_size; - - // get the exponent (possibly negative) - char* exponent_string = strchr(buffer, 'e'); - assert(exponent_string); - - int exponent = atoi(exponent_string + 1); - - // extract mantissa string: skip sign - char* mantissa = buffer[0] == '-' ? buffer + 1 : buffer; - assert(mantissa[0] != '0' && mantissa[1] == '.'); - - // divide mantissa by 10 to eliminate integer part - mantissa[1] = mantissa[0]; - mantissa++; - exponent++; - - // remove extra mantissa digits and zero-terminate mantissa - truncate_zeros(mantissa, exponent_string); - - // fill results - *out_mantissa = mantissa; - *out_exponent = exponent; - } -#endif - - PUGI__FN xpath_string convert_number_to_string(double value, xpath_allocator* alloc) - { - // try special number conversion - const char_t* special = convert_number_to_string_special(value); - if (special) return xpath_string_const(special); - - // get mantissa + exponent form - char mantissa_buffer[64]; - - char* mantissa; - int exponent; - convert_number_to_mantissa_exponent(value, mantissa_buffer, sizeof(mantissa_buffer), &mantissa, &exponent); - - // make the number! - char_t result[512]; - char_t* s = result; - - // sign - if (value < 0) *s++ = '-'; - - // integer part - if (exponent <= 0) - { - *s++ = '0'; - } - else - { - while (exponent > 0) - { - assert(*mantissa == 0 || static_cast(*mantissa - '0') <= 9); - *s++ = *mantissa ? *mantissa++ : '0'; - exponent--; - } - } - - // fractional part - if (*mantissa) - { - // decimal point - *s++ = '.'; - - // extra zeroes from negative exponent - while (exponent < 0) - { - *s++ = '0'; - exponent++; - } - - // extra mantissa digits - while (*mantissa) - { - assert(static_cast(*mantissa - '0') <= 9); - *s++ = *mantissa++; - } - } - - // zero-terminate - assert(s < result + sizeof(result) / sizeof(result[0])); - *s = 0; - - return xpath_string(result, alloc); - } - - PUGI__FN bool check_string_to_number_format(const char_t* string) - { - // parse leading whitespace - while (PUGI__IS_CHARTYPE(*string, ct_space)) ++string; - - // parse sign - if (*string == '-') ++string; - - if (!*string) return false; - - // if there is no integer part, there should be a decimal part with at least one digit - if (!PUGI__IS_CHARTYPEX(string[0], ctx_digit) && (string[0] != '.' || !PUGI__IS_CHARTYPEX(string[1], ctx_digit))) return false; - - // parse integer part - while (PUGI__IS_CHARTYPEX(*string, ctx_digit)) ++string; - - // parse decimal part - if (*string == '.') - { - ++string; - - while (PUGI__IS_CHARTYPEX(*string, ctx_digit)) ++string; - } - - // parse trailing whitespace - while (PUGI__IS_CHARTYPE(*string, ct_space)) ++string; - - return *string == 0; - } - - PUGI__FN double convert_string_to_number(const char_t* string) - { - // check string format - if (!check_string_to_number_format(string)) return gen_nan(); - - // parse string - #ifdef PUGIXML_WCHAR_MODE - return wcstod(string, 0); - #else - return atof(string); - #endif - } - - PUGI__FN bool convert_string_to_number(const char_t* begin, const char_t* end, double* out_result) - { - char_t buffer[32]; - - size_t length = static_cast(end - begin); - char_t* scratch = buffer; - - if (length >= sizeof(buffer) / sizeof(buffer[0])) - { - // need to make dummy on-heap copy - scratch = static_cast(xml_memory::allocate((length + 1) * sizeof(char_t))); - if (!scratch) return false; - } - - // copy string to zero-terminated buffer and perform conversion - memcpy(scratch, begin, length * sizeof(char_t)); - scratch[length] = 0; - - *out_result = convert_string_to_number(scratch); - - // free dummy buffer - if (scratch != buffer) xml_memory::deallocate(scratch); - - return true; - } - - PUGI__FN double round_nearest(double value) - { - return floor(value + 0.5); - } - - PUGI__FN double round_nearest_nzero(double value) - { - // same as round_nearest, but returns -0 for [-0.5, -0] - // ceil is used to differentiate between +0 and -0 (we return -0 for [-0.5, -0] and +0 for +0) - return (value >= -0.5 && value <= 0) ? ceil(value) : floor(value + 0.5); - } - - PUGI__FN const char_t* qualified_name(const xpath_node& node) - { - return node.attribute() ? node.attribute().name() : node.node().name(); - } - - PUGI__FN const char_t* local_name(const xpath_node& node) - { - const char_t* name = qualified_name(node); - const char_t* p = find_char(name, ':'); - - return p ? p + 1 : name; - } - - struct namespace_uri_predicate - { - const char_t* prefix; - size_t prefix_length; - - namespace_uri_predicate(const char_t* name) - { - const char_t* pos = find_char(name, ':'); - - prefix = pos ? name : 0; - prefix_length = pos ? static_cast(pos - name) : 0; - } - - bool operator()(const xml_attribute& a) const - { - const char_t* name = a.name(); - - if (!starts_with(name, PUGIXML_TEXT("xmlns"))) return false; - - return prefix ? name[5] == ':' && strequalrange(name + 6, prefix, prefix_length) : name[5] == 0; - } - }; - - PUGI__FN const char_t* namespace_uri(const xml_node& node) - { - namespace_uri_predicate pred = node.name(); - - xml_node p = node; - - while (p) - { - xml_attribute a = p.find_attribute(pred); - - if (a) return a.value(); - - p = p.parent(); - } - - return PUGIXML_TEXT(""); - } - - PUGI__FN const char_t* namespace_uri(const xml_attribute& attr, const xml_node& parent) - { - namespace_uri_predicate pred = attr.name(); - - // Default namespace does not apply to attributes - if (!pred.prefix) return PUGIXML_TEXT(""); - - xml_node p = parent; - - while (p) - { - xml_attribute a = p.find_attribute(pred); - - if (a) return a.value(); - - p = p.parent(); - } - - return PUGIXML_TEXT(""); - } - - PUGI__FN const char_t* namespace_uri(const xpath_node& node) - { - return node.attribute() ? namespace_uri(node.attribute(), node.parent()) : namespace_uri(node.node()); - } - - PUGI__FN void normalize_space(char_t* buffer) - { - char_t* write = buffer; - - for (char_t* it = buffer; *it; ) - { - char_t ch = *it++; - - if (PUGI__IS_CHARTYPE(ch, ct_space)) - { - // replace whitespace sequence with single space - while (PUGI__IS_CHARTYPE(*it, ct_space)) it++; - - // avoid leading spaces - if (write != buffer) *write++ = ' '; - } - else *write++ = ch; - } - - // remove trailing space - if (write != buffer && PUGI__IS_CHARTYPE(write[-1], ct_space)) write--; - - // zero-terminate - *write = 0; - } - - PUGI__FN void translate(char_t* buffer, const char_t* from, const char_t* to) - { - size_t to_length = strlength(to); - - char_t* write = buffer; - - while (*buffer) - { - PUGI__DMC_VOLATILE char_t ch = *buffer++; - - const char_t* pos = find_char(from, ch); - - if (!pos) - *write++ = ch; // do not process - else if (static_cast(pos - from) < to_length) - *write++ = to[pos - from]; // replace - } - - // zero-terminate - *write = 0; - } - - struct xpath_variable_boolean: xpath_variable - { - xpath_variable_boolean(): value(false) - { - } - - bool value; - char_t name[1]; - }; - - struct xpath_variable_number: xpath_variable - { - xpath_variable_number(): value(0) - { - } - - double value; - char_t name[1]; - }; - - struct xpath_variable_string: xpath_variable - { - xpath_variable_string(): value(0) - { - } - - ~xpath_variable_string() - { - if (value) xml_memory::deallocate(value); - } - - char_t* value; - char_t name[1]; - }; - - struct xpath_variable_node_set: xpath_variable - { - xpath_node_set value; - char_t name[1]; - }; - - static const xpath_node_set dummy_node_set; - - PUGI__FN unsigned int hash_string(const char_t* str) - { - // Jenkins one-at-a-time hash (http://en.wikipedia.org/wiki/Jenkins_hash_function#one-at-a-time) - unsigned int result = 0; - - while (*str) - { - result += static_cast(*str++); - result += result << 10; - result ^= result >> 6; - } - - result += result << 3; - result ^= result >> 11; - result += result << 15; - - return result; - } - - template PUGI__FN T* new_xpath_variable(const char_t* name) - { - size_t length = strlength(name); - if (length == 0) return 0; // empty variable names are invalid - - // $$ we can't use offsetof(T, name) because T is non-POD, so we just allocate additional length characters - void* memory = xml_memory::allocate(sizeof(T) + length * sizeof(char_t)); - if (!memory) return 0; - - T* result = new (memory) T(); - - memcpy(result->name, name, (length + 1) * sizeof(char_t)); - - return result; - } - - PUGI__FN xpath_variable* new_xpath_variable(xpath_value_type type, const char_t* name) - { - switch (type) - { - case xpath_type_node_set: - return new_xpath_variable(name); - - case xpath_type_number: - return new_xpath_variable(name); - - case xpath_type_string: - return new_xpath_variable(name); - - case xpath_type_boolean: - return new_xpath_variable(name); - - default: - return 0; - } - } - - template PUGI__FN void delete_xpath_variable(T* var) - { - var->~T(); - xml_memory::deallocate(var); - } - - PUGI__FN void delete_xpath_variable(xpath_value_type type, xpath_variable* var) - { - switch (type) - { - case xpath_type_node_set: - delete_xpath_variable(static_cast(var)); - break; - - case xpath_type_number: - delete_xpath_variable(static_cast(var)); - break; - - case xpath_type_string: - delete_xpath_variable(static_cast(var)); - break; - - case xpath_type_boolean: - delete_xpath_variable(static_cast(var)); - break; - - default: - assert(!"Invalid variable type"); - } - } - - PUGI__FN xpath_variable* get_variable(xpath_variable_set* set, const char_t* begin, const char_t* end) - { - char_t buffer[32]; - - size_t length = static_cast(end - begin); - char_t* scratch = buffer; - - if (length >= sizeof(buffer) / sizeof(buffer[0])) - { - // need to make dummy on-heap copy - scratch = static_cast(xml_memory::allocate((length + 1) * sizeof(char_t))); - if (!scratch) return 0; - } - - // copy string to zero-terminated buffer and perform lookup - memcpy(scratch, begin, length * sizeof(char_t)); - scratch[length] = 0; - - xpath_variable* result = set->get(scratch); - - // free dummy buffer - if (scratch != buffer) xml_memory::deallocate(scratch); - - return result; - } -PUGI__NS_END - -// Internal node set class -PUGI__NS_BEGIN - PUGI__FN xpath_node_set::type_t xpath_sort(xpath_node* begin, xpath_node* end, xpath_node_set::type_t type, bool rev) - { - xpath_node_set::type_t order = rev ? xpath_node_set::type_sorted_reverse : xpath_node_set::type_sorted; - - if (type == xpath_node_set::type_unsorted) - { - sort(begin, end, document_order_comparator()); - - type = xpath_node_set::type_sorted; - } - - if (type != order) reverse(begin, end); - - return order; - } - - PUGI__FN xpath_node xpath_first(const xpath_node* begin, const xpath_node* end, xpath_node_set::type_t type) - { - if (begin == end) return xpath_node(); - - switch (type) - { - case xpath_node_set::type_sorted: - return *begin; - - case xpath_node_set::type_sorted_reverse: - return *(end - 1); - - case xpath_node_set::type_unsorted: - return *min_element(begin, end, document_order_comparator()); - - default: - assert(!"Invalid node set type"); - return xpath_node(); - } - } - - class xpath_node_set_raw - { - xpath_node_set::type_t _type; - - xpath_node* _begin; - xpath_node* _end; - xpath_node* _eos; - - public: - xpath_node_set_raw(): _type(xpath_node_set::type_unsorted), _begin(0), _end(0), _eos(0) - { - } - - xpath_node* begin() const - { - return _begin; - } - - xpath_node* end() const - { - return _end; - } - - bool empty() const - { - return _begin == _end; - } - - size_t size() const - { - return static_cast(_end - _begin); - } - - xpath_node first() const - { - return xpath_first(_begin, _end, _type); - } - - void push_back(const xpath_node& node, xpath_allocator* alloc) - { - if (_end == _eos) - { - size_t capacity = static_cast(_eos - _begin); - - // get new capacity (1.5x rule) - size_t new_capacity = capacity + capacity / 2 + 1; - - // reallocate the old array or allocate a new one - xpath_node* data = static_cast(alloc->reallocate(_begin, capacity * sizeof(xpath_node), new_capacity * sizeof(xpath_node))); - assert(data); - - // finalize - _begin = data; - _end = data + capacity; - _eos = data + new_capacity; - } - - *_end++ = node; - } - - void append(const xpath_node* begin_, const xpath_node* end_, xpath_allocator* alloc) - { - size_t size_ = static_cast(_end - _begin); - size_t capacity = static_cast(_eos - _begin); - size_t count = static_cast(end_ - begin_); - - if (size_ + count > capacity) - { - // reallocate the old array or allocate a new one - xpath_node* data = static_cast(alloc->reallocate(_begin, capacity * sizeof(xpath_node), (size_ + count) * sizeof(xpath_node))); - assert(data); - - // finalize - _begin = data; - _end = data + size_; - _eos = data + size_ + count; - } - - memcpy(_end, begin_, count * sizeof(xpath_node)); - _end += count; - } - - void sort_do() - { - _type = xpath_sort(_begin, _end, _type, false); - } - - void truncate(xpath_node* pos) - { - assert(_begin <= pos && pos <= _end); - - _end = pos; - } - - void remove_duplicates() - { - if (_type == xpath_node_set::type_unsorted) - sort(_begin, _end, duplicate_comparator()); - - _end = unique(_begin, _end); - } - - xpath_node_set::type_t type() const - { - return _type; - } - - void set_type(xpath_node_set::type_t value) - { - _type = value; - } - }; -PUGI__NS_END - -PUGI__NS_BEGIN - struct xpath_context - { - xpath_node n; - size_t position, size; - - xpath_context(const xpath_node& n_, size_t position_, size_t size_): n(n_), position(position_), size(size_) - { - } - }; - - enum lexeme_t - { - lex_none = 0, - lex_equal, - lex_not_equal, - lex_less, - lex_greater, - lex_less_or_equal, - lex_greater_or_equal, - lex_plus, - lex_minus, - lex_multiply, - lex_union, - lex_var_ref, - lex_open_brace, - lex_close_brace, - lex_quoted_string, - lex_number, - lex_slash, - lex_double_slash, - lex_open_square_brace, - lex_close_square_brace, - lex_string, - lex_comma, - lex_axis_attribute, - lex_dot, - lex_double_dot, - lex_double_colon, - lex_eof - }; - - struct xpath_lexer_string - { - const char_t* begin; - const char_t* end; - - xpath_lexer_string(): begin(0), end(0) - { - } - - bool operator==(const char_t* other) const - { - size_t length = static_cast(end - begin); - - return strequalrange(other, begin, length); - } - }; - - class xpath_lexer - { - const char_t* _cur; - const char_t* _cur_lexeme_pos; - xpath_lexer_string _cur_lexeme_contents; - - lexeme_t _cur_lexeme; - - public: - explicit xpath_lexer(const char_t* query): _cur(query) - { - next(); - } - - const char_t* state() const - { - return _cur; - } - - void next() - { - const char_t* cur = _cur; - - while (PUGI__IS_CHARTYPE(*cur, ct_space)) ++cur; - - // save lexeme position for error reporting - _cur_lexeme_pos = cur; - - switch (*cur) - { - case 0: - _cur_lexeme = lex_eof; - break; - - case '>': - if (*(cur+1) == '=') - { - cur += 2; - _cur_lexeme = lex_greater_or_equal; - } - else - { - cur += 1; - _cur_lexeme = lex_greater; - } - break; - - case '<': - if (*(cur+1) == '=') - { - cur += 2; - _cur_lexeme = lex_less_or_equal; - } - else - { - cur += 1; - _cur_lexeme = lex_less; - } - break; - - case '!': - if (*(cur+1) == '=') - { - cur += 2; - _cur_lexeme = lex_not_equal; - } - else - { - _cur_lexeme = lex_none; - } - break; - - case '=': - cur += 1; - _cur_lexeme = lex_equal; - - break; - - case '+': - cur += 1; - _cur_lexeme = lex_plus; - - break; - - case '-': - cur += 1; - _cur_lexeme = lex_minus; - - break; - - case '*': - cur += 1; - _cur_lexeme = lex_multiply; - - break; - - case '|': - cur += 1; - _cur_lexeme = lex_union; - - break; - - case '$': - cur += 1; - - if (PUGI__IS_CHARTYPEX(*cur, ctx_start_symbol)) - { - _cur_lexeme_contents.begin = cur; - - while (PUGI__IS_CHARTYPEX(*cur, ctx_symbol)) cur++; - - if (cur[0] == ':' && PUGI__IS_CHARTYPEX(cur[1], ctx_symbol)) // qname - { - cur++; // : - - while (PUGI__IS_CHARTYPEX(*cur, ctx_symbol)) cur++; - } - - _cur_lexeme_contents.end = cur; - - _cur_lexeme = lex_var_ref; - } - else - { - _cur_lexeme = lex_none; - } - - break; - - case '(': - cur += 1; - _cur_lexeme = lex_open_brace; - - break; - - case ')': - cur += 1; - _cur_lexeme = lex_close_brace; - - break; - - case '[': - cur += 1; - _cur_lexeme = lex_open_square_brace; - - break; - - case ']': - cur += 1; - _cur_lexeme = lex_close_square_brace; - - break; - - case ',': - cur += 1; - _cur_lexeme = lex_comma; - - break; - - case '/': - if (*(cur+1) == '/') - { - cur += 2; - _cur_lexeme = lex_double_slash; - } - else - { - cur += 1; - _cur_lexeme = lex_slash; - } - break; - - case '.': - if (*(cur+1) == '.') - { - cur += 2; - _cur_lexeme = lex_double_dot; - } - else if (PUGI__IS_CHARTYPEX(*(cur+1), ctx_digit)) - { - _cur_lexeme_contents.begin = cur; // . - - ++cur; - - while (PUGI__IS_CHARTYPEX(*cur, ctx_digit)) cur++; - - _cur_lexeme_contents.end = cur; - - _cur_lexeme = lex_number; - } - else - { - cur += 1; - _cur_lexeme = lex_dot; - } - break; - - case '@': - cur += 1; - _cur_lexeme = lex_axis_attribute; - - break; - - case '"': - case '\'': - { - char_t terminator = *cur; - - ++cur; - - _cur_lexeme_contents.begin = cur; - while (*cur && *cur != terminator) cur++; - _cur_lexeme_contents.end = cur; - - if (!*cur) - _cur_lexeme = lex_none; - else - { - cur += 1; - _cur_lexeme = lex_quoted_string; - } - - break; - } - - case ':': - if (*(cur+1) == ':') - { - cur += 2; - _cur_lexeme = lex_double_colon; - } - else - { - _cur_lexeme = lex_none; - } - break; - - default: - if (PUGI__IS_CHARTYPEX(*cur, ctx_digit)) - { - _cur_lexeme_contents.begin = cur; - - while (PUGI__IS_CHARTYPEX(*cur, ctx_digit)) cur++; - - if (*cur == '.') - { - cur++; - - while (PUGI__IS_CHARTYPEX(*cur, ctx_digit)) cur++; - } - - _cur_lexeme_contents.end = cur; - - _cur_lexeme = lex_number; - } - else if (PUGI__IS_CHARTYPEX(*cur, ctx_start_symbol)) - { - _cur_lexeme_contents.begin = cur; - - while (PUGI__IS_CHARTYPEX(*cur, ctx_symbol)) cur++; - - if (cur[0] == ':') - { - if (cur[1] == '*') // namespace test ncname:* - { - cur += 2; // :* - } - else if (PUGI__IS_CHARTYPEX(cur[1], ctx_symbol)) // namespace test qname - { - cur++; // : - - while (PUGI__IS_CHARTYPEX(*cur, ctx_symbol)) cur++; - } - } - - _cur_lexeme_contents.end = cur; - - _cur_lexeme = lex_string; - } - else - { - _cur_lexeme = lex_none; - } - } - - _cur = cur; - } - - lexeme_t current() const - { - return _cur_lexeme; - } - - const char_t* current_pos() const - { - return _cur_lexeme_pos; - } - - const xpath_lexer_string& contents() const - { - assert(_cur_lexeme == lex_var_ref || _cur_lexeme == lex_number || _cur_lexeme == lex_string || _cur_lexeme == lex_quoted_string); - - return _cur_lexeme_contents; - } - }; - - enum ast_type_t - { - ast_op_or, // left or right - ast_op_and, // left and right - ast_op_equal, // left = right - ast_op_not_equal, // left != right - ast_op_less, // left < right - ast_op_greater, // left > right - ast_op_less_or_equal, // left <= right - ast_op_greater_or_equal, // left >= right - ast_op_add, // left + right - ast_op_subtract, // left - right - ast_op_multiply, // left * right - ast_op_divide, // left / right - ast_op_mod, // left % right - ast_op_negate, // left - right - ast_op_union, // left | right - ast_predicate, // apply predicate to set; next points to next predicate - ast_filter, // select * from left where right - ast_filter_posinv, // select * from left where right; proximity position invariant - ast_string_constant, // string constant - ast_number_constant, // number constant - ast_variable, // variable - ast_func_last, // last() - ast_func_position, // position() - ast_func_count, // count(left) - ast_func_id, // id(left) - ast_func_local_name_0, // local-name() - ast_func_local_name_1, // local-name(left) - ast_func_namespace_uri_0, // namespace-uri() - ast_func_namespace_uri_1, // namespace-uri(left) - ast_func_name_0, // name() - ast_func_name_1, // name(left) - ast_func_string_0, // string() - ast_func_string_1, // string(left) - ast_func_concat, // concat(left, right, siblings) - ast_func_starts_with, // starts_with(left, right) - ast_func_contains, // contains(left, right) - ast_func_substring_before, // substring-before(left, right) - ast_func_substring_after, // substring-after(left, right) - ast_func_substring_2, // substring(left, right) - ast_func_substring_3, // substring(left, right, third) - ast_func_string_length_0, // string-length() - ast_func_string_length_1, // string-length(left) - ast_func_normalize_space_0, // normalize-space() - ast_func_normalize_space_1, // normalize-space(left) - ast_func_translate, // translate(left, right, third) - ast_func_boolean, // boolean(left) - ast_func_not, // not(left) - ast_func_true, // true() - ast_func_false, // false() - ast_func_lang, // lang(left) - ast_func_number_0, // number() - ast_func_number_1, // number(left) - ast_func_sum, // sum(left) - ast_func_floor, // floor(left) - ast_func_ceiling, // ceiling(left) - ast_func_round, // round(left) - ast_step, // process set left with step - ast_step_root // select root node - }; - - enum axis_t - { - axis_ancestor, - axis_ancestor_or_self, - axis_attribute, - axis_child, - axis_descendant, - axis_descendant_or_self, - axis_following, - axis_following_sibling, - axis_namespace, - axis_parent, - axis_preceding, - axis_preceding_sibling, - axis_self - }; - - enum nodetest_t - { - nodetest_none, - nodetest_name, - nodetest_type_node, - nodetest_type_comment, - nodetest_type_pi, - nodetest_type_text, - nodetest_pi, - nodetest_all, - nodetest_all_in_namespace - }; - - template struct axis_to_type - { - static const axis_t axis; - }; - - template const axis_t axis_to_type::axis = N; - - class xpath_ast_node - { - private: - // node type - char _type; - char _rettype; - - // for ast_step / ast_predicate - char _axis; - char _test; - - // tree node structure - xpath_ast_node* _left; - xpath_ast_node* _right; - xpath_ast_node* _next; - - union - { - // value for ast_string_constant - const char_t* string; - // value for ast_number_constant - double number; - // variable for ast_variable - xpath_variable* variable; - // node test for ast_step (node name/namespace/node type/pi target) - const char_t* nodetest; - } _data; - - xpath_ast_node(const xpath_ast_node&); - xpath_ast_node& operator=(const xpath_ast_node&); - - template static bool compare_eq(xpath_ast_node* lhs, xpath_ast_node* rhs, const xpath_context& c, const xpath_stack& stack, const Comp& comp) - { - xpath_value_type lt = lhs->rettype(), rt = rhs->rettype(); - - if (lt != xpath_type_node_set && rt != xpath_type_node_set) - { - if (lt == xpath_type_boolean || rt == xpath_type_boolean) - return comp(lhs->eval_boolean(c, stack), rhs->eval_boolean(c, stack)); - else if (lt == xpath_type_number || rt == xpath_type_number) - return comp(lhs->eval_number(c, stack), rhs->eval_number(c, stack)); - else if (lt == xpath_type_string || rt == xpath_type_string) - { - xpath_allocator_capture cr(stack.result); - - xpath_string ls = lhs->eval_string(c, stack); - xpath_string rs = rhs->eval_string(c, stack); - - return comp(ls, rs); - } - } - else if (lt == xpath_type_node_set && rt == xpath_type_node_set) - { - xpath_allocator_capture cr(stack.result); - - xpath_node_set_raw ls = lhs->eval_node_set(c, stack); - xpath_node_set_raw rs = rhs->eval_node_set(c, stack); - - for (const xpath_node* li = ls.begin(); li != ls.end(); ++li) - for (const xpath_node* ri = rs.begin(); ri != rs.end(); ++ri) - { - xpath_allocator_capture cri(stack.result); - - if (comp(string_value(*li, stack.result), string_value(*ri, stack.result))) - return true; - } - - return false; - } - else - { - if (lt == xpath_type_node_set) - { - swap(lhs, rhs); - swap(lt, rt); - } - - if (lt == xpath_type_boolean) - return comp(lhs->eval_boolean(c, stack), rhs->eval_boolean(c, stack)); - else if (lt == xpath_type_number) - { - xpath_allocator_capture cr(stack.result); - - double l = lhs->eval_number(c, stack); - xpath_node_set_raw rs = rhs->eval_node_set(c, stack); - - for (const xpath_node* ri = rs.begin(); ri != rs.end(); ++ri) - { - xpath_allocator_capture cri(stack.result); - - if (comp(l, convert_string_to_number(string_value(*ri, stack.result).c_str()))) - return true; - } - - return false; - } - else if (lt == xpath_type_string) - { - xpath_allocator_capture cr(stack.result); - - xpath_string l = lhs->eval_string(c, stack); - xpath_node_set_raw rs = rhs->eval_node_set(c, stack); - - for (const xpath_node* ri = rs.begin(); ri != rs.end(); ++ri) - { - xpath_allocator_capture cri(stack.result); - - if (comp(l, string_value(*ri, stack.result))) - return true; - } - - return false; - } - } - - assert(!"Wrong types"); - return false; - } - - template static bool compare_rel(xpath_ast_node* lhs, xpath_ast_node* rhs, const xpath_context& c, const xpath_stack& stack, const Comp& comp) - { - xpath_value_type lt = lhs->rettype(), rt = rhs->rettype(); - - if (lt != xpath_type_node_set && rt != xpath_type_node_set) - return comp(lhs->eval_number(c, stack), rhs->eval_number(c, stack)); - else if (lt == xpath_type_node_set && rt == xpath_type_node_set) - { - xpath_allocator_capture cr(stack.result); - - xpath_node_set_raw ls = lhs->eval_node_set(c, stack); - xpath_node_set_raw rs = rhs->eval_node_set(c, stack); - - for (const xpath_node* li = ls.begin(); li != ls.end(); ++li) - { - xpath_allocator_capture cri(stack.result); - - double l = convert_string_to_number(string_value(*li, stack.result).c_str()); - - for (const xpath_node* ri = rs.begin(); ri != rs.end(); ++ri) - { - xpath_allocator_capture crii(stack.result); - - if (comp(l, convert_string_to_number(string_value(*ri, stack.result).c_str()))) - return true; - } - } - - return false; - } - else if (lt != xpath_type_node_set && rt == xpath_type_node_set) - { - xpath_allocator_capture cr(stack.result); - - double l = lhs->eval_number(c, stack); - xpath_node_set_raw rs = rhs->eval_node_set(c, stack); - - for (const xpath_node* ri = rs.begin(); ri != rs.end(); ++ri) - { - xpath_allocator_capture cri(stack.result); - - if (comp(l, convert_string_to_number(string_value(*ri, stack.result).c_str()))) - return true; - } - - return false; - } - else if (lt == xpath_type_node_set && rt != xpath_type_node_set) - { - xpath_allocator_capture cr(stack.result); - - xpath_node_set_raw ls = lhs->eval_node_set(c, stack); - double r = rhs->eval_number(c, stack); - - for (const xpath_node* li = ls.begin(); li != ls.end(); ++li) - { - xpath_allocator_capture cri(stack.result); - - if (comp(convert_string_to_number(string_value(*li, stack.result).c_str()), r)) - return true; - } - - return false; - } - else - { - assert(!"Wrong types"); - return false; - } - } - - void apply_predicate(xpath_node_set_raw& ns, size_t first, xpath_ast_node* expr, const xpath_stack& stack) - { - assert(ns.size() >= first); - - size_t i = 1; - size_t size = ns.size() - first; - - xpath_node* last = ns.begin() + first; - - // remove_if... or well, sort of - for (xpath_node* it = last; it != ns.end(); ++it, ++i) - { - xpath_context c(*it, i, size); - - if (expr->rettype() == xpath_type_number) - { - if (expr->eval_number(c, stack) == i) - *last++ = *it; - } - else if (expr->eval_boolean(c, stack)) - *last++ = *it; - } - - ns.truncate(last); - } - - void apply_predicates(xpath_node_set_raw& ns, size_t first, const xpath_stack& stack) - { - if (ns.size() == first) return; - - for (xpath_ast_node* pred = _right; pred; pred = pred->_next) - { - apply_predicate(ns, first, pred->_left, stack); - } - } - - void step_push(xpath_node_set_raw& ns, const xml_attribute& a, const xml_node& parent, xpath_allocator* alloc) - { - if (!a) return; - - const char_t* name = a.name(); - - // There are no attribute nodes corresponding to attributes that declare namespaces - // That is, "xmlns:..." or "xmlns" - if (starts_with(name, PUGIXML_TEXT("xmlns")) && (name[5] == 0 || name[5] == ':')) return; - - switch (_test) - { - case nodetest_name: - if (strequal(name, _data.nodetest)) ns.push_back(xpath_node(a, parent), alloc); - break; - - case nodetest_type_node: - case nodetest_all: - ns.push_back(xpath_node(a, parent), alloc); - break; - - case nodetest_all_in_namespace: - if (starts_with(name, _data.nodetest)) - ns.push_back(xpath_node(a, parent), alloc); - break; - - default: - ; - } - } - - void step_push(xpath_node_set_raw& ns, const xml_node& n, xpath_allocator* alloc) - { - if (!n) return; - - switch (_test) - { - case nodetest_name: - if (n.type() == node_element && strequal(n.name(), _data.nodetest)) ns.push_back(n, alloc); - break; - - case nodetest_type_node: - ns.push_back(n, alloc); - break; - - case nodetest_type_comment: - if (n.type() == node_comment) - ns.push_back(n, alloc); - break; - - case nodetest_type_text: - if (n.type() == node_pcdata || n.type() == node_cdata) - ns.push_back(n, alloc); - break; - - case nodetest_type_pi: - if (n.type() == node_pi) - ns.push_back(n, alloc); - break; - - case nodetest_pi: - if (n.type() == node_pi && strequal(n.name(), _data.nodetest)) - ns.push_back(n, alloc); - break; - - case nodetest_all: - if (n.type() == node_element) - ns.push_back(n, alloc); - break; - - case nodetest_all_in_namespace: - if (n.type() == node_element && starts_with(n.name(), _data.nodetest)) - ns.push_back(n, alloc); - break; - - default: - assert(!"Unknown axis"); - } - } - - template void step_fill(xpath_node_set_raw& ns, const xml_node& n, xpath_allocator* alloc, T) - { - const axis_t axis = T::axis; - - switch (axis) - { - case axis_attribute: - { - for (xml_attribute a = n.first_attribute(); a; a = a.next_attribute()) - step_push(ns, a, n, alloc); - - break; - } - - case axis_child: - { - for (xml_node c = n.first_child(); c; c = c.next_sibling()) - step_push(ns, c, alloc); - - break; - } - - case axis_descendant: - case axis_descendant_or_self: - { - if (axis == axis_descendant_or_self) - step_push(ns, n, alloc); - - xml_node cur = n.first_child(); - - while (cur && cur != n) - { - step_push(ns, cur, alloc); - - if (cur.first_child()) - cur = cur.first_child(); - else if (cur.next_sibling()) - cur = cur.next_sibling(); - else - { - while (!cur.next_sibling() && cur != n) - cur = cur.parent(); - - if (cur != n) cur = cur.next_sibling(); - } - } - - break; - } - - case axis_following_sibling: - { - for (xml_node c = n.next_sibling(); c; c = c.next_sibling()) - step_push(ns, c, alloc); - - break; - } - - case axis_preceding_sibling: - { - for (xml_node c = n.previous_sibling(); c; c = c.previous_sibling()) - step_push(ns, c, alloc); - - break; - } - - case axis_following: - { - xml_node cur = n; - - // exit from this node so that we don't include descendants - while (cur && !cur.next_sibling()) cur = cur.parent(); - cur = cur.next_sibling(); - - for (;;) - { - step_push(ns, cur, alloc); - - if (cur.first_child()) - cur = cur.first_child(); - else if (cur.next_sibling()) - cur = cur.next_sibling(); - else - { - while (cur && !cur.next_sibling()) cur = cur.parent(); - cur = cur.next_sibling(); - - if (!cur) break; - } - } - - break; - } - - case axis_preceding: - { - xml_node cur = n; - - while (cur && !cur.previous_sibling()) cur = cur.parent(); - cur = cur.previous_sibling(); - - for (;;) - { - if (cur.last_child()) - cur = cur.last_child(); - else - { - // leaf node, can't be ancestor - step_push(ns, cur, alloc); - - if (cur.previous_sibling()) - cur = cur.previous_sibling(); - else - { - do - { - cur = cur.parent(); - if (!cur) break; - - if (!node_is_ancestor(cur, n)) step_push(ns, cur, alloc); - } - while (!cur.previous_sibling()); - - cur = cur.previous_sibling(); - - if (!cur) break; - } - } - } - - break; - } - - case axis_ancestor: - case axis_ancestor_or_self: - { - if (axis == axis_ancestor_or_self) - step_push(ns, n, alloc); - - xml_node cur = n.parent(); - - while (cur) - { - step_push(ns, cur, alloc); - - cur = cur.parent(); - } - - break; - } - - case axis_self: - { - step_push(ns, n, alloc); - - break; - } - - case axis_parent: - { - if (n.parent()) step_push(ns, n.parent(), alloc); - - break; - } - - default: - assert(!"Unimplemented axis"); - } - } - - template void step_fill(xpath_node_set_raw& ns, const xml_attribute& a, const xml_node& p, xpath_allocator* alloc, T v) - { - const axis_t axis = T::axis; - - switch (axis) - { - case axis_ancestor: - case axis_ancestor_or_self: - { - if (axis == axis_ancestor_or_self && _test == nodetest_type_node) // reject attributes based on principal node type test - step_push(ns, a, p, alloc); - - xml_node cur = p; - - while (cur) - { - step_push(ns, cur, alloc); - - cur = cur.parent(); - } - - break; - } - - case axis_descendant_or_self: - case axis_self: - { - if (_test == nodetest_type_node) // reject attributes based on principal node type test - step_push(ns, a, p, alloc); - - break; - } - - case axis_following: - { - xml_node cur = p; - - for (;;) - { - if (cur.first_child()) - cur = cur.first_child(); - else if (cur.next_sibling()) - cur = cur.next_sibling(); - else - { - while (cur && !cur.next_sibling()) cur = cur.parent(); - cur = cur.next_sibling(); - - if (!cur) break; - } - - step_push(ns, cur, alloc); - } - - break; - } - - case axis_parent: - { - step_push(ns, p, alloc); - - break; - } - - case axis_preceding: - { - // preceding:: axis does not include attribute nodes and attribute ancestors (they are the same as parent's ancestors), so we can reuse node preceding - step_fill(ns, p, alloc, v); - break; - } - - default: - assert(!"Unimplemented axis"); - } - } - - template xpath_node_set_raw step_do(const xpath_context& c, const xpath_stack& stack, T v) - { - const axis_t axis = T::axis; - bool attributes = (axis == axis_ancestor || axis == axis_ancestor_or_self || axis == axis_descendant_or_self || axis == axis_following || axis == axis_parent || axis == axis_preceding || axis == axis_self); - - xpath_node_set_raw ns; - ns.set_type((axis == axis_ancestor || axis == axis_ancestor_or_self || axis == axis_preceding || axis == axis_preceding_sibling) ? xpath_node_set::type_sorted_reverse : xpath_node_set::type_sorted); - - if (_left) - { - xpath_node_set_raw s = _left->eval_node_set(c, stack); - - // self axis preserves the original order - if (axis == axis_self) ns.set_type(s.type()); - - for (const xpath_node* it = s.begin(); it != s.end(); ++it) - { - size_t size = ns.size(); - - // in general, all axes generate elements in a particular order, but there is no order guarantee if axis is applied to two nodes - if (axis != axis_self && size != 0) ns.set_type(xpath_node_set::type_unsorted); - - if (it->node()) - step_fill(ns, it->node(), stack.result, v); - else if (attributes) - step_fill(ns, it->attribute(), it->parent(), stack.result, v); - - apply_predicates(ns, size, stack); - } - } - else - { - if (c.n.node()) - step_fill(ns, c.n.node(), stack.result, v); - else if (attributes) - step_fill(ns, c.n.attribute(), c.n.parent(), stack.result, v); - - apply_predicates(ns, 0, stack); - } - - // child, attribute and self axes always generate unique set of nodes - // for other axis, if the set stayed sorted, it stayed unique because the traversal algorithms do not visit the same node twice - if (axis != axis_child && axis != axis_attribute && axis != axis_self && ns.type() == xpath_node_set::type_unsorted) - ns.remove_duplicates(); - - return ns; - } - - public: - xpath_ast_node(ast_type_t type, xpath_value_type rettype_, const char_t* value): - _type(static_cast(type)), _rettype(static_cast(rettype_)), _axis(0), _test(0), _left(0), _right(0), _next(0) - { - assert(type == ast_string_constant); - _data.string = value; - } - - xpath_ast_node(ast_type_t type, xpath_value_type rettype_, double value): - _type(static_cast(type)), _rettype(static_cast(rettype_)), _axis(0), _test(0), _left(0), _right(0), _next(0) - { - assert(type == ast_number_constant); - _data.number = value; - } - - xpath_ast_node(ast_type_t type, xpath_value_type rettype_, xpath_variable* value): - _type(static_cast(type)), _rettype(static_cast(rettype_)), _axis(0), _test(0), _left(0), _right(0), _next(0) - { - assert(type == ast_variable); - _data.variable = value; - } - - xpath_ast_node(ast_type_t type, xpath_value_type rettype_, xpath_ast_node* left = 0, xpath_ast_node* right = 0): - _type(static_cast(type)), _rettype(static_cast(rettype_)), _axis(0), _test(0), _left(left), _right(right), _next(0) - { - } - - xpath_ast_node(ast_type_t type, xpath_ast_node* left, axis_t axis, nodetest_t test, const char_t* contents): - _type(static_cast(type)), _rettype(xpath_type_node_set), _axis(static_cast(axis)), _test(static_cast(test)), _left(left), _right(0), _next(0) - { - _data.nodetest = contents; - } - - void set_next(xpath_ast_node* value) - { - _next = value; - } - - void set_right(xpath_ast_node* value) - { - _right = value; - } - - bool eval_boolean(const xpath_context& c, const xpath_stack& stack) - { - switch (_type) - { - case ast_op_or: - return _left->eval_boolean(c, stack) || _right->eval_boolean(c, stack); - - case ast_op_and: - return _left->eval_boolean(c, stack) && _right->eval_boolean(c, stack); - - case ast_op_equal: - return compare_eq(_left, _right, c, stack, equal_to()); - - case ast_op_not_equal: - return compare_eq(_left, _right, c, stack, not_equal_to()); - - case ast_op_less: - return compare_rel(_left, _right, c, stack, less()); - - case ast_op_greater: - return compare_rel(_right, _left, c, stack, less()); - - case ast_op_less_or_equal: - return compare_rel(_left, _right, c, stack, less_equal()); - - case ast_op_greater_or_equal: - return compare_rel(_right, _left, c, stack, less_equal()); - - case ast_func_starts_with: - { - xpath_allocator_capture cr(stack.result); - - xpath_string lr = _left->eval_string(c, stack); - xpath_string rr = _right->eval_string(c, stack); - - return starts_with(lr.c_str(), rr.c_str()); - } - - case ast_func_contains: - { - xpath_allocator_capture cr(stack.result); - - xpath_string lr = _left->eval_string(c, stack); - xpath_string rr = _right->eval_string(c, stack); - - return find_substring(lr.c_str(), rr.c_str()) != 0; - } - - case ast_func_boolean: - return _left->eval_boolean(c, stack); - - case ast_func_not: - return !_left->eval_boolean(c, stack); - - case ast_func_true: - return true; - - case ast_func_false: - return false; - - case ast_func_lang: - { - if (c.n.attribute()) return false; - - xpath_allocator_capture cr(stack.result); - - xpath_string lang = _left->eval_string(c, stack); - - for (xml_node n = c.n.node(); n; n = n.parent()) - { - xml_attribute a = n.attribute(PUGIXML_TEXT("xml:lang")); - - if (a) - { - const char_t* value = a.value(); - - // strnicmp / strncasecmp is not portable - for (const char_t* lit = lang.c_str(); *lit; ++lit) - { - if (tolower_ascii(*lit) != tolower_ascii(*value)) return false; - ++value; - } - - return *value == 0 || *value == '-'; - } - } - - return false; - } - - case ast_variable: - { - assert(_rettype == _data.variable->type()); - - if (_rettype == xpath_type_boolean) - return _data.variable->get_boolean(); - - // fallthrough to type conversion - } - - default: - { - switch (_rettype) - { - case xpath_type_number: - return convert_number_to_boolean(eval_number(c, stack)); - - case xpath_type_string: - { - xpath_allocator_capture cr(stack.result); - - return !eval_string(c, stack).empty(); - } - - case xpath_type_node_set: - { - xpath_allocator_capture cr(stack.result); - - return !eval_node_set(c, stack).empty(); - } - - default: - assert(!"Wrong expression for return type boolean"); - return false; - } - } - } - } - - double eval_number(const xpath_context& c, const xpath_stack& stack) - { - switch (_type) - { - case ast_op_add: - return _left->eval_number(c, stack) + _right->eval_number(c, stack); - - case ast_op_subtract: - return _left->eval_number(c, stack) - _right->eval_number(c, stack); - - case ast_op_multiply: - return _left->eval_number(c, stack) * _right->eval_number(c, stack); - - case ast_op_divide: - return _left->eval_number(c, stack) / _right->eval_number(c, stack); - - case ast_op_mod: - return fmod(_left->eval_number(c, stack), _right->eval_number(c, stack)); - - case ast_op_negate: - return -_left->eval_number(c, stack); - - case ast_number_constant: - return _data.number; - - case ast_func_last: - return static_cast(c.size); - - case ast_func_position: - return static_cast(c.position); - - case ast_func_count: - { - xpath_allocator_capture cr(stack.result); - - return static_cast(_left->eval_node_set(c, stack).size()); - } - - case ast_func_string_length_0: - { - xpath_allocator_capture cr(stack.result); - - return static_cast(string_value(c.n, stack.result).length()); - } - - case ast_func_string_length_1: - { - xpath_allocator_capture cr(stack.result); - - return static_cast(_left->eval_string(c, stack).length()); - } - - case ast_func_number_0: - { - xpath_allocator_capture cr(stack.result); - - return convert_string_to_number(string_value(c.n, stack.result).c_str()); - } - - case ast_func_number_1: - return _left->eval_number(c, stack); - - case ast_func_sum: - { - xpath_allocator_capture cr(stack.result); - - double r = 0; - - xpath_node_set_raw ns = _left->eval_node_set(c, stack); - - for (const xpath_node* it = ns.begin(); it != ns.end(); ++it) - { - xpath_allocator_capture cri(stack.result); - - r += convert_string_to_number(string_value(*it, stack.result).c_str()); - } - - return r; - } - - case ast_func_floor: - { - double r = _left->eval_number(c, stack); - - return r == r ? floor(r) : r; - } - - case ast_func_ceiling: - { - double r = _left->eval_number(c, stack); - - return r == r ? ceil(r) : r; - } - - case ast_func_round: - return round_nearest_nzero(_left->eval_number(c, stack)); - - case ast_variable: - { - assert(_rettype == _data.variable->type()); - - if (_rettype == xpath_type_number) - return _data.variable->get_number(); - - // fallthrough to type conversion - } - - default: - { - switch (_rettype) - { - case xpath_type_boolean: - return eval_boolean(c, stack) ? 1 : 0; - - case xpath_type_string: - { - xpath_allocator_capture cr(stack.result); - - return convert_string_to_number(eval_string(c, stack).c_str()); - } - - case xpath_type_node_set: - { - xpath_allocator_capture cr(stack.result); - - return convert_string_to_number(eval_string(c, stack).c_str()); - } - - default: - assert(!"Wrong expression for return type number"); - return 0; - } - - } - } - } - - xpath_string eval_string_concat(const xpath_context& c, const xpath_stack& stack) - { - assert(_type == ast_func_concat); - - xpath_allocator_capture ct(stack.temp); - - // count the string number - size_t count = 1; - for (xpath_ast_node* nc = _right; nc; nc = nc->_next) count++; - - // gather all strings - xpath_string static_buffer[4]; - xpath_string* buffer = static_buffer; - - // allocate on-heap for large concats - if (count > sizeof(static_buffer) / sizeof(static_buffer[0])) - { - buffer = static_cast(stack.temp->allocate(count * sizeof(xpath_string))); - assert(buffer); - } - - // evaluate all strings to temporary stack - xpath_stack swapped_stack = {stack.temp, stack.result}; - - buffer[0] = _left->eval_string(c, swapped_stack); - - size_t pos = 1; - for (xpath_ast_node* n = _right; n; n = n->_next, ++pos) buffer[pos] = n->eval_string(c, swapped_stack); - assert(pos == count); - - // get total length - size_t length = 0; - for (size_t i = 0; i < count; ++i) length += buffer[i].length(); - - // create final string - char_t* result = static_cast(stack.result->allocate((length + 1) * sizeof(char_t))); - assert(result); - - char_t* ri = result; - - for (size_t j = 0; j < count; ++j) - for (const char_t* bi = buffer[j].c_str(); *bi; ++bi) - *ri++ = *bi; - - *ri = 0; - - return xpath_string(result, true); - } - - xpath_string eval_string(const xpath_context& c, const xpath_stack& stack) - { - switch (_type) - { - case ast_string_constant: - return xpath_string_const(_data.string); - - case ast_func_local_name_0: - { - xpath_node na = c.n; - - return xpath_string_const(local_name(na)); - } - - case ast_func_local_name_1: - { - xpath_allocator_capture cr(stack.result); - - xpath_node_set_raw ns = _left->eval_node_set(c, stack); - xpath_node na = ns.first(); - - return xpath_string_const(local_name(na)); - } - - case ast_func_name_0: - { - xpath_node na = c.n; - - return xpath_string_const(qualified_name(na)); - } - - case ast_func_name_1: - { - xpath_allocator_capture cr(stack.result); - - xpath_node_set_raw ns = _left->eval_node_set(c, stack); - xpath_node na = ns.first(); - - return xpath_string_const(qualified_name(na)); - } - - case ast_func_namespace_uri_0: - { - xpath_node na = c.n; - - return xpath_string_const(namespace_uri(na)); - } - - case ast_func_namespace_uri_1: - { - xpath_allocator_capture cr(stack.result); - - xpath_node_set_raw ns = _left->eval_node_set(c, stack); - xpath_node na = ns.first(); - - return xpath_string_const(namespace_uri(na)); - } - - case ast_func_string_0: - return string_value(c.n, stack.result); - - case ast_func_string_1: - return _left->eval_string(c, stack); - - case ast_func_concat: - return eval_string_concat(c, stack); - - case ast_func_substring_before: - { - xpath_allocator_capture cr(stack.temp); - - xpath_stack swapped_stack = {stack.temp, stack.result}; - - xpath_string s = _left->eval_string(c, swapped_stack); - xpath_string p = _right->eval_string(c, swapped_stack); - - const char_t* pos = find_substring(s.c_str(), p.c_str()); - - return pos ? xpath_string(s.c_str(), pos, stack.result) : xpath_string(); - } - - case ast_func_substring_after: - { - xpath_allocator_capture cr(stack.temp); - - xpath_stack swapped_stack = {stack.temp, stack.result}; - - xpath_string s = _left->eval_string(c, swapped_stack); - xpath_string p = _right->eval_string(c, swapped_stack); - - const char_t* pos = find_substring(s.c_str(), p.c_str()); - if (!pos) return xpath_string(); - - const char_t* result = pos + p.length(); - - return s.uses_heap() ? xpath_string(result, stack.result) : xpath_string_const(result); - } - - case ast_func_substring_2: - { - xpath_allocator_capture cr(stack.temp); - - xpath_stack swapped_stack = {stack.temp, stack.result}; - - xpath_string s = _left->eval_string(c, swapped_stack); - size_t s_length = s.length(); - - double first = round_nearest(_right->eval_number(c, stack)); - - if (is_nan(first)) return xpath_string(); // NaN - else if (first >= s_length + 1) return xpath_string(); - - size_t pos = first < 1 ? 1 : static_cast(first); - assert(1 <= pos && pos <= s_length + 1); - - const char_t* rbegin = s.c_str() + (pos - 1); - - return s.uses_heap() ? xpath_string(rbegin, stack.result) : xpath_string_const(rbegin); - } - - case ast_func_substring_3: - { - xpath_allocator_capture cr(stack.temp); - - xpath_stack swapped_stack = {stack.temp, stack.result}; - - xpath_string s = _left->eval_string(c, swapped_stack); - size_t s_length = s.length(); - - double first = round_nearest(_right->eval_number(c, stack)); - double last = first + round_nearest(_right->_next->eval_number(c, stack)); - - if (is_nan(first) || is_nan(last)) return xpath_string(); - else if (first >= s_length + 1) return xpath_string(); - else if (first >= last) return xpath_string(); - else if (last < 1) return xpath_string(); - - size_t pos = first < 1 ? 1 : static_cast(first); - size_t end = last >= s_length + 1 ? s_length + 1 : static_cast(last); - - assert(1 <= pos && pos <= end && end <= s_length + 1); - const char_t* rbegin = s.c_str() + (pos - 1); - const char_t* rend = s.c_str() + (end - 1); - - return (end == s_length + 1 && !s.uses_heap()) ? xpath_string_const(rbegin) : xpath_string(rbegin, rend, stack.result); - } - - case ast_func_normalize_space_0: - { - xpath_string s = string_value(c.n, stack.result); - - normalize_space(s.data(stack.result)); - - return s; - } - - case ast_func_normalize_space_1: - { - xpath_string s = _left->eval_string(c, stack); - - normalize_space(s.data(stack.result)); - - return s; - } - - case ast_func_translate: - { - xpath_allocator_capture cr(stack.temp); - - xpath_stack swapped_stack = {stack.temp, stack.result}; - - xpath_string s = _left->eval_string(c, stack); - xpath_string from = _right->eval_string(c, swapped_stack); - xpath_string to = _right->_next->eval_string(c, swapped_stack); - - translate(s.data(stack.result), from.c_str(), to.c_str()); - - return s; - } - - case ast_variable: - { - assert(_rettype == _data.variable->type()); - - if (_rettype == xpath_type_string) - return xpath_string_const(_data.variable->get_string()); - - // fallthrough to type conversion - } - - default: - { - switch (_rettype) - { - case xpath_type_boolean: - return xpath_string_const(eval_boolean(c, stack) ? PUGIXML_TEXT("true") : PUGIXML_TEXT("false")); - - case xpath_type_number: - return convert_number_to_string(eval_number(c, stack), stack.result); - - case xpath_type_node_set: - { - xpath_allocator_capture cr(stack.temp); - - xpath_stack swapped_stack = {stack.temp, stack.result}; - - xpath_node_set_raw ns = eval_node_set(c, swapped_stack); - return ns.empty() ? xpath_string() : string_value(ns.first(), stack.result); - } - - default: - assert(!"Wrong expression for return type string"); - return xpath_string(); - } - } - } - } - - xpath_node_set_raw eval_node_set(const xpath_context& c, const xpath_stack& stack) - { - switch (_type) - { - case ast_op_union: - { - xpath_allocator_capture cr(stack.temp); - - xpath_stack swapped_stack = {stack.temp, stack.result}; - - xpath_node_set_raw ls = _left->eval_node_set(c, swapped_stack); - xpath_node_set_raw rs = _right->eval_node_set(c, stack); - - // we can optimize merging two sorted sets, but this is a very rare operation, so don't bother - rs.set_type(xpath_node_set::type_unsorted); - - rs.append(ls.begin(), ls.end(), stack.result); - rs.remove_duplicates(); - - return rs; - } - - case ast_filter: - case ast_filter_posinv: - { - xpath_node_set_raw set = _left->eval_node_set(c, stack); - - // either expression is a number or it contains position() call; sort by document order - if (_type == ast_filter) set.sort_do(); - - apply_predicate(set, 0, _right, stack); - - return set; - } - - case ast_func_id: - return xpath_node_set_raw(); - - case ast_step: - { - switch (_axis) - { - case axis_ancestor: - return step_do(c, stack, axis_to_type()); - - case axis_ancestor_or_self: - return step_do(c, stack, axis_to_type()); - - case axis_attribute: - return step_do(c, stack, axis_to_type()); - - case axis_child: - return step_do(c, stack, axis_to_type()); - - case axis_descendant: - return step_do(c, stack, axis_to_type()); - - case axis_descendant_or_self: - return step_do(c, stack, axis_to_type()); - - case axis_following: - return step_do(c, stack, axis_to_type()); - - case axis_following_sibling: - return step_do(c, stack, axis_to_type()); - - case axis_namespace: - // namespaced axis is not supported - return xpath_node_set_raw(); - - case axis_parent: - return step_do(c, stack, axis_to_type()); - - case axis_preceding: - return step_do(c, stack, axis_to_type()); - - case axis_preceding_sibling: - return step_do(c, stack, axis_to_type()); - - case axis_self: - return step_do(c, stack, axis_to_type()); - - default: - assert(!"Unknown axis"); - return xpath_node_set_raw(); - } - } - - case ast_step_root: - { - assert(!_right); // root step can't have any predicates - - xpath_node_set_raw ns; - - ns.set_type(xpath_node_set::type_sorted); - - if (c.n.node()) ns.push_back(c.n.node().root(), stack.result); - else if (c.n.attribute()) ns.push_back(c.n.parent().root(), stack.result); - - return ns; - } - - case ast_variable: - { - assert(_rettype == _data.variable->type()); - - if (_rettype == xpath_type_node_set) - { - const xpath_node_set& s = _data.variable->get_node_set(); - - xpath_node_set_raw ns; - - ns.set_type(s.type()); - ns.append(s.begin(), s.end(), stack.result); - - return ns; - } - - // fallthrough to type conversion - } - - default: - assert(!"Wrong expression for return type node set"); - return xpath_node_set_raw(); - } - } - - bool is_posinv() - { - switch (_type) - { - case ast_func_position: - return false; - - case ast_string_constant: - case ast_number_constant: - case ast_variable: - return true; - - case ast_step: - case ast_step_root: - return true; - - case ast_predicate: - case ast_filter: - case ast_filter_posinv: - return true; - - default: - if (_left && !_left->is_posinv()) return false; - - for (xpath_ast_node* n = _right; n; n = n->_next) - if (!n->is_posinv()) return false; - - return true; - } - } - - xpath_value_type rettype() const - { - return static_cast(_rettype); - } - }; - - struct xpath_parser - { - xpath_allocator* _alloc; - xpath_lexer _lexer; - - const char_t* _query; - xpath_variable_set* _variables; - - xpath_parse_result* _result; - - #ifdef PUGIXML_NO_EXCEPTIONS - jmp_buf _error_handler; - #endif - - void throw_error(const char* message) - { - _result->error = message; - _result->offset = _lexer.current_pos() - _query; - - #ifdef PUGIXML_NO_EXCEPTIONS - longjmp(_error_handler, 1); - #else - throw xpath_exception(*_result); - #endif - } - - void throw_error_oom() - { - #ifdef PUGIXML_NO_EXCEPTIONS - throw_error("Out of memory"); - #else - throw std::bad_alloc(); - #endif - } - - void* alloc_node() - { - void* result = _alloc->allocate_nothrow(sizeof(xpath_ast_node)); - - if (!result) throw_error_oom(); - - return result; - } - - const char_t* alloc_string(const xpath_lexer_string& value) - { - if (value.begin) - { - size_t length = static_cast(value.end - value.begin); - - char_t* c = static_cast(_alloc->allocate_nothrow((length + 1) * sizeof(char_t))); - if (!c) throw_error_oom(); - - memcpy(c, value.begin, length * sizeof(char_t)); - c[length] = 0; - - return c; - } - else return 0; - } - - xpath_ast_node* parse_function_helper(ast_type_t type0, ast_type_t type1, size_t argc, xpath_ast_node* args[2]) - { - assert(argc <= 1); - - if (argc == 1 && args[0]->rettype() != xpath_type_node_set) throw_error("Function has to be applied to node set"); - - return new (alloc_node()) xpath_ast_node(argc == 0 ? type0 : type1, xpath_type_string, args[0]); - } - - xpath_ast_node* parse_function(const xpath_lexer_string& name, size_t argc, xpath_ast_node* args[2]) - { - switch (name.begin[0]) - { - case 'b': - if (name == PUGIXML_TEXT("boolean") && argc == 1) - return new (alloc_node()) xpath_ast_node(ast_func_boolean, xpath_type_boolean, args[0]); - - break; - - case 'c': - if (name == PUGIXML_TEXT("count") && argc == 1) - { - if (args[0]->rettype() != xpath_type_node_set) throw_error("Function has to be applied to node set"); - return new (alloc_node()) xpath_ast_node(ast_func_count, xpath_type_number, args[0]); - } - else if (name == PUGIXML_TEXT("contains") && argc == 2) - return new (alloc_node()) xpath_ast_node(ast_func_contains, xpath_type_string, args[0], args[1]); - else if (name == PUGIXML_TEXT("concat") && argc >= 2) - return new (alloc_node()) xpath_ast_node(ast_func_concat, xpath_type_string, args[0], args[1]); - else if (name == PUGIXML_TEXT("ceiling") && argc == 1) - return new (alloc_node()) xpath_ast_node(ast_func_ceiling, xpath_type_number, args[0]); - - break; - - case 'f': - if (name == PUGIXML_TEXT("false") && argc == 0) - return new (alloc_node()) xpath_ast_node(ast_func_false, xpath_type_boolean); - else if (name == PUGIXML_TEXT("floor") && argc == 1) - return new (alloc_node()) xpath_ast_node(ast_func_floor, xpath_type_number, args[0]); - - break; - - case 'i': - if (name == PUGIXML_TEXT("id") && argc == 1) - return new (alloc_node()) xpath_ast_node(ast_func_id, xpath_type_node_set, args[0]); - - break; - - case 'l': - if (name == PUGIXML_TEXT("last") && argc == 0) - return new (alloc_node()) xpath_ast_node(ast_func_last, xpath_type_number); - else if (name == PUGIXML_TEXT("lang") && argc == 1) - return new (alloc_node()) xpath_ast_node(ast_func_lang, xpath_type_boolean, args[0]); - else if (name == PUGIXML_TEXT("local-name") && argc <= 1) - return parse_function_helper(ast_func_local_name_0, ast_func_local_name_1, argc, args); - - break; - - case 'n': - if (name == PUGIXML_TEXT("name") && argc <= 1) - return parse_function_helper(ast_func_name_0, ast_func_name_1, argc, args); - else if (name == PUGIXML_TEXT("namespace-uri") && argc <= 1) - return parse_function_helper(ast_func_namespace_uri_0, ast_func_namespace_uri_1, argc, args); - else if (name == PUGIXML_TEXT("normalize-space") && argc <= 1) - return new (alloc_node()) xpath_ast_node(argc == 0 ? ast_func_normalize_space_0 : ast_func_normalize_space_1, xpath_type_string, args[0], args[1]); - else if (name == PUGIXML_TEXT("not") && argc == 1) - return new (alloc_node()) xpath_ast_node(ast_func_not, xpath_type_boolean, args[0]); - else if (name == PUGIXML_TEXT("number") && argc <= 1) - return new (alloc_node()) xpath_ast_node(argc == 0 ? ast_func_number_0 : ast_func_number_1, xpath_type_number, args[0]); - - break; - - case 'p': - if (name == PUGIXML_TEXT("position") && argc == 0) - return new (alloc_node()) xpath_ast_node(ast_func_position, xpath_type_number); - - break; - - case 'r': - if (name == PUGIXML_TEXT("round") && argc == 1) - return new (alloc_node()) xpath_ast_node(ast_func_round, xpath_type_number, args[0]); - - break; - - case 's': - if (name == PUGIXML_TEXT("string") && argc <= 1) - return new (alloc_node()) xpath_ast_node(argc == 0 ? ast_func_string_0 : ast_func_string_1, xpath_type_string, args[0]); - else if (name == PUGIXML_TEXT("string-length") && argc <= 1) - return new (alloc_node()) xpath_ast_node(argc == 0 ? ast_func_string_length_0 : ast_func_string_length_1, xpath_type_string, args[0]); - else if (name == PUGIXML_TEXT("starts-with") && argc == 2) - return new (alloc_node()) xpath_ast_node(ast_func_starts_with, xpath_type_boolean, args[0], args[1]); - else if (name == PUGIXML_TEXT("substring-before") && argc == 2) - return new (alloc_node()) xpath_ast_node(ast_func_substring_before, xpath_type_string, args[0], args[1]); - else if (name == PUGIXML_TEXT("substring-after") && argc == 2) - return new (alloc_node()) xpath_ast_node(ast_func_substring_after, xpath_type_string, args[0], args[1]); - else if (name == PUGIXML_TEXT("substring") && (argc == 2 || argc == 3)) - return new (alloc_node()) xpath_ast_node(argc == 2 ? ast_func_substring_2 : ast_func_substring_3, xpath_type_string, args[0], args[1]); - else if (name == PUGIXML_TEXT("sum") && argc == 1) - { - if (args[0]->rettype() != xpath_type_node_set) throw_error("Function has to be applied to node set"); - return new (alloc_node()) xpath_ast_node(ast_func_sum, xpath_type_number, args[0]); - } - - break; - - case 't': - if (name == PUGIXML_TEXT("translate") && argc == 3) - return new (alloc_node()) xpath_ast_node(ast_func_translate, xpath_type_string, args[0], args[1]); - else if (name == PUGIXML_TEXT("true") && argc == 0) - return new (alloc_node()) xpath_ast_node(ast_func_true, xpath_type_boolean); - - break; - - default: - break; - } - - throw_error("Unrecognized function or wrong parameter count"); - - return 0; - } - - axis_t parse_axis_name(const xpath_lexer_string& name, bool& specified) - { - specified = true; - - switch (name.begin[0]) - { - case 'a': - if (name == PUGIXML_TEXT("ancestor")) - return axis_ancestor; - else if (name == PUGIXML_TEXT("ancestor-or-self")) - return axis_ancestor_or_self; - else if (name == PUGIXML_TEXT("attribute")) - return axis_attribute; - - break; - - case 'c': - if (name == PUGIXML_TEXT("child")) - return axis_child; - - break; - - case 'd': - if (name == PUGIXML_TEXT("descendant")) - return axis_descendant; - else if (name == PUGIXML_TEXT("descendant-or-self")) - return axis_descendant_or_self; - - break; - - case 'f': - if (name == PUGIXML_TEXT("following")) - return axis_following; - else if (name == PUGIXML_TEXT("following-sibling")) - return axis_following_sibling; - - break; - - case 'n': - if (name == PUGIXML_TEXT("namespace")) - return axis_namespace; - - break; - - case 'p': - if (name == PUGIXML_TEXT("parent")) - return axis_parent; - else if (name == PUGIXML_TEXT("preceding")) - return axis_preceding; - else if (name == PUGIXML_TEXT("preceding-sibling")) - return axis_preceding_sibling; - - break; - - case 's': - if (name == PUGIXML_TEXT("self")) - return axis_self; - - break; - - default: - break; - } - - specified = false; - return axis_child; - } - - nodetest_t parse_node_test_type(const xpath_lexer_string& name) - { - switch (name.begin[0]) - { - case 'c': - if (name == PUGIXML_TEXT("comment")) - return nodetest_type_comment; - - break; - - case 'n': - if (name == PUGIXML_TEXT("node")) - return nodetest_type_node; - - break; - - case 'p': - if (name == PUGIXML_TEXT("processing-instruction")) - return nodetest_type_pi; - - break; - - case 't': - if (name == PUGIXML_TEXT("text")) - return nodetest_type_text; - - break; - - default: - break; - } - - return nodetest_none; - } - - // PrimaryExpr ::= VariableReference | '(' Expr ')' | Literal | Number | FunctionCall - xpath_ast_node* parse_primary_expression() - { - switch (_lexer.current()) - { - case lex_var_ref: - { - xpath_lexer_string name = _lexer.contents(); - - if (!_variables) - throw_error("Unknown variable: variable set is not provided"); - - xpath_variable* var = get_variable(_variables, name.begin, name.end); - - if (!var) - throw_error("Unknown variable: variable set does not contain the given name"); - - _lexer.next(); - - return new (alloc_node()) xpath_ast_node(ast_variable, var->type(), var); - } - - case lex_open_brace: - { - _lexer.next(); - - xpath_ast_node* n = parse_expression(); - - if (_lexer.current() != lex_close_brace) - throw_error("Unmatched braces"); - - _lexer.next(); - - return n; - } - - case lex_quoted_string: - { - const char_t* value = alloc_string(_lexer.contents()); - - xpath_ast_node* n = new (alloc_node()) xpath_ast_node(ast_string_constant, xpath_type_string, value); - _lexer.next(); - - return n; - } - - case lex_number: - { - double value = 0; - - if (!convert_string_to_number(_lexer.contents().begin, _lexer.contents().end, &value)) - throw_error_oom(); - - xpath_ast_node* n = new (alloc_node()) xpath_ast_node(ast_number_constant, xpath_type_number, value); - _lexer.next(); - - return n; - } - - case lex_string: - { - xpath_ast_node* args[2] = {0}; - size_t argc = 0; - - xpath_lexer_string function = _lexer.contents(); - _lexer.next(); - - xpath_ast_node* last_arg = 0; - - if (_lexer.current() != lex_open_brace) - throw_error("Unrecognized function call"); - _lexer.next(); - - if (_lexer.current() != lex_close_brace) - args[argc++] = parse_expression(); - - while (_lexer.current() != lex_close_brace) - { - if (_lexer.current() != lex_comma) - throw_error("No comma between function arguments"); - _lexer.next(); - - xpath_ast_node* n = parse_expression(); - - if (argc < 2) args[argc] = n; - else last_arg->set_next(n); - - argc++; - last_arg = n; - } - - _lexer.next(); - - return parse_function(function, argc, args); - } - - default: - throw_error("Unrecognizable primary expression"); - - return 0; - } - } - - // FilterExpr ::= PrimaryExpr | FilterExpr Predicate - // Predicate ::= '[' PredicateExpr ']' - // PredicateExpr ::= Expr - xpath_ast_node* parse_filter_expression() - { - xpath_ast_node* n = parse_primary_expression(); - - while (_lexer.current() == lex_open_square_brace) - { - _lexer.next(); - - xpath_ast_node* expr = parse_expression(); - - if (n->rettype() != xpath_type_node_set) throw_error("Predicate has to be applied to node set"); - - bool posinv = expr->rettype() != xpath_type_number && expr->is_posinv(); - - n = new (alloc_node()) xpath_ast_node(posinv ? ast_filter_posinv : ast_filter, xpath_type_node_set, n, expr); - - if (_lexer.current() != lex_close_square_brace) - throw_error("Unmatched square brace"); - - _lexer.next(); - } - - return n; - } - - // Step ::= AxisSpecifier NodeTest Predicate* | AbbreviatedStep - // AxisSpecifier ::= AxisName '::' | '@'? - // NodeTest ::= NameTest | NodeType '(' ')' | 'processing-instruction' '(' Literal ')' - // NameTest ::= '*' | NCName ':' '*' | QName - // AbbreviatedStep ::= '.' | '..' - xpath_ast_node* parse_step(xpath_ast_node* set) - { - if (set && set->rettype() != xpath_type_node_set) - throw_error("Step has to be applied to node set"); - - bool axis_specified = false; - axis_t axis = axis_child; // implied child axis - - if (_lexer.current() == lex_axis_attribute) - { - axis = axis_attribute; - axis_specified = true; - - _lexer.next(); - } - else if (_lexer.current() == lex_dot) - { - _lexer.next(); - - return new (alloc_node()) xpath_ast_node(ast_step, set, axis_self, nodetest_type_node, 0); - } - else if (_lexer.current() == lex_double_dot) - { - _lexer.next(); - - return new (alloc_node()) xpath_ast_node(ast_step, set, axis_parent, nodetest_type_node, 0); - } - - nodetest_t nt_type = nodetest_none; - xpath_lexer_string nt_name; - - if (_lexer.current() == lex_string) - { - // node name test - nt_name = _lexer.contents(); - _lexer.next(); - - // was it an axis name? - if (_lexer.current() == lex_double_colon) - { - // parse axis name - if (axis_specified) throw_error("Two axis specifiers in one step"); - - axis = parse_axis_name(nt_name, axis_specified); - - if (!axis_specified) throw_error("Unknown axis"); - - // read actual node test - _lexer.next(); - - if (_lexer.current() == lex_multiply) - { - nt_type = nodetest_all; - nt_name = xpath_lexer_string(); - _lexer.next(); - } - else if (_lexer.current() == lex_string) - { - nt_name = _lexer.contents(); - _lexer.next(); - } - else throw_error("Unrecognized node test"); - } - - if (nt_type == nodetest_none) - { - // node type test or processing-instruction - if (_lexer.current() == lex_open_brace) - { - _lexer.next(); - - if (_lexer.current() == lex_close_brace) - { - _lexer.next(); - - nt_type = parse_node_test_type(nt_name); - - if (nt_type == nodetest_none) throw_error("Unrecognized node type"); - - nt_name = xpath_lexer_string(); - } - else if (nt_name == PUGIXML_TEXT("processing-instruction")) - { - if (_lexer.current() != lex_quoted_string) - throw_error("Only literals are allowed as arguments to processing-instruction()"); - - nt_type = nodetest_pi; - nt_name = _lexer.contents(); - _lexer.next(); - - if (_lexer.current() != lex_close_brace) - throw_error("Unmatched brace near processing-instruction()"); - _lexer.next(); - } - else - throw_error("Unmatched brace near node type test"); - - } - // QName or NCName:* - else - { - if (nt_name.end - nt_name.begin > 2 && nt_name.end[-2] == ':' && nt_name.end[-1] == '*') // NCName:* - { - nt_name.end--; // erase * - - nt_type = nodetest_all_in_namespace; - } - else nt_type = nodetest_name; - } - } - } - else if (_lexer.current() == lex_multiply) - { - nt_type = nodetest_all; - _lexer.next(); - } - else throw_error("Unrecognized node test"); - - xpath_ast_node* n = new (alloc_node()) xpath_ast_node(ast_step, set, axis, nt_type, alloc_string(nt_name)); - - xpath_ast_node* last = 0; - - while (_lexer.current() == lex_open_square_brace) - { - _lexer.next(); - - xpath_ast_node* expr = parse_expression(); - - xpath_ast_node* pred = new (alloc_node()) xpath_ast_node(ast_predicate, xpath_type_node_set, expr); - - if (_lexer.current() != lex_close_square_brace) - throw_error("Unmatched square brace"); - _lexer.next(); - - if (last) last->set_next(pred); - else n->set_right(pred); - - last = pred; - } - - return n; - } - - // RelativeLocationPath ::= Step | RelativeLocationPath '/' Step | RelativeLocationPath '//' Step - xpath_ast_node* parse_relative_location_path(xpath_ast_node* set) - { - xpath_ast_node* n = parse_step(set); - - while (_lexer.current() == lex_slash || _lexer.current() == lex_double_slash) - { - lexeme_t l = _lexer.current(); - _lexer.next(); - - if (l == lex_double_slash) - n = new (alloc_node()) xpath_ast_node(ast_step, n, axis_descendant_or_self, nodetest_type_node, 0); - - n = parse_step(n); - } - - return n; - } - - // LocationPath ::= RelativeLocationPath | AbsoluteLocationPath - // AbsoluteLocationPath ::= '/' RelativeLocationPath? | '//' RelativeLocationPath - xpath_ast_node* parse_location_path() - { - if (_lexer.current() == lex_slash) - { - _lexer.next(); - - xpath_ast_node* n = new (alloc_node()) xpath_ast_node(ast_step_root, xpath_type_node_set); - - // relative location path can start from axis_attribute, dot, double_dot, multiply and string lexemes; any other lexeme means standalone root path - lexeme_t l = _lexer.current(); - - if (l == lex_string || l == lex_axis_attribute || l == lex_dot || l == lex_double_dot || l == lex_multiply) - return parse_relative_location_path(n); - else - return n; - } - else if (_lexer.current() == lex_double_slash) - { - _lexer.next(); - - xpath_ast_node* n = new (alloc_node()) xpath_ast_node(ast_step_root, xpath_type_node_set); - n = new (alloc_node()) xpath_ast_node(ast_step, n, axis_descendant_or_self, nodetest_type_node, 0); - - return parse_relative_location_path(n); - } - - // else clause moved outside of if because of bogus warning 'control may reach end of non-void function being inlined' in gcc 4.0.1 - return parse_relative_location_path(0); - } - - // PathExpr ::= LocationPath - // | FilterExpr - // | FilterExpr '/' RelativeLocationPath - // | FilterExpr '//' RelativeLocationPath - xpath_ast_node* parse_path_expression() - { - // Clarification. - // PathExpr begins with either LocationPath or FilterExpr. - // FilterExpr begins with PrimaryExpr - // PrimaryExpr begins with '$' in case of it being a variable reference, - // '(' in case of it being an expression, string literal, number constant or - // function call. - - if (_lexer.current() == lex_var_ref || _lexer.current() == lex_open_brace || - _lexer.current() == lex_quoted_string || _lexer.current() == lex_number || - _lexer.current() == lex_string) - { - if (_lexer.current() == lex_string) - { - // This is either a function call, or not - if not, we shall proceed with location path - const char_t* state = _lexer.state(); - - while (PUGI__IS_CHARTYPE(*state, ct_space)) ++state; - - if (*state != '(') return parse_location_path(); - - // This looks like a function call; however this still can be a node-test. Check it. - if (parse_node_test_type(_lexer.contents()) != nodetest_none) return parse_location_path(); - } - - xpath_ast_node* n = parse_filter_expression(); - - if (_lexer.current() == lex_slash || _lexer.current() == lex_double_slash) - { - lexeme_t l = _lexer.current(); - _lexer.next(); - - if (l == lex_double_slash) - { - if (n->rettype() != xpath_type_node_set) throw_error("Step has to be applied to node set"); - - n = new (alloc_node()) xpath_ast_node(ast_step, n, axis_descendant_or_self, nodetest_type_node, 0); - } - - // select from location path - return parse_relative_location_path(n); - } - - return n; - } - else return parse_location_path(); - } - - // UnionExpr ::= PathExpr | UnionExpr '|' PathExpr - xpath_ast_node* parse_union_expression() - { - xpath_ast_node* n = parse_path_expression(); - - while (_lexer.current() == lex_union) - { - _lexer.next(); - - xpath_ast_node* expr = parse_union_expression(); - - if (n->rettype() != xpath_type_node_set || expr->rettype() != xpath_type_node_set) - throw_error("Union operator has to be applied to node sets"); - - n = new (alloc_node()) xpath_ast_node(ast_op_union, xpath_type_node_set, n, expr); - } - - return n; - } - - // UnaryExpr ::= UnionExpr | '-' UnaryExpr - xpath_ast_node* parse_unary_expression() - { - if (_lexer.current() == lex_minus) - { - _lexer.next(); - - xpath_ast_node* expr = parse_unary_expression(); - - return new (alloc_node()) xpath_ast_node(ast_op_negate, xpath_type_number, expr); - } - else return parse_union_expression(); - } - - // MultiplicativeExpr ::= UnaryExpr - // | MultiplicativeExpr '*' UnaryExpr - // | MultiplicativeExpr 'div' UnaryExpr - // | MultiplicativeExpr 'mod' UnaryExpr - xpath_ast_node* parse_multiplicative_expression() - { - xpath_ast_node* n = parse_unary_expression(); - - while (_lexer.current() == lex_multiply || (_lexer.current() == lex_string && - (_lexer.contents() == PUGIXML_TEXT("mod") || _lexer.contents() == PUGIXML_TEXT("div")))) - { - ast_type_t op = _lexer.current() == lex_multiply ? ast_op_multiply : - _lexer.contents().begin[0] == 'd' ? ast_op_divide : ast_op_mod; - _lexer.next(); - - xpath_ast_node* expr = parse_unary_expression(); - - n = new (alloc_node()) xpath_ast_node(op, xpath_type_number, n, expr); - } - - return n; - } - - // AdditiveExpr ::= MultiplicativeExpr - // | AdditiveExpr '+' MultiplicativeExpr - // | AdditiveExpr '-' MultiplicativeExpr - xpath_ast_node* parse_additive_expression() - { - xpath_ast_node* n = parse_multiplicative_expression(); - - while (_lexer.current() == lex_plus || _lexer.current() == lex_minus) - { - lexeme_t l = _lexer.current(); - - _lexer.next(); - - xpath_ast_node* expr = parse_multiplicative_expression(); - - n = new (alloc_node()) xpath_ast_node(l == lex_plus ? ast_op_add : ast_op_subtract, xpath_type_number, n, expr); - } - - return n; - } - - // RelationalExpr ::= AdditiveExpr - // | RelationalExpr '<' AdditiveExpr - // | RelationalExpr '>' AdditiveExpr - // | RelationalExpr '<=' AdditiveExpr - // | RelationalExpr '>=' AdditiveExpr - xpath_ast_node* parse_relational_expression() - { - xpath_ast_node* n = parse_additive_expression(); - - while (_lexer.current() == lex_less || _lexer.current() == lex_less_or_equal || - _lexer.current() == lex_greater || _lexer.current() == lex_greater_or_equal) - { - lexeme_t l = _lexer.current(); - _lexer.next(); - - xpath_ast_node* expr = parse_additive_expression(); - - n = new (alloc_node()) xpath_ast_node(l == lex_less ? ast_op_less : l == lex_greater ? ast_op_greater : - l == lex_less_or_equal ? ast_op_less_or_equal : ast_op_greater_or_equal, xpath_type_boolean, n, expr); - } - - return n; - } - - // EqualityExpr ::= RelationalExpr - // | EqualityExpr '=' RelationalExpr - // | EqualityExpr '!=' RelationalExpr - xpath_ast_node* parse_equality_expression() - { - xpath_ast_node* n = parse_relational_expression(); - - while (_lexer.current() == lex_equal || _lexer.current() == lex_not_equal) - { - lexeme_t l = _lexer.current(); - - _lexer.next(); - - xpath_ast_node* expr = parse_relational_expression(); - - n = new (alloc_node()) xpath_ast_node(l == lex_equal ? ast_op_equal : ast_op_not_equal, xpath_type_boolean, n, expr); - } - - return n; - } - - // AndExpr ::= EqualityExpr | AndExpr 'and' EqualityExpr - xpath_ast_node* parse_and_expression() - { - xpath_ast_node* n = parse_equality_expression(); - - while (_lexer.current() == lex_string && _lexer.contents() == PUGIXML_TEXT("and")) - { - _lexer.next(); - - xpath_ast_node* expr = parse_equality_expression(); - - n = new (alloc_node()) xpath_ast_node(ast_op_and, xpath_type_boolean, n, expr); - } - - return n; - } - - // OrExpr ::= AndExpr | OrExpr 'or' AndExpr - xpath_ast_node* parse_or_expression() - { - xpath_ast_node* n = parse_and_expression(); - - while (_lexer.current() == lex_string && _lexer.contents() == PUGIXML_TEXT("or")) - { - _lexer.next(); - - xpath_ast_node* expr = parse_and_expression(); - - n = new (alloc_node()) xpath_ast_node(ast_op_or, xpath_type_boolean, n, expr); - } - - return n; - } - - // Expr ::= OrExpr - xpath_ast_node* parse_expression() - { - return parse_or_expression(); - } - - xpath_parser(const char_t* query, xpath_variable_set* variables, xpath_allocator* alloc, xpath_parse_result* result): _alloc(alloc), _lexer(query), _query(query), _variables(variables), _result(result) - { - } - - xpath_ast_node* parse() - { - xpath_ast_node* result = parse_expression(); - - if (_lexer.current() != lex_eof) - { - // there are still unparsed tokens left, error - throw_error("Incorrect query"); - } - - return result; - } - - static xpath_ast_node* parse(const char_t* query, xpath_variable_set* variables, xpath_allocator* alloc, xpath_parse_result* result) - { - xpath_parser parser(query, variables, alloc, result); - - #ifdef PUGIXML_NO_EXCEPTIONS - int error = setjmp(parser._error_handler); - - return (error == 0) ? parser.parse() : 0; - #else - return parser.parse(); - #endif - } - }; - - struct xpath_query_impl - { - static xpath_query_impl* create() - { - void* memory = xml_memory::allocate(sizeof(xpath_query_impl)); - - return new (memory) xpath_query_impl(); - } - - static void destroy(void* ptr) - { - if (!ptr) return; - - // free all allocated pages - static_cast(ptr)->alloc.release(); - - // free allocator memory (with the first page) - xml_memory::deallocate(ptr); - } - - xpath_query_impl(): root(0), alloc(&block) - { - block.next = 0; - } - - xpath_ast_node* root; - xpath_allocator alloc; - xpath_memory_block block; - }; - - PUGI__FN xpath_string evaluate_string_impl(xpath_query_impl* impl, const xpath_node& n, xpath_stack_data& sd) - { - if (!impl) return xpath_string(); - - #ifdef PUGIXML_NO_EXCEPTIONS - if (setjmp(sd.error_handler)) return xpath_string(); - #endif - - xpath_context c(n, 1, 1); - - return impl->root->eval_string(c, sd.stack); - } -PUGI__NS_END - -namespace pugi -{ -#ifndef PUGIXML_NO_EXCEPTIONS - PUGI__FN xpath_exception::xpath_exception(const xpath_parse_result& result_): _result(result_) - { - assert(_result.error); - } - - PUGI__FN const char* xpath_exception::what() const throw() - { - return _result.error; - } - - PUGI__FN const xpath_parse_result& xpath_exception::result() const - { - return _result; - } -#endif - - PUGI__FN xpath_node::xpath_node() - { - } - - PUGI__FN xpath_node::xpath_node(const xml_node& node_): _node(node_) - { - } - - PUGI__FN xpath_node::xpath_node(const xml_attribute& attribute_, const xml_node& parent_): _node(attribute_ ? parent_ : xml_node()), _attribute(attribute_) - { - } - - PUGI__FN xml_node xpath_node::node() const - { - return _attribute ? xml_node() : _node; - } - - PUGI__FN xml_attribute xpath_node::attribute() const - { - return _attribute; - } - - PUGI__FN xml_node xpath_node::parent() const - { - return _attribute ? _node : _node.parent(); - } - - PUGI__FN static void unspecified_bool_xpath_node(xpath_node***) - { - } - - PUGI__FN xpath_node::operator xpath_node::unspecified_bool_type() const - { - return (_node || _attribute) ? unspecified_bool_xpath_node : 0; - } - - PUGI__FN bool xpath_node::operator!() const - { - return !(_node || _attribute); - } - - PUGI__FN bool xpath_node::operator==(const xpath_node& n) const - { - return _node == n._node && _attribute == n._attribute; - } - - PUGI__FN bool xpath_node::operator!=(const xpath_node& n) const - { - return _node != n._node || _attribute != n._attribute; - } - -#ifdef __BORLANDC__ - PUGI__FN bool operator&&(const xpath_node& lhs, bool rhs) - { - return (bool)lhs && rhs; - } - - PUGI__FN bool operator||(const xpath_node& lhs, bool rhs) - { - return (bool)lhs || rhs; - } -#endif - - PUGI__FN void xpath_node_set::_assign(const_iterator begin_, const_iterator end_) - { - assert(begin_ <= end_); - - size_t size_ = static_cast(end_ - begin_); - - if (size_ <= 1) - { - // deallocate old buffer - if (_begin != &_storage) impl::xml_memory::deallocate(_begin); - - // use internal buffer - if (begin_ != end_) _storage = *begin_; - - _begin = &_storage; - _end = &_storage + size_; - } - else - { - // make heap copy - xpath_node* storage = static_cast(impl::xml_memory::allocate(size_ * sizeof(xpath_node))); - - if (!storage) - { - #ifdef PUGIXML_NO_EXCEPTIONS - return; - #else - throw std::bad_alloc(); - #endif - } - - memcpy(storage, begin_, size_ * sizeof(xpath_node)); - - // deallocate old buffer - if (_begin != &_storage) impl::xml_memory::deallocate(_begin); - - // finalize - _begin = storage; - _end = storage + size_; - } - } - - PUGI__FN xpath_node_set::xpath_node_set(): _type(type_unsorted), _begin(&_storage), _end(&_storage) - { - } - - PUGI__FN xpath_node_set::xpath_node_set(const_iterator begin_, const_iterator end_, type_t type_): _type(type_), _begin(&_storage), _end(&_storage) - { - _assign(begin_, end_); - } - - PUGI__FN xpath_node_set::~xpath_node_set() - { - if (_begin != &_storage) impl::xml_memory::deallocate(_begin); - } - - PUGI__FN xpath_node_set::xpath_node_set(const xpath_node_set& ns): _type(ns._type), _begin(&_storage), _end(&_storage) - { - _assign(ns._begin, ns._end); - } - - PUGI__FN xpath_node_set& xpath_node_set::operator=(const xpath_node_set& ns) - { - if (this == &ns) return *this; - - _type = ns._type; - _assign(ns._begin, ns._end); - - return *this; - } - - PUGI__FN xpath_node_set::type_t xpath_node_set::type() const - { - return _type; - } - - PUGI__FN size_t xpath_node_set::size() const - { - return _end - _begin; - } - - PUGI__FN bool xpath_node_set::empty() const - { - return _begin == _end; - } - - PUGI__FN const xpath_node& xpath_node_set::operator[](size_t index) const - { - assert(index < size()); - return _begin[index]; - } - - PUGI__FN xpath_node_set::const_iterator xpath_node_set::begin() const - { - return _begin; - } - - PUGI__FN xpath_node_set::const_iterator xpath_node_set::end() const - { - return _end; - } - - PUGI__FN void xpath_node_set::sort(bool reverse) - { - _type = impl::xpath_sort(_begin, _end, _type, reverse); - } - - PUGI__FN xpath_node xpath_node_set::first() const - { - return impl::xpath_first(_begin, _end, _type); - } - - PUGI__FN xpath_parse_result::xpath_parse_result(): error("Internal error"), offset(0) - { - } - - PUGI__FN xpath_parse_result::operator bool() const - { - return error == 0; - } - - PUGI__FN const char* xpath_parse_result::description() const - { - return error ? error : "No error"; - } - - PUGI__FN xpath_variable::xpath_variable() - { - } - - PUGI__FN const char_t* xpath_variable::name() const - { - switch (_type) - { - case xpath_type_node_set: - return static_cast(this)->name; - - case xpath_type_number: - return static_cast(this)->name; - - case xpath_type_string: - return static_cast(this)->name; - - case xpath_type_boolean: - return static_cast(this)->name; - - default: - assert(!"Invalid variable type"); - return 0; - } - } - - PUGI__FN xpath_value_type xpath_variable::type() const - { - return _type; - } - - PUGI__FN bool xpath_variable::get_boolean() const - { - return (_type == xpath_type_boolean) ? static_cast(this)->value : false; - } - - PUGI__FN double xpath_variable::get_number() const - { - return (_type == xpath_type_number) ? static_cast(this)->value : impl::gen_nan(); - } - - PUGI__FN const char_t* xpath_variable::get_string() const - { - const char_t* value = (_type == xpath_type_string) ? static_cast(this)->value : 0; - return value ? value : PUGIXML_TEXT(""); - } - - PUGI__FN const xpath_node_set& xpath_variable::get_node_set() const - { - return (_type == xpath_type_node_set) ? static_cast(this)->value : impl::dummy_node_set; - } - - PUGI__FN bool xpath_variable::set(bool value) - { - if (_type != xpath_type_boolean) return false; - - static_cast(this)->value = value; - return true; - } - - PUGI__FN bool xpath_variable::set(double value) - { - if (_type != xpath_type_number) return false; - - static_cast(this)->value = value; - return true; - } - - PUGI__FN bool xpath_variable::set(const char_t* value) - { - if (_type != xpath_type_string) return false; - - impl::xpath_variable_string* var = static_cast(this); - - // duplicate string - size_t size = (impl::strlength(value) + 1) * sizeof(char_t); - - char_t* copy = static_cast(impl::xml_memory::allocate(size)); - if (!copy) return false; - - memcpy(copy, value, size); - - // replace old string - if (var->value) impl::xml_memory::deallocate(var->value); - var->value = copy; - - return true; - } - - PUGI__FN bool xpath_variable::set(const xpath_node_set& value) - { - if (_type != xpath_type_node_set) return false; - - static_cast(this)->value = value; - return true; - } - - PUGI__FN xpath_variable_set::xpath_variable_set() - { - for (size_t i = 0; i < sizeof(_data) / sizeof(_data[0]); ++i) _data[i] = 0; - } - - PUGI__FN xpath_variable_set::~xpath_variable_set() - { - for (size_t i = 0; i < sizeof(_data) / sizeof(_data[0]); ++i) - { - xpath_variable* var = _data[i]; - - while (var) - { - xpath_variable* next = var->_next; - - impl::delete_xpath_variable(var->_type, var); - - var = next; - } - } - } - - PUGI__FN xpath_variable* xpath_variable_set::find(const char_t* name) const - { - const size_t hash_size = sizeof(_data) / sizeof(_data[0]); - size_t hash = impl::hash_string(name) % hash_size; - - // look for existing variable - for (xpath_variable* var = _data[hash]; var; var = var->_next) - if (impl::strequal(var->name(), name)) - return var; - - return 0; - } - - PUGI__FN xpath_variable* xpath_variable_set::add(const char_t* name, xpath_value_type type) - { - const size_t hash_size = sizeof(_data) / sizeof(_data[0]); - size_t hash = impl::hash_string(name) % hash_size; - - // look for existing variable - for (xpath_variable* var = _data[hash]; var; var = var->_next) - if (impl::strequal(var->name(), name)) - return var->type() == type ? var : 0; - - // add new variable - xpath_variable* result = impl::new_xpath_variable(type, name); - - if (result) - { - result->_type = type; - result->_next = _data[hash]; - - _data[hash] = result; - } - - return result; - } - - PUGI__FN bool xpath_variable_set::set(const char_t* name, bool value) - { - xpath_variable* var = add(name, xpath_type_boolean); - return var ? var->set(value) : false; - } - - PUGI__FN bool xpath_variable_set::set(const char_t* name, double value) - { - xpath_variable* var = add(name, xpath_type_number); - return var ? var->set(value) : false; - } - - PUGI__FN bool xpath_variable_set::set(const char_t* name, const char_t* value) - { - xpath_variable* var = add(name, xpath_type_string); - return var ? var->set(value) : false; - } - - PUGI__FN bool xpath_variable_set::set(const char_t* name, const xpath_node_set& value) - { - xpath_variable* var = add(name, xpath_type_node_set); - return var ? var->set(value) : false; - } - - PUGI__FN xpath_variable* xpath_variable_set::get(const char_t* name) - { - return find(name); - } - - PUGI__FN const xpath_variable* xpath_variable_set::get(const char_t* name) const - { - return find(name); - } - - PUGI__FN xpath_query::xpath_query(const char_t* query, xpath_variable_set* variables): _impl(0) - { - impl::xpath_query_impl* qimpl = impl::xpath_query_impl::create(); - - if (!qimpl) - { - #ifdef PUGIXML_NO_EXCEPTIONS - _result.error = "Out of memory"; - #else - throw std::bad_alloc(); - #endif - } - else - { - impl::buffer_holder impl_holder(qimpl, impl::xpath_query_impl::destroy); - - qimpl->root = impl::xpath_parser::parse(query, variables, &qimpl->alloc, &_result); - - if (qimpl->root) - { - _impl = static_cast(impl_holder.release()); - _result.error = 0; - } - } - } - - PUGI__FN xpath_query::~xpath_query() - { - impl::xpath_query_impl::destroy(_impl); - } - - PUGI__FN xpath_value_type xpath_query::return_type() const - { - if (!_impl) return xpath_type_none; - - return static_cast(_impl)->root->rettype(); - } - - PUGI__FN bool xpath_query::evaluate_boolean(const xpath_node& n) const - { - if (!_impl) return false; - - impl::xpath_context c(n, 1, 1); - impl::xpath_stack_data sd; - - #ifdef PUGIXML_NO_EXCEPTIONS - if (setjmp(sd.error_handler)) return false; - #endif - - return static_cast(_impl)->root->eval_boolean(c, sd.stack); - } - - PUGI__FN double xpath_query::evaluate_number(const xpath_node& n) const - { - if (!_impl) return impl::gen_nan(); - - impl::xpath_context c(n, 1, 1); - impl::xpath_stack_data sd; - - #ifdef PUGIXML_NO_EXCEPTIONS - if (setjmp(sd.error_handler)) return impl::gen_nan(); - #endif - - return static_cast(_impl)->root->eval_number(c, sd.stack); - } - -#ifndef PUGIXML_NO_STL - PUGI__FN string_t xpath_query::evaluate_string(const xpath_node& n) const - { - impl::xpath_stack_data sd; - - return impl::evaluate_string_impl(static_cast(_impl), n, sd).c_str(); - } -#endif - - PUGI__FN size_t xpath_query::evaluate_string(char_t* buffer, size_t capacity, const xpath_node& n) const - { - impl::xpath_stack_data sd; - - impl::xpath_string r = impl::evaluate_string_impl(static_cast(_impl), n, sd); - - size_t full_size = r.length() + 1; - - if (capacity > 0) - { - size_t size = (full_size < capacity) ? full_size : capacity; - assert(size > 0); - - memcpy(buffer, r.c_str(), (size - 1) * sizeof(char_t)); - buffer[size - 1] = 0; - } - - return full_size; - } - - PUGI__FN xpath_node_set xpath_query::evaluate_node_set(const xpath_node& n) const - { - if (!_impl) return xpath_node_set(); - - impl::xpath_ast_node* root = static_cast(_impl)->root; - - if (root->rettype() != xpath_type_node_set) - { - #ifdef PUGIXML_NO_EXCEPTIONS - return xpath_node_set(); - #else - xpath_parse_result res; - res.error = "Expression does not evaluate to node set"; - - throw xpath_exception(res); - #endif - } - - impl::xpath_context c(n, 1, 1); - impl::xpath_stack_data sd; - - #ifdef PUGIXML_NO_EXCEPTIONS - if (setjmp(sd.error_handler)) return xpath_node_set(); - #endif - - impl::xpath_node_set_raw r = root->eval_node_set(c, sd.stack); - - return xpath_node_set(r.begin(), r.end(), r.type()); - } - - PUGI__FN const xpath_parse_result& xpath_query::result() const - { - return _result; - } - - PUGI__FN static void unspecified_bool_xpath_query(xpath_query***) - { - } - - PUGI__FN xpath_query::operator xpath_query::unspecified_bool_type() const - { - return _impl ? unspecified_bool_xpath_query : 0; - } - - PUGI__FN bool xpath_query::operator!() const - { - return !_impl; - } - - PUGI__FN xpath_node xml_node::select_single_node(const char_t* query, xpath_variable_set* variables) const - { - xpath_query q(query, variables); - return select_single_node(q); - } - - PUGI__FN xpath_node xml_node::select_single_node(const xpath_query& query) const - { - xpath_node_set s = query.evaluate_node_set(*this); - return s.empty() ? xpath_node() : s.first(); - } - - PUGI__FN xpath_node_set xml_node::select_nodes(const char_t* query, xpath_variable_set* variables) const - { - xpath_query q(query, variables); - return select_nodes(q); - } - - PUGI__FN xpath_node_set xml_node::select_nodes(const xpath_query& query) const - { - return query.evaluate_node_set(*this); - } -} - -#endif - -#ifdef __BORLANDC__ -# pragma option pop -#endif - -// Intel C++ does not properly keep warning state for function templates, -// so popping warning state at the end of translation unit leads to warnings in the middle. -#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) -# pragma warning(pop) -#endif - -// Undefine all local macros (makes sure we're not leaking macros in header-only mode) -#undef PUGI__NO_INLINE -#undef PUGI__STATIC_ASSERT -#undef PUGI__DMC_VOLATILE -#undef PUGI__MSVC_CRT_VERSION -#undef PUGI__NS_BEGIN -#undef PUGI__NS_END -#undef PUGI__FN -#undef PUGI__FN_NO_INLINE -#undef PUGI__IS_CHARTYPE_IMPL -#undef PUGI__IS_CHARTYPE -#undef PUGI__IS_CHARTYPEX -#undef PUGI__SKIPWS -#undef PUGI__OPTSET -#undef PUGI__PUSHNODE -#undef PUGI__POPNODE -#undef PUGI__SCANFOR -#undef PUGI__SCANWHILE -#undef PUGI__ENDSEG -#undef PUGI__THROW_ERROR -#undef PUGI__CHECK_ERROR - -#endif - -/** - * Copyright (c) 2006-2012 Arseny Kapoulkine - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ From 0a7605cae11fc5278c4cde0850154c625a45103b Mon Sep 17 00:00:00 2001 From: Jools Wills Date: Tue, 4 Apr 2017 03:06:07 +0100 Subject: [PATCH 67/74] we map to pageup/pagedown not leftbottom/rightbottom - fixes page up / down buttons in date input etc --- es-core/src/InputManager.cpp | 4 ++-- es-core/src/components/ComponentList.cpp | 4 ++-- es-core/src/components/DateTimeComponent.cpp | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/es-core/src/InputManager.cpp b/es-core/src/InputManager.cpp index f03fbc14ec..e109dd99ac 100644 --- a/es-core/src/InputManager.cpp +++ b/es-core/src/InputManager.cpp @@ -287,8 +287,8 @@ void InputManager::loadDefaultKBConfig() cfg->mapInput("start", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_F1, 1, true)); cfg->mapInput("select", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_F2, 1, true)); - cfg->mapInput("leftbottom", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_RIGHTBRACKET, 1, true)); - cfg->mapInput("rightbottom", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_LEFTBRACKET, 1, true)); + cfg->mapInput("pageup", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_RIGHTBRACKET, 1, true)); + cfg->mapInput("pagedown", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_LEFTBRACKET, 1, true)); } void InputManager::writeDeviceConfig(InputConfig* config) diff --git a/es-core/src/components/ComponentList.cpp b/es-core/src/components/ComponentList.cpp index 77b9ae83bc..a16bcb0975 100644 --- a/es-core/src/components/ComponentList.cpp +++ b/es-core/src/components/ComponentList.cpp @@ -81,10 +81,10 @@ bool ComponentList::input(InputConfig* config, Input input) }else if(config->isMappedTo("down", input)) { return listInput(input.value != 0 ? 1 : 0); - }else if(config->isMappedTo("leftbottom", input)) + }else if(config->isMappedTo("pageup", input)) { return listInput(input.value != 0 ? -7 : 0); - }else if(config->isMappedTo("rightbottom", input)){ + }else if(config->isMappedTo("pagedown", input)){ return listInput(input.value != 0 ? 7 : 0); } diff --git a/es-core/src/components/DateTimeComponent.cpp b/es-core/src/components/DateTimeComponent.cpp index a360be44f3..7113ec4950 100644 --- a/es-core/src/components/DateTimeComponent.cpp +++ b/es-core/src/components/DateTimeComponent.cpp @@ -54,9 +54,9 @@ bool DateTimeComponent::input(InputConfig* config, Input input) } int incDir = 0; - if(config->isMappedTo("up", input) || config->isMappedTo("leftbottom", input)) + if(config->isMappedTo("up", input) || config->isMappedTo("pageup", input)) incDir = 1; - else if(config->isMappedTo("down", input) || config->isMappedTo("rightbottom", input)) + else if(config->isMappedTo("down", input) || config->isMappedTo("pagedown", input)) incDir = -1; if(incDir != 0) From fbf349d61adfe5acbb760b981438f56840294da3 Mon Sep 17 00:00:00 2001 From: jrassa Date: Mon, 3 Apr 2017 22:24:52 -0400 Subject: [PATCH 68/74] fix image ratio for first image in video game list view --- es-app/src/views/gamelist/VideoGameListView.cpp | 7 ++++++- es-app/src/views/gamelist/VideoGameListView.h | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/es-app/src/views/gamelist/VideoGameListView.cpp b/es-app/src/views/gamelist/VideoGameListView.cpp index 2a270be028..a12e3fddf2 100644 --- a/es-app/src/views/gamelist/VideoGameListView.cpp +++ b/es-app/src/views/gamelist/VideoGameListView.cpp @@ -94,7 +94,6 @@ VideoGameListView::VideoGameListView(Window* window, FileData* root) : initMDLabels(); initMDValues(); - updateInfoPanel(); } VideoGameListView::~VideoGameListView() @@ -343,3 +342,9 @@ void VideoGameListView::update(int deltaTime) BasicGameListView::update(deltaTime); mVideo.update(deltaTime); } + +void VideoGameListView::onShow() +{ + GuiComponent::onShow(); + updateInfoPanel(); +} diff --git a/es-app/src/views/gamelist/VideoGameListView.h b/es-app/src/views/gamelist/VideoGameListView.h index b0673d396d..0857f6ce25 100644 --- a/es-app/src/views/gamelist/VideoGameListView.h +++ b/es-app/src/views/gamelist/VideoGameListView.h @@ -12,6 +12,8 @@ class VideoGameListView : public BasicGameListView VideoGameListView(Window* window, FileData* root); virtual ~VideoGameListView(); + virtual void onShow() override; + virtual void onThemeChanged(const std::shared_ptr& theme) override; virtual const char* getName() const override { return "video"; } From e740e58004ec054e21f493fbb83e6f26433aa3d3 Mon Sep 17 00:00:00 2001 From: Jools Wills Date: Tue, 4 Apr 2017 04:30:17 +0100 Subject: [PATCH 69/74] bump version to 2.1.6 --- es-app/src/EmulationStation.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/es-app/src/EmulationStation.h b/es-app/src/EmulationStation.h index 0c6b1dddc4..b543edca00 100644 --- a/es-app/src/EmulationStation.h +++ b/es-app/src/EmulationStation.h @@ -4,10 +4,10 @@ // Do this version number update as the very last commit for the new release version. #define PROGRAM_VERSION_MAJOR 2 #define PROGRAM_VERSION_MINOR 1 -#define PROGRAM_VERSION_MAINTENANCE 5 -#define PROGRAM_VERSION_STRING "2.1.5rp" +#define PROGRAM_VERSION_MAINTENANCE 6 +#define PROGRAM_VERSION_STRING "2.1.6rp" #define PROGRAM_BUILT_STRING __DATE__ " - " __TIME__ -#define RESOURCE_VERSION_STRING "2,1,5\0" +#define RESOURCE_VERSION_STRING "2,1,6\0" #define RESOURCE_VERSION PROGRAM_VERSION_MAJOR,PROGRAM_VERSION_MINOR,PROGRAM_VERSION_MAINTENANCE From 4cc0ced851fc8bcbebeeba14d349e400a6722890 Mon Sep 17 00:00:00 2001 From: Jools Wills Date: Tue, 4 Apr 2017 04:54:04 +0100 Subject: [PATCH 70/74] use -O2 --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5961fff7bc..2f8e4e2d65 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -90,8 +90,8 @@ if (CMAKE_BUILD_TYPE MATCHES Debug) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wno-attributes -O0") #support C++11 for std::, optimize set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -O0") else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wno-attributes -O3") #support C++11 for std::, optimize - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -O3") #-s = strip binary + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wno-attributes -O2") #support C++11 for std::, optimize + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -O2") #-s = strip binary endif() endif() From 323feb11e50807160a622a6a102ffb33ff610bc5 Mon Sep 17 00:00:00 2001 From: Kaptain Date: Mon, 16 Feb 2015 14:30:33 -0600 Subject: [PATCH 71/74] Add Favorites List Add Favorites List functionality --- GAMELISTS.md | 2 + THEMES.md | 6 + es-app/src/FileData.cpp | 16 +++ es-app/src/FileData.h | 1 + es-app/src/MetaData.cpp | 3 +- es-app/src/SystemData.cpp | 6 + es-app/src/SystemData.h | 4 + es-app/src/guis/GuiFastSelect.h | 3 +- es-app/src/guis/GuiGamelistOptions.cpp | 28 +++++ es-app/src/guis/GuiGamelistOptions.h | 10 ++ es-app/src/views/SystemView.cpp | 23 ++-- es-app/src/views/ViewController.cpp | 85 +++++++++++++- es-app/src/views/ViewController.h | 7 ++ .../src/views/gamelist/BasicGameListView.cpp | 34 +++++- es-app/src/views/gamelist/BasicGameListView.h | 4 +- .../views/gamelist/DetailedGameListView.cpp | 106 +++++++++++++++--- .../src/views/gamelist/DetailedGameListView.h | 14 ++- .../src/views/gamelist/GridGameListView.cpp | 13 ++- es-app/src/views/gamelist/IGameListView.h | 5 + .../views/gamelist/ISimpleGameListView.cpp | 42 ++++++- .../src/views/gamelist/ISimpleGameListView.h | 8 +- es-core/src/GuiComponent.cpp | 2 +- es-core/src/GuiComponent.h | 2 + es-core/src/Settings.cpp | 1 + es-core/src/ThemeData.cpp | 5 + es-core/src/ThemeData.h | 2 + es-core/src/guis/GuiInputConfig.cpp | 8 -- 27 files changed, 387 insertions(+), 53 deletions(-) diff --git a/GAMELISTS.md b/GAMELISTS.md index 5c0ae17366..4b72360e68 100644 --- a/GAMELISTS.md +++ b/GAMELISTS.md @@ -52,6 +52,7 @@ Some metadata is also marked as "statistic" - these are kept track of by ES and * `players` - integer, the number of players the game supports. * `playcount` - statistic, integer, the number of times this game has been played * `lastplayed` - statistic, datetime, the last date and time this game was played. +* `favorite` - string, yes / no is this a favorite. #### `` @@ -85,3 +86,4 @@ Things to be Aware Of * If at least one game in a system has an image specified, ES will use the detailed view for that system (which displays metadata alongside the game list). * If you want to write your own scraper, the built-in scraping system is actually pretty extendable if you can get past the ugly function declarations and your instinctual fear of C++. Check out `src/scrapers/GamesDBScraper.cpp` for an example (it's less than a hundred lines of actual code). An offline scraper is also possible (though you'll have to subclass `ScraperRequest`). I hope to write a more complete guide on how to do this in the future. + diff --git a/THEMES.md b/THEMES.md index a361cfca67..5d0446b5cf 100644 --- a/THEMES.md +++ b/THEMES.md @@ -259,6 +259,9 @@ Which is equivalent to: 48474D + + 48474D + ``` @@ -307,6 +310,7 @@ Reference * `text name="md_lbl_players"` - ALL * `text name="md_lbl_lastplayed"` - ALL * `text name="md_lbl_playcount"` - ALL + * `text name="md_lbl_favorite"` - ALL * Values * All values will follow to the right of their labels if a position isn't specified. @@ -329,6 +333,8 @@ Reference - The "lastplayed" metadata. Displayed as a string representing the time relative to "now" (e.g. "3 hours ago"). * `text name="md_playcount"` - ALL - The "playcount" metadata (number of times the game has been played). + * `text name="md_favorite"` - ALL + - The "favorite" metadata (is this game a favorite). * `text name="md_description"` - POSITION | SIZE | FONT_PATH | FONT_SIZE | COLOR - Text is the "desc" metadata. If no `pos`/`size` is specified, will move and resize to fit under the lowest label and reach to the bottom of the screen. diff --git a/es-app/src/FileData.cpp b/es-app/src/FileData.cpp index c8409d4d59..edd00b2aaf 100644 --- a/es-app/src/FileData.cpp +++ b/es-app/src/FileData.cpp @@ -127,6 +127,22 @@ std::vector FileData::getFilesRecursive(unsigned int typeMask) const return out; } +std::vector FileData::getFavoritesRecursive(unsigned int typeMask) const +{ + std::vector out; + std::vector files = getFilesRecursive(typeMask); + + for (auto it = files.begin(); it != files.end(); it++) + { + if ((*it)->metadata.get("favorite").compare("yes") == 0) + { + out.push_back(*it); + } + } + + return out; +} + void FileData::addChild(FileData* file) { assert(mType == FOLDER); diff --git a/es-app/src/FileData.h b/es-app/src/FileData.h index bd59ac0710..85be6aa0ca 100644 --- a/es-app/src/FileData.h +++ b/es-app/src/FileData.h @@ -49,6 +49,7 @@ class FileData virtual const std::string& getMarqueePath() const; std::vector getFilesRecursive(unsigned int typeMask) const; + std::vector getFavoritesRecursive(unsigned int typeMask) const; void addChild(FileData* file); // Error if mType != FOLDER void removeChild(FileData* file); //Error if mType != FOLDER diff --git a/es-app/src/MetaData.cpp b/es-app/src/MetaData.cpp index 1f99228235..be6017316b 100644 --- a/es-app/src/MetaData.cpp +++ b/es-app/src/MetaData.cpp @@ -20,7 +20,8 @@ MetaDataDecl gameDecls[] = { {"genre", MD_STRING, "unknown", false, "genre", "enter game genre"}, {"players", MD_INT, "1", false, "players", "enter number of players"}, {"playcount", MD_INT, "0", true, "play count", "enter number of times played"}, - {"lastplayed", MD_TIME, "0", true, "last played", "enter last played date"} + {"lastplayed", MD_TIME, "0", true, "last played", "enter last played date"}, + {"favorite", MD_STRING, "no", false, "favorite", "enter favorite"} }; const std::vector gameMDD(gameDecls, gameDecls + sizeof(gameDecls) / sizeof(gameDecls[0])); diff --git a/es-app/src/SystemData.cpp b/es-app/src/SystemData.cpp index cb46f1c47c..79f32394b7 100644 --- a/es-app/src/SystemData.cpp +++ b/es-app/src/SystemData.cpp @@ -429,6 +429,11 @@ unsigned int SystemData::getGameCount() const return mRootFolder->getFilesRecursive(GAME).size(); } +unsigned int SystemData::getFavoritesCount() const +{ + return mRootFolder->getFavoritesRecursive(GAME).size(); +} + void SystemData::loadTheme() { mTheme = std::make_shared(); @@ -441,6 +446,7 @@ void SystemData::loadTheme() try { mTheme->loadFile(path); + mHasFavorites = mTheme->getHasFavoritesInTheme(); } catch(ThemeException& e) { LOG(LogError) << e.what(); diff --git a/es-app/src/SystemData.h b/es-app/src/SystemData.h index 2a0ac81886..a9759cd5d8 100644 --- a/es-app/src/SystemData.h +++ b/es-app/src/SystemData.h @@ -21,6 +21,7 @@ class SystemData inline const std::string& getStartPath() const { return mStartPath; } inline const std::vector& getExtensions() const { return mSearchExtensions; } inline const std::string& getThemeFolder() const { return mThemeFolder; } + inline bool getHasFavorites() const { return mHasFavorites; } inline const std::vector& getPlatformIds() const { return mPlatformIds; } inline bool hasPlatformId(PlatformIds::PlatformId id) { return std::find(mPlatformIds.begin(), mPlatformIds.end(), id) != mPlatformIds.end(); } @@ -32,6 +33,7 @@ class SystemData std::string getThemePath() const; unsigned int getGameCount() const; + unsigned int getFavoritesCount() const; void launchGame(Window* window, FileData* game); @@ -74,6 +76,8 @@ class SystemData std::string mThemeFolder; std::shared_ptr mTheme; + bool mHasFavorites; + void populateFolder(FileData* folder); FileData* mRootFolder; diff --git a/es-app/src/guis/GuiFastSelect.h b/es-app/src/guis/GuiFastSelect.h index 012c06de62..42eb9b69f2 100644 --- a/es-app/src/guis/GuiFastSelect.h +++ b/es-app/src/guis/GuiFastSelect.h @@ -13,9 +13,8 @@ class GuiFastSelect : public GuiComponent bool input(InputConfig* config, Input input); void update(int deltaTime); - + virtual void setScrollDir(int dir); private: - void setScrollDir(int dir); void scroll(); void updateGameListCursor(); void updateGameListSort(); diff --git a/es-app/src/guis/GuiGamelistOptions.cpp b/es-app/src/guis/GuiGamelistOptions.cpp index cb8f45d68b..38792d1f06 100644 --- a/es-app/src/guis/GuiGamelistOptions.cpp +++ b/es-app/src/guis/GuiGamelistOptions.cpp @@ -1,7 +1,10 @@ #include "GuiGamelistOptions.h" #include "GuiMetaDataEd.h" +#include "Settings.h" #include "views/gamelist/IGameListView.h" #include "views/ViewController.h" +#include "components/SwitchComponent.h" +#include "guis/GuiSettings.h" GuiGamelistOptions::GuiGamelistOptions(Window* window, SystemData* system) : GuiComponent(window), mSystem(system), @@ -45,6 +48,11 @@ GuiGamelistOptions::GuiGamelistOptions(Window* window, SystemData* system) : Gui mMenu.addWithLabel("SORT GAMES BY", mListSort); + auto favorite_only = std::make_shared(mWindow); + favorite_only->setState(Settings::getInstance()->getBool("FavoritesOnly")); + mMenu.addWithLabel("FAVORITES ONLY", favorite_only); + addSaveFunc([favorite_only] { Settings::getInstance()->setBool("FavoritesOnly", favorite_only->getState()); }); + // edit game metadata row.elements.clear(); row.addElement(std::make_shared(mWindow, "EDIT THIS GAME'S METADATA", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true); @@ -55,6 +63,8 @@ GuiGamelistOptions::GuiGamelistOptions(Window* window, SystemData* system) : Gui // center the menu setSize((float)Renderer::getScreenWidth(), (float)Renderer::getScreenHeight()); mMenu.setPosition((mSize.x() - mMenu.getSize().x()) / 2, (mSize.y() - mMenu.getSize().y()) / 2); + + mFavoriteState = Settings::getInstance()->getBool("FavoritesOnly"); } GuiGamelistOptions::~GuiGamelistOptions() @@ -65,6 +75,12 @@ GuiGamelistOptions::~GuiGamelistOptions() // notify that the root folder was sorted getGamelist()->onFileChanged(root, FILE_SORTED); + + if (Settings::getInstance()->getBool("FavoritesOnly") != mFavoriteState) + { + ViewController::get()->setAllInvalidGamesList(getGamelist()->getCursor()->getSystem()); + ViewController::get()->reloadGameListView(getGamelist()->getCursor()->getSystem()); + } } void GuiGamelistOptions::openMetaDataEd() @@ -119,6 +135,7 @@ bool GuiGamelistOptions::input(InputConfig* config, Input input) { if((config->isMappedTo("b", input) || config->isMappedTo("select", input)) && input.value) { + save(); delete this; return true; } @@ -137,3 +154,14 @@ IGameListView* GuiGamelistOptions::getGamelist() { return ViewController::get()->getGameListView(mSystem).get(); } + +void GuiGamelistOptions::save() +{ + if (!mSaveFuncs.size()) + return; + + for (auto it = mSaveFuncs.begin(); it != mSaveFuncs.end(); it++) + (*it)(); + + Settings::getInstance()->saveFile(); +} diff --git a/es-app/src/guis/GuiGamelistOptions.h b/es-app/src/guis/GuiGamelistOptions.h index 2ce685c9e7..46dd386585 100644 --- a/es-app/src/guis/GuiGamelistOptions.h +++ b/es-app/src/guis/GuiGamelistOptions.h @@ -1,6 +1,7 @@ #include "GuiComponent.h" #include "components/MenuComponent.h" #include "components/OptionListComponent.h" +#include "components/SwitchComponent.h" #include "FileSorts.h" class IGameListView; @@ -11,6 +12,9 @@ class GuiGamelistOptions : public GuiComponent GuiGamelistOptions(Window* window, SystemData* system); virtual ~GuiGamelistOptions(); + void save(); + inline void addSaveFunc(const std::function& func) { mSaveFuncs.push_back(func); }; + virtual bool input(InputConfig* config, Input input) override; virtual std::vector getHelpPrompts() override; @@ -20,11 +24,17 @@ class GuiGamelistOptions : public GuiComponent MenuComponent mMenu; + std::vector< std::function > mSaveFuncs; + typedef OptionListComponent LetterList; std::shared_ptr mJumpToLetterList; typedef OptionListComponent SortList; std::shared_ptr mListSort; + + std::shared_ptr mFavoriteOption; + + bool mFavoriteState; SystemData* mSystem; IGameListView* getGamelist(); diff --git a/es-app/src/views/SystemView.cpp b/es-app/src/views/SystemView.cpp index 272d4c6342..c79fc492b2 100644 --- a/es-app/src/views/SystemView.cpp +++ b/es-app/src/views/SystemView.cpp @@ -187,32 +187,29 @@ void SystemView::onCursorChanged(const CursorState& state) }, (int)(infoStartOpacity * 150)); unsigned int gameCount = getSelected()->getGameCount(); + unsigned int favoritesCount = getSelected()->getFavoritesCount(); // also change the text after we've fully faded out - setAnimation(infoFadeOut, 0, [this, gameCount] { + setAnimation(infoFadeOut, 0, [this, gameCount, favoritesCount] { std::stringstream ss; - + if (getSelected()->getName() == "retropie") ss << "CONFIGURATION"; // only display a game count if there are at least 2 games else if(gameCount > 1) ss << gameCount << " GAMES AVAILABLE"; - mSystemInfo.setText(ss.str()); + mSystemInfo.setText(ss.str()); }, false, 1); - // only display a game count if there are at least 2 games - if(gameCount > 1) + Animation* infoFadeIn = new LambdaAnimation( + [this](float t) { - Animation* infoFadeIn = new LambdaAnimation( - [this](float t) - { - mSystemInfo.setOpacity((unsigned char)(lerp(0.f, 1.f, t) * 255)); - }, 300); + mSystemInfo.setOpacity((unsigned char)(lerp(0.f, 1.f, t) * 255)); + }, 300); - // wait 600ms to fade in - setAnimation(infoFadeIn, 2000, nullptr, false, 2); - } + // wait ms to fade in + setAnimation(infoFadeIn, 800, nullptr, false, 2); // no need to animate transition, we're not going anywhere (probably mEntries.size() == 1) if(endPos == mCamOffset && endPos == mExtrasCamOffset) diff --git a/es-app/src/views/ViewController.cpp b/es-app/src/views/ViewController.cpp index cc83eece51..407bf52515 100644 --- a/es-app/src/views/ViewController.cpp +++ b/es-app/src/views/ViewController.cpp @@ -32,6 +32,7 @@ ViewController::ViewController(Window* window) : GuiComponent(window), mCurrentView(nullptr), mCamera(Eigen::Affine3f::Identity()), mFadeOpacity(0), mLockInput(false) { mState.viewing = NOTHING; + mFavoritesOnly = Settings::getInstance()->getBool("FavoritesOnly"); } ViewController::~ViewController() @@ -104,6 +105,17 @@ void ViewController::goToGameList(SystemData* system) mCamera.translation().x() -= offX; } + if (mInvalidGameList[system] == true) + { + updateFavorite(system, getGameListView(system).get()->getCursor()); + if (mFavoritesOnly != Settings::getInstance()->getBool("FavoritesOnly")) + { + reloadGameListView(system); + mFavoritesOnly = Settings::getInstance()->getBool("FavoritesOnly"); + } + mInvalidGameList[system] = false; + } + mState.viewing = GAME_LIST; mState.system = system; @@ -119,6 +131,52 @@ void ViewController::goToGameList(SystemData* system) playViewTransition(); } +void ViewController::updateFavorite(SystemData* system, FileData* file) +{ + IGameListView* view = getGameListView(system).get(); + if (Settings::getInstance()->getBool("FavoritesOnly")) + { + const std::vector& files = system->getRootFolder()->getChildren(); + view->populateList(files); + int pos = std::find(files.begin(), files.end(), file) - files.begin(); + bool found = false; + for (auto it = files.begin() + pos; it != files.end(); it++) + { + if ((*it)->getType() == GAME) + { + if ((*it)->metadata.get("favorite").compare("yes") == 0) + { + view->setCursor(*it); + found = true; + break; + } + } + } + + if (!found) + { + for (auto it = files.begin() + pos; it != files.begin(); it--) + { + if ((*it)->getType() == GAME) + { + if ((*it)->metadata.get("favorite").compare("yes") == 0) + { + view->setCursor(*it); + break; + } + } + } + } + + if (!found) + { + view->setCursor(*(files.begin() + pos)); + } + } + + view->updateInfoPanel(); +} + void ViewController::playViewTransition() { Eigen::Vector3f target(Eigen::Vector3f::Identity()); @@ -247,7 +305,8 @@ std::shared_ptr ViewController::getGameListView(SystemData* syste // Don't break out in case any subsequent files have video } } - + + if (video) // Create the view view = std::shared_ptr(new VideoGameListView(mWindow, system->getRootFolder())); @@ -268,6 +327,7 @@ std::shared_ptr ViewController::getGameListView(SystemData* syste addChild(view.get()); mGameListViews[system] = view; + mInvalidGameList[system] = false; return view; } @@ -419,6 +479,29 @@ void ViewController::reloadAll() updateHelpPrompts(); } +void ViewController::setInvalidGamesList(SystemData* system) +{ + for (auto it = mGameListViews.begin(); it != mGameListViews.end(); it++) + { + if (system == (it->first)) + { + mInvalidGameList[it->first] = true; + break; + } + } +} + +void ViewController::setAllInvalidGamesList(SystemData* systemExclude) +{ + for (auto it = mGameListViews.begin(); it != mGameListViews.end(); it++) + { + if (systemExclude != (it->first)) + { + mInvalidGameList[it->first] = true; + } + } +} + std::vector ViewController::getHelpPrompts() { std::vector prompts; diff --git a/es-app/src/views/ViewController.h b/es-app/src/views/ViewController.h index 2658f44a9f..2b0cf9fd75 100644 --- a/es-app/src/views/ViewController.h +++ b/es-app/src/views/ViewController.h @@ -23,6 +23,8 @@ class ViewController : public GuiComponent void reloadGameListView(IGameListView* gamelist, bool reloadTheme = false); inline void reloadGameListView(SystemData* system, bool reloadTheme = false) { reloadGameListView(getGameListView(system).get(), reloadTheme); } void reloadAll(); // Reload everything with a theme. Used when the "ThemeSet" setting changes. + void setInvalidGamesList(SystemData* system); + void setAllInvalidGamesList(SystemData* systemExclude); // Navigation. void goToNextGameList(); @@ -33,6 +35,8 @@ class ViewController : public GuiComponent void onFileChanged(FileData* file, FileChangeType change); + void updateFavorite(SystemData* system, FileData* file); + // Plays a nice launch effect and launches the game at the end of it. // Once the game terminates, plays a return effect. void launch(FileData* game, Eigen::Vector3f centerCameraOn = Eigen::Vector3f(Renderer::getScreenWidth() / 2.0f, Renderer::getScreenHeight() / 2.0f, 0)); @@ -78,10 +82,13 @@ class ViewController : public GuiComponent std::shared_ptr mCurrentView; std::map< SystemData*, std::shared_ptr > mGameListViews; std::shared_ptr mSystemListView; + + std::map mInvalidGameList; Eigen::Affine3f mCamera; float mFadeOpacity; bool mLockInput; + bool mFavoritesOnly; State mState; }; diff --git a/es-app/src/views/gamelist/BasicGameListView.cpp b/es-app/src/views/gamelist/BasicGameListView.cpp index d3cbc017a1..d358df2088 100644 --- a/es-app/src/views/gamelist/BasicGameListView.cpp +++ b/es-app/src/views/gamelist/BasicGameListView.cpp @@ -41,9 +41,39 @@ void BasicGameListView::populateList(const std::vector& files) mHeaderText.setText(files.at(0)->getSystem()->getFullName()); + bool hasFavorites = false; + + if (Settings::getInstance()->getBool("FavoritesOnly")) + { + for (auto it = files.begin(); it != files.end(); it++) + { + if ((*it)->getType() == GAME) + { + if ((*it)->metadata.get("favorite").compare("yes") == 0) + { + hasFavorites = true; + break; + } + } + } + } + for(auto it = files.begin(); it != files.end(); it++) { - mList.add((*it)->getName(), *it, ((*it)->getType() == FOLDER)); + if (Settings::getInstance()->getBool("FavoritesOnly") && hasFavorites) + { + if ((*it)->getType() == GAME) + { + if ((*it)->metadata.get("favorite").compare("yes") == 0) + { + mList.add((*it)->getName(), *it, ((*it)->getType() == FOLDER)); + } + } + } + else + { + mList.add((*it)->getName(), *it, ((*it)->getType() == FOLDER)); + } } } @@ -108,6 +138,8 @@ void BasicGameListView::remove(FileData *game) onFileChanged(game, FILE_REMOVED); // update the view, with game removed } +void BasicGameListView::updateInfoPanel() {} + std::vector BasicGameListView::getHelpPrompts() { std::vector prompts; diff --git a/es-app/src/views/gamelist/BasicGameListView.h b/es-app/src/views/gamelist/BasicGameListView.h index a1bf0b5d6f..b11f7cc756 100644 --- a/es-app/src/views/gamelist/BasicGameListView.h +++ b/es-app/src/views/gamelist/BasicGameListView.h @@ -20,8 +20,10 @@ class BasicGameListView : public ISimpleGameListView virtual std::vector getHelpPrompts() override; -protected: virtual void populateList(const std::vector& files) override; + + virtual inline void updateInfoPanel() override {} +protected: virtual void launch(FileData* game) override; virtual void remove(FileData* game) override; diff --git a/es-app/src/views/gamelist/DetailedGameListView.cpp b/es-app/src/views/gamelist/DetailedGameListView.cpp index de16110145..607e8d18e0 100644 --- a/es-app/src/views/gamelist/DetailedGameListView.cpp +++ b/es-app/src/views/gamelist/DetailedGameListView.cpp @@ -1,18 +1,19 @@ #include "views/gamelist/DetailedGameListView.h" #include "views/ViewController.h" #include "Window.h" +#include "Settings.h" #include "animations/LambdaAnimation.h" -DetailedGameListView::DetailedGameListView(Window* window, FileData* root) : +DetailedGameListView::DetailedGameListView(Window* window, FileData* root, SystemData* system) : BasicGameListView(window, root), mDescContainer(window), mDescription(window), - mImage(window), + mImage(window), mSystem(system), mLblRating(window), mLblReleaseDate(window), mLblDeveloper(window), mLblPublisher(window), - mLblGenre(window), mLblPlayers(window), mLblLastPlayed(window), mLblPlayCount(window), + mLblGenre(window), mLblPlayers(window), mLblLastPlayed(window), mLblPlayCount(window), mLblFavorite(window), mRating(window), mReleaseDate(window), mDeveloper(window), mPublisher(window), - mGenre(window), mPlayers(window), mLastPlayed(window), mPlayCount(window) + mGenre(window), mPlayers(window), mLastPlayed(window), mPlayCount(window), mFavorite(window) { //mHeaderImage.setPosition(mSize.x() * 0.25f, 0); @@ -55,6 +56,12 @@ DetailedGameListView::DetailedGameListView(Window* window, FileData* root) : mLblPlayCount.setText("Times played: "); addChild(&mLblPlayCount); addChild(&mPlayCount); + if (system->getHasFavorites()) + { + mLblFavorite.setText("Favorite: "); + addChild(&mLblFavorite); + addChild(&mFavorite); + } mDescContainer.setPosition(mSize.x() * padding, mSize.y() * 0.65f); mDescContainer.setSize(mSize.x() * (0.50f - 2*padding), mSize.y() - mDescContainer.getPosition().y()); @@ -80,29 +87,62 @@ void DetailedGameListView::onThemeChanged(const std::shared_ptr& them initMDLabels(); std::vector labels = getMDLabels(); - assert(labels.size() == 8); - const char* lblElements[8] = { - "md_lbl_rating", "md_lbl_releasedate", "md_lbl_developer", "md_lbl_publisher", - "md_lbl_genre", "md_lbl_players", "md_lbl_lastplayed", "md_lbl_playcount" - }; - for(unsigned int i = 0; i < labels.size(); i++) + if (mSystem->getHasFavorites()) { - labels[i]->applyTheme(theme, getName(), lblElements[i], ALL); + assert(labels.size() == 9); + const char* lblElements[9] = { + "md_lbl_rating", "md_lbl_releasedate", "md_lbl_developer", "md_lbl_publisher", + "md_lbl_genre", "md_lbl_players", "md_lbl_lastplayed", "md_lbl_playcount", "md_lbl_favorite" + }; + + for (unsigned int i = 0; i < labels.size(); i++) + { + labels[i]->applyTheme(theme, getName(), lblElements[i], ALL); + } } + else + { + assert(labels.size() == 8); + const char* lblElements[8] = { + "md_lbl_rating", "md_lbl_releasedate", "md_lbl_developer", "md_lbl_publisher", + "md_lbl_genre", "md_lbl_players", "md_lbl_lastplayed", "md_lbl_playcount" + }; + for(unsigned int i = 0; i < labels.size(); i++) + { + labels[i]->applyTheme(theme, getName(), lblElements[i], ALL); + } + } initMDValues(); std::vector values = getMDValues(); - assert(values.size() == 8); - const char* valElements[8] = { - "md_rating", "md_releasedate", "md_developer", "md_publisher", - "md_genre", "md_players", "md_lastplayed", "md_playcount" - }; - for(unsigned int i = 0; i < values.size(); i++) + if (mSystem->getHasFavorites()) { - values[i]->applyTheme(theme, getName(), valElements[i], ALL ^ ThemeFlags::TEXT); + assert(values.size() == 9); + const char* valElements[9] = { + "md_rating", "md_releasedate", "md_developer", "md_publisher", + "md_genre", "md_players", "md_lastplayed", "md_playcount", "md_favorite" + }; + + for (unsigned int i = 0; i < values.size(); i++) + { + values[i]->applyTheme(theme, getName(), valElements[i], ALL ^ ThemeFlags::TEXT); + } + } + else + { + assert(values.size() == 8); + const char* valElements[8] = { + "md_rating", "md_releasedate", "md_developer", "md_publisher", + "md_genre", "md_players", "md_lastplayed", "md_playcount" + }; + + for (unsigned int i = 0; i < values.size(); i++) + { + values[i]->applyTheme(theme, getName(), valElements[i], ALL ^ ThemeFlags::TEXT); + } } mDescContainer.applyTheme(theme, getName(), "md_description", POSITION | ThemeFlags::SIZE); @@ -158,6 +198,7 @@ void DetailedGameListView::initMDValues() mPlayers.setFont(defaultFont); mLastPlayed.setFont(defaultFont); mPlayCount.setFont(defaultFont); + mFavorite.setFont(defaultFont); float bottom = 0.0f; @@ -202,6 +243,7 @@ void DetailedGameListView::updateInfoPanel() mPlayers.setValue(file->metadata.get("players")); mLastPlayed.setValue(file->metadata.get("lastplayed")); mPlayCount.setValue(file->metadata.get("playcount")); + mFavorite.setValue(file->metadata.get("favorite")); } fadingOut = false; @@ -252,6 +294,10 @@ std::vector DetailedGameListView::getMDLabels() ret.push_back(&mLblPlayers); ret.push_back(&mLblLastPlayed); ret.push_back(&mLblPlayCount); + if (mSystem->getHasFavorites()) + { + ret.push_back(&mLblFavorite); + } return ret; } @@ -266,5 +312,29 @@ std::vector DetailedGameListView::getMDValues() ret.push_back(&mPlayers); ret.push_back(&mLastPlayed); ret.push_back(&mPlayCount); + if (mSystem->getHasFavorites()) + { + ret.push_back(&mFavorite); + } return ret; } + +std::vector DetailedGameListView::getHelpPrompts() +{ + std::vector prompts; + + if (Settings::getInstance()->getBool("QuickSystemSelect")) + { + prompts.push_back(HelpPrompt("left/right", "system")); + } + prompts.push_back(HelpPrompt("up/down", "choose")); + prompts.push_back(HelpPrompt("a", "launch")); + prompts.push_back(HelpPrompt("b", "back")); + if (mSystem->getHasFavorites()) + { + prompts.push_back(HelpPrompt("x", "toggle favorite")); + } + prompts.push_back(HelpPrompt("select", "options")); + return prompts; +} + diff --git a/es-app/src/views/gamelist/DetailedGameListView.h b/es-app/src/views/gamelist/DetailedGameListView.h index 30396e04c7..cbb29b1c05 100644 --- a/es-app/src/views/gamelist/DetailedGameListView.h +++ b/es-app/src/views/gamelist/DetailedGameListView.h @@ -4,28 +4,31 @@ #include "components/ScrollableContainer.h" #include "components/RatingComponent.h" #include "components/DateTimeComponent.h" +#include "SystemData.h" class DetailedGameListView : public BasicGameListView { public: - DetailedGameListView(Window* window, FileData* root); + DetailedGameListView(Window* window, FileData* root, SystemData* system); virtual void onThemeChanged(const std::shared_ptr& theme) override; virtual const char* getName() const override { return "detailed"; } + virtual void updateInfoPanel() override; + protected: virtual void launch(FileData* game) override; -private: - void updateInfoPanel(); + virtual std::vector getHelpPrompts() override; +private: void initMDLabels(); void initMDValues(); ImageComponent mImage; - TextComponent mLblRating, mLblReleaseDate, mLblDeveloper, mLblPublisher, mLblGenre, mLblPlayers, mLblLastPlayed, mLblPlayCount; + TextComponent mLblRating, mLblReleaseDate, mLblDeveloper, mLblPublisher, mLblGenre, mLblPlayers, mLblLastPlayed, mLblPlayCount, mLblFavorite; RatingComponent mRating; DateTimeComponent mReleaseDate; @@ -35,10 +38,13 @@ class DetailedGameListView : public BasicGameListView TextComponent mPlayers; DateTimeComponent mLastPlayed; TextComponent mPlayCount; + TextComponent mFavorite; std::vector getMDLabels(); std::vector getMDValues(); ScrollableContainer mDescContainer; TextComponent mDescription; + + SystemData* mSystem; }; diff --git a/es-app/src/views/gamelist/GridGameListView.cpp b/es-app/src/views/gamelist/GridGameListView.cpp index c34b4b8ba0..76e1e38ac6 100644 --- a/es-app/src/views/gamelist/GridGameListView.cpp +++ b/es-app/src/views/gamelist/GridGameListView.cpp @@ -2,6 +2,7 @@ #include "ThemeData.h" #include "Window.h" #include "views/ViewController.h" +#include "Settings.h" GridGameListView::GridGameListView(Window* window, FileData* root) : ISimpleGameListView(window, root), mGrid(window) @@ -40,7 +41,17 @@ void GridGameListView::populateList(const std::vector& files) mGrid.clear(); for(auto it = files.begin(); it != files.end(); it++) { - mGrid.add((*it)->getName(), (*it)->getThumbnailPath(), *it); + if (Settings::getInstance()->getBool("FavoritesOnly")) + { + if ((*it)->metadata.get("favorite").compare("yes") == 0) + { + mGrid.add((*it)->getName(), (*it)->getThumbnailPath(), *it); + } + } + else + { + mGrid.add((*it)->getName(), (*it)->getThumbnailPath(), *it); + } } } diff --git a/es-app/src/views/gamelist/IGameListView.h b/es-app/src/views/gamelist/IGameListView.h index ec98a9de97..b8f696f52d 100644 --- a/es-app/src/views/gamelist/IGameListView.h +++ b/es-app/src/views/gamelist/IGameListView.h @@ -37,6 +37,11 @@ class IGameListView : public GuiComponent virtual const char* getName() const = 0; virtual HelpStyle getHelpStyle() override; + + virtual void updateInfoPanel() = 0; + + virtual void populateList(const std::vector& files) = 0; + protected: FileData* mRoot; std::shared_ptr mTheme; diff --git a/es-app/src/views/gamelist/ISimpleGameListView.cpp b/es-app/src/views/gamelist/ISimpleGameListView.cpp index dd6df5b634..76e74f8bd8 100644 --- a/es-app/src/views/gamelist/ISimpleGameListView.cpp +++ b/es-app/src/views/gamelist/ISimpleGameListView.cpp @@ -1,12 +1,14 @@ #include "views/gamelist/ISimpleGameListView.h" #include "ThemeData.h" +#include "SystemData.h" #include "Window.h" #include "views/ViewController.h" #include "Sound.h" #include "Settings.h" +#include "Gamelist.h" ISimpleGameListView::ISimpleGameListView(Window* window, FileData* root) : IGameListView(window, root), - mHeaderText(window), mHeaderImage(window), mBackground(window), mThemeExtras(window) +mHeaderText(window), mHeaderImage(window), mBackground(window), mThemeExtras(window), mFavoriteChange(false) { mHeaderText.setText("Logo Text"); mHeaderText.setSize(mSize.x(), 0); @@ -82,15 +84,48 @@ bool ISimpleGameListView::input(InputConfig* config, Input input) Sound::getFromTheme(getTheme(), getName(), "back")->play(); }else{ onFocusLost(); + + if (mFavoriteChange) + { + ViewController::get()->setInvalidGamesList(getCursor()->getSystem()); + mFavoriteChange = false; + } + ViewController::get()->goToSystemView(getCursor()->getSystem()); } return true; + }else if (config->isMappedTo("x", input)) + { + FileData* cursor = getCursor(); + if (cursor->getSystem()->getHasFavorites()) + { + if (cursor->getType() == GAME) + { + mFavoriteChange = true; + MetaDataList* md = &cursor->metadata; + std::string value = md->get("favorite"); + if (value.compare("no") == 0) + { + md->set("favorite", "yes"); + } + else + { + md->set("favorite", "no"); + } + updateInfoPanel(); + } + } }else if(config->isMappedTo("right", input)) { if(Settings::getInstance()->getBool("QuickSystemSelect")) { onFocusLost(); + if (mFavoriteChange) + { + ViewController::get()->setInvalidGamesList(getCursor()->getSystem()); + mFavoriteChange = false; + } ViewController::get()->goToNextGameList(); return true; } @@ -99,6 +134,11 @@ bool ISimpleGameListView::input(InputConfig* config, Input input) if(Settings::getInstance()->getBool("QuickSystemSelect")) { onFocusLost(); + if (mFavoriteChange) + { + ViewController::get()->setInvalidGamesList(getCursor()->getSystem()); + mFavoriteChange = false; + } ViewController::get()->goToPrevGameList(); return true; } diff --git a/es-app/src/views/gamelist/ISimpleGameListView.h b/es-app/src/views/gamelist/ISimpleGameListView.h index 9022cde73e..c83b2bb240 100644 --- a/es-app/src/views/gamelist/ISimpleGameListView.h +++ b/es-app/src/views/gamelist/ISimpleGameListView.h @@ -24,8 +24,11 @@ class ISimpleGameListView : public IGameListView virtual bool input(InputConfig* config, Input input) override; + virtual inline void updateInfoPanel() override {} + + virtual inline void populateList(const std::vector& files) override {} + protected: - virtual void populateList(const std::vector& files) = 0; virtual void launch(FileData* game) = 0; TextComponent mHeaderText; @@ -35,4 +38,7 @@ class ISimpleGameListView : public IGameListView ThemeExtras mThemeExtras; std::stack mCursorStack; + +private: + bool mFavoriteChange; }; diff --git a/es-core/src/GuiComponent.cpp b/es-core/src/GuiComponent.cpp index 6ba531f2bf..4365e3b50b 100644 --- a/es-core/src/GuiComponent.cpp +++ b/es-core/src/GuiComponent.cpp @@ -358,4 +358,4 @@ void GuiComponent::onHide() getChild(i)->onHide(); } - +void GuiComponent::setScrollDir(int dir) {} diff --git a/es-core/src/GuiComponent.h b/es-core/src/GuiComponent.h index e37abe69f0..379fe6c5be 100644 --- a/es-core/src/GuiComponent.h +++ b/es-core/src/GuiComponent.h @@ -96,6 +96,8 @@ class GuiComponent // Returns true if the component is busy doing background processing (e.g. HTTP downloads) bool isProcessing() const; + virtual inline void setScrollDir(int dir) {} + protected: void renderChildren(const Eigen::Affine3f& transform) const; void updateSelf(int deltaTime); // updates animations diff --git a/es-core/src/Settings.cpp b/es-core/src/Settings.cpp index 05c286dba3..e0523c420c 100644 --- a/es-core/src/Settings.cpp +++ b/es-core/src/Settings.cpp @@ -61,6 +61,7 @@ void Settings::setDefaults() mBoolMap["HideConsole"] = true; mBoolMap["QuickSystemSelect"] = true; mBoolMap["SaveGamelistsOnExit"] = true; + mBoolMap["FavoritesOnly"] = false; mBoolMap["Debug"] = false; mBoolMap["DebugGrid"] = false; diff --git a/es-core/src/ThemeData.cpp b/es-core/src/ThemeData.cpp index 50958b11f8..b67bb62dd8 100644 --- a/es-core/src/ThemeData.cpp +++ b/es-core/src/ThemeData.cpp @@ -525,3 +525,8 @@ fs::path ThemeData::getThemeFromCurrentSet(const std::string& system) return set->second.getThemePath(system); } + +bool ThemeData::getHasFavoritesInTheme() +{ + return (mVersion >= CURRENT_THEME_FORMAT_VERSION); +} diff --git a/es-core/src/ThemeData.h b/es-core/src/ThemeData.h index 8231e07ede..1e1ee5f1e1 100644 --- a/es-core/src/ThemeData.h +++ b/es-core/src/ThemeData.h @@ -147,6 +147,8 @@ class ThemeData static std::map getThemeSets(); static boost::filesystem::path getThemeFromCurrentSet(const std::string& system); + bool getHasFavoritesInTheme(); + private: static std::map< std::string, std::map > sElementMap; static std::vector sSupportedFeatures; diff --git a/es-core/src/guis/GuiInputConfig.cpp b/es-core/src/guis/GuiInputConfig.cpp index 996133596b..0963651267 100644 --- a/es-core/src/guis/GuiInputConfig.cpp +++ b/es-core/src/guis/GuiInputConfig.cpp @@ -7,14 +7,6 @@ #include "components/ButtonComponent.h" #include "Util.h" -// static const int inputCount = 10; -// static const char* inputName[inputCount] = { "Up", "Down", "Left", "Right", "A", "B", "Start", "Select", "PageUp", "PageDown" }; -// static const bool inputSkippable[inputCount] = { false, false, false, false, false, false, false, false, true, true }; -// static const char* inputDispName[inputCount] = { "UP", "DOWN", "LEFT", "RIGHT", "A", "B", "START", "SELECT", "PAGE UP", "PAGE DOWN" }; -// static const char* inputIcon[inputCount] = { ":/help/dpad_up.svg", ":/help/dpad_down.svg", ":/help/dpad_left.svg", ":/help/dpad_right.svg", -// ":/help/button_a.svg", ":/help/button_b.svg", ":/help/button_start.svg", ":/help/button_select.svg", -// ":/help/button_l.svg", ":/help/button_r.svg" }; - static const int inputCount = 24; static const char* inputName[inputCount] = { From 84f7294d203fc13490e6321642c70ffec31a8402 Mon Sep 17 00:00:00 2001 From: "D. Polders" Date: Fri, 20 Nov 2015 15:21:21 +0100 Subject: [PATCH 72/74] Introduction of UI modes for ES: Kids, Kiosk, Full New user interface modes to support the hiding of UI elements, and certain games to protect the system from tampering, and young minds from items deemed too mature. The kid mode only shows game-items which are specifically whitelisted as child-proof (via new metadata tag). In Kiosk mode, all games are shown, except for those that are explicitly hidden (again via metadata tag). In both these modes, UI elements that allow the user to change system configuration are not shown. In Full mode, none of these constraints are present. Switching from either kids or kiosk mode is done via an input sequence, the default being the konami cheat code. --- GAMELISTS.md | 1 + THEMES.md | 3 + es-app/src/EmulationStation.h | 2 +- es-app/src/FileData.cpp | 98 ++++++++++++--- es-app/src/FileData.h | 9 +- es-app/src/Gamelist.cpp | 9 +- es-app/src/MetaData.cpp | 6 +- es-app/src/MetaData.h | 1 + es-app/src/ScraperCmdLine.cpp | 4 +- es-app/src/SystemData.cpp | 37 ++++-- es-app/src/SystemData.h | 14 ++- es-app/src/components/TextListComponent.h | 3 +- es-app/src/guis/GuiFastSelect.cpp | 2 +- es-app/src/guis/GuiGamelistOptions.cpp | 89 ++++++++++--- es-app/src/guis/GuiGamelistOptions.h | 8 +- es-app/src/guis/GuiMenu.cpp | 117 +++++++++++++----- es-app/src/guis/GuiMetaDataEd.cpp | 21 +++- es-app/src/guis/GuiScraperStart.cpp | 11 +- es-app/src/main.cpp | 2 + es-app/src/views/SystemView.cpp | 109 ++++++++-------- es-app/src/views/ViewController.cpp | 115 +++++++++++++++-- es-app/src/views/ViewController.h | 8 +- .../src/views/gamelist/BasicGameListView.cpp | 57 ++++----- .../views/gamelist/DetailedGameListView.cpp | 90 +++++++------- .../src/views/gamelist/DetailedGameListView.h | 10 +- .../src/views/gamelist/GridGameListView.cpp | 11 +- es-app/src/views/gamelist/IGameListView.cpp | 1 + .../views/gamelist/ISimpleGameListView.cpp | 57 ++++++--- .../src/views/gamelist/ISimpleGameListView.h | 3 +- es-core/src/GuiComponent.cpp | 7 +- es-core/src/GuiComponent.h | 6 +- es-core/src/InputConfig.cpp | 2 + es-core/src/InputManager.cpp | 9 +- es-core/src/Settings.cpp | 4 + es-core/src/ThemeData.cpp | 5 + es-core/src/ThemeData.h | 1 + es-core/src/Util.cpp | 13 +- es-core/src/Window.cpp | 69 +++++++++++ es-core/src/Window.h | 4 + es-core/src/components/ComponentList.cpp | 1 + es-core/src/components/IList.h | 1 + es-core/src/components/ImageComponent.cpp | 19 ++- es-core/src/components/ImageComponent.h | 12 +- es-core/src/components/OptionListComponent.h | 1 + es-core/src/components/SwitchComponent.cpp | 20 +++ es-core/src/components/SwitchComponent.h | 5 +- es-core/src/platform.cpp | 10 +- 47 files changed, 801 insertions(+), 286 deletions(-) diff --git a/GAMELISTS.md b/GAMELISTS.md index 4b72360e68..94bdbb168c 100644 --- a/GAMELISTS.md +++ b/GAMELISTS.md @@ -53,6 +53,7 @@ Some metadata is also marked as "statistic" - these are kept track of by ES and * `playcount` - statistic, integer, the number of times this game has been played * `lastplayed` - statistic, datetime, the last date and time this game was played. * `favorite` - string, yes / no is this a favorite. +* `kidgame` - string, yes / no, is this a kid-friendly game? #### `` diff --git a/THEMES.md b/THEMES.md index 5d0446b5cf..2fa44271a8 100644 --- a/THEMES.md +++ b/THEMES.md @@ -262,6 +262,9 @@ Which is equivalent to: 48474D + + 48474D + ``` diff --git a/es-app/src/EmulationStation.h b/es-app/src/EmulationStation.h index b543edca00..2ea6437c78 100644 --- a/es-app/src/EmulationStation.h +++ b/es-app/src/EmulationStation.h @@ -5,7 +5,7 @@ #define PROGRAM_VERSION_MAJOR 2 #define PROGRAM_VERSION_MINOR 1 #define PROGRAM_VERSION_MAINTENANCE 6 -#define PROGRAM_VERSION_STRING "2.1.6rp" +#define PROGRAM_VERSION_STRING "2.1.6rp_Kid_Kiosk_UI_Favorites" #define PROGRAM_BUILT_STRING __DATE__ " - " __TIME__ diff --git a/es-app/src/FileData.cpp b/es-app/src/FileData.cpp index edd00b2aaf..c3174307f5 100644 --- a/es-app/src/FileData.cpp +++ b/es-app/src/FileData.cpp @@ -1,5 +1,7 @@ #include "FileData.h" #include "SystemData.h" +#include "Log.h" +#include "Settings.h" namespace fs = boost::filesystem; @@ -75,10 +77,43 @@ std::string FileData::getCleanName() const const std::string& FileData::getThumbnailPath() const { - if(!metadata.get("thumbnail").empty()) + if(!metadata.get("thumbnail").empty()) { return metadata.get("thumbnail"); - else + } else { return metadata.get("image"); + } +} + +std::vector FileData::getChildren(bool filter) const +{ + LOG(LogDebug) << "FileData::getChildren(" << filter << ")"; + std::vector fileList = mChildren; + LOG(LogDebug) << " fileList.size() = " << fileList.size(); + + if (filter) + { + //filter out unwanted items from mChildren + bool filterHidden = (Settings::getInstance()->getString("UIMode") != "Full"); + bool filterFav = (Settings::getInstance()->getBool("FavoritesOnly")); + bool filterKid = (Settings::getInstance()->getString("UIMode") == "Kid"); + + LOG(LogDebug) << " filtering (" << filterHidden << filterFav << filterKid << ")."; + + // then filter out all we do not want. + if (filterHidden) { + fileList = filterFileData(fileList, "hidden", "false"); + } + if (filterFav) { + fileList = filterFileData(fileList, "favorite", "true"); + } + if (filterKid) { + fileList = filterFileData(fileList, "kidgame", "true"); + } + + } + //LOG(LogDebug) << " returning " << fileList.size() << " files, done."; + + return fileList; } const std::string& FileData::getVideoPath() const @@ -108,33 +143,43 @@ const std::string& FileData::getMarqueePath() const } -std::vector FileData::getFilesRecursive(unsigned int typeMask) const +std::vector FileData::getFilesRecursive(unsigned int typeMask, bool filter) const { - std::vector out; + LOG(LogDebug) << "FileData::getFilesRecursive(" << filter << ")"; - for(auto it = mChildren.begin(); it != mChildren.end(); it++) + // first populate with all we can find + std::vector allfiles = getChildren(filter); + std::vector fileList; + + //LOG(LogDebug) << "FileData::getFilesRecursive(): allfiles contains " << allfiles.size() << " items"; + + for(auto it = allfiles.begin(); it != allfiles.end(); it++) { - if((*it)->getType() & typeMask) - out.push_back(*it); + if((*it)->getType() & typeMask) { + fileList.push_back(*it); + } - if((*it)->getChildren().size() > 0) - { - std::vector subchildren = (*it)->getFilesRecursive(typeMask); - out.insert(out.end(), subchildren.cbegin(), subchildren.cend()); + if((*it)->getChildren(filter).size() > 1) { + //LOG(LogDebug) << "FileData::getFilesRecursive(): Recursing!"; + std::vector subchildren = (*it)->getFilesRecursive(typeMask, filter); + fileList.insert(fileList.end(), subchildren.cbegin(), subchildren.cend()); } } + - return out; + LOG(LogDebug) << "FileData::getFilesRecursive():returning " << fileList.size() << " games"; + return fileList; } -std::vector FileData::getFavoritesRecursive(unsigned int typeMask) const +std::vector FileData::filterFileData(std::vector in, std::string filtername, std::string passString) const { + //LOG(LogDebug) << "FileData::filterFileData(" << filtername << ", needs to be: " << passString << ")"; + std::vector out; - std::vector files = getFilesRecursive(typeMask); - for (auto it = files.begin(); it != files.end(); it++) + for (auto it = in.begin(); it != in.end(); it++) { - if ((*it)->metadata.get("favorite").compare("yes") == 0) + if ((*it)->metadata.get(filtername).compare(passString) == 0) { out.push_back(*it); } @@ -194,3 +239,24 @@ void FileData::sort(const SortType& type) { sort(*type.comparisonFunction, type.ascending); } + +FileData* FileData::getRandom() const +{ + LOG(LogDebug) << "FileData::getRandom()"; + + //Get list of files + std::vector list = getFilesRecursive(GAME,true); // always filter + const unsigned long n = list.size(); + LOG(LogDebug) << " found games: " << n; + + //Select random system + //const unsigned long divisor = (RAND_MAX + 1) / n; + const unsigned long divisor = (RAND_MAX) / n; // the above is correct, but gives compiler warning. + unsigned long k; + do { + k = std::rand() / divisor; + } while (k >= n); // pick the first within range + + LOG(LogDebug) << " Picked game: " << list.at(k)->getName(); + return list.at(k); +} diff --git a/es-app/src/FileData.h b/es-app/src/FileData.h index 85be6aa0ca..8637f2ee0f 100644 --- a/es-app/src/FileData.h +++ b/es-app/src/FileData.h @@ -41,16 +41,17 @@ class FileData inline const boost::filesystem::path& getPath() const { return mPath; } inline FileData* getParent() const { return mParent; } inline const std::unordered_map& getChildrenByFilename() const { return mChildrenByFilename; } - inline const std::vector& getChildren() const { return mChildren; } inline SystemData* getSystem() const { return mSystem; } virtual const std::string& getThumbnailPath() const; virtual const std::string& getVideoPath() const; virtual const std::string& getMarqueePath() const; - std::vector getFilesRecursive(unsigned int typeMask) const; - std::vector getFavoritesRecursive(unsigned int typeMask) const; - + std::vector getChildren(bool filter = false) const; + std::vector getFilesRecursive(unsigned int typeMask, bool filter) const; + std::vector filterFileData(std::vector in, std::string filtername, std::string passString) const; + FileData* getRandom() const; + void addChild(FileData* file); // Error if mType != FOLDER void removeChild(FileData* file); //Error if mType != FOLDER diff --git a/es-app/src/Gamelist.cpp b/es-app/src/Gamelist.cpp index e5bc7da3bc..76b69cbdf5 100644 --- a/es-app/src/Gamelist.cpp +++ b/es-app/src/Gamelist.cpp @@ -151,7 +151,8 @@ void addFileDataNode(pugi::xml_node& parent, const FileData* file, const char* t pugi::xml_node newNode = parent.append_child(tag); //write metadata - file->metadata.appendToXML(newNode, true, system->getStartPath()); + //file->metadata.appendToXML(newNode, true, system->getStartPath()); + file->metadata.appendToXML(newNode, false, system->getStartPath()); // set ignore defaults to false to force writing all values if(newNode.children().begin() == newNode.child("name") //first element is name && ++newNode.children().begin() == newNode.children().end() //theres only one element @@ -174,7 +175,8 @@ void updateGamelist(SystemData* system) //because there might be information missing in our systemdata which would then miss in the new XML. //We have the complete information for every game though, so we can simply remove a game //we already have in the system from the XML, and then add it back from its GameData information... - + LOG(LogDebug) << "updateGamelist("<< system->getFullName() <<")"; + if(Settings::getInstance()->getBool("IgnoreGamelist")) return; @@ -212,7 +214,7 @@ void updateGamelist(SystemData* system) int numUpdated = 0; //get only files, no folders - std::vector files = rootFolder->getFilesRecursive(GAME | FOLDER); + std::vector files = rootFolder->getFilesRecursive(GAME | FOLDER, false); //iterate through all files, checking if they're already in the XML for(std::vector::const_iterator fit = files.cbegin(); fit != files.cend(); ++fit) { @@ -252,7 +254,6 @@ void updateGamelist(SystemData* system) addFileDataNode(root, *fit, tag, system); ++numUpdated; } - //now write the file if (numUpdated > 0) { diff --git a/es-app/src/MetaData.cpp b/es-app/src/MetaData.cpp index be6017316b..d19d89e4d5 100644 --- a/es-app/src/MetaData.cpp +++ b/es-app/src/MetaData.cpp @@ -19,9 +19,11 @@ MetaDataDecl gameDecls[] = { {"publisher", MD_STRING, "unknown", false, "publisher", "enter game publisher"}, {"genre", MD_STRING, "unknown", false, "genre", "enter game genre"}, {"players", MD_INT, "1", false, "players", "enter number of players"}, + {"favorite", MD_BOOL, "false", false, "favorite", "enter favorite off/on"}, + {"kidgame", MD_BOOL, "false", false, "kidgame", "enter kidgame off/on"}, + {"hidden", MD_BOOL, "false", false, "hidden", "enter hidden off/on"}, {"playcount", MD_INT, "0", true, "play count", "enter number of times played"}, - {"lastplayed", MD_TIME, "0", true, "last played", "enter last played date"}, - {"favorite", MD_STRING, "no", false, "favorite", "enter favorite"} + {"lastplayed", MD_TIME, "0", true, "last played", "enter last played date"} }; const std::vector gameMDD(gameDecls, gameDecls + sizeof(gameDecls) / sizeof(gameDecls[0])); diff --git a/es-app/src/MetaData.h b/es-app/src/MetaData.h index f9b867450d..62c9869e61 100644 --- a/es-app/src/MetaData.h +++ b/es-app/src/MetaData.h @@ -13,6 +13,7 @@ enum MetaDataType MD_STRING, MD_INT, MD_FLOAT, + MD_BOOL, //specialized types MD_MULTILINE_STRING, diff --git a/es-app/src/ScraperCmdLine.cpp b/es-app/src/ScraperCmdLine.cpp index f6f6952525..c13def46a4 100644 --- a/es-app/src/ScraperCmdLine.cpp +++ b/es-app/src/ScraperCmdLine.cpp @@ -65,7 +65,7 @@ int run_scraper_cmdline() out << "Will scrape all platforms.\n"; for(auto i = SystemData::sSystemVector.begin(); i != SystemData::sSystemVector.end(); i++) { - out << " " << (*i)->getName() << " (" << (*i)->getGameCount() << " games)\n"; + out << " " << (*i)->getName() << " (" << (*i)->getGameCount(false) << " games)\n"; systems.push_back(*i); } @@ -83,7 +83,7 @@ int run_scraper_cmdline() else out << " "; - out << "\"" << (*i)->getName() << "\" (" << (*i)->getGameCount() << " games)\n"; + out << "\"" << (*i)->getName() << "\" (" << (*i)->getGameCount(false) << " games)\n"; } std::getline(std::cin, sys_name); diff --git a/es-app/src/SystemData.cpp b/es-app/src/SystemData.cpp index 79f32394b7..102f36e376 100644 --- a/es-app/src/SystemData.cpp +++ b/es-app/src/SystemData.cpp @@ -424,14 +424,9 @@ bool SystemData::hasGamelist() const return (fs::exists(getGamelistPath(false))); } -unsigned int SystemData::getGameCount() const +unsigned int SystemData::getGameCount(bool filter) const { - return mRootFolder->getFilesRecursive(GAME).size(); -} - -unsigned int SystemData::getFavoritesCount() const -{ - return mRootFolder->getFavoritesRecursive(GAME).size(); + return mRootFolder->getFilesRecursive(GAME,filter).size(); } void SystemData::loadTheme() @@ -447,9 +442,37 @@ void SystemData::loadTheme() { mTheme->loadFile(path); mHasFavorites = mTheme->getHasFavoritesInTheme(); + mHasKidGames = mTheme->getHasKidGamesInTheme(); } catch(ThemeException& e) { LOG(LogError) << e.what(); mTheme = std::make_shared(); // reset to empty } } + +SystemData* SystemData::getRandom() const +{ + LOG(LogDebug) << "SystemData::getRandom()"; + //Get list of systems with # games > 0, given the filters + std::vector validSystems; + for (auto it = sSystemVector.begin(); it != sSystemVector.end(); it++) { + if((*it)->getGameCount(true) > 0) { + validSystems.push_back(*it); + } + } + + const unsigned long n = validSystems.size(); + LOG(LogDebug) << " Valid systems: " << n; + + //Select random system + //const unsigned long divisor = (RAND_MAX + 1) / n; + const unsigned long divisor = (RAND_MAX) / n; // the above is correct, but gives compiler warning. + unsigned long k; + do { + k = std::rand() / divisor; + } while (k >= n); // pick the first within range + + LOG(LogDebug) << " Picked system: " << validSystems.at(k)->getFullName(); + + return validSystems.at(k); +} diff --git a/es-app/src/SystemData.h b/es-app/src/SystemData.h index a9759cd5d8..9710bbae8f 100644 --- a/es-app/src/SystemData.h +++ b/es-app/src/SystemData.h @@ -21,7 +21,9 @@ class SystemData inline const std::string& getStartPath() const { return mStartPath; } inline const std::vector& getExtensions() const { return mSearchExtensions; } inline const std::string& getThemeFolder() const { return mThemeFolder; } - inline bool getHasFavorites() const { return mHasFavorites; } + inline bool getHasFavorites() const { return mHasFavorites; } + inline bool getHasKidGames() const { return mHasKidGames; } + inline const std::vector& getPlatformIds() const { return mPlatformIds; } inline bool hasPlatformId(PlatformIds::PlatformId id) { return std::find(mPlatformIds.begin(), mPlatformIds.end(), id) != mPlatformIds.end(); } @@ -32,9 +34,8 @@ class SystemData bool hasGamelist() const; std::string getThemePath() const; - unsigned int getGameCount() const; - unsigned int getFavoritesCount() const; - + unsigned int getGameCount(bool filter) const; + void launchGame(Window* window, FileData* game); static void deleteSystems(); @@ -62,7 +63,9 @@ class SystemData if(it == sSystemVector.rend()) it = sSystemVector.rbegin(); return *it; } - + + SystemData* getRandom() const; + // Load or re-load theme. void loadTheme(); @@ -77,6 +80,7 @@ class SystemData std::shared_ptr mTheme; bool mHasFavorites; + bool mHasKidGames; void populateFolder(FileData* folder); diff --git a/es-app/src/components/TextListComponent.h b/es-app/src/components/TextListComponent.h index 8067cd7391..4c3a9625c0 100644 --- a/es-app/src/components/TextListComponent.h +++ b/es-app/src/components/TextListComponent.h @@ -309,9 +309,10 @@ void TextListComponent::onCursorChanged(const CursorState& state) { mMarqueeOffset = 0; mMarqueeTime = -MARQUEE_DELAY; - if(mCursorChangedCallback) + { mCursorChangedCallback(state); + } } template diff --git a/es-app/src/guis/GuiFastSelect.cpp b/es-app/src/guis/GuiFastSelect.cpp index 31db350414..9ed7e5bb48 100644 --- a/es-app/src/guis/GuiFastSelect.cpp +++ b/es-app/src/guis/GuiFastSelect.cpp @@ -141,7 +141,7 @@ void GuiFastSelect::updateGameListSort() void GuiFastSelect::updateGameListCursor() { - const std::vector& list = mGameList->getCursor()->getParent()->getChildren(); + const std::vector& list = mGameList->getCursor()->getParent()->getChildren(true); // only skip by letter when the sort mode is alphabetical const FileData::SortType& sort = FileSorts::SortTypes.at(mSortId); diff --git a/es-app/src/guis/GuiGamelistOptions.cpp b/es-app/src/guis/GuiGamelistOptions.cpp index 38792d1f06..b778edd5e2 100644 --- a/es-app/src/guis/GuiGamelistOptions.cpp +++ b/es-app/src/guis/GuiGamelistOptions.cpp @@ -5,11 +5,15 @@ #include "views/ViewController.h" #include "components/SwitchComponent.h" #include "guis/GuiSettings.h" +#include "Log.h" +#include "SystemData.h" +#include "FileData.h" GuiGamelistOptions::GuiGamelistOptions(Window* window, SystemData* system) : GuiComponent(window), mSystem(system), mMenu(window, "OPTIONS") { + LOG(LogDebug) << "GUIGamelistOptions::GuiGamelistOptions()"; addChild(&mMenu); // jump to letter @@ -38,6 +42,18 @@ GuiGamelistOptions::GuiGamelistOptions(Window* window, SystemData* system) : Gui }; mMenu.addRow(row); + row.elements.clear(); + row.addElement(std::make_shared(mWindow, "SURPRISE ME!", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true); + row.input_handler = [&](InputConfig* config, Input input) { + if(config->isMappedTo("a", input) && input.value) + { + SurpriseMe(); + return true; + } + return false; + }; + mMenu.addRow(row); + // sort list by mListSort = std::make_shared(mWindow, "SORT GAMES BY", false); for(unsigned int i = 0; i < FileSorts::SortTypes.size(); i++) @@ -47,39 +63,69 @@ GuiGamelistOptions::GuiGamelistOptions(Window* window, SystemData* system) : Gui } mMenu.addWithLabel("SORT GAMES BY", mListSort); - + + // Toggle: Show favorites-only auto favorite_only = std::make_shared(mWindow); favorite_only->setState(Settings::getInstance()->getBool("FavoritesOnly")); mMenu.addWithLabel("FAVORITES ONLY", favorite_only); - addSaveFunc([favorite_only] { Settings::getInstance()->setBool("FavoritesOnly", favorite_only->getState()); }); - - // edit game metadata - row.elements.clear(); - row.addElement(std::make_shared(mWindow, "EDIT THIS GAME'S METADATA", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true); - row.addElement(makeArrow(mWindow), false); - row.makeAcceptInputHandler(std::bind(&GuiGamelistOptions::openMetaDataEd, this)); - mMenu.addRow(row); + addSaveFunc([favorite_only, this] { + + // First save to settings, in order for filtering to work + if (favorite_only->getState() != Settings::getInstance()->getBool("FavoritesOnly")) + { + Settings::getInstance()->setBool("FavoritesOnly", favorite_only->getState()); + mFavoriteStateChanged = true; + } + if(favorite_only->getState()) + { + bool hasFavorite = false; + // check if there is anything at all to show, otherwise revert + for(auto it = SystemData::sSystemVector.begin(); it != SystemData::sSystemVector.end(); it++) { + if( (*it)->getGameCount(true) > 0 ) { + hasFavorite = true; + break; + } + } + if(!hasFavorite) + { + LOG(LogDebug) << "Nothing to show in selected favorites mode, resetting"; + favorite_only->setState(false); + Settings::getInstance()->setBool("FavoritesOnly", favorite_only->getState()); + } + } + }); + + // edit game metadata - only in Full UI mode + if(Settings::getInstance()->getString("UIMode") == "Full") + { + row.elements.clear(); + row.addElement(std::make_shared(mWindow, "EDIT THIS GAME'S METADATA", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true); + row.addElement(makeArrow(mWindow), false); + row.makeAcceptInputHandler(std::bind(&GuiGamelistOptions::openMetaDataEd, this)); + mMenu.addRow(row); + } // center the menu setSize((float)Renderer::getScreenWidth(), (float)Renderer::getScreenHeight()); mMenu.setPosition((mSize.x() - mMenu.getSize().x()) / 2, (mSize.y() - mMenu.getSize().y()) / 2); - - mFavoriteState = Settings::getInstance()->getBool("FavoritesOnly"); } GuiGamelistOptions::~GuiGamelistOptions() { + LOG(LogDebug) << "GUIGamelistOptions::~GuiGamelistOptions()"; // apply sort FileData* root = getGamelist()->getCursor()->getSystem()->getRootFolder(); root->sort(*mListSort->getSelected()); // will also recursively sort children - + // notify that the root folder was sorted - getGamelist()->onFileChanged(root, FILE_SORTED); - - if (Settings::getInstance()->getBool("FavoritesOnly") != mFavoriteState) + + getGamelist()->onFileChanged(root, FILE_SORTED); + if (mFavoriteStateChanged) { + LOG(LogDebug) << " GUIGamelistOptions::~GuiGamelistOptions(): FavoriteStateChanged, reloading GameList"; ViewController::get()->setAllInvalidGamesList(getGamelist()->getCursor()->getSystem()); - ViewController::get()->reloadGameListView(getGamelist()->getCursor()->getSystem()); + //ViewController::get()->reloadGameListView(getGamelist()->getCursor()->getSystem()); + ViewController::get()->reloadAll(); } } @@ -102,7 +148,7 @@ void GuiGamelistOptions::jumpToLetter() IGameListView* gamelist = getGamelist(); // this is a really shitty way to get a list of files - const std::vector& files = gamelist->getCursor()->getParent()->getChildren(); + const std::vector& files = gamelist->getCursor()->getParent()->getChildren(true); long min = 0; long max = files.size() - 1; @@ -137,7 +183,7 @@ bool GuiGamelistOptions::input(InputConfig* config, Input input) { save(); delete this; - return true; + return true; } return mMenu.input(config, input); @@ -165,3 +211,10 @@ void GuiGamelistOptions::save() Settings::getInstance()->saveFile(); } + +void GuiGamelistOptions::SurpriseMe() +{ + LOG(LogDebug) << "GuiGamelistOptions::SurpriseMe()"; + ViewController::get()->goToRandomGame(); + delete this; +} diff --git a/es-app/src/guis/GuiGamelistOptions.h b/es-app/src/guis/GuiGamelistOptions.h index 46dd386585..3abba851d4 100644 --- a/es-app/src/guis/GuiGamelistOptions.h +++ b/es-app/src/guis/GuiGamelistOptions.h @@ -21,6 +21,8 @@ class GuiGamelistOptions : public GuiComponent private: void openMetaDataEd(); void jumpToLetter(); + void SurpriseMe(); + MenuComponent mMenu; @@ -28,13 +30,15 @@ class GuiGamelistOptions : public GuiComponent typedef OptionListComponent LetterList; std::shared_ptr mJumpToLetterList; - + typedef OptionListComponent SortList; std::shared_ptr mListSort; std::shared_ptr mFavoriteOption; + bool mFavoriteStateChanged; - bool mFavoriteState; + typedef OptionListComponent SurpriseEnums; + std::shared_ptr mSurpriseModes; SystemData* mSystem; IGameListView* getGamelist(); diff --git a/es-app/src/guis/GuiMenu.cpp b/es-app/src/guis/GuiMenu.cpp index 68b1a355d1..bc1420afe7 100644 --- a/es-app/src/guis/GuiMenu.cpp +++ b/es-app/src/guis/GuiMenu.cpp @@ -31,7 +31,10 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MEN // [version] auto openScrapeNow = [this] { mWindow->pushGui(new GuiScraperStart(mWindow)); }; - addEntry("SCRAPER", 0x777777FF, true, + + if(Settings::getInstance()->getString("UIMode") == "Full") + { + addEntry("SCRAPER", 0x777777FF, true, [this, openScrapeNow] { auto s = new GuiSettings(mWindow, "SCRAPER"); @@ -63,31 +66,84 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MEN s->addRow(row); mWindow->pushGui(s); - }); + }); + } addEntry("SOUND SETTINGS", 0x777777FF, true, - [this] { - auto s = new GuiSettings(mWindow, "SOUND SETTINGS"); - - // volume - auto volume = std::make_shared(mWindow, 0.f, 100.f, 1.f, "%"); - volume->setValue((float)VolumeControl::getInstance()->getVolume()); - s->addWithLabel("SYSTEM VOLUME", volume); - s->addSaveFunc([volume] { VolumeControl::getInstance()->setVolume((int)round(volume->getValue())); }); - - // disable sounds + [this] { + auto s = new GuiSettings(mWindow, "SOUND SETTINGS"); + + // volume + auto volume = std::make_shared(mWindow, 0.f, 100.f, 1.f, "%"); + volume->setValue((float)VolumeControl::getInstance()->getVolume()); + s->addWithLabel("SYSTEM VOLUME", volume); + s->addSaveFunc([volume] { VolumeControl::getInstance()->setVolume((int)round(volume->getValue())); }); + + if(Settings::getInstance()->getString("UIMode") == "Full") + { + // enable / disable sounds auto sounds_enabled = std::make_shared(mWindow); sounds_enabled->setState(Settings::getInstance()->getBool("EnableSounds")); s->addWithLabel("ENABLE SOUNDS", sounds_enabled); s->addSaveFunc([sounds_enabled] { Settings::getInstance()->setBool("EnableSounds", sounds_enabled->getState()); }); - - mWindow->pushGui(s); + } + mWindow->pushGui(s); }); - addEntry("UI SETTINGS", 0x777777FF, true, - [this] { + if(Settings::getInstance()->getString("UIMode") == "Full") + { + addEntry("UI SETTINGS", 0x777777FF, true, + [this] { auto s = new GuiSettings(mWindow, "UI SETTINGS"); + auto UImodeSelection = std::make_shared< OptionListComponent >(mWindow, "UI MODE", false); + std::vector UImodes; + UImodes.push_back("Full"); + UImodes.push_back("Kiosk"); + UImodes.push_back("Kid"); + for(auto it = UImodes.begin(); it != UImodes.end(); it++) + UImodeSelection->add(*it, *it, Settings::getInstance()->getString("UIMode") == *it); + s->addWithLabel("UI MODE", UImodeSelection); + Window* window = mWindow; + s->addSaveFunc([UImodeSelection, window] + { + LOG(LogDebug) << "Changing UI mode to" << UImodeSelection->getSelected(); + + bool needReload = false; + if(Settings::getInstance()->getString("UIMode") != UImodeSelection->getSelected()) + { + needReload = true; + + // First write to settings, in order for filtering to work + Settings::getInstance()->setString("UIMode", UImodeSelection->getSelected()); + Settings::getInstance()->setBool("FavoritesOnly", false); // reset favoritesOnly option upon mode change + + LOG(LogDebug) << "Checking if the proposed UI mode has anything at all to show:"; + + bool hasContent = false; + for(auto it = SystemData::sSystemVector.begin(); it != SystemData::sSystemVector.end(); it++) { + LOG(LogDebug) << "System = " << (*it)->getName() << ", "<< (*it)->getGameCount(true) << " games found"; + if ((*it)->getGameCount(true) > 0) + { + hasContent = true; + break; + } + } + if (!hasContent) { + LOG(LogDebug) << "Nothing to show in selected mode (" << UImodeSelection->getSelected() << "), resetting to full"; + window->pushGui(new GuiMsgBox(window, "The selected view mode has nothing to show,\n returning to UI mode = FULL", + "OK", nullptr)); + Settings::getInstance()->setString("UIMode", "Full"); + needReload = false; + } + } + if(needReload) + { + ViewController::get()->reloadAll(); + ViewController::get()->goToStart(); + } + }); + // screensaver time auto screensaver_time = std::make_shared(mWindow, 0.f, 30.f, 1.f, "m"); screensaver_time->setValue((float)(Settings::getInstance()->getInt("ScreenSaverTime") / (1000 * 60))); @@ -101,7 +157,7 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MEN screensavers.push_back("black"); for(auto it = screensavers.begin(); it != screensavers.end(); it++) screensaver_behavior->add(*it, *it, Settings::getInstance()->getString("ScreenSaverBehavior") == *it); - s->addWithLabel("SCREENSAVER BEHAVIOR", screensaver_behavior); + s->addWithLabel("SCREENSAVER TYPE", screensaver_behavior); s->addSaveFunc([screensaver_behavior] { Settings::getInstance()->setString("ScreenSaverBehavior", screensaver_behavior->getSelected()); }); // framerate @@ -159,12 +215,14 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MEN ViewController::get()->reloadAll(); // TODO - replace this with some sort of signal-based implementation }); } - mWindow->pushGui(s); - }); + }); - addEntry("OTHER SETTINGS", 0x777777FF, true, - [this] { + + if(Settings::getInstance()->getString("UIMode") == "Full") + { + addEntry("OTHER SETTINGS", 0x777777FF, true, + [this] { auto s = new GuiSettings(mWindow, "OTHER SETTINGS"); // gamelists @@ -185,17 +243,18 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MEN s->addSaveFunc([max_vram] { Settings::getInstance()->setInt("MaxVRAM", (int)round(max_vram->getValue())); }); mWindow->pushGui(s); - }); + }); - addEntry("CONFIGURE INPUT", 0x777777FF, true, - [this] { + addEntry("CONFIGURE INPUT", 0x777777FF, true, + [this] { Window* window = mWindow; window->pushGui(new GuiMsgBox(window, "ARE YOU SURE YOU WANT TO CONFIGURE INPUT?", "YES", [window] { - window->pushGui(new GuiDetectDevice(window, false, nullptr)); - }, "NO", nullptr) + window->pushGui(new GuiDetectDevice(window, false, nullptr)); + }, "NO", nullptr) ); - }); + }); + } addEntry("QUIT", 0x777777FF, true, [this] { @@ -236,7 +295,9 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MEN row.addElement(std::make_shared(window, "SHUTDOWN SYSTEM", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true); s->addRow(row); - if(Settings::getInstance()->getBool("ShowExit")) + if (Settings::getInstance()->getBool("ShowExit") && + ((Settings::getInstance()->getString("UIMode") == "Full") || + (Settings::getInstance()->getBool("Debug")))) { row.elements.clear(); row.makeAcceptInputHandler([window] { diff --git a/es-app/src/guis/GuiMetaDataEd.cpp b/es-app/src/guis/GuiMetaDataEd.cpp index 11367c2ad2..a2e011257b 100644 --- a/es-app/src/guis/GuiMetaDataEd.cpp +++ b/es-app/src/guis/GuiMetaDataEd.cpp @@ -7,10 +7,12 @@ #include "guis/GuiGameScraper.h" #include "guis/GuiMsgBox.h" #include +#include "Gamelist.h" #include "components/TextEditComponent.h" #include "components/DateTimeComponent.h" #include "components/RatingComponent.h" +#include "components/SwitchComponent.h" #include "guis/GuiTextEditPopup.h" using namespace Eigen; @@ -59,6 +61,12 @@ GuiMetaDataEd::GuiMetaDataEd(Window* window, MetaDataList* md, const std::vector switch(iter->type) { + case MD_BOOL: + { + ed = std::make_shared(window); + row.addElement(ed, false, true); + break; + } case MD_RATING: { ed = std::make_shared(window); @@ -170,14 +178,17 @@ void GuiMetaDataEd::onSizeChanged() void GuiMetaDataEd::save() { + LOG(LogDebug) << "Starting Save Function"; for(unsigned int i = 0; i < mEditors.size(); i++) { if(mMetaDataDecl.at(i).isStatistic) continue; - + //LOG(LogDebug) << i << ": Setting "<< mMetaDataDecl.at(i).key << " to be :" << mEditors.at(i)->getValue(); mMetaData->set(mMetaDataDecl.at(i).key, mEditors.at(i)->getValue()); } - + LOG(LogError) << "updating XML"; + updateGamelist(mScraperParams.system); + if(mSavedCallback) mSavedCallback(); } @@ -204,12 +215,17 @@ void GuiMetaDataEd::close(bool closeAllWindows) { // find out if the user made any changes bool dirty = false; + LOG(LogDebug) << "GuiMetaDataEd::close()"; + //LOG(LogDebug) << " checking metadata fields (size = "<get(key) != mEditors.at(i)->getValue()) { + //LOG(LogDebug) << "mEditors.at("<getValue(); + //LOG(LogDebug) << "mMetaData->get("<get(key); dirty = true; + LOG(LogDebug) << " dirty!"; break; } } @@ -236,6 +252,7 @@ void GuiMetaDataEd::close(bool closeAllWindows) "NO", closeFunc )); }else{ + LOG(LogDebug) << " no changes found, closing"; closeFunc(); } } diff --git a/es-app/src/guis/GuiScraperStart.cpp b/es-app/src/guis/GuiScraperStart.cpp index 7d1ebab436..2dc5b811c9 100644 --- a/es-app/src/guis/GuiScraperStart.cpp +++ b/es-app/src/guis/GuiScraperStart.cpp @@ -75,13 +75,10 @@ void GuiScraperStart::start() std::queue GuiScraperStart::getSearches(std::vector systems, GameFilterFunc selector) { std::queue queue; - for(auto sys = systems.begin(); sys != systems.end(); sys++) - { - std::vector games = (*sys)->getRootFolder()->getFilesRecursive(GAME); - for(auto game = games.begin(); game != games.end(); game++) - { - if(selector((*sys), (*game))) - { + for(auto sys = systems.begin(); sys != systems.end(); sys++) { + std::vector games = (*sys)->getRootFolder()->getFilesRecursive(GAME, false); + for(auto game = games.begin(); game != games.end(); game++) { + if(selector((*sys), (*game))) { ScraperSearchParams search; search.game = *game; search.system = *sys; diff --git a/es-app/src/main.cpp b/es-app/src/main.cpp index c3d030ec4b..8968932b92 100644 --- a/es-app/src/main.cpp +++ b/es-app/src/main.cpp @@ -166,6 +166,8 @@ void onExit() int main(int argc, char* argv[]) { + srand(time(NULL)); + unsigned int width = 0; unsigned int height = 0; diff --git a/es-app/src/views/SystemView.cpp b/es-app/src/views/SystemView.cpp index c79fc492b2..b66d808f1c 100644 --- a/es-app/src/views/SystemView.cpp +++ b/es-app/src/views/SystemView.cpp @@ -23,60 +23,70 @@ SystemView::SystemView(Window* window) : IList(wind void SystemView::populate() { + LOG(LogDebug) << "SystemView::populate()"; + LOG(LogDebug) << " Settings.UIMode = " << Settings::getInstance()->getString("UIMode"); + LOG(LogDebug) << " Settings.FavoritesOnly = " << Settings::getInstance()->getBool("FavoritesOnly"); + mEntries.clear(); - for(auto it = SystemData::sSystemVector.begin(); it != SystemData::sSystemVector.end(); it++) { - const std::shared_ptr& theme = (*it)->getTheme(); + LOG(LogDebug) << "System = " << (*it)->getName(); - if(mViewNeedsReload) - getViewElements(theme); + if ((*it)->getGameCount(true) > 0) { + LOG(LogDebug) << (*it)->getGameCount(true) << " games found, populating."; - Entry e; - e.name = (*it)->getName(); - e.object = *it; + if (mViewNeedsReload) + getViewElements(theme); - // make logo - if(theme->getElement("system", "logo", "image")) - { - ImageComponent* logo = new ImageComponent(mWindow); - logo->setMaxSize(Eigen::Vector2f(mCarousel.logoSize.x(), mCarousel.logoSize.y())); - logo->applyTheme((*it)->getTheme(), "system", "logo", ThemeFlags::PATH); - logo->setPosition((mCarousel.logoSize.x() - logo->getSize().x()) / 2, - (mCarousel.logoSize.y() - logo->getSize().y()) / 2); // center - e.data.logo = std::shared_ptr(logo); - - ImageComponent* logoSelected = new ImageComponent(mWindow); - logoSelected->setMaxSize(Eigen::Vector2f(mCarousel.logoSize.x() * mCarousel.logoScale, mCarousel.logoSize.y() * mCarousel.logoScale)); - logoSelected->applyTheme((*it)->getTheme(), "system", "logo", ThemeFlags::PATH | ThemeFlags::COLOR); - logoSelected->setPosition((mCarousel.logoSize.x() - logoSelected->getSize().x()) / 2, - (mCarousel.logoSize.y() - logoSelected->getSize().y()) / 2); // center - e.data.logoSelected = std::shared_ptr(logoSelected); - - }else{ - // no logo in theme; use text - TextComponent* text = new TextComponent(mWindow, - (*it)->getName(), - Font::get(FONT_SIZE_LARGE), - 0x000000FF, - ALIGN_CENTER); - text->setSize(mCarousel.logoSize); - e.data.logo = std::shared_ptr(text); - - TextComponent* textSelected = new TextComponent(mWindow, - (*it)->getName(), - Font::get((int)(FONT_SIZE_LARGE * 1.5)), - 0x000000FF, - ALIGN_CENTER); - textSelected->setSize(mCarousel.logoSize); - e.data.logoSelected = std::shared_ptr(textSelected); - } + const std::shared_ptr& theme = (*it)->getTheme(); - // make background extras - e.data.backgroundExtras = std::shared_ptr(new ThemeExtras(mWindow)); - e.data.backgroundExtras->setExtras(ThemeData::makeExtras((*it)->getTheme(), "system", mWindow)); + Entry e; + e.name = (*it)->getName(); + e.object = *it; - this->add(e); + // make logo + if (theme->getElement("system", "logo", "image")) + { + ImageComponent* logo = new ImageComponent(mWindow); + logo->setMaxSize(Eigen::Vector2f(mCarousel.logoSize.x(), mCarousel.logoSize.y())); + logo->applyTheme((*it)->getTheme(), "system", "logo", ThemeFlags::PATH); + logo->setPosition((mCarousel.logoSize.x() - logo->getSize().x()) / 2, + (mCarousel.logoSize.y() - logo->getSize().y()) / 2); // center + e.data.logo = std::shared_ptr(logo); + + ImageComponent* logoSelected = new ImageComponent(mWindow); + logoSelected->setMaxSize(Eigen::Vector2f(mCarousel.logoSize.x() * mCarousel.logoScale, mCarousel.logoSize.y() * mCarousel.logoScale)); + logoSelected->applyTheme((*it)->getTheme(), "system", "logo", ThemeFlags::PATH | ThemeFlags::COLOR); + logoSelected->setPosition((mCarousel.logoSize.x() - logoSelected->getSize().x()) / 2, + (mCarousel.logoSize.y() - logoSelected->getSize().y()) / 2); // center + e.data.logoSelected = std::shared_ptr(logoSelected); + + } + else { + // no logo in theme; use text + TextComponent* text = new TextComponent(mWindow, + (*it)->getName(), + Font::get(FONT_SIZE_LARGE), + 0x000000FF, + ALIGN_CENTER); + text->setSize(mCarousel.logoSize); + e.data.logo = std::shared_ptr(text); + + TextComponent* textSelected = new TextComponent(mWindow, + (*it)->getName(), + Font::get((int)(FONT_SIZE_LARGE * 1.5)), + 0x000000FF, + ALIGN_CENTER); + textSelected->setSize(mCarousel.logoSize); + e.data.logoSelected = std::shared_ptr(textSelected); + } + + // make background extras + e.data.backgroundExtras = std::shared_ptr(new ThemeExtras(mWindow)); + e.data.backgroundExtras->setExtras(ThemeData::makeExtras((*it)->getTheme(), "system", mWindow)); + + this->add(e); + } } } @@ -96,6 +106,7 @@ bool SystemView::input(InputConfig* config, Input input) { LOG(LogInfo) << " Reloading all"; ViewController::get()->reloadAll(); + return true; } @@ -186,11 +197,9 @@ void SystemView::onCursorChanged(const CursorState& state) mSystemInfo.setOpacity((unsigned char)(lerp(infoStartOpacity, 0.f, t) * 255)); }, (int)(infoStartOpacity * 150)); - unsigned int gameCount = getSelected()->getGameCount(); - unsigned int favoritesCount = getSelected()->getFavoritesCount(); - // also change the text after we've fully faded out - setAnimation(infoFadeOut, 0, [this, gameCount, favoritesCount] { + setAnimation(infoFadeOut, 0, [this] { + unsigned int gameCount = getSelected()->getGameCount(true); std::stringstream ss; if (getSelected()->getName() == "retropie") diff --git a/es-app/src/views/ViewController.cpp b/es-app/src/views/ViewController.cpp index 407bf52515..90f5ad9f9e 100644 --- a/es-app/src/views/ViewController.cpp +++ b/es-app/src/views/ViewController.cpp @@ -33,6 +33,7 @@ ViewController::ViewController(Window* window) { mState.viewing = NOTHING; mFavoritesOnly = Settings::getInstance()->getBool("FavoritesOnly"); + mKidGamesOnly = Settings::getInstance()->getString("UIMode") == "Kid"; } ViewController::~ViewController() @@ -81,7 +82,14 @@ void ViewController::goToNextGameList() assert(mState.viewing == GAME_LIST); SystemData* system = getState().getSystem(); assert(system); - goToGameList(system->getNext()); + + // skip systems that don't have a game list, this will always end since it is called + // from a system with a game list and the iterator is cyclic + do { + system = system->getNext(); + } while ( system->getGameCount(true) == 0 ); + + goToGameList(system); } void ViewController::goToPrevGameList() @@ -89,7 +97,14 @@ void ViewController::goToPrevGameList() assert(mState.viewing == GAME_LIST); SystemData* system = getState().getSystem(); assert(system); - goToGameList(system->getPrev()); + + // skip systems that don't have a game list, this will always end since it is called + // from a system with a game list and the iterator is cyclic + do { + system = system->getPrev(); + } while ( system->getGameCount(true) == 0 ); + + goToGameList(system); } void ViewController::goToGameList(SystemData* system) @@ -107,11 +122,16 @@ void ViewController::goToGameList(SystemData* system) if (mInvalidGameList[system] == true) { - updateFavorite(system, getGameListView(system).get()->getCursor()); - if (mFavoritesOnly != Settings::getInstance()->getBool("FavoritesOnly")) + updateView(system, getGameListView(system).get()->getCursor()); + //updateFavorite(system, getGameListView(system).get()->getCursor()); + //updateKidGame(system, getGameListView(system).get()->getCursor()); + + if ((mFavoritesOnly != Settings::getInstance()->getBool("FavoritesOnly")) || + (mKidGamesOnly != (Settings::getInstance()->getString("UIMode") == "Kid"))) { reloadGameListView(system); mFavoritesOnly = Settings::getInstance()->getBool("FavoritesOnly"); + mKidGamesOnly = Settings::getInstance()->getString("UIMode") == "Kid"; } mInvalidGameList[system] = false; } @@ -131,12 +151,27 @@ void ViewController::goToGameList(SystemData* system) playViewTransition(); } +void ViewController::goToRandomGame() +{ + LOG(LogDebug) << "ViewController::goToRandomGame()"; + + goToGameList(mState.system->getRandom()); + + FileData* selected = mState.system->getRootFolder()->getRandom(); + + IGameListView* view = getGameListView(mState.system).get(); + view->setCursor(selected); + + //mCurrentView.get()->setCursor(selected); + LOG(LogDebug) << "ViewController::goToRandomGame: done."; +} +/* void ViewController::updateFavorite(SystemData* system, FileData* file) { IGameListView* view = getGameListView(system).get(); if (Settings::getInstance()->getBool("FavoritesOnly")) { - const std::vector& files = system->getRootFolder()->getChildren(); + const std::vector& files = system->getRootFolder()->getChildren(true); view->populateList(files); int pos = std::find(files.begin(), files.end(), file) - files.begin(); bool found = false; @@ -144,7 +179,7 @@ void ViewController::updateFavorite(SystemData* system, FileData* file) { if ((*it)->getType() == GAME) { - if ((*it)->metadata.get("favorite").compare("yes") == 0) + if ((*it)->metadata.get("favorite").compare("true") == 0) { view->setCursor(*it); found = true; @@ -159,7 +194,7 @@ void ViewController::updateFavorite(SystemData* system, FileData* file) { if ((*it)->getType() == GAME) { - if ((*it)->metadata.get("favorite").compare("yes") == 0) + if ((*it)->metadata.get("favorite").compare("true") == 0) { view->setCursor(*it); break; @@ -177,6 +212,66 @@ void ViewController::updateFavorite(SystemData* system, FileData* file) view->updateInfoPanel(); } +// presumably, this function tries to shift the focus to the next (or previous) kidgame, when the display +// mode demands it. This should be solved by reducing the total view/list to contain only valid items. +void ViewController::updateKidGame(SystemData* system, FileData* file) +{ + IGameListView* view = getGameListView(system).get(); + if (Settings::getInstance()->getString("UIMode") == "Kid") // if we are in kidsmode + { + const std::vector& files = system->getRootFolder()->getChildren(true); + view->populateList(files); // populate a new view + int pos = std::find(files.begin(), files.end(), file) - files.begin(); // save current position in that view + bool found = false; + for (auto it = files.begin() + pos; it != files.end(); it++) //try to find another kidgame + { + if ((*it)->getType() == GAME) + { + if ((*it)->metadata.get("kidgame").compare("true") == 0) + { + view->setCursor(*it); // and set the cursor to that one + found = true; + break; + } + } + } + + if (!found) + { + for (auto it = files.begin() + pos; it != files.begin(); it--) + { + if ((*it)->getType() == GAME) + { + if ((*it)->metadata.get("kidgame").compare("true") == 0) + { + view->setCursor(*it); + break; + } + } + } + } + + if (!found) + { + view->setCursor(*(files.begin() + pos)); + } + } + + view->updateInfoPanel(); //update metadata display +} + ***/ + +// Update the view after a viewing mode change has occured (fav only, or hide files, or kids only) +void ViewController::updateView(SystemData* system, FileData* file) +{ + IGameListView* view = getGameListView(system).get(); + const std::vector& files = system->getRootFolder()->getChildren(true); + view->populateList(files); + view->setCursor(*(files.begin())); + view->updateInfoPanel(); +} + + void ViewController::playViewTransition() { Eigen::Vector3f target(Eigen::Vector3f::Identity()); @@ -289,9 +384,9 @@ std::shared_ptr ViewController::getGameListView(SystemData* syste bool themeHasVideoView = system->getTheme()->hasView("video"); //decide type + std::vector files = system->getRootFolder()->getFilesRecursive(GAME | FOLDER, false); bool detailed = false; bool video = false; - std::vector files = system->getRootFolder()->getFilesRecursive(GAME | FOLDER); for(auto it = files.begin(); it != files.end(); it++) { if(themeHasVideoView && !(*it)->getVideoPath().empty()) @@ -314,7 +409,7 @@ std::shared_ptr ViewController::getGameListView(SystemData* syste view = std::shared_ptr(new DetailedGameListView(mWindow, system->getRootFolder())); else view = std::shared_ptr(new BasicGameListView(mWindow, system->getRootFolder())); - + // uncomment for experimental "image grid" view //view = std::shared_ptr(new GridGameListView(mWindow, system->getRootFolder())); @@ -520,4 +615,4 @@ HelpStyle ViewController::getHelpStyle() return GuiComponent::getHelpStyle(); return mCurrentView->getHelpStyle(); -} +} \ No newline at end of file diff --git a/es-app/src/views/ViewController.h b/es-app/src/views/ViewController.h index 2b0cf9fd75..d09be1fb61 100644 --- a/es-app/src/views/ViewController.h +++ b/es-app/src/views/ViewController.h @@ -32,11 +32,14 @@ class ViewController : public GuiComponent void goToGameList(SystemData* system); void goToSystemView(SystemData* system); void goToStart(); + void goToRandomGame(); void onFileChanged(FileData* file, FileChangeType change); - void updateFavorite(SystemData* system, FileData* file); - + //void updateFavorite(SystemData* system, FileData* file); + //void updateKidGame(SystemData* system, FileData* file); + void updateView(SystemData* system, FileData* file); + // Plays a nice launch effect and launches the game at the end of it. // Once the game terminates, plays a return effect. void launch(FileData* game, Eigen::Vector3f centerCameraOn = Eigen::Vector3f(Renderer::getScreenWidth() / 2.0f, Renderer::getScreenHeight() / 2.0f, 0)); @@ -89,6 +92,7 @@ class ViewController : public GuiComponent float mFadeOpacity; bool mLockInput; bool mFavoritesOnly; + bool mKidGamesOnly; State mState; }; diff --git a/es-app/src/views/gamelist/BasicGameListView.cpp b/es-app/src/views/gamelist/BasicGameListView.cpp index d358df2088..f5e4c84e7d 100644 --- a/es-app/src/views/gamelist/BasicGameListView.cpp +++ b/es-app/src/views/gamelist/BasicGameListView.cpp @@ -5,15 +5,18 @@ #include "ThemeData.h" #include "SystemData.h" #include "Settings.h" +#include "Log.h" + BasicGameListView::BasicGameListView(Window* window, FileData* root) : ISimpleGameListView(window, root), mList(window) { + //LOG(LogDebug) << "BasicGameListView::BasicGameListView()"; mList.setSize(mSize.x(), mSize.y() * 0.8f); mList.setPosition(0, mSize.y() * 0.2f); addChild(&mList); - populateList(root->getChildren()); + populateList(root->getChildren(true)); // This returns a filtered list based on UImode } void BasicGameListView::onThemeChanged(const std::shared_ptr& theme) @@ -37,44 +40,28 @@ void BasicGameListView::onFileChanged(FileData* file, FileChangeType change) void BasicGameListView::populateList(const std::vector& files) { + if (files.size() > 0) { + LOG(LogDebug) << "BasicGameListView::populateList(): system = " << files.at(0)->getSystem()->getFullName(); + } mList.clear(); - mHeaderText.setText(files.at(0)->getSystem()->getFullName()); + // TODO: how to handle empty lists?? - bool hasFavorites = false; - - if (Settings::getInstance()->getBool("FavoritesOnly")) - { - for (auto it = files.begin(); it != files.end(); it++) - { - if ((*it)->getType() == GAME) - { - if ((*it)->metadata.get("favorite").compare("yes") == 0) - { - hasFavorites = true; - break; - } - } - } + // file list can be empty if direct launch item (@@ do we still have those?) + if (files.size()==0) { + return; } - - for(auto it = files.begin(); it != files.end(); it++) - { - if (Settings::getInstance()->getBool("FavoritesOnly") && hasFavorites) - { - if ((*it)->getType() == GAME) - { - if ((*it)->metadata.get("favorite").compare("yes") == 0) - { - mList.add((*it)->getName(), *it, ((*it)->getType() == FOLDER)); - } - } - } - else + + mHeaderText.setText(files.at(0)->getSystem()->getFullName()); + for (auto it = files.begin(); it != files.end(); it++) { + if ((*it)->getType() == GAME) { - mList.add((*it)->getName(), *it, ((*it)->getType() == FOLDER)); + mList.add((*it)->getName(), *it, 0); + } else { // its a folder! + mList.add((*it)->getName(), *it, 1); } } + LOG(LogDebug)<< "BasicGameListView::populateList(): added " << mList.size() << " items. END"; } FileData* BasicGameListView::getCursor() @@ -86,7 +73,7 @@ void BasicGameListView::setCursor(FileData* cursor) { if(!mList.setCursor(cursor)) { - populateList(cursor->getParent()->getChildren()); + populateList(cursor->getParent()->getChildren(true)); mList.setCursor(cursor); // update our cursor stack in case our cursor just got set to some folder we weren't in before @@ -121,7 +108,7 @@ void BasicGameListView::remove(FileData *game) boost::filesystem::remove(game->getPath()); // actually delete the file on the filesystem if (getCursor() == game) // Select next element in list, or prev if none { - std::vector siblings = game->getParent()->getChildren(); + std::vector siblings = game->getParent()->getChildren(true); auto gameIter = std::find(siblings.begin(), siblings.end(), game); auto gamePos = std::distance(siblings.begin(), gameIter); if (gameIter != siblings.end()) @@ -151,4 +138,4 @@ std::vector BasicGameListView::getHelpPrompts() prompts.push_back(HelpPrompt("b", "back")); prompts.push_back(HelpPrompt("select", "options")); return prompts; -} +} \ No newline at end of file diff --git a/es-app/src/views/gamelist/DetailedGameListView.cpp b/es-app/src/views/gamelist/DetailedGameListView.cpp index 607e8d18e0..dedcb4c819 100644 --- a/es-app/src/views/gamelist/DetailedGameListView.cpp +++ b/es-app/src/views/gamelist/DetailedGameListView.cpp @@ -3,6 +3,7 @@ #include "Window.h" #include "Settings.h" #include "animations/LambdaAnimation.h" +#include "ThemeData.h" DetailedGameListView::DetailedGameListView(Window* window, FileData* root, SystemData* system) : BasicGameListView(window, root), @@ -10,10 +11,10 @@ DetailedGameListView::DetailedGameListView(Window* window, FileData* root, Syste mImage(window), mSystem(system), mLblRating(window), mLblReleaseDate(window), mLblDeveloper(window), mLblPublisher(window), - mLblGenre(window), mLblPlayers(window), mLblLastPlayed(window), mLblPlayCount(window), mLblFavorite(window), + mLblGenre(window), mLblPlayers(window), mLblLastPlayed(window), mLblPlayCount(window), mRating(window), mReleaseDate(window), mDeveloper(window), mPublisher(window), - mGenre(window), mPlayers(window), mLastPlayed(window), mPlayCount(window), mFavorite(window) + mGenre(window), mPlayers(window), mLastPlayed(window), mPlayCount(window), mFavorite(window), mKidGame(window), mHidden(window) { //mHeaderImage.setPosition(mSize.x() * 0.25f, 0); @@ -58,9 +59,9 @@ DetailedGameListView::DetailedGameListView(Window* window, FileData* root, Syste addChild(&mPlayCount); if (system->getHasFavorites()) { - mLblFavorite.setText("Favorite: "); - addChild(&mLblFavorite); addChild(&mFavorite); + addChild(&mKidGame); + addChild(&mHidden); } mDescContainer.setPosition(mSize.x() * padding, mSize.y() * 0.65f); @@ -84,54 +85,43 @@ void DetailedGameListView::onThemeChanged(const std::shared_ptr& them using namespace ThemeFlags; mImage.applyTheme(theme, getName(), "md_image", POSITION | ThemeFlags::SIZE); - - initMDLabels(); - std::vector labels = getMDLabels(); + if (mSystem->getHasFavorites()) { - assert(labels.size() == 9); - const char* lblElements[9] = { - "md_lbl_rating", "md_lbl_releasedate", "md_lbl_developer", "md_lbl_publisher", - "md_lbl_genre", "md_lbl_players", "md_lbl_lastplayed", "md_lbl_playcount", "md_lbl_favorite" - }; - - for (unsigned int i = 0; i < labels.size(); i++) - { - labels[i]->applyTheme(theme, getName(), lblElements[i], ALL); - } + mKidGame.applyTheme(theme, getName(), "md_kidgame", PATH | POSITION | ThemeFlags::SIZE); + mFavorite.applyTheme(theme, getName(), "md_favorite", PATH | POSITION | ThemeFlags::SIZE); + mHidden.applyTheme(theme, getName(), "md_hidden", PATH | POSITION | ThemeFlags::SIZE); } - else - { - assert(labels.size() == 8); - const char* lblElements[8] = { - "md_lbl_rating", "md_lbl_releasedate", "md_lbl_developer", "md_lbl_publisher", - "md_lbl_genre", "md_lbl_players", "md_lbl_lastplayed", "md_lbl_playcount" - }; - for(unsigned int i = 0; i < labels.size(); i++) - { - labels[i]->applyTheme(theme, getName(), lblElements[i], ALL); - } + initMDLabels(); + std::vector labels = getMDLabels(); + assert(labels.size() == 8); + const char* lblElements[8] = { + "md_lbl_rating", "md_lbl_releasedate", "md_lbl_developer", "md_lbl_publisher", + "md_lbl_genre", "md_lbl_players", "md_lbl_lastplayed", "md_lbl_playcount"}; + + for(unsigned int i = 0; i < labels.size(); i++) + { + labels[i]->applyTheme(theme, getName(), lblElements[i], ALL); } + initMDValues(); std::vector values = getMDValues(); - if (mSystem->getHasFavorites()) { - assert(values.size() == 9); - const char* valElements[9] = { - "md_rating", "md_releasedate", "md_developer", "md_publisher", - "md_genre", "md_players", "md_lastplayed", "md_playcount", "md_favorite" + assert(values.size() == 11); + const char* valElements[11] = { + "md_rating", "md_releasedate", "md_developer", "md_publisher","md_genre", + "md_players", "md_lastplayed", "md_playcount", "md_favorite", "md_kidgame", "md_hidden" }; for (unsigned int i = 0; i < values.size(); i++) { values[i]->applyTheme(theme, getName(), valElements[i], ALL ^ ThemeFlags::TEXT); } - } - else + }else { assert(values.size() == 8); const char* valElements[8] = { @@ -145,6 +135,7 @@ void DetailedGameListView::onThemeChanged(const std::shared_ptr& them } } + mDescContainer.applyTheme(theme, getName(), "md_description", POSITION | ThemeFlags::SIZE); mDescription.setSize(mDescContainer.getSize().x(), 0); mDescription.applyTheme(theme, getName(), "md_description", ALL ^ (POSITION | ThemeFlags::SIZE | TEXT)); @@ -198,7 +189,6 @@ void DetailedGameListView::initMDValues() mPlayers.setFont(defaultFont); mLastPlayed.setFont(defaultFont); mPlayCount.setFont(defaultFont); - mFavorite.setFont(defaultFont); float bottom = 0.0f; @@ -220,8 +210,8 @@ void DetailedGameListView::initMDValues() void DetailedGameListView::updateInfoPanel() { + LOG(LogDebug) << "DetailedGameListView::UpdateInfoPanel()"; FileData* file = (mList.size() == 0 || mList.isScrolling()) ? NULL : mList.getSelected(); - bool fadingOut; if(file == NULL) { @@ -244,17 +234,17 @@ void DetailedGameListView::updateInfoPanel() mLastPlayed.setValue(file->metadata.get("lastplayed")); mPlayCount.setValue(file->metadata.get("playcount")); mFavorite.setValue(file->metadata.get("favorite")); + mKidGame.setValue(file->metadata.get("kidgame")); + mHidden.setValue(file->metadata.get("hidden")); } - fadingOut = false; } - std::vector comps = getMDValues(); comps.push_back(&mImage); comps.push_back(&mDescription); + std::vector labels = getMDLabels(); comps.insert(comps.end(), labels.begin(), labels.end()); - for(auto it = comps.begin(); it != comps.end(); it++) { GuiComponent* comp = *it; @@ -283,6 +273,8 @@ void DetailedGameListView::launch(FileData* game) ViewController::get()->launch(game, target); } +// This function returns a pointer vector to all metadata labels supported by the theme +// TODO: auto populate this based on the theme xml std::vector DetailedGameListView::getMDLabels() { std::vector ret; @@ -294,13 +286,11 @@ std::vector DetailedGameListView::getMDLabels() ret.push_back(&mLblPlayers); ret.push_back(&mLblLastPlayed); ret.push_back(&mLblPlayCount); - if (mSystem->getHasFavorites()) - { - ret.push_back(&mLblFavorite); - } return ret; } +// This function returns a pointer vector to all metadata values supported by the theme +// TODO: auto populate this based on the theme xml std::vector DetailedGameListView::getMDValues() { std::vector ret; @@ -315,6 +305,8 @@ std::vector DetailedGameListView::getMDValues() if (mSystem->getHasFavorites()) { ret.push_back(&mFavorite); + ret.push_back(&mKidGame); + ret.push_back(&mHidden); } return ret; } @@ -330,9 +322,15 @@ std::vector DetailedGameListView::getHelpPrompts() prompts.push_back(HelpPrompt("up/down", "choose")); prompts.push_back(HelpPrompt("a", "launch")); prompts.push_back(HelpPrompt("b", "back")); - if (mSystem->getHasFavorites()) + + // TODO: ? if the following works, why do we need the extra function (msystem->getHasKidGames)? + if (mSystem->getTheme()->getHasKidGamesInTheme() && (Settings::getInstance()->getString("UIMode") == "Full")) + { + prompts.push_back(HelpPrompt("y", "Kid-game")); + } + if (mSystem->getHasFavorites() && (Settings::getInstance()->getString("UIMode") == "Full")) { - prompts.push_back(HelpPrompt("x", "toggle favorite")); + prompts.push_back(HelpPrompt("x", "favorite")); } prompts.push_back(HelpPrompt("select", "options")); return prompts; diff --git a/es-app/src/views/gamelist/DetailedGameListView.h b/es-app/src/views/gamelist/DetailedGameListView.h index cbb29b1c05..ead49f21f1 100644 --- a/es-app/src/views/gamelist/DetailedGameListView.h +++ b/es-app/src/views/gamelist/DetailedGameListView.h @@ -6,7 +6,7 @@ #include "components/DateTimeComponent.h" #include "SystemData.h" -class DetailedGameListView : public BasicGameListView +class DetailedGameListView : public BasicGameListView { public: DetailedGameListView(Window* window, FileData* root, SystemData* system); @@ -28,7 +28,7 @@ class DetailedGameListView : public BasicGameListView ImageComponent mImage; - TextComponent mLblRating, mLblReleaseDate, mLblDeveloper, mLblPublisher, mLblGenre, mLblPlayers, mLblLastPlayed, mLblPlayCount, mLblFavorite; + TextComponent mLblRating, mLblReleaseDate, mLblDeveloper, mLblPublisher, mLblGenre, mLblPlayers, mLblLastPlayed, mLblPlayCount; RatingComponent mRating; DateTimeComponent mReleaseDate; @@ -38,8 +38,10 @@ class DetailedGameListView : public BasicGameListView TextComponent mPlayers; DateTimeComponent mLastPlayed; TextComponent mPlayCount; - TextComponent mFavorite; - + ImageComponent mFavorite; + ImageComponent mKidGame; + ImageComponent mHidden; + std::vector getMDLabels(); std::vector getMDValues(); diff --git a/es-app/src/views/gamelist/GridGameListView.cpp b/es-app/src/views/gamelist/GridGameListView.cpp index 76e1e38ac6..f46e3159c2 100644 --- a/es-app/src/views/gamelist/GridGameListView.cpp +++ b/es-app/src/views/gamelist/GridGameListView.cpp @@ -43,12 +43,17 @@ void GridGameListView::populateList(const std::vector& files) { if (Settings::getInstance()->getBool("FavoritesOnly")) { - if ((*it)->metadata.get("favorite").compare("yes") == 0) + if ((*it)->metadata.get("favorite").compare("true") == 0) { mGrid.add((*it)->getName(), (*it)->getThumbnailPath(), *it); } - } - else + }else if(Settings::getInstance()->getString("UIMode") == "Kid") + { + if ((*it)->metadata.get("kidgame").compare("true") == 0) + { + mGrid.add((*it)->getName(), (*it)->getThumbnailPath(), *it); + } + }else { mGrid.add((*it)->getName(), (*it)->getThumbnailPath(), *it); } diff --git a/es-app/src/views/gamelist/IGameListView.cpp b/es-app/src/views/gamelist/IGameListView.cpp index 69799cdd90..c45f3b7ff6 100644 --- a/es-app/src/views/gamelist/IGameListView.cpp +++ b/es-app/src/views/gamelist/IGameListView.cpp @@ -13,6 +13,7 @@ bool IGameListView::input(InputConfig* config, Input input) // select to open GuiGamelistOptions if(config->isMappedTo("select", input) && input.value) { + LOG(LogDebug) << "IGameListView::input(): select detected, opening GuiGameListOptions"; Sound::getFromTheme(mTheme, getName(), "menuOpen")->play(); mWindow->pushGui(new GuiGamelistOptions(mWindow, this->mRoot->getSystem())); return true; diff --git a/es-app/src/views/gamelist/ISimpleGameListView.cpp b/es-app/src/views/gamelist/ISimpleGameListView.cpp index 76e74f8bd8..fa9bcac07b 100644 --- a/es-app/src/views/gamelist/ISimpleGameListView.cpp +++ b/es-app/src/views/gamelist/ISimpleGameListView.cpp @@ -6,9 +6,10 @@ #include "Sound.h" #include "Settings.h" #include "Gamelist.h" +#include "Log.h" ISimpleGameListView::ISimpleGameListView(Window* window, FileData* root) : IGameListView(window, root), -mHeaderText(window), mHeaderImage(window), mBackground(window), mThemeExtras(window), mFavoriteChange(false) +mHeaderText(window), mHeaderImage(window), mBackground(window), mThemeExtras(window), mFavoriteChange(false), mKidGameChange(false) { mHeaderText.setText("Logo Text"); mHeaderText.setSize(mSize.x(), 0); @@ -49,7 +50,7 @@ void ISimpleGameListView::onFileChanged(FileData* file, FileChangeType change) // we could be tricky here to be efficient; // but this shouldn't happen very often so we'll just always repopulate FileData* cursor = getCursor(); - populateList(cursor->getParent()->getChildren()); + populateList(cursor->getParent()->getChildren(true)); setCursor(cursor); } @@ -59,6 +60,7 @@ bool ISimpleGameListView::input(InputConfig* config, Input input) { if(config->isMappedTo("a", input)) { + LOG(LogDebug) << "ISimpleGameListView::input(): a detected!"; FileData* cursor = getCursor(); if(cursor->getType() == GAME) { @@ -66,31 +68,31 @@ bool ISimpleGameListView::input(InputConfig* config, Input input) launch(cursor); }else{ // it's a folder - if(cursor->getChildren().size() > 0) + if(cursor->getChildren(true).size() > 0) { mCursorStack.push(cursor); - populateList(cursor->getChildren()); + populateList(cursor->getChildren(true)); } } return true; }else if(config->isMappedTo("b", input)) { + LOG(LogDebug) << "ISimpleGameListView::input(): b detected!"; if(mCursorStack.size()) { - populateList(mCursorStack.top()->getParent()->getChildren()); + populateList(mCursorStack.top()->getParent()->getChildren(true)); setCursor(mCursorStack.top()); mCursorStack.pop(); Sound::getFromTheme(getTheme(), getName(), "back")->play(); }else{ onFocusLost(); - - if (mFavoriteChange) + if (mFavoriteChange || mKidGameChange) { ViewController::get()->setInvalidGamesList(getCursor()->getSystem()); mFavoriteChange = false; + mKidGameChange = false; } - ViewController::get()->goToSystemView(getCursor()->getSystem()); } @@ -98,6 +100,7 @@ bool ISimpleGameListView::input(InputConfig* config, Input input) }else if (config->isMappedTo("x", input)) { FileData* cursor = getCursor(); + LOG(LogDebug) << "ISimpleGameListView::input(): x detected!"; if (cursor->getSystem()->getHasFavorites()) { if (cursor->getType() == GAME) @@ -105,14 +108,36 @@ bool ISimpleGameListView::input(InputConfig* config, Input input) mFavoriteChange = true; MetaDataList* md = &cursor->metadata; std::string value = md->get("favorite"); - if (value.compare("no") == 0) + LOG(LogDebug) << "Favorite = "<< value; + if (value.compare("false") == 0) { - md->set("favorite", "yes"); - } - else + md->set("favorite", "true"); + }else { - md->set("favorite", "no"); + md->set("favorite", "false"); + } + LOG(LogDebug) << "New Favorite value set to: "<< md->get("favorite"); + updateInfoPanel(); + } + } + }else if (config->isMappedTo("y", input)) + { + LOG(LogDebug) << "ISimpleGameListView::input(): y detected!"; + FileData* cursor = getCursor(); + if (cursor->getSystem()->getHasKidGames() && + Settings::getInstance()->getString("UIMode") == "Full") + { // only when kidgames are supported by system+theme, and when in full UImode + if (cursor->getType() == GAME) { + mKidGameChange = true; + MetaDataList* md = &cursor->metadata; + std::string value = md->get("kidgame"); + LOG(LogDebug) << "kidgame = "<< value; + if (value.compare("false") == 0) { + md->set("kidgame", "true"); + } else { + md->set("kidgame", "false"); } + LOG(LogDebug) << "New kidgame value set to: "<< md->get("kidgame"); updateInfoPanel(); } } @@ -121,10 +146,11 @@ bool ISimpleGameListView::input(InputConfig* config, Input input) if(Settings::getInstance()->getBool("QuickSystemSelect")) { onFocusLost(); - if (mFavoriteChange) + if (mFavoriteChange || mKidGameChange) { ViewController::get()->setInvalidGamesList(getCursor()->getSystem()); mFavoriteChange = false; + mKidGameChange = false; } ViewController::get()->goToNextGameList(); return true; @@ -134,10 +160,11 @@ bool ISimpleGameListView::input(InputConfig* config, Input input) if(Settings::getInstance()->getBool("QuickSystemSelect")) { onFocusLost(); - if (mFavoriteChange) + if (mFavoriteChange || mKidGameChange) { ViewController::get()->setInvalidGamesList(getCursor()->getSystem()); mFavoriteChange = false; + mKidGameChange = false; } ViewController::get()->goToPrevGameList(); return true; diff --git a/es-app/src/views/gamelist/ISimpleGameListView.h b/es-app/src/views/gamelist/ISimpleGameListView.h index c83b2bb240..49787161a6 100644 --- a/es-app/src/views/gamelist/ISimpleGameListView.h +++ b/es-app/src/views/gamelist/ISimpleGameListView.h @@ -40,5 +40,6 @@ class ISimpleGameListView : public IGameListView std::stack mCursorStack; private: - bool mFavoriteChange; + bool mFavoriteChange; + bool mKidGameChange; }; diff --git a/es-core/src/GuiComponent.cpp b/es-core/src/GuiComponent.cpp index 4365e3b50b..40ee91e8ab 100644 --- a/es-core/src/GuiComponent.cpp +++ b/es-core/src/GuiComponent.cpp @@ -95,14 +95,14 @@ Eigen::Vector2f GuiComponent::getSize() const void GuiComponent::setSize(const Eigen::Vector2f& size) { - mSize = size; - onSizeChanged(); + mSize = size; + onSizeChanged(); } void GuiComponent::setSize(float w, float h) { mSize << w, h; - onSizeChanged(); + onSizeChanged(); } //Children stuff. @@ -186,6 +186,7 @@ const Eigen::Affine3f& GuiComponent::getTransform() void GuiComponent::setValue(const std::string& value) { + LOG(LogDebug)<< "GuiComponent::setValue(), this is an empty function, use overrides instead!"; } std::string GuiComponent::getValue() const diff --git a/es-core/src/GuiComponent.h b/es-core/src/GuiComponent.h index 379fe6c5be..1c7baae7db 100644 --- a/es-core/src/GuiComponent.h +++ b/es-core/src/GuiComponent.h @@ -42,9 +42,9 @@ class GuiComponent virtual void onPositionChanged() {}; Eigen::Vector2f getSize() const; - void setSize(const Eigen::Vector2f& size); - void setSize(float w, float h); - virtual void onSizeChanged() {}; + void setSize(const Eigen::Vector2f& size); + void setSize(float w, float h); + virtual void onSizeChanged() {}; void setParent(GuiComponent* parent); GuiComponent* getParent() const; diff --git a/es-core/src/InputConfig.cpp b/es-core/src/InputConfig.cpp index 90b2729390..d885ec3d60 100644 --- a/es-core/src/InputConfig.cpp +++ b/es-core/src/InputConfig.cpp @@ -148,6 +148,7 @@ std::vector InputConfig::getMappedTo(Input input) void InputConfig::loadFromXML(pugi::xml_node node) { + LOG(LogDebug) << "InputConfig::loadFromXML()"; clear(); for(pugi::xml_node input = node.child("input"); input; input = input.next_sibling("input")) @@ -169,6 +170,7 @@ void InputConfig::loadFromXML(pugi::xml_node node) LOG(LogWarning) << "WARNING: InputConfig value is 0 for " << type << " " << id << "!\n"; mNameMap[toLower(name)] = Input(mDeviceId, typeEnum, id, value, true); + LOG(LogDebug) << " mDeviceID = "<< mDeviceId <<", TypeEnum = " << typeEnum << ", id = " << id << ", value = " << value ; } } diff --git a/es-core/src/InputManager.cpp b/es-core/src/InputManager.cpp index 610b2d0d2d..f6d8d7b184 100644 --- a/es-core/src/InputManager.cpp +++ b/es-core/src/InputManager.cpp @@ -243,6 +243,7 @@ bool InputManager::parseEvent(const SDL_Event& ev, Window* window) bool InputManager::loadInputConfig(InputConfig* config) { + LOG(LogDebug) << "InputManager::loadInputConfig() "; std::string path = getConfigPath(); if(!fs::exists(path)) return false; @@ -265,7 +266,8 @@ bool InputManager::loadInputConfig(InputConfig* config) configNode = root.find_child_by_attribute("inputConfig", "deviceName", config->getDeviceName().c_str()); if(!configNode) return false; - + + LOG(LogDebug) << " Trying to load: " << configNode; config->loadFromXML(configNode); return true; } @@ -274,6 +276,8 @@ bool InputManager::loadInputConfig(InputConfig* config) //allows the user to select to reconfigure in menus if this happens without having to delete es_input.cfg manually void InputManager::loadDefaultKBConfig() { + LOG(LogDebug) << "InputManager::loadDefaultKBConfig() "; + InputConfig* cfg = getInputConfigByDevice(DEVICE_KEYBOARD); cfg->clear(); @@ -286,11 +290,12 @@ void InputManager::loadDefaultKBConfig() cfg->mapInput("b", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_ESCAPE, 1, true)); cfg->mapInput("start", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_F1, 1, true)); cfg->mapInput("select", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_F2, 1, true)); + cfg->mapInput("x", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_x, 1, true)); + cfg->mapInput("y", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_y, 1, true)); cfg->mapInput("pageup", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_RIGHTBRACKET, 1, true)); cfg->mapInput("pagedown", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_LEFTBRACKET, 1, true)); } - void InputManager::writeDeviceConfig(InputConfig* config) { assert(initialized()); diff --git a/es-core/src/Settings.cpp b/es-core/src/Settings.cpp index e0523c420c..e867a55e84 100644 --- a/es-core/src/Settings.cpp +++ b/es-core/src/Settings.cpp @@ -76,6 +76,10 @@ void Settings::setDefaults() mStringMap["ThemeSet"] = ""; mStringMap["ScreenSaverBehavior"] = "dim"; mStringMap["Scraper"] = "TheGamesDB"; + mStringMap["UIMode"] = "Full"; + + //mStringMap["UIMode_passkey"] = "↑↑↓↓←→←→ba"; + mStringMap["UIMode_passkey"] = "uuddlrlrba"; } template diff --git a/es-core/src/ThemeData.cpp b/es-core/src/ThemeData.cpp index b67bb62dd8..1a9427b007 100644 --- a/es-core/src/ThemeData.cpp +++ b/es-core/src/ThemeData.cpp @@ -530,3 +530,8 @@ bool ThemeData::getHasFavoritesInTheme() { return (mVersion >= CURRENT_THEME_FORMAT_VERSION); } + +bool ThemeData::getHasKidGamesInTheme() +{ + return (mVersion >= CURRENT_THEME_FORMAT_VERSION); +} \ No newline at end of file diff --git a/es-core/src/ThemeData.h b/es-core/src/ThemeData.h index 1e1ee5f1e1..dd94387678 100644 --- a/es-core/src/ThemeData.h +++ b/es-core/src/ThemeData.h @@ -148,6 +148,7 @@ class ThemeData static boost::filesystem::path getThemeFromCurrentSet(const std::string& system); bool getHasFavoritesInTheme(); + bool getHasKidGamesInTheme(); private: static std::map< std::string, std::map > sElementMap; diff --git a/es-core/src/Util.cpp b/es-core/src/Util.cpp index 8d88104252..e7bbaaca62 100644 --- a/es-core/src/Util.cpp +++ b/es-core/src/Util.cpp @@ -2,6 +2,9 @@ #include "resources/ResourceManager.h" #include "platform.h" + +#include + namespace fs = boost::filesystem; std::string strToUpper(const char* from) @@ -25,7 +28,6 @@ std::string strToUpper(const std::string& str) return strToUpper(str.c_str()); } - #if defined(_WIN32) && _MSC_VER < 1800 float round(float num) { @@ -33,6 +35,15 @@ float round(float num) } #endif +#if _MSC_VER >= 1700 +FILE iob[] = {*stdin, *stdout, *stderr }; +FILE * __iob_func(void) +{ + return iob; +} +#endif +#endif + Eigen::Affine3f& roundMatrix(Eigen::Affine3f& mat) { mat.translation()[0] = round(mat.translation()[0]); diff --git a/es-core/src/Window.cpp b/es-core/src/Window.cpp index e402162c3d..7e7a598532 100644 --- a/es-core/src/Window.cpp +++ b/es-core/src/Window.cpp @@ -8,12 +8,15 @@ #include #include "components/HelpComponent.h" #include "components/ImageComponent.h" +#include "platform.h" + Window::Window() : mNormalizeNextUpdate(false), mFrameTimeElapsed(0), mFrameCountElapsed(0), mAverageDeltaTime(10), mAllowSleep(true), mSleeping(false), mTimeSinceLastInput(0) { mHelp = new HelpComponent(this); mBackgroundOverlay = new ImageComponent(this); + mPasskeyCounter = 0; } Window::~Window() @@ -134,6 +137,8 @@ void Window::input(InputConfig* config, Input input) if(peekGui()) this->peekGui()->input(config, input); } + + ListenForPassKeySequence(config, input); } void Window::update(int deltaTime) @@ -356,3 +361,67 @@ void Window::renderScreenSaver() unsigned char opacity = Settings::getInstance()->getString("ScreenSaverBehavior") == "dim" ? 0xA0 : 0xFF; Renderer::drawRect(0, 0, Renderer::getScreenWidth(), Renderer::getScreenHeight(), 0x00000000 | opacity); } + +// This function reads the current input to listen for the passkey +// sequence to unlock the UI mode. +// the progress is saved in mPasskeyCounter +// supported inputs: +// ↑ = u, ↓ = d, ← = l, → = r, A, B, X, Y +// default passkeyseq = "↑↑↓↓←→←→ba"; +void Window::ListenForPassKeySequence(InputConfig* config, Input input) +{ + //LOG(LogDebug) << "Window::ListenForPassKeySequence(), mPasskeyCounter ="<< mPasskeyCounter; + std::string passkeyseq = Settings::getInstance()->getString("UIMode_passkey"); + + if(!input.value){ + return; // its an event, but prob the keyup/release: change nothing + } + + if(config->isMappedTo("down", input) && (passkeyseq[ mPasskeyCounter ] == 'd')) + { + ++mPasskeyCounter; + }else if(config->isMappedTo("up", input) && (passkeyseq[mPasskeyCounter] == 'u')) + { + ++mPasskeyCounter; + }else if(config->isMappedTo("left", input) && (passkeyseq[mPasskeyCounter] == 'l')) + { + ++mPasskeyCounter; + }else if(config->isMappedTo("right", input) && (passkeyseq[mPasskeyCounter] == 'r')) + { + ++mPasskeyCounter; + }else if(config->isMappedTo("a", input) && (passkeyseq[mPasskeyCounter] == 'a')) + { + ++mPasskeyCounter; + }else if(config->isMappedTo("b", input) && (passkeyseq[mPasskeyCounter] == 'b')) + { + ++mPasskeyCounter; + }else if(config->isMappedTo("x", input) && (passkeyseq[mPasskeyCounter] == 'x')) + { + ++mPasskeyCounter; + }else if(config->isMappedTo("y", input) && (passkeyseq[mPasskeyCounter] == 'y')) + { + ++mPasskeyCounter; + }else + { + mPasskeyCounter = 0; // current input is incorrect, reset counter + } + + if (mPasskeyCounter >= (passkeyseq.length())) + { + // When we have reached the end of the list, trigger UI_mode unlock + LOG(LogDebug) << "Window::ListenForPassKeySequence(): Passkey sequence completed, switching UIMode to full"; + Settings::getInstance()->setString("UIMode", "Full"); + Settings::getInstance()->saveFile(); + //mRestartNeeded = true; + mPasskeyCounter = 0; + while (true) + { + if(Settings::getInstance()->getString("UIMode") == "Full") + break; + } + + if(quitES("/tmp/es-restart") != 0) + LOG(LogWarning) << "Restart terminated with non-zero result!"; + + } +} diff --git a/es-core/src/Window.h b/es-core/src/Window.h index 5eee873a2c..ac20a1de3d 100644 --- a/es-core/src/Window.h +++ b/es-core/src/Window.h @@ -65,4 +65,8 @@ class Window unsigned int mTimeSinceLastInput; bool mRenderedHelpPrompts; + + void ListenForPassKeySequence(InputConfig* config, Input input); + int mPasskeyCounter; + bool mRestartNeeded; }; diff --git a/es-core/src/components/ComponentList.cpp b/es-core/src/components/ComponentList.cpp index a16bcb0975..1a69b60e54 100644 --- a/es-core/src/components/ComponentList.cpp +++ b/es-core/src/components/ComponentList.cpp @@ -107,6 +107,7 @@ void ComponentList::onCursorChanged(const CursorState& state) { // update the selector bar position // in the future this might be animated + mSelectorBarOffset = 0; for(int i = 0; i < mCursor; i++) { diff --git a/es-core/src/components/IList.h b/es-core/src/components/IList.h index ede3360a9d..7d860aecc1 100644 --- a/es-core/src/components/IList.h +++ b/es-core/src/components/IList.h @@ -7,6 +7,7 @@ #include "components/ImageComponent.h" #include "resources/Font.h" #include "Renderer.h" +#include "Log.h" enum CursorState { diff --git a/es-core/src/components/ImageComponent.cpp b/es-core/src/components/ImageComponent.cpp index 0705e0c28f..885cba5b05 100644 --- a/es-core/src/components/ImageComponent.cpp +++ b/es-core/src/components/ImageComponent.cpp @@ -22,8 +22,9 @@ Eigen::Vector2f ImageComponent::getCenter() const } ImageComponent::ImageComponent(Window* window, bool forceLoad, bool dynamic) : GuiComponent(window), - mTargetIsMax(false), mFlipX(false), mFlipY(false), mOrigin(0.0, 0.0), mTargetSize(0, 0), mColorShift(0xFFFFFFFF), + mTargetIsMax(false), mFlipX(false), mFlipY(false), mVisible(true), mOrigin(0.0, 0.0), mTargetSize(0, 0), mColorShift(0xFFFFFFFF), mForceLoad(forceLoad), mDynamic(dynamic), mFadeOpacity(0.0f), mFading(false) + { updateColors(); } @@ -173,6 +174,18 @@ void ImageComponent::setOpacity(unsigned char opacity) updateColors(); } +void ImageComponent::setValue(std::string valuestr) // takes value = "true" or "false" +{ + if(valuestr == "true") + { + mVisible = true; + } else if (valuestr == "false") + { + mVisible = false; + } + return; +} + void ImageComponent::updateVertices() { if(!mTexture || !mTexture->isInitialized()) @@ -239,7 +252,7 @@ void ImageComponent::render(const Eigen::Affine3f& parentTrans) Eigen::Affine3f trans = roundMatrix(parentTrans * getTransform()); Renderer::setMatrix(trans); - if(mTexture && mOpacity > 0) + if(mTexture && mOpacity > 0 && mVisible) { if(mTexture->isInitialized()) { @@ -333,7 +346,7 @@ void ImageComponent::applyTheme(const std::shared_ptr& theme, const s { return; } - + Eigen::Vector2f scale = getParent() ? getParent()->getSize() : Eigen::Vector2f((float)Renderer::getScreenWidth(), (float)Renderer::getScreenHeight()); if(properties & POSITION && elem->has("pos")) diff --git a/es-core/src/components/ImageComponent.h b/es-core/src/components/ImageComponent.h index 3ff1ffbb27..98ae6db652 100644 --- a/es-core/src/components/ImageComponent.h +++ b/es-core/src/components/ImageComponent.h @@ -61,11 +61,13 @@ class ImageComponent : public GuiComponent virtual void applyTheme(const std::shared_ptr& theme, const std::string& view, const std::string& element, unsigned int properties) override; virtual std::vector getHelpPrompts() override; + + void setValue(std::string valuestr); // set the opacity via string values, takes value = "true" or "false" private: Eigen::Vector2f mTargetSize; Eigen::Vector2f mOrigin; - bool mFlipX, mFlipY, mTargetIsMax; + bool mFlipX, mFlipY, mTargetIsMax, mVisible; // Calculates the correct mSize from our resizing information (set by setResize/setMaxSize). // Used internally whenever the resizing parameters or texture change. @@ -86,10 +88,10 @@ class ImageComponent : public GuiComponent unsigned int mColorShift; std::shared_ptr mTexture; - unsigned char mFadeOpacity; - bool mFading; - bool mForceLoad; - bool mDynamic; + unsigned char mFadeOpacity; + bool mFading; + bool mForceLoad; + bool mDynamic; }; #endif diff --git a/es-core/src/components/OptionListComponent.h b/es-core/src/components/OptionListComponent.h index 40ff34ffff..e5e85d2acf 100644 --- a/es-core/src/components/OptionListComponent.h +++ b/es-core/src/components/OptionListComponent.h @@ -236,6 +236,7 @@ class OptionListComponent : public GuiComponent { assert(mMultiSelect == false); auto selected = getSelectedObjects(); + assert(selected.size() == 1); return selected.at(0); } diff --git a/es-core/src/components/SwitchComponent.cpp b/es-core/src/components/SwitchComponent.cpp index 07b425b259..b0bc4fdf78 100644 --- a/es-core/src/components/SwitchComponent.cpp +++ b/es-core/src/components/SwitchComponent.cpp @@ -3,6 +3,8 @@ #include "resources/Font.h" #include "Window.h" +#include "Log.h" + SwitchComponent::SwitchComponent(Window* window, bool state) : GuiComponent(window), mImage(window), mState(state) { mImage.setImage(":/off.svg"); @@ -41,12 +43,30 @@ bool SwitchComponent::getState() const return mState; } +std::string SwitchComponent::getValue() const +{ + return mState ? "true" : "false"; +} + void SwitchComponent::setState(bool state) { mState = state; onStateChanged(); } +void SwitchComponent::setValue(const std::string& statestring) +{ + LOG(LogDebug) << "SwitchComponent::setValue(" << statestring << ")"; + if (statestring == "true") + { + mState = true; + }else + { + mState = false; + } + onStateChanged(); +} + void SwitchComponent::onStateChanged() { mImage.setImage(mState ? ":/on.svg" : ":/off.svg"); diff --git a/es-core/src/components/SwitchComponent.h b/es-core/src/components/SwitchComponent.h index e173762a74..87efed9369 100644 --- a/es-core/src/components/SwitchComponent.h +++ b/es-core/src/components/SwitchComponent.h @@ -15,11 +15,12 @@ class SwitchComponent : public GuiComponent void onSizeChanged() override; bool getState() const; + std::string getValue() const; void setState(bool state); + void setValue(const std::string& statestring) override; virtual std::vector getHelpPrompts() override; - -private: + private: void onStateChanged(); ImageComponent mImage; diff --git a/es-core/src/platform.cpp b/es-core/src/platform.cpp index 04d02b98f6..ff2606eeda 100644 --- a/es-core/src/platform.cpp +++ b/es-core/src/platform.cpp @@ -5,10 +5,18 @@ #include #include -#ifdef WIN32 +#if defined(WIN32) #include +#include +#include +#include +#elif defined(__linux__) +#include +#include #endif + + std::string getHomePath() { std::string homePath; From 77953414849bbe5d1637f6c00cbd2bbba309eaca Mon Sep 17 00:00:00 2001 From: Matthew Nohr Date: Mon, 26 Sep 2016 03:48:20 -0500 Subject: [PATCH 73/74] Add ability to show/hide hidden games in Full mode (#33) * Add ability to show/hide hidden games in all modes * Updates from PR comments --- es-app/src/FileData.cpp | 22 ++++---- es-app/src/guis/GuiGamelistOptions.cpp | 69 ++++++++++++++++++++------ es-app/src/guis/GuiGamelistOptions.h | 9 ++-- 3 files changed, 69 insertions(+), 31 deletions(-) diff --git a/es-app/src/FileData.cpp b/es-app/src/FileData.cpp index c3174307f5..566a8009af 100644 --- a/es-app/src/FileData.cpp +++ b/es-app/src/FileData.cpp @@ -93,12 +93,12 @@ std::vector FileData::getChildren(bool filter) const if (filter) { //filter out unwanted items from mChildren - bool filterHidden = (Settings::getInstance()->getString("UIMode") != "Full"); + bool filterHidden = (Settings::getInstance()->getString("UIMode") != "Full") || !(Settings::getInstance()->getBool("ShowHidden")); bool filterFav = (Settings::getInstance()->getBool("FavoritesOnly")); bool filterKid = (Settings::getInstance()->getString("UIMode") == "Kid"); - + LOG(LogDebug) << " filtering (" << filterHidden << filterFav << filterKid << ")."; - + // then filter out all we do not want. if (filterHidden) { fileList = filterFileData(fileList, "hidden", "false"); @@ -150,22 +150,22 @@ std::vector FileData::getFilesRecursive(unsigned int typeMask, bool f // first populate with all we can find std::vector allfiles = getChildren(filter); std::vector fileList; - + //LOG(LogDebug) << "FileData::getFilesRecursive(): allfiles contains " << allfiles.size() << " items"; - for(auto it = allfiles.begin(); it != allfiles.end(); it++) + for(auto it = allfiles.begin(); it != allfiles.end(); it++) { if((*it)->getType() & typeMask) { fileList.push_back(*it); } - + if((*it)->getChildren(filter).size() > 1) { //LOG(LogDebug) << "FileData::getFilesRecursive(): Recursing!"; std::vector subchildren = (*it)->getFilesRecursive(typeMask, filter); fileList.insert(fileList.end(), subchildren.cbegin(), subchildren.cend()); } } - + LOG(LogDebug) << "FileData::getFilesRecursive():returning " << fileList.size() << " games"; return fileList; @@ -243,12 +243,12 @@ void FileData::sort(const SortType& type) FileData* FileData::getRandom() const { LOG(LogDebug) << "FileData::getRandom()"; - + //Get list of files std::vector list = getFilesRecursive(GAME,true); // always filter const unsigned long n = list.size(); LOG(LogDebug) << " found games: " << n; - + //Select random system //const unsigned long divisor = (RAND_MAX + 1) / n; const unsigned long divisor = (RAND_MAX) / n; // the above is correct, but gives compiler warning. @@ -256,7 +256,7 @@ FileData* FileData::getRandom() const do { k = std::rand() / divisor; } while (k >= n); // pick the first within range - + LOG(LogDebug) << " Picked game: " << list.at(k)->getName(); - return list.at(k); + return list.at(k); } diff --git a/es-app/src/guis/GuiGamelistOptions.cpp b/es-app/src/guis/GuiGamelistOptions.cpp index b778edd5e2..78ad7f8c70 100644 --- a/es-app/src/guis/GuiGamelistOptions.cpp +++ b/es-app/src/guis/GuiGamelistOptions.cpp @@ -9,8 +9,8 @@ #include "SystemData.h" #include "FileData.h" -GuiGamelistOptions::GuiGamelistOptions(Window* window, SystemData* system) : GuiComponent(window), - mSystem(system), +GuiGamelistOptions::GuiGamelistOptions(Window* window, SystemData* system) : GuiComponent(window), + mSystem(system), mMenu(window, "OPTIONS") { LOG(LogDebug) << "GUIGamelistOptions::GuiGamelistOptions()"; @@ -53,7 +53,7 @@ GuiGamelistOptions::GuiGamelistOptions(Window* window, SystemData* system) : Gui return false; }; mMenu.addRow(row); - + // sort list by mListSort = std::make_shared(mWindow, "SORT GAMES BY", false); for(unsigned int i = 0; i < FileSorts::SortTypes.size(); i++) @@ -63,13 +63,13 @@ GuiGamelistOptions::GuiGamelistOptions(Window* window, SystemData* system) : Gui } mMenu.addWithLabel("SORT GAMES BY", mListSort); - + // Toggle: Show favorites-only auto favorite_only = std::make_shared(mWindow); favorite_only->setState(Settings::getInstance()->getBool("FavoritesOnly")); mMenu.addWithLabel("FAVORITES ONLY", favorite_only); addSaveFunc([favorite_only, this] { - + // First save to settings, in order for filtering to work if (favorite_only->getState() != Settings::getInstance()->getBool("FavoritesOnly")) { @@ -89,12 +89,44 @@ GuiGamelistOptions::GuiGamelistOptions(Window* window, SystemData* system) : Gui if(!hasFavorite) { LOG(LogDebug) << "Nothing to show in selected favorites mode, resetting"; - favorite_only->setState(false); + favorite_only->setState(false); Settings::getInstance()->setBool("FavoritesOnly", favorite_only->getState()); } } }); - + + // Toggle: Show hidden + if(Settings::getInstance()->getString("UIMode") == "Full") + { + auto show_hidden = std::make_shared(mWindow); + show_hidden->setState(Settings::getInstance()->getBool("ShowHidden")); + mMenu.addWithLabel("SHOW HIDDEN", show_hidden); + addSaveFunc([show_hidden, this] { + // First save to settings, in order for filtering to work + if(show_hidden->getState() != Settings::getInstance()->getBool("ShowHidden")) + { + Settings::getInstance()->setBool("ShowHidden", show_hidden->getState()); + mHiddenStateChanged = true; + } + if(!show_hidden->getState()) + { + bool hasNonHidden = false; + for(auto it = SystemData::sSystemVector.begin(); it != SystemData::sSystemVector.end(); it++) { + if( (*it)->getGameCount(true) > 0 ) { + hasNonHidden = true; + break; + } + } + if(!hasNonHidden) + { + LOG(LogDebug) << "Nothing to show in selected show hidden mode, resetting"; + show_hidden->setState(true); + Settings::getInstance()->setBool("ShowHidden", show_hidden->getState()); + } + } + }); + } + // edit game metadata - only in Full UI mode if(Settings::getInstance()->getString("UIMode") == "Full") { @@ -116,13 +148,18 @@ GuiGamelistOptions::~GuiGamelistOptions() // apply sort FileData* root = getGamelist()->getCursor()->getSystem()->getRootFolder(); root->sort(*mListSort->getSelected()); // will also recursively sort children - + // notify that the root folder was sorted - - getGamelist()->onFileChanged(root, FILE_SORTED); - if (mFavoriteStateChanged) + + getGamelist()->onFileChanged(root, FILE_SORTED); + if (mFavoriteStateChanged || mHiddenStateChanged) { - LOG(LogDebug) << " GUIGamelistOptions::~GuiGamelistOptions(): FavoriteStateChanged, reloading GameList"; + if (mFavoriteStateChanged) { + LOG(LogDebug) << " GUIGamelistOptions::~GuiGamelistOptions(): FavoriteStateChanged, reloading GameList"; + } + if (mHiddenStateChanged) { + LOG(LogDebug) << " GUIGamelistOptions::~GuiGamelistOptions(): HiddenStateChanged, reloading GameList"; + } ViewController::get()->setAllInvalidGamesList(getGamelist()->getCursor()->getSystem()); //ViewController::get()->reloadGameListView(getGamelist()->getCursor()->getSystem()); ViewController::get()->reloadAll(); @@ -136,8 +173,8 @@ void GuiGamelistOptions::openMetaDataEd() ScraperSearchParams p; p.game = file; p.system = file->getSystem(); - mWindow->pushGui(new GuiMetaDataEd(mWindow, &file->metadata, file->metadata.getMDD(), p, file->getPath().filename().string(), - std::bind(&IGameListView::onFileChanged, getGamelist(), file, FILE_METADATA_CHANGED), [this, file] { + mWindow->pushGui(new GuiMetaDataEd(mWindow, &file->metadata, file->metadata.getMDD(), p, file->getPath().filename().string(), + std::bind(&IGameListView::onFileChanged, getGamelist(), file, FILE_METADATA_CHANGED), [this, file] { getGamelist()->remove(file); })); } @@ -149,7 +186,7 @@ void GuiGamelistOptions::jumpToLetter() // this is a really shitty way to get a list of files const std::vector& files = gamelist->getCursor()->getParent()->getChildren(true); - + long min = 0; long max = files.size() - 1; long mid = 0; @@ -183,7 +220,7 @@ bool GuiGamelistOptions::input(InputConfig* config, Input input) { save(); delete this; - return true; + return true; } return mMenu.input(config, input); diff --git a/es-app/src/guis/GuiGamelistOptions.h b/es-app/src/guis/GuiGamelistOptions.h index 3abba851d4..1746aadeee 100644 --- a/es-app/src/guis/GuiGamelistOptions.h +++ b/es-app/src/guis/GuiGamelistOptions.h @@ -22,24 +22,25 @@ class GuiGamelistOptions : public GuiComponent void openMetaDataEd(); void jumpToLetter(); void SurpriseMe(); - - + + MenuComponent mMenu; std::vector< std::function > mSaveFuncs; typedef OptionListComponent LetterList; std::shared_ptr mJumpToLetterList; - + typedef OptionListComponent SortList; std::shared_ptr mListSort; std::shared_ptr mFavoriteOption; bool mFavoriteStateChanged; + bool mHiddenStateChanged; typedef OptionListComponent SurpriseEnums; std::shared_ptr mSurpriseModes; - + SystemData* mSystem; IGameListView* getGamelist(); }; From 8835a56f0b80526043c4bece2003123533198108 Mon Sep 17 00:00:00 2001 From: "D. Polders" Date: Mon, 26 Sep 2016 21:38:33 +0200 Subject: [PATCH 74/74] Support for favorite toggling and fallback mechanism when nothing is to shown in a filtered view. --- GAMELISTS.md | 1 - README.md | 4 +- THEMES.md | 2 +- es-app/src/FileData.cpp | 67 +---- es-app/src/FileData.h | 6 +- es-app/src/Gamelist.cpp | 6 +- es-app/src/MetaData.cpp | 8 +- es-app/src/ScraperCmdLine.cpp | 4 +- es-app/src/SystemData.cpp | 39 ++- es-app/src/SystemData.h | 10 +- es-app/src/components/TextListComponent.h | 2 - es-app/src/guis/GuiFastSelect.cpp | 1 + es-app/src/guis/GuiGamelistOptions.cpp | 121 +++------ es-app/src/guis/GuiGamelistOptions.h | 8 +- es-app/src/guis/GuiMenu.cpp | 146 +++++----- es-app/src/guis/GuiMetaDataEd.cpp | 6 - es-app/src/guis/GuiScraperStart.cpp | 11 +- es-app/src/main.cpp | 2 - es-app/src/views/SystemView.cpp | 41 ++- es-app/src/views/SystemView.h | 3 +- es-app/src/views/ViewController.cpp | 256 ++++++++---------- es-app/src/views/ViewController.h | 13 +- .../src/views/gamelist/BasicGameListView.cpp | 29 +- es-app/src/views/gamelist/BasicGameListView.h | 2 +- .../views/gamelist/DetailedGameListView.cpp | 5 +- .../src/views/gamelist/GridGameListView.cpp | 18 +- .../views/gamelist/ISimpleGameListView.cpp | 25 +- es-core/src/GuiComponent.cpp | 2 - es-core/src/InputConfig.cpp | 2 - es-core/src/InputManager.cpp | 6 +- es-core/src/Settings.cpp | 7 +- es-core/src/Util.cpp | 2 +- es-core/src/Window.h | 2 +- es-core/src/components/ComponentList.cpp | 1 - es-core/src/components/IList.h | 1 - es-core/src/components/OptionListComponent.h | 1 - es-core/src/components/SwitchComponent.cpp | 3 - 37 files changed, 345 insertions(+), 518 deletions(-) diff --git a/GAMELISTS.md b/GAMELISTS.md index 94bdbb168c..eec2a2533c 100644 --- a/GAMELISTS.md +++ b/GAMELISTS.md @@ -87,4 +87,3 @@ Things to be Aware Of * If at least one game in a system has an image specified, ES will use the detailed view for that system (which displays metadata alongside the game list). * If you want to write your own scraper, the built-in scraping system is actually pretty extendable if you can get past the ugly function declarations and your instinctual fear of C++. Check out `src/scrapers/GamesDBScraper.cpp` for an example (it's less than a hundred lines of actual code). An offline scraper is also possible (though you'll have to subclass `ScraperRequest`). I hope to write a more complete guide on how to do this in the future. - diff --git a/README.md b/README.md index 1113c6d03f..bad4d0492c 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -EmulationStation -================ +EmulationStation - KidMode UI +============================= A cross-platform graphical front-end for emulators with controller navigation. diff --git a/THEMES.md b/THEMES.md index 2fa44271a8..e3188733b7 100644 --- a/THEMES.md +++ b/THEMES.md @@ -313,7 +313,7 @@ Reference * `text name="md_lbl_players"` - ALL * `text name="md_lbl_lastplayed"` - ALL * `text name="md_lbl_playcount"` - ALL - * `text name="md_lbl_favorite"` - ALL + * `text name="md_lbl_favorite"` - ALL * Values * All values will follow to the right of their labels if a position isn't specified. diff --git a/es-app/src/FileData.cpp b/es-app/src/FileData.cpp index 566a8009af..791dbbb56c 100644 --- a/es-app/src/FileData.cpp +++ b/es-app/src/FileData.cpp @@ -77,41 +77,28 @@ std::string FileData::getCleanName() const const std::string& FileData::getThumbnailPath() const { - if(!metadata.get("thumbnail").empty()) { + if(!metadata.get("thumbnail").empty()) return metadata.get("thumbnail"); - } else { + else return metadata.get("image"); - } } std::vector FileData::getChildren(bool filter) const { - LOG(LogDebug) << "FileData::getChildren(" << filter << ")"; std::vector fileList = mChildren; - LOG(LogDebug) << " fileList.size() = " << fileList.size(); - - if (filter) + if (filter) //filter out unwanted items from mChildren { - //filter out unwanted items from mChildren - bool filterHidden = (Settings::getInstance()->getString("UIMode") != "Full") || !(Settings::getInstance()->getBool("ShowHidden")); - bool filterFav = (Settings::getInstance()->getBool("FavoritesOnly")); - bool filterKid = (Settings::getInstance()->getString("UIMode") == "Kid"); - - LOG(LogDebug) << " filtering (" << filterHidden << filterFav << filterKid << ")."; + bool filterHidden = Settings::getInstance()->getString("UIMode") != "Full"; + bool filterFav = Settings::getInstance()->getBool("FavoritesOnly"); + bool filterKid = Settings::getInstance()->getString("UIMode") == "Kid"; - // then filter out all we do not want. - if (filterHidden) { + if (filterHidden) fileList = filterFileData(fileList, "hidden", "false"); - } - if (filterFav) { + if (filterFav) fileList = filterFileData(fileList, "favorite", "true"); - } - if (filterKid) { + if (filterKid) fileList = filterFileData(fileList, "kidgame", "true"); - } - } - //LOG(LogDebug) << " returning " << fileList.size() << " files, done."; return fileList; } @@ -147,39 +134,31 @@ std::vector FileData::getFilesRecursive(unsigned int typeMask, bool f { LOG(LogDebug) << "FileData::getFilesRecursive(" << filter << ")"; - // first populate with all we can find std::vector allfiles = getChildren(filter); std::vector fileList; - //LOG(LogDebug) << "FileData::getFilesRecursive(): allfiles contains " << allfiles.size() << " items"; - for(auto it = allfiles.begin(); it != allfiles.end(); it++) { - if((*it)->getType() & typeMask) { + if((*it)->getType() & typeMask) fileList.push_back(*it); - } - if((*it)->getChildren(filter).size() > 1) { - //LOG(LogDebug) << "FileData::getFilesRecursive(): Recursing!"; + if(((*it)->getType() == FOLDER) && (*it)->getChildren(filter).size() > 1) { std::vector subchildren = (*it)->getFilesRecursive(typeMask, filter); fileList.insert(fileList.end(), subchildren.cbegin(), subchildren.cend()); } } - LOG(LogDebug) << "FileData::getFilesRecursive():returning " << fileList.size() << " games"; return fileList; } std::vector FileData::filterFileData(std::vector in, std::string filtername, std::string passString) const { - //LOG(LogDebug) << "FileData::filterFileData(" << filtername << ", needs to be: " << passString << ")"; - std::vector out; for (auto it = in.begin(); it != in.end(); it++) { - if ((*it)->metadata.get(filtername).compare(passString) == 0) + if (((*it)->getType() == FOLDER) || ((*it)->metadata.get(filtername).compare(passString) == 0)) { out.push_back(*it); } @@ -221,6 +200,7 @@ void FileData::removeChild(FileData* file) } +// This function recursively sorts the Filelist, based on the selected sort type void FileData::sort(ComparisonFunction& comparator, bool ascending) { std::sort(mChildren.begin(), mChildren.end(), comparator); @@ -239,24 +219,3 @@ void FileData::sort(const SortType& type) { sort(*type.comparisonFunction, type.ascending); } - -FileData* FileData::getRandom() const -{ - LOG(LogDebug) << "FileData::getRandom()"; - - //Get list of files - std::vector list = getFilesRecursive(GAME,true); // always filter - const unsigned long n = list.size(); - LOG(LogDebug) << " found games: " << n; - - //Select random system - //const unsigned long divisor = (RAND_MAX + 1) / n; - const unsigned long divisor = (RAND_MAX) / n; // the above is correct, but gives compiler warning. - unsigned long k; - do { - k = std::rand() / divisor; - } while (k >= n); // pick the first within range - - LOG(LogDebug) << " Picked game: " << list.at(k)->getName(); - return list.at(k); -} diff --git a/es-app/src/FileData.h b/es-app/src/FileData.h index 8637f2ee0f..0cd2cfbdc9 100644 --- a/es-app/src/FileData.h +++ b/es-app/src/FileData.h @@ -19,7 +19,8 @@ enum FileChangeType FILE_ADDED, FILE_METADATA_CHANGED, FILE_REMOVED, - FILE_SORTED + FILE_SORTED, + FILE_FILTERED }; // Used for loading/saving gamelist.xml. @@ -48,9 +49,8 @@ class FileData virtual const std::string& getMarqueePath() const; std::vector getChildren(bool filter = false) const; - std::vector getFilesRecursive(unsigned int typeMask, bool filter) const; + std::vector getFilesRecursive(unsigned int typeMask, bool filter = false) const; std::vector filterFileData(std::vector in, std::string filtername, std::string passString) const; - FileData* getRandom() const; void addChild(FileData* file); // Error if mType != FOLDER void removeChild(FileData* file); //Error if mType != FOLDER diff --git a/es-app/src/Gamelist.cpp b/es-app/src/Gamelist.cpp index 76b69cbdf5..45128c89a6 100644 --- a/es-app/src/Gamelist.cpp +++ b/es-app/src/Gamelist.cpp @@ -151,8 +151,7 @@ void addFileDataNode(pugi::xml_node& parent, const FileData* file, const char* t pugi::xml_node newNode = parent.append_child(tag); //write metadata - //file->metadata.appendToXML(newNode, true, system->getStartPath()); - file->metadata.appendToXML(newNode, false, system->getStartPath()); // set ignore defaults to false to force writing all values + file->metadata.appendToXML(newNode, true, system->getStartPath()); if(newNode.children().begin() == newNode.child("name") //first element is name && ++newNode.children().begin() == newNode.children().end() //theres only one element @@ -175,7 +174,6 @@ void updateGamelist(SystemData* system) //because there might be information missing in our systemdata which would then miss in the new XML. //We have the complete information for every game though, so we can simply remove a game //we already have in the system from the XML, and then add it back from its GameData information... - LOG(LogDebug) << "updateGamelist("<< system->getFullName() <<")"; if(Settings::getInstance()->getBool("IgnoreGamelist")) return; @@ -214,7 +212,7 @@ void updateGamelist(SystemData* system) int numUpdated = 0; //get only files, no folders - std::vector files = rootFolder->getFilesRecursive(GAME | FOLDER, false); + std::vector files = rootFolder->getFilesRecursive(GAME | FOLDER); //iterate through all files, checking if they're already in the XML for(std::vector::const_iterator fit = files.cbegin(); fit != files.cend(); ++fit) { diff --git a/es-app/src/MetaData.cpp b/es-app/src/MetaData.cpp index d19d89e4d5..0882e16023 100644 --- a/es-app/src/MetaData.cpp +++ b/es-app/src/MetaData.cpp @@ -28,10 +28,10 @@ MetaDataDecl gameDecls[] = { const std::vector gameMDD(gameDecls, gameDecls + sizeof(gameDecls) / sizeof(gameDecls[0])); MetaDataDecl folderDecls[] = { - {"name", MD_STRING, "", false}, - {"desc", MD_MULTILINE_STRING, "", false}, - {"image", MD_PATH, "", false}, - {"thumbnail", MD_PATH, "", false}, + {"name", MD_STRING, "", false}, + {"desc", MD_MULTILINE_STRING, "", false}, + {"image", MD_PATH, "", false}, + {"thumbnail", MD_PATH, "", false}, }; const std::vector folderMDD(folderDecls, folderDecls + sizeof(folderDecls) / sizeof(folderDecls[0])); diff --git a/es-app/src/ScraperCmdLine.cpp b/es-app/src/ScraperCmdLine.cpp index c13def46a4..f6f6952525 100644 --- a/es-app/src/ScraperCmdLine.cpp +++ b/es-app/src/ScraperCmdLine.cpp @@ -65,7 +65,7 @@ int run_scraper_cmdline() out << "Will scrape all platforms.\n"; for(auto i = SystemData::sSystemVector.begin(); i != SystemData::sSystemVector.end(); i++) { - out << " " << (*i)->getName() << " (" << (*i)->getGameCount(false) << " games)\n"; + out << " " << (*i)->getName() << " (" << (*i)->getGameCount() << " games)\n"; systems.push_back(*i); } @@ -83,7 +83,7 @@ int run_scraper_cmdline() else out << " "; - out << "\"" << (*i)->getName() << "\" (" << (*i)->getGameCount(false) << " games)\n"; + out << "\"" << (*i)->getName() << "\" (" << (*i)->getGameCount() << " games)\n"; } std::getline(std::cin, sys_name); diff --git a/es-app/src/SystemData.cpp b/es-app/src/SystemData.cpp index 102f36e376..a169cda246 100644 --- a/es-app/src/SystemData.cpp +++ b/es-app/src/SystemData.cpp @@ -14,6 +14,7 @@ #include "FileSorts.h" std::vector SystemData::sSystemVector; +std::vector SystemData::sFilteredSystemVector; namespace fs = boost::filesystem; @@ -450,29 +451,21 @@ void SystemData::loadTheme() } } -SystemData* SystemData::getRandom() const +// This function returns true when there is at least a single system with a valid item. +bool SystemData::isValidFilter() const { - LOG(LogDebug) << "SystemData::getRandom()"; - //Get list of systems with # games > 0, given the filters - std::vector validSystems; - for (auto it = sSystemVector.begin(); it != sSystemVector.end(); it++) { - if((*it)->getGameCount(true) > 0) { - validSystems.push_back(*it); + LOG(LogDebug) << "SystemData::isValidFilter()"; + bool found = false; + + for(auto it = sSystemVector.begin(); it != sSystemVector.end(); it++) { + if( (*it)->getGameCount(true) > 0 ) { + found = true; + LOG(LogDebug) << " Valid system found!"; + break; } } - - const unsigned long n = validSystems.size(); - LOG(LogDebug) << " Valid systems: " << n; - - //Select random system - //const unsigned long divisor = (RAND_MAX + 1) / n; - const unsigned long divisor = (RAND_MAX) / n; // the above is correct, but gives compiler warning. - unsigned long k; - do { - k = std::rand() / divisor; - } while (k >= n); // pick the first within range - - LOG(LogDebug) << " Picked system: " << validSystems.at(k)->getFullName(); - - return validSystems.at(k); -} + if (!found){ + LOG(LogDebug) << " No valid system found."; + } + return found; +} \ No newline at end of file diff --git a/es-app/src/SystemData.h b/es-app/src/SystemData.h index 9710bbae8f..4bd5e0ee26 100644 --- a/es-app/src/SystemData.h +++ b/es-app/src/SystemData.h @@ -32,9 +32,12 @@ class SystemData std::string getGamelistPath(bool forWrite) const; bool hasGamelist() const; + + bool isValidFilter() const; // Checks if the current filter setting has any system with valid items left. + std::string getThemePath() const; - unsigned int getGameCount(bool filter) const; + unsigned int getGameCount(bool filter = false) const; void launchGame(Window* window, FileData* game); @@ -43,7 +46,8 @@ class SystemData static void writeExampleConfig(const std::string& path); static std::string getConfigPath(bool forWrite); // if forWrite, will only return ~/.emulationstation/es_systems.cfg, never /etc/emulationstation/es_systems.cfg - static std::vector sSystemVector; + static std::vector sSystemVector; // the complete set of systems + static std::vector sFilteredSystemVector; // the remaining set of systems, once filtered inline std::vector::const_iterator getIterator() const { return std::find(sSystemVector.begin(), sSystemVector.end(), this); }; inline std::vector::const_reverse_iterator getRevIterator() const { return std::find(sSystemVector.rbegin(), sSystemVector.rend(), this); }; @@ -64,8 +68,6 @@ class SystemData return *it; } - SystemData* getRandom() const; - // Load or re-load theme. void loadTheme(); diff --git a/es-app/src/components/TextListComponent.h b/es-app/src/components/TextListComponent.h index 4c3a9625c0..c490f0cb76 100644 --- a/es-app/src/components/TextListComponent.h +++ b/es-app/src/components/TextListComponent.h @@ -310,9 +310,7 @@ void TextListComponent::onCursorChanged(const CursorState& state) mMarqueeOffset = 0; mMarqueeTime = -MARQUEE_DELAY; if(mCursorChangedCallback) - { mCursorChangedCallback(state); - } } template diff --git a/es-app/src/guis/GuiFastSelect.cpp b/es-app/src/guis/GuiFastSelect.cpp index 9ed7e5bb48..9d0b48cd28 100644 --- a/es-app/src/guis/GuiFastSelect.cpp +++ b/es-app/src/guis/GuiFastSelect.cpp @@ -3,6 +3,7 @@ #include "FileSorts.h" #include "SystemData.h" + static const std::string LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; GuiFastSelect::GuiFastSelect(Window* window, IGameListView* gamelist) : GuiComponent(window), diff --git a/es-app/src/guis/GuiGamelistOptions.cpp b/es-app/src/guis/GuiGamelistOptions.cpp index 78ad7f8c70..13a5ceacda 100644 --- a/es-app/src/guis/GuiGamelistOptions.cpp +++ b/es-app/src/guis/GuiGamelistOptions.cpp @@ -13,7 +13,6 @@ GuiGamelistOptions::GuiGamelistOptions(Window* window, SystemData* system) : Gui mSystem(system), mMenu(window, "OPTIONS") { - LOG(LogDebug) << "GUIGamelistOptions::GuiGamelistOptions()"; addChild(&mMenu); // jump to letter @@ -42,86 +41,62 @@ GuiGamelistOptions::GuiGamelistOptions(Window* window, SystemData* system) : Gui }; mMenu.addRow(row); - row.elements.clear(); - row.addElement(std::make_shared(mWindow, "SURPRISE ME!", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true); - row.input_handler = [&](InputConfig* config, Input input) { - if(config->isMappedTo("a", input) && input.value) - { - SurpriseMe(); - return true; - } - return false; - }; - mMenu.addRow(row); - // sort list by - mListSort = std::make_shared(mWindow, "SORT GAMES BY", false); + std::shared_ptr list_sorts = std::make_shared(mWindow, "SORT GAMES BY", false); for(unsigned int i = 0; i < FileSorts::SortTypes.size(); i++) { const FileData::SortType& sort = FileSorts::SortTypes.at(i); - mListSort->add(sort.description, &sort, i == 0); // TODO - actually make the sort type persistent + list_sorts->add(sort.description, &sort, Settings::getInstance()->getString("SortMode") == sort.description); } - mMenu.addWithLabel("SORT GAMES BY", mListSort); - + mMenu.addWithLabel("SORT GAMES BY", list_sorts); + addSaveFunc([list_sorts, this]{ + if (list_sorts->getSelected()->description != Settings::getInstance()->getString("SortMode")) + { + Settings::getInstance()->setString("SortMode", list_sorts->getSelected()->description); + FileData* root = getGamelist()->getCursor()->getSystem()->getRootFolder(); + root->sort(*list_sorts->getSelected()); + getGamelist()->onFileChanged(root, FILE_SORTED); // notify that the root folder was sorted + } + }); + // Toggle: Show favorites-only auto favorite_only = std::make_shared(mWindow); favorite_only->setState(Settings::getInstance()->getBool("FavoritesOnly")); mMenu.addWithLabel("FAVORITES ONLY", favorite_only); addSaveFunc([favorite_only, this] { - - // First save to settings, in order for filtering to work if (favorite_only->getState() != Settings::getInstance()->getBool("FavoritesOnly")) { - Settings::getInstance()->setBool("FavoritesOnly", favorite_only->getState()); - mFavoriteStateChanged = true; - } - if(favorite_only->getState()) - { - bool hasFavorite = false; - // check if there is anything at all to show, otherwise revert - for(auto it = SystemData::sSystemVector.begin(); it != SystemData::sSystemVector.end(); it++) { - if( (*it)->getGameCount(true) > 0 ) { - hasFavorite = true; - break; - } - } - if(!hasFavorite) + Settings::getInstance()->setBool("FavoritesOnly", favorite_only->getState()); // First save to settings, in order for filtering to work + if(! mSystem->isValidFilter()) // then check if there is anything at all to show in any system + { + LOG(LogDebug) << "Nothing to show in selected favorites mode, resetting"; // if not, then revert chenge. + Settings::getInstance()->setBool("FavoritesOnly", false); + } else { - LOG(LogDebug) << "Nothing to show in selected favorites mode, resetting"; - favorite_only->setState(false); - Settings::getInstance()->setBool("FavoritesOnly", favorite_only->getState()); + mViewStateChanged = true; } } }); - // Toggle: Show hidden + // Toggle: Show hidden, only in Full UI mode if(Settings::getInstance()->getString("UIMode") == "Full") { auto show_hidden = std::make_shared(mWindow); show_hidden->setState(Settings::getInstance()->getBool("ShowHidden")); mMenu.addWithLabel("SHOW HIDDEN", show_hidden); addSaveFunc([show_hidden, this] { - // First save to settings, in order for filtering to work + if(show_hidden->getState() != Settings::getInstance()->getBool("ShowHidden")) { - Settings::getInstance()->setBool("ShowHidden", show_hidden->getState()); - mHiddenStateChanged = true; - } - if(!show_hidden->getState()) - { - bool hasNonHidden = false; - for(auto it = SystemData::sSystemVector.begin(); it != SystemData::sSystemVector.end(); it++) { - if( (*it)->getGameCount(true) > 0 ) { - hasNonHidden = true; - break; - } - } - if(!hasNonHidden) + Settings::getInstance()->setBool("ShowHidden", show_hidden->getState()); // First save to settings, in order for filtering to work + if (!mSystem->isValidFilter()) // then check if there is anything at all to show in any system + { + LOG(LogDebug) << "Nothing to show when not showing hidden files, resetting"; // if not, then revert change. + Settings::getInstance()->setBool("ShowHidden", true); + } else { - LOG(LogDebug) << "Nothing to show in selected show hidden mode, resetting"; - show_hidden->setState(true); - Settings::getInstance()->setBool("ShowHidden", show_hidden->getState()); + mViewStateChanged = true; } } }); @@ -145,24 +120,20 @@ GuiGamelistOptions::GuiGamelistOptions(Window* window, SystemData* system) : Gui GuiGamelistOptions::~GuiGamelistOptions() { LOG(LogDebug) << "GUIGamelistOptions::~GuiGamelistOptions()"; - // apply sort - FileData* root = getGamelist()->getCursor()->getSystem()->getRootFolder(); - root->sort(*mListSort->getSelected()); // will also recursively sort children + if (mViewStateChanged) + refreshView(); - // notify that the root folder was sorted +} - getGamelist()->onFileChanged(root, FILE_SORTED); - if (mFavoriteStateChanged || mHiddenStateChanged) - { - if (mFavoriteStateChanged) { - LOG(LogDebug) << " GUIGamelistOptions::~GuiGamelistOptions(): FavoriteStateChanged, reloading GameList"; - } - if (mHiddenStateChanged) { - LOG(LogDebug) << " GUIGamelistOptions::~GuiGamelistOptions(): HiddenStateChanged, reloading GameList"; - } - ViewController::get()->setAllInvalidGamesList(getGamelist()->getCursor()->getSystem()); - //ViewController::get()->reloadGameListView(getGamelist()->getCursor()->getSystem()); - ViewController::get()->reloadAll(); +void GuiGamelistOptions::refreshView() +{ + LOG(LogDebug) << " Updating filter mode, or edited metadata, notifying ViewController"; + FileData* root = mSystem->getRootFolder(); + ViewController::get()->onFileChanged(root, FILE_FILTERED); + + if (mSystem->getGameCount(true) == 0) { //still, the current gamelist might be empty, so lets check and otherwise revert + LOG(LogDebug) << " Whoops, nothing to see here, returning to start."; + ViewController::get()->goToStart(); } } @@ -177,6 +148,9 @@ void GuiGamelistOptions::openMetaDataEd() std::bind(&IGameListView::onFileChanged, getGamelist(), file, FILE_METADATA_CHANGED), [this, file] { getGamelist()->remove(file); })); + + //This might be too costly, but is a failsave way to trigger a game-list refresh. + mViewStateChanged = true; } void GuiGamelistOptions::jumpToLetter() @@ -248,10 +222,3 @@ void GuiGamelistOptions::save() Settings::getInstance()->saveFile(); } - -void GuiGamelistOptions::SurpriseMe() -{ - LOG(LogDebug) << "GuiGamelistOptions::SurpriseMe()"; - ViewController::get()->goToRandomGame(); - delete this; -} diff --git a/es-app/src/guis/GuiGamelistOptions.h b/es-app/src/guis/GuiGamelistOptions.h index 1746aadeee..d7e0c4dbba 100644 --- a/es-app/src/guis/GuiGamelistOptions.h +++ b/es-app/src/guis/GuiGamelistOptions.h @@ -21,8 +21,7 @@ class GuiGamelistOptions : public GuiComponent private: void openMetaDataEd(); void jumpToLetter(); - void SurpriseMe(); - + void refreshView(); MenuComponent mMenu; @@ -35,11 +34,8 @@ class GuiGamelistOptions : public GuiComponent std::shared_ptr mListSort; std::shared_ptr mFavoriteOption; - bool mFavoriteStateChanged; - bool mHiddenStateChanged; - typedef OptionListComponent SurpriseEnums; - std::shared_ptr mSurpriseModes; + bool mViewStateChanged; SystemData* mSystem; IGameListView* getGamelist(); diff --git a/es-app/src/guis/GuiMenu.cpp b/es-app/src/guis/GuiMenu.cpp index bc1420afe7..d50513f0f4 100644 --- a/es-app/src/guis/GuiMenu.cpp +++ b/es-app/src/guis/GuiMenu.cpp @@ -90,10 +90,10 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MEN mWindow->pushGui(s); }); - if(Settings::getInstance()->getString("UIMode") == "Full") + if (Settings::getInstance()->getString("UIMode") == "Full") { addEntry("UI SETTINGS", 0x777777FF, true, - [this] { + [this] { auto s = new GuiSettings(mWindow, "UI SETTINGS"); auto UImodeSelection = std::make_shared< OptionListComponent >(mWindow, "UI MODE", false); @@ -101,43 +101,34 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MEN UImodes.push_back("Full"); UImodes.push_back("Kiosk"); UImodes.push_back("Kid"); - for(auto it = UImodes.begin(); it != UImodes.end(); it++) + for (auto it = UImodes.begin(); it != UImodes.end(); it++) UImodeSelection->add(*it, *it, Settings::getInstance()->getString("UIMode") == *it); s->addWithLabel("UI MODE", UImodeSelection); Window* window = mWindow; - s->addSaveFunc([UImodeSelection, window] + s->addSaveFunc([UImodeSelection, window] { LOG(LogDebug) << "Changing UI mode to" << UImodeSelection->getSelected(); bool needReload = false; - if(Settings::getInstance()->getString("UIMode") != UImodeSelection->getSelected()) + if (Settings::getInstance()->getString("UIMode") != UImodeSelection->getSelected()) { needReload = true; - + // First write to settings, in order for filtering to work Settings::getInstance()->setString("UIMode", UImodeSelection->getSelected()); Settings::getInstance()->setBool("FavoritesOnly", false); // reset favoritesOnly option upon mode change LOG(LogDebug) << "Checking if the proposed UI mode has anything at all to show:"; - - bool hasContent = false; - for(auto it = SystemData::sSystemVector.begin(); it != SystemData::sSystemVector.end(); it++) { - LOG(LogDebug) << "System = " << (*it)->getName() << ", "<< (*it)->getGameCount(true) << " games found"; - if ((*it)->getGameCount(true) > 0) + if (!SystemData::sSystemVector.at(0)->isValidFilter()) // check if there is anything at all to show in any system, otherwise revert { - hasContent = true; - break; - } - } - if (!hasContent) { LOG(LogDebug) << "Nothing to show in selected mode (" << UImodeSelection->getSelected() << "), resetting to full"; window->pushGui(new GuiMsgBox(window, "The selected view mode has nothing to show,\n returning to UI mode = FULL", - "OK", nullptr)); + "OK", nullptr)); Settings::getInstance()->setString("UIMode", "Full"); needReload = false; - } + } } - if(needReload) + if (needReload) { ViewController::get()->reloadAll(); ViewController::get()->goToStart(); @@ -155,7 +146,7 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MEN std::vector screensavers; screensavers.push_back("dim"); screensavers.push_back("black"); - for(auto it = screensavers.begin(); it != screensavers.end(); it++) + for (auto it = screensavers.begin(); it != screensavers.end(); it++) screensaver_behavior->add(*it, *it, Settings::getInstance()->getString("ScreenSaverBehavior") == *it); s->addWithLabel("SCREENSAVER TYPE", screensaver_behavior); s->addSaveFunc([screensaver_behavior] { Settings::getInstance()->setString("ScreenSaverBehavior", screensaver_behavior->getSelected()); }); @@ -183,7 +174,7 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MEN std::vector transitions; transitions.push_back("fade"); transitions.push_back("slide"); - for(auto it = transitions.begin(); it != transitions.end(); it++) + for (auto it = transitions.begin(); it != transitions.end(); it++) transition_style->add(*it, *it, Settings::getInstance()->getString("TransitionStyle") == *it); s->addWithLabel("TRANSITION STYLE", transition_style); s->addSaveFunc([transition_style] { Settings::getInstance()->setString("TransitionStyle", transition_style->getSelected()); }); @@ -191,52 +182,50 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MEN // theme set auto themeSets = ThemeData::getThemeSets(); - if(!themeSets.empty()) + if (!themeSets.empty()) { auto selectedSet = themeSets.find(Settings::getInstance()->getString("ThemeSet")); - if(selectedSet == themeSets.end()) + if (selectedSet == themeSets.end()) selectedSet = themeSets.begin(); auto theme_set = std::make_shared< OptionListComponent >(mWindow, "THEME SET", false); - for(auto it = themeSets.begin(); it != themeSets.end(); it++) + for (auto it = themeSets.begin(); it != themeSets.end(); it++) theme_set->add(it->first, it->first, it == selectedSet); s->addWithLabel("THEME SET", theme_set); Window* window = mWindow; - s->addSaveFunc([window, theme_set] + s->addSaveFunc([window, theme_set] { bool needReload = false; - if(Settings::getInstance()->getString("ThemeSet") != theme_set->getSelected()) + if (Settings::getInstance()->getString("ThemeSet") != theme_set->getSelected()) needReload = true; Settings::getInstance()->setString("ThemeSet", theme_set->getSelected()); - if(needReload) + if (needReload) ViewController::get()->reloadAll(); // TODO - replace this with some sort of signal-based implementation }); } mWindow->pushGui(s); }); - - if(Settings::getInstance()->getString("UIMode") == "Full") - { addEntry("OTHER SETTINGS", 0x777777FF, true, [this] { auto s = new GuiSettings(mWindow, "OTHER SETTINGS"); - // gamelists + // Save GameList.xml files when exiting ES auto save_gamelists = std::make_shared(mWindow); save_gamelists->setState(Settings::getInstance()->getBool("SaveGamelistsOnExit")); s->addWithLabel("SAVE METADATA ON EXIT", save_gamelists); s->addSaveFunc([save_gamelists] { Settings::getInstance()->setBool("SaveGamelistsOnExit", save_gamelists->getState()); }); + // Only read in GameList.xml files, skip file parsing. auto parse_gamelists = std::make_shared(mWindow); parse_gamelists->setState(Settings::getInstance()->getBool("ParseGamelistOnly")); s->addWithLabel("PARSE GAMESLISTS ONLY", parse_gamelists); s->addSaveFunc([parse_gamelists] { Settings::getInstance()->setBool("ParseGamelistOnly", parse_gamelists->getState()); }); - // maximum vram + // Set maximum VRAM auto max_vram = std::make_shared(mWindow, 0.f, 1000.f, 10.f, "Mb"); max_vram->setValue((float)(Settings::getInstance()->getInt("MaxVRAM"))); s->addWithLabel("VRAM LIMIT", max_vram); @@ -256,65 +245,66 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MEN }); } - addEntry("QUIT", 0x777777FF, true, + addEntry("QUIT", 0x777777FF, true, [this] { - auto s = new GuiSettings(mWindow, "QUIT"); - - Window* window = mWindow; + auto s = new GuiSettings(mWindow, "QUIT"); - ComponentListRow row; - row.makeAcceptInputHandler([window] { - window->pushGui(new GuiMsgBox(window, "REALLY RESTART?", "YES", + Window* window = mWindow; + + ComponentListRow row; + row.makeAcceptInputHandler([window] { + window->pushGui(new GuiMsgBox(window, "REALLY RESTART?", "YES", [] { - if(quitES("/tmp/es-restart") != 0) - LOG(LogWarning) << "Restart terminated with non-zero result!"; - }, "NO", nullptr)); - }); - row.addElement(std::make_shared(window, "RESTART EMULATIONSTATION", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true); - s->addRow(row); + if (quitES("/tmp/es-restart") != 0) + LOG(LogWarning) << "Restart terminated with non-zero result!"; + }, "NO", nullptr)); + }); + row.addElement(std::make_shared(window, "RESTART EMULATIONSTATION", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true); + s->addRow(row); - row.elements.clear(); - row.makeAcceptInputHandler([window] { - window->pushGui(new GuiMsgBox(window, "REALLY RESTART?", "YES", - [] { - if(quitES("/tmp/es-sysrestart") != 0) - LOG(LogWarning) << "Restart terminated with non-zero result!"; - }, "NO", nullptr)); - }); - row.addElement(std::make_shared(window, "RESTART SYSTEM", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true); - s->addRow(row); + row.elements.clear(); + row.makeAcceptInputHandler([window] { + window->pushGui(new GuiMsgBox(window, "REALLY RESTART?", "YES", + [] { + if (quitES("/tmp/es-sysrestart") != 0) + LOG(LogWarning) << "Restart terminated with non-zero result!"; + }, "NO", nullptr)); + }); + row.addElement(std::make_shared(window, "RESTART SYSTEM", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true); + s->addRow(row); + + row.elements.clear(); + row.makeAcceptInputHandler([window] { + window->pushGui(new GuiMsgBox(window, "REALLY SHUTDOWN?", "YES", + [] { + if (quitES("/tmp/es-shutdown") != 0) + LOG(LogWarning) << "Shutdown terminated with non-zero result!"; + }, "NO", nullptr)); + }); + row.addElement(std::make_shared(window, "SHUTDOWN SYSTEM", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true); + s->addRow(row); + if (Settings::getInstance()->getBool("ShowExit") && + ((Settings::getInstance()->getString("UIMode") == "Full") || + (Settings::getInstance()->getBool("Debug")))) + { row.elements.clear(); row.makeAcceptInputHandler([window] { - window->pushGui(new GuiMsgBox(window, "REALLY SHUTDOWN?", "YES", - [] { - if(quitES("/tmp/es-shutdown") != 0) - LOG(LogWarning) << "Shutdown terminated with non-zero result!"; + window->pushGui(new GuiMsgBox(window, "REALLY QUIT?", "YES", + [] { + SDL_Event ev; + ev.type = SDL_QUIT; + SDL_PushEvent(&ev); }, "NO", nullptr)); }); - row.addElement(std::make_shared(window, "SHUTDOWN SYSTEM", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true); + row.addElement(std::make_shared(window, "QUIT EMULATIONSTATION", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true); s->addRow(row); + } - if (Settings::getInstance()->getBool("ShowExit") && - ((Settings::getInstance()->getString("UIMode") == "Full") || - (Settings::getInstance()->getBool("Debug")))) - { - row.elements.clear(); - row.makeAcceptInputHandler([window] { - window->pushGui(new GuiMsgBox(window, "REALLY QUIT?", "YES", - [] { - SDL_Event ev; - ev.type = SDL_QUIT; - SDL_PushEvent(&ev); - }, "NO", nullptr)); - }); - row.addElement(std::make_shared(window, "QUIT EMULATIONSTATION", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true); - s->addRow(row); - } - - mWindow->pushGui(s); + mWindow->pushGui(s); }); + mVersion.setFont(Font::get(FONT_SIZE_SMALL)); mVersion.setColor(0xC6C6C6FF); mVersion.setText("EMULATIONSTATION V" + strToUpper(PROGRAM_VERSION_STRING)); diff --git a/es-app/src/guis/GuiMetaDataEd.cpp b/es-app/src/guis/GuiMetaDataEd.cpp index a2e011257b..2dafcb28c2 100644 --- a/es-app/src/guis/GuiMetaDataEd.cpp +++ b/es-app/src/guis/GuiMetaDataEd.cpp @@ -183,7 +183,6 @@ void GuiMetaDataEd::save() { if(mMetaDataDecl.at(i).isStatistic) continue; - //LOG(LogDebug) << i << ": Setting "<< mMetaDataDecl.at(i).key << " to be :" << mEditors.at(i)->getValue(); mMetaData->set(mMetaDataDecl.at(i).key, mEditors.at(i)->getValue()); } LOG(LogError) << "updating XML"; @@ -216,16 +215,12 @@ void GuiMetaDataEd::close(bool closeAllWindows) // find out if the user made any changes bool dirty = false; LOG(LogDebug) << "GuiMetaDataEd::close()"; - //LOG(LogDebug) << " checking metadata fields (size = "<get(key) != mEditors.at(i)->getValue()) { - //LOG(LogDebug) << "mEditors.at("<getValue(); - //LOG(LogDebug) << "mMetaData->get("<get(key); dirty = true; - LOG(LogDebug) << " dirty!"; break; } } @@ -252,7 +247,6 @@ void GuiMetaDataEd::close(bool closeAllWindows) "NO", closeFunc )); }else{ - LOG(LogDebug) << " no changes found, closing"; closeFunc(); } } diff --git a/es-app/src/guis/GuiScraperStart.cpp b/es-app/src/guis/GuiScraperStart.cpp index 2dc5b811c9..7d1ebab436 100644 --- a/es-app/src/guis/GuiScraperStart.cpp +++ b/es-app/src/guis/GuiScraperStart.cpp @@ -75,10 +75,13 @@ void GuiScraperStart::start() std::queue GuiScraperStart::getSearches(std::vector systems, GameFilterFunc selector) { std::queue queue; - for(auto sys = systems.begin(); sys != systems.end(); sys++) { - std::vector games = (*sys)->getRootFolder()->getFilesRecursive(GAME, false); - for(auto game = games.begin(); game != games.end(); game++) { - if(selector((*sys), (*game))) { + for(auto sys = systems.begin(); sys != systems.end(); sys++) + { + std::vector games = (*sys)->getRootFolder()->getFilesRecursive(GAME); + for(auto game = games.begin(); game != games.end(); game++) + { + if(selector((*sys), (*game))) + { ScraperSearchParams search; search.game = *game; search.system = *sys; diff --git a/es-app/src/main.cpp b/es-app/src/main.cpp index 8968932b92..c3d030ec4b 100644 --- a/es-app/src/main.cpp +++ b/es-app/src/main.cpp @@ -166,8 +166,6 @@ void onExit() int main(int argc, char* argv[]) { - srand(time(NULL)); - unsigned int width = 0; unsigned int height = 0; diff --git a/es-app/src/views/SystemView.cpp b/es-app/src/views/SystemView.cpp index b66d808f1c..b3faabcd09 100644 --- a/es-app/src/views/SystemView.cpp +++ b/es-app/src/views/SystemView.cpp @@ -23,23 +23,18 @@ SystemView::SystemView(Window* window) : IList(wind void SystemView::populate() { - LOG(LogDebug) << "SystemView::populate()"; - LOG(LogDebug) << " Settings.UIMode = " << Settings::getInstance()->getString("UIMode"); - LOG(LogDebug) << " Settings.FavoritesOnly = " << Settings::getInstance()->getBool("FavoritesOnly"); - mEntries.clear(); + for(auto it = SystemData::sSystemVector.begin(); it != SystemData::sSystemVector.end(); it++) { - LOG(LogDebug) << "System = " << (*it)->getName(); - - if ((*it)->getGameCount(true) > 0) { - LOG(LogDebug) << (*it)->getGameCount(true) << " games found, populating."; + if ((*it)->getGameCount(true) > 0) + { + const std::shared_ptr& theme = (*it)->getTheme(); + if (mViewNeedsReload) getViewElements(theme); - const std::shared_ptr& theme = (*it)->getTheme(); - Entry e; e.name = (*it)->getName(); e.object = *it; @@ -106,7 +101,6 @@ bool SystemView::input(InputConfig* config, Input input) { LOG(LogInfo) << " Reloading all"; ViewController::get()->reloadAll(); - return true; } @@ -197,11 +191,11 @@ void SystemView::onCursorChanged(const CursorState& state) mSystemInfo.setOpacity((unsigned char)(lerp(infoStartOpacity, 0.f, t) * 255)); }, (int)(infoStartOpacity * 150)); + unsigned int gameCount = getSelected()->getGameCount(true); + // also change the text after we've fully faded out - setAnimation(infoFadeOut, 0, [this] { - unsigned int gameCount = getSelected()->getGameCount(true); + setAnimation(infoFadeOut, 0, [this, gameCount] { std::stringstream ss; - if (getSelected()->getName() == "retropie") ss << "CONFIGURATION"; // only display a game count if there are at least 2 games @@ -211,15 +205,18 @@ void SystemView::onCursorChanged(const CursorState& state) mSystemInfo.setText(ss.str()); }, false, 1); - Animation* infoFadeIn = new LambdaAnimation( - [this](float t) + // only display a game count if there are at least 2 games + if(gameCount > 1) { - mSystemInfo.setOpacity((unsigned char)(lerp(0.f, 1.f, t) * 255)); - }, 300); - - // wait ms to fade in - setAnimation(infoFadeIn, 800, nullptr, false, 2); - + Animation* infoFadeIn = new LambdaAnimation( + [this](float t) + { + mSystemInfo.setOpacity((unsigned char)(lerp(0.f, 1.f, t) * 255)); + }, 300); + // wait 600ms to fade in + setAnimation(infoFadeIn, 2000, nullptr, false, 2); + } + // no need to animate transition, we're not going anywhere (probably mEntries.size() == 1) if(endPos == mCamOffset && endPos == mExtrasCamOffset) return; diff --git a/es-app/src/views/SystemView.h b/es-app/src/views/SystemView.h index 209c4b0e95..80fdd1beb7 100644 --- a/es-app/src/views/SystemView.h +++ b/es-app/src/views/SystemView.h @@ -50,12 +50,11 @@ class SystemView : public IList std::vector getHelpPrompts() override; virtual HelpStyle getHelpStyle() override; - + void populate(); protected: void onCursorChanged(const CursorState& state) override; private: - void populate(); void getViewElements(const std::shared_ptr& theme); void getDefaultElements(void); void getCarouselFromTheme(const ThemeData::ThemeElement* elem); diff --git a/es-app/src/views/ViewController.cpp b/es-app/src/views/ViewController.cpp index 90f5ad9f9e..12378a254d 100644 --- a/es-app/src/views/ViewController.cpp +++ b/es-app/src/views/ViewController.cpp @@ -3,6 +3,7 @@ #include "SystemData.h" #include "Settings.h" +#include "views/SystemView.h" #include "views/gamelist/BasicGameListView.h" #include "views/gamelist/DetailedGameListView.h" #include "views/gamelist/VideoGameListView.h" @@ -32,8 +33,6 @@ ViewController::ViewController(Window* window) : GuiComponent(window), mCurrentView(nullptr), mCamera(Eigen::Affine3f::Identity()), mFadeOpacity(0), mLockInput(false) { mState.viewing = NOTHING; - mFavoritesOnly = Settings::getInstance()->getBool("FavoritesOnly"); - mKidGamesOnly = Settings::getInstance()->getString("UIMode") == "Kid"; } ViewController::~ViewController() @@ -44,10 +43,7 @@ ViewController::~ViewController() void ViewController::goToStart() { - // TODO - /* mState.viewing = START_SCREEN; - mCurrentView.reset(); - playViewTransition(); */ + LOG(LogDebug) << "ViewController::goToStart()"; goToSystemView(SystemData::sSystemVector.at(0)); } @@ -122,17 +118,7 @@ void ViewController::goToGameList(SystemData* system) if (mInvalidGameList[system] == true) { - updateView(system, getGameListView(system).get()->getCursor()); - //updateFavorite(system, getGameListView(system).get()->getCursor()); - //updateKidGame(system, getGameListView(system).get()->getCursor()); - - if ((mFavoritesOnly != Settings::getInstance()->getBool("FavoritesOnly")) || - (mKidGamesOnly != (Settings::getInstance()->getString("UIMode") == "Kid"))) - { - reloadGameListView(system); - mFavoritesOnly = Settings::getInstance()->getBool("FavoritesOnly"); - mKidGamesOnly = Settings::getInstance()->getString("UIMode") == "Kid"; - } + reloadGameListView(system); mInvalidGameList[system] = false; } @@ -151,127 +137,66 @@ void ViewController::goToGameList(SystemData* system) playViewTransition(); } -void ViewController::goToRandomGame() +/* +// Update the cursor location to the nearest valid location, before re-populating +// the gamelist to reflect new filter-values. +void ViewController::updateCursor(SystemData* system, FileData* file) { - LOG(LogDebug) << "ViewController::goToRandomGame()"; + LOG(LogDebug) << "ViewController::nudgeCursor()"; + // There are two scenario's here: + // 1) a single file's metadata has changed, toggling its + // validity in the current view. In this case, some consistency in the cursor location is wanted. + // 2) the view itself has changed, changing the visibility of many + // items, so the cursor's consistency is not relevant. + + // get the old size of valid items + IGameListView* view = getGameListView(system).get(); + int nr_old = view->getChildCount(); - goToGameList(mState.system->getRandom()); + // populate new view + const std::vector& newfiles = system->getRootFolder()->getChildren(true); + view->populateList(newfiles); - FileData* selected = mState.system->getRootFolder()->getRandom(); + // get pos in old list + int pos = std::find(fullfiles.begin(), fullfiles.end(), file) - fullfiles.begin(); // save current position in that view + // try to reproduce that pos in new list - IGameListView* view = getGameListView(mState.system).get(); - view->setCursor(selected); - - //mCurrentView.get()->setCursor(selected); - LOG(LogDebug) << "ViewController::goToRandomGame: done."; -} -/* -void ViewController::updateFavorite(SystemData* system, FileData* file) -{ - IGameListView* view = getGameListView(system).get(); - if (Settings::getInstance()->getBool("FavoritesOnly")) - { - const std::vector& files = system->getRootFolder()->getChildren(true); - view->populateList(files); - int pos = std::find(files.begin(), files.end(), file) - files.begin(); - bool found = false; - for (auto it = files.begin() + pos; it != files.end(); it++) - { - if ((*it)->getType() == GAME) - { - if ((*it)->metadata.get("favorite").compare("true") == 0) - { - view->setCursor(*it); - found = true; - break; - } - } - } - - if (!found) - { - for (auto it = files.begin() + pos; it != files.begin(); it--) - { - if ((*it)->getType() == GAME) - { - if ((*it)->metadata.get("favorite").compare("true") == 0) - { - view->setCursor(*it); - break; - } - } - } - } - - if (!found) + + + + + + view->populateList(newfilesfiles); // populate a new view + + + bool found = false; + int count = files.size(); + for (int i = 0; i < count; i++) + { + // This does an inside-out search from pos, pos+1, pos-1, pos+2, pos-2 etc to find the closest match. + int index = (pos + ((i%2==0) ? i/2 : count-(i+1)/2) ) % count; + if (files.at(index)->getType() == GAME) { - view->setCursor(*(files.begin() + pos)); + view->setCursor(*it); // and set the cursor to that one + found = true; + break; } } - view->updateInfoPanel(); -} - -// presumably, this function tries to shift the focus to the next (or previous) kidgame, when the display -// mode demands it. This should be solved by reducing the total view/list to contain only valid items. -void ViewController::updateKidGame(SystemData* system, FileData* file) -{ - IGameListView* view = getGameListView(system).get(); - if (Settings::getInstance()->getString("UIMode") == "Kid") // if we are in kidsmode + if (!found) { - const std::vector& files = system->getRootFolder()->getChildren(true); - view->populateList(files); // populate a new view - int pos = std::find(files.begin(), files.end(), file) - files.begin(); // save current position in that view - bool found = false; - for (auto it = files.begin() + pos; it != files.end(); it++) //try to find another kidgame - { - if ((*it)->getType() == GAME) - { - if ((*it)->metadata.get("kidgame").compare("true") == 0) - { - view->setCursor(*it); // and set the cursor to that one - found = true; - break; - } - } - } - - if (!found) - { - for (auto it = files.begin() + pos; it != files.begin(); it--) - { - if ((*it)->getType() == GAME) - { - if ((*it)->metadata.get("kidgame").compare("true") == 0) - { - view->setCursor(*it); - break; - } - } - } - } - - if (!found) - { - view->setCursor(*(files.begin() + pos)); - } + //If there is no hit in the current list, move to system selection view (aka start) + goToStart(); + //view->setCursor(*(files.begin() + pos)); + } view->updateInfoPanel(); //update metadata display + //view->populateList(files); + //view->setCursor(*(files.begin())); + //view->updateInfoPanel(); } - ***/ - -// Update the view after a viewing mode change has occured (fav only, or hide files, or kids only) -void ViewController::updateView(SystemData* system, FileData* file) -{ - IGameListView* view = getGameListView(system).get(); - const std::vector& files = system->getRootFolder()->getChildren(true); - view->populateList(files); - view->setCursor(*(files.begin())); - view->updateInfoPanel(); -} - - +*/ void ViewController::playViewTransition() { Eigen::Vector3f target(Eigen::Vector3f::Identity()); @@ -317,11 +242,23 @@ void ViewController::playViewTransition() } } +// This function triggers the calls to onFileChanged in BasicGameListView and ISimpleGameListView void ViewController::onFileChanged(FileData* file, FileChangeType change) { + LOG(LogDebug) << "ViewController::onFileChanged()"; + + // check if the file is part of current collection of IGameListViews auto it = mGameListViews.find(file->getSystem()); if(it != mGameListViews.end()) + { + if((change == FILE_FILTERED) || (change == FILE_SORTED)) // affects all GameListViews + { + LOG(LogDebug) << "ViewController::onFileChanged(): change might affect all systems, setting all invalid"; + reloadSystemListView(); + setAllInvalidGamesList(file->getSystem()); + } it->second->onFileChanged(file, change); + } } void ViewController::launch(FileData* game, Eigen::Vector3f center) @@ -371,22 +308,25 @@ void ViewController::launch(FileData* game, Eigen::Vector3f center) } } -std::shared_ptr ViewController::getGameListView(SystemData* system) +// This function populates mGameListViews, which maps systemData to IGameListViews: +// like this: std::map< SystemData*, std::shared_ptr > +std::shared_ptr ViewController::getGameListView(SystemData* system, bool forceReload) { //if we already made one, return that one auto exists = mGameListViews.find(system); - if(exists != mGameListViews.end()) + if(exists != mGameListViews.end() && !forceReload) return exists->second; - //if we didn't, make it, remember it, and return it + //if we didn't, or we want to reload anyway, make it, remember it, and return it std::shared_ptr view; bool themeHasVideoView = system->getTheme()->hasView("video"); //decide type - std::vector files = system->getRootFolder()->getFilesRecursive(GAME | FOLDER, false); bool detailed = false; bool video = false; + std::vector files = system->getRootFolder()->getFilesRecursive(GAME | FOLDER); + for(auto it = files.begin(); it != files.end(); it++) { if(themeHasVideoView && !(*it)->getVideoPath().empty()) @@ -400,13 +340,11 @@ std::shared_ptr ViewController::getGameListView(SystemData* syste // Don't break out in case any subsequent files have video } } - - if (video) // Create the view view = std::shared_ptr(new VideoGameListView(mWindow, system->getRootFolder())); else if(detailed) - view = std::shared_ptr(new DetailedGameListView(mWindow, system->getRootFolder())); + view = std::shared_ptr(new DetailedGameListView(mWindow, system->getRootFolder(), system)); // TODO: remove this last argument! else view = std::shared_ptr(new BasicGameListView(mWindow, system->getRootFolder())); @@ -510,35 +448,59 @@ void ViewController::preload() } } -void ViewController::reloadGameListView(IGameListView* view, bool reloadTheme) +// This function finds the current IGameListView, stores the cursor, loads +// a new gamelistview for system, and sets the cursor again. +// TODO: what if the cursor position (file) is no longer valid? +void ViewController::reloadGameListView(IGameListView* oldview, bool reloadTheme) { + LOG(LogDebug) << "ViewController::reloadGameListView()"; for(auto it = mGameListViews.begin(); it != mGameListViews.end(); it++) { - if(it->second.get() == view) + if(it->second.get() == oldview) { + LOG(LogDebug) << "ViewController::reloadGameListView(): found GameListView for " << oldview->getName(); + bool isCurrent = (mCurrentView == it->second); SystemData* system = it->first; - FileData* cursor = view->getCursor(); + FileData* cursor = oldview->getCursor(); mGameListViews.erase(it); if(reloadTheme) system->loadTheme(); - std::shared_ptr newView = getGameListView(system); - newView->setCursor(cursor); + LOG(LogDebug) << "ViewController::reloadGameListView(): getting new GameListView for system: " << system->getName(); - if(isCurrent) - mCurrentView = newView; + std::shared_ptr newView = getGameListView(system); // always returns a fresh one, as we just erased the stale one. + + LOG(LogDebug) << "ViewController::reloadGameListView(): List number of entries = "<< system->getGameCount(true); + + if (system->getGameCount(true) > 0) + { + newView->setCursor(cursor); + if(isCurrent){ + mCurrentView = newView; + } + } else + { + LOG(LogDebug) << "ViewController::reloadGameListView(): No files left in view, go to start."; + goToStart(); + break; + } + //newView->updateInfoPanel(); + break; } } + // Redisplay the current view if (mCurrentView) mCurrentView->onShow(); - } +// This reloads all gameslists. This is an expensive operation! +// The UI remains much more response when a gameslist is only reloaded when +// its actually being requested by the user. void ViewController::reloadAll() { std::map cursorMap; @@ -574,8 +536,11 @@ void ViewController::reloadAll() updateHelpPrompts(); } +// This function sets a specific system's gameslist to be invalid, +// so it is reloaded when requested. void ViewController::setInvalidGamesList(SystemData* system) { + LOG(LogDebug) << "ViewController::setInvalidGamesList()"; for (auto it = mGameListViews.begin(); it != mGameListViews.end(); it++) { if (system == (it->first)) @@ -586,6 +551,9 @@ void ViewController::setInvalidGamesList(SystemData* system) } } +// This function sets the gameslists for all systems (except for the systemExclude one) +// to invalid, this will cause the gamelist to be reloaded on demand. +// This is more efficient than calling reloadAll everytime. void ViewController::setAllInvalidGamesList(SystemData* systemExclude) { for (auto it = mGameListViews.begin(); it != mGameListViews.end(); it++) @@ -615,4 +583,10 @@ HelpStyle ViewController::getHelpStyle() return GuiComponent::getHelpStyle(); return mCurrentView->getHelpStyle(); -} \ No newline at end of file +} + +// Trigger repopulating the list of valid systems +void ViewController::reloadSystemListView() const +{ + mSystemListView->populate(); +} diff --git a/es-app/src/views/ViewController.h b/es-app/src/views/ViewController.h index d09be1fb61..315886b73c 100644 --- a/es-app/src/views/ViewController.h +++ b/es-app/src/views/ViewController.h @@ -21,7 +21,9 @@ class ViewController : public GuiComponent // If a basic view detected a metadata change, it can request to recreate // the current gamelist view (as it may change to be detailed). void reloadGameListView(IGameListView* gamelist, bool reloadTheme = false); - inline void reloadGameListView(SystemData* system, bool reloadTheme = false) { reloadGameListView(getGameListView(system).get(), reloadTheme); } + inline void reloadGameListView(SystemData* system, bool reloadTheme = false) { reloadGameListView(getGameListView(system, true).get(), reloadTheme); } + + void reloadSystemListView() const; void reloadAll(); // Reload everything with a theme. Used when the "ThemeSet" setting changes. void setInvalidGamesList(SystemData* system); void setAllInvalidGamesList(SystemData* systemExclude); @@ -32,13 +34,9 @@ class ViewController : public GuiComponent void goToGameList(SystemData* system); void goToSystemView(SystemData* system); void goToStart(); - void goToRandomGame(); void onFileChanged(FileData* file, FileChangeType change); - //void updateFavorite(SystemData* system, FileData* file); - //void updateKidGame(SystemData* system, FileData* file); - void updateView(SystemData* system, FileData* file); // Plays a nice launch effect and launches the game at the end of it. // Once the game terminates, plays a return effect. @@ -72,7 +70,7 @@ class ViewController : public GuiComponent virtual std::vector getHelpPrompts() override; virtual HelpStyle getHelpStyle() override; - std::shared_ptr getGameListView(SystemData* system); + std::shared_ptr getGameListView(SystemData* system, bool forceReload = false); std::shared_ptr getSystemListView(); private: @@ -84,9 +82,8 @@ class ViewController : public GuiComponent std::shared_ptr mCurrentView; std::map< SystemData*, std::shared_ptr > mGameListViews; - std::shared_ptr mSystemListView; - std::map mInvalidGameList; + std::shared_ptr mSystemListView; Eigen::Affine3f mCamera; float mFadeOpacity; diff --git a/es-app/src/views/gamelist/BasicGameListView.cpp b/es-app/src/views/gamelist/BasicGameListView.cpp index f5e4c84e7d..b093506711 100644 --- a/es-app/src/views/gamelist/BasicGameListView.cpp +++ b/es-app/src/views/gamelist/BasicGameListView.cpp @@ -11,11 +11,10 @@ BasicGameListView::BasicGameListView(Window* window, FileData* root) : ISimpleGameListView(window, root), mList(window) { - //LOG(LogDebug) << "BasicGameListView::BasicGameListView()"; mList.setSize(mSize.x(), mSize.y() * 0.8f); mList.setPosition(0, mSize.y() * 0.2f); addChild(&mList); - + populateList(root->getChildren(true)); // This returns a filtered list based on UImode } @@ -34,21 +33,15 @@ void BasicGameListView::onFileChanged(FileData* file, FileChangeType change) ViewController::get()->reloadGameListView(this); return; } - ISimpleGameListView::onFileChanged(file, change); } void BasicGameListView::populateList(const std::vector& files) { - if (files.size() > 0) { - LOG(LogDebug) << "BasicGameListView::populateList(): system = " << files.at(0)->getSystem()->getFullName(); - } mList.clear(); - // TODO: how to handle empty lists?? - - // file list can be empty if direct launch item (@@ do we still have those?) if (files.size()==0) { + LOG(LogDebug) << "BasicGameListView::populateList(): The current List is empty!"; return; } @@ -61,7 +54,6 @@ void BasicGameListView::populateList(const std::vector& files) mList.add((*it)->getName(), *it, 1); } } - LOG(LogDebug)<< "BasicGameListView::populateList(): added " << mList.size() << " items. END"; } FileData* BasicGameListView::getCursor() @@ -73,8 +65,13 @@ void BasicGameListView::setCursor(FileData* cursor) { if(!mList.setCursor(cursor)) { - populateList(cursor->getParent()->getChildren(true)); - mList.setCursor(cursor); + std::vector files = cursor->getParent()->getChildren(true); + populateList(files); + if (files.size() > 0 && !mList.setCursor(cursor)) + { + // cursor is really no longer in the list, so jump to front + mList.setCursor(files.front()); + } // update our cursor stack in case our cursor just got set to some folder we weren't in before if(mCursorStack.empty() || mCursorStack.top() != cursor->getParent()) @@ -105,8 +102,8 @@ void BasicGameListView::launch(FileData* game) void BasicGameListView::remove(FileData *game) { - boost::filesystem::remove(game->getPath()); // actually delete the file on the filesystem - if (getCursor() == game) // Select next element in list, or prev if none + boost::filesystem::remove(game->getPath()); // actually delete the file on the filesystem + if (getCursor() == game) // Select next element in list, or prev if none { std::vector siblings = game->getParent()->getChildren(true); auto gameIter = std::find(siblings.begin(), siblings.end(), game); @@ -125,8 +122,6 @@ void BasicGameListView::remove(FileData *game) onFileChanged(game, FILE_REMOVED); // update the view, with game removed } -void BasicGameListView::updateInfoPanel() {} - std::vector BasicGameListView::getHelpPrompts() { std::vector prompts; @@ -138,4 +133,4 @@ std::vector BasicGameListView::getHelpPrompts() prompts.push_back(HelpPrompt("b", "back")); prompts.push_back(HelpPrompt("select", "options")); return prompts; -} \ No newline at end of file +} diff --git a/es-app/src/views/gamelist/BasicGameListView.h b/es-app/src/views/gamelist/BasicGameListView.h index b11f7cc756..1a1d8945e2 100644 --- a/es-app/src/views/gamelist/BasicGameListView.h +++ b/es-app/src/views/gamelist/BasicGameListView.h @@ -21,8 +21,8 @@ class BasicGameListView : public ISimpleGameListView virtual std::vector getHelpPrompts() override; virtual void populateList(const std::vector& files) override; - virtual inline void updateInfoPanel() override {} + protected: virtual void launch(FileData* game) override; virtual void remove(FileData* game) override; diff --git a/es-app/src/views/gamelist/DetailedGameListView.cpp b/es-app/src/views/gamelist/DetailedGameListView.cpp index dedcb4c819..72dee38c44 100644 --- a/es-app/src/views/gamelist/DetailedGameListView.cpp +++ b/es-app/src/views/gamelist/DetailedGameListView.cpp @@ -262,6 +262,7 @@ void DetailedGameListView::updateInfoPanel() comp->setAnimation(new LambdaAnimation(func, 150), 0, nullptr, fadingOut); } } + LOG(LogDebug) << "DetailedGameListView::UpdateInfoPanel():end"; } void DetailedGameListView::launch(FileData* game) @@ -273,8 +274,6 @@ void DetailedGameListView::launch(FileData* game) ViewController::get()->launch(game, target); } -// This function returns a pointer vector to all metadata labels supported by the theme -// TODO: auto populate this based on the theme xml std::vector DetailedGameListView::getMDLabels() { std::vector ret; @@ -289,8 +288,6 @@ std::vector DetailedGameListView::getMDLabels() return ret; } -// This function returns a pointer vector to all metadata values supported by the theme -// TODO: auto populate this based on the theme xml std::vector DetailedGameListView::getMDValues() { std::vector ret; diff --git a/es-app/src/views/gamelist/GridGameListView.cpp b/es-app/src/views/gamelist/GridGameListView.cpp index f46e3159c2..0e2b2c402d 100644 --- a/es-app/src/views/gamelist/GridGameListView.cpp +++ b/es-app/src/views/gamelist/GridGameListView.cpp @@ -10,7 +10,6 @@ GridGameListView::GridGameListView(Window* window, FileData* root) : ISimpleGame mGrid.setPosition(0, mSize.y() * 0.2f); mGrid.setSize(mSize.x(), mSize.y() * 0.8f); addChild(&mGrid); - populateList(root->getChildren()); } @@ -41,22 +40,7 @@ void GridGameListView::populateList(const std::vector& files) mGrid.clear(); for(auto it = files.begin(); it != files.end(); it++) { - if (Settings::getInstance()->getBool("FavoritesOnly")) - { - if ((*it)->metadata.get("favorite").compare("true") == 0) - { - mGrid.add((*it)->getName(), (*it)->getThumbnailPath(), *it); - } - }else if(Settings::getInstance()->getString("UIMode") == "Kid") - { - if ((*it)->metadata.get("kidgame").compare("true") == 0) - { - mGrid.add((*it)->getName(), (*it)->getThumbnailPath(), *it); - } - }else - { - mGrid.add((*it)->getName(), (*it)->getThumbnailPath(), *it); - } + mGrid.add((*it)->getName(), (*it)->getThumbnailPath(), *it); } } diff --git a/es-app/src/views/gamelist/ISimpleGameListView.cpp b/es-app/src/views/gamelist/ISimpleGameListView.cpp index fa9bcac07b..2c3374879b 100644 --- a/es-app/src/views/gamelist/ISimpleGameListView.cpp +++ b/es-app/src/views/gamelist/ISimpleGameListView.cpp @@ -48,7 +48,8 @@ void ISimpleGameListView::onThemeChanged(const std::shared_ptr& theme void ISimpleGameListView::onFileChanged(FileData* file, FileChangeType change) { // we could be tricky here to be efficient; - // but this shouldn't happen very often so we'll just always repopulate + // but this shouldn't happen very often so we'll just always repopulate. + LOG(LogDebug) << "ISimpleGameLIstView::onFileChanged()"; FileData* cursor = getCursor(); populateList(cursor->getParent()->getChildren(true)); setCursor(cursor); @@ -74,11 +75,11 @@ bool ISimpleGameListView::input(InputConfig* config, Input input) populateList(cursor->getChildren(true)); } } - return true; }else if(config->isMappedTo("b", input)) { LOG(LogDebug) << "ISimpleGameListView::input(): b detected!"; + if(mCursorStack.size()) { populateList(mCursorStack.top()->getParent()->getChildren(true)); @@ -97,12 +98,10 @@ bool ISimpleGameListView::input(InputConfig* config, Input input) } return true; - }else if (config->isMappedTo("x", input)) + }else if ((config->isMappedTo("x", input)) || + (config->getDeviceId() == DEVICE_KEYBOARD && input.value && input.id == SDLK_f && Settings::getInstance()->getBool("Debug")) ) { FileData* cursor = getCursor(); - LOG(LogDebug) << "ISimpleGameListView::input(): x detected!"; - if (cursor->getSystem()->getHasFavorites()) - { if (cursor->getType() == GAME) { mFavoriteChange = true; @@ -117,17 +116,19 @@ bool ISimpleGameListView::input(InputConfig* config, Input input) md->set("favorite", "false"); } LOG(LogDebug) << "New Favorite value set to: "<< md->get("favorite"); + if (Settings::getInstance()->getBool("FavoritesOnly")) + ViewController::get()->reloadSystemListView(); updateInfoPanel(); } - } - }else if (config->isMappedTo("y", input)) + }else if ((config->isMappedTo("y", input)) || + (config->getDeviceId() == DEVICE_KEYBOARD && input.value && input.id == SDLK_k && Settings::getInstance()->getBool("Debug"))) { - LOG(LogDebug) << "ISimpleGameListView::input(): y detected!"; FileData* cursor = getCursor(); - if (cursor->getSystem()->getHasKidGames() && - Settings::getInstance()->getString("UIMode") == "Full") + if(Settings::getInstance()->getString("UIMode") == "Full") + { // only when kidgames are supported by system+theme, and when in full UImode - if (cursor->getType() == GAME) { + if (cursor->getType() == GAME) + { mKidGameChange = true; MetaDataList* md = &cursor->metadata; std::string value = md->get("kidgame"); diff --git a/es-core/src/GuiComponent.cpp b/es-core/src/GuiComponent.cpp index 40ee91e8ab..17f069a37d 100644 --- a/es-core/src/GuiComponent.cpp +++ b/es-core/src/GuiComponent.cpp @@ -358,5 +358,3 @@ void GuiComponent::onHide() for(unsigned int i = 0; i < getChildCount(); i++) getChild(i)->onHide(); } - -void GuiComponent::setScrollDir(int dir) {} diff --git a/es-core/src/InputConfig.cpp b/es-core/src/InputConfig.cpp index d885ec3d60..90b2729390 100644 --- a/es-core/src/InputConfig.cpp +++ b/es-core/src/InputConfig.cpp @@ -148,7 +148,6 @@ std::vector InputConfig::getMappedTo(Input input) void InputConfig::loadFromXML(pugi::xml_node node) { - LOG(LogDebug) << "InputConfig::loadFromXML()"; clear(); for(pugi::xml_node input = node.child("input"); input; input = input.next_sibling("input")) @@ -170,7 +169,6 @@ void InputConfig::loadFromXML(pugi::xml_node node) LOG(LogWarning) << "WARNING: InputConfig value is 0 for " << type << " " << id << "!\n"; mNameMap[toLower(name)] = Input(mDeviceId, typeEnum, id, value, true); - LOG(LogDebug) << " mDeviceID = "<< mDeviceId <<", TypeEnum = " << typeEnum << ", id = " << id << ", value = " << value ; } } diff --git a/es-core/src/InputManager.cpp b/es-core/src/InputManager.cpp index f6d8d7b184..b5c97fe252 100644 --- a/es-core/src/InputManager.cpp +++ b/es-core/src/InputManager.cpp @@ -243,7 +243,6 @@ bool InputManager::parseEvent(const SDL_Event& ev, Window* window) bool InputManager::loadInputConfig(InputConfig* config) { - LOG(LogDebug) << "InputManager::loadInputConfig() "; std::string path = getConfigPath(); if(!fs::exists(path)) return false; @@ -266,8 +265,6 @@ bool InputManager::loadInputConfig(InputConfig* config) configNode = root.find_child_by_attribute("inputConfig", "deviceName", config->getDeviceName().c_str()); if(!configNode) return false; - - LOG(LogDebug) << " Trying to load: " << configNode; config->loadFromXML(configNode); return true; } @@ -276,8 +273,6 @@ bool InputManager::loadInputConfig(InputConfig* config) //allows the user to select to reconfigure in menus if this happens without having to delete es_input.cfg manually void InputManager::loadDefaultKBConfig() { - LOG(LogDebug) << "InputManager::loadDefaultKBConfig() "; - InputConfig* cfg = getInputConfigByDevice(DEVICE_KEYBOARD); cfg->clear(); @@ -296,6 +291,7 @@ void InputManager::loadDefaultKBConfig() cfg->mapInput("pageup", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_RIGHTBRACKET, 1, true)); cfg->mapInput("pagedown", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_LEFTBRACKET, 1, true)); } + void InputManager::writeDeviceConfig(InputConfig* config) { assert(initialized()); diff --git a/es-core/src/Settings.cpp b/es-core/src/Settings.cpp index e867a55e84..c6eb969de8 100644 --- a/es-core/src/Settings.cpp +++ b/es-core/src/Settings.cpp @@ -8,7 +8,7 @@ Settings* Settings::sInstance = NULL; // these values are NOT saved to es_settings.xml -// since they're set through command-line arguments, and not the in-program settings menu +// since they're set through command-line arguments, , and not the in-program settings menu std::vector settings_dont_save = boost::assign::list_of ("Debug") ("DebugGrid") @@ -77,9 +77,8 @@ void Settings::setDefaults() mStringMap["ScreenSaverBehavior"] = "dim"; mStringMap["Scraper"] = "TheGamesDB"; mStringMap["UIMode"] = "Full"; - - //mStringMap["UIMode_passkey"] = "↑↑↓↓←→←→ba"; - mStringMap["UIMode_passkey"] = "uuddlrlrba"; + mStringMap["SortMode"] = "filename, ascending"; + mStringMap["UIMode_passkey"] = "uuddlrlrba"; // "↑↑↓↓←→←→ba" } template diff --git a/es-core/src/Util.cpp b/es-core/src/Util.cpp index e7bbaaca62..e6fb560767 100644 --- a/es-core/src/Util.cpp +++ b/es-core/src/Util.cpp @@ -42,7 +42,7 @@ FILE * __iob_func(void) return iob; } #endif -#endif + Eigen::Affine3f& roundMatrix(Eigen::Affine3f& mat) { diff --git a/es-core/src/Window.h b/es-core/src/Window.h index ac20a1de3d..67e635b7a7 100644 --- a/es-core/src/Window.h +++ b/es-core/src/Window.h @@ -67,6 +67,6 @@ class Window bool mRenderedHelpPrompts; void ListenForPassKeySequence(InputConfig* config, Input input); - int mPasskeyCounter; + unsigned int mPasskeyCounter; bool mRestartNeeded; }; diff --git a/es-core/src/components/ComponentList.cpp b/es-core/src/components/ComponentList.cpp index 1a69b60e54..a16bcb0975 100644 --- a/es-core/src/components/ComponentList.cpp +++ b/es-core/src/components/ComponentList.cpp @@ -107,7 +107,6 @@ void ComponentList::onCursorChanged(const CursorState& state) { // update the selector bar position // in the future this might be animated - mSelectorBarOffset = 0; for(int i = 0; i < mCursor; i++) { diff --git a/es-core/src/components/IList.h b/es-core/src/components/IList.h index 7d860aecc1..ede3360a9d 100644 --- a/es-core/src/components/IList.h +++ b/es-core/src/components/IList.h @@ -7,7 +7,6 @@ #include "components/ImageComponent.h" #include "resources/Font.h" #include "Renderer.h" -#include "Log.h" enum CursorState { diff --git a/es-core/src/components/OptionListComponent.h b/es-core/src/components/OptionListComponent.h index e5e85d2acf..40ff34ffff 100644 --- a/es-core/src/components/OptionListComponent.h +++ b/es-core/src/components/OptionListComponent.h @@ -236,7 +236,6 @@ class OptionListComponent : public GuiComponent { assert(mMultiSelect == false); auto selected = getSelectedObjects(); - assert(selected.size() == 1); return selected.at(0); } diff --git a/es-core/src/components/SwitchComponent.cpp b/es-core/src/components/SwitchComponent.cpp index b0bc4fdf78..072b9dc96a 100644 --- a/es-core/src/components/SwitchComponent.cpp +++ b/es-core/src/components/SwitchComponent.cpp @@ -3,8 +3,6 @@ #include "resources/Font.h" #include "Window.h" -#include "Log.h" - SwitchComponent::SwitchComponent(Window* window, bool state) : GuiComponent(window), mImage(window), mState(state) { mImage.setImage(":/off.svg"); @@ -56,7 +54,6 @@ void SwitchComponent::setState(bool state) void SwitchComponent::setValue(const std::string& statestring) { - LOG(LogDebug) << "SwitchComponent::setValue(" << statestring << ")"; if (statestring == "true") { mState = true;