summaryrefslogtreecommitdiffstats
path: root/scene
diff options
context:
space:
mode:
Diffstat (limited to 'scene')
-rw-r--r--scene/2d/animated_sprite.cpp14
-rw-r--r--scene/2d/animated_sprite.h3
-rw-r--r--scene/2d/audio_stream_player_2d.cpp1
-rw-r--r--scene/2d/canvas_item.cpp24
-rw-r--r--scene/2d/canvas_item.h2
-rw-r--r--scene/2d/collision_object_2d.cpp27
-rw-r--r--scene/2d/collision_object_2d.h4
-rw-r--r--scene/2d/collision_polygon_2d.cpp4
-rw-r--r--scene/2d/collision_shape_2d.cpp2
-rw-r--r--scene/2d/line_2d.cpp5
-rw-r--r--scene/2d/line_2d.h4
-rw-r--r--scene/2d/line_builder.cpp15
-rw-r--r--scene/2d/line_builder.h2
-rw-r--r--scene/2d/navigation2d.cpp40
-rw-r--r--scene/2d/navigation_polygon.cpp10
-rw-r--r--scene/2d/node_2d.cpp3
-rw-r--r--scene/2d/physics_body_2d.cpp459
-rw-r--r--scene/2d/physics_body_2d.h48
-rw-r--r--scene/2d/polygon_2d.cpp28
-rw-r--r--scene/2d/ray_cast_2d.cpp34
-rw-r--r--scene/2d/ray_cast_2d.h9
-rw-r--r--scene/2d/remote_transform_2d.cpp7
-rw-r--r--scene/2d/skeleton_2d.cpp14
-rw-r--r--scene/2d/tile_map.cpp35
-rw-r--r--scene/2d/tile_map.h5
-rw-r--r--scene/3d/audio_stream_player_3d.cpp2
-rw-r--r--scene/3d/baked_lightmap.cpp1
-rw-r--r--scene/3d/camera.cpp281
-rw-r--r--scene/3d/camera.h63
-rw-r--r--scene/3d/collision_object.cpp2
-rw-r--r--scene/3d/collision_object.h1
-rw-r--r--scene/3d/collision_shape.h1
-rw-r--r--scene/3d/cpu_particles.cpp12
-rw-r--r--scene/3d/gi_probe.cpp1
-rw-r--r--scene/3d/light.cpp1
-rw-r--r--scene/3d/mesh_instance.cpp3
-rw-r--r--scene/3d/mesh_instance.h1
-rw-r--r--scene/3d/navigation.cpp36
-rw-r--r--scene/3d/navigation_mesh.cpp8
-rw-r--r--scene/3d/particles.cpp2
-rw-r--r--scene/3d/physics_body.cpp413
-rw-r--r--scene/3d/physics_body.h40
-rw-r--r--scene/3d/ray_cast.cpp34
-rw-r--r--scene/3d/ray_cast.h10
-rw-r--r--scene/3d/reflection_probe.cpp1
-rw-r--r--scene/3d/remote_transform.cpp4
-rw-r--r--scene/3d/skeleton.cpp141
-rw-r--r--scene/3d/skeleton.h10
-rw-r--r--scene/3d/soft_body.cpp799
-rw-r--r--scene/3d/soft_body.h200
-rw-r--r--scene/3d/spatial.cpp37
-rw-r--r--scene/3d/spatial.h5
-rw-r--r--scene/3d/spatial_velocity_tracker.cpp6
-rw-r--r--scene/3d/spring_arm.cpp172
-rw-r--r--scene/3d/spring_arm.h71
-rw-r--r--scene/3d/vehicle_body.cpp30
-rw-r--r--scene/3d/vehicle_body.h2
-rw-r--r--scene/3d/visual_instance.cpp16
-rw-r--r--scene/3d/visual_instance.h3
-rw-r--r--scene/3d/voxel_light_baker.cpp130
-rw-r--r--scene/animation/animation_blend_space_1d.cpp78
-rw-r--r--scene/animation/animation_blend_space_1d.h16
-rw-r--r--scene/animation/animation_blend_space_2d.cpp84
-rw-r--r--scene/animation/animation_blend_space_2d.h14
-rw-r--r--scene/animation/animation_blend_tree.cpp524
-rw-r--r--scene/animation/animation_blend_tree.h112
-rw-r--r--scene/animation/animation_cache.cpp12
-rw-r--r--scene/animation/animation_node_state_machine.cpp843
-rw-r--r--scene/animation/animation_node_state_machine.h109
-rw-r--r--scene/animation/animation_player.cpp21
-rw-r--r--scene/animation/animation_player.h1
-rw-r--r--scene/animation/animation_tree.cpp382
-rw-r--r--scene/animation/animation_tree.h69
-rw-r--r--scene/animation/animation_tree_player.cpp12
-rw-r--r--scene/animation/skeleton_ik.cpp555
-rw-r--r--scene/animation/skeleton_ik.h216
-rw-r--r--scene/animation/tween.cpp128
-rw-r--r--scene/animation/tween.h9
-rw-r--r--scene/audio/audio_player.cpp1
-rw-r--r--scene/gui/control.cpp13
-rw-r--r--scene/gui/control.h4
-rw-r--r--scene/gui/file_dialog.cpp3
-rw-r--r--scene/gui/gradient_edit.cpp5
-rw-r--r--scene/gui/graph_edit.cpp73
-rw-r--r--scene/gui/graph_edit.h8
-rw-r--r--scene/gui/item_list.cpp55
-rw-r--r--scene/gui/label.cpp2
-rw-r--r--scene/gui/line_edit.cpp105
-rw-r--r--scene/gui/line_edit.h18
-rw-r--r--scene/gui/menu_button.h3
-rw-r--r--scene/gui/option_button.cpp2
-rw-r--r--scene/gui/popup_menu.cpp129
-rw-r--r--scene/gui/popup_menu.h6
-rw-r--r--scene/gui/range.cpp4
-rw-r--r--scene/gui/reference_rect.cpp18
-rw-r--r--scene/gui/reference_rect.h5
-rw-r--r--scene/gui/rich_text_label.cpp71
-rw-r--r--scene/gui/rich_text_label.h5
-rw-r--r--scene/gui/scroll_bar.cpp6
-rw-r--r--scene/gui/tabs.cpp43
-rw-r--r--scene/gui/tabs.h5
-rw-r--r--scene/gui/text_edit.cpp96
-rw-r--r--scene/gui/text_edit.h12
-rw-r--r--scene/gui/texture_progress.cpp29
-rw-r--r--scene/gui/texture_progress.h5
-rw-r--r--scene/gui/tree.cpp127
-rw-r--r--scene/main/canvas_layer.cpp23
-rw-r--r--scene/main/canvas_layer.h1
-rw-r--r--scene/main/node.cpp35
-rw-r--r--scene/main/node.h9
-rw-r--r--scene/main/scene_tree.cpp33
-rw-r--r--scene/main/scene_tree.h3
-rw-r--r--scene/main/viewport.cpp95
-rw-r--r--scene/main/viewport.h6
-rw-r--r--scene/register_scene_types.cpp80
-rw-r--r--scene/resources/animation.cpp100
-rw-r--r--scene/resources/audio_stream_sample.cpp74
-rw-r--r--scene/resources/audio_stream_sample.h2
-rw-r--r--scene/resources/bit_mask.cpp234
-rw-r--r--scene/resources/bit_mask.h2
-rw-r--r--scene/resources/color_ramp.cpp20
-rw-r--r--scene/resources/color_ramp.h6
-rw-r--r--scene/resources/concave_polygon_shape.cpp4
-rw-r--r--scene/resources/convex_polygon_shape.cpp4
-rw-r--r--scene/resources/curve.cpp72
-rw-r--r--scene/resources/default_theme/default_theme.cpp12
-rw-r--r--scene/resources/default_theme/line_edit_clear.pngbin0 -> 158 bytes
-rwxr-xr-xscene/resources/default_theme/make_header.py26
-rw-r--r--scene/resources/default_theme/theme_data.h236
-rw-r--r--scene/resources/dynamic_font.cpp28
-rw-r--r--scene/resources/font.cpp4
-rw-r--r--scene/resources/material.cpp111
-rw-r--r--scene/resources/material.h24
-rw-r--r--scene/resources/mesh.cpp116
-rw-r--r--scene/resources/mesh.h5
-rw-r--r--scene/resources/mesh_data_tool.cpp30
-rw-r--r--scene/resources/mesh_library.cpp2
-rw-r--r--scene/resources/packed_scene.cpp50
-rw-r--r--scene/resources/physics_material.cpp76
-rw-r--r--scene/resources/physics_material.h74
-rw-r--r--scene/resources/polygon_path_finder.cpp80
-rw-r--r--scene/resources/scene_format_text.cpp4
-rw-r--r--scene/resources/shader.cpp18
-rw-r--r--scene/resources/shader.h3
-rw-r--r--scene/resources/shape.cpp23
-rw-r--r--scene/resources/shape.h6
-rw-r--r--scene/resources/sky_box.cpp16
-rw-r--r--scene/resources/style_box.cpp36
-rw-r--r--scene/resources/style_box.h10
-rw-r--r--scene/resources/surface_tool.cpp37
-rw-r--r--scene/resources/text_file.cpp77
-rw-r--r--scene/resources/text_file.h55
-rw-r--r--scene/resources/texture.cpp593
-rw-r--r--scene/resources/texture.h157
-rw-r--r--scene/resources/tile_set.cpp33
-rw-r--r--scene/resources/tile_set.h2
-rw-r--r--scene/resources/visual_shader.cpp1555
-rw-r--r--scene/resources/visual_shader.h284
-rw-r--r--scene/resources/visual_shader_nodes.cpp1896
-rw-r--r--scene/resources/visual_shader_nodes.h861
-rw-r--r--scene/scene_string_names.cpp4
-rw-r--r--scene/scene_string_names.h4
162 files changed, 12471 insertions, 2256 deletions
diff --git a/scene/2d/animated_sprite.cpp b/scene/2d/animated_sprite.cpp
index e3d1592be0..85e7f8df92 100644
--- a/scene/2d/animated_sprite.cpp
+++ b/scene/2d/animated_sprite.cpp
@@ -192,6 +192,16 @@ void SpriteFrames::get_animation_list(List<StringName> *r_animations) const {
}
}
+Vector<String> SpriteFrames::get_animation_names() const {
+
+ Vector<String> names;
+ for (const Map<StringName, Anim>::Element *E = animations.front(); E; E = E->next()) {
+ names.push_back(E->key());
+ }
+ names.sort();
+ return names;
+}
+
void SpriteFrames::set_animation_speed(const StringName &p_anim, float p_fps) {
ERR_FAIL_COND(p_fps < 0);
@@ -225,7 +235,7 @@ void SpriteFrames::_set_frames(const Array &p_frames) {
E->get().frames.resize(p_frames.size());
for (int i = 0; i < E->get().frames.size(); i++)
- E->get().frames[i] = p_frames[i];
+ E->get().frames.write[i] = p_frames[i];
}
Array SpriteFrames::_get_frames() const {
@@ -283,6 +293,8 @@ void SpriteFrames::_bind_methods() {
ClassDB::bind_method(D_METHOD("remove_animation", "anim"), &SpriteFrames::remove_animation);
ClassDB::bind_method(D_METHOD("rename_animation", "anim", "newname"), &SpriteFrames::rename_animation);
+ ClassDB::bind_method(D_METHOD("get_animation_names"), &SpriteFrames::get_animation_names);
+
ClassDB::bind_method(D_METHOD("set_animation_speed", "anim", "speed"), &SpriteFrames::set_animation_speed);
ClassDB::bind_method(D_METHOD("get_animation_speed", "anim"), &SpriteFrames::get_animation_speed);
diff --git a/scene/2d/animated_sprite.h b/scene/2d/animated_sprite.h
index 806052a696..cc49465403 100644
--- a/scene/2d/animated_sprite.h
+++ b/scene/2d/animated_sprite.h
@@ -72,6 +72,7 @@ public:
void rename_animation(const StringName &p_prev, const StringName &p_next);
void get_animation_list(List<StringName> *r_animations) const;
+ Vector<String> get_animation_names() const;
void set_animation_speed(const StringName &p_anim, float p_fps);
float get_animation_speed(const StringName &p_anim) const;
@@ -112,7 +113,7 @@ public:
ERR_FAIL_COND(p_idx < 0);
if (p_idx >= E->get().frames.size())
return;
- E->get().frames[p_idx] = p_frame;
+ E->get().frames.write[p_idx] = p_frame;
}
void remove_frame(const StringName &p_anim, int p_idx);
void clear(const StringName &p_anim);
diff --git a/scene/2d/audio_stream_player_2d.cpp b/scene/2d/audio_stream_player_2d.cpp
index 507499a324..559e041dbf 100644
--- a/scene/2d/audio_stream_player_2d.cpp
+++ b/scene/2d/audio_stream_player_2d.cpp
@@ -296,6 +296,7 @@ float AudioStreamPlayer2D::get_volume_db() const {
}
void AudioStreamPlayer2D::set_pitch_scale(float p_pitch_scale) {
+ ERR_FAIL_COND(p_pitch_scale <= 0.0);
pitch_scale = p_pitch_scale;
}
float AudioStreamPlayer2D::get_pitch_scale() const {
diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp
index 47326b9be2..7f7e3542ed 100644
--- a/scene/2d/canvas_item.cpp
+++ b/scene/2d/canvas_item.cpp
@@ -349,23 +349,12 @@ void CanvasItem::_update_callback() {
Transform2D CanvasItem::get_global_transform_with_canvas() const {
- const CanvasItem *ci = this;
- Transform2D xform;
- const CanvasItem *last_valid = NULL;
-
- while (ci) {
-
- last_valid = ci;
- xform = ci->get_transform() * xform;
- ci = ci->get_parent_item();
- }
-
- if (last_valid->canvas_layer)
- return last_valid->canvas_layer->get_transform() * xform;
+ if (canvas_layer)
+ return canvas_layer->get_transform() * get_global_transform();
else if (is_inside_tree())
- return get_viewport()->get_canvas_transform() * xform;
-
- return xform;
+ return get_viewport()->get_canvas_transform() * get_global_transform();
+ else
+ return get_global_transform();
}
Transform2D CanvasItem::get_global_transform() const {
@@ -411,6 +400,9 @@ void CanvasItem::_enter_canvas() {
if (canvas_layer) {
break;
}
+ if (Object::cast_to<Viewport>(n)) {
+ break;
+ }
n = n->get_parent();
}
diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h
index 1e6a251c9c..85f8564ac2 100644
--- a/scene/2d/canvas_item.h
+++ b/scene/2d/canvas_item.h
@@ -139,6 +139,8 @@ class CanvasItem : public Node {
GDCLASS(CanvasItem, Node);
+ friend class CanvasLayer;
+
public:
enum BlendMode {
diff --git a/scene/2d/collision_object_2d.cpp b/scene/2d/collision_object_2d.cpp
index d05c818ae1..52d04ac10a 100644
--- a/scene/2d/collision_object_2d.cpp
+++ b/scene/2d/collision_object_2d.cpp
@@ -38,10 +38,14 @@ void CollisionObject2D::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE: {
+ Transform2D global_transform = get_global_transform_with_canvas();
+
if (area)
- Physics2DServer::get_singleton()->area_set_transform(rid, get_global_transform());
+ Physics2DServer::get_singleton()->area_set_transform(rid, global_transform);
else
- Physics2DServer::get_singleton()->body_set_state(rid, Physics2DServer::BODY_STATE_TRANSFORM, get_global_transform());
+ Physics2DServer::get_singleton()->body_set_state(rid, Physics2DServer::BODY_STATE_TRANSFORM, global_transform);
+
+ last_transform = global_transform;
RID space = get_world_2d()->get_space();
if (area) {
@@ -60,10 +64,18 @@ void CollisionObject2D::_notification(int p_what) {
} break;
case NOTIFICATION_TRANSFORM_CHANGED: {
+ Transform2D global_transform = get_global_transform_with_canvas();
+
+ if (only_update_transform_changes && global_transform == last_transform) {
+ return;
+ }
+
if (area)
- Physics2DServer::get_singleton()->area_set_transform(rid, get_global_transform());
+ Physics2DServer::get_singleton()->area_set_transform(rid, global_transform);
else
- Physics2DServer::get_singleton()->body_set_state(rid, Physics2DServer::BODY_STATE_TRANSFORM, get_global_transform());
+ Physics2DServer::get_singleton()->body_set_state(rid, Physics2DServer::BODY_STATE_TRANSFORM, global_transform);
+
+ last_transform = global_transform;
} break;
case NOTIFICATION_EXIT_TREE: {
@@ -247,7 +259,7 @@ void CollisionObject2D::shape_owner_remove_shape(uint32_t p_owner, int p_shape)
for (Map<uint32_t, ShapeData>::Element *E = shapes.front(); E; E = E->next()) {
for (int i = 0; i < E->get().shapes.size(); i++) {
if (E->get().shapes[i].index > index_to_remove) {
- E->get().shapes[i].index -= 1;
+ E->get().shapes.write[i].index -= 1;
}
}
}
@@ -318,6 +330,10 @@ void CollisionObject2D::_mouse_exit() {
emit_signal(SceneStringNames::get_singleton()->mouse_exited);
}
+void CollisionObject2D::set_only_update_transform_changes(bool p_enable) {
+ only_update_transform_changes = p_enable;
+}
+
void CollisionObject2D::_update_pickable() {
if (!is_inside_tree())
return;
@@ -384,6 +400,7 @@ CollisionObject2D::CollisionObject2D(RID p_rid, bool p_area) {
pickable = true;
set_notify_transform(true);
total_subshapes = 0;
+ only_update_transform_changes = false;
if (p_area) {
diff --git a/scene/2d/collision_object_2d.h b/scene/2d/collision_object_2d.h
index 6da63d1a0b..29a00bd9f9 100644
--- a/scene/2d/collision_object_2d.h
+++ b/scene/2d/collision_object_2d.h
@@ -65,6 +65,8 @@ class CollisionObject2D : public Node2D {
int total_subshapes;
Map<uint32_t, ShapeData> shapes;
+ Transform2D last_transform;
+ bool only_update_transform_changes; //this is used for sync physics in KinematicBody
protected:
CollisionObject2D(RID p_rid, bool p_area);
@@ -78,6 +80,8 @@ protected:
void _mouse_enter();
void _mouse_exit();
+ void set_only_update_transform_changes(bool p_enable);
+
public:
uint32_t create_shape_owner(Object *p_owner);
void remove_shape_owner(uint32_t owner);
diff --git a/scene/2d/collision_polygon_2d.cpp b/scene/2d/collision_polygon_2d.cpp
index 9d2a83fda7..9f19f56e75 100644
--- a/scene/2d/collision_polygon_2d.cpp
+++ b/scene/2d/collision_polygon_2d.cpp
@@ -102,11 +102,11 @@ Vector<Vector<Vector2> > CollisionPolygon2D::_decompose_in_convex() {
TriangulatorPoly &tp = I->get();
- decomp[idx].resize(tp.GetNumPoints());
+ decomp.write[idx].resize(tp.GetNumPoints());
for (int i = 0; i < tp.GetNumPoints(); i++) {
- decomp[idx][i] = tp.GetPoint(i);
+ decomp.write[idx].write[i] = tp.GetPoint(i);
}
idx++;
diff --git a/scene/2d/collision_shape_2d.cpp b/scene/2d/collision_shape_2d.cpp
index 83ef4df8f4..ff5f7062c4 100644
--- a/scene/2d/collision_shape_2d.cpp
+++ b/scene/2d/collision_shape_2d.cpp
@@ -119,7 +119,7 @@ void CollisionShape2D::_notification(int p_what) {
Color draw_col = get_tree()->get_debug_collisions_color();
if (disabled) {
- float g = draw_col.gray();
+ float g = draw_col.get_v();
draw_col.r = g;
draw_col.g = g;
draw_col.b = g;
diff --git a/scene/2d/line_2d.cpp b/scene/2d/line_2d.cpp
index 3e61dd05f4..ad9775c0b7 100644
--- a/scene/2d/line_2d.cpp
+++ b/scene/2d/line_2d.cpp
@@ -239,7 +239,7 @@ void Line2D::_draw() {
{
PoolVector<Vector2>::Read points_read = _points.read();
for (int i = 0; i < len; ++i) {
- points[i] = points_read[i];
+ points.write[i] = points_read[i];
}
}
@@ -349,7 +349,7 @@ void Line2D::_bind_methods() {
ADD_GROUP("Fill", "");
ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "gradient", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_gradient", "get_gradient");
ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture");
- ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "texture_mode", PROPERTY_HINT_ENUM, "None,Tile"), "set_texture_mode", "get_texture_mode");
+ ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "texture_mode", PROPERTY_HINT_ENUM, "None,Tile,Stretch"), "set_texture_mode", "get_texture_mode");
ADD_GROUP("Capping", "");
ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "joint_mode", PROPERTY_HINT_ENUM, "Sharp,Bevel,Round"), "set_joint_mode", "get_joint_mode");
ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "begin_cap_mode", PROPERTY_HINT_ENUM, "None,Box,Round"), "set_begin_cap_mode", "get_begin_cap_mode");
@@ -368,6 +368,7 @@ void Line2D::_bind_methods() {
BIND_ENUM_CONSTANT(LINE_TEXTURE_NONE);
BIND_ENUM_CONSTANT(LINE_TEXTURE_TILE);
+ BIND_ENUM_CONSTANT(LINE_TEXTURE_STRETCH);
ClassDB::bind_method(D_METHOD("_gradient_changed"), &Line2D::_gradient_changed);
}
diff --git a/scene/2d/line_2d.h b/scene/2d/line_2d.h
index 24c48982cd..6918018c12 100644
--- a/scene/2d/line_2d.h
+++ b/scene/2d/line_2d.h
@@ -52,8 +52,8 @@ public:
enum LineTextureMode {
LINE_TEXTURE_NONE = 0,
- LINE_TEXTURE_TILE
- // TODO STRETCH mode
+ LINE_TEXTURE_TILE,
+ LINE_TEXTURE_STRETCH
};
Line2D();
diff --git a/scene/2d/line_builder.cpp b/scene/2d/line_builder.cpp
index 845788bada..a3f1b25e05 100644
--- a/scene/2d/line_builder.cpp
+++ b/scene/2d/line_builder.cpp
@@ -146,7 +146,9 @@ void LineBuilder::build() {
float current_distance1 = 0.f;
float total_distance = 0.f;
_interpolate_color = gradient != NULL;
- bool distance_required = _interpolate_color || texture_mode == Line2D::LINE_TEXTURE_TILE;
+ bool distance_required = _interpolate_color ||
+ texture_mode == Line2D::LINE_TEXTURE_TILE ||
+ texture_mode == Line2D::LINE_TEXTURE_STRETCH;
if (distance_required)
total_distance = calculate_total_distance(points);
if (_interpolate_color)
@@ -170,7 +172,7 @@ void LineBuilder::build() {
if (texture_mode == Line2D::LINE_TEXTURE_TILE) {
uvx0 = 0.5f / tile_aspect;
}
- new_arc(pos0, pos_up0 - pos0, -Math_PI, color0, Rect2(0.f, 0.f, 1.f, 1.f));
+ new_arc(pos0, pos_up0 - pos0, -Math_PI, color0, Rect2(0.f, 0.f, fmin(uvx0 * 2, 1.f), 1.f));
total_distance += width;
current_distance0 += hw;
current_distance1 = current_distance0;
@@ -290,8 +292,10 @@ void LineBuilder::build() {
color1 = gradient->get_color_at_offset(current_distance1 / total_distance);
}
if (texture_mode == Line2D::LINE_TEXTURE_TILE) {
- uvx0 = current_distance0 / (width * tile_aspect);
uvx1 = current_distance1 / (width * tile_aspect);
+ } else if (texture_mode == Line2D::LINE_TEXTURE_STRETCH) {
+ uvx0 = current_distance0 / total_distance;
+ uvx1 = current_distance1 / total_distance;
}
strip_add_quad(pos_up1, pos_down1, color1, uvx1);
@@ -301,7 +305,6 @@ void LineBuilder::build() {
u0 = u1;
f0 = f1;
pos0 = pos1;
- current_distance0 = current_distance1;
if (intersection_result == SEGMENT_INTERSECT) {
if (current_joint_mode == Line2D::LINE_JOINT_SHARP) {
pos_up0 = pos_up1;
@@ -378,6 +381,8 @@ void LineBuilder::build() {
}
if (texture_mode == Line2D::LINE_TEXTURE_TILE) {
uvx1 = current_distance1 / (width * tile_aspect);
+ } else if (texture_mode == Line2D::LINE_TEXTURE_STRETCH) {
+ uvx1 = current_distance1 / total_distance;
}
strip_add_quad(pos_up1, pos_down1, color1, uvx1);
@@ -386,7 +391,7 @@ void LineBuilder::build() {
if (end_cap_mode == Line2D::LINE_CAP_ROUND) {
// Note: color is not used in case we don't interpolate...
Color color = _interpolate_color ? gradient->get_color(gradient->get_points_count() - 1) : Color(0, 0, 0);
- new_arc(pos1, pos_up1 - pos1, Math_PI, color, Rect2(uvx1 - 0.5f, 0.f, 1.f, 1.f));
+ new_arc(pos1, pos_up1 - pos1, Math_PI, color, Rect2(uvx1 - 0.5f / tile_aspect, 0.f, 1.0f / tile_aspect, 1.f));
}
}
diff --git a/scene/2d/line_builder.h b/scene/2d/line_builder.h
index b1c62f84e2..edfdf97c47 100644
--- a/scene/2d/line_builder.h
+++ b/scene/2d/line_builder.h
@@ -33,8 +33,8 @@
#include "color.h"
#include "line_2d.h"
-#include "math_2d.h"
#include "scene/resources/color_ramp.h"
+#include "vector2.h"
class LineBuilder {
public:
diff --git a/scene/2d/navigation2d.cpp b/scene/2d/navigation2d.cpp
index 16e0386952..e3b048fd74 100644
--- a/scene/2d/navigation2d.cpp
+++ b/scene/2d/navigation2d.cpp
@@ -74,7 +74,7 @@ void Navigation2D::_navpoly_link(int p_id) {
Vector2 ep = nm.xform.xform(r[idx]);
center += ep;
e.point = _get_point(ep);
- p.edges[j] = e;
+ p.edges.write[j] = e;
int idxn = indices[(j + 1) % plen];
if (idxn < 0 || idxn >= len) {
@@ -119,17 +119,17 @@ void Navigation2D::_navpoly_link(int p_id) {
ConnectionPending pending;
pending.polygon = &p;
pending.edge = j;
- p.edges[j].P = C->get().pending.push_back(pending);
+ p.edges.write[j].P = C->get().pending.push_back(pending);
continue;
//print_line(String()+_get_vertex(ek.a)+" -> "+_get_vertex(ek.b));
}
C->get().B = &p;
C->get().B_edge = j;
- C->get().A->edges[C->get().A_edge].C = &p;
- C->get().A->edges[C->get().A_edge].C_edge = j;
- p.edges[j].C = C->get().A;
- p.edges[j].C_edge = C->get().A_edge;
+ C->get().A->edges.write[C->get().A_edge].C = &p;
+ C->get().A->edges.write[C->get().A_edge].C_edge = j;
+ p.edges.write[j].C = C->get().A;
+ p.edges.write[j].C_edge = C->get().A_edge;
//connection successful.
}
}
@@ -167,10 +167,10 @@ void Navigation2D::_navpoly_unlink(int p_id) {
} else if (C->get().B) {
//disconnect
- C->get().B->edges[C->get().B_edge].C = NULL;
- C->get().B->edges[C->get().B_edge].C_edge = -1;
- C->get().A->edges[C->get().A_edge].C = NULL;
- C->get().A->edges[C->get().A_edge].C_edge = -1;
+ C->get().B->edges.write[C->get().B_edge].C = NULL;
+ C->get().B->edges.write[C->get().B_edge].C_edge = -1;
+ C->get().A->edges.write[C->get().A_edge].C = NULL;
+ C->get().A->edges.write[C->get().A_edge].C_edge = -1;
if (C->get().A == &E->get()) {
@@ -187,11 +187,11 @@ void Navigation2D::_navpoly_unlink(int p_id) {
C->get().B = cp.polygon;
C->get().B_edge = cp.edge;
- C->get().A->edges[C->get().A_edge].C = cp.polygon;
- C->get().A->edges[C->get().A_edge].C_edge = cp.edge;
- cp.polygon->edges[cp.edge].C = C->get().A;
- cp.polygon->edges[cp.edge].C_edge = C->get().A_edge;
- cp.polygon->edges[cp.edge].P = NULL;
+ C->get().A->edges.write[C->get().A_edge].C = cp.polygon;
+ C->get().A->edges.write[C->get().A_edge].C_edge = cp.edge;
+ cp.polygon->edges.write[cp.edge].C = C->get().A;
+ cp.polygon->edges.write[cp.edge].C_edge = C->get().A_edge;
+ cp.polygon->edges.write[cp.edge].P = NULL;
}
} else {
@@ -339,8 +339,8 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vect
Vector<Vector2> path;
path.resize(2);
- path[0] = begin_point;
- path[1] = end_point;
+ path.write[0] = begin_point;
+ path.write[1] = end_point;
//print_line("Direct Path");
return path;
}
@@ -408,7 +408,7 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vect
for (int i = 0; i < es; i++) {
- Polygon::Edge &e = p->edges[i];
+ Polygon::Edge &e = p->edges.write[i];
if (!e.C)
continue;
@@ -586,7 +586,7 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vect
if (!path.size() || path[path.size() - 1].distance_squared_to(begin_point) > CMP_EPSILON) {
path.push_back(begin_point); // Add the begin point
} else {
- path[path.size() - 1] = begin_point; // Replace first midpoint by the exact begin point
+ path.write[path.size() - 1] = begin_point; // Replace first midpoint by the exact begin point
}
path.invert();
@@ -594,7 +594,7 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vect
if (path.size() <= 1 || path[path.size() - 1].distance_squared_to(end_point) > CMP_EPSILON) {
path.push_back(end_point); // Add the end point
} else {
- path[path.size() - 1] = end_point; // Replace last midpoint by the exact end point
+ path.write[path.size() - 1] = end_point; // Replace last midpoint by the exact end point
}
return path;
diff --git a/scene/2d/navigation_polygon.cpp b/scene/2d/navigation_polygon.cpp
index 6e27bf1c1d..2d6679272a 100644
--- a/scene/2d/navigation_polygon.cpp
+++ b/scene/2d/navigation_polygon.cpp
@@ -91,7 +91,7 @@ void NavigationPolygon::_set_polygons(const Array &p_array) {
polygons.resize(p_array.size());
for (int i = 0; i < p_array.size(); i++) {
- polygons[i].indices = p_array[i];
+ polygons.write[i].indices = p_array[i];
}
}
@@ -110,7 +110,7 @@ void NavigationPolygon::_set_outlines(const Array &p_array) {
outlines.resize(p_array.size());
for (int i = 0; i < p_array.size(); i++) {
- outlines[i] = p_array[i];
+ outlines.write[i] = p_array[i];
}
rect_cache_dirty = true;
}
@@ -166,7 +166,7 @@ int NavigationPolygon::get_outline_count() const {
void NavigationPolygon::set_outline(int p_idx, const PoolVector<Vector2> &p_outline) {
ERR_FAIL_INDEX(p_idx, outlines.size());
- outlines[p_idx] = p_outline;
+ outlines.write[p_idx] = p_outline;
rect_cache_dirty = true;
}
@@ -432,8 +432,8 @@ void NavigationPolygonInstance::_notification(int p_what) {
{
PoolVector<Vector2>::Read vr = verts.read();
for (int i = 0; i < vsize; i++) {
- vertices[i] = vr[i];
- colors[i] = color;
+ vertices.write[i] = vr[i];
+ colors.write[i] = color;
}
}
diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp
index 3813bd96fe..7de72dc41d 100644
--- a/scene/2d/node_2d.cpp
+++ b/scene/2d/node_2d.cpp
@@ -130,7 +130,6 @@ void Node2D::_update_xform_values() {
void Node2D::_update_transform() {
- Transform2D mat(angle, pos);
_mat.set_rotation_and_scale(angle, _scale);
_mat.elements[2] = pos;
@@ -444,7 +443,7 @@ void Node2D::_bind_methods() {
ADD_GROUP("Transform", "");
ADD_PROPERTYNZ(PropertyInfo(Variant::VECTOR2, "position"), "set_position", "get_position");
ADD_PROPERTYNZ(PropertyInfo(Variant::REAL, "rotation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_rotation", "get_rotation");
- ADD_PROPERTYNZ(PropertyInfo(Variant::REAL, "rotation_degrees", PROPERTY_HINT_RANGE, "-1440,1440,0.1", PROPERTY_USAGE_EDITOR), "set_rotation_degrees", "get_rotation_degrees");
+ ADD_PROPERTYNZ(PropertyInfo(Variant::REAL, "rotation_degrees", PROPERTY_HINT_RANGE, "-1080,1080,0.1,or_lesser,or_greater", PROPERTY_USAGE_EDITOR), "set_rotation_degrees", "get_rotation_degrees");
ADD_PROPERTYNO(PropertyInfo(Variant::VECTOR2, "scale"), "set_scale", "get_scale");
ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "transform", PROPERTY_HINT_NONE, "", 0), "set_transform", "get_transform");
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index feb11089d0..66686f10a8 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -30,24 +30,12 @@
#include "physics_body_2d.h"
+#include "core/core_string_names.h"
#include "core/method_bind_ext.gen.inc"
#include "engine.h"
+#include "math_funcs.h"
#include "scene/scene_string_names.h"
-void PhysicsBody2D::_notification(int p_what) {
-
- /*
- switch(p_what) {
-
- case NOTIFICATION_TRANSFORM_CHANGED: {
-
- Physics2DServer::get_singleton()->body_set_state(get_rid(),Physics2DServer::BODY_STATE_TRANSFORM,get_global_transform());
-
- } break;
- }
- */
-}
-
void PhysicsBody2D::_set_layers(uint32_t p_mask) {
set_collision_layer(p_mask);
@@ -186,28 +174,76 @@ real_t StaticBody2D::get_constant_angular_velocity() const {
return constant_angular_velocity;
}
+#ifndef DISABLE_DEPRECATED
void StaticBody2D::set_friction(real_t p_friction) {
+ ERR_EXPLAIN("The method set_friction has been deprecated and will be removed in the future, use physical material")
+ WARN_DEPRECATED
+
ERR_FAIL_COND(p_friction < 0 || p_friction > 1);
- friction = p_friction;
- Physics2DServer::get_singleton()->body_set_param(get_rid(), Physics2DServer::BODY_PARAM_FRICTION, friction);
+ if (physics_material_override.is_null()) {
+ physics_material_override.instance();
+ set_physics_material_override(physics_material_override);
+ }
+ physics_material_override->set_friction(p_friction);
}
+
real_t StaticBody2D::get_friction() const {
- return friction;
+ ERR_EXPLAIN("The method get_friction has been deprecated and will be removed in the future, use physical material")
+ WARN_DEPRECATED
+
+ if (physics_material_override.is_null()) {
+ return 1;
+ }
+
+ return physics_material_override->get_friction();
}
void StaticBody2D::set_bounce(real_t p_bounce) {
+ ERR_EXPLAIN("The method set_bounce has been deprecated and will be removed in the future, use physical material")
+ WARN_DEPRECATED
+
ERR_FAIL_COND(p_bounce < 0 || p_bounce > 1);
- bounce = p_bounce;
- Physics2DServer::get_singleton()->body_set_param(get_rid(), Physics2DServer::BODY_PARAM_BOUNCE, bounce);
+ if (physics_material_override.is_null()) {
+ physics_material_override.instance();
+ set_physics_material_override(physics_material_override);
+ }
+ physics_material_override->set_bounce(p_bounce);
}
+
real_t StaticBody2D::get_bounce() const {
- return bounce;
+ ERR_EXPLAIN("The method get_bounce has been deprecated and will be removed in the future, use physical material")
+ WARN_DEPRECATED
+
+ if (physics_material_override.is_null()) {
+ return 0;
+ }
+
+ return physics_material_override->get_bounce();
+}
+#endif // DISABLE_DEPRECATED
+
+void StaticBody2D::set_physics_material_override(const Ref<PhysicsMaterial> &p_physics_material_override) {
+ if (physics_material_override.is_valid()) {
+ if (physics_material_override->is_connected(CoreStringNames::get_singleton()->changed, this, "_reload_physics_characteristics"))
+ physics_material_override->disconnect(CoreStringNames::get_singleton()->changed, this, "_reload_physics_characteristics");
+ }
+
+ physics_material_override = p_physics_material_override;
+
+ if (physics_material_override.is_valid()) {
+ physics_material_override->connect(CoreStringNames::get_singleton()->changed, this, "_reload_physics_characteristics");
+ }
+ _reload_physics_characteristics();
+}
+
+Ref<PhysicsMaterial> StaticBody2D::get_physics_material_override() const {
+ return physics_material_override;
}
void StaticBody2D::_bind_methods() {
@@ -216,29 +252,48 @@ void StaticBody2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_constant_angular_velocity", "vel"), &StaticBody2D::set_constant_angular_velocity);
ClassDB::bind_method(D_METHOD("get_constant_linear_velocity"), &StaticBody2D::get_constant_linear_velocity);
ClassDB::bind_method(D_METHOD("get_constant_angular_velocity"), &StaticBody2D::get_constant_angular_velocity);
+
+#ifndef DISABLE_DEPRECATED
ClassDB::bind_method(D_METHOD("set_friction", "friction"), &StaticBody2D::set_friction);
ClassDB::bind_method(D_METHOD("get_friction"), &StaticBody2D::get_friction);
ClassDB::bind_method(D_METHOD("set_bounce", "bounce"), &StaticBody2D::set_bounce);
ClassDB::bind_method(D_METHOD("get_bounce"), &StaticBody2D::get_bounce);
+#endif // DISABLE_DEPRECATED
+
+ ClassDB::bind_method(D_METHOD("set_physics_material_override", "physics_material_override"), &StaticBody2D::set_physics_material_override);
+ ClassDB::bind_method(D_METHOD("get_physics_material_override"), &StaticBody2D::get_physics_material_override);
+
+ ClassDB::bind_method(D_METHOD("_reload_physics_characteristics"), &StaticBody2D::_reload_physics_characteristics);
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "constant_linear_velocity"), "set_constant_linear_velocity", "get_constant_linear_velocity");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "constant_angular_velocity"), "set_constant_angular_velocity", "get_constant_angular_velocity");
+#ifndef DISABLE_DEPRECATED
ADD_PROPERTY(PropertyInfo(Variant::REAL, "friction", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_friction", "get_friction");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "bounce", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_bounce", "get_bounce");
+#endif // DISABLE_DEPRECATED
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "physics_material_override", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), "set_physics_material_override", "get_physics_material_override");
}
StaticBody2D::StaticBody2D() :
PhysicsBody2D(Physics2DServer::BODY_MODE_STATIC) {
constant_angular_velocity = 0;
- bounce = 0;
- friction = 1;
}
StaticBody2D::~StaticBody2D() {
}
+void StaticBody2D::_reload_physics_characteristics() {
+ if (physics_material_override.is_null()) {
+ Physics2DServer::get_singleton()->body_set_param(get_rid(), Physics2DServer::BODY_PARAM_BOUNCE, 0);
+ Physics2DServer::get_singleton()->body_set_param(get_rid(), Physics2DServer::BODY_PARAM_FRICTION, 1);
+ } else {
+ Physics2DServer::get_singleton()->body_set_param(get_rid(), Physics2DServer::BODY_PARAM_BOUNCE, physics_material_override->computed_bounce());
+ Physics2DServer::get_singleton()->body_set_param(get_rid(), Physics2DServer::BODY_PARAM_FRICTION, physics_material_override->computed_friction());
+ }
+}
+
void RigidBody2D::_body_enter_tree(ObjectID p_id) {
Object *obj = ObjectDB::get_instance(p_id);
@@ -368,7 +423,7 @@ bool RigidBody2D::_test_motion(const Vector2 &p_motion, bool p_infinite_inertia,
Physics2DServer::MotionResult *r = NULL;
if (p_result.is_valid())
r = p_result->get_result_ptr();
- return Physics2DServer::get_singleton()->body_test_motion(get_rid(), get_global_transform(), p_motion, p_infinite_inertia, p_margin, r);
+ return Physics2DServer::get_singleton()->body_test_motion(get_rid(), get_global_transform_with_canvas(), p_motion, p_infinite_inertia, p_margin, r);
}
void RigidBody2D::_direct_state_changed(Object *p_state) {
@@ -381,7 +436,7 @@ void RigidBody2D::_direct_state_changed(Object *p_state) {
set_block_transform_notify(true); // don't want notify (would feedback loop)
if (mode != MODE_KINEMATIC)
- set_global_transform(state->get_transform());
+ set_global_transform(get_canvas_transform().affine_inverse() * state->get_transform());
linear_velocity = state->get_linear_velocity();
angular_velocity = state->get_angular_velocity();
if (sleeping != state->is_sleeping()) {
@@ -545,28 +600,73 @@ real_t RigidBody2D::get_weight() const {
return mass * real_t(GLOBAL_DEF("physics/2d/default_gravity", 98)) / 10;
}
+#ifndef DISABLE_DEPRECATED
void RigidBody2D::set_friction(real_t p_friction) {
+ ERR_EXPLAIN("The method set_friction has been deprecated and will be removed in the future, use physical material")
+ WARN_DEPRECATED
ERR_FAIL_COND(p_friction < 0 || p_friction > 1);
- friction = p_friction;
- Physics2DServer::get_singleton()->body_set_param(get_rid(), Physics2DServer::BODY_PARAM_FRICTION, friction);
+ if (physics_material_override.is_null()) {
+ physics_material_override.instance();
+ set_physics_material_override(physics_material_override);
+ }
+ physics_material_override->set_friction(p_friction);
}
real_t RigidBody2D::get_friction() const {
- return friction;
+ ERR_EXPLAIN("The method get_friction has been deprecated and will be removed in the future, use physical material")
+ WARN_DEPRECATED
+
+ if (physics_material_override.is_null()) {
+ return 1;
+ }
+
+ return physics_material_override->get_friction();
}
void RigidBody2D::set_bounce(real_t p_bounce) {
+ ERR_EXPLAIN("The method set_bounce has been deprecated and will be removed in the future, use physical material")
+ WARN_DEPRECATED
+
ERR_FAIL_COND(p_bounce < 0 || p_bounce > 1);
- bounce = p_bounce;
- Physics2DServer::get_singleton()->body_set_param(get_rid(), Physics2DServer::BODY_PARAM_BOUNCE, bounce);
+ if (physics_material_override.is_null()) {
+ physics_material_override.instance();
+ set_physics_material_override(physics_material_override);
+ }
+ physics_material_override->set_bounce(p_bounce);
}
real_t RigidBody2D::get_bounce() const {
- return bounce;
+ ERR_EXPLAIN("The method get_bounce has been deprecated and will be removed in the future, use physical material")
+ WARN_DEPRECATED
+
+ if (physics_material_override.is_null()) {
+ return 0;
+ }
+
+ return physics_material_override->get_bounce();
+}
+#endif // DISABLE_DEPRECATED
+
+void RigidBody2D::set_physics_material_override(const Ref<PhysicsMaterial> &p_physics_material_override) {
+ if (physics_material_override.is_valid()) {
+ if (physics_material_override->is_connected(CoreStringNames::get_singleton()->changed, this, "_reload_physics_characteristics"))
+ physics_material_override->disconnect(CoreStringNames::get_singleton()->changed, this, "_reload_physics_characteristics");
+ }
+
+ physics_material_override = p_physics_material_override;
+
+ if (physics_material_override.is_valid()) {
+ physics_material_override->connect(CoreStringNames::get_singleton()->changed, this, "_reload_physics_characteristics");
+ }
+ _reload_physics_characteristics();
+}
+
+Ref<PhysicsMaterial> RigidBody2D::get_physics_material_override() const {
+ return physics_material_override;
}
void RigidBody2D::set_gravity_scale(real_t p_gravity_scale) {
@@ -690,11 +790,19 @@ int RigidBody2D::get_max_contacts_reported() const {
return max_contacts_reported;
}
+void RigidBody2D::apply_central_impulse(const Vector2 &p_impulse) {
+ Physics2DServer::get_singleton()->body_apply_central_impulse(get_rid(), p_impulse);
+}
+
void RigidBody2D::apply_impulse(const Vector2 &p_offset, const Vector2 &p_impulse) {
Physics2DServer::get_singleton()->body_apply_impulse(get_rid(), p_offset, p_impulse);
}
+void RigidBody2D::apply_torque_impulse(float p_torque) {
+ Physics2DServer::get_singleton()->body_apply_torque_impulse(get_rid(), p_torque);
+}
+
void RigidBody2D::set_applied_force(const Vector2 &p_force) {
Physics2DServer::get_singleton()->body_set_applied_force(get_rid(), p_force);
@@ -715,11 +823,19 @@ float RigidBody2D::get_applied_torque() const {
return Physics2DServer::get_singleton()->body_get_applied_torque(get_rid());
};
+void RigidBody2D::add_central_force(const Vector2 &p_force) {
+ Physics2DServer::get_singleton()->body_add_central_force(get_rid(), p_force);
+}
+
void RigidBody2D::add_force(const Vector2 &p_offset, const Vector2 &p_force) {
Physics2DServer::get_singleton()->body_add_force(get_rid(), p_offset, p_force);
}
+void RigidBody2D::add_torque(const float p_torque) {
+ Physics2DServer::get_singleton()->body_add_torque(get_rid(), p_torque);
+}
+
void RigidBody2D::set_continuous_collision_detection_mode(CCDMode p_mode) {
ccd_mode = p_mode;
@@ -837,11 +953,18 @@ void RigidBody2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_weight", "weight"), &RigidBody2D::set_weight);
ClassDB::bind_method(D_METHOD("get_weight"), &RigidBody2D::get_weight);
+#ifndef DISABLE_DEPRECATED
ClassDB::bind_method(D_METHOD("set_friction", "friction"), &RigidBody2D::set_friction);
ClassDB::bind_method(D_METHOD("get_friction"), &RigidBody2D::get_friction);
ClassDB::bind_method(D_METHOD("set_bounce", "bounce"), &RigidBody2D::set_bounce);
ClassDB::bind_method(D_METHOD("get_bounce"), &RigidBody2D::get_bounce);
+#endif // DISABLE_DEPRECATED
+
+ ClassDB::bind_method(D_METHOD("set_physics_material_override", "physics_material_override"), &RigidBody2D::set_physics_material_override);
+ ClassDB::bind_method(D_METHOD("get_physics_material_override"), &RigidBody2D::get_physics_material_override);
+
+ ClassDB::bind_method(D_METHOD("_reload_physics_characteristics"), &RigidBody2D::_reload_physics_characteristics);
ClassDB::bind_method(D_METHOD("set_gravity_scale", "gravity_scale"), &RigidBody2D::set_gravity_scale);
ClassDB::bind_method(D_METHOD("get_gravity_scale"), &RigidBody2D::get_gravity_scale);
@@ -871,7 +994,9 @@ void RigidBody2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_continuous_collision_detection_mode"), &RigidBody2D::get_continuous_collision_detection_mode);
ClassDB::bind_method(D_METHOD("set_axis_velocity", "axis_velocity"), &RigidBody2D::set_axis_velocity);
+ ClassDB::bind_method(D_METHOD("apply_central_impulse", "impulse"), &RigidBody2D::apply_central_impulse);
ClassDB::bind_method(D_METHOD("apply_impulse", "offset", "impulse"), &RigidBody2D::apply_impulse);
+ ClassDB::bind_method(D_METHOD("apply_torque_impulse", "torque"), &RigidBody2D::apply_torque_impulse);
ClassDB::bind_method(D_METHOD("set_applied_force", "force"), &RigidBody2D::set_applied_force);
ClassDB::bind_method(D_METHOD("get_applied_force"), &RigidBody2D::get_applied_force);
@@ -879,7 +1004,9 @@ void RigidBody2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_applied_torque", "torque"), &RigidBody2D::set_applied_torque);
ClassDB::bind_method(D_METHOD("get_applied_torque"), &RigidBody2D::get_applied_torque);
+ ClassDB::bind_method(D_METHOD("add_central_force", "force"), &RigidBody2D::add_central_force);
ClassDB::bind_method(D_METHOD("add_force", "offset", "force"), &RigidBody2D::add_force);
+ ClassDB::bind_method(D_METHOD("add_torque", "torque"), &RigidBody2D::add_torque);
ClassDB::bind_method(D_METHOD("set_sleeping", "sleeping"), &RigidBody2D::set_sleeping);
ClassDB::bind_method(D_METHOD("is_sleeping"), &RigidBody2D::is_sleeping);
@@ -901,8 +1028,11 @@ void RigidBody2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "mass", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01"), "set_mass", "get_mass");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "inertia", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01", 0), "set_inertia", "get_inertia");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "weight", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01", PROPERTY_USAGE_EDITOR), "set_weight", "get_weight");
+#ifndef DISABLE_DEPRECATED
ADD_PROPERTY(PropertyInfo(Variant::REAL, "friction", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_friction", "get_friction");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "bounce", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_bounce", "get_bounce");
+#endif // DISABLE_DEPRECATED
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "physics_material_override", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), "set_physics_material_override", "get_physics_material_override");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "gravity_scale", PROPERTY_HINT_RANGE, "-128,128,0.01"), "set_gravity_scale", "get_gravity_scale");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "custom_integrator"), "set_use_custom_integrator", "is_using_custom_integrator");
ADD_PROPERTY(PropertyInfo(Variant::INT, "continuous_cd", PROPERTY_HINT_ENUM, "Disabled,Cast Ray,Cast Shape"), "set_continuous_collision_detection_mode", "get_continuous_collision_detection_mode");
@@ -941,9 +1071,7 @@ RigidBody2D::RigidBody2D() :
mode = MODE_RIGID;
- bounce = 0;
mass = 1;
- friction = 1;
gravity_scale = 1;
linear_damp = -1;
@@ -969,13 +1097,23 @@ RigidBody2D::~RigidBody2D() {
memdelete(contact_monitor);
}
+void RigidBody2D::_reload_physics_characteristics() {
+ if (physics_material_override.is_null()) {
+ Physics2DServer::get_singleton()->body_set_param(get_rid(), Physics2DServer::BODY_PARAM_BOUNCE, 0);
+ Physics2DServer::get_singleton()->body_set_param(get_rid(), Physics2DServer::BODY_PARAM_FRICTION, 1);
+ } else {
+ Physics2DServer::get_singleton()->body_set_param(get_rid(), Physics2DServer::BODY_PARAM_BOUNCE, physics_material_override->computed_bounce());
+ Physics2DServer::get_singleton()->body_set_param(get_rid(), Physics2DServer::BODY_PARAM_FRICTION, physics_material_override->computed_friction());
+ }
+}
+
//////////////////////////
-Ref<KinematicCollision2D> KinematicBody2D::_move(const Vector2 &p_motion, bool p_infinite_inertia) {
+Ref<KinematicCollision2D> KinematicBody2D::_move(const Vector2 &p_motion, bool p_infinite_inertia, bool p_exclude_raycast_shapes, bool p_test_only) {
Collision col;
- if (move_and_collide(p_motion, p_infinite_inertia, col)) {
+ if (move_and_collide(p_motion, p_infinite_inertia, col, p_exclude_raycast_shapes, p_test_only)) {
if (motion_cache.is_null()) {
motion_cache.instance();
motion_cache->owner = this;
@@ -989,11 +1127,48 @@ Ref<KinematicCollision2D> KinematicBody2D::_move(const Vector2 &p_motion, bool p
return Ref<KinematicCollision2D>();
}
-bool KinematicBody2D::move_and_collide(const Vector2 &p_motion, bool p_infinite_inertia, Collision &r_collision) {
+bool KinematicBody2D::separate_raycast_shapes(bool p_infinite_inertia, Collision &r_collision) {
- Transform2D gt = get_global_transform();
+ Physics2DServer::SeparationResult sep_res[8]; //max 8 rays
+
+ Transform2D gt = get_global_transform_with_canvas();
+
+ Vector2 recover;
+ int hits = Physics2DServer::get_singleton()->body_test_ray_separation(get_rid(), gt, p_infinite_inertia, recover, sep_res, 8, margin);
+ int deepest = -1;
+ float deepest_depth;
+ for (int i = 0; i < hits; i++) {
+ if (deepest == -1 || sep_res[i].collision_depth > deepest_depth) {
+ deepest = i;
+ deepest_depth = sep_res[i].collision_depth;
+ }
+ }
+
+ gt.elements[2] += recover;
+ set_global_transform(get_canvas_transform().affine_inverse() * gt);
+
+ if (deepest != -1) {
+ r_collision.collider = sep_res[deepest].collider_id;
+ r_collision.collider_metadata = sep_res[deepest].collider_metadata;
+ r_collision.collider_shape = sep_res[deepest].collider_shape;
+ r_collision.collider_vel = sep_res[deepest].collider_velocity;
+ r_collision.collision = sep_res[deepest].collision_point;
+ r_collision.normal = sep_res[deepest].collision_normal;
+ r_collision.local_shape = sep_res[deepest].collision_local_shape;
+ r_collision.travel = recover;
+ r_collision.remainder = Vector2();
+
+ return true;
+ } else {
+ return false;
+ }
+}
+
+bool KinematicBody2D::move_and_collide(const Vector2 &p_motion, bool p_infinite_inertia, Collision &r_collision, bool p_exclude_raycast_shapes, bool p_test_only) {
+
+ Transform2D gt = get_global_transform_with_canvas();
Physics2DServer::MotionResult result;
- bool colliding = Physics2DServer::get_singleton()->body_test_motion(get_rid(), gt, p_motion, p_infinite_inertia, margin, &result);
+ bool colliding = Physics2DServer::get_singleton()->body_test_motion(get_rid(), gt, p_motion, p_infinite_inertia, margin, &result, p_exclude_raycast_shapes);
if (colliding) {
r_collision.collider_metadata = result.collider_metadata;
@@ -1002,73 +1177,121 @@ bool KinematicBody2D::move_and_collide(const Vector2 &p_motion, bool p_infinite_
r_collision.collision = result.collision_point;
r_collision.normal = result.collision_normal;
r_collision.collider = result.collider_id;
+ r_collision.collider_rid = result.collider;
r_collision.travel = result.motion;
r_collision.remainder = result.remainder;
r_collision.local_shape = result.collision_local_shape;
}
- gt.elements[2] += result.motion;
- set_global_transform(gt);
+ if (!p_test_only) {
+ gt.elements[2] += result.motion;
+ set_global_transform(get_canvas_transform().affine_inverse() * gt);
+ }
return colliding;
}
-Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction, bool p_infinite_inertia, float p_slope_stop_min_velocity, int p_max_slides, float p_floor_max_angle) {
+//so, if you pass 45 as limit, avoid numerical precision erros when angle is 45.
+#define FLOOR_ANGLE_THRESHOLD 0.01
+
+Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction, bool p_infinite_inertia, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle) {
+
+ Vector2 floor_motion = floor_velocity;
+ if (on_floor && on_floor_body.is_valid()) {
+ //this approach makes sure there is less delay between the actual body velocity and the one we saved
+ Physics2DDirectBodyState *bs = Physics2DServer::get_singleton()->body_get_direct_state(on_floor_body);
+ if (bs) {
+ floor_motion = bs->get_linear_velocity();
+ }
+ }
- Vector2 motion = (floor_velocity + p_linear_velocity) * get_physics_process_delta_time();
+ Vector2 motion = (floor_motion + p_linear_velocity) * get_physics_process_delta_time();
Vector2 lv = p_linear_velocity;
on_floor = false;
+ on_floor_body = RID();
on_ceiling = false;
on_wall = false;
colliders.clear();
floor_velocity = Vector2();
+ Vector2 lv_n = p_linear_velocity.normalized();
+
while (p_max_slides) {
Collision collision;
+ bool found_collision = false;
+
+ for (int i = 0; i < 2; i++) {
+ bool collided;
+ if (i == 0) { //collide
+ collided = move_and_collide(motion, p_infinite_inertia, collision);
+ if (!collided) {
+ motion = Vector2(); //clear because no collision happened and motion completed
+ }
+ } else { //separate raycasts (if any)
+ collided = separate_raycast_shapes(p_infinite_inertia, collision);
+ if (collided) {
+ collision.remainder = motion; //keep
+ collision.travel = Vector2();
+ }
+ }
- bool collided = move_and_collide(motion, p_infinite_inertia, collision);
-
- if (collided) {
-
- motion = collision.remainder;
-
- if (p_floor_direction == Vector2()) {
- //all is a wall
- on_wall = true;
- } else {
- if (collision.normal.dot(p_floor_direction) >= Math::cos(p_floor_max_angle)) { //floor
+ if (collided) {
+ found_collision = true;
+ }
- on_floor = true;
- floor_velocity = collision.collider_vel;
+ if (collided) {
- Vector2 rel_v = lv - floor_velocity;
- Vector2 hv = rel_v - p_floor_direction * p_floor_direction.dot(rel_v);
+ colliders.push_back(collision);
+ motion = collision.remainder;
- if (collision.travel.length() < 1 && hv.length() < p_slope_stop_min_velocity) {
- Transform2D gt = get_global_transform();
- gt.elements[2] -= collision.travel;
- set_global_transform(gt);
- return Vector2();
+ bool is_on_slope = false;
+ if (p_floor_direction == Vector2()) {
+ //all is a wall
+ on_wall = true;
+ } else {
+ if (collision.normal.dot(p_floor_direction) >= Math::cos(p_floor_max_angle + FLOOR_ANGLE_THRESHOLD)) { //floor
+
+ on_floor = true;
+ on_floor_body = collision.collider_rid;
+ floor_velocity = collision.collider_vel;
+
+ if (p_stop_on_slope) {
+ if (Vector2() == lv_n + p_floor_direction) {
+ Transform2D gt = get_global_transform_with_canvas();
+ gt.elements[2] -= collision.travel;
+ set_global_transform(get_canvas_transform().affine_inverse() * gt);
+ return Vector2();
+ }
+ }
+
+ is_on_slope = true;
+
+ } else if (collision.normal.dot(-p_floor_direction) >= Math::cos(p_floor_max_angle + FLOOR_ANGLE_THRESHOLD)) { //ceiling
+ on_ceiling = true;
+ } else {
+ on_wall = true;
}
- } else if (collision.normal.dot(-p_floor_direction) >= Math::cos(p_floor_max_angle)) { //ceiling
- on_ceiling = true;
+ }
+
+ if (p_stop_on_slope && is_on_slope) {
+ motion = motion.slide(p_floor_direction);
+ lv = lv.slide(p_floor_direction);
} else {
- on_wall = true;
+ Vector2 n = collision.normal;
+ motion = motion.slide(n);
+ lv = lv.slide(n);
}
}
- Vector2 n = collision.normal;
- motion = motion.slide(n);
- lv = lv.slide(n);
-
- colliders.push_back(collision);
+ if (p_stop_on_slope)
+ break;
+ }
- } else {
+ if (!found_collision) {
break;
}
-
p_max_slides--;
if (motion == Vector2())
break;
@@ -1077,6 +1300,31 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const
return lv;
}
+Vector2 KinematicBody2D::move_and_slide_with_snap(const Vector2 &p_linear_velocity, const Vector2 &p_snap, const Vector2 &p_floor_direction, bool p_infinite_inertia, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle) {
+
+ bool was_on_floor = on_floor;
+
+ Vector2 ret = move_and_slide(p_linear_velocity, p_floor_direction, p_infinite_inertia, p_stop_on_slope, p_max_slides, p_floor_max_angle);
+ if (!was_on_floor || p_snap == Vector2()) {
+ return ret;
+ }
+
+ Collision col;
+ Transform2D gt = get_global_transform_with_canvas();
+
+ if (move_and_collide(p_snap, p_infinite_inertia, col, false, true)) {
+ gt.elements[2] += col.travel;
+ if (p_floor_direction != Vector2() && Math::acos(p_floor_direction.normalized().dot(col.normal)) < p_floor_max_angle) {
+ on_floor = true;
+ on_floor_body = col.collider_rid;
+ floor_velocity = col.collider_vel;
+ }
+ set_global_transform(get_canvas_transform().affine_inverse() * gt);
+ }
+
+ return ret;
+}
+
bool KinematicBody2D::is_on_floor() const {
return on_floor;
@@ -1130,18 +1378,68 @@ Ref<KinematicCollision2D> KinematicBody2D::_get_slide_collision(int p_bounce) {
}
if (slide_colliders[p_bounce].is_null()) {
- slide_colliders[p_bounce].instance();
- slide_colliders[p_bounce]->owner = this;
+ slide_colliders.write[p_bounce].instance();
+ slide_colliders.write[p_bounce]->owner = this;
}
- slide_colliders[p_bounce]->collision = colliders[p_bounce];
+ slide_colliders.write[p_bounce]->collision = colliders[p_bounce];
return slide_colliders[p_bounce];
}
+void KinematicBody2D::set_sync_to_physics(bool p_enable) {
+
+ if (sync_to_physics == p_enable) {
+ return;
+ }
+ sync_to_physics = p_enable;
+ if (p_enable) {
+ Physics2DServer::get_singleton()->body_set_force_integration_callback(get_rid(), this, "_direct_state_changed");
+ set_only_update_transform_changes(true);
+ set_notify_local_transform(true);
+ } else {
+ Physics2DServer::get_singleton()->body_set_force_integration_callback(get_rid(), NULL, "");
+ set_only_update_transform_changes(false);
+ set_notify_local_transform(false);
+ }
+}
+
+bool KinematicBody2D::is_sync_to_physics_enabled() const {
+ return sync_to_physics;
+}
+
+void KinematicBody2D::_direct_state_changed(Object *p_state) {
+
+ if (!sync_to_physics)
+ return;
+
+ Physics2DDirectBodyState *state = Object::cast_to<Physics2DDirectBodyState>(p_state);
+
+ last_valid_transform = state->get_transform();
+ set_notify_local_transform(false);
+ set_global_transform(get_canvas_transform().affine_inverse() * last_valid_transform);
+ set_notify_local_transform(true);
+}
+
+void KinematicBody2D::_notification(int p_what) {
+ if (p_what == NOTIFICATION_ENTER_TREE) {
+ last_valid_transform = get_global_transform_with_canvas();
+ }
+
+ if (p_what == NOTIFICATION_LOCAL_TRANSFORM_CHANGED) {
+ //used by sync to physics, send the new transform to the physics
+ Transform2D new_transform = get_global_transform_with_canvas();
+ Physics2DServer::get_singleton()->body_set_state(get_rid(), Physics2DServer::BODY_STATE_TRANSFORM, new_transform);
+ //but then revert changes
+ set_notify_local_transform(false);
+ set_global_transform(get_canvas_transform().affine_inverse() * last_valid_transform);
+ set_notify_local_transform(true);
+ }
+}
void KinematicBody2D::_bind_methods() {
- ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia"), &KinematicBody2D::_move, DEFVAL(true));
- ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "floor_normal", "infinite_inertia", "slope_stop_min_velocity", "max_bounces", "floor_max_angle"), &KinematicBody2D::move_and_slide, DEFVAL(Vector2(0, 0)), DEFVAL(true), DEFVAL(5), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)));
+ ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "exclude_raycast_shapes", "test_only"), &KinematicBody2D::_move, DEFVAL(true), DEFVAL(true), DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "floor_normal", "infinite_inertia", "stop_on_slope", "max_bounces", "floor_max_angle"), &KinematicBody2D::move_and_slide, DEFVAL(Vector2(0, 0)), DEFVAL(true), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)));
+ ClassDB::bind_method(D_METHOD("move_and_slide_with_snap", "linear_velocity", "snap", "floor_normal", "infinite_inertia", "stop_on_slope", "max_bounces", "floor_max_angle"), &KinematicBody2D::move_and_slide_with_snap, DEFVAL(Vector2(0, 0)), DEFVAL(true), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)));
ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec", "infinite_inertia"), &KinematicBody2D::test_move);
@@ -1156,7 +1454,13 @@ void KinematicBody2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_slide_count"), &KinematicBody2D::get_slide_count);
ClassDB::bind_method(D_METHOD("get_slide_collision", "slide_idx"), &KinematicBody2D::_get_slide_collision);
+ ClassDB::bind_method(D_METHOD("set_sync_to_physics", "enable"), &KinematicBody2D::set_sync_to_physics);
+ ClassDB::bind_method(D_METHOD("is_sync_to_physics_enabled"), &KinematicBody2D::is_sync_to_physics_enabled);
+
+ ClassDB::bind_method(D_METHOD("_direct_state_changed"), &KinematicBody2D::_direct_state_changed);
+
ADD_PROPERTY(PropertyInfo(Variant::REAL, "collision/safe_margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_safe_margin", "get_safe_margin");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "motion/sync_to_physics"), "set_sync_to_physics", "is_sync_to_physics_enabled");
}
KinematicBody2D::KinematicBody2D() :
@@ -1167,6 +1471,7 @@ KinematicBody2D::KinematicBody2D() :
on_floor = false;
on_ceiling = false;
on_wall = false;
+ sync_to_physics = false;
}
KinematicBody2D::~KinematicBody2D() {
if (motion_cache.is_valid()) {
@@ -1175,7 +1480,7 @@ KinematicBody2D::~KinematicBody2D() {
for (int i = 0; i < slide_colliders.size(); i++) {
if (slide_colliders[i].is_valid()) {
- slide_colliders[i]->owner = NULL;
+ slide_colliders.write[i]->owner = NULL;
}
}
}
diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h
index 0fda3c5c05..0900438e3c 100644
--- a/scene/2d/physics_body_2d.h
+++ b/scene/2d/physics_body_2d.h
@@ -32,6 +32,7 @@
#define PHYSICS_BODY_2D_H
#include "scene/2d/collision_object_2d.h"
+#include "scene/resources/physics_material.h"
#include "servers/physics_2d_server.h"
#include "vset.h"
@@ -48,7 +49,6 @@ class PhysicsBody2D : public CollisionObject2D {
uint32_t _get_layers() const;
protected:
- void _notification(int p_what);
PhysicsBody2D(Physics2DServer::BodyMode p_mode);
static void _bind_methods();
@@ -79,18 +79,21 @@ class StaticBody2D : public PhysicsBody2D {
Vector2 constant_linear_velocity;
real_t constant_angular_velocity;
- real_t bounce;
- real_t friction;
+ Ref<PhysicsMaterial> physics_material_override;
protected:
static void _bind_methods();
public:
+#ifndef DISABLE_DEPRECATED
void set_friction(real_t p_friction);
real_t get_friction() const;
void set_bounce(real_t p_bounce);
real_t get_bounce() const;
+#endif
+ void set_physics_material_override(const Ref<PhysicsMaterial> &p_physics_material_override);
+ Ref<PhysicsMaterial> get_physics_material_override() const;
void set_constant_linear_velocity(const Vector2 &p_vel);
void set_constant_angular_velocity(real_t p_vel);
@@ -100,6 +103,9 @@ public:
StaticBody2D();
~StaticBody2D();
+
+private:
+ void _reload_physics_characteristics();
};
class RigidBody2D : public PhysicsBody2D {
@@ -125,9 +131,8 @@ private:
Physics2DDirectBodyState *state;
Mode mode;
- real_t bounce;
real_t mass;
- real_t friction;
+ Ref<PhysicsMaterial> physics_material_override;
real_t gravity_scale;
real_t linear_damp;
real_t angular_damp;
@@ -204,11 +209,16 @@ public:
void set_weight(real_t p_weight);
real_t get_weight() const;
+#ifndef DISABLE_DEPRECATED
void set_friction(real_t p_friction);
real_t get_friction() const;
void set_bounce(real_t p_bounce);
real_t get_bounce() const;
+#endif
+
+ void set_physics_material_override(const Ref<PhysicsMaterial> &p_physics_material_override);
+ Ref<PhysicsMaterial> get_physics_material_override() const;
void set_gravity_scale(real_t p_gravity_scale);
real_t get_gravity_scale() const;
@@ -245,7 +255,9 @@ public:
void set_continuous_collision_detection_mode(CCDMode p_mode);
CCDMode get_continuous_collision_detection_mode() const;
+ void apply_central_impulse(const Vector2 &p_impulse);
void apply_impulse(const Vector2 &p_offset, const Vector2 &p_impulse);
+ void apply_torque_impulse(float p_torque);
void set_applied_force(const Vector2 &p_force);
Vector2 get_applied_force() const;
@@ -253,7 +265,9 @@ public:
void set_applied_torque(const float p_torque);
float get_applied_torque() const;
+ void add_central_force(const Vector2 &p_force);
void add_force(const Vector2 &p_offset, const Vector2 &p_force);
+ void add_torque(float p_torque);
Array get_colliding_bodies() const; //function for script
@@ -261,6 +275,9 @@ public:
RigidBody2D();
~RigidBody2D();
+
+private:
+ void _reload_physics_characteristics();
};
VARIANT_ENUM_CAST(RigidBody2D::Mode);
@@ -276,6 +293,7 @@ public:
Vector2 normal;
Vector2 collider_vel;
ObjectID collider;
+ RID collider_rid;
int collider_shape;
Variant collider_metadata;
Vector2 remainder;
@@ -287,29 +305,40 @@ private:
float margin;
Vector2 floor_velocity;
+ RID on_floor_body;
bool on_floor;
bool on_ceiling;
bool on_wall;
+ bool sync_to_physics;
+
Vector<Collision> colliders;
Vector<Ref<KinematicCollision2D> > slide_colliders;
Ref<KinematicCollision2D> motion_cache;
_FORCE_INLINE_ bool _ignores_mode(Physics2DServer::BodyMode) const;
- Ref<KinematicCollision2D> _move(const Vector2 &p_motion, bool p_infinite_inertia = true);
+ Ref<KinematicCollision2D> _move(const Vector2 &p_motion, bool p_infinite_inertia = true, bool p_exclude_raycast_shapes = true, bool p_test_only = false);
Ref<KinematicCollision2D> _get_slide_collision(int p_bounce);
+ Transform2D last_valid_transform;
+ void _direct_state_changed(Object *p_state);
+
protected:
+ void _notification(int p_what);
static void _bind_methods();
public:
- bool move_and_collide(const Vector2 &p_motion, bool p_infinite_inertia, Collision &r_collision);
+ bool move_and_collide(const Vector2 &p_motion, bool p_infinite_inertia, Collision &r_collision, bool p_exclude_raycast_shapes = true, bool p_test_only = false);
+
bool test_move(const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia);
+ bool separate_raycast_shapes(bool p_infinite_inertia, Collision &r_collision);
+
void set_safe_margin(float p_margin);
float get_safe_margin() const;
- Vector2 move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction = Vector2(0, 0), bool p_infinite_inertia = true, float p_slope_stop_min_velocity = 5, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45));
+ Vector2 move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction = Vector2(0, 0), bool p_infinite_inertia = true, bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45));
+ Vector2 move_and_slide_with_snap(const Vector2 &p_linear_velocity, const Vector2 &p_snap, const Vector2 &p_floor_direction = Vector2(0, 0), bool p_infinite_inertia = true, bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45));
bool is_on_floor() const;
bool is_on_wall() const;
bool is_on_ceiling() const;
@@ -318,6 +347,9 @@ public:
int get_slide_count() const;
Collision get_slide_collision(int p_bounce) const;
+ void set_sync_to_physics(bool p_enable);
+ bool is_sync_to_physics_enabled() const;
+
KinematicBody2D();
~KinematicBody2D();
};
diff --git a/scene/2d/polygon_2d.cpp b/scene/2d/polygon_2d.cpp
index 81ed3c63c3..34f4ccc03e 100644
--- a/scene/2d/polygon_2d.cpp
+++ b/scene/2d/polygon_2d.cpp
@@ -29,8 +29,10 @@
/*************************************************************************/
#include "polygon_2d.h"
+
#include "core/math/geometry.h"
#include "skeleton_2d.h"
+
Dictionary Polygon2D::_edit_get_state() const {
Dictionary state = Node2D::_edit_get_state();
state["offset"] = offset;
@@ -113,7 +115,7 @@ void Polygon2D::_notification(int p_what) {
PoolVector<Vector2>::Read polyr = polygon.read();
for (int i = 0; i < len; i++) {
- points[i] = polyr[i] + offset;
+ points.write[i] = polyr[i] + offset;
}
}
@@ -153,18 +155,18 @@ void Polygon2D::_notification(int p_what) {
SWAP(ep[1], ep[4]);
SWAP(ep[2], ep[3]);
SWAP(ep[5], ep[0]);
- SWAP(ep[6], points[highest_idx]);
+ SWAP(ep[6], points.write[highest_idx]);
}
points.resize(points.size() + 7);
for (int i = points.size() - 1; i >= highest_idx + 7; i--) {
- points[i] = points[i - 7];
+ points.write[i] = points[i - 7];
}
for (int i = 0; i < 7; i++) {
- points[highest_idx + i + 1] = ep[i];
+ points.write[highest_idx + i + 1] = ep[i];
}
len = points.size();
@@ -182,12 +184,12 @@ void Polygon2D::_notification(int p_what) {
PoolVector<Vector2>::Read uvr = uv.read();
for (int i = 0; i < len; i++) {
- uvs[i] = texmat.xform(uvr[i]) / tex_size;
+ uvs.write[i] = texmat.xform(uvr[i]) / tex_size;
}
} else {
for (int i = 0; i < len; i++) {
- uvs[i] = texmat.xform(points[i]) / tex_size;
+ uvs.write[i] = texmat.xform(points[i]) / tex_size;
}
}
}
@@ -262,10 +264,10 @@ void Polygon2D::_notification(int p_what) {
{
PoolVector<Color>::Read color_r = vertex_colors.read();
for (int i = 0; i < color_len && i < len; i++) {
- colors[i] = color_r[i];
+ colors.write[i] = color_r[i];
}
for (int i = color_len; i < len; i++) {
- colors[i] = color;
+ colors.write[i] = color;
}
}
@@ -333,13 +335,13 @@ void Polygon2D::_notification(int p_what) {
Vector<Vector2> vertices;
vertices.resize(loop.size());
for (int j = 0; j < vertices.size(); j++) {
- vertices[j] = points[loop[j]];
+ vertices.write[j] = points[loop[j]];
}
Vector<int> sub_indices = Geometry::triangulate_polygon(vertices);
int from = indices.size();
indices.resize(from + sub_indices.size());
for (int j = 0; j < sub_indices.size(); j++) {
- indices[from + j] = loop[sub_indices[j]];
+ indices.write[from + j] = loop[sub_indices[j]];
}
}
@@ -538,12 +540,12 @@ void Polygon2D::clear_bones() {
void Polygon2D::set_bone_weights(int p_index, const PoolVector<float> &p_weights) {
ERR_FAIL_INDEX(p_index, bone_weights.size());
- bone_weights[p_index].weights = p_weights;
+ bone_weights.write[p_index].weights = p_weights;
update();
}
void Polygon2D::set_bone_path(int p_index, const NodePath &p_path) {
ERR_FAIL_INDEX(p_index, bone_weights.size());
- bone_weights[p_index].path = p_path;
+ bone_weights.write[p_index].path = p_path;
update();
}
@@ -646,7 +648,7 @@ void Polygon2D::_bind_methods() {
ADD_GROUP("Texture", "texture_");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "texture_offset"), "set_texture_offset", "get_texture_offset");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "texture_scale"), "set_texture_scale", "get_texture_scale");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "texture_rotation_degrees", PROPERTY_HINT_RANGE, "-1440,1440,0.1"), "set_texture_rotation_degrees", "get_texture_rotation_degrees");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "texture_rotation_degrees", PROPERTY_HINT_RANGE, "-1080,1080,0.1,or_lesser,or_greater"), "set_texture_rotation_degrees", "get_texture_rotation_degrees");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "texture_rotation", PROPERTY_HINT_NONE, "", 0), "set_texture_rotation", "get_texture_rotation");
ADD_GROUP("Skeleton", "");
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "skeleton", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Skeleton2D"), "set_skeleton", "get_skeleton");
diff --git a/scene/2d/ray_cast_2d.cpp b/scene/2d/ray_cast_2d.cpp
index 255d2d38d5..9582c08110 100644
--- a/scene/2d/ray_cast_2d.cpp
+++ b/scene/2d/ray_cast_2d.cpp
@@ -209,7 +209,7 @@ void RayCast2D::_update_raycast_state() {
Physics2DDirectSpaceState::RayResult rr;
- if (dss->intersect_ray(gt.get_origin(), gt.xform(to), rr, exclude, collision_mask)) {
+ if (dss->intersect_ray(gt.get_origin(), gt.xform(to), rr, exclude, collision_mask, collide_with_bodies, collide_with_areas)) {
collided = true;
against = rr.collider_id;
@@ -258,6 +258,26 @@ void RayCast2D::clear_exceptions() {
exclude.clear();
}
+void RayCast2D::set_collide_with_areas(bool p_clip) {
+
+ collide_with_areas = p_clip;
+}
+
+bool RayCast2D::is_collide_with_areas_enabled() const {
+
+ return collide_with_areas;
+}
+
+void RayCast2D::set_collide_with_bodies(bool p_clip) {
+
+ collide_with_bodies = p_clip;
+}
+
+bool RayCast2D::is_collide_with_bodies_enabled() const {
+
+ return collide_with_bodies;
+}
+
void RayCast2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &RayCast2D::set_enabled);
@@ -291,10 +311,20 @@ void RayCast2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_exclude_parent_body", "mask"), &RayCast2D::set_exclude_parent_body);
ClassDB::bind_method(D_METHOD("get_exclude_parent_body"), &RayCast2D::get_exclude_parent_body);
+ ClassDB::bind_method(D_METHOD("set_collide_with_areas", "enable"), &RayCast2D::set_collide_with_areas);
+ ClassDB::bind_method(D_METHOD("is_collide_with_areas_enabled"), &RayCast2D::is_collide_with_areas_enabled);
+
+ ClassDB::bind_method(D_METHOD("set_collide_with_bodies", "enable"), &RayCast2D::set_collide_with_bodies);
+ ClassDB::bind_method(D_METHOD("is_collide_with_bodies_enabled"), &RayCast2D::is_collide_with_bodies_enabled);
+
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "exclude_parent"), "set_exclude_parent_body", "get_exclude_parent_body");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "cast_to"), "set_cast_to", "get_cast_to");
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_collision_mask", "get_collision_mask");
+
+ ADD_GROUP("Collide With", "collide_with");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with_areas", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collide_with_areas", "is_collide_with_areas_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with_bodies", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collide_with_bodies", "is_collide_with_bodies_enabled");
}
RayCast2D::RayCast2D() {
@@ -306,4 +336,6 @@ RayCast2D::RayCast2D() {
collision_mask = 1;
cast_to = Vector2(0, 50);
exclude_parent_body = true;
+ collide_with_bodies = true;
+ collide_with_areas = false;
}
diff --git a/scene/2d/ray_cast_2d.h b/scene/2d/ray_cast_2d.h
index 0850cdc7cc..a438be87b6 100644
--- a/scene/2d/ray_cast_2d.h
+++ b/scene/2d/ray_cast_2d.h
@@ -49,12 +49,21 @@ class RayCast2D : public Node2D {
Vector2 cast_to;
+ bool collide_with_areas;
+ bool collide_with_bodies;
+
protected:
void _notification(int p_what);
void _update_raycast_state();
static void _bind_methods();
public:
+ void set_collide_with_areas(bool p_clip);
+ bool is_collide_with_areas_enabled() const;
+
+ void set_collide_with_bodies(bool p_clip);
+ bool is_collide_with_bodies_enabled() const;
+
void set_enabled(bool p_enabled);
bool is_enabled() const;
diff --git a/scene/2d/remote_transform_2d.cpp b/scene/2d/remote_transform_2d.cpp
index 63c3d78dfd..f0274e5206 100644
--- a/scene/2d/remote_transform_2d.cpp
+++ b/scene/2d/remote_transform_2d.cpp
@@ -67,7 +67,7 @@ void RemoteTransform2D::_update_remote() {
} else {
Transform2D n_trans = n->get_global_transform();
Transform2D our_trans = get_global_transform();
- Vector2 n_scale = n->get_global_scale();
+ Vector2 n_scale = n->get_scale();
if (!update_remote_position)
our_trans.set_origin(n_trans.get_origin());
@@ -131,8 +131,10 @@ void RemoteTransform2D::_notification(int p_what) {
void RemoteTransform2D::set_remote_node(const NodePath &p_remote_node) {
remote_node = p_remote_node;
- if (is_inside_tree())
+ if (is_inside_tree()) {
_update_cache();
+ _update_remote();
+ }
update_configuration_warning();
}
@@ -144,6 +146,7 @@ NodePath RemoteTransform2D::get_remote_node() const {
void RemoteTransform2D::set_use_global_coordinates(const bool p_enable) {
use_global_coordinates = p_enable;
+ _update_remote();
}
bool RemoteTransform2D::get_use_global_coordinates() const {
diff --git a/scene/2d/skeleton_2d.cpp b/scene/2d/skeleton_2d.cpp
index 8ceffb3c27..2c362f1b31 100644
--- a/scene/2d/skeleton_2d.cpp
+++ b/scene/2d/skeleton_2d.cpp
@@ -191,13 +191,13 @@ void Skeleton2D::_update_bone_setup() {
bones.sort(); //sorty so they are always in the same order/index
for (int i = 0; i < bones.size(); i++) {
- bones[i].rest_inverse = bones[i].bone->get_skeleton_rest().affine_inverse(); //bind pose
- bones[i].bone->skeleton_index = i;
+ bones.write[i].rest_inverse = bones[i].bone->get_skeleton_rest().affine_inverse(); //bind pose
+ bones.write[i].bone->skeleton_index = i;
Bone2D *parent_bone = Object::cast_to<Bone2D>(bones[i].bone->get_parent());
if (parent_bone) {
- bones[i].parent_index = parent_bone->skeleton_index;
+ bones.write[i].parent_index = parent_bone->skeleton_index;
} else {
- bones[i].parent_index = -1;
+ bones.write[i].parent_index = -1;
}
}
@@ -230,9 +230,9 @@ void Skeleton2D::_update_transform() {
ERR_CONTINUE(bones[i].parent_index >= i);
if (bones[i].parent_index >= 0) {
- bones[i].accum_transform = bones[bones[i].parent_index].accum_transform * bones[i].bone->get_transform();
+ bones.write[i].accum_transform = bones[bones[i].parent_index].accum_transform * bones[i].bone->get_transform();
} else {
- bones[i].accum_transform = bones[i].bone->get_transform();
+ bones.write[i].accum_transform = bones[i].bone->get_transform();
}
}
@@ -288,7 +288,7 @@ void Skeleton2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("_update_transform"), &Skeleton2D::_update_transform);
ClassDB::bind_method(D_METHOD("get_bone_count"), &Skeleton2D::get_bone_count);
- ClassDB::bind_method(D_METHOD("get_bone"), &Skeleton2D::get_bone);
+ ClassDB::bind_method(D_METHOD("get_bone", "idx"), &Skeleton2D::get_bone);
ClassDB::bind_method(D_METHOD("get_skeleton"), &Skeleton2D::get_skeleton);
}
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index 9a343ca0f0..80565fa455 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -62,7 +62,7 @@ void TileMap::_notification(int p_what) {
pending_update = true;
_recreate_quadrants();
- _update_dirty_quadrants();
+ update_dirty_quadrants();
RID space = get_world_2d()->get_space();
_update_quadrant_transform();
_update_quadrant_space(space);
@@ -245,7 +245,7 @@ void TileMap::_fix_cell_transform(Transform2D &xform, const Cell &p_cell, const
xform.elements[2].y += offset.y;
}
-void TileMap::_update_dirty_quadrants() {
+void TileMap::update_dirty_quadrants() {
if (!pending_update)
return;
@@ -368,7 +368,7 @@ void TileMap::_update_dirty_quadrants() {
}
Rect2 r = tile_set->tile_get_region(c.id);
- if (tile_set->tile_get_tile_mode(c.id) == TileSet::AUTO_TILE) {
+ if (tile_set->tile_get_tile_mode(c.id) == TileSet::AUTO_TILE || tile_set->tile_get_tile_mode(c.id) == TileSet::ATLAS_TILE) {
int spacing = tile_set->autotile_get_spacing(c.id);
r.size = tile_set->autotile_get_size(c.id);
r.position += (r.size + Vector2(spacing, spacing)) * Vector2(c.autotile_coord_x, c.autotile_coord_y);
@@ -491,7 +491,7 @@ void TileMap::_update_dirty_quadrants() {
if (navigation) {
Ref<NavigationPolygon> navpoly;
Vector2 npoly_ofs;
- if (tile_set->tile_get_tile_mode(c.id) == TileSet::AUTO_TILE) {
+ if (tile_set->tile_get_tile_mode(c.id) == TileSet::AUTO_TILE || tile_set->tile_get_tile_mode(c.id) == TileSet::ATLAS_TILE) {
navpoly = tile_set->autotile_get_navigation_polygon(c.id, Vector2(c.autotile_coord_x, c.autotile_coord_y));
npoly_ofs = Vector2();
} else {
@@ -529,8 +529,8 @@ void TileMap::_update_dirty_quadrants() {
{
PoolVector<Vector2>::Read vr = navigation_polygon_vertices.read();
for (int i = 0; i < vsize; i++) {
- vertices[i] = vr[i];
- colors[i] = debug_navigation_color;
+ vertices.write[i] = vr[i];
+ colors.write[i] = debug_navigation_color;
}
}
@@ -563,7 +563,7 @@ void TileMap::_update_dirty_quadrants() {
}
Ref<OccluderPolygon2D> occluder;
- if (tile_set->tile_get_tile_mode(c.id) == TileSet::AUTO_TILE) {
+ if (tile_set->tile_get_tile_mode(c.id) == TileSet::AUTO_TILE || tile_set->tile_get_tile_mode(c.id) == TileSet::ATLAS_TILE) {
occluder = tile_set->autotile_get_light_occluder(c.id, Vector2(c.autotile_coord_x, c.autotile_coord_y));
} else {
occluder = tile_set->tile_get_light_occluder(c.id);
@@ -631,11 +631,7 @@ void TileMap::_recompute_rect_cache() {
r_total = r_total.merge(r);
}
- if (r_total == Rect2()) {
- rect_cache = Rect2(-10, -10, 20, 20);
- } else {
- rect_cache = r_total.grow(MAX(cell_size.x, cell_size.y) * _get_quadrant_size());
- }
+ rect_cache = r_total;
item_rect_changed();
@@ -721,7 +717,7 @@ void TileMap::_make_quadrant_dirty(Map<PosKey, Quadrant>::Element *Q, bool updat
return;
if (update) {
- _update_dirty_quadrants();
+ call_deferred("update_dirty_quadrants");
}
}
@@ -840,7 +836,7 @@ void TileMap::update_cell_bitmask(int p_x, int p_y) {
Map<PosKey, Cell>::Element *E = tile_map.find(p);
if (E != NULL) {
int id = get_cell(p_x, p_y);
- if (tile_set->tile_get_tile_mode(id) == TileSet::AUTO_TILE) {
+ if (tile_set->tile_get_tile_mode(id) == TileSet::AUTO_TILE || tile_set->tile_get_tile_mode(id) == TileSet::ATLAS_TILE) {
uint16_t mask = 0;
if (tile_set->autotile_get_bitmask_mode(id) == TileSet::BITMASK_2X2) {
if (tile_set->is_tile_bound(id, get_cell(p_x - 1, p_y - 1)) && tile_set->is_tile_bound(id, get_cell(p_x, p_y - 1)) && tile_set->is_tile_bound(id, get_cell(p_x - 1, p_y))) {
@@ -1026,7 +1022,7 @@ void TileMap::_recreate_quadrants() {
Q->get().cells.insert(E->key());
_make_quadrant_dirty(Q, false);
}
- _update_dirty_quadrants();
+ update_dirty_quadrants();
}
void TileMap::_clear_quadrants() {
@@ -1152,6 +1148,11 @@ PoolVector<int> TileMap::_get_tile_data() const {
return data;
}
+Rect2 TileMap::_edit_get_rect() const {
+ const_cast<TileMap *>(this)->update_dirty_quadrants();
+ return rect_cache;
+}
+
void TileMap::set_collision_layer(uint32_t p_layer) {
collision_layer = p_layer;
@@ -1611,7 +1612,7 @@ void TileMap::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_cell", "x", "y", "tile", "flip_x", "flip_y", "transpose", "autotile_coord"), &TileMap::set_cell, DEFVAL(false), DEFVAL(false), DEFVAL(false), DEFVAL(Vector2()));
ClassDB::bind_method(D_METHOD("set_cellv", "position", "tile", "flip_x", "flip_y", "transpose"), &TileMap::set_cellv, DEFVAL(false), DEFVAL(false), DEFVAL(false));
- ClassDB::bind_method(D_METHOD("set_celld", "data"), &TileMap::set_celld);
+ ClassDB::bind_method(D_METHOD("set_celld", "position", "data"), &TileMap::set_celld);
ClassDB::bind_method(D_METHOD("get_cell", "x", "y"), &TileMap::get_cell);
ClassDB::bind_method(D_METHOD("get_cellv", "position"), &TileMap::get_cellv);
ClassDB::bind_method(D_METHOD("is_cell_x_flipped", "x", "y"), &TileMap::is_cell_x_flipped);
@@ -1630,7 +1631,7 @@ void TileMap::_bind_methods() {
ClassDB::bind_method(D_METHOD("_clear_quadrants"), &TileMap::_clear_quadrants);
ClassDB::bind_method(D_METHOD("_recreate_quadrants"), &TileMap::_recreate_quadrants);
- ClassDB::bind_method(D_METHOD("_update_dirty_quadrants"), &TileMap::_update_dirty_quadrants);
+ ClassDB::bind_method(D_METHOD("update_dirty_quadrants"), &TileMap::update_dirty_quadrants);
ClassDB::bind_method(D_METHOD("update_bitmask_area", "position"), &TileMap::update_bitmask_area);
ClassDB::bind_method(D_METHOD("update_bitmask_region", "start", "end"), &TileMap::update_bitmask_region, DEFVAL(Vector2()), DEFVAL(Vector2()));
diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h
index 79d79ca59f..52aa6e8e2a 100644
--- a/scene/2d/tile_map.h
+++ b/scene/2d/tile_map.h
@@ -191,7 +191,6 @@ private:
void _make_quadrant_dirty(Map<PosKey, Quadrant>::Element *Q, bool update = true);
void _recreate_quadrants();
void _clear_quadrants();
- void _update_dirty_quadrants();
void _update_quadrant_space(const RID &p_space);
void _update_quadrant_transform();
void _recompute_rect_cache();
@@ -224,6 +223,8 @@ public:
INVALID_CELL = -1
};
+ virtual Rect2 _edit_get_rect() const;
+
void set_tileset(const Ref<TileSet> &p_tileset);
Ref<TileSet> get_tileset() const;
@@ -251,6 +252,8 @@ public:
void update_cell_bitmask(int p_x, int p_y);
void update_dirty_bitmask();
+ void update_dirty_quadrants();
+
void set_collision_layer(uint32_t p_layer);
uint32_t get_collision_layer() const;
diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp
index d46231a677..8504a18f54 100644
--- a/scene/3d/audio_stream_player_3d.cpp
+++ b/scene/3d/audio_stream_player_3d.cpp
@@ -626,6 +626,7 @@ float AudioStreamPlayer3D::get_max_db() const {
}
void AudioStreamPlayer3D::set_pitch_scale(float p_pitch_scale) {
+ ERR_FAIL_COND(p_pitch_scale <= 0.0);
pitch_scale = p_pitch_scale;
}
float AudioStreamPlayer3D::get_pitch_scale() const {
@@ -991,6 +992,7 @@ AudioStreamPlayer3D::AudioStreamPlayer3D() {
velocity_tracker.instance();
AudioServer::get_singleton()->connect("bus_layout_changed", this, "_bus_layout_changed");
+ set_disable_scale(true);
}
AudioStreamPlayer3D::~AudioStreamPlayer3D() {
}
diff --git a/scene/3d/baked_lightmap.cpp b/scene/3d/baked_lightmap.cpp
index 204aaef7ec..26fd5ed658 100644
--- a/scene/3d/baked_lightmap.cpp
+++ b/scene/3d/baked_lightmap.cpp
@@ -811,4 +811,5 @@ BakedLightmap::BakedLightmap() {
propagation = 1;
hdr = false;
image_path = ".";
+ set_disable_scale(true);
}
diff --git a/scene/3d/camera.cpp b/scene/3d/camera.cpp
index e11e8abe5b..a4582b7d7d 100644
--- a/scene/3d/camera.cpp
+++ b/scene/3d/camera.cpp
@@ -31,9 +31,10 @@
#include "camera.h"
#include "camera_matrix.h"
+#include "collision_object.h"
+#include "engine.h"
#include "scene/resources/material.h"
#include "scene/resources/surface_tool.h"
-
void Camera::_update_audio_listener_state() {
}
@@ -74,10 +75,7 @@ void Camera::_update_camera() {
if (!is_inside_tree())
return;
- Transform tr = get_camera_transform();
- tr.origin += tr.basis.get_axis(1) * v_offset;
- tr.origin += tr.basis.get_axis(0) * h_offset;
- VisualServer::get_singleton()->camera_set_transform(camera, tr);
+ VisualServer::get_singleton()->camera_set_transform(camera, get_camera_transform());
// here goes listener stuff
/*
@@ -143,7 +141,10 @@ void Camera::_notification(int p_what) {
Transform Camera::get_camera_transform() const {
- return get_global_transform().orthonormalized();
+ Transform tr = get_global_transform().orthonormalized();
+ tr.origin += tr.basis.get_axis(1) * v_offset;
+ tr.origin += tr.basis.get_axis(0) * h_offset;
+ return tr;
}
void Camera::set_perspective(float p_fovy_degrees, float p_z_near, float p_z_far) {
@@ -313,6 +314,32 @@ bool Camera::is_position_behind(const Vector3 &p_pos) const {
return eyedir.dot(p_pos) < (eyedir.dot(t.origin) + near);
}
+Vector<Vector3> Camera::get_near_plane_points() const {
+ if (!is_inside_tree()) {
+ ERR_EXPLAIN("Camera is not inside scene.");
+ ERR_FAIL_COND_V(!is_inside_tree(), Vector<Vector3>());
+ }
+
+ Size2 viewport_size = get_viewport()->get_visible_rect().size;
+
+ CameraMatrix cm;
+
+ if (mode == PROJECTION_ORTHOGONAL)
+ cm.set_orthogonal(size, viewport_size.aspect(), near, far, keep_aspect == KEEP_WIDTH);
+ else
+ cm.set_perspective(fov, viewport_size.aspect(), near, far, keep_aspect == KEEP_WIDTH);
+
+ Vector3 endpoints[8];
+ cm.get_endpoints(Transform(), endpoints);
+
+ Vector<Vector3> points;
+ points.push_back(Vector3());
+ for (int i = 0; i < 4; i++) {
+ points.push_back(endpoints[i + 4]);
+ }
+ return points;
+}
+
Point2 Camera::unproject_position(const Vector3 &p_pos) const {
if (!is_inside_tree()) {
@@ -468,6 +495,10 @@ void Camera::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_keep_aspect_mode"), &Camera::get_keep_aspect_mode);
ClassDB::bind_method(D_METHOD("set_doppler_tracking", "mode"), &Camera::set_doppler_tracking);
ClassDB::bind_method(D_METHOD("get_doppler_tracking"), &Camera::get_doppler_tracking);
+
+ ClassDB::bind_method(D_METHOD("set_cull_mask_bit", "layer", "enable"), &Camera::set_cull_mask_bit);
+ ClassDB::bind_method(D_METHOD("get_cull_mask_bit", "layer"), &Camera::get_cull_mask_bit);
+
//ClassDB::bind_method(D_METHOD("_camera_make_current"),&Camera::_camera_make_current );
ADD_PROPERTY(PropertyInfo(Variant::INT, "keep_aspect", PROPERTY_HINT_ENUM, "Keep Width,Keep Height"), "set_keep_aspect_mode", "get_keep_aspect_mode");
@@ -480,7 +511,7 @@ void Camera::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "current"), "set_current", "is_current");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "fov", PROPERTY_HINT_RANGE, "1,179,0.1"), "set_fov", "get_fov");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "size", PROPERTY_HINT_RANGE, "0.1,16384,0.01"), "set_size", "get_size");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "near", PROPERTY_HINT_EXP_RANGE, "0.1,8192,0.1,or_greater"), "set_znear", "get_znear");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "near", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01,or_greater"), "set_znear", "get_znear");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "far", PROPERTY_HINT_EXP_RANGE, "0.1,8192,0.1,or_greater"), "set_zfar", "get_zfar");
BIND_ENUM_CONSTANT(PROJECTION_PERSPECTIVE);
@@ -550,6 +581,20 @@ uint32_t Camera::get_cull_mask() const {
return layers;
}
+void Camera::set_cull_mask_bit(int p_layer, bool p_enable) {
+ ERR_FAIL_INDEX(p_layer, 32);
+ if (p_enable) {
+ set_cull_mask(layers | (1 << p_layer));
+ } else {
+ set_cull_mask(layers & (~(1 << p_layer)));
+ }
+}
+
+bool Camera::get_cull_mask_bit(int p_layer) const {
+ ERR_FAIL_INDEX_V(p_layer, 32, false);
+ return (layers & (1 << p_layer));
+}
+
Vector<Plane> Camera::get_frustum() const {
ERR_FAIL_COND_V(!is_inside_world(), Vector<Plane>());
@@ -613,9 +658,231 @@ Camera::Camera() {
velocity_tracker.instance();
doppler_tracking = DOPPLER_TRACKING_DISABLED;
set_notify_transform(true);
+ set_disable_scale(true);
}
Camera::~Camera() {
VisualServer::get_singleton()->free(camera);
}
+
+////////////////////////////////////////
+
+void ClippedCamera::set_margin(float p_margin) {
+ margin = p_margin;
+}
+float ClippedCamera::get_margin() const {
+ return margin;
+}
+void ClippedCamera::set_process_mode(ProcessMode p_mode) {
+
+ if (process_mode == p_mode) {
+ return;
+ }
+ set_process_internal(p_mode == CLIP_PROCESS_IDLE);
+ set_physics_process_internal(p_mode == CLIP_PROCESS_PHYSICS);
+}
+ClippedCamera::ProcessMode ClippedCamera::get_process_mode() const {
+ return process_mode;
+}
+
+Transform ClippedCamera::get_camera_transform() const {
+
+ Transform t = Camera::get_camera_transform();
+ t.origin += -t.basis.get_axis(Vector3::AXIS_Z).normalized() * clip_offset;
+ return t;
+}
+
+void ClippedCamera::_notification(int p_what) {
+ if (p_what == NOTIFICATION_INTERNAL_PROCESS || p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS) {
+
+ Spatial *parent = Object::cast_to<Spatial>(get_parent());
+ if (!parent) {
+ return;
+ }
+
+ PhysicsDirectSpaceState *dspace = get_world()->get_direct_space_state();
+ ERR_FAIL_COND(!dspace); // most likely physics set to threads
+
+ Vector3 cam_fw = -get_global_transform().basis.get_axis(Vector3::AXIS_Z).normalized();
+ Vector3 cam_pos = get_global_transform().origin;
+ Vector3 parent_pos = parent->get_global_transform().origin;
+
+ Plane parent_plane(parent_pos, cam_fw);
+
+ if (parent_plane.is_point_over(cam_pos)) {
+ //cam is beyond parent plane
+ return;
+ }
+
+ Vector3 ray_from = parent_plane.project(cam_pos);
+
+ clip_offset = 0; //reset by defau;t
+
+ { //check if points changed
+ Vector<Vector3> local_points = get_near_plane_points();
+
+ bool all_equal = true;
+
+ for (int i = 0; i < 5; i++) {
+ if (points[i] != local_points[i]) {
+ all_equal = false;
+ break;
+ }
+ }
+
+ if (!all_equal) {
+ PhysicsServer::get_singleton()->shape_set_data(pyramid_shape, local_points);
+ points = local_points;
+ }
+ }
+
+ Transform xf = get_global_transform();
+ xf.origin = ray_from;
+ xf.orthonormalize();
+
+ float csafe, cunsafe;
+ if (dspace->cast_motion(pyramid_shape, xf, cam_pos - ray_from, margin, csafe, cunsafe, exclude, collision_mask, clip_to_bodies, clip_to_areas)) {
+ clip_offset = cam_pos.distance_to(ray_from + (cam_pos - ray_from).normalized() * csafe);
+ }
+
+ _update_camera();
+ }
+
+ if (p_what == NOTIFICATION_LOCAL_TRANSFORM_CHANGED) {
+ update_gizmo();
+ }
+}
+
+void ClippedCamera::set_collision_mask(uint32_t p_mask) {
+
+ collision_mask = p_mask;
+}
+
+uint32_t ClippedCamera::get_collision_mask() const {
+
+ return collision_mask;
+}
+
+void ClippedCamera::set_collision_mask_bit(int p_bit, bool p_value) {
+
+ uint32_t mask = get_collision_mask();
+ if (p_value)
+ mask |= 1 << p_bit;
+ else
+ mask &= ~(1 << p_bit);
+ set_collision_mask(mask);
+}
+
+bool ClippedCamera::get_collision_mask_bit(int p_bit) const {
+
+ return get_collision_mask() & (1 << p_bit);
+}
+
+void ClippedCamera::add_exception_rid(const RID &p_rid) {
+
+ exclude.insert(p_rid);
+}
+
+void ClippedCamera::add_exception(const Object *p_object) {
+
+ ERR_FAIL_NULL(p_object);
+ const CollisionObject *co = Object::cast_to<CollisionObject>(p_object);
+ if (!co)
+ return;
+ add_exception_rid(co->get_rid());
+}
+
+void ClippedCamera::remove_exception_rid(const RID &p_rid) {
+
+ exclude.erase(p_rid);
+}
+
+void ClippedCamera::remove_exception(const Object *p_object) {
+
+ ERR_FAIL_NULL(p_object);
+ const CollisionObject *co = Object::cast_to<CollisionObject>(p_object);
+ if (!co)
+ return;
+ remove_exception_rid(co->get_rid());
+}
+
+void ClippedCamera::clear_exceptions() {
+
+ exclude.clear();
+}
+
+void ClippedCamera::set_clip_to_areas(bool p_clip) {
+
+ clip_to_areas = p_clip;
+}
+
+bool ClippedCamera::is_clip_to_areas_enabled() const {
+
+ return clip_to_areas;
+}
+
+void ClippedCamera::set_clip_to_bodies(bool p_clip) {
+
+ clip_to_bodies = p_clip;
+}
+
+bool ClippedCamera::is_clip_to_bodies_enabled() const {
+
+ return clip_to_bodies;
+}
+
+void ClippedCamera::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_margin", "margin"), &ClippedCamera::set_margin);
+ ClassDB::bind_method(D_METHOD("get_margin"), &ClippedCamera::get_margin);
+
+ ClassDB::bind_method(D_METHOD("set_process_mode", "process_mode"), &ClippedCamera::set_process_mode);
+ ClassDB::bind_method(D_METHOD("get_process_mode"), &ClippedCamera::get_process_mode);
+
+ ClassDB::bind_method(D_METHOD("set_collision_mask", "mask"), &ClippedCamera::set_collision_mask);
+ ClassDB::bind_method(D_METHOD("get_collision_mask"), &ClippedCamera::get_collision_mask);
+
+ ClassDB::bind_method(D_METHOD("set_collision_mask_bit", "bit", "value"), &ClippedCamera::set_collision_mask_bit);
+ ClassDB::bind_method(D_METHOD("get_collision_mask_bit", "bit"), &ClippedCamera::get_collision_mask_bit);
+
+ ClassDB::bind_method(D_METHOD("add_exception_rid", "rid"), &ClippedCamera::add_exception_rid);
+ ClassDB::bind_method(D_METHOD("add_exception", "node"), &ClippedCamera::add_exception);
+
+ ClassDB::bind_method(D_METHOD("remove_exception_rid", "rid"), &ClippedCamera::remove_exception_rid);
+ ClassDB::bind_method(D_METHOD("remove_exception", "node"), &ClippedCamera::remove_exception);
+
+ ClassDB::bind_method(D_METHOD("set_clip_to_areas", "enable"), &ClippedCamera::set_clip_to_areas);
+ ClassDB::bind_method(D_METHOD("is_clip_to_areas_enabled"), &ClippedCamera::is_clip_to_areas_enabled);
+
+ ClassDB::bind_method(D_METHOD("set_clip_to_bodies", "enable"), &ClippedCamera::set_clip_to_bodies);
+ ClassDB::bind_method(D_METHOD("is_clip_to_bodies_enabled"), &ClippedCamera::is_clip_to_bodies_enabled);
+
+ ClassDB::bind_method(D_METHOD("clear_exceptions"), &ClippedCamera::clear_exceptions);
+
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "margin", PROPERTY_HINT_RANGE, "0,32,0.01"), "set_margin", "get_margin");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_process_mode", "get_process_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask");
+
+ ADD_GROUP("Clip To", "clip_to");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clip_to_areas", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_clip_to_areas", "is_clip_to_areas_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clip_to_bodies", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_clip_to_bodies", "is_clip_to_bodies_enabled");
+
+ BIND_ENUM_CONSTANT(CLIP_PROCESS_PHYSICS);
+ BIND_ENUM_CONSTANT(CLIP_PROCESS_IDLE);
+}
+ClippedCamera::ClippedCamera() {
+ margin = 0;
+ clip_offset = 0;
+ process_mode = CLIP_PROCESS_PHYSICS;
+ set_physics_process_internal(true);
+ collision_mask = 1;
+ set_notify_local_transform(Engine::get_singleton()->is_editor_hint());
+ points.resize(5);
+ pyramid_shape = PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_CONVEX_POLYGON);
+ clip_to_areas = false;
+ clip_to_bodies = true;
+}
+ClippedCamera::~ClippedCamera() {
+ PhysicsServer::get_singleton()->free(pyramid_shape);
+}
diff --git a/scene/3d/camera.h b/scene/3d/camera.h
index 1b506e0c4f..a35c9d6e7f 100644
--- a/scene/3d/camera.h
+++ b/scene/3d/camera.h
@@ -139,9 +139,14 @@ public:
bool is_position_behind(const Vector3 &p_pos) const;
virtual Vector3 project_position(const Point2 &p_point) const;
+ Vector<Vector3> get_near_plane_points() const;
+
void set_cull_mask(uint32_t p_layers);
uint32_t get_cull_mask() const;
+ void set_cull_mask_bit(int p_layer, bool p_enable);
+ bool get_cull_mask_bit(int p_layer) const;
+
virtual Vector<Plane> get_frustum() const;
void set_environment(const Ref<Environment> &p_environment);
@@ -169,4 +174,62 @@ VARIANT_ENUM_CAST(Camera::Projection);
VARIANT_ENUM_CAST(Camera::KeepAspect);
VARIANT_ENUM_CAST(Camera::DopplerTracking);
+class ClippedCamera : public Camera {
+
+ GDCLASS(ClippedCamera, Camera);
+
+public:
+ enum ProcessMode {
+ CLIP_PROCESS_PHYSICS,
+ CLIP_PROCESS_IDLE,
+ };
+
+private:
+ ProcessMode process_mode;
+ RID pyramid_shape;
+ float margin;
+ float clip_offset;
+ uint32_t collision_mask;
+ bool clip_to_areas;
+ bool clip_to_bodies;
+
+ Set<RID> exclude;
+
+ Vector<Vector3> points;
+
+protected:
+ void _notification(int p_what);
+ static void _bind_methods();
+ virtual Transform get_camera_transform() const;
+
+public:
+ void set_clip_to_areas(bool p_clip);
+ bool is_clip_to_areas_enabled() const;
+
+ void set_clip_to_bodies(bool p_clip);
+ bool is_clip_to_bodies_enabled() const;
+
+ void set_margin(float p_margin);
+ float get_margin() const;
+
+ void set_process_mode(ProcessMode p_mode);
+ ProcessMode get_process_mode() const;
+
+ void set_collision_mask(uint32_t p_mask);
+ uint32_t get_collision_mask() const;
+
+ void set_collision_mask_bit(int p_bit, bool p_value);
+ bool get_collision_mask_bit(int p_bit) const;
+
+ void add_exception_rid(const RID &p_rid);
+ void add_exception(const Object *p_object);
+ void remove_exception_rid(const RID &p_rid);
+ void remove_exception(const Object *p_object);
+ void clear_exceptions();
+
+ ClippedCamera();
+ ~ClippedCamera();
+};
+
+VARIANT_ENUM_CAST(ClippedCamera::ProcessMode);
#endif
diff --git a/scene/3d/collision_object.cpp b/scene/3d/collision_object.cpp
index 1d5d1b2afe..e19e45b263 100644
--- a/scene/3d/collision_object.cpp
+++ b/scene/3d/collision_object.cpp
@@ -305,7 +305,7 @@ void CollisionObject::shape_owner_remove_shape(uint32_t p_owner, int p_shape) {
for (Map<uint32_t, ShapeData>::Element *E = shapes.front(); E; E = E->next()) {
for (int i = 0; i < E->get().shapes.size(); i++) {
if (E->get().shapes[i].index > index_to_remove) {
- E->get().shapes[i].index -= 1;
+ E->get().shapes.write[i].index -= 1;
}
}
}
diff --git a/scene/3d/collision_object.h b/scene/3d/collision_object.h
index f31d65e411..f8ef04b78f 100644
--- a/scene/3d/collision_object.h
+++ b/scene/3d/collision_object.h
@@ -39,6 +39,7 @@ class CollisionObject : public Spatial {
GDCLASS(CollisionObject, Spatial);
bool area;
+
RID rid;
struct ShapeData {
diff --git a/scene/3d/collision_shape.h b/scene/3d/collision_shape.h
index c9c91a5824..6ca8e80ea1 100644
--- a/scene/3d/collision_shape.h
+++ b/scene/3d/collision_shape.h
@@ -49,6 +49,7 @@ class CollisionShape : public Spatial {
void resource_changed(RES res);
bool disabled;
+protected:
void _create_debug_shape();
void _update_in_shape_owner(bool p_xform_only = false);
diff --git a/scene/3d/cpu_particles.cpp b/scene/3d/cpu_particles.cpp
index 2e897c1c73..8b2000d2e9 100644
--- a/scene/3d/cpu_particles.cpp
+++ b/scene/3d/cpu_particles.cpp
@@ -25,6 +25,8 @@ void CPUParticles::set_emitting(bool p_emitting) {
update_mutex->lock();
#endif
VS::get_singleton()->connect("frame_pre_draw", this, "_update_render_thread");
+ VS::get_singleton()->instance_geometry_set_flag(get_instance(), VS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE, true);
+
#ifndef NO_THREADS
update_mutex->unlock();
#endif
@@ -446,6 +448,8 @@ float rand_from_seed_m1_p1(uint32_t &seed) {
void CPUParticles::_particles_process(float p_delta) {
+ p_delta *= speed_scale;
+
int pcount = particles.size();
PoolVector<Particle>::Write w = particles.write();
@@ -475,7 +479,7 @@ void CPUParticles::_particles_process(float p_delta) {
if (!emitting && !p.active)
continue;
- float restart_time = float(i) / float(pcount);
+ float restart_time = (float(i) / float(pcount)) * lifetime;
float local_delta = p_delta;
if (randomness_ratio > 0.0) {
@@ -643,7 +647,7 @@ void CPUParticles::_particles_process(float p_delta) {
uint32_t alt_seed = p.seed;
p.time += local_delta;
- p.custom[1] += p.time / lifetime;
+ p.custom[1] = p.time / lifetime;
float tex_linear_velocity = 0.0;
if (curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) {
@@ -979,6 +983,7 @@ void CPUParticles::_notification(int p_what) {
update_mutex->lock();
#endif
VS::get_singleton()->connect("frame_pre_draw", this, "_update_render_thread");
+ VS::get_singleton()->instance_geometry_set_flag(get_instance(), VS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE, true);
#ifndef NO_THREADS
update_mutex->unlock();
#endif
@@ -992,6 +997,7 @@ void CPUParticles::_notification(int p_what) {
update_mutex->lock();
#endif
VS::get_singleton()->disconnect("frame_pre_draw", this, "_update_render_thread");
+ VS::get_singleton()->instance_geometry_set_flag(get_instance(), VS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE, false);
#ifndef NO_THREADS
update_mutex->unlock();
#endif
@@ -1018,6 +1024,8 @@ void CPUParticles::_notification(int p_what) {
update_mutex->lock();
#endif
VS::get_singleton()->disconnect("frame_pre_draw", this, "_update_render_thread");
+ VS::get_singleton()->instance_geometry_set_flag(get_instance(), VS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE, false);
+
#ifndef NO_THREADS
update_mutex->unlock();
#endif
diff --git a/scene/3d/gi_probe.cpp b/scene/3d/gi_probe.cpp
index 4ad2eb60ee..6276d02eff 100644
--- a/scene/3d/gi_probe.cpp
+++ b/scene/3d/gi_probe.cpp
@@ -557,6 +557,7 @@ GIProbe::GIProbe() {
compress = false;
gi_probe = VS::get_singleton()->gi_probe_create();
+ set_disable_scale(true);
}
GIProbe::~GIProbe() {
diff --git a/scene/3d/light.cpp b/scene/3d/light.cpp
index 7c42638107..16164cf3bf 100644
--- a/scene/3d/light.cpp
+++ b/scene/3d/light.cpp
@@ -306,6 +306,7 @@ Light::Light(VisualServer::LightType p_type) {
set_param(PARAM_SHADOW_SPLIT_3_OFFSET, 0.5);
set_param(PARAM_SHADOW_NORMAL_BIAS, 0.0);
set_param(PARAM_SHADOW_BIAS, 0.15);
+ set_disable_scale(true);
}
Light::Light() {
diff --git a/scene/3d/mesh_instance.cpp b/scene/3d/mesh_instance.cpp
index e836a6154a..e277cae5b7 100644
--- a/scene/3d/mesh_instance.cpp
+++ b/scene/3d/mesh_instance.cpp
@@ -36,6 +36,7 @@
#include "scene/resources/material.h"
#include "scene/scene_string_names.h"
#include "skeleton.h"
+
bool MeshInstance::_set(const StringName &p_name, const Variant &p_value) {
//this is not _too_ bad performance wise, really. it only arrives here if the property was not set anywhere else.
@@ -256,7 +257,7 @@ void MeshInstance::set_surface_material(int p_surface, const Ref<Material> &p_ma
ERR_FAIL_INDEX(p_surface, materials.size());
- materials[p_surface] = p_material;
+ materials.write[p_surface] = p_material;
if (materials[p_surface].is_valid())
VS::get_singleton()->instance_set_surface_material(get_instance(), p_surface, materials[p_surface]->get_rid());
diff --git a/scene/3d/mesh_instance.h b/scene/3d/mesh_instance.h
index 5d359cd4d5..0dfec538f9 100644
--- a/scene/3d/mesh_instance.h
+++ b/scene/3d/mesh_instance.h
@@ -41,6 +41,7 @@ class MeshInstance : public GeometryInstance {
GDCLASS(MeshInstance, GeometryInstance);
+protected:
Ref<Mesh> mesh;
NodePath skeleton_path;
diff --git a/scene/3d/navigation.cpp b/scene/3d/navigation.cpp
index 77bf703706..f5b77d361c 100644
--- a/scene/3d/navigation.cpp
+++ b/scene/3d/navigation.cpp
@@ -73,7 +73,7 @@ void Navigation::_navmesh_link(int p_id) {
Vector3 ep = nm.xform.xform(r[idx]);
center += ep;
e.point = _get_point(ep);
- p.edges[j] = e;
+ p.edges.write[j] = e;
if (j >= 2) {
Vector3 epa = nm.xform.xform(r[indices[j - 2]]);
@@ -118,7 +118,7 @@ void Navigation::_navmesh_link(int p_id) {
ConnectionPending pending;
pending.polygon = &p;
pending.edge = j;
- p.edges[j].P = C->get().pending.push_back(pending);
+ p.edges.write[j].P = C->get().pending.push_back(pending);
continue;
//print_line(String()+_get_vertex(ek.a)+" -> "+_get_vertex(ek.b));
}
@@ -126,10 +126,10 @@ void Navigation::_navmesh_link(int p_id) {
C->get().B = &p;
C->get().B_edge = j;
- C->get().A->edges[C->get().A_edge].C = &p;
- C->get().A->edges[C->get().A_edge].C_edge = j;
- p.edges[j].C = C->get().A;
- p.edges[j].C_edge = C->get().A_edge;
+ C->get().A->edges.write[C->get().A_edge].C = &p;
+ C->get().A->edges.write[C->get().A_edge].C_edge = j;
+ p.edges.write[j].C = C->get().A;
+ p.edges.write[j].C_edge = C->get().A_edge;
//connection successful.
}
}
@@ -165,10 +165,10 @@ void Navigation::_navmesh_unlink(int p_id) {
} else if (C->get().B) {
//disconnect
- C->get().B->edges[C->get().B_edge].C = NULL;
- C->get().B->edges[C->get().B_edge].C_edge = -1;
- C->get().A->edges[C->get().A_edge].C = NULL;
- C->get().A->edges[C->get().A_edge].C_edge = -1;
+ C->get().B->edges.write[C->get().B_edge].C = NULL;
+ C->get().B->edges.write[C->get().B_edge].C_edge = -1;
+ C->get().A->edges.write[C->get().A_edge].C = NULL;
+ C->get().A->edges.write[C->get().A_edge].C_edge = -1;
if (C->get().A == &E->get()) {
@@ -185,11 +185,11 @@ void Navigation::_navmesh_unlink(int p_id) {
C->get().B = cp.polygon;
C->get().B_edge = cp.edge;
- C->get().A->edges[C->get().A_edge].C = cp.polygon;
- C->get().A->edges[C->get().A_edge].C_edge = cp.edge;
- cp.polygon->edges[cp.edge].C = C->get().A;
- cp.polygon->edges[cp.edge].C_edge = C->get().A_edge;
- cp.polygon->edges[cp.edge].P = NULL;
+ C->get().A->edges.write[C->get().A_edge].C = cp.polygon;
+ C->get().A->edges.write[C->get().A_edge].C_edge = cp.edge;
+ cp.polygon->edges.write[cp.edge].C = C->get().A;
+ cp.polygon->edges.write[cp.edge].C_edge = C->get().A_edge;
+ cp.polygon->edges.write[cp.edge].P = NULL;
}
} else {
@@ -320,8 +320,8 @@ Vector<Vector3> Navigation::get_simple_path(const Vector3 &p_start, const Vector
Vector<Vector3> path;
path.resize(2);
- path[0] = begin_point;
- path[1] = end_point;
+ path.write[0] = begin_point;
+ path.write[1] = end_point;
//print_line("Direct Path");
return path;
}
@@ -375,7 +375,7 @@ Vector<Vector3> Navigation::get_simple_path(const Vector3 &p_start, const Vector
for (int i = 0; i < p->edges.size(); i++) {
- Polygon::Edge &e = p->edges[i];
+ Polygon::Edge &e = p->edges.write[i];
if (!e.C)
continue;
diff --git a/scene/3d/navigation_mesh.cpp b/scene/3d/navigation_mesh.cpp
index 073e56fdb4..99680b7273 100644
--- a/scene/3d/navigation_mesh.cpp
+++ b/scene/3d/navigation_mesh.cpp
@@ -55,9 +55,9 @@ void NavigationMesh::create_from_mesh(const Ref<Mesh> &p_mesh) {
for (int j = 0; j < rlen; j += 3) {
Vector<int> vi;
vi.resize(3);
- vi[0] = r[j + 0] + from;
- vi[1] = r[j + 1] + from;
- vi[2] = r[j + 2] + from;
+ vi.write[0] = r[j + 0] + from;
+ vi.write[1] = r[j + 1] + from;
+ vi.write[2] = r[j + 2] + from;
add_polygon(vi);
}
@@ -215,7 +215,7 @@ void NavigationMesh::_set_polygons(const Array &p_array) {
polygons.resize(p_array.size());
for (int i = 0; i < p_array.size(); i++) {
- polygons[i].indices = p_array[i];
+ polygons.write[i].indices = p_array[i];
}
}
diff --git a/scene/3d/particles.cpp b/scene/3d/particles.cpp
index 2b3a62fcdc..4900692155 100644
--- a/scene/3d/particles.cpp
+++ b/scene/3d/particles.cpp
@@ -185,7 +185,7 @@ void Particles::set_draw_pass_mesh(int p_pass, const Ref<Mesh> &p_mesh) {
ERR_FAIL_INDEX(p_pass, draw_passes.size());
- draw_passes[p_pass] = p_mesh;
+ draw_passes.write[p_pass] = p_mesh;
RID mesh_rid;
if (p_mesh.is_valid())
diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp
index e851c8d643..2df6ef7c8a 100644
--- a/scene/3d/physics_body.cpp
+++ b/scene/3d/physics_body.cpp
@@ -30,6 +30,7 @@
#include "physics_body.h"
+#include "core/core_string_names.h"
#include "engine.h"
#include "method_bind_ext.gen.inc"
#include "scene/scene_string_names.h"
@@ -121,23 +122,23 @@ bool PhysicsBody::get_collision_layer_bit(int p_bit) const {
void PhysicsBody::add_collision_exception_with(Node *p_node) {
ERR_FAIL_NULL(p_node);
- PhysicsBody *physics_body = Object::cast_to<PhysicsBody>(p_node);
- if (!physics_body) {
- ERR_EXPLAIN("Collision exception only works between two objects of PhysicsBody type");
+ CollisionObject *collision_object = Object::cast_to<CollisionObject>(p_node);
+ if (!collision_object) {
+ ERR_EXPLAIN("Collision exception only works between two CollisionObject");
}
- ERR_FAIL_COND(!physics_body);
- PhysicsServer::get_singleton()->body_add_collision_exception(get_rid(), physics_body->get_rid());
+ ERR_FAIL_COND(!collision_object);
+ PhysicsServer::get_singleton()->body_add_collision_exception(get_rid(), collision_object->get_rid());
}
void PhysicsBody::remove_collision_exception_with(Node *p_node) {
ERR_FAIL_NULL(p_node);
- PhysicsBody *physics_body = Object::cast_to<PhysicsBody>(p_node);
- if (!physics_body) {
- ERR_EXPLAIN("Collision exception only works between two objects of PhysicsBody type");
+ CollisionObject *collision_object = Object::cast_to<CollisionObject>(p_node);
+ if (!collision_object) {
+ ERR_EXPLAIN("Collision exception only works between two CollisionObject");
}
- ERR_FAIL_COND(!physics_body);
- PhysicsServer::get_singleton()->body_remove_collision_exception(get_rid(), physics_body->get_rid());
+ ERR_FAIL_COND(!collision_object);
+ PhysicsServer::get_singleton()->body_remove_collision_exception(get_rid(), collision_object->get_rid());
}
void PhysicsBody::_set_layers(uint32_t p_mask) {
@@ -178,28 +179,77 @@ PhysicsBody::PhysicsBody(PhysicsServer::BodyMode p_mode) :
collision_mask = 1;
}
+#ifndef DISABLE_DEPRECATED
void StaticBody::set_friction(real_t p_friction) {
+ ERR_EXPLAIN("The method set_friction has been deprecated and will be removed in the future, use physical material")
+ WARN_DEPRECATED
+
ERR_FAIL_COND(p_friction < 0 || p_friction > 1);
- friction = p_friction;
- PhysicsServer::get_singleton()->body_set_param(get_rid(), PhysicsServer::BODY_PARAM_FRICTION, friction);
+ if (physics_material_override.is_null()) {
+ physics_material_override.instance();
+ set_physics_material_override(physics_material_override);
+ }
+
+ physics_material_override->set_friction(p_friction);
}
+
real_t StaticBody::get_friction() const {
- return friction;
+ ERR_EXPLAIN("The method get_friction has been deprecated and will be removed in the future, use physical material")
+ WARN_DEPRECATED
+
+ if (physics_material_override.is_null()) {
+ return 1;
+ }
+
+ return physics_material_override->get_friction();
}
void StaticBody::set_bounce(real_t p_bounce) {
+ ERR_EXPLAIN("The method set_bounce has been deprecated and will be removed in the future, use physical material")
+ WARN_DEPRECATED
+
ERR_FAIL_COND(p_bounce < 0 || p_bounce > 1);
- bounce = p_bounce;
- PhysicsServer::get_singleton()->body_set_param(get_rid(), PhysicsServer::BODY_PARAM_BOUNCE, bounce);
+ if (physics_material_override.is_null()) {
+ physics_material_override.instance();
+ set_physics_material_override(physics_material_override);
+ }
+ physics_material_override->set_bounce(p_bounce);
}
+
real_t StaticBody::get_bounce() const {
- return bounce;
+ ERR_EXPLAIN("The method get_bounce has been deprecated and will be removed in the future, use physical material")
+ WARN_DEPRECATED
+
+ if (physics_material_override.is_null()) {
+ return 0;
+ }
+
+ return physics_material_override->get_bounce();
+}
+#endif
+
+void StaticBody::set_physics_material_override(const Ref<PhysicsMaterial> &p_physics_material_override) {
+ if (physics_material_override.is_valid()) {
+ if (physics_material_override->is_connected(CoreStringNames::get_singleton()->changed, this, "_reload_physics_characteristics"))
+ physics_material_override->disconnect(CoreStringNames::get_singleton()->changed, this, "_reload_physics_characteristics");
+ }
+
+ physics_material_override = p_physics_material_override;
+
+ if (physics_material_override.is_valid()) {
+ physics_material_override->connect(CoreStringNames::get_singleton()->changed, this, "_reload_physics_characteristics");
+ }
+ _reload_physics_characteristics();
+}
+
+Ref<PhysicsMaterial> StaticBody::get_physics_material_override() const {
+ return physics_material_override;
}
void StaticBody::set_constant_linear_velocity(const Vector3 &p_vel) {
@@ -230,30 +280,45 @@ void StaticBody::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_constant_linear_velocity"), &StaticBody::get_constant_linear_velocity);
ClassDB::bind_method(D_METHOD("get_constant_angular_velocity"), &StaticBody::get_constant_angular_velocity);
+#ifndef DISABLE_DEPRECATED
ClassDB::bind_method(D_METHOD("set_friction", "friction"), &StaticBody::set_friction);
ClassDB::bind_method(D_METHOD("get_friction"), &StaticBody::get_friction);
ClassDB::bind_method(D_METHOD("set_bounce", "bounce"), &StaticBody::set_bounce);
ClassDB::bind_method(D_METHOD("get_bounce"), &StaticBody::get_bounce);
+#endif // DISABLE_DEPRECATED
+
+ ClassDB::bind_method(D_METHOD("set_physics_material_override", "physics_material_override"), &StaticBody::set_physics_material_override);
+ ClassDB::bind_method(D_METHOD("get_physics_material_override"), &StaticBody::get_physics_material_override);
+
+ ClassDB::bind_method(D_METHOD("_reload_physics_characteristics"), &StaticBody::_reload_physics_characteristics);
ClassDB::bind_method(D_METHOD("add_collision_exception_with", "body"), &PhysicsBody::add_collision_exception_with);
ClassDB::bind_method(D_METHOD("remove_collision_exception_with", "body"), &PhysicsBody::remove_collision_exception_with);
+#ifndef DISABLE_DEPRECATED
ADD_PROPERTY(PropertyInfo(Variant::REAL, "friction", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_friction", "get_friction");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "bounce", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_bounce", "get_bounce");
-
+#endif // DISABLE_DEPRECATED
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "physics_material_override", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), "set_physics_material_override", "get_physics_material_override");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "constant_linear_velocity"), "set_constant_linear_velocity", "get_constant_linear_velocity");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "constant_angular_velocity"), "set_constant_angular_velocity", "get_constant_angular_velocity");
}
StaticBody::StaticBody() :
PhysicsBody(PhysicsServer::BODY_MODE_STATIC) {
-
- bounce = 0;
- friction = 1;
}
-StaticBody::~StaticBody() {
+StaticBody::~StaticBody() {}
+
+void StaticBody::_reload_physics_characteristics() {
+ if (physics_material_override.is_null()) {
+ PhysicsServer::get_singleton()->body_set_param(get_rid(), PhysicsServer::BODY_PARAM_BOUNCE, 0);
+ PhysicsServer::get_singleton()->body_set_param(get_rid(), PhysicsServer::BODY_PARAM_FRICTION, 1);
+ } else {
+ PhysicsServer::get_singleton()->body_set_param(get_rid(), PhysicsServer::BODY_PARAM_BOUNCE, physics_material_override->computed_bounce());
+ PhysicsServer::get_singleton()->body_set_param(get_rid(), PhysicsServer::BODY_PARAM_FRICTION, physics_material_override->computed_friction());
+ }
}
void RigidBody::_body_enter_tree(ObjectID p_id) {
@@ -550,28 +615,68 @@ real_t RigidBody::get_weight() const {
return mass * real_t(GLOBAL_DEF("physics/3d/default_gravity", 9.8));
}
+#ifndef DISABLE_DEPRECATED
void RigidBody::set_friction(real_t p_friction) {
+ ERR_EXPLAIN("The method set_friction has been deprecated and will be removed in the future, use physical material")
+ WARN_DEPRECATED
ERR_FAIL_COND(p_friction < 0 || p_friction > 1);
- friction = p_friction;
- PhysicsServer::get_singleton()->body_set_param(get_rid(), PhysicsServer::BODY_PARAM_FRICTION, friction);
+ if (physics_material_override.is_null()) {
+ physics_material_override.instance();
+ set_physics_material_override(physics_material_override);
+ }
+ physics_material_override->set_friction(p_friction);
}
real_t RigidBody::get_friction() const {
- return friction;
+ ERR_EXPLAIN("The method get_friction has been deprecated and will be removed in the future, use physical material")
+ WARN_DEPRECATED
+ if (physics_material_override.is_null()) {
+ return 1;
+ }
+
+ return physics_material_override->get_friction();
}
void RigidBody::set_bounce(real_t p_bounce) {
-
+ ERR_EXPLAIN("The method set_bounce has been deprecated and will be removed in the future, use physical material")
+ WARN_DEPRECATED
ERR_FAIL_COND(p_bounce < 0 || p_bounce > 1);
- bounce = p_bounce;
- PhysicsServer::get_singleton()->body_set_param(get_rid(), PhysicsServer::BODY_PARAM_BOUNCE, bounce);
+ if (physics_material_override.is_null()) {
+ physics_material_override.instance();
+ set_physics_material_override(physics_material_override);
+ }
+ physics_material_override->set_bounce(p_bounce);
}
real_t RigidBody::get_bounce() const {
+ ERR_EXPLAIN("The method get_bounce has been deprecated and will be removed in the future, use physical material")
+ WARN_DEPRECATED
+ if (physics_material_override.is_null()) {
+ return 0;
+ }
- return bounce;
+ return physics_material_override->get_bounce();
+}
+#endif // DISABLE_DEPRECATED
+
+void RigidBody::set_physics_material_override(const Ref<PhysicsMaterial> &p_physics_material_override) {
+ if (physics_material_override.is_valid()) {
+ if (physics_material_override->is_connected(CoreStringNames::get_singleton()->changed, this, "_reload_physics_characteristics"))
+ physics_material_override->disconnect(CoreStringNames::get_singleton()->changed, this, "_reload_physics_characteristics");
+ }
+
+ physics_material_override = p_physics_material_override;
+
+ if (physics_material_override.is_valid()) {
+ physics_material_override->connect(CoreStringNames::get_singleton()->changed, this, "_reload_physics_characteristics");
+ }
+ _reload_physics_characteristics();
+}
+
+Ref<PhysicsMaterial> RigidBody::get_physics_material_override() const {
+ return physics_material_override;
}
void RigidBody::set_gravity_scale(real_t p_gravity_scale) {
@@ -693,6 +798,22 @@ int RigidBody::get_max_contacts_reported() const {
return max_contacts_reported;
}
+void RigidBody::add_central_force(const Vector3 &p_force) {
+ PhysicsServer::get_singleton()->body_add_central_force(get_rid(), p_force);
+}
+
+void RigidBody::add_force(const Vector3 &p_force, const Vector3 &p_pos) {
+ PhysicsServer::get_singleton()->body_add_force(get_rid(), p_force, p_pos);
+}
+
+void RigidBody::add_torque(const Vector3 &p_torque) {
+ PhysicsServer::get_singleton()->body_add_torque(get_rid(), p_torque);
+}
+
+void RigidBody::apply_central_impulse(const Vector3 &p_impulse) {
+ PhysicsServer::get_singleton()->body_apply_central_impulse(get_rid(), p_impulse);
+}
+
void RigidBody::apply_impulse(const Vector3 &p_pos, const Vector3 &p_impulse) {
PhysicsServer::get_singleton()->body_apply_impulse(get_rid(), p_pos, p_impulse);
@@ -806,11 +927,18 @@ void RigidBody::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_weight", "weight"), &RigidBody::set_weight);
ClassDB::bind_method(D_METHOD("get_weight"), &RigidBody::get_weight);
+#ifndef DISABLE_DEPRECATED
ClassDB::bind_method(D_METHOD("set_friction", "friction"), &RigidBody::set_friction);
ClassDB::bind_method(D_METHOD("get_friction"), &RigidBody::get_friction);
ClassDB::bind_method(D_METHOD("set_bounce", "bounce"), &RigidBody::set_bounce);
ClassDB::bind_method(D_METHOD("get_bounce"), &RigidBody::get_bounce);
+#endif // DISABLE_DEPRECATED
+
+ ClassDB::bind_method(D_METHOD("set_physics_material_override", "physics_material_override"), &RigidBody::set_physics_material_override);
+ ClassDB::bind_method(D_METHOD("get_physics_material_override"), &RigidBody::get_physics_material_override);
+
+ ClassDB::bind_method(D_METHOD("_reload_physics_characteristics"), &RigidBody::_reload_physics_characteristics);
ClassDB::bind_method(D_METHOD("set_linear_velocity", "linear_velocity"), &RigidBody::set_linear_velocity);
ClassDB::bind_method(D_METHOD("get_linear_velocity"), &RigidBody::get_linear_velocity);
@@ -840,6 +968,12 @@ void RigidBody::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_using_continuous_collision_detection"), &RigidBody::is_using_continuous_collision_detection);
ClassDB::bind_method(D_METHOD("set_axis_velocity", "axis_velocity"), &RigidBody::set_axis_velocity);
+
+ ClassDB::bind_method(D_METHOD("add_central_force", "force"), &RigidBody::add_central_force);
+ ClassDB::bind_method(D_METHOD("add_force", "force", "position"), &RigidBody::add_force);
+ ClassDB::bind_method(D_METHOD("add_torque", "torque"), &RigidBody::add_torque);
+
+ ClassDB::bind_method(D_METHOD("apply_central_impulse", "impulse"), &RigidBody::apply_central_impulse);
ClassDB::bind_method(D_METHOD("apply_impulse", "position", "impulse"), &RigidBody::apply_impulse);
ClassDB::bind_method(D_METHOD("apply_torque_impulse", "impulse"), &RigidBody::apply_torque_impulse);
@@ -863,8 +997,11 @@ void RigidBody::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Rigid,Static,Character,Kinematic"), "set_mode", "get_mode");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "mass", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01"), "set_mass", "get_mass");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "weight", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01", PROPERTY_USAGE_EDITOR), "set_weight", "get_weight");
+#ifndef DISABLE_DEPRECATED
ADD_PROPERTY(PropertyInfo(Variant::REAL, "friction", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_friction", "get_friction");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "bounce", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_bounce", "get_bounce");
+#endif // DISABLE_DEPRECATED
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "physics_material_override", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), "set_physics_material_override", "get_physics_material_override");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "gravity_scale", PROPERTY_HINT_RANGE, "-128,128,0.01"), "set_gravity_scale", "get_gravity_scale");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "custom_integrator"), "set_use_custom_integrator", "is_using_custom_integrator");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "continuous_cd"), "set_use_continuous_collision_detection", "is_using_continuous_collision_detection");
@@ -903,9 +1040,7 @@ RigidBody::RigidBody() :
mode = MODE_RIGID;
- bounce = 0;
mass = 1;
- friction = 1;
max_contacts_reported = 0;
state = NULL;
@@ -929,13 +1064,24 @@ RigidBody::~RigidBody() {
if (contact_monitor)
memdelete(contact_monitor);
}
+
+void RigidBody::_reload_physics_characteristics() {
+ if (physics_material_override.is_null()) {
+ PhysicsServer::get_singleton()->body_set_param(get_rid(), PhysicsServer::BODY_PARAM_BOUNCE, 0);
+ PhysicsServer::get_singleton()->body_set_param(get_rid(), PhysicsServer::BODY_PARAM_FRICTION, 1);
+ } else {
+ PhysicsServer::get_singleton()->body_set_param(get_rid(), PhysicsServer::BODY_PARAM_BOUNCE, physics_material_override->computed_bounce());
+ PhysicsServer::get_singleton()->body_set_param(get_rid(), PhysicsServer::BODY_PARAM_FRICTION, physics_material_override->computed_friction());
+ }
+}
+
//////////////////////////////////////////////////////
//////////////////////////
-Ref<KinematicCollision> KinematicBody::_move(const Vector3 &p_motion, bool p_infinite_inertia) {
+Ref<KinematicCollision> KinematicBody::_move(const Vector3 &p_motion, bool p_infinite_inertia, bool p_test_only) {
Collision col;
- if (move_and_collide(p_motion, p_infinite_inertia, col)) {
+ if (move_and_collide(p_motion, p_infinite_inertia, col, p_test_only)) {
if (motion_cache.is_null()) {
motion_cache.instance();
motion_cache->owner = this;
@@ -949,7 +1095,7 @@ Ref<KinematicCollision> KinematicBody::_move(const Vector3 &p_motion, bool p_inf
return Ref<KinematicCollision>();
}
-bool KinematicBody::move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, Collision &r_collision) {
+bool KinematicBody::move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, Collision &r_collision, bool p_test_only) {
Transform gt = get_global_transform();
PhysicsServer::MotionResult result;
@@ -962,6 +1108,7 @@ bool KinematicBody::move_and_collide(const Vector3 &p_motion, bool p_infinite_in
r_collision.collision = result.collision_point;
r_collision.normal = result.collision_normal;
r_collision.collider = result.collider_id;
+ r_collision.collider_rid = result.collider;
r_collision.travel = result.motion;
r_collision.remainder = result.remainder;
r_collision.local_shape = result.collision_local_shape;
@@ -973,13 +1120,18 @@ bool KinematicBody::move_and_collide(const Vector3 &p_motion, bool p_infinite_in
}
}
- gt.origin += result.motion;
- set_global_transform(gt);
+ if (!p_test_only) {
+ gt.origin += result.motion;
+ set_global_transform(gt);
+ }
return colliding;
}
-Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_floor_direction, float p_slope_stop_min_velocity, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) {
+//so, if you pass 45 as limit, avoid numerical precision erros when angle is 45.
+#define FLOOR_ANGLE_THRESHOLD 0.01
+
+Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_floor_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) {
Vector3 lv = p_linear_velocity;
@@ -997,69 +1149,127 @@ Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Ve
colliders.clear();
floor_velocity = Vector3();
+ Vector3 lv_n = p_linear_velocity.normalized();
+
while (p_max_slides) {
Collision collision;
- bool collided = move_and_collide(motion, p_infinite_inertia, collision);
-
- if (collided) {
+ bool found_collision = false;
- motion = collision.remainder;
+ int test_type = 0;
- if (p_floor_direction == Vector3()) {
- //all is a wall
- on_wall = true;
+ do {
+ bool collided;
+ if (test_type == 0) { //collide
+ collided = move_and_collide(motion, p_infinite_inertia, collision);
+ if (!collided) {
+ motion = Vector3(); //clear because no collision happened and motion completed
+ }
} else {
- if (collision.normal.dot(p_floor_direction) >= Math::cos(p_floor_max_angle)) { //floor
+ collided = separate_raycast_shapes(p_infinite_inertia, collision);
+ if (collided) {
+ collision.remainder = motion; //keep
+ collision.travel = Vector3();
+ }
+ }
- on_floor = true;
- floor_velocity = collision.collider_vel;
+ if (collided) {
+ found_collision = true;
+ }
- Vector3 rel_v = lv - floor_velocity;
- Vector3 hv = rel_v - p_floor_direction * p_floor_direction.dot(rel_v);
+ if (collided) {
- if (collision.travel.length() < 0.05 && hv.length() < p_slope_stop_min_velocity) {
- Transform gt = get_global_transform();
- gt.origin -= collision.travel;
- set_global_transform(gt);
- return floor_velocity - p_floor_direction * p_floor_direction.dot(floor_velocity);
- }
- } else if (collision.normal.dot(-p_floor_direction) >= Math::cos(p_floor_max_angle)) { //ceiling
- on_ceiling = true;
- } else {
+ colliders.push_back(collision);
+ motion = collision.remainder;
+
+ bool is_on_slope = false;
+ if (p_floor_direction == Vector3()) {
+ //all is a wall
on_wall = true;
+ } else {
+ if (collision.normal.dot(p_floor_direction) >= Math::cos(p_floor_max_angle + FLOOR_ANGLE_THRESHOLD)) { //floor
+
+ on_floor = true;
+ on_floor_body = collision.collider_rid;
+ floor_velocity = collision.collider_vel;
+
+ if (p_stop_on_slope) {
+ if (Vector3() == lv_n + p_floor_direction) {
+ Transform gt = get_global_transform();
+ gt.origin -= collision.travel;
+ set_global_transform(gt);
+ return Vector3();
+ }
+ }
+
+ is_on_slope = true;
+
+ } else if (collision.normal.dot(-p_floor_direction) >= Math::cos(p_floor_max_angle + FLOOR_ANGLE_THRESHOLD)) { //ceiling
+ on_ceiling = true;
+ } else {
+ on_wall = true;
+ }
}
- }
- Vector3 n = collision.normal;
- motion = motion.slide(n);
- lv = lv.slide(n);
+ if (p_stop_on_slope && is_on_slope) {
+ motion = motion.slide(p_floor_direction);
+ lv = lv.slide(p_floor_direction);
+ } else {
+ Vector3 n = collision.normal;
+ motion = motion.slide(n);
+ lv = lv.slide(n);
+ }
- for (int i = 0; i < 3; i++) {
- if (locked_axis & (1 << i)) {
- lv[i] = 0;
+ for (int i = 0; i < 3; i++) {
+ if (locked_axis & (1 << i)) {
+ lv[i] = 0;
+ }
}
}
- colliders.push_back(collision);
+ ++test_type;
+ } while (!p_stop_on_slope && test_type < 2);
- } else {
+ if (!found_collision || motion == Vector3())
break;
- }
- p_max_slides--;
- if (motion == Vector3())
- break;
+ --p_max_slides;
}
return lv;
}
+Vector3 KinematicBody::move_and_slide_with_snap(const Vector3 &p_linear_velocity, const Vector3 &p_snap, const Vector3 &p_floor_direction, bool p_infinite_inertia, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle) {
+
+ bool was_on_floor = on_floor;
+
+ Vector3 ret = move_and_slide(p_linear_velocity, p_floor_direction, p_stop_on_slope, p_max_slides, p_floor_max_angle, p_infinite_inertia);
+ if (!was_on_floor || p_snap == Vector3()) {
+ return ret;
+ }
+
+ Collision col;
+ Transform gt = get_global_transform();
+
+ if (move_and_collide(p_snap, p_infinite_inertia, col, true)) {
+ gt.origin += col.travel;
+ if (p_floor_direction != Vector3() && Math::acos(p_floor_direction.normalized().dot(col.normal)) < p_floor_max_angle) {
+ on_floor = true;
+ on_floor_body = col.collider_rid;
+ floor_velocity = col.collider_vel;
+ }
+ set_global_transform(gt);
+ }
+
+ return ret;
+}
+
bool KinematicBody::is_on_floor() const {
return on_floor;
}
+
bool KinematicBody::is_on_wall() const {
return on_wall;
@@ -1081,6 +1291,43 @@ bool KinematicBody::test_move(const Transform &p_from, const Vector3 &p_motion,
return PhysicsServer::get_singleton()->body_test_motion(get_rid(), p_from, p_motion, p_infinite_inertia);
}
+bool KinematicBody::separate_raycast_shapes(bool p_infinite_inertia, Collision &r_collision) {
+
+ PhysicsServer::SeparationResult sep_res[8]; //max 8 rays
+
+ Transform gt = get_global_transform();
+
+ Vector3 recover;
+ int hits = PhysicsServer::get_singleton()->body_test_ray_separation(get_rid(), gt, p_infinite_inertia, recover, sep_res, 8, margin);
+ int deepest = -1;
+ float deepest_depth;
+ for (int i = 0; i < hits; i++) {
+ if (deepest == -1 || sep_res[i].collision_depth > deepest_depth) {
+ deepest = i;
+ deepest_depth = sep_res[i].collision_depth;
+ }
+ }
+
+ gt.origin += recover;
+ set_global_transform(gt);
+
+ if (deepest != -1) {
+ r_collision.collider = sep_res[deepest].collider_id;
+ r_collision.collider_metadata = sep_res[deepest].collider_metadata;
+ r_collision.collider_shape = sep_res[deepest].collider_shape;
+ r_collision.collider_vel = sep_res[deepest].collider_velocity;
+ r_collision.collision = sep_res[deepest].collision_point;
+ r_collision.normal = sep_res[deepest].collision_normal;
+ r_collision.local_shape = sep_res[deepest].collision_local_shape;
+ r_collision.travel = recover;
+ r_collision.remainder = Vector3();
+
+ return true;
+ } else {
+ return false;
+ }
+}
+
void KinematicBody::set_axis_lock(PhysicsServer::BodyAxis p_axis, bool p_lock) {
PhysicsServer::get_singleton()->body_set_axis_lock(get_rid(), p_axis, p_lock);
}
@@ -1117,18 +1364,19 @@ Ref<KinematicCollision> KinematicBody::_get_slide_collision(int p_bounce) {
}
if (slide_colliders[p_bounce].is_null()) {
- slide_colliders[p_bounce].instance();
- slide_colliders[p_bounce]->owner = this;
+ slide_colliders.write[p_bounce].instance();
+ slide_colliders.write[p_bounce]->owner = this;
}
- slide_colliders[p_bounce]->collision = colliders[p_bounce];
+ slide_colliders.write[p_bounce]->collision = colliders[p_bounce];
return slide_colliders[p_bounce];
}
void KinematicBody::_bind_methods() {
- ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia"), &KinematicBody::_move, DEFVAL(true));
- ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "floor_normal", "slope_stop_min_velocity", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody::move_and_slide, DEFVAL(Vector3(0, 0, 0)), DEFVAL(0.05), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true));
+ ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "test_only"), &KinematicBody::_move, DEFVAL(true), DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "floor_normal", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody::move_and_slide, DEFVAL(Vector3(0, 0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true));
+ ClassDB::bind_method(D_METHOD("move_and_slide_with_snap", "linear_velocity", "snap", "floor_normal", "infinite_inertia", "stop_on_slope", "max_bounces", "floor_max_angle"), &KinematicBody::move_and_slide_with_snap, DEFVAL(Vector3(0, 0, 0)), DEFVAL(true), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)));
ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec", "infinite_inertia"), &KinematicBody::test_move);
@@ -1146,13 +1394,9 @@ void KinematicBody::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_slide_count"), &KinematicBody::get_slide_count);
ClassDB::bind_method(D_METHOD("get_slide_collision", "slide_idx"), &KinematicBody::_get_slide_collision);
- ADD_GROUP("Axis Lock", "axis_lock_");
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_x"), "set_axis_lock", "get_axis_lock", PhysicsServer::BODY_AXIS_LINEAR_X);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_y"), "set_axis_lock", "get_axis_lock", PhysicsServer::BODY_AXIS_LINEAR_Y);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_z"), "set_axis_lock", "get_axis_lock", PhysicsServer::BODY_AXIS_LINEAR_Z);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_x"), "set_axis_lock", "get_axis_lock", PhysicsServer::BODY_AXIS_ANGULAR_X);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_y"), "set_axis_lock", "get_axis_lock", PhysicsServer::BODY_AXIS_ANGULAR_Y);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_z"), "set_axis_lock", "get_axis_lock", PhysicsServer::BODY_AXIS_ANGULAR_Z);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "move_lock_x", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_axis_lock", "get_axis_lock", PhysicsServer::BODY_AXIS_LINEAR_X);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "move_lock_y", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_axis_lock", "get_axis_lock", PhysicsServer::BODY_AXIS_LINEAR_Y);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "move_lock_z", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_axis_lock", "get_axis_lock", PhysicsServer::BODY_AXIS_LINEAR_Z);
ADD_PROPERTY(PropertyInfo(Variant::REAL, "collision/safe_margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_safe_margin", "get_safe_margin");
}
@@ -1174,7 +1418,7 @@ KinematicBody::~KinematicBody() {
for (int i = 0; i < slide_colliders.size(); i++) {
if (slide_colliders[i].is_valid()) {
- slide_colliders[i]->owner = NULL;
+ slide_colliders.write[i]->owner = NULL;
}
}
}
@@ -1893,6 +2137,8 @@ void PhysicalBone::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_simulating_physics"), &PhysicalBone::is_simulating_physics);
+ ClassDB::bind_method(D_METHOD("get_bone_id"), &PhysicalBone::get_bone_id);
+
ClassDB::bind_method(D_METHOD("set_mass", "mass"), &PhysicalBone::set_mass);
ClassDB::bind_method(D_METHOD("get_mass"), &PhysicalBone::get_mass);
@@ -2228,6 +2474,7 @@ void PhysicalBone::set_bounce(real_t p_bounce) {
bounce = p_bounce;
PhysicsServer::get_singleton()->body_set_param(get_rid(), PhysicsServer::BODY_PARAM_BOUNCE, bounce);
}
+
real_t PhysicalBone::get_bounce() const {
return bounce;
diff --git a/scene/3d/physics_body.h b/scene/3d/physics_body.h
index 0190dcbfc3..c4db41f577 100644
--- a/scene/3d/physics_body.h
+++ b/scene/3d/physics_body.h
@@ -32,6 +32,7 @@
#define PHYSICS_BODY__H
#include "scene/3d/collision_object.h"
+#include "scene/resources/physics_material.h"
#include "servers/physics_server.h"
#include "skeleton.h"
#include "vset.h"
@@ -81,18 +82,22 @@ class StaticBody : public PhysicsBody {
Vector3 constant_linear_velocity;
Vector3 constant_angular_velocity;
- real_t bounce;
- real_t friction;
+ Ref<PhysicsMaterial> physics_material_override;
protected:
static void _bind_methods();
public:
+#ifndef DISABLE_DEPRECATED
void set_friction(real_t p_friction);
real_t get_friction() const;
void set_bounce(real_t p_bounce);
real_t get_bounce() const;
+#endif
+
+ void set_physics_material_override(const Ref<PhysicsMaterial> &p_physics_material_override);
+ Ref<PhysicsMaterial> get_physics_material_override() const;
void set_constant_linear_velocity(const Vector3 &p_vel);
void set_constant_angular_velocity(const Vector3 &p_vel);
@@ -102,6 +107,9 @@ public:
StaticBody();
~StaticBody();
+
+private:
+ void _reload_physics_characteristics();
};
class RigidBody : public PhysicsBody {
@@ -121,9 +129,8 @@ protected:
PhysicsDirectBodyState *state;
Mode mode;
- real_t bounce;
real_t mass;
- real_t friction;
+ Ref<PhysicsMaterial> physics_material_override;
Vector3 linear_velocity;
Vector3 angular_velocity;
@@ -196,11 +203,16 @@ public:
void set_weight(real_t p_weight);
real_t get_weight() const;
+#ifndef DISABLE_DEPRECATED
void set_friction(real_t p_friction);
real_t get_friction() const;
void set_bounce(real_t p_bounce);
real_t get_bounce() const;
+#endif
+
+ void set_physics_material_override(const Ref<PhysicsMaterial> &p_physics_material_override);
+ Ref<PhysicsMaterial> get_physics_material_override() const;
void set_linear_velocity(const Vector3 &p_velocity);
Vector3 get_linear_velocity() const;
@@ -242,6 +254,11 @@ public:
Array get_colliding_bodies() const;
+ void add_central_force(const Vector3 &p_force);
+ void add_force(const Vector3 &p_force, const Vector3 &p_pos);
+ void add_torque(const Vector3 &p_torque);
+
+ void apply_central_impulse(const Vector3 &p_impulse);
void apply_impulse(const Vector3 &p_pos, const Vector3 &p_impulse);
void apply_torque_impulse(const Vector3 &p_impulse);
@@ -249,6 +266,9 @@ public:
RigidBody();
~RigidBody();
+
+private:
+ void _reload_physics_characteristics();
};
VARIANT_ENUM_CAST(RigidBody::Mode);
@@ -265,6 +285,7 @@ public:
Vector3 normal;
Vector3 collider_vel;
ObjectID collider;
+ RID collider_rid;
int collider_shape;
Variant collider_metadata;
Vector3 remainder;
@@ -278,6 +299,7 @@ private:
float margin;
Vector3 floor_velocity;
+ RID on_floor_body;
bool on_floor;
bool on_ceiling;
bool on_wall;
@@ -287,23 +309,26 @@ private:
_FORCE_INLINE_ bool _ignores_mode(PhysicsServer::BodyMode) const;
- Ref<KinematicCollision> _move(const Vector3 &p_motion, bool p_infinite_inertia = true);
+ Ref<KinematicCollision> _move(const Vector3 &p_motion, bool p_infinite_inertia = true, bool p_test_only = false);
Ref<KinematicCollision> _get_slide_collision(int p_bounce);
protected:
static void _bind_methods();
public:
- bool move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, Collision &r_collision);
+ bool move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, Collision &r_collisionz, bool p_test_only = false);
bool test_move(const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia);
+ bool separate_raycast_shapes(bool p_infinite_inertia, Collision &r_collision);
+
void set_axis_lock(PhysicsServer::BodyAxis p_axis, bool p_lock);
bool get_axis_lock(PhysicsServer::BodyAxis p_axis) const;
void set_safe_margin(float p_margin);
float get_safe_margin() const;
- Vector3 move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_floor_direction = Vector3(0, 0, 0), float p_slope_stop_min_velocity = 0.05, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true);
+ Vector3 move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_floor_direction = Vector3(0, 0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true);
+ Vector3 move_and_slide_with_snap(const Vector3 &p_linear_velocity, const Vector3 &p_snap, const Vector3 &p_floor_direction = Vector3(0, 0, 0), bool p_infinite_inertia = true, bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45));
bool is_on_floor() const;
bool is_on_wall() const;
bool is_on_ceiling() const;
@@ -537,6 +562,7 @@ protected:
private:
static Skeleton *find_skeleton_parent(Node *p_parent);
+
void _fix_joint_offset();
void _reload_joint();
diff --git a/scene/3d/ray_cast.cpp b/scene/3d/ray_cast.cpp
index 7f83e2c3ea..b846a5b6c0 100644
--- a/scene/3d/ray_cast.cpp
+++ b/scene/3d/ray_cast.cpp
@@ -208,7 +208,7 @@ void RayCast::_update_raycast_state() {
PhysicsDirectSpaceState::RayResult rr;
- if (dss->intersect_ray(gt.get_origin(), gt.xform(to), rr, exclude, collision_mask)) {
+ if (dss->intersect_ray(gt.get_origin(), gt.xform(to), rr, exclude, collision_mask, collide_with_bodies, collide_with_areas)) {
collided = true;
against = rr.collider_id;
@@ -259,6 +259,26 @@ void RayCast::clear_exceptions() {
exclude.clear();
}
+void RayCast::set_collide_with_areas(bool p_clip) {
+
+ collide_with_areas = p_clip;
+}
+
+bool RayCast::is_collide_with_areas_enabled() const {
+
+ return collide_with_areas;
+}
+
+void RayCast::set_collide_with_bodies(bool p_clip) {
+
+ collide_with_bodies = p_clip;
+}
+
+bool RayCast::is_collide_with_bodies_enabled() const {
+
+ return collide_with_bodies;
+}
+
void RayCast::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &RayCast::set_enabled);
@@ -292,10 +312,20 @@ void RayCast::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_exclude_parent_body", "mask"), &RayCast::set_exclude_parent_body);
ClassDB::bind_method(D_METHOD("get_exclude_parent_body"), &RayCast::get_exclude_parent_body);
+ ClassDB::bind_method(D_METHOD("set_collide_with_areas", "enable"), &RayCast::set_collide_with_areas);
+ ClassDB::bind_method(D_METHOD("is_collide_with_areas_enabled"), &RayCast::is_collide_with_areas_enabled);
+
+ ClassDB::bind_method(D_METHOD("set_collide_with_bodies", "enable"), &RayCast::set_collide_with_bodies);
+ ClassDB::bind_method(D_METHOD("is_collide_with_bodies_enabled"), &RayCast::is_collide_with_bodies_enabled);
+
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "exclude_parent"), "set_exclude_parent_body", "get_exclude_parent_body");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "cast_to"), "set_cast_to", "get_cast_to");
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask");
+
+ ADD_GROUP("Collide With", "collide_with");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with_areas", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collide_with_areas", "is_collide_with_areas_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with_bodies", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collide_with_bodies", "is_collide_with_bodies_enabled");
}
void RayCast::_create_debug_shape() {
@@ -370,4 +400,6 @@ RayCast::RayCast() {
cast_to = Vector3(0, -1, 0);
debug_shape = NULL;
exclude_parent_body = true;
+ collide_with_areas = false;
+ collide_with_bodies = true;
}
diff --git a/scene/3d/ray_cast.h b/scene/3d/ray_cast.h
index 20cea80700..e95382e1fe 100644
--- a/scene/3d/ray_cast.h
+++ b/scene/3d/ray_cast.h
@@ -45,7 +45,6 @@ class RayCast : public Spatial {
Vector3 collision_normal;
Vector3 cast_to;
-
Set<RID> exclude;
uint32_t collision_mask;
@@ -58,12 +57,21 @@ class RayCast : public Spatial {
void _update_debug_shape();
void _clear_debug_shape();
+ bool collide_with_areas;
+ bool collide_with_bodies;
+
protected:
void _notification(int p_what);
void _update_raycast_state();
static void _bind_methods();
public:
+ void set_collide_with_areas(bool p_clip);
+ bool is_collide_with_areas_enabled() const;
+
+ void set_collide_with_bodies(bool p_clip);
+ bool is_collide_with_bodies_enabled() const;
+
void set_enabled(bool p_enabled);
bool is_enabled() const;
diff --git a/scene/3d/reflection_probe.cpp b/scene/3d/reflection_probe.cpp
index 4d50945062..fe522bbe97 100644
--- a/scene/3d/reflection_probe.cpp
+++ b/scene/3d/reflection_probe.cpp
@@ -274,6 +274,7 @@ ReflectionProbe::ReflectionProbe() {
probe = VisualServer::get_singleton()->reflection_probe_create();
VS::get_singleton()->instance_set_base(get_instance(), probe);
+ set_disable_scale(true);
}
ReflectionProbe::~ReflectionProbe() {
diff --git a/scene/3d/remote_transform.cpp b/scene/3d/remote_transform.cpp
index 2156e24cd0..c12e49fb47 100644
--- a/scene/3d/remote_transform.cpp
+++ b/scene/3d/remote_transform.cpp
@@ -124,8 +124,10 @@ void RemoteTransform::_notification(int p_what) {
void RemoteTransform::set_remote_node(const NodePath &p_remote_node) {
remote_node = p_remote_node;
- if (is_inside_tree())
+ if (is_inside_tree()) {
_update_cache();
+ _update_remote();
+ }
update_configuration_warning();
}
diff --git a/scene/3d/skeleton.cpp b/scene/3d/skeleton.cpp
index 8d91b6f09f..c796e47f25 100644
--- a/scene/3d/skeleton.cpp
+++ b/scene/3d/skeleton.cpp
@@ -66,7 +66,7 @@ bool Skeleton::_set(const StringName &p_path, const Variant &p_value) {
Array children = p_value;
if (is_inside_tree()) {
- bones[which].nodes_bound.clear();
+ bones.write[which].nodes_bound.clear();
for (int i = 0; i < children.size(); i++) {
@@ -131,7 +131,7 @@ void Skeleton::_get_property_list(List<PropertyInfo> *p_list) const {
String prep = "bones/" + itos(i) + "/";
p_list->push_back(PropertyInfo(Variant::STRING, prep + "name"));
- p_list->push_back(PropertyInfo(Variant::INT, prep + "parent", PROPERTY_HINT_RANGE, "-1," + itos(i - 1) + ",1"));
+ p_list->push_back(PropertyInfo(Variant::INT, prep + "parent", PROPERTY_HINT_RANGE, "-1," + itos(bones.size() - 1) + ",1"));
p_list->push_back(PropertyInfo(Variant::TRANSFORM, prep + "rest"));
p_list->push_back(PropertyInfo(Variant::BOOL, prep + "enabled"));
p_list->push_back(PropertyInfo(Variant::TRANSFORM, prep + "pose", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
@@ -139,6 +139,59 @@ void Skeleton::_get_property_list(List<PropertyInfo> *p_list) const {
}
}
+void Skeleton::_update_process_order() {
+
+ if (!process_order_dirty)
+ return;
+
+ Bone *bonesptr = bones.ptrw();
+ int len = bones.size();
+
+ process_order.resize(len);
+ int *order = process_order.ptrw();
+ for (int i = 0; i < len; i++) {
+
+ if (bonesptr[i].parent >= len) {
+ //validate this just in case
+ ERR_PRINTS("Bone " + itos(i) + " has invalid parent: " + itos(bonesptr[i].parent));
+ bonesptr[i].parent = -1;
+ }
+ order[i] = i;
+ bonesptr[i].sort_index = i;
+ }
+ //now check process order
+ int pass_count = 0;
+ while (pass_count < len * len) {
+ //using bubblesort because of simplicity, it wont run every frame though.
+ //bublesort worst case is O(n^2), and this may be an infinite loop if cyclic
+ bool swapped = false;
+ for (int i = 0; i < len; i++) {
+ int parent_idx = bonesptr[order[i]].parent;
+ if (parent_idx < 0)
+ continue; //do nothing because it has no parent
+ //swap indices
+ int parent_order = bonesptr[parent_idx].sort_index;
+ if (parent_order > i) {
+ bonesptr[order[i]].sort_index = parent_order;
+ bonesptr[parent_idx].sort_index = i;
+ //swap order
+ SWAP(order[i], order[parent_order]);
+ swapped = true;
+ }
+ }
+
+ if (!swapped)
+ break;
+ pass_count++;
+ }
+
+ if (pass_count == len * len) {
+ ERR_PRINT("Skeleton parenthood graph is cyclic");
+ }
+
+ process_order_dirty = false;
+}
+
void Skeleton::_notification(int p_what) {
switch (p_what) {
@@ -176,24 +229,28 @@ void Skeleton::_notification(int p_what) {
case NOTIFICATION_UPDATE_SKELETON: {
VisualServer *vs = VisualServer::get_singleton();
- Bone *bonesptr = &bones[0];
+ Bone *bonesptr = bones.ptrw();
int len = bones.size();
vs->skeleton_allocate(skeleton, len); // if same size, nothin really happens
+ _update_process_order();
+
+ const int *order = process_order.ptr();
+
// pose changed, rebuild cache of inverses
if (rest_global_inverse_dirty) {
// calculate global rests and invert them
for (int i = 0; i < len; i++) {
- Bone &b = bonesptr[i];
+ Bone &b = bonesptr[order[i]];
if (b.parent >= 0)
b.rest_global_inverse = bonesptr[b.parent].rest_global_inverse * b.rest;
else
b.rest_global_inverse = b.rest;
}
for (int i = 0; i < len; i++) {
- Bone &b = bonesptr[i];
+ Bone &b = bonesptr[order[i]];
b.rest_global_inverse.affine_invert();
}
@@ -205,7 +262,7 @@ void Skeleton::_notification(int p_what) {
for (int i = 0; i < len; i++) {
- Bone &b = bonesptr[i];
+ Bone &b = bonesptr[order[i]];
if (b.disable_rest) {
if (b.enabled) {
@@ -319,12 +376,13 @@ void Skeleton::add_bone(const String &p_name) {
for (int i = 0; i < bones.size(); i++) {
- ERR_FAIL_COND(bones[i].name == "p_name");
+ ERR_FAIL_COND(bones[i].name == p_name);
}
Bone b;
b.name = p_name;
bones.push_back(b);
+ process_order_dirty = true;
rest_global_inverse_dirty = true;
_make_dirty();
@@ -368,10 +426,11 @@ int Skeleton::get_bone_count() const {
void Skeleton::set_bone_parent(int p_bone, int p_parent) {
ERR_FAIL_INDEX(p_bone, bones.size());
- ERR_FAIL_COND(p_parent != -1 && (p_parent < 0 || p_parent >= p_bone));
+ ERR_FAIL_COND(p_parent != -1 && (p_parent < 0));
- bones[p_bone].parent = p_parent;
+ bones.write[p_bone].parent = p_parent;
rest_global_inverse_dirty = true;
+ process_order_dirty = true;
_make_dirty();
}
@@ -379,21 +438,24 @@ void Skeleton::unparent_bone_and_rest(int p_bone) {
ERR_FAIL_INDEX(p_bone, bones.size());
+ _update_process_order();
+
int parent = bones[p_bone].parent;
while (parent >= 0) {
- bones[p_bone].rest = bones[parent].rest * bones[p_bone].rest;
+ bones.write[p_bone].rest = bones[parent].rest * bones[p_bone].rest;
parent = bones[parent].parent;
}
- bones[p_bone].parent = -1;
- bones[p_bone].rest_global_inverse = bones[p_bone].rest.affine_inverse(); //same thing
+ bones.write[p_bone].parent = -1;
+ bones.write[p_bone].rest_global_inverse = bones[p_bone].rest.affine_inverse(); //same thing
+ process_order_dirty = true;
_make_dirty();
}
void Skeleton::set_bone_ignore_animation(int p_bone, bool p_ignore) {
ERR_FAIL_INDEX(p_bone, bones.size());
- bones[p_bone].ignore_animation = p_ignore;
+ bones.write[p_bone].ignore_animation = p_ignore;
}
bool Skeleton::is_bone_ignore_animation(int p_bone) const {
@@ -405,7 +467,7 @@ bool Skeleton::is_bone_ignore_animation(int p_bone) const {
void Skeleton::set_bone_disable_rest(int p_bone, bool p_disable) {
ERR_FAIL_INDEX(p_bone, bones.size());
- bones[p_bone].disable_rest = p_disable;
+ bones.write[p_bone].disable_rest = p_disable;
}
bool Skeleton::is_bone_rest_disabled(int p_bone) const {
@@ -425,7 +487,7 @@ void Skeleton::set_bone_rest(int p_bone, const Transform &p_rest) {
ERR_FAIL_INDEX(p_bone, bones.size());
- bones[p_bone].rest = p_rest;
+ bones.write[p_bone].rest = p_rest;
rest_global_inverse_dirty = true;
_make_dirty();
}
@@ -440,7 +502,7 @@ void Skeleton::set_bone_enabled(int p_bone, bool p_enabled) {
ERR_FAIL_INDEX(p_bone, bones.size());
- bones[p_bone].enabled = p_enabled;
+ bones.write[p_bone].enabled = p_enabled;
rest_global_inverse_dirty = true;
_make_dirty();
}
@@ -457,13 +519,13 @@ void Skeleton::bind_child_node_to_bone(int p_bone, Node *p_node) {
uint32_t id = p_node->get_instance_id();
- for (List<uint32_t>::Element *E = bones[p_bone].nodes_bound.front(); E; E = E->next()) {
+ for (const List<uint32_t>::Element *E = bones[p_bone].nodes_bound.front(); E; E = E->next()) {
if (E->get() == id)
return; // already here
}
- bones[p_bone].nodes_bound.push_back(id);
+ bones.write[p_bone].nodes_bound.push_back(id);
}
void Skeleton::unbind_child_node_from_bone(int p_bone, Node *p_node) {
@@ -471,7 +533,7 @@ void Skeleton::unbind_child_node_from_bone(int p_bone, Node *p_node) {
ERR_FAIL_INDEX(p_bone, bones.size());
uint32_t id = p_node->get_instance_id();
- bones[p_bone].nodes_bound.erase(id);
+ bones.write[p_bone].nodes_bound.erase(id);
}
void Skeleton::get_bound_child_nodes_to_bone(int p_bone, List<Node *> *p_bound) const {
@@ -489,6 +551,8 @@ void Skeleton::clear_bones() {
bones.clear();
rest_global_inverse_dirty = true;
+ process_order_dirty = true;
+
_make_dirty();
}
@@ -499,7 +563,7 @@ void Skeleton::set_bone_pose(int p_bone, const Transform &p_pose) {
ERR_FAIL_INDEX(p_bone, bones.size());
ERR_FAIL_COND(!is_inside_tree());
- bones[p_bone].pose = p_pose;
+ bones.write[p_bone].pose = p_pose;
_make_dirty();
}
Transform Skeleton::get_bone_pose(int p_bone) const {
@@ -513,8 +577,8 @@ void Skeleton::set_bone_custom_pose(int p_bone, const Transform &p_custom_pose)
ERR_FAIL_INDEX(p_bone, bones.size());
//ERR_FAIL_COND( !is_inside_scene() );
- bones[p_bone].custom_pose_enable = (p_custom_pose != Transform());
- bones[p_bone].custom_pose = p_custom_pose;
+ bones.write[p_bone].custom_pose_enable = (p_custom_pose != Transform());
+ bones.write[p_bone].custom_pose = p_custom_pose;
_make_dirty();
}
@@ -538,12 +602,21 @@ void Skeleton::_make_dirty() {
dirty = true;
}
+int Skeleton::get_process_order(int p_idx) {
+ ERR_FAIL_INDEX_V(p_idx, bones.size(), -1);
+ _update_process_order();
+ return process_order[p_idx];
+}
+
void Skeleton::localize_rests() {
- for (int i = bones.size() - 1; i >= 0; i--) {
+ _update_process_order();
- if (bones[i].parent >= 0)
- set_bone_rest(i, bones[bones[i].parent].rest.affine_inverse() * bones[i].rest);
+ for (int i = bones.size() - 1; i >= 0; i--) {
+ int idx = process_order[i];
+ if (bones[idx].parent >= 0) {
+ set_bone_rest(idx, bones[bones[idx].parent].rest.affine_inverse() * bones[idx].rest);
+ }
}
}
@@ -553,14 +626,14 @@ void Skeleton::bind_physical_bone_to_bone(int p_bone, PhysicalBone *p_physical_b
ERR_FAIL_INDEX(p_bone, bones.size());
ERR_FAIL_COND(bones[p_bone].physical_bone);
ERR_FAIL_COND(!p_physical_bone);
- bones[p_bone].physical_bone = p_physical_bone;
+ bones.write[p_bone].physical_bone = p_physical_bone;
_rebuild_physical_bones_cache();
}
void Skeleton::unbind_physical_bone_from_bone(int p_bone) {
ERR_FAIL_INDEX(p_bone, bones.size());
- bones[p_bone].physical_bone = NULL;
+ bones.write[p_bone].physical_bone = NULL;
_rebuild_physical_bones_cache();
}
@@ -600,9 +673,12 @@ PhysicalBone *Skeleton::_get_physical_bone_parent(int p_bone) {
void Skeleton::_rebuild_physical_bones_cache() {
const int b_size = bones.size();
for (int i = 0; i < b_size; ++i) {
- bones[i].cache_parent_physical_bone = _get_physical_bone_parent(i);
- if (bones[i].physical_bone)
- bones[i].physical_bone->_on_bone_parent_changed();
+ PhysicalBone *parent_pb = _get_physical_bone_parent(i);
+ if (parent_pb != bones[i].physical_bone) {
+ bones.write[i].cache_parent_physical_bone = parent_pb;
+ if (bones[i].physical_bone)
+ bones[i].physical_bone->_on_bone_parent_changed();
+ }
}
}
@@ -660,7 +736,7 @@ void Skeleton::physical_bones_start_simulation_on(const Array &p_bones) {
if (Variant::STRING == p_bones.get(i).get_type()) {
int bone_id = find_bone(p_bones.get(i));
if (bone_id != -1)
- sim_bones[c++] = bone_id;
+ sim_bones.write[c++] = bone_id;
}
}
sim_bones.resize(c);
@@ -740,6 +816,8 @@ void Skeleton::_bind_methods() {
#endif // _3D_DISABLED
+ ClassDB::bind_method(D_METHOD("set_bone_ignore_animation", "bone", "ignore"), &Skeleton::set_bone_ignore_animation);
+
BIND_CONSTANT(NOTIFICATION_UPDATE_SKELETON);
}
@@ -747,6 +825,7 @@ Skeleton::Skeleton() {
rest_global_inverse_dirty = true;
dirty = false;
+ process_order_dirty = true;
skeleton = VisualServer::get_singleton()->skeleton_create();
set_notify_transform(true);
}
diff --git a/scene/3d/skeleton.h b/scene/3d/skeleton.h
index 9672acb57a..e044e08437 100644
--- a/scene/3d/skeleton.h
+++ b/scene/3d/skeleton.h
@@ -39,6 +39,8 @@
*/
#ifndef _3D_DISABLED
+typedef int BoneId;
+
class PhysicalBone;
#endif // _3D_DISABLED
@@ -52,6 +54,7 @@ class Skeleton : public Spatial {
bool enabled;
int parent;
+ int sort_index; //used for re-sorting process order
bool ignore_animation;
@@ -90,13 +93,15 @@ class Skeleton : public Spatial {
bool rest_global_inverse_dirty;
Vector<Bone> bones;
+ Vector<int> process_order;
+ bool process_order_dirty;
RID skeleton;
void _make_dirty();
bool dirty;
- //bind helpers
+ // bind helpers
Array _get_bound_child_nodes_to_bone(int p_bone) const {
Array bound;
@@ -110,6 +115,8 @@ class Skeleton : public Spatial {
return bound;
}
+ void _update_process_order();
+
protected:
bool _get(const StringName &p_path, Variant &r_ret) const;
bool _set(const StringName &p_path, const Variant &p_value);
@@ -170,6 +177,7 @@ public:
Transform get_bone_custom_pose(int p_bone) const;
void localize_rests(); // used for loaders and tools
+ int get_process_order(int p_idx);
#ifndef _3D_DISABLED
// Physical bone API
diff --git a/scene/3d/soft_body.cpp b/scene/3d/soft_body.cpp
new file mode 100644
index 0000000000..980c348c9b
--- /dev/null
+++ b/scene/3d/soft_body.cpp
@@ -0,0 +1,799 @@
+/*************************************************************************/
+/* soft_physics_body.cpp */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* 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. */
+/*************************************************************************/
+
+#include "soft_body.h"
+#include "os/os.h"
+#include "scene/3d/collision_object.h"
+#include "scene/3d/skeleton.h"
+#include "servers/physics_server.h"
+
+SoftBodyVisualServerHandler::SoftBodyVisualServerHandler() {}
+
+void SoftBodyVisualServerHandler::prepare(RID p_mesh, int p_surface) {
+ clear();
+
+ ERR_FAIL_COND(!p_mesh.is_valid());
+
+ mesh = p_mesh;
+ surface = p_surface;
+
+ const uint32_t surface_format = VS::get_singleton()->mesh_surface_get_format(mesh, surface);
+ const int surface_vertex_len = VS::get_singleton()->mesh_surface_get_array_len(mesh, p_surface);
+ const int surface_index_len = VS::get_singleton()->mesh_surface_get_array_index_len(mesh, p_surface);
+ uint32_t surface_offsets[VS::ARRAY_MAX];
+
+ buffer = VS::get_singleton()->mesh_surface_get_array(mesh, surface);
+ stride = VS::get_singleton()->mesh_surface_make_offsets_from_format(surface_format, surface_vertex_len, surface_index_len, surface_offsets);
+ offset_vertices = surface_offsets[VS::ARRAY_VERTEX];
+ offset_normal = surface_offsets[VS::ARRAY_NORMAL];
+}
+
+void SoftBodyVisualServerHandler::clear() {
+
+ if (mesh.is_valid()) {
+ buffer.resize(0);
+ }
+
+ mesh = RID();
+}
+
+void SoftBodyVisualServerHandler::open() {
+ write_buffer = buffer.write();
+}
+
+void SoftBodyVisualServerHandler::close() {
+ write_buffer = PoolVector<uint8_t>::Write();
+}
+
+void SoftBodyVisualServerHandler::commit_changes() {
+ VS::get_singleton()->mesh_surface_update_region(mesh, surface, 0, buffer);
+}
+
+void SoftBodyVisualServerHandler::set_vertex(int p_vertex_id, const void *p_vector3) {
+ copymem(&write_buffer[p_vertex_id * stride + offset_vertices], p_vector3, sizeof(float) * 3);
+}
+
+void SoftBodyVisualServerHandler::set_normal(int p_vertex_id, const void *p_vector3) {
+ copymem(&write_buffer[p_vertex_id * stride + offset_normal], p_vector3, sizeof(float) * 3);
+}
+
+void SoftBodyVisualServerHandler::set_aabb(const AABB &p_aabb) {
+ VS::get_singleton()->mesh_set_custom_aabb(mesh, p_aabb);
+}
+
+SoftBody::PinnedPoint::PinnedPoint() :
+ point_index(-1),
+ spatial_attachment(NULL) {
+}
+
+SoftBody::PinnedPoint::PinnedPoint(const PinnedPoint &obj_tocopy) {
+ point_index = obj_tocopy.point_index;
+ spatial_attachment_path = obj_tocopy.spatial_attachment_path;
+ spatial_attachment = obj_tocopy.spatial_attachment;
+ offset = obj_tocopy.offset;
+}
+
+void SoftBody::_update_pickable() {
+ if (!is_inside_tree())
+ return;
+ bool pickable = ray_pickable && is_inside_tree() && is_visible_in_tree();
+ PhysicsServer::get_singleton()->soft_body_set_ray_pickable(physics_rid, pickable);
+}
+
+bool SoftBody::_set(const StringName &p_name, const Variant &p_value) {
+ String name = p_name;
+ String which = name.get_slicec('/', 0);
+
+ if ("pinned_points" == which) {
+
+ return _set_property_pinned_points_indices(p_value);
+
+ } else if ("attachments" == which) {
+
+ int idx = name.get_slicec('/', 1).to_int();
+ String what = name.get_slicec('/', 2);
+
+ return _set_property_pinned_points_attachment(idx, what, p_value);
+ }
+
+ return false;
+}
+
+bool SoftBody::_get(const StringName &p_name, Variant &r_ret) const {
+ String name = p_name;
+ String which = name.get_slicec('/', 0);
+
+ if ("pinned_points" == which) {
+ Array arr_ret;
+ const int pinned_points_indices_size = pinned_points.size();
+ PoolVector<PinnedPoint>::Read r = pinned_points.read();
+ arr_ret.resize(pinned_points_indices_size);
+
+ for (int i = 0; i < pinned_points_indices_size; ++i) {
+ arr_ret[i] = r[i].point_index;
+ }
+
+ r_ret = arr_ret;
+ return true;
+
+ } else if ("attachments" == which) {
+
+ int idx = name.get_slicec('/', 1).to_int();
+ String what = name.get_slicec('/', 2);
+
+ return _get_property_pinned_points(idx, what, r_ret);
+ }
+
+ return false;
+}
+
+void SoftBody::_get_property_list(List<PropertyInfo> *p_list) const {
+
+ const int pinned_points_indices_size = pinned_points.size();
+
+ p_list->push_back(PropertyInfo(Variant::POOL_INT_ARRAY, "pinned_points"));
+
+ for (int i = 0; i < pinned_points_indices_size; ++i) {
+ p_list->push_back(PropertyInfo(Variant::INT, "attachments/" + itos(i) + "/point_index"));
+ p_list->push_back(PropertyInfo(Variant::NODE_PATH, "attachments/" + itos(i) + "/spatial_attachment_path"));
+ p_list->push_back(PropertyInfo(Variant::VECTOR3, "attachments/" + itos(i) + "/offset"));
+ }
+}
+
+bool SoftBody::_set_property_pinned_points_indices(const Array &p_indices) {
+
+ const int p_indices_size = p_indices.size();
+
+ { // Remove the pined points on physics server that will be removed by resize
+ PoolVector<PinnedPoint>::Read r = pinned_points.read();
+ if (p_indices_size < pinned_points.size()) {
+ for (int i = pinned_points.size() - 1; i >= p_indices_size; --i) {
+ pin_point(r[i].point_index, false);
+ }
+ }
+ }
+
+ pinned_points.resize(p_indices_size);
+
+ PoolVector<PinnedPoint>::Write w = pinned_points.write();
+ int point_index;
+ for (int i = 0; i < p_indices_size; ++i) {
+ point_index = p_indices.get(i);
+ if (w[i].point_index != point_index) {
+ if (-1 != w[i].point_index)
+ pin_point(w[i].point_index, false);
+ w[i].point_index = point_index;
+ pin_point(w[i].point_index, true);
+ }
+ }
+ return true;
+}
+
+bool SoftBody::_set_property_pinned_points_attachment(int p_item, const String &p_what, const Variant &p_value) {
+ if (pinned_points.size() <= p_item) {
+ return false;
+ }
+
+ if ("spatial_attachment_path" == p_what) {
+ PoolVector<PinnedPoint>::Write w = pinned_points.write();
+ pin_point(w[p_item].point_index, true, p_value);
+ _make_cache_dirty();
+ } else if ("offset" == p_what) {
+ PoolVector<PinnedPoint>::Write w = pinned_points.write();
+ w[p_item].offset = p_value;
+ } else {
+ return false;
+ }
+
+ return true;
+}
+
+bool SoftBody::_get_property_pinned_points(int p_item, const String &p_what, Variant &r_ret) const {
+ if (pinned_points.size() <= p_item) {
+ return false;
+ }
+ PoolVector<PinnedPoint>::Read r = pinned_points.read();
+
+ if ("point_index" == p_what) {
+ r_ret = r[p_item].point_index;
+ } else if ("spatial_attachment_path" == p_what) {
+ r_ret = r[p_item].spatial_attachment_path;
+ } else if ("offset" == p_what) {
+ r_ret = r[p_item].offset;
+ } else {
+ return false;
+ }
+
+ return true;
+}
+
+void SoftBody::_changed_callback(Object *p_changed, const char *p_prop) {
+ update_physics_server();
+ _reset_points_offsets();
+#ifdef TOOLS_ENABLED
+ if (p_changed == this) {
+ update_configuration_warning();
+ }
+#endif
+}
+
+void SoftBody::_notification(int p_what) {
+ switch (p_what) {
+ case NOTIFICATION_ENTER_WORLD: {
+
+ if (Engine::get_singleton()->is_editor_hint()) {
+
+ add_change_receptor(this);
+ }
+
+ RID space = get_world()->get_space();
+ PhysicsServer::get_singleton()->soft_body_set_space(physics_rid, space);
+ update_physics_server();
+ } break;
+ case NOTIFICATION_READY: {
+ if (!parent_collision_ignore.is_empty())
+ add_collision_exception_with(get_node(parent_collision_ignore));
+
+ } break;
+ case NOTIFICATION_TRANSFORM_CHANGED: {
+
+ if (Engine::get_singleton()->is_editor_hint()) {
+ _reset_points_offsets();
+ return;
+ }
+
+ PhysicsServer::get_singleton()->soft_body_set_transform(physics_rid, get_global_transform());
+
+ set_notify_transform(false);
+ // Required to be top level with Transform at center of world in order to modify VisualServer only to support custom Transform
+ set_as_toplevel(true);
+ set_transform(Transform());
+ set_notify_transform(true);
+
+ } break;
+ case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
+
+ if (!simulation_started)
+ return;
+
+ _update_cache_pin_points_datas();
+ // Submit bone attachment
+ const int pinned_points_indices_size = pinned_points.size();
+ PoolVector<PinnedPoint>::Read r = pinned_points.read();
+ for (int i = 0; i < pinned_points_indices_size; ++i) {
+ if (r[i].spatial_attachment) {
+ PhysicsServer::get_singleton()->soft_body_move_point(physics_rid, r[i].point_index, r[i].spatial_attachment->get_global_transform().xform(r[i].offset));
+ }
+ }
+ } break;
+ case NOTIFICATION_VISIBILITY_CHANGED: {
+
+ _update_pickable();
+
+ } break;
+ case NOTIFICATION_EXIT_WORLD: {
+
+ PhysicsServer::get_singleton()->soft_body_set_space(physics_rid, RID());
+
+ } break;
+ }
+
+#ifdef TOOLS_ENABLED
+
+ if (p_what == NOTIFICATION_LOCAL_TRANSFORM_CHANGED) {
+ if (Engine::get_singleton()->is_editor_hint()) {
+ update_configuration_warning();
+ }
+ }
+
+#endif
+}
+
+void SoftBody::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("_draw_soft_mesh"), &SoftBody::_draw_soft_mesh);
+
+ ClassDB::bind_method(D_METHOD("set_collision_mask", "collision_mask"), &SoftBody::set_collision_mask);
+ ClassDB::bind_method(D_METHOD("get_collision_mask"), &SoftBody::get_collision_mask);
+
+ ClassDB::bind_method(D_METHOD("set_collision_layer", "collision_layer"), &SoftBody::set_collision_layer);
+ ClassDB::bind_method(D_METHOD("get_collision_layer"), &SoftBody::get_collision_layer);
+
+ ClassDB::bind_method(D_METHOD("set_collision_mask_bit", "bit", "value"), &SoftBody::set_collision_mask_bit);
+ ClassDB::bind_method(D_METHOD("get_collision_mask_bit", "bit"), &SoftBody::get_collision_mask_bit);
+
+ ClassDB::bind_method(D_METHOD("set_collision_layer_bit", "bit", "value"), &SoftBody::set_collision_layer_bit);
+ ClassDB::bind_method(D_METHOD("get_collision_layer_bit", "bit"), &SoftBody::get_collision_layer_bit);
+
+ ClassDB::bind_method(D_METHOD("set_parent_collision_ignore", "parent_collision_ignore"), &SoftBody::set_parent_collision_ignore);
+ ClassDB::bind_method(D_METHOD("get_parent_collision_ignore"), &SoftBody::get_parent_collision_ignore);
+
+ ClassDB::bind_method(D_METHOD("add_collision_exception_with", "body"), &SoftBody::add_collision_exception_with);
+ ClassDB::bind_method(D_METHOD("remove_collision_exception_with", "body"), &SoftBody::remove_collision_exception_with);
+
+ ClassDB::bind_method(D_METHOD("set_simulation_precision", "simulation_precision"), &SoftBody::set_simulation_precision);
+ ClassDB::bind_method(D_METHOD("get_simulation_precision"), &SoftBody::get_simulation_precision);
+
+ ClassDB::bind_method(D_METHOD("set_total_mass", "mass"), &SoftBody::set_total_mass);
+ ClassDB::bind_method(D_METHOD("get_total_mass"), &SoftBody::get_total_mass);
+
+ ClassDB::bind_method(D_METHOD("set_linear_stiffness", "linear_stiffness"), &SoftBody::set_linear_stiffness);
+ ClassDB::bind_method(D_METHOD("get_linear_stiffness"), &SoftBody::get_linear_stiffness);
+
+ ClassDB::bind_method(D_METHOD("set_areaAngular_stiffness", "areaAngular_stiffness"), &SoftBody::set_areaAngular_stiffness);
+ ClassDB::bind_method(D_METHOD("get_areaAngular_stiffness"), &SoftBody::get_areaAngular_stiffness);
+
+ ClassDB::bind_method(D_METHOD("set_volume_stiffness", "volume_stiffness"), &SoftBody::set_volume_stiffness);
+ ClassDB::bind_method(D_METHOD("get_volume_stiffness"), &SoftBody::get_volume_stiffness);
+
+ ClassDB::bind_method(D_METHOD("set_pressure_coefficient", "pressure_coefficient"), &SoftBody::set_pressure_coefficient);
+ ClassDB::bind_method(D_METHOD("get_pressure_coefficient"), &SoftBody::get_pressure_coefficient);
+
+ ClassDB::bind_method(D_METHOD("set_pose_matching_coefficient", "pose_matching_coefficient"), &SoftBody::set_pose_matching_coefficient);
+ ClassDB::bind_method(D_METHOD("get_pose_matching_coefficient"), &SoftBody::get_pose_matching_coefficient);
+
+ ClassDB::bind_method(D_METHOD("set_damping_coefficient", "damping_coefficient"), &SoftBody::set_damping_coefficient);
+ ClassDB::bind_method(D_METHOD("get_damping_coefficient"), &SoftBody::get_damping_coefficient);
+
+ ClassDB::bind_method(D_METHOD("set_drag_coefficient", "drag_coefficient"), &SoftBody::set_drag_coefficient);
+ ClassDB::bind_method(D_METHOD("get_drag_coefficient"), &SoftBody::get_drag_coefficient);
+
+ ClassDB::bind_method(D_METHOD("set_ray_pickable", "ray_pickable"), &SoftBody::set_ray_pickable);
+ ClassDB::bind_method(D_METHOD("is_ray_pickable"), &SoftBody::is_ray_pickable);
+
+ ADD_GROUP("Collision", "collision_");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_layer", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_layer", "get_collision_layer");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask");
+
+ ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "parent_collision_ignore", PROPERTY_HINT_PROPERTY_OF_VARIANT_TYPE, "Parent collision object"), "set_parent_collision_ignore", "get_parent_collision_ignore");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "simulation_precision", PROPERTY_HINT_RANGE, "1,100,1"), "set_simulation_precision", "get_simulation_precision");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "total_mass", PROPERTY_HINT_RANGE, "0.01,10000,1"), "set_total_mass", "get_total_mass");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_stiffness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_linear_stiffness", "get_linear_stiffness");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "areaAngular_stiffness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_areaAngular_stiffness", "get_areaAngular_stiffness");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "volume_stiffness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_volume_stiffness", "get_volume_stiffness");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "pressure_coefficient"), "set_pressure_coefficient", "get_pressure_coefficient");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "damping_coefficient", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_damping_coefficient", "get_damping_coefficient");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "drag_coefficient", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_drag_coefficient", "get_drag_coefficient");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "pose_matching_coefficient", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_pose_matching_coefficient", "get_pose_matching_coefficient");
+}
+
+String SoftBody::get_configuration_warning() const {
+
+ String warning = MeshInstance::get_configuration_warning();
+
+ if (get_mesh().is_null()) {
+ if (!warning.empty())
+ warning += "\n\n";
+
+ warning += TTR("This body will be ignored until you set a mesh");
+ }
+
+ Transform t = get_transform();
+ if ((ABS(t.basis.get_axis(0).length() - 1.0) > 0.05 || ABS(t.basis.get_axis(1).length() - 1.0) > 0.05 || ABS(t.basis.get_axis(0).length() - 1.0) > 0.05)) {
+ if (!warning.empty())
+ warning += "\n\n";
+
+ warning += TTR("Size changes to SoftBody will be overriden by the physics engine when running.\nChange the size in children collision shapes instead.");
+ }
+
+ return warning;
+}
+
+void SoftBody::_draw_soft_mesh() {
+ if (get_mesh().is_null())
+ return;
+
+ if (!visual_server_handler.is_ready()) {
+
+ visual_server_handler.prepare(get_mesh()->get_rid(), 0);
+
+ /// Necessary in order to render the mesh correctly (Soft body nodes are in global space)
+ simulation_started = true;
+ call_deferred("set_as_toplevel", true);
+ call_deferred("set_transform", Transform());
+ }
+
+ visual_server_handler.open();
+ PhysicsServer::get_singleton()->soft_body_update_visual_server(physics_rid, &visual_server_handler);
+ visual_server_handler.close();
+
+ visual_server_handler.commit_changes();
+}
+
+void SoftBody::update_physics_server() {
+
+ if (Engine::get_singleton()->is_editor_hint()) {
+
+ if (get_mesh().is_valid())
+ PhysicsServer::get_singleton()->soft_body_set_mesh(physics_rid, get_mesh());
+ else
+ PhysicsServer::get_singleton()->soft_body_set_mesh(physics_rid, NULL);
+
+ return;
+ }
+
+ if (get_mesh().is_valid()) {
+
+ become_mesh_owner();
+ PhysicsServer::get_singleton()->soft_body_set_mesh(physics_rid, get_mesh());
+ VS::get_singleton()->connect("frame_pre_draw", this, "_draw_soft_mesh");
+ } else {
+
+ PhysicsServer::get_singleton()->soft_body_set_mesh(physics_rid, NULL);
+ VS::get_singleton()->disconnect("frame_pre_draw", this, "_draw_soft_mesh");
+ }
+}
+
+void SoftBody::become_mesh_owner() {
+ if (mesh.is_null())
+ return;
+
+ if (!mesh_owner) {
+ mesh_owner = true;
+
+ Vector<Ref<Material> > copy_materials;
+ copy_materials.append_array(materials);
+
+ ERR_FAIL_COND(!mesh->get_surface_count());
+
+ // Get current mesh array and create new mesh array with necessary flag for softbody
+ Array surface_arrays = mesh->surface_get_arrays(0);
+ Array surface_blend_arrays = mesh->surface_get_blend_shape_arrays(0);
+ uint32_t surface_format = mesh->surface_get_format(0);
+
+ surface_format &= ~(Mesh::ARRAY_COMPRESS_VERTEX | Mesh::ARRAY_COMPRESS_NORMAL);
+ surface_format |= Mesh::ARRAY_FLAG_USE_DYNAMIC_UPDATE;
+
+ Ref<ArrayMesh> soft_mesh;
+ soft_mesh.instance();
+ soft_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, surface_arrays, surface_blend_arrays, surface_format);
+ soft_mesh->surface_set_material(0, mesh->surface_get_material(0));
+
+ set_mesh(soft_mesh);
+
+ for (int i = copy_materials.size() - 1; 0 <= i; --i) {
+ set_surface_material(i, copy_materials[i]);
+ }
+ }
+}
+
+void SoftBody::set_collision_mask(uint32_t p_mask) {
+ collision_mask = p_mask;
+ PhysicsServer::get_singleton()->soft_body_set_collision_mask(physics_rid, p_mask);
+}
+
+uint32_t SoftBody::get_collision_mask() const {
+ return collision_mask;
+}
+void SoftBody::set_collision_layer(uint32_t p_layer) {
+ collision_layer = p_layer;
+ PhysicsServer::get_singleton()->soft_body_set_collision_layer(physics_rid, p_layer);
+}
+
+uint32_t SoftBody::get_collision_layer() const {
+ return collision_layer;
+}
+
+void SoftBody::set_collision_mask_bit(int p_bit, bool p_value) {
+ uint32_t mask = get_collision_mask();
+ if (p_value)
+ mask |= 1 << p_bit;
+ else
+ mask &= ~(1 << p_bit);
+ set_collision_mask(mask);
+}
+
+bool SoftBody::get_collision_mask_bit(int p_bit) const {
+ return get_collision_mask() & (1 << p_bit);
+}
+
+void SoftBody::set_collision_layer_bit(int p_bit, bool p_value) {
+ uint32_t layer = get_collision_layer();
+ if (p_value)
+ layer |= 1 << p_bit;
+ else
+ layer &= ~(1 << p_bit);
+ set_collision_layer(layer);
+}
+
+bool SoftBody::get_collision_layer_bit(int p_bit) const {
+ return get_collision_layer() & (1 << p_bit);
+}
+
+void SoftBody::set_parent_collision_ignore(const NodePath &p_parent_collision_ignore) {
+ parent_collision_ignore = p_parent_collision_ignore;
+}
+
+const NodePath &SoftBody::get_parent_collision_ignore() const {
+ return parent_collision_ignore;
+}
+
+void SoftBody::set_pinned_points_indices(PoolVector<SoftBody::PinnedPoint> p_pinned_points_indices) {
+ pinned_points = p_pinned_points_indices;
+ PoolVector<PinnedPoint>::Read w = pinned_points.read();
+ for (int i = pinned_points.size() - 1; 0 <= i; --i) {
+ pin_point(p_pinned_points_indices[i].point_index, true);
+ }
+}
+
+PoolVector<SoftBody::PinnedPoint> SoftBody::get_pinned_points_indices() {
+ return pinned_points;
+}
+
+void SoftBody::add_collision_exception_with(Node *p_node) {
+ ERR_FAIL_NULL(p_node);
+ CollisionObject *collision_object = Object::cast_to<CollisionObject>(p_node);
+ if (!collision_object) {
+ ERR_EXPLAIN("Collision exception only works between two CollisionObject");
+ }
+ ERR_FAIL_COND(!collision_object);
+ PhysicsServer::get_singleton()->soft_body_add_collision_exception(physics_rid, collision_object->get_rid());
+}
+
+void SoftBody::remove_collision_exception_with(Node *p_node) {
+ ERR_FAIL_NULL(p_node);
+ CollisionObject *collision_object = Object::cast_to<CollisionObject>(p_node);
+ if (!collision_object) {
+ ERR_EXPLAIN("Collision exception only works between two CollisionObject");
+ }
+ ERR_FAIL_COND(!collision_object);
+ PhysicsServer::get_singleton()->soft_body_remove_collision_exception(physics_rid, collision_object->get_rid());
+}
+
+int SoftBody::get_simulation_precision() {
+ return PhysicsServer::get_singleton()->soft_body_get_simulation_precision(physics_rid);
+}
+
+void SoftBody::set_simulation_precision(int p_simulation_precision) {
+ PhysicsServer::get_singleton()->soft_body_set_simulation_precision(physics_rid, p_simulation_precision);
+}
+
+real_t SoftBody::get_total_mass() {
+ return PhysicsServer::get_singleton()->soft_body_get_total_mass(physics_rid);
+}
+
+void SoftBody::set_total_mass(real_t p_total_mass) {
+ PhysicsServer::get_singleton()->soft_body_set_total_mass(physics_rid, p_total_mass);
+}
+
+void SoftBody::set_linear_stiffness(real_t p_linear_stiffness) {
+ PhysicsServer::get_singleton()->soft_body_set_linear_stiffness(physics_rid, p_linear_stiffness);
+}
+
+real_t SoftBody::get_linear_stiffness() {
+ return PhysicsServer::get_singleton()->soft_body_get_linear_stiffness(physics_rid);
+}
+
+void SoftBody::set_areaAngular_stiffness(real_t p_areaAngular_stiffness) {
+ PhysicsServer::get_singleton()->soft_body_set_areaAngular_stiffness(physics_rid, p_areaAngular_stiffness);
+}
+
+real_t SoftBody::get_areaAngular_stiffness() {
+ return PhysicsServer::get_singleton()->soft_body_get_areaAngular_stiffness(physics_rid);
+}
+
+void SoftBody::set_volume_stiffness(real_t p_volume_stiffness) {
+ PhysicsServer::get_singleton()->soft_body_set_volume_stiffness(physics_rid, p_volume_stiffness);
+}
+
+real_t SoftBody::get_volume_stiffness() {
+ return PhysicsServer::get_singleton()->soft_body_get_volume_stiffness(physics_rid);
+}
+
+real_t SoftBody::get_pressure_coefficient() {
+ return PhysicsServer::get_singleton()->soft_body_get_pressure_coefficient(physics_rid);
+}
+
+void SoftBody::set_pose_matching_coefficient(real_t p_pose_matching_coefficient) {
+ PhysicsServer::get_singleton()->soft_body_set_pose_matching_coefficient(physics_rid, p_pose_matching_coefficient);
+}
+
+real_t SoftBody::get_pose_matching_coefficient() {
+ return PhysicsServer::get_singleton()->soft_body_get_pose_matching_coefficient(physics_rid);
+}
+
+void SoftBody::set_pressure_coefficient(real_t p_pressure_coefficient) {
+ PhysicsServer::get_singleton()->soft_body_set_pressure_coefficient(physics_rid, p_pressure_coefficient);
+}
+
+real_t SoftBody::get_damping_coefficient() {
+ return PhysicsServer::get_singleton()->soft_body_get_damping_coefficient(physics_rid);
+}
+
+void SoftBody::set_damping_coefficient(real_t p_damping_coefficient) {
+ PhysicsServer::get_singleton()->soft_body_set_damping_coefficient(physics_rid, p_damping_coefficient);
+}
+
+real_t SoftBody::get_drag_coefficient() {
+ return PhysicsServer::get_singleton()->soft_body_get_drag_coefficient(physics_rid);
+}
+
+void SoftBody::set_drag_coefficient(real_t p_drag_coefficient) {
+ PhysicsServer::get_singleton()->soft_body_set_drag_coefficient(physics_rid, p_drag_coefficient);
+}
+
+Vector3 SoftBody::get_point_transform(int p_point_index) {
+ return PhysicsServer::get_singleton()->soft_body_get_point_global_position(physics_rid, p_point_index);
+}
+
+void SoftBody::pin_point_toggle(int p_point_index) {
+ pin_point(p_point_index, !(-1 != _has_pinned_point(p_point_index)));
+}
+
+void SoftBody::pin_point(int p_point_index, bool pin, const NodePath &p_spatial_attachment_path) {
+ _pin_point_on_physics_server(p_point_index, pin);
+ if (pin) {
+ _add_pinned_point(p_point_index, p_spatial_attachment_path);
+ } else {
+ _remove_pinned_point(p_point_index);
+ }
+}
+
+bool SoftBody::is_point_pinned(int p_point_index) const {
+ return -1 != _has_pinned_point(p_point_index);
+}
+
+void SoftBody::set_ray_pickable(bool p_ray_pickable) {
+
+ ray_pickable = p_ray_pickable;
+ _update_pickable();
+}
+
+bool SoftBody::is_ray_pickable() const {
+
+ return ray_pickable;
+}
+
+SoftBody::SoftBody() :
+ MeshInstance(),
+ physics_rid(PhysicsServer::get_singleton()->soft_body_create()),
+ mesh_owner(false),
+ collision_mask(1),
+ collision_layer(1),
+ simulation_started(false),
+ pinned_points_cache_dirty(true) {
+
+ PhysicsServer::get_singleton()->body_attach_object_instance_id(physics_rid, get_instance_id());
+ //set_notify_transform(true);
+ set_physics_process_internal(true);
+}
+
+SoftBody::~SoftBody() {
+}
+
+void SoftBody::reset_softbody_pin() {
+ PhysicsServer::get_singleton()->soft_body_remove_all_pinned_points(physics_rid);
+ PoolVector<PinnedPoint>::Read pps = pinned_points.read();
+ for (int i = pinned_points.size() - 1; 0 < i; --i) {
+ PhysicsServer::get_singleton()->soft_body_pin_point(physics_rid, pps[i].point_index, true);
+ }
+}
+
+void SoftBody::_make_cache_dirty() {
+ pinned_points_cache_dirty = true;
+}
+
+void SoftBody::_update_cache_pin_points_datas() {
+ if (!pinned_points_cache_dirty)
+ return;
+
+ pinned_points_cache_dirty = false;
+
+ PoolVector<PinnedPoint>::Write w = pinned_points.write();
+ for (int i = pinned_points.size() - 1; 0 <= i; --i) {
+
+ if (!w[i].spatial_attachment_path.is_empty()) {
+ w[i].spatial_attachment = Object::cast_to<Spatial>(get_node(w[i].spatial_attachment_path));
+ }
+ if (!w[i].spatial_attachment) {
+ ERR_PRINT("Spatial node not defined in the pinned point, Softbody undefined behaviour!");
+ }
+ }
+}
+
+void SoftBody::_pin_point_on_physics_server(int p_point_index, bool pin) {
+ PhysicsServer::get_singleton()->soft_body_pin_point(physics_rid, p_point_index, pin);
+}
+
+void SoftBody::_add_pinned_point(int p_point_index, const NodePath &p_spatial_attachment_path) {
+ SoftBody::PinnedPoint *pinned_point;
+ if (-1 == _get_pinned_point(p_point_index, pinned_point)) {
+
+ // Create new
+ PinnedPoint pp;
+ pp.point_index = p_point_index;
+ pp.spatial_attachment_path = p_spatial_attachment_path;
+
+ if (!p_spatial_attachment_path.is_empty() && has_node(p_spatial_attachment_path)) {
+ pp.spatial_attachment = Object::cast_to<Spatial>(get_node(p_spatial_attachment_path));
+ pp.offset = (pp.spatial_attachment->get_global_transform().affine_inverse() * get_global_transform()).xform(PhysicsServer::get_singleton()->soft_body_get_point_global_position(physics_rid, pp.point_index));
+ }
+
+ pinned_points.push_back(pp);
+
+ } else {
+
+ pinned_point->point_index = p_point_index;
+ pinned_point->spatial_attachment_path = p_spatial_attachment_path;
+
+ if (!p_spatial_attachment_path.is_empty() && has_node(p_spatial_attachment_path)) {
+ pinned_point->spatial_attachment = Object::cast_to<Spatial>(get_node(p_spatial_attachment_path));
+ pinned_point->offset = (pinned_point->spatial_attachment->get_global_transform().affine_inverse() * get_global_transform()).xform(PhysicsServer::get_singleton()->soft_body_get_point_global_position(physics_rid, pinned_point->point_index));
+ }
+ }
+}
+
+void SoftBody::_reset_points_offsets() {
+
+ if (!Engine::get_singleton()->is_editor_hint())
+ return;
+
+ PoolVector<PinnedPoint>::Read r = pinned_points.read();
+ PoolVector<PinnedPoint>::Write w = pinned_points.write();
+ for (int i = pinned_points.size() - 1; 0 <= i; --i) {
+
+ if (!r[i].spatial_attachment)
+ w[i].spatial_attachment = Object::cast_to<Spatial>(get_node(r[i].spatial_attachment_path));
+
+ if (!r[i].spatial_attachment)
+ continue;
+
+ w[i].offset = (r[i].spatial_attachment->get_global_transform().affine_inverse() * get_global_transform()).xform(PhysicsServer::get_singleton()->soft_body_get_point_global_position(physics_rid, r[i].point_index));
+ }
+}
+
+void SoftBody::_remove_pinned_point(int p_point_index) {
+ const int id(_has_pinned_point(p_point_index));
+ if (-1 != id) {
+ pinned_points.remove(id);
+ }
+}
+
+int SoftBody::_get_pinned_point(int p_point_index, SoftBody::PinnedPoint *&r_point) const {
+ const int id = _has_pinned_point(p_point_index);
+ if (-1 == id) {
+ r_point = NULL;
+ return -1;
+ } else {
+ r_point = const_cast<SoftBody::PinnedPoint *>(&pinned_points.read()[id]);
+ return id;
+ }
+}
+
+int SoftBody::_has_pinned_point(int p_point_index) const {
+ PoolVector<PinnedPoint>::Read r = pinned_points.read();
+ for (int i = pinned_points.size() - 1; 0 <= i; --i) {
+ if (p_point_index == r[i].point_index) {
+ return i;
+ }
+ }
+ return -1;
+}
diff --git a/scene/3d/soft_body.h b/scene/3d/soft_body.h
new file mode 100644
index 0000000000..cee32b9651
--- /dev/null
+++ b/scene/3d/soft_body.h
@@ -0,0 +1,200 @@
+/*************************************************************************/
+/* soft_physics_body.h */
+/* Author: AndreaCatania */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* 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. */
+/*************************************************************************/
+
+#ifndef SOFT_PHYSICS_BODY_H
+#define SOFT_PHYSICS_BODY_H
+
+#include "scene/3d/mesh_instance.h"
+
+class SoftBody;
+
+class SoftBodyVisualServerHandler {
+
+ friend class SoftBody;
+
+ RID mesh;
+ int surface;
+ PoolVector<uint8_t> buffer;
+ uint32_t stride;
+ uint32_t offset_vertices;
+ uint32_t offset_normal;
+
+ PoolVector<uint8_t>::Write write_buffer;
+
+private:
+ SoftBodyVisualServerHandler();
+ bool is_ready() { return mesh.is_valid(); }
+ void prepare(RID p_mesh_rid, int p_surface);
+ void clear();
+ void open();
+ void close();
+ void commit_changes();
+
+public:
+ void set_vertex(int p_vertex_id, const void *p_vector3);
+ void set_normal(int p_vertex_id, const void *p_vector3);
+ void set_aabb(const AABB &p_aabb);
+};
+
+class SoftBody : public MeshInstance {
+ GDCLASS(SoftBody, MeshInstance);
+
+public:
+ struct PinnedPoint {
+ int point_index;
+ NodePath spatial_attachment_path;
+ Spatial *spatial_attachment; // Cache
+ Vector3 offset;
+
+ PinnedPoint();
+ PinnedPoint(const PinnedPoint &obj_tocopy);
+ };
+
+private:
+ SoftBodyVisualServerHandler visual_server_handler;
+
+ RID physics_rid;
+
+ bool mesh_owner;
+ uint32_t collision_mask;
+ uint32_t collision_layer;
+ NodePath parent_collision_ignore;
+ PoolVector<PinnedPoint> pinned_points;
+ bool simulation_started;
+ bool pinned_points_cache_dirty;
+
+ Ref<ArrayMesh> debug_mesh_cache;
+ class MeshInstance *debug_mesh;
+
+ bool capture_input_on_drag;
+ bool ray_pickable;
+
+ void _update_pickable();
+
+protected:
+ bool _set(const StringName &p_name, const Variant &p_value);
+ bool _get(const StringName &p_name, Variant &r_ret) const;
+ void _get_property_list(List<PropertyInfo> *p_list) const;
+
+ bool _set_property_pinned_points_indices(const Array &p_indices);
+ bool _set_property_pinned_points_attachment(int p_item, const String &p_what, const Variant &p_value);
+ bool _get_property_pinned_points(int p_item, const String &p_what, Variant &r_ret) const;
+
+ virtual void _changed_callback(Object *p_changed, const char *p_prop);
+
+ void _notification(int p_what);
+ static void _bind_methods();
+
+ virtual String get_configuration_warning() const;
+
+protected:
+ void _draw_soft_mesh();
+
+public:
+ void update_physics_server();
+ void become_mesh_owner();
+
+ void set_collision_mask(uint32_t p_mask);
+ uint32_t get_collision_mask() const;
+
+ void set_collision_layer(uint32_t p_layer);
+ uint32_t get_collision_layer() const;
+
+ void set_collision_mask_bit(int p_bit, bool p_value);
+ bool get_collision_mask_bit(int p_bit) const;
+
+ void set_collision_layer_bit(int p_bit, bool p_value);
+ bool get_collision_layer_bit(int p_bit) const;
+
+ void set_parent_collision_ignore(const NodePath &p_parent_collision_ignore);
+ const NodePath &get_parent_collision_ignore() const;
+
+ void set_pinned_points_indices(PoolVector<PinnedPoint> p_pinned_points_indices);
+ PoolVector<PinnedPoint> get_pinned_points_indices();
+
+ void set_simulation_precision(int p_simulation_precision);
+ int get_simulation_precision();
+
+ void set_total_mass(real_t p_total_mass);
+ real_t get_total_mass();
+
+ void set_linear_stiffness(real_t p_linear_stiffness);
+ real_t get_linear_stiffness();
+
+ void set_areaAngular_stiffness(real_t p_areaAngular_stiffness);
+ real_t get_areaAngular_stiffness();
+
+ void set_volume_stiffness(real_t p_volume_stiffness);
+ real_t get_volume_stiffness();
+
+ void set_pressure_coefficient(real_t p_pressure_coefficient);
+ real_t get_pressure_coefficient();
+
+ void set_pose_matching_coefficient(real_t p_pose_matching_coefficient);
+ real_t get_pose_matching_coefficient();
+
+ void set_damping_coefficient(real_t p_damping_coefficient);
+ real_t get_damping_coefficient();
+
+ void set_drag_coefficient(real_t p_drag_coefficient);
+ real_t get_drag_coefficient();
+
+ void add_collision_exception_with(Node *p_node);
+ void remove_collision_exception_with(Node *p_node);
+
+ Vector3 get_point_transform(int p_point_index);
+
+ void pin_point_toggle(int p_point_index);
+ void pin_point(int p_point_index, bool pin, const NodePath &p_spatial_attachment_path = NodePath());
+ bool is_point_pinned(int p_point_index) const;
+
+ void set_ray_pickable(bool p_ray_pickable);
+ bool is_ray_pickable() const;
+
+ SoftBody();
+ ~SoftBody();
+
+private:
+ void reset_softbody_pin();
+
+ void _make_cache_dirty();
+ void _update_cache_pin_points_datas();
+
+ void _pin_point_on_physics_server(int p_point_index, bool pin);
+ void _add_pinned_point(int p_point_index, const NodePath &p_spatial_attachment_path);
+ void _reset_points_offsets();
+
+ void _remove_pinned_point(int p_point_index);
+ int _get_pinned_point(int p_point_index, PinnedPoint *&r_point) const;
+ int _has_pinned_point(int p_point_index) const;
+};
+
+#endif // SOFT_PHYSICS_BODY_H
diff --git a/scene/3d/spatial.cpp b/scene/3d/spatial.cpp
index 748aa8aad4..3f494264e7 100644
--- a/scene/3d/spatial.cpp
+++ b/scene/3d/spatial.cpp
@@ -202,6 +202,7 @@ void Spatial::_notification(int p_what) {
#ifdef TOOLS_ENABLED
if (data.gizmo.is_valid()) {
data.gizmo->free();
+ data.gizmo.unref();
}
#endif
@@ -280,6 +281,10 @@ Transform Spatial::get_global_transform() const {
data.global_transform = data.local_transform;
}
+ if (data.disable_scale) {
+ data.global_transform.basis.orthonormalize();
+ }
+
data.dirty &= ~DIRTY_GLOBAL;
}
@@ -467,6 +472,15 @@ void Spatial::set_disable_gizmo(bool p_enabled) {
#endif
+void Spatial::set_disable_scale(bool p_enabled) {
+
+ data.disable_scale = p_enabled;
+}
+
+bool Spatial::is_scale_disabled() const {
+ return data.disable_scale;
+}
+
void Spatial::set_as_toplevel(bool p_enabled) {
if (data.toplevel == p_enabled)
@@ -632,19 +646,15 @@ void Spatial::scale_object_local(const Vector3 &p_scale) {
void Spatial::global_rotate(const Vector3 &p_axis, float p_angle) {
- Basis rotation(p_axis, p_angle);
Transform t = get_global_transform();
- t.basis = rotation * t.basis;
+ t.basis.rotate(p_axis, p_angle);
set_global_transform(t);
}
void Spatial::global_scale(const Vector3 &p_scale) {
- Basis s;
- s.set_scale(p_scale);
-
Transform t = get_global_transform();
- t.basis = s * t.basis;
+ t.basis.scale(p_scale);
set_global_transform(t);
}
@@ -735,6 +745,8 @@ void Spatial::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_ignore_transform_notification", "enabled"), &Spatial::set_ignore_transform_notification);
ClassDB::bind_method(D_METHOD("set_as_toplevel", "enable"), &Spatial::set_as_toplevel);
ClassDB::bind_method(D_METHOD("is_set_as_toplevel"), &Spatial::is_set_as_toplevel);
+ ClassDB::bind_method(D_METHOD("set_disable_scale", "disable"), &Spatial::set_disable_scale);
+ ClassDB::bind_method(D_METHOD("is_scale_disabled"), &Spatial::is_scale_disabled);
ClassDB::bind_method(D_METHOD("get_world"), &Spatial::get_world);
ClassDB::bind_method(D_METHOD("_update_gizmo"), &Spatial::_update_gizmo);
@@ -755,15 +767,6 @@ void Spatial::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_notify_transform", "enable"), &Spatial::set_notify_transform);
ClassDB::bind_method(D_METHOD("is_transform_notification_enabled"), &Spatial::is_transform_notification_enabled);
- void rotate(const Vector3 &p_axis, float p_angle);
- void rotate_x(float p_angle);
- void rotate_y(float p_angle);
- void rotate_z(float p_angle);
- void translate(const Vector3 &p_offset);
- void scale(const Vector3 &p_ratio);
- void global_rotate(const Vector3 &p_axis, float p_angle);
- void global_translate(const Vector3 &p_offset);
-
ClassDB::bind_method(D_METHOD("rotate", "axis", "angle"), &Spatial::rotate);
ClassDB::bind_method(D_METHOD("global_rotate", "axis", "angle"), &Spatial::global_rotate);
ClassDB::bind_method(D_METHOD("global_scale", "scale"), &Spatial::global_scale);
@@ -791,12 +794,13 @@ void Spatial::_bind_methods() {
//ADD_PROPERTY( PropertyInfo(Variant::TRANSFORM,"transform/global",PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR ), "set_global_transform", "get_global_transform") ;
ADD_GROUP("Transform", "");
- ADD_PROPERTYNZ(PropertyInfo(Variant::TRANSFORM, "transform", PROPERTY_HINT_NONE, ""), "set_transform", "get_transform");
ADD_PROPERTYNZ(PropertyInfo(Variant::TRANSFORM, "global_transform", PROPERTY_HINT_NONE, "", 0), "set_global_transform", "get_global_transform");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "translation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_translation", "get_translation");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "rotation_degrees", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_rotation_degrees", "get_rotation_degrees");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "rotation", PROPERTY_HINT_NONE, "", 0), "set_rotation", "get_rotation");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "scale", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_scale", "get_scale");
+ ADD_GROUP("Matrix", "");
+ ADD_PROPERTYNZ(PropertyInfo(Variant::TRANSFORM, "transform", PROPERTY_HINT_NONE, ""), "set_transform", "get_transform");
ADD_GROUP("Visibility", "");
ADD_PROPERTYNO(PropertyInfo(Variant::BOOL, "visible"), "set_visible", "is_visible");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "gizmo", PROPERTY_HINT_RESOURCE_TYPE, "SpatialGizmo", 0), "set_gizmo", "get_gizmo");
@@ -817,6 +821,7 @@ Spatial::Spatial() :
data.viewport = NULL;
data.inside_world = false;
data.visible = true;
+ data.disable_scale = false;
#ifdef TOOLS_ENABLED
data.gizmo_disabled = false;
diff --git a/scene/3d/spatial.h b/scene/3d/spatial.h
index a43bed3e4a..bc054a8763 100644
--- a/scene/3d/spatial.h
+++ b/scene/3d/spatial.h
@@ -51,6 +51,7 @@ public:
virtual bool can_draw() const = 0;
SpatialGizmo();
+ virtual ~SpatialGizmo() {}
};
class Spatial : public Node {
@@ -92,6 +93,7 @@ class Spatial : public Node {
bool notify_transform;
bool visible;
+ bool disable_scale;
#ifdef TOOLS_ENABLED
Ref<SpatialGizmo> gizmo;
@@ -153,6 +155,9 @@ public:
void set_as_toplevel(bool p_enabled);
bool is_set_as_toplevel() const;
+ void set_disable_scale(bool p_enabled);
+ bool is_scale_disabled() const;
+
void set_disable_gizmo(bool p_enabled);
void update_gizmo();
void set_gizmo(const Ref<SpatialGizmo> &p_gizmo);
diff --git a/scene/3d/spatial_velocity_tracker.cpp b/scene/3d/spatial_velocity_tracker.cpp
index c547e76e30..d96b003a81 100644
--- a/scene/3d/spatial_velocity_tracker.cpp
+++ b/scene/3d/spatial_velocity_tracker.cpp
@@ -53,11 +53,11 @@ void SpatialVelocityTracker::update_position(const Vector3 &p_position) {
if (position_history_len == 0 || position_history[0].frame != ph.frame) { //in same frame, use latest
position_history_len = MIN(position_history.size(), position_history_len + 1);
for (int i = position_history_len - 1; i > 0; i--) {
- position_history[i] = position_history[i - 1];
+ position_history.write[i] = position_history[i - 1];
}
}
- position_history[0] = ph;
+ position_history.write[0] = ph;
}
Vector3 SpatialVelocityTracker::get_tracked_linear_velocity() const {
@@ -114,7 +114,7 @@ void SpatialVelocityTracker::reset(const Vector3 &p_new_pos) {
ph.frame = Engine::get_singleton()->get_idle_frame_ticks();
}
- position_history[0] = ph;
+ position_history.write[0] = ph;
position_history_len = 1;
}
diff --git a/scene/3d/spring_arm.cpp b/scene/3d/spring_arm.cpp
new file mode 100644
index 0000000000..492c6b806e
--- /dev/null
+++ b/scene/3d/spring_arm.cpp
@@ -0,0 +1,172 @@
+/*************************************************************************/
+/* spring_arm.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* 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. */
+/*************************************************************************/
+
+#include "spring_arm.h"
+#include "engine.h"
+#include "scene/3d/collision_object.h"
+#include "scene/resources/sphere_shape.h"
+#include "servers/physics_server.h"
+
+SpringArm::SpringArm() :
+ spring_length(1),
+ mask(1),
+ current_spring_length(0),
+ margin(0.01) {}
+
+void SpringArm::_notification(int p_what) {
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE:
+ if (!Engine::get_singleton()->is_editor_hint()) {
+ set_process_internal(true);
+ }
+ break;
+ case NOTIFICATION_EXIT_TREE:
+ if (!Engine::get_singleton()->is_editor_hint()) {
+ set_process_internal(false);
+ }
+ break;
+ case NOTIFICATION_INTERNAL_PROCESS:
+ process_spring();
+ break;
+ }
+}
+
+void SpringArm::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("get_hit_length"), &SpringArm::get_hit_length);
+
+ ClassDB::bind_method(D_METHOD("set_length", "length"), &SpringArm::set_length);
+ ClassDB::bind_method(D_METHOD("get_length"), &SpringArm::get_length);
+
+ ClassDB::bind_method(D_METHOD("set_shape", "shape"), &SpringArm::set_shape);
+ ClassDB::bind_method(D_METHOD("get_shape"), &SpringArm::get_shape);
+
+ ClassDB::bind_method(D_METHOD("add_excluded_object", "RID"), &SpringArm::add_excluded_object);
+ ClassDB::bind_method(D_METHOD("remove_excluded_object", "RID"), &SpringArm::remove_excluded_object);
+ ClassDB::bind_method(D_METHOD("clear_excluded_objects"), &SpringArm::clear_excluded_objects);
+
+ ClassDB::bind_method(D_METHOD("set_collision_mask", "mask"), &SpringArm::set_mask);
+ ClassDB::bind_method(D_METHOD("get_collision_mask"), &SpringArm::get_mask);
+
+ ClassDB::bind_method(D_METHOD("set_margin", "margin"), &SpringArm::set_margin);
+ ClassDB::bind_method(D_METHOD("get_margin"), &SpringArm::get_margin);
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape"), "set_shape", "get_shape");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "spring_length"), "set_length", "get_length");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "margin"), "set_margin", "get_margin");
+}
+
+float SpringArm::get_length() const {
+ return spring_length;
+}
+
+void SpringArm::set_length(float p_length) {
+ if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_collisions_hint()))
+ update_gizmo();
+
+ spring_length = p_length;
+}
+
+void SpringArm::set_shape(Ref<Shape> p_shape) {
+ shape = p_shape;
+}
+
+Ref<Shape> SpringArm::get_shape() const {
+ return shape;
+}
+
+void SpringArm::set_mask(uint32_t p_mask) {
+ mask = p_mask;
+}
+
+uint32_t SpringArm::get_mask() {
+ return mask;
+}
+
+float SpringArm::get_margin() {
+ return margin;
+}
+
+void SpringArm::set_margin(float p_margin) {
+ margin = p_margin;
+}
+
+void SpringArm::add_excluded_object(RID p_rid) {
+ excluded_objects.insert(p_rid);
+}
+
+bool SpringArm::remove_excluded_object(RID p_rid) {
+ return excluded_objects.erase(p_rid);
+}
+
+void SpringArm::clear_excluded_objects() {
+ excluded_objects.clear();
+}
+
+float SpringArm::get_hit_length() {
+ return current_spring_length;
+}
+
+void SpringArm::process_spring() {
+ // From
+ real_t motion_delta(1);
+ real_t motion_delta_unsafe(1);
+
+ Vector3 motion;
+ const Vector3 cast_direction(get_global_transform().basis.xform(Vector3(0, 0, 1)));
+
+ if (shape.is_null()) {
+ motion = Vector3(cast_direction * (spring_length));
+ PhysicsDirectSpaceState::RayResult r;
+ bool intersected = get_world()->get_direct_space_state()->intersect_ray(get_global_transform().origin, get_global_transform().origin + motion, r, excluded_objects, mask);
+ if (intersected) {
+ float dist = get_global_transform().origin.distance_to(r.position);
+ dist -= margin;
+ motion_delta = dist / (spring_length);
+ }
+ } else {
+ motion = Vector3(cast_direction * spring_length);
+ get_world()->get_direct_space_state()->cast_motion(shape->get_rid(), get_global_transform(), motion, 0, motion_delta, motion_delta_unsafe, excluded_objects, mask);
+ }
+
+ current_spring_length = spring_length * motion_delta;
+ Transform childs_transform;
+ childs_transform.origin = get_global_transform().origin + cast_direction * (spring_length * motion_delta);
+
+ for (int i = get_child_count() - 1; 0 <= i; --i) {
+
+ Spatial *child = Object::cast_to<Spatial>(get_child(i));
+ if (child) {
+ childs_transform.basis = child->get_global_transform().basis;
+ child->set_global_transform(childs_transform);
+ }
+ }
+}
diff --git a/scene/3d/spring_arm.h b/scene/3d/spring_arm.h
new file mode 100644
index 0000000000..24d912d371
--- /dev/null
+++ b/scene/3d/spring_arm.h
@@ -0,0 +1,71 @@
+/*************************************************************************/
+/* spring_arm.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* 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. */
+/*************************************************************************/
+
+#ifndef SPRING_ARM_H
+#define SPRING_ARM_H
+
+#include "scene/3d/spatial.h"
+
+class SpringArm : public Spatial {
+ GDCLASS(SpringArm, Spatial);
+
+ Ref<Shape> shape;
+ Set<RID> excluded_objects;
+ float spring_length;
+ bool keep_child_basis;
+ float current_spring_length;
+ uint32_t mask;
+ float margin;
+
+protected:
+ void _notification(int p_what);
+ static void _bind_methods();
+
+public:
+ void set_length(float p_length);
+ float get_length() const;
+ void set_shape(Ref<Shape> p_shape);
+ Ref<Shape> get_shape() const;
+ void set_mask(uint32_t p_mask);
+ uint32_t get_mask();
+ void add_excluded_object(RID p_rid);
+ bool remove_excluded_object(RID p_rid);
+ void clear_excluded_objects();
+ float get_hit_length();
+ void set_margin(float p_margin);
+ float get_margin();
+
+ SpringArm();
+
+private:
+ void process_spring();
+};
+
+#endif
diff --git a/scene/3d/vehicle_body.cpp b/scene/3d/vehicle_body.cpp
index 385956dc16..26958930e4 100644
--- a/scene/3d/vehicle_body.cpp
+++ b/scene/3d/vehicle_body.cpp
@@ -524,7 +524,7 @@ void VehicleBody::_update_suspension(PhysicsDirectBodyState *s) {
//bilateral constraint between two dynamic objects
void VehicleBody::_resolve_single_bilateral(PhysicsDirectBodyState *s, const Vector3 &pos1,
- PhysicsBody *body2, const Vector3 &pos2, const Vector3 &normal, real_t &impulse, real_t p_rollInfluence) {
+ PhysicsBody *body2, const Vector3 &pos2, const Vector3 &normal, real_t &impulse, const real_t p_rollInfluence) {
real_t normalLenSqr = normal.length_squared();
//ERR_FAIL_COND( normalLenSqr < real_t(1.1));
@@ -677,8 +677,8 @@ void VehicleBody::_update_friction(PhysicsDirectBodyState *s) {
//collapse all those loops into one!
for (int i = 0; i < wheels.size(); i++) {
- m_sideImpulse[i] = real_t(0.);
- m_forwardImpulse[i] = real_t(0.);
+ m_sideImpulse.write[i] = real_t(0.);
+ m_forwardImpulse.write[i] = real_t(0.);
}
{
@@ -693,22 +693,22 @@ void VehicleBody::_update_friction(PhysicsDirectBodyState *s) {
Basis wheelBasis0 = wheelInfo.m_worldTransform.basis; //get_global_transform().basis;
- m_axle[i] = wheelBasis0.get_axis(Vector3::AXIS_X);
+ m_axle.write[i] = wheelBasis0.get_axis(Vector3::AXIS_X);
//m_axle[i] = wheelInfo.m_raycastInfo.m_wheelAxleWS;
const Vector3 &surfNormalWS = wheelInfo.m_raycastInfo.m_contactNormalWS;
real_t proj = m_axle[i].dot(surfNormalWS);
- m_axle[i] -= surfNormalWS * proj;
- m_axle[i] = m_axle[i].normalized();
+ m_axle.write[i] -= surfNormalWS * proj;
+ m_axle.write[i] = m_axle[i].normalized();
- m_forwardWS[i] = surfNormalWS.cross(m_axle[i]);
- m_forwardWS[i].normalize();
+ m_forwardWS.write[i] = surfNormalWS.cross(m_axle[i]);
+ m_forwardWS.write[i].normalize();
_resolve_single_bilateral(s, wheelInfo.m_raycastInfo.m_contactPointWS,
wheelInfo.m_raycastInfo.m_groundObject, wheelInfo.m_raycastInfo.m_contactPointWS,
- m_axle[i], m_sideImpulse[i], wheelInfo.m_rollInfluence);
+ m_axle[i], m_sideImpulse.write[i], wheelInfo.m_rollInfluence);
- m_sideImpulse[i] *= sideFrictionStiffness2;
+ m_sideImpulse.write[i] *= sideFrictionStiffness2;
}
}
}
@@ -739,7 +739,7 @@ void VehicleBody::_update_friction(PhysicsDirectBodyState *s) {
//switch between active rolling (throttle), braking and non-active rolling friction (no throttle/break)
- m_forwardImpulse[wheel] = real_t(0.);
+ m_forwardImpulse.write[wheel] = real_t(0.);
wheelInfo.m_skidInfo = real_t(1.);
if (wheelInfo.m_raycastInfo.m_isInContact) {
@@ -750,7 +750,7 @@ void VehicleBody::_update_friction(PhysicsDirectBodyState *s) {
real_t maximpSquared = maximp * maximpSide;
- m_forwardImpulse[wheel] = rollingFriction; //wheelInfo.m_engineForce* timeStep;
+ m_forwardImpulse.write[wheel] = rollingFriction; //wheelInfo.m_engineForce* timeStep;
real_t x = (m_forwardImpulse[wheel]) * fwdFactor;
real_t y = (m_sideImpulse[wheel]) * sideFactor;
@@ -772,8 +772,8 @@ void VehicleBody::_update_friction(PhysicsDirectBodyState *s) {
for (int wheel = 0; wheel < wheels.size(); wheel++) {
if (m_sideImpulse[wheel] != real_t(0.)) {
if (wheels[wheel]->m_skidInfo < real_t(1.)) {
- m_forwardImpulse[wheel] *= wheels[wheel]->m_skidInfo;
- m_sideImpulse[wheel] *= wheels[wheel]->m_skidInfo;
+ m_forwardImpulse.write[wheel] *= wheels[wheel]->m_skidInfo;
+ m_sideImpulse.write[wheel] *= wheels[wheel]->m_skidInfo;
}
}
}
@@ -942,8 +942,6 @@ VehicleBody::VehicleBody() :
engine_force = 0;
brake = 0;
- friction = 1;
-
state = NULL;
ccd = false;
diff --git a/scene/3d/vehicle_body.h b/scene/3d/vehicle_body.h
index 1ac3693cc4..68fbf8d873 100644
--- a/scene/3d/vehicle_body.h
+++ b/scene/3d/vehicle_body.h
@@ -168,7 +168,7 @@ class VehicleBody : public RigidBody {
btVehicleWheelContactPoint(PhysicsDirectBodyState *s, PhysicsBody *body1, const Vector3 &frictionPosWorld, const Vector3 &frictionDirectionWorld, real_t maxImpulse);
};
- void _resolve_single_bilateral(PhysicsDirectBodyState *s, const Vector3 &pos1, PhysicsBody *body2, const Vector3 &pos2, const Vector3 &normal, real_t &impulse, real_t p_rollInfluence);
+ void _resolve_single_bilateral(PhysicsDirectBodyState *s, const Vector3 &pos1, PhysicsBody *body2, const Vector3 &pos2, const Vector3 &normal, real_t &impulse, const real_t p_rollInfluence);
real_t _calc_rolling_friction(btVehicleWheelContactPoint &contactPoint);
void _update_friction(PhysicsDirectBodyState *s);
diff --git a/scene/3d/visual_instance.cpp b/scene/3d/visual_instance.cpp
index 00541a7d8a..767518dc83 100644
--- a/scene/3d/visual_instance.cpp
+++ b/scene/3d/visual_instance.cpp
@@ -105,12 +105,28 @@ uint32_t VisualInstance::get_layer_mask() const {
return layers;
}
+void VisualInstance::set_layer_mask_bit(int p_layer, bool p_enable) {
+ ERR_FAIL_INDEX(p_layer, 32);
+ if (p_enable) {
+ set_layer_mask(layers | (1 << p_layer));
+ } else {
+ set_layer_mask(layers & (~(1 << p_layer)));
+ }
+}
+
+bool VisualInstance::get_layer_mask_bit(int p_layer) const {
+ ERR_FAIL_INDEX_V(p_layer, 32, false);
+ return (layers & (1 << p_layer));
+}
+
void VisualInstance::_bind_methods() {
ClassDB::bind_method(D_METHOD("_get_visual_instance_rid"), &VisualInstance::_get_visual_instance_rid);
ClassDB::bind_method(D_METHOD("set_base", "base"), &VisualInstance::set_base);
ClassDB::bind_method(D_METHOD("set_layer_mask", "mask"), &VisualInstance::set_layer_mask);
ClassDB::bind_method(D_METHOD("get_layer_mask"), &VisualInstance::get_layer_mask);
+ ClassDB::bind_method(D_METHOD("set_layer_mask_bit", "layer", "enabled"), &VisualInstance::set_layer_mask_bit);
+ ClassDB::bind_method(D_METHOD("get_layer_mask_bit", "layer"), &VisualInstance::get_layer_mask_bit);
ClassDB::bind_method(D_METHOD("get_transformed_aabb"), &VisualInstance::get_transformed_aabb);
diff --git a/scene/3d/visual_instance.h b/scene/3d/visual_instance.h
index 8458a343b2..9249bc04ce 100644
--- a/scene/3d/visual_instance.h
+++ b/scene/3d/visual_instance.h
@@ -73,6 +73,9 @@ public:
void set_layer_mask(uint32_t p_mask);
uint32_t get_layer_mask() const;
+ void set_layer_mask_bit(int p_layer, bool p_enable);
+ bool get_layer_mask_bit(int p_layer) const;
+
VisualInstance();
~VisualInstance();
};
diff --git a/scene/3d/voxel_light_baker.cpp b/scene/3d/voxel_light_baker.cpp
index 670df5cc7f..f3abdc6bbe 100644
--- a/scene/3d/voxel_light_baker.cpp
+++ b/scene/3d/voxel_light_baker.cpp
@@ -113,7 +113,7 @@ static bool planeBoxOverlap(Vector3 normal, float d, Vector3 maxbox) {
rad = fa * boxhalfsize.x + fb * boxhalfsize.z; \
if (min > rad || max < -rad) return false;
- /*======================== Z-tests ========================*/
+/*======================== Z-tests ========================*/
#define AXISTEST_Z12(a, b, fa, fb) \
p1 = a * v1.x - b * v1.y; \
@@ -409,16 +409,16 @@ void VoxelLightBaker::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p
}
//put this temporarily here, corrected in a later step
- bake_cells[p_idx].albedo[0] += albedo_accum.r;
- bake_cells[p_idx].albedo[1] += albedo_accum.g;
- bake_cells[p_idx].albedo[2] += albedo_accum.b;
- bake_cells[p_idx].emission[0] += emission_accum.r;
- bake_cells[p_idx].emission[1] += emission_accum.g;
- bake_cells[p_idx].emission[2] += emission_accum.b;
- bake_cells[p_idx].normal[0] += normal_accum.x;
- bake_cells[p_idx].normal[1] += normal_accum.y;
- bake_cells[p_idx].normal[2] += normal_accum.z;
- bake_cells[p_idx].alpha += alpha;
+ bake_cells.write[p_idx].albedo[0] += albedo_accum.r;
+ bake_cells.write[p_idx].albedo[1] += albedo_accum.g;
+ bake_cells.write[p_idx].albedo[2] += albedo_accum.b;
+ bake_cells.write[p_idx].emission[0] += emission_accum.r;
+ bake_cells.write[p_idx].emission[1] += emission_accum.g;
+ bake_cells.write[p_idx].emission[2] += emission_accum.b;
+ bake_cells.write[p_idx].normal[0] += normal_accum.x;
+ bake_cells.write[p_idx].normal[1] += normal_accum.y;
+ bake_cells.write[p_idx].normal[2] += normal_accum.z;
+ bake_cells.write[p_idx].alpha += alpha;
} else {
//go down
@@ -465,9 +465,9 @@ void VoxelLightBaker::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p
//sub cell must be created
uint32_t child_idx = bake_cells.size();
- bake_cells[p_idx].children[i] = child_idx;
+ bake_cells.write[p_idx].children[i] = child_idx;
bake_cells.resize(bake_cells.size() + 1);
- bake_cells[child_idx].level = p_level + 1;
+ bake_cells.write[child_idx].level = p_level + 1;
}
_plot_face(bake_cells[p_idx].children[i], p_level + 1, nx, ny, nz, p_vtx, p_normal, p_uv, p_material, aabb);
@@ -483,7 +483,7 @@ Vector<Color> VoxelLightBaker::_get_bake_texture(Ref<Image> p_image, const Color
ret.resize(bake_texture_size * bake_texture_size);
for (int i = 0; i < bake_texture_size * bake_texture_size; i++) {
- ret[i] = p_color_add;
+ ret.write[i] = p_color_add;
}
return ret;
@@ -509,7 +509,7 @@ Vector<Color> VoxelLightBaker::_get_bake_texture(Ref<Image> p_image, const Color
c.a = r[i * 4 + 3] / 255.0;
- ret[i] = c;
+ ret.write[i] = c;
}
return ret;
@@ -686,13 +686,13 @@ void VoxelLightBaker::plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, con
void VoxelLightBaker::_init_light_plot(int p_idx, int p_level, int p_x, int p_y, int p_z, uint32_t p_parent) {
- bake_light[p_idx].x = p_x;
- bake_light[p_idx].y = p_y;
- bake_light[p_idx].z = p_z;
+ bake_light.write[p_idx].x = p_x;
+ bake_light.write[p_idx].y = p_y;
+ bake_light.write[p_idx].z = p_z;
if (p_level == cell_subdiv - 1) {
- bake_light[p_idx].next_leaf = first_leaf;
+ bake_light.write[p_idx].next_leaf = first_leaf;
first_leaf = p_idx;
} else {
@@ -1197,33 +1197,33 @@ void VoxelLightBaker::_fixup_plot(int p_idx, int p_level) {
leaf_voxel_count++;
float alpha = bake_cells[p_idx].alpha;
- bake_cells[p_idx].albedo[0] /= alpha;
- bake_cells[p_idx].albedo[1] /= alpha;
- bake_cells[p_idx].albedo[2] /= alpha;
+ bake_cells.write[p_idx].albedo[0] /= alpha;
+ bake_cells.write[p_idx].albedo[1] /= alpha;
+ bake_cells.write[p_idx].albedo[2] /= alpha;
//transfer emission to light
- bake_cells[p_idx].emission[0] /= alpha;
- bake_cells[p_idx].emission[1] /= alpha;
- bake_cells[p_idx].emission[2] /= alpha;
+ bake_cells.write[p_idx].emission[0] /= alpha;
+ bake_cells.write[p_idx].emission[1] /= alpha;
+ bake_cells.write[p_idx].emission[2] /= alpha;
- bake_cells[p_idx].normal[0] /= alpha;
- bake_cells[p_idx].normal[1] /= alpha;
- bake_cells[p_idx].normal[2] /= alpha;
+ bake_cells.write[p_idx].normal[0] /= alpha;
+ bake_cells.write[p_idx].normal[1] /= alpha;
+ bake_cells.write[p_idx].normal[2] /= alpha;
Vector3 n(bake_cells[p_idx].normal[0], bake_cells[p_idx].normal[1], bake_cells[p_idx].normal[2]);
if (n.length() < 0.01) {
//too much fight over normal, zero it
- bake_cells[p_idx].normal[0] = 0;
- bake_cells[p_idx].normal[1] = 0;
- bake_cells[p_idx].normal[2] = 0;
+ bake_cells.write[p_idx].normal[0] = 0;
+ bake_cells.write[p_idx].normal[1] = 0;
+ bake_cells.write[p_idx].normal[2] = 0;
} else {
n.normalize();
- bake_cells[p_idx].normal[0] = n.x;
- bake_cells[p_idx].normal[1] = n.y;
- bake_cells[p_idx].normal[2] = n.z;
+ bake_cells.write[p_idx].normal[0] = n.x;
+ bake_cells.write[p_idx].normal[1] = n.y;
+ bake_cells.write[p_idx].normal[2] = n.z;
}
- bake_cells[p_idx].alpha = 1.0;
+ bake_cells.write[p_idx].alpha = 1.0;
/*if (bake_light.size()) {
for(int i=0;i<6;i++) {
@@ -1235,20 +1235,20 @@ void VoxelLightBaker::_fixup_plot(int p_idx, int p_level) {
//go down
- bake_cells[p_idx].emission[0] = 0;
- bake_cells[p_idx].emission[1] = 0;
- bake_cells[p_idx].emission[2] = 0;
- bake_cells[p_idx].normal[0] = 0;
- bake_cells[p_idx].normal[1] = 0;
- bake_cells[p_idx].normal[2] = 0;
- bake_cells[p_idx].albedo[0] = 0;
- bake_cells[p_idx].albedo[1] = 0;
- bake_cells[p_idx].albedo[2] = 0;
+ bake_cells.write[p_idx].emission[0] = 0;
+ bake_cells.write[p_idx].emission[1] = 0;
+ bake_cells.write[p_idx].emission[2] = 0;
+ bake_cells.write[p_idx].normal[0] = 0;
+ bake_cells.write[p_idx].normal[1] = 0;
+ bake_cells.write[p_idx].normal[2] = 0;
+ bake_cells.write[p_idx].albedo[0] = 0;
+ bake_cells.write[p_idx].albedo[1] = 0;
+ bake_cells.write[p_idx].albedo[2] = 0;
if (bake_light.size()) {
for (int j = 0; j < 6; j++) {
- bake_light[p_idx].accum[j][0] = 0;
- bake_light[p_idx].accum[j][1] = 0;
- bake_light[p_idx].accum[j][2] = 0;
+ bake_light.write[p_idx].accum[j][0] = 0;
+ bake_light.write[p_idx].accum[j][1] = 0;
+ bake_light.write[p_idx].accum[j][2] = 0;
}
}
@@ -1267,29 +1267,29 @@ void VoxelLightBaker::_fixup_plot(int p_idx, int p_level) {
if (bake_light.size() > 0) {
for (int j = 0; j < 6; j++) {
- bake_light[p_idx].accum[j][0] += bake_light[child].accum[j][0];
- bake_light[p_idx].accum[j][1] += bake_light[child].accum[j][1];
- bake_light[p_idx].accum[j][2] += bake_light[child].accum[j][2];
+ bake_light.write[p_idx].accum[j][0] += bake_light[child].accum[j][0];
+ bake_light.write[p_idx].accum[j][1] += bake_light[child].accum[j][1];
+ bake_light.write[p_idx].accum[j][2] += bake_light[child].accum[j][2];
}
- bake_cells[p_idx].emission[0] += bake_cells[child].emission[0];
- bake_cells[p_idx].emission[1] += bake_cells[child].emission[1];
- bake_cells[p_idx].emission[2] += bake_cells[child].emission[2];
+ bake_cells.write[p_idx].emission[0] += bake_cells[child].emission[0];
+ bake_cells.write[p_idx].emission[1] += bake_cells[child].emission[1];
+ bake_cells.write[p_idx].emission[2] += bake_cells[child].emission[2];
}
children_found++;
}
- bake_cells[p_idx].alpha = alpha_average / 8.0;
+ bake_cells.write[p_idx].alpha = alpha_average / 8.0;
if (bake_light.size() && children_found) {
float divisor = Math::lerp(8, children_found, propagation);
for (int j = 0; j < 6; j++) {
- bake_light[p_idx].accum[j][0] /= divisor;
- bake_light[p_idx].accum[j][1] /= divisor;
- bake_light[p_idx].accum[j][2] /= divisor;
+ bake_light.write[p_idx].accum[j][0] /= divisor;
+ bake_light.write[p_idx].accum[j][1] /= divisor;
+ bake_light.write[p_idx].accum[j][2] /= divisor;
}
- bake_cells[p_idx].emission[0] /= divisor;
- bake_cells[p_idx].emission[1] /= divisor;
- bake_cells[p_idx].emission[2] /= divisor;
+ bake_cells.write[p_idx].emission[0] /= divisor;
+ bake_cells.write[p_idx].emission[1] /= divisor;
+ bake_cells.write[p_idx].emission[2] /= divisor;
}
}
}
@@ -1961,7 +1961,7 @@ Error VoxelLightBaker::make_lightmap(const Transform &p_xform, Ref<Mesh> &p_mesh
#endif
for (int i = 0; i < height; i++) {
- //print_line("bake line " + itos(i) + " / " + itos(height));
+ //print_line("bake line " + itos(i) + " / " + itos(height));
#ifdef _OPENMP
#pragma omp parallel for schedule(dynamic, 1)
#endif
@@ -2403,25 +2403,25 @@ PoolVector<uint8_t> VoxelLightBaker::create_capture_octree(int p_subdiv) {
new_size++;
demap.push_back(i);
}
- remap[i] = c;
+ remap.write[i] = c;
}
Vector<VoxelLightBakerOctree> octree;
octree.resize(new_size);
for (int i = 0; i < new_size; i++) {
- octree[i].alpha = bake_cells[demap[i]].alpha;
+ octree.write[i].alpha = bake_cells[demap[i]].alpha;
for (int j = 0; j < 6; j++) {
for (int k = 0; k < 3; k++) {
float l = bake_light[demap[i]].accum[j][k]; //add anisotropic light
l += bake_cells[demap[i]].emission[k]; //add emission
- octree[i].light[j][k] = CLAMP(l * 1024, 0, 65535); //give two more bits to octree
+ octree.write[i].light[j][k] = CLAMP(l * 1024, 0, 65535); //give two more bits to octree
}
}
for (int j = 0; j < 8; j++) {
uint32_t child = bake_cells[demap[i]].children[j];
- octree[i].children[j] = child == CHILD_EMPTY ? CHILD_EMPTY : remap[child];
+ octree.write[i].children[j] = child == CHILD_EMPTY ? CHILD_EMPTY : remap[child];
}
}
diff --git a/scene/animation/animation_blend_space_1d.cpp b/scene/animation/animation_blend_space_1d.cpp
index d3d2870c3f..289cf7a3a7 100644
--- a/scene/animation/animation_blend_space_1d.cpp
+++ b/scene/animation/animation_blend_space_1d.cpp
@@ -1,13 +1,14 @@
#include "animation_blend_space_1d.h"
-void AnimationNodeBlendSpace1D::set_tree(AnimationTree *p_player) {
-
- AnimationRootNode::set_tree(p_player);
-
- for(int i=0;i<blend_points_used;i++) {
- blend_points[i].node->set_tree(p_player);
- }
+void AnimationNodeBlendSpace1D::get_parameter_list(List<PropertyInfo> *r_list) const {
+ r_list->push_back(PropertyInfo(Variant::REAL, blend_position));
+}
+Variant AnimationNodeBlendSpace1D::get_parameter_default_value(const StringName &p_parameter) const {
+ return 0;
+}
+Ref<AnimationNode> AnimationNodeBlendSpace1D::get_child_by_name(const StringName &p_name) {
+ return get_blend_point_node(p_name.operator String().to_int());
}
void AnimationNodeBlendSpace1D::_validate_property(PropertyInfo &property) const {
@@ -21,6 +22,10 @@ void AnimationNodeBlendSpace1D::_validate_property(PropertyInfo &property) const
AnimationRootNode::_validate_property(property);
}
+void AnimationNodeBlendSpace1D::_tree_changed() {
+ emit_signal("tree_changed");
+}
+
void AnimationNodeBlendSpace1D::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_blend_point", "node", "pos", "at_index"), &AnimationNodeBlendSpace1D::add_blend_point, DEFVAL(-1));
ClassDB::bind_method(D_METHOD("set_blend_point_position", "point", "pos"), &AnimationNodeBlendSpace1D::set_blend_point_position);
@@ -39,30 +44,37 @@ void AnimationNodeBlendSpace1D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_snap", "snap"), &AnimationNodeBlendSpace1D::set_snap);
ClassDB::bind_method(D_METHOD("get_snap"), &AnimationNodeBlendSpace1D::get_snap);
- ClassDB::bind_method(D_METHOD("set_blend_pos", "pos"), &AnimationNodeBlendSpace1D::set_blend_pos);
- ClassDB::bind_method(D_METHOD("get_blend_pos"), &AnimationNodeBlendSpace1D::get_blend_pos);
-
ClassDB::bind_method(D_METHOD("set_value_label", "text"), &AnimationNodeBlendSpace1D::set_value_label);
ClassDB::bind_method(D_METHOD("get_value_label"), &AnimationNodeBlendSpace1D::get_value_label);
ClassDB::bind_method(D_METHOD("_add_blend_point", "index", "node"), &AnimationNodeBlendSpace1D::_add_blend_point);
+ ClassDB::bind_method(D_METHOD("_tree_changed"), &AnimationNodeBlendSpace1D::_tree_changed);
+
for (int i = 0; i < MAX_BLEND_POINTS; i++) {
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "blend_point_" + itos(i) + "/node", PROPERTY_HINT_RESOURCE_TYPE, "AnimationRootNode", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE), "_add_blend_point", "get_blend_point_node", i);
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "blend_point_" + itos(i) + "/node", PROPERTY_HINT_RESOURCE_TYPE, "AnimationRootNode", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_add_blend_point", "get_blend_point_node", i);
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "blend_point_" + itos(i) + "/pos", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_blend_point_position", "get_blend_point_position", i);
}
ADD_PROPERTY(PropertyInfo(Variant::REAL, "min_space", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_min_space", "get_min_space");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_space", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_max_space", "get_max_space");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "snap", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_snap", "get_snap");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "blend_pos", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_blend_pos", "get_blend_pos");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "value_label", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_value_label", "get_value_label");
}
+void AnimationNodeBlendSpace1D::get_child_nodes(List<ChildNode> *r_child_nodes) {
+ for (int i = 0; i < blend_points_used; i++) {
+ ChildNode cn;
+ cn.name = itos(i);
+ cn.node = blend_points[i].node;
+ r_child_nodes->push_back(cn);
+ }
+}
+
void AnimationNodeBlendSpace1D::add_blend_point(const Ref<AnimationRootNode> &p_node, float p_position, int p_at_index) {
ERR_FAIL_COND(blend_points_used >= MAX_BLEND_POINTS);
ERR_FAIL_COND(p_node.is_null());
- ERR_FAIL_COND(p_node->get_parent().is_valid());
+
ERR_FAIL_COND(p_at_index < -1 || p_at_index > blend_points_used);
if (p_at_index == -1 || p_at_index == blend_points_used) {
@@ -76,10 +88,10 @@ void AnimationNodeBlendSpace1D::add_blend_point(const Ref<AnimationRootNode> &p_
blend_points[p_at_index].node = p_node;
blend_points[p_at_index].position = p_position;
- blend_points[p_at_index].node->set_parent(this);
- blend_points[p_at_index].node->set_tree(get_tree());
+ blend_points[p_at_index].node->connect("tree_changed", this, "_tree_changed", varray(), CONNECT_REFERENCE_COUNTED);
blend_points_used++;
+ emit_signal("tree_changed");
}
void AnimationNodeBlendSpace1D::set_blend_point_position(int p_point, float p_position) {
@@ -93,13 +105,13 @@ void AnimationNodeBlendSpace1D::set_blend_point_node(int p_point, const Ref<Anim
ERR_FAIL_COND(p_node.is_null());
if (blend_points[p_point].node.is_valid()) {
- blend_points[p_point].node->set_parent(NULL);
- blend_points[p_point].node->set_tree(NULL);
+ blend_points[p_point].node->disconnect("tree_changed", this, "_tree_changed");
}
blend_points[p_point].node = p_node;
- blend_points[p_point].node->set_parent(this);
- blend_points[p_point].node->set_tree(get_tree());
+ blend_points[p_point].node->connect("tree_changed", this, "_tree_changed", varray(), CONNECT_REFERENCE_COUNTED);
+
+ emit_signal("tree_changed");
}
float AnimationNodeBlendSpace1D::get_blend_point_position(int p_point) const {
@@ -115,14 +127,14 @@ Ref<AnimationRootNode> AnimationNodeBlendSpace1D::get_blend_point_node(int p_poi
void AnimationNodeBlendSpace1D::remove_blend_point(int p_point) {
ERR_FAIL_INDEX(p_point, blend_points_used);
- blend_points[p_point].node->set_parent(NULL);
- blend_points[p_point].node->set_tree(NULL);
+ blend_points[p_point].node->disconnect("tree_changed", this, "_tree_changed");
for (int i = p_point; i < blend_points_used - 1; i++) {
blend_points[i] = blend_points[i + 1];
}
blend_points_used--;
+ emit_signal("tree_changed");
}
int AnimationNodeBlendSpace1D::get_blend_point_count() const {
@@ -162,14 +174,6 @@ float AnimationNodeBlendSpace1D::get_snap() const {
return snap;
}
-void AnimationNodeBlendSpace1D::set_blend_pos(float p_pos) {
- blend_pos = p_pos;
-}
-
-float AnimationNodeBlendSpace1D::get_blend_pos() const {
- return blend_pos;
-}
-
void AnimationNodeBlendSpace1D::set_value_label(const String &p_label) {
value_label = p_label;
}
@@ -194,9 +198,11 @@ float AnimationNodeBlendSpace1D::process(float p_time, bool p_seek) {
if (blend_points_used == 1) {
// only one point available, just play that animation
- return blend_node(blend_points[0].node, p_time, p_seek, 1.0, FILTER_IGNORE, false);
+ return blend_node(blend_points[0].name, blend_points[0].node, p_time, p_seek, 1.0, FILTER_IGNORE, false);
}
+ float blend_pos = get_parameter(blend_position);
+
float weights[MAX_BLEND_POINTS] = {};
int point_lower = -1;
@@ -263,7 +269,7 @@ float AnimationNodeBlendSpace1D::process(float p_time, bool p_seek) {
float max_time_remaining = 0.0;
for (int i = 0; i < blend_points_used; i++) {
- float remaining = blend_node(blend_points[i].node, p_time, p_seek, weights[i], FILTER_IGNORE, false);
+ float remaining = blend_node(blend_points[i].name, blend_points[i].node, p_time, p_seek, weights[i], FILTER_IGNORE, false);
max_time_remaining = MAX(max_time_remaining, remaining);
}
@@ -277,18 +283,18 @@ String AnimationNodeBlendSpace1D::get_caption() const {
AnimationNodeBlendSpace1D::AnimationNodeBlendSpace1D() {
+ for (int i = 0; i < MAX_BLEND_POINTS; i++) {
+ blend_points[i].name = itos(i);
+ }
blend_points_used = 0;
max_space = 1;
min_space = -1;
snap = 0.1;
value_label = "value";
+
+ blend_position = "blend_position";
}
AnimationNodeBlendSpace1D::~AnimationNodeBlendSpace1D() {
-
- for (int i = 0; i < blend_points_used; i++) {
- blend_points[i].node->set_parent(this);
- blend_points[i].node->set_tree(get_tree());
- }
}
diff --git a/scene/animation/animation_blend_space_1d.h b/scene/animation/animation_blend_space_1d.h
index 774894ef4b..f4e20f0d70 100644
--- a/scene/animation/animation_blend_space_1d.h
+++ b/scene/animation/animation_blend_space_1d.h
@@ -11,6 +11,7 @@ class AnimationNodeBlendSpace1D : public AnimationRootNode {
};
struct BlendPoint {
+ StringName name;
Ref<AnimationRootNode> node;
float position;
};
@@ -18,8 +19,6 @@ class AnimationNodeBlendSpace1D : public AnimationRootNode {
BlendPoint blend_points[MAX_BLEND_POINTS];
int blend_points_used;
- float blend_pos;
-
float max_space;
float min_space;
@@ -29,13 +28,19 @@ class AnimationNodeBlendSpace1D : public AnimationRootNode {
void _add_blend_point(int p_index, const Ref<AnimationRootNode> &p_node);
+ void _tree_changed();
+
+ StringName blend_position;
+
protected:
virtual void _validate_property(PropertyInfo &property) const;
static void _bind_methods();
public:
+ virtual void get_parameter_list(List<PropertyInfo> *r_list) const;
+ virtual Variant get_parameter_default_value(const StringName &p_parameter) const;
- virtual void set_tree(AnimationTree *p_player);
+ virtual void get_child_nodes(List<ChildNode> *r_child_nodes);
void add_blend_point(const Ref<AnimationRootNode> &p_node, float p_position, int p_at_index = -1);
void set_blend_point_position(int p_point, float p_position);
@@ -55,15 +60,14 @@ public:
void set_snap(float p_snap);
float get_snap() const;
- void set_blend_pos(float p_pos);
- float get_blend_pos() const;
-
void set_value_label(const String &p_label);
String get_value_label() const;
float process(float p_time, bool p_seek);
String get_caption() const;
+ Ref<AnimationNode> get_child_by_name(const StringName &p_name);
+
AnimationNodeBlendSpace1D();
~AnimationNodeBlendSpace1D();
};
diff --git a/scene/animation/animation_blend_space_2d.cpp b/scene/animation/animation_blend_space_2d.cpp
index 82db647124..3dc7f2a86f 100644
--- a/scene/animation/animation_blend_space_2d.cpp
+++ b/scene/animation/animation_blend_space_2d.cpp
@@ -1,19 +1,25 @@
#include "animation_blend_space_2d.h"
#include "math/delaunay.h"
-void AnimationNodeBlendSpace2D::set_tree(AnimationTree *p_player) {
- AnimationRootNode::set_tree(p_player);
+void AnimationNodeBlendSpace2D::get_parameter_list(List<PropertyInfo> *r_list) const {
+ r_list->push_back(PropertyInfo(Variant::VECTOR2, blend_position));
+}
+Variant AnimationNodeBlendSpace2D::get_parameter_default_value(const StringName &p_parameter) const {
+ return Vector2();
+}
- for(int i=0;i<blend_points_used;i++) {
- blend_points[i].node->set_tree(p_player);
+void AnimationNodeBlendSpace2D::get_child_nodes(List<ChildNode> *r_child_nodes) {
+ for (int i = 0; i < blend_points_used; i++) {
+ ChildNode cn;
+ cn.name = itos(i);
+ cn.node = blend_points[i].node;
+ r_child_nodes->push_back(cn);
}
}
-
void AnimationNodeBlendSpace2D::add_blend_point(const Ref<AnimationRootNode> &p_node, const Vector2 &p_position, int p_at_index) {
ERR_FAIL_COND(blend_points_used >= MAX_BLEND_POINTS);
ERR_FAIL_COND(p_node.is_null());
- ERR_FAIL_COND(p_node->get_parent().is_valid());
ERR_FAIL_COND(p_at_index < -1 || p_at_index > blend_points_used);
if (p_at_index == -1 || p_at_index == blend_points_used) {
@@ -25,7 +31,7 @@ void AnimationNodeBlendSpace2D::add_blend_point(const Ref<AnimationRootNode> &p_
for (int i = 0; i < triangles.size(); i++) {
for (int j = 0; j < 3; j++) {
if (triangles[i].points[j] >= p_at_index) {
- triangles[i].points[j]++;
+ triangles.write[i].points[j]++;
}
}
}
@@ -33,13 +39,13 @@ void AnimationNodeBlendSpace2D::add_blend_point(const Ref<AnimationRootNode> &p_
blend_points[p_at_index].node = p_node;
blend_points[p_at_index].position = p_position;
- blend_points[p_at_index].node->set_parent(this);
- blend_points[p_at_index].node->set_tree(get_tree());
+ blend_points[p_at_index].node->connect("tree_changed", this, "_tree_changed", varray(), CONNECT_REFERENCE_COUNTED);
blend_points_used++;
if (auto_triangles) {
trianges_dirty = true;
}
+ emit_signal("tree_changed");
}
void AnimationNodeBlendSpace2D::set_blend_point_position(int p_point, const Vector2 &p_position) {
@@ -54,12 +60,12 @@ void AnimationNodeBlendSpace2D::set_blend_point_node(int p_point, const Ref<Anim
ERR_FAIL_COND(p_node.is_null());
if (blend_points[p_point].node.is_valid()) {
- blend_points[p_point].node->set_parent(NULL);
- blend_points[p_point].node->set_tree(NULL);
+ blend_points[p_point].node->disconnect("tree_changed", this, "_tree_changed");
}
blend_points[p_point].node = p_node;
- blend_points[p_point].node->set_parent(this);
- blend_points[p_point].node->set_tree(get_tree());
+ blend_points[p_point].node->connect("tree_changed", this, "_tree_changed", varray(), CONNECT_REFERENCE_COUNTED);
+
+ emit_signal("tree_changed");
}
Vector2 AnimationNodeBlendSpace2D::get_blend_point_position(int p_point) const {
ERR_FAIL_INDEX_V(p_point, blend_points_used, Vector2());
@@ -72,8 +78,7 @@ Ref<AnimationRootNode> AnimationNodeBlendSpace2D::get_blend_point_node(int p_poi
void AnimationNodeBlendSpace2D::remove_blend_point(int p_point) {
ERR_FAIL_INDEX(p_point, blend_points_used);
- blend_points[p_point].node->set_parent(NULL);
- blend_points[p_point].node->set_tree(NULL);
+ blend_points[p_point].node->disconnect("tree_changed", this, "_tree_changed");
for (int i = 0; i < triangles.size(); i++) {
bool erase = false;
@@ -82,7 +87,7 @@ void AnimationNodeBlendSpace2D::remove_blend_point(int p_point) {
erase = true;
break;
} else if (triangles[i].points[j] > p_point) {
- triangles[i].points[j]--;
+ triangles.write[i].points[j]--;
}
}
if (erase) {
@@ -96,6 +101,7 @@ void AnimationNodeBlendSpace2D::remove_blend_point(int p_point) {
blend_points[i] = blend_points[i + 1];
}
blend_points_used--;
+ emit_signal("tree_changed");
}
int AnimationNodeBlendSpace2D::get_blend_point_count() const {
@@ -218,13 +224,6 @@ Vector2 AnimationNodeBlendSpace2D::get_snap() const {
return snap;
}
-void AnimationNodeBlendSpace2D::set_blend_position(const Vector2 &p_pos) {
- blend_pos = p_pos;
-}
-Vector2 AnimationNodeBlendSpace2D::get_blend_position() const {
- return blend_pos;
-}
-
void AnimationNodeBlendSpace2D::set_x_label(const String &p_label) {
x_label = p_label;
}
@@ -265,9 +264,9 @@ Vector<int> AnimationNodeBlendSpace2D::_get_triangles() const {
t.resize(triangles.size() * 3);
for (int i = 0; i < triangles.size(); i++) {
- t[i * 3 + 0] = triangles[i].points[0];
- t[i * 3 + 1] = triangles[i].points[1];
- t[i * 3 + 2] = triangles[i].points[2];
+ t.write[i * 3 + 0] = triangles[i].points[0];
+ t.write[i * 3 + 1] = triangles[i].points[1];
+ t.write[i * 3 + 2] = triangles[i].points[2];
}
return t;
}
@@ -285,7 +284,7 @@ void AnimationNodeBlendSpace2D::_update_triangles() {
Vector<Vector2> points;
points.resize(blend_points_used);
for (int i = 0; i < blend_points_used; i++) {
- points[i] = blend_points[i].position;
+ points.write[i] = blend_points[i].position;
}
Vector<Delaunay2D::Triangle> triangles = Delaunay2D::triangulate(points);
@@ -382,6 +381,8 @@ float AnimationNodeBlendSpace2D::process(float p_time, bool p_seek) {
_update_triangles();
+ Vector2 blend_pos = get_parameter(blend_position);
+
if (triangles.size() == 0)
return 0;
@@ -444,7 +445,7 @@ float AnimationNodeBlendSpace2D::process(float p_time, bool p_seek) {
for (int j = 0; j < 3; j++) {
if (i == triangle_points[j]) {
//blend with the given weight
- float t = blend_node(blend_points[i].node, p_time, p_seek, blend_weights[j], FILTER_IGNORE, false);
+ float t = blend_node(blend_points[i].name, blend_points[i].node, p_time, p_seek, blend_weights[j], FILTER_IGNORE, false);
if (first || t < mind) {
mind = t;
first = false;
@@ -456,7 +457,7 @@ float AnimationNodeBlendSpace2D::process(float p_time, bool p_seek) {
if (!found) {
//ignore
- blend_node(blend_points[i].node, p_time, p_seek, 0, FILTER_IGNORE, false);
+ blend_node(blend_points[i].name, blend_points[i].node, p_time, p_seek, 0, FILTER_IGNORE, false);
}
}
return mind;
@@ -488,6 +489,14 @@ bool AnimationNodeBlendSpace2D::get_auto_triangles() const {
return auto_triangles;
}
+Ref<AnimationNode> AnimationNodeBlendSpace2D::get_child_by_name(const StringName &p_name) {
+ return get_blend_point_node(p_name.operator String().to_int());
+}
+
+void AnimationNodeBlendSpace2D::_tree_changed() {
+ emit_signal("tree_changed");
+}
+
void AnimationNodeBlendSpace2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_blend_point", "node", "pos", "at_index"), &AnimationNodeBlendSpace2D::add_blend_point, DEFVAL(-1));
@@ -512,9 +521,6 @@ void AnimationNodeBlendSpace2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_snap", "snap"), &AnimationNodeBlendSpace2D::set_snap);
ClassDB::bind_method(D_METHOD("get_snap"), &AnimationNodeBlendSpace2D::get_snap);
- ClassDB::bind_method(D_METHOD("set_blend_position", "pos"), &AnimationNodeBlendSpace2D::set_blend_position);
- ClassDB::bind_method(D_METHOD("get_blend_position"), &AnimationNodeBlendSpace2D::get_blend_position);
-
ClassDB::bind_method(D_METHOD("set_x_label", "text"), &AnimationNodeBlendSpace2D::set_x_label);
ClassDB::bind_method(D_METHOD("get_x_label"), &AnimationNodeBlendSpace2D::get_x_label);
@@ -529,10 +535,12 @@ void AnimationNodeBlendSpace2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_auto_triangles", "enable"), &AnimationNodeBlendSpace2D::set_auto_triangles);
ClassDB::bind_method(D_METHOD("get_auto_triangles"), &AnimationNodeBlendSpace2D::get_auto_triangles);
+ ClassDB::bind_method(D_METHOD("_tree_changed"), &AnimationNodeBlendSpace2D::_tree_changed);
+
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_triangles", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_auto_triangles", "get_auto_triangles");
for (int i = 0; i < MAX_BLEND_POINTS; i++) {
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "blend_point_" + itos(i) + "/node", PROPERTY_HINT_RESOURCE_TYPE, "AnimationRootNode", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE), "_add_blend_point", "get_blend_point_node", i);
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "blend_point_" + itos(i) + "/node", PROPERTY_HINT_RESOURCE_TYPE, "AnimationRootNode", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_add_blend_point", "get_blend_point_node", i);
ADD_PROPERTYI(PropertyInfo(Variant::VECTOR2, "blend_point_" + itos(i) + "/pos", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_blend_point_position", "get_blend_point_position", i);
}
@@ -541,13 +549,15 @@ void AnimationNodeBlendSpace2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "min_space", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_min_space", "get_min_space");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "max_space", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_max_space", "get_max_space");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "snap", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_snap", "get_snap");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "blend_position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_blend_position", "get_blend_position");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "x_label", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_x_label", "get_x_label");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "y_label", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_y_label", "get_y_label");
}
AnimationNodeBlendSpace2D::AnimationNodeBlendSpace2D() {
+ for (int i = 0; i < MAX_BLEND_POINTS; i++) {
+ blend_points[i].name = itos(i);
+ }
auto_triangles = true;
blend_points_used = 0;
max_space = Vector2(1, 1);
@@ -556,12 +566,8 @@ AnimationNodeBlendSpace2D::AnimationNodeBlendSpace2D() {
x_label = "x";
y_label = "y";
trianges_dirty = false;
+ blend_position = "blend_position";
}
AnimationNodeBlendSpace2D::~AnimationNodeBlendSpace2D() {
-
- for (int i = 0; i < blend_points_used; i++) {
- blend_points[i].node->set_parent(this);
- blend_points[i].node->set_tree(get_tree());
- }
}
diff --git a/scene/animation/animation_blend_space_2d.h b/scene/animation/animation_blend_space_2d.h
index 4778299df1..3e1c66c924 100644
--- a/scene/animation/animation_blend_space_2d.h
+++ b/scene/animation/animation_blend_space_2d.h
@@ -11,6 +11,7 @@ class AnimationNodeBlendSpace2D : public AnimationRootNode {
};
struct BlendPoint {
+ StringName name;
Ref<AnimationRootNode> node;
Vector2 position;
};
@@ -24,7 +25,7 @@ class AnimationNodeBlendSpace2D : public AnimationRootNode {
Vector<BlendTriangle> triangles;
- Vector2 blend_pos;
+ StringName blend_position;
Vector2 max_space;
Vector2 min_space;
Vector2 snap;
@@ -42,13 +43,17 @@ class AnimationNodeBlendSpace2D : public AnimationRootNode {
void _update_triangles();
+ void _tree_changed();
+
protected:
virtual void _validate_property(PropertyInfo &property) const;
static void _bind_methods();
public:
+ virtual void get_parameter_list(List<PropertyInfo> *r_list) const;
+ virtual Variant get_parameter_default_value(const StringName &p_parameter) const;
- virtual void set_tree(AnimationTree *p_player);
+ virtual void get_child_nodes(List<ChildNode> *r_child_nodes);
void add_blend_point(const Ref<AnimationRootNode> &p_node, const Vector2 &p_position, int p_at_index = -1);
void set_blend_point_position(int p_point, const Vector2 &p_position);
@@ -73,9 +78,6 @@ public:
void set_snap(const Vector2 &p_snap);
Vector2 get_snap() const;
- void set_blend_position(const Vector2 &p_pos);
- Vector2 get_blend_position() const;
-
void set_x_label(const String &p_label);
String get_x_label() const;
@@ -90,6 +92,8 @@ public:
void set_auto_triangles(bool p_enable);
bool get_auto_triangles() const;
+ virtual Ref<AnimationNode> get_child_by_name(const StringName &p_name);
+
AnimationNodeBlendSpace2D();
~AnimationNodeBlendSpace2D();
};
diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp
index 6dcd5ca8ea..10bab3ce38 100644
--- a/scene/animation/animation_blend_tree.cpp
+++ b/scene/animation/animation_blend_tree.cpp
@@ -3,6 +3,7 @@
void AnimationNodeAnimation::set_animation(const StringName &p_name) {
animation = p_name;
+ _change_notify("animation");
}
StringName AnimationNodeAnimation::get_animation() const {
@@ -13,43 +14,36 @@ float AnimationNodeAnimation::get_playback_time() const {
return time;
}
+Vector<String> (*AnimationNodeAnimation::get_editable_animation_list)() = NULL;
+
void AnimationNodeAnimation::_validate_property(PropertyInfo &property) const {
- if (property.name == "animation") {
- AnimationTree *gp = get_tree();
- if (gp && gp->has_node(gp->get_animation_player())) {
- AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(gp->get_node(gp->get_animation_player()));
- if (ap) {
- List<StringName> names;
- ap->get_animation_list(&names);
- String anims;
- for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
- if (E != names.front()) {
- anims += ",";
- }
- anims += String(E->get());
- }
- if (anims != String()) {
- property.hint = PROPERTY_HINT_ENUM;
- property.hint_string = anims;
- }
+ if (property.name == "animation" && get_editable_animation_list) {
+ Vector<String> names = get_editable_animation_list();
+ String anims;
+ for (int i = 0; i < names.size(); i++) {
+
+ if (i > 0) {
+ anims += ",";
}
+ anims += String(names[i]);
+ }
+ if (anims != String()) {
+ property.hint = PROPERTY_HINT_ENUM;
+ property.hint_string = anims;
}
}
-
- AnimationRootNode::_validate_property(property);
}
float AnimationNodeAnimation::process(float p_time, bool p_seek) {
- AnimationPlayer *ap = get_player();
+ AnimationPlayer *ap = state->player;
ERR_FAIL_COND_V(!ap, 0);
- Ref<Animation> anim = ap->get_animation(animation);
- if (!anim.is_valid()) {
+ if (!ap->has_animation(animation)) {
- Ref<AnimationNodeBlendTree> tree = get_parent();
- if (tree.is_valid()) {
+ AnimationNodeBlendTree *tree = Object::cast_to<AnimationNodeBlendTree>(parent);
+ if (tree) {
String name = tree->get_node_name(Ref<AnimationNodeAnimation>(this));
make_invalid(vformat(RTR("On BlendTree node '%s', animation not found: '%s'"), name, animation));
@@ -60,6 +54,8 @@ float AnimationNodeAnimation::process(float p_time, bool p_seek) {
return 0;
}
+ Ref<Animation> anim = ap->get_animation(animation);
+
if (p_seek) {
time = p_time;
step = 0;
@@ -108,6 +104,20 @@ AnimationNodeAnimation::AnimationNodeAnimation() {
////////////////////////////////////////////////////////
+void AnimationNodeOneShot::get_parameter_list(List<PropertyInfo> *r_list) const {
+ r_list->push_back(PropertyInfo(Variant::BOOL, active));
+ r_list->push_back(PropertyInfo(Variant::BOOL, prev_active, PROPERTY_HINT_NONE, "", 0));
+ r_list->push_back(PropertyInfo(Variant::REAL, time, PROPERTY_HINT_NONE, "", 0));
+ r_list->push_back(PropertyInfo(Variant::REAL, remaining, PROPERTY_HINT_NONE, "", 0));
+}
+Variant AnimationNodeOneShot::get_parameter_default_value(const StringName &p_parameter) const {
+ if (p_parameter == active || p_parameter == prev_active) {
+ return false;
+ } else {
+ return 0.0;
+ }
+}
+
void AnimationNodeOneShot::set_fadein_time(float p_time) {
fade_in = p_time;
@@ -162,18 +172,6 @@ AnimationNodeOneShot::MixMode AnimationNodeOneShot::get_mix_mode() const {
return mix;
}
-void AnimationNodeOneShot::start() {
- active = true;
- do_start = true;
-}
-void AnimationNodeOneShot::stop() {
- active = false;
-}
-bool AnimationNodeOneShot::is_active() const {
-
- return active;
-}
-
String AnimationNodeOneShot::get_caption() const {
return "OneShot";
}
@@ -184,8 +182,16 @@ bool AnimationNodeOneShot::has_filter() const {
float AnimationNodeOneShot::process(float p_time, bool p_seek) {
+ bool active = get_parameter(this->active);
+ bool prev_active = get_parameter(this->prev_active);
+ float time = get_parameter(this->time);
+ float remaining = get_parameter(this->remaining);
+
if (!active) {
//make it as if this node doesn't exist, pass input 0 by.
+ if (prev_active) {
+ set_parameter(this->prev_active, false);
+ }
return blend_input(0, p_time, p_seek, 1.0, FILTER_IGNORE, !sync);
}
@@ -193,9 +199,12 @@ float AnimationNodeOneShot::process(float p_time, bool p_seek) {
if (p_seek)
time = p_time;
+ bool do_start = !prev_active;
+
if (do_start) {
time = 0;
os_seek = true;
+ set_parameter(this->prev_active, true);
}
float blend;
@@ -233,10 +242,15 @@ float AnimationNodeOneShot::process(float p_time, bool p_seek) {
if (!p_seek) {
time += p_time;
remaining = os_rem;
- if (remaining <= 0)
- active = false;
+ if (remaining <= 0) {
+ set_parameter(this->active, false);
+ set_parameter(this->prev_active, false);
+ }
}
+ set_parameter(this->time, time);
+ set_parameter(this->remaining, remaining);
+
return MAX(main_rem, remaining);
}
void AnimationNodeOneShot::set_use_sync(bool p_sync) {
@@ -269,10 +283,6 @@ void AnimationNodeOneShot::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_mix_mode", "mode"), &AnimationNodeOneShot::set_mix_mode);
ClassDB::bind_method(D_METHOD("get_mix_mode"), &AnimationNodeOneShot::get_mix_mode);
- ClassDB::bind_method(D_METHOD("start"), &AnimationNodeOneShot::start);
- ClassDB::bind_method(D_METHOD("stop"), &AnimationNodeOneShot::stop);
- ClassDB::bind_method(D_METHOD("is_active"), &AnimationNodeOneShot::is_active);
-
ClassDB::bind_method(D_METHOD("set_use_sync", "enable"), &AnimationNodeOneShot::set_use_sync);
ClassDB::bind_method(D_METHOD("is_using_sync"), &AnimationNodeOneShot::is_using_sync);
@@ -288,8 +298,8 @@ void AnimationNodeOneShot::_bind_methods() {
ADD_GROUP("", "");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sync"), "set_use_sync", "is_using_sync");
- BIND_CONSTANT(MIX_MODE_BLEND)
- BIND_CONSTANT(MIX_MODE_ADD)
+ BIND_ENUM_CONSTANT(MIX_MODE_BLEND)
+ BIND_ENUM_CONSTANT(MIX_MODE_ADD)
}
AnimationNodeOneShot::AnimationNodeOneShot() {
@@ -297,26 +307,27 @@ AnimationNodeOneShot::AnimationNodeOneShot() {
add_input("in");
add_input("shot");
- time = 0;
fade_in = 0.1;
fade_out = 0.1;
autorestart = false;
autorestart_delay = 1;
- autorestart_remaining = 0;
+
mix = MIX_MODE_BLEND;
- active = false;
- do_start = false;
sync = false;
+
+ active = "active";
+ prev_active = "prev_active";
+ time = "time";
+ remaining = "remaining";
}
////////////////////////////////////////////////
-void AnimationNodeAdd2::set_amount(float p_amount) {
- amount = p_amount;
+void AnimationNodeAdd2::get_parameter_list(List<PropertyInfo> *r_list) const {
+ r_list->push_back(PropertyInfo(Variant::REAL, add_amount, PROPERTY_HINT_RANGE, "0,1,0.01"));
}
-
-float AnimationNodeAdd2::get_amount() const {
- return amount;
+Variant AnimationNodeAdd2::get_parameter_default_value(const StringName &p_parameter) const {
+ return 0;
}
String AnimationNodeAdd2::get_caption() const {
@@ -339,6 +350,7 @@ bool AnimationNodeAdd2::has_filter() const {
float AnimationNodeAdd2::process(float p_time, bool p_seek) {
+ float amount = get_parameter(add_amount);
float rem0 = blend_input(0, p_time, p_seek, 1.0, FILTER_IGNORE, !sync);
blend_input(1, p_time, p_seek, amount, FILTER_PASS, !sync);
@@ -347,32 +359,27 @@ float AnimationNodeAdd2::process(float p_time, bool p_seek) {
void AnimationNodeAdd2::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_amount", "amount"), &AnimationNodeAdd2::set_amount);
- ClassDB::bind_method(D_METHOD("get_amount"), &AnimationNodeAdd2::get_amount);
-
ClassDB::bind_method(D_METHOD("set_use_sync", "enable"), &AnimationNodeAdd2::set_use_sync);
ClassDB::bind_method(D_METHOD("is_using_sync"), &AnimationNodeAdd2::is_using_sync);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "amount", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_amount", "get_amount");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sync"), "set_use_sync", "is_using_sync");
}
AnimationNodeAdd2::AnimationNodeAdd2() {
+ add_amount = "add_amount";
add_input("in");
add_input("add");
- amount = 0;
sync = false;
}
////////////////////////////////////////////////
-void AnimationNodeAdd3::set_amount(float p_amount) {
- amount = p_amount;
+void AnimationNodeAdd3::get_parameter_list(List<PropertyInfo> *r_list) const {
+ r_list->push_back(PropertyInfo(Variant::REAL, add_amount, PROPERTY_HINT_RANGE, "-1,1,0.01"));
}
-
-float AnimationNodeAdd3::get_amount() const {
- return amount;
+Variant AnimationNodeAdd3::get_parameter_default_value(const StringName &p_parameter) const {
+ return 0;
}
String AnimationNodeAdd3::get_caption() const {
@@ -395,6 +402,7 @@ bool AnimationNodeAdd3::has_filter() const {
float AnimationNodeAdd3::process(float p_time, bool p_seek) {
+ float amount = get_parameter(add_amount);
blend_input(0, p_time, p_seek, MAX(0, -amount), FILTER_PASS, !sync);
float rem0 = blend_input(1, p_time, p_seek, 1.0, FILTER_IGNORE, !sync);
blend_input(2, p_time, p_seek, MAX(0, amount), FILTER_PASS, !sync);
@@ -404,39 +412,37 @@ float AnimationNodeAdd3::process(float p_time, bool p_seek) {
void AnimationNodeAdd3::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_amount", "amount"), &AnimationNodeAdd3::set_amount);
- ClassDB::bind_method(D_METHOD("get_amount"), &AnimationNodeAdd3::get_amount);
-
ClassDB::bind_method(D_METHOD("set_use_sync", "enable"), &AnimationNodeAdd3::set_use_sync);
ClassDB::bind_method(D_METHOD("is_using_sync"), &AnimationNodeAdd3::is_using_sync);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "amount", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_amount", "get_amount");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sync"), "set_use_sync", "is_using_sync");
}
AnimationNodeAdd3::AnimationNodeAdd3() {
+ add_amount = "add_amount";
add_input("-add");
add_input("in");
add_input("+add");
- amount = 0;
sync = false;
}
/////////////////////////////////////////////
-void AnimationNodeBlend2::set_amount(float p_amount) {
- amount = p_amount;
+void AnimationNodeBlend2::get_parameter_list(List<PropertyInfo> *r_list) const {
+ r_list->push_back(PropertyInfo(Variant::REAL, blend_amount, PROPERTY_HINT_RANGE, "0,1,0.01"));
}
-
-float AnimationNodeBlend2::get_amount() const {
- return amount;
+Variant AnimationNodeBlend2::get_parameter_default_value(const StringName &p_parameter) const {
+ return 0; //for blend amount
}
+
String AnimationNodeBlend2::get_caption() const {
return "Blend2";
}
float AnimationNodeBlend2::process(float p_time, bool p_seek) {
+ float amount = get_parameter(blend_amount);
+
float rem0 = blend_input(0, p_time, p_seek, 1.0 - amount, FILTER_BLEND, !sync);
float rem1 = blend_input(1, p_time, p_seek, amount, FILTER_PASS, !sync);
@@ -459,31 +465,25 @@ bool AnimationNodeBlend2::has_filter() const {
}
void AnimationNodeBlend2::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_amount", "amount"), &AnimationNodeBlend2::set_amount);
- ClassDB::bind_method(D_METHOD("get_amount"), &AnimationNodeBlend2::get_amount);
-
ClassDB::bind_method(D_METHOD("set_use_sync", "enable"), &AnimationNodeBlend2::set_use_sync);
ClassDB::bind_method(D_METHOD("is_using_sync"), &AnimationNodeBlend2::is_using_sync);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "amount", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_amount", "get_amount");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sync"), "set_use_sync", "is_using_sync");
}
AnimationNodeBlend2::AnimationNodeBlend2() {
+ blend_amount = "blend_amount";
add_input("in");
add_input("blend");
sync = false;
-
- amount = 0;
}
//////////////////////////////////////
-void AnimationNodeBlend3::set_amount(float p_amount) {
- amount = p_amount;
+void AnimationNodeBlend3::get_parameter_list(List<PropertyInfo> *r_list) const {
+ r_list->push_back(PropertyInfo(Variant::REAL, blend_amount, PROPERTY_HINT_RANGE, "-1,1,0.01"));
}
-
-float AnimationNodeBlend3::get_amount() const {
- return amount;
+Variant AnimationNodeBlend3::get_parameter_default_value(const StringName &p_parameter) const {
+ return 0; //for blend amount
}
String AnimationNodeBlend3::get_caption() const {
@@ -502,6 +502,7 @@ bool AnimationNodeBlend3::is_using_sync() const {
float AnimationNodeBlend3::process(float p_time, bool p_seek) {
+ float amount = get_parameter(blend_amount);
float rem0 = blend_input(0, p_time, p_seek, MAX(0, -amount), FILTER_IGNORE, !sync);
float rem1 = blend_input(1, p_time, p_seek, 1.0 - ABS(amount), FILTER_IGNORE, !sync);
float rem2 = blend_input(2, p_time, p_seek, MAX(0, amount), FILTER_IGNORE, !sync);
@@ -511,31 +512,26 @@ float AnimationNodeBlend3::process(float p_time, bool p_seek) {
void AnimationNodeBlend3::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_amount", "amount"), &AnimationNodeBlend3::set_amount);
- ClassDB::bind_method(D_METHOD("get_amount"), &AnimationNodeBlend3::get_amount);
-
ClassDB::bind_method(D_METHOD("set_use_sync", "enable"), &AnimationNodeBlend3::set_use_sync);
ClassDB::bind_method(D_METHOD("is_using_sync"), &AnimationNodeBlend3::is_using_sync);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "amount", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_amount", "get_amount");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sync"), "set_use_sync", "is_using_sync");
}
AnimationNodeBlend3::AnimationNodeBlend3() {
+ blend_amount = "blend_amount";
add_input("-blend");
add_input("in");
add_input("+blend");
sync = false;
- amount = 0;
}
/////////////////////////////////
-void AnimationNodeTimeScale::set_scale(float p_scale) {
- scale = p_scale;
+void AnimationNodeTimeScale::get_parameter_list(List<PropertyInfo> *r_list) const {
+ r_list->push_back(PropertyInfo(Variant::REAL, scale, PROPERTY_HINT_RANGE, "0,32,0.01,or_greater"));
}
-
-float AnimationNodeTimeScale::get_scale() const {
- return scale;
+Variant AnimationNodeTimeScale::get_parameter_default_value(const StringName &p_parameter) const {
+ return 1.0; //initial timescale
}
String AnimationNodeTimeScale::get_caption() const {
@@ -544,6 +540,7 @@ String AnimationNodeTimeScale::get_caption() const {
float AnimationNodeTimeScale::process(float p_time, bool p_seek) {
+ float scale = get_parameter(this->scale);
if (p_seek) {
return blend_input(0, p_time, true, 1.0, FILTER_IGNORE, false);
} else {
@@ -552,25 +549,19 @@ float AnimationNodeTimeScale::process(float p_time, bool p_seek) {
}
void AnimationNodeTimeScale::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("set_scale", "scale"), &AnimationNodeTimeScale::set_scale);
- ClassDB::bind_method(D_METHOD("get_scale"), &AnimationNodeTimeScale::get_scale);
-
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "scale", PROPERTY_HINT_RANGE, "0,32,0.01,or_greater"), "set_scale", "get_scale");
}
AnimationNodeTimeScale::AnimationNodeTimeScale() {
+ scale = "scale";
add_input("in");
- scale = 1.0;
}
////////////////////////////////////
-void AnimationNodeTimeSeek::set_seek_pos(float p_seek_pos) {
- seek_pos = p_seek_pos;
+void AnimationNodeTimeSeek::get_parameter_list(List<PropertyInfo> *r_list) const {
+ r_list->push_back(PropertyInfo(Variant::REAL, seek_pos, PROPERTY_HINT_RANGE, "-1,3600,0.01,or_greater"));
}
-
-float AnimationNodeTimeSeek::get_seek_pos() const {
- return seek_pos;
+Variant AnimationNodeTimeSeek::get_parameter_default_value(const StringName &p_parameter) const {
+ return 1.0; //initial timescale
}
String AnimationNodeTimeSeek::get_caption() const {
@@ -579,11 +570,12 @@ String AnimationNodeTimeSeek::get_caption() const {
float AnimationNodeTimeSeek::process(float p_time, bool p_seek) {
+ float seek_pos = get_parameter(this->seek_pos);
if (p_seek) {
return blend_input(0, p_time, true, 1.0, FILTER_IGNORE, false);
} else if (seek_pos >= 0) {
float ret = blend_input(0, seek_pos, true, 1.0, FILTER_IGNORE, false);
- seek_pos = -1;
+ set_parameter(this->seek_pos, -1.0); //reset
_change_notify("seek_pos");
return ret;
} else {
@@ -592,19 +584,41 @@ float AnimationNodeTimeSeek::process(float p_time, bool p_seek) {
}
void AnimationNodeTimeSeek::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("set_seek_pos", "seek_pos"), &AnimationNodeTimeSeek::set_seek_pos);
- ClassDB::bind_method(D_METHOD("get_seek_pos"), &AnimationNodeTimeSeek::get_seek_pos);
-
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "seek_pos", PROPERTY_HINT_RANGE, "-1,3600,0.01,or_greater"), "set_seek_pos", "get_seek_pos");
}
+
AnimationNodeTimeSeek::AnimationNodeTimeSeek() {
add_input("in");
- seek_pos = -1;
+ seek_pos = "seek_position";
}
/////////////////////////////////////////////////
+void AnimationNodeTransition::get_parameter_list(List<PropertyInfo> *r_list) const {
+
+ String anims;
+ for (int i = 0; i < enabled_inputs; i++) {
+ if (i > 0) {
+ anims += ",";
+ }
+ anims += inputs[i].name;
+ }
+
+ r_list->push_back(PropertyInfo(Variant::INT, current, PROPERTY_HINT_ENUM, anims));
+ r_list->push_back(PropertyInfo(Variant::INT, prev_current, PROPERTY_HINT_NONE, "", 0));
+ r_list->push_back(PropertyInfo(Variant::INT, prev, PROPERTY_HINT_NONE, "", 0));
+ r_list->push_back(PropertyInfo(Variant::REAL, time, PROPERTY_HINT_NONE, "", 0));
+ r_list->push_back(PropertyInfo(Variant::REAL, prev_xfading, PROPERTY_HINT_NONE, "", 0));
+}
+Variant AnimationNodeTransition::get_parameter_default_value(const StringName &p_parameter) const {
+ if (p_parameter == time || p_parameter == prev_xfading) {
+ return 0.0;
+ } else if (p_parameter == prev || p_parameter == prev_current) {
+ return -1;
+ } else {
+ return 0;
+ }
+}
+
String AnimationNodeTransition::get_caption() const {
return "Transition";
}
@@ -650,18 +664,12 @@ String AnimationNodeTransition::get_input_caption(int p_input) const {
return inputs[p_input].name;
}
-void AnimationNodeTransition::set_current(int p_current) {
-
- if (current == p_current)
- return;
- ERR_FAIL_INDEX(p_current, enabled_inputs);
-
+#if 0
Ref<AnimationNodeBlendTree> tree = get_parent();
if (tree.is_valid() && current >= 0) {
prev = current;
- prev_xfading = xfade;
- prev_time = time;
+ prev_xfading = xfade;
time = 0;
current = p_current;
switched = true;
@@ -669,11 +677,8 @@ void AnimationNodeTransition::set_current(int p_current) {
} else {
current = p_current;
}
-}
+#endif
-int AnimationNodeTransition::get_current() const {
- return current;
-}
void AnimationNodeTransition::set_cross_fade_time(float p_fade) {
xfade = p_fade;
}
@@ -684,9 +689,34 @@ float AnimationNodeTransition::get_cross_fade_time() const {
float AnimationNodeTransition::process(float p_time, bool p_seek) {
+ int current = get_parameter(this->current);
+ int prev = get_parameter(this->prev);
+ int prev_current = get_parameter(this->prev_current);
+
+ float time = get_parameter(this->time);
+ float prev_xfading = get_parameter(this->prev_xfading);
+
+ bool switched = current != prev_current;
+
+ if (switched) {
+ set_parameter(this->prev_current, current);
+ set_parameter(this->prev, prev_current);
+
+ prev = prev_current;
+ prev_xfading = xfade;
+ time = 0;
+ switched = true;
+ }
+
+ if (current < 0 || current >= enabled_inputs || prev >= enabled_inputs) {
+ return 0;
+ }
+
+ float rem = 0;
+
if (prev < 0) { // process current animation, check for transition
- float rem = blend_input(current, p_time, p_seek, 1.0, FILTER_IGNORE, false);
+ rem = blend_input(current, p_time, p_seek, 1.0, FILTER_IGNORE, false);
if (p_seek)
time = p_time;
@@ -695,16 +725,13 @@ float AnimationNodeTransition::process(float p_time, bool p_seek) {
if (inputs[current].auto_advance && rem <= xfade) {
- set_current((current + 1) % enabled_inputs);
+ set_parameter(this->current, (current + 1) % enabled_inputs);
}
- return rem;
} else { // cross-fading from prev to current
float blend = xfade ? (prev_xfading / xfade) : 1;
- float rem;
-
if (!p_seek && switched) { //just switched, seek to start of current
rem = blend_input(current, 0, true, 1.0 - blend, FILTER_IGNORE, false);
@@ -723,28 +750,19 @@ float AnimationNodeTransition::process(float p_time, bool p_seek) {
time += p_time;
prev_xfading -= p_time;
if (prev_xfading < 0) {
- prev = -1;
+ set_parameter(this->prev, -1);
}
}
-
- return rem;
}
+
+ set_parameter(this->time, time);
+ set_parameter(this->prev_xfading, prev_xfading);
+
+ return rem;
}
void AnimationNodeTransition::_validate_property(PropertyInfo &property) const {
- if (property.name == "current" && enabled_inputs > 0) {
- property.hint = PROPERTY_HINT_ENUM;
- String anims;
- for (int i = 0; i < enabled_inputs; i++) {
- if (i > 0) {
- anims += ",";
- }
- anims += inputs[i].name;
- }
- property.hint_string = anims;
- }
-
if (property.name.begins_with("input_")) {
String n = property.name.get_slicec('/', 0).get_slicec('_', 1);
if (n != "count") {
@@ -769,14 +787,10 @@ void AnimationNodeTransition::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_input_caption", "input", "caption"), &AnimationNodeTransition::set_input_caption);
ClassDB::bind_method(D_METHOD("get_input_caption", "input"), &AnimationNodeTransition::get_input_caption);
- ClassDB::bind_method(D_METHOD("set_current", "index"), &AnimationNodeTransition::set_current);
- ClassDB::bind_method(D_METHOD("get_current"), &AnimationNodeTransition::get_current);
-
ClassDB::bind_method(D_METHOD("set_cross_fade_time", "time"), &AnimationNodeTransition::set_cross_fade_time);
ClassDB::bind_method(D_METHOD("get_cross_fade_time"), &AnimationNodeTransition::get_cross_fade_time);
ADD_PROPERTY(PropertyInfo(Variant::INT, "input_count", PROPERTY_HINT_RANGE, "0,64,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_enabled_inputs", "get_enabled_inputs");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "current", PROPERTY_HINT_RANGE, "0,64,1"), "set_current", "get_current");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "xfade_time", PROPERTY_HINT_RANGE, "0,120,0.01"), "set_cross_fade_time", "get_cross_fade_time");
for (int i = 0; i < MAX_INPUTS; i++) {
@@ -786,13 +800,15 @@ void AnimationNodeTransition::_bind_methods() {
}
AnimationNodeTransition::AnimationNodeTransition() {
+
+ prev_xfading = "prev_xfading";
+ prev = "prev";
+ time = "time";
+ current = "current";
+ prev_current = "prev_current";
+ ;
+
enabled_inputs = 0;
- xfade = 0;
- current = -1;
- prev = -1;
- prev_time = 0;
- prev_xfading = 0;
- switched = false;
for (int i = 0; i < MAX_INPUTS; i++) {
inputs[i].auto_advance = false;
inputs[i].name = itos(i + 1);
@@ -814,69 +830,102 @@ AnimationNodeOutput::AnimationNodeOutput() {
}
///////////////////////////////////////////////////////
-void AnimationNodeBlendTree::add_node(const StringName &p_name, Ref<AnimationNode> p_node) {
+void AnimationNodeBlendTree::add_node(const StringName &p_name, Ref<AnimationNode> p_node, const Vector2 &p_position) {
ERR_FAIL_COND(nodes.has(p_name));
ERR_FAIL_COND(p_node.is_null());
- ERR_FAIL_COND(p_node->get_parent().is_valid());
- ERR_FAIL_COND(p_node->get_tree() != NULL);
ERR_FAIL_COND(p_name == SceneStringNames::get_singleton()->output);
ERR_FAIL_COND(String(p_name).find("/") != -1);
- nodes[p_name] = p_node;
- p_node->set_parent(this);
- p_node->set_tree(get_tree());
+ Node n;
+ n.node = p_node;
+ n.position = p_position;
+ n.connections.resize(n.node->get_input_count());
+ nodes[p_name] = n;
emit_changed();
+ emit_signal("tree_changed");
+
+ p_node->connect("tree_changed", this, "_tree_changed", varray(), CONNECT_REFERENCE_COUNTED);
+ p_node->connect("changed", this, "_node_changed", varray(p_name), CONNECT_REFERENCE_COUNTED);
}
Ref<AnimationNode> AnimationNodeBlendTree::get_node(const StringName &p_name) const {
ERR_FAIL_COND_V(!nodes.has(p_name), Ref<AnimationNode>());
- return nodes[p_name];
+ return nodes[p_name].node;
}
StringName AnimationNodeBlendTree::get_node_name(const Ref<AnimationNode> &p_node) const {
- for (Map<StringName, Ref<AnimationNode> >::Element *E = nodes.front(); E; E = E->next()) {
- if (E->get() == p_node) {
+ for (Map<StringName, Node>::Element *E = nodes.front(); E; E = E->next()) {
+ if (E->get().node == p_node) {
return E->key();
}
}
ERR_FAIL_V(StringName());
}
+
+void AnimationNodeBlendTree::set_node_position(const StringName &p_node, const Vector2 &p_position) {
+ ERR_FAIL_COND(!nodes.has(p_node));
+ nodes[p_node].position = p_position;
+}
+
+Vector2 AnimationNodeBlendTree::get_node_position(const StringName &p_node) const {
+ ERR_FAIL_COND_V(!nodes.has(p_node), Vector2());
+ return nodes[p_node].position;
+}
+
+void AnimationNodeBlendTree::get_child_nodes(List<ChildNode> *r_child_nodes) {
+ Vector<StringName> ns;
+
+ for (Map<StringName, Node>::Element *E = nodes.front(); E; E = E->next()) {
+ ns.push_back(E->key());
+ }
+
+ ns.sort_custom<StringName::AlphCompare>();
+
+ for (int i = 0; i < ns.size(); i++) {
+ ChildNode cn;
+ cn.name = ns[i];
+ cn.node = nodes[cn.name].node;
+ r_child_nodes->push_back(cn);
+ }
+}
+
bool AnimationNodeBlendTree::has_node(const StringName &p_name) const {
return nodes.has(p_name);
}
+Vector<StringName> AnimationNodeBlendTree::get_node_connection_array(const StringName &p_name) const {
+
+ ERR_FAIL_COND_V(!nodes.has(p_name), Vector<StringName>());
+ return nodes[p_name].connections;
+}
void AnimationNodeBlendTree::remove_node(const StringName &p_name) {
ERR_FAIL_COND(!nodes.has(p_name));
ERR_FAIL_COND(p_name == SceneStringNames::get_singleton()->output); //can't delete output
{
- //erase node connections
- Ref<AnimationNode> node = nodes[p_name];
- for (int i = 0; i < node->get_input_count(); i++) {
- node->set_input_connection(i, StringName());
- }
- node->set_parent(NULL);
- node->set_tree(NULL);
+ Ref<AnimationNode> node = nodes[p_name].node;
+ node->disconnect("tree_changed", this, "_tree_changed");
+ node->disconnect("changed", this, "_node_changed");
}
nodes.erase(p_name);
//erase connections to name
- for (Map<StringName, Ref<AnimationNode> >::Element *E = nodes.front(); E; E = E->next()) {
- Ref<AnimationNode> node = E->get();
- for (int i = 0; i < node->get_input_count(); i++) {
- if (node->get_input_connection(i) == p_name) {
- node->set_input_connection(i, StringName());
+ for (Map<StringName, Node>::Element *E = nodes.front(); E; E = E->next()) {
+ for (int i = 0; i < E->get().connections.size(); i++) {
+ if (E->get().connections[i] == p_name) {
+ E->get().connections.write[i] = StringName();
}
}
}
emit_changed();
+ emit_signal("tree_changed");
}
void AnimationNodeBlendTree::rename_node(const StringName &p_name, const StringName &p_new_name) {
@@ -886,18 +935,24 @@ void AnimationNodeBlendTree::rename_node(const StringName &p_name, const StringN
ERR_FAIL_COND(p_name == SceneStringNames::get_singleton()->output);
ERR_FAIL_COND(p_new_name == SceneStringNames::get_singleton()->output);
+ nodes[p_name].node->disconnect("changed", this, "_node_changed");
+
nodes[p_new_name] = nodes[p_name];
nodes.erase(p_name);
//rename connections
- for (Map<StringName, Ref<AnimationNode> >::Element *E = nodes.front(); E; E = E->next()) {
- Ref<AnimationNode> node = E->get();
- for (int i = 0; i < node->get_input_count(); i++) {
- if (node->get_input_connection(i) == p_name) {
- node->set_input_connection(i, p_new_name);
+ for (Map<StringName, Node>::Element *E = nodes.front(); E; E = E->next()) {
+
+ for (int i = 0; i < E->get().connections.size(); i++) {
+ if (E->get().connections[i] == p_name) {
+ E->get().connections.write[i] = p_new_name;
}
}
}
+ //connection must be done with new name
+ nodes[p_new_name].node->connect("changed", this, "_node_changed", varray(p_new_name), CONNECT_REFERENCE_COUNTED);
+
+ emit_signal("tree_changed");
}
void AnimationNodeBlendTree::connect_node(const StringName &p_input_node, int p_input_index, const StringName &p_output_node) {
@@ -907,18 +962,18 @@ void AnimationNodeBlendTree::connect_node(const StringName &p_input_node, int p_
ERR_FAIL_COND(p_output_node == SceneStringNames::get_singleton()->output);
ERR_FAIL_COND(p_input_node == p_output_node);
- Ref<AnimationNode> input = nodes[p_input_node];
- ERR_FAIL_INDEX(p_input_index, input->get_input_count());
+ Ref<AnimationNode> input = nodes[p_input_node].node;
+ ERR_FAIL_INDEX(p_input_index, nodes[p_input_node].connections.size());
- for (Map<StringName, Ref<AnimationNode> >::Element *E = nodes.front(); E; E = E->next()) {
- Ref<AnimationNode> node = E->get();
- for (int i = 0; i < node->get_input_count(); i++) {
- StringName output = node->get_input_connection(i);
+ for (Map<StringName, Node>::Element *E = nodes.front(); E; E = E->next()) {
+ for (int i = 0; i < E->get().connections.size(); i++) {
+ StringName output = E->get().connections[i];
ERR_FAIL_COND(output == p_output_node);
}
}
- input->set_input_connection(p_input_index, p_output_node);
+ nodes[p_input_node].connections.write[p_input_index] = p_output_node;
+
emit_changed();
}
@@ -926,20 +981,10 @@ void AnimationNodeBlendTree::disconnect_node(const StringName &p_node, int p_inp
ERR_FAIL_COND(!nodes.has(p_node));
- Ref<AnimationNode> input = nodes[p_node];
- ERR_FAIL_INDEX(p_input_index, input->get_input_count());
+ Ref<AnimationNode> input = nodes[p_node].node;
+ ERR_FAIL_INDEX(p_input_index, nodes[p_node].connections.size());
- input->set_input_connection(p_input_index, StringName());
-}
-
-float AnimationNodeBlendTree::get_connection_activity(const StringName &p_input_node, int p_input_index) const {
-
- ERR_FAIL_COND_V(!nodes.has(p_input_node), 0);
-
- Ref<AnimationNode> input = nodes[p_input_node];
- ERR_FAIL_INDEX_V(p_input_index, input->get_input_count(), 0);
-
- return input->get_input_activity(p_input_index);
+ nodes[p_node].connections.write[p_input_index] = StringName();
}
AnimationNodeBlendTree::ConnectionError AnimationNodeBlendTree::can_connect_node(const StringName &p_input_node, int p_input_index, const StringName &p_output_node) const {
@@ -956,20 +1001,19 @@ AnimationNodeBlendTree::ConnectionError AnimationNodeBlendTree::can_connect_node
return CONNECTION_ERROR_SAME_NODE;
}
- Ref<AnimationNode> input = nodes[p_input_node];
+ Ref<AnimationNode> input = nodes[p_input_node].node;
- if (p_input_index < 0 || p_input_index >= input->get_input_count()) {
+ if (p_input_index < 0 || p_input_index >= nodes[p_input_node].connections.size()) {
return CONNECTION_ERROR_NO_INPUT_INDEX;
}
- if (input->get_input_connection(p_input_index) != StringName()) {
+ if (nodes[p_input_node].connections[p_input_index] != StringName()) {
return CONNECTION_ERROR_CONNECTION_EXISTS;
}
- for (Map<StringName, Ref<AnimationNode> >::Element *E = nodes.front(); E; E = E->next()) {
- Ref<AnimationNode> node = E->get();
- for (int i = 0; i < node->get_input_count(); i++) {
- StringName output = node->get_input_connection(i);
+ for (Map<StringName, Node>::Element *E = nodes.front(); E; E = E->next()) {
+ for (int i = 0; i < E->get().connections.size(); i++) {
+ StringName output = E->get().connections[i];
if (output == p_output_node) {
return CONNECTION_ERROR_CONNECTION_EXISTS;
}
@@ -980,10 +1024,9 @@ AnimationNodeBlendTree::ConnectionError AnimationNodeBlendTree::can_connect_node
void AnimationNodeBlendTree::get_node_connections(List<NodeConnection> *r_connections) const {
- for (Map<StringName, Ref<AnimationNode> >::Element *E = nodes.front(); E; E = E->next()) {
- Ref<AnimationNode> node = E->get();
- for (int i = 0; i < node->get_input_count(); i++) {
- StringName output = node->get_input_connection(i);
+ for (Map<StringName, Node>::Element *E = nodes.front(); E; E = E->next()) {
+ for (int i = 0; i < E->get().connections.size(); i++) {
+ StringName output = E->get().connections[i];
if (output != StringName()) {
NodeConnection nc;
nc.input_node = E->key();
@@ -1001,13 +1044,13 @@ String AnimationNodeBlendTree::get_caption() const {
float AnimationNodeBlendTree::process(float p_time, bool p_seek) {
- Ref<AnimationNodeOutput> output = nodes[SceneStringNames::get_singleton()->output];
- return blend_node(output, p_time, p_seek, 1.0);
+ Ref<AnimationNodeOutput> output = nodes[SceneStringNames::get_singleton()->output].node;
+ return _blend_node("output", nodes[SceneStringNames::get_singleton()->output].connections, this, output, p_time, p_seek, 1.0);
}
void AnimationNodeBlendTree::get_node_list(List<StringName> *r_list) {
- for (Map<StringName, Ref<AnimationNode> >::Element *E = nodes.front(); E; E = E->next()) {
+ for (Map<StringName, Node>::Element *E = nodes.front(); E; E = E->next()) {
r_list->push_back(E->key());
}
}
@@ -1022,14 +1065,8 @@ Vector2 AnimationNodeBlendTree::get_graph_offset() const {
return graph_offset;
}
-void AnimationNodeBlendTree::set_tree(AnimationTree *p_player) {
-
- AnimationNode::set_tree(p_player);
-
- for (Map<StringName, Ref<AnimationNode> >::Element *E = nodes.front(); E; E = E->next()) {
- Ref<AnimationNode> node = E->get();
- node->set_tree(p_player);
- }
+Ref<AnimationNode> AnimationNodeBlendTree::get_child_by_name(const StringName &p_name) {
+ return get_node(p_name);
}
bool AnimationNodeBlendTree::_set(const StringName &p_name, const Variant &p_value) {
@@ -1051,7 +1088,7 @@ bool AnimationNodeBlendTree::_set(const StringName &p_name, const Variant &p_val
if (what == "position") {
if (nodes.has(node_name)) {
- nodes[node_name]->set_position(p_value);
+ nodes[node_name].position = p_value;
}
return true;
}
@@ -1078,7 +1115,7 @@ bool AnimationNodeBlendTree::_get(const StringName &p_name, Variant &r_ret) cons
if (what == "node") {
if (nodes.has(node_name)) {
- r_ret = nodes[node_name];
+ r_ret = nodes[node_name].node;
return true;
}
}
@@ -1086,7 +1123,7 @@ bool AnimationNodeBlendTree::_get(const StringName &p_name, Variant &r_ret) cons
if (what == "position") {
if (nodes.has(node_name)) {
- r_ret = nodes[node_name]->get_position();
+ r_ret = nodes[node_name].position;
return true;
}
}
@@ -1113,7 +1150,7 @@ bool AnimationNodeBlendTree::_get(const StringName &p_name, Variant &r_ret) cons
void AnimationNodeBlendTree::_get_property_list(List<PropertyInfo> *p_list) const {
List<StringName> names;
- for (Map<StringName, Ref<AnimationNode> >::Element *E = nodes.front(); E; E = E->next()) {
+ for (Map<StringName, Node>::Element *E = nodes.front(); E; E = E->next()) {
names.push_back(E->key());
}
names.sort_custom<StringName::AlphCompare>();
@@ -1121,7 +1158,7 @@ void AnimationNodeBlendTree::_get_property_list(List<PropertyInfo> *p_list) cons
for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
String name = E->get();
if (name != "output") {
- p_list->push_back(PropertyInfo(Variant::OBJECT, "nodes/" + name + "/node", PROPERTY_HINT_RESOURCE_TYPE, "AnimationNode", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, "nodes/" + name + "/node", PROPERTY_HINT_RESOURCE_TYPE, "AnimationNode", PROPERTY_USAGE_NOEDITOR));
}
p_list->push_back(PropertyInfo(Variant::VECTOR2, "nodes/" + name + "/position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
}
@@ -1129,9 +1166,19 @@ void AnimationNodeBlendTree::_get_property_list(List<PropertyInfo> *p_list) cons
p_list->push_back(PropertyInfo(Variant::ARRAY, "node_connections", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
}
+void AnimationNodeBlendTree::_tree_changed() {
+ emit_signal("tree_changed");
+}
+
+void AnimationNodeBlendTree::_node_changed(const StringName &p_node) {
+
+ ERR_FAIL_COND(!nodes.has(p_node));
+ nodes[p_node].connections.resize(nodes[p_node].node->get_input_count());
+}
+
void AnimationNodeBlendTree::_bind_methods() {
- ClassDB::bind_method(D_METHOD("add_node", "name", "node"), &AnimationNodeBlendTree::add_node);
+ ClassDB::bind_method(D_METHOD("add_node", "name", "node", "position"), &AnimationNodeBlendTree::add_node, DEFVAL(Vector2()));
ClassDB::bind_method(D_METHOD("get_node", "name"), &AnimationNodeBlendTree::get_node);
ClassDB::bind_method(D_METHOD("remove_node", "name"), &AnimationNodeBlendTree::remove_node);
ClassDB::bind_method(D_METHOD("rename_node", "name", "new_name"), &AnimationNodeBlendTree::rename_node);
@@ -1139,9 +1186,15 @@ void AnimationNodeBlendTree::_bind_methods() {
ClassDB::bind_method(D_METHOD("connect_node", "input_node", "input_index", "output_node"), &AnimationNodeBlendTree::connect_node);
ClassDB::bind_method(D_METHOD("disconnect_node", "input_node", "input_index"), &AnimationNodeBlendTree::disconnect_node);
+ ClassDB::bind_method(D_METHOD("set_node_position", "name", "position"), &AnimationNodeBlendTree::set_node_position);
+ ClassDB::bind_method(D_METHOD("get_node_position", "name"), &AnimationNodeBlendTree::get_node_position);
+
ClassDB::bind_method(D_METHOD("set_graph_offset", "offset"), &AnimationNodeBlendTree::set_graph_offset);
ClassDB::bind_method(D_METHOD("get_graph_offset"), &AnimationNodeBlendTree::get_graph_offset);
+ ClassDB::bind_method(D_METHOD("_tree_changed"), &AnimationNodeBlendTree::_tree_changed);
+ ClassDB::bind_method(D_METHOD("_node_changed", "node"), &AnimationNodeBlendTree::_node_changed);
+
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "graph_offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_graph_offset", "get_graph_offset");
BIND_CONSTANT(CONNECTION_OK);
@@ -1156,15 +1209,12 @@ AnimationNodeBlendTree::AnimationNodeBlendTree() {
Ref<AnimationNodeOutput> output;
output.instance();
- output->set_position(Vector2(300, 150));
- output->set_parent(this);
- nodes["output"] = output;
+ Node n;
+ n.node = output;
+ n.position = Vector2(300, 150);
+ n.connections.resize(1);
+ nodes["output"] = n;
}
AnimationNodeBlendTree::~AnimationNodeBlendTree() {
-
- for (Map<StringName, Ref<AnimationNode> >::Element *E = nodes.front(); E; E = E->next()) {
- E->get()->set_parent(NULL);
- E->get()->set_tree(NULL);
- }
}
diff --git a/scene/animation/animation_blend_tree.h b/scene/animation/animation_blend_tree.h
index e86cc2e823..7bf2917c1e 100644
--- a/scene/animation/animation_blend_tree.h
+++ b/scene/animation/animation_blend_tree.h
@@ -20,6 +20,8 @@ protected:
static void _bind_methods();
public:
+ static Vector<String> (*get_editable_animation_list)();
+
virtual String get_caption() const;
virtual float process(float p_time, bool p_seek);
@@ -41,8 +43,6 @@ public:
};
private:
- bool active;
- bool do_start;
float fade_in;
float fade_out;
@@ -51,15 +51,25 @@ private:
float autorestart_random_delay;
MixMode mix;
- float time;
- float remaining;
- float autorestart_remaining;
bool sync;
+ /* bool active;
+ bool do_start;
+ float time;
+ float remaining;*/
+
+ StringName active;
+ StringName prev_active;
+ StringName time;
+ StringName remaining;
+
protected:
static void _bind_methods();
public:
+ virtual void get_parameter_list(List<PropertyInfo> *r_list) const;
+ virtual Variant get_parameter_default_value(const StringName &p_parameter) const;
+
virtual String get_caption() const;
void set_fadein_time(float p_time);
@@ -79,10 +89,6 @@ public:
void set_mix_mode(MixMode p_mix);
MixMode get_mix_mode() const;
- void start();
- void stop();
- bool is_active() const;
-
void set_use_sync(bool p_sync);
bool is_using_sync() const;
@@ -97,17 +103,17 @@ VARIANT_ENUM_CAST(AnimationNodeOneShot::MixMode)
class AnimationNodeAdd2 : public AnimationNode {
GDCLASS(AnimationNodeAdd2, AnimationNode);
- float amount;
+ StringName add_amount;
bool sync;
protected:
static void _bind_methods();
public:
- virtual String get_caption() const;
+ void get_parameter_list(List<PropertyInfo> *r_list) const;
+ virtual Variant get_parameter_default_value(const StringName &p_parameter) const;
- void set_amount(float p_amount);
- float get_amount() const;
+ virtual String get_caption() const;
void set_use_sync(bool p_sync);
bool is_using_sync() const;
@@ -121,17 +127,17 @@ public:
class AnimationNodeAdd3 : public AnimationNode {
GDCLASS(AnimationNodeAdd3, AnimationNode);
- float amount;
+ StringName add_amount;
bool sync;
protected:
static void _bind_methods();
public:
- virtual String get_caption() const;
+ void get_parameter_list(List<PropertyInfo> *r_list) const;
+ virtual Variant get_parameter_default_value(const StringName &p_parameter) const;
- void set_amount(float p_amount);
- float get_amount() const;
+ virtual String get_caption() const;
void set_use_sync(bool p_sync);
bool is_using_sync() const;
@@ -145,19 +151,19 @@ public:
class AnimationNodeBlend2 : public AnimationNode {
GDCLASS(AnimationNodeBlend2, AnimationNode);
- float amount;
+ StringName blend_amount;
bool sync;
protected:
static void _bind_methods();
public:
+ virtual void get_parameter_list(List<PropertyInfo> *r_list) const;
+ virtual Variant get_parameter_default_value(const StringName &p_parameter) const;
+
virtual String get_caption() const;
virtual float process(float p_time, bool p_seek);
- void set_amount(float p_amount);
- float get_amount() const;
-
void set_use_sync(bool p_sync);
bool is_using_sync() const;
@@ -168,17 +174,17 @@ public:
class AnimationNodeBlend3 : public AnimationNode {
GDCLASS(AnimationNodeBlend3, AnimationNode);
- float amount;
+ StringName blend_amount;
bool sync;
protected:
static void _bind_methods();
public:
- virtual String get_caption() const;
+ virtual void get_parameter_list(List<PropertyInfo> *r_list) const;
+ virtual Variant get_parameter_default_value(const StringName &p_parameter) const;
- void set_amount(float p_amount);
- float get_amount() const;
+ virtual String get_caption() const;
void set_use_sync(bool p_sync);
bool is_using_sync() const;
@@ -190,16 +196,16 @@ public:
class AnimationNodeTimeScale : public AnimationNode {
GDCLASS(AnimationNodeTimeScale, AnimationNode);
- float scale;
+ StringName scale;
protected:
static void _bind_methods();
public:
- virtual String get_caption() const;
+ virtual void get_parameter_list(List<PropertyInfo> *r_list) const;
+ virtual Variant get_parameter_default_value(const StringName &p_parameter) const;
- void set_scale(float p_scale);
- float get_scale() const;
+ virtual String get_caption() const;
float process(float p_time, bool p_seek);
@@ -209,16 +215,16 @@ public:
class AnimationNodeTimeSeek : public AnimationNode {
GDCLASS(AnimationNodeTimeSeek, AnimationNode);
- float seek_pos;
+ StringName seek_pos;
protected:
static void _bind_methods();
public:
- virtual String get_caption() const;
+ virtual void get_parameter_list(List<PropertyInfo> *r_list) const;
+ virtual Variant get_parameter_default_value(const StringName &p_parameter) const;
- void set_seek_pos(float p_sec);
- float get_seek_pos() const;
+ virtual String get_caption() const;
float process(float p_time, bool p_seek);
@@ -241,13 +247,18 @@ class AnimationNodeTransition : public AnimationNode {
InputData inputs[MAX_INPUTS];
int enabled_inputs;
- float prev_time;
+ /*
float prev_xfading;
int prev;
- bool switched;
-
float time;
int current;
+ int prev_current; */
+
+ StringName prev_xfading;
+ StringName prev;
+ StringName time;
+ StringName current;
+ StringName prev_current;
float xfade;
@@ -258,6 +269,9 @@ protected:
void _validate_property(PropertyInfo &property) const;
public:
+ virtual void get_parameter_list(List<PropertyInfo> *r_list) const;
+ virtual Variant get_parameter_default_value(const StringName &p_parameter) const;
+
virtual String get_caption() const;
void set_enabled_inputs(int p_inputs);
@@ -269,9 +283,6 @@ public:
void set_input_caption(int p_input, const String &p_name);
String get_input_caption(int p_input) const;
- void set_current(int p_current);
- int get_current() const;
-
void set_cross_fade_time(float p_fade);
float get_cross_fade_time() const;
@@ -293,10 +304,19 @@ public:
class AnimationNodeBlendTree : public AnimationRootNode {
GDCLASS(AnimationNodeBlendTree, AnimationRootNode)
- Map<StringName, Ref<AnimationNode> > nodes;
+ struct Node {
+ Ref<AnimationNode> node;
+ Vector2 position;
+ Vector<StringName> connections;
+ };
+
+ Map<StringName, Node> nodes;
Vector2 graph_offset;
+ void _tree_changed();
+ void _node_changed(const StringName &p_node);
+
protected:
static void _bind_methods();
bool _set(const StringName &p_name, const Variant &p_value);
@@ -314,16 +334,21 @@ public:
//no need to check for cycles due to tree topology
};
- void add_node(const StringName &p_name, Ref<AnimationNode> p_node);
+ void add_node(const StringName &p_name, Ref<AnimationNode> p_node, const Vector2 &p_position = Vector2());
Ref<AnimationNode> get_node(const StringName &p_name) const;
void remove_node(const StringName &p_name);
void rename_node(const StringName &p_name, const StringName &p_new_name);
bool has_node(const StringName &p_name) const;
StringName get_node_name(const Ref<AnimationNode> &p_node) const;
+ Vector<StringName> get_node_connection_array(const StringName &p_name) const;
+
+ void set_node_position(const StringName &p_node, const Vector2 &p_position);
+ Vector2 get_node_position(const StringName &p_node) const;
+
+ virtual void get_child_nodes(List<ChildNode> *r_child_nodes);
void connect_node(const StringName &p_input_node, int p_input_index, const StringName &p_output_node);
void disconnect_node(const StringName &p_node, int p_input_index);
- float get_connection_activity(const StringName &p_input_node, int p_input_index) const;
struct NodeConnection {
StringName input_node;
@@ -342,7 +367,8 @@ public:
void set_graph_offset(const Vector2 &p_graph_offset);
Vector2 get_graph_offset() const;
- virtual void set_tree(AnimationTree *p_player);
+ virtual Ref<AnimationNode> get_child_by_name(const StringName &p_name);
+
AnimationNodeBlendTree();
~AnimationNodeBlendTree();
};
diff --git a/scene/animation/animation_cache.cpp b/scene/animation/animation_cache.cpp
index 949a0be3bc..756907c41c 100644
--- a/scene/animation/animation_cache.cpp
+++ b/scene/animation/animation_cache.cpp
@@ -43,7 +43,7 @@ void AnimationCache::_node_exit_tree(Node *p_node) {
if (path_cache[i].node != p_node)
continue;
- path_cache[i].valid = false; //invalidate path cache
+ path_cache.write[i].valid = false; //invalidate path cache
}
}
@@ -196,7 +196,7 @@ void AnimationCache::set_track_transform(int p_idx, const Transform &p_transform
ERR_FAIL_COND(!cache_valid);
ERR_FAIL_INDEX(p_idx, path_cache.size());
- Path &p = path_cache[p_idx];
+ Path &p = path_cache.write[p_idx];
if (!p.valid)
return;
@@ -217,7 +217,7 @@ void AnimationCache::set_track_value(int p_idx, const Variant &p_value) {
ERR_FAIL_COND(!cache_valid);
ERR_FAIL_INDEX(p_idx, path_cache.size());
- Path &p = path_cache[p_idx];
+ Path &p = path_cache.write[p_idx];
if (!p.valid)
return;
@@ -232,7 +232,7 @@ void AnimationCache::call_track(int p_idx, const StringName &p_method, const Var
ERR_FAIL_COND(!cache_valid);
ERR_FAIL_INDEX(p_idx, path_cache.size());
- Path &p = path_cache[p_idx];
+ Path &p = path_cache.write[p_idx];
if (!p.valid)
return;
@@ -297,11 +297,11 @@ void AnimationCache::set_all(float p_time, float p_delta) {
call_track(i, name, NULL, 0, err);
} else {
- Vector<Variant *> argptrs;
+ Vector<const Variant *> argptrs;
argptrs.resize(args.size());
for (int j = 0; j < args.size(); j++) {
- argptrs[j] = &args[j];
+ argptrs.write[j] = &args.write[j];
}
call_track(i, name, (const Variant **)&argptrs[0], args.size(), err);
diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp
index c5ad980806..09c36eb081 100644
--- a/scene/animation/animation_node_state_machine.cpp
+++ b/scene/animation/animation_node_state_machine.cpp
@@ -20,6 +20,26 @@ bool AnimationNodeStateMachineTransition::has_auto_advance() const {
return auto_advance;
}
+void AnimationNodeStateMachineTransition::set_advance_condition(const StringName &p_condition) {
+ String cs = p_condition;
+ ERR_FAIL_COND(cs.find("/") != -1 || cs.find(":") != -1);
+ advance_condition = p_condition;
+ if (cs != String()) {
+ advance_condition_name = "conditions/" + cs;
+ } else {
+ advance_condition_name = StringName();
+ }
+ emit_signal("advance_condition_changed");
+}
+
+StringName AnimationNodeStateMachineTransition::get_advance_condition() const {
+ return advance_condition;
+}
+
+StringName AnimationNodeStateMachineTransition::get_advance_condition_name() const {
+ return advance_condition_name;
+}
+
void AnimationNodeStateMachineTransition::set_xfade_time(float p_xfade) {
ERR_FAIL_COND(p_xfade < 0);
@@ -56,6 +76,9 @@ void AnimationNodeStateMachineTransition::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_auto_advance", "auto_advance"), &AnimationNodeStateMachineTransition::set_auto_advance);
ClassDB::bind_method(D_METHOD("has_auto_advance"), &AnimationNodeStateMachineTransition::has_auto_advance);
+ ClassDB::bind_method(D_METHOD("set_advance_condition", "name"), &AnimationNodeStateMachineTransition::set_advance_condition);
+ ClassDB::bind_method(D_METHOD("get_advance_condition"), &AnimationNodeStateMachineTransition::get_advance_condition);
+
ClassDB::bind_method(D_METHOD("set_xfade_time", "secs"), &AnimationNodeStateMachineTransition::set_xfade_time);
ClassDB::bind_method(D_METHOD("get_xfade_time"), &AnimationNodeStateMachineTransition::get_xfade_time);
@@ -67,13 +90,16 @@ void AnimationNodeStateMachineTransition::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "switch_mode", PROPERTY_HINT_ENUM, "Immediate,Sync,AtEnd"), "set_switch_mode", "get_switch_mode");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_advance"), "set_auto_advance", "has_auto_advance");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "advance_condition"), "set_advance_condition", "get_advance_condition");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "xfade_time", PROPERTY_HINT_RANGE, "0,240,0.01"), "set_xfade_time", "get_xfade_time");
ADD_PROPERTY(PropertyInfo(Variant::INT, "priority", PROPERTY_HINT_RANGE, "0,32,1"), "set_priority", "get_priority");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disabled"), "set_disabled", "is_disabled");
- BIND_CONSTANT(SWITCH_MODE_IMMEDIATE);
- BIND_CONSTANT(SWITCH_MODE_SYNC);
- BIND_CONSTANT(SWITCH_MODE_AT_END);
+ BIND_ENUM_CONSTANT(SWITCH_MODE_IMMEDIATE);
+ BIND_ENUM_CONSTANT(SWITCH_MODE_SYNC);
+ BIND_ENUM_CONSTANT(SWITCH_MODE_AT_END);
+
+ ADD_SIGNAL(MethodInfo("advance_condition_changed"));
}
AnimationNodeStateMachineTransition::AnimationNodeStateMachineTransition() {
@@ -85,277 +111,240 @@ AnimationNodeStateMachineTransition::AnimationNodeStateMachineTransition() {
priority = 1;
}
-///////////////////////////////////////////////////////
-void AnimationNodeStateMachine::add_node(const StringName &p_name, Ref<AnimationNode> p_node) {
-
- ERR_FAIL_COND(states.has(p_name));
- ERR_FAIL_COND(p_node.is_null());
- ERR_FAIL_COND(p_node->get_parent().is_valid());
- ERR_FAIL_COND(p_node->get_tree() != NULL);
- ERR_FAIL_COND(String(p_name).find("/") != -1);
- states[p_name] = p_node;
+////////////////////////////////////////////////////////
- p_node->set_parent(this);
- p_node->set_tree(get_tree());
+void AnimationNodeStateMachinePlayback::travel(const StringName &p_state) {
- emit_changed();
+ start_request_travel = true;
+ start_request = p_state;
+ stop_request = false;
}
-Ref<AnimationNode> AnimationNodeStateMachine::get_node(const StringName &p_name) const {
-
- ERR_FAIL_COND_V(!states.has(p_name), Ref<AnimationNode>());
-
- return states[p_name];
+void AnimationNodeStateMachinePlayback::start(const StringName &p_state) {
+ start_request_travel = false;
+ start_request = p_state;
+ stop_request = false;
}
+void AnimationNodeStateMachinePlayback::stop() {
-StringName AnimationNodeStateMachine::get_node_name(const Ref<AnimationNode> &p_node) const {
- for (Map<StringName, Ref<AnimationRootNode> >::Element *E = states.front(); E; E = E->next()) {
- if (E->get() == p_node) {
- return E->key();
- }
- }
-
- ERR_FAIL_V(StringName());
+ stop_request = true;
}
-
-bool AnimationNodeStateMachine::has_node(const StringName &p_name) const {
- return states.has(p_name);
+bool AnimationNodeStateMachinePlayback::is_playing() const {
+ return playing;
+}
+StringName AnimationNodeStateMachinePlayback::get_current_node() const {
+ return current;
+}
+StringName AnimationNodeStateMachinePlayback::get_blend_from_node() const {
+ return fading_from;
+}
+Vector<StringName> AnimationNodeStateMachinePlayback::get_travel_path() const {
+ return path;
+}
+float AnimationNodeStateMachinePlayback::get_current_play_pos() const {
+ return pos_current;
+}
+float AnimationNodeStateMachinePlayback::get_current_length() const {
+ return len_current;
}
-void AnimationNodeStateMachine::remove_node(const StringName &p_name) {
-
- ERR_FAIL_COND(!states.has(p_name));
-
- {
- //erase node connections
- Ref<AnimationNode> node = states[p_name];
- for (int i = 0; i < node->get_input_count(); i++) {
- node->set_input_connection(i, StringName());
- }
- node->set_parent(NULL);
- node->set_tree(NULL);
- }
- states.erase(p_name);
- path.erase(p_name);
+bool AnimationNodeStateMachinePlayback::_travel(AnimationNodeStateMachine *sm, const StringName &p_travel) {
- for (int i = 0; i < transitions.size(); i++) {
- if (transitions[i].from == p_name || transitions[i].to == p_name) {
- transitions.remove(i);
- i--;
- }
- }
+ ERR_FAIL_COND_V(!playing, false);
+ ERR_FAIL_COND_V(!sm->states.has(p_travel), false);
+ ERR_FAIL_COND_V(!sm->states.has(current), false);
- if (start_node == p_name) {
- start_node = StringName();
- }
+ path.clear(); //a new one will be needed
- if (end_node == p_name) {
- end_node = StringName();
- }
+ if (current == p_travel)
+ return true; //nothing to do
- if (playing && current == p_name) {
- stop();
- }
- emit_changed();
-}
+ loops_current = 0; // reset loops, so fade does not happen immediately
-void AnimationNodeStateMachine::rename_node(const StringName &p_name, const StringName &p_new_name) {
+ Vector2 current_pos = sm->states[current].position;
+ Vector2 target_pos = sm->states[p_travel].position;
- ERR_FAIL_COND(!states.has(p_name));
- ERR_FAIL_COND(states.has(p_new_name));
+ Map<StringName, AStarCost> cost_map;
- states[p_new_name] = states[p_name];
- states.erase(p_name);
+ List<int> open_list;
- for (int i = 0; i < transitions.size(); i++) {
- if (transitions[i].from == p_name) {
- transitions[i].from = p_new_name;
- }
+ //build open list
+ for (int i = 0; i < sm->transitions.size(); i++) {
+ if (sm->transitions[i].from == current) {
+ open_list.push_back(i);
+ float cost = sm->states[sm->transitions[i].to].position.distance_to(current_pos);
+ cost *= sm->transitions[i].transition->get_priority();
+ AStarCost ap;
+ ap.prev = current;
+ ap.distance = cost;
+ cost_map[sm->transitions[i].to] = ap;
- if (transitions[i].to == p_name) {
- transitions[i].to = p_new_name;
+ if (sm->transitions[i].to == p_travel) { //prematurely found it! :D
+ path.push_back(p_travel);
+ return true;
+ }
}
}
- if (start_node == p_name) {
- start_node = p_new_name;
- }
+ //begin astar
+ bool found_route = false;
+ while (!found_route) {
- if (end_node == p_name) {
- end_node = p_new_name;
- }
+ if (open_list.size() == 0) {
+ return false; //no path found
+ }
- if (playing && current == p_name) {
- current = p_new_name;
- }
+ //find the last cost transition
+ List<int>::Element *least_cost_transition = NULL;
+ float least_cost = 1e20;
- path.clear(); //clear path
-}
+ for (List<int>::Element *E = open_list.front(); E; E = E->next()) {
-void AnimationNodeStateMachine::get_node_list(List<StringName> *r_nodes) const {
+ float cost = cost_map[sm->transitions[E->get()].to].distance;
+ cost += sm->states[sm->transitions[E->get()].to].position.distance_to(target_pos);
- List<StringName> nodes;
- for (Map<StringName, Ref<AnimationRootNode> >::Element *E = states.front(); E; E = E->next()) {
- nodes.push_back(E->key());
- }
- nodes.sort_custom<StringName::AlphCompare>();
+ if (cost < least_cost) {
+ least_cost_transition = E;
+ }
+ }
- for (List<StringName>::Element *E = nodes.front(); E; E = E->next()) {
- r_nodes->push_back(E->get());
- }
-}
+ StringName transition_prev = sm->transitions[least_cost_transition->get()].from;
+ StringName transition = sm->transitions[least_cost_transition->get()].to;
-bool AnimationNodeStateMachine::has_transition(const StringName &p_from, const StringName &p_to) const {
+ for (int i = 0; i < sm->transitions.size(); i++) {
+ if (sm->transitions[i].from != transition || sm->transitions[i].to == transition_prev) {
+ continue; //not interested on those
+ }
- for (int i = 0; i < transitions.size(); i++) {
- if (transitions[i].from == p_from && transitions[i].to == p_to)
- return true;
- }
- return false;
-}
+ float distance = sm->states[sm->transitions[i].from].position.distance_to(sm->states[sm->transitions[i].to].position);
+ distance *= sm->transitions[i].transition->get_priority();
+ distance += cost_map[sm->transitions[i].from].distance;
-int AnimationNodeStateMachine::find_transition(const StringName &p_from, const StringName &p_to) const {
+ if (cost_map.has(sm->transitions[i].to)) {
+ //oh this was visited already, can we win the cost?
+ if (distance < cost_map[sm->transitions[i].to].distance) {
+ cost_map[sm->transitions[i].to].distance = distance;
+ cost_map[sm->transitions[i].to].prev = sm->transitions[i].from;
+ }
+ } else {
+ //add to open list
+ AStarCost ac;
+ ac.prev = sm->transitions[i].from;
+ ac.distance = distance;
+ cost_map[sm->transitions[i].to] = ac;
- for (int i = 0; i < transitions.size(); i++) {
- if (transitions[i].from == p_from && transitions[i].to == p_to)
- return i;
- }
- return -1;
-}
+ open_list.push_back(i);
-void AnimationNodeStateMachine::add_transition(const StringName &p_from, const StringName &p_to, const Ref<AnimationNodeStateMachineTransition> &p_transition) {
+ if (sm->transitions[i].to == p_travel) {
+ found_route = true;
+ break;
+ }
+ }
+ }
- ERR_FAIL_COND(p_from == p_to);
- ERR_FAIL_COND(!states.has(p_from));
- ERR_FAIL_COND(!states.has(p_to));
- ERR_FAIL_COND(p_transition.is_null());
+ if (found_route) {
+ break;
+ }
- for (int i = 0; i < transitions.size(); i++) {
- ERR_FAIL_COND(transitions[i].from == p_from && transitions[i].to == p_to);
+ open_list.erase(least_cost_transition);
}
- Transition tr;
- tr.from = p_from;
- tr.to = p_to;
- tr.transition = p_transition;
-
- transitions.push_back(tr);
-}
-
-Ref<AnimationNodeStateMachineTransition> AnimationNodeStateMachine::get_transition(int p_transition) const {
- ERR_FAIL_INDEX_V(p_transition, transitions.size(), Ref<AnimationNodeStateMachineTransition>());
- return transitions[p_transition].transition;
-}
-StringName AnimationNodeStateMachine::get_transition_from(int p_transition) const {
+ //make path
+ StringName at = p_travel;
+ while (at != current) {
+ path.push_back(at);
+ at = cost_map[at].prev;
+ }
- ERR_FAIL_INDEX_V(p_transition, transitions.size(), StringName());
- return transitions[p_transition].from;
-}
-StringName AnimationNodeStateMachine::get_transition_to(int p_transition) const {
+ path.invert();
- ERR_FAIL_INDEX_V(p_transition, transitions.size(), StringName());
- return transitions[p_transition].to;
+ return true;
}
-int AnimationNodeStateMachine::get_transition_count() const {
-
- return transitions.size();
-}
-void AnimationNodeStateMachine::remove_transition(const StringName &p_from, const StringName &p_to) {
+float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *sm, float p_time, bool p_seek) {
- for (int i = 0; i < transitions.size(); i++) {
- if (transitions[i].from == p_from && transitions[i].to == p_to) {
- transitions.remove(i);
- return;
+ //if not playing and it can restart, then restart
+ if (!playing && start_request == StringName()) {
+ if (!stop_request && sm->start_node) {
+ start(sm->start_node);
+ } else {
+ return 0;
}
}
- if (playing) {
- path.clear();
- }
-}
-
-void AnimationNodeStateMachine::remove_transition_by_index(int p_transition) {
-
- transitions.remove(p_transition);
- if (playing) {
- path.clear();
+ if (playing && stop_request) {
+ stop_request = false;
+ playing = false;
+ return 0;
}
-}
-
-void AnimationNodeStateMachine::set_start_node(const StringName &p_node) {
-
- ERR_FAIL_COND(p_node != StringName() && !states.has(p_node));
- start_node = p_node;
-}
-
-String AnimationNodeStateMachine::get_start_node() const {
-
- return start_node;
-}
-
-void AnimationNodeStateMachine::set_end_node(const StringName &p_node) {
-
- ERR_FAIL_COND(p_node != StringName() && !states.has(p_node));
- end_node = p_node;
-}
-
-String AnimationNodeStateMachine::get_end_node() const {
-
- return end_node;
-}
-void AnimationNodeStateMachine::set_graph_offset(const Vector2 &p_offset) {
- graph_offset = p_offset;
-}
+ bool play_start = false;
-Vector2 AnimationNodeStateMachine::get_graph_offset() const {
- return graph_offset;
-}
+ if (start_request != StringName()) {
-float AnimationNodeStateMachine::process(float p_time, bool p_seek) {
+ if (start_request_travel) {
+ if (!playing) {
+ start_request = StringName();
+ ERR_EXPLAIN("Can't travel to '" + String(start_request) + "' if state machine is not active.");
+ ERR_FAIL_V(0);
+ }
- //if not playing and it can restart, then restart
- if (!playing) {
- if (start_node) {
- start(start_node);
+ if (!_travel(sm, start_request)) {
+ //cant travel, then teleport
+ path.clear();
+ current = start_request;
+ }
} else {
- return 0;
+ path.clear();
+ current = start_request;
+ playing = true;
+ play_start = true;
}
+
+ start_request = StringName(); //clear start request
}
bool do_start = (p_seek && p_time == 0) || play_start || current == StringName();
if (do_start) {
- if (start_node != StringName() && p_seek && p_time == 0) {
- current = start_node;
+ if (sm->start_node != StringName() && p_seek && p_time == 0) {
+ current = sm->start_node;
}
- len_current = blend_node(states[current], 0, true, 1.0, FILTER_IGNORE, false);
+ len_current = sm->blend_node(current, sm->states[current].node, 0, true, 1.0, AnimationNode::FILTER_IGNORE, false);
pos_current = 0;
loops_current = 0;
play_start = false;
}
+ if (!sm->states.has(current)) {
+ playing = false; //current does not exist
+ current = StringName();
+ return 0;
+ }
float fade_blend = 1.0;
if (fading_from != StringName()) {
- if (!p_seek) {
- fading_pos += p_time;
- }
- fade_blend = MIN(1.0, fading_pos / fading_time);
- if (fade_blend >= 1.0) {
+ if (!sm->states.has(fading_from)) {
fading_from = StringName();
+ } else {
+ if (!p_seek) {
+ fading_pos += p_time;
+ }
+ fade_blend = MIN(1.0, fading_pos / fading_time);
+ if (fade_blend >= 1.0) {
+ fading_from = StringName();
+ }
}
}
- float rem = blend_node(states[current], p_time, p_seek, fade_blend, FILTER_IGNORE, false);
+ float rem = sm->blend_node(current, sm->states[current].node, p_time, p_seek, fade_blend, AnimationNode::FILTER_IGNORE, false);
if (fading_from != StringName()) {
- blend_node(states[fading_from], p_time, p_seek, 1.0 - fade_blend, FILTER_IGNORE, false);
+ sm->blend_node(current, sm->states[fading_from].node, p_time, p_seek, 1.0 - fade_blend, AnimationNode::FILTER_IGNORE, false);
}
//guess playback position
@@ -380,29 +369,39 @@ float AnimationNodeStateMachine::process(float p_time, bool p_seek) {
if (path.size()) {
- for (int i = 0; i < transitions.size(); i++) {
- if (transitions[i].from == current && transitions[i].to == path[0]) {
- next_xfade = transitions[i].transition->get_xfade_time();
- switch_mode = transitions[i].transition->get_switch_mode();
+ for (int i = 0; i < sm->transitions.size(); i++) {
+ if (sm->transitions[i].from == current && sm->transitions[i].to == path[0]) {
+ next_xfade = sm->transitions[i].transition->get_xfade_time();
+ switch_mode = sm->transitions[i].transition->get_switch_mode();
next = path[0];
}
}
} else {
float priority_best = 1e20;
int auto_advance_to = -1;
- for (int i = 0; i < transitions.size(); i++) {
- if (transitions[i].from == current && transitions[i].transition->has_auto_advance()) {
+ for (int i = 0; i < sm->transitions.size(); i++) {
+
+ bool auto_advance = false;
+ if (sm->transitions[i].transition->has_auto_advance()) {
+ auto_advance = true;
+ }
+ StringName advance_condition_name = sm->transitions[i].transition->get_advance_condition_name();
+ if (advance_condition_name != StringName() && bool(sm->get_parameter(advance_condition_name))) {
+ auto_advance = true;
+ }
+
+ if (sm->transitions[i].from == current && sm->transitions[i].transition->has_auto_advance()) {
- if (transitions[i].transition->get_priority() < priority_best) {
+ if (sm->transitions[i].transition->get_priority() < priority_best) {
auto_advance_to = i;
}
}
}
if (auto_advance_to != -1) {
- next = transitions[auto_advance_to].to;
- next_xfade = transitions[auto_advance_to].transition->get_xfade_time();
- switch_mode = transitions[auto_advance_to].transition->get_switch_mode();
+ next = sm->transitions[auto_advance_to].to;
+ next_xfade = sm->transitions[auto_advance_to].transition->get_xfade_time();
+ switch_mode = sm->transitions[auto_advance_to].transition->get_switch_mode();
}
}
@@ -437,12 +436,12 @@ float AnimationNodeStateMachine::process(float p_time, bool p_seek) {
}
current = next;
if (switch_mode == AnimationNodeStateMachineTransition::SWITCH_MODE_SYNC) {
- len_current = blend_node(states[current], 0, true, 0, FILTER_IGNORE, false);
+ len_current = sm->blend_node(current, sm->states[current].node, 0, true, 0, AnimationNode::FILTER_IGNORE, false);
pos_current = MIN(pos_current, len_current);
- blend_node(states[current], pos_current, true, 0, FILTER_IGNORE, false);
+ sm->blend_node(current, sm->states[current].node, pos_current, true, 0, AnimationNode::FILTER_IGNORE, false);
} else {
- len_current = blend_node(states[current], 0, true, 0, FILTER_IGNORE, false);
+ len_current = sm->blend_node(current, sm->states[current].node, 0, true, 0, AnimationNode::FILTER_IGNORE, false);
pos_current = 0;
}
@@ -453,169 +452,321 @@ float AnimationNodeStateMachine::process(float p_time, bool p_seek) {
//compute time left for transitions by using the end node
- if (end_node != StringName() && end_node != current) {
+ if (sm->end_node != StringName() && sm->end_node != current) {
- rem = blend_node(states[end_node], 0, true, 0, FILTER_IGNORE, false);
+ rem = sm->blend_node(current, sm->states[sm->end_node].node, 0, true, 0, AnimationNode::FILTER_IGNORE, false);
}
return rem;
}
-bool AnimationNodeStateMachine::travel(const StringName &p_state) {
- ERR_FAIL_COND_V(!playing, false);
- ERR_FAIL_COND_V(!states.has(p_state), false);
- ERR_FAIL_COND_V(!states.has(current), false);
+void AnimationNodeStateMachinePlayback::_bind_methods() {
- path.clear(); //a new one will be needed
+ ClassDB::bind_method(D_METHOD("travel", "to_node"), &AnimationNodeStateMachinePlayback::travel);
+ ClassDB::bind_method(D_METHOD("start", "node"), &AnimationNodeStateMachinePlayback::start);
+ ClassDB::bind_method(D_METHOD("stop"), &AnimationNodeStateMachinePlayback::stop);
+ ClassDB::bind_method(D_METHOD("is_playing"), &AnimationNodeStateMachinePlayback::is_playing);
+ ClassDB::bind_method(D_METHOD("get_current_node"), &AnimationNodeStateMachinePlayback::get_current_node);
+ ClassDB::bind_method(D_METHOD("get_travel_path"), &AnimationNodeStateMachinePlayback::get_travel_path);
+}
- if (current == p_state)
- return true; //nothing to do
+AnimationNodeStateMachinePlayback::AnimationNodeStateMachinePlayback() {
+ set_local_to_scene(true); //only one per instanced scene
- loops_current = 0; // reset loops, so fade does not happen immediately
+ playing = false;
+ len_current = 0;
+ fading_time = 0;
+ stop_request = false;
+}
- Vector2 current_pos = states[current]->get_position();
- Vector2 target_pos = states[p_state]->get_position();
+///////////////////////////////////////////////////////
- Map<StringName, AStarCost> cost_map;
+void AnimationNodeStateMachine::get_parameter_list(List<PropertyInfo> *r_list) const {
+ r_list->push_back(PropertyInfo(Variant::OBJECT, playback, PROPERTY_HINT_RESOURCE_TYPE, "AnimationNodeStateMachinePlayback", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE));
+ List<StringName> advance_conditions;
+ for (int i = 0; i < transitions.size(); i++) {
+ StringName ac = transitions[i].transition->get_advance_condition_name();
+ if (ac != StringName() && advance_conditions.find(ac) == NULL) {
+ advance_conditions.push_back(ac);
+ }
+ }
- List<int> open_list;
+ advance_conditions.sort_custom<StringName::AlphCompare>();
+ for (List<StringName>::Element *E = advance_conditions.front(); E; E = E->next()) {
+ r_list->push_back(PropertyInfo(Variant::BOOL, E->get()));
+ }
+}
- //build open list
- for (int i = 0; i < transitions.size(); i++) {
- if (transitions[i].from == current) {
- open_list.push_back(i);
- float cost = states[transitions[i].to]->get_position().distance_to(current_pos);
- cost *= transitions[i].transition->get_priority();
- AStarCost ap;
- ap.prev = current;
- ap.distance = cost;
- cost_map[transitions[i].to] = ap;
+Variant AnimationNodeStateMachine::get_parameter_default_value(const StringName &p_parameter) const {
- if (transitions[i].to == p_state) { //prematurely found it! :D
- path.push_back(p_state);
- return true;
- }
- }
+ if (p_parameter == playback) {
+ Ref<AnimationNodeStateMachinePlayback> p;
+ p.instance();
+ return p;
+ } else {
+ return false; //advance condition
}
+}
- //begin astar
- bool found_route = false;
- while (!found_route) {
+void AnimationNodeStateMachine::add_node(const StringName &p_name, Ref<AnimationNode> p_node, const Vector2 &p_position) {
- if (open_list.size() == 0) {
- return false; //no path found
+ ERR_FAIL_COND(states.has(p_name));
+ ERR_FAIL_COND(p_node.is_null());
+ ERR_FAIL_COND(String(p_name).find("/") != -1);
+
+ State state;
+ state.node = p_node;
+ state.position = p_position;
+
+ states[p_name] = state;
+
+ emit_changed();
+ emit_signal("tree_changed");
+
+ p_node->connect("tree_changed", this, "_tree_changed", varray(), CONNECT_REFERENCE_COUNTED);
+}
+
+Ref<AnimationNode> AnimationNodeStateMachine::get_node(const StringName &p_name) const {
+
+ ERR_FAIL_COND_V(!states.has(p_name), Ref<AnimationNode>());
+
+ return states[p_name].node;
+}
+
+StringName AnimationNodeStateMachine::get_node_name(const Ref<AnimationNode> &p_node) const {
+ for (Map<StringName, State>::Element *E = states.front(); E; E = E->next()) {
+ if (E->get().node == p_node) {
+ return E->key();
}
+ }
- //find the last cost transition
- List<int>::Element *least_cost_transition = NULL;
- float least_cost = 1e20;
+ ERR_FAIL_V(StringName());
+}
- for (List<int>::Element *E = open_list.front(); E; E = E->next()) {
+void AnimationNodeStateMachine::get_child_nodes(List<ChildNode> *r_child_nodes) {
+ Vector<StringName> nodes;
- float cost = cost_map[transitions[E->get()].to].distance;
- cost += states[transitions[E->get()].to]->get_position().distance_to(target_pos);
+ for (Map<StringName, State>::Element *E = states.front(); E; E = E->next()) {
+ nodes.push_back(E->key());
+ }
- if (cost < least_cost) {
- least_cost_transition = E;
- }
+ nodes.sort_custom<StringName::AlphCompare>();
+
+ for (int i = 0; i < nodes.size(); i++) {
+ ChildNode cn;
+ cn.name = nodes[i];
+ cn.node = states[cn.name].node;
+ r_child_nodes->push_back(cn);
+ }
+}
+
+bool AnimationNodeStateMachine::has_node(const StringName &p_name) const {
+ return states.has(p_name);
+}
+void AnimationNodeStateMachine::remove_node(const StringName &p_name) {
+
+ ERR_FAIL_COND(!states.has(p_name));
+
+ {
+ Ref<AnimationNode> node = states[p_name].node;
+ node->disconnect("tree_changed", this, "_tree_changed");
+ }
+
+ states.erase(p_name);
+ //path.erase(p_name);
+
+ for (int i = 0; i < transitions.size(); i++) {
+ if (transitions[i].from == p_name || transitions[i].to == p_name) {
+ transitions.write[i].transition->disconnect("advance_condition_changed", this, "_tree_changed");
+ transitions.remove(i);
+ i--;
}
+ }
- StringName transition_prev = transitions[least_cost_transition->get()].from;
- StringName transition = transitions[least_cost_transition->get()].to;
+ if (start_node == p_name) {
+ start_node = StringName();
+ }
- for (int i = 0; i < transitions.size(); i++) {
- if (transitions[i].from != transition || transitions[i].to == transition_prev) {
- continue; //not interested on those
- }
+ if (end_node == p_name) {
+ end_node = StringName();
+ }
- float distance = states[transitions[i].from]->get_position().distance_to(states[transitions[i].to]->get_position());
- distance *= transitions[i].transition->get_priority();
- distance += cost_map[transitions[i].from].distance;
+ /*if (playing && current == p_name) {
+ stop();
+ }*/
- if (cost_map.has(transitions[i].to)) {
- //oh this was visited already, can we win the cost?
- if (distance < cost_map[transitions[i].to].distance) {
- cost_map[transitions[i].to].distance = distance;
- cost_map[transitions[i].to].prev = transitions[i].from;
- }
- } else {
- //add to open list
- AStarCost ac;
- ac.prev = transitions[i].from;
- ac.distance = distance;
- cost_map[transitions[i].to] = ac;
+ emit_changed();
+ emit_signal("tree_changed");
+}
- open_list.push_back(i);
+void AnimationNodeStateMachine::rename_node(const StringName &p_name, const StringName &p_new_name) {
- if (transitions[i].to == p_state) {
- found_route = true;
- break;
- }
- }
+ ERR_FAIL_COND(!states.has(p_name));
+ ERR_FAIL_COND(states.has(p_new_name));
+
+ states[p_new_name] = states[p_name];
+ states.erase(p_name);
+
+ for (int i = 0; i < transitions.size(); i++) {
+ if (transitions[i].from == p_name) {
+ transitions.write[i].from = p_new_name;
}
- if (found_route) {
- break;
+ if (transitions[i].to == p_name) {
+ transitions.write[i].to = p_new_name;
}
+ }
- open_list.erase(least_cost_transition);
+ if (start_node == p_name) {
+ start_node = p_new_name;
}
- //make path
- StringName at = p_state;
- while (at != current) {
- path.push_back(at);
- at = cost_map[at].prev;
+ if (end_node == p_name) {
+ end_node = p_new_name;
}
- path.invert();
+ /*if (playing && current == p_name) {
+ current = p_new_name;
+ }*/
- return true;
+ //path.clear(); //clear path
+ emit_signal("tree_changed");
}
-void AnimationNodeStateMachine::start(const StringName &p_state) {
+void AnimationNodeStateMachine::get_node_list(List<StringName> *r_nodes) const {
+
+ List<StringName> nodes;
+ for (Map<StringName, State>::Element *E = states.front(); E; E = E->next()) {
+ nodes.push_back(E->key());
+ }
+ nodes.sort_custom<StringName::AlphCompare>();
- ERR_FAIL_COND(!states.has(p_state));
- path.clear();
- current = p_state;
- playing = true;
- play_start = true;
+ for (List<StringName>::Element *E = nodes.front(); E; E = E->next()) {
+ r_nodes->push_back(E->get());
+ }
}
-void AnimationNodeStateMachine::stop() {
- playing = false;
- play_start = false;
- current = StringName();
+
+bool AnimationNodeStateMachine::has_transition(const StringName &p_from, const StringName &p_to) const {
+
+ for (int i = 0; i < transitions.size(); i++) {
+ if (transitions[i].from == p_from && transitions[i].to == p_to)
+ return true;
+ }
+ return false;
}
-bool AnimationNodeStateMachine::is_playing() const {
- return playing;
+int AnimationNodeStateMachine::find_transition(const StringName &p_from, const StringName &p_to) const {
+
+ for (int i = 0; i < transitions.size(); i++) {
+ if (transitions[i].from == p_from && transitions[i].to == p_to)
+ return i;
+ }
+ return -1;
}
-StringName AnimationNodeStateMachine::get_current_node() const {
- if (!playing) {
- return StringName();
+
+void AnimationNodeStateMachine::add_transition(const StringName &p_from, const StringName &p_to, const Ref<AnimationNodeStateMachineTransition> &p_transition) {
+
+ ERR_FAIL_COND(p_from == p_to);
+ ERR_FAIL_COND(!states.has(p_from));
+ ERR_FAIL_COND(!states.has(p_to));
+ ERR_FAIL_COND(p_transition.is_null());
+
+ for (int i = 0; i < transitions.size(); i++) {
+ ERR_FAIL_COND(transitions[i].from == p_from && transitions[i].to == p_to);
}
- return current;
+ Transition tr;
+ tr.from = p_from;
+ tr.to = p_to;
+ tr.transition = p_transition;
+
+ tr.transition->connect("advance_condition_changed", this, "_tree_changed", varray(), CONNECT_REFERENCE_COUNTED);
+
+ transitions.push_back(tr);
+}
+
+Ref<AnimationNodeStateMachineTransition> AnimationNodeStateMachine::get_transition(int p_transition) const {
+ ERR_FAIL_INDEX_V(p_transition, transitions.size(), Ref<AnimationNodeStateMachineTransition>());
+ return transitions[p_transition].transition;
}
+StringName AnimationNodeStateMachine::get_transition_from(int p_transition) const {
+
+ ERR_FAIL_INDEX_V(p_transition, transitions.size(), StringName());
+ return transitions[p_transition].from;
+}
+StringName AnimationNodeStateMachine::get_transition_to(int p_transition) const {
+
+ ERR_FAIL_INDEX_V(p_transition, transitions.size(), StringName());
+ return transitions[p_transition].to;
+}
+
+int AnimationNodeStateMachine::get_transition_count() const {
+
+ return transitions.size();
+}
+void AnimationNodeStateMachine::remove_transition(const StringName &p_from, const StringName &p_to) {
-StringName AnimationNodeStateMachine::get_blend_from_node() const {
- if (!playing) {
- return StringName();
+ for (int i = 0; i < transitions.size(); i++) {
+ if (transitions[i].from == p_from && transitions[i].to == p_to) {
+ transitions.write[i].transition->disconnect("advance_condition_changed", this, "_tree_changed");
+ transitions.remove(i);
+ return;
+ }
}
- return fading_from;
+ /*if (playing) {
+ path.clear();
+ }*/
}
-float AnimationNodeStateMachine::get_current_play_pos() const {
- return pos_current;
+void AnimationNodeStateMachine::remove_transition_by_index(int p_transition) {
+
+ ERR_FAIL_INDEX(p_transition, transitions.size());
+ transitions.write[p_transition].transition->disconnect("advance_condition_changed", this, "_tree_changed");
+ transitions.remove(p_transition);
+ /*if (playing) {
+ path.clear();
+ }*/
}
-float AnimationNodeStateMachine::get_current_length() const {
- return len_current;
+
+void AnimationNodeStateMachine::set_start_node(const StringName &p_node) {
+
+ ERR_FAIL_COND(p_node != StringName() && !states.has(p_node));
+ start_node = p_node;
}
-Vector<StringName> AnimationNodeStateMachine::get_travel_path() const {
- return path;
+String AnimationNodeStateMachine::get_start_node() const {
+
+ return start_node;
+}
+
+void AnimationNodeStateMachine::set_end_node(const StringName &p_node) {
+
+ ERR_FAIL_COND(p_node != StringName() && !states.has(p_node));
+ end_node = p_node;
+}
+
+String AnimationNodeStateMachine::get_end_node() const {
+
+ return end_node;
+}
+
+void AnimationNodeStateMachine::set_graph_offset(const Vector2 &p_offset) {
+ graph_offset = p_offset;
+}
+
+Vector2 AnimationNodeStateMachine::get_graph_offset() const {
+ return graph_offset;
+}
+
+float AnimationNodeStateMachine::process(float p_time, bool p_seek) {
+
+ Ref<AnimationNodeStateMachinePlayback> playback = get_parameter(this->playback);
+ ERR_FAIL_COND_V(playback.is_null(), 0.0);
+
+ return playback->process(this, p_time, p_seek);
}
+
String AnimationNodeStateMachine::get_caption() const {
return "StateMachine";
}
@@ -623,14 +774,8 @@ String AnimationNodeStateMachine::get_caption() const {
void AnimationNodeStateMachine::_notification(int p_what) {
}
-void AnimationNodeStateMachine::set_tree(AnimationTree *p_player) {
-
- AnimationNode::set_tree(p_player);
-
- for (Map<StringName, Ref<AnimationRootNode> >::Element *E = states.front(); E; E = E->next()) {
- Ref<AnimationRootNode> node = E->get();
- node->set_tree(p_player);
- }
+Ref<AnimationNode> AnimationNodeStateMachine::get_child_by_name(const StringName &p_name) {
+ return get_node(p_name);
}
bool AnimationNodeStateMachine::_set(const StringName &p_name, const Variant &p_value) {
@@ -651,7 +796,7 @@ bool AnimationNodeStateMachine::_set(const StringName &p_name, const Variant &p_
if (what == "position") {
if (states.has(node_name)) {
- states[node_name]->set_position(p_value);
+ states[node_name].position = p_value;
}
return true;
}
@@ -687,7 +832,7 @@ bool AnimationNodeStateMachine::_get(const StringName &p_name, Variant &r_ret) c
if (what == "node") {
if (states.has(node_name)) {
- r_ret = states[node_name];
+ r_ret = states[node_name].node;
return true;
}
}
@@ -695,7 +840,7 @@ bool AnimationNodeStateMachine::_get(const StringName &p_name, Variant &r_ret) c
if (what == "position") {
if (states.has(node_name)) {
- r_ret = states[node_name]->get_position();
+ r_ret = states[node_name].position;
return true;
}
}
@@ -727,14 +872,14 @@ bool AnimationNodeStateMachine::_get(const StringName &p_name, Variant &r_ret) c
void AnimationNodeStateMachine::_get_property_list(List<PropertyInfo> *p_list) const {
List<StringName> names;
- for (Map<StringName, Ref<AnimationRootNode> >::Element *E = states.front(); E; E = E->next()) {
+ for (Map<StringName, State>::Element *E = states.front(); E; E = E->next()) {
names.push_back(E->key());
}
names.sort_custom<StringName::AlphCompare>();
for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
String name = E->get();
- p_list->push_back(PropertyInfo(Variant::OBJECT, "states/" + name + "/node", PROPERTY_HINT_RESOURCE_TYPE, "AnimationNode", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, "states/" + name + "/node", PROPERTY_HINT_RESOURCE_TYPE, "AnimationNode", PROPERTY_USAGE_NOEDITOR));
p_list->push_back(PropertyInfo(Variant::VECTOR2, "states/" + name + "/position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
}
@@ -744,16 +889,34 @@ void AnimationNodeStateMachine::_get_property_list(List<PropertyInfo> *p_list) c
p_list->push_back(PropertyInfo(Variant::VECTOR2, "graph_offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
}
+void AnimationNodeStateMachine::set_node_position(const StringName &p_name, const Vector2 &p_position) {
+ ERR_FAIL_COND(!states.has(p_name));
+ states[p_name].position = p_position;
+}
+
+Vector2 AnimationNodeStateMachine::get_node_position(const StringName &p_name) const {
+
+ ERR_FAIL_COND_V(!states.has(p_name), Vector2());
+ return states[p_name].position;
+}
+
+void AnimationNodeStateMachine::_tree_changed() {
+ emit_signal("tree_changed");
+}
+
void AnimationNodeStateMachine::_bind_methods() {
- ClassDB::bind_method(D_METHOD("add_node", "name", "node"), &AnimationNodeStateMachine::add_node);
+ ClassDB::bind_method(D_METHOD("add_node", "name", "node", "position"), &AnimationNodeStateMachine::add_node, DEFVAL(Vector2()));
ClassDB::bind_method(D_METHOD("get_node", "name"), &AnimationNodeStateMachine::get_node);
ClassDB::bind_method(D_METHOD("remove_node", "name"), &AnimationNodeStateMachine::remove_node);
ClassDB::bind_method(D_METHOD("rename_node", "name", "new_name"), &AnimationNodeStateMachine::rename_node);
ClassDB::bind_method(D_METHOD("has_node", "name"), &AnimationNodeStateMachine::has_node);
ClassDB::bind_method(D_METHOD("get_node_name", "node"), &AnimationNodeStateMachine::get_node_name);
- ClassDB::bind_method(D_METHOD("has_transition", "from", "to"), &AnimationNodeStateMachine::add_transition);
+ ClassDB::bind_method(D_METHOD("set_node_position", "name", "position"), &AnimationNodeStateMachine::set_node_position);
+ ClassDB::bind_method(D_METHOD("get_node_position", "name"), &AnimationNodeStateMachine::get_node_position);
+
+ ClassDB::bind_method(D_METHOD("has_transition", "from", "to"), &AnimationNodeStateMachine::has_transition);
ClassDB::bind_method(D_METHOD("add_transition", "from", "to", "transition"), &AnimationNodeStateMachine::add_transition);
ClassDB::bind_method(D_METHOD("get_transition", "idx"), &AnimationNodeStateMachine::get_transition);
ClassDB::bind_method(D_METHOD("get_transition_from", "idx"), &AnimationNodeStateMachine::get_transition_from);
@@ -771,20 +934,10 @@ void AnimationNodeStateMachine::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_graph_offset", "name"), &AnimationNodeStateMachine::set_graph_offset);
ClassDB::bind_method(D_METHOD("get_graph_offset"), &AnimationNodeStateMachine::get_graph_offset);
- ClassDB::bind_method(D_METHOD("travel", "to_node"), &AnimationNodeStateMachine::travel);
- ClassDB::bind_method(D_METHOD("start", "node"), &AnimationNodeStateMachine::start);
- ClassDB::bind_method(D_METHOD("stop"), &AnimationNodeStateMachine::stop);
- ClassDB::bind_method(D_METHOD("is_playing"), &AnimationNodeStateMachine::is_playing);
- ClassDB::bind_method(D_METHOD("get_current_node"), &AnimationNodeStateMachine::get_current_node);
- ClassDB::bind_method(D_METHOD("get_travel_path"), &AnimationNodeStateMachine::get_travel_path);
+ ClassDB::bind_method(D_METHOD("_tree_changed"), &AnimationNodeStateMachine::_tree_changed);
}
AnimationNodeStateMachine::AnimationNodeStateMachine() {
- play_start = false;
-
- playing = false;
- len_current = 0;
-
- fading_time = 0;
+ playback = "playback";
}
diff --git a/scene/animation/animation_node_state_machine.h b/scene/animation/animation_node_state_machine.h
index e7357e09ea..5d633d6334 100644
--- a/scene/animation/animation_node_state_machine.h
+++ b/scene/animation/animation_node_state_machine.h
@@ -15,6 +15,8 @@ public:
private:
SwitchMode switch_mode;
bool auto_advance;
+ StringName advance_condition;
+ StringName advance_condition_name;
float xfade;
bool disabled;
int priority;
@@ -29,6 +31,11 @@ public:
void set_auto_advance(bool p_enable);
bool has_auto_advance() const;
+ void set_advance_condition(const StringName &p_condition);
+ StringName get_advance_condition() const;
+
+ StringName get_advance_condition_name() const;
+
void set_xfade_time(float p_xfade);
float get_xfade_time() const;
@@ -43,39 +50,24 @@ public:
VARIANT_ENUM_CAST(AnimationNodeStateMachineTransition::SwitchMode)
-class AnimationNodeStateMachine : public AnimationRootNode {
-
- GDCLASS(AnimationNodeStateMachine, AnimationRootNode);
+class AnimationNodeStateMachine;
-private:
- Map<StringName, Ref<AnimationRootNode> > states;
+class AnimationNodeStateMachinePlayback : public Resource {
+ GDCLASS(AnimationNodeStateMachinePlayback, Resource);
- struct Transition {
-
- StringName from;
- StringName to;
- Ref<AnimationNodeStateMachineTransition> transition;
- };
+ friend class AnimationNodeStateMachine;
struct AStarCost {
float distance;
StringName prev;
};
- Vector<Transition> transitions;
-
float len_total;
float len_current;
float pos_current;
int loops_current;
- bool play_start;
- StringName start_node;
- StringName end_node;
-
- Vector2 graph_offset;
-
StringName current;
StringName fading_from;
@@ -85,6 +77,63 @@ private:
Vector<StringName> path;
bool playing;
+ StringName start_request;
+ bool start_request_travel;
+ bool stop_request;
+
+ bool _travel(AnimationNodeStateMachine *p_state_machine, const StringName &p_travel);
+
+ float process(AnimationNodeStateMachine *p_state_machine, float p_time, bool p_seek);
+
+protected:
+ static void _bind_methods();
+
+public:
+ void travel(const StringName &p_state);
+ void start(const StringName &p_state);
+ void stop();
+ bool is_playing() const;
+ StringName get_current_node() const;
+ StringName get_blend_from_node() const;
+ Vector<StringName> get_travel_path() const;
+ float get_current_play_pos() const;
+ float get_current_length() const;
+
+ AnimationNodeStateMachinePlayback();
+};
+
+class AnimationNodeStateMachine : public AnimationRootNode {
+
+ GDCLASS(AnimationNodeStateMachine, AnimationRootNode);
+
+private:
+ friend class AnimationNodeStateMachinePlayback;
+
+ struct State {
+ Ref<AnimationRootNode> node;
+ Vector2 position;
+ };
+
+ Map<StringName, State> states;
+
+ struct Transition {
+
+ StringName from;
+ StringName to;
+ Ref<AnimationNodeStateMachineTransition> transition;
+ };
+
+ Vector<Transition> transitions;
+
+ StringName playback;
+
+ StringName start_node;
+ StringName end_node;
+
+ Vector2 graph_offset;
+
+ void _tree_changed();
+
protected:
void _notification(int p_what);
static void _bind_methods();
@@ -94,7 +143,10 @@ protected:
void _get_property_list(List<PropertyInfo> *p_list) const;
public:
- void add_node(const StringName &p_name, Ref<AnimationNode> p_node);
+ virtual void get_parameter_list(List<PropertyInfo> *r_list) const;
+ virtual Variant get_parameter_default_value(const StringName &p_parameter) const;
+
+ void add_node(const StringName &p_name, Ref<AnimationNode> p_node, const Vector2 &p_position = Vector2());
Ref<AnimationNode> get_node(const StringName &p_name) const;
void remove_node(const StringName &p_name);
void rename_node(const StringName &p_name, const StringName &p_new_name);
@@ -102,6 +154,11 @@ public:
StringName get_node_name(const Ref<AnimationNode> &p_node) const;
void get_node_list(List<StringName> *r_nodes) const;
+ void set_node_position(const StringName &p_name, const Vector2 &p_position);
+ Vector2 get_node_position(const StringName &p_name) const;
+
+ virtual void get_child_nodes(List<ChildNode> *r_child_nodes);
+
bool has_transition(const StringName &p_from, const StringName &p_to) const;
int find_transition(const StringName &p_from, const StringName &p_to) const;
void add_transition(const StringName &p_from, const StringName &p_to, const Ref<AnimationNodeStateMachineTransition> &p_transition);
@@ -124,17 +181,7 @@ public:
virtual float process(float p_time, bool p_seek);
virtual String get_caption() const;
- bool travel(const StringName &p_state);
- void start(const StringName &p_state);
- void stop();
- bool is_playing() const;
- StringName get_current_node() const;
- StringName get_blend_from_node() const;
- Vector<StringName> get_travel_path() const;
- float get_current_play_pos() const;
- float get_current_length() const;
-
- virtual void set_tree(AnimationTree *p_player);
+ virtual Ref<AnimationNode> get_child_by_name(const StringName &p_name);
AnimationNodeStateMachine();
};
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp
index eac2c8d0c1..a660665d3f 100644
--- a/scene/animation/animation_player.cpp
+++ b/scene/animation/animation_player.cpp
@@ -233,7 +233,7 @@ void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim) {
for (int i = 0; i < a->get_track_count(); i++) {
- p_anim->node_cache[i] = NULL;
+ p_anim->node_cache.write[i] = NULL;
RES resource;
Vector<StringName> leftover_path;
Node *child = parent->get_node_and_resource(a->track_get_path(i), resource, leftover_path);
@@ -265,12 +265,12 @@ void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim) {
if (node_cache_map.has(key)) {
- p_anim->node_cache[i] = &node_cache_map[key];
+ p_anim->node_cache.write[i] = &node_cache_map[key];
} else {
node_cache_map[key] = TrackNodeCache();
- p_anim->node_cache[i] = &node_cache_map[key];
+ p_anim->node_cache.write[i] = &node_cache_map[key];
p_anim->node_cache[i]->path = a->track_get_path(i);
p_anim->node_cache[i]->node = child;
p_anim->node_cache[i]->resource = resource;
@@ -331,11 +331,7 @@ void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim) {
if (!p_anim->node_cache[i]->bezier_anim.has(a->track_get_path(i).get_concatenated_subnames())) {
TrackNodeCache::BezierAnim ba;
- String path = leftover_path[leftover_path.size() - 1];
- Vector<String> index = path.split(".");
- for (int j = 0; j < index.size(); j++) {
- ba.bezier_property.push_back(index[j]);
- }
+ ba.bezier_property = leftover_path;
ba.object = resource.is_valid() ? (Object *)resource.ptr() : (Object *)child;
ba.owner = p_anim->node_cache[i];
@@ -549,6 +545,12 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
int s = params.size();
ERR_CONTINUE(s > VARIANT_ARG_MAX);
+#ifdef DEBUG_ENABLED
+ if (!nc->node->has_method(method)) {
+ ERR_PRINTS("Invalid method call '" + method + "'. '" + a->get_name() + "' at node '" + get_path() + "'.");
+ }
+#endif
+
if (can_call) {
MessageQueue::get_singleton()->push_call(
nc->node,
@@ -1642,7 +1644,7 @@ void AnimationPlayer::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "current_animation_position", PROPERTY_HINT_NONE, "", 0), "", "get_current_animation_position");
ADD_GROUP("Playback Options", "playback_");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "playback_process_mode", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_animation_process_mode", "get_animation_process_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "playback_process_mode", PROPERTY_HINT_ENUM, "Physics,Idle,Manual"), "set_animation_process_mode", "get_animation_process_mode");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "playback_default_blend_time", PROPERTY_HINT_RANGE, "0,4096,0.01"), "set_default_blend_time", "get_default_blend_time");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playback_active", PROPERTY_HINT_NONE, "", 0), "set_active", "is_active");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "playback_speed", PROPERTY_HINT_RANGE, "-64,64,0.01"), "set_speed_scale", "get_speed_scale");
@@ -1654,6 +1656,7 @@ void AnimationPlayer::_bind_methods() {
BIND_ENUM_CONSTANT(ANIMATION_PROCESS_PHYSICS);
BIND_ENUM_CONSTANT(ANIMATION_PROCESS_IDLE);
+ BIND_ENUM_CONSTANT(ANIMATION_PROCESS_MANUAL);
}
AnimationPlayer::AnimationPlayer() {
diff --git a/scene/animation/animation_player.h b/scene/animation/animation_player.h
index 49c73e54ad..f50b2454ec 100644
--- a/scene/animation/animation_player.h
+++ b/scene/animation/animation_player.h
@@ -65,6 +65,7 @@ public:
enum AnimationProcessMode {
ANIMATION_PROCESS_PHYSICS,
ANIMATION_PROCESS_IDLE,
+ ANIMATION_PROCESS_MANUAL,
};
private:
diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp
index 83ec9f819b..76f0ee9359 100644
--- a/scene/animation/animation_tree.cpp
+++ b/scene/animation/animation_tree.cpp
@@ -5,6 +5,34 @@
#include "scene/scene_string_names.h"
#include "servers/audio/audio_stream.h"
+void AnimationNode::get_parameter_list(List<PropertyInfo> *r_list) const {
+}
+
+Variant AnimationNode::get_parameter_default_value(const StringName &p_parameter) const {
+ return Variant();
+}
+
+void AnimationNode::set_parameter(const StringName &p_name, const Variant &p_value) {
+ ERR_FAIL_COND(!state);
+ ERR_FAIL_COND(!state->tree->property_parent_map.has(base_path));
+ ERR_FAIL_COND(!state->tree->property_parent_map[base_path].has(p_name));
+ StringName path = state->tree->property_parent_map[base_path][p_name];
+
+ state->tree->property_map[path] = p_value;
+}
+
+Variant AnimationNode::get_parameter(const StringName &p_name) const {
+ ERR_FAIL_COND_V(!state, Variant());
+ ERR_FAIL_COND_V(!state->tree->property_parent_map.has(base_path), Variant());
+ ERR_FAIL_COND_V(!state->tree->property_parent_map[base_path].has(p_name), Variant());
+
+ StringName path = state->tree->property_parent_map[base_path][p_name];
+ return state->tree->property_map[path];
+}
+
+void AnimationNode::get_child_nodes(List<ChildNode> *r_child_nodes) {
+}
+
void AnimationNode::blend_animation(const StringName &p_animation, float p_time, float p_delta, bool p_seeked, float p_blend) {
ERR_FAIL_COND(!state);
@@ -14,8 +42,8 @@ void AnimationNode::blend_animation(const StringName &p_animation, float p_time,
if (animation.is_null()) {
- Ref<AnimationNodeBlendTree> btree = get_parent();
- if (btree.is_valid()) {
+ AnimationNodeBlendTree *btree = Object::cast_to<AnimationNodeBlendTree>(parent);
+ if (btree) {
String name = btree->get_node_name(Ref<AnimationNodeAnimation>(this));
make_invalid(vformat(RTR("In node '%s', invalid animation: '%s'."), name, p_animation));
} else {
@@ -37,10 +65,20 @@ void AnimationNode::blend_animation(const StringName &p_animation, float p_time,
state->animation_states.push_back(anim_state);
}
-float AnimationNode::_pre_process(State *p_state, float p_time, bool p_seek) {
+float AnimationNode::_pre_process(const StringName &p_base_path, AnimationNode *p_parent, State *p_state, float p_time, bool p_seek, const Vector<StringName> &p_connections) {
+
+ base_path = p_base_path;
+ parent = p_parent;
+ connections = p_connections;
state = p_state;
+
float t = process(p_time, p_seek);
+
state = NULL;
+ parent = NULL;
+ base_path = StringName();
+ connections.clear();
+
return t;
}
@@ -56,39 +94,39 @@ void AnimationNode::make_invalid(const String &p_reason) {
float AnimationNode::blend_input(int p_input, float p_time, bool p_seek, float p_blend, FilterAction p_filter, bool p_optimize) {
ERR_FAIL_INDEX_V(p_input, inputs.size(), 0);
ERR_FAIL_COND_V(!state, 0);
- ERR_FAIL_COND_V(!get_tree(), 0); //should not happen, but used to catch bugs
- Ref<AnimationNodeBlendTree> tree = get_parent();
+ AnimationNodeBlendTree *blend_tree = Object::cast_to<AnimationNodeBlendTree>(parent);
+ ERR_FAIL_COND_V(!blend_tree, 0);
- if (!tree.is_valid() && get_tree()->get_tree_root().ptr() != this) {
- make_invalid(RTR("Can't blend input because node is not in a tree"));
+ StringName node_name = connections[p_input];
+
+ if (!blend_tree->has_node(node_name)) {
+ String name = blend_tree->get_node_name(Ref<AnimationNode>(this));
+ make_invalid(vformat(RTR("Nothing connected to input '%s' of node '%s'."), get_input_name(p_input), name));
return 0;
}
- ERR_FAIL_COND_V(!tree.is_valid(), 0); //should not happen
+ Ref<AnimationNode> node = blend_tree->get_node(node_name);
- StringName anim_name = inputs[p_input].connected_to;
+ //inputs.write[p_input].last_pass = state->last_pass;
+ float activity=0;
+ float ret = _blend_node(node_name, blend_tree->get_node_connection_array(node_name), NULL, node, p_time, p_seek, p_blend, p_filter, p_optimize, &activity);
- Ref<AnimationNode> node = tree->get_node(anim_name);
+ Vector<AnimationTree::Activity> *activity_ptr = state->tree->input_activity_map.getptr(base_path);
- if (node.is_null()) {
-
- String name = tree->get_node_name(Ref<AnimationNodeAnimation>(this));
- make_invalid(vformat(RTR("Nothing connected to input '%s' of node '%s'."), get_input_name(p_input), name));
- return 0;
+ if (activity_ptr && p_input<activity_ptr->size()) {
+ activity_ptr->write[p_input].last_pass = state->last_pass;
+ activity_ptr->write[p_input].activity = activity;
}
-
- inputs[p_input].last_pass = state->last_pass;
-
- return _blend_node(node, p_time, p_seek, p_blend, p_filter, p_optimize, &inputs[p_input].activity);
+ return ret;
}
-float AnimationNode::blend_node(Ref<AnimationNode> p_node, float p_time, bool p_seek, float p_blend, FilterAction p_filter, bool p_optimize) {
+float AnimationNode::blend_node(const StringName &p_sub_path, Ref<AnimationNode> p_node, float p_time, bool p_seek, float p_blend, FilterAction p_filter, bool p_optimize) {
- return _blend_node(p_node, p_time, p_seek, p_blend, p_filter, p_optimize);
+ return _blend_node(p_sub_path, Vector<StringName>(), this, p_node, p_time, p_seek, p_blend, p_filter, p_optimize);
}
-float AnimationNode::_blend_node(Ref<AnimationNode> p_node, float p_time, bool p_seek, float p_blend, FilterAction p_filter, bool p_optimize, float *r_max) {
+float AnimationNode::_blend_node(const StringName &p_subpath, const Vector<StringName> &p_connections, AnimationNode *p_new_parent, Ref<AnimationNode> p_node, float p_time, bool p_seek, float p_blend, FilterAction p_filter, bool p_optimize, float *r_max) {
ERR_FAIL_COND_V(!p_node.is_valid(), 0);
ERR_FAIL_COND_V(!state, 0);
@@ -189,7 +227,19 @@ float AnimationNode::_blend_node(Ref<AnimationNode> p_node, float p_time, bool p
if (!p_seek && p_optimize && !any_valid) //pointless to go on, all are zero
return 0;
- return p_node->_pre_process(state, p_time, p_seek);
+ String new_path;
+ AnimationNode *new_parent;
+
+ //this is the slowest part of processing, but as strings process in powers of 2, and the paths always exist, it will not result in that many allocations
+ if (p_new_parent) {
+ new_parent = p_new_parent;
+ new_path = String(base_path) + String(p_subpath) + "/";
+ } else {
+ ERR_FAIL_COND_V(!parent, 0);
+ new_parent = parent;
+ new_path = String(parent->base_path) + String(p_subpath) + "/";
+ }
+ return p_node->_pre_process(new_path, new_parent, state, p_time, p_seek, p_connections);
}
int AnimationNode::get_input_count() const {
@@ -201,29 +251,6 @@ String AnimationNode::get_input_name(int p_input) {
return inputs[p_input].name;
}
-float AnimationNode::get_input_activity(int p_input) const {
-
- ERR_FAIL_INDEX_V(p_input, inputs.size(), 0);
- if (!get_tree())
- return 0;
-
- if (get_tree()->get_last_process_pass() != inputs[p_input].last_pass) {
- return 0;
- }
- return inputs[p_input].activity;
-}
-StringName AnimationNode::get_input_connection(int p_input) {
-
- ERR_FAIL_INDEX_V(p_input, inputs.size(), StringName());
- return inputs[p_input].connected_to;
-}
-
-void AnimationNode::set_input_connection(int p_input, const StringName &p_connection) {
-
- ERR_FAIL_INDEX(p_input, inputs.size());
- inputs[p_input].connected_to = p_connection;
-}
-
String AnimationNode::get_caption() const {
if (get_script_instance()) {
@@ -239,8 +266,6 @@ void AnimationNode::add_input(const String &p_name) {
Input input;
ERR_FAIL_COND(p_name.find(".") != -1 || p_name.find("/") != -1);
input.name = p_name;
- input.activity = 0;
- input.last_pass = 0;
inputs.push_back(input);
emit_changed();
}
@@ -248,7 +273,7 @@ void AnimationNode::add_input(const String &p_name) {
void AnimationNode::set_input_name(int p_input, const String &p_name) {
ERR_FAIL_INDEX(p_input, inputs.size());
ERR_FAIL_COND(p_name.find(".") != -1 || p_name.find("/") != -1);
- inputs[p_input].name = p_name;
+ inputs.write[p_input].name = p_name;
emit_changed();
}
@@ -258,35 +283,6 @@ void AnimationNode::remove_input(int p_index) {
emit_changed();
}
-void AnimationNode::_set_parent(Object *p_parent) {
- set_parent(Object::cast_to<AnimationNode>(p_parent));
-}
-
-void AnimationNode::set_parent(AnimationNode *p_parent) {
- parent = p_parent; //do not use ref because parent contains children
- if (get_script_instance()) {
- get_script_instance()->call("_parent_set", p_parent);
- }
-}
-
-Ref<AnimationNode> AnimationNode::get_parent() const {
- if (parent) {
- return Ref<AnimationNode>(parent);
- }
-
- return Ref<AnimationNode>();
-}
-
-AnimationTree *AnimationNode::get_tree() const {
-
- return player;
-}
-
-AnimationPlayer *AnimationNode::get_player() const {
- ERR_FAIL_COND_V(!state, NULL);
- return state->player;
-}
-
float AnimationNode::process(float p_time, bool p_seek) {
if (get_script_instance()) {
@@ -320,22 +316,6 @@ bool AnimationNode::has_filter() const {
return false;
}
-void AnimationNode::set_position(const Vector2 &p_position) {
- position = p_position;
-}
-
-Vector2 AnimationNode::get_position() const {
- return position;
-}
-
-void AnimationNode::set_tree(AnimationTree *p_player) {
-
- if (player != NULL && p_player == NULL) {
- emit_signal("removed_from_graph");
- }
- player = p_player;
-}
-
Array AnimationNode::_get_filters() const {
Array paths;
@@ -361,12 +341,14 @@ void AnimationNode::_validate_property(PropertyInfo &property) const {
}
}
+Ref<AnimationNode> AnimationNode::get_child_by_name(const StringName &p_name) {
+ return Ref<AnimationNode>();
+}
+
void AnimationNode::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_input_count"), &AnimationNode::get_input_count);
ClassDB::bind_method(D_METHOD("get_input_name", "input"), &AnimationNode::get_input_name);
- ClassDB::bind_method(D_METHOD("get_input_connection", "input"), &AnimationNode::get_input_connection);
- ClassDB::bind_method(D_METHOD("get_input_activity", "input"), &AnimationNode::get_input_activity);
ClassDB::bind_method(D_METHOD("add_input", "name"), &AnimationNode::add_input);
ClassDB::bind_method(D_METHOD("remove_input", "index"), &AnimationNode::remove_input);
@@ -377,19 +359,15 @@ void AnimationNode::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_filter_enabled", "enable"), &AnimationNode::set_filter_enabled);
ClassDB::bind_method(D_METHOD("is_filter_enabled"), &AnimationNode::is_filter_enabled);
- ClassDB::bind_method(D_METHOD("set_position", "position"), &AnimationNode::set_position);
- ClassDB::bind_method(D_METHOD("get_position"), &AnimationNode::get_position);
-
ClassDB::bind_method(D_METHOD("_set_filters", "filters"), &AnimationNode::_set_filters);
ClassDB::bind_method(D_METHOD("_get_filters"), &AnimationNode::_get_filters);
ClassDB::bind_method(D_METHOD("blend_animation", "animation", "time", "delta", "seeked", "blend"), &AnimationNode::blend_animation);
- ClassDB::bind_method(D_METHOD("blend_node", "node", "time", "seek", "blend", "filter", "optimize"), &AnimationNode::blend_node, DEFVAL(FILTER_IGNORE), DEFVAL(true));
+ ClassDB::bind_method(D_METHOD("blend_node", "name", "node", "time", "seek", "blend", "filter", "optimize"), &AnimationNode::blend_node, DEFVAL(FILTER_IGNORE), DEFVAL(true));
ClassDB::bind_method(D_METHOD("blend_input", "input_index", "time", "seek", "blend", "filter", "optimize"), &AnimationNode::blend_input, DEFVAL(FILTER_IGNORE), DEFVAL(true));
- ClassDB::bind_method(D_METHOD("set_parent", "parent"), &AnimationNode::_set_parent);
- ClassDB::bind_method(D_METHOD("get_parent"), &AnimationNode::get_parent);
- ClassDB::bind_method(D_METHOD("get_tree"), &AnimationNode::get_tree);
+ ClassDB::bind_method(D_METHOD("set_parameter", "name", "value"), &AnimationNode::set_parameter);
+ ClassDB::bind_method(D_METHOD("get_parameter", "name"), &AnimationNode::get_parameter);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "filter_enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_filter_enabled", "is_filter_enabled");
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "filters", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_filters", "_get_filters");
@@ -397,9 +375,11 @@ void AnimationNode::_bind_methods() {
BIND_VMETHOD(MethodInfo("process", PropertyInfo(Variant::REAL, "time"), PropertyInfo(Variant::BOOL, "seek")));
BIND_VMETHOD(MethodInfo(Variant::STRING, "get_caption"));
BIND_VMETHOD(MethodInfo(Variant::STRING, "has_filter"));
- BIND_VMETHOD(MethodInfo("_parent_set", PropertyInfo(Variant::OBJECT, "parent")));
ADD_SIGNAL(MethodInfo("removed_from_graph"));
+
+ ADD_SIGNAL(MethodInfo("tree_changed"));
+
BIND_ENUM_CONSTANT(FILTER_IGNORE);
BIND_ENUM_CONSTANT(FILTER_PASS);
BIND_ENUM_CONSTANT(FILTER_STOP);
@@ -410,8 +390,6 @@ AnimationNode::AnimationNode() {
state = NULL;
parent = NULL;
- player = NULL;
- set_local_to_scene(true);
filter_enabled = false;
}
@@ -420,18 +398,17 @@ AnimationNode::AnimationNode() {
void AnimationTree::set_tree_root(const Ref<AnimationNode> &p_root) {
if (root.is_valid()) {
- root->set_tree(NULL);
- }
- if (p_root.is_valid()) {
- ERR_EXPLAIN("root node already set to another player");
- ERR_FAIL_COND(p_root->player);
+ root->disconnect("tree_changed", this, "_tree_changed");
}
+
root = p_root;
if (root.is_valid()) {
- root->set_tree(this);
+ root->connect("tree_changed", this, "_tree_changed");
}
+ properties_dirty = true;
+
update_configuration_warning();
}
@@ -699,7 +676,10 @@ void AnimationTree::_clear_caches() {
void AnimationTree::_process_graph(float p_delta) {
+ _update_properties(); //if properties need updating, update them
+
//check all tracks, see if they need modification
+
root_motion_transform = Transform();
if (!root.is_valid()) {
@@ -741,6 +721,7 @@ void AnimationTree::_process_graph(float p_delta) {
state.valid = true;
state.player = player;
state.last_pass = process_pass;
+ state.tree = this;
// root source blends
@@ -757,11 +738,11 @@ void AnimationTree::_process_graph(float p_delta) {
if (started) {
//if started, seek
- root->_pre_process(&state, 0, true);
+ root->_pre_process(SceneStringNames::get_singleton()->parameters_base_path, NULL, &state, 0, true, Vector<StringName>());
started = false;
}
- root->_pre_process(&state, p_delta, false);
+ root->_pre_process(SceneStringNames::get_singleton()->parameters_base_path, NULL, &state, p_delta, false, Vector<StringName>());
}
if (!state.valid) {
@@ -877,7 +858,7 @@ void AnimationTree::_process_graph(float p_delta) {
continue;
t->loc = t->loc.linear_interpolate(loc, blend);
- if (t->rot_blend_accum==0) {
+ if (t->rot_blend_accum == 0) {
t->rot = rot;
t->rot_blend_accum = blend;
} else {
@@ -1052,7 +1033,7 @@ void AnimationTree::_process_graph(float p_delta) {
float len = t->start > time ? (a->get_length() - t->start) + time : time - t->start;
if (len > t->len) {
- stop=true;
+ stop = true;
}
}
@@ -1065,7 +1046,7 @@ void AnimationTree::_process_graph(float p_delta) {
}
}
- float db = Math::linear2db(MAX(blend,0.00001));
+ float db = Math::linear2db(MAX(blend, 0.00001));
if (t->object->has_method("set_unit_db")) {
t->object->call("set_unit_db", db);
} else {
@@ -1199,6 +1180,11 @@ void AnimationTree::_process_graph(float p_delta) {
}
}
+void AnimationTree::advance(float p_time) {
+
+ _process_graph(p_time);
+}
+
void AnimationTree::_notification(int p_what) {
if (active && p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS && process_mode == ANIMATION_PROCESS_PHYSICS) {
@@ -1292,6 +1278,149 @@ Transform AnimationTree::get_root_motion_transform() const {
return root_motion_transform;
}
+void AnimationTree::_tree_changed() {
+ if (properties_dirty) {
+ return;
+ }
+
+ call_deferred("_update_properties");
+ properties_dirty = true;
+}
+
+void AnimationTree::_update_properties_for_node(const String &p_base_path, Ref<AnimationNode> node) {
+
+ if (!property_parent_map.has(p_base_path)) {
+ property_parent_map[p_base_path] = HashMap<StringName, StringName>();
+ }
+
+ if (node->get_input_count() && !input_activity_map.has(p_base_path)) {
+
+ Vector<Activity> activity;
+ for(int i=0;i<node->get_input_count();i++) {
+ Activity a;
+ a.last_pass=0;
+ activity.push_back(a);
+ }
+ input_activity_map[p_base_path] = activity;
+ input_activity_map_get[String(p_base_path).substr(0,String(p_base_path).length()-1)]=&input_activity_map[p_base_path];
+ }
+
+ List<PropertyInfo> plist;
+ node->get_parameter_list(&plist);
+ for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
+ PropertyInfo pinfo = E->get();
+
+ StringName key = pinfo.name;
+
+ if (!property_map.has(p_base_path + key)) {
+ property_map[p_base_path + key] = node->get_parameter_default_value(key);
+ }
+
+ property_parent_map[p_base_path][key] = p_base_path + key;
+
+ pinfo.name = p_base_path + key;
+ properties.push_back(pinfo);
+ }
+
+ List<AnimationNode::ChildNode> children;
+ node->get_child_nodes(&children);
+
+ for (List<AnimationNode::ChildNode>::Element *E = children.front(); E; E = E->next()) {
+ _update_properties_for_node(p_base_path + E->get().name + "/", E->get().node);
+ }
+}
+
+void AnimationTree::_update_properties() {
+ if (!properties_dirty) {
+ return;
+ }
+
+ properties.clear();
+ property_parent_map.clear();
+ input_activity_map.clear();
+ input_activity_map_get.clear();
+
+ if (root.is_valid()) {
+ _update_properties_for_node(SceneStringNames::get_singleton()->parameters_base_path, root);
+ }
+
+ properties_dirty = false;
+
+ _change_notify();
+}
+
+bool AnimationTree::_set(const StringName &p_name, const Variant &p_value) {
+ if (properties_dirty) {
+ _update_properties();
+ }
+
+ if (property_map.has(p_name)) {
+ property_map[p_name] = p_value;
+#ifdef TOOLS_ENABLED
+ _change_notify(p_name.operator String().utf8().get_data());
+#endif
+ return true;
+ }
+
+ return false;
+}
+
+bool AnimationTree::_get(const StringName &p_name, Variant &r_ret) const {
+ if (properties_dirty) {
+ const_cast<AnimationTree *>(this)->_update_properties();
+ }
+
+ if (property_map.has(p_name)) {
+ r_ret = property_map[p_name];
+ return true;
+ }
+
+ return false;
+}
+void AnimationTree::_get_property_list(List<PropertyInfo> *p_list) const {
+ if (properties_dirty) {
+ const_cast<AnimationTree *>(this)->_update_properties();
+ }
+
+ for (const List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) {
+ p_list->push_back(E->get());
+ }
+}
+
+void AnimationTree::rename_parameter(const String &p_base, const String &p_new_base) {
+
+ //rename values first
+ for (const List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) {
+ if (E->get().name.begins_with(p_base)) {
+ String new_name = E->get().name.replace_first(p_base, p_new_base);
+ property_map[new_name] = property_map[E->get().name];
+ }
+ }
+
+ //update tree second
+ properties_dirty = true;
+ _update_properties();
+}
+
+float AnimationTree::get_connection_activity(const StringName& p_path,int p_connection) const {
+
+ if (!input_activity_map_get.has(p_path)) {
+ return 0;
+ }
+ const Vector<Activity> *activity = input_activity_map_get[p_path];
+
+ if (!activity || p_connection<0 || p_connection>=activity->size()) {
+ return 0;
+ }
+
+ if ((*activity)[p_connection].last_pass != process_pass) {
+ return 0;
+ }
+
+ return (*activity)[p_connection].activity;
+}
+
+
void AnimationTree::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_active", "active"), &AnimationTree::set_active);
ClassDB::bind_method(D_METHOD("is_active"), &AnimationTree::is_active);
@@ -1310,16 +1439,25 @@ void AnimationTree::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_root_motion_transform"), &AnimationTree::get_root_motion_transform);
+ ClassDB::bind_method(D_METHOD("_tree_changed"), &AnimationTree::_tree_changed);
+ ClassDB::bind_method(D_METHOD("_update_properties"), &AnimationTree::_update_properties);
+ ClassDB::bind_method(D_METHOD("rename_parameter", "old_name", "new_name"), &AnimationTree::rename_parameter);
+
+ ClassDB::bind_method(D_METHOD("advance", "delta"), &AnimationTree::advance);
ClassDB::bind_method(D_METHOD("_node_removed"), &AnimationTree::_node_removed);
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "tree_root", PROPERTY_HINT_RESOURCE_TYPE, "AnimationRootNode", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE), "set_tree_root", "get_tree_root");
- ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "anim_player",PROPERTY_HINT_NODE_PATH_VALID_TYPES,"AnimationPlayer"), "set_animation_player", "get_animation_player");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "tree_root", PROPERTY_HINT_RESOURCE_TYPE, "AnimationRootNode"), "set_tree_root", "get_tree_root");
+ ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "anim_player", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "AnimationPlayer"), "set_animation_player", "get_animation_player");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "active"), "set_active", "is_active");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_process_mode", "get_process_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Physics,Idle,Manual"), "set_process_mode", "get_process_mode");
ADD_GROUP("Root Motion", "root_motion_");
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "root_motion_track"), "set_root_motion_track", "get_root_motion_track");
+
+ BIND_ENUM_CONSTANT(ANIMATION_PROCESS_PHYSICS);
+ BIND_ENUM_CONSTANT(ANIMATION_PROCESS_IDLE);
+ BIND_ENUM_CONSTANT(ANIMATION_PROCESS_MANUAL);
}
AnimationTree::AnimationTree() {
@@ -1329,10 +1467,8 @@ AnimationTree::AnimationTree() {
cache_valid = false;
setup_pass = 1;
started = true;
+ properties_dirty = true;
}
AnimationTree::~AnimationTree() {
- if (root.is_valid()) {
- root->player = NULL;
- }
}
diff --git a/scene/animation/animation_tree.h b/scene/animation/animation_tree.h
index 540c36437a..70f3932f21 100644
--- a/scene/animation/animation_tree.h
+++ b/scene/animation/animation_tree.h
@@ -23,9 +23,6 @@ public:
struct Input {
String name;
- StringName connected_to;
- float activity;
- uint64_t last_pass;
};
Vector<Input> inputs;
@@ -51,30 +48,33 @@ public:
List<AnimationState> animation_states;
bool valid;
AnimationPlayer *player;
+ AnimationTree *tree;
String invalid_reasons;
uint64_t last_pass;
};
Vector<float> blends;
State *state;
- float _pre_process(State *p_state, float p_time, bool p_seek);
+
+ float _pre_process(const StringName &p_base_path, AnimationNode *p_parent, State *p_state, float p_time, bool p_seek, const Vector<StringName> &p_connections);
void _pre_update_animations(HashMap<NodePath, int> *track_map);
- Vector2 position;
+ //all this is temporary
+ StringName base_path;
+ Vector<StringName> connections;
AnimationNode *parent;
- AnimationTree *player;
-
- float _blend_node(Ref<AnimationNode> p_node, float p_time, bool p_seek, float p_blend, FilterAction p_filter = FILTER_IGNORE, bool p_optimize = true, float *r_max = NULL);
HashMap<NodePath, bool> filter;
bool filter_enabled;
Array _get_filters() const;
void _set_filters(const Array &p_filters);
+ friend class AnimationNodeBlendTree;
+ float _blend_node(const StringName &p_subpath, const Vector<StringName> &p_connections, AnimationNode *p_new_parent, Ref<AnimationNode> p_node, float p_time, bool p_seek, float p_blend, FilterAction p_filter = FILTER_IGNORE, bool p_optimize = true, float *r_max = NULL);
protected:
void blend_animation(const StringName &p_animation, float p_time, float p_delta, bool p_seeked, float p_blend);
- float blend_node(Ref<AnimationNode> p_node, float p_time, bool p_seek, float p_blend, FilterAction p_filter = FILTER_IGNORE, bool p_optimize = true);
+ float blend_node(const StringName &p_sub_path, Ref<AnimationNode> p_node, float p_time, bool p_seek, float p_blend, FilterAction p_filter = FILTER_IGNORE, bool p_optimize = true);
float blend_input(int p_input, float p_time, bool p_seek, float p_blend, FilterAction p_filter = FILTER_IGNORE, bool p_optimize = true);
void make_invalid(const String &p_reason);
@@ -85,20 +85,24 @@ protected:
void _set_parent(Object *p_parent);
public:
- void set_parent(AnimationNode *p_parent);
- Ref<AnimationNode> get_parent() const;
- virtual void set_tree(AnimationTree *p_player);
- AnimationTree *get_tree() const;
- AnimationPlayer *get_player() const;
+ virtual void get_parameter_list(List<PropertyInfo> *r_list) const;
+ virtual Variant get_parameter_default_value(const StringName &p_parameter) const;
+
+ void set_parameter(const StringName &p_name, const Variant &p_value);
+ Variant get_parameter(const StringName &p_name) const;
+
+ struct ChildNode {
+ StringName name;
+ Ref<AnimationNode> node;
+ };
+
+ virtual void get_child_nodes(List<ChildNode> *r_child_nodes);
virtual float process(float p_time, bool p_seek);
virtual String get_caption() const;
int get_input_count() const;
String get_input_name(int p_input);
- StringName get_input_connection(int p_input);
- void set_input_connection(int p_input, const StringName &p_connection);
- float get_input_activity(int p_input) const;
void add_input(const String &p_name);
void set_input_name(int p_input, const String &p_name);
@@ -112,8 +116,7 @@ public:
virtual bool has_filter() const;
- void set_position(const Vector2 &p_position);
- Vector2 get_position() const;
+ virtual Ref<AnimationNode> get_child_by_name(const StringName &p_name);
AnimationNode();
};
@@ -133,6 +136,7 @@ public:
enum AnimationProcessMode {
ANIMATION_PROCESS_PHYSICS,
ANIMATION_PROCESS_IDLE,
+ ANIMATION_PROCESS_MANUAL,
};
private:
@@ -244,7 +248,29 @@ private:
NodePath root_motion_track;
Transform root_motion_transform;
+ friend class AnimationNode;
+ bool properties_dirty;
+ void _tree_changed();
+ void _update_properties();
+ List<PropertyInfo> properties;
+ HashMap<StringName, HashMap<StringName, StringName> > property_parent_map;
+ HashMap<StringName, Variant> property_map;
+
+ struct Activity {
+ uint64_t last_pass;
+ float activity;
+ };
+
+ HashMap<StringName, Vector<Activity> > input_activity_map;
+ HashMap<StringName, Vector<Activity> *> input_activity_map_get;
+
+ void _update_properties_for_node(const String &p_base_path, Ref<AnimationNode> node);
+
protected:
+ bool _set(const StringName &p_name, const Variant &p_value);
+ bool _get(const StringName &p_name, Variant &r_ret) const;
+ void _get_property_list(List<PropertyInfo> *p_list) const;
+
void _notification(int p_what);
static void _bind_methods();
@@ -271,6 +297,11 @@ public:
Transform get_root_motion_transform() const;
+ float get_connection_activity(const StringName &p_path, int p_connection) const;
+ void advance(float p_time);
+
+ void rename_parameter(const String &p_base, const String &p_new_base);
+
uint64_t get_last_process_pass() const;
AnimationTree();
~AnimationTree();
diff --git a/scene/animation/animation_tree_player.cpp b/scene/animation/animation_tree_player.cpp
index 026215508b..179f5d9698 100644
--- a/scene/animation/animation_tree_player.cpp
+++ b/scene/animation/animation_tree_player.cpp
@@ -1152,7 +1152,7 @@ void AnimationTreePlayer::transition_node_set_input_auto_advance(const StringNam
GET_NODE(NODE_TRANSITION, TransitionNode);
ERR_FAIL_INDEX(p_input, n->input_data.size());
- n->input_data[p_input].auto_advance = p_auto_advance;
+ n->input_data.write[p_input].auto_advance = p_auto_advance;
}
void AnimationTreePlayer::transition_node_set_xfade_time(const StringName &p_node, float p_time) {
@@ -1365,7 +1365,7 @@ void AnimationTreePlayer::remove_node(const StringName &p_node) {
for (int i = 0; i < nb->inputs.size(); i++) {
if (nb->inputs[i].node == p_node)
- nb->inputs[i].node = StringName();
+ nb->inputs.write[i].node = StringName();
}
}
@@ -1426,11 +1426,11 @@ Error AnimationTreePlayer::connect_nodes(const StringName &p_src_node, const Str
for (int i = 0; i < nb->inputs.size(); i++) {
if (nb->inputs[i].node == p_src_node)
- nb->inputs[i].node = StringName();
+ nb->inputs.write[i].node = StringName();
}
}
- dst->inputs[p_dst_input].node = p_src_node;
+ dst->inputs.write[p_dst_input].node = p_src_node;
_clear_cycle_test();
@@ -1463,7 +1463,7 @@ void AnimationTreePlayer::disconnect_nodes(const StringName &p_node, int p_input
NodeBase *dst = node_map[p_node];
ERR_FAIL_INDEX(p_input, dst->inputs.size());
- dst->inputs[p_input].node = StringName();
+ dst->inputs.write[p_input].node = StringName();
last_error = CONNECT_INCOMPLETE;
dirty_caches = true;
}
@@ -1703,7 +1703,7 @@ Error AnimationTreePlayer::node_rename(const StringName &p_node, const StringNam
for (int i = 0; i < nb->inputs.size(); i++) {
if (nb->inputs[i].node == p_node) {
- nb->inputs[i].node = p_new_name;
+ nb->inputs.write[i].node = p_new_name;
}
}
}
diff --git a/scene/animation/skeleton_ik.cpp b/scene/animation/skeleton_ik.cpp
new file mode 100644
index 0000000000..9b1cb1369a
--- /dev/null
+++ b/scene/animation/skeleton_ik.cpp
@@ -0,0 +1,555 @@
+/*************************************************************************/
+/* skeleton_ik.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* 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. */
+/*************************************************************************/
+
+/**
+ * @author AndreaCatania
+ */
+
+#include "skeleton_ik.h"
+
+#ifndef _3D_DISABLED
+
+FabrikInverseKinematic::ChainItem *FabrikInverseKinematic::ChainItem::find_child(const BoneId p_bone_id) {
+ for (int i = childs.size() - 1; 0 <= i; --i) {
+ if (p_bone_id == childs[i].bone) {
+ return &childs.write[i];
+ }
+ }
+ return NULL;
+}
+
+FabrikInverseKinematic::ChainItem *FabrikInverseKinematic::ChainItem::add_child(const BoneId p_bone_id) {
+ const int infant_child_id = childs.size();
+ childs.resize(infant_child_id + 1);
+ childs.write[infant_child_id].bone = p_bone_id;
+ childs.write[infant_child_id].parent_item = this;
+ return &childs.write[infant_child_id];
+}
+
+/// Build a chain that starts from the root to tip
+void FabrikInverseKinematic::build_chain(Task *p_task, bool p_force_simple_chain) {
+
+ ERR_FAIL_COND(-1 == p_task->root_bone);
+
+ Chain &chain(p_task->chain);
+
+ chain.tips.resize(p_task->end_effectors.size());
+ chain.chain_root.bone = p_task->root_bone;
+ chain.chain_root.initial_transform = p_task->skeleton->get_bone_global_pose(chain.chain_root.bone);
+ chain.chain_root.current_pos = chain.chain_root.initial_transform.origin;
+ chain.chain_root.pb = p_task->skeleton->get_physical_bone(chain.chain_root.bone);
+ chain.middle_chain_item = NULL;
+
+ // Holds all IDs that are composing a single chain in reverse order
+ Vector<BoneId> chain_ids;
+ // This is used to know the chain size
+ int sub_chain_size;
+ // Resize only one time in order to fit all joints for performance reason
+ chain_ids.resize(p_task->skeleton->get_bone_count());
+
+ for (int x = p_task->end_effectors.size() - 1; 0 <= x; --x) {
+
+ const EndEffector *ee(&p_task->end_effectors[x]);
+ ERR_FAIL_COND(p_task->root_bone >= ee->tip_bone);
+ ERR_FAIL_INDEX(ee->tip_bone, p_task->skeleton->get_bone_count());
+
+ sub_chain_size = 0;
+ // Picks all IDs that composing a single chain in reverse order (except the root)
+ BoneId chain_sub_tip(ee->tip_bone);
+ while (chain_sub_tip > p_task->root_bone) {
+
+ chain_ids.write[sub_chain_size++] = chain_sub_tip;
+ chain_sub_tip = p_task->skeleton->get_bone_parent(chain_sub_tip);
+ }
+
+ BoneId middle_chain_item_id = (((float)sub_chain_size) * 0.5);
+
+ // Build chain by reading chain ids in reverse order
+ // For each chain item id will be created a ChainItem if doesn't exists
+ ChainItem *sub_chain(&chain.chain_root);
+ for (int i = sub_chain_size - 1; 0 <= i; --i) {
+
+ ChainItem *child_ci(sub_chain->find_child(chain_ids[i]));
+ if (!child_ci) {
+
+ child_ci = sub_chain->add_child(chain_ids[i]);
+
+ child_ci->pb = p_task->skeleton->get_physical_bone(child_ci->bone);
+
+ child_ci->initial_transform = p_task->skeleton->get_bone_global_pose(child_ci->bone);
+ child_ci->current_pos = child_ci->initial_transform.origin;
+
+ if (child_ci->parent_item) {
+ child_ci->length = (child_ci->current_pos - child_ci->parent_item->current_pos).length();
+ }
+ }
+
+ sub_chain = child_ci;
+
+ if (middle_chain_item_id == i) {
+ chain.middle_chain_item = child_ci;
+ }
+ }
+
+ if (!middle_chain_item_id)
+ chain.middle_chain_item = NULL;
+
+ // Initialize current tip
+ chain.tips.write[x].chain_item = sub_chain;
+ chain.tips.write[x].end_effector = ee;
+
+ if (p_force_simple_chain) {
+ // NOTE:
+ // This is an "hack" that force to create only one tip per chain since the solver of multi tip (end effector)
+ // is not yet created.
+ // Remove this code when this is done
+ break;
+ }
+ }
+}
+
+void FabrikInverseKinematic::update_chain(const Skeleton *p_sk, ChainItem *p_chain_item) {
+
+ if (!p_chain_item)
+ return;
+
+ p_chain_item->initial_transform = p_sk->get_bone_global_pose(p_chain_item->bone);
+ p_chain_item->current_pos = p_chain_item->initial_transform.origin;
+
+ for (int i = p_chain_item->childs.size() - 1; 0 <= i; --i) {
+ update_chain(p_sk, &p_chain_item->childs.write[i]);
+ }
+}
+
+void FabrikInverseKinematic::solve_simple(Task *p_task, bool p_solve_magnet) {
+
+ real_t distance_to_goal(1e4);
+ real_t previous_distance_to_goal(0);
+ int can_solve(p_task->max_iterations);
+ while (distance_to_goal > p_task->min_distance && Math::abs(previous_distance_to_goal - distance_to_goal) > 0.005 && can_solve) {
+ previous_distance_to_goal = distance_to_goal;
+ --can_solve;
+
+ solve_simple_backwards(p_task->chain, p_solve_magnet);
+ solve_simple_forwards(p_task->chain, p_solve_magnet);
+
+ distance_to_goal = (p_task->chain.tips[0].chain_item->current_pos - p_task->chain.tips[0].end_effector->goal_transform.origin).length();
+ }
+}
+
+void FabrikInverseKinematic::solve_simple_backwards(Chain &r_chain, bool p_solve_magnet) {
+
+ if (p_solve_magnet && !r_chain.middle_chain_item) {
+ return;
+ }
+
+ Vector3 goal;
+ ChainItem *sub_chain_tip;
+ if (p_solve_magnet) {
+ goal = r_chain.magnet_position;
+ sub_chain_tip = r_chain.middle_chain_item;
+ } else {
+ goal = r_chain.tips[0].end_effector->goal_transform.origin;
+ sub_chain_tip = r_chain.tips[0].chain_item;
+ }
+
+ while (sub_chain_tip) {
+ sub_chain_tip->current_pos = goal;
+
+ if (sub_chain_tip->parent_item) {
+ // Not yet in the chain root
+ // So calculate next goal location
+
+ const Vector3 look_parent((sub_chain_tip->parent_item->current_pos - sub_chain_tip->current_pos).normalized());
+ goal = sub_chain_tip->current_pos + (look_parent * sub_chain_tip->length);
+
+ // [TODO] Constraints goes here
+ }
+
+ sub_chain_tip = sub_chain_tip->parent_item;
+ }
+}
+
+void FabrikInverseKinematic::solve_simple_forwards(Chain &r_chain, bool p_solve_magnet) {
+
+ if (p_solve_magnet && !r_chain.middle_chain_item) {
+ return;
+ }
+
+ ChainItem *sub_chain_root(&r_chain.chain_root);
+ Vector3 origin(r_chain.chain_root.initial_transform.origin);
+
+ while (sub_chain_root) { // Reach the tip
+ sub_chain_root->current_pos = origin;
+
+ if (!sub_chain_root->childs.empty()) {
+
+ ChainItem &child(sub_chain_root->childs.write[0]);
+
+ // Is not tip
+ // So calculate next origin location
+
+ // Look child
+ sub_chain_root->current_ori = (child.current_pos - sub_chain_root->current_pos).normalized();
+ origin = sub_chain_root->current_pos + (sub_chain_root->current_ori * child.length);
+
+ // [TODO] Constraints goes here
+
+ if (p_solve_magnet && sub_chain_root == r_chain.middle_chain_item) {
+ // In case of magnet solving this is the tip
+ sub_chain_root = NULL;
+ } else {
+ sub_chain_root = &child;
+ }
+ } else {
+
+ // Is tip
+ sub_chain_root = NULL;
+ }
+ }
+}
+
+FabrikInverseKinematic::Task *FabrikInverseKinematic::create_simple_task(Skeleton *p_sk, BoneId root_bone, BoneId tip_bone, const Transform &goal_transform) {
+
+ FabrikInverseKinematic::EndEffector ee;
+ ee.tip_bone = tip_bone;
+
+ Task *task(memnew(Task));
+ task->skeleton = p_sk;
+ task->root_bone = root_bone;
+ task->end_effectors.push_back(ee);
+ task->goal_global_transform = goal_transform;
+
+ build_chain(task);
+
+ return task;
+}
+
+void FabrikInverseKinematic::free_task(Task *p_task) {
+ if (p_task)
+ memdelete(p_task);
+}
+
+void FabrikInverseKinematic::set_goal(Task *p_task, const Transform &p_goal) {
+ p_task->goal_global_transform = p_goal;
+}
+
+void FabrikInverseKinematic::make_goal(Task *p_task, const Transform &p_inverse_transf, real_t blending_delta) {
+
+ if (blending_delta >= 0.99f) {
+ // Update the end_effector (local transform) without blending
+ p_task->end_effectors.write[0].goal_transform = p_inverse_transf * p_task->goal_global_transform;
+ } else {
+
+ // End effector in local transform
+ const Transform end_effector_pose(p_task->skeleton->get_bone_global_pose(p_task->end_effectors.write[0].tip_bone));
+
+ // Update the end_effector (local transform) by blending with current pose
+ p_task->end_effectors.write[0].goal_transform = end_effector_pose.interpolate_with(p_inverse_transf * p_task->goal_global_transform, blending_delta);
+ }
+}
+
+void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool p_use_magnet, const Vector3 &p_magnet_position) {
+
+ if (blending_delta <= 0.01f) {
+ return; // Skip solving
+ }
+
+ make_goal(p_task, p_task->skeleton->get_global_transform().affine_inverse().scaled(p_task->skeleton->get_global_transform().get_basis().get_scale()), blending_delta);
+
+ update_chain(p_task->skeleton, &p_task->chain.chain_root);
+
+ if (p_use_magnet && p_task->chain.middle_chain_item) {
+ p_task->chain.magnet_position = p_task->chain.middle_chain_item->initial_transform.origin.linear_interpolate(p_magnet_position, blending_delta);
+ solve_simple(p_task, true);
+ }
+ solve_simple(p_task, false);
+
+ // Assign new bone position.
+ ChainItem *ci(&p_task->chain.chain_root);
+ while (ci) {
+ Transform new_bone_pose(ci->initial_transform);
+ new_bone_pose.origin = ci->current_pos;
+
+ if (!ci->childs.empty()) {
+
+ /// Rotate basis
+ const Vector3 initial_ori((ci->childs[0].initial_transform.origin - ci->initial_transform.origin).normalized());
+ const Vector3 rot_axis(initial_ori.cross(ci->current_ori).normalized());
+
+ if (rot_axis[0] != 0 && rot_axis[1] != 0 && rot_axis[2] != 0) {
+ const real_t rot_angle(Math::acos(CLAMP(initial_ori.dot(ci->current_ori), -1, 1)));
+ new_bone_pose.basis.rotate(rot_axis, rot_angle);
+ }
+ } else {
+ // Set target orientation to tip
+ new_bone_pose.basis = p_task->chain.tips[0].end_effector->goal_transform.basis;
+ }
+
+ p_task->skeleton->set_bone_global_pose(ci->bone, new_bone_pose);
+
+ if (!ci->childs.empty())
+ ci = &ci->childs.write[0];
+ else
+ ci = NULL;
+ }
+}
+
+void SkeletonIK::_validate_property(PropertyInfo &property) const {
+
+ if (property.name == "root_bone" || property.name == "tip_bone") {
+
+ if (skeleton) {
+
+ String names;
+ for (int i = 0; i < skeleton->get_bone_count(); i++) {
+ if (i > 0)
+ names += ",";
+ names += skeleton->get_bone_name(i);
+ }
+
+ property.hint = PROPERTY_HINT_ENUM;
+ property.hint_string = names;
+ } else {
+
+ property.hint = PROPERTY_HINT_NONE;
+ property.hint_string = "";
+ }
+ }
+}
+
+void SkeletonIK::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_root_bone", "root_bone"), &SkeletonIK::set_root_bone);
+ ClassDB::bind_method(D_METHOD("get_root_bone"), &SkeletonIK::get_root_bone);
+
+ ClassDB::bind_method(D_METHOD("set_tip_bone", "tip_bone"), &SkeletonIK::set_tip_bone);
+ ClassDB::bind_method(D_METHOD("get_tip_bone"), &SkeletonIK::get_tip_bone);
+
+ ClassDB::bind_method(D_METHOD("set_interpolation", "interpolation"), &SkeletonIK::set_interpolation);
+ ClassDB::bind_method(D_METHOD("get_interpolation"), &SkeletonIK::get_interpolation);
+
+ ClassDB::bind_method(D_METHOD("set_target_transform", "target"), &SkeletonIK::set_target_transform);
+ ClassDB::bind_method(D_METHOD("get_target_transform"), &SkeletonIK::get_target_transform);
+
+ ClassDB::bind_method(D_METHOD("set_target_node", "node"), &SkeletonIK::set_target_node);
+ ClassDB::bind_method(D_METHOD("get_target_node"), &SkeletonIK::get_target_node);
+
+ ClassDB::bind_method(D_METHOD("set_use_magnet", "use"), &SkeletonIK::set_use_magnet);
+ ClassDB::bind_method(D_METHOD("is_using_magnet"), &SkeletonIK::is_using_magnet);
+
+ ClassDB::bind_method(D_METHOD("set_magnet_position", "local_position"), &SkeletonIK::set_magnet_position);
+ ClassDB::bind_method(D_METHOD("get_magnet_position"), &SkeletonIK::get_magnet_position);
+
+ ClassDB::bind_method(D_METHOD("get_parent_skeleton"), &SkeletonIK::get_parent_skeleton);
+ ClassDB::bind_method(D_METHOD("is_running"), &SkeletonIK::is_running);
+
+ ClassDB::bind_method(D_METHOD("set_min_distance", "min_distance"), &SkeletonIK::set_min_distance);
+ ClassDB::bind_method(D_METHOD("get_min_distance"), &SkeletonIK::get_min_distance);
+
+ ClassDB::bind_method(D_METHOD("set_max_iterations", "iterations"), &SkeletonIK::set_max_iterations);
+ ClassDB::bind_method(D_METHOD("get_max_iterations"), &SkeletonIK::get_max_iterations);
+
+ ClassDB::bind_method(D_METHOD("start", "one_time"), &SkeletonIK::start, DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("stop"), &SkeletonIK::stop);
+
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "root_bone"), "set_root_bone", "get_root_bone");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "tip_bone"), "set_tip_bone", "get_tip_bone");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "interpolation", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_interpolation", "get_interpolation");
+ ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "target"), "set_target_transform", "get_target_transform");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_magnet"), "set_use_magnet", "is_using_magnet");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "magnet"), "set_magnet_position", "get_magnet_position");
+ ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "target_node"), "set_target_node", "get_target_node");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "min_distance"), "set_min_distance", "get_min_distance");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "max_iterations"), "set_max_iterations", "get_max_iterations");
+}
+
+void SkeletonIK::_notification(int p_what) {
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE: {
+ skeleton = Object::cast_to<Skeleton>(get_parent());
+ reload_chain();
+ } break;
+ case NOTIFICATION_INTERNAL_PROCESS: {
+
+ if (target_node_override)
+ reload_goal();
+
+ _solve_chain();
+
+ } break;
+ case NOTIFICATION_EXIT_TREE: {
+ reload_chain();
+ } break;
+ }
+}
+
+SkeletonIK::SkeletonIK() :
+ Node(),
+ interpolation(1),
+ skeleton(NULL),
+ target_node_override(NULL),
+ use_magnet(false),
+ min_distance(0.01),
+ max_iterations(10),
+ task(NULL) {
+
+ set_process_priority(1);
+}
+
+SkeletonIK::~SkeletonIK() {
+ FabrikInverseKinematic::free_task(task);
+ task = NULL;
+}
+
+void SkeletonIK::set_root_bone(const StringName &p_root_bone) {
+ root_bone = p_root_bone;
+ reload_chain();
+}
+
+StringName SkeletonIK::get_root_bone() const {
+ return root_bone;
+}
+
+void SkeletonIK::set_tip_bone(const StringName &p_tip_bone) {
+ tip_bone = p_tip_bone;
+ reload_chain();
+}
+
+StringName SkeletonIK::get_tip_bone() const {
+ return tip_bone;
+}
+
+void SkeletonIK::set_interpolation(real_t p_interpolation) {
+ interpolation = p_interpolation;
+}
+
+real_t SkeletonIK::get_interpolation() const {
+ return interpolation;
+}
+
+void SkeletonIK::set_target_transform(const Transform &p_target) {
+ target = p_target;
+ reload_goal();
+}
+
+const Transform &SkeletonIK::get_target_transform() const {
+ return target;
+}
+
+void SkeletonIK::set_target_node(const NodePath &p_node) {
+ target_node_path_override = p_node;
+ target_node_override = NULL;
+ reload_goal();
+}
+
+NodePath SkeletonIK::get_target_node() {
+ return target_node_path_override;
+}
+
+void SkeletonIK::set_use_magnet(bool p_use) {
+ use_magnet = p_use;
+}
+
+bool SkeletonIK::is_using_magnet() const {
+ return use_magnet;
+}
+
+void SkeletonIK::set_magnet_position(const Vector3 &p_local_position) {
+ magnet_position = p_local_position;
+}
+
+const Vector3 &SkeletonIK::get_magnet_position() const {
+ return magnet_position;
+}
+
+void SkeletonIK::set_min_distance(real_t p_min_distance) {
+ min_distance = p_min_distance;
+}
+
+void SkeletonIK::set_max_iterations(int p_iterations) {
+ max_iterations = p_iterations;
+}
+
+bool SkeletonIK::is_running() {
+ return is_processing_internal();
+}
+
+void SkeletonIK::start(bool p_one_time) {
+ if (p_one_time) {
+ set_process_internal(false);
+ _solve_chain();
+ } else {
+ set_process_internal(true);
+ }
+}
+
+void SkeletonIK::stop() {
+ set_process_internal(false);
+}
+
+Transform SkeletonIK::_get_target_transform() {
+
+ if (!target_node_override && !target_node_path_override.is_empty())
+ target_node_override = Object::cast_to<Spatial>(get_node(target_node_path_override));
+
+ if (target_node_override)
+ return target_node_override->get_global_transform();
+ else
+ return target;
+}
+
+void SkeletonIK::reload_chain() {
+
+ FabrikInverseKinematic::free_task(task);
+ task = NULL;
+
+ if (!skeleton)
+ return;
+
+ task = FabrikInverseKinematic::create_simple_task(skeleton, skeleton->find_bone(root_bone), skeleton->find_bone(tip_bone), _get_target_transform());
+ task->max_iterations = max_iterations;
+ task->min_distance = min_distance;
+}
+
+void SkeletonIK::reload_goal() {
+ if (!task)
+ return;
+
+ FabrikInverseKinematic::set_goal(task, _get_target_transform());
+}
+
+void SkeletonIK::_solve_chain() {
+ if (!task)
+ return;
+ FabrikInverseKinematic::solve(task, interpolation, use_magnet, magnet_position);
+}
+
+#endif // _3D_DISABLED
diff --git a/scene/animation/skeleton_ik.h b/scene/animation/skeleton_ik.h
new file mode 100644
index 0000000000..08fb00e798
--- /dev/null
+++ b/scene/animation/skeleton_ik.h
@@ -0,0 +1,216 @@
+/*************************************************************************/
+/* skeleton_ik.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* 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. */
+/*************************************************************************/
+
+#ifndef SKELETON_IK_H
+#define SKELETON_IK_H
+
+#ifndef _3D_DISABLED
+
+/**
+ * @author AndreaCatania
+ */
+
+#include "core/math/transform.h"
+#include "scene/3d/skeleton.h"
+
+class FabrikInverseKinematic {
+
+ struct EndEffector {
+ BoneId tip_bone;
+ Transform goal_transform;
+ };
+
+ struct ChainItem {
+
+ Vector<ChainItem> childs;
+ ChainItem *parent_item;
+
+ // Bone info
+ BoneId bone;
+ PhysicalBone *pb;
+
+ real_t length;
+ /// Positions relative to root bone
+ Transform initial_transform;
+ Vector3 current_pos;
+ // Direction from this bone to child
+ Vector3 current_ori;
+
+ ChainItem() :
+ parent_item(NULL),
+ bone(-1),
+ pb(NULL),
+ length(0) {}
+
+ ChainItem *find_child(const BoneId p_bone_id);
+ ChainItem *add_child(const BoneId p_bone_id);
+ };
+
+ struct ChainTip {
+ ChainItem *chain_item;
+ const EndEffector *end_effector;
+
+ ChainTip() :
+ chain_item(NULL),
+ end_effector(NULL) {}
+
+ ChainTip(ChainItem *p_chain_item, const EndEffector *p_end_effector) :
+ chain_item(p_chain_item),
+ end_effector(p_end_effector) {}
+
+ ChainTip(const ChainTip &p_other_ct) :
+ chain_item(p_other_ct.chain_item),
+ end_effector(p_other_ct.end_effector) {}
+ };
+
+ struct Chain {
+ ChainItem chain_root;
+ ChainItem *middle_chain_item;
+ Vector<ChainTip> tips;
+ Vector3 magnet_position;
+ };
+
+public:
+ struct Task : public RID_Data {
+ RID self;
+ Skeleton *skeleton;
+
+ Chain chain;
+
+ // Settings
+ real_t min_distance;
+ int max_iterations;
+
+ // Bone data
+ BoneId root_bone;
+ Vector<EndEffector> end_effectors;
+
+ Transform goal_global_transform;
+
+ Task() :
+ skeleton(NULL),
+ min_distance(0.01),
+ max_iterations(10),
+ root_bone(-1) {}
+ };
+
+private:
+ /// Init a chain that starts from the root to tip
+ static void build_chain(Task *p_task, bool p_force_simple_chain = true);
+
+ static void update_chain(const Skeleton *p_sk, ChainItem *p_chain_item);
+
+ static void solve_simple(Task *p_task, bool p_solve_magnet);
+ /// Special solvers that solve only chains with one end effector
+ static void solve_simple_backwards(Chain &r_chain, bool p_solve_magnet);
+ static void solve_simple_forwards(Chain &r_chain, bool p_solve_magnet);
+
+public:
+ static Task *create_simple_task(Skeleton *p_sk, BoneId root_bone, BoneId tip_bone, const Transform &goal_transform);
+ static void free_task(Task *p_task);
+ // The goal of chain should be always in local space
+ static void set_goal(Task *p_task, const Transform &p_goal);
+ static void make_goal(Task *p_task, const Transform &p_inverse_transf, real_t blending_delta);
+ static void solve(Task *p_task, real_t blending_delta, bool p_use_magnet, const Vector3 &p_magnet_position);
+};
+
+class SkeletonIK : public Node {
+ GDCLASS(SkeletonIK, Node);
+
+ StringName root_bone;
+ StringName tip_bone;
+ real_t interpolation;
+ Transform target;
+ NodePath target_node_path_override;
+ bool use_magnet;
+ Vector3 magnet_position;
+
+ real_t min_distance;
+ int max_iterations;
+
+ Skeleton *skeleton;
+ Spatial *target_node_override;
+ FabrikInverseKinematic::Task *task;
+
+protected:
+ virtual void
+ _validate_property(PropertyInfo &property) const;
+
+ static void _bind_methods();
+ virtual void _notification(int p_notification);
+
+public:
+ SkeletonIK();
+ virtual ~SkeletonIK();
+
+ void set_root_bone(const StringName &p_root_bone);
+ StringName get_root_bone() const;
+
+ void set_tip_bone(const StringName &p_tip_bone);
+ StringName get_tip_bone() const;
+
+ void set_interpolation(real_t p_interpolation);
+ real_t get_interpolation() const;
+
+ void set_target_transform(const Transform &p_target);
+ const Transform &get_target_transform() const;
+
+ void set_target_node(const NodePath &p_node);
+ NodePath get_target_node();
+
+ void set_use_magnet(bool p_use);
+ bool is_using_magnet() const;
+
+ void set_magnet_position(const Vector3 &p_constraint);
+ const Vector3 &get_magnet_position() const;
+
+ void set_min_distance(real_t p_min_distance);
+ real_t get_min_distance() const { return min_distance; }
+
+ void set_max_iterations(int p_iterations);
+ int get_max_iterations() const { return max_iterations; }
+
+ Skeleton *get_parent_skeleton() const { return skeleton; }
+
+ bool is_running();
+
+ void start(bool p_one_time = false);
+ void stop();
+
+private:
+ Transform _get_target_transform();
+ void reload_chain();
+ void reload_goal();
+ void _solve_chain();
+};
+
+#endif // _3D_DISABLED
+
+#endif // SKELETON_IK_H
diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp
index 9f7503577b..58be636e44 100644
--- a/scene/animation/tween.cpp
+++ b/scene/animation/tween.cpp
@@ -150,7 +150,7 @@ void Tween::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE: {
- if (!processing) {
+ if (!is_active()) {
//make sure that a previous process state was not saved
//only process if "processing" is set
set_physics_process_internal(false);
@@ -164,7 +164,7 @@ void Tween::_notification(int p_what) {
if (tween_process_mode == TWEEN_PROCESS_PHYSICS)
break;
- if (processing)
+ if (is_active())
_tween_process(get_process_delta_time());
} break;
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
@@ -172,7 +172,7 @@ void Tween::_notification(int p_what) {
if (tween_process_mode == TWEEN_PROCESS_IDLE)
break;
- if (processing)
+ if (is_active())
_tween_process(get_physics_process_delta_time());
} break;
case NOTIFICATION_EXIT_TREE: {
@@ -201,11 +201,10 @@ void Tween::_bind_methods() {
ClassDB::bind_method(D_METHOD("reset_all"), &Tween::reset_all);
ClassDB::bind_method(D_METHOD("stop", "object", "key"), &Tween::stop, DEFVAL(""));
ClassDB::bind_method(D_METHOD("stop_all"), &Tween::stop_all);
- ClassDB::bind_method(D_METHOD("is_stopped"), &Tween::is_stopped);
ClassDB::bind_method(D_METHOD("resume", "object", "key"), &Tween::resume, DEFVAL(""));
ClassDB::bind_method(D_METHOD("resume_all"), &Tween::resume_all);
ClassDB::bind_method(D_METHOD("remove", "object", "key"), &Tween::remove, DEFVAL(""));
- ClassDB::bind_method(D_METHOD("_remove", "object", "key", "first_only"), &Tween::_remove);
+ ClassDB::bind_method(D_METHOD("_remove_by_uid", "uid"), &Tween::_remove_by_uid);
ClassDB::bind_method(D_METHOD("remove_all"), &Tween::remove_all);
ClassDB::bind_method(D_METHOD("seek", "time"), &Tween::seek);
ClassDB::bind_method(D_METHOD("tell"), &Tween::tell);
@@ -522,8 +521,8 @@ void Tween::_tween_process(float p_delta) {
pending_update++;
// if repeat and all interpolates was finished then reset all interpolates
+ bool all_finished = true;
if (repeat) {
- bool all_finished = true;
for (List<InterpolateData>::Element *E = interpolates.front(); E; E = E->next()) {
@@ -539,9 +538,12 @@ void Tween::_tween_process(float p_delta) {
reset_all();
}
+ all_finished = true;
for (List<InterpolateData>::Element *E = interpolates.front(); E; E = E->next()) {
InterpolateData &data = E->get();
+ all_finished = all_finished && data.finish;
+
if (!data.active || data.finish)
continue;
@@ -555,8 +557,8 @@ void Tween::_tween_process(float p_delta) {
continue;
else if (prev_delaying) {
- emit_signal("tween_started", object, NodePath(Vector<StringName>(), data.key, false));
_apply_tween_value(data, data.initial_val);
+ emit_signal("tween_started", object, NodePath(Vector<StringName>(), data.key, false));
}
if (data.elapsed > (data.delay + data.duration)) {
@@ -603,32 +605,29 @@ void Tween::_tween_process(float p_delta) {
}
} else {
Variant result = _run_equation(data);
- emit_signal("tween_step", object, NodePath(Vector<StringName>(), data.key, false), data.elapsed, result);
_apply_tween_value(data, result);
+ emit_signal("tween_step", object, NodePath(Vector<StringName>(), data.key, false), data.elapsed, result);
}
if (data.finish) {
_apply_tween_value(data, data.final_val);
+ data.elapsed = 0;
emit_signal("tween_completed", object, NodePath(Vector<StringName>(), data.key, false));
// not repeat mode, remove completed action
if (!repeat)
- call_deferred("_remove", object, NodePath(Vector<StringName>(), data.key, false), true);
- }
+ call_deferred("_remove_by_uid", data.uid);
+ } else if (!repeat)
+ all_finished = all_finished && data.finish;
}
pending_update--;
+
+ if (all_finished)
+ set_active(false);
}
void Tween::set_tween_process_mode(TweenProcessMode p_mode) {
- if (tween_process_mode == p_mode)
- return;
-
- bool pr = processing;
- if (pr)
- _set_process(false);
tween_process_mode = p_mode;
- if (pr)
- _set_process(true);
}
Tween::TweenProcessMode Tween::get_tween_process_mode() const {
@@ -636,32 +635,21 @@ Tween::TweenProcessMode Tween::get_tween_process_mode() const {
return tween_process_mode;
}
-void Tween::_set_process(bool p_process, bool p_force) {
-
- if (processing == p_process && !p_force)
- return;
-
- switch (tween_process_mode) {
-
- case TWEEN_PROCESS_PHYSICS: set_physics_process_internal(p_process && active); break;
- case TWEEN_PROCESS_IDLE: set_process_internal(p_process && active); break;
- }
-
- processing = p_process;
-}
-
bool Tween::is_active() const {
- return active;
+ return is_processing_internal() || is_physics_processing_internal();
}
void Tween::set_active(bool p_active) {
- if (active == p_active)
+ if (is_active() == p_active)
return;
- active = p_active;
- _set_process(processing, true);
+ switch (tween_process_mode) {
+
+ case TWEEN_PROCESS_IDLE: set_process_internal(p_active); break;
+ case TWEEN_PROCESS_PHYSICS: set_physics_process_internal(p_active); break;
+ }
}
bool Tween::is_repeat() const {
@@ -687,7 +675,6 @@ float Tween::get_speed_scale() const {
bool Tween::start() {
set_active(true);
- _set_process(true);
return true;
}
@@ -744,14 +731,9 @@ bool Tween::stop(Object *p_object, StringName p_key) {
return true;
}
-bool Tween::is_stopped() const {
- return tell() >= get_runtime();
-}
-
bool Tween::stop_all() {
set_active(false);
- _set_process(false);
pending_update++;
for (List<InterpolateData>::Element *E = interpolates.front(); E; E = E->next()) {
@@ -766,7 +748,6 @@ bool Tween::stop_all() {
bool Tween::resume(Object *p_object, StringName p_key) {
set_active(true);
- _set_process(true);
pending_update++;
for (List<InterpolateData>::Element *E = interpolates.front(); E; E = E->next()) {
@@ -785,7 +766,6 @@ bool Tween::resume(Object *p_object, StringName p_key) {
bool Tween::resume_all() {
set_active(true);
- _set_process(true);
pending_update++;
for (List<InterpolateData>::Element *E = interpolates.front(); E; E = E->next()) {
@@ -798,15 +778,9 @@ bool Tween::resume_all() {
}
bool Tween::remove(Object *p_object, StringName p_key) {
- _remove(p_object, p_key, false);
- return true;
-}
-
-void Tween::_remove(Object *p_object, StringName p_key, bool first_only) {
-
if (pending_update != 0) {
- call_deferred("_remove", p_object, p_key, first_only);
- return;
+ call_deferred("remove", p_object, p_key);
+ return true;
}
List<List<InterpolateData>::Element *> for_removal;
for (List<InterpolateData>::Element *E = interpolates.front(); E; E = E->next()) {
@@ -817,14 +791,33 @@ void Tween::_remove(Object *p_object, StringName p_key, bool first_only) {
continue;
if (object == p_object && (data.concatenated_key == p_key || p_key == "")) {
for_removal.push_back(E);
- if (first_only) {
- break;
- }
}
}
for (List<List<InterpolateData>::Element *>::Element *E = for_removal.front(); E; E = E->next()) {
interpolates.erase(E->get());
}
+ return true;
+}
+
+void Tween::_remove_by_uid(int uid) {
+ if (pending_update != 0) {
+ call_deferred("_remove_by_uid", uid);
+ return;
+ }
+
+ for (List<InterpolateData>::Element *E = interpolates.front(); E; E = E->next()) {
+ if (uid == E->get().uid) {
+ E->erase();
+ break;
+ }
+ }
+}
+
+void Tween::_push_interpolate_data(InterpolateData &p_data) {
+ pending_update++;
+ p_data.uid = ++uid;
+ interpolates.push_back(p_data);
+ pending_update--;
}
bool Tween::remove_all() {
@@ -834,8 +827,8 @@ bool Tween::remove_all() {
return true;
}
set_active(false);
- _set_process(false);
interpolates.clear();
+ uid = 0;
return true;
}
@@ -1048,7 +1041,7 @@ bool Tween::interpolate_property(Object *p_object, NodePath p_property, Variant
if (!_calc_delta_val(data.initial_val, data.final_val, data.delta_val))
return false;
- interpolates.push_back(data);
+ _push_interpolate_data(data);
return true;
}
@@ -1091,7 +1084,7 @@ bool Tween::interpolate_method(Object *p_object, StringName p_method, Variant p_
if (!_calc_delta_val(data.initial_val, data.final_val, data.delta_val))
return false;
- interpolates.push_back(data);
+ _push_interpolate_data(data);
return true;
}
@@ -1143,9 +1136,7 @@ bool Tween::interpolate_callback(Object *p_object, real_t p_duration, String p_c
data.arg[3] = p_arg4;
data.arg[4] = p_arg5;
- pending_update++;
- interpolates.push_back(data);
- pending_update--;
+ _push_interpolate_data(data);
return true;
}
@@ -1196,9 +1187,7 @@ bool Tween::interpolate_deferred_callback(Object *p_object, real_t p_duration, S
data.arg[3] = p_arg4;
data.arg[4] = p_arg5;
- pending_update++;
- interpolates.push_back(data);
- pending_update--;
+ _push_interpolate_data(data);
return true;
}
@@ -1253,7 +1242,7 @@ bool Tween::follow_property(Object *p_object, NodePath p_property, Variant p_ini
data.ease_type = p_ease_type;
data.delay = p_delay;
- interpolates.push_back(data);
+ _push_interpolate_data(data);
return true;
}
@@ -1304,7 +1293,7 @@ bool Tween::follow_method(Object *p_object, StringName p_method, Variant p_initi
data.ease_type = p_ease_type;
data.delay = p_delay;
- interpolates.push_back(data);
+ _push_interpolate_data(data);
return true;
}
@@ -1362,7 +1351,7 @@ bool Tween::targeting_property(Object *p_object, NodePath p_property, Object *p_
if (!_calc_delta_val(data.initial_val, data.final_val, data.delta_val))
return false;
- interpolates.push_back(data);
+ _push_interpolate_data(data);
return true;
}
@@ -1417,7 +1406,7 @@ bool Tween::targeting_method(Object *p_object, StringName p_method, Object *p_in
if (!_calc_delta_val(data.initial_val, data.final_val, data.delta_val))
return false;
- interpolates.push_back(data);
+ _push_interpolate_data(data);
return true;
}
@@ -1425,11 +1414,10 @@ Tween::Tween() {
//String autoplay;
tween_process_mode = TWEEN_PROCESS_IDLE;
- processing = false;
- active = false;
repeat = false;
speed_scale = 1;
pending_update = 0;
+ uid = 0;
}
Tween::~Tween() {
diff --git a/scene/animation/tween.h b/scene/animation/tween.h
index 36094bf294..aa47c00717 100644
--- a/scene/animation/tween.h
+++ b/scene/animation/tween.h
@@ -100,15 +100,15 @@ private:
real_t delay;
int args;
Variant arg[5];
+ int uid;
};
String autoplay;
TweenProcessMode tween_process_mode;
- bool processing;
- bool active;
bool repeat;
float speed_scale;
mutable int pending_update;
+ int uid;
List<InterpolateData> interpolates;
@@ -133,8 +133,8 @@ private:
bool _apply_tween_value(InterpolateData &p_data, Variant &value);
void _tween_process(float p_delta);
- void _set_process(bool p_process, bool p_force = false);
- void _remove(Object *p_object, StringName p_key, bool first_only);
+ void _remove_by_uid(int uid);
+ void _push_interpolate_data(InterpolateData &p_data);
protected:
bool _set(const StringName &p_name, const Variant &p_value);
@@ -162,7 +162,6 @@ public:
bool reset_all();
bool stop(Object *p_object, StringName p_key);
bool stop_all();
- bool is_stopped() const;
bool resume(Object *p_object, StringName p_key);
bool resume_all();
bool remove(Object *p_object, StringName p_key);
diff --git a/scene/audio/audio_player.cpp b/scene/audio/audio_player.cpp
index 863b278b62..7a9f2bd8d0 100644
--- a/scene/audio/audio_player.cpp
+++ b/scene/audio/audio_player.cpp
@@ -192,6 +192,7 @@ float AudioStreamPlayer::get_volume_db() const {
}
void AudioStreamPlayer::set_pitch_scale(float p_pitch_scale) {
+ ERR_FAIL_COND(p_pitch_scale <= 0.0);
pitch_scale = p_pitch_scale;
}
float AudioStreamPlayer::get_pitch_scale() const {
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index 068af42260..18f06eca31 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -663,6 +663,9 @@ void Control::_notification(int p_notification) {
bool Control::clips_input() const {
+ if (get_script_instance()) {
+ return get_script_instance()->call(SceneStringNames::get_singleton()->_clips_input);
+ }
return false;
}
bool Control::has_point(const Point2 &p_point) const {
@@ -2188,10 +2191,17 @@ void Control::set_tooltip(const String &p_tooltip) {
data.tooltip = p_tooltip;
}
+
String Control::get_tooltip(const Point2 &p_pos) const {
return data.tooltip;
}
+Control *Control::make_custom_tooltip(const String &p_text) const {
+ if (get_script_instance()) {
+ return const_cast<Control *>(this)->call("_make_custom_tooltip", p_text);
+ }
+ return NULL;
+}
void Control::set_default_cursor_shape(CursorShape p_shape) {
@@ -2820,6 +2830,8 @@ void Control::_bind_methods() {
BIND_VMETHOD(MethodInfo(Variant::OBJECT, "get_drag_data", PropertyInfo(Variant::VECTOR2, "position")));
BIND_VMETHOD(MethodInfo(Variant::BOOL, "can_drop_data", PropertyInfo(Variant::VECTOR2, "position"), PropertyInfo(Variant::NIL, "data")));
BIND_VMETHOD(MethodInfo("drop_data", PropertyInfo(Variant::VECTOR2, "position"), PropertyInfo(Variant::NIL, "data")));
+ BIND_VMETHOD(MethodInfo(Variant::OBJECT, "_make_custom_tooltip", PropertyInfo(Variant::STRING, "for_text")));
+ BIND_VMETHOD(MethodInfo(Variant::BOOL, "_clips_input"));
ADD_GROUP("Anchor", "anchor_");
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anchor_left", PROPERTY_HINT_RANGE, "0,1,0.01"), "_set_anchor", "get_anchor", MARGIN_LEFT);
@@ -2964,7 +2976,6 @@ Control::Control() {
data.SI = NULL;
data.MI = NULL;
data.RI = NULL;
- data.modal = false;
data.theme_owner = NULL;
data.modal_exclusive = false;
data.default_cursor = CURSOR_ARROW;
diff --git a/scene/gui/control.h b/scene/gui/control.h
index fa5274d854..c6bd2f097d 100644
--- a/scene/gui/control.h
+++ b/scene/gui/control.h
@@ -31,13 +31,13 @@
#ifndef CONTROL_H
#define CONTROL_H
-#include "math_2d.h"
#include "rid.h"
#include "scene/2d/canvas_item.h"
#include "scene/gui/shortcut.h"
#include "scene/main/node.h"
#include "scene/main/timer.h"
#include "scene/resources/theme.h"
+#include "transform_2d.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
@@ -182,7 +182,6 @@ private:
Control *parent;
ObjectID drag_owner;
- bool modal;
bool modal_exclusive;
uint64_t modal_frame; //frame used to put something as modal
Ref<Theme> theme;
@@ -454,6 +453,7 @@ public:
void set_tooltip(const String &p_tooltip);
virtual String get_tooltip(const Point2 &p_pos) const;
+ virtual Control *make_custom_tooltip(const String &p_text) const;
/* CURSOR */
diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp
index 25cb74a494..635f812805 100644
--- a/scene/gui/file_dialog.cpp
+++ b/scene/gui/file_dialog.cpp
@@ -582,7 +582,8 @@ void FileDialog::set_current_file(const String &p_file) {
int lp = p_file.find_last(".");
if (lp != -1) {
file->select(0, lp);
- file->grab_focus();
+ if (file->is_inside_tree())
+ file->grab_focus();
}
}
void FileDialog::set_current_path(const String &p_path) {
diff --git a/scene/gui/gradient_edit.cpp b/scene/gui/gradient_edit.cpp
index b5622604e2..e82c0c4ad1 100644
--- a/scene/gui/gradient_edit.cpp
+++ b/scene/gui/gradient_edit.cpp
@@ -147,7 +147,6 @@ void GradientEdit::_gui_input(const Ref<InputEvent> &p_event) {
grabbed = _get_point_from_pos(x);
//grab or select
if (grabbed != -1) {
- grabbed = false;
return;
}
@@ -256,7 +255,7 @@ void GradientEdit::_gui_input(const Ref<InputEvent> &p_event) {
if (!valid)
return;
- points[grabbed].offset = newofs;
+ points.write[grabbed].offset = newofs;
points.sort();
for (int i = 0; i < points.size(); i++) {
@@ -407,7 +406,7 @@ void GradientEdit::_color_changed(const Color &p_color) {
if (grabbed == -1)
return;
- points[grabbed].color = p_color;
+ points.write[grabbed].color = p_color;
update();
emit_signal("ramp_changed");
}
diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp
index e2c730a56e..a7163adbe6 100644
--- a/scene/gui/graph_edit.cpp
+++ b/scene/gui/graph_edit.cpp
@@ -268,6 +268,10 @@ void GraphEdit::remove_child_notify(Node *p_child) {
void GraphEdit::_notification(int p_what) {
+ if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
+ port_grab_distance_horizontal = get_constant("port_grab_distance_horizontal");
+ port_grab_distance_vertical = get_constant("port_grab_distance_vertical");
+ }
if (p_what == NOTIFICATION_READY) {
Size2 hmin = h_scroll->get_combined_minimum_size();
Size2 vmin = v_scroll->get_combined_minimum_size();
@@ -343,8 +347,6 @@ bool GraphEdit::_filter_input(const Point2 &p_point) {
Ref<Texture> port = get_icon("port", "GraphNode");
- float grab_r_extend = 2.0;
- float grab_r = port->get_width() * 0.5 * grab_r_extend;
for (int i = get_child_count() - 1; i >= 0; i--) {
GraphNode *gn = Object::cast_to<GraphNode>(get_child(i));
@@ -354,14 +356,14 @@ bool GraphEdit::_filter_input(const Point2 &p_point) {
for (int j = 0; j < gn->get_connection_output_count(); j++) {
Vector2 pos = gn->get_connection_output_position(j) + gn->get_position();
- if (pos.distance_to(p_point) < grab_r)
+ if (is_in_hot_zone(pos, p_point))
return true;
}
for (int j = 0; j < gn->get_connection_input_count(); j++) {
Vector2 pos = gn->get_connection_input_position(j) + gn->get_position();
- if (pos.distance_to(p_point) < grab_r) {
+ if (is_in_hot_zone(pos, p_point)) {
return true;
}
}
@@ -372,13 +374,11 @@ bool GraphEdit::_filter_input(const Point2 &p_point) {
void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
- float grab_r_extend = 2.0;
Ref<InputEventMouseButton> mb = p_ev;
if (mb.is_valid() && mb->get_button_index() == BUTTON_LEFT && mb->is_pressed()) {
Ref<Texture> port = get_icon("port", "GraphNode");
Vector2 mpos(mb->get_position().x, mb->get_position().y);
- float grab_r = port->get_width() * 0.5 * grab_r_extend;
for (int i = get_child_count() - 1; i >= 0; i--) {
GraphNode *gn = Object::cast_to<GraphNode>(get_child(i));
@@ -388,7 +388,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
for (int j = 0; j < gn->get_connection_output_count(); j++) {
Vector2 pos = gn->get_connection_output_position(j) + gn->get_position();
- if (pos.distance_to(mpos) < grab_r) {
+ if (is_in_hot_zone(pos, mpos)) {
if (valid_left_disconnect_types.has(gn->get_connection_output_type(j))) {
//check disconnect
@@ -435,8 +435,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
for (int j = 0; j < gn->get_connection_input_count(); j++) {
Vector2 pos = gn->get_connection_input_position(j) + gn->get_position();
-
- if (pos.distance_to(mpos) < grab_r) {
+ if (is_in_hot_zone(pos, mpos)) {
if (right_disconnects || valid_right_disconnect_types.has(gn->get_connection_input_type(j))) {
//check disconnect
@@ -492,7 +491,6 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
Ref<Texture> port = get_icon("port", "GraphNode");
Vector2 mpos = mm->get_position();
- float grab_r = port->get_width() * 0.5 * grab_r_extend;
for (int i = get_child_count() - 1; i >= 0; i--) {
GraphNode *gn = Object::cast_to<GraphNode>(get_child(i));
@@ -504,7 +502,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
Vector2 pos = gn->get_connection_output_position(j) + gn->get_position();
int type = gn->get_connection_output_type(j);
- if ((type == connecting_type || valid_connection_types.has(ConnType(type, connecting_type))) && pos.distance_to(mpos) < grab_r) {
+ if ((type == connecting_type || valid_connection_types.has(ConnType(type, connecting_type))) && is_in_hot_zone(pos, mpos)) {
connecting_target = true;
connecting_to = pos;
@@ -519,7 +517,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
Vector2 pos = gn->get_connection_input_position(j) + gn->get_position();
int type = gn->get_connection_input_type(j);
- if ((type == connecting_type || valid_connection_types.has(ConnType(type, connecting_type))) && pos.distance_to(mpos) < grab_r) {
+ if ((type == connecting_type || valid_connection_types.has(ConnType(type, connecting_type))) && is_in_hot_zone(pos, mpos)) {
connecting_target = true;
connecting_to = pos;
connecting_target_to = gn->get_name();
@@ -559,6 +557,57 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
}
}
+bool GraphEdit::_check_clickable_control(Control *p_control, const Vector2 &pos) {
+
+ if (p_control->is_set_as_toplevel() || !p_control->is_visible())
+ return false;
+
+ if (!p_control->has_point(pos) || p_control->get_mouse_filter() == MOUSE_FILTER_IGNORE) {
+ //test children
+ for (int i = 0; i < p_control->get_child_count(); i++) {
+ Control *subchild = Object::cast_to<Control>(p_control->get_child(i));
+ if (!subchild)
+ continue;
+ if (_check_clickable_control(subchild, pos - subchild->get_position())) {
+ return true;
+ }
+ }
+
+ return false;
+ } else {
+ return true;
+ }
+}
+
+bool GraphEdit::is_in_hot_zone(const Vector2 &pos, const Vector2 &p_mouse_pos) {
+ if (!Rect2(pos.x - port_grab_distance_horizontal, pos.y - port_grab_distance_vertical, port_grab_distance_horizontal * 2, port_grab_distance_vertical * 2).has_point(p_mouse_pos))
+ return false;
+
+ for (int i = 0; i < get_child_count(); i++) {
+ Control *child = Object::cast_to<Control>(get_child(i));
+ if (!child)
+ continue;
+ Rect2 rect = child->get_rect();
+ if (rect.has_point(p_mouse_pos)) {
+
+ //check sub-controls
+ Vector2 subpos = p_mouse_pos - rect.position;
+
+ for (int j = 0; j < child->get_child_count(); j++) {
+ Control *subchild = Object::cast_to<Control>(child->get_child(j));
+ if (!subchild)
+ continue;
+
+ if (_check_clickable_control(subchild, subpos - subchild->get_position())) {
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
template <class Vector2>
static _FORCE_INLINE_ Vector2 _bezier_interp(real_t t, Vector2 start, Vector2 control_1, Vector2 control_2, Vector2 end) {
/* Formula from Wikipedia article on Bezier curves. */
diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h
index 14789001e4..31a449eb59 100644
--- a/scene/gui/graph_edit.h
+++ b/scene/gui/graph_edit.h
@@ -81,6 +81,9 @@ private:
HScrollBar *h_scroll;
VScrollBar *v_scroll;
+ float port_grab_distance_horizontal;
+ float port_grab_distance_vertical;
+
bool connecting;
String connecting_from;
bool connecting_out;
@@ -127,6 +130,9 @@ private:
Control *connections_layer;
GraphEditFilter *top_layer;
void _top_layer_input(const Ref<InputEvent> &p_ev);
+
+ bool is_in_hot_zone(const Vector2 &pos, const Vector2 &p_mouse_pos);
+
void _top_layer_draw();
void _connections_layer_draw();
void _update_scroll_offset();
@@ -166,6 +172,8 @@ private:
void _snap_toggled();
void _snap_value_changed(double);
+ bool _check_clickable_control(Control *p_control, const Vector2 &pos);
+
protected:
static void _bind_methods();
virtual void add_child_notify(Node *p_child);
diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp
index 72ed0e9b81..d61bd97c2a 100644
--- a/scene/gui/item_list.cpp
+++ b/scene/gui/item_list.cpp
@@ -72,7 +72,7 @@ void ItemList::set_item_text(int p_idx, const String &p_text) {
ERR_FAIL_INDEX(p_idx, items.size());
- items[p_idx].text = p_text;
+ items.write[p_idx].text = p_text;
update();
shape_changed = true;
}
@@ -85,7 +85,7 @@ String ItemList::get_item_text(int p_idx) const {
void ItemList::set_item_tooltip_enabled(int p_idx, const bool p_enabled) {
ERR_FAIL_INDEX(p_idx, items.size());
- items[p_idx].tooltip_enabled = p_enabled;
+ items.write[p_idx].tooltip_enabled = p_enabled;
}
bool ItemList::is_item_tooltip_enabled(int p_idx) const {
@@ -97,7 +97,7 @@ void ItemList::set_item_tooltip(int p_idx, const String &p_tooltip) {
ERR_FAIL_INDEX(p_idx, items.size());
- items[p_idx].tooltip = p_tooltip;
+ items.write[p_idx].tooltip = p_tooltip;
update();
shape_changed = true;
}
@@ -112,7 +112,7 @@ void ItemList::set_item_icon(int p_idx, const Ref<Texture> &p_icon) {
ERR_FAIL_INDEX(p_idx, items.size());
- items[p_idx].icon = p_icon;
+ items.write[p_idx].icon = p_icon;
update();
shape_changed = true;
}
@@ -128,7 +128,7 @@ void ItemList::set_item_icon_region(int p_idx, const Rect2 &p_region) {
ERR_FAIL_INDEX(p_idx, items.size());
- items[p_idx].icon_region = p_region;
+ items.write[p_idx].icon_region = p_region;
update();
shape_changed = true;
}
@@ -144,7 +144,7 @@ void ItemList::set_item_icon_modulate(int p_idx, const Color &p_modulate) {
ERR_FAIL_INDEX(p_idx, items.size());
- items[p_idx].icon_modulate = p_modulate;
+ items.write[p_idx].icon_modulate = p_modulate;
update();
}
@@ -159,7 +159,7 @@ void ItemList::set_item_custom_bg_color(int p_idx, const Color &p_custom_bg_colo
ERR_FAIL_INDEX(p_idx, items.size());
- items[p_idx].custom_bg = p_custom_bg_color;
+ items.write[p_idx].custom_bg = p_custom_bg_color;
}
Color ItemList::get_item_custom_bg_color(int p_idx) const {
@@ -173,7 +173,7 @@ void ItemList::set_item_custom_fg_color(int p_idx, const Color &p_custom_fg_colo
ERR_FAIL_INDEX(p_idx, items.size());
- items[p_idx].custom_fg = p_custom_fg_color;
+ items.write[p_idx].custom_fg = p_custom_fg_color;
}
Color ItemList::get_item_custom_fg_color(int p_idx) const {
@@ -187,7 +187,7 @@ void ItemList::set_item_tag_icon(int p_idx, const Ref<Texture> &p_tag_icon) {
ERR_FAIL_INDEX(p_idx, items.size());
- items[p_idx].tag_icon = p_tag_icon;
+ items.write[p_idx].tag_icon = p_tag_icon;
update();
shape_changed = true;
}
@@ -202,7 +202,7 @@ void ItemList::set_item_selectable(int p_idx, bool p_selectable) {
ERR_FAIL_INDEX(p_idx, items.size());
- items[p_idx].selectable = p_selectable;
+ items.write[p_idx].selectable = p_selectable;
}
bool ItemList::is_item_selectable(int p_idx) const {
@@ -215,7 +215,7 @@ void ItemList::set_item_disabled(int p_idx, bool p_disabled) {
ERR_FAIL_INDEX(p_idx, items.size());
- items[p_idx].disabled = p_disabled;
+ items.write[p_idx].disabled = p_disabled;
update();
}
@@ -229,7 +229,7 @@ void ItemList::set_item_metadata(int p_idx, const Variant &p_metadata) {
ERR_FAIL_INDEX(p_idx, items.size());
- items[p_idx].metadata = p_metadata;
+ items.write[p_idx].metadata = p_metadata;
update();
shape_changed = true;
}
@@ -250,7 +250,7 @@ void ItemList::select(int p_idx, bool p_single) {
}
for (int i = 0; i < items.size(); i++) {
- items[i].selected = p_idx == i;
+ items.write[i].selected = p_idx == i;
}
current = p_idx;
@@ -258,7 +258,7 @@ void ItemList::select(int p_idx, bool p_single) {
} else {
if (items[p_idx].selectable && !items[p_idx].disabled) {
- items[p_idx].selected = true;
+ items.write[p_idx].selected = true;
}
}
update();
@@ -268,10 +268,10 @@ void ItemList::unselect(int p_idx) {
ERR_FAIL_INDEX(p_idx, items.size());
if (select_mode != SELECT_MULTI) {
- items[p_idx].selected = false;
+ items.write[p_idx].selected = false;
current = -1;
} else {
- items[p_idx].selected = false;
+ items.write[p_idx].selected = false;
}
update();
}
@@ -283,9 +283,9 @@ void ItemList::unselect_all() {
for (int i = 0; i < items.size(); i++) {
- items[i].selected = false;
+ items.write[i].selected = false;
}
-
+ current = -1;
update();
}
@@ -869,8 +869,8 @@ void ItemList::_notification(int p_what) {
// elements need to adapt to the selected size
minsize.y += vseparation;
minsize.x += hseparation;
- items[i].rect_cache.size = minsize;
- items[i].min_rect_cache.size = minsize;
+ items.write[i].rect_cache.size = minsize;
+ items.write[i].min_rect_cache.size = minsize;
}
int fit_size = size.x - bg->get_minimum_size().width - mw;
@@ -897,8 +897,8 @@ void ItemList::_notification(int p_what) {
}
if (same_column_width)
- items[i].rect_cache.size.x = max_column_width;
- items[i].rect_cache.position = ofs;
+ items.write[i].rect_cache.size.x = max_column_width;
+ items.write[i].rect_cache.position = ofs;
max_h = MAX(max_h, items[i].rect_cache.size.y);
ofs.x += items[i].rect_cache.size.x + hseparation;
col++;
@@ -908,7 +908,7 @@ void ItemList::_notification(int p_what) {
separators.push_back(ofs.y + max_h + vseparation / 2);
for (int j = i; j >= 0 && col > 0; j--, col--) {
- items[j].rect_cache.size.y = max_h;
+ items.write[j].rect_cache.size.y = max_h;
}
ofs.x = 0;
@@ -919,7 +919,7 @@ void ItemList::_notification(int p_what) {
}
for (int j = items.size() - 1; j >= 0 && col > 0; j--, col--) {
- items[j].rect_cache.size.y = max_h;
+ items.write[j].rect_cache.size.y = max_h;
}
if (all_fit) {
@@ -1103,8 +1103,8 @@ void ItemList::_notification(int p_what) {
int cs = j < ss ? font->get_char_size(items[i].text[j], items[i].text[j + 1]).x : 0;
if (ofs + cs > max_len || j == ss) {
- line_limit_cache[line] = j;
- line_size_cache[line] = ofs;
+ line_limit_cache.write[line] = j;
+ line_size_cache.write[line] = ofs;
line++;
ofs = 0;
if (line >= max_text_lines)
@@ -1423,6 +1423,9 @@ void ItemList::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_item_custom_bg_color", "idx", "custom_bg_color"), &ItemList::set_item_custom_bg_color);
ClassDB::bind_method(D_METHOD("get_item_custom_bg_color", "idx"), &ItemList::get_item_custom_bg_color);
+ ClassDB::bind_method(D_METHOD("set_item_custom_fg_color", "idx", "custom_fg_color"), &ItemList::set_item_custom_fg_color);
+ ClassDB::bind_method(D_METHOD("get_item_custom_fg_color", "idx"), &ItemList::get_item_custom_fg_color);
+
ClassDB::bind_method(D_METHOD("set_item_tooltip_enabled", "idx", "enable"), &ItemList::set_item_tooltip_enabled);
ClassDB::bind_method(D_METHOD("is_item_tooltip_enabled", "idx"), &ItemList::is_item_tooltip_enabled);
diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp
index 9af479c1cc..0b36e1663c 100644
--- a/scene/gui/label.cpp
+++ b/scene/gui/label.cpp
@@ -75,7 +75,7 @@ void Label::_notification(int p_what) {
if (p_what == NOTIFICATION_DRAW) {
- if (clip || autowrap) {
+ if (clip) {
VisualServer::get_singleton()->canvas_item_set_clip(get_canvas_item(), true);
}
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index b71a4dd133..549daecdae 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -35,7 +35,9 @@
#include "os/os.h"
#include "print_string.h"
#include "translation.h"
+
#ifdef TOOLS_ENABLED
+#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
#endif
@@ -64,6 +66,12 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
_reset_caret_blink_timer();
if (b->is_pressed()) {
+ if (!text.empty() && is_editable() && _is_over_clear_button(b->get_position())) {
+ clear_button_status.press_attempt = true;
+ clear_button_status.pressing_inside = true;
+ return;
+ }
+
shift_selection_check_pre(b->get_shift());
set_cursor_at_pixel_pos(b->get_position().x);
@@ -100,6 +108,15 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
} else {
+ if (!text.empty() && is_editable() && clear_button_enabled) {
+ bool press_attempt = clear_button_status.press_attempt;
+ clear_button_status.press_attempt = false;
+ if (press_attempt && clear_button_status.pressing_inside && _is_over_clear_button(b->get_position())) {
+ clear();
+ return;
+ }
+ }
+
if ((!selection.creating) && (!selection.doubleclick)) {
deselect();
}
@@ -117,6 +134,14 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
if (m.is_valid()) {
+ if (!text.empty() && is_editable() && clear_button_enabled) {
+ bool last_press_inside = clear_button_status.pressing_inside;
+ clear_button_status.pressing_inside = clear_button_status.press_attempt && _is_over_clear_button(m->get_position());
+ if (last_press_inside != clear_button_status.pressing_inside) {
+ update();
+ }
+ }
+
if (m->get_button_mask() & BUTTON_LEFT) {
if (selection.creating) {
@@ -548,6 +573,25 @@ void LineEdit::drop_data(const Point2 &p_point, const Variant &p_data) {
}
}
+Control::CursorShape LineEdit::get_cursor_shape(const Point2 &p_pos) const {
+ if (!text.empty() && is_editable() && _is_over_clear_button(p_pos)) {
+ return CURSOR_ARROW;
+ }
+ return Control::get_cursor_shape(p_pos);
+}
+
+bool LineEdit::_is_over_clear_button(const Point2 &p_pos) const {
+ if (!clear_button_enabled || !has_point(p_pos)) {
+ return false;
+ }
+ Ref<Texture> icon = Control::get_icon("clear");
+ int x_ofs = get_stylebox("normal")->get_offset().x;
+ if (p_pos.x > get_size().width - icon->get_width() - x_ofs) {
+ return true;
+ }
+ return false;
+}
+
void LineEdit::_notification(int p_what) {
switch (p_what) {
@@ -640,7 +684,7 @@ void LineEdit::_notification(int p_what) {
int char_ofs = window_pos;
int y_area = height - style->get_minimum_size().height;
- int y_ofs = style->get_offset().y;
+ int y_ofs = style->get_offset().y + (y_area - font->get_height()) / 2;
int font_ascent = font->get_ascent();
@@ -655,10 +699,26 @@ void LineEdit::_notification(int p_what) {
font_color.a *= placeholder_alpha;
font_color.a *= disabled_alpha;
- if (has_icon("right_icon")) {
- Ref<Texture> r_icon = Control::get_icon("right_icon");
- ofs_max -= r_icon->get_width();
- r_icon->draw(ci, Point2(width - r_icon->get_width() - x_ofs, height / 2 - r_icon->get_height() / 2), Color(1, 1, 1, disabled_alpha * .9));
+ bool display_clear_icon = !using_placeholder && is_editable() && clear_button_enabled;
+ if (right_icon.is_valid() || display_clear_icon) {
+ Ref<Texture> r_icon = display_clear_icon ? Control::get_icon("clear") : right_icon;
+ Color color_icon(1, 1, 1, disabled_alpha * .9);
+ if (display_clear_icon) {
+ if (clear_button_status.press_attempt && clear_button_status.pressing_inside) {
+ color_icon = get_color("clear_button_color_pressed");
+ } else {
+ color_icon = get_color("clear_button_color");
+ }
+ }
+ r_icon->draw(ci, Point2(width - r_icon->get_width() - style->get_margin(MARGIN_RIGHT), height / 2 - r_icon->get_height() / 2), color_icon);
+
+ if (align == ALIGN_CENTER) {
+ if (window_pos == 0) {
+ x_ofs = MAX(style->get_margin(MARGIN_LEFT), int(size.width - cached_text_width - r_icon->get_width() - style->get_margin(MARGIN_RIGHT) * 2) / 2);
+ }
+ } else {
+ x_ofs = MAX(style->get_margin(MARGIN_LEFT), x_ofs - r_icon->get_width() - style->get_margin(MARGIN_RIGHT));
+ }
}
int caret_height = font->get_height() > y_area ? y_area : font->get_height();
@@ -716,7 +776,11 @@ void LineEdit::_notification(int p_what) {
if (char_ofs == cursor_pos && draw_caret) {
if (ime_text.length() == 0) {
+#ifdef TOOLS_ENABLED
+ VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(x_ofs, y_ofs), Size2(Math::round(EDSCALE), caret_height)), cursor_color);
+#else
VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(x_ofs, y_ofs), Size2(1, caret_height)), cursor_color);
+#endif
}
}
@@ -755,7 +819,11 @@ void LineEdit::_notification(int p_what) {
if (char_ofs == cursor_pos && draw_caret) { //may be at the end
if (ime_text.length() == 0) {
+#ifdef TOOLS_ENABLED
+ VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(x_ofs, y_ofs), Size2(Math::round(EDSCALE), caret_height)), cursor_color);
+#else
VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(x_ofs, y_ofs), Size2(1, caret_height)), cursor_color);
+#endif
}
}
@@ -1086,9 +1154,8 @@ void LineEdit::set_cursor_position(int p_pos) {
} else if (cursor_pos > window_pos) {
/* Adjust window if cursor goes too much to the right */
int window_width = get_size().width - style->get_minimum_size().width;
- if (has_icon("right_icon")) {
- Ref<Texture> r_icon = Control::get_icon("right_icon");
- window_width -= r_icon->get_width();
+ if (right_icon.is_valid()) {
+ window_width -= right_icon->get_width();
}
if (window_width < 0)
@@ -1375,10 +1442,26 @@ void LineEdit::set_expand_to_text_length(bool p_enabled) {
}
bool LineEdit::get_expand_to_text_length() const {
-
return expand_to_text_length;
}
+void LineEdit::set_clear_button_enabled(bool p_enabled) {
+ clear_button_enabled = p_enabled;
+ update();
+}
+
+bool LineEdit::is_clear_button_enabled() const {
+ return clear_button_enabled;
+}
+
+void LineEdit::set_right_icon(const Ref<Texture> &p_icon) {
+ if (right_icon == p_icon) {
+ return;
+ }
+ right_icon = p_icon;
+ update();
+}
+
void LineEdit::_ime_text_callback(void *p_self, String p_text, Point2 p_selection) {
LineEdit *self = (LineEdit *)p_self;
self->ime_text = p_text;
@@ -1471,6 +1554,8 @@ void LineEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_menu"), &LineEdit::get_menu);
ClassDB::bind_method(D_METHOD("set_context_menu_enabled", "enable"), &LineEdit::set_context_menu_enabled);
ClassDB::bind_method(D_METHOD("is_context_menu_enabled"), &LineEdit::is_context_menu_enabled);
+ ClassDB::bind_method(D_METHOD("set_clear_button_enabled", "enable"), &LineEdit::set_clear_button_enabled);
+ ClassDB::bind_method(D_METHOD("is_clear_button_enabled"), &LineEdit::is_clear_button_enabled);
ADD_SIGNAL(MethodInfo("text_changed", PropertyInfo(Variant::STRING, "new_text")));
ADD_SIGNAL(MethodInfo("text_entered", PropertyInfo(Variant::STRING, "new_text")));
@@ -1498,6 +1583,7 @@ void LineEdit::_bind_methods() {
ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "expand_to_text_length"), "set_expand_to_text_length", "get_expand_to_text_length");
ADD_PROPERTY(PropertyInfo(Variant::INT, "focus_mode", PROPERTY_HINT_ENUM, "None,Click,All"), "set_focus_mode", "get_focus_mode");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "context_menu_enabled"), "set_context_menu_enabled", "is_context_menu_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clear_button_enabled"), "set_clear_button_enabled", "is_clear_button_enabled");
ADD_GROUP("Placeholder", "placeholder_");
ADD_PROPERTYNZ(PropertyInfo(Variant::STRING, "placeholder_text"), "set_placeholder", "get_placeholder");
ADD_PROPERTYNZ(PropertyInfo(Variant::REAL, "placeholder_alpha", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_placeholder_alpha", "get_placeholder_alpha");
@@ -1522,6 +1608,7 @@ LineEdit::LineEdit() {
secret_character = "*";
text_changed_dirty = false;
placeholder_alpha = 0.6;
+ clear_button_enabled = false;
deselect();
set_focus_mode(FOCUS_ALL);
diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h
index e9314ba8dd..5294d99da0 100644
--- a/scene/gui/line_edit.h
+++ b/scene/gui/line_edit.h
@@ -87,6 +87,10 @@ private:
int cached_width;
int cached_placeholder_width;
+ bool clear_button_enabled;
+
+ Ref<Texture> right_icon;
+
struct Selection {
int begin;
@@ -105,6 +109,13 @@ private:
List<TextOperation> undo_stack;
List<TextOperation>::Element *undo_stack_pos;
+ struct ClearButtonStatus {
+ bool press_attempt;
+ bool pressing_inside;
+ } clear_button_status;
+
+ bool _is_over_clear_button(const Point2 &p_pos) const;
+
void _clear_undo_stack();
void _clear_redo();
void _create_undo_state();
@@ -150,6 +161,8 @@ public:
virtual bool can_drop_data(const Point2 &p_point, const Variant &p_data) const;
virtual void drop_data(const Point2 &p_point, const Variant &p_data);
+ virtual CursorShape get_cursor_shape(const Point2 &p_pos) const;
+
void menu_option(int p_option);
void set_context_menu_enabled(bool p_enable);
bool is_context_menu_enabled();
@@ -201,6 +214,11 @@ public:
void set_expand_to_text_length(bool p_enabled);
bool get_expand_to_text_length() const;
+ void set_clear_button_enabled(bool p_enabled);
+ bool is_clear_button_enabled() const;
+
+ void set_right_icon(const Ref<Texture> &p_icon);
+
virtual bool is_text_field() const;
LineEdit();
~LineEdit();
diff --git a/scene/gui/menu_button.h b/scene/gui/menu_button.h
index 2356444ecb..0636accfee 100644
--- a/scene/gui/menu_button.h
+++ b/scene/gui/menu_button.h
@@ -43,7 +43,6 @@ class MenuButton : public Button {
bool clicked;
bool disable_shortcuts;
PopupMenu *popup;
- virtual void pressed();
void _unhandled_key_input(Ref<InputEvent> p_event);
Array _get_items() const;
@@ -55,6 +54,8 @@ protected:
static void _bind_methods();
public:
+ virtual void pressed();
+
PopupMenu *get_popup() const;
void set_disable_shortcuts(bool p_disabled);
diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp
index c5e4149782..2901176a69 100644
--- a/scene/gui/option_button.cpp
+++ b/scene/gui/option_button.cpp
@@ -36,7 +36,7 @@ Size2 OptionButton::get_minimum_size() const {
Size2 minsize = Button::get_minimum_size();
if (has_icon("arrow"))
- minsize.width += Control::get_icon("arrow")->get_width();
+ minsize.width += Control::get_icon("arrow")->get_width() + get_constant("hseparation");
return minsize;
}
diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp
index f5890fa2ee..436dda41a4 100644
--- a/scene/gui/popup_menu.cpp
+++ b/scene/gui/popup_menu.cpp
@@ -410,7 +410,7 @@ void PopupMenu::_notification(int p_what) {
case NOTIFICATION_TRANSLATION_CHANGED: {
for (int i = 0; i < items.size(); i++) {
- items[i].xl_text = tr(items[i].text);
+ items.write[i].xl_text = tr(items[i].text);
}
minimum_size_changed();
@@ -430,6 +430,8 @@ void PopupMenu::_notification(int p_what) {
Ref<Texture> uncheck[] = { get_icon("unchecked"), get_icon("radio_unchecked") };
Ref<Texture> submenu = get_icon("submenu");
Ref<StyleBox> separator = get_stylebox("separator");
+ Ref<StyleBox> labeled_separator_left = get_stylebox("labeled_separator_left");
+ Ref<StyleBox> labeled_separator_right = get_stylebox("labeled_separator_right");
style->draw(ci, Rect2(Point2(), get_size()));
Point2 ofs = style->get_offset();
@@ -466,10 +468,25 @@ void PopupMenu::_notification(int p_what) {
hover->draw(ci, Rect2(item_ofs + Point2(-hseparation, -vseparation / 2), Size2(get_size().width - style->get_minimum_size().width + hseparation * 2, h + vseparation)));
}
+ String text = items[i].shortcut.is_valid() ? String(tr(items[i].shortcut->get_name())) : items[i].xl_text;
+
if (items[i].separator) {
int sep_h = separator->get_center_size().height + separator->get_minimum_size().height;
- separator->draw(ci, Rect2(item_ofs + Point2(0, Math::floor((h - sep_h) / 2.0)), Size2(get_size().width - style->get_minimum_size().width, sep_h)));
+ if (text != String()) {
+ int ss = font->get_string_size(text).width;
+ int center = (get_size().width) / 2;
+ int l = center - ss / 2;
+ int r = center + ss / 2;
+ if (l > item_ofs.x) {
+ labeled_separator_left->draw(ci, Rect2(item_ofs + Point2(0, Math::floor((h - sep_h) / 2.0)), Size2(MAX(0, l - item_ofs.x), sep_h)));
+ }
+ if (r < get_size().width - style->get_margin(MARGIN_RIGHT)) {
+ labeled_separator_right->draw(ci, Rect2(Point2(r, item_ofs.y + Math::floor((h - sep_h) / 2.0)), Size2(MAX(0, get_size().width - style->get_margin(MARGIN_RIGHT) - r), sep_h)));
+ }
+ } else {
+ separator->draw(ci, Rect2(item_ofs + Point2(0, Math::floor((h - sep_h) / 2.0)), Size2(get_size().width - style->get_minimum_size().width, sep_h)));
+ }
}
if (items[i].checkable_type) {
@@ -489,8 +506,13 @@ void PopupMenu::_notification(int p_what) {
}
item_ofs.y += font->get_ascent();
- String text = items[i].shortcut.is_valid() ? String(tr(items[i].shortcut->get_name())) : items[i].xl_text;
- if (!items[i].separator) {
+ if (items[i].separator) {
+
+ if (text != String()) {
+ int center = (get_size().width - font->get_string_size(text).width) / 2;
+ font->draw(ci, Point2(center, item_ofs.y + Math::floor((h - font_h) / 2.0)), text, font_color_disabled);
+ }
+ } else {
font->draw(ci, item_ofs + Point2(0, Math::floor((h - font_h) / 2.0)), text, items[i].disabled ? font_color_disabled : (i == mouse_over ? font_color_hover : font_color));
}
@@ -502,12 +524,17 @@ void PopupMenu::_notification(int p_what) {
font->draw(ci, item_ofs + Point2(0, Math::floor((h - font_h) / 2.0)), text, i == mouse_over ? font_color_hover : font_color_accel);
}
- items[i]._ofs_cache = ofs.y;
+ items.write[i]._ofs_cache = ofs.y;
ofs.y += h;
}
} break;
+ case MainLoop::NOTIFICATION_WM_FOCUS_OUT: {
+
+ if (hide_on_window_lose_focus)
+ hide();
+ } break;
case NOTIFICATION_MOUSE_ENTER: {
grab_focus();
@@ -600,7 +627,7 @@ void PopupMenu::add_check_item(const String &p_label, int p_ID, uint32_t p_accel
void PopupMenu::add_radio_check_item(const String &p_label, int p_ID, uint32_t p_accel) {
add_check_item(p_label, p_ID, p_accel);
- items[items.size() - 1].checkable_type = Item::CHECKABLE_TYPE_RADIO_BUTTON;
+ items.write[items.size() - 1].checkable_type = Item::CHECKABLE_TYPE_RADIO_BUTTON;
update();
minimum_size_changed();
}
@@ -608,7 +635,7 @@ void PopupMenu::add_radio_check_item(const String &p_label, int p_ID, uint32_t p
void PopupMenu::add_icon_radio_check_item(const Ref<Texture> &p_icon, const String &p_label, int p_ID, uint32_t p_accel) {
add_icon_check_item(p_icon, p_label, p_ID, p_accel);
- items[items.size() - 1].checkable_type = Item::CHECKABLE_TYPE_RADIO_BUTTON;
+ items.write[items.size() - 1].checkable_type = Item::CHECKABLE_TYPE_RADIO_BUTTON;
update();
minimum_size_changed();
}
@@ -680,7 +707,7 @@ void PopupMenu::add_check_shortcut(const Ref<ShortCut> &p_shortcut, int p_ID, bo
void PopupMenu::add_radio_check_shortcut(const Ref<ShortCut> &p_shortcut, int p_ID, bool p_global) {
add_check_shortcut(p_shortcut, p_ID, p_global);
- items[items.size() - 1].checkable_type = Item::CHECKABLE_TYPE_RADIO_BUTTON;
+ items.write[items.size() - 1].checkable_type = Item::CHECKABLE_TYPE_RADIO_BUTTON;
update();
minimum_size_changed();
}
@@ -702,8 +729,8 @@ void PopupMenu::add_multistate_item(const String &p_label, int p_max_states, int
void PopupMenu::set_item_text(int p_idx, const String &p_text) {
ERR_FAIL_INDEX(p_idx, items.size());
- items[p_idx].text = p_text;
- items[p_idx].xl_text = tr(p_text);
+ items.write[p_idx].text = p_text;
+ items.write[p_idx].xl_text = tr(p_text);
update();
minimum_size_changed();
@@ -711,7 +738,7 @@ void PopupMenu::set_item_text(int p_idx, const String &p_text) {
void PopupMenu::set_item_icon(int p_idx, const Ref<Texture> &p_icon) {
ERR_FAIL_INDEX(p_idx, items.size());
- items[p_idx].icon = p_icon;
+ items.write[p_idx].icon = p_icon;
update();
minimum_size_changed();
@@ -720,7 +747,7 @@ void PopupMenu::set_item_checked(int p_idx, bool p_checked) {
ERR_FAIL_INDEX(p_idx, items.size());
- items[p_idx].checked = p_checked;
+ items.write[p_idx].checked = p_checked;
update();
minimum_size_changed();
@@ -728,7 +755,7 @@ void PopupMenu::set_item_checked(int p_idx, bool p_checked) {
void PopupMenu::set_item_id(int p_idx, int p_ID) {
ERR_FAIL_INDEX(p_idx, items.size());
- items[p_idx].ID = p_ID;
+ items.write[p_idx].ID = p_ID;
update();
minimum_size_changed();
@@ -737,7 +764,7 @@ void PopupMenu::set_item_id(int p_idx, int p_ID) {
void PopupMenu::set_item_accelerator(int p_idx, uint32_t p_accel) {
ERR_FAIL_INDEX(p_idx, items.size());
- items[p_idx].accel = p_accel;
+ items.write[p_idx].accel = p_accel;
update();
minimum_size_changed();
@@ -746,7 +773,7 @@ void PopupMenu::set_item_accelerator(int p_idx, uint32_t p_accel) {
void PopupMenu::set_item_metadata(int p_idx, const Variant &p_meta) {
ERR_FAIL_INDEX(p_idx, items.size());
- items[p_idx].metadata = p_meta;
+ items.write[p_idx].metadata = p_meta;
update();
minimum_size_changed();
}
@@ -754,7 +781,7 @@ void PopupMenu::set_item_metadata(int p_idx, const Variant &p_meta) {
void PopupMenu::set_item_disabled(int p_idx, bool p_disabled) {
ERR_FAIL_INDEX(p_idx, items.size());
- items[p_idx].disabled = p_disabled;
+ items.write[p_idx].disabled = p_disabled;
update();
minimum_size_changed();
}
@@ -762,7 +789,7 @@ void PopupMenu::set_item_disabled(int p_idx, bool p_disabled) {
void PopupMenu::set_item_submenu(int p_idx, const String &p_submenu) {
ERR_FAIL_INDEX(p_idx, items.size());
- items[p_idx].submenu = p_submenu;
+ items.write[p_idx].submenu = p_submenu;
update();
minimum_size_changed();
}
@@ -770,7 +797,7 @@ void PopupMenu::set_item_submenu(int p_idx, const String &p_submenu) {
void PopupMenu::toggle_item_checked(int p_idx) {
ERR_FAIL_INDEX(p_idx, items.size());
- items[p_idx].checked = !items[p_idx].checked;
+ items.write[p_idx].checked = !items[p_idx].checked;
update();
minimum_size_changed();
}
@@ -864,7 +891,7 @@ int PopupMenu::get_item_state(int p_idx) const {
void PopupMenu::set_item_as_separator(int p_idx, bool p_separator) {
ERR_FAIL_INDEX(p_idx, items.size());
- items[p_idx].separator = p_separator;
+ items.write[p_idx].separator = p_separator;
update();
}
@@ -876,21 +903,21 @@ bool PopupMenu::is_item_separator(int p_idx) const {
void PopupMenu::set_item_as_checkable(int p_idx, bool p_checkable) {
ERR_FAIL_INDEX(p_idx, items.size());
- items[p_idx].checkable_type = p_checkable ? Item::CHECKABLE_TYPE_CHECK_BOX : Item::CHECKABLE_TYPE_NONE;
+ items.write[p_idx].checkable_type = p_checkable ? Item::CHECKABLE_TYPE_CHECK_BOX : Item::CHECKABLE_TYPE_NONE;
update();
}
void PopupMenu::set_item_as_radio_checkable(int p_idx, bool p_radio_checkable) {
ERR_FAIL_INDEX(p_idx, items.size());
- items[p_idx].checkable_type = p_radio_checkable ? Item::CHECKABLE_TYPE_RADIO_BUTTON : Item::CHECKABLE_TYPE_NONE;
+ items.write[p_idx].checkable_type = p_radio_checkable ? Item::CHECKABLE_TYPE_RADIO_BUTTON : Item::CHECKABLE_TYPE_NONE;
update();
}
void PopupMenu::set_item_tooltip(int p_idx, const String &p_tooltip) {
ERR_FAIL_INDEX(p_idx, items.size());
- items[p_idx].tooltip = p_tooltip;
+ items.write[p_idx].tooltip = p_tooltip;
update();
}
@@ -899,8 +926,8 @@ void PopupMenu::set_item_shortcut(int p_idx, const Ref<ShortCut> &p_shortcut, bo
if (items[p_idx].shortcut.is_valid()) {
_unref_shortcut(items[p_idx].shortcut);
}
- items[p_idx].shortcut = p_shortcut;
- items[p_idx].shortcut_is_global = p_global;
+ items.write[p_idx].shortcut = p_shortcut;
+ items.write[p_idx].shortcut_is_global = p_global;
if (items[p_idx].shortcut.is_valid()) {
_ref_shortcut(items[p_idx].shortcut);
@@ -912,7 +939,7 @@ void PopupMenu::set_item_shortcut(int p_idx, const Ref<ShortCut> &p_shortcut, bo
void PopupMenu::set_item_h_offset(int p_idx, int p_offset) {
ERR_FAIL_INDEX(p_idx, items.size());
- items[p_idx].h_ofs = p_offset;
+ items.write[p_idx].h_ofs = p_offset;
update();
minimum_size_changed();
}
@@ -920,14 +947,14 @@ void PopupMenu::set_item_h_offset(int p_idx, int p_offset) {
void PopupMenu::set_item_multistate(int p_idx, int p_state) {
ERR_FAIL_INDEX(p_idx, items.size());
- items[p_idx].state = p_state;
+ items.write[p_idx].state = p_state;
update();
}
void PopupMenu::set_item_shortcut_disabled(int p_idx, bool p_disabled) {
ERR_FAIL_INDEX(p_idx, items.size());
- items[p_idx].shortcut_is_disabled = p_disabled;
+ items.write[p_idx].shortcut_is_disabled = p_disabled;
update();
}
@@ -938,9 +965,9 @@ void PopupMenu::toggle_item_multistate(int p_idx) {
return;
}
- ++items[p_idx].state;
- if (items[p_idx].max_states <= items[p_idx].state)
- items[p_idx].state = 0;
+ ++items.write[p_idx].state;
+ if (items.write[p_idx].max_states <= items[p_idx].state)
+ items.write[p_idx].state = 0;
update();
}
@@ -1022,10 +1049,8 @@ void PopupMenu::activate_item(int p_item) {
ERR_FAIL_INDEX(p_item, items.size());
ERR_FAIL_COND(items[p_item].separator);
int id = items[p_item].ID >= 0 ? items[p_item].ID : p_item;
- emit_signal("id_pressed", id);
- emit_signal("index_pressed", p_item);
- //hide all parent PopupMenue's
+ //hide all parent PopupMenus
Node *next = get_parent();
PopupMenu *pop = Object::cast_to<PopupMenu>(next);
while (pop) {
@@ -1049,16 +1074,23 @@ void PopupMenu::activate_item(int p_item) {
// Hides popup by default; unless otherwise specified
// by using set_hide_on_item_selection and set_hide_on_checkable_item_selection
+ bool need_hide = true;
+
if (items[p_item].checkable_type) {
if (!hide_on_checkable_item_selection)
- return;
+ need_hide = false;
} else if (0 < items[p_item].max_states) {
if (!hide_on_multistate_item_selection)
- return;
+ need_hide = false;
} else if (!hide_on_item_selection)
- return;
+ need_hide = false;
+
+ emit_signal("id_pressed", id);
+ emit_signal("index_pressed", p_item);
- hide();
+ if (need_hide) {
+ hide();
+ }
}
void PopupMenu::remove_item(int p_idx) {
@@ -1071,13 +1103,18 @@ void PopupMenu::remove_item(int p_idx) {
items.remove(p_idx);
update();
+ minimum_size_changed();
}
-void PopupMenu::add_separator() {
+void PopupMenu::add_separator(const String &p_text) {
Item sep;
sep.separator = true;
sep.ID = -1;
+ if (p_text != String()) {
+ sep.text = p_text;
+ sep.xl_text = tr(p_text);
+ }
items.push_back(sep);
update();
}
@@ -1223,6 +1260,16 @@ float PopupMenu::get_submenu_popup_delay() const {
return submenu_timer->get_wait_time();
}
+void PopupMenu::set_hide_on_window_lose_focus(bool p_enabled) {
+
+ hide_on_window_lose_focus = p_enabled;
+}
+
+bool PopupMenu::is_hide_on_window_lose_focus() const {
+
+ return hide_on_window_lose_focus;
+}
+
String PopupMenu::get_tooltip(const Point2 &p_pos) const {
int over = _get_mouse_over(p_pos);
@@ -1310,7 +1357,7 @@ void PopupMenu::_bind_methods() {
ClassDB::bind_method(D_METHOD("remove_item", "idx"), &PopupMenu::remove_item);
- ClassDB::bind_method(D_METHOD("add_separator"), &PopupMenu::add_separator);
+ ClassDB::bind_method(D_METHOD("add_separator", "label"), &PopupMenu::add_separator, DEFVAL(String()));
ClassDB::bind_method(D_METHOD("clear"), &PopupMenu::clear);
ClassDB::bind_method(D_METHOD("_set_items"), &PopupMenu::_set_items);
@@ -1327,6 +1374,10 @@ void PopupMenu::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_submenu_popup_delay", "seconds"), &PopupMenu::set_submenu_popup_delay);
ClassDB::bind_method(D_METHOD("get_submenu_popup_delay"), &PopupMenu::get_submenu_popup_delay);
+
+ ClassDB::bind_method(D_METHOD("set_hide_on_window_lose_focus", "enable"), &PopupMenu::set_hide_on_window_lose_focus);
+ ClassDB::bind_method(D_METHOD("is_hide_on_window_lose_focus"), &PopupMenu::is_hide_on_window_lose_focus);
+
ClassDB::bind_method(D_METHOD("_submenu_timeout"), &PopupMenu::_submenu_timeout);
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "items", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_items", "_get_items");
diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h
index 44f02a9d3d..a06a17c9fe 100644
--- a/scene/gui/popup_menu.h
+++ b/scene/gui/popup_menu.h
@@ -101,6 +101,7 @@ class PopupMenu : public Popup {
bool hide_on_item_selection;
bool hide_on_checkable_item_selection;
bool hide_on_multistate_item_selection;
+ bool hide_on_window_lose_focus;
Vector2 moved;
Array _get_items() const;
@@ -180,7 +181,7 @@ public:
void remove_item(int p_idx);
- void add_separator();
+ void add_separator(const String &p_text = String());
void clear();
@@ -207,6 +208,9 @@ public:
virtual void popup(const Rect2 &p_bounds = Rect2());
+ void set_hide_on_window_lose_focus(bool p_enabled);
+ bool is_hide_on_window_lose_focus() const;
+
PopupMenu();
~PopupMenu();
};
diff --git a/scene/gui/range.cpp b/scene/gui/range.cpp
index 4062e48640..09d8664240 100644
--- a/scene/gui/range.cpp
+++ b/scene/gui/range.cpp
@@ -260,8 +260,8 @@ void Range::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "ratio", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_as_ratio", "get_as_ratio");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "exp_edit"), "set_exp_ratio", "is_ratio_exp");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "rounded"), "set_use_rounded_values", "is_using_rounded_values");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "allow_greater"), "set_allow_greater", "is_greater_allowed");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "allow_lesser"), "set_allow_lesser", "is_lesser_allowed");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_greater"), "set_allow_greater", "is_greater_allowed");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_lesser"), "set_allow_lesser", "is_lesser_allowed");
}
void Range::set_use_rounded_values(bool p_enable) {
diff --git a/scene/gui/reference_rect.cpp b/scene/gui/reference_rect.cpp
index 5e25f43daf..74e68598f4 100644
--- a/scene/gui/reference_rect.cpp
+++ b/scene/gui/reference_rect.cpp
@@ -39,9 +39,25 @@ void ReferenceRect::_notification(int p_what) {
if (!is_inside_tree())
return;
if (Engine::get_singleton()->is_editor_hint())
- draw_style_box(get_stylebox("border"), Rect2(Point2(), get_size()));
+ draw_rect(Rect2(Point2(), get_size()), border_color, false);
}
}
+void ReferenceRect::set_border_color(const Color &color) {
+ border_color = color;
+}
+
+Color ReferenceRect::get_border_color() const {
+ return border_color;
+}
+
+void ReferenceRect::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("get_border_color"), &ReferenceRect::get_border_color);
+ ClassDB::bind_method(D_METHOD("set_border_color", "color"), &ReferenceRect::set_border_color);
+
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "border_color"), "set_border_color", "get_border_color");
+}
+
ReferenceRect::ReferenceRect() {
+ border_color = Color(1, 0, 0);
}
diff --git a/scene/gui/reference_rect.h b/scene/gui/reference_rect.h
index 473e348c85..9fad1a06b0 100644
--- a/scene/gui/reference_rect.h
+++ b/scene/gui/reference_rect.h
@@ -36,12 +36,17 @@
class ReferenceRect : public Control {
GDCLASS(ReferenceRect, Control);
+ Color border_color;
protected:
void _notification(int p_what);
+ static void _bind_methods();
public:
ReferenceRect();
+
+ void set_border_color(const Color &color);
+ Color get_border_color() const;
};
#endif // REFERENCE_RECT_H
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index ce2e3538da..a3748bf14c 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -149,7 +149,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
if (r_click_item)
*r_click_item = NULL;
}
- Line &l = p_frame->lines[p_line];
+ Line &l = p_frame->lines.write[p_line];
Item *it = l.from;
int line_ofs = 0;
@@ -535,9 +535,9 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
int idx = 0;
//set minimums to zero
for (int i = 0; i < table->columns.size(); i++) {
- table->columns[i].min_width = 0;
- table->columns[i].max_width = 0;
- table->columns[i].width = 0;
+ table->columns.write[i].min_width = 0;
+ table->columns.write[i].max_width = 0;
+ table->columns.write[i].width = 0;
}
//compute minimum width for each cell
const int available_width = p_width - hseparation * (table->columns.size() - 1) - wofs;
@@ -553,8 +553,8 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
for (int i = 0; i < frame->lines.size(); i++) {
_process_line(frame, Point2(), ly, available_width, i, PROCESS_CACHE, cfont, Color(), font_color_shadow, use_outline, shadow_ofs);
- table->columns[column].min_width = MAX(table->columns[column].min_width, frame->lines[i].minimum_width);
- table->columns[column].max_width = MAX(table->columns[column].max_width, frame->lines[i].maximum_width);
+ table->columns.write[column].min_width = MAX(table->columns[column].min_width, frame->lines[i].minimum_width);
+ table->columns.write[column].max_width = MAX(table->columns[column].max_width, frame->lines[i].maximum_width);
}
idx++;
}
@@ -568,16 +568,16 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
for (int i = 0; i < table->columns.size(); i++) {
remaining_width -= table->columns[i].min_width;
if (table->columns[i].max_width > table->columns[i].min_width)
- table->columns[i].expand = true;
+ table->columns.write[i].expand = true;
if (table->columns[i].expand)
total_ratio += table->columns[i].expand_ratio;
}
//assign actual widths
for (int i = 0; i < table->columns.size(); i++) {
- table->columns[i].width = table->columns[i].min_width;
+ table->columns.write[i].width = table->columns[i].min_width;
if (table->columns[i].expand)
- table->columns[i].width += table->columns[i].expand_ratio * remaining_width / total_ratio;
+ table->columns.write[i].width += table->columns[i].expand_ratio * remaining_width / total_ratio;
table->total_width += table->columns[i].width + hseparation;
}
@@ -592,7 +592,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
int dif = table->columns[i].width - table->columns[i].max_width;
if (dif > 0) {
table_need_fit = true;
- table->columns[i].width = table->columns[i].max_width;
+ table->columns.write[i].width = table->columns[i].max_width;
table->total_width -= dif;
total_ratio -= table->columns[i].expand_ratio;
}
@@ -606,7 +606,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
if (dif > 0) {
int slice = table->columns[i].expand_ratio * remaining_width / total_ratio;
int incr = MIN(dif, slice);
- table->columns[i].width += incr;
+ table->columns.write[i].width += incr;
table->total_width += incr;
}
}
@@ -626,8 +626,8 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
int ly = 0;
_process_line(frame, Point2(), ly, table->columns[column].width, i, PROCESS_CACHE, cfont, Color(), font_color_shadow, use_outline, shadow_ofs);
- frame->lines[i].height_cache = ly; //actual height
- frame->lines[i].height_accum_cache = ly; //actual height
+ frame->lines.write[i].height_cache = ly; //actual height
+ frame->lines.write[i].height_accum_cache = ly; //actual height
}
idx++;
}
@@ -669,7 +669,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
yofs += frame->lines[i].height_cache;
if (p_mode == PROCESS_CACHE) {
- frame->lines[i].height_accum_cache = offset.y + draw_ofs.y + frame->lines[i].height_cache;
+ frame->lines.write[i].height_accum_cache = offset.y + draw_ofs.y + frame->lines[i].height_cache;
}
}
@@ -1253,6 +1253,9 @@ void RichTextLabel::_validate_line_caches(ItemFrame *p_frame) {
//validate invalid lines
Size2 size = get_size();
+ if (fixed_width != -1) {
+ size.width = fixed_width;
+ }
Rect2 text_rect = _get_text_rect();
Color font_color_shadow = get_color("font_color_shadow");
bool use_outline = get_constant("shadow_as_outline");
@@ -1264,11 +1267,11 @@ void RichTextLabel::_validate_line_caches(ItemFrame *p_frame) {
int y = 0;
_process_line(p_frame, text_rect.get_position(), y, text_rect.get_size().width - scroll_w, i, PROCESS_CACHE, base_font, Color(), font_color_shadow, use_outline, shadow_ofs);
- p_frame->lines[i].height_cache = y;
- p_frame->lines[i].height_accum_cache = y;
+ p_frame->lines.write[i].height_cache = y;
+ p_frame->lines.write[i].height_accum_cache = y;
if (i > 0)
- p_frame->lines[i].height_accum_cache += p_frame->lines[i - 1].height_accum_cache;
+ p_frame->lines.write[i].height_accum_cache += p_frame->lines[i - 1].height_accum_cache;
}
int total_height = 0;
@@ -1343,7 +1346,7 @@ void RichTextLabel::add_text(const String &p_text) {
_add_item(item, false);
current_frame->lines.resize(current_frame->lines.size() + 1);
if (item->type != ITEM_NEWLINE)
- current_frame->lines[current_frame->lines.size() - 1].from = item;
+ current_frame->lines.write[current_frame->lines.size() - 1].from = item;
_invalidate_current_line(current_frame);
}
@@ -1366,7 +1369,7 @@ void RichTextLabel::_add_item(Item *p_item, bool p_enter, bool p_ensure_newline)
}
if (current_frame->lines[current_frame->lines.size() - 1].from == NULL) {
- current_frame->lines[current_frame->lines.size() - 1].from = p_item;
+ current_frame->lines.write[current_frame->lines.size() - 1].from = p_item;
}
p_item->line = current_frame->lines.size() - 1;
@@ -1428,7 +1431,7 @@ bool RichTextLabel::remove_line(const int p_line) {
_remove_item(current->subitems[lines], current->subitems[lines]->line, lines);
if (p_line == 0) {
- main->lines[0].from = main;
+ main->lines.write[0].from = main;
}
main->first_invalid_line = 0;
@@ -1507,8 +1510,8 @@ void RichTextLabel::push_table(int p_columns) {
item->columns.resize(p_columns);
item->total_width = 0;
for (int i = 0; i < item->columns.size(); i++) {
- item->columns[i].expand = false;
- item->columns[i].expand_ratio = 1;
+ item->columns.write[i].expand = false;
+ item->columns.write[i].expand_ratio = 1;
}
_add_item(item, true, true);
}
@@ -1518,8 +1521,8 @@ void RichTextLabel::set_table_column_expand(int p_column, bool p_expand, int p_r
ERR_FAIL_COND(current->type != ITEM_TABLE);
ItemTable *table = static_cast<ItemTable *>(current);
ERR_FAIL_INDEX(p_column, table->columns.size());
- table->columns[p_column].expand = p_expand;
- table->columns[p_column].expand_ratio = p_ratio;
+ table->columns.write[p_column].expand = p_expand;
+ table->columns.write[p_column].expand_ratio = p_ratio;
}
void RichTextLabel::push_cell() {
@@ -1533,7 +1536,7 @@ void RichTextLabel::push_cell() {
item->cell = true;
item->parent_line = item->parent_frame->lines.size() - 1;
item->lines.resize(1);
- item->lines[0].from = NULL;
+ item->lines.write[0].from = NULL;
item->first_invalid_line = 0;
}
@@ -2245,13 +2248,28 @@ int RichTextLabel::get_total_character_count() const {
return tc;
}
+void RichTextLabel::set_fixed_size_to_width(int p_width) {
+ fixed_width = p_width;
+ minimum_size_changed();
+}
+
+Size2 RichTextLabel::get_minimum_size() const {
+
+ if (fixed_width != -1) {
+ const_cast<RichTextLabel *>(this)->_validate_line_caches(main);
+ return Size2(fixed_width, const_cast<RichTextLabel *>(this)->get_content_height());
+ }
+
+ return Size2();
+}
+
RichTextLabel::RichTextLabel() {
main = memnew(ItemFrame);
main->index = 0;
current = main;
main->lines.resize(1);
- main->lines[0].from = main;
+ main->lines.write[0].from = main;
main->first_invalid_line = 0;
current_frame = main;
tab_size = 4;
@@ -2287,6 +2305,7 @@ RichTextLabel::RichTextLabel() {
percent_visible = 1;
visible_line_count = 0;
+ fixed_width = -1;
set_clip_contents(true);
}
diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h
index af368af46a..06e9b8efe3 100644
--- a/scene/gui/rich_text_label.h
+++ b/scene/gui/rich_text_label.h
@@ -293,6 +293,8 @@ private:
void _update_all_lines();
+ int fixed_width;
+
protected:
void _notification(int p_what);
@@ -368,6 +370,9 @@ public:
void set_percent_visible(float p_percent);
float get_percent_visible() const;
+ void set_fixed_size_to_width(int p_width);
+ virtual Size2 get_minimum_size() const;
+
RichTextLabel();
~RichTextLabel();
};
diff --git a/scene/gui/scroll_bar.cpp b/scene/gui/scroll_bar.cpp
index 6ec67aca6b..e5bd1c453d 100644
--- a/scene/gui/scroll_bar.cpp
+++ b/scene/gui/scroll_bar.cpp
@@ -257,9 +257,7 @@ void ScrollBar::_notification(int p_what) {
Point2 ofs;
- VisualServer *vs = VisualServer::get_singleton();
-
- vs->canvas_item_add_texture_rect(ci, Rect2(Point2(), decr->get_size()), decr->get_rid());
+ decr->draw(ci, Point2());
if (orientation == HORIZONTAL)
ofs.x += decr->get_width();
@@ -280,7 +278,7 @@ void ScrollBar::_notification(int p_what) {
else
ofs.height += area.height;
- vs->canvas_item_add_texture_rect(ci, Rect2(ofs, decr->get_size()), incr->get_rid());
+ incr->draw(ci, ofs);
Rect2 grabber_rect;
if (orientation == HORIZONTAL) {
diff --git a/scene/gui/tabs.cpp b/scene/gui/tabs.cpp
index b114264de1..2075f7ce70 100644
--- a/scene/gui/tabs.cpp
+++ b/scene/gui/tabs.cpp
@@ -189,7 +189,7 @@ void Tabs::_gui_input(const Ref<InputEvent> &p_event) {
update();
}
- if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
+ if (mb->is_pressed() && (mb->get_button_index() == BUTTON_LEFT || (select_with_rmb && mb->get_button_index() == BUTTON_RIGHT))) {
// clicks
Point2 pos(mb->get_position().x, mb->get_position().y);
@@ -286,7 +286,7 @@ void Tabs::_notification(int p_what) {
for (int i = 0; i < tabs.size(); i++) {
- tabs[i].ofs_cache = mw;
+ tabs.write[i].ofs_cache = mw;
mw += get_tab_width(i);
}
@@ -314,7 +314,7 @@ void Tabs::_notification(int p_what) {
if (i < offset)
continue;
- tabs[i].ofs_cache = w;
+ tabs.write[i].ofs_cache = w;
int lsize = tabs[i].size_cache;
@@ -379,7 +379,7 @@ void Tabs::_notification(int p_what) {
rb->draw(ci, Point2i(w + style->get_margin(MARGIN_LEFT), rb_rect.position.y + style->get_margin(MARGIN_TOP)));
w += rb->get_width();
- tabs[i].rb_rect = rb_rect;
+ tabs.write[i].rb_rect = rb_rect;
}
if (cb_displaypolicy == CLOSE_BUTTON_SHOW_ALWAYS || (cb_displaypolicy == CLOSE_BUTTON_SHOW_ACTIVE_ONLY && i == current)) {
@@ -403,7 +403,7 @@ void Tabs::_notification(int p_what) {
cb->draw(ci, Point2i(w + style->get_margin(MARGIN_LEFT), cb_rect.position.y + style->get_margin(MARGIN_TOP)));
w += cb->get_width();
- tabs[i].cb_rect = cb_rect;
+ tabs.write[i].cb_rect = cb_rect;
}
w += sb->get_margin(MARGIN_RIGHT);
@@ -471,7 +471,7 @@ bool Tabs::get_offset_buttons_visible() const {
void Tabs::set_tab_title(int p_tab, const String &p_title) {
ERR_FAIL_INDEX(p_tab, tabs.size());
- tabs[p_tab].text = p_title;
+ tabs.write[p_tab].text = p_title;
update();
minimum_size_changed();
}
@@ -485,7 +485,7 @@ String Tabs::get_tab_title(int p_tab) const {
void Tabs::set_tab_icon(int p_tab, const Ref<Texture> &p_icon) {
ERR_FAIL_INDEX(p_tab, tabs.size());
- tabs[p_tab].icon = p_icon;
+ tabs.write[p_tab].icon = p_icon;
update();
minimum_size_changed();
}
@@ -499,7 +499,7 @@ Ref<Texture> Tabs::get_tab_icon(int p_tab) const {
void Tabs::set_tab_disabled(int p_tab, bool p_disabled) {
ERR_FAIL_INDEX(p_tab, tabs.size());
- tabs[p_tab].disabled = p_disabled;
+ tabs.write[p_tab].disabled = p_disabled;
update();
}
bool Tabs::get_tab_disabled(int p_tab) const {
@@ -511,7 +511,7 @@ bool Tabs::get_tab_disabled(int p_tab) const {
void Tabs::set_tab_right_button(int p_tab, const Ref<Texture> &p_right_button) {
ERR_FAIL_INDEX(p_tab, tabs.size());
- tabs[p_tab].right_button = p_right_button;
+ tabs.write[p_tab].right_button = p_right_button;
_update_cache();
update();
minimum_size_changed();
@@ -536,9 +536,9 @@ void Tabs::_update_cache() {
int size_fixed = 0;
int count_resize = 0;
for (int i = 0; i < tabs.size(); i++) {
- tabs[i].ofs_cache = mw;
- tabs[i].size_cache = get_tab_width(i);
- tabs[i].size_text = font->get_string_size(tabs[i].text).width;
+ tabs.write[i].ofs_cache = mw;
+ tabs.write[i].size_cache = get_tab_width(i);
+ tabs.write[i].size_text = font->get_string_size(tabs[i].text).width;
mw += tabs[i].size_cache;
if (tabs[i].size_cache <= min_width || i == current) {
size_fixed += tabs[i].size_cache;
@@ -579,9 +579,9 @@ void Tabs::_update_cache() {
lsize = m_width;
}
}
- tabs[i].ofs_cache = w;
- tabs[i].size_cache = lsize;
- tabs[i].size_text = slen;
+ tabs.write[i].ofs_cache = w;
+ tabs.write[i].size_cache = lsize;
+ tabs.write[i].size_text = slen;
w += lsize;
}
}
@@ -920,6 +920,14 @@ int Tabs::get_tabs_rearrange_group() const {
return tabs_rearrange_group;
}
+void Tabs::set_select_with_rmb(bool p_enabled) {
+ select_with_rmb = p_enabled;
+}
+
+bool Tabs::get_select_with_rmb() const {
+ return select_with_rmb;
+}
+
void Tabs::_bind_methods() {
ClassDB::bind_method(D_METHOD("_gui_input"), &Tabs::_gui_input);
@@ -950,6 +958,9 @@ void Tabs::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_tabs_rearrange_group", "group_id"), &Tabs::set_tabs_rearrange_group);
ClassDB::bind_method(D_METHOD("get_tabs_rearrange_group"), &Tabs::get_tabs_rearrange_group);
+ ClassDB::bind_method(D_METHOD("set_select_with_rmb", "enabled"), &Tabs::set_select_with_rmb);
+ ClassDB::bind_method(D_METHOD("get_select_with_rmb"), &Tabs::get_select_with_rmb);
+
ADD_SIGNAL(MethodInfo("tab_changed", PropertyInfo(Variant::INT, "tab")));
ADD_SIGNAL(MethodInfo("right_button_pressed", PropertyInfo(Variant::INT, "tab")));
ADD_SIGNAL(MethodInfo("tab_close", PropertyInfo(Variant::INT, "tab")));
@@ -988,6 +999,8 @@ Tabs::Tabs() {
offset = 0;
max_drawn_tab = 0;
+ select_with_rmb = false;
+
min_width = 0;
scrolling_enabled = true;
buttons_visible = false;
diff --git a/scene/gui/tabs.h b/scene/gui/tabs.h
index 3b38e7f2cb..e204f4364b 100644
--- a/scene/gui/tabs.h
+++ b/scene/gui/tabs.h
@@ -83,6 +83,8 @@ private:
int rb_hover;
bool rb_pressing;
+ bool select_with_rmb;
+
int cb_hover;
bool cb_pressing;
CloseButtonDisplayPolicy cb_displaypolicy;
@@ -150,6 +152,9 @@ public:
void set_tabs_rearrange_group(int p_group_id);
int get_tabs_rearrange_group() const;
+ void set_select_with_rmb(bool p_enabled);
+ bool get_select_with_rmb() const;
+
void ensure_tab_visible(int p_idx);
void set_min_width(int p_width);
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 218b5060a1..9a8dc62e4e 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -127,13 +127,13 @@ void TextEdit::Text::_update_line_cache(int p_line) const {
w += get_char_width(str[i], str[i + 1], w);
}
- text[p_line].width_cache = w;
+ text.write[p_line].width_cache = w;
- text[p_line].wrap_amount_cache = -1;
+ text.write[p_line].wrap_amount_cache = -1;
//update regions
- text[p_line].region_info.clear();
+ text.write[p_line].region_info.clear();
for (int i = 0; i < len; i++) {
@@ -172,7 +172,7 @@ void TextEdit::Text::_update_line_cache(int p_line) const {
ColorRegionInfo cri;
cri.end = false;
cri.region = j;
- text[p_line].region_info[i] = cri;
+ text.write[p_line].region_info[i] = cri;
i += lr - 1;
break;
@@ -200,7 +200,7 @@ void TextEdit::Text::_update_line_cache(int p_line) const {
ColorRegionInfo cri;
cri.end = true;
cri.region = j;
- text[p_line].region_info[i] = cri;
+ text.write[p_line].region_info[i] = cri;
i += lr - 1;
break;
@@ -236,7 +236,7 @@ void TextEdit::Text::set_line_wrap_amount(int p_line, int p_wrap_amount) const {
ERR_FAIL_INDEX(p_line, text.size());
- text[p_line].wrap_amount_cache = p_wrap_amount;
+ text.write[p_line].wrap_amount_cache = p_wrap_amount;
}
int TextEdit::Text::get_line_wrap_amount(int p_line) const {
@@ -249,14 +249,14 @@ int TextEdit::Text::get_line_wrap_amount(int p_line) const {
void TextEdit::Text::clear_width_cache() {
for (int i = 0; i < text.size(); i++) {
- text[i].width_cache = -1;
+ text.write[i].width_cache = -1;
}
}
void TextEdit::Text::clear_wrap_cache() {
for (int i = 0; i < text.size(); i++) {
- text[i].wrap_amount_cache = -1;
+ text.write[i].wrap_amount_cache = -1;
}
}
@@ -281,15 +281,16 @@ void TextEdit::Text::set(int p_line, const String &p_text) {
ERR_FAIL_INDEX(p_line, text.size());
- text[p_line].width_cache = -1;
- text[p_line].wrap_amount_cache = -1;
- text[p_line].data = p_text;
+ text.write[p_line].width_cache = -1;
+ text.write[p_line].wrap_amount_cache = -1;
+ text.write[p_line].data = p_text;
}
void TextEdit::Text::insert(int p_at, const String &p_text) {
Line line;
line.marked = false;
+ line.safe = false;
line.breakpoint = false;
line.hidden = false;
line.width_cache = -1;
@@ -336,10 +337,6 @@ void TextEdit::_update_scrollbars() {
int hscroll_rows = ((hmin.height - 1) / get_row_height()) + 1;
int visible_rows = get_visible_rows();
- int first_vis_line = get_first_visible_line();
- int wi;
- int num_rows = MAX(visible_rows, num_lines_from_rows(first_vis_line, cursor.wrap_ofs, visible_rows, wi));
-
int total_rows = get_total_visible_rows();
if (scroll_past_end_of_file_enabled) {
total_rows += visible_rows - 1;
@@ -972,7 +969,7 @@ void TextEdit::_notification(int p_what) {
fc = line_num_padding + fc;
}
- cache.font->draw(ci, Point2(cache.style_normal->get_margin(MARGIN_LEFT) + cache.breakpoint_gutter_width + ofs_x, yofs + cache.font->get_ascent()), fc, cache.line_number_color);
+ cache.font->draw(ci, Point2(cache.style_normal->get_margin(MARGIN_LEFT) + cache.breakpoint_gutter_width + ofs_x, yofs + cache.font->get_ascent()), fc, text.is_safe(line) ? cache.safe_line_number_color : cache.line_number_color);
}
}
@@ -1151,10 +1148,18 @@ void TextEdit::_notification(int p_what) {
if (ime_text.length() == 0) {
if (draw_caret) {
if (insert_mode) {
- int caret_h = (block_caret) ? 4 : 1;
+#ifdef TOOLS_ENABLED
+ int caret_h = (block_caret) ? 4 : 2 * EDSCALE;
+#else
+ int caret_h = (block_caret) ? 4 : 2;
+#endif
VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(cursor_pos, Size2i(caret_w, caret_h)), cache.caret_color);
} else {
- caret_w = (block_caret) ? caret_w : 1;
+#ifdef TOOLS_ENABLED
+ caret_w = (block_caret) ? caret_w : 2 * EDSCALE;
+#else
+ caret_w = (block_caret) ? caret_w : 2;
+#endif
VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(cursor_pos, Size2i(caret_w, get_row_height())), cache.caret_color);
}
}
@@ -1172,7 +1177,12 @@ void TextEdit::_notification(int p_what) {
int yofs = ofs_y + (get_row_height() - cache.font->get_height()) / 2;
int w = drawer.draw_char(ci, Point2i(char_ofs + char_margin + ofs_x, yofs + ascent), str[j], str[j + 1], in_selection && override_selected_font_color ? cache.font_selected_color : color);
if (underlined) {
- draw_rect(Rect2(char_ofs + char_margin + ofs_x, yofs + ascent + 2, w, 1), in_selection && override_selected_font_color ? cache.font_selected_color : color);
+ float line_width = 1.0;
+#ifdef TOOLS_ENABLED
+ line_width *= EDSCALE;
+#endif
+
+ draw_rect(Rect2(char_ofs + char_margin + ofs_x, yofs + ascent + 2, w, line_width), in_selection && override_selected_font_color ? cache.font_selected_color : color);
}
} else if (draw_tabs && str[j] == '\t') {
int yofs = (get_row_height() - cache.tab_icon->get_height()) / 2;
@@ -1227,11 +1237,19 @@ void TextEdit::_notification(int p_what) {
if (draw_caret) {
if (insert_mode) {
int char_w = cache.font->get_char_size(' ').width;
- int caret_h = (block_caret) ? 4 : 1;
+#ifdef TOOLS_ENABLED
+ int caret_h = (block_caret) ? 4 : 2 * EDSCALE;
+#else
+ int caret_h = (block_caret) ? 4 : 2;
+#endif
VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(cursor_pos, Size2i(char_w, caret_h)), cache.caret_color);
} else {
int char_w = cache.font->get_char_size(' ').width;
- int caret_w = (block_caret) ? char_w : 1;
+#ifdef TOOLS_ENABLED
+ int caret_w = (block_caret) ? char_w : 2 * EDSCALE;
+#else
+ int caret_w = (block_caret) ? char_w : 2;
+#endif
VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(cursor_pos, Size2i(caret_w, get_row_height())), cache.caret_color);
}
}
@@ -1672,7 +1690,6 @@ void TextEdit::_get_mouse_pos(const Point2i &p_mouse, int &r_row, int &r_col) co
rows /= get_row_height();
rows += get_v_scroll_offset();
int first_vis_line = get_first_visible_line();
- int last_vis_line = get_last_visible_line();
int row = first_vis_line + Math::floor(rows);
int wrap_index = 0;
@@ -2183,9 +2200,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
k->set_shift(false);
}
- if (!k->get_command()) {
- _reset_caret_blink_timer();
- }
+ _reset_caret_blink_timer();
// save here for insert mode, just in case it is cleared in the following section
bool had_selection = selection.active;
@@ -3799,7 +3814,6 @@ Vector<String> TextEdit::get_wrap_rows_text(int p_line) const {
}
// line ends before hit wrap_at; add this word to the substring
wrap_substring += word_str;
- px += word_px;
lines.push_back(wrap_substring);
return lines;
}
@@ -4314,6 +4328,7 @@ void TextEdit::_update_caches() {
cache.caret_color = get_color("caret_color");
cache.caret_background_color = get_color("caret_background_color");
cache.line_number_color = get_color("line_number_color");
+ cache.safe_line_number_color = get_color("safe_line_number_color");
cache.font_color = get_color("font_color");
cache.font_selected_color = get_color("font_selected_color");
cache.keyword_color = get_color("keyword_color");
@@ -4332,7 +4347,11 @@ void TextEdit::_update_caches() {
cache.search_result_border_color = get_color("search_result_border_color");
cache.symbol_color = get_color("symbol_color");
cache.background_color = get_color("background_color");
+#ifdef TOOLS_ENABLED
+ cache.line_spacing = get_constant("line_spacing") * EDSCALE;
+#else
cache.line_spacing = get_constant("line_spacing");
+#endif
cache.row_height = cache.font->get_height() + cache.line_spacing;
cache.tab_icon = get_icon("tab");
cache.folded_icon = get_icon("GuiTreeArrowRight", "EditorIcons");
@@ -4885,6 +4904,17 @@ void TextEdit::set_line_as_marked(int p_line, bool p_marked) {
update();
}
+void TextEdit::set_line_as_safe(int p_line, bool p_safe) {
+ ERR_FAIL_INDEX(p_line, text.size());
+ text.set_safe(p_line, p_safe);
+ update();
+}
+
+bool TextEdit::is_line_set_as_safe(int p_line) const {
+ ERR_FAIL_INDEX_V(p_line, text.size(), false);
+ return text.is_safe(p_line);
+}
+
bool TextEdit::is_line_set_as_breakpoint(int p_line) const {
ERR_FAIL_INDEX_V(p_line, text.size(), false);
@@ -5506,9 +5536,8 @@ int TextEdit::get_last_visible_line() const {
int TextEdit::get_last_visible_line_wrap_index() const {
int first_vis_line = get_first_visible_line();
- int last_vis_line = 0;
int wi;
- last_vis_line = first_vis_line + num_lines_from_rows(first_vis_line, cursor.wrap_ofs, get_visible_rows() + 1, wi) - 1;
+ num_lines_from_rows(first_vis_line, cursor.wrap_ofs, get_visible_rows() + 1, wi);
return wi;
}
@@ -5723,7 +5752,7 @@ void TextEdit::_update_completion_candidates() {
for (int i = 0; i < completion_strings.size(); i++) {
if (single_quote && completion_strings[i].is_quoted()) {
- completion_strings[i] = completion_strings[i].unquote().quote("'");
+ completion_strings.write[i] = completion_strings[i].unquote().quote("'");
}
if (s == completion_strings[i]) {
@@ -5739,8 +5768,11 @@ void TextEdit::_update_completion_candidates() {
}
// Calculate the similarity to keep completions in good order
float similarity;
- if (completion_strings[i].to_lower().begins_with(s.to_lower())) {
- // Substrings are the best candidates
+ if (completion_strings[i].begins_with(s)) {
+ // Substrings (same case) are the best candidates
+ similarity = 1.2;
+ } else if (completion_strings[i].to_lower().begins_with(s.to_lower())) {
+ // then any substrings
similarity = 1.1;
} else {
// Otherwise compute the similarity
@@ -6384,7 +6416,7 @@ Map<int, TextEdit::HighlighterInfo> TextEdit::_get_line_syntax_highlighting(int
}
// check for dot or underscore or 'x' for hex notation in floating point number
- if ((str[j] == '.' || str[j] == 'x' || str[j] == '_') && !in_word && prev_is_number && !is_number) {
+ if ((str[j] == '.' || str[j] == 'x' || str[j] == '_' || str[j] == 'f') && !in_word && prev_is_number && !is_number) {
is_number = true;
is_symbol = false;
is_char = false;
diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h
index 586f4c8e93..19b5d574c6 100644
--- a/scene/gui/text_edit.h
+++ b/scene/gui/text_edit.h
@@ -76,6 +76,7 @@ public:
bool marked : 1;
bool breakpoint : 1;
bool hidden : 1;
+ bool safe : 1;
int wrap_amount_cache : 24;
Map<int, ColorRegionInfo> region_info;
String data;
@@ -100,12 +101,14 @@ public:
int get_line_wrap_amount(int p_line) const;
const Map<int, ColorRegionInfo> &get_color_region_info(int p_line) const;
void set(int p_line, const String &p_text);
- void set_marked(int p_line, bool p_marked) { text[p_line].marked = p_marked; }
+ void set_marked(int p_line, bool p_marked) { text.write[p_line].marked = p_marked; }
bool is_marked(int p_line) const { return text[p_line].marked; }
- void set_breakpoint(int p_line, bool p_breakpoint) { text[p_line].breakpoint = p_breakpoint; }
+ void set_breakpoint(int p_line, bool p_breakpoint) { text.write[p_line].breakpoint = p_breakpoint; }
bool is_breakpoint(int p_line) const { return text[p_line].breakpoint; }
- void set_hidden(int p_line, bool p_hidden) { text[p_line].hidden = p_hidden; }
+ void set_hidden(int p_line, bool p_hidden) { text.write[p_line].hidden = p_hidden; }
bool is_hidden(int p_line) const { return text[p_line].hidden; }
+ void set_safe(int p_line, bool p_safe) { text.write[p_line].safe = p_safe; }
+ bool is_safe(int p_line) const { return text[p_line].safe; }
void insert(int p_at, const String &p_text);
void remove(int p_at);
int size() const { return text.size(); }
@@ -165,6 +168,7 @@ private:
Color caret_color;
Color caret_background_color;
Color line_number_color;
+ Color safe_line_number_color;
Color font_color;
Color font_selected_color;
Color keyword_color;
@@ -472,6 +476,8 @@ public:
void set_line_as_marked(int p_line, bool p_marked);
void set_line_as_breakpoint(int p_line, bool p_breakpoint);
bool is_line_set_as_breakpoint(int p_line) const;
+ void set_line_as_safe(int p_line, bool p_safe);
+ bool is_line_set_as_safe(int p_line) const;
void get_breakpoints(List<int> *p_breakpoints) const;
Array get_breakpoints_array() const;
void remove_breakpoints();
diff --git a/scene/gui/texture_progress.cpp b/scene/gui/texture_progress.cpp
index 82d983184b..6e4fe88dbf 100644
--- a/scene/gui/texture_progress.cpp
+++ b/scene/gui/texture_progress.cpp
@@ -309,15 +309,23 @@ void TextureProgress::_notification(int p_what) {
draw_texture_rect_region(progress, region, region, tint_progress);
} break;
case FILL_CLOCKWISE:
- case FILL_COUNTER_CLOCKWISE: {
+ case FILL_COUNTER_CLOCKWISE:
+ case FILL_CLOCKWISE_AND_COUNTER_CLOCKWISE: {
float val = get_as_ratio() * rad_max_degrees / 360;
if (val == 1) {
Rect2 region = Rect2(Point2(), s);
draw_texture_rect_region(progress, region, region, tint_progress);
} else if (val != 0) {
Array pts;
- float direction = mode == FILL_CLOCKWISE ? 1 : -1;
- float start = rad_init_angle / 360;
+ float direction = mode == FILL_COUNTER_CLOCKWISE ? -1 : 1;
+ float start;
+
+ if (mode == FILL_CLOCKWISE_AND_COUNTER_CLOCKWISE) {
+ start = rad_init_angle / 360 - val / 2;
+ } else {
+ start = rad_init_angle / 360;
+ }
+
float end = start + direction * val;
pts.append(start);
pts.append(end);
@@ -351,6 +359,14 @@ void TextureProgress::_notification(int p_what) {
draw_line(p - Point2(0, 8), p + Point2(0, 8), Color(0.9, 0.5, 0.5), 2);
}
} break;
+ case FILL_BILINEAR_LEFT_AND_RIGHT: {
+ Rect2 region = Rect2(Point2(s.x / 2 - s.x * get_as_ratio() / 2, 0), Size2(s.x * get_as_ratio(), s.y));
+ draw_texture_rect_region(progress, region, region, tint_progress);
+ } break;
+ case FILL_BILINEAR_TOP_AND_BOTTOM: {
+ Rect2 region = Rect2(Point2(0, s.y / 2 - s.y * get_as_ratio() / 2), Size2(s.x, s.y * get_as_ratio()));
+ draw_texture_rect_region(progress, region, region, tint_progress);
+ } break;
default:
draw_texture_rect_region(progress, Rect2(Point2(), Size2(s.x * get_as_ratio(), s.y)), Rect2(Point2(), Size2(s.x * get_as_ratio(), s.y)), tint_progress);
}
@@ -364,7 +380,7 @@ void TextureProgress::_notification(int p_what) {
}
void TextureProgress::set_fill_mode(int p_fill) {
- ERR_FAIL_INDEX(p_fill, 6);
+ ERR_FAIL_INDEX(p_fill, 9);
mode = (FillMode)p_fill;
update();
}
@@ -446,7 +462,7 @@ void TextureProgress::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_under", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_under_texture", "get_under_texture");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_over", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_over_texture", "get_over_texture");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_progress", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_progress_texture", "get_progress_texture");
- ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "fill_mode", PROPERTY_HINT_ENUM, "Left to Right,Right to Left,Top to Bottom,Bottom to Top,Clockwise,Counter Clockwise"), "set_fill_mode", "get_fill_mode");
+ ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "fill_mode", PROPERTY_HINT_ENUM, "Left to Right,Right to Left,Top to Bottom,Bottom to Top,Clockwise,Counter Clockwise,Bilinear (Left and Right),Bilinear (Top and Bottom), Clockwise and Counter Clockwise"), "set_fill_mode", "get_fill_mode");
ADD_GROUP("Tint", "tint_");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "tint_under", PROPERTY_HINT_COLOR_NO_ALPHA), "set_tint_under", "get_tint_under");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "tint_over", PROPERTY_HINT_COLOR_NO_ALPHA), "set_tint_over", "get_tint_over");
@@ -468,6 +484,9 @@ void TextureProgress::_bind_methods() {
BIND_ENUM_CONSTANT(FILL_BOTTOM_TO_TOP);
BIND_ENUM_CONSTANT(FILL_CLOCKWISE);
BIND_ENUM_CONSTANT(FILL_COUNTER_CLOCKWISE);
+ BIND_ENUM_CONSTANT(FILL_BILINEAR_LEFT_AND_RIGHT);
+ BIND_ENUM_CONSTANT(FILL_BILINEAR_TOP_AND_BOTTOM);
+ BIND_ENUM_CONSTANT(FILL_CLOCKWISE_AND_COUNTER_CLOCKWISE);
}
TextureProgress::TextureProgress() {
diff --git a/scene/gui/texture_progress.h b/scene/gui/texture_progress.h
index 34158b5db5..a11e55234a 100644
--- a/scene/gui/texture_progress.h
+++ b/scene/gui/texture_progress.h
@@ -52,7 +52,10 @@ public:
FILL_TOP_TO_BOTTOM,
FILL_BOTTOM_TO_TOP,
FILL_CLOCKWISE,
- FILL_COUNTER_CLOCKWISE
+ FILL_COUNTER_CLOCKWISE,
+ FILL_BILINEAR_LEFT_AND_RIGHT,
+ FILL_BILINEAR_TOP_AND_BOTTOM,
+ FILL_CLOCKWISE_AND_COUNTER_CLOCKWISE
};
void set_fill_mode(int p_fill);
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index 1d27612766..6f09488b64 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -121,7 +121,7 @@ void TreeItem::_cell_deselected(int p_cell) {
void TreeItem::set_cell_mode(int p_column, TreeCellMode p_mode) {
ERR_FAIL_INDEX(p_column, cells.size());
- Cell &c = cells[p_column];
+ Cell &c = cells.write[p_column];
c.mode = p_mode;
c.min = 0;
c.max = 100;
@@ -144,7 +144,7 @@ TreeItem::TreeCellMode TreeItem::get_cell_mode(int p_column) const {
void TreeItem::set_checked(int p_column, bool p_checked) {
ERR_FAIL_INDEX(p_column, cells.size());
- cells[p_column].checked = p_checked;
+ cells.write[p_column].checked = p_checked;
_changed_notify(p_column);
}
@@ -157,22 +157,22 @@ bool TreeItem::is_checked(int p_column) const {
void TreeItem::set_text(int p_column, String p_text) {
ERR_FAIL_INDEX(p_column, cells.size());
- cells[p_column].text = p_text;
+ cells.write[p_column].text = p_text;
if (cells[p_column].mode == TreeItem::CELL_MODE_RANGE || cells[p_column].mode == TreeItem::CELL_MODE_RANGE_EXPRESSION) {
Vector<String> strings = p_text.split(",");
- cells[p_column].min = INT_MAX;
- cells[p_column].max = INT_MIN;
+ cells.write[p_column].min = INT_MAX;
+ cells.write[p_column].max = INT_MIN;
for (int i = 0; i < strings.size(); i++) {
int value = i;
if (!strings[i].get_slicec(':', 1).empty()) {
value = strings[i].get_slicec(':', 1).to_int();
}
- cells[p_column].min = MIN(cells[p_column].min, value);
- cells[p_column].max = MAX(cells[p_column].max, value);
+ cells.write[p_column].min = MIN(cells[p_column].min, value);
+ cells.write[p_column].max = MAX(cells[p_column].max, value);
}
- cells[p_column].step = 0;
+ cells.write[p_column].step = 0;
}
_changed_notify(p_column);
}
@@ -186,7 +186,7 @@ String TreeItem::get_text(int p_column) const {
void TreeItem::set_suffix(int p_column, String p_suffix) {
ERR_FAIL_INDEX(p_column, cells.size());
- cells[p_column].suffix = p_suffix;
+ cells.write[p_column].suffix = p_suffix;
_changed_notify(p_column);
}
@@ -200,7 +200,7 @@ String TreeItem::get_suffix(int p_column) const {
void TreeItem::set_icon(int p_column, const Ref<Texture> &p_icon) {
ERR_FAIL_INDEX(p_column, cells.size());
- cells[p_column].icon = p_icon;
+ cells.write[p_column].icon = p_icon;
_changed_notify(p_column);
}
@@ -213,7 +213,7 @@ Ref<Texture> TreeItem::get_icon(int p_column) const {
void TreeItem::set_icon_region(int p_column, const Rect2 &p_icon_region) {
ERR_FAIL_INDEX(p_column, cells.size());
- cells[p_column].icon_region = p_icon_region;
+ cells.write[p_column].icon_region = p_icon_region;
_changed_notify(p_column);
}
@@ -226,7 +226,7 @@ Rect2 TreeItem::get_icon_region(int p_column) const {
void TreeItem::set_icon_color(int p_column, const Color &p_icon_color) {
ERR_FAIL_INDEX(p_column, cells.size());
- cells[p_column].icon_color = p_icon_color;
+ cells.write[p_column].icon_color = p_icon_color;
_changed_notify(p_column);
}
@@ -239,7 +239,7 @@ Color TreeItem::get_icon_color(int p_column) const {
void TreeItem::set_icon_max_width(int p_column, int p_max) {
ERR_FAIL_INDEX(p_column, cells.size());
- cells[p_column].icon_max_w = p_max;
+ cells.write[p_column].icon_max_w = p_max;
_changed_notify(p_column);
}
@@ -260,7 +260,7 @@ void TreeItem::set_range(int p_column, double p_value) {
if (p_value > cells[p_column].max)
p_value = cells[p_column].max;
- cells[p_column].val = p_value;
+ cells.write[p_column].val = p_value;
_changed_notify(p_column);
}
@@ -278,10 +278,10 @@ bool TreeItem::is_range_exponential(int p_column) const {
void TreeItem::set_range_config(int p_column, double p_min, double p_max, double p_step, bool p_exp) {
ERR_FAIL_INDEX(p_column, cells.size());
- cells[p_column].min = p_min;
- cells[p_column].max = p_max;
- cells[p_column].step = p_step;
- cells[p_column].expr = p_exp;
+ cells.write[p_column].min = p_min;
+ cells.write[p_column].max = p_max;
+ cells.write[p_column].step = p_step;
+ cells.write[p_column].expr = p_exp;
_changed_notify(p_column);
}
@@ -296,7 +296,7 @@ void TreeItem::get_range_config(int p_column, double &r_min, double &r_max, doub
void TreeItem::set_metadata(int p_column, const Variant &p_meta) {
ERR_FAIL_INDEX(p_column, cells.size());
- cells[p_column].meta = p_meta;
+ cells.write[p_column].meta = p_meta;
}
Variant TreeItem::get_metadata(int p_column) const {
@@ -311,8 +311,8 @@ void TreeItem::set_custom_draw(int p_column, Object *p_object, const StringName
ERR_FAIL_INDEX(p_column, cells.size());
ERR_FAIL_NULL(p_object);
- cells[p_column].custom_draw_obj = p_object->get_instance_id();
- cells[p_column].custom_draw_callback = p_callback;
+ cells.write[p_column].custom_draw_obj = p_object->get_instance_id();
+ cells.write[p_column].custom_draw_callback = p_callback;
}
void TreeItem::set_collapsed(bool p_collapsed) {
@@ -467,7 +467,7 @@ void TreeItem::remove_child(TreeItem *p_item) {
void TreeItem::set_selectable(int p_column, bool p_selectable) {
ERR_FAIL_INDEX(p_column, cells.size());
- cells[p_column].selectable = p_selectable;
+ cells.write[p_column].selectable = p_selectable;
}
bool TreeItem::is_selectable(int p_column) const {
@@ -517,7 +517,7 @@ void TreeItem::add_button(int p_column, const Ref<Texture> &p_button, int p_id,
button.id = p_id;
button.disabled = p_disabled;
button.tooltip = p_tooltip;
- cells[p_column].buttons.push_back(button);
+ cells.write[p_column].buttons.push_back(button);
_changed_notify(p_column);
}
@@ -540,7 +540,7 @@ void TreeItem::erase_button(int p_column, int p_idx) {
ERR_FAIL_INDEX(p_column, cells.size());
ERR_FAIL_INDEX(p_idx, cells[p_column].buttons.size());
- cells[p_column].buttons.remove(p_idx);
+ cells.write[p_column].buttons.remove(p_idx);
_changed_notify(p_column);
}
@@ -568,7 +568,7 @@ void TreeItem::set_button(int p_column, int p_idx, const Ref<Texture> &p_button)
ERR_FAIL_COND(p_button.is_null());
ERR_FAIL_INDEX(p_column, cells.size());
ERR_FAIL_INDEX(p_idx, cells[p_column].buttons.size());
- cells[p_column].buttons[p_idx].texture = p_button;
+ cells.write[p_column].buttons.write[p_idx].texture = p_button;
_changed_notify(p_column);
}
@@ -576,14 +576,14 @@ void TreeItem::set_button_color(int p_column, int p_idx, const Color &p_color) {
ERR_FAIL_INDEX(p_column, cells.size());
ERR_FAIL_INDEX(p_idx, cells[p_column].buttons.size());
- cells[p_column].buttons[p_idx].color = p_color;
+ cells.write[p_column].buttons.write[p_idx].color = p_color;
_changed_notify(p_column);
}
void TreeItem::set_editable(int p_column, bool p_editable) {
ERR_FAIL_INDEX(p_column, cells.size());
- cells[p_column].editable = p_editable;
+ cells.write[p_column].editable = p_editable;
_changed_notify(p_column);
}
@@ -596,8 +596,8 @@ bool TreeItem::is_editable(int p_column) {
void TreeItem::set_custom_color(int p_column, const Color &p_color) {
ERR_FAIL_INDEX(p_column, cells.size());
- cells[p_column].custom_color = true;
- cells[p_column].color = p_color;
+ cells.write[p_column].custom_color = true;
+ cells.write[p_column].color = p_color;
_changed_notify(p_column);
}
Color TreeItem::get_custom_color(int p_column) const {
@@ -610,15 +610,15 @@ Color TreeItem::get_custom_color(int p_column) const {
void TreeItem::clear_custom_color(int p_column) {
ERR_FAIL_INDEX(p_column, cells.size());
- cells[p_column].custom_color = false;
- cells[p_column].color = Color();
+ cells.write[p_column].custom_color = false;
+ cells.write[p_column].color = Color();
_changed_notify(p_column);
}
void TreeItem::set_tooltip(int p_column, const String &p_tooltip) {
ERR_FAIL_INDEX(p_column, cells.size());
- cells[p_column].tooltip = p_tooltip;
+ cells.write[p_column].tooltip = p_tooltip;
}
String TreeItem::get_tooltip(int p_column) const {
@@ -630,17 +630,17 @@ String TreeItem::get_tooltip(int p_column) const {
void TreeItem::set_custom_bg_color(int p_column, const Color &p_color, bool p_bg_outline) {
ERR_FAIL_INDEX(p_column, cells.size());
- cells[p_column].custom_bg_color = true;
- cells[p_column].custom_bg_outline = p_bg_outline;
- cells[p_column].bg_color = p_color;
+ cells.write[p_column].custom_bg_color = true;
+ cells.write[p_column].custom_bg_outline = p_bg_outline;
+ cells.write[p_column].bg_color = p_color;
_changed_notify(p_column);
}
void TreeItem::clear_custom_bg_color(int p_column) {
ERR_FAIL_INDEX(p_column, cells.size());
- cells[p_column].custom_bg_color = false;
- cells[p_column].bg_color = Color();
+ cells.write[p_column].custom_bg_color = false;
+ cells.write[p_column].bg_color = Color();
_changed_notify(p_column);
}
@@ -655,7 +655,7 @@ Color TreeItem::get_custom_bg_color(int p_column) const {
void TreeItem::set_custom_as_button(int p_column, bool p_button) {
ERR_FAIL_INDEX(p_column, cells.size());
- cells[p_column].custom_button = p_button;
+ cells.write[p_column].custom_button = p_button;
}
bool TreeItem::is_custom_set_as_button(int p_column) const {
@@ -666,7 +666,7 @@ bool TreeItem::is_custom_set_as_button(int p_column) const {
void TreeItem::set_text_align(int p_column, TextAlign p_align) {
ERR_FAIL_INDEX(p_column, cells.size());
- cells[p_column].text_align = p_align;
+ cells.write[p_column].text_align = p_align;
_changed_notify(p_column);
}
@@ -678,7 +678,7 @@ TreeItem::TextAlign TreeItem::get_text_align(int p_column) const {
void TreeItem::set_expand_right(int p_column, bool p_enable) {
ERR_FAIL_INDEX(p_column, cells.size());
- cells[p_column].expand_right = p_enable;
+ cells.write[p_column].expand_right = p_enable;
_changed_notify(p_column);
}
@@ -1486,7 +1486,7 @@ int Tree::_count_selected_items(TreeItem *p_from) const {
}
void Tree::select_single_item(TreeItem *p_selected, TreeItem *p_current, int p_col, TreeItem *p_prev, bool *r_in_range, bool p_force_deselect) {
- TreeItem::Cell &selected_cell = p_selected->cells[p_col];
+ TreeItem::Cell &selected_cell = p_selected->cells.write[p_col];
bool switched = false;
if (r_in_range && !*r_in_range && (p_current == p_selected || p_current == p_prev)) {
@@ -1498,7 +1498,7 @@ void Tree::select_single_item(TreeItem *p_selected, TreeItem *p_current, int p_c
for (int i = 0; i < columns.size(); i++) {
- TreeItem::Cell &c = p_current->cells[i];
+ TreeItem::Cell &c = p_current->cells.write[i];
if (!c.selectable)
continue;
@@ -1689,7 +1689,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool
return -1; //collapse/uncollapse because nothing can be done with item
}
- TreeItem::Cell &c = p_item->cells[col];
+ const TreeItem::Cell &c = p_item->cells[col];
bool already_selected = c.selected;
bool already_cursor = (p_item == selected_item) && col == selected_col;
@@ -1990,7 +1990,7 @@ void Tree::text_editor_enter(String p_text) {
if (popup_edited_item_col < 0 || popup_edited_item_col > columns.size())
return;
- TreeItem::Cell &c = popup_edited_item->cells[popup_edited_item_col];
+ TreeItem::Cell &c = popup_edited_item->cells.write[popup_edited_item_col];
switch (c.mode) {
case TreeItem::CELL_MODE_STRING: {
@@ -2041,7 +2041,7 @@ void Tree::value_editor_changed(double p_value) {
return;
}
- TreeItem::Cell &c = popup_edited_item->cells[popup_edited_item_col];
+ TreeItem::Cell &c = popup_edited_item->cells.write[popup_edited_item_col];
c.val = p_value;
item_edited(popup_edited_item_col, popup_edited_item);
update();
@@ -2055,7 +2055,7 @@ void Tree::popup_select(int p_option) {
if (popup_edited_item_col < 0 || popup_edited_item_col > columns.size())
return;
- popup_edited_item->cells[popup_edited_item_col].val = p_option;
+ popup_edited_item->cells.write[popup_edited_item_col].val = p_option;
//popup_edited_item->edited_signal.call( popup_edited_item_col );
update();
item_edited(popup_edited_item_col, popup_edited_item);
@@ -2426,14 +2426,23 @@ void Tree::_gui_input(Ref<InputEvent> p_event) {
int col, h, section;
TreeItem *it = _find_item_at_pos(root, mpos, col, h, section);
- if ((drop_mode_flags && it != drop_mode_over) || section != drop_mode_section) {
- drop_mode_over = it;
- drop_mode_section = section;
- update();
+ if (drop_mode_flags) {
+ if (it != drop_mode_over) {
+ drop_mode_over = it;
+ update();
+ }
+ if (it && section != drop_mode_section) {
+ drop_mode_section = section;
+ update();
+ }
}
- if (it != cache.hover_item || col != cache.hover_cell) {
+ if (it != cache.hover_item) {
cache.hover_item = it;
+ update();
+ }
+
+ if (it && col != cache.hover_cell) {
cache.hover_cell = col;
update();
}
@@ -2458,7 +2467,7 @@ void Tree::_gui_input(Ref<InputEvent> p_event) {
}
} else {
- TreeItem::Cell &c = popup_edited_item->cells[popup_edited_item_col];
+ const TreeItem::Cell &c = popup_edited_item->cells[popup_edited_item_col];
float diff_y = -mm->get_relative().y;
diff_y = Math::pow(ABS(diff_y), 1.8f) * SGN(diff_y);
diff_y *= 0.1;
@@ -2672,7 +2681,7 @@ bool Tree::edit_selected() {
popup_edited_item = s;
popup_edited_item_col = col;
- TreeItem::Cell &c = s->cells[col];
+ const TreeItem::Cell &c = s->cells[col];
if (c.mode == TreeItem::CELL_MODE_CHECK) {
@@ -3063,7 +3072,7 @@ void Tree::item_selected(int p_column, TreeItem *p_item) {
if (!p_item->cells[p_column].selectable)
return;
- p_item->cells[p_column].selected = true;
+ p_item->cells.write[p_column].selected = true;
//emit_signal("multi_selected",p_item,p_column,true); - NO this is for TreeItem::select
selected_col = p_column;
@@ -3077,7 +3086,7 @@ void Tree::item_selected(int p_column, TreeItem *p_item) {
void Tree::item_deselected(int p_column, TreeItem *p_item) {
if (select_mode == SELECT_MULTI || select_mode == SELECT_SINGLE) {
- p_item->cells[p_column].selected = false;
+ p_item->cells.write[p_column].selected = false;
}
update();
}
@@ -3158,14 +3167,14 @@ void Tree::set_column_min_width(int p_column, int p_min_width) {
if (p_min_width < 1)
return;
- columns[p_column].min_width = p_min_width;
+ columns.write[p_column].min_width = p_min_width;
update();
}
void Tree::set_column_expand(int p_column, bool p_expand) {
ERR_FAIL_INDEX(p_column, columns.size());
- columns[p_column].expand = p_expand;
+ columns.write[p_column].expand = p_expand;
update();
}
@@ -3413,7 +3422,7 @@ bool Tree::are_column_titles_visible() const {
void Tree::set_column_title(int p_column, const String &p_title) {
ERR_FAIL_INDEX(p_column, columns.size());
- columns[p_column].title = p_title;
+ columns.write[p_column].title = p_title;
update();
}
@@ -3659,7 +3668,7 @@ String Tree::get_tooltip(const Point2 &p_pos) const {
if (it) {
- TreeItem::Cell &c = it->cells[col];
+ const TreeItem::Cell &c = it->cells[col];
int col_width = get_column_width(col);
for (int j = c.buttons.size() - 1; j >= 0; j--) {
Ref<Texture> b = c.buttons[j].texture;
diff --git a/scene/main/canvas_layer.cpp b/scene/main/canvas_layer.cpp
index 8414210952..c044443b51 100644
--- a/scene/main/canvas_layer.cpp
+++ b/scene/main/canvas_layer.cpp
@@ -29,6 +29,7 @@
/*************************************************************************/
#include "canvas_layer.h"
+#include "scene/2d/canvas_item.h"
#include "viewport.h"
void CanvasLayer::set_layer(int p_xform) {
@@ -62,6 +63,24 @@ void CanvasLayer::_update_xform() {
transform.set_origin(ofs);
if (viewport.is_valid())
VisualServer::get_singleton()->viewport_set_canvas_transform(viewport, canvas, transform);
+
+ if (!is_inside_tree())
+ return;
+
+ _notify_xform(this);
+}
+
+void CanvasLayer::_notify_xform(Node *p_node) {
+
+ for (int i = 0; i < p_node->get_child_count(); i++) {
+
+ CanvasItem *ci = Object::cast_to<CanvasItem>(p_node->get_child(i));
+ if (ci) {
+ ci->_notify_transform(ci);
+ } else {
+ _notify_xform(p_node->get_child(i));
+ }
+ }
}
void CanvasLayer::_update_locrotscale() {
@@ -248,12 +267,10 @@ void CanvasLayer::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_custom_viewport"), &CanvasLayer::get_custom_viewport);
ClassDB::bind_method(D_METHOD("get_canvas"), &CanvasLayer::get_canvas);
- //ClassDB::bind_method(D_METHOD("get_viewport"),&CanvasLayer::get_viewport);
ADD_PROPERTY(PropertyInfo(Variant::INT, "layer", PROPERTY_HINT_RANGE, "-128,128,1"), "set_layer", "get_layer");
- //ADD_PROPERTY( PropertyInfo(Variant::MATRIX32,"transform",PROPERTY_HINT_RANGE),"set_transform","get_transform") ;
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_offset", "get_offset");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "rotation_degrees", PROPERTY_HINT_RANGE, "-1440,1440,0.1", PROPERTY_USAGE_EDITOR), "set_rotation_degrees", "get_rotation_degrees");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "rotation_degrees", PROPERTY_HINT_RANGE, "-1080,1080,0.1,or_lesser,or_greater", PROPERTY_USAGE_EDITOR), "set_rotation_degrees", "get_rotation_degrees");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "rotation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_rotation", "get_rotation");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "scale"), "set_scale", "get_scale");
ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "transform"), "set_transform", "get_transform");
diff --git a/scene/main/canvas_layer.h b/scene/main/canvas_layer.h
index aae23fbb12..fd347c4739 100644
--- a/scene/main/canvas_layer.h
+++ b/scene/main/canvas_layer.h
@@ -56,6 +56,7 @@ class CanvasLayer : public Node {
int sort_index;
void _update_xform();
+ void _notify_xform(Node *p_node);
void _update_locrotscale();
protected:
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index 6d18cce21d..f6905e7c2e 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -240,7 +240,7 @@ void Node::_propagate_enter_tree() {
void Node::_propagate_exit_tree() {
-//block while removing children
+ //block while removing children
#ifdef DEBUG_ENABLED
@@ -725,6 +725,17 @@ const Map<StringName, MultiplayerAPI::RPCMode>::Element *Node::get_node_rset_mod
return data.rpc_properties.find(p_property);
}
+bool Node::can_process_notification(int p_what) const {
+ switch (p_what) {
+ case NOTIFICATION_PHYSICS_PROCESS: return data.physics_process;
+ case NOTIFICATION_PROCESS: return data.idle_process;
+ case NOTIFICATION_INTERNAL_PROCESS: return data.idle_process_internal;
+ case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: return data.physics_process_internal;
+ }
+
+ return true;
+}
+
bool Node::can_process() const {
ERR_FAIL_COND_V(!is_inside_tree(), false);
@@ -809,6 +820,22 @@ bool Node::is_processing_internal() const {
return data.idle_process_internal;
}
+void Node::set_process_priority(int p_priority) {
+ data.process_priority = p_priority;
+
+ if (is_processing())
+ data.tree->make_group_changed("idle_process");
+
+ if (is_processing_internal())
+ data.tree->make_group_changed("idle_process_internal");
+
+ if (is_physics_processing())
+ data.tree->make_group_changed("physics_process");
+
+ if (is_physics_processing_internal())
+ data.tree->make_group_changed("physics_process_internal");
+}
+
void Node::set_process_input(bool p_enable) {
if (p_enable == data.input)
@@ -2528,6 +2555,9 @@ void Node::clear_internal_tree_resource_paths() {
String Node::get_configuration_warning() const {
+ if (get_script_instance() && get_script_instance()->has_method("_get_configuration_warning")) {
+ return get_script_instance()->call("_get_configuration_warning");
+ }
return String();
}
@@ -2608,6 +2638,7 @@ void Node::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_physics_processing"), &Node::is_physics_processing);
ClassDB::bind_method(D_METHOD("get_process_delta_time"), &Node::get_process_delta_time);
ClassDB::bind_method(D_METHOD("set_process", "enable"), &Node::set_process);
+ ClassDB::bind_method(D_METHOD("set_process_priority", "priority"), &Node::set_process_priority);
ClassDB::bind_method(D_METHOD("is_processing"), &Node::is_processing);
ClassDB::bind_method(D_METHOD("set_process_input", "enable"), &Node::set_process_input);
ClassDB::bind_method(D_METHOD("is_processing_input"), &Node::is_processing_input);
@@ -2735,6 +2766,7 @@ void Node::_bind_methods() {
BIND_VMETHOD(MethodInfo("_input", PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent")));
BIND_VMETHOD(MethodInfo("_unhandled_input", PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent")));
BIND_VMETHOD(MethodInfo("_unhandled_key_input", PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEventKey")));
+ BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_configuration_warning"));
//ClassDB::bind_method(D_METHOD("get_child",&Node::get_child,PH("index")));
//ClassDB::bind_method(D_METHOD("get_node",&Node::get_node,PH("path")));
@@ -2759,6 +2791,7 @@ Node::Node() {
data.tree = NULL;
data.physics_process = false;
data.idle_process = false;
+ data.process_priority = 0;
data.physics_process_internal = false;
data.idle_process_internal = false;
data.inside_tree = false;
diff --git a/scene/main/node.h b/scene/main/node.h
index 341349de79..f3422618ce 100644
--- a/scene/main/node.h
+++ b/scene/main/node.h
@@ -70,6 +70,11 @@ public:
bool operator()(const Node *p_a, const Node *p_b) const { return p_b->is_greater_than(p_a); }
};
+ struct ComparatorWithPriority {
+
+ bool operator()(const Node *p_a, const Node *p_b) const { return p_b->data.process_priority == p_a->data.process_priority ? p_b->is_greater_than(p_a) : p_b->data.process_priority > p_a->data.process_priority; }
+ };
+
private:
struct GroupData {
@@ -118,6 +123,7 @@ private:
//should move all the stuff below to bits
bool physics_process;
bool idle_process;
+ int process_priority;
bool physics_process_internal;
bool idle_process_internal;
@@ -319,6 +325,8 @@ public:
void set_process_internal(bool p_idle_process_internal);
bool is_processing_internal() const;
+ void set_process_priority(int p_priority);
+
void set_process_input(bool p_enable);
bool is_processing_input() const;
@@ -355,6 +363,7 @@ public:
void set_pause_mode(PauseMode p_mode);
PauseMode get_pause_mode() const;
bool can_process() const;
+ bool can_process_notification(int p_what) const;
void request_ready();
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp
index 6438616cf2..e99f785848 100644
--- a/scene/main/scene_tree.cpp
+++ b/scene/main/scene_tree.cpp
@@ -132,6 +132,12 @@ void SceneTree::remove_from_group(const StringName &p_group, Node *p_node) {
group_map.erase(E);
}
+void SceneTree::make_group_changed(const StringName &p_group) {
+ Map<StringName, Group>::Element *E = group_map.find(p_group);
+ if (E)
+ E->get().changed = true;
+}
+
void SceneTree::flush_transform_notifications() {
SelfList<Node> *n = xform_change_list.first();
@@ -165,18 +171,23 @@ void SceneTree::_flush_ugc() {
ugc_locked = false;
}
-void SceneTree::_update_group_order(Group &g) {
+void SceneTree::_update_group_order(Group &g, bool p_use_priority) {
if (!g.changed)
return;
if (g.nodes.empty())
return;
- Node **nodes = &g.nodes[0];
+ Node **nodes = g.nodes.ptrw();
int node_count = g.nodes.size();
- SortArray<Node *, Node::Comparator> node_sort;
- node_sort.sort(nodes, node_count);
+ if (p_use_priority) {
+ SortArray<Node *, Node::ComparatorWithPriority> node_sort;
+ node_sort.sort(nodes, node_count);
+ } else {
+ SortArray<Node *, Node::Comparator> node_sort;
+ node_sort.sort(nodes, node_count);
+ }
g.changed = false;
}
@@ -216,7 +227,7 @@ void SceneTree::call_group_flags(uint32_t p_call_flags, const StringName &p_grou
_update_group_order(g);
Vector<Node *> nodes_copy = g.nodes;
- Node **nodes = &nodes_copy[0];
+ Node **nodes = nodes_copy.ptrw();
int node_count = nodes_copy.size();
call_lock++;
@@ -271,7 +282,7 @@ void SceneTree::notify_group_flags(uint32_t p_call_flags, const StringName &p_gr
_update_group_order(g);
Vector<Node *> nodes_copy = g.nodes;
- Node **nodes = &nodes_copy[0];
+ Node **nodes = nodes_copy.ptrw();
int node_count = nodes_copy.size();
call_lock++;
@@ -320,7 +331,7 @@ void SceneTree::set_group_flags(uint32_t p_call_flags, const StringName &p_group
_update_group_order(g);
Vector<Node *> nodes_copy = g.nodes;
- Node **nodes = &nodes_copy[0];
+ Node **nodes = nodes_copy.ptrw();
int node_count = nodes_copy.size();
call_lock++;
@@ -884,7 +895,7 @@ void SceneTree::_call_input_pause(const StringName &p_group, const StringName &p
Vector<Node *> nodes_copy = g.nodes;
int node_count = nodes_copy.size();
- Node **nodes = &nodes_copy[0];
+ Node **nodes = nodes_copy.ptrw();
Variant arg = p_input;
const Variant *v[1] = { &arg };
@@ -921,14 +932,14 @@ void SceneTree::_notify_group_pause(const StringName &p_group, int p_notificatio
if (g.nodes.empty())
return;
- _update_group_order(g);
+ _update_group_order(g, p_notification == Node::NOTIFICATION_PROCESS || p_notification == Node::NOTIFICATION_INTERNAL_PROCESS || p_notification == Node::NOTIFICATION_PHYSICS_PROCESS || p_notification == Node::NOTIFICATION_INTERNAL_PHYSICS_PROCESS);
//copy, so copy on write happens in case something is removed from process while being called
//performance is not lost because only if something is added/removed the vector is copied.
Vector<Node *> nodes_copy = g.nodes;
int node_count = nodes_copy.size();
- Node **nodes = &nodes_copy[0];
+ Node **nodes = nodes_copy.ptrw();
call_lock++;
@@ -940,6 +951,8 @@ void SceneTree::_notify_group_pause(const StringName &p_group, int p_notificatio
if (!n->can_process())
continue;
+ if (!n->can_process_notification(p_notification))
+ continue;
n->notification(p_notification);
//ERR_FAIL_COND(node_count != g.nodes.size());
diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h
index aa8d78b1e1..11201097d4 100644
--- a/scene/main/scene_tree.h
+++ b/scene/main/scene_tree.h
@@ -161,7 +161,7 @@ private:
bool ugc_locked;
void _flush_ugc();
- _FORCE_INLINE_ void _update_group_order(Group &g);
+ _FORCE_INLINE_ void _update_group_order(Group &g, bool p_use_priority = false);
void _update_listener();
Array _get_nodes_in_group(const StringName &p_group);
@@ -204,6 +204,7 @@ private:
Group *add_to_group(const StringName &p_group, Node *p_node);
void remove_from_group(const StringName &p_group, Node *p_node);
+ void make_group_changed(const StringName &p_group);
void _notify_group_pause(const StringName &p_group, int p_notification);
void _call_input_pause(const StringName &p_group, const StringName &p_method, const Ref<InputEvent> &p_input);
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 01302d4214..f92b6e7583 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -41,7 +41,10 @@
#include "scene/3d/spatial.h"
#include "scene/gui/control.h"
#include "scene/gui/label.h"
+#include "scene/gui/menu_button.h"
#include "scene/gui/panel.h"
+#include "scene/gui/panel_container.h"
+#include "scene/gui/popup_menu.h"
#include "scene/main/timer.h"
#include "scene/resources/mesh.h"
#include "scene/scene_string_names.h"
@@ -166,9 +169,9 @@ ViewportTexture::~ViewportTexture() {
/////////////////////////////////////
-class TooltipPanel : public Panel {
+class TooltipPanel : public PanelContainer {
- GDCLASS(TooltipPanel, Panel)
+ GDCLASS(TooltipPanel, PanelContainer)
public:
TooltipPanel(){};
};
@@ -441,7 +444,7 @@ void Viewport::_notification(int p_what) {
Vector2 point = get_canvas_transform().affine_inverse().xform(pos);
Physics2DDirectSpaceState::ShapeResult res[64];
- int rc = ss2d->intersect_point(point, res, 64, Set<RID>(), 0xFFFFFFFF, true);
+ int rc = ss2d->intersect_point(point, res, 64, Set<RID>(), 0xFFFFFFFF, true, true, true);
for (int i = 0; i < rc; i++) {
if (res[i].collider_id && res[i].collider) {
@@ -524,7 +527,7 @@ void Viewport::_notification(int p_what) {
PhysicsDirectSpaceState *space = PhysicsServer::get_singleton()->space_get_direct_state(find_world()->get_space());
if (space) {
- bool col = space->intersect_ray(from, from + dir * 10000, result, Set<RID>(), 0xFFFFFFFF, true);
+ bool col = space->intersect_ray(from, from + dir * 10000, result, Set<RID>(), 0xFFFFFFFF, true, true, true);
ObjectID new_collider = 0;
if (col) {
@@ -560,7 +563,7 @@ void Viewport::_notification(int p_what) {
PhysicsDirectSpaceState *space = PhysicsServer::get_singleton()->space_get_direct_state(find_world()->get_space());
if (space) {
- bool col = space->intersect_ray(from, from + dir * 10000, result, Set<RID>(), 0xFFFFFFFF, true);
+ bool col = space->intersect_ray(from, from + dir * 10000, result, Set<RID>(), 0xFFFFFFFF, true, true, true);
ObjectID new_collider = 0;
if (col) {
CollisionObject *co = Object::cast_to<CollisionObject>(result.collider);
@@ -1305,10 +1308,11 @@ void Viewport::_gui_cancel_tooltip() {
if (gui.tooltip_popup) {
gui.tooltip_popup->queue_delete();
gui.tooltip_popup = NULL;
+ gui.tooltip_label = NULL;
}
}
-String Viewport::_gui_get_tooltip(Control *p_control, const Vector2 &p_pos) {
+String Viewport::_gui_get_tooltip(Control *p_control, const Vector2 &p_pos, Control **r_which) {
Vector2 pos = p_pos;
String tooltip;
@@ -1317,6 +1321,10 @@ String Viewport::_gui_get_tooltip(Control *p_control, const Vector2 &p_pos) {
tooltip = p_control->get_tooltip(pos);
+ if (r_which) {
+ *r_which = p_control;
+ }
+
if (tooltip != String())
break;
pos = p_control->get_transform().xform(pos);
@@ -1338,41 +1346,49 @@ void Viewport::_gui_show_tooltip() {
return;
}
- String tooltip = _gui_get_tooltip(gui.tooltip, gui.tooltip->get_global_transform().xform_inv(gui.tooltip_pos));
+ Control *which = NULL;
+ String tooltip = _gui_get_tooltip(gui.tooltip, gui.tooltip->get_global_transform().xform_inv(gui.tooltip_pos), &which);
if (tooltip.length() == 0)
return; // bye
if (gui.tooltip_popup) {
memdelete(gui.tooltip_popup);
gui.tooltip_popup = NULL;
+ gui.tooltip_label = NULL;
}
- if (!gui.tooltip) {
+ if (!which) {
return;
}
- Control *rp = gui.tooltip->get_root_parent_control();
+ Control *rp = which; //->get_root_parent_control();
if (!rp)
return;
- gui.tooltip_popup = memnew(TooltipPanel);
+ gui.tooltip_popup = which->make_custom_tooltip(tooltip);
+
+ if (!gui.tooltip_popup) {
+ gui.tooltip_popup = memnew(TooltipPanel);
+
+ gui.tooltip_label = memnew(TooltipLabel);
+ gui.tooltip_popup->add_child(gui.tooltip_label);
+
+ Ref<StyleBox> ttp = gui.tooltip_label->get_stylebox("panel", "TooltipPanel");
+
+ gui.tooltip_label->set_anchor_and_margin(MARGIN_LEFT, Control::ANCHOR_BEGIN, ttp->get_margin(MARGIN_LEFT));
+ gui.tooltip_label->set_anchor_and_margin(MARGIN_TOP, Control::ANCHOR_BEGIN, ttp->get_margin(MARGIN_TOP));
+ gui.tooltip_label->set_anchor_and_margin(MARGIN_RIGHT, Control::ANCHOR_END, -ttp->get_margin(MARGIN_RIGHT));
+ gui.tooltip_label->set_anchor_and_margin(MARGIN_BOTTOM, Control::ANCHOR_END, -ttp->get_margin(MARGIN_BOTTOM));
+ gui.tooltip_label->set_text(tooltip.strip_edges());
+ }
rp->add_child(gui.tooltip_popup);
gui.tooltip_popup->force_parent_owned();
- gui.tooltip_label = memnew(TooltipLabel);
- gui.tooltip_popup->add_child(gui.tooltip_label);
gui.tooltip_popup->set_as_toplevel(true);
- gui.tooltip_popup->hide();
+ //gui.tooltip_popup->hide();
- Ref<StyleBox> ttp = gui.tooltip_label->get_stylebox("panel", "TooltipPanel");
-
- gui.tooltip_label->set_anchor_and_margin(MARGIN_LEFT, Control::ANCHOR_BEGIN, ttp->get_margin(MARGIN_LEFT));
- gui.tooltip_label->set_anchor_and_margin(MARGIN_TOP, Control::ANCHOR_BEGIN, ttp->get_margin(MARGIN_TOP));
- gui.tooltip_label->set_anchor_and_margin(MARGIN_RIGHT, Control::ANCHOR_END, -ttp->get_margin(MARGIN_RIGHT));
- gui.tooltip_label->set_anchor_and_margin(MARGIN_BOTTOM, Control::ANCHOR_END, -ttp->get_margin(MARGIN_BOTTOM));
- gui.tooltip_label->set_text(tooltip.strip_edges());
- Rect2 r(gui.tooltip_pos + Point2(10, 10), gui.tooltip_label->get_minimum_size() + ttp->get_minimum_size());
- Rect2 vr = gui.tooltip_label->get_viewport_rect();
+ Rect2 r(gui.tooltip_pos + Point2(10, 10), gui.tooltip_popup->get_minimum_size());
+ Rect2 vr = gui.tooltip_popup->get_viewport_rect();
if (r.size.x + r.position.x > vr.size.x)
r.position.x = vr.size.x - r.size.x;
else if (r.position.x < 0)
@@ -1840,8 +1856,32 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
if (gui.drag_data.get_type() == Variant::NIL && over && !gui.modal_stack.empty()) {
Control *top = gui.modal_stack.back()->get();
+
if (over != top && !top->is_a_parent_of(over)) {
- over = NULL; //nothing can be found outside the modal stack
+
+ PopupMenu *popup_menu = Object::cast_to<PopupMenu>(top);
+ MenuButton *popup_menu_parent = NULL;
+ MenuButton *menu_button = Object::cast_to<MenuButton>(over);
+
+ if (popup_menu)
+ popup_menu_parent = Object::cast_to<MenuButton>(popup_menu->get_parent());
+
+ // If the mouse is over a menu button, this menu will open automatically
+ // if there is already a pop-up menu open at the same hierarchical level.
+ if (popup_menu_parent && menu_button &&
+ popup_menu_parent->get_icon().is_null() &&
+ menu_button->get_icon().is_null() &&
+ (popup_menu->get_parent()->get_parent()->is_a_parent_of(menu_button) ||
+ menu_button->get_parent()->is_a_parent_of(popup_menu))) {
+
+ popup_menu->notification(Control::NOTIFICATION_MODAL_CLOSE);
+ popup_menu->_modal_stack_remove();
+ popup_menu->hide();
+
+ menu_button->pressed();
+ } else {
+ over = NULL; //nothing can be found outside the modal stack
+ }
}
}
@@ -1891,13 +1931,18 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
bool is_tooltip_shown = false;
if (gui.tooltip_popup) {
- if (can_tooltip) {
+ if (can_tooltip && gui.tooltip) {
String tooltip = _gui_get_tooltip(over, gui.tooltip->get_global_transform().xform_inv(mpos));
if (tooltip.length() == 0)
_gui_cancel_tooltip();
- else if (tooltip == gui.tooltip_label->get_text())
+ else if (gui.tooltip_label) {
+ if (tooltip == gui.tooltip_label->get_text()) {
+ is_tooltip_shown = true;
+ }
+ } else if (tooltip == String(gui.tooltip_popup->call("get_tooltip_text"))) {
is_tooltip_shown = true;
+ }
} else
_gui_cancel_tooltip();
}
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index 3000398540..e4ef373c77 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -31,11 +31,11 @@
#ifndef VIEWPORT_H
#define VIEWPORT_H
-#include "math_2d.h"
#include "scene/main/node.h"
#include "scene/resources/texture.h"
#include "scene/resources/world_2d.h"
#include "servers/visual_server.h"
+#include "transform_2d.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
@@ -255,7 +255,7 @@ private:
Control *key_focus;
Control *mouse_over;
Control *tooltip;
- Panel *tooltip_popup;
+ Control *tooltip_popup;
Label *tooltip_label;
Point2 tooltip_pos;
Point2 last_mouse_pos;
@@ -312,7 +312,7 @@ private:
void _gui_remove_root_control(List<Control *>::Element *RI);
void _gui_remove_subwindow_control(List<Control *>::Element *SI);
- String _gui_get_tooltip(Control *p_control, const Vector2 &p_pos);
+ String _gui_get_tooltip(Control *p_control, const Vector2 &p_pos, Control **r_which = NULL);
void _gui_cancel_tooltip();
void _gui_show_tooltip();
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index a0bac09442..da4e2f991d 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -51,7 +51,6 @@
#include "scene/2d/parallax_background.h"
#include "scene/2d/parallax_layer.h"
#include "scene/2d/particles_2d.h"
-
#include "scene/2d/path_2d.h"
#include "scene/2d/physics_body_2d.h"
#include "scene/2d/polygon_2d.h"
@@ -156,9 +155,12 @@
#include "scene/resources/sky_box.h"
#include "scene/resources/sphere_shape.h"
#include "scene/resources/surface_tool.h"
+#include "scene/resources/text_file.h"
#include "scene/resources/texture.h"
#include "scene/resources/tile_set.h"
#include "scene/resources/video_stream.h"
+#include "scene/resources/visual_shader.h"
+#include "scene/resources/visual_shader_nodes.h"
#include "scene/resources/world.h"
#include "scene/resources/world_2d.h"
#include "scene/scene_string_names.h"
@@ -197,10 +199,14 @@
#include "scene/3d/remote_transform.h"
#include "scene/3d/room_instance.h"
#include "scene/3d/skeleton.h"
+#include "scene/3d/soft_body.h"
+#include "scene/3d/spring_arm.h"
#include "scene/3d/sprite_3d.h"
#include "scene/3d/vehicle_body.h"
#include "scene/3d/visibility_notifier.h"
+#include "scene/animation/skeleton_ik.h"
#include "scene/resources/environment.h"
+#include "scene/resources/physics_material.h"
#endif
static ResourceFormatLoaderTheme *resource_loader_theme = NULL;
@@ -211,6 +217,7 @@ static ResourceFormatLoaderText *resource_loader_text = NULL;
static ResourceFormatLoaderDynamicFont *resource_loader_dynamic_font = NULL;
static ResourceFormatLoaderStreamTexture *resource_loader_stream_texture = NULL;
+static ResourceFormatLoaderTextureLayered *resource_loader_texture_layered = NULL;
static ResourceFormatLoaderBMFont *resource_loader_bmfont = NULL;
@@ -231,6 +238,9 @@ void register_scene_types() {
resource_loader_stream_texture = memnew(ResourceFormatLoaderStreamTexture);
ResourceLoader::add_resource_format_loader(resource_loader_stream_texture);
+ resource_loader_texture_layered = memnew(ResourceFormatLoaderTextureLayered);
+ ResourceLoader::add_resource_format_loader(resource_loader_texture_layered);
+
resource_loader_theme = memnew(ResourceFormatLoaderTheme);
ResourceLoader::add_resource_format_loader(resource_loader_theme);
@@ -310,21 +320,19 @@ void register_scene_types() {
ClassDB::register_class<CenterContainer>();
ClassDB::register_class<ScrollContainer>();
ClassDB::register_class<PanelContainer>();
- ClassDB::register_virtual_class<SplitContainer>();
- ClassDB::register_class<HSplitContainer>();
- ClassDB::register_class<VSplitContainer>();
- ClassDB::register_class<GraphNode>();
- ClassDB::register_class<GraphEdit>();
OS::get_singleton()->yield(); //may take time to init
ClassDB::register_class<TextureProgress>();
ClassDB::register_class<ItemList>();
+ ClassDB::register_class<LineEdit>();
+ ClassDB::register_class<VideoPlayer>();
+
#ifndef ADVANCED_GUI_DISABLED
ClassDB::register_class<FileDialog>();
- ClassDB::register_class<LineEdit>();
+
ClassDB::register_class<PopupMenu>();
ClassDB::register_class<Tree>();
@@ -341,9 +349,13 @@ void register_scene_types() {
ClassDB::register_class<WindowDialog>();
ClassDB::register_class<AcceptDialog>();
ClassDB::register_class<ConfirmationDialog>();
- ClassDB::register_class<VideoPlayer>();
ClassDB::register_class<MarginContainer>();
ClassDB::register_class<ViewportContainer>();
+ ClassDB::register_virtual_class<SplitContainer>();
+ ClassDB::register_class<HSplitContainer>();
+ ClassDB::register_class<VSplitContainer>();
+ ClassDB::register_class<GraphNode>();
+ ClassDB::register_class<GraphEdit>();
OS::get_singleton()->yield(); //may take time to init
@@ -360,10 +372,10 @@ void register_scene_types() {
OS::get_singleton()->yield(); //may take time to init
#ifndef _3D_DISABLED
- ClassDB::register_class<BoneAttachment>();
ClassDB::register_virtual_class<VisualInstance>();
ClassDB::register_virtual_class<GeometryInstance>();
ClassDB::register_class<Camera>();
+ ClassDB::register_class<ClippedCamera>();
ClassDB::register_class<Listener>();
ClassDB::register_class<ARVRCamera>();
ClassDB::register_class<ARVRController>();
@@ -402,6 +414,8 @@ void register_scene_types() {
ClassDB::register_class<AnimationNodeBlendSpace1D>();
ClassDB::register_class<AnimationNodeBlendSpace2D>();
ClassDB::register_class<AnimationNodeStateMachine>();
+ ClassDB::register_class<AnimationNodeStateMachinePlayback>();
+
ClassDB::register_class<AnimationNodeStateMachineTransition>();
ClassDB::register_class<AnimationNodeOutput>();
ClassDB::register_class<AnimationNodeOneShot>();
@@ -422,7 +436,13 @@ void register_scene_types() {
ClassDB::register_class<RigidBody>();
ClassDB::register_class<KinematicCollision>();
ClassDB::register_class<KinematicBody>();
+ ClassDB::register_class<SpringArm>();
+
ClassDB::register_class<PhysicalBone>();
+ ClassDB::register_class<SoftBody>();
+
+ ClassDB::register_class<SkeletonIK>();
+ ClassDB::register_class<BoneAttachment>();
ClassDB::register_class<VehicleBody>();
ClassDB::register_class<VehicleWheel>();
@@ -456,6 +476,39 @@ void register_scene_types() {
AcceptDialog::set_swap_ok_cancel(GLOBAL_DEF("gui/common/swap_ok_cancel", bool(OS::get_singleton()->get_swap_ok_cancel())));
ClassDB::register_class<Shader>();
+ ClassDB::register_class<VisualShader>();
+ ClassDB::register_virtual_class<VisualShaderNode>();
+ ClassDB::register_class<VisualShaderNodeInput>();
+ ClassDB::register_virtual_class<VisualShaderNodeOutput>();
+ ClassDB::register_class<VisualShaderNodeScalarConstant>();
+ ClassDB::register_class<VisualShaderNodeColorConstant>();
+ ClassDB::register_class<VisualShaderNodeVec3Constant>();
+ ClassDB::register_class<VisualShaderNodeTransformConstant>();
+ ClassDB::register_class<VisualShaderNodeScalarOp>();
+ ClassDB::register_class<VisualShaderNodeVectorOp>();
+ ClassDB::register_class<VisualShaderNodeColorOp>();
+ ClassDB::register_class<VisualShaderNodeTransformMult>();
+ ClassDB::register_class<VisualShaderNodeTransformVecMult>();
+ ClassDB::register_class<VisualShaderNodeScalarFunc>();
+ ClassDB::register_class<VisualShaderNodeVectorFunc>();
+ ClassDB::register_class<VisualShaderNodeDotProduct>();
+ ClassDB::register_class<VisualShaderNodeVectorLen>();
+ ClassDB::register_class<VisualShaderNodeScalarInterp>();
+ ClassDB::register_class<VisualShaderNodeVectorInterp>();
+ ClassDB::register_class<VisualShaderNodeVectorCompose>();
+ ClassDB::register_class<VisualShaderNodeTransformCompose>();
+ ClassDB::register_class<VisualShaderNodeVectorDecompose>();
+ ClassDB::register_class<VisualShaderNodeTransformDecompose>();
+ ClassDB::register_class<VisualShaderNodeTexture>();
+ ClassDB::register_class<VisualShaderNodeCubeMap>();
+ ClassDB::register_virtual_class<VisualShaderNodeUniform>();
+ ClassDB::register_class<VisualShaderNodeScalarUniform>();
+ ClassDB::register_class<VisualShaderNodeColorUniform>();
+ ClassDB::register_class<VisualShaderNodeVec3Uniform>();
+ ClassDB::register_class<VisualShaderNodeTransformUniform>();
+ ClassDB::register_class<VisualShaderNodeTextureUniform>();
+ ClassDB::register_class<VisualShaderNodeCubeMapUniform>();
+
ClassDB::register_class<ShaderMaterial>();
ClassDB::register_virtual_class<CanvasItem>();
ClassDB::register_class<CanvasItemMaterial>();
@@ -553,6 +606,8 @@ void register_scene_types() {
OS::get_singleton()->yield(); //may take time to init
ClassDB::register_class<SpatialVelocityTracker>();
+
+ ClassDB::register_class<PhysicsMaterial>();
#endif
ClassDB::register_class<World>();
ClassDB::register_class<Environment>();
@@ -568,12 +623,18 @@ void register_scene_types() {
ClassDB::register_class<CurveTexture>();
ClassDB::register_class<GradientTexture>();
ClassDB::register_class<ProxyTexture>();
+ ClassDB::register_class<AnimatedTexture>();
ClassDB::register_class<CubeMap>();
+ ClassDB::register_virtual_class<TextureLayered>();
+ ClassDB::register_class<Texture3D>();
+ ClassDB::register_class<TextureArray>();
ClassDB::register_class<Animation>();
ClassDB::register_virtual_class<Font>();
ClassDB::register_class<BitmapFont>();
ClassDB::register_class<Curve>();
+ ClassDB::register_class<TextFile>();
+
ClassDB::register_class<DynamicFontData>();
ClassDB::register_class<DynamicFont>();
@@ -680,6 +741,7 @@ void unregister_scene_types() {
memdelete(resource_loader_dynamic_font);
memdelete(resource_loader_stream_texture);
+ memdelete(resource_loader_texture_layered);
memdelete(resource_loader_theme);
DynamicFont::finish_dynamic_fonts();
diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp
index e57a2b68c8..7041b62487 100644
--- a/scene/resources/animation.cpp
+++ b/scene/resources/animation.cpp
@@ -100,7 +100,7 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) {
for (int i = 0; i < (vcount / 12); i++) {
- TKey<TransformKey> &tk = tt->transforms[i];
+ TKey<TransformKey> &tk = tt->transforms.write[i];
const float *ofs = &r[i * 12];
tk.time = ofs[0];
tk.transition = ofs[1];
@@ -154,8 +154,8 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) {
for (int i = 0; i < valcount; i++) {
- vt->values[i].time = rt[i];
- vt->values[i].value = values[i];
+ vt->values.write[i].time = rt[i];
+ vt->values.write[i].value = values[i];
}
if (d.has("transitions")) {
@@ -167,7 +167,7 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) {
for (int i = 0; i < valcount; i++) {
- vt->values[i].transition = rtr[i];
+ vt->values.write[i].transition = rtr[i];
}
}
}
@@ -235,13 +235,13 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) {
for (int i = 0; i < valcount; i++) {
- bt->values[i].time = rt[i];
- bt->values[i].transition = 0; //unused in bezier
- bt->values[i].value.value = rv[i * 5 + 0];
- bt->values[i].value.in_handle.x = rv[i * 5 + 1];
- bt->values[i].value.in_handle.y = rv[i * 5 + 2];
- bt->values[i].value.out_handle.x = rv[i * 5 + 3];
- bt->values[i].value.out_handle.y = rv[i * 5 + 4];
+ bt->values.write[i].time = rt[i];
+ bt->values.write[i].transition = 0; //unused in bezier
+ bt->values.write[i].value.value = rv[i * 5 + 0];
+ bt->values.write[i].value.in_handle.x = rv[i * 5 + 1];
+ bt->values.write[i].value.in_handle.y = rv[i * 5 + 2];
+ bt->values.write[i].value.out_handle.x = rv[i * 5 + 3];
+ bt->values.write[i].value.out_handle.y = rv[i * 5 + 4];
}
}
@@ -313,7 +313,7 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) {
TKey<StringName> ak;
ak.time = rt[i];
ak.value = rc[i];
- an->values[i] = ak;
+ an->values.write[i] = ak;
}
}
@@ -822,7 +822,7 @@ int Animation::_insert(float p_time, T &p_keys, const V &p_value) {
} else if (p_keys[idx - 1].time == p_time) {
// condition for replacing.
- p_keys[idx - 1] = p_value;
+ p_keys.write[idx - 1] = p_value;
return idx - 1;
}
@@ -1349,18 +1349,18 @@ void Animation::track_set_key_value(int p_track, int p_key_idx, const Variant &p
ERR_FAIL_INDEX(p_key_idx, tt->transforms.size());
Dictionary d = p_value;
if (d.has("location"))
- tt->transforms[p_key_idx].value.loc = d["location"];
+ tt->transforms.write[p_key_idx].value.loc = d["location"];
if (d.has("rotation"))
- tt->transforms[p_key_idx].value.rot = d["rotation"];
+ tt->transforms.write[p_key_idx].value.rot = d["rotation"];
if (d.has("scale"))
- tt->transforms[p_key_idx].value.scale = d["scale"];
+ tt->transforms.write[p_key_idx].value.scale = d["scale"];
} break;
case TYPE_VALUE: {
ValueTrack *vt = static_cast<ValueTrack *>(t);
ERR_FAIL_INDEX(p_key_idx, vt->values.size());
- vt->values[p_key_idx].value = p_value;
+ vt->values.write[p_key_idx].value = p_value;
} break;
case TYPE_METHOD: {
@@ -1369,9 +1369,9 @@ void Animation::track_set_key_value(int p_track, int p_key_idx, const Variant &p
ERR_FAIL_INDEX(p_key_idx, mt->methods.size());
Dictionary d = p_value;
if (d.has("method"))
- mt->methods[p_key_idx].method = d["method"];
+ mt->methods.write[p_key_idx].method = d["method"];
if (d.has("args"))
- mt->methods[p_key_idx].params = d["args"];
+ mt->methods.write[p_key_idx].params = d["args"];
} break;
case TYPE_BEZIER: {
@@ -1381,11 +1381,11 @@ void Animation::track_set_key_value(int p_track, int p_key_idx, const Variant &p
Array arr = p_value;
ERR_FAIL_COND(arr.size() != 5);
- bt->values[p_key_idx].value.value = arr[0];
- bt->values[p_key_idx].value.in_handle.x = arr[1];
- bt->values[p_key_idx].value.in_handle.y = arr[2];
- bt->values[p_key_idx].value.out_handle.x = arr[3];
- bt->values[p_key_idx].value.out_handle.y = arr[4];
+ bt->values.write[p_key_idx].value.value = arr[0];
+ bt->values.write[p_key_idx].value.in_handle.x = arr[1];
+ bt->values.write[p_key_idx].value.in_handle.y = arr[2];
+ bt->values.write[p_key_idx].value.out_handle.x = arr[3];
+ bt->values.write[p_key_idx].value.out_handle.y = arr[4];
} break;
case TYPE_AUDIO: {
@@ -1397,16 +1397,16 @@ void Animation::track_set_key_value(int p_track, int p_key_idx, const Variant &p
ERR_FAIL_COND(!k.has("end_offset"));
ERR_FAIL_COND(!k.has("stream"));
- at->values[p_key_idx].value.start_offset = k["start_offset"];
- at->values[p_key_idx].value.end_offset = k["end_offset"];
- at->values[p_key_idx].value.stream = k["stream"];
+ at->values.write[p_key_idx].value.start_offset = k["start_offset"];
+ at->values.write[p_key_idx].value.end_offset = k["end_offset"];
+ at->values.write[p_key_idx].value.stream = k["stream"];
} break;
case TYPE_ANIMATION: {
AnimationTrack *at = static_cast<AnimationTrack *>(t);
- at->values[p_key_idx].value = p_value;
+ at->values.write[p_key_idx].value = p_value;
} break;
}
@@ -1423,20 +1423,20 @@ void Animation::track_set_key_transition(int p_track, int p_key_idx, float p_tra
TransformTrack *tt = static_cast<TransformTrack *>(t);
ERR_FAIL_INDEX(p_key_idx, tt->transforms.size());
- tt->transforms[p_key_idx].transition = p_transition;
+ tt->transforms.write[p_key_idx].transition = p_transition;
} break;
case TYPE_VALUE: {
ValueTrack *vt = static_cast<ValueTrack *>(t);
ERR_FAIL_INDEX(p_key_idx, vt->values.size());
- vt->values[p_key_idx].transition = p_transition;
+ vt->values.write[p_key_idx].transition = p_transition;
} break;
case TYPE_METHOD: {
MethodTrack *mt = static_cast<MethodTrack *>(t);
ERR_FAIL_INDEX(p_key_idx, mt->methods.size());
- mt->methods[p_key_idx].transition = p_transition;
+ mt->methods.write[p_key_idx].transition = p_transition;
} break;
case TYPE_BEZIER:
@@ -2210,7 +2210,7 @@ void Animation::bezier_track_set_key_value(int p_track, int p_index, float p_val
ERR_FAIL_INDEX(p_index, bt->values.size());
- bt->values[p_index].value.value = p_value;
+ bt->values.write[p_index].value.value = p_value;
emit_changed();
}
@@ -2224,9 +2224,9 @@ void Animation::bezier_track_set_key_in_handle(int p_track, int p_index, const V
ERR_FAIL_INDEX(p_index, bt->values.size());
- bt->values[p_index].value.in_handle = p_handle;
+ bt->values.write[p_index].value.in_handle = p_handle;
if (bt->values[p_index].value.in_handle.x > 0) {
- bt->values[p_index].value.in_handle.x = 0;
+ bt->values.write[p_index].value.in_handle.x = 0;
}
emit_changed();
}
@@ -2240,9 +2240,9 @@ void Animation::bezier_track_set_key_out_handle(int p_track, int p_index, const
ERR_FAIL_INDEX(p_index, bt->values.size());
- bt->values[p_index].value.out_handle = p_handle;
+ bt->values.write[p_index].value.out_handle = p_handle;
if (bt->values[p_index].value.out_handle.x < 0) {
- bt->values[p_index].value.out_handle.x = 0;
+ bt->values.write[p_index].value.out_handle.x = 0;
}
emit_changed();
}
@@ -2329,13 +2329,14 @@ float Animation::bezier_track_interpolate(int p_track, float p_time) const {
int iterations = 10;
- float low = 0;
- float high = bt->values[idx + 1].time - bt->values[idx].time;
+ float duration = bt->values[idx + 1].time - bt->values[idx].time; // time duration between our two keyframes
+ float low = 0; // 0% of the current animation segment
+ float high = 1; // 100% of the current animation segment
float middle = 0;
Vector2 start(0, bt->values[idx].value.value);
Vector2 start_out = start + bt->values[idx].value.out_handle;
- Vector2 end(high, bt->values[idx + 1].value.value);
+ Vector2 end(duration, bt->values[idx + 1].value.value);
Vector2 end_in = end + bt->values[idx + 1].value.in_handle;
//narrow high and low as much as possible
@@ -2355,7 +2356,6 @@ float Animation::bezier_track_interpolate(int p_track, float p_time) const {
//interpolate the result:
Vector2 low_pos = _bezier_interp(low, start, start_out, end_in, end);
Vector2 high_pos = _bezier_interp(high, start, start_out, end_in, end);
-
float c = (t - low_pos.x) / (high_pos.x - low_pos.x);
return low_pos.linear_interpolate(high_pos, c).y;
@@ -2396,7 +2396,7 @@ void Animation::audio_track_set_key_stream(int p_track, int p_key, const RES &p_
ERR_FAIL_INDEX(p_key, at->values.size());
- at->values[p_key].value.stream = p_stream;
+ at->values.write[p_key].value.stream = p_stream;
emit_changed();
}
@@ -2414,7 +2414,7 @@ void Animation::audio_track_set_key_start_offset(int p_track, int p_key, float p
if (p_offset < 0)
p_offset = 0;
- at->values[p_key].value.start_offset = p_offset;
+ at->values.write[p_key].value.start_offset = p_offset;
emit_changed();
}
@@ -2432,7 +2432,7 @@ void Animation::audio_track_set_key_end_offset(int p_track, int p_key, float p_o
if (p_offset < 0)
p_offset = 0;
- at->values[p_key].value.end_offset = p_offset;
+ at->values.write[p_key].value.end_offset = p_offset;
emit_changed();
}
@@ -2505,7 +2505,7 @@ void Animation::animation_track_set_key_animation(int p_track, int p_key, const
ERR_FAIL_INDEX(p_key, at->values.size());
- at->values[p_key].value = p_animation;
+ at->values.write[p_key].value = p_animation;
emit_changed();
}
@@ -2550,7 +2550,7 @@ void Animation::track_move_up(int p_track) {
if (p_track >= 0 && p_track < (tracks.size() - 1)) {
- SWAP(tracks[p_track], tracks[p_track + 1]);
+ SWAP(tracks.write[p_track], tracks.write[p_track + 1]);
}
emit_changed();
@@ -2585,7 +2585,7 @@ void Animation::track_move_down(int p_track) {
if (p_track > 0 && p_track < tracks.size()) {
- SWAP(tracks[p_track], tracks[p_track - 1]);
+ SWAP(tracks.write[p_track], tracks.write[p_track - 1]);
}
emit_changed();
}
@@ -2596,7 +2596,7 @@ void Animation::track_swap(int p_track, int p_with_track) {
ERR_FAIL_INDEX(p_with_track, tracks.size());
if (p_track == p_with_track)
return;
- SWAP(tracks[p_track], tracks[p_with_track]);
+ SWAP(tracks.write[p_track], tracks.write[p_with_track]);
emit_changed();
}
@@ -2927,9 +2927,9 @@ void Animation::_transform_track_optimize(int p_idx, float p_allowed_linear_err,
for (int i = 1; i < tt->transforms.size() - 1; i++) {
- TKey<TransformKey> &t0 = tt->transforms[i - 1];
- TKey<TransformKey> &t1 = tt->transforms[i];
- TKey<TransformKey> &t2 = tt->transforms[i + 1];
+ TKey<TransformKey> &t0 = tt->transforms.write[i - 1];
+ TKey<TransformKey> &t1 = tt->transforms.write[i];
+ TKey<TransformKey> &t2 = tt->transforms.write[i + 1];
bool erase = _transform_track_optimize_key(t0, t1, t2, p_allowed_linear_err, p_allowed_angular_err, p_max_optimizable_angle, norm);
if (erase && !prev_erased) {
diff --git a/scene/resources/audio_stream_sample.cpp b/scene/resources/audio_stream_sample.cpp
index 02a9e4d69b..e6a4b01deb 100644
--- a/scene/resources/audio_stream_sample.cpp
+++ b/scene/resources/audio_stream_sample.cpp
@@ -29,6 +29,8 @@
/*************************************************************************/
#include "audio_stream_sample.h"
+#include "io/marshalls.h"
+#include "os/file_access.h"
void AudioStreamPlaybackSample::start(float p_from_pos) {
@@ -509,6 +511,76 @@ PoolVector<uint8_t> AudioStreamSample::get_data() const {
return pv;
}
+void AudioStreamSample::save_to_wav(String p_path) {
+ if (format == AudioStreamSample::FORMAT_IMA_ADPCM) {
+ WARN_PRINTS("Saving IMA_ADPC samples are not supported yet");
+ return;
+ }
+
+ int sub_chunk_2_size = data_bytes; //Subchunk2Size = Size of data in bytes
+
+ // Format code
+ // 1:PCM format (for 8 or 16 bit)
+ // 3:IEEE float format
+ int format_code = (format == FORMAT_IMA_ADPCM) ? 3 : 1;
+
+ int n_channels = stereo ? 2 : 1;
+
+ long sample_rate = mix_rate;
+
+ int byte_pr_sample = 0;
+ switch (format) {
+ case AudioStreamSample::FORMAT_8_BITS: byte_pr_sample = 1; break;
+ case AudioStreamSample::FORMAT_16_BITS: byte_pr_sample = 2; break;
+ case AudioStreamSample::FORMAT_IMA_ADPCM: byte_pr_sample = 4; break;
+ }
+
+ String file_path = p_path;
+ if (!(file_path.substr(file_path.length() - 4, 4) == ".wav")) {
+ file_path += ".wav";
+ }
+
+ Error err;
+ FileAccess *file = FileAccess::open(file_path, FileAccess::WRITE, &err); //Overrides existing file if present
+
+ // Create WAV Header
+ file->store_string("RIFF"); //ChunkID
+ file->store_32(sub_chunk_2_size + 36); //ChunkSize = 36 + SubChunk2Size (size of entire file minus the 8 bits for this and previous header)
+ file->store_string("WAVE"); //Format
+ file->store_string("fmt "); //Subchunk1ID
+ file->store_32(16); //Subchunk1Size = 16
+ file->store_16(format_code); //AudioFormat
+ file->store_16(n_channels); //Number of Channels
+ file->store_32(sample_rate); //SampleRate
+ file->store_32(sample_rate * n_channels * byte_pr_sample); //ByteRate
+ file->store_16(n_channels * byte_pr_sample); //BlockAlign = NumChannels * BytePrSample
+ file->store_16(byte_pr_sample * 8); //BitsPerSample
+ file->store_string("data"); //Subchunk2ID
+ file->store_32(sub_chunk_2_size); //Subchunk2Size
+
+ // Add data
+ PoolVector<uint8_t>::Read read_data = get_data().read();
+ switch (format) {
+ case AudioStreamSample::FORMAT_8_BITS:
+ for (int i = 0; i < data_bytes; i++) {
+ uint8_t data_point = (read_data[i] + 128);
+ file->store_8(data_point);
+ }
+ break;
+ case AudioStreamSample::FORMAT_16_BITS:
+ for (int i = 0; i < data_bytes / 2; i++) {
+ uint16_t data_point = decode_uint16(&read_data[i * 2]);
+ file->store_16(data_point);
+ }
+ break;
+ case AudioStreamSample::FORMAT_IMA_ADPCM:
+ //Unimplemented
+ break;
+ }
+
+ file->close();
+}
+
Ref<AudioStreamPlayback> AudioStreamSample::instance_playback() {
Ref<AudioStreamPlaybackSample> sample;
@@ -545,6 +617,8 @@ void AudioStreamSample::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_stereo", "stereo"), &AudioStreamSample::set_stereo);
ClassDB::bind_method(D_METHOD("is_stereo"), &AudioStreamSample::is_stereo);
+ ClassDB::bind_method(D_METHOD("save_to_wav", "path"), &AudioStreamSample::save_to_wav);
+
ADD_PROPERTY(PropertyInfo(Variant::POOL_BYTE_ARRAY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_data", "get_data");
ADD_PROPERTY(PropertyInfo(Variant::INT, "format", PROPERTY_HINT_ENUM, "8-Bit,16-Bit,IMA-ADPCM"), "set_format", "get_format");
ADD_PROPERTY(PropertyInfo(Variant::INT, "loop_mode", PROPERTY_HINT_ENUM, "Disabled,Forward,Ping-Pong"), "set_loop_mode", "get_loop_mode");
diff --git a/scene/resources/audio_stream_sample.h b/scene/resources/audio_stream_sample.h
index 5fe65c194e..a27acc92b7 100644
--- a/scene/resources/audio_stream_sample.h
+++ b/scene/resources/audio_stream_sample.h
@@ -140,6 +140,8 @@ public:
void set_data(const PoolVector<uint8_t> &p_data);
PoolVector<uint8_t> get_data() const;
+ void save_to_wav(String p_path);
+
virtual Ref<AudioStreamPlayback> instance_playback();
virtual String get_stream_name() const;
diff --git a/scene/resources/bit_mask.cpp b/scene/resources/bit_mask.cpp
index 29ffefd9d6..39206ed043 100644
--- a/scene/resources/bit_mask.cpp
+++ b/scene/resources/bit_mask.cpp
@@ -29,6 +29,7 @@
/*************************************************************************/
#include "bit_mask.h"
+
#include "io/image_loader.h"
void BitMap::create(const Size2 &p_size) {
@@ -130,7 +131,7 @@ void BitMap::set_bit(const Point2 &p_pos, bool p_value) {
else
b &= ~(1 << bbit);
- bitmask[bbyte] = b;
+ bitmask.write[bbyte] = b;
}
bool BitMap::get_bit(const Point2 &p_pos) const {
@@ -189,13 +190,13 @@ Vector<Vector2> BitMap::_march_square(const Rect2i &rect, const Point2i &start)
{ //square value
/*
- checking the 2x2 pixel grid, assigning these values to each pixel, if not transparent
- +---+---+
- | 1 | 2 |
- +---+---+
- | 4 | 8 | <- current pixel (curx,cury)
- +---+---+
- */
+ checking the 2x2 pixel grid, assigning these values to each pixel, if not transparent
+ +---+---+
+ | 1 | 2 |
+ +---+---+
+ | 4 | 8 | <- current pixel (curx,cury)
+ +---+---+
+ */
//NOTE: due to the way we pick points from texture, rect needs to be smaller, otherwise it goes outside 1 pixel
Rect2i fixed_rect = Rect2i(rect.position, rect.size - Size2i(2, 2));
Point2i tl = Point2i(curx - 1, cury - 1);
@@ -215,13 +216,13 @@ Vector<Vector2> BitMap::_march_square(const Rect2i &rect, const Point2i &start)
case 5:
case 13:
/* going UP with these cases:
- 1 5 13
- +---+---+ +---+---+ +---+---+
- | 1 | | | 1 | | | 1 | |
- +---+---+ +---+---+ +---+---+
- | | | | 4 | | | 4 | 8 |
- +---+---+ +---+---+ +---+---+
- */
+ 1 5 13
+ +---+---+ +---+---+ +---+---+
+ | 1 | | | 1 | | | 1 | |
+ +---+---+ +---+---+ +---+---+
+ | | | | 4 | | | 4 | 8 |
+ +---+---+ +---+---+ +---+---+
+ */
stepx = 0;
stepy = -1;
break;
@@ -230,13 +231,13 @@ Vector<Vector2> BitMap::_march_square(const Rect2i &rect, const Point2i &start)
case 10:
case 11:
/* going DOWN with these cases:
- 8 10 11
- +---+---+ +---+---+ +---+---+
- | | | | | 2 | | 1 | 2 |
- +---+---+ +---+---+ +---+---+
- | | 8 | | | 8 | | | 8 |
- +---+---+ +---+---+ +---+---+
- */
+ 8 10 11
+ +---+---+ +---+---+ +---+---+
+ | | | | | 2 | | 1 | 2 |
+ +---+---+ +---+---+ +---+---+
+ | | 8 | | | 8 | | | 8 |
+ +---+---+ +---+---+ +---+---+
+ */
stepx = 0;
stepy = 1;
break;
@@ -245,13 +246,13 @@ Vector<Vector2> BitMap::_march_square(const Rect2i &rect, const Point2i &start)
case 12:
case 14:
/* going LEFT with these cases:
- 4 12 14
- +---+---+ +---+---+ +---+---+
- | | | | | | | | 2 |
- +---+---+ +---+---+ +---+---+
- | 4 | | | 4 | 8 | | 4 | 8 |
- +---+---+ +---+---+ +---+---+
- */
+ 4 12 14
+ +---+---+ +---+---+ +---+---+
+ | | | | | | | | 2 |
+ +---+---+ +---+---+ +---+---+
+ | 4 | | | 4 | 8 | | 4 | 8 |
+ +---+---+ +---+---+ +---+---+
+ */
stepx = -1;
stepy = 0;
break;
@@ -260,25 +261,25 @@ Vector<Vector2> BitMap::_march_square(const Rect2i &rect, const Point2i &start)
case 3:
case 7:
/* going RIGHT with these cases:
- 2 3 7
- +---+---+ +---+---+ +---+---+
- | | 2 | | 1 | 2 | | 1 | 2 |
- +---+---+ +---+---+ +---+---+
- | | | | | | | 4 | |
- +---+---+ +---+---+ +---+---+
- */
+ 2 3 7
+ +---+---+ +---+---+ +---+---+
+ | | 2 | | 1 | 2 | | 1 | 2 |
+ +---+---+ +---+---+ +---+---+
+ | | | | | | | 4 | |
+ +---+---+ +---+---+ +---+---+
+ */
stepx = 1;
stepy = 0;
break;
case 9:
/*
- +---+---+
- | 1 | |
- +---+---+
- | | 8 |
- +---+---+
- this should normally go UP, but if we already been here, we go down
- */
+ +---+---+
+ | 1 | |
+ +---+---+
+ | | 8 |
+ +---+---+
+ this should normally go UP, but if we already been here, we go down
+ */
if (case9s.has(Point2i(curx, cury))) {
//found, so we go down, and delete from case9s;
stepx = 0;
@@ -293,14 +294,14 @@ Vector<Vector2> BitMap::_march_square(const Rect2i &rect, const Point2i &start)
break;
case 6:
/*
- 6
- +---+---+
- | | 2 |
- +---+---+
- | 4 | |
- +---+---+
- this normally go RIGHT, but if its coming from UP, it should go LEFT
- */
+ 6
+ +---+---+
+ | | 2 |
+ +---+---+
+ | 4 | |
+ +---+---+
+ this normally go RIGHT, but if its coming from UP, it should go LEFT
+ */
if (case6s.has(Point2i(curx, cury))) {
//found, so we go down, and delete from case6s;
stepx = -1;
@@ -322,8 +323,8 @@ Vector<Vector2> BitMap::_march_square(const Rect2i &rect, const Point2i &start)
curx += stepx;
cury += stepy;
if (stepx == prevx && stepy == prevy) {
- _points[_points.size() - 1].x = (float)(curx - rect.position.x);
- _points[_points.size() - 1].y = (float)(cury + rect.position.y);
+ _points.write[_points.size() - 1].x = (float)(curx - rect.position.x);
+ _points.write[_points.size() - 1].y = (float)(cury + rect.position.y);
} else {
_points.push_back(Vector2((float)(curx - rect.position.x), (float)(cury + rect.position.y)));
}
@@ -373,11 +374,11 @@ static Vector<Vector2> rdp(const Vector<Vector2> &v, float optimization) {
Vector<Vector2> left, right;
left.resize(index);
for (int i = 0; i < index; i++) {
- left[i] = v[i];
+ left.write[i] = v[i];
}
right.resize(v.size() - index);
for (int i = 0; i < right.size(); i++) {
- right[i] = v[index + i];
+ right.write[i] = v[index + i];
}
Vector<Vector2> r1 = rdp(left, optimization);
Vector<Vector2> r2 = rdp(right, optimization);
@@ -385,7 +386,7 @@ static Vector<Vector2> rdp(const Vector<Vector2> &v, float optimization) {
int middle = r1.size();
r1.resize(r1.size() + r2.size());
for (int i = 0; i < r2.size(); i++) {
- r1[middle + i] = r2[i];
+ r1.write[middle + i] = r2[i];
}
return r1;
} else {
@@ -412,37 +413,97 @@ static Vector<Vector2> reduce(const Vector<Vector2> &points, const Rect2i &rect,
Vector2 last = result[result.size() - 1];
if (last.y > result[0].y && last.distance_to(result[0]) < ep * 0.5f) {
- result[0].y = last.y;
+ result.write[0].y = last.y;
result.resize(result.size() - 1);
}
return result;
}
+struct FillBitsStackEntry {
+ Point2i pos;
+ int i;
+ int j;
+};
+
static void fill_bits(const BitMap *p_src, Ref<BitMap> &p_map, const Point2i &p_pos, const Rect2i &rect) {
- for (int i = p_pos.x - 1; i <= p_pos.x + 1; i++) {
- for (int j = p_pos.y - 1; j <= p_pos.y + 1; j++) {
+ // Using a custom stack to work iteratively to avoid stack overflow on big bitmaps
+ PoolVector<FillBitsStackEntry> stack;
+ // Tracking size since we won't be shrinking the stack vector
+ int stack_size = 0;
- if (i < rect.position.x || i >= rect.position.x + rect.size.x)
- continue;
- if (j < rect.position.y || j >= rect.position.y + rect.size.y)
- continue;
+ Point2i pos = p_pos;
+ int next_i;
+ int next_j;
- if (p_map->get_bit(Vector2(i, j)))
- continue;
+ bool reenter = true;
+ bool popped = false;
+ do {
+ if (reenter) {
+ next_i = pos.x - 1;
+ next_j = pos.y - 1;
+ reenter = false;
+ }
+
+ for (int i = next_i; i <= pos.x + 1; i++) {
+ for (int j = next_j; j <= pos.y + 1; j++) {
+ if (popped) {
+ // The next loop over j must start normally
+ next_j = pos.y;
+ popped = false;
+ // Skip because an iteration was already executed with current counter values
+ continue;
+ }
- else if (p_src->get_bit(Vector2(i, j))) {
- p_map->set_bit(Vector2(i, j), true);
- fill_bits(p_src, p_map, Point2i(i, j), rect);
+ if (i < rect.position.x || i >= rect.position.x + rect.size.x)
+ continue;
+ if (j < rect.position.y || j >= rect.position.y + rect.size.y)
+ continue;
+
+ if (p_map->get_bit(Vector2(i, j)))
+ continue;
+
+ else if (p_src->get_bit(Vector2(i, j))) {
+ p_map->set_bit(Vector2(i, j), true);
+
+ FillBitsStackEntry se = { pos, i, j };
+ stack.resize(MAX(stack_size + 1, stack.size()));
+ stack.set(stack_size, se);
+ stack_size++;
+
+ pos = Point2i(i, j);
+ reenter = true;
+ break;
+ }
+ }
+ if (reenter) {
+ break;
}
}
- }
+ if (!reenter) {
+ if (stack_size) {
+ FillBitsStackEntry se = stack.get(stack_size - 1);
+ stack_size--;
+ pos = se.pos;
+ next_i = se.i;
+ next_j = se.j;
+ popped = true;
+ }
+ }
+ } while (reenter || popped);
+
+#ifdef DEBUG_ENABLED
+ print_line("max stack size: " + itos(stack.size()));
+#endif
}
+
Vector<Vector<Vector2> > BitMap::clip_opaque_to_polygons(const Rect2 &p_rect, float p_epsilon) const {
Rect2i r = Rect2i(0, 0, width, height).clip(p_rect);
+#ifdef DEBUG_ENABLED
print_line("Rect: " + r);
+#endif
Point2i from;
Ref<BitMap> fill;
fill.instance();
@@ -454,9 +515,13 @@ Vector<Vector<Vector2> > BitMap::clip_opaque_to_polygons(const Rect2 &p_rect, fl
if (!fill->get_bit(Point2(j, i)) && get_bit(Point2(j, i))) {
Vector<Vector2> polygon = _march_square(r, Point2i(j, i));
+#ifdef DEBUG_ENABLED
print_line("pre reduce: " + itos(polygon.size()));
+#endif
polygon = reduce(polygon, r, p_epsilon);
+#ifdef DEBUG_ENABLED
print_line("post reduce: " + itos(polygon.size()));
+#endif
polygons.push_back(polygon);
fill_bits(this, fill, Point2i(j, i), r);
}
@@ -510,6 +575,34 @@ void BitMap::grow_mask(int p_pixels, const Rect2 &p_rect) {
}
}
+Array BitMap::_opaque_to_polygons_bind(const Rect2 &p_rect, float p_epsilon) const {
+
+ Vector<Vector<Vector2> > result = clip_opaque_to_polygons(p_rect, p_epsilon);
+
+ // Convert result to bindable types
+
+ Array result_array;
+ result_array.resize(result.size());
+ for (int i = 0; i < result.size(); i++) {
+
+ const Vector<Vector2> &polygon = result[i];
+
+ PoolVector2Array polygon_array;
+ polygon_array.resize(polygon.size());
+
+ {
+ PoolVector2Array::Write w = polygon_array.write();
+ for (int j = 0; j < polygon.size(); j++) {
+ w[j] = polygon[j];
+ }
+ }
+
+ result_array[i] = polygon_array;
+ }
+
+ return result_array;
+}
+
void BitMap::_bind_methods() {
ClassDB::bind_method(D_METHOD("create", "size"), &BitMap::create);
@@ -526,6 +619,9 @@ void BitMap::_bind_methods() {
ClassDB::bind_method(D_METHOD("_set_data"), &BitMap::_set_data);
ClassDB::bind_method(D_METHOD("_get_data"), &BitMap::_get_data);
+ ClassDB::bind_method(D_METHOD("grow_mask", "pixels", "rect"), &BitMap::grow_mask);
+ ClassDB::bind_method(D_METHOD("opaque_to_polygons", "rect", "epsilon"), &BitMap::_opaque_to_polygons_bind, DEFVAL(2.0));
+
ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_data", "_get_data");
}
diff --git a/scene/resources/bit_mask.h b/scene/resources/bit_mask.h
index dcd5edb4fb..40f0bfb04a 100644
--- a/scene/resources/bit_mask.h
+++ b/scene/resources/bit_mask.h
@@ -46,6 +46,8 @@ class BitMap : public Resource {
Vector<Vector2> _march_square(const Rect2i &rect, const Point2i &start) const;
+ Array _opaque_to_polygons_bind(const Rect2 &p_rect, float p_epsilon) const;
+
protected:
void _set_data(const Dictionary &p_d);
Dictionary _get_data() const;
diff --git a/scene/resources/color_ramp.cpp b/scene/resources/color_ramp.cpp
index b2f586d02d..4a43303d84 100644
--- a/scene/resources/color_ramp.cpp
+++ b/scene/resources/color_ramp.cpp
@@ -40,10 +40,10 @@
Gradient::Gradient() {
//Set initial color ramp transition from black to white
points.resize(2);
- points[0].color = Color(0, 0, 0, 1);
- points[0].offset = 0;
- points[1].color = Color(1, 1, 1, 1);
- points[1].offset = 1;
+ points.write[0].color = Color(0, 0, 0, 1);
+ points.write[0].offset = 0;
+ points.write[1].color = Color(1, 1, 1, 1);
+ points.write[1].offset = 1;
is_sorted = true;
}
@@ -79,7 +79,7 @@ Vector<float> Gradient::get_offsets() const {
Vector<float> offsets;
offsets.resize(points.size());
for (int i = 0; i < points.size(); i++) {
- offsets[i] = points[i].offset;
+ offsets.write[i] = points[i].offset;
}
return offsets;
}
@@ -88,7 +88,7 @@ Vector<Color> Gradient::get_colors() const {
Vector<Color> colors;
colors.resize(points.size());
for (int i = 0; i < points.size(); i++) {
- colors[i] = points[i].color;
+ colors.write[i] = points[i].color;
}
return colors;
}
@@ -96,7 +96,7 @@ Vector<Color> Gradient::get_colors() const {
void Gradient::set_offsets(const Vector<float> &p_offsets) {
points.resize(p_offsets.size());
for (int i = 0; i < points.size(); i++) {
- points[i].offset = p_offsets[i];
+ points.write[i].offset = p_offsets[i];
}
is_sorted = false;
emit_signal(CoreStringNames::get_singleton()->changed);
@@ -107,7 +107,7 @@ void Gradient::set_colors(const Vector<Color> &p_colors) {
is_sorted = false;
points.resize(p_colors.size());
for (int i = 0; i < points.size(); i++) {
- points[i].color = p_colors[i];
+ points.write[i].color = p_colors[i];
}
emit_signal(CoreStringNames::get_singleton()->changed);
}
@@ -144,7 +144,7 @@ void Gradient::set_points(Vector<Gradient::Point> &p_points) {
void Gradient::set_offset(int pos, const float offset) {
if (points.size() <= pos)
points.resize(pos + 1);
- points[pos].offset = offset;
+ points.write[pos].offset = offset;
is_sorted = false;
emit_signal(CoreStringNames::get_singleton()->changed);
}
@@ -160,7 +160,7 @@ void Gradient::set_color(int pos, const Color &color) {
points.resize(pos + 1);
is_sorted = false;
}
- points[pos].color = color;
+ points.write[pos].color = color;
emit_signal(CoreStringNames::get_singleton()->changed);
}
diff --git a/scene/resources/color_ramp.h b/scene/resources/color_ramp.h
index c042a0d3d0..070ad7f0d3 100644
--- a/scene/resources/color_ramp.h
+++ b/scene/resources/color_ramp.h
@@ -98,7 +98,7 @@ public:
while (low <= high) {
middle = (low + high) / 2;
- Point &point = points[middle];
+ const Point &point = points[middle];
if (point.offset > p_offset) {
high = middle - 1; //search low end of array
} else if (point.offset < p_offset) {
@@ -118,8 +118,8 @@ public:
return points[points.size() - 1].color;
if (first < 0)
return points[0].color;
- Point &pointFirst = points[first];
- Point &pointSecond = points[second];
+ const Point &pointFirst = points[first];
+ const Point &pointSecond = points[second];
return pointFirst.color.linear_interpolate(pointSecond.color, (p_offset - pointFirst.offset) / (pointSecond.offset - pointFirst.offset));
}
diff --git a/scene/resources/concave_polygon_shape.cpp b/scene/resources/concave_polygon_shape.cpp
index 935f041837..bc9e2848b3 100644
--- a/scene/resources/concave_polygon_shape.cpp
+++ b/scene/resources/concave_polygon_shape.cpp
@@ -56,8 +56,8 @@ Vector<Vector3> ConcavePolygonShape::_gen_debug_mesh_lines() {
int idx = 0;
for (Set<DrawEdge>::Element *E = edges.front(); E; E = E->next()) {
- points[idx + 0] = E->get().a;
- points[idx + 1] = E->get().b;
+ points.write[idx + 0] = E->get().a;
+ points.write[idx + 1] = E->get().b;
idx += 2;
}
diff --git a/scene/resources/convex_polygon_shape.cpp b/scene/resources/convex_polygon_shape.cpp
index a2e0996996..fa9369d3bc 100644
--- a/scene/resources/convex_polygon_shape.cpp
+++ b/scene/resources/convex_polygon_shape.cpp
@@ -46,8 +46,8 @@ Vector<Vector3> ConvexPolygonShape::_gen_debug_mesh_lines() {
Vector<Vector3> lines;
lines.resize(md.edges.size() * 2);
for (int i = 0; i < md.edges.size(); i++) {
- lines[i * 2 + 0] = md.vertices[md.edges[i].a];
- lines[i * 2 + 1] = md.vertices[md.edges[i].b];
+ lines.write[i * 2 + 0] = md.vertices[md.edges[i].a];
+ lines.write[i * 2 + 1] = md.vertices[md.edges[i].b];
}
return lines;
}
diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp
index f2fd919f20..d8989bf062 100644
--- a/scene/resources/curve.cpp
+++ b/scene/resources/curve.cpp
@@ -153,25 +153,25 @@ void Curve::clean_dupes() {
void Curve::set_point_left_tangent(int i, real_t tangent) {
ERR_FAIL_INDEX(i, _points.size());
- _points[i].left_tangent = tangent;
- _points[i].left_mode = TANGENT_FREE;
+ _points.write[i].left_tangent = tangent;
+ _points.write[i].left_mode = TANGENT_FREE;
mark_dirty();
}
void Curve::set_point_right_tangent(int i, real_t tangent) {
ERR_FAIL_INDEX(i, _points.size());
- _points[i].right_tangent = tangent;
- _points[i].right_mode = TANGENT_FREE;
+ _points.write[i].right_tangent = tangent;
+ _points.write[i].right_mode = TANGENT_FREE;
mark_dirty();
}
void Curve::set_point_left_mode(int i, TangentMode p_mode) {
ERR_FAIL_INDEX(i, _points.size());
- _points[i].left_mode = p_mode;
+ _points.write[i].left_mode = p_mode;
if (i > 0) {
if (p_mode == TANGENT_LINEAR) {
Vector2 v = (_points[i - 1].pos - _points[i].pos).normalized();
- _points[i].left_tangent = v.y / v.x;
+ _points.write[i].left_tangent = v.y / v.x;
}
}
mark_dirty();
@@ -179,11 +179,11 @@ void Curve::set_point_left_mode(int i, TangentMode p_mode) {
void Curve::set_point_right_mode(int i, TangentMode p_mode) {
ERR_FAIL_INDEX(i, _points.size());
- _points[i].right_mode = p_mode;
+ _points.write[i].right_mode = p_mode;
if (i + 1 < _points.size()) {
if (p_mode == TANGENT_LINEAR) {
Vector2 v = (_points[i + 1].pos - _points[i].pos).normalized();
- _points[i].right_tangent = v.y / v.x;
+ _points.write[i].right_tangent = v.y / v.x;
}
}
mark_dirty();
@@ -222,7 +222,7 @@ void Curve::clear_points() {
void Curve::set_point_value(int p_index, real_t pos) {
ERR_FAIL_INDEX(p_index, _points.size());
- _points[p_index].pos.y = pos;
+ _points.write[p_index].pos.y = pos;
update_auto_tangents(p_index);
mark_dirty();
}
@@ -232,10 +232,10 @@ int Curve::set_point_offset(int p_index, float offset) {
Point p = _points[p_index];
remove_point(p_index);
int i = add_point(Vector2(offset, p.pos.y));
- _points[i].left_tangent = p.left_tangent;
- _points[i].right_tangent = p.right_tangent;
- _points[i].left_mode = p.left_mode;
- _points[i].right_mode = p.right_mode;
+ _points.write[i].left_tangent = p.left_tangent;
+ _points.write[i].right_tangent = p.right_tangent;
+ _points.write[i].left_mode = p.left_mode;
+ _points.write[i].right_mode = p.right_mode;
if (p_index != i)
update_auto_tangents(p_index);
update_auto_tangents(i);
@@ -254,7 +254,7 @@ Curve::Point Curve::get_point(int p_index) const {
void Curve::update_auto_tangents(int i) {
- Point &p = _points[i];
+ Point &p = _points.write[i];
if (i > 0) {
if (p.left_mode == TANGENT_LINEAR) {
@@ -263,7 +263,7 @@ void Curve::update_auto_tangents(int i) {
}
if (_points[i - 1].right_mode == TANGENT_LINEAR) {
Vector2 v = (_points[i - 1].pos - p.pos).normalized();
- _points[i - 1].right_tangent = v.y / v.x;
+ _points.write[i - 1].right_tangent = v.y / v.x;
}
}
@@ -274,7 +274,7 @@ void Curve::update_auto_tangents(int i) {
}
if (_points[i + 1].left_mode == TANGENT_LINEAR) {
Vector2 v = (_points[i + 1].pos - p.pos).normalized();
- _points[i + 1].left_tangent = v.y / v.x;
+ _points.write[i + 1].left_tangent = v.y / v.x;
}
}
}
@@ -402,7 +402,7 @@ void Curve::set_data(Array input) {
for (int j = 0; j < _points.size(); ++j) {
- Point &p = _points[j];
+ Point &p = _points.write[j];
int i = j * ELEMS;
p.pos = input[i];
@@ -426,12 +426,12 @@ void Curve::bake() {
for (int i = 1; i < _bake_resolution - 1; ++i) {
real_t x = i / static_cast<real_t>(_bake_resolution);
real_t y = interpolate(x);
- _baked_cache[i] = y;
+ _baked_cache.write[i] = y;
}
if (_points.size() != 0) {
- _baked_cache[0] = _points[0].pos.y;
- _baked_cache[_baked_cache.size() - 1] = _points[_points.size() - 1].pos.y;
+ _baked_cache.write[0] = _points[0].pos.y;
+ _baked_cache.write[_baked_cache.size() - 1] = _points[_points.size() - 1].pos.y;
}
_baked_cache_dirty = false;
@@ -553,7 +553,7 @@ void Curve2D::set_point_position(int p_index, const Vector2 &p_pos) {
ERR_FAIL_INDEX(p_index, points.size());
- points[p_index].pos = p_pos;
+ points.write[p_index].pos = p_pos;
baked_cache_dirty = true;
emit_signal(CoreStringNames::get_singleton()->changed);
}
@@ -567,7 +567,7 @@ void Curve2D::set_point_in(int p_index, const Vector2 &p_in) {
ERR_FAIL_INDEX(p_index, points.size());
- points[p_index].in = p_in;
+ points.write[p_index].in = p_in;
baked_cache_dirty = true;
emit_signal(CoreStringNames::get_singleton()->changed);
}
@@ -581,7 +581,7 @@ void Curve2D::set_point_out(int p_index, const Vector2 &p_out) {
ERR_FAIL_INDEX(p_index, points.size());
- points[p_index].out = p_out;
+ points.write[p_index].out = p_out;
baked_cache_dirty = true;
emit_signal(CoreStringNames::get_singleton()->changed);
}
@@ -930,9 +930,9 @@ void Curve2D::_set_data(const Dictionary &p_data) {
for (int i = 0; i < points.size(); i++) {
- points[i].in = r[i * 3 + 0];
- points[i].out = r[i * 3 + 1];
- points[i].pos = r[i * 3 + 2];
+ points.write[i].in = r[i * 3 + 0];
+ points.write[i].out = r[i * 3 + 1];
+ points.write[i].pos = r[i * 3 + 2];
}
baked_cache_dirty = true;
@@ -952,7 +952,7 @@ PoolVector2Array Curve2D::tessellate(int p_max_stages, float p_tolerance) const
int pc = 1;
for (int i = 0; i < points.size() - 1; i++) {
- _bake_segment2d(midpoints[i], 0, 1, points[i].pos, points[i].out, points[i + 1].pos, points[i + 1].in, 0, p_max_stages, p_tolerance);
+ _bake_segment2d(midpoints.write[i], 0, 1, points[i].pos, points[i].out, points[i + 1].pos, points[i + 1].in, 0, p_max_stages, p_tolerance);
pc++;
pc += midpoints[i].size();
}
@@ -1049,7 +1049,7 @@ void Curve3D::set_point_position(int p_index, const Vector3 &p_pos) {
ERR_FAIL_INDEX(p_index, points.size());
- points[p_index].pos = p_pos;
+ points.write[p_index].pos = p_pos;
baked_cache_dirty = true;
emit_signal(CoreStringNames::get_singleton()->changed);
}
@@ -1063,7 +1063,7 @@ void Curve3D::set_point_tilt(int p_index, float p_tilt) {
ERR_FAIL_INDEX(p_index, points.size());
- points[p_index].tilt = p_tilt;
+ points.write[p_index].tilt = p_tilt;
baked_cache_dirty = true;
emit_signal(CoreStringNames::get_singleton()->changed);
}
@@ -1077,7 +1077,7 @@ void Curve3D::set_point_in(int p_index, const Vector3 &p_in) {
ERR_FAIL_INDEX(p_index, points.size());
- points[p_index].in = p_in;
+ points.write[p_index].in = p_in;
baked_cache_dirty = true;
emit_signal(CoreStringNames::get_singleton()->changed);
}
@@ -1091,7 +1091,7 @@ void Curve3D::set_point_out(int p_index, const Vector3 &p_out) {
ERR_FAIL_INDEX(p_index, points.size());
- points[p_index].out = p_out;
+ points.write[p_index].out = p_out;
baked_cache_dirty = true;
emit_signal(CoreStringNames::get_singleton()->changed);
}
@@ -1621,10 +1621,10 @@ void Curve3D::_set_data(const Dictionary &p_data) {
for (int i = 0; i < points.size(); i++) {
- points[i].in = r[i * 3 + 0];
- points[i].out = r[i * 3 + 1];
- points[i].pos = r[i * 3 + 2];
- points[i].tilt = rt[i];
+ points.write[i].in = r[i * 3 + 0];
+ points.write[i].out = r[i * 3 + 1];
+ points.write[i].pos = r[i * 3 + 2];
+ points.write[i].tilt = rt[i];
}
baked_cache_dirty = true;
@@ -1644,7 +1644,7 @@ PoolVector3Array Curve3D::tessellate(int p_max_stages, float p_tolerance) const
int pc = 1;
for (int i = 0; i < points.size() - 1; i++) {
- _bake_segment3d(midpoints[i], 0, 1, points[i].pos, points[i].out, points[i + 1].pos, points[i + 1].in, 0, p_max_stages, p_tolerance);
+ _bake_segment3d(midpoints.write[i], 0, 1, points[i].pos, points[i].out, points[i + 1].pos, points[i + 1].in, 0, p_max_stages, p_tolerance);
pc++;
pc += midpoints[i].size();
}
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index 702953fa40..0eee2ae393 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -434,9 +434,13 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_color("font_color_selected", "LineEdit", Color(0, 0, 0));
theme->set_color("cursor_color", "LineEdit", control_font_color_hover);
theme->set_color("selection_color", "LineEdit", font_color_selection);
+ theme->set_color("clear_button_color", "LineEdit", control_font_color);
+ theme->set_color("clear_button_color_pressed", "LineEdit", control_font_color_pressed);
theme->set_constant("minimum_spaces", "LineEdit", 12 * scale);
+ theme->set_icon("clear", "LineEdit", make_icon(line_edit_clear_png));
+
// ProgressBar
theme->set_stylebox("bg", "ProgressBar", make_stylebox(progress_bar_png, 4, 4, 4, 4, 0, 0, 0, 0));
@@ -476,6 +480,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_color("symbol_color", "TextEdit", control_font_color_hover);
theme->set_color("brace_mismatch_color", "TextEdit", Color(1, 0.2, 0.2));
theme->set_color("line_number_color", "TextEdit", Color::html("66aaaaaa"));
+ theme->set_color("safe_line_number_color", "TextEdit", Color::html("99aac8aa"));
theme->set_color("function_color", "TextEdit", Color::html("66a2ce"));
theme->set_color("member_variable_color", "TextEdit", Color::html("e64e59"));
theme->set_color("number_color", "TextEdit", Color::html("EB9532"));
@@ -585,6 +590,8 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_stylebox("panel_disabled", "PopupMenu", make_stylebox(popup_bg_disabled_png, 4, 4, 4, 4));
theme->set_stylebox("hover", "PopupMenu", selected);
theme->set_stylebox("separator", "PopupMenu", make_stylebox(vseparator_png, 3, 3, 3, 3));
+ theme->set_stylebox("labeled_separator_left", "PopupMenu", make_stylebox(vseparator_png, 0, 0, 0, 0));
+ theme->set_stylebox("labeled_separator_right", "PopupMenu", make_stylebox(vseparator_png, 0, 0, 0, 0));
theme->set_icon("checked", "PopupMenu", make_icon(checked_png));
theme->set_icon("unchecked", "PopupMenu", make_icon(unchecked_png));
@@ -860,7 +867,6 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
Ref<StyleBoxTexture> ttnc = make_stylebox(full_panel_bg_png, 8, 8, 8, 8);
ttnc->set_draw_center(false);
- theme->set_stylebox("border", "ReferenceRect", make_stylebox(reference_border_png, 4, 4, 4, 4));
theme->set_stylebox("panelnc", "Panel", ttnc);
theme->set_stylebox("panelf", "Panel", tc_sb);
@@ -880,6 +886,10 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_icon("logo", "Icons", make_icon(logo_png));
+ // Visual Node Ports
+ theme->set_constant("port_grab_distance_horizontal", "GraphEdit", 48 * scale);
+ theme->set_constant("port_grab_distance_vertical", "GraphEdit", 6 * scale);
+
// Theme
default_icon = make_icon(error_icon_png);
diff --git a/scene/resources/default_theme/line_edit_clear.png b/scene/resources/default_theme/line_edit_clear.png
new file mode 100644
index 0000000000..af2775a132
--- /dev/null
+++ b/scene/resources/default_theme/line_edit_clear.png
Binary files differ
diff --git a/scene/resources/default_theme/make_header.py b/scene/resources/default_theme/make_header.py
index db449f9417..73b1ae0b0b 100755
--- a/scene/resources/default_theme/make_header.py
+++ b/scene/resources/default_theme/make_header.py
@@ -4,15 +4,16 @@ import os
import glob
import string
+enc = "utf-8"
# Generate include files
f = open("theme_data.h", "wb")
-f.write("// THIS FILE HAS BEEN AUTOGENERATED, DON'T EDIT!!\n")
+f.write(b"// THIS FILE HAS BEEN AUTOGENERATED, DON\'T EDIT!!\n")
# Generate png image block
-f.write("\n// png image block\n");
+f.write(b"\n// png image block\n")
pixmaps = glob.glob("*.png")
pixmaps.sort()
@@ -21,22 +22,23 @@ for x in pixmaps:
var_str = x[:-4] + "_png"
- f.write("\nstatic const unsigned char " + var_str + "[] = {\n\t")
+ s = "\nstatic const unsigned char " + var_str + "[] = {\n\t"
+ f.write(s.encode(enc))
pngf = open(x, "rb")
b = pngf.read(1)
while(len(b) == 1):
- f.write(hex(ord(b)))
+ f.write(hex(ord(b)).encode(enc))
b = pngf.read(1)
if (len(b) == 1):
- f.write(", ")
+ f.write(b", ")
- f.write("\n};\n")
+ f.write(b"\n};\n")
pngf.close()
# Generate shaders block
-f.write("\n// shaders block\n");
+f.write(b"\n// shaders block\n");
shaders = glob.glob("*.gsl")
shaders.sort()
@@ -45,7 +47,8 @@ for x in shaders:
var_str = x[:-4] + "_shader_code"
- f.write("\nstatic const char *" + var_str + " = \n")
+ s = "\nstatic const char *" + var_str + " = \n"
+ f.write(s.encode(enc))
sf = open(x, "rb")
@@ -55,12 +58,13 @@ for x in shaders:
b = b[:-2]
if (b.endswith("\n")):
b = b[:-1]
- f.write(" \"" + b)
+ s = ' \"' + b
+ f.write(s.encode(enc))
b = sf.readline()
if (b != ""):
- f.write("\"\n")
+ f.write(b'"\n')
- f.write("\";\n")
+ f.write(b'";\n')
sf.close()
f.close()
diff --git a/scene/resources/default_theme/theme_data.h b/scene/resources/default_theme/theme_data.h
index c6b37cad5a..353e7eddbe 100644
--- a/scene/resources/default_theme/theme_data.h
+++ b/scene/resources/default_theme/theme_data.h
@@ -3,35 +3,35 @@
// png image block
static const unsigned char arrow_down_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x6, 0x0, 0x0, 0x0, 0x56, 0x75, 0x5c, 0xe7, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x6d, 0x49, 0x44, 0x41, 0x54, 0x28, 0x91, 0x63, 0x60, 0x18, 0x74, 0x80, 0x11, 0xc6, 0x78, 0xf0, 0xe0, 0xc1, 0x7f, 0x7c, 0xa, 0x15, 0x14, 0x14, 0x18, 0x19, 0x18, 0x18, 0x18, 0x98, 0x48, 0xb5, 0x81, 0x7c, 0xd, 0x8c, 0x8c, 0x8c, 0xf1, 0xc, 0xc, 0xc, 0x5f, 0xb1, 0xa8, 0xf9, 0xce, 0xc8, 0xc8, 0x98, 0xe, 0x57, 0x87, 0x2c, 0x73, 0xff, 0xfe, 0x7d, 0xd, 0x6, 0x6, 0x86, 0x55, 0x8c, 0x8c, 0x8c, 0xba, 0x50, 0xa1, 0x1b, 0xcc, 0xcc, 0xcc, 0x61, 0xb2, 0xb2, 0xb2, 0x97, 0xb1, 0x6a, 0x60, 0x60, 0x60, 0x60, 0x78, 0xf1, 0xe2, 0x5, 0xf7, 0xcf, 0x9f, 0x3f, 0xa7, 0x30, 0x30, 0x30, 0x30, 0xb0, 0xb3, 0xb3, 0xe7, 0x48, 0x48, 0x48, 0x60, 0xb3, 0x75, 0x30, 0x1, 0x0, 0x28, 0x20, 0x14, 0xc2, 0x1b, 0xd0, 0x7c, 0xca, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x4, 0x0, 0x0, 0x0, 0xfc, 0x7c, 0x94, 0x6c, 0x0, 0x0, 0x0, 0x34, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0xa0, 0x32, 0x78, 0xf0, 0x1f, 0x15, 0x52, 0x20, 0xf1, 0x30, 0xee, 0xc1, 0x17, 0xb8, 0xf0, 0xb7, 0x87, 0x69, 0x48, 0xb6, 0xdc, 0xd7, 0xb8, 0x7f, 0x9, 0x2c, 0x7c, 0xfd, 0xb1, 0x2e, 0x9a, 0x3, 0x5e, 0x70, 0x3f, 0x9c, 0xff, 0x70, 0xfe, 0xb, 0x6e, 0x6, 0xea, 0x3, 0x0, 0xfb, 0x81, 0x48, 0xb8, 0x4d, 0xe4, 0x75, 0xd9, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char arrow_right_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x6, 0x0, 0x0, 0x0, 0x56, 0x75, 0x5c, 0xe7, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x6c, 0x49, 0x44, 0x41, 0x54, 0x28, 0x91, 0x63, 0x60, 0xa0, 0x35, 0x60, 0x44, 0xe6, 0x3c, 0x78, 0xf0, 0xe0, 0x3f, 0x8c, 0xfd, 0xff, 0xff, 0xff, 0x44, 0x45, 0x45, 0xc5, 0x5, 0xe8, 0x1a, 0x98, 0x70, 0x9a, 0xc4, 0xc8, 0x38, 0xe5, 0xe1, 0xc3, 0x87, 0xda, 0x44, 0x6b, 0x60, 0x60, 0x60, 0xe0, 0xfe, 0xff, 0xff, 0xff, 0xaa, 0x17, 0x2f, 0x5e, 0x70, 0x13, 0xab, 0x81, 0x81, 0x81, 0x81, 0x41, 0xeb, 0xe7, 0xcf, 0x9f, 0x53, 0x48, 0xd1, 0x80, 0x1, 0x8, 0x69, 0xb8, 0xc6, 0xce, 0xce, 0x9e, 0x43, 0xac, 0x86, 0xaf, 0x8c, 0x8c, 0x8c, 0x61, 0x12, 0x12, 0x12, 0x5f, 0x89, 0xd2, 0xf0, 0xff, 0xff, 0xff, 0x1c, 0x79, 0x79, 0xf9, 0xab, 0x84, 0x1d, 0x49, 0x6d, 0x0, 0x0, 0x8f, 0x30, 0x1e, 0x10, 0x6e, 0x79, 0xda, 0xf9, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x4, 0x0, 0x0, 0x0, 0xfc, 0x7c, 0x94, 0x6c, 0x0, 0x0, 0x0, 0x2e, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x20, 0x17, 0x3c, 0xf8, 0xf, 0x82, 0xf7, 0x13, 0x70, 0x48, 0x3c, 0xf8, 0xf2, 0x50, 0x1b, 0x43, 0x2, 0xa, 0xaf, 0xbe, 0xe0, 0xc6, 0x2e, 0xf1, 0xff, 0xe1, 0x7c, 0x12, 0x24, 0x10, 0x46, 0x11, 0xb6, 0x1c, 0xe1, 0x5c, 0xa, 0x0, 0x0, 0xe0, 0x14, 0x48, 0xb1, 0x3d, 0x1b, 0x7a, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char background_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x20, 0x8, 0x3, 0x0, 0x0, 0x0, 0x44, 0xa4, 0x8a, 0xc6, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x1, 0x11, 0x50, 0x4c, 0x54, 0x45, 0x91, 0xc9, 0xab, 0x90, 0xc9, 0xab, 0x90, 0xc9, 0xaa, 0x90, 0xc8, 0xab, 0x91, 0xc9, 0xaa, 0x91, 0xc8, 0xab, 0x90, 0xc8, 0xaa, 0x8f, 0xc8, 0xab, 0x8f, 0xc9, 0xab, 0x8f, 0xc8, 0xaa, 0x90, 0xc7, 0xaa, 0x90, 0xc7, 0xab, 0x8f, 0xc7, 0xaa, 0x8f, 0xc7, 0xab, 0x8e, 0xc7, 0xab, 0x8e, 0xc6, 0xab, 0x8f, 0xc6, 0xab, 0x8e, 0xc6, 0xaa, 0x8f, 0xc6, 0xaa, 0x8e, 0xc7, 0xaa, 0x8e, 0xc5, 0xaa, 0x8e, 0xc5, 0xab, 0x8d, 0xc5, 0xaa, 0x8d, 0xc5, 0xab, 0x8d, 0xc6, 0xaa, 0x8d, 0xc6, 0xab, 0x8d, 0xc4, 0xaa, 0x8e, 0xc4, 0xab, 0x8d, 0xc4, 0xab, 0x8e, 0xc4, 0xaa, 0x8c, 0xc4, 0xaa, 0x8c, 0xc5, 0xaa, 0x8d, 0xc3, 0xab, 0x8d, 0xc3, 0xaa, 0x8c, 0xc3, 0xaa, 0x8c, 0xc4, 0xab, 0x8c, 0xc3, 0xab, 0x8c, 0xc2, 0xab, 0x8b, 0xc2, 0xaa, 0x8b, 0xc3, 0xaa, 0x8b, 0xc3, 0xab, 0x8c, 0xc2, 0xaa, 0x8b, 0xc2, 0xab, 0x8b, 0xc1, 0xaa, 0x8b, 0xc1, 0xab, 0x8a, 0xc2, 0xaa, 0x8a, 0xc1, 0xaa, 0x8a, 0xc0, 0xaa, 0x8b, 0xc0, 0xaa, 0x8a, 0xc1, 0xa9, 0x8a, 0xc0, 0xa9, 0x89, 0xc0, 0xaa, 0x8a, 0xbf, 0xaa, 0x89, 0xbf, 0xaa, 0x89, 0xbf, 0xa9, 0x8a, 0xbf, 0xa9, 0x88, 0xbf, 0xaa, 0x89, 0xbe, 0xaa, 0x89, 0xbe, 0xa9, 0x88, 0xbf, 0xa9, 0x88, 0xbe, 0xa9, 0x88, 0xbe, 0xaa, 0x88, 0xbd, 0xaa, 0x88, 0xbd, 0xa9, 0x89, 0xbd, 0xaa, 0x89, 0xbd, 0xa9, 0x87, 0xbe, 0xa9, 0x87, 0xbd, 0xaa, 0x87, 0xbe, 0xaa, 0x87, 0xbd, 0xa9, 0x87, 0xbc, 0xaa, 0x88, 0xbc, 0xa9, 0x88, 0xbc, 0xaa, 0x87, 0xbc, 0xa9, 0x86, 0xbc, 0xa9, 0x87, 0xbb, 0xaa, 0x87, 0xbb, 0xa9, 0x86, 0xbb, 0xa9, 0x86, 0xbc, 0xaa, 0x86, 0xbb, 0xaa, 0x86, 0xba, 0xaa, 0x86, 0xba, 0xa9, 0x85, 0xba, 0xa9, 0x85, 0xbb, 0xaa, 0x85, 0xbb, 0xa9, 0x85, 0xba, 0xaa, 0x85, 0xb9, 0xa9, 0x86, 0xb9, 0xa9, 0x86, 0xb9, 0xaa, 0x85, 0xb9, 0xaa, 0xff, 0xff, 0xff, 0x25, 0xe, 0xc5, 0xe1, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x5a, 0x3, 0xbb, 0xa5, 0xa2, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x2, 0xaa, 0x49, 0x44, 0x41, 0x54, 0x38, 0xcb, 0x45, 0x4b, 0xd, 0x63, 0x9a, 0x56, 0x14, 0xbd, 0x86, 0x2d, 0x24, 0x2b, 0xf8, 0x8a, 0x1, 0xcc, 0x18, 0x23, 0xcd, 0x8b, 0xc5, 0x2a, 0xa9, 0x6e, 0x51, 0x98, 0x58, 0x3e, 0xda, 0x52, 0x69, 0x9e, 0x4a, 0x10, 0xba, 0xb8, 0xec, 0xff, 0xff, 0x91, 0x9d, 0x47, 0xd2, 0xf5, 0xbc, 0xcb, 0x3d, 0x1f, 0xf7, 0x40, 0xd4, 0x23, 0x4c, 0x4f, 0x2, 0x9b, 0xa8, 0x93, 0x27, 0x9d, 0xa3, 0xe7, 0x50, 0xe9, 0xc9, 0x79, 0x69, 0x74, 0xf7, 0x9f, 0x7a, 0x8a, 0xd2, 0xfb, 0xf9, 0xf4, 0x25, 0x53, 0xd5, 0x33, 0xf4, 0xcf, 0xce, 0x90, 0x9d, 0xa8, 0xa, 0x80, 0x75, 0xaa, 0xc8, 0xca, 0xa9, 0xa2, 0x9c, 0xf4, 0x54, 0x52, 0x91, 0x9c, 0xab, 0x2a, 0x46, 0x42, 0xf9, 0xe5, 0xb4, 0x2b, 0xa9, 0xe7, 0xca, 0xab, 0x57, 0xc8, 0x15, 0x8d, 0x74, 0x4d, 0xd5, 0x25, 0x40, 0x8a, 0xae, 0xea, 0xda, 0xb9, 0xd6, 0x59, 0x55, 0x12, 0xfe, 0xd0, 0x49, 0xef, 0xb3, 0xbe, 0xfe, 0x5a, 0x37, 0x34, 0x66, 0x30, 0x5d, 0xd3, 0xfb, 0xfa, 0x80, 0x69, 0x3, 0x7d, 0x70, 0xd1, 0xd5, 0xfa, 0x9a, 0x4e, 0x3, 0xe3, 0x62, 0xd0, 0xd7, 0xd, 0xd6, 0x37, 0x98, 0xd1, 0xef, 0xf, 0xc0, 0x9a, 0xc1, 0x2e, 0xc, 0xc6, 0x2e, 0xd8, 0xeb, 0x1, 0x86, 0x98, 0x61, 0x32, 0x13, 0x7f, 0x33, 0x66, 0x49, 0x36, 0xba, 0x41, 0x68, 0x18, 0xdd, 0x66, 0x64, 0x5b, 0x96, 0x69, 0x59, 0x90, 0xd6, 0xf0, 0x72, 0x68, 0x9a, 0x43, 0xd3, 0xfa, 0xd5, 0x32, 0x2f, 0x6d, 0xe3, 0xd2, 0xb2, 0x98, 0x65, 0x30, 0x93, 0x1c, 0x7b, 0x88, 0x67, 0xdb, 0xa6, 0xd, 0x72, 0x7e, 0x1b, 0xba, 0xa8, 0xc0, 0xda, 0xbf, 0xf, 0x91, 0xba, 0xb6, 0x4b, 0x8e, 0xe7, 0x78, 0xee, 0xd0, 0x75, 0x87, 0x1e, 0xac, 0xe3, 0x60, 0x5f, 0x39, 0x57, 0xe, 0x84, 0xe7, 0xd8, 0xb6, 0x63, 0x5f, 0xd1, 0x1b, 0xe7, 0x9a, 0xcb, 0x92, 0xe7, 0xba, 0xae, 0xe7, 0xf0, 0x1b, 0xc7, 0xb9, 0x76, 0x3c, 0x8e, 0xb3, 0x87, 0x16, 0xbf, 0xf1, 0x88, 0x73, 0xee, 0x8c, 0x46, 0xd8, 0xd7, 0x7c, 0xe4, 0xf1, 0xef, 0x18, 0x79, 0x37, 0x9c, 0x7b, 0x6f, 0xbc, 0x11, 0x27, 0xfe, 0xd6, 0xf7, 0xf9, 0x98, 0xf3, 0x77, 0x13, 0xfe, 0x96, 0x8f, 0xb8, 0x3f, 0x96, 0x65, 0x9f, 0x4f, 0x38, 0x1f, 0x4f, 0xf8, 0x68, 0xc2, 0xc9, 0x7f, 0xc6, 0x74, 0xea, 0x73, 0x49, 0x13, 0xcc, 0x78, 0xe2, 0xfb, 0x13, 0x59, 0xf2, 0xdf, 0xf9, 0x63, 0xa, 0xa6, 0xfe, 0x34, 0xf0, 0xf1, 0xba, 0xe9, 0x20, 0x39, 0xf0, 0x6f, 0x83, 0xdb, 0x69, 0x10, 0x4c, 0x29, 0x78, 0x3f, 0xb, 0x50, 0x91, 0xe7, 0xc0, 0x9f, 0x61, 0xdd, 0x6, 0xb3, 0xd9, 0xcc, 0xf7, 0xdf, 0x83, 0xe0, 0x2, 0x9a, 0xcd, 0x67, 0xcf, 0x98, 0x77, 0xea, 0xf, 0x29, 0xe4, 0xfc, 0x9, 0x13, 0x40, 0xd0, 0x1c, 0x87, 0x1f, 0xb8, 0x93, 0xab, 0xb, 0xee, 0x5e, 0x62, 0x5a, 0x2c, 0xe7, 0x21, 0x78, 0xb9, 0x58, 0x2e, 0xb1, 0xd1, 0xb8, 0x5b, 0x84, 0x4b, 0xd8, 0xf9, 0x7c, 0x81, 0xef, 0x2e, 0xa4, 0xc5, 0x22, 0xc, 0x97, 0x61, 0x18, 0x85, 0x12, 0x51, 0x4, 0x5e, 0x46, 0x61, 0xf4, 0x97, 0x74, 0xb, 0xb9, 0xa8, 0x3b, 0xad, 0xe2, 0x38, 0xa, 0xd7, 0xab, 0x28, 0x4, 0x85, 0x1f, 0xe2, 0x10, 0x1c, 0xc5, 0xe1, 0x2a, 0x5c, 0x25, 0x2b, 0x4a, 0xe3, 0x38, 0x49, 0x93, 0x24, 0x4d, 0xe3, 0x34, 0x4e, 0xe2, 0x68, 0xd, 0x1f, 0xad, 0x93, 0x24, 0x59, 0x23, 0xfa, 0xb0, 0x4e, 0x53, 0xca, 0xf2, 0x2c, 0xfb, 0xf8, 0xf1, 0x13, 0x6c, 0x92, 0x42, 0xa7, 0x49, 0x9e, 0xe6, 0x69, 0x92, 0x49, 0xd3, 0x65, 0x94, 0x7d, 0xce, 0xb2, 0x2c, 0xc9, 0xd2, 0xa2, 0xf8, 0x92, 0xe7, 0x59, 0x51, 0xc0, 0x7d, 0xce, 0xb, 0xc8, 0x1c, 0xc8, 0x36, 0x5, 0x95, 0x5f, 0xb3, 0x72, 0x53, 0x66, 0xf7, 0x5f, 0x37, 0x70, 0xf7, 0x79, 0x51, 0x88, 0xfb, 0x12, 0x3d, 0x91, 0xdd, 0x8b, 0x4d, 0x99, 0x8b, 0x92, 0x44, 0x59, 0xa, 0x51, 0x8a, 0x72, 0xb, 0x2e, 0x37, 0x2, 0x1a, 0xa2, 0x0, 0x8b, 0xd, 0x62, 0x21, 0x48, 0xec, 0x76, 0x7b, 0x21, 0xaa, 0x52, 0xec, 0xb6, 0xa2, 0xaa, 0xb6, 0xf, 0xfb, 0x7d, 0x2d, 0xc4, 0xf6, 0xa1, 0x7a, 0x10, 0xdb, 0x9d, 0x28, 0x77, 0x15, 0x55, 0xbb, 0xba, 0x92, 0xd8, 0x57, 0xbb, 0xaa, 0xaa, 0xeb, 0x7d, 0x2d, 0xed, 0xff, 0xdf, 0xbe, 0xa6, 0x43, 0xd5, 0x34, 0x75, 0xd3, 0x54, 0xcd, 0xa1, 0xaa, 0xf, 0x75, 0x83, 0xbc, 0xae, 0x5a, 0xb4, 0x64, 0xf6, 0xd, 0x1d, 0x6a, 0x25, 0x9a, 0xa6, 0x6d, 0xab, 0x43, 0x3, 0xfc, 0x2d, 0x57, 0x8b, 0xf7, 0xf8, 0xd8, 0xb4, 0x87, 0xb6, 0x6e, 0xe9, 0xb1, 0x6d, 0x8e, 0x6d, 0x7b, 0x6c, 0xff, 0x39, 0x3e, 0x1d, 0x9f, 0x20, 0x8f, 0xd2, 0x1d, 0xff, 0x45, 0xa, 0xdd, 0xb6, 0x4f, 0xff, 0x1, 0xbe, 0xd3, 0xa6, 0xf7, 0x55, 0x9e, 0xe1, 0xf0, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x20, 0x8, 0x3, 0x0, 0x0, 0x0, 0x44, 0xa4, 0x8a, 0xc6, 0x0, 0x0, 0x1, 0xe, 0x50, 0x4c, 0x54, 0x45, 0x91, 0xc9, 0xab, 0x90, 0xc9, 0xab, 0x90, 0xc9, 0xaa, 0x90, 0xc8, 0xab, 0x91, 0xc9, 0xaa, 0x91, 0xc8, 0xab, 0x90, 0xc8, 0xaa, 0x8f, 0xc8, 0xab, 0x8f, 0xc9, 0xab, 0x8f, 0xc8, 0xaa, 0x90, 0xc7, 0xaa, 0x90, 0xc7, 0xab, 0x8f, 0xc7, 0xaa, 0x8f, 0xc7, 0xab, 0x8e, 0xc7, 0xab, 0x8e, 0xc6, 0xab, 0x8f, 0xc6, 0xab, 0x8e, 0xc6, 0xaa, 0x8f, 0xc6, 0xaa, 0x8e, 0xc7, 0xaa, 0x8e, 0xc5, 0xaa, 0x8e, 0xc5, 0xab, 0x8d, 0xc5, 0xaa, 0x8d, 0xc5, 0xab, 0x8d, 0xc6, 0xaa, 0x8d, 0xc6, 0xab, 0x8d, 0xc4, 0xaa, 0x8e, 0xc4, 0xab, 0x8d, 0xc4, 0xab, 0x8e, 0xc4, 0xaa, 0x8c, 0xc4, 0xaa, 0x8c, 0xc5, 0xaa, 0x8d, 0xc3, 0xab, 0x8d, 0xc3, 0xaa, 0x8c, 0xc3, 0xaa, 0x8c, 0xc4, 0xab, 0x8c, 0xc3, 0xab, 0x8c, 0xc2, 0xab, 0x8b, 0xc2, 0xaa, 0x8b, 0xc3, 0xaa, 0x8b, 0xc3, 0xab, 0x8c, 0xc2, 0xaa, 0x8b, 0xc2, 0xab, 0x8b, 0xc1, 0xaa, 0x8b, 0xc1, 0xab, 0x8a, 0xc2, 0xaa, 0x8a, 0xc1, 0xaa, 0x8a, 0xc0, 0xaa, 0x8b, 0xc0, 0xaa, 0x8a, 0xc1, 0xa9, 0x8a, 0xc0, 0xa9, 0x89, 0xc0, 0xaa, 0x8a, 0xbf, 0xaa, 0x89, 0xbf, 0xaa, 0x89, 0xbf, 0xa9, 0x8a, 0xbf, 0xa9, 0x88, 0xbf, 0xaa, 0x89, 0xbe, 0xaa, 0x89, 0xbe, 0xa9, 0x88, 0xbf, 0xa9, 0x88, 0xbe, 0xa9, 0x88, 0xbe, 0xaa, 0x88, 0xbd, 0xaa, 0x88, 0xbd, 0xa9, 0x89, 0xbd, 0xaa, 0x89, 0xbd, 0xa9, 0x87, 0xbe, 0xa9, 0x87, 0xbd, 0xaa, 0x87, 0xbe, 0xaa, 0x87, 0xbd, 0xa9, 0x87, 0xbc, 0xaa, 0x88, 0xbc, 0xa9, 0x88, 0xbc, 0xaa, 0x87, 0xbc, 0xa9, 0x86, 0xbc, 0xa9, 0x87, 0xbb, 0xaa, 0x87, 0xbb, 0xa9, 0x86, 0xbb, 0xa9, 0x86, 0xbc, 0xaa, 0x86, 0xbb, 0xaa, 0x86, 0xba, 0xaa, 0x86, 0xba, 0xa9, 0x85, 0xba, 0xa9, 0x85, 0xbb, 0xaa, 0x85, 0xbb, 0xa9, 0x85, 0xba, 0xaa, 0x85, 0xb9, 0xa9, 0x86, 0xb9, 0xa9, 0x86, 0xb9, 0xaa, 0x85, 0xb9, 0xaa, 0x3e, 0xa0, 0x4f, 0x4f, 0x0, 0x0, 0x2, 0x3, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x2d, 0x4a, 0x7, 0x82, 0x4, 0x37, 0x12, 0x2, 0xa, 0x4a, 0xea, 0x9e, 0xbd, 0xff, 0x3f, 0xf5, 0x6c, 0x4f, 0x4b, 0xda, 0x58, 0x91, 0x24, 0x10, 0x20, 0xf8, 0x5d, 0x20, 0x81, 0x1f, 0xa8, 0x1f, 0xf6, 0x7, 0xf5, 0x7d, 0x0, 0x0, 0x3c, 0x0, 0x8, 0x14, 0x28, 0xb8, 0x41, 0x0, 0x50, 0x7b, 0x70, 0x63, 0xc, 0x9, 0x1c, 0xaa, 0x52, 0xeb, 0x4, 0x5b, 0xfb, 0x1d, 0x89, 0x68, 0xe1, 0x39, 0x9c, 0x7d, 0x68, 0x77, 0x60, 0x8c, 0x7a, 0x80, 0xe5, 0x6e, 0xdc, 0x41, 0x47, 0x51, 0x5f, 0xb8, 0xdd, 0xed, 0xa0, 0x9f, 0xc6, 0xad, 0xba, 0xee, 0xfb, 0xee, 0xde, 0x97, 0x74, 0x6f, 0x98, 0x82, 0x26, 0x51, 0x30, 0xa6, 0x3f, 0x10, 0xc8, 0xad, 0x13, 0xe4, 0x83, 0x0, 0x7a, 0x4, 0x4a, 0xd9, 0x5c, 0xde, 0xd2, 0x16, 0x15, 0xf2, 0xac, 0xac, 0x3e, 0x8f, 0x5a, 0x15, 0x3a, 0x5a, 0xe0, 0x6a, 0x1, 0xdc, 0xbd, 0x9b, 0x47, 0x44, 0xb6, 0x1e, 0x44, 0x5b, 0xe7, 0x84, 0x4b, 0xc3, 0xc, 0x1b, 0x51, 0xeb, 0xaa, 0x54, 0xc7, 0xb3, 0xeb, 0xca, 0x1a, 0x36, 0xbc, 0x76, 0x64, 0x4a, 0x62, 0x54, 0x3c, 0xe7, 0xf4, 0xc0, 0xd4, 0x1b, 0xda, 0x48, 0xa4, 0xc1, 0xd7, 0x98, 0xc2, 0xac, 0x19, 0x76, 0xd7, 0x44, 0x80, 0x33, 0xfe, 0xcb, 0x2b, 0x97, 0x6d, 0x8e, 0x2, 0x36, 0x4a, 0xfd, 0xc, 0xef, 0xb1, 0x35, 0x76, 0x63, 0x62, 0xc6, 0x5b, 0x38, 0xd3, 0x7e, 0x0, 0x7b, 0xfe, 0xef, 0x48, 0x93, 0xff, 0xdc, 0x3d, 0xed, 0xf4, 0xc4, 0xc4, 0x99, 0x93, 0xd3, 0x68, 0x5c, 0x9e, 0xee, 0x87, 0x16, 0xca, 0x1f, 0xbb, 0x80, 0x9e, 0xa0, 0x5, 0x47, 0x0, 0xbc, 0x5f, 0x7, 0x79, 0xa9, 0x3, 0x99, 0x80, 0x8f, 0xa7, 0x16, 0x68, 0xcd, 0x3a, 0x3d, 0x32, 0x60, 0xc0, 0x6f, 0xd8, 0x2b, 0x8a, 0xe1, 0x20, 0xf, 0xe3, 0x4, 0xcf, 0xfa, 0x1a, 0xb, 0x90, 0xfb, 0x2a, 0x57, 0x4a, 0xa8, 0xc9, 0xb7, 0x91, 0x37, 0x82, 0xf7, 0x4c, 0xd2, 0xa9, 0x9a, 0x78, 0x8f, 0x53, 0x22, 0x40, 0xfd, 0x44, 0x5c, 0xdf, 0xeb, 0x89, 0x4a, 0xc9, 0x0, 0xe7, 0x74, 0x1, 0x28, 0xff, 0xa6, 0x7e, 0xa, 0x4, 0xe9, 0x43, 0xe2, 0x7, 0x7d, 0xaf, 0x9, 0xca, 0x61, 0x3, 0x88, 0x13, 0x20, 0xab, 0x50, 0x1e, 0x41, 0xbc, 0x68, 0x3, 0xd5, 0xc2, 0x69, 0xa4, 0x5b, 0x22, 0xbb, 0x35, 0xdc, 0x45, 0x72, 0x94, 0xba, 0x85, 0xee, 0x82, 0x54, 0x0, 0xcb, 0x45, 0xa4, 0x78, 0xa, 0xc0, 0x28, 0x1c, 0x91, 0x46, 0x50, 0xa3, 0x34, 0xcb, 0x63, 0xfa, 0xeb, 0xb8, 0xd8, 0x5e, 0x9e, 0xde, 0x2b, 0xa3, 0xda, 0x35, 0xd3, 0x62, 0xc4, 0x8e, 0xca, 0x39, 0xf0, 0xb1, 0x7a, 0xd6, 0x69, 0x5f, 0x5, 0xa1, 0xa4, 0xa3, 0x3a, 0xdf, 0x8, 0xd8, 0xcf, 0x62, 0xf7, 0x14, 0x4f, 0x5a, 0x87, 0xa5, 0xc1, 0x22, 0x51, 0xe2, 0xd5, 0x9a, 0xc1, 0x1c, 0x37, 0x5e, 0xd6, 0x7f, 0xed, 0xfb, 0x41, 0x5e, 0xb7, 0xf, 0x7c, 0xe3, 0xba, 0x7b, 0xd0, 0xa5, 0x3a, 0xb3, 0x8c, 0xd7, 0x2e, 0x4e, 0xd7, 0xba, 0xbb, 0xd7, 0xc6, 0xb, 0x8d, 0x17, 0x1f, 0xe3, 0x46, 0x9, 0x49, 0xa1, 0x8c, 0x13, 0x63, 0x4c, 0xa6, 0xfa, 0x2a, 0x8c, 0x38, 0x88, 0x6a, 0xc9, 0x32, 0x4c, 0x1b, 0xa3, 0x44, 0x43, 0xd9, 0x55, 0xdb, 0xce, 0xc1, 0xe9, 0x92, 0x2f, 0x4a, 0x25, 0x59, 0x36, 0x52, 0x52, 0x41, 0xc4, 0x16, 0x2, 0x41, 0x32, 0x7a, 0x73, 0x4b, 0x21, 0xb, 0x8, 0x57, 0x89, 0xc2, 0x90, 0x65, 0xa8, 0xdc, 0x46, 0x56, 0x14, 0x15, 0x8e, 0xc1, 0x20, 0xd7, 0xcc, 0x40, 0x76, 0x42, 0x3a, 0x83, 0xf, 0x83, 0x46, 0xf5, 0x27, 0xa7, 0x80, 0x7e, 0xcf, 0xd2, 0x74, 0xd0, 0x78, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char base_green_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x20, 0x1, 0x3, 0x0, 0x0, 0x0, 0x49, 0xb4, 0xe8, 0xb7, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x6, 0x50, 0x4c, 0x54, 0x45, 0x90, 0xc9, 0xab, 0xff, 0xff, 0xff, 0xc6, 0xd0, 0x9d, 0x30, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x1, 0xff, 0x2, 0x2d, 0xde, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0xc, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0x18, 0xdc, 0x0, 0x0, 0x0, 0xa0, 0x0, 0x1, 0x61, 0x25, 0x7d, 0x47, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x20, 0x1, 0x3, 0x0, 0x0, 0x0, 0x49, 0xb4, 0xe8, 0xb7, 0x0, 0x0, 0x0, 0x6, 0x50, 0x4c, 0x54, 0x45, 0x90, 0xc9, 0xab, 0xff, 0xff, 0xff, 0xc6, 0xd0, 0x9d, 0x30, 0x0, 0x0, 0x0, 0xb, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x18, 0xe4, 0x0, 0x0, 0x0, 0xa0, 0x0, 0x1, 0xf3, 0xdb, 0xea, 0x79, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char button_disabled_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x2, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x87, 0x8f, 0xcc, 0xbf, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0xd9, 0x49, 0x44, 0x41, 0x54, 0x28, 0xcf, 0x7d, 0x91, 0x41, 0x4e, 0xc3, 0x30, 0x14, 0x44, 0x9f, 0xed, 0x8f, 0x6d, 0x35, 0x8b, 0x9a, 0x6d, 0xb9, 0x6, 0xfb, 0xde, 0x81, 0xd3, 0xe4, 0x8, 0xf4, 0x32, 0xbd, 0x1, 0xb, 0x6e, 0xc0, 0x25, 0x60, 0x83, 0xa8, 0x2, 0x6a, 0xa4, 0xc6, 0x49, 0xfc, 0xbb, 0x88, 0x54, 0x11, 0x94, 0x30, 0xb3, 0xf9, 0xd2, 0x9f, 0x19, 0x8d, 0x34, 0x6, 0xc1, 0x13, 0x88, 0x78, 0x1c, 0x96, 0x9, 0x85, 0x91, 0xcc, 0x85, 0x8e, 0x2c, 0x78, 0x2a, 0x12, 0x5b, 0x2a, 0x2, 0x6, 0x3, 0x28, 0x4a, 0x47, 0xcb, 0x37, 0xd, 0x8, 0x81, 0xb4, 0x7f, 0x7a, 0xa8, 0x87, 0xc4, 0xc, 0xd2, 0xbc, 0x3f, 0xbf, 0x1e, 0x19, 0x84, 0xc8, 0x76, 0x57, 0x9f, 0xd2, 0x80, 0xfe, 0x7a, 0x1b, 0x24, 0xed, 0x6a, 0x5e, 0x38, 0xb, 0x9e, 0xaa, 0x4f, 0xfd, 0xdc, 0x8e, 0xd2, 0xd3, 0x27, 0x2a, 0xbc, 0xe0, 0x8, 0x65, 0xe6, 0xe6, 0xd6, 0x94, 0x80, 0x13, 0x2c, 0x46, 0x29, 0xb, 0x2, 0x5, 0x83, 0x15, 0xc0, 0xac, 0x26, 0x18, 0x90, 0xe9, 0x5c, 0x11, 0x30, 0x9, 0x54, 0x17, 0x5, 0xa, 0xa, 0x42, 0x41, 0xcb, 0x62, 0x87, 0x2, 0x4a, 0x11, 0x46, 0xba, 0xd5, 0x84, 0x8e, 0xd1, 0x92, 0x69, 0x6d, 0xe3, 0xd0, 0x3f, 0x74, 0xd8, 0x86, 0x96, 0xec, 0xb8, 0xc3, 0xa5, 0xaf, 0xfb, 0x47, 0x1f, 0x3d, 0xe1, 0xc6, 0x48, 0x3c, 0x7d, 0x1e, 0x3e, 0xde, 0xf8, 0x31, 0x6c, 0xfe, 0x1d, 0xab, 0x15, 0x32, 0x30, 0x70, 0x5e, 0x9b, 0xfb, 0xa, 0xbb, 0x7c, 0x61, 0xa2, 0x50, 0x44, 0x45, 0xca, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0xc7, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x6c, 0xd0, 0x81, 0x66, 0x43, 0x31, 0x14, 0x87, 0xf1, 0xf, 0x5, 0x17, 0xb8, 0x28, 0x2e, 0x8, 0x71, 0xf3, 0x6, 0x19, 0xb6, 0xb9, 0xcb, 0xac, 0x95, 0xa4, 0xb7, 0xad, 0x6a, 0xd5, 0x68, 0x5f, 0xe4, 0x3e, 0x76, 0x1e, 0xe1, 0xbf, 0x21, 0xa6, 0xab, 0xf8, 0x1, 0x7c, 0x9c, 0x73, 0xe, 0xac, 0xe8, 0xe8, 0x19, 0x30, 0x58, 0xc6, 0xca, 0x62, 0x18, 0xe8, 0xe9, 0x58, 0x41, 0xc7, 0x1a, 0x87, 0x27, 0x10, 0x49, 0xe4, 0x5f, 0x89, 0x48, 0xc0, 0xe3, 0x58, 0xd3, 0x41, 0x8f, 0xb, 0xcb, 0xbd, 0x7c, 0xeb, 0xbf, 0x7b, 0x9, 0xb, 0x8e, 0x1e, 0x6, 0xfc, 0xad, 0x64, 0x6d, 0xb5, 0x79, 0xb0, 0x55, 0xd6, 0xad, 0xe0, 0x19, 0xc0, 0x10, 0xae, 0xda, 0x34, 0x5c, 0x45, 0xc0, 0x80, 0x25, 0x5e, 0xf4, 0xd5, 0x70, 0x11, 0x11, 0xb, 0x23, 0xe9, 0xac, 0xcf, 0x86, 0xb3, 0x48, 0x8c, 0x30, 0x92, 0x4f, 0xa, 0xd, 0x27, 0x91, 0x6b, 0x70, 0xd4, 0x47, 0xc3, 0xf1, 0x2f, 0x48, 0x7, 0x4d, 0xd, 0x87, 0x3a, 0xc2, 0x12, 0x67, 0xbd, 0x37, 0xcc, 0x75, 0x49, 0x43, 0xd8, 0xe9, 0xad, 0x61, 0x57, 0xcf, 0x1c, 0xf0, 0xfb, 0x32, 0xe9, 0xf5, 0xc9, 0xa4, 0x7d, 0x7d, 0x54, 0x8f, 0x7b, 0x59, 0xe6, 0x92, 0x14, 0x1f, 0x24, 0xcd, 0x3f, 0x7b, 0x6b, 0xa, 0xe, 0x6a, 0x82, 0x91, 0x45, 0x30, 0xba, 0x1, 0x4a, 0x51, 0xc4, 0x35, 0x1f, 0xe5, 0xa1, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char button_focus_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x30, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0xff, 0xff, 0xff, 0xb9, 0xa2, 0x9b, 0xc9, 0x0, 0x0, 0x0, 0xf, 0x74, 0x52, 0x4e, 0x53, 0x0, 0xe, 0x39, 0x68, 0x7a, 0x7b, 0x3a, 0x74, 0x10, 0x8, 0x69, 0xf, 0x6, 0x75, 0x11, 0xb8, 0x16, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0xf, 0x18, 0xba, 0x0, 0xd9, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x3f, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0xc0, 0x4, 0x42, 0x26, 0xa1, 0xa1, 0xce, 0x8a, 0x40, 0x46, 0x7a, 0xe7, 0xcc, 0x99, 0x33, 0xca, 0x80, 0x8c, 0xd5, 0x20, 0xe1, 0x5d, 0x40, 0x1c, 0x3, 0x62, 0x1c, 0x5, 0xe2, 0x48, 0x10, 0x63, 0x2a, 0x7e, 0x6, 0x5c, 0x31, 0x58, 0xbb, 0x14, 0x10, 0xe7, 0xee, 0x9c, 0x39, 0x73, 0x1e, 0xc8, 0x40, 0x31, 0x98, 0x15, 0xe8, 0x0, 0x0, 0xec, 0xe0, 0x11, 0x6d, 0x2c, 0x6f, 0x45, 0x2b, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x2d, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x62, 0xed, 0x5e, 0xfc, 0x0, 0x0, 0x0, 0xf, 0x74, 0x52, 0x4e, 0x53, 0x0, 0xe, 0x39, 0x68, 0x7a, 0x7b, 0x3a, 0x74, 0x10, 0x8, 0x69, 0xf, 0x6, 0x75, 0x11, 0xb8, 0x16, 0x0, 0x1, 0x0, 0x0, 0x0, 0x3e, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0xc0, 0x2, 0x84, 0x4c, 0x42, 0x43, 0x9d, 0x15, 0x81, 0x8c, 0xf4, 0xce, 0x99, 0x33, 0x67, 0x94, 0x1, 0x19, 0xab, 0x41, 0xc2, 0xbb, 0x80, 0x38, 0x6, 0xc4, 0x38, 0xa, 0xc4, 0x91, 0x20, 0xc6, 0x54, 0x3c, 0xc, 0xb8, 0x62, 0x98, 0x76, 0x29, 0x20, 0xce, 0xdd, 0x39, 0x73, 0xe6, 0x3c, 0x90, 0x81, 0x62, 0x10, 0x2b, 0x30, 0x1, 0x0, 0xec, 0xe0, 0x11, 0x6d, 0xb5, 0xe0, 0x8c, 0x99, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char button_hover_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x8d, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x42, 0x40, 0x4b, 0x5f, 0x5a, 0x6c, 0x5f, 0x5a, 0x6b, 0x56, 0x53, 0x64, 0x57, 0x53, 0x64, 0x3e, 0x3b, 0x46, 0x57, 0x53, 0x63, 0x57, 0x53, 0x63, 0x5b, 0x57, 0x68, 0x5a, 0x56, 0x67, 0x4d, 0x4a, 0x57, 0x49, 0x46, 0x52, 0x48, 0x45, 0x51, 0x5b, 0x57, 0x66, 0x59, 0x55, 0x64, 0x47, 0x44, 0x50, 0x58, 0x54, 0x64, 0x46, 0x43, 0x50, 0x56, 0x53, 0x63, 0x45, 0x42, 0x4f, 0x56, 0x53, 0x62, 0x45, 0x42, 0x4e, 0x55, 0x51, 0x62, 0x44, 0x41, 0x4e, 0x55, 0x51, 0x60, 0x44, 0x41, 0x4d, 0x43, 0x40, 0x4c, 0x47, 0x43, 0x51, 0x43, 0x3f, 0x4d, 0x42, 0x3f, 0x4c, 0x53, 0x50, 0x5f, 0x53, 0x4f, 0x5e, 0xff, 0xff, 0xff, 0x99, 0x8b, 0x2e, 0x55, 0x0, 0x0, 0x0, 0x16, 0x74, 0x52, 0x4e, 0x53, 0x4, 0xa, 0x11, 0x19, 0x1f, 0x22, 0x24, 0x15, 0x25, 0x34, 0x3f, 0x46, 0x47, 0x48, 0x77, 0xef, 0xef, 0xef, 0xef, 0x77, 0xef, 0xed, 0x6b, 0x28, 0x52, 0x7a, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x2e, 0x54, 0xd3, 0x10, 0x87, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x97, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x65, 0xcf, 0x49, 0x12, 0x82, 0x30, 0x10, 0x5, 0xd0, 0xce, 0x48, 0x46, 0x40, 0x51, 0x4, 0x41, 0x45, 0xc4, 0x20, 0x88, 0xf7, 0xbf, 0x9e, 0x21, 0x45, 0x65, 0xa1, 0x6f, 0xd7, 0xbf, 0xaa, 0x27, 0x0, 0x84, 0x9, 0x65, 0xdc, 0x63, 0x94, 0x60, 0x4, 0x80, 0x12, 0x21, 0x95, 0x36, 0xd6, 0x1a, 0xad, 0xa4, 0x48, 0x10, 0x60, 0x91, 0x66, 0xe5, 0x29, 0x28, 0xb3, 0x54, 0x60, 0x20, 0x32, 0xaf, 0xea, 0x73, 0x50, 0x57, 0xb9, 0x24, 0x40, 0x55, 0xb3, 0xd5, 0x3e, 0x69, 0x14, 0x5, 0xa6, 0xdb, 0x4b, 0xd4, 0x6a, 0x6, 0xdc, 0x5c, 0x6f, 0xd1, 0xd5, 0x70, 0xe0, 0xb6, 0xbb, 0x47, 0x9d, 0x5d, 0x83, 0xfe, 0x11, 0xf5, 0x6b, 0x60, 0x86, 0x67, 0x34, 0xf8, 0x16, 0xa6, 0xdd, 0x18, 0x39, 0x3f, 0x94, 0x2a, 0x37, 0xbe, 0x36, 0xa3, 0xf3, 0x6b, 0x89, 0xdc, 0x4d, 0xf3, 0x3b, 0x98, 0xa7, 0xbd, 0x3f, 0xc, 0x8b, 0xe2, 0xb0, 0x7c, 0x82, 0xe5, 0x58, 0xf8, 0xd3, 0xff, 0x9e, 0xfb, 0x7d, 0xff, 0xb, 0x74, 0xeb, 0x15, 0x11, 0xe1, 0xa7, 0x60, 0xfc, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x8a, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x42, 0x40, 0x4b, 0x5f, 0x5a, 0x6c, 0x5f, 0x5a, 0x6b, 0x56, 0x53, 0x64, 0x57, 0x53, 0x64, 0x3e, 0x3b, 0x46, 0x57, 0x53, 0x63, 0x57, 0x53, 0x63, 0x5b, 0x57, 0x68, 0x5a, 0x56, 0x67, 0x4d, 0x4a, 0x57, 0x49, 0x46, 0x52, 0x48, 0x45, 0x51, 0x5b, 0x57, 0x66, 0x59, 0x55, 0x64, 0x47, 0x44, 0x50, 0x58, 0x54, 0x64, 0x46, 0x43, 0x50, 0x56, 0x53, 0x63, 0x45, 0x42, 0x4f, 0x56, 0x53, 0x62, 0x45, 0x42, 0x4e, 0x55, 0x51, 0x62, 0x44, 0x41, 0x4e, 0x55, 0x51, 0x60, 0x44, 0x41, 0x4d, 0x43, 0x40, 0x4c, 0x47, 0x43, 0x51, 0x43, 0x3f, 0x4d, 0x42, 0x3f, 0x4c, 0x53, 0x50, 0x5f, 0x53, 0x4f, 0x5e, 0x40, 0xdc, 0xe6, 0x80, 0x0, 0x0, 0x0, 0x16, 0x74, 0x52, 0x4e, 0x53, 0x4, 0xa, 0x11, 0x19, 0x1f, 0x22, 0x24, 0x15, 0x25, 0x34, 0x3f, 0x46, 0x47, 0x48, 0x77, 0xef, 0xef, 0xef, 0xef, 0x77, 0xef, 0xed, 0x6b, 0x28, 0x52, 0x7a, 0x0, 0x0, 0x0, 0x67, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x5d, 0xcf, 0x47, 0x2, 0x83, 0x30, 0x10, 0x43, 0x51, 0x69, 0x98, 0xf4, 0xe4, 0xfe, 0x87, 0x24, 0xfb, 0xf4, 0x8, 0xd1, 0xb1, 0x3f, 0xb8, 0xbd, 0xdd, 0x24, 0x38, 0x4, 0x40, 0x43, 0xc9, 0xfd, 0x24, 0x1a, 0x7a, 0x27, 0x2d, 0x7, 0xc2, 0x41, 0x2f, 0xbd, 0x69, 0x88, 0x23, 0x27, 0x38, 0x3d, 0xfd, 0x22, 0x2f, 0xd3, 0x1b, 0xc3, 0x35, 0xe9, 0x85, 0x39, 0xd, 0x10, 0x2c, 0x0, 0x25, 0x20, 0x81, 0x2d, 0xc0, 0xa0, 0x2d, 0x8, 0xa9, 0x12, 0x64, 0x0, 0x66, 0x91, 0xa5, 0x61, 0xf3, 0xbe, 0xc5, 0x18, 0xd9, 0x7e, 0x7e, 0x21, 0x45, 0x1b, 0x53, 0x77, 0x4a, 0xac, 0x87, 0x63, 0x3d, 0x7e, 0x7, 0x87, 0x7b, 0x3b, 0x5b, 0x7a, 0xd3, 0xea, 0x4, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char button_normal_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x8a, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3c, 0x3a, 0x44, 0x56, 0x53, 0x61, 0x56, 0x52, 0x60, 0x47, 0x44, 0x52, 0x33, 0x31, 0x39, 0x47, 0x44, 0x50, 0x47, 0x44, 0x51, 0x52, 0x50, 0x5d, 0x51, 0x4f, 0x5d, 0x46, 0x42, 0x4e, 0x42, 0x3e, 0x4a, 0x41, 0x3e, 0x49, 0x51, 0x4e, 0x5b, 0x40, 0x3e, 0x48, 0x4f, 0x4c, 0x59, 0x3f, 0x3d, 0x47, 0x4e, 0x4a, 0x58, 0x3e, 0x3b, 0x46, 0x4b, 0x49, 0x55, 0x3c, 0x3a, 0x44, 0x4a, 0x47, 0x54, 0x3b, 0x39, 0x43, 0x49, 0x46, 0x53, 0x3a, 0x38, 0x42, 0x47, 0x45, 0x50, 0x39, 0x37, 0x40, 0x47, 0x43, 0x50, 0x38, 0x35, 0x3f, 0x36, 0x34, 0x3e, 0x44, 0x42, 0x4d, 0x44, 0x41, 0x4c, 0xff, 0xff, 0xff, 0xe5, 0x37, 0x10, 0x78, 0x0, 0x0, 0x0, 0x15, 0x74, 0x52, 0x4e, 0x53, 0x4, 0xa, 0x11, 0x19, 0x1f, 0x22, 0x24, 0x15, 0x25, 0x34, 0x3f, 0x46, 0x47, 0x48, 0x77, 0xef, 0xef, 0xef, 0x77, 0xef, 0xed, 0xe8, 0xff, 0x76, 0xed, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x2d, 0xcd, 0xda, 0x41, 0x3d, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x93, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x65, 0xcf, 0x47, 0x12, 0x82, 0x40, 0x10, 0x5, 0xd0, 0x9e, 0xc8, 0x44, 0x92, 0x22, 0x41, 0x54, 0x44, 0x40, 0x14, 0xef, 0x7f, 0x3e, 0x7, 0x8a, 0xea, 0x85, 0xbe, 0xe5, 0xaf, 0xea, 0xf0, 0x1, 0x8, 0x65, 0x5c, 0xc8, 0x40, 0x70, 0x46, 0x9, 0x0, 0x89, 0x94, 0x36, 0xd6, 0x79, 0xef, 0xac, 0xd1, 0x2a, 0x22, 0x40, 0x55, 0x9c, 0x14, 0xa7, 0x4d, 0x91, 0xc4, 0x8a, 0x2, 0xd3, 0x69, 0x59, 0xd5, 0x9b, 0xaa, 0x4c, 0x35, 0x3, 0x6e, 0x9a, 0xfa, 0xbc, 0xab, 0x1b, 0xc3, 0x41, 0xd8, 0xf6, 0x82, 0x5a, 0x2b, 0x40, 0xba, 0xeb, 0xd, 0x5d, 0x9d, 0x4, 0xe9, 0xbb, 0x3b, 0xea, 0xfc, 0x1a, 0xf4, 0xf, 0xd4, 0xaf, 0x81, 0x1b, 0x46, 0x34, 0x84, 0x11, 0x61, 0xa7, 0x27, 0x9a, 0xc2, 0x52, 0x6e, 0xe6, 0x17, 0x9a, 0xc3, 0x59, 0xa6, 0xb3, 0xf1, 0xbd, 0x1b, 0xb3, 0xf0, 0x18, 0x55, 0xf9, 0x61, 0xf9, 0x6c, 0x96, 0x63, 0x1e, 0x5e, 0xff, 0x2b, 0xf7, 0x5b, 0xff, 0xb, 0x69, 0x5a, 0x14, 0xfa, 0x84, 0xf6, 0xc2, 0x8, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x87, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3c, 0x3a, 0x44, 0x56, 0x53, 0x61, 0x56, 0x52, 0x60, 0x47, 0x44, 0x52, 0x33, 0x31, 0x39, 0x47, 0x44, 0x50, 0x47, 0x44, 0x51, 0x52, 0x50, 0x5d, 0x51, 0x4f, 0x5d, 0x46, 0x42, 0x4e, 0x42, 0x3e, 0x4a, 0x41, 0x3e, 0x49, 0x51, 0x4e, 0x5b, 0x40, 0x3e, 0x48, 0x4f, 0x4c, 0x59, 0x3f, 0x3d, 0x47, 0x4e, 0x4a, 0x58, 0x3e, 0x3b, 0x46, 0x4b, 0x49, 0x55, 0x3c, 0x3a, 0x44, 0x4a, 0x47, 0x54, 0x3b, 0x39, 0x43, 0x49, 0x46, 0x53, 0x3a, 0x38, 0x42, 0x47, 0x45, 0x50, 0x39, 0x37, 0x40, 0x47, 0x43, 0x50, 0x38, 0x35, 0x3f, 0x36, 0x34, 0x3e, 0x44, 0x42, 0x4d, 0x44, 0x41, 0x4c, 0x3f, 0x38, 0xaa, 0x5e, 0x0, 0x0, 0x0, 0x15, 0x74, 0x52, 0x4e, 0x53, 0x4, 0xa, 0x11, 0x19, 0x1f, 0x22, 0x24, 0x15, 0x25, 0x34, 0x3f, 0x46, 0x47, 0x48, 0x77, 0xef, 0xef, 0xef, 0x77, 0xef, 0xed, 0xe8, 0xff, 0x76, 0xed, 0x0, 0x0, 0x0, 0x65, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x65, 0xcf, 0x45, 0x2, 0x84, 0x30, 0x14, 0x4, 0xd1, 0x2e, 0x1c, 0xee, 0x7f, 0xca, 0xd1, 0xed, 0x28, 0x8d, 0x4b, 0x92, 0x5a, 0xbe, 0xe8, 0x2f, 0xc4, 0x9c, 0x24, 0xcf, 0x15, 0x54, 0xab, 0x78, 0xee, 0x53, 0x30, 0x4a, 0x85, 0xa6, 0xfc, 0xf1, 0x87, 0x11, 0xb2, 0x9a, 0x15, 0x9a, 0x37, 0x13, 0x74, 0xce, 0xb4, 0xd4, 0x77, 0xcb, 0xe, 0xb4, 0x96, 0x99, 0x10, 0x34, 0x81, 0x42, 0x50, 0x21, 0x9d, 0x41, 0x23, 0xf8, 0xc, 0x56, 0xe1, 0x10, 0x9c, 0x40, 0x4e, 0xfe, 0x6e, 0x72, 0x96, 0x7e, 0xd7, 0xdf, 0x3f, 0xb3, 0x79, 0x90, 0xcd, 0xf1, 0xc4, 0x26, 0x1e, 0x8e, 0x78, 0xfc, 0x1, 0xf5, 0x61, 0x3f, 0x44, 0xe8, 0xf1, 0xdd, 0xba, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char button_pressed_png[] = {
@@ -39,19 +39,19 @@ static const unsigned char button_pressed_png[] = {
};
static const unsigned char checked_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x8d, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x58, 0x56, 0x63, 0xb0, 0xaf, 0xb5, 0x38, 0x37, 0x40, 0x20, 0x20, 0x24, 0xb6, 0xb6, 0xb9, 0x57, 0x57, 0x5a, 0x20, 0x20, 0x24, 0x38, 0x36, 0x40, 0x20, 0x20, 0x25, 0x1e, 0x1e, 0x22, 0x1f, 0x1f, 0x23, 0x8b, 0x8b, 0x8d, 0xff, 0xff, 0xff, 0x20, 0x20, 0x24, 0x22, 0x22, 0x27, 0x23, 0x23, 0x28, 0x42, 0x42, 0x47, 0xf8, 0xf8, 0xf8, 0xfe, 0xfe, 0xfe, 0x25, 0x25, 0x2a, 0x4e, 0x4e, 0x52, 0x26, 0x26, 0x2b, 0xc5, 0xc5, 0xc7, 0xaa, 0xaa, 0xab, 0xb8, 0xb8, 0xba, 0x5f, 0x5f, 0x63, 0x74, 0x74, 0x77, 0xed, 0xed, 0xed, 0x33, 0x33, 0x38, 0x8d, 0x8d, 0x8f, 0xb8, 0xb8, 0xb9, 0x35, 0x35, 0x39, 0x3a, 0x3a, 0x3e, 0xfb, 0xfb, 0xfb, 0xfa, 0xfa, 0xfa, 0xb2, 0xb2, 0xb4, 0x45, 0x45, 0x49, 0x61, 0x61, 0x65, 0x8f, 0x8f, 0x92, 0x63, 0x63, 0x66, 0x2a, 0x2a, 0x2f, 0x40, 0x82, 0xb, 0xf6, 0x0, 0x0, 0x0, 0xf, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x7, 0x27, 0x50, 0x66, 0x68, 0x6a, 0x81, 0xb4, 0xfa, 0xdd, 0xfb, 0xfb, 0xb4, 0xfa, 0xb8, 0xf0, 0x7f, 0x59, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x12, 0x7b, 0xbc, 0x6c, 0x0, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x4, 0x4e, 0x1d, 0x2, 0xaf, 0x0, 0x0, 0x0, 0x8e, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x65, 0xcf, 0x5b, 0x12, 0x82, 0x30, 0xc, 0x40, 0x51, 0x48, 0x5b, 0x15, 0x5, 0x5b, 0x42, 0x2b, 0x4, 0x50, 0x40, 0xc5, 0xb7, 0xee, 0x7f, 0x79, 0x96, 0x8a, 0x88, 0x7a, 0x3f, 0xcf, 0x4c, 0x26, 0x89, 0xe7, 0xfd, 0xe5, 0x3, 0xe3, 0xc2, 0x35, 0x99, 0x82, 0x6f, 0x1, 0x66, 0x81, 0x54, 0xae, 0x18, 0xe7, 0x60, 0x81, 0x5, 0x89, 0x36, 0x5d, 0xab, 0x34, 0x5b, 0x30, 0xb, 0x5c, 0x6a, 0xa2, 0xbc, 0x20, 0x2a, 0x71, 0x2d, 0xb9, 0x5, 0xa1, 0xc, 0x6d, 0xb0, 0xa2, 0x1a, 0x9b, 0xad, 0x12, 0x3d, 0xec, 0x70, 0xdf, 0x36, 0x58, 0x9b, 0x1, 0xe, 0xc7, 0xd3, 0x19, 0x4b, 0xfa, 0x80, 0x9d, 0xc9, 0xd2, 0xcb, 0x18, 0xae, 0x88, 0x37, 0x1a, 0x43, 0x91, 0xdf, 0x1f, 0x6f, 0x70, 0x6b, 0x5f, 0x69, 0xb7, 0x76, 0x38, 0xcc, 0xe8, 0x24, 0xec, 0xe, 0x83, 0x28, 0xec, 0x4f, 0x97, 0xcb, 0x8, 0xbe, 0x9e, 0xe3, 0xcc, 0x3d, 0xf7, 0xd3, 0x13, 0x10, 0x58, 0xd, 0x44, 0xd4, 0xa5, 0x38, 0x3e, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x8d, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x58, 0x56, 0x63, 0xb0, 0xaf, 0xb5, 0x38, 0x37, 0x40, 0x20, 0x20, 0x24, 0xb6, 0xb6, 0xb9, 0x57, 0x57, 0x5a, 0x20, 0x20, 0x24, 0x38, 0x36, 0x40, 0x20, 0x20, 0x25, 0x1e, 0x1e, 0x22, 0x1f, 0x1f, 0x23, 0x8b, 0x8b, 0x8d, 0xff, 0xff, 0xff, 0x20, 0x20, 0x24, 0x22, 0x22, 0x27, 0x23, 0x23, 0x28, 0x42, 0x42, 0x47, 0xf8, 0xf8, 0xf8, 0xfe, 0xfe, 0xfe, 0x25, 0x25, 0x2a, 0x4e, 0x4e, 0x52, 0x26, 0x26, 0x2b, 0xc5, 0xc5, 0xc7, 0xaa, 0xaa, 0xab, 0xb8, 0xb8, 0xba, 0x5f, 0x5f, 0x63, 0x74, 0x74, 0x77, 0xed, 0xed, 0xed, 0x33, 0x33, 0x38, 0x8d, 0x8d, 0x8f, 0xb8, 0xb8, 0xb9, 0x35, 0x35, 0x39, 0x3a, 0x3a, 0x3e, 0xfb, 0xfb, 0xfb, 0xfa, 0xfa, 0xfa, 0xb2, 0xb2, 0xb4, 0x45, 0x45, 0x49, 0x61, 0x61, 0x65, 0x8f, 0x8f, 0x92, 0x63, 0x63, 0x66, 0x2a, 0x2a, 0x2f, 0x40, 0x82, 0xb, 0xf6, 0x0, 0x0, 0x0, 0xf, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x7, 0x27, 0x50, 0x66, 0x68, 0x6a, 0x81, 0xb4, 0xfa, 0xdd, 0xfb, 0xfb, 0xb4, 0xfa, 0xb8, 0xf0, 0x7f, 0x59, 0x0, 0x0, 0x0, 0x7e, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x5d, 0xca, 0x5, 0xb2, 0x2, 0x30, 0x18, 0x3, 0xe1, 0x4d, 0xed, 0xb9, 0x60, 0xf7, 0x3f, 0x20, 0xee, 0x4e, 0x99, 0xe0, 0xb0, 0x63, 0xfd, 0xbf, 0x86, 0xd7, 0x12, 0x72, 0x38, 0x69, 0x5b, 0x6b, 0x42, 0x45, 0xe5, 0xa, 0xab, 0x95, 0x41, 0x9f, 0x32, 0x20, 0x69, 0x2d, 0xbc, 0x50, 0x46, 0x3a, 0x10, 0x17, 0x5f, 0x49, 0x4, 0x7f, 0x90, 0x57, 0x89, 0xb7, 0xc5, 0x5f, 0x96, 0x17, 0x2e, 0x93, 0xcb, 0x8e, 0x3a, 0x83, 0xb, 0xc4, 0x8e, 0xd4, 0xff, 0x5c, 0x73, 0x83, 0x69, 0x9e, 0x95, 0xfc, 0x3b, 0xf4, 0x33, 0xe0, 0xf8, 0x61, 0xd3, 0xf1, 0x7d, 0x5d, 0x30, 0x7a, 0x6f, 0x89, 0xb, 0xd4, 0x5a, 0xe1, 0x40, 0xf, 0xfc, 0x34, 0x6c, 0xd2, 0x56, 0x80, 0xef, 0xfd, 0x9, 0xd2, 0x3a, 0x5e, 0x41, 0x15, 0x21, 0x77, 0x6, 0xc7, 0x6b, 0x47, 0x4e, 0x3a, 0x2f, 0x53, 0xb4, 0x10, 0xc7, 0x8c, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char checker_bg_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x8, 0x0, 0x0, 0x0, 0x0, 0xe1, 0x64, 0xe1, 0x57, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x2, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x87, 0x8f, 0xcc, 0xbf, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xe, 0xc4, 0x0, 0x0, 0xe, 0xc4, 0x1, 0x95, 0x2b, 0xe, 0x1b, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x1a, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0xfc, 0xcf, 0xc0, 0xc0, 0xd0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc4, 0x0, 0x5, 0x98, 0xc, 0xc6, 0x7a, 0xc2, 0x6a, 0x0, 0x8b, 0x7a, 0x2, 0x8d, 0x68, 0x67, 0xe3, 0xa, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x8, 0x0, 0x0, 0x0, 0x0, 0xe1, 0x64, 0xe1, 0x57, 0x0, 0x0, 0x0, 0x14, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0xfc, 0xcf, 0xc0, 0xc0, 0xd0, 0x0, 0xc4, 0xf8, 0x18, 0xf5, 0x84, 0x19, 0x0, 0x9f, 0x5f, 0xa, 0x1, 0xf8, 0xef, 0x65, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char close_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x9b, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xcd, 0x92, 0x31, 0xe, 0xc2, 0x30, 0x10, 0x4, 0x17, 0xaa, 0x3d, 0x67, 0xdb, 0x58, 0xd0, 0xd3, 0xf0, 0xa3, 0x7c, 0x36, 0x3c, 0x82, 0x48, 0x44, 0x22, 0x6f, 0xb1, 0x4d, 0x85, 0x14, 0x81, 0xf, 0x2c, 0x28, 0xe0, 0xda, 0xd5, 0x8c, 0x4e, 0x77, 0xb, 0xfc, 0xd5, 0x98, 0xd9, 0x20, 0x29, 0x7a, 0xb9, 0xa4, 0x68, 0x66, 0x83, 0xb, 0x93, 0xcc, 0x24, 0xa7, 0x9a, 0x44, 0x52, 0x24, 0x39, 0x91, 0xcc, 0x55, 0x89, 0xa4, 0xde, 0xcc, 0xce, 0x24, 0xb, 0xc9, 0x39, 0x84, 0xb0, 0xf7, 0xb2, 0xae, 0xeb, 0x76, 0xde, 0x8a, 0x4f, 0x92, 0x66, 0xd8, 0x91, 0x5c, 0x49, 0x5e, 0x9a, 0xe1, 0xb5, 0x64, 0x5, 0x16, 0x92, 0x8b, 0x7, 0x6f, 0x9b, 0x8c, 0x0, 0x4a, 0x29, 0x9b, 0x26, 0x81, 0xa4, 0x3e, 0xa5, 0x34, 0x2, 0x38, 0x2, 0x58, 0x0, 0xcc, 0x0, 0xe, 0x39, 0xe7, 0xd3, 0xfa, 0xb0, 0xee, 0xea, 0x8f, 0x7, 0x7b, 0xf5, 0x9d, 0xb7, 0xb0, 0x97, 0x55, 0x25, 0x5f, 0x17, 0xe9, 0x2e, 0xf9, 0xb8, 0xca, 0x3f, 0x9b, 0x1b, 0x1a, 0xe3, 0x40, 0x47, 0xa0, 0xda, 0xda, 0x61, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x62, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0xa0, 0x16, 0xe0, 0x8c, 0xe0, 0x11, 0x43, 0xe6, 0xf3, 0x88, 0x71, 0x46, 0xa0, 0x48, 0x73, 0xfc, 0xe3, 0xb8, 0xcc, 0x23, 0x86, 0x90, 0xe6, 0xb8, 0xcc, 0xf1, 0xf, 0x49, 0x9, 0x8f, 0x28, 0xe7, 0x25, 0x8e, 0xff, 0x1c, 0xd7, 0xb9, 0x24, 0x91, 0x79, 0xdc, 0x12, 0x40, 0xe, 0xa6, 0x12, 0x54, 0x69, 0x4c, 0x25, 0xb7, 0x38, 0xae, 0x21, 0xa4, 0x31, 0x94, 0x80, 0x24, 0x81, 0xf0, 0x36, 0x48, 0x1a, 0xaf, 0x2, 0x88, 0x5b, 0xf0, 0x5a, 0x81, 0xa1, 0x4, 0xe1, 0x34, 0x84, 0x73, 0xb1, 0x4a, 0xa3, 0x7b, 0x9a, 0x70, 0x40, 0x11, 0xe, 0x6a, 0xca, 0x1, 0x0, 0x2a, 0x28, 0x37, 0x83, 0x3e, 0x27, 0xb0, 0x34, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char close_hl_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x9b, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xcd, 0x92, 0x31, 0xe, 0xc2, 0x30, 0x10, 0x4, 0x17, 0xaa, 0x3d, 0x67, 0xdb, 0x58, 0xd0, 0xd3, 0xf0, 0xa3, 0x7c, 0x36, 0x3c, 0x82, 0x48, 0x44, 0x22, 0x6f, 0xb1, 0x4d, 0x85, 0x14, 0x81, 0xf, 0x2c, 0x28, 0xe0, 0xda, 0xd5, 0x8c, 0x4e, 0x77, 0xb, 0xfc, 0xd5, 0x98, 0xd9, 0x20, 0x29, 0x7a, 0xb9, 0xa4, 0x68, 0x66, 0x83, 0xb, 0x93, 0xcc, 0x24, 0xa7, 0x9a, 0x44, 0x52, 0x24, 0x39, 0x91, 0xcc, 0x55, 0x89, 0xa4, 0xde, 0xcc, 0xce, 0x24, 0xb, 0xc9, 0x39, 0x84, 0xb0, 0xf7, 0xb2, 0xae, 0xeb, 0x76, 0xde, 0x8a, 0x4f, 0x92, 0x66, 0xd8, 0x91, 0x5c, 0x49, 0x5e, 0x9a, 0xe1, 0xb5, 0x64, 0x5, 0x16, 0x92, 0x8b, 0x7, 0x6f, 0x9b, 0x8c, 0x0, 0x4a, 0x29, 0x9b, 0x26, 0x81, 0xa4, 0x3e, 0xa5, 0x34, 0x2, 0x38, 0x2, 0x58, 0x0, 0xcc, 0x0, 0xe, 0x39, 0xe7, 0xd3, 0xfa, 0xb0, 0xee, 0xea, 0x8f, 0x7, 0x7b, 0xf5, 0x9d, 0xb7, 0xb0, 0x97, 0x55, 0x25, 0x5f, 0x17, 0xe9, 0x2e, 0xf9, 0xb8, 0xca, 0x3f, 0x9b, 0x1b, 0x1a, 0xe3, 0x40, 0x47, 0xa0, 0xda, 0xda, 0x61, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x62, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0xa0, 0x16, 0xe0, 0x8c, 0xe0, 0x11, 0x43, 0xe6, 0xf3, 0x88, 0x71, 0x46, 0xa0, 0x48, 0x73, 0xfc, 0xe3, 0xb8, 0xcc, 0x23, 0x86, 0x90, 0xe6, 0xb8, 0xcc, 0xf1, 0xf, 0x49, 0x9, 0x8f, 0x28, 0xe7, 0x25, 0x8e, 0xff, 0x1c, 0xd7, 0xb9, 0x24, 0x91, 0x79, 0xdc, 0x12, 0x40, 0xe, 0xa6, 0x12, 0x54, 0x69, 0x4c, 0x25, 0xb7, 0x38, 0xae, 0x21, 0xa4, 0x31, 0x94, 0x80, 0x24, 0x81, 0xf0, 0x36, 0x48, 0x1a, 0xaf, 0x2, 0x88, 0x5b, 0xf0, 0x5a, 0x81, 0xa1, 0x4, 0xe1, 0x34, 0x84, 0x73, 0xb1, 0x4a, 0xa3, 0x7b, 0x9a, 0x70, 0x40, 0x11, 0xe, 0x6a, 0xca, 0x1, 0x0, 0x2a, 0x28, 0x37, 0x83, 0x3e, 0x27, 0xb0, 0x34, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char color_picker_hue_png[] = {
@@ -59,31 +59,31 @@ static const unsigned char color_picker_hue_png[] = {
};
static const unsigned char color_picker_sample_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x14, 0x8, 0x2, 0x0, 0x0, 0x0, 0xed, 0x20, 0x74, 0x8, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x9, 0x18, 0xc, 0x27, 0x37, 0x29, 0x4f, 0x42, 0x2d, 0x0, 0x0, 0x0, 0x61, 0x49, 0x44, 0x41, 0x54, 0x68, 0xde, 0xed, 0xd9, 0xb1, 0xd, 0x0, 0x21, 0xc, 0x3, 0x40, 0x40, 0xbf, 0x5f, 0x66, 0xcd, 0x84, 0xf9, 0x96, 0x19, 0xf0, 0x5d, 0x87, 0x5c, 0x5b, 0x9, 0xca, 0x9e, 0x99, 0x75, 0xe9, 0xee, 0xfb, 0x59, 0x55, 0x52, 0xe9, 0xc3, 0xe9, 0x59, 0x10, 0x4c, 0x1, 0x50, 0x0, 0x50, 0x0, 0x8, 0xf4, 0xf9, 0x15, 0x49, 0x93, 0x53, 0x13, 0x0, 0x2b, 0x10, 0x28, 0x0, 0x28, 0x0, 0x64, 0xd9, 0x2e, 0xc1, 0xd2, 0xe4, 0xd4, 0x4, 0xc0, 0xa, 0x4, 0xa, 0x0, 0xa, 0x0, 0x59, 0x5c, 0x82, 0xa5, 0xd1, 0xa9, 0x9, 0x80, 0x15, 0x8, 0x14, 0x0, 0x14, 0x0, 0xb2, 0xfc, 0x5b, 0xb2, 0x3c, 0x5a, 0x4, 0xa1, 0xf3, 0x57, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x14, 0x8, 0x0, 0x0, 0x0, 0x0, 0x47, 0x29, 0xbc, 0x83, 0x0, 0x0, 0x0, 0x3c, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0xed, 0xd5, 0x21, 0x11, 0x0, 0x30, 0xc, 0x4, 0xc1, 0xfa, 0x57, 0x53, 0x87, 0xed, 0x4, 0x45, 0xc4, 0xed, 0xa3, 0xc3, 0x4b, 0xfe, 0xbc, 0xd9, 0x9d, 0x35, 0x2b, 0xe, 0x0, 0x0, 0x0, 0x80, 0xed, 0x66, 0xc5, 0x1, 0x0, 0x0, 0x0, 0xe0, 0x6, 0x1, 0x0, 0x0, 0x90, 0x6, 0x70, 0x83, 0x0, 0x0, 0x0, 0x28, 0x3, 0x7c, 0x54, 0x93, 0xd6, 0xf1, 0xd1, 0x16, 0x8a, 0x17, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char dosfont_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x80, 0x0, 0x0, 0x0, 0x80, 0x1, 0x0, 0x0, 0x0, 0x0, 0xeb, 0x45, 0x5c, 0x66, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x2, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x0, 0x76, 0x93, 0xcd, 0x38, 0x0, 0x0, 0x0, 0x2, 0x62, 0x4b, 0x47, 0x44, 0x0, 0x1, 0xdd, 0x8a, 0x13, 0xa4, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x89, 0x0, 0x0, 0xb, 0x89, 0x1, 0x37, 0xc9, 0xcb, 0xad, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x2, 0x83, 0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0xed, 0xd4, 0xb1, 0x6e, 0xdb, 0x30, 0x10, 0x0, 0x50, 0x22, 0x3, 0x27, 0x22, 0xc8, 0x78, 0x83, 0x91, 0xa9, 0x1f, 0xc0, 0xa9, 0x10, 0xa, 0x7e, 0xc, 0x11, 0x14, 0x87, 0xc, 0x1c, 0x32, 0x9, 0x1a, 0xe, 0x46, 0xa6, 0xfc, 0x43, 0xff, 0x86, 0xb5, 0x80, 0x9b, 0x88, 0x8e, 0x5d, 0x64, 0x18, 0x9e, 0xdc, 0xd5, 0x53, 0x91, 0xc1, 0xa0, 0x7a, 0xa4, 0xe4, 0xd4, 0x31, 0xd2, 0x25, 0x70, 0x97, 0xa2, 0x37, 0x48, 0xe6, 0x33, 0x45, 0xdd, 0x51, 0x24, 0x95, 0x7a, 0x23, 0xe0, 0x75, 0x13, 0xb, 0xd8, 0x93, 0xbf, 0x51, 0x51, 0xa3, 0xac, 0x99, 0xc9, 0x29, 0x87, 0x81, 0x83, 0xb2, 0x0, 0xc7, 0xfe, 0xee, 0x43, 0x58, 0x85, 0x95, 0xb7, 0xa6, 0xb6, 0xaf, 0x7a, 0xe9, 0x93, 0x63, 0xc3, 0xf2, 0xc, 0x96, 0x3e, 0xba, 0x97, 0x11, 0x3, 0xb5, 0x46, 0xc0, 0x15, 0x30, 0x43, 0x1, 0xbd, 0x6, 0x81, 0x71, 0xa9, 0xb2, 0x82, 0x9, 0x92, 0x3d, 0xf6, 0xb0, 0xbd, 0x5c, 0xf2, 0x53, 0xf2, 0x75, 0xc, 0x11, 0x5f, 0xc7, 0xe0, 0xc4, 0xaa, 0xb4, 0x40, 0x41, 0xc4, 0x69, 0xd0, 0x27, 0x55, 0x12, 0x13, 0x78, 0x74, 0xa7, 0xb5, 0xd8, 0x3f, 0x14, 0x77, 0x81, 0x0, 0x22, 0x93, 0x9b, 0x4c, 0x54, 0x5b, 0x72, 0x6d, 0x98, 0x17, 0xd1, 0x33, 0xb3, 0x94, 0xaa, 0x3c, 0x93, 0xea, 0xb4, 0x76, 0x31, 0x6a, 0x66, 0x0, 0xa9, 0x59, 0x1c, 0x8c, 0xe, 0x33, 0xc0, 0x12, 0x4c, 0x29, 0xc2, 0xa5, 0xc3, 0xc1, 0xd0, 0xb2, 0x64, 0x6a, 0x60, 0xa3, 0xc0, 0xea, 0xac, 0x19, 0x58, 0x4b, 0xa9, 0x4a, 0x17, 0xf0, 0xda, 0x68, 0xb6, 0x5, 0xec, 0xb2, 0xf6, 0x88, 0x33, 0xc8, 0x18, 0x52, 0xd5, 0x5a, 0x1, 0xb3, 0x61, 0x1, 0x53, 0xdf, 0x2, 0x51, 0x2d, 0x33, 0xdd, 0x12, 0x59, 0xea, 0x94, 0x95, 0x3c, 0x80, 0x2e, 0x5e, 0xf9, 0xdb, 0x71, 0x73, 0x70, 0xcf, 0x39, 0x3b, 0x76, 0xb7, 0xbb, 0x7d, 0xcf, 0x74, 0x50, 0xd, 0x62, 0x40, 0x44, 0x6, 0x83, 0xfe, 0xc7, 0x8e, 0x51, 0x5, 0x5c, 0xe1, 0xdd, 0xdd, 0xaa, 0xc2, 0xf8, 0x53, 0x80, 0x31, 0xe2, 0xfd, 0x7d, 0x14, 0x8, 0x7e, 0xcc, 0x5, 0x28, 0x62, 0xd7, 0xc5, 0xc, 0xa6, 0xf3, 0xc3, 0x46, 0xa6, 0x30, 0xd7, 0x1e, 0x1b, 0x2e, 0xd0, 0x7f, 0x63, 0x5f, 0x1f, 0xf1, 0x32, 0xc9, 0x90, 0x82, 0xef, 0xb9, 0x82, 0xc, 0x5a, 0x1, 0xef, 0x66, 0x90, 0xd7, 0x7a, 0x2c, 0x80, 0x13, 0x94, 0xc4, 0xf6, 0x9f, 0xd8, 0x75, 0xbb, 0x2c, 0x89, 0xed, 0xff, 0x42, 0xe9, 0xa7, 0xfb, 0xa4, 0x84, 0xec, 0x13, 0x45, 0x7, 0x1a, 0xb9, 0x97, 0x18, 0x65, 0xab, 0x4, 0xf9, 0x54, 0x8c, 0x3c, 0x54, 0xe8, 0xed, 0xa3, 0x7c, 0x7b, 0x55, 0xe0, 0x8b, 0x0, 0xf6, 0x4f, 0x36, 0xd6, 0x3d, 0xc3, 0xe8, 0x41, 0xc0, 0xa1, 0xb1, 0xdb, 0x9, 0xa8, 0x29, 0x0, 0xe, 0xec, 0xc3, 0x4, 0xc1, 0x8, 0xc, 0x0, 0xd6, 0x36, 0xf3, 0x23, 0xba, 0x80, 0x3, 0x6f, 0x17, 0x15, 0xbe, 0x4b, 0xe5, 0x8c, 0x23, 0xc2, 0x57, 0x7b, 0x5d, 0x61, 0x53, 0xc0, 0x61, 0xf, 0xbd, 0xd5, 0x15, 0x68, 0x47, 0x8e, 0x0, 0x7b, 0x37, 0xba, 0xab, 0xba, 0x59, 0xcc, 0x79, 0x3d, 0xd7, 0xaf, 0x5a, 0xe3, 0x85, 0x66, 0x69, 0xab, 0x16, 0x32, 0x31, 0x5b, 0xd0, 0xdb, 0x66, 0x2, 0x2f, 0x6f, 0xe, 0xb2, 0x42, 0xb5, 0x87, 0xdf, 0xf0, 0x59, 0xae, 0x6a, 0x86, 0xae, 0x93, 0x4c, 0x7d, 0x1b, 0x9a, 0x6b, 0x84, 0xdd, 0x9a, 0xd6, 0xca, 0xc8, 0x89, 0xc3, 0xfb, 0xd4, 0x82, 0xe, 0x30, 0xa2, 0x2c, 0x18, 0xc2, 0x98, 0xb2, 0x4f, 0x8, 0xba, 0x83, 0xa1, 0x40, 0x12, 0x88, 0x6f, 0x43, 0x38, 0x82, 0x1c, 0x1f, 0x15, 0x70, 0x82, 0x96, 0xa8, 0xa5, 0x3d, 0xed, 0x9c, 0xde, 0xb9, 0x1, 0xe9, 0xb8, 0x5f, 0x4c, 0x39, 0xd2, 0xa6, 0xac, 0xa6, 0x48, 0xe7, 0xd0, 0x95, 0x53, 0xb0, 0xc4, 0x7b, 0x97, 0xd4, 0xcd, 0x3c, 0xdd, 0xf0, 0xd0, 0x4e, 0xbf, 0xe6, 0x65, 0x24, 0x5b, 0x7b, 0x7d, 0xe, 0xe5, 0xd6, 0xae, 0xe9, 0x90, 0x64, 0xfd, 0x70, 0x9e, 0x21, 0xb5, 0x6c, 0x5, 0xa4, 0xa2, 0x87, 0xe9, 0xa3, 0x25, 0xf4, 0x5, 0x5c, 0x39, 0x61, 0xa6, 0x1e, 0xbe, 0x11, 0x18, 0x80, 0xed, 0xb, 0x18, 0x9b, 0x70, 0x70, 0xec, 0x5f, 0x80, 0x3f, 0x26, 0x27, 0xb3, 0xc9, 0x33, 0xc8, 0x5c, 0x2c, 0x5a, 0x59, 0x1f, 0xcb, 0x2c, 0x89, 0x9d, 0xae, 0xf, 0x7d, 0xcc, 0xdb, 0x9c, 0xdd, 0xd5, 0xed, 0x7c, 0x7f, 0xbe, 0xd0, 0x52, 0xf9, 0x1f, 0xff, 0x76, 0xfc, 0x2, 0x24, 0x3a, 0x65, 0x42, 0xf6, 0x41, 0x91, 0x95, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x80, 0x0, 0x0, 0x0, 0x80, 0x1, 0x0, 0x0, 0x0, 0x0, 0xeb, 0x45, 0x5c, 0x66, 0x0, 0x0, 0x0, 0x2, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x0, 0x76, 0x93, 0xcd, 0x38, 0x0, 0x0, 0x2, 0x64, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0xbc, 0xd4, 0x81, 0x86, 0x2c, 0x47, 0x14, 0xc6, 0xf1, 0xcf, 0x45, 0x81, 0x32, 0x2, 0x38, 0x58, 0x17, 0xe4, 0x1, 0xa, 0x44, 0x8b, 0x7a, 0x98, 0xb2, 0xe2, 0xb8, 0x28, 0x2c, 0x68, 0x8d, 0x63, 0x5c, 0xb0, 0xef, 0x90, 0xb7, 0xe9, 0x6c, 0x71, 0x40, 0x9, 0x20, 0xd0, 0x63, 0x2d, 0x98, 0x0, 0xc, 0x88, 0x60, 0x54, 0xa7, 0xaa, 0xba, 0xef, 0x66, 0x67, 0x5d, 0x10, 0x37, 0xf7, 0xf, 0xc3, 0x4f, 0x39, 0x53, 0x87, 0xd2, 0xf8, 0x5a, 0x84, 0x9b, 0xb8, 0x81, 0xc3, 0x6b, 0xc4, 0x90, 0x1, 0xce, 0xee, 0xe4, 0xe1, 0x39, 0x6a, 0x84, 0x23, 0xda, 0x80, 0xe1, 0x7f, 0x8c, 0x4f, 0xf1, 0x29, 0x38, 0x8b, 0xd6, 0x87, 0x4, 0x8f, 0x32, 0xf, 0xa, 0x67, 0x99, 0x2a, 0x98, 0x4, 0x42, 0x94, 0xd1, 0x56, 0xf0, 0xd, 0xec, 0xd2, 0xc0, 0x9c, 0xa8, 0xc2, 0x7a, 0x44, 0x1, 0x6d, 0x90, 0xdd, 0x97, 0x13, 0x2e, 0x1, 0x28, 0x8f, 0x39, 0xf4, 0x19, 0x55, 0x42, 0x9f, 0xa1, 0x59, 0x41, 0x4, 0x10, 0x68, 0xe6, 0x6d, 0xe8, 0x23, 0xac, 0xeb, 0xf0, 0xd9, 0xbf, 0xdd, 0xc5, 0xdd, 0x2c, 0xf7, 0x4d, 0x23, 0x11, 0x5b, 0x86, 0x22, 0x82, 0x96, 0x0, 0x83, 0xea, 0xdd, 0x1c, 0x54, 0x15, 0x30, 0x8, 0x2a, 0x98, 0x8c, 0xf1, 0xf3, 0x6c, 0x54, 0x89, 0x2c, 0x5c, 0x75, 0xb2, 0x26, 0xee, 0x40, 0x47, 0xb2, 0x15, 0xc8, 0xe7, 0xeb, 0xd5, 0xca, 0x11, 0x70, 0xb0, 0xf4, 0xc, 0x72, 0xa6, 0x18, 0x25, 0x35, 0x40, 0x80, 0x69, 0x10, 0x8c, 0x35, 0xea, 0x1a, 0xb8, 0xa3, 0x6d, 0x30, 0xef, 0x40, 0x44, 0x20, 0x9c, 0x40, 0xaa, 0x56, 0x2b, 0xd8, 0xfe, 0x2f, 0x34, 0xe3, 0x58, 0xe4, 0xa3, 0x88, 0x93, 0x9, 0xce, 0x20, 0x90, 0xe0, 0xfb, 0xf4, 0xc3, 0xd5, 0xff, 0x5d, 0x8a, 0x57, 0xff, 0xf1, 0x7c, 0x49, 0x2a, 0x57, 0xc, 0xcc, 0x91, 0x99, 0x95, 0x2c, 0x87, 0x3f, 0xcf, 0xca, 0x88, 0xfc, 0xc4, 0xf7, 0xf7, 0x4f, 0x1d, 0xd6, 0xbf, 0x2a, 0x28, 0xcf, 0xfc, 0xe9, 0xd3, 0x5c, 0x21, 0x86, 0xb5, 0x34, 0x90, 0x99, 0xa7, 0x69, 0x2e, 0x64, 0xa7, 0xb0, 0x3c, 0xab, 0xa0, 0xf4, 0x13, 0xcf, 0xda, 0x20, 0xfd, 0xae, 0x1, 0x5a, 0x21, 0x4, 0x55, 0xca, 0x31, 0x24, 0x6d, 0xd0, 0x86, 0x76, 0xe0, 0xfb, 0x1d, 0x38, 0x72, 0xe0, 0x6, 0xbc, 0x41, 0xbb, 0xd8, 0xe5, 0x67, 0xf5, 0xd3, 0xb9, 0x24, 0x95, 0xcb, 0xff, 0xb0, 0x3a, 0xdc, 0x2d, 0xc, 0x15, 0xe4, 0x2a, 0xab, 0xa6, 0xda, 0xea, 0xe1, 0x23, 0x8, 0xca, 0xba, 0x74, 0x48, 0xee, 0xb3, 0x55, 0xa0, 0xc1, 0xaf, 0x15, 0x38, 0x3d, 0xba, 0xd9, 0xa2, 0x43, 0xa0, 0xa, 0x9e, 0xad, 0x7b, 0xd9, 0x40, 0x86, 0x6, 0xe4, 0xc9, 0x3d, 0x6c, 0x10, 0x6d, 0x85, 0x85, 0xc8, 0xb9, 0x61, 0x3, 0x36, 0xd, 0x3c, 0x5, 0x77, 0xd7, 0xe1, 0xf, 0x56, 0x52, 0x5e, 0x99, 0x7e, 0x73, 0x87, 0xe, 0xcf, 0xd, 0x3c, 0x27, 0x4a, 0xce, 0x74, 0x90, 0xb3, 0x78, 0x21, 0x4e, 0x7e, 0xf5, 0x1f, 0x7c, 0x83, 0xaa, 0xb7, 0x1d, 0xf0, 0xb6, 0x15, 0xdf, 0xa6, 0x17, 0xdc, 0x61, 0xc0, 0xb, 0x99, 0x97, 0x61, 0x83, 0x0, 0x8b, 0x88, 0x40, 0x26, 0xd0, 0xbf, 0xf0, 0xb, 0x2, 0xb0, 0xc3, 0x34, 0x89, 0x97, 0x30, 0xc6, 0xe1, 0xc0, 0x74, 0x3e, 0xc9, 0x9, 0x36, 0x6a, 0xd4, 0x4b, 0x1e, 0xc9, 0x44, 0x5a, 0x59, 0x19, 0xc2, 0x73, 0x2e, 0x21, 0x33, 0x99, 0x89, 0x96, 0x6, 0xb9, 0xc2, 0xfc, 0x75, 0x88, 0x5f, 0x40, 0xb3, 0x76, 0xe0, 0xd, 0x46, 0x91, 0x51, 0x2e, 0x72, 0xf6, 0xe6, 0xec, 0x17, 0x16, 0xc1, 0x96, 0x5, 0x18, 0xad, 0xb0, 0x43, 0x7e, 0xf, 0x13, 0xe0, 0xd1, 0xba, 0xfc, 0xe7, 0x77, 0xd3, 0x3b, 0xd0, 0xc3, 0x78, 0xf3, 0xb9, 0x22, 0xa2, 0xd3, 0x7b, 0x40, 0x6d, 0x3c, 0xc9, 0x35, 0xa7, 0x94, 0xb4, 0xec, 0x90, 0x47, 0x75, 0x15, 0x58, 0xf3, 0x3, 0xe, 0x1d, 0x38, 0x34, 0xf0, 0x4a, 0xb5, 0xe, 0x61, 0xa8, 0xb0, 0x90, 0xba, 0x57, 0xb0, 0x2e, 0xf3, 0xe2, 0x35, 0xbc, 0x82, 0xfe, 0x94, 0xfd, 0xca, 0xaa, 0x3b, 0xc8, 0x45, 0xee, 0x46, 0xe2, 0x74, 0x2c, 0xf5, 0x62, 0x6f, 0xdf, 0x87, 0xc1, 0x9e, 0x7d, 0xf7, 0xfb, 0xcf, 0x18, 0xe4, 0xa0, 0xf4, 0xf, 0x22, 0x3c, 0x3d, 0xa, 0x46, 0x1, 0x0, 0x24, 0x3a, 0x65, 0x42, 0x42, 0xc7, 0x4f, 0x7c, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char dropdown_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x8, 0x4, 0x0, 0x0, 0x0, 0x6e, 0x6, 0x76, 0x0, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x2, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x87, 0x8f, 0xcc, 0xbf, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x64, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0x60, 0xf8, 0xc0, 0xcc, 0x0, 0x5, 0x1f, 0x98, 0x19, 0x18, 0x18, 0x3f, 0x30, 0xff, 0xd3, 0x83, 0x70, 0xff, 0x33, 0x33, 0x30, 0x8, 0x9f, 0x61, 0xf9, 0x6b, 0xff, 0x65, 0x2f, 0x3, 0x1c, 0xbc, 0xea, 0x66, 0x62, 0xbc, 0xcf, 0xc0, 0xc0, 0xf0, 0x7, 0x26, 0xc0, 0x74, 0x89, 0x89, 0xe9, 0x29, 0x9f, 0x14, 0x3, 0xb, 0xc3, 0x5f, 0x6, 0x6, 0x6, 0x6, 0xee, 0x38, 0x91, 0x25, 0xc, 0xc, 0xc, 0x1f, 0xd8, 0xde, 0x4b, 0x3e, 0xfc, 0xff, 0xf0, 0xff, 0x9b, 0x58, 0xb8, 0xce, 0xf, 0x6c, 0xef, 0xe4, 0xde, 0xa4, 0x32, 0x20, 0x83, 0xf, 0x4c, 0x30, 0x16, 0x0, 0x75, 0xad, 0x1b, 0x7f, 0x65, 0xec, 0x78, 0x4c, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x8, 0x4, 0x0, 0x0, 0x0, 0x6e, 0x6, 0x76, 0x0, 0x0, 0x0, 0x0, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x60, 0x60, 0xf8, 0xc0, 0xcc, 0x0, 0x2, 0x60, 0x16, 0x98, 0x78, 0x67, 0x8, 0x81, 0x6f, 0x4d, 0xde, 0x9a, 0x0, 0x5, 0xde, 0x3a, 0x3d, 0xfc, 0x8f, 0x80, 0xaf, 0xba, 0x18, 0xde, 0x29, 0x2, 0x19, 0xbf, 0x61, 0x2, 0x6f, 0x62, 0x18, 0x3e, 0xb0, 0xbd, 0x97, 0x4, 0x32, 0xff, 0x80, 0xb9, 0xb1, 0x20, 0x93, 0xc0, 0x42, 0x8, 0x2e, 0x54, 0xe8, 0x9d, 0xdc, 0x9b, 0x54, 0x10, 0xb, 0x21, 0xc4, 0x4, 0x63, 0x1, 0x0, 0x86, 0x1f, 0x3b, 0x1e, 0x92, 0x22, 0x3f, 0x40, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char error_icon_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x20, 0x8, 0x4, 0x0, 0x0, 0x0, 0xd9, 0x73, 0xb2, 0x7f, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x2, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x87, 0x8f, 0xcc, 0xbf, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x5d, 0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0xed, 0x94, 0xc1, 0xe, 0x80, 0x20, 0xc, 0x43, 0x5b, 0xe3, 0xff, 0xff, 0x72, 0x3d, 0xcc, 0x85, 0xa1, 0xbb, 0x18, 0xf4, 0x62, 0xca, 0xa9, 0x74, 0xe3, 0x65, 0xd, 0x1, 0xa, 0x6b, 0x6b, 0x5b, 0x3c, 0x6f, 0x80, 0x1, 0x7f, 0x1, 0xec, 0x29, 0x78, 0xbe, 0x2a, 0x31, 0x94, 0x98, 0x9e, 0x98, 0xf5, 0xab, 0x37, 0x1, 0xaa, 0x19, 0x8d, 0xe2, 0x50, 0xb1, 0x9b, 0xbd, 0xb7, 0x23, 0x8c, 0x21, 0x7b, 0xd5, 0xf5, 0x3d, 0x88, 0x50, 0x1, 0xdf, 0x46, 0xb8, 0xf, 0x5c, 0xef, 0xa6, 0xab, 0xd1, 0x7f, 0xa2, 0x1, 0x6, 0x0, 0x0, 0xe, 0x62, 0x6, 0x31, 0x47, 0xb6, 0x7f, 0xdd, 0x14, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x20, 0x8, 0x4, 0x0, 0x0, 0x0, 0xd9, 0x73, 0xb2, 0x7f, 0x0, 0x0, 0x0, 0x36, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0xa0, 0x36, 0x18, 0x5, 0xa3, 0x60, 0x14, 0xfc, 0x87, 0x40, 0x38, 0xb, 0x21, 0x6, 0x6, 0x18, 0x62, 0x98, 0x6, 0xa0, 0xb1, 0xfe, 0xe3, 0x67, 0xd1, 0xc2, 0x0, 0x10, 0xc4, 0xc5, 0x82, 0x91, 0x43, 0xc0, 0xb, 0xb8, 0x15, 0x63, 0x78, 0x6, 0x5, 0x8c, 0x82, 0x51, 0x30, 0xa, 0x0, 0x35, 0xa3, 0x4c, 0xb4, 0x7c, 0x8a, 0x7, 0x6, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char focus_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x4, 0x3, 0x0, 0x0, 0x0, 0xa4, 0x5b, 0x41, 0xd4, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x30, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0xff, 0xff, 0xff, 0xb9, 0xa2, 0x9b, 0xc9, 0x0, 0x0, 0x0, 0xf, 0x74, 0x52, 0x4e, 0x53, 0x0, 0xe, 0x39, 0x68, 0x7a, 0x7b, 0x3a, 0x74, 0x10, 0x8, 0x69, 0xf, 0x6, 0x75, 0x11, 0xb8, 0x16, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0xf, 0x18, 0xba, 0x0, 0xd9, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x38, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x10, 0x32, 0x9, 0xd, 0x75, 0x56, 0x64, 0x48, 0xef, 0x9c, 0x39, 0x73, 0x46, 0x19, 0xc3, 0x6a, 0x6, 0x20, 0xd8, 0xc5, 0x10, 0x3, 0xa2, 0x8e, 0x32, 0x44, 0x82, 0xa8, 0xa9, 0xd8, 0x29, 0xa8, 0x12, 0xb0, 0x6, 0x29, 0x86, 0xdc, 0x9d, 0x33, 0x67, 0xce, 0x2b, 0x63, 0x10, 0x3, 0x1b, 0x6, 0x0, 0xdf, 0xc6, 0x11, 0x6d, 0xb8, 0xf4, 0x9c, 0xac, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x4, 0x3, 0x0, 0x0, 0x0, 0xa4, 0x5b, 0x41, 0xd4, 0x0, 0x0, 0x0, 0x30, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0xff, 0xff, 0xff, 0xb9, 0xa2, 0x9b, 0xc9, 0x0, 0x0, 0x0, 0xf, 0x74, 0x52, 0x4e, 0x53, 0x0, 0xe, 0x39, 0x68, 0x7a, 0x7b, 0x3a, 0x74, 0x10, 0x8, 0x69, 0xf, 0x6, 0x75, 0x11, 0xb8, 0x16, 0x0, 0x1, 0x0, 0x0, 0x0, 0x38, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x10, 0x32, 0x9, 0xd, 0x75, 0x56, 0x64, 0x48, 0xef, 0x9c, 0x39, 0x73, 0x46, 0x19, 0xc3, 0x6a, 0x6, 0x20, 0xd8, 0xc5, 0x10, 0x3, 0xa2, 0x8e, 0x32, 0x44, 0x82, 0xa8, 0xa9, 0xd8, 0x29, 0xa8, 0x12, 0xb0, 0x6, 0x29, 0x86, 0xdc, 0x9d, 0x33, 0x67, 0xce, 0x2b, 0x63, 0x10, 0x3, 0x1b, 0x6, 0x0, 0xdf, 0xc6, 0x11, 0x6d, 0xb8, 0xf4, 0x9c, 0xac, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char frame_focus_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x4, 0x3, 0x0, 0x0, 0x0, 0xa4, 0x5b, 0x41, 0xd4, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x30, 0x50, 0x4c, 0x54, 0x45, 0xff, 0xff, 0xff, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0xff, 0xff, 0xff, 0xcc, 0x40, 0x27, 0xb9, 0x0, 0x0, 0x0, 0xf, 0x74, 0x52, 0x4e, 0x53, 0x0, 0xe, 0x39, 0x68, 0x7a, 0x7b, 0x3a, 0x74, 0x10, 0x8, 0x69, 0xf, 0x6, 0x75, 0x11, 0xb8, 0x16, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x0, 0x88, 0x5, 0x1d, 0x48, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x4, 0x4e, 0x1d, 0x2, 0xaf, 0x0, 0x0, 0x0, 0x38, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x10, 0x32, 0x9, 0xd, 0x75, 0x56, 0x64, 0x48, 0xef, 0x9c, 0x39, 0x73, 0x46, 0x19, 0xc3, 0x6a, 0x6, 0x20, 0xd8, 0xc5, 0x10, 0x3, 0xa2, 0x8e, 0x32, 0x44, 0x82, 0xa8, 0xa9, 0xd8, 0x29, 0xa8, 0x12, 0xb0, 0x6, 0x29, 0x86, 0xdc, 0x9d, 0x33, 0x67, 0xce, 0x2b, 0x63, 0x10, 0x3, 0x1b, 0x6, 0x0, 0xdf, 0xc6, 0x11, 0x6d, 0xb8, 0xf4, 0x9c, 0xac, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x4, 0x3, 0x0, 0x0, 0x0, 0xa4, 0x5b, 0x41, 0xd4, 0x0, 0x0, 0x0, 0x30, 0x50, 0x4c, 0x54, 0x45, 0xff, 0xff, 0xff, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0xff, 0xff, 0xff, 0xcc, 0x40, 0x27, 0xb9, 0x0, 0x0, 0x0, 0xf, 0x74, 0x52, 0x4e, 0x53, 0x0, 0xe, 0x39, 0x68, 0x7a, 0x7b, 0x3a, 0x74, 0x10, 0x8, 0x69, 0xf, 0x6, 0x75, 0x11, 0xb8, 0x16, 0x0, 0x1, 0x0, 0x0, 0x0, 0x38, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x10, 0x32, 0x9, 0xd, 0x75, 0x56, 0x64, 0x48, 0xef, 0x9c, 0x39, 0x73, 0x46, 0x19, 0xc3, 0x6a, 0x6, 0x20, 0xd8, 0xc5, 0x10, 0x3, 0xa2, 0x8e, 0x32, 0x44, 0x82, 0xa8, 0xa9, 0xd8, 0x29, 0xa8, 0x12, 0xb0, 0x6, 0x29, 0x86, 0xdc, 0x9d, 0x33, 0x67, 0xce, 0x2b, 0x63, 0x10, 0x3, 0x1b, 0x6, 0x0, 0xdf, 0xc6, 0x11, 0x6d, 0xb8, 0xf4, 0x9c, 0xac, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char full_panel_bg_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x20, 0x8, 0x3, 0x0, 0x0, 0x0, 0x44, 0xa4, 0x8a, 0xc6, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x33, 0x50, 0x4c, 0x54, 0x45, 0x27, 0x27, 0x29, 0x26, 0x26, 0x28, 0x25, 0x25, 0x27, 0x24, 0x24, 0x26, 0x23, 0x23, 0x25, 0x22, 0x22, 0x24, 0x21, 0x21, 0x23, 0x1e, 0x1e, 0x20, 0x1d, 0x1d, 0x1f, 0x1c, 0x1c, 0x1e, 0x31, 0x30, 0x32, 0x50, 0x4e, 0x54, 0x4e, 0x4c, 0x50, 0x4c, 0x4a, 0x4e, 0x3d, 0x3b, 0x3f, 0x38, 0x36, 0x3a, 0xff, 0xff, 0xff, 0x4, 0xb3, 0x69, 0x9b, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x10, 0x95, 0xb2, 0xd, 0x2c, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x63, 0x49, 0x44, 0x41, 0x54, 0x38, 0xcb, 0xed, 0x93, 0x29, 0x12, 0xc0, 0x30, 0xc, 0xc4, 0x7c, 0x3b, 0x67, 0xf3, 0xff, 0xdf, 0xb6, 0xe1, 0xce, 0x98, 0x15, 0x45, 0x58, 0xb3, 0x68, 0x5, 0x0, 0x80, 0x48, 0x21, 0x88, 0xb0, 0x41, 0x62, 0x51, 0xb, 0x50, 0x61, 0xda, 0xa, 0xb1, 0x79, 0xa9, 0x1, 0xc5, 0x8d, 0xe9, 0x1b, 0x60, 0x6b, 0x7d, 0xcc, 0x80, 0xd1, 0x9b, 0x31, 0x2, 0x8a, 0xf7, 0x67, 0x85, 0x3c, 0xdd, 0x5, 0x81, 0xb4, 0x8c, 0x75, 0x60, 0x14, 0x25, 0x20, 0xab, 0xf3, 0x24, 0xcc, 0x6a, 0x57, 0xb8, 0xc2, 0xff, 0x42, 0x76, 0xda, 0xf4, 0xf6, 0x69, 0x38, 0x69, 0x7a, 0x79, 0xbc, 0x49, 0xfe, 0x2f, 0x65, 0xd3, 0x2d, 0x45, 0xb, 0x5e, 0xbc, 0x3b, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x20, 0x4, 0x3, 0x0, 0x0, 0x0, 0x81, 0x54, 0x67, 0xc7, 0x0, 0x0, 0x0, 0x30, 0x50, 0x4c, 0x54, 0x45, 0x27, 0x27, 0x29, 0x26, 0x26, 0x28, 0x25, 0x25, 0x27, 0x24, 0x24, 0x26, 0x23, 0x23, 0x25, 0x22, 0x22, 0x24, 0x21, 0x21, 0x23, 0x1e, 0x1e, 0x20, 0x1d, 0x1d, 0x1f, 0x1c, 0x1c, 0x1e, 0x31, 0x30, 0x32, 0x50, 0x4e, 0x54, 0x4e, 0x4c, 0x50, 0x4c, 0x4a, 0x4e, 0x3d, 0x3b, 0x3f, 0x38, 0x36, 0x3a, 0xb3, 0xde, 0x6f, 0x4d, 0x0, 0x0, 0x0, 0x5a, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x60, 0x60, 0x14, 0x52, 0x82, 0x3, 0x45, 0x1, 0x20, 0x5f, 0xd9, 0x35, 0xd, 0xe, 0x42, 0x8c, 0x4, 0x18, 0x98, 0xcc, 0x2a, 0x66, 0xc2, 0x41, 0x7b, 0xb2, 0x2, 0x83, 0x70, 0xd6, 0x9e, 0xbb, 0x70, 0x70, 0x7a, 0x99, 0x21, 0x83, 0x48, 0xf5, 0xfb, 0xff, 0x70, 0xf0, 0x6f, 0xbb, 0x23, 0x83, 0x6a, 0xcf, 0x7f, 0x24, 0x70, 0x22, 0x88, 0x41, 0x6d, 0x2e, 0xb2, 0xc0, 0xcd, 0x24, 0x8a, 0x5, 0x46, 0x5, 0x30, 0x2, 0x19, 0x23, 0x1a, 0x30, 0x22, 0xa, 0x23, 0x2a, 0x31, 0x22, 0x1b, 0x23, 0x39, 0x0, 0x0, 0x8c, 0xb1, 0x80, 0xd2, 0x41, 0x59, 0x8c, 0x74, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char graph_node_png[] = {
@@ -91,391 +91,395 @@ static const unsigned char graph_node_png[] = {
};
static const unsigned char graph_node_breakpoint_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x40, 0x8, 0x6, 0x0, 0x0, 0x0, 0x13, 0x7d, 0xf7, 0x96, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x8, 0x6, 0xf, 0x3b, 0x1c, 0xec, 0x64, 0x51, 0x75, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x8f, 0x49, 0x44, 0x41, 0x54, 0x58, 0xc3, 0xed, 0xd7, 0xbd, 0x9, 0xc0, 0x20, 0x10, 0x5, 0xe0, 0x53, 0x2c, 0x5d, 0x40, 0x74, 0x4, 0xf7, 0x9f, 0xc4, 0x11, 0x22, 0x2e, 0x60, 0x6f, 0x9a, 0x13, 0x4e, 0x21, 0x41, 0x50, 0x48, 0x91, 0x77, 0x95, 0xf8, 0xf3, 0x79, 0x62, 0xf5, 0x88, 0x36, 0x4b, 0xf5, 0x41, 0x2d, 0xf1, 0x22, 0x22, 0xbf, 0x78, 0x2e, 0x5b, 0x97, 0x2, 0xc9, 0xc3, 0xc, 0x2c, 0x95, 0xdc, 0x6f, 0x78, 0xce, 0x5b, 0x97, 0xd4, 0x42, 0x27, 0xd9, 0xba, 0x14, 0xac, 0x4b, 0xa1, 0x96, 0xd8, 0x24, 0x20, 0x9f, 0x41, 0x1d, 0x7b, 0xba, 0x59, 0xb6, 0xaf, 0xa7, 0x3d, 0x7e, 0x78, 0xdb, 0x54, 0xbc, 0x36, 0x74, 0xa7, 0x77, 0x7f, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7e, 0x4, 0xe4, 0xb7, 0xfc, 0xc8, 0x6b, 0x59, 0xce, 0x99, 0x39, 0x95, 0x71, 0xb4, 0x6b, 0x4b, 0x89, 0xf5, 0x44, 0x72, 0x3d, 0x93, 0x9d, 0x3f, 0xad, 0x1b, 0x54, 0xed, 0x49, 0xd3, 0x36, 0x45, 0x4f, 0x1f, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x40, 0x2, 0x3, 0x0, 0x0, 0x0, 0x6e, 0x13, 0x1f, 0x5, 0x0, 0x0, 0x0, 0x9, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0xf4, 0xe7, 0x2c, 0xf4, 0xe7, 0x2c, 0xec, 0x5a, 0x6b, 0x42, 0x0, 0x0, 0x0, 0x2, 0x74, 0x52, 0x4e, 0x53, 0x0, 0xe4, 0xd1, 0xf4, 0xeb, 0x59, 0x0, 0x0, 0x0, 0x30, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x0, 0x3, 0xb6, 0x55, 0xab, 0x26, 0x30, 0x88, 0x30, 0x0, 0x91, 0x42, 0xd6, 0x4a, 0xe, 0x6, 0x45, 0x7, 0x46, 0xf, 0x6, 0x25, 0x6, 0x86, 0xe, 0x20, 0x31, 0x4a, 0x80, 0x42, 0x3, 0x1c, 0x2e, 0xe0, 0x10, 0x82, 0x84, 0x15, 0x1c, 0x0, 0x0, 0x41, 0x2d, 0x2b, 0x21, 0xbb, 0xb7, 0x1a, 0xa9, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char graph_node_close_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x6, 0x0, 0x0, 0x0, 0x56, 0x75, 0x5c, 0xe7, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x93, 0x49, 0x44, 0x41, 0x54, 0x28, 0x91, 0x95, 0x92, 0x31, 0xe, 0xc2, 0x30, 0x10, 0x4, 0x17, 0xaa, 0x3d, 0x7b, 0xdb, 0x58, 0xa4, 0xa7, 0xe1, 0x47, 0xfe, 0x2c, 0x3c, 0x82, 0x48, 0x44, 0x22, 0x6f, 0xb1, 0x4d, 0x15, 0xc9, 0x20, 0x1f, 0x52, 0xae, 0xdd, 0xd9, 0x2b, 0xe6, 0xe, 0x0, 0x60, 0x66, 0x59, 0x52, 0x82, 0x33, 0x92, 0x92, 0x99, 0x65, 0xec, 0x30, 0xc9, 0x4a, 0x72, 0x19, 0x95, 0x24, 0x25, 0x92, 0xb, 0xc9, 0x6a, 0x66, 0x19, 0x92, 0x26, 0x33, 0x7b, 0x92, 0x6c, 0x24, 0xd7, 0x10, 0xc2, 0xdc, 0xc1, 0x5f, 0x59, 0x8c, 0xf1, 0x32, 0xc, 0x42, 0x8, 0xb3, 0xb, 0x3b, 0xdb, 0xde, 0x24, 0x5f, 0x2e, 0xdc, 0x97, 0x3a, 0xb0, 0x91, 0xdc, 0x7e, 0xe1, 0xb3, 0x67, 0x66, 0x9f, 0xd6, 0xda, 0x69, 0x58, 0x90, 0x34, 0x95, 0x52, 0xee, 0x0, 0x6e, 0x0, 0x36, 0x0, 0x2b, 0x80, 0x6b, 0xad, 0xf5, 0xd1, 0x8b, 0x70, 0x6d, 0xb8, 0xf6, 0xfe, 0xd9, 0x18, 0x96, 0xe, 0x1f, 0xe, 0x38, 0xf6, 0x1a, 0x1f, 0x9f, 0xec, 0x40, 0x47, 0x56, 0x51, 0x84, 0x77, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x4, 0x0, 0x0, 0x0, 0xfc, 0x7c, 0x94, 0x6c, 0x0, 0x0, 0x0, 0x5f, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x75, 0x90, 0xb5, 0x1, 0xc0, 0x30, 0x10, 0x3, 0x55, 0x1a, 0xbe, 0xc, 0x6e, 0xe6, 0xb5, 0xc3, 0x34, 0x4b, 0x98, 0xcc, 0xee, 0x7c, 0x4f, 0x92, 0x0, 0x70, 0x45, 0x19, 0x8c, 0x47, 0x19, 0x57, 0x37, 0x66, 0x1b, 0x6b, 0x74, 0x89, 0x32, 0xd6, 0xb0, 0xed, 0x2c, 0x51, 0xca, 0x6b, 0xb6, 0xb3, 0x41, 0x94, 0x0, 0xfe, 0x9f, 0x2c, 0x0, 0xa3, 0x64, 0x61, 0xa3, 0x6f, 0x66, 0xbd, 0xc6, 0x7f, 0xe9, 0x86, 0x3b, 0x5b, 0x34, 0x76, 0xa, 0xcf, 0xad, 0xe0, 0xaa, 0xbf, 0xa4, 0x4f, 0x5a, 0xa, 0x6d, 0x25, 0xba, 0x14, 0x37, 0x18, 0x8b, 0xe4, 0x0, 0x6f, 0xe9, 0x37, 0x83, 0x22, 0x73, 0x83, 0x23, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char graph_node_comment_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x40, 0x8, 0x6, 0x0, 0x0, 0x0, 0x13, 0x7d, 0xf7, 0x96, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x8, 0x19, 0x11, 0x2a, 0x1d, 0xd6, 0x78, 0x8b, 0x40, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x1, 0x74, 0x49, 0x44, 0x41, 0x54, 0x58, 0xc3, 0xed, 0x97, 0xbf, 0x4e, 0xc2, 0x50, 0x14, 0xc6, 0x7f, 0x6d, 0x91, 0x56, 0x1b, 0x90, 0x80, 0x2c, 0x44, 0xc2, 0xa0, 0x2e, 0xe, 0x3e, 0x3, 0x89, 0x93, 0xf1, 0x1d, 0x4c, 0x18, 0x4d, 0x1c, 0x7c, 0xb, 0x57, 0x7, 0x13, 0x47, 0x13, 0x77, 0x46, 0xe3, 0xc4, 0x4b, 0x98, 0x60, 0x4c, 0xd4, 0x81, 0x60, 0x58, 0x94, 0xff, 0x22, 0x2d, 0xd0, 0xd6, 0xe5, 0xde, 0x88, 0x8, 0x2, 0x35, 0x6e, 0xf7, 0x5b, 0x6e, 0x9a, 0x9c, 0xef, 0x77, 0xee, 0x39, 0x37, 0x1d, 0x3e, 0x8d, 0x2f, 0x69, 0x80, 0xe, 0x18, 0xe2, 0xd4, 0xf8, 0xae, 0x0, 0xf0, 0x1, 0x4f, 0x9c, 0x1, 0x63, 0x45, 0x3a, 0xb0, 0x6, 0x24, 0x81, 0x34, 0x10, 0x7, 0x56, 0x26, 0x0, 0x43, 0xa0, 0x3, 0xbc, 0x2, 0xd, 0xe0, 0x3, 0xf0, 0x65, 0x57, 0x1b, 0xd8, 0x5e, 0x8f, 0x25, 0x8e, 0x2d, 0xd3, 0x3a, 0x88, 0x46, 0xcd, 0x4d, 0xa6, 0x68, 0x30, 0x70, 0x5f, 0x1c, 0xd7, 0xb9, 0x6d, 0x77, 0x5b, 0x97, 0xc0, 0x13, 0xd0, 0xd3, 0x44, 0xa7, 0x5c, 0x32, 0x91, 0x3a, 0xdf, 0xca, 0xed, 0x1c, 0x16, 0x52, 0xdd, 0x2a, 0xbf, 0xe8, 0xaa, 0x1e, 0xcb, 0x3e, 0x57, 0x1e, 0x6f, 0x1a, 0xad, 0xfa, 0x29, 0x50, 0x91, 0x33, 0xa7, 0x4d, 0xd3, 0xca, 0xcf, 0x33, 0x3, 0x14, 0x52, 0xdd, 0xaa, 0x69, 0x5a, 0x79, 0x31, 0xaa, 0x21, 0x97, 0x65, 0x47, 0x8c, 0x88, 0xcd, 0x82, 0x12, 0xb5, 0x36, 0xa0, 0x49, 0x80, 0xc1, 0xf2, 0x32, 0x24, 0x20, 0x90, 0x4f, 0x12, 0x46, 0x3a, 0x7f, 0x94, 0x2, 0x28, 0x80, 0x2, 0x88, 0x5f, 0x7b, 0xfc, 0xe3, 0xec, 0xe1, 0x3d, 0x1b, 0x1a, 0x30, 0x1a, 0x7a, 0x1c, 0x65, 0xd8, 0x5f, 0xc4, 0x74, 0x5d, 0xa3, 0xa4, 0x5e, 0x41, 0x1, 0x14, 0x40, 0x1, 0x14, 0x40, 0x1, 0x14, 0x40, 0x1, 0xfe, 0x15, 0xa0, 0x4d, 0xc9, 0x88, 0x4b, 0xdf, 0xc0, 0xf, 0xe1, 0xf5, 0x25, 0xc0, 0x7, 0x1c, 0xcf, 0xf3, 0xdc, 0x45, 0x9d, 0xa2, 0xd6, 0x1, 0x7c, 0x5d, 0x44, 0xd9, 0xba, 0xe3, 0xf6, 0xcb, 0xc5, 0xa6, 0x5d, 0x9a, 0x67, 0x2e, 0x36, 0xed, 0x92, 0xe3, 0xf6, 0xcb, 0x40, 0x1d, 0xf0, 0x64, 0x72, 0x5d, 0x7, 0xf6, 0xe2, 0x76, 0xe2, 0xc2, 0x32, 0x57, 0x77, 0xd, 0xc3, 0xd0, 0x67, 0x74, 0xf6, 0x1d, 0xb7, 0x7f, 0xdf, 0xe9, 0xb5, 0x4e, 0x80, 0x3b, 0xa0, 0xad, 0x8d, 0x45, 0xb8, 0x38, 0x90, 0x1, 0x36, 0x0, 0x73, 0x46, 0xf8, 0x76, 0x81, 0x37, 0xa0, 0x26, 0x72, 0xb4, 0xa7, 0x4d, 0x2c, 0x34, 0x22, 0xf3, 0xe0, 0x8c, 0x9, 0x2, 0x31, 0xf2, 0x28, 0xe4, 0xe2, 0x7f, 0xea, 0x13, 0x64, 0x47, 0x6c, 0x83, 0x36, 0x6d, 0xd2, 0x40, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x40, 0x8, 0x3, 0x0, 0x0, 0x0, 0x24, 0xa3, 0x7, 0xa4, 0x0, 0x0, 0x0, 0x78, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xd, 0x10, 0x17, 0x14, 0x18, 0x1d, 0x1a, 0x1f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x12, 0x10, 0x13, 0x35, 0x2f, 0x38, 0x96, 0x42, 0x2b, 0x0, 0x0, 0x0, 0x19, 0x17, 0x1b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x19, 0x15, 0x1c, 0x77, 0x2f, 0x1c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x16, 0x12, 0x19, 0x0, 0x0, 0x0, 0xe, 0xb, 0x10, 0x24, 0x1e, 0x27, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0xb, 0x10, 0x16, 0x12, 0x19, 0x0, 0x0, 0x0, 0x85, 0xbb, 0x9b, 0xdf, 0x0, 0x0, 0x0, 0x28, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x1, 0x3, 0x6, 0x8, 0x9, 0x2, 0xc, 0x1e, 0x33, 0x41, 0x46, 0xd, 0x31, 0x9a, 0xe3, 0xff, 0x5, 0x24, 0xb4, 0xff, 0xe2, 0x39, 0xf4, 0x44, 0xa, 0x47, 0xff, 0x42, 0x45, 0x3d, 0xf8, 0x2a, 0xcd, 0xff, 0x11, 0x3f, 0xd3, 0xfd, 0x2b, 0x31, 0x64, 0xfe, 0xeb, 0x0, 0x0, 0x0, 0x8d, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0xed, 0xc8, 0x35, 0x62, 0x3, 0x41, 0x14, 0x4, 0xd1, 0xee, 0x21, 0x33, 0x33, 0xdb, 0xf7, 0xbf, 0x93, 0x99, 0x49, 0xcc, 0xd2, 0x7c, 0x2d, 0x53, 0xa6, 0x58, 0x5b, 0x59, 0x3d, 0x2, 0xc, 0x3, 0x20, 0x61, 0x20, 0x5c, 0x9, 0xc6, 0x74, 0x11, 0x20, 0x2c, 0x86, 0xbd, 0xec, 0x63, 0xa1, 0xd9, 0xa7, 0x47, 0x9a, 0x92, 0x7f, 0xda, 0x83, 0xa1, 0xcd, 0x60, 0xb2, 0xfa, 0xc7, 0x33, 0xf6, 0xb, 0xb0, 0x2e, 0xb4, 0xce, 0x2e, 0x17, 0x20, 0x2f, 0x82, 0x5d, 0x66, 0x2f, 0xb2, 0x20, 0xd4, 0x50, 0xc3, 0x19, 0x59, 0x1, 0xe3, 0xb, 0xa0, 0xa6, 0x34, 0xe7, 0x9c, 0x65, 0xa0, 0xe5, 0x9d, 0x7b, 0x3b, 0xe4, 0x38, 0x79, 0x27, 0xd2, 0xa2, 0xbb, 0x22, 0xd9, 0x8b, 0x7e, 0x43, 0x44, 0x5e, 0x8, 0x75, 0x67, 0x66, 0x1f, 0x3b, 0x0, 0x5a, 0x67, 0x7a, 0xfa, 0xe0, 0x9, 0xb8, 0x99, 0x3a, 0x44, 0xd8, 0xaf, 0xd7, 0x63, 0x10, 0x95, 0xe6, 0x1e, 0x57, 0xc1, 0x90, 0xf7, 0xdc, 0x9d, 0x9f, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char graph_node_comment_focus_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x40, 0x8, 0x6, 0x0, 0x0, 0x0, 0x13, 0x7d, 0xf7, 0x96, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf9, 0x43, 0xbb, 0x7f, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x9, 0x2, 0xe, 0x16, 0x22, 0xbe, 0xef, 0xc2, 0xe1, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x1, 0x4a, 0x49, 0x44, 0x41, 0x54, 0x58, 0xc3, 0xed, 0xd7, 0xbf, 0x4b, 0xdb, 0x41, 0x1c, 0xc6, 0xf1, 0xd7, 0x37, 0x51, 0x4, 0x3, 0xa, 0xa2, 0x20, 0xd2, 0xe2, 0xe2, 0x64, 0x41, 0xdc, 0xdc, 0xac, 0xe0, 0x54, 0xdc, 0xb2, 0xe6, 0x2f, 0x10, 0x1a, 0xf0, 0x4f, 0x11, 0x22, 0xf8, 0x17, 0x64, 0xcd, 0x26, 0x9d, 0x1c, 0x74, 0x73, 0x13, 0x21, 0x4e, 0x2e, 0xa5, 0xa5, 0x14, 0xac, 0x82, 0x82, 0x62, 0xd0, 0x7c, 0xd3, 0xa1, 0x77, 0x18, 0x35, 0xfe, 0x48, 0xa4, 0xdb, 0x3d, 0x70, 0xdc, 0xf2, 0x79, 0xde, 0x77, 0xf7, 0x39, 0x38, 0xee, 0xc9, 0xdc, 0x2b, 0x43, 0x1, 0xc5, 0x30, 0x67, 0x1e, 0xaa, 0x83, 0x1c, 0xed, 0x30, 0x77, 0x74, 0x15, 0x15, 0x30, 0x8a, 0x9, 0x4c, 0x61, 0xc, 0xc3, 0x8f, 0x0, 0xb7, 0xb8, 0xc4, 0x29, 0xce, 0x71, 0x8d, 0x3c, 0xae, 0x5a, 0xc2, 0x5c, 0xa3, 0x5a, 0x59, 0xc7, 0x17, 0x7c, 0xd0, 0x5b, 0x3f, 0xf1, 0xad, 0x5c, 0xab, 0x6f, 0xe3, 0x4, 0x57, 0x59, 0x58, 0x69, 0xb6, 0x51, 0xad, 0x6c, 0x62, 0xed, 0x77, 0xf3, 0xf0, 0x87, 0x17, 0x34, 0xfd, 0x69, 0xf1, 0x23, 0x76, 0xca, 0xb5, 0xfa, 0x6, 0xbe, 0xc7, 0x33, 0x4f, 0x61, 0xe5, 0x35, 0x33, 0x84, 0x9a, 0x95, 0xe0, 0x29, 0xc6, 0x66, 0x95, 0xc2, 0x78, 0xab, 0x62, 0x7d, 0x16, 0x1, 0x45, 0xfd, 0xab, 0x18, 0x1, 0x9d, 0x78, 0x25, 0x83, 0xa8, 0xe0, 0x9d, 0x4a, 0x80, 0x4, 0x48, 0x80, 0x7f, 0x1a, 0xea, 0xf1, 0xda, 0xc, 0xe, 0x38, 0xd8, 0xdf, 0x5b, 0x7d, 0x8b, 0x69, 0x69, 0xf9, 0xf3, 0x6e, 0xba, 0x85, 0x4, 0x48, 0x80, 0x4, 0x48, 0x80, 0x4, 0x48, 0x80, 0x4, 0xf8, 0xaf, 0x80, 0xac, 0x47, 0x46, 0xec, 0x7b, 0x7, 0xf9, 0x0, 0xde, 0x3c, 0x2, 0x72, 0xdc, 0xa0, 0xd5, 0x87, 0xb9, 0x15, 0x3c, 0x79, 0x21, 0x44, 0xd9, 0x33, 0x34, 0xbb, 0x3f, 0x4f, 0xaf, 0x7c, 0xb0, 0x9a, 0xc1, 0xd3, 0x8e, 0xc9, 0x75, 0x1c, 0xb, 0x8d, 0x6a, 0x65, 0xb, 0xf3, 0x2f, 0x34, 0x37, 0xc7, 0x71, 0xb9, 0x56, 0xff, 0x8a, 0x23, 0x5c, 0x64, 0x5d, 0x11, 0x6e, 0xc, 0x33, 0x98, 0xc4, 0xc8, 0x33, 0xe1, 0xbb, 0x85, 0x3f, 0xf8, 0x15, 0x72, 0x74, 0x3b, 0x7b, 0xd4, 0xd0, 0xa1, 0x98, 0x7, 0x9f, 0xd9, 0x41, 0x27, 0x1c, 0xf9, 0x6e, 0xc0, 0xc6, 0x3f, 0xd5, 0x5f, 0x9d, 0x54, 0x4e, 0x15, 0xfd, 0xeb, 0xb4, 0x4f, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x40, 0x8, 0x3, 0x0, 0x0, 0x0, 0x24, 0xa3, 0x7, 0xa4, 0x0, 0x0, 0x0, 0x6f, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xae, 0x6d, 0x5b, 0xae, 0x6d, 0x5b, 0xae, 0x6d, 0x5b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xae, 0x6d, 0x5b, 0x96, 0x42, 0x2b, 0x0, 0x0, 0x0, 0xae, 0x6d, 0x5b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x77, 0x2f, 0x1c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xae, 0x6d, 0x5b, 0x0, 0x0, 0x0, 0xae, 0x6d, 0x5b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xae, 0x6d, 0x5b, 0xae, 0x6d, 0x5b, 0x0, 0x0, 0x0, 0x5f, 0x8c, 0x8b, 0xc7, 0x0, 0x0, 0x0, 0x25, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x1, 0x3, 0x6, 0x8, 0x9, 0x2, 0xc, 0x1e, 0x33, 0x41, 0x46, 0xd, 0x31, 0x9a, 0xe3, 0xff, 0x5, 0x24, 0xb4, 0xe2, 0x39, 0xf4, 0x44, 0xa, 0x47, 0x42, 0x45, 0x3d, 0xf8, 0x2a, 0xcd, 0x11, 0x3f, 0xd3, 0xfd, 0x2b, 0xb1, 0x1b, 0xa4, 0x4f, 0x0, 0x0, 0x0, 0x90, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0xed, 0xca, 0xb5, 0x75, 0xc4, 0x50, 0x0, 0x5, 0xd1, 0xf7, 0x49, 0xcc, 0xcc, 0xdc, 0x7f, 0x8b, 0x2b, 0xe6, 0xc8, 0xb1, 0x75, 0xc3, 0x39, 0x3, 0x80, 0x50, 0xc6, 0xc5, 0x84, 0x33, 0x4a, 0x30, 0x91, 0x64, 0x45, 0xd5, 0xf4, 0x89, 0xa6, 0x2a, 0xb2, 0x4, 0x48, 0x86, 0x69, 0xd9, 0xce, 0xc2, 0xb6, 0x4c, 0x43, 0x82, 0xeb, 0xf9, 0x4e, 0xb0, 0x71, 0x7c, 0xcf, 0x5, 0xf, 0xa3, 0xe0, 0x10, 0x85, 0x1c, 0x22, 0x76, 0xce, 0xe0, 0xc4, 0x2, 0x49, 0x7a, 0xd, 0x69, 0x2, 0xa1, 0xff, 0xb3, 0x70, 0xda, 0x42, 0x76, 0xf8, 0x73, 0xf8, 0xc2, 0x17, 0x92, 0xf4, 0x19, 0xf2, 0x6b, 0xc8, 0x13, 0xf0, 0xa2, 0x3c, 0x43, 0x59, 0x70, 0xb8, 0x55, 0x7d, 0x2c, 0x4e, 0x5d, 0xb9, 0x90, 0x9a, 0xb6, 0xeb, 0x9d, 0x45, 0xdf, 0xb5, 0x8d, 0x4, 0xd0, 0x66, 0x68, 0xf5, 0x74, 0xa2, 0xb7, 0x43, 0x43, 0x31, 0x91, 0x98, 0x48, 0x16, 0x82, 0x49, 0x78, 0x1b, 0x1, 0xf, 0xa7, 0x50, 0x68, 0x35, 0xb8, 0x84, 0x4, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char graph_node_default_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x39, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x16, 0x12, 0x19, 0xe, 0xb, 0x10, 0xe, 0xb, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x16, 0x12, 0x19, 0x0, 0x0, 0x0, 0x19, 0x15, 0x1c, 0x24, 0x1e, 0x27, 0x16, 0x12, 0x19, 0xff, 0xff, 0xff, 0x2b, 0x4d, 0xfd, 0x66, 0x0, 0x0, 0x0, 0xf, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x46, 0x47, 0x3f, 0x2b, 0x11, 0x3, 0xfd, 0xd3, 0xcd, 0x2a, 0x73, 0x45, 0xf8, 0x3d, 0x3f, 0x57, 0xda, 0x84, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x12, 0x7b, 0xbc, 0x6c, 0x0, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x4, 0x4e, 0x1d, 0x2, 0xaf, 0x0, 0x0, 0x0, 0x38, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, 0x64, 0x2, 0x2, 0x46, 0x8, 0xc9, 0xcc, 0xc2, 0xca, 0xc6, 0xc0, 0x8f, 0x4, 0xd8, 0x39, 0x98, 0x59, 0x19, 0x50, 0x80, 0x0, 0x27, 0x17, 0xaa, 0x0, 0x83, 0x20, 0x37, 0x9a, 0x0, 0x3f, 0xd3, 0xc0, 0x8, 0xf0, 0xa0, 0x9, 0xf0, 0xf2, 0x61, 0x3a, 0x1d, 0xc3, 0x73, 0xe8, 0xde, 0x7, 0x0, 0x89, 0x4d, 0x2, 0xf2, 0x16, 0xd3, 0x74, 0x45, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x36, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x16, 0x12, 0x19, 0xe, 0xb, 0x10, 0xe, 0xb, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x16, 0x12, 0x19, 0x0, 0x0, 0x0, 0x19, 0x15, 0x1c, 0x24, 0x1e, 0x27, 0x16, 0x12, 0x19, 0x76, 0x9, 0xd2, 0x13, 0x0, 0x0, 0x0, 0xf, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x46, 0x47, 0x3f, 0x2b, 0x11, 0x3, 0xfd, 0xd3, 0xcd, 0x2a, 0x73, 0x45, 0xf8, 0x3d, 0x3f, 0x57, 0xda, 0x84, 0x0, 0x0, 0x0, 0x37, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x60, 0x64, 0x2, 0x2, 0x46, 0x8, 0xc9, 0xcc, 0xc2, 0xca, 0xc6, 0xc0, 0x8f, 0x4, 0xd8, 0x39, 0x98, 0x59, 0x19, 0x50, 0x80, 0x0, 0x27, 0x17, 0x3, 0x2a, 0x10, 0xe4, 0x46, 0x13, 0xe0, 0x67, 0x1a, 0x18, 0x1, 0x1e, 0x34, 0x1, 0x5e, 0x3e, 0xc, 0xa7, 0x63, 0x78, 0xe, 0xc3, 0xfb, 0x0, 0x89, 0x4d, 0x2, 0xf2, 0xa2, 0x23, 0x3b, 0xc4, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char graph_node_default_focus_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x2, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x87, 0x8f, 0xcc, 0xbf, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0xb7, 0x49, 0x44, 0x41, 0x54, 0x28, 0xcf, 0x9d, 0x91, 0x3d, 0x6a, 0x42, 0x61, 0x10, 0x45, 0xcf, 0x8c, 0x4f, 0x22, 0x7c, 0x58, 0x84, 0x14, 0x2e, 0xc0, 0xf5, 0x64, 0x17, 0xba, 0x3, 0x2d, 0x4, 0x41, 0x17, 0x96, 0x2a, 0x65, 0x5c, 0x43, 0x7a, 0xb, 0x53, 0xfa, 0xc3, 0x63, 0x9c, 0x6b, 0xf1, 0x4, 0xf9, 0x24, 0x31, 0x21, 0xb7, 0x1b, 0xe6, 0x14, 0x33, 0xe7, 0x1a, 0x80, 0xc, 0xc7, 0x1, 0xa7, 0x4b, 0x2, 0x49, 0x9a, 0xc0, 0x34, 0xc2, 0xbb, 0x11, 0xae, 0x58, 0x92, 0x4, 0x2d, 0x2d, 0x61, 0xb2, 0x99, 0xf8, 0x26, 0xfd, 0xaf, 0xe1, 0xdb, 0x62, 0xca, 0x89, 0x40, 0x88, 0x35, 0x13, 0xb6, 0x15, 0xb0, 0x7d, 0x99, 0x68, 0xfd, 0xae, 0xa2, 0x1e, 0x42, 0xcc, 0x9, 0x4a, 0x5, 0x94, 0x71, 0xd8, 0xfc, 0xa8, 0x67, 0xf5, 0x1d, 0x40, 0x34, 0xec, 0x2b, 0x60, 0xff, 0xd9, 0x48, 0x3, 0x1a, 0xdc, 0x79, 0x14, 0xbf, 0x3d, 0xf6, 0x4f, 0x80, 0xdf, 0x80, 0xfc, 0x2b, 0x60, 0x77, 0x16, 0x3a, 0x13, 0x76, 0x24, 0x48, 0x7, 0x28, 0x2c, 0x89, 0x6a, 0x1d, 0xc3, 0xe5, 0xae, 0x7c, 0xd0, 0x92, 0x3f, 0xa8, 0xb6, 0x53, 0xd9, 0xac, 0x5e, 0x39, 0x10, 0x8f, 0xcb, 0x4a, 0x3b, 0x5b, 0x67, 0x12, 0x80, 0xa7, 0xea, 0xbc, 0x6b, 0xdd, 0x17, 0xbe, 0x3f, 0x4f, 0x23, 0x27, 0x82, 0x63, 0x73, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x8a, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x0, 0x81, 0xff, 0x8c, 0xff, 0x99, 0xff, 0xb3, 0x2, 0x21, 0x3b, 0x4, 0x82, 0xd8, 0x40, 0x11, 0x46, 0x88, 0xa4, 0xf8, 0x7f, 0x49, 0x20, 0x14, 0xff, 0x2f, 0xa, 0x84, 0x8, 0xb6, 0xe0, 0x7f, 0x6e, 0xa0, 0x22, 0x90, 0x92, 0x92, 0xff, 0xd8, 0x60, 0xe5, 0x9b, 0xb6, 0x15, 0xff, 0x79, 0xc1, 0x4a, 0xb0, 0x83, 0x17, 0xc2, 0x29, 0xff, 0x1b, 0xe, 0x1, 0x4d, 0x61, 0xc6, 0xa1, 0x80, 0x5b, 0xf9, 0xf, 0x63, 0xe9, 0x77, 0xa0, 0x45, 0xac, 0xc, 0x38, 0x0, 0xd8, 0x72, 0xa0, 0x5b, 0xd8, 0xf1, 0x2b, 0x10, 0x27, 0xa4, 0x40, 0x92, 0x7c, 0x5, 0x8, 0x2b, 0xc8, 0x77, 0xe4, 0xb, 0xe1, 0xd2, 0x6f, 0x78, 0xbc, 0xf9, 0x87, 0x17, 0x18, 0x50, 0x7, 0x40, 0x1, 0x85, 0x23, 0xa8, 0x4b, 0xbf, 0x3, 0xc3, 0x91, 0x1f, 0x14, 0xd4, 0x78, 0x23, 0xb, 0x2d, 0xa0, 0xff, 0xb3, 0x23, 0x20, 0x22, 0xba, 0x1, 0x39, 0x96, 0x8a, 0xa5, 0x9b, 0x88, 0xa3, 0x56, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char graph_node_position_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x40, 0x8, 0x6, 0x0, 0x0, 0x0, 0x13, 0x7d, 0xf7, 0x96, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x8, 0x6, 0xf, 0x3b, 0x3b, 0x49, 0x6e, 0xe4, 0x1e, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x90, 0x49, 0x44, 0x41, 0x54, 0x58, 0xc3, 0xed, 0xd7, 0xbd, 0x9, 0xc0, 0x20, 0x10, 0x5, 0xe0, 0x53, 0x2c, 0xdd, 0x40, 0x47, 0x70, 0x7, 0x67, 0x77, 0x7, 0x47, 0x88, 0x1b, 0xd8, 0x9b, 0xe6, 0x84, 0x53, 0x48, 0x10, 0x14, 0x52, 0xe4, 0x5d, 0x25, 0xfe, 0x7c, 0x9e, 0x58, 0x3d, 0xa2, 0xcd, 0x52, 0x7d, 0x50, 0x63, 0xb8, 0x88, 0xc8, 0x2d, 0x9e, 0x2b, 0x36, 0x65, 0x4f, 0xf2, 0x30, 0x3, 0x4b, 0x25, 0xf7, 0x1b, 0x9e, 0x73, 0x36, 0x65, 0xb5, 0xd0, 0x49, 0xb1, 0x29, 0x7b, 0x9b, 0xb2, 0xaf, 0x31, 0x34, 0x9, 0xc8, 0x67, 0x50, 0xc7, 0x9e, 0x6e, 0x96, 0xed, 0xeb, 0x69, 0x8f, 0x1b, 0xde, 0x36, 0x15, 0xaf, 0xd, 0xdd, 0xe9, 0xdd, 0x5f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0x1f, 0x1, 0xe5, 0x2d, 0x3f, 0xf2, 0x5a, 0x91, 0x73, 0x66, 0x4e, 0x65, 0x1c, 0xed, 0xda, 0x52, 0x62, 0x3d, 0x91, 0x5c, 0xcf, 0x64, 0xe7, 0x4f, 0xeb, 0x6, 0x80, 0xff, 0x44, 0x93, 0xd4, 0xd9, 0xea, 0x7e, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x40, 0x2, 0x3, 0x0, 0x0, 0x0, 0x6e, 0x13, 0x1f, 0x5, 0x0, 0x0, 0x0, 0x9, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0xf4, 0x3f, 0x2c, 0xf4, 0x3f, 0x2c, 0x1c, 0x3e, 0x10, 0xcd, 0x0, 0x0, 0x0, 0x2, 0x74, 0x52, 0x4e, 0x53, 0x0, 0xe4, 0xd1, 0xf4, 0xeb, 0x59, 0x0, 0x0, 0x0, 0x30, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x0, 0x3, 0xb6, 0x55, 0xab, 0x26, 0x30, 0x88, 0x30, 0x0, 0x91, 0x42, 0xd6, 0x4a, 0xe, 0x6, 0x45, 0x7, 0x46, 0xf, 0x6, 0x25, 0x6, 0x86, 0xe, 0x20, 0x31, 0x4a, 0x80, 0x42, 0x3, 0x1c, 0x2e, 0xe0, 0x10, 0x82, 0x84, 0x15, 0x1c, 0x0, 0x0, 0x41, 0x2d, 0x2b, 0x21, 0xbb, 0xb7, 0x1a, 0xa9, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char graph_node_selected_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x40, 0x8, 0x6, 0x0, 0x0, 0x0, 0x13, 0x7d, 0xf7, 0x96, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x8, 0x17, 0xd, 0x4, 0x3b, 0xfa, 0x91, 0x2a, 0xb6, 0x0, 0x0, 0x3, 0x44, 0x49, 0x44, 0x41, 0x54, 0x58, 0xc3, 0xed, 0x97, 0x3f, 0x68, 0xdc, 0x76, 0x14, 0xc7, 0xbf, 0xef, 0xa7, 0x9f, 0x7e, 0x3a, 0xdd, 0x39, 0xf6, 0xdd, 0x95, 0xb3, 0x3, 0xc1, 0x75, 0x1b, 0x70, 0xa, 0xe9, 0x98, 0x25, 0x93, 0x87, 0x52, 0x3a, 0x4, 0x2, 0xce, 0xe0, 0xd2, 0x34, 0x35, 0x94, 0x8e, 0x1d, 0xbc, 0xd5, 0x4b, 0xc7, 0x2e, 0x25, 0x63, 0x2, 0x5d, 0xa, 0xa5, 0xb1, 0x1b, 0x2, 0xf5, 0xd0, 0x40, 0xa0, 0x90, 0x10, 0x3a, 0x64, 0xca, 0x92, 0x31, 0x81, 0x24, 0xd0, 0xd2, 0x9a, 0x40, 0x2f, 0x17, 0xdf, 0x1f, 0xfb, 0x74, 0xf2, 0xe9, 0x27, 0xfd, 0x5e, 0x7, 0x49, 0xb6, 0x4e, 0xe7, 0xea, 0x86, 0x6e, 0xe5, 0x1e, 0xdc, 0x49, 0x42, 0xef, 0x7d, 0xde, 0xf7, 0x7d, 0xf5, 0x13, 0xe8, 0x47, 0xcc, 0x4c, 0x0, 0xc4, 0xbd, 0x7b, 0x4f, 0x9c, 0xb0, 0xdd, 0x71, 0xdb, 0xfb, 0x2d, 0xc7, 0xb0, 0x11, 0x5a, 0x7, 0x84, 0x4c, 0xd8, 0xb6, 0x62, 0x41, 0xc2, 0xd4, 0x67, 0x1b, 0x43, 0x59, 0xaf, 0xf9, 0x97, 0x2f, 0x5f, 0x18, 0x2, 0x30, 0xc4, 0xcc, 0xd6, 0xdd, 0x1f, 0xef, 0x9e, 0xea, 0x79, 0x83, 0x33, 0xed, 0x6e, 0xf7, 0x6c, 0xaf, 0xd7, 0x59, 0xe8, 0x7b, 0xfd, 0x72, 0x10, 0x4, 0x32, 0xb, 0x50, 0x4a, 0x85, 0x33, 0x95, 0x99, 0xc1, 0xdc, 0x5c, 0xad, 0x59, 0xaf, 0x56, 0x7f, 0x9f, 0xab, 0x94, 0x5f, 0xad, 0x7e, 0xbe, 0x7a, 0x40, 0x5b, 0x5b, 0xf7, 0x2b, 0x41, 0xbb, 0xf9, 0x6e, 0xa7, 0xd7, 0x5e, 0xb9, 0x72, 0x75, 0xe5, 0x86, 0x72, 0xa4, 0x85, 0x82, 0x8, 0x86, 0x61, 0xf4, 0xcb, 0x9d, 0x47, 0x1b, 0xb5, 0xb9, 0xfa, 0x23, 0x55, 0x5f, 0xf8, 0x43, 0xea, 0x4e, 0xb7, 0xdc, 0x7c, 0xf3, 0xfa, 0xdc, 0xc7, 0xeb, 0x1f, 0xdc, 0x64, 0x66, 0x71, 0xb8, 0x37, 0xbb, 0x2b, 0x1d, 0xb, 0x44, 0x23, 0x13, 0x80, 0x99, 0x11, 0xe, 0x23, 0x50, 0x65, 0x6f, 0x71, 0xf5, 0x93, 0x95, 0x9b, 0x3f, 0x6f, 0xff, 0xb6, 0x76, 0x9a, 0x9c, 0xa6, 0x8, 0x42, 0x5f, 0x79, 0xfd, 0x83, 0x79, 0xa7, 0x24, 0x5, 0xfc, 0xfa, 0x2e, 0x9, 0x42, 0xa8, 0xd, 0xc2, 0x20, 0x1a, 0xfd, 0x69, 0x3, 0x12, 0x4, 0xf8, 0xf5, 0x5d, 0xa7, 0x24, 0x85, 0xd7, 0x3f, 0x98, 0xf, 0x42, 0x5f, 0x9, 0xc3, 0x46, 0xc, 0xfc, 0x81, 0xb, 0x0, 0x91, 0x66, 0x30, 0x1b, 0x10, 0x0, 0x98, 0x6c, 0x7b, 0x80, 0xc0, 0x60, 0x66, 0x44, 0x21, 0x3, 0x0, 0x6, 0xfe, 0xc0, 0x35, 0x6c, 0x84, 0xd0, 0x5a, 0x53, 0x84, 0x88, 0x0, 0x80, 0x13, 0xd9, 0xcc, 0xc, 0x88, 0xb8, 0x10, 0x0, 0x40, 0x0, 0x1b, 0x0, 0xcc, 0x0, 0xc7, 0x39, 0x11, 0x22, 0xd2, 0x5a, 0x93, 0xb4, 0x6d, 0x9b, 0x11, 0x25, 0x89, 0x86, 0xc1, 0x20, 0x80, 0x18, 0xa0, 0xe3, 0xee, 0x47, 0xd0, 0xcc, 0x31, 0xad, 0x91, 0x79, 0xa3, 0x40, 0x4, 0x80, 0x91, 0xe6, 0xe5, 0x83, 0x73, 0x37, 0x64, 0xee, 0x2e, 0xd8, 0x24, 0x9, 0xc4, 0xc7, 0xa, 0xb2, 0x6a, 0x8a, 0x0, 0x1c, 0xf7, 0xce, 0x5e, 0xc4, 0xc5, 0xe6, 0x18, 0x92, 0x57, 0x36, 0x2, 0x30, 0x26, 0x33, 0x7b, 0xe2, 0x1e, 0x71, 0xe2, 0xb, 0x33, 0x68, 0xf2, 0x8, 0xd9, 0x16, 0x94, 0xd1, 0x13, 0xff, 0x9b, 0x49, 0xa, 0xc0, 0x6, 0x6c, 0x72, 0xf6, 0x8f, 0xbb, 0x58, 0xe0, 0x41, 0x32, 0x77, 0x22, 0x1a, 0xc9, 0xf2, 0x49, 0x87, 0x89, 0xcf, 0x8a, 0x14, 0xc4, 0x0, 0x93, 0x14, 0x66, 0xba, 0xd1, 0xf1, 0xec, 0xa6, 0x18, 0x60, 0xe2, 0xfa, 0x91, 0xde, 0xd9, 0xae, 0x34, 0xf9, 0x31, 0x52, 0xba, 0x1e, 0x28, 0x5d, 0x4c, 0x94, 0xfa, 0x99, 0xbc, 0xf, 0x45, 0xa, 0x4c, 0x5c, 0x38, 0xd6, 0xc9, 0xe0, 0xe8, 0x89, 0xe4, 0xad, 0x1d, 0x5f, 0xca, 0x9c, 0x7f, 0x15, 0x8b, 0x63, 0xdc, 0xc4, 0x7c, 0x8f, 0x8c, 0x91, 0xb9, 0x93, 0x71, 0xc0, 0xd7, 0xdf, 0x7c, 0xf5, 0xea, 0xd9, 0x8b, 0xa7, 0x85, 0x1d, 0xcf, 0x9f, 0x7b, 0x1f, 0xdf, 0xdf, 0xfa, 0x76, 0xf1, 0x44, 0xc0, 0xd9, 0xa5, 0x65, 0x58, 0xc2, 0x2e, 0x4, 0x2c, 0x2d, 0xbe, 0xf3, 0xef, 0xa, 0x3c, 0xaf, 0x8f, 0xde, 0x7e, 0xb7, 0x10, 0xe0, 0x79, 0xfd, 0x91, 0x6b, 0x81, 0xff, 0x18, 0x53, 0xc0, 0x14, 0x30, 0x5, 0x4c, 0x1, 0x53, 0xc0, 0x14, 0x30, 0x5, 0xfc, 0xff, 0x0, 0x5a, 0x6b, 0x82, 0x75, 0xe2, 0xe7, 0xcf, 0xc9, 0x91, 0xe6, 0x58, 0x19, 0x5, 0x16, 0x2c, 0x6, 0x0, 0x5b, 0xca, 0x89, 0xf5, 0x69, 0x4e, 0x5a, 0x23, 0x1c, 0xe5, 0x44, 0x8e, 0x52, 0x1, 0x0, 0x94, 0xdd, 0x99, 0x89, 0x80, 0x34, 0xc7, 0x51, 0x2a, 0x70, 0x94, 0x13, 0x49, 0x25, 0xdd, 0xa0, 0xe4, 0x96, 0x5b, 0xc3, 0x43, 0xcd, 0x1b, 0x9b, 0x9f, 0x5e, 0xbc, 0x71, 0x9d, 0x1e, 0xf, 0xfc, 0x3, 0xe8, 0x30, 0x1c, 0xd9, 0x74, 0xd9, 0x52, 0xa2, 0xec, 0x9e, 0xc2, 0xc6, 0xe6, 0xd5, 0x8b, 0xc3, 0x43, 0xcd, 0x25, 0xb7, 0xdc, 0x52, 0xd2, 0xd, 0x68, 0x6b, 0xeb, 0x7e, 0x65, 0xef, 0xaf, 0x97, 0xcb, 0xdd, 0xfd, 0xce, 0x87, 0x9f, 0x7d, 0x71, 0xe9, 0xba, 0xe3, 0xda, 0x85, 0x4e, 0xc, 0x7d, 0xcd, 0x3f, 0xfd, 0xf0, 0xeb, 0x66, 0x75, 0xb6, 0xf6, 0xf0, 0xad, 0xb7, 0x97, 0x5f, 0x12, 0x33, 0x5b, 0xb7, 0xbf, 0xbb, 0x3d, 0xdb, 0xea, 0x74, 0x97, 0x3a, 0xdd, 0xee, 0x7b, 0x3, 0xdf, 0x9b, 0xd7, 0x5a, 0xdb, 0xc6, 0x8c, 0x7e, 0xad, 0xa, 0x21, 0x60, 0xdb, 0xb6, 0x2e, 0xbb, 0x95, 0xd7, 0xb5, 0x6a, 0xf5, 0x79, 0xa3, 0x56, 0xfd, 0xf3, 0xda, 0x97, 0xd7, 0xf6, 0x29, 0xdd, 0xbd, 0x6f, 0x6f, 0x3f, 0x28, 0xf5, 0xff, 0x6e, 0x56, 0xb4, 0x19, 0x2a, 0x66, 0x73, 0xe2, 0xe3, 0x25, 0x12, 0xc6, 0x16, 0x4e, 0x30, 0x73, 0x7a, 0xc1, 0x5b, 0x5f, 0xff, 0xe8, 0x10, 0xc0, 0xd1, 0xf6, 0x4, 0xcc, 0x4c, 0x3b, 0x3b, 0x3b, 0xa2, 0xd1, 0x68, 0x14, 0x8e, 0xd0, 0x6a, 0xb5, 0x78, 0x6d, 0x6d, 0xcd, 0x10, 0xc5, 0xdb, 0xba, 0x7f, 0x0, 0xb2, 0x1f, 0xaf, 0x82, 0x62, 0x7a, 0x69, 0xbb, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x40, 0x8, 0x3, 0x0, 0x0, 0x0, 0x24, 0xa3, 0x7, 0xa4, 0x0, 0x0, 0x1, 0x5f, 0x50, 0x4c, 0x54, 0x45, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb2, 0xb2, 0xcc, 0xae, 0xa0, 0xbb, 0x9c, 0x92, 0xa6, 0x9a, 0x91, 0xa4, 0x95, 0x8c, 0x9e, 0xaf, 0x9f, 0xaf, 0xa0, 0x94, 0xa5, 0x8e, 0x84, 0x95, 0x7f, 0x75, 0x84, 0x73, 0x6a, 0x78, 0x6d, 0x64, 0x72, 0xa2, 0xa2, 0xb9, 0x9c, 0x90, 0xa2, 0x8b, 0x81, 0x90, 0xdc, 0xda, 0xce, 0xe2, 0xe1, 0xd2, 0x9d, 0x91, 0xa9, 0x85, 0x7c, 0x8c, 0xdb, 0xd9, 0xce, 0xdb, 0xd9, 0xcd, 0xda, 0xce, 0xe0, 0xde, 0xd5, 0xe3, 0xdf, 0xd6, 0xe4, 0x97, 0x8d, 0xa0, 0x7a, 0x70, 0x7f, 0xdb, 0xd0, 0xdf, 0xdb, 0xd0, 0xe1, 0xda, 0xd0, 0xe1, 0x70, 0x67, 0x75, 0xd8, 0xcb, 0xde, 0xda, 0xcf, 0xdf, 0xdb, 0xce, 0xe1, 0xdb, 0xcf, 0xe1, 0xdb, 0xd0, 0xe0, 0xda, 0xcf, 0xe0, 0xd8, 0xcc, 0xde, 0x90, 0x87, 0x99, 0x6d, 0x67, 0x72, 0xd7, 0xcc, 0xdf, 0xda, 0xce, 0xdf, 0xd8, 0xcb, 0xdf, 0xd7, 0xca, 0xde, 0xd9, 0xcc, 0xdf, 0xd9, 0xcd, 0xdf, 0xd6, 0xc9, 0xdd, 0xd9, 0xcd, 0xde, 0xd6, 0xc8, 0xdc, 0xd5, 0xc8, 0xdc, 0xd7, 0xcb, 0xdd, 0xd7, 0xca, 0xdd, 0xd5, 0xc7, 0xdc, 0xd3, 0xc6, 0xdb, 0xd5, 0xc9, 0xdc, 0xd5, 0xc9, 0xdd, 0xd6, 0xc9, 0xdc, 0xd4, 0xc6, 0xdb, 0xd3, 0xc5, 0xdb, 0xd5, 0xc8, 0xdb, 0xd4, 0xc8, 0xdc, 0xd3, 0xc4, 0xd9, 0xd4, 0xc6, 0xda, 0xd2, 0xc3, 0xd9, 0xd3, 0xc5, 0xda, 0xd2, 0xc5, 0xd9, 0xd3, 0xc5, 0xd9, 0xd2, 0xc5, 0xda, 0xd1, 0xc2, 0xd9, 0xd2, 0xc4, 0xd8, 0xd2, 0xc4, 0xd9, 0xd0, 0xc2, 0xd9, 0xd0, 0xc1, 0xd7, 0xd0, 0xc2, 0xd7, 0xd0, 0xc2, 0xd8, 0xd1, 0xc2, 0xd7, 0xcf, 0xc1, 0xd7, 0xd0, 0xc2, 0xd6, 0xcf, 0xc1, 0xd6, 0xcf, 0xc2, 0xd7, 0xcf, 0xc0, 0xd7, 0xce, 0xbf, 0xd6, 0xce, 0xc0, 0xd5, 0xce, 0xc0, 0xd6, 0xce, 0xbf, 0xd5, 0xcd, 0xbf, 0xd5, 0xcd, 0xbe, 0xd5, 0xcd, 0xbe, 0xd4, 0xcc, 0xbd, 0xd5, 0xcc, 0xbd, 0xd4, 0xcc, 0xbc, 0xd4, 0x47, 0x40, 0x4a, 0x1d, 0x1a, 0x1f, 0x69, 0x5f, 0x6f, 0x4a, 0x42, 0x4f, 0x5e, 0x54, 0x63, 0x3b, 0x34, 0x3f, 0x5e, 0x55, 0x63, 0x63, 0x59, 0x67, 0x77, 0x6d, 0x7b, 0x6d, 0x62, 0x73, 0x7f, 0x76, 0x85, 0xdb, 0xd9, 0xcd, 0xdb, 0xd8, 0xcd, 0x6d, 0x62, 0x74, 0x8f, 0x84, 0x94, 0x7f, 0x76, 0x83, 0xdb, 0xd8, 0xcd, 0xa4, 0x95, 0xa4, 0x7e, 0x74, 0x84, 0x74, 0x6b, 0x79, 0x6f, 0x66, 0x74, 0x96, 0x8a, 0xa2, 0x91, 0x88, 0x9b, 0x0, 0x0, 0x0, 0xaa, 0xaa, 0xaa, 0xbf, 0xbf, 0xbf, 0xf0, 0xc9, 0xec, 0x71, 0x0, 0x0, 0x0, 0x75, 0x74, 0x52, 0x4e, 0x53, 0x1, 0x3, 0xa, 0x13, 0x1a, 0x1c, 0x1d, 0x10, 0x2b, 0x4d, 0x64, 0x6e, 0x72, 0xb, 0x2c, 0x6a, 0xfc, 0xff, 0x15, 0x52, 0xfd, 0xff, 0xe2, 0xe2, 0xe2, 0x1b, 0x68, 0xe2, 0xe2, 0xe2, 0x71, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0x1e, 0x72, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0x6b, 0xc7, 0x56, 0xfe, 0xff, 0xc7, 0x30, 0x74, 0xfe, 0x11, 0x57, 0x6d, 0x72, 0x16, 0x1c, 0x0, 0x3, 0x4, 0x35, 0xf5, 0x4, 0x26, 0x0, 0x0, 0x1, 0x1f, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0xec, 0xd0, 0x35, 0x82, 0x1c, 0x31, 0x14, 0x84, 0xe1, 0xbf, 0xa4, 0xd7, 0x32, 0x33, 0xb3, 0xf, 0x63, 0x8e, 0xcd, 0x10, 0xcd, 0x99, 0x1c, 0x3a, 0x75, 0xe8, 0xcc, 0xbe, 0x8e, 0x99, 0x79, 0xb9, 0x49, 0x6f, 0x49, 0xd3, 0xcb, 0x7b, 0x82, 0xa9, 0xac, 0x3e, 0xb1, 0xc, 0xad, 0x4, 0xf0, 0x95, 0x98, 0xd2, 0x6, 0x68, 0xec, 0x60, 0xa9, 0xac, 0x52, 0xb2, 0x6a, 0xf3, 0x92, 0x3d, 0x9a, 0xdf, 0x2f, 0x39, 0x20, 0xf7, 0xb9, 0x7d, 0x6e, 0xbf, 0xcf, 0x62, 0xea, 0xaa, 0x96, 0x24, 0x69, 0xce, 0xbe, 0xd9, 0x55, 0x4d, 0xef, 0x5b, 0xd8, 0xbb, 0x90, 0x9a, 0xa6, 0x39, 0x21, 0xf6, 0x5d, 0xb5, 0x77, 0xa9, 0x8a, 0x7, 0x35, 0xd5, 0xc0, 0x19, 0x32, 0x9f, 0xcf, 0x1b, 0x10, 0x3d, 0x9c, 0x1, 0x20, 0x2, 0x6, 0x84, 0xbf, 0x24, 0x9a, 0x44, 0x73, 0xac, 0x80, 0x4e, 0x80, 0x5c, 0x4e, 0x28, 0x60, 0x2, 0xc9, 0x3d, 0xa8, 0x40, 0x25, 0xe6, 0x0, 0xe, 0xe4, 0x2, 0x51, 0x1c, 0x2, 0x40, 0x5, 0x82, 0xa4, 0x2c, 0x3c, 0x76, 0xc3, 0x12, 0x51, 0xfb, 0x9e, 0xba, 0xdb, 0x3b, 0x6c, 0x2a, 0x45, 0xd8, 0xaf, 0x3c, 0x86, 0x3e, 0x57, 0x31, 0xc7, 0x7e, 0x98, 0x51, 0x25, 0x39, 0xca, 0x15, 0x1a, 0x3, 0x2, 0x8f, 0xc0, 0x70, 0xa, 0x20, 0x1c, 0x2f, 0x10, 0x87, 0x2f, 0x1c, 0x66, 0xec, 0xe, 0x1b, 0x33, 0x81, 0xd, 0x99, 0xc0, 0x55, 0xfd, 0x8, 0x5e, 0x4a, 0xe0, 0x82, 0x1b, 0xf3, 0x68, 0xc, 0x62, 0x7e, 0xaf, 0x4d, 0xdf, 0x79, 0x15, 0xf2, 0x30, 0xe3, 0xfa, 0x1b, 0xab, 0xc3, 0x3d, 0x59, 0xe3, 0x99, 0xa0, 0xe4, 0xf7, 0xbc, 0xb6, 0xd6, 0xa4, 0x97, 0x65, 0xc6, 0x63, 0xf7, 0xd6, 0x66, 0x62, 0x1f, 0x9f, 0xe9, 0x5, 0x30, 0x72, 0xef, 0xe2, 0x8c, 0xf9, 0xf3, 0x83, 0x23, 0xbd, 0x3e, 0xf, 0x2c, 0x6e, 0xbb, 0xf7, 0xff, 0x5, 0x5f, 0xfe, 0xb3, 0x14, 0x31, 0xf4, 0x31, 0x33, 0xfa, 0x41, 0xd3, 0xe9, 0xe7, 0x22, 0x6, 0x0, 0xb4, 0xb3, 0x74, 0xef, 0x4f, 0xde, 0x59, 0x95, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char graph_port_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0xa, 0x8, 0x6, 0x0, 0x0, 0x0, 0x8d, 0x32, 0xcf, 0xbd, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0xc6, 0x49, 0x44, 0x41, 0x54, 0x18, 0x95, 0x6d, 0x90, 0x3d, 0x4e, 0xc4, 0x30, 0x14, 0x84, 0xbf, 0xb1, 0xa8, 0x92, 0x48, 0x39, 0x46, 0xe2, 0x9a, 0x9f, 0x12, 0xc1, 0xbd, 0x16, 0x25, 0x4b, 0x41, 0xb, 0x67, 0xa1, 0xa7, 0xa2, 0x63, 0xa1, 0x76, 0x94, 0x5b, 0x58, 0x72, 0x52, 0x3e, 0xd3, 0xc4, 0x11, 0xda, 0xe5, 0xab, 0x46, 0xa3, 0xd1, 0x68, 0xde, 0x13, 0x1b, 0x21, 0x84, 0x7, 0x49, 0x3, 0x70, 0xbb, 0x59, 0x5f, 0xc0, 0x5b, 0xdf, 0xf7, 0xef, 0x0, 0x2, 0x98, 0xa6, 0xe9, 0x0, 0x1c, 0x1, 0xc7, 0x19, 0x39, 0xe7, 0x67, 0xef, 0xfd, 0xa0, 0xad, 0xe9, 0x3, 0x70, 0x6d, 0xdb, 0x52, 0xd7, 0x35, 0x0, 0xcb, 0xb2, 0x10, 0x63, 0x4, 0x30, 0xe7, 0xdc, 0xe3, 0x95, 0xa4, 0xb1, 0x84, 0x9a, 0xa6, 0xd9, 0x9b, 0x8a, 0x8e, 0x31, 0x3a, 0x33, 0x1b, 0x1d, 0x70, 0xd, 0xec, 0x4d, 0x7f, 0xa9, 0xaa, 0xaa, 0xc8, 0x1b, 0x7, 0xe4, 0x8b, 0xc4, 0x25, 0xd9, 0x1, 0x3f, 0x65, 0xd3, 0x39, 0xeb, 0xba, 0x16, 0xf9, 0xed, 0x80, 0xd7, 0x6d, 0xb, 0x29, 0x25, 0xcc, 0xc, 0x33, 0x23, 0xa5, 0xb4, 0x1f, 0x23, 0x69, 0x14, 0x40, 0x8, 0xe1, 0x28, 0xe9, 0xf0, 0xcf, 0x7b, 0x2c, 0xe7, 0xfc, 0xe4, 0xbd, 0x7f, 0x51, 0x71, 0xe6, 0x79, 0xbe, 0x37, 0xb3, 0x1, 0xb8, 0xdb, 0x76, 0x9f, 0x24, 0x8d, 0x5d, 0xd7, 0x7d, 0x2, 0xfc, 0x2, 0xfb, 0x83, 0x50, 0x87, 0x89, 0x31, 0xee, 0x78, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0xa, 0x8, 0x4, 0x0, 0x0, 0x0, 0x27, 0x3b, 0x7, 0x36, 0x0, 0x0, 0x0, 0x72, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x65, 0xce, 0x41, 0xa, 0x83, 0x30, 0x10, 0x85, 0xe1, 0xb9, 0x98, 0xe2, 0x9, 0x3c, 0x50, 0xe9, 0xc6, 0x83, 0x45, 0x7b, 0x8b, 0xfc, 0x7a, 0x1, 0xd7, 0x49, 0xba, 0xd, 0xd3, 0x79, 0xd0, 0x16, 0x41, 0xfe, 0x6c, 0xe6, 0x83, 0xc0, 0x33, 0x8f, 0xf2, 0xc4, 0xc6, 0x3b, 0x5a, 0x99, 0x75, 0xc7, 0xe3, 0x49, 0xc7, 0x7f, 0xe5, 0x25, 0x30, 0x4f, 0xa2, 0xd3, 0x6b, 0x74, 0x8a, 0xfb, 0x31, 0x1a, 0x2f, 0x51, 0xfb, 0x26, 0x66, 0x35, 0x1a, 0x5e, 0xff, 0x58, 0x84, 0xd5, 0xa8, 0x37, 0x2c, 0xc6, 0x76, 0xfb, 0x9e, 0x8c, 0x19, 0x17, 0x97, 0x48, 0x44, 0xdf, 0x7, 0xad, 0x5c, 0x2e, 0x93, 0x7a, 0x7e, 0x68, 0x67, 0x74, 0x8c, 0x24, 0x1a, 0x95, 0xb4, 0xf, 0xba, 0x3f, 0x56, 0x94, 0xa6, 0x72, 0xc9, 0xf9, 0xda, 0xf8, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char hseparator_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x2, 0x3, 0x0, 0x0, 0x0, 0xb9, 0x61, 0x56, 0x18, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0xc, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x73, 0x9b, 0xaa, 0xce, 0xdc, 0xe1, 0xff, 0xff, 0xff, 0x64, 0x6c, 0x1, 0xd2, 0x0, 0x0, 0x0, 0x3, 0x74, 0x52, 0x4e, 0x53, 0x0, 0xb3, 0xb3, 0x67, 0xf6, 0xdb, 0x93, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x3, 0x11, 0xc, 0x4c, 0xf2, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x10, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0x64, 0x60, 0x60, 0xc2, 0x40, 0x8c, 0xc, 0x0, 0x0, 0xc7, 0x0, 0xf, 0xf5, 0x92, 0x2f, 0xa7, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x2, 0x3, 0x0, 0x0, 0x0, 0xb9, 0x61, 0x56, 0x18, 0x0, 0x0, 0x0, 0xc, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x73, 0x9b, 0xaa, 0xce, 0xdc, 0xe1, 0xff, 0xff, 0xff, 0x64, 0x6c, 0x1, 0xd2, 0x0, 0x0, 0x0, 0x3, 0x74, 0x52, 0x4e, 0x53, 0x0, 0xb3, 0xb3, 0x67, 0xf6, 0xdb, 0x93, 0x0, 0x0, 0x0, 0x10, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0x64, 0x60, 0x60, 0xc2, 0x40, 0x8c, 0xc, 0x0, 0x0, 0xc7, 0x0, 0xf, 0xf5, 0x92, 0x2f, 0xa7, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char hslider_bg_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x4e, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x40, 0x3e, 0x4a, 0x2a, 0x29, 0x2f, 0x20, 0x20, 0x24, 0x3f, 0x3e, 0x49, 0x1f, 0x1f, 0x24, 0x20, 0x20, 0x24, 0x4d, 0x4b, 0x59, 0x3f, 0x3e, 0x49, 0x3f, 0x3e, 0x49, 0x1e, 0x1e, 0x23, 0x1f, 0x1f, 0x23, 0x20, 0x20, 0x25, 0x22, 0x22, 0x27, 0x23, 0x23, 0x27, 0x23, 0x23, 0x28, 0x25, 0x25, 0x2a, 0xff, 0xff, 0xff, 0x5f, 0xd6, 0x94, 0x4d, 0x0, 0x0, 0x0, 0x12, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x0, 0x4, 0x19, 0x40, 0x5d, 0x66, 0x68, 0x28, 0x93, 0xf0, 0xfc, 0x94, 0xfc, 0xfd, 0x1a, 0x96, 0x95, 0x6b, 0xe2, 0xd5, 0x49, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x19, 0xec, 0x6e, 0xb5, 0x88, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x65, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x85, 0xce, 0xdd, 0xe, 0x80, 0x20, 0x8, 0x5, 0x60, 0x54, 0xb4, 0x22, 0xb5, 0x34, 0x7f, 0x7a, 0xff, 0x27, 0x8d, 0xad, 0xd6, 0x6a, 0x5c, 0xf8, 0xdd, 0xc1, 0x6, 0xe7, 0x0, 0x8c, 0xa9, 0x1f, 0x9e, 0xb5, 0x41, 0xeb, 0x26, 0xe6, 0x2c, 0x1a, 0xad, 0x40, 0xcf, 0xb, 0xad, 0xf9, 0x60, 0x79, 0xa5, 0x65, 0xd6, 0x60, 0x7c, 0x28, 0xb5, 0x75, 0xd6, 0x6a, 0x9, 0xde, 0x0, 0x52, 0xe9, 0xe7, 0xa3, 0x17, 0x42, 0xb0, 0xb1, 0x9e, 0xaf, 0x1a, 0xad, 0x5c, 0x88, 0x93, 0x6d, 0xff, 0x3e, 0xdd, 0x37, 0x8e, 0x4d, 0x14, 0xef, 0xd8, 0x48, 0x89, 0x63, 0x45, 0x31, 0x51, 0x7d, 0xe8, 0x2, 0xf5, 0xf, 0x9, 0x67, 0xd9, 0x88, 0x8f, 0x5b, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x4b, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x40, 0x3e, 0x4a, 0x2a, 0x29, 0x2f, 0x20, 0x20, 0x24, 0x3f, 0x3e, 0x49, 0x1f, 0x1f, 0x24, 0x20, 0x20, 0x24, 0x4d, 0x4b, 0x59, 0x3f, 0x3e, 0x49, 0x3f, 0x3e, 0x49, 0x1e, 0x1e, 0x23, 0x1f, 0x1f, 0x23, 0x20, 0x20, 0x25, 0x22, 0x22, 0x27, 0x23, 0x23, 0x27, 0x23, 0x23, 0x28, 0x25, 0x25, 0x2a, 0x57, 0x2e, 0xcb, 0x70, 0x0, 0x0, 0x0, 0x12, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x0, 0x4, 0x19, 0x40, 0x5d, 0x66, 0x68, 0x28, 0x93, 0xf0, 0xfc, 0x94, 0xfc, 0xfd, 0x1a, 0x96, 0x95, 0x6b, 0xe2, 0xd5, 0x49, 0x0, 0x0, 0x0, 0x59, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x85, 0x4f, 0x83, 0x11, 0x3, 0x1, 0x10, 0xcc, 0x39, 0xef, 0xfe, 0xb, 0x7d, 0xdb, 0xc6, 0x8e, 0x8e, 0xb, 0xf8, 0x9d, 0x70, 0x1d, 0x9c, 0x46, 0x2d, 0xcc, 0x18, 0xea, 0x11, 0x80, 0xda, 0xb7, 0x36, 0xe, 0xf2, 0xbe, 0x2f, 0x80, 0x1c, 0xb0, 0xe5, 0xa2, 0x1f, 0xa5, 0xc0, 0xea, 0x12, 0x2c, 0x4, 0x75, 0x52, 0x80, 0x38, 0x46, 0x2b, 0x65, 0x9d, 0xa7, 0x97, 0xc1, 0xf5, 0x25, 0x82, 0x7a, 0x47, 0x4a, 0x83, 0xac, 0x93, 0x33, 0x8f, 0x83, 0xaa, 0xb2, 0xb4, 0xb8, 0x18, 0xbb, 0x58, 0xff, 0x4e, 0xdb, 0x1, 0xc3, 0xf1, 0x34, 0x3b, 0x7e, 0xbc, 0xb3, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char hslider_grabber_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x2, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x87, 0x8f, 0xcc, 0xbf, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x1, 0x1d, 0x49, 0x44, 0x41, 0x54, 0x28, 0xcf, 0x85, 0xd1, 0x3f, 0x4b, 0xc3, 0x40, 0x18, 0xc7, 0xf1, 0xef, 0x25, 0xad, 0x89, 0xa9, 0x70, 0x83, 0x43, 0x5d, 0xc4, 0x21, 0x6e, 0x4a, 0x7, 0x47, 0xdf, 0x83, 0x53, 0x16, 0x17, 0xd7, 0x4e, 0xbe, 0x2, 0x5f, 0x85, 0x83, 0xa0, 0xb8, 0x38, 0xb8, 0x88, 0xd0, 0x51, 0x5d, 0x1c, 0x1c, 0x1c, 0x1c, 0x2a, 0xa2, 0xe8, 0x22, 0x2d, 0x82, 0x2d, 0x88, 0x54, 0xed, 0x3f, 0x1b, 0x9a, 0x78, 0x49, 0x1c, 0x9a, 0x54, 0x4f, 0x5, 0x6f, 0x3a, 0xee, 0xf9, 0xf0, 0x3c, 0x3f, 0x9e, 0x83, 0x7f, 0x8e, 0x18, 0xdf, 0x4c, 0x1c, 0x24, 0x5, 0x60, 0x40, 0x17, 0x9f, 0x48, 0x7, 0x26, 0xd3, 0xe5, 0x55, 0xd7, 0x93, 0x25, 0xe8, 0xde, 0xd4, 0x2b, 0xbb, 0x7, 0xbc, 0x8e, 0x88, 0x99, 0x82, 0xa9, 0xf2, 0xda, 0xe2, 0x86, 0x58, 0x78, 0xb7, 0x87, 0xf6, 0xc4, 0xdc, 0xcc, 0xd2, 0x6c, 0xfb, 0xf2, 0x8e, 0x10, 0xc0, 0x48, 0x81, 0x74, 0x3d, 0x55, 0xf4, 0x51, 0x28, 0x7c, 0x54, 0xd1, 0xf5, 0x90, 0xa3, 0x42, 0x6, 0xa, 0xb2, 0x14, 0x90, 0x0, 0x90, 0x10, 0x20, 0x4b, 0x14, 0x74, 0x20, 0x62, 0xf1, 0x3d, 0x7b, 0x24, 0xb2, 0x74, 0x19, 0x8, 0x83, 0x96, 0x39, 0x2e, 0xb, 0x82, 0x37, 0x94, 0xe, 0x6, 0xbd, 0xdb, 0xfc, 0x18, 0xe4, 0x49, 0x9e, 0xf0, 0x75, 0xd0, 0xbf, 0x3e, 0xb6, 0x22, 0x23, 0x7d, 0x9a, 0x4c, 0xce, 0xf6, 0xe8, 0xe9, 0x20, 0xb8, 0xaa, 0x6, 0xcd, 0x1c, 0x0, 0x39, 0x3e, 0x1e, 0x4f, 0xce, 0x7f, 0x76, 0x88, 0x1f, 0x1a, 0xcf, 0xa7, 0xe, 0x6, 0x6, 0xe, 0x8d, 0x23, 0xd5, 0x22, 0xd6, 0x41, 0x42, 0x77, 0x6b, 0x33, 0xaa, 0x59, 0x58, 0xc4, 0xf5, 0x9d, 0xed, 0x6c, 0xc0, 0xd7, 0x26, 0x21, 0xe, 0x7, 0x9d, 0xda, 0xf2, 0x8a, 0x1d, 0x1f, 0xae, 0xdf, 0x57, 0x19, 0xfe, 0x6, 0xa0, 0x9a, 0x2f, 0xf3, 0xed, 0xfe, 0xc5, 0x7e, 0x85, 0xce, 0x5f, 0xbf, 0x39, 0xca, 0x67, 0x21, 0x18, 0x66, 0x3b, 0x0, 0xf8, 0x4, 0x7e, 0x5c, 0x62, 0x33, 0x51, 0xf0, 0xbb, 0xff, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0xf3, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x20, 0x1e, 0x30, 0x33, 0xf0, 0x32, 0xc8, 0x30, 0xa8, 0x3, 0xa1, 0xc, 0x90, 0xc5, 0x8c, 0x29, 0x2d, 0x96, 0x96, 0xd7, 0x79, 0x70, 0xc6, 0xfb, 0x19, 0xef, 0x3b, 0xf, 0xa6, 0xe5, 0x31, 0x88, 0xa1, 0x2b, 0xe1, 0x4d, 0xcb, 0x9b, 0xf4, 0xa2, 0xef, 0x7f, 0x3b, 0x10, 0xf6, 0xfd, 0x9f, 0xf4, 0x2, 0xa8, 0x84, 0x17, 0x55, 0x81, 0x4c, 0xe7, 0xc1, 0xbe, 0xff, 0x2d, 0xff, 0x9b, 0x81, 0xb0, 0x5, 0xa8, 0xa4, 0xf3, 0x20, 0xd0, 0x22, 0x14, 0xa0, 0x3e, 0xe3, 0x7d, 0x3b, 0x50, 0x12, 0xc, 0x81, 0xa6, 0xcc, 0x78, 0xf, 0x74, 0xb, 0xa, 0xd0, 0x98, 0xf6, 0x1, 0x59, 0xc1, 0xd4, 0xf, 0xc, 0x1a, 0xa8, 0xa, 0x94, 0xfa, 0x6f, 0x77, 0xc1, 0x15, 0x74, 0xfc, 0xef, 0xbb, 0xc7, 0xa0, 0x82, 0xaa, 0x40, 0xbc, 0x71, 0x7d, 0x3f, 0x5c, 0x41, 0xef, 0xff, 0xde, 0xa3, 0xc, 0x52, 0xa8, 0xa, 0xb8, 0x82, 0x52, 0xa7, 0xfd, 0x69, 0x5, 0x4b, 0xb7, 0xfe, 0x9f, 0xf6, 0xcf, 0x37, 0x85, 0x81, 0x7, 0x2d, 0x1c, 0x14, 0xd, 0xfb, 0x1f, 0x74, 0x82, 0x15, 0x74, 0xfe, 0x9f, 0xf8, 0x80, 0x45, 0x83, 0x81, 0x9, 0x55, 0x1, 0x23, 0x83, 0x48, 0xc5, 0x9c, 0xc9, 0xff, 0x5b, 0x81, 0x70, 0xf2, 0xff, 0x92, 0xa9, 0xc, 0xc2, 0x98, 0x41, 0xcd, 0xca, 0xa3, 0x33, 0xe1, 0x76, 0xcf, 0xff, 0x9e, 0xff, 0x13, 0xef, 0xf0, 0xe8, 0x30, 0xb0, 0x62, 0x8b, 0xd, 0x6e, 0xb, 0xff, 0x39, 0x5f, 0xe6, 0x7c, 0x77, 0x8, 0x45, 0xd8, 0x8f, 0x61, 0x4d, 0x51, 0x71, 0x55, 0x2d, 0x83, 0x18, 0x90, 0x85, 0x3, 0xb0, 0x30, 0x70, 0x3, 0x75, 0xb3, 0x20, 0xb, 0x1, 0x0, 0x86, 0xe, 0x79, 0x54, 0x16, 0xbe, 0x69, 0xf5, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char hslider_grabber_disabled_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x2, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x87, 0x8f, 0xcc, 0xbf, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe1, 0x7, 0xa, 0x13, 0x2f, 0x7, 0x5e, 0x49, 0xee, 0x14, 0x0, 0x0, 0x0, 0x1d, 0x69, 0x54, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x0, 0x0, 0x0, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x64, 0x2e, 0x65, 0x7, 0x0, 0x0, 0x0, 0xea, 0x49, 0x44, 0x41, 0x54, 0x28, 0xcf, 0x63, 0x60, 0x20, 0x1a, 0x30, 0x33, 0xf0, 0x32, 0xc8, 0x30, 0xa8, 0x3, 0xa1, 0xc, 0x90, 0xc5, 0x8c, 0x29, 0x2d, 0x66, 0x9c, 0xe7, 0x7a, 0xd0, 0xe7, 0xbd, 0xcf, 0x7b, 0xd7, 0x83, 0xc6, 0x79, 0xc, 0x62, 0xe8, 0x4a, 0x78, 0x8d, 0xf3, 0x3c, 0x5f, 0xb8, 0xff, 0x77, 0x1, 0x42, 0xf7, 0xff, 0x9e, 0x2f, 0x80, 0x4a, 0x78, 0x51, 0x15, 0xc8, 0xb8, 0x1e, 0x74, 0xff, 0xef, 0x4, 0x85, 0xee, 0xff, 0x5d, 0xf, 0x2, 0x2d, 0x42, 0x1, 0xea, 0x3e, 0xef, 0x5d, 0xe0, 0xa, 0x5c, 0xfe, 0xfb, 0xbc, 0x7, 0xba, 0x5, 0x5, 0x68, 0x78, 0x7f, 0x40, 0x56, 0xe0, 0xfd, 0x81, 0x41, 0x3, 0x55, 0x81, 0x92, 0xc7, 0x6d, 0x57, 0x24, 0x5, 0xee, 0xf7, 0x18, 0x54, 0x50, 0x15, 0x88, 0x3b, 0xae, 0xf7, 0x40, 0x72, 0x83, 0xfb, 0x51, 0x6, 0x29, 0x54, 0x5, 0x5c, 0x9a, 0xa9, 0xde, 0x7f, 0x9c, 0xc1, 0xd2, 0xce, 0xff, 0xbd, 0xff, 0xa9, 0xa7, 0x30, 0xf0, 0xa0, 0x85, 0x83, 0xa0, 0xa1, 0xc7, 0x3, 0x88, 0x25, 0xae, 0xff, 0x3d, 0x1f, 0x30, 0x69, 0x30, 0x30, 0xa1, 0x2a, 0x60, 0x64, 0x10, 0xb1, 0x99, 0xe3, 0x5, 0xd4, 0xed, 0xfc, 0xdf, 0xeb, 0xbf, 0xd5, 0x54, 0x6, 0x61, 0xcc, 0xa0, 0x66, 0x65, 0xd3, 0xf1, 0xb8, 0xed, 0xf6, 0xdf, 0xed, 0xbf, 0xe7, 0x1d, 0x36, 0x1d, 0x6, 0x56, 0x6c, 0xb1, 0xc1, 0x2d, 0xe3, 0xef, 0xf7, 0xc5, 0xef, 0xbb, 0x42, 0x28, 0xba, 0xfd, 0x48, 0xd6, 0x58, 0x16, 0xdb, 0xd6, 0x2, 0xe3, 0x81, 0x11, 0x57, 0x8c, 0xb2, 0x30, 0x70, 0x3, 0x75, 0xb3, 0x20, 0xb, 0x1, 0x0, 0x4, 0x5c, 0x63, 0x9b, 0x17, 0x86, 0x76, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0xe7, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x20, 0x1e, 0x30, 0x33, 0xf0, 0x32, 0xc8, 0x30, 0xa8, 0x3, 0xa1, 0xc, 0x90, 0xc5, 0x8c, 0x29, 0x2d, 0x66, 0x9c, 0xe7, 0x7a, 0xd0, 0xe7, 0xbd, 0xcf, 0x7b, 0xd7, 0x83, 0xc6, 0x79, 0xc, 0x62, 0xe8, 0x4a, 0x78, 0x8d, 0xf3, 0x3c, 0x5f, 0xb8, 0xff, 0x77, 0x1, 0x42, 0xf7, 0xff, 0x9e, 0x2f, 0x80, 0x4a, 0x78, 0x51, 0x15, 0xc8, 0xb8, 0x1e, 0x74, 0xff, 0xef, 0x4, 0x81, 0x40, 0x25, 0xae, 0x7, 0x81, 0x16, 0xa1, 0x0, 0x75, 0x9f, 0xf7, 0x2e, 0x30, 0x5, 0x40, 0x53, 0x7c, 0xde, 0x3, 0xdd, 0x82, 0x2, 0x34, 0xbc, 0x3f, 0x20, 0x2b, 0xf0, 0xfe, 0xc0, 0xa0, 0x81, 0xaa, 0x40, 0xc9, 0xe3, 0xb6, 0x2b, 0x92, 0x2, 0xf7, 0x7b, 0xc, 0x2a, 0xa8, 0xa, 0xc4, 0x1d, 0xd7, 0x7b, 0x20, 0xb9, 0xc1, 0xfd, 0x28, 0x83, 0x14, 0xaa, 0x2, 0x2e, 0xcd, 0x54, 0xef, 0x3f, 0xce, 0x60, 0x69, 0xe7, 0xff, 0xde, 0xff, 0xd4, 0x53, 0x18, 0x78, 0xd0, 0xc2, 0x41, 0xd0, 0xd0, 0xe3, 0x1, 0xc4, 0x12, 0xd7, 0xff, 0x9e, 0xf, 0x98, 0x34, 0x18, 0x98, 0x50, 0x15, 0x30, 0x32, 0x88, 0xd8, 0xcc, 0xf1, 0xfa, 0xef, 0xc, 0x84, 0x5e, 0xff, 0xad, 0xa6, 0x32, 0x8, 0x63, 0x6, 0x35, 0x2b, 0x9b, 0x8e, 0xc7, 0x6d, 0xb7, 0xff, 0x6e, 0xff, 0x3d, 0xef, 0xb0, 0xe9, 0x30, 0xb0, 0x62, 0x8b, 0xd, 0x6e, 0x19, 0x7f, 0xbf, 0x2f, 0x7e, 0xdf, 0x15, 0x42, 0x11, 0xf6, 0x63, 0x58, 0x63, 0x59, 0x6c, 0x5b, 0xcb, 0x20, 0x6, 0x64, 0xe1, 0x0, 0x2c, 0xc, 0xdc, 0x40, 0xdd, 0x2c, 0xc8, 0x42, 0x0, 0x4, 0x5c, 0x63, 0x9b, 0xfc, 0xae, 0x1b, 0x2a, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char hslider_grabber_hl_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0xc6, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x48, 0x83, 0x83, 0x60, 0xaf, 0xb1, 0x65, 0xbb, 0xca, 0x61, 0xb3, 0xc2, 0x0, 0x0, 0x0, 0x63, 0xb7, 0xc8, 0x63, 0xb7, 0xc7, 0x0, 0x0, 0x0, 0x61, 0xb3, 0xbc, 0x60, 0xb1, 0xbc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5b, 0xa6, 0xa5, 0x63, 0xb4, 0xb6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3a, 0x69, 0x69, 0x5e, 0xb1, 0xcd, 0x5e, 0xb0, 0xcd, 0x36, 0x63, 0x63, 0x0, 0x0, 0x0, 0x17, 0x2a, 0x29, 0x60, 0xb2, 0xbd, 0x62, 0xb3, 0xbf, 0x3, 0x5, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x55, 0x9b, 0x9a, 0x52, 0x96, 0x95, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0xf, 0xf, 0x62, 0xb4, 0xbd, 0x63, 0xb7, 0xbf, 0x0, 0x0, 0x0, 0x27, 0x48, 0x47, 0x68, 0xc0, 0xcf, 0x68, 0xc1, 0xcf, 0x2d, 0x52, 0x52, 0x51, 0x93, 0x92, 0x56, 0x9d, 0x9c, 0x0, 0x0, 0x0, 0x54, 0xa2, 0xc8, 0x4c, 0x94, 0xc2, 0x48, 0x8e, 0xc0, 0x47, 0x8c, 0xbf, 0x4b, 0x93, 0xc2, 0x4b, 0x92, 0xc2, 0x4f, 0x98, 0xc4, 0x4d, 0x96, 0xc3, 0x55, 0xa3, 0xc8, 0x53, 0x9f, 0xc7, 0x49, 0x8f, 0xc0, 0x4e, 0x97, 0xc4, 0x5a, 0xab, 0xcb, 0x5a, 0xac, 0xcc, 0x52, 0x9e, 0xc6, 0x51, 0x9d, 0xc6, 0xff, 0xff, 0xff, 0x6b, 0x1e, 0xb5, 0x61, 0x0, 0x0, 0x0, 0x31, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x3, 0xd, 0x1c, 0x27, 0x16, 0x6e, 0xc1, 0xef, 0xe8, 0x28, 0xf0, 0xf0, 0x22, 0xdb, 0xde, 0x24, 0x17, 0xaf, 0xc5, 0x1a, 0xa, 0x65, 0xfc, 0xfe, 0x64, 0xc, 0x31, 0xe0, 0xe0, 0x28, 0x2, 0x1, 0x14, 0x9c, 0x95, 0x13, 0x5, 0x2c, 0xdb, 0xdc, 0xb, 0x4f, 0xf4, 0xf7, 0x55, 0x73, 0x7d, 0x4, 0x28, 0xf1, 0xfd, 0xa1, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x41, 0x89, 0xde, 0x6c, 0x4e, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x4, 0x4e, 0x1d, 0x2, 0xaf, 0x0, 0x0, 0x0, 0x9e, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x6d, 0xcf, 0xd7, 0x12, 0x82, 0x30, 0x10, 0x5, 0x50, 0x48, 0x42, 0x12, 0xb0, 0x77, 0x8d, 0xd, 0xb, 0x28, 0x56, 0x12, 0x62, 0xd, 0x96, 0xff, 0xff, 0x2a, 0x61, 0xc, 0xe0, 0x83, 0xfb, 0xb4, 0xf7, 0xcc, 0xec, 0xcc, 0x5d, 0xc3, 0xf8, 0x37, 0x26, 0x80, 0x8, 0x41, 0x60, 0xe6, 0xd9, 0xc2, 0x84, 0x52, 0x82, 0xad, 0x4c, 0x0, 0xb6, 0xb9, 0x10, 0xdc, 0xc6, 0x40, 0x3, 0x24, 0x3c, 0x92, 0x32, 0xe2, 0x4, 0x6a, 0x40, 0x54, 0xc8, 0x64, 0x4, 0x45, 0x1a, 0x9c, 0xd2, 0x29, 0x85, 0x73, 0xd9, 0xd1, 0x50, 0xa9, 0x5e, 0x52, 0xb8, 0xd6, 0xea, 0x1a, 0x1a, 0xcd, 0x5b, 0xa, 0xf7, 0x56, 0x5b, 0x43, 0xa7, 0xdb, 0x53, 0x52, 0xaa, 0xfe, 0x80, 0x65, 0x3d, 0x86, 0xa3, 0x58, 0xca, 0x78, 0x3c, 0x99, 0x6a, 0x70, 0x67, 0xf3, 0x87, 0x52, 0xcf, 0xc5, 0x32, 0xaf, 0xee, 0xf9, 0xab, 0xd7, 0x7b, 0xed, 0x7b, 0xc5, 0x33, 0xc1, 0x66, 0xbb, 0xdb, 0xb3, 0x22, 0x27, 0x47, 0x87, 0xa3, 0xe5, 0xfe, 0xfe, 0x1b, 0x6, 0x2c, 0xfc, 0x6e, 0x1f, 0x93, 0x2a, 0x10, 0x62, 0x3, 0x21, 0x32, 0x75, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0xc3, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x48, 0x83, 0x83, 0x60, 0xaf, 0xb1, 0x65, 0xbb, 0xca, 0x61, 0xb3, 0xc2, 0x0, 0x0, 0x0, 0x63, 0xb7, 0xc8, 0x63, 0xb7, 0xc7, 0x0, 0x0, 0x0, 0x61, 0xb3, 0xbc, 0x60, 0xb1, 0xbc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5b, 0xa6, 0xa5, 0x63, 0xb4, 0xb6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3a, 0x69, 0x69, 0x5e, 0xb1, 0xcd, 0x5e, 0xb0, 0xcd, 0x36, 0x63, 0x63, 0x0, 0x0, 0x0, 0x17, 0x2a, 0x29, 0x60, 0xb2, 0xbd, 0x62, 0xb3, 0xbf, 0x3, 0x5, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x55, 0x9b, 0x9a, 0x52, 0x96, 0x95, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0xf, 0xf, 0x62, 0xb4, 0xbd, 0x63, 0xb7, 0xbf, 0x0, 0x0, 0x0, 0x27, 0x48, 0x47, 0x68, 0xc0, 0xcf, 0x68, 0xc1, 0xcf, 0x2d, 0x52, 0x52, 0x51, 0x93, 0x92, 0x56, 0x9d, 0x9c, 0x0, 0x0, 0x0, 0x54, 0xa2, 0xc8, 0x4c, 0x94, 0xc2, 0x48, 0x8e, 0xc0, 0x47, 0x8c, 0xbf, 0x4b, 0x93, 0xc2, 0x4b, 0x92, 0xc2, 0x4f, 0x98, 0xc4, 0x4d, 0x96, 0xc3, 0x55, 0xa3, 0xc8, 0x53, 0x9f, 0xc7, 0x49, 0x8f, 0xc0, 0x4e, 0x97, 0xc4, 0x5a, 0xab, 0xcb, 0x5a, 0xac, 0xcc, 0x52, 0x9e, 0xc6, 0x51, 0x9d, 0xc6, 0xd4, 0xd, 0x1d, 0x1c, 0x0, 0x0, 0x0, 0x31, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x3, 0xd, 0x1c, 0x27, 0x16, 0x6e, 0xc1, 0xef, 0xe8, 0x28, 0xf0, 0xf0, 0x22, 0xdb, 0xde, 0x24, 0x17, 0xaf, 0xc5, 0x1a, 0xa, 0x65, 0xfc, 0xfe, 0x64, 0xc, 0x31, 0xe0, 0xe0, 0x28, 0x2, 0x1, 0x14, 0x9c, 0x95, 0x13, 0x5, 0x2c, 0xdb, 0xdc, 0xb, 0x4f, 0xf4, 0xf7, 0x55, 0x73, 0x7d, 0x4, 0x28, 0xf1, 0xfd, 0xa1, 0x0, 0x0, 0x0, 0x7d, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x5d, 0xcc, 0x81, 0x6, 0xc3, 0x40, 0x10, 0x84, 0xe1, 0xdd, 0x9d, 0xd9, 0x3d, 0x40, 0x1f, 0xa1, 0x0, 0xd1, 0xbe, 0xff, 0xbb, 0x94, 0x10, 0x29, 0x40, 0x1a, 0x40, 0x9, 0xa, 0xbd, 0x34, 0x7b, 0x39, 0xfa, 0x63, 0xf0, 0x61, 0x4c, 0xfe, 0xfa, 0x81, 0x1a, 0x48, 0x98, 0x36, 0x50, 0x66, 0xda, 0x40, 0x71, 0xab, 0x41, 0x3b, 0xc, 0x56, 0x1b, 0x3a, 0xd4, 0x8e, 0x4d, 0x8, 0x40, 0x6a, 0x64, 0x24, 0x0, 0xb6, 0x83, 0xa1, 0x1, 0x79, 0x0, 0x79, 0xc2, 0x54, 0x44, 0xca, 0x14, 0x91, 0xb0, 0xba, 0xef, 0xa7, 0xee, 0x9e, 0x70, 0x8d, 0xd0, 0x52, 0x2c, 0xe2, 0x99, 0x30, 0x93, 0xb, 0x7d, 0x81, 0x4a, 0x82, 0x8c, 0xc0, 0xba, 0xfa, 0x7b, 0x3c, 0x41, 0xb6, 0xd, 0x78, 0x84, 0x74, 0x98, 0x2f, 0x9f, 0xd7, 0x7d, 0x96, 0xbd, 0x2f, 0xa5, 0x6b, 0x13, 0xc4, 0x35, 0x90, 0x18, 0xcd, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char hslider_tick_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xc3, 0x98, 0xc3, 0xc0, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x1e, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x38, 0x55, 0x5f, 0x8c, 0xac, 0xb8, 0x81, 0xa2, 0xad, 0x98, 0x98, 0x98, 0x4e, 0x4e, 0x4e, 0x8d, 0x8d, 0x8d, 0x82, 0x82, 0x82, 0x4e, 0x4e, 0x4e, 0xff, 0xff, 0xff, 0xc1, 0xc9, 0xb1, 0x80, 0x0, 0x0, 0x0, 0x9, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x0, 0x0, 0x0, 0x79, 0x31, 0x79, 0x79, 0x1c, 0x7e, 0xed, 0x4b, 0xf4, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x9, 0xf1, 0xd9, 0xa5, 0xec, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x21, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0x9, 0x60, 0x60, 0xb, 0x60, 0x60, 0xf, 0x60, 0x60, 0x6d, 0x60, 0x60, 0x14, 0x60, 0xc0, 0x4, 0x4c, 0x2, 0xc, 0xcc, 0x2, 0xc, 0x30, 0x65, 0x0, 0x46, 0x9d, 0x2, 0xbe, 0x9f, 0x3a, 0x6c, 0xab, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xc3, 0x98, 0xc3, 0xc0, 0x0, 0x0, 0x0, 0x1b, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x38, 0x55, 0x5f, 0x8c, 0xac, 0xb8, 0x81, 0xa2, 0xad, 0x98, 0x98, 0x98, 0x4e, 0x4e, 0x4e, 0x8d, 0x8d, 0x8d, 0x82, 0x82, 0x82, 0x4e, 0x4e, 0x4e, 0xc9, 0xf6, 0x7, 0x31, 0x0, 0x0, 0x0, 0x9, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x0, 0x0, 0x0, 0x79, 0x31, 0x79, 0x79, 0x1c, 0x7e, 0xed, 0x4b, 0xf4, 0x0, 0x0, 0x0, 0x20, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x60, 0x9, 0x60, 0x60, 0xb, 0x60, 0x60, 0xf, 0x60, 0x60, 0x6d, 0x60, 0x60, 0x14, 0x60, 0xc0, 0x4, 0x4c, 0x2, 0xc, 0xcc, 0x2, 0x70, 0x65, 0x0, 0x46, 0x9d, 0x2, 0xbe, 0xb7, 0xdf, 0x14, 0x38, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char hsplit_bg_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x1, 0x3, 0x0, 0x0, 0x0, 0xfe, 0xc1, 0x2c, 0xc8, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x6, 0x50, 0x4c, 0x54, 0x45, 0x27, 0x27, 0x29, 0xff, 0xff, 0xff, 0x11, 0xab, 0xb9, 0xf3, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x1, 0xff, 0x2, 0x2d, 0xde, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0xb, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0x40, 0x5, 0x0, 0x0, 0x10, 0x0, 0x1, 0xa1, 0xc5, 0x21, 0xc1, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x1, 0x3, 0x0, 0x0, 0x0, 0xfe, 0xc1, 0x2c, 0xc8, 0x0, 0x0, 0x0, 0x6, 0x50, 0x4c, 0x54, 0x45, 0x27, 0x27, 0x29, 0xff, 0xff, 0xff, 0x11, 0xab, 0xb9, 0xf3, 0x0, 0x0, 0x0, 0xa, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x40, 0x3, 0x0, 0x0, 0x10, 0x0, 0x1, 0xb3, 0xac, 0xe2, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char hsplitter_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x40, 0x8, 0x0, 0x0, 0x0, 0x0, 0x2, 0x6f, 0x69, 0x56, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x2, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x0, 0x76, 0x93, 0xcd, 0x38, 0x0, 0x0, 0x0, 0x2, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x87, 0x8f, 0xcc, 0xbf, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x4, 0x4e, 0x1d, 0x2, 0xaf, 0x0, 0x0, 0x0, 0x27, 0x49, 0x44, 0x41, 0x54, 0x28, 0xcf, 0x63, 0x60, 0x80, 0x2, 0x66, 0x86, 0x5, 0xa2, 0xe7, 0x18, 0x16, 0x88, 0x9e, 0x63, 0x66, 0x10, 0xbd, 0xf6, 0x98, 0x41, 0xf4, 0xda, 0x63, 0x6, 0xc, 0x30, 0xaa, 0x66, 0x54, 0xd, 0x9a, 0x1a, 0x0, 0x5c, 0x29, 0x6a, 0x81, 0x90, 0x8f, 0x52, 0x12, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x40, 0x8, 0x0, 0x0, 0x0, 0x0, 0x2, 0x6f, 0x69, 0x56, 0x0, 0x0, 0x0, 0x2, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x0, 0x76, 0x93, 0xcd, 0x38, 0x0, 0x0, 0x0, 0x1a, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x40, 0x80, 0x5, 0xa9, 0x10, 0xcc, 0x90, 0x6a, 0xd, 0xc6, 0x70, 0x80, 0x4b, 0xcd, 0xa8, 0x9a, 0x51, 0x35, 0x0, 0x78, 0xd5, 0x34, 0xa1, 0x54, 0x8c, 0xd5, 0x84, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char icon_add_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x36, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0x63, 0x60, 0xa0, 0x25, 0x78, 0xf0, 0xe0, 0xc1, 0xff, 0x7, 0xf, 0x1e, 0xfc, 0xc7, 0xa7, 0x86, 0x89, 0x52, 0x4b, 0x46, 0xd, 0x60, 0x60, 0x60, 0x64, 0x60, 0x80, 0x84, 0x36, 0x39, 0x9a, 0x15, 0x14, 0x14, 0x18, 0x29, 0x76, 0x1, 0x5e, 0x30, 0x9a, 0xe, 0xe8, 0x64, 0x0, 0xc5, 0x0, 0x0, 0xc7, 0x6e, 0x12, 0x94, 0xf9, 0x26, 0x2e, 0xdb, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x1d, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x20, 0x11, 0x3c, 0xf8, 0xff, 0xe0, 0xff, 0xd0, 0x52, 0x80, 0x10, 0xc4, 0xd, 0x9, 0x2a, 0x18, 0x26, 0xe1, 0x40, 0x18, 0x0, 0x0, 0x5b, 0x26, 0x61, 0x4d, 0xc9, 0xc1, 0x48, 0x81, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char icon_close_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x9b, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xcd, 0x92, 0x31, 0xe, 0xc2, 0x30, 0x10, 0x4, 0x17, 0xaa, 0x3d, 0x67, 0xdb, 0x58, 0xd0, 0xd3, 0xf0, 0xa3, 0x7c, 0x36, 0x3c, 0x82, 0x48, 0x44, 0x22, 0x6f, 0xb1, 0x4d, 0x85, 0x14, 0x81, 0xf, 0x2c, 0x28, 0xe0, 0xda, 0xd5, 0x8c, 0x4e, 0x77, 0xb, 0xfc, 0xd5, 0x98, 0xd9, 0x20, 0x29, 0x7a, 0xb9, 0xa4, 0x68, 0x66, 0x83, 0xb, 0x93, 0xcc, 0x24, 0xa7, 0x9a, 0x44, 0x52, 0x24, 0x39, 0x91, 0xcc, 0x55, 0x89, 0xa4, 0xde, 0xcc, 0xce, 0x24, 0xb, 0xc9, 0x39, 0x84, 0xb0, 0xf7, 0xb2, 0xae, 0xeb, 0x76, 0xde, 0x8a, 0x4f, 0x92, 0x66, 0xd8, 0x91, 0x5c, 0x49, 0x5e, 0x9a, 0xe1, 0xb5, 0x64, 0x5, 0x16, 0x92, 0x8b, 0x7, 0x6f, 0x9b, 0x8c, 0x0, 0x4a, 0x29, 0x9b, 0x26, 0x81, 0xa4, 0x3e, 0xa5, 0x34, 0x2, 0x38, 0x2, 0x58, 0x0, 0xcc, 0x0, 0xe, 0x39, 0xe7, 0xd3, 0xfa, 0xb0, 0xee, 0xea, 0x8f, 0x7, 0x7b, 0xf5, 0x9d, 0xb7, 0xb0, 0x97, 0x55, 0x25, 0x5f, 0x17, 0xe9, 0x2e, 0xf9, 0xb8, 0xca, 0x3f, 0x9b, 0x1b, 0x1a, 0xe3, 0x40, 0x47, 0xa0, 0xda, 0xda, 0x61, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x62, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0xa0, 0x16, 0xe0, 0x8c, 0xe0, 0x11, 0x43, 0xe6, 0xf3, 0x88, 0x71, 0x46, 0xa0, 0x48, 0x73, 0xfc, 0xe3, 0xb8, 0xcc, 0x23, 0x86, 0x90, 0xe6, 0xb8, 0xcc, 0xf1, 0xf, 0x49, 0x9, 0x8f, 0x28, 0xe7, 0x25, 0x8e, 0xff, 0x1c, 0xd7, 0xb9, 0x24, 0x91, 0x79, 0xdc, 0x12, 0x40, 0xe, 0xa6, 0x12, 0x54, 0x69, 0x4c, 0x25, 0xb7, 0x38, 0xae, 0x21, 0xa4, 0x31, 0x94, 0x80, 0x24, 0x81, 0xf0, 0x36, 0x48, 0x1a, 0xaf, 0x2, 0x88, 0x5b, 0xf0, 0x5a, 0x81, 0xa1, 0x4, 0xe1, 0x34, 0x84, 0x73, 0xb1, 0x4a, 0xa3, 0x7b, 0x9a, 0x70, 0x40, 0x11, 0xe, 0x6a, 0xca, 0x1, 0x0, 0x2a, 0x28, 0x37, 0x83, 0x3e, 0x27, 0xb0, 0x34, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char icon_color_pick_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x1, 0x55, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xb5, 0x92, 0xb1, 0x4a, 0x3, 0x41, 0x14, 0x45, 0xef, 0xdb, 0x6c, 0xac, 0xf2, 0x1, 0xda, 0xcd, 0x40, 0x4, 0x25, 0x11, 0x4, 0x8b, 0x80, 0x8d, 0x20, 0x88, 0x5d, 0x20, 0x88, 0x90, 0x22, 0x9d, 0x9d, 0xa0, 0x85, 0x58, 0xeb, 0x7, 0x88, 0xe0, 0x7, 0x58, 0x8b, 0x36, 0x5a, 0x88, 0xa0, 0xa5, 0x85, 0xa5, 0x60, 0x61, 0xb0, 0x70, 0xb2, 0xef, 0x8d, 0x44, 0x41, 0x21, 0x1f, 0x20, 0x6c, 0xf2, 0x2c, 0xcc, 0xc2, 0x12, 0x92, 0x8d, 0x45, 0xbc, 0xe5, 0xdc, 0xb9, 0x67, 0xee, 0xbc, 0x19, 0xe0, 0xbf, 0xe5, 0xbd, 0x2f, 0x35, 0x9b, 0xcd, 0x29, 0x0, 0x10, 0x91, 0x9a, 0x88, 0x7c, 0x88, 0xc8, 0xa7, 0x88, 0xd4, 0x0, 0x80, 0xb2, 0xc2, 0xcc, 0x5c, 0x21, 0xa2, 0x5b, 0x22, 0xba, 0xef, 0x76, 0xbb, 0x97, 0x44, 0x74, 0x4a, 0x44, 0x61, 0xdf, 0xfe, 0x32, 0xc6, 0x4c, 0x87, 0x59, 0x0, 0x0, 0xdf, 0x0, 0x62, 0x55, 0xad, 0x6, 0x41, 0x50, 0x1d, 0xf0, 0x62, 0x0, 0x8, 0xb2, 0xd2, 0xd6, 0xda, 0x27, 0x0, 0x27, 0x83, 0xeb, 0xaa, 0x1a, 0x3, 0xd8, 0x19, 0xb, 0x60, 0xe6, 0x3a, 0x80, 0x6d, 0x0, 0xd, 0x0, 0x9d, 0x14, 0x60, 0xcb, 0x18, 0x73, 0x95, 0x9, 0x60, 0xe6, 0x3a, 0x11, 0x1d, 0xc7, 0x71, 0xbc, 0x6e, 0x8c, 0x39, 0x53, 0xd5, 0xdd, 0xc4, 0xcb, 0xe5, 0x72, 0x1b, 0xc9, 0x60, 0x87, 0x2, 0xd2, 0xe1, 0x62, 0xb1, 0xf8, 0xec, 0xbd, 0x2f, 0x11, 0xd1, 0x51, 0xaf, 0xd7, 0x3b, 0x0, 0xd0, 0x51, 0xd5, 0x95, 0x42, 0xa1, 0x30, 0x3b, 0xf2, 0x64, 0x11, 0x79, 0x77, 0xce, 0x95, 0x81, 0xdf, 0x67, 0x14, 0x91, 0x76, 0xff, 0x3a, 0x60, 0xe6, 0x45, 0x66, 0xae, 0xc, 0xd, 0x47, 0x51, 0xb4, 0x29, 0x22, 0xed, 0x56, 0xab, 0xb5, 0xd0, 0xdf, 0x3c, 0xe7, 0xbd, 0x7f, 0x8b, 0xa2, 0xa8, 0x31, 0x7a, 0x52, 0x93, 0x8, 0x8b, 0xc8, 0x72, 0xba, 0xb6, 0x73, 0xae, 0x9c, 0xae, 0x9d, 0xa5, 0x0, 0x0, 0x88, 0x68, 0xd, 0xc0, 0x8b, 0xaa, 0xbe, 0x3a, 0xe7, 0xca, 0x61, 0x18, 0xde, 0xa9, 0xea, 0xbe, 0xb5, 0xf6, 0x7c, 0x1c, 0x20, 0xf9, 0x89, 0x4b, 0x0, 0x56, 0xf3, 0xf9, 0xfc, 0xd, 0x80, 0x79, 0x55, 0xdd, 0xb3, 0xd6, 0x5e, 0x8c, 0xad, 0x9e, 0x0, 0x54, 0x75, 0x86, 0x88, 0xae, 0x1, 0x3c, 0x2, 0x38, 0x34, 0xc6, 0x3c, 0xfc, 0x25, 0x3c, 0x11, 0xfd, 0x0, 0x28, 0x54, 0xbb, 0xfe, 0xad, 0x99, 0xe5, 0xb8, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0xaa, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x9d, 0x8e, 0x35, 0x82, 0x2, 0x41, 0x10, 0x45, 0x3b, 0xda, 0x3d, 0xca, 0xba, 0x44, 0x2b, 0x70, 0x9, 0xdc, 0xe1, 0x20, 0xe8, 0x91, 0x90, 0x78, 0x6e, 0x40, 0x4c, 0x82, 0x74, 0xff, 0xc2, 0x9d, 0x18, 0xa7, 0x6, 0x77, 0x7b, 0x23, 0x2d, 0xaf, 0x4c, 0xdc, 0xc, 0xbd, 0x65, 0x1e, 0x84, 0x80, 0x19, 0x55, 0x34, 0x60, 0x3e, 0xd0, 0xea, 0x17, 0x3d, 0x4a, 0xc8, 0x80, 0x1a, 0x60, 0xc2, 0x4f, 0xfd, 0x30, 0xe0, 0x1b, 0x2d, 0x16, 0xab, 0xa7, 0x2c, 0xe, 0x41, 0x68, 0xa5, 0xb9, 0xca, 0x91, 0x16, 0x2e, 0x54, 0xe0, 0x59, 0x54, 0x91, 0xfe, 0xa3, 0x3a, 0xff, 0xce, 0xab, 0x5b, 0xf, 0xa0, 0x4, 0x8f, 0x7b, 0x4c, 0xd3, 0x1b, 0xca, 0x32, 0xcc, 0x55, 0x7a, 0xf4, 0x76, 0x42, 0x2b, 0x97, 0x3e, 0xae, 0xfa, 0xdd, 0xd2, 0xd2, 0x8e, 0x72, 0xe1, 0x83, 0xaf, 0x9f, 0xa9, 0x28, 0x7d, 0x5b, 0xe2, 0x2a, 0xd, 0xc3, 0xa2, 0x78, 0xfe, 0x7d, 0x51, 0xfc, 0x0, 0x8a, 0x41, 0xcb, 0x3d, 0xb2, 0xae, 0x1c, 0xd3, 0xc, 0xa5, 0x30, 0x81, 0xc6, 0xda, 0x29, 0x8e, 0x83, 0x34, 0x25, 0x29, 0x4a, 0x46, 0x71, 0x1f, 0x33, 0xbe, 0x51, 0x89, 0xaf, 0x78, 0xe3, 0x97, 0x7e, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char icon_folder_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x5f, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xed, 0x8f, 0xc1, 0xd, 0x80, 0x30, 0x8, 0x45, 0x9f, 0x9d, 0x84, 0x39, 0x4c, 0x3b, 0xbd, 0x75, 0x8f, 0x32, 0x9, 0x5e, 0xec, 0xa5, 0x9, 0xa4, 0xc6, 0x26, 0x5e, 0x7c, 0x17, 0xe, 0xc0, 0xe3, 0x3, 0x5f, 0xb3, 0x1, 0xb4, 0xd6, 0x4e, 0x60, 0x77, 0x66, 0xaa, 0x88, 0x14, 0x4f, 0x90, 0xee, 0xea, 0x2d, 0x3, 0xe4, 0x28, 0x41, 0x8a, 0x9a, 0x1d, 0x55, 0x75, 0x25, 0xfd, 0x5, 0x9b, 0x11, 0xd, 0x54, 0x11, 0x29, 0x53, 0x9, 0x1c, 0x32, 0x4c, 0xbe, 0x10, 0xf1, 0xb, 0x16, 0xa, 0xea, 0xd3, 0x45, 0x33, 0x3b, 0xde, 0x1e, 0x5f, 0xc3, 0x5, 0x1f, 0xc5, 0x12, 0x2c, 0xc5, 0x88, 0xe1, 0xb4, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x2e, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0xa0, 0x6, 0x78, 0x70, 0xf4, 0xc1, 0x7f, 0x24, 0x78, 0x18, 0x53, 0xc1, 0x7f, 0x54, 0x48, 0x50, 0xc1, 0x43, 0x1b, 0xbc, 0xa, 0x50, 0xad, 0x23, 0xa4, 0xe0, 0xff, 0x70, 0x52, 0x70, 0x18, 0x97, 0xf4, 0xfd, 0x43, 0xd4, 0x88, 0x4a, 0x0, 0x5a, 0xcb, 0x18, 0xab, 0x5e, 0xd9, 0x1a, 0x53, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char icon_parent_folder_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x4, 0x73, 0x42, 0x49, 0x54, 0x8, 0x8, 0x8, 0x8, 0x7c, 0x8, 0x64, 0x88, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xe, 0xc4, 0x0, 0x0, 0xe, 0xc4, 0x1, 0x95, 0x2b, 0xe, 0x1b, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x0, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x6e, 0x6b, 0x73, 0x63, 0x61, 0x70, 0x65, 0x2e, 0x6f, 0x72, 0x67, 0x9b, 0xee, 0x3c, 0x1a, 0x0, 0x0, 0x0, 0xc6, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xdd, 0x90, 0xbd, 0x6a, 0x2, 0x51, 0x10, 0x46, 0xcf, 0x8c, 0xbb, 0xaf, 0x10, 0xdb, 0xcb, 0x2e, 0x4b, 0x40, 0xf2, 0x14, 0x51, 0x8b, 0x3c, 0x70, 0x44, 0x48, 0x48, 0x15, 0x4c, 0x61, 0x67, 0xd2, 0x4, 0x96, 0xb, 0x5b, 0x89, 0x58, 0x59, 0xee, 0x8f, 0x3b, 0x36, 0xbb, 0x8d, 0x78, 0xa3, 0x92, 0x4a, 0x4f, 0xf9, 0xcd, 0xcc, 0x99, 0x61, 0xe0, 0xe6, 0x91, 0x50, 0xc1, 0x7b, 0x3f, 0x54, 0xd5, 0x39, 0x60, 0x6d, 0xdb, 0xbe, 0x24, 0x49, 0xb2, 0xb9, 0x58, 0x90, 0xe7, 0xf9, 0x43, 0x1c, 0xc7, 0xef, 0x66, 0xf6, 0xd4, 0x45, 0xbf, 0xc0, 0xb3, 0x73, 0x6e, 0x7d, 0x56, 0x70, 0x62, 0xb8, 0xe7, 0xa4, 0x44, 0x8f, 0xcf, 0x8e, 0xa2, 0xe8, 0xa3, 0x1b, 0xfe, 0xee, 0x62, 0x13, 0x91, 0x1f, 0xe0, 0x11, 0x78, 0xf3, 0xde, 0xf, 0x83, 0x2, 0x55, 0x9d, 0x1, 0x23, 0x60, 0xd5, 0x34, 0xcd, 0xb4, 0xcf, 0xab, 0xaa, 0x1a, 0x77, 0xc2, 0x91, 0xaa, 0xbe, 0x6, 0x5, 0xc0, 0xe, 0xf8, 0x2a, 0xcb, 0x72, 0x92, 0xa6, 0xe9, 0xb6, 0xf, 0xb3, 0x2c, 0xdb, 0xd6, 0x75, 0x3d, 0x11, 0x91, 0x25, 0x50, 0xfe, 0xf9, 0x83, 0x1e, 0x33, 0x93, 0xa2, 0x28, 0xf6, 0x80, 0x39, 0xe7, 0x6, 0xa1, 0xbe, 0xe3, 0xb, 0xae, 0x26, 0x28, 0x10, 0x11, 0x3, 0x16, 0x22, 0xf2, 0xf9, 0xdf, 0x25, 0xf7, 0xce, 0x1, 0x9e, 0x13, 0x48, 0xe9, 0x87, 0xc5, 0x3a, 0xd2, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x68, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0xa0, 0x33, 0xb8, 0x27, 0xfe, 0xe0, 0xfc, 0x83, 0x73, 0xf7, 0xc4, 0x71, 0x48, 0xdf, 0x11, 0x7b, 0x78, 0xe9, 0xc1, 0x3f, 0x20, 0xbc, 0xfe, 0x40, 0x12, 0x8f, 0x34, 0x4c, 0x9, 0xa6, 0xe1, 0x57, 0x80, 0x12, 0x17, 0x81, 0xf8, 0x2f, 0x58, 0xe1, 0x15, 0x34, 0x8b, 0x1e, 0x9c, 0x5, 0xa, 0x5e, 0xb8, 0x23, 0x6, 0x52, 0x70, 0x5b, 0x14, 0xac, 0xf0, 0xc, 0xaa, 0x82, 0x7d, 0xf, 0x8e, 0xde, 0x14, 0xf9, 0xcf, 0x8, 0x52, 0xc0, 0xc0, 0x70, 0x5b, 0xf4, 0xe1, 0xc9, 0x7, 0x47, 0xb1, 0xb8, 0x3, 0xaa, 0x0, 0xa, 0x48, 0x52, 0x80, 0xb0, 0xea, 0xc8, 0xc3, 0x83, 0xc, 0x83, 0xe, 0x0, 0x0, 0xb8, 0x27, 0x55, 0x4c, 0xbe, 0xc0, 0xd2, 0xac, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char icon_play_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0xa2, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0x63, 0x60, 0x18, 0xf2, 0x80, 0x11, 0x99, 0xf3, 0xe0, 0xc1, 0x83, 0xc3, 0xc, 0xc, 0xc, 0xc2, 0xc, 0xc, 0xc, 0xa5, 0xa, 0xa, 0xa, 0x5b, 0xc9, 0x31, 0xe0, 0x3f, 0x5c, 0x82, 0x91, 0x71, 0x27, 0x3, 0x3, 0x43, 0x91, 0xbc, 0xbc, 0xfc, 0x35, 0x7c, 0x6, 0x30, 0xe1, 0x92, 0xf8, 0xff, 0xff, 0xbf, 0xfb, 0xff, 0xff, 0xff, 0x2f, 0x3e, 0x78, 0xf0, 0x60, 0xca, 0x93, 0x27, 0x4f, 0x84, 0x49, 0x76, 0x1, 0x1a, 0xf8, 0xc0, 0xc8, 0xc8, 0xd8, 0xf1, 0xeb, 0xd7, 0xaf, 0x9, 0xaa, 0xaa, 0xaa, 0x3f, 0x89, 0x72, 0x1, 0x1a, 0x10, 0xf8, 0xff, 0xff, 0x7f, 0x7, 0x2b, 0x2b, 0xeb, 0x1e, 0x74, 0x9, 0x62, 0xd, 0xc0, 0x9, 0x88, 0x35, 0xe0, 0x3d, 0x23, 0x23, 0x63, 0xc5, 0xef, 0xdf, 0xbf, 0x5d, 0xd0, 0x25, 0x58, 0x8, 0x68, 0xfc, 0xc3, 0xc0, 0xc0, 0x30, 0x93, 0x85, 0x85, 0xa5, 0x5e, 0x46, 0x46, 0xe6, 0x2d, 0x36, 0x5, 0x38, 0xd, 0x20, 0x36, 0x1a, 0xd1, 0xd, 0x38, 0xc2, 0x0, 0x4d, 0x48, 0xf2, 0xf2, 0xf2, 0x44, 0x25, 0xa4, 0x61, 0x0, 0x0, 0x1e, 0x57, 0x33, 0x3c, 0xcc, 0xe7, 0x34, 0x69, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x41, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0xa0, 0x1b, 0x78, 0x70, 0xf8, 0xc1, 0xb5, 0x7, 0xde, 0xf8, 0x14, 0xfc, 0x7, 0xc1, 0x87, 0x3b, 0x1e, 0x6a, 0xe1, 0x54, 0x0, 0x85, 0xbf, 0x1f, 0x4c, 0x79, 0x22, 0x8c, 0x5d, 0x1, 0x2, 0xbe, 0x7f, 0x58, 0x7e, 0x9b, 0x1d, 0x43, 0x1, 0x1a, 0x3c, 0x4c, 0x91, 0x82, 0x77, 0x8, 0x2b, 0x8, 0x3b, 0x12, 0xd3, 0x9b, 0x84, 0x3, 0x8a, 0xfe, 0x0, 0x0, 0xa4, 0x15, 0x70, 0xca, 0x48, 0x40, 0x6f, 0xa6, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char icon_reload_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x1, 0x59, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xcd, 0x92, 0x31, 0x4b, 0x3, 0x31, 0x18, 0x86, 0x9f, 0x5c, 0xe, 0xec, 0x20, 0x76, 0x70, 0x39, 0xd0, 0xe3, 0xba, 0x74, 0x51, 0x41, 0xdd, 0xfc, 0x7, 0xba, 0xb8, 0x8, 0x52, 0xec, 0x2e, 0x4e, 0x3a, 0x88, 0x3f, 0xa3, 0xa3, 0x53, 0x7, 0x47, 0x67, 0x41, 0x17, 0xdd, 0x9c, 0x5c, 0x3b, 0xd8, 0x82, 0x64, 0x68, 0xca, 0xd5, 0x55, 0x11, 0x3c, 0x1a, 0x87, 0x24, 0x2e, 0xd7, 0x72, 0x9e, 0x9e, 0xab, 0xbe, 0xd3, 0xc7, 0x1b, 0x9e, 0x37, 0xf9, 0xbe, 0x7c, 0xf0, 0xd7, 0x12, 0x3f, 0x99, 0x4a, 0xa9, 0xb9, 0x30, 0xc, 0x8f, 0x84, 0x10, 0x7, 0xc0, 0x5a, 0x6e, 0x3f, 0x3a, 0xe7, 0x2e, 0xad, 0xb5, 0xdd, 0x66, 0xb3, 0xf9, 0x51, 0x19, 0x90, 0xa6, 0xe9, 0x92, 0xb5, 0xf6, 0x6, 0x58, 0xaf, 0xb8, 0xb4, 0x27, 0xa5, 0xdc, 0x8d, 0xe3, 0xf8, 0x19, 0x20, 0x28, 0xdf, 0x5c, 0x80, 0x53, 0x60, 0xdf, 0x18, 0x53, 0x37, 0xc6, 0xd4, 0xbd, 0xf7, 0x7b, 0xc0, 0x13, 0xb0, 0x61, 0xad, 0xbd, 0x56, 0x4a, 0xcd, 0x1, 0x84, 0xc5, 0x80, 0x30, 0xc, 0x8f, 0xa6, 0xb0, 0x94, 0x72, 0x33, 0x8e, 0xe3, 0x97, 0xc2, 0xf1, 0xd5, 0x68, 0x34, 0xba, 0xf7, 0xde, 0xf7, 0x80, 0xd, 0x29, 0xe5, 0x21, 0x70, 0xfe, 0xe5, 0x5, 0x42, 0x88, 0x76, 0x5e, 0x9e, 0x96, 0x60, 0x0, 0x92, 0x24, 0x79, 0x75, 0xce, 0x9d, 0x1, 0x4, 0x41, 0xd0, 0xfe, 0xd6, 0x2, 0xb0, 0x2, 0x60, 0x8c, 0xb9, 0xab, 0xe8, 0x1f, 0x6b, 0xed, 0x6d, 0x5e, 0xae, 0xce, 0x2, 0xb4, 0xd6, 0x17, 0x5a, 0x6b, 0x7, 0xcc, 0x3, 0xd4, 0x6a, 0xb5, 0x37, 0xad, 0xf5, 0xc5, 0x4f, 0x1, 0x41, 0x10, 0x7c, 0x19, 0x7c, 0x90, 0x3, 0xc7, 0xc0, 0xa0, 0xe0, 0xf, 0x72, 0xef, 0x9b, 0x84, 0x10, 0xdb, 0x79, 0xd9, 0x9f, 0x5, 0x44, 0x51, 0x94, 0x9, 0x21, 0x5a, 0x40, 0x6, 0x64, 0x42, 0x88, 0x56, 0x14, 0x45, 0x59, 0x19, 0x1e, 0x8f, 0xc7, 0x8b, 0x52, 0xca, 0xe, 0x80, 0x73, 0xee, 0x12, 0xa, 0xbf, 0x90, 0x24, 0x49, 0x7f, 0x38, 0x1c, 0x1e, 0x3, 0x34, 0x1a, 0x8d, 0x7e, 0x11, 0x54, 0x4a, 0x2d, 0x48, 0x29, 0x77, 0xac, 0xb5, 0x1d, 0xef, 0xfd, 0x32, 0xd0, 0x9b, 0x4c, 0x26, 0x5d, 0xa8, 0xd8, 0xc4, 0xb2, 0xf2, 0xf9, 0x4c, 0x55, 0xbd, 0x48, 0xbf, 0xe8, 0x1d, 0x78, 0x70, 0xce, 0x9d, 0x64, 0x59, 0xb6, 0x35, 0x85, 0xff, 0x87, 0x3e, 0x1, 0x53, 0x7, 0x87, 0x11, 0xd3, 0x3a, 0x9b, 0x9e, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0xb1, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0xad, 0x50, 0x35, 0xba, 0xc2, 0x40, 0x10, 0x7e, 0xcd, 0x33, 0x5c, 0xca, 0x1c, 0x21, 0x87, 0xc1, 0xa9, 0xd3, 0x23, 0x47, 0xca, 0x69, 0xb0, 0x6, 0x77, 0xdb, 0xfd, 0x17, 0x2f, 0x91, 0x3e, 0xee, 0xd2, 0xc1, 0x4e, 0xb5, 0xdf, 0xcc, 0xaf, 0x5f, 0x9f, 0x7c, 0xdb, 0x5f, 0xda, 0x44, 0x17, 0x2f, 0x75, 0xba, 0xa4, 0xb1, 0xfd, 0xf5, 0xad, 0x8f, 0x1c, 0x86, 0x90, 0x5c, 0x33, 0x38, 0x72, 0x1e, 0xb4, 0xbe, 0x66, 0x28, 0xad, 0xe2, 0xab, 0x38, 0xcd, 0x63, 0xa9, 0x9d, 0xb8, 0x58, 0x68, 0x53, 0x5b, 0x1f, 0x33, 0xd6, 0x9f, 0xa5, 0xc1, 0x20, 0x91, 0xba, 0x7d, 0x80, 0x1e, 0x24, 0x94, 0xdc, 0x92, 0xa4, 0x2, 0x9, 0x1d, 0xe7, 0xe0, 0x9, 0x69, 0x15, 0xf7, 0x58, 0x4e, 0x40, 0xc2, 0xc3, 0x58, 0x8a, 0xb6, 0x31, 0xd1, 0x39, 0xd8, 0x27, 0xed, 0x83, 0x5b, 0x14, 0x33, 0x7d, 0x3d, 0xbb, 0x45, 0x5d, 0x12, 0x55, 0x97, 0x4, 0xe3, 0xb5, 0xf4, 0x8c, 0x77, 0xd6, 0xa7, 0x2c, 0x3b, 0x78, 0x4c, 0x52, 0x81, 0xa, 0x8e, 0x3a, 0xa9, 0x6a, 0x6b, 0xc, 0xe6, 0x3f, 0xa1, 0x8d, 0x86, 0x16, 0xe5, 0x39, 0x78, 0xa2, 0x4d, 0xea, 0xe, 0xfa, 0xdd, 0xa7, 0x0, 0x90, 0x4f, 0x8b, 0xd0, 0xe1, 0x9e, 0x1b, 0xc2, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char icon_snap_grid_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x4, 0x73, 0x42, 0x49, 0x54, 0x8, 0x8, 0x8, 0x8, 0x7c, 0x8, 0x64, 0x88, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xe, 0xc4, 0x0, 0x0, 0xe, 0xc4, 0x1, 0x95, 0x2b, 0xe, 0x1b, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x0, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x6e, 0x6b, 0x73, 0x63, 0x61, 0x70, 0x65, 0x2e, 0x6f, 0x72, 0x67, 0x9b, 0xee, 0x3c, 0x1a, 0x0, 0x0, 0x0, 0xc2, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xad, 0x90, 0xbd, 0xa, 0xc2, 0x30, 0x14, 0x85, 0xbf, 0x5b, 0x5c, 0x23, 0xe8, 0x6c, 0x9f, 0xc1, 0xb7, 0xd0, 0x47, 0xd1, 0x47, 0x70, 0x48, 0xa1, 0x43, 0x57, 0xe9, 0xd3, 0x88, 0x93, 0xef, 0xe0, 0xea, 0x5c, 0x9d, 0x1d, 0xb2, 0x96, 0xc6, 0xa1, 0x9, 0xd4, 0xd8, 0xd8, 0x4a, 0xfd, 0x20, 0x10, 0xee, 0xcf, 0xe1, 0xdc, 0x3, 0x1d, 0x8c, 0x31, 0xd6, 0x18, 0x63, 0x9, 0x88, 0xd5, 0x1, 0x92, 0xbe, 0xe2, 0x2f, 0x4c, 0x16, 0x90, 0x98, 0xb5, 0x21, 0x94, 0x52, 0xf2, 0x17, 0x7, 0x6f, 0x7c, 0xb, 0x2b, 0xc6, 0x64, 0x7, 0xb3, 0xa1, 0x1, 0x5b, 0x14, 0x29, 0x50, 0x2, 0x1b, 0x0, 0x44, 0x2e, 0x34, 0xcd, 0x41, 0xb2, 0xec, 0x6, 0x20, 0xdd, 0x61, 0x6f, 0xdf, 0x7, 0xe4, 0x96, 0xaf, 0xc0, 0x32, 0xd0, 0x7d, 0x2, 0x6b, 0xd1, 0xba, 0x4a, 0xfc, 0xdd, 0x91, 0xdb, 0x4b, 0xb7, 0x7c, 0x2, 0x56, 0xd4, 0x75, 0xa, 0x9c, 0x81, 0x5, 0x70, 0x84, 0xe1, 0xc, 0x5a, 0xdb, 0x75, 0xbd, 0x17, 0xad, 0x1f, 0x92, 0xe7, 0x77, 0x60, 0xe7, 0x7a, 0x5b, 0x80, 0x44, 0x29, 0x25, 0xfe, 0xf5, 0x8, 0x28, 0x0, 0xb7, 0xd8, 0x46, 0xa0, 0x75, 0xe5, 0xbe, 0xf3, 0x31, 0xe, 0x7e, 0x23, 0xcc, 0xc2, 0x3a, 0xc2, 0xb9, 0x58, 0xfd, 0x83, 0xc9, 0x2, 0x63, 0x78, 0x1, 0x4a, 0x50, 0x70, 0x86, 0xcc, 0x86, 0x2, 0x4, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x33, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0xf3, 0xf3, 0xf3, 0xff, 0x84, 0x84, 0xff, 0x84, 0x84, 0xff, 0x84, 0x84, 0xff, 0x85, 0x85, 0xff, 0x83, 0x83, 0xff, 0x84, 0x84, 0xff, 0x84, 0x84, 0xff, 0x84, 0x84, 0xff, 0x84, 0x84, 0xff, 0x84, 0x84, 0xff, 0x80, 0x80, 0xff, 0x84, 0x84, 0xff, 0x84, 0x84, 0xff, 0x84, 0x84, 0xff, 0xff, 0xff, 0xa, 0xa5, 0x43, 0x1, 0x0, 0x0, 0x0, 0x10, 0x74, 0x52, 0x4e, 0x53, 0x0, 0xff, 0x1d, 0xac, 0xf2, 0xaf, 0x27, 0xed, 0xff, 0xee, 0xb4, 0x1b, 0x1c, 0xb6, 0xaa, 0xf1, 0x50, 0xa6, 0xdd, 0x5f, 0x0, 0x0, 0x0, 0x4e, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x62, 0x0, 0x2, 0x40, 0x23, 0xd3, 0x60, 0x0, 0x40, 0xc, 0x3, 0xaf, 0x76, 0x93, 0xfd, 0x97, 0x7d, 0x9b, 0x55, 0x70, 0x12, 0x62, 0xaf, 0x68, 0x0, 0xc4, 0xe9, 0x3c, 0x1, 0x67, 0xf7, 0x17, 0x20, 0x95, 0xd6, 0xc6, 0xee, 0x80, 0x74, 0xde, 0x7b, 0x1f, 0x24, 0xb0, 0x64, 0x29, 0x1f, 0x53, 0x2e, 0xbe, 0x6e, 0x80, 0xf6, 0x19, 0x90, 0x9e, 0x36, 0x8b, 0xf7, 0xc0, 0x5c, 0xdf, 0x0, 0x66, 0x60, 0xae, 0xf3, 0xb9, 0x1, 0xfb, 0xe9, 0x1, 0xa6, 0x26, 0x1, 0xcd, 0x30, 0x66, 0x63, 0x6, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char icon_stop_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x2, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x87, 0x8f, 0xcc, 0xbf, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x4, 0x4e, 0x1d, 0x2, 0xaf, 0x0, 0x0, 0x0, 0x2b, 0x49, 0x44, 0x41, 0x54, 0x28, 0xcf, 0x63, 0x60, 0x20, 0xc, 0x3e, 0x30, 0xe3, 0x93, 0x61, 0x64, 0x60, 0x60, 0x60, 0x78, 0xf8, 0x1f, 0xbb, 0x2, 0x79, 0x46, 0x6, 0x6, 0x26, 0x42, 0xe6, 0x8f, 0x2a, 0xa0, 0x96, 0x2, 0x6, 0x42, 0x91, 0x45, 0x10, 0x0, 0x0, 0x95, 0x31, 0x5, 0xe4, 0xe, 0x1, 0x8e, 0x3, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x1e, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x20, 0x2, 0x7c, 0x60, 0x26, 0x28, 0xf3, 0xf0, 0x3f, 0x76, 0x8, 0x94, 0xa2, 0x97, 0x82, 0x51, 0x5, 0x84, 0x23, 0x8b, 0x30, 0x0, 0x0, 0x66, 0x60, 0x11, 0xdc, 0x92, 0xb3, 0xb7, 0xe7, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char icon_zoom_less_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x25, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0x63, 0x60, 0x18, 0x5, 0xc3, 0x0, 0x30, 0x32, 0x30, 0x30, 0x30, 0x3c, 0x78, 0xf0, 0xe0, 0x3f, 0x39, 0x9a, 0x15, 0x14, 0x14, 0x18, 0x99, 0xa8, 0xeb, 0x9e, 0x51, 0x30, 0x44, 0x1, 0x0, 0xff, 0xa9, 0x4, 0x4, 0x4a, 0xae, 0x20, 0xfa, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x13, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x18, 0x31, 0xe0, 0xc1, 0x7f, 0x3c, 0x90, 0xb0, 0x82, 0x11, 0x2, 0x0, 0xbf, 0x57, 0x36, 0x25, 0x52, 0x24, 0x7b, 0x26, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char icon_zoom_more_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x36, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0x63, 0x60, 0xa0, 0x25, 0x78, 0xf0, 0xe0, 0xc1, 0xff, 0x7, 0xf, 0x1e, 0xfc, 0xc7, 0xa7, 0x86, 0x89, 0x52, 0x4b, 0x46, 0xd, 0x60, 0x60, 0x60, 0x64, 0x60, 0x80, 0x84, 0x36, 0x39, 0x9a, 0x15, 0x14, 0x14, 0x18, 0x29, 0x76, 0x1, 0x5e, 0x30, 0x9a, 0xe, 0xe8, 0x64, 0x0, 0xc5, 0x0, 0x0, 0xc7, 0x6e, 0x12, 0x94, 0xf9, 0x26, 0x2e, 0xdb, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x1c, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x20, 0x11, 0x3c, 0xf8, 0xf, 0x84, 0x43, 0x4a, 0x1, 0x42, 0x10, 0xf, 0x24, 0xa8, 0x60, 0x78, 0x84, 0x3, 0x61, 0x0, 0x0, 0xca, 0x3a, 0x6d, 0x8d, 0x50, 0x1e, 0x9a, 0xaa, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char icon_zoom_reset_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x6f, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xdd, 0x91, 0xbb, 0xd, 0x80, 0x30, 0x10, 0x43, 0x1f, 0x11, 0x23, 0x20, 0xea, 0x4c, 0xc5, 0x62, 0x48, 0xec, 0xc0, 0x56, 0x97, 0x26, 0x43, 0xa4, 0x31, 0x15, 0x12, 0x45, 0x72, 0x8a, 0x14, 0xa, 0x84, 0xab, 0xfb, 0x58, 0x3e, 0xeb, 0xc, 0x83, 0x98, 0xee, 0x22, 0xa5, 0xb4, 0x49, 0x3a, 0x1, 0x62, 0x8c, 0x53, 0x8d, 0x5c, 0xe3, 0x4, 0x80, 0x9c, 0xf3, 0x22, 0x69, 0xf7, 0x2e, 0xb5, 0x38, 0x1, 0xa0, 0x94, 0x72, 0x0, 0xab, 0x27, 0xd0, 0xc3, 0xc1, 0xcc, 0x64, 0x66, 0x6a, 0xf5, 0xb5, 0x59, 0x70, 0x15, 0x3b, 0x30, 0x7b, 0xcb, 0xd6, 0x33, 0x9f, 0x18, 0x76, 0xf0, 0x71, 0x81, 0x5a, 0xa, 0xaf, 0x3b, 0xf8, 0x41, 0xa, 0xc3, 0xb8, 0x0, 0x6c, 0x9c, 0x3f, 0xb8, 0x84, 0xfc, 0x5b, 0x85, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x33, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x20, 0xa, 0x3c, 0xc, 0x7b, 0xf0, 0xff, 0xc1, 0x7f, 0x9c, 0x22, 0xcf, 0x44, 0x1e, 0xbc, 0x84, 0x72, 0xb1, 0x8b, 0x3c, 0x58, 0x5, 0xe4, 0x40, 0xb8, 0x38, 0x45, 0x18, 0x60, 0x5c, 0x84, 0x30, 0x59, 0xa, 0xa0, 0x80, 0x6e, 0xa, 0x86, 0x92, 0x2f, 0x8, 0x3, 0x0, 0x69, 0xc8, 0x86, 0x87, 0x72, 0xca, 0x85, 0x23, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char line_edit_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0xa, 0x4, 0x3, 0x0, 0x0, 0x0, 0x7f, 0x1c, 0xd2, 0x8e, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x2a, 0x50, 0x4c, 0x54, 0x45, 0x17, 0x16, 0x1a, 0x1d, 0x1c, 0x21, 0x20, 0x1e, 0x24, 0x21, 0x1f, 0x25, 0x1d, 0x1c, 0x21, 0x20, 0x1e, 0x24, 0x1d, 0x1c, 0x21, 0x1d, 0x1c, 0x21, 0x24, 0x22, 0x29, 0x28, 0x26, 0x2d, 0x28, 0x26, 0x2e, 0x2b, 0x2a, 0x31, 0x2c, 0x2a, 0x32, 0xff, 0xff, 0xff, 0xb9, 0x11, 0x56, 0x3e, 0x0, 0x0, 0x0, 0x8, 0x74, 0x52, 0x4e, 0x53, 0x6f, 0xef, 0xf7, 0xf7, 0xf0, 0xf9, 0xf1, 0xee, 0xcf, 0x21, 0xd2, 0xdf, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0xd, 0xf6, 0xb4, 0x61, 0xf5, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x4, 0x4e, 0x1d, 0x2, 0xaf, 0x0, 0x0, 0x0, 0x2d, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0x54, 0x36, 0x36, 0x12, 0x60, 0xf0, 0x98, 0xb5, 0x6a, 0x65, 0xb, 0x43, 0xe4, 0x9e, 0x33, 0xa7, 0xa7, 0x32, 0x58, 0x9d, 0x39, 0x73, 0x66, 0x31, 0x16, 0x12, 0x22, 0xb, 0x52, 0xd9, 0xc6, 0xc0, 0x2, 0xd4, 0x55, 0x0, 0x0, 0xc, 0x14, 0x1a, 0x90, 0x55, 0x1a, 0xec, 0xdb, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0xa, 0x4, 0x3, 0x0, 0x0, 0x0, 0x7f, 0x1c, 0xd2, 0x8e, 0x0, 0x0, 0x0, 0x2a, 0x50, 0x4c, 0x54, 0x45, 0x17, 0x16, 0x1a, 0x1d, 0x1c, 0x21, 0x20, 0x1e, 0x24, 0x21, 0x1f, 0x25, 0x1d, 0x1c, 0x21, 0x20, 0x1e, 0x24, 0x1d, 0x1c, 0x21, 0x1d, 0x1c, 0x21, 0x24, 0x22, 0x29, 0x28, 0x26, 0x2d, 0x28, 0x26, 0x2e, 0x2b, 0x2a, 0x31, 0x2c, 0x2a, 0x32, 0xff, 0xff, 0xff, 0xb9, 0x11, 0x56, 0x3e, 0x0, 0x0, 0x0, 0x8, 0x74, 0x52, 0x4e, 0x53, 0x6f, 0xef, 0xf7, 0xf7, 0xf0, 0xf9, 0xf1, 0xee, 0xcf, 0x21, 0xd2, 0xdf, 0x0, 0x0, 0x0, 0x2d, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0x54, 0x36, 0x36, 0x12, 0x60, 0xf0, 0x98, 0xb5, 0x6a, 0x65, 0xb, 0x43, 0xe4, 0x9e, 0x33, 0xa7, 0xa7, 0x32, 0x58, 0x9d, 0x39, 0x73, 0x66, 0x31, 0x16, 0x12, 0x22, 0xb, 0x52, 0xd9, 0xc6, 0xc0, 0x2, 0xd4, 0x55, 0x0, 0x0, 0xc, 0x14, 0x1a, 0x90, 0x55, 0x1a, 0xec, 0xdb, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+};
+
+static const unsigned char line_edit_clear_png[] = {
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x65, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0xad, 0x90, 0x1, 0x6, 0xc0, 0x30, 0xc, 0x45, 0x77, 0x89, 0xd5, 0x76, 0xb3, 0x9e, 0x7b, 0x65, 0x63, 0xd, 0xf9, 0xbb, 0x48, 0x3b, 0xb3, 0x92, 0x54, 0x42, 0xb1, 0x5, 0x88, 0xf7, 0xc8, 0xcf, 0x9f, 0xfe, 0x1a, 0x8e, 0x14, 0xf4, 0x4e, 0x81, 0x63, 0x87, 0x51, 0x90, 0x28, 0x8, 0x46, 0x42, 0x51, 0x4a, 0x9e, 0x79, 0x43, 0xc5, 0x81, 0x55, 0x6f, 0xbc, 0x34, 0xdc, 0x2b, 0x2e, 0x16, 0xe5, 0x3a, 0xb1, 0xb, 0xb6, 0xca, 0x3, 0x2b, 0xb2, 0xc2, 0xbe, 0xf0, 0x66, 0x71, 0x4f, 0x70, 0x3b, 0x61, 0x14, 0x89, 0x26, 0x71, 0x5d, 0x6c, 0x9f, 0x1e, 0x17, 0x35, 0xae, 0xfa, 0xeb, 0xdc, 0x62, 0xc3, 0x84, 0x2d, 0x77, 0x22, 0xda, 0x98, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char line_edit_disabled_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0xa, 0x8, 0x4, 0x0, 0x0, 0x0, 0x27, 0x3b, 0x7, 0x36, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x2, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x87, 0x8f, 0xcc, 0xbf, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x64, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x95, 0xce, 0x31, 0x12, 0x2, 0x21, 0x10, 0x44, 0xd1, 0x3f, 0x40, 0xa1, 0x44, 0xa6, 0x46, 0xde, 0x63, 0x4f, 0xe5, 0x15, 0x38, 0xb2, 0xd6, 0x6, 0xb0, 0xc8, 0x30, 0x6, 0x96, 0xac, 0x56, 0x99, 0xf8, 0xb3, 0x7e, 0x51, 0xcb, 0xf9, 0x1a, 0xb3, 0x3f, 0xa, 0xaf, 0xc, 0xad, 0x2d, 0xcb, 0xe5, 0x76, 0x38, 0x5, 0x76, 0xec, 0x6c, 0xf7, 0xe0, 0x53, 0xe0, 0x13, 0xa1, 0x27, 0x27, 0x43, 0x26, 0x81, 0x20, 0xc8, 0x70, 0xfc, 0xe8, 0xf, 0x34, 0x67, 0xd8, 0x9c, 0x86, 0x61, 0x2e, 0x68, 0xe9, 0x91, 0xaf, 0x4b, 0x5a, 0x7d, 0x2a, 0x2c, 0x3, 0xed, 0xef, 0x1e, 0x6b, 0xcb, 0x4f, 0xa6, 0x66, 0x2b, 0x25, 0x6, 0x1, 0x37, 0x40, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0xa, 0x8, 0x4, 0x0, 0x0, 0x0, 0x27, 0x3b, 0x7, 0x36, 0x0, 0x0, 0x0, 0x4e, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x94, 0xc8, 0x67, 0x6b, 0x60, 0xe6, 0x60, 0x64, 0x80, 0x80, 0xff, 0xc, 0x7f, 0x7f, 0xfc, 0x6a, 0x60, 0x94, 0xfb, 0xc0, 0xce, 0xcf, 0xc2, 0x80, 0x10, 0xfc, 0xc3, 0xf0, 0xf3, 0x23, 0xa3, 0xe2, 0x4f, 0xe, 0x36, 0x54, 0xc1, 0x1f, 0xbf, 0x18, 0x95, 0xbe, 0x73, 0x70, 0xb0, 0x30, 0xc0, 0x1, 0x48, 0xf0, 0x7, 0x85, 0x82, 0x58, 0x2d, 0xc2, 0xe6, 0xa4, 0x4f, 0x20, 0xc7, 0x37, 0x32, 0xb3, 0x23, 0x39, 0xfe, 0xfb, 0xaf, 0x46, 0x0, 0xee, 0x2a, 0x2f, 0xce, 0x4c, 0x47, 0x66, 0xf6, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char line_edit_focus_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0xab, 0x50, 0x4c, 0x54, 0x45, 0x1b, 0x17, 0x18, 0x1b, 0x17, 0x18, 0x1b, 0x17, 0x18, 0xc8, 0x68, 0x12, 0xef, 0xed, 0xe7, 0xef, 0xed, 0xe8, 0xf0, 0xed, 0xe8, 0xf0, 0xee, 0xe8, 0xf0, 0xed, 0xe7, 0xed, 0xeb, 0xe5, 0xee, 0xeb, 0xe5, 0xee, 0xeb, 0xe6, 0xec, 0xe9, 0xe3, 0xeb, 0xe9, 0xe3, 0xeb, 0xe9, 0xe2, 0xec, 0xe9, 0xe2, 0xe9, 0xe6, 0xe0, 0xea, 0xe7, 0xe0, 0xea, 0xe7, 0xe1, 0xe8, 0xe4, 0xdd, 0xe8, 0xe5, 0xde, 0xe8, 0xe5, 0xdd, 0xe8, 0xe4, 0xde, 0xe6, 0xe2, 0xdb, 0xe6, 0xe3, 0xdb, 0xe6, 0xe3, 0xdc, 0xe7, 0xe2, 0xdb, 0xe7, 0xe3, 0xdb, 0xe4, 0xe0, 0xd8, 0xe5, 0xe0, 0xd8, 0xe5, 0xe1, 0xd9, 0xe5, 0xe0, 0xd9, 0xe4, 0xe1, 0xd9, 0xe5, 0xe1, 0xd8, 0xe4, 0xe0, 0xd9, 0xe2, 0xdf, 0xd6, 0xe3, 0xdf, 0xd6, 0xe3, 0xde, 0xd6, 0xe2, 0xde, 0xd6, 0xe1, 0xdc, 0xd4, 0xe1, 0xdc, 0xd3, 0xe0, 0xdc, 0xd3, 0xe1, 0xdd, 0xd3, 0xe1, 0xdd, 0xd4, 0xdf, 0xda, 0xd0, 0xdf, 0xda, 0xd1, 0xdf, 0xdb, 0xd1, 0xe0, 0xda, 0xd1, 0xdd, 0xd8, 0xcf, 0xdd, 0xd8, 0xce, 0xde, 0xd9, 0xce, 0xde, 0xd8, 0xce, 0xdd, 0xd9, 0xce, 0xdc, 0xd6, 0xcc, 0xdb, 0xd6, 0xcc, 0xdc, 0xd6, 0xcb, 0xff, 0xff, 0xff, 0x73, 0x72, 0x65, 0x6f, 0x0, 0x0, 0x0, 0x2, 0x74, 0x52, 0x4e, 0x53, 0x36, 0x61, 0xc5, 0x3a, 0xd, 0x83, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x38, 0xa0, 0x7, 0xa5, 0xd6, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x9e, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x5d, 0xcf, 0xdb, 0x16, 0x82, 0x20, 0x10, 0x85, 0x61, 0xb4, 0xb4, 0x13, 0x1d, 0x28, 0x14, 0xcb, 0x4a, 0x33, 0xf, 0x59, 0x52, 0x98, 0x62, 0xef, 0xff, 0x66, 0xd1, 0xf6, 0xca, 0xfe, 0x19, 0xd6, 0x62, 0x7d, 0x77, 0x43, 0x88, 0x3d, 0x88, 0x10, 0x7b, 0x34, 0xc8, 0x36, 0x30, 0x76, 0x1c, 0x77, 0xe2, 0x3a, 0xee, 0xd4, 0x7c, 0x0, 0xb3, 0x79, 0x3f, 0xa6, 0x5, 0x80, 0xa2, 0x25, 0xa5, 0xab, 0x35, 0x5, 0x6c, 0x18, 0x63, 0x5b, 0xd6, 0x7, 0xd8, 0x71, 0xcf, 0xe3, 0x9c, 0xfb, 0x9c, 0x7b, 0x3e, 0x40, 0x4, 0xfb, 0xe0, 0x10, 0x84, 0xa1, 0x8, 0x85, 0x0, 0x1c, 0x4f, 0xe7, 0x28, 0xbe, 0x44, 0x71, 0x9c, 0x24, 0x67, 0xc0, 0x35, 0x4d, 0xb3, 0x2c, 0xcb, 0xcd, 0x4b, 0x73, 0x40, 0x71, 0x33, 0x15, 0xe5, 0xfd, 0x51, 0x16, 0x25, 0xa0, 0x92, 0xf2, 0xf9, 0x92, 0xbf, 0x2a, 0x9, 0x50, 0xaa, 0x56, 0xef, 0x46, 0xb5, 0x4d, 0x5b, 0x37, 0x0, 0xdd, 0x7d, 0xb4, 0x36, 0xdb, 0x69, 0xad, 0x1, 0x7f, 0xc7, 0x59, 0xc3, 0xf3, 0xad, 0x2f, 0x30, 0x4f, 0x11, 0x50, 0x3e, 0x12, 0x48, 0xdb, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0xa8, 0x50, 0x4c, 0x54, 0x45, 0x1b, 0x17, 0x18, 0x1b, 0x17, 0x18, 0x1b, 0x17, 0x18, 0xc8, 0x68, 0x12, 0xef, 0xed, 0xe7, 0xef, 0xed, 0xe8, 0xf0, 0xed, 0xe8, 0xf0, 0xee, 0xe8, 0xf0, 0xed, 0xe7, 0xed, 0xeb, 0xe5, 0xee, 0xeb, 0xe5, 0xee, 0xeb, 0xe6, 0xec, 0xe9, 0xe3, 0xeb, 0xe9, 0xe3, 0xeb, 0xe9, 0xe2, 0xec, 0xe9, 0xe2, 0xe9, 0xe6, 0xe0, 0xea, 0xe7, 0xe0, 0xea, 0xe7, 0xe1, 0xe8, 0xe4, 0xdd, 0xe8, 0xe5, 0xde, 0xe8, 0xe5, 0xdd, 0xe8, 0xe4, 0xde, 0xe6, 0xe2, 0xdb, 0xe6, 0xe3, 0xdb, 0xe6, 0xe3, 0xdc, 0xe7, 0xe2, 0xdb, 0xe7, 0xe3, 0xdb, 0xe4, 0xe0, 0xd8, 0xe5, 0xe0, 0xd8, 0xe5, 0xe1, 0xd9, 0xe5, 0xe0, 0xd9, 0xe4, 0xe1, 0xd9, 0xe5, 0xe1, 0xd8, 0xe4, 0xe0, 0xd9, 0xe2, 0xdf, 0xd6, 0xe3, 0xdf, 0xd6, 0xe3, 0xde, 0xd6, 0xe2, 0xde, 0xd6, 0xe1, 0xdc, 0xd4, 0xe1, 0xdc, 0xd3, 0xe0, 0xdc, 0xd3, 0xe1, 0xdd, 0xd3, 0xe1, 0xdd, 0xd4, 0xdf, 0xda, 0xd0, 0xdf, 0xda, 0xd1, 0xdf, 0xdb, 0xd1, 0xe0, 0xda, 0xd1, 0xdd, 0xd8, 0xcf, 0xdd, 0xd8, 0xce, 0xde, 0xd9, 0xce, 0xde, 0xd8, 0xce, 0xdd, 0xd9, 0xce, 0xdc, 0xd6, 0xcc, 0xdb, 0xd6, 0xcc, 0xdc, 0xd6, 0xcb, 0xbd, 0x92, 0xbc, 0xa2, 0x0, 0x0, 0x0, 0x2, 0x74, 0x52, 0x4e, 0x53, 0x36, 0x61, 0xc5, 0x3a, 0xd, 0x83, 0x0, 0x0, 0x0, 0x72, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x4c, 0x8c, 0x55, 0x2, 0x4, 0x1, 0x8, 0x85, 0xc0, 0xc9, 0xfb, 0x1f, 0x76, 0x7b, 0x75, 0x3a, 0xf0, 0xc7, 0xc0, 0x27, 0xc1, 0x9d, 0x34, 0xe4, 0x4e, 0xb5, 0xa0, 0x68, 0x95, 0xf1, 0x93, 0xc4, 0xb0, 0xb7, 0xd6, 0x2, 0x7c, 0x2d, 0x46, 0xc3, 0x82, 0x45, 0xf8, 0x87, 0x16, 0x5a, 0xd7, 0x71, 0x21, 0x9e, 0x2c, 0x86, 0x52, 0x10, 0x89, 0xee, 0x86, 0x15, 0xd9, 0xf0, 0x6b, 0x7f, 0xac, 0x8b, 0xce, 0x85, 0xb4, 0x8b, 0xe1, 0xb7, 0x2e, 0x6, 0xd9, 0x53, 0x6a, 0x3c, 0x43, 0xa9, 0xd0, 0xcc, 0xd8, 0x5f, 0xd0, 0x4, 0xa2, 0xf6, 0x50, 0xac, 0x68, 0xff, 0x6d, 0xf9, 0x3f, 0xc, 0x93, 0x88, 0x59, 0x68, 0x81, 0x69, 0x18, 0x9e, 0x3, 0xba, 0x1b, 0x55, 0x0, 0x0, 0x0, 0x69, 0x26, 0x8d, 0xeb, 0x4b, 0xad, 0xe7, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char logo_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x80, 0x0, 0x0, 0x0, 0x80, 0x8, 0x6, 0x0, 0x0, 0x0, 0xc3, 0x3e, 0x61, 0xcb, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0x2e, 0x23, 0x0, 0x0, 0x2e, 0x23, 0x1, 0x78, 0xa5, 0x3f, 0x76, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xdc, 0x9, 0x7, 0x13, 0x2, 0x0, 0x15, 0xb9, 0x53, 0x97, 0x0, 0x0, 0x21, 0x58, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0xed, 0x7d, 0x79, 0x9c, 0x1c, 0x55, 0xb5, 0xff, 0xf7, 0x7b, 0xab, 0x7b, 0x66, 0x48, 0x8, 0x61, 0xd1, 0x90, 0xb0, 0x88, 0x91, 0x27, 0x24, 0x24, 0x21, 0x3b, 0x8, 0x4, 0x42, 0x58, 0x54, 0xe0, 0x91, 0x80, 0x24, 0x1, 0x2, 0x9, 0x42, 0x80, 0x4, 0x11, 0x90, 0x9f, 0xf2, 0xd3, 0xa7, 0xcf, 0xe7, 0xf3, 0x3d, 0x1f, 0x1f, 0x7f, 0xea, 0xd3, 0x48, 0x4c, 0x8, 0x61, 0xd, 0x49, 0x64, 0x89, 0x82, 0x40, 0x58, 0x4, 0x64, 0xb, 0x44, 0x25, 0x9b, 0xd9, 0x51, 0x14, 0x41, 0x3, 0xc8, 0x16, 0x20, 0xfb, 0x4c, 0x77, 0xdd, 0xef, 0xef, 0x8f, 0xaa, 0xea, 0xae, 0xee, 0xa9, 0xea, 0x9e, 0xee, 0xae, 0x99, 0xe9, 0xe0, 0x9c, 0xf9, 0xd4, 0x74, 0xd5, 0xad, 0x5b, 0x77, 0x39, 0xe7, 0xdc, 0x7b, 0xcf, 0x39, 0xf7, 0xdc, 0x7b, 0x81, 0x2e, 0xe8, 0x82, 0x2e, 0xe8, 0x82, 0x2e, 0xe8, 0x82, 0x2e, 0xe8, 0x82, 0x2e, 0xe8, 0x82, 0x2e, 0xf8, 0xe7, 0x2, 0x76, 0x76, 0x1, 0xea, 0x1, 0xe, 0xff, 0xc2, 0xcc, 0xbd, 0x60, 0x5b, 0x6e, 0xb6, 0xd6, 0xf6, 0x2, 0xb8, 0x8d, 0xc6, 0x6c, 0x36, 0x34, 0x6f, 0x81, 0x7c, 0x43, 0x30, 0x7f, 0x27, 0xcd, 0xdf, 0x8c, 0xe3, 0x6c, 0xda, 0x70, 0xef, 0xf4, 0x37, 0x3b, 0xbb, 0xac, 0x49, 0x43, 0xaa, 0xb3, 0xb, 0x50, 0xf, 0x20, 0x9b, 0xfd, 0x96, 0xcd, 0xb6, 0x4c, 0x40, 0xd0, 0x20, 0x2c, 0xac, 0x4b, 0xb3, 0x3, 0xc0, 0x36, 0x80, 0x5b, 0x41, 0x6c, 0x75, 0x5b, 0xb8, 0xed, 0xb0, 0x71, 0xff, 0xbb, 0x83, 0xc6, 0x6c, 0x26, 0x9d, 0x65, 0x74, 0xd2, 0x4f, 0x6e, 0x5c, 0x74, 0xc5, 0xba, 0xce, 0x2e, 0x7b, 0xad, 0xf0, 0x4f, 0xdf, 0x3, 0xf4, 0x9f, 0x38, 0xb7, 0x5b, 0x76, 0xd7, 0x7, 0x2f, 0xcb, 0xda, 0x3, 0xc8, 0x42, 0x94, 0x48, 0x6a, 0x15, 0x9f, 0x24, 0x0, 0xbe, 0x43, 0xe3, 0xfc, 0xc1, 0x49, 0x37, 0x4d, 0xdd, 0xf8, 0x8b, 0x2b, 0xff, 0xde, 0xd9, 0x75, 0xa8, 0x5, 0x76, 0x2b, 0x6, 0xe8, 0x37, 0x7e, 0xf6, 0x18, 0xeb, 0xb6, 0x9c, 0x6, 0x69, 0xf, 0x1a, 0xf3, 0xc1, 0x1f, 0xef, 0xbb, 0xe6, 0xdb, 0xb5, 0xa4, 0x37, 0xf2, 0x9a, 0xa5, 0xdc, 0xb2, 0x69, 0xe5, 0x69, 0xca, 0xec, 0xf8, 0xa5, 0xa4, 0x26, 0x48, 0xf2, 0x29, 0x8c, 0x82, 0x7b, 0x40, 0x3e, 0xae, 0xfc, 0x5f, 0x41, 0x82, 0x4d, 0x37, 0xf5, 0x18, 0xb7, 0xd7, 0xc1, 0xc3, 0x1f, 0xfe, 0xfd, 0x4f, 0x3e, 0xa3, 0x2a, 0x8b, 0xd0, 0xe9, 0x50, 0xf7, 0xc, 0x70, 0xf8, 0x39, 0xb3, 0x3e, 0x9, 0xb9, 0xa7, 0x48, 0xf6, 0x70, 0xb9, 0xd9, 0xd1, 0x90, 0x3b, 0xd2, 0x2b, 0x39, 0x9b, 0x4d, 0xaa, 0x69, 0xfa, 0x1f, 0xef, 0xbb, 0xfa, 0x8e, 0x5a, 0xd2, 0x3f, 0x6c, 0xdc, 0x8f, 0x9f, 0x91, 0xcd, 0x8c, 0x2, 0xe9, 0xe4, 0x43, 0x3, 0x7a, 0xc7, 0x80, 0x4, 0x80, 0xbb, 0x9c, 0x74, 0xd3, 0x77, 0xdd, 0xcc, 0xce, 0x1f, 0xbc, 0xfc, 0xd0, 0xd7, 0x6d, 0x67, 0xe3, 0xa9, 0x5a, 0xa8, 0x5b, 0x19, 0xa0, 0xdf, 0xf8, 0xd9, 0x47, 0x42, 0xee, 0x51, 0x72, 0x5b, 0x3e, 0x6b, 0xdd, 0xcc, 0x69, 0x0, 0xf6, 0xf4, 0x8, 0xe3, 0x75, 0xc3, 0x92, 0x1a, 0x6d, 0x66, 0xd7, 0x8f, 0xfa, 0x8d, 0x9f, 0xf5, 0xe7, 0x97, 0x7e, 0x71, 0xe5, 0xf3, 0x55, 0xe5, 0x31, 0xe1, 0xc6, 0x83, 0xdc, 0x5d, 0x5b, 0x46, 0x3, 0x7e, 0xb3, 0xce, 0x51, 0xbd, 0x74, 0xbb, 0xf0, 0x9b, 0xbb, 0x23, 0xd9, 0x23, 0x59, 0xf7, 0x4d, 0xa8, 0x34, 0xd4, 0x1d, 0x3, 0xf4, 0x3b, 0x67, 0xf6, 0x20, 0xc0, 0x1d, 0x65, 0xb3, 0xcd, 0x67, 0xc9, 0xcd, 0x9c, 0xa, 0x9f, 0x1a, 0xfe, 0xd8, 0x5b, 0xd0, 0x15, 0xb, 0xda, 0xcf, 0x66, 0x9a, 0x7f, 0xd8, 0x7f, 0xc2, 0x9c, 0xb1, 0x1b, 0x17, 0x4d, 0x7f, 0xa7, 0x92, 0x7c, 0xe, 0xff, 0xc2, 0xd, 0x69, 0x58, 0x77, 0x1c, 0x40, 0x17, 0x84, 0x3, 0x54, 0x48, 0x4a, 0xd2, 0x91, 0x75, 0x7, 0x38, 0x4d, 0x7b, 0xef, 0xd6, 0x2c, 0x50, 0x37, 0xc, 0xd0, 0x7f, 0xc2, 0x8d, 0x7, 0x3, 0x1a, 0x65, 0x33, 0xcd, 0x97, 0x58, 0x9b, 0x3d, 0x5, 0x0, 0x40, 0xe6, 0x5a, 0xa6, 0x82, 0x47, 0xbf, 0x13, 0x0, 0x21, 0x82, 0x90, 0xdc, 0xcf, 0xc8, 0x66, 0xbe, 0xd6, 0x6f, 0xfc, 0xac, 0xef, 0xbc, 0xf4, 0x8b, 0x2b, 0x77, 0xb5, 0x35, 0x3f, 0x93, 0x6a, 0xb4, 0x36, 0xb3, 0xe3, 0x7c, 0x1a, 0xe3, 0x8f, 0xe9, 0xe1, 0x21, 0x3f, 0x4, 0xe1, 0xd1, 0x40, 0x80, 0x24, 0xd1, 0x90, 0x10, 0x8c, 0x64, 0xf, 0x31, 0xa9, 0xa6, 0x2e, 0x6, 0x48, 0x2, 0x64, 0xb3, 0xdf, 0xb0, 0xd9, 0xe6, 0x2f, 0x1, 0x41, 0x6b, 0xf7, 0x9, 0x2f, 0x91, 0x1e, 0x23, 0x78, 0x40, 0x9f, 0x8, 0x34, 0x41, 0x90, 0x75, 0x33, 0xbb, 0xfe, 0xaf, 0xd3, 0xd0, 0x7d, 0xd9, 0x61, 0xe3, 0x7e, 0x78, 0xdf, 0x9f, 0x1e, 0xb8, 0x2e, 0x72, 0x3c, 0x1e, 0x30, 0xe9, 0xce, 0x94, 0xdb, 0xb2, 0x7d, 0x1f, 0xd2, 0xf4, 0x0, 0x6c, 0x1a, 0xb2, 0xbd, 0x65, 0xdd, 0xcf, 0x0, 0x30, 0x0, 0x41, 0x42, 0x91, 0xbd, 0x0, 0xb, 0xef, 0x49, 0x52, 0x9e, 0x7a, 0x40, 0x48, 0x7b, 0xee, 0x6, 0x62, 0x54, 0x49, 0xa8, 0x1b, 0x6, 0xb0, 0xd9, 0xcc, 0x39, 0x7e, 0x6b, 0xb, 0xda, 0x5c, 0xa8, 0xeb, 0x2f, 0x4, 0x7a, 0x81, 0x41, 0x3c, 0x3, 0x10, 0x36, 0xbb, 0xeb, 0xc7, 0x4e, 0x43, 0x8f, 0xd7, 0xfa, 0x4f, 0xb8, 0x71, 0x3, 0x68, 0xf6, 0x7, 0xb0, 0x37, 0x81, 0x34, 0x8, 0xca, 0xda, 0x46, 0xb7, 0x65, 0xeb, 0x27, 0x20, 0x3b, 0xd8, 0x75, 0xdd, 0xbe, 0x4, 0xf6, 0x83, 0x74, 0x30, 0x80, 0x40, 0xf0, 0x53, 0x25, 0x43, 0x0, 0xfd, 0xff, 0x22, 0xad, 0xcd, 0xee, 0xac, 0x59, 0x3, 0xe8, 0x7f, 0xee, 0x2d, 0xdd, 0x36, 0xde, 0x73, 0xe9, 0x8e, 0xce, 0xc0, 0x7b, 0xdd, 0x30, 0x0, 0x8d, 0xf3, 0xb2, 0xac, 0x3e, 0xe, 0xc0, 0x20, 0x4e, 0xc, 0xf, 0xc8, 0x1e, 0x3c, 0xf9, 0x8a, 0x3a, 0x49, 0x40, 0xf6, 0x60, 0xeb, 0xb6, 0xfc, 0x1f, 0xd2, 0xac, 0xb3, 0xb6, 0xf9, 0x24, 0x78, 0xad, 0xbb, 0x9b, 0x17, 0xb5, 0x90, 0x46, 0xca, 0x25, 0x46, 0x85, 0x52, 0x8e, 0xcb, 0xa7, 0x30, 0xdc, 0x4a, 0xa0, 0x21, 0xe8, 0x7d, 0xed, 0x36, 0x6f, 0xad, 0x89, 0x1, 0x8e, 0x38, 0x77, 0x6e, 0x5f, 0xeb, 0xb6, 0x9c, 0xde, 0x7f, 0xc2, 0x9c, 0xe7, 0x36, 0x2e, 0x9a, 0xbe, 0xb6, 0xc3, 0xf1, 0xde, 0xd1, 0x19, 0xc6, 0x41, 0xff, 0x9, 0xb3, 0xbf, 0x67, 0x33, 0xcd, 0x5f, 0x96, 0x6c, 0xcf, 0x70, 0xab, 0x8f, 0xa3, 0x43, 0x41, 0xb8, 0x4, 0x90, 0x16, 0x80, 0x41, 0xd8, 0x78, 0x43, 0x6, 0xef, 0x8a, 0xf4, 0x7a, 0x9, 0xf2, 0xfa, 0x7d, 0xff, 0xb1, 0x40, 0x0, 0x60, 0x51, 0xde, 0xc5, 0xf9, 0x11, 0x39, 0x23, 0x51, 0xd6, 0x69, 0xdc, 0xf3, 0x18, 0xc9, 0xbe, 0x61, 0x9c, 0x86, 0xad, 0x1b, 0xee, 0x9e, 0xba, 0xb5, 0xad, 0xf5, 0x3d, 0xe2, 0xbc, 0x5b, 0xbb, 0xc1, 0xba, 0x9f, 0xc8, 0x66, 0xb6, 0x2f, 0x86, 0x74, 0x28, 0x80, 0xb7, 0x4d, 0xba, 0xdb, 0xb9, 0xc6, 0x38, 0x4b, 0x37, 0xdc, 0x73, 0x59, 0x4b, 0x47, 0xe1, 0xbd, 0x6e, 0x18, 0xa0, 0xdf, 0x84, 0x39, 0xa7, 0x2b, 0xb3, 0x73, 0x2e, 0xa0, 0x3, 0x81, 0x60, 0x9c, 0x6f, 0x73, 0xb7, 0x1c, 0xc8, 0xb, 0x20, 0xf3, 0xad, 0x3a, 0xf4, 0x9c, 0x78, 0x3d, 0x95, 0x37, 0x13, 0x92, 0xc6, 0xf9, 0xb, 0x9d, 0xf4, 0x22, 0x63, 0x52, 0xb7, 0x3, 0x78, 0x3d, 0xdb, 0xbc, 0x6d, 0xe7, 0x9f, 0x1e, 0xf8, 0x6a, 0xac, 0x6d, 0xa0, 0xff, 0x84, 0x39, 0xfb, 0x4b, 0xee, 0x14, 0x9b, 0x69, 0xfe, 0x41, 0x90, 0x9a, 0x2f, 0x5b, 0xc0, 0xa4, 0x9b, 0xfe, 0xcd, 0x18, 0xe7, 0x96, 0xd, 0xf7, 0x4e, 0x7f, 0xb7, 0x23, 0xf0, 0x5e, 0x37, 0xc, 0xd0, 0xff, 0xdc, 0x9b, 0x3f, 0x65, 0x5b, 0xb6, 0x3f, 0x21, 0xd9, 0x4f, 0x41, 0x8, 0x24, 0xed, 0xb6, 0x95, 0x56, 0x65, 0xde, 0x25, 0x55, 0x53, 0x3f, 0xad, 0x9c, 0x26, 0xe0, 0x3f, 0x14, 0xf4, 0x1e, 0x26, 0x75, 0x3f, 0x9d, 0x86, 0x9f, 0xd2, 0x49, 0xaf, 0xec, 0xd1, 0xfb, 0x88, 0x6d, 0xc5, 0x56, 0xc2, 0xfe, 0x13, 0x6f, 0x3a, 0xcc, 0x66, 0x9b, 0xe7, 0x40, 0xee, 0x18, 0x0, 0x5e, 0xaf, 0x15, 0x24, 0x3, 0x8, 0x24, 0x8d, 0xd3, 0x70, 0x13, 0x4c, 0xea, 0xfb, 0x1b, 0xef, 0x9d, 0xf6, 0x6a, 0x7b, 0xe3, 0xdd, 0xb4, 0x77, 0x6, 0x6d, 0x85, 0x8d, 0xf7, 0x5c, 0xf6, 0xa, 0x69, 0x9a, 0x3d, 0x51, 0x3b, 0xc0, 0x26, 0xfd, 0xb, 0xa5, 0x9, 0x58, 0xaa, 0xa3, 0x28, 0xf7, 0x6d, 0x25, 0xe0, 0xa7, 0x95, 0x27, 0x3e, 0x94, 0xcf, 0xc0, 0xd3, 0x26, 0xad, 0x9b, 0x3d, 0xdb, 0x6d, 0xd9, 0xf1, 0x8c, 0x6d, 0xd9, 0xfe, 0xdc, 0x96, 0xd7, 0x57, 0x9f, 0x11, 0xfe, 0xfc, 0x88, 0x73, 0xe7, 0x9e, 0xec, 0xb6, 0xec, 0xd8, 0x28, 0xeb, 0x8e, 0xf1, 0xbe, 0xf5, 0xf1, 0x2f, 0x88, 0xa0, 0xcf, 0x48, 0xb4, 0xd6, 0x6d, 0x99, 0x66, 0xb3, 0x2d, 0xf3, 0xfb, 0x4f, 0x9c, 0x7b, 0x5c, 0x7b, 0xe3, 0xbd, 0x6e, 0x7a, 0x0, 0x0, 0xe8, 0x77, 0xce, 0xcf, 0x9e, 0xb3, 0x6e, 0xe6, 0x78, 0x20, 0x5a, 0xfa, 0xaf, 0x3f, 0x8, 0x86, 0x81, 0x7c, 0x61, 0xfd, 0x91, 0x41, 0x64, 0xa0, 0x5a, 0x38, 0x2b, 0x4c, 0xba, 0xf1, 0x3b, 0x4, 0x7a, 0x66, 0x5b, 0x76, 0x2c, 0xf4, 0xf8, 0xbb, 0xd5, 0xb0, 0x54, 0xd0, 0x4f, 0x5, 0x6a, 0x26, 0x8d, 0x79, 0x8d, 0x4e, 0xd3, 0xbf, 0xbd, 0xb4, 0x68, 0xda, 0x5d, 0xed, 0x55, 0x3, 0xa7, 0xf6, 0x24, 0x92, 0x83, 0x8f, 0xf, 0x1c, 0x9b, 0x2, 0x34, 0x9c, 0x40, 0x8f, 0x78, 0xcb, 0x4c, 0x3d, 0x41, 0xd0, 0x45, 0xf9, 0xe0, 0xcb, 0x2d, 0xbe, 0xd5, 0x92, 0x14, 0x24, 0xa2, 0xb7, 0x6c, 0x76, 0x82, 0xac, 0x7b, 0x16, 0x29, 0x27, 0x50, 0x21, 0x1, 0x85, 0xba, 0xba, 0x5c, 0x37, 0xe2, 0xdb, 0xbb, 0x72, 0x36, 0xb0, 0xbd, 0x61, 0xdd, 0x13, 0xf7, 0x3f, 0xf2, 0xec, 0x96, 0x77, 0xd6, 0x2f, 0xfe, 0x5d, 0x7b, 0xd4, 0xa0, 0x6e, 0x86, 0x0, 0xaf, 0x34, 0xce, 0x12, 0x0, 0xef, 0x7b, 0xf7, 0x86, 0xf9, 0x21, 0x60, 0x37, 0xb9, 0x8c, 0xf1, 0x94, 0xc3, 0x80, 0x71, 0x69, 0x40, 0xd2, 0x90, 0x6c, 0x0, 0xd4, 0x0, 0x18, 0x79, 0x17, 0x8, 0x18, 0x45, 0xa4, 0xe1, 0x31, 0x81, 0x31, 0xfe, 0x7b, 0x3, 0x40, 0xfb, 0x65, 0x33, 0xbb, 0xbe, 0xde, 0x6f, 0xc2, 0x9c, 0xaf, 0xb4, 0x7, 0xca, 0xeb, 0xa6, 0x7, 0xe8, 0x3f, 0x71, 0xee, 0x4, 0x4f, 0x38, 0x52, 0x3f, 0xf8, 0xb6, 0x9e, 0xd0, 0xe8, 0xba, 0xfb, 0x5c, 0x44, 0xae, 0xfd, 0xe7, 0xee, 0x1, 0xbf, 0x67, 0x80, 0x7f, 0x11, 0xa1, 0x77, 0x45, 0xdf, 0x93, 0xa1, 0x74, 0x82, 0x1e, 0x61, 0x4f, 0xca, 0xe, 0xea, 0x35, 0xe8, 0x2c, 0xe7, 0x9d, 0xf5, 0x8b, 0x97, 0x26, 0x89, 0xf7, 0xba, 0x30, 0x4, 0xf5, 0x9f, 0x78, 0xd3, 0x2c, 0x9b, 0xdd, 0x75, 0x36, 0xa0, 0x3e, 0xde, 0x18, 0x69, 0x24, 0x28, 0x6c, 0x0, 0xde, 0x1d, 0x81, 0x31, 0xf7, 0x6d, 0x6, 0x6f, 0x14, 0xf4, 0x70, 0x21, 0xb0, 0x1b, 0xc8, 0xee, 0x49, 0x17, 0xb2, 0xd3, 0x19, 0xe0, 0xf0, 0x73, 0x66, 0x3d, 0xad, 0x6c, 0xcb, 0x48, 0x0, 0xdd, 0xbd, 0x39, 0x1e, 0xdf, 0x74, 0x53, 0xef, 0xc3, 0x7f, 0x87, 0x40, 0xce, 0xe4, 0xd, 0x1a, 0x67, 0xb5, 0x71, 0xd2, 0xd7, 0x27, 0x9d, 0x43, 0x62, 0xc, 0x70, 0xc4, 0xb9, 0x73, 0x7f, 0x24, 0x61, 0x1b, 0x8d, 0xf3, 0xd3, 0xd, 0x77, 0x4f, 0x7d, 0xbf, 0x5c, 0xfc, 0x81, 0x93, 0xee, 0xd8, 0x23, 0xdb, 0xb2, 0xe3, 0x31, 0xd9, 0xec, 0x9, 0x5e, 0x3f, 0x97, 0x13, 0x80, 0xbb, 0x88, 0xef, 0x83, 0x6f, 0xc0, 0x24, 0xe9, 0xbc, 0x63, 0x9c, 0xf4, 0xe2, 0x75, 0x3f, 0xbf, 0x38, 0x71, 0xb, 0x61, 0x22, 0x98, 0x3e, 0xe2, 0xbc, 0x5b, 0x47, 0xd8, 0xcc, 0xce, 0x7, 0x25, 0x75, 0xa3, 0x71, 0xd6, 0x80, 0xe6, 0x75, 0xd2, 0xfc, 0x99, 0xc6, 0x99, 0xb7, 0xe1, 0xee, 0xa9, 0x7f, 0x2e, 0x8e, 0xdf, 0xff, 0xdc, 0x5b, 0xe, 0x95, 0xdb, 0x72, 0x87, 0x6c, 0x76, 0x14, 0xe9, 0xab, 0xc2, 0x5e, 0x4d, 0xe1, 0x49, 0xc7, 0x51, 0xc5, 0x8c, 0x33, 0xb9, 0x87, 0xe7, 0x85, 0x54, 0xe2, 0x9b, 0x62, 0x3, 0x6f, 0xb9, 0xb4, 0x63, 0xb5, 0xb4, 0x88, 0xf0, 0xa8, 0xef, 0x2a, 0x29, 0x6f, 0xeb, 0x6f, 0x72, 0xbe, 0x67, 0x0, 0x41, 0xe7, 0x91, 0x74, 0xd3, 0x9e, 0xe3, 0xd7, 0x2e, 0x98, 0xb2, 0xb3, 0x1a, 0xfa, 0x94, 0x82, 0x9a, 0x19, 0xe0, 0x88, 0xf3, 0xe7, 0xf5, 0x50, 0x76, 0xc7, 0xc3, 0xb2, 0xee, 0x71, 0x80, 0x42, 0x5a, 0x85, 0xd9, 0x42, 0x63, 0xd6, 0x80, 0xce, 0x4a, 0x1a, 0xe7, 0x77, 0x26, 0x95, 0x7e, 0x74, 0xdd, 0x82, 0x29, 0x1f, 0x1c, 0x71, 0xfe, 0x6d, 0x43, 0x6c, 0x66, 0xd7, 0x4d, 0x90, 0x7b, 0x54, 0xa8, 0x18, 0xc2, 0x6e, 0x3e, 0xe0, 0x27, 0xa, 0xca, 0xd9, 0x1c, 0x9, 0x3a, 0xaf, 0x9a, 0x54, 0xc3, 0xbf, 0x6f, 0xb8, 0xfb, 0xd2, 0x85, 0xed, 0x91, 0x55, 0xcd, 0x43, 0x80, 0xdc, 0xe6, 0x1f, 0xcb, 0xba, 0xbe, 0xf1, 0xc6, 0x84, 0xed, 0xf0, 0x7b, 0xc9, 0xba, 0xa3, 0x0, 0x77, 0x94, 0xac, 0x73, 0x86, 0xac, 0x3b, 0xae, 0xff, 0xc4, 0xb9, 0x7f, 0x57, 0xb6, 0x79, 0x38, 0x64, 0x8f, 0xf2, 0x6c, 0xf4, 0xb9, 0x7e, 0xdf, 0x17, 0xf8, 0xca, 0xb5, 0xe0, 0xb6, 0x98, 0xf5, 0x2b, 0x69, 0x95, 0xc5, 0x3e, 0x9f, 0xe1, 0xfb, 0x72, 0x71, 0xdb, 0x52, 0xd6, 0xf0, 0x77, 0x71, 0xe5, 0x2c, 0xec, 0x11, 0x3c, 0xe9, 0x97, 0xb9, 0xf9, 0x26, 0x1a, 0xe7, 0xa9, 0xc6, 0x6e, 0x3d, 0xef, 0xa9, 0x95, 0x4e, 0x71, 0x50, 0x53, 0xab, 0x1b, 0x70, 0xfe, 0x6d, 0x5f, 0xb0, 0x99, 0x9d, 0xbf, 0x90, 0x37, 0x8b, 0x9f, 0xa3, 0x62, 0x48, 0x82, 0x97, 0x82, 0x3c, 0xa, 0x3c, 0xee, 0x68, 0x25, 0x85, 0xad, 0xfd, 0x5d, 0xad, 0x3f, 0x4, 0x9e, 0x25, 0x90, 0x34, 0x4e, 0xea, 0x45, 0x3a, 0xd, 0xd7, 0xad, 0xbf, 0xeb, 0xe2, 0xe7, 0xda, 0x2b, 0xaf, 0xaa, 0x7b, 0x80, 0x81, 0x93, 0xee, 0x38, 0xd8, 0xcd, 0xec, 0xfc, 0xbe, 0x2, 0xa3, 0x95, 0xef, 0x58, 0xc5, 0x90, 0xff, 0x4e, 0xce, 0x98, 0x27, 0x8, 0x26, 0x4f, 0x64, 0x8f, 0xf8, 0x7e, 0xb7, 0x5f, 0xcd, 0x5c, 0x5d, 0x12, 0xf3, 0x7b, 0xd5, 0xb0, 0x5e, 0xa9, 0x6f, 0x8a, 0x1c, 0xc7, 0x2b, 0xae, 0x47, 0xe1, 0x77, 0xde, 0x9d, 0x71, 0xee, 0x69, 0x4f, 0xe2, 0x3, 0x55, 0x5a, 0x2, 0x7, 0x4c, 0x9a, 0xd7, 0x60, 0x6d, 0xf6, 0x5a, 0x59, 0xfb, 0x69, 0x7f, 0xf2, 0xc6, 0x9b, 0x5d, 0x2f, 0x12, 0xdf, 0x73, 0xcf, 0x45, 0xe3, 0xbb, 0x37, 0xe7, 0x91, 0x73, 0xac, 0xa9, 0x1c, 0x2a, 0xfc, 0x46, 0x2a, 0xe8, 0x9f, 0x15, 0xfc, 0x13, 0x50, 0xe0, 0x3e, 0x20, 0x95, 0x49, 0xa8, 0xd4, 0xc4, 0x12, 0x8b, 0x7e, 0x2b, 0xad, 0x7, 0x8b, 0x5f, 0x30, 0x5e, 0x8e, 0x4c, 0x10, 0x2a, 0x66, 0x80, 0x81, 0x17, 0xce, 0x77, 0x20, 0x3b, 0xda, 0x66, 0x5b, 0xae, 0xcd, 0x9b, 0xc1, 0xc3, 0x53, 0x76, 0x9d, 0x7b, 0x29, 0x34, 0x43, 0xe7, 0xdf, 0xfb, 0x73, 0xed, 0x1e, 0x81, 0x25, 0xd0, 0x37, 0x34, 0xe4, 0xae, 0xe0, 0x1d, 0xa3, 0x6d, 0x73, 0xf2, 0xd3, 0xca, 0xdd, 0xb7, 0xff, 0xe5, 0x33, 0xa9, 0xdc, 0x2f, 0xc, 0x98, 0x74, 0xc7, 0xf1, 0xed, 0xc9, 0x0, 0x15, 0xb7, 0xbf, 0x41, 0x17, 0xce, 0xef, 0x93, 0x6d, 0xd9, 0xf9, 0x0, 0xac, 0x3b, 0xd2, 0xeb, 0xc0, 0xe3, 0x54, 0xb7, 0x4a, 0x8a, 0x50, 0x4a, 0x65, 0x2, 0x4a, 0xb, 0x5c, 0x39, 0xc8, 0x77, 0xa2, 0xa, 0xd4, 0xa7, 0x82, 0xb4, 0x3e, 0x0, 0xf9, 0x3e, 0x80, 0x6d, 0x0, 0x76, 0x92, 0xdc, 0x5, 0xd2, 0x42, 0x8, 0xe4, 0x91, 0x14, 0x80, 0x26, 0x9, 0xdd, 0x20, 0xbb, 0xf, 0xa0, 0x5e, 0x90, 0x6f, 0x2a, 0x67, 0x4c, 0x1e, 0x35, 0x6b, 0x2e, 0x11, 0xf5, 0x93, 0xe7, 0x13, 0x0, 0xc2, 0x42, 0x32, 0x34, 0xce, 0x93, 0x26, 0xd5, 0x78, 0xd9, 0xba, 0x85, 0x17, 0xbd, 0x5a, 0x5b, 0x5e, 0xa5, 0x4b, 0xd0, 0x26, 0x18, 0x7c, 0xc5, 0x33, 0xcc, 0x7e, 0xf8, 0xea, 0x19, 0x36, 0xb3, 0xf3, 0x21, 0x0, 0x16, 0x81, 0x12, 0x1f, 0xae, 0x8a, 0xe2, 0x13, 0x2d, 0x18, 0xf2, 0x22, 0x4, 0xe7, 0x3c, 0xef, 0x7, 0xe6, 0xaf, 0xfc, 0x87, 0xad, 0xc8, 0xee, 0x8b, 0x1d, 0xa, 0xd6, 0x8a, 0x84, 0xe6, 0x66, 0xfd, 0x98, 0x2d, 0x34, 0xce, 0x3f, 0x24, 0xbc, 0x4d, 0x9a, 0x4d, 0x30, 0x66, 0x1d, 0xc0, 0x97, 0x48, 0xfe, 0x15, 0xe0, 0x3b, 0x20, 0xdf, 0x23, 0xd4, 0xec, 0x5a, 0x65, 0xd2, 0xe9, 0x86, 0x46, 0xeb, 0x66, 0xba, 0x1, 0xd8, 0xd7, 0x5a, 0xdb, 0x7, 0xd2, 0x0, 0xc9, 0x8e, 0x24, 0x74, 0xb0, 0xa4, 0x8f, 0x1, 0x3a, 0x0, 0xb2, 0xfb, 0x86, 0xab, 0xc2, 0x90, 0xcf, 0x7a, 0x1, 0x33, 0xa8, 0x75, 0x7d, 0xa, 0xe4, 0xfd, 0x8, 0x33, 0x40, 0x41, 0x13, 0xa, 0x3b, 0xc6, 0x7a, 0x35, 0xb2, 0x74, 0x1a, 0xe6, 0x34, 0xef, 0xdc, 0x7e, 0xd5, 0x5f, 0x1e, 0xb8, 0x3a, 0xf1, 0x15, 0x48, 0x15, 0x9, 0x81, 0xee, 0x96, 0xbf, 0xd, 0x92, 0xdb, 0xf2, 0x7d, 0x80, 0xa0, 0x6f, 0xb0, 0xf7, 0xb0, 0x9f, 0x9b, 0xb7, 0x40, 0xde, 0x23, 0xab, 0x88, 0x82, 0xb9, 0xa7, 0xd0, 0xff, 0x1c, 0xc5, 0x43, 0x2c, 0xc3, 0xa8, 0xc6, 0xdb, 0x2a, 0x2c, 0xb0, 0x93, 0x4, 0x62, 0x86, 0xfc, 0x29, 0x78, 0x80, 0x7c, 0xf, 0x30, 0x9b, 0x4, 0xb3, 0x96, 0x4e, 0x6a, 0x71, 0x3a, 0xd5, 0xf0, 0xe0, 0xea, 0x3b, 0x27, 0x95, 0x33, 0xa0, 0xb4, 0x0, 0xd8, 0xa, 0xe0, 0x2d, 0x0, 0x1b, 0x1, 0x3c, 0x15, 0xbc, 0x18, 0x30, 0xe9, 0xce, 0x7e, 0xb2, 0x99, 0x89, 0x80, 0x8e, 0x83, 0xec, 0xa1, 0x92, 0x3d, 0x8, 0x42, 0x63, 0xa0, 0xc1, 0x7a, 0x79, 0x2a, 0x50, 0x79, 0x42, 0x66, 0xcc, 0xbc, 0xab, 0x40, 0x58, 0xd, 0xca, 0xd7, 0x3b, 0xa8, 0x17, 0xfc, 0x70, 0xbf, 0x4a, 0xfe, 0xa, 0x88, 0xc0, 0x30, 0x26, 0xc1, 0x48, 0xee, 0x99, 0x4d, 0xdd, 0xf7, 0x5a, 0xe, 0xe0, 0xf6, 0xa4, 0x19, 0xa0, 0xa2, 0x1e, 0x60, 0xe0, 0x5, 0x77, 0x9e, 0xea, 0x66, 0x76, 0x3e, 0x26, 0xc9, 0x84, 0xb1, 0xdf, 0x91, 0x10, 0xb2, 0x15, 0xcb, 0xd7, 0x32, 0x7c, 0xe, 0xe0, 0xfb, 0x24, 0xdf, 0xa2, 0x49, 0xdd, 0x6c, 0x1c, 0x67, 0xf6, 0xda, 0x5, 0x53, 0xda, 0xbc, 0x48, 0xa4, 0xad, 0x30, 0x60, 0xd2, 0xbc, 0x43, 0x21, 0xf7, 0xbb, 0x92, 0x1d, 0x29, 0xeb, 0x7e, 0x2, 0x52, 0x93, 0xbf, 0x4c, 0x2d, 0xd4, 0x10, 0x12, 0xad, 0x6b, 0xde, 0xa7, 0x91, 0xce, 0x12, 0xa6, 0xf6, 0x38, 0x75, 0xfd, 0xc2, 0xb, 0x9a, 0x93, 0xcc, 0xa3, 0x32, 0x6, 0x98, 0x7c, 0x57, 0xa3, 0xcd, 0x36, 0x9f, 0x23, 0xb7, 0xe5, 0x4e, 0x40, 0x4e, 0xe0, 0x80, 0xd9, 0x51, 0xf6, 0xfb, 0x80, 0xf8, 0x61, 0x84, 0x4b, 0xd8, 0x49, 0x60, 0x87, 0x49, 0x37, 0x7e, 0x7b, 0xdd, 0xc2, 0x8b, 0x6e, 0x6c, 0xf7, 0x42, 0x0, 0x18, 0x30, 0xf9, 0xee, 0x94, 0x32, 0xdb, 0xe7, 0xca, 0xba, 0xa7, 0x1, 0xda, 0x3f, 0xb7, 0x78, 0x25, 0xef, 0x26, 0x98, 0x38, 0x42, 0x24, 0xb9, 0x34, 0xa9, 0x7b, 0x36, 0xdc, 0x3d, 0xf5, 0x82, 0x24, 0xd3, 0xad, 0x5c, 0x8, 0x9c, 0xbc, 0x70, 0xf, 0xeb, 0x66, 0x2f, 0xb3, 0xd9, 0xe6, 0x19, 0xf0, 0xc7, 0x5b, 0x4f, 0x14, 0xc8, 0x69, 0x57, 0x25, 0xd2, 0x2c, 0x67, 0x15, 0xb, 0xc7, 0x29, 0xf2, 0xe5, 0xf7, 0xa7, 0x46, 0xe1, 0x59, 0x19, 0xe1, 0x79, 0xd2, 0x3a, 0x5b, 0x61, 0x9c, 0xdb, 0x68, 0x52, 0x5f, 0x5f, 0xbf, 0x70, 0x72, 0x87, 0xb9, 0x52, 0x7, 0x30, 0x70, 0xf2, 0xcf, 0xbb, 0xb9, 0x2d, 0xdb, 0x97, 0x41, 0xb6, 0x2f, 0xc0, 0x3d, 0x2, 0xe7, 0x64, 0x32, 0xf0, 0x48, 0xe, 0x44, 0xa4, 0x52, 0xe, 0xe6, 0xc5, 0x78, 0x88, 0x14, 0x72, 0x25, 0x89, 0xa0, 0x59, 0xed, 0xa4, 0x1a, 0x3f, 0xb7, 0x6e, 0xe1, 0x94, 0xb7, 0xc2, 0x2f, 0x47, 0x5e, 0xb3, 0x94, 0x3b, 0xdf, 0x7b, 0xc5, 0xd0, 0x69, 0xa0, 0xcd, 0x6c, 0x27, 0x4d, 0x9a, 0x0, 0xdd, 0x75, 0xb, 0x2e, 0x70, 0xcb, 0xd5, 0xa1, 0x2a, 0x2e, 0x1d, 0x34, 0xf9, 0xe7, 0x7b, 0x58, 0xb7, 0xe5, 0xdb, 0x36, 0xdb, 0xf2, 0x75, 0x2, 0x26, 0x34, 0xf0, 0x33, 0x69, 0x57, 0xae, 0x70, 0x97, 0xf, 0x8f, 0xf8, 0x2, 0x0, 0x63, 0xcc, 0x66, 0xa6, 0x1a, 0xc7, 0xae, 0x5b, 0x30, 0x39, 0x51, 0x7, 0x89, 0x6a, 0x60, 0xc0, 0xa4, 0x79, 0xd7, 0xd9, 0x6c, 0xf3, 0x37, 0x0, 0xed, 0xcb, 0xb0, 0x47, 0x50, 0x72, 0x26, 0xab, 0x80, 0xe9, 0x41, 0x93, 0x7a, 0x7e, 0xc3, 0xdd, 0x53, 0x8f, 0x1f, 0x34, 0xe5, 0xee, 0x46, 0x9b, 0x6d, 0xa6, 0x71, 0x1a, 0x9a, 0x24, 0xb7, 0x2f, 0xa4, 0x8f, 0x9, 0xea, 0x49, 0xa0, 0x87, 0xa4, 0x3, 0x69, 0x9c, 0x17, 0x20, 0xf7, 0xf9, 0x75, 0xb, 0x2f, 0xca, 0x94, 0x4a, 0xbc, 0xea, 0xc2, 0xd, 0xbc, 0x70, 0x61, 0x83, 0x6c, 0xf6, 0xdf, 0xe5, 0xb6, 0x7c, 0x13, 0x64, 0xb0, 0x20, 0x23, 0xbf, 0xd8, 0x22, 0x49, 0x8, 0x98, 0x4a, 0x82, 0xa4, 0xac, 0x71, 0x52, 0xcf, 0x3b, 0xd, 0xdd, 0xce, 0x5e, 0x33, 0xef, 0xbc, 0xf, 0x92, 0xcf, 0xac, 0x5a, 0x7c, 0x2c, 0x18, 0x63, 0xb3, 0xbb, 0xe6, 0xc9, 0xda, 0x83, 0x3d, 0x43, 0x17, 0x3, 0x49, 0xbe, 0xf6, 0x6, 0x91, 0x5f, 0xdc, 0x2, 0x1, 0xbb, 0x48, 0xf3, 0x1a, 0xa4, 0xde, 0x80, 0x7a, 0x2, 0x28, 0xd2, 0x81, 0x82, 0x7b, 0xae, 0x34, 0xa9, 0xc6, 0xeb, 0xd6, 0x2d, 0x9c, 0xfc, 0x54, 0xa9, 0xa4, 0xab, 0xf6, 0x9, 0x5c, 0xb7, 0xe0, 0x82, 0x16, 0xa7, 0xb1, 0xfb, 0x7f, 0x99, 0x54, 0xe3, 0x75, 0x4, 0xb2, 0x8, 0x69, 0x33, 0x89, 0x9b, 0x45, 0x7c, 0x24, 0x90, 0xcc, 0x1a, 0x27, 0xfd, 0xf0, 0xfa, 0xbb, 0x2e, 0x19, 0x53, 0x4f, 0xc4, 0xf7, 0xf0, 0x71, 0xe1, 0xd3, 0x26, 0xd5, 0x78, 0xa, 0xe9, 0x6c, 0x40, 0x41, 0xd9, 0x6b, 0x77, 0x6d, 0x43, 0xe1, 0x6f, 0x23, 0x64, 0xf, 0x3, 0xb4, 0x17, 0x8a, 0xde, 0x15, 0xde, 0x6b, 0x88, 0xa0, 0x7f, 0x29, 0x57, 0xee, 0x9a, 0x9c, 0x42, 0xd7, 0xdc, 0x3e, 0x3e, 0xeb, 0x34, 0x74, 0x9f, 0x69, 0x52, 0x4d, 0x53, 0x4, 0xbe, 0xdf, 0x76, 0x8b, 0x60, 0x18, 0x4a, 0x85, 0x31, 0xc7, 0xd6, 0x5e, 0xbf, 0x9f, 0x7a, 0x72, 0xfd, 0x5d, 0x17, 0x9f, 0x95, 0x18, 0xd5, 0x12, 0x86, 0x75, 0xb, 0x26, 0xff, 0xc9, 0x34, 0x34, 0x9d, 0x49, 0xe3, 0x2c, 0xf7, 0x2d, 0x8e, 0xfe, 0xf0, 0x15, 0x26, 0x63, 0x31, 0x59, 0x4b, 0x85, 0x79, 0xcf, 0x7e, 0x7, 0x2b, 0xd2, 0xc8, 0xf3, 0x31, 0xd, 0x2e, 0x8a, 0x34, 0xc1, 0xd4, 0x51, 0x51, 0x47, 0x6c, 0xc, 0x81, 0x4f, 0x7e, 0xea, 0xc2, 0x87, 0x4a, 0xf6, 0x3e, 0x35, 0x7b, 0x5, 0xaf, 0xbe, 0xfd, 0x9c, 0x2c, 0x53, 0xd, 0xf7, 0x93, 0xdc, 0x51, 0x64, 0xa, 0x29, 0x1, 0x51, 0xcc, 0x50, 0x18, 0x26, 0xbf, 0x1f, 0x83, 0xe7, 0x2b, 0x0, 0xe3, 0xa4, 0x9f, 0x6c, 0x49, 0xf7, 0x3a, 0xbd, 0xdd, 0xa8, 0x97, 0x10, 0xac, 0x9b, 0x7f, 0xc1, 0x2b, 0x26, 0xd5, 0x38, 0x85, 0xc6, 0x59, 0x82, 0xfc, 0xec, 0x28, 0xa2, 0x99, 0x1c, 0x65, 0xc2, 0xf2, 0xcf, 0xcc, 0xdb, 0xa9, 0xc3, 0xef, 0x99, 0x7f, 0x95, 0x8b, 0x27, 0x4f, 0x39, 0x12, 0xac, 0xcd, 0x9e, 0xd7, 0x9d, 0x1f, 0x4e, 0x2c, 0x55, 0xde, 0x44, 0xdc, 0xc2, 0x6d, 0x36, 0xd3, 0xf, 0x40, 0xda, 0xa3, 0x17, 0x13, 0x71, 0xe7, 0x26, 0xd, 0x5, 0x58, 0x6f, 0x4a, 0x3c, 0xfd, 0xa8, 0x93, 0x6e, 0x1a, 0xff, 0xf2, 0xbc, 0xd3, 0x77, 0x8b, 0xcd, 0x98, 0xd6, 0xce, 0xbf, 0x60, 0x23, 0x4c, 0x6a, 0x16, 0xe9, 0xbc, 0xec, 0x4d, 0x31, 0x18, 0xc9, 0x53, 0x97, 0x6a, 0xc6, 0x4b, 0x1b, 0x2e, 0x6, 0xb3, 0x6d, 0x90, 0xfa, 0xca, 0xaa, 0x7f, 0xfb, 0x33, 0x80, 0x9b, 0x99, 0x1, 0x70, 0xdf, 0x9a, 0x13, 0x2a, 0x4, 0x1, 0x34, 0x34, 0xce, 0x5a, 0x9a, 0xf4, 0xd, 0x6b, 0xe6, 0x9d, 0xf7, 0x61, 0x7b, 0x11, 0xac, 0x3d, 0x60, 0xfd, 0xc2, 0xc9, 0xf7, 0xc0, 0xa4, 0x6e, 0x7, 0xb9, 0xcd, 0xb7, 0x57, 0x75, 0x98, 0xd1, 0x2c, 0xbc, 0x48, 0x56, 0x50, 0x8f, 0x52, 0x71, 0x6b, 0x66, 0x80, 0x23, 0xa7, 0xdc, 0xb5, 0x17, 0x60, 0x87, 0x92, 0x48, 0xe5, 0xf5, 0xde, 0x44, 0xc4, 0x1e, 0x92, 0xdc, 0x42, 0x93, 0x5a, 0xb0, 0x76, 0xfe, 0xa4, 0xc7, 0x3a, 0xa, 0x79, 0x49, 0x82, 0x31, 0xce, 0x2c, 0x9a, 0xd4, 0xbd, 0xbe, 0x8d, 0x3a, 0x98, 0x25, 0x69, 0xf7, 0x19, 0xc5, 0x80, 0xf8, 0xbe, 0xf6, 0x7c, 0xe4, 0xc0, 0xc9, 0xb, 0x87, 0xc4, 0x96, 0xb1, 0x96, 0xa, 0x1e, 0x7d, 0xed, 0xef, 0x8, 0x72, 0x38, 0x80, 0xb4, 0x97, 0xa1, 0xd7, 0xcd, 0xd5, 0xd2, 0x83, 0xf9, 0x5, 0xf7, 0x2a, 0xe0, 0xa4, 0x1e, 0x0, 0x4d, 0xe2, 0xf6, 0xef, 0x8e, 0x82, 0xb5, 0xf3, 0x27, 0x6d, 0x31, 0x4e, 0xfa, 0x36, 0x18, 0x67, 0x29, 0xfc, 0x3e, 0xd9, 0x9f, 0xe9, 0xab, 0xc, 0x27, 0x11, 0xf7, 0x88, 0x9, 0xf7, 0x47, 0x1, 0xff, 0x3f, 0x1, 0x6b, 0x4f, 0x80, 0x74, 0x76, 0x5c, 0x19, 0x6b, 0x62, 0x80, 0x6d, 0xff, 0xd8, 0x48, 0xeb, 0x66, 0xcf, 0x25, 0x4d, 0xca, 0x2f, 0x51, 0xcd, 0xeb, 0x79, 0x7c, 0x75, 0x9f, 0xa0, 0x79, 0x15, 0x30, 0xf7, 0xaf, 0x9b, 0x3f, 0xa9, 0xa2, 0xdd, 0xbf, 0xea, 0xd, 0xd6, 0xde, 0x79, 0xfe, 0xb, 0x34, 0xa9, 0xc5, 0x0, 0x0, 0x1a, 0x11, 0xac, 0x58, 0x31, 0x64, 0xc4, 0x3d, 0x63, 0xc2, 0x8b, 0xf0, 0x28, 0x92, 0xd, 0x24, 0xfa, 0xc6, 0x95, 0xaf, 0x26, 0x6, 0x58, 0x7f, 0xd7, 0xc5, 0x56, 0x6e, 0x76, 0x2c, 0xa0, 0x34, 0x69, 0xc2, 0x5b, 0xaf, 0x54, 0x7e, 0x91, 0x81, 0xe4, 0xef, 0xf5, 0x22, 0xc6, 0x59, 0x44, 0x63, 0x1e, 0xef, 0x6c, 0x2, 0x26, 0x1, 0xa4, 0x59, 0x4c, 0x93, 0x7a, 0x12, 0xfe, 0x7e, 0x46, 0x28, 0x35, 0xc, 0xb0, 0xb6, 0x6, 0x54, 0x98, 0x16, 0x82, 0x6e, 0xb5, 0xf1, 0xd3, 0xe3, 0xe7, 0x46, 0xd2, 0xba, 0x26, 0x6, 0x18, 0x74, 0xd1, 0x3d, 0x7d, 0x41, 0xf4, 0xf6, 0xc4, 0x76, 0x28, 0xa7, 0xf2, 0x56, 0x39, 0xec, 0xfb, 0x92, 0x3f, 0x49, 0xf3, 0x16, 0x8d, 0xf3, 0xd4, 0xda, 0x3b, 0xcf, 0xdf, 0xde, 0xd9, 0xc4, 0x4b, 0x2, 0xd6, 0xde, 0x79, 0xfe, 0x5a, 0x3a, 0xa9, 0xf9, 0x5e, 0x25, 0x73, 0xe, 0x1f, 0x25, 0xc4, 0x9f, 0xda, 0x2f, 0xcf, 0xaf, 0xc4, 0x50, 0x9e, 0xf5, 0xb4, 0x67, 0x63, 0xb7, 0x1e, 0x7, 0x46, 0x95, 0xad, 0x6a, 0x6, 0x18, 0x7c, 0xc9, 0xfd, 0x29, 0x59, 0x3b, 0xa, 0xa0, 0x4d, 0xa2, 0xe4, 0x81, 0x1, 0x3, 0x20, 0x68, 0x9c, 0xf9, 0x34, 0xce, 0x8a, 0xce, 0x26, 0x5c, 0xa2, 0x40, 0xf3, 0x57, 0xd2, 0xbc, 0x8b, 0x76, 0x76, 0x9f, 0xb, 0x5c, 0xe2, 0xfc, 0x1d, 0x67, 0xe0, 0x73, 0xc3, 0xc1, 0x10, 0x3e, 0x1d, 0x55, 0xac, 0xaa, 0x19, 0x60, 0xf5, 0x6d, 0x67, 0x67, 0x9, 0x7d, 0x26, 0x34, 0xd3, 0x55, 0x93, 0x9a, 0xc3, 0xdc, 0x46, 0x4e, 0x0, 0x4d, 0x6a, 0xd9, 0x9a, 0x3b, 0x26, 0xee, 0xd6, 0x63, 0x7f, 0x31, 0x18, 0x63, 0xd6, 0x9b, 0x54, 0xc3, 0x6c, 0xff, 0x51, 0x91, 0x5b, 0x91, 0xd7, 0x0, 0x85, 0x3e, 0x9, 0x9e, 0x22, 0xe8, 0xd, 0xa5, 0xe6, 0x15, 0x3a, 0xa9, 0xfb, 0x49, 0xf3, 0x46, 0xd4, 0x77, 0x6d, 0xf6, 0x8, 0x1a, 0x74, 0xd1, 0xdd, 0x4d, 0xa4, 0xb3, 0xbf, 0xac, 0xed, 0x2b, 0xe8, 0x40, 0x2, 0x7b, 0x43, 0xee, 0x98, 0xdc, 0x86, 0x8d, 0xc9, 0xa8, 0xb9, 0x24, 0xb9, 0x9, 0xe0, 0xa6, 0x24, 0x91, 0x53, 0xf, 0xb0, 0xfa, 0xf6, 0x9, 0x9b, 0x7, 0x7f, 0x71, 0xd1, 0x43, 0x0, 0xfe, 0x3, 0x0, 0x61, 0x12, 0x30, 0xc1, 0x84, 0x26, 0x80, 0x48, 0x12, 0xb2, 0xca, 0xeb, 0x1, 0x7c, 0x97, 0xc6, 0x79, 0x96, 0x74, 0x16, 0x64, 0x65, 0x16, 0x6f, 0xb8, 0x73, 0x42, 0x36, 0x2a, 0x89, 0x58, 0x6, 0x18, 0x74, 0xd1, 0xbd, 0x3d, 0x21, 0x1d, 0xe, 0xe8, 0x40, 0x90, 0x7b, 0x41, 0xea, 0x25, 0x65, 0x8f, 0x90, 0x75, 0x8f, 0x83, 0xf4, 0xe9, 0x60, 0xe1, 0x7a, 0x68, 0x51, 0x67, 0xad, 0x1e, 0x31, 0x9e, 0x3b, 0x21, 0x53, 0x33, 0x4, 0xac, 0x69, 0x2f, 0x42, 0x74, 0x26, 0x8, 0xb0, 0xa0, 0x79, 0x1f, 0xd2, 0x3e, 0x9, 0x35, 0x97, 0xc0, 0x21, 0xc7, 0x73, 0x8e, 0x1, 0x29, 0x70, 0x33, 0xc9, 0x55, 0x34, 0xa9, 0x87, 0x8c, 0x93, 0x9a, 0xbf, 0xfa, 0xf6, 0xf1, 0x9b, 0x4b, 0x25, 0x11, 0xc9, 0x0, 0x83, 0xbf, 0xb8, 0x68, 0x7f, 0x2b, 0xf7, 0x7c, 0x59, 0x77, 0x3a, 0x64, 0xf, 0x2f, 0xcc, 0x33, 0xa7, 0xb0, 0x7b, 0x4e, 0xa, 0xf0, 0xf9, 0xad, 0xb6, 0x1e, 0x20, 0x67, 0x2c, 0x37, 0x8e, 0xf3, 0xfc, 0x9a, 0x3b, 0x26, 0x6e, 0x4b, 0x8, 0xe7, 0x75, 0x5, 0x92, 0xb6, 0x3, 0xf8, 0x33, 0x80, 0x91, 0x40, 0xa2, 0xdb, 0xd7, 0x51, 0xe0, 0x3f, 0xe8, 0x38, 0xaf, 0x11, 0xe6, 0x41, 0x90, 0x3f, 0x5d, 0x3b, 0xef, 0xdc, 0x36, 0x9, 0xd0, 0x31, 0x3d, 0x80, 0xc6, 0xcb, 0x75, 0xbf, 0x5, 0xe8, 0x63, 0x60, 0xd8, 0xf1, 0xb3, 0xc0, 0x41, 0x23, 0x34, 0x3f, 0xd1, 0x26, 0xb7, 0xed, 0x92, 0x15, 0xc8, 0xff, 0x7c, 0x74, 0xd7, 0x86, 0x93, 0x7c, 0x1b, 0x26, 0xf5, 0x88, 0x6c, 0x76, 0x24, 0x22, 0x5d, 0xca, 0x83, 0xa0, 0x72, 0x4b, 0x90, 0x82, 0x77, 0xca, 0xe1, 0x8d, 0x4e, 0xfa, 0x47, 0xae, 0xab, 0x19, 0x1b, 0x16, 0x9c, 0x57, 0xd6, 0xb, 0x28, 0xc, 0x91, 0x3, 0x91, 0x80, 0x5e, 0x0, 0x1a, 0xbc, 0x42, 0x7b, 0x53, 0x8f, 0x79, 0xe9, 0xd2, 0x14, 0x49, 0xb1, 0x40, 0xe9, 0xe7, 0x8a, 0x6c, 0x1, 0xbb, 0x4, 0x54, 0x54, 0x81, 0xdd, 0x9, 0xd6, 0xdc, 0x31, 0xe1, 0x7d, 0x1a, 0xe7, 0x49, 0x1f, 0x47, 0x11, 0xb6, 0x80, 0x0, 0x8a, 0x9f, 0x11, 0xf3, 0x2e, 0xf7, 0xed, 0x7, 0x80, 0xb9, 0xad, 0x52, 0xe2, 0x3, 0x31, 0x3d, 0x80, 0x64, 0xf, 0x0, 0xb0, 0x97, 0x37, 0xbf, 0xac, 0xfc, 0xc6, 0x36, 0xde, 0x5b, 0x54, 0xd6, 0x73, 0xb5, 0x69, 0x95, 0x6c, 0xb0, 0x2e, 0xe7, 0x1d, 0x82, 0x1d, 0xee, 0xdb, 0xd7, 0x91, 0x40, 0xf2, 0x3d, 0x1f, 0xaf, 0x3e, 0x46, 0x8b, 0x5b, 0x7d, 0x2e, 0x66, 0x4c, 0xa, 0xa1, 0xb5, 0x29, 0xc1, 0xa2, 0x8, 0xc3, 0xb4, 0xe3, 0x38, 0x4d, 0xd5, 0x94, 0x27, 0x7a, 0x8, 0x10, 0x7a, 0xe6, 0xed, 0xcb, 0xc5, 0x63, 0x55, 0xa5, 0x3d, 0x74, 0xb9, 0xf8, 0x61, 0x2c, 0xf0, 0x75, 0x10, 0x89, 0xbb, 0x73, 0xd7, 0x15, 0xd0, 0x8, 0x84, 0x65, 0x68, 0x51, 0x4d, 0x8, 0xf, 0x6d, 0x49, 0x20, 0x7f, 0x97, 0x1f, 0x2d, 0x53, 0x81, 0x3c, 0x56, 0x29, 0x44, 0x32, 0x0, 0x8d, 0x69, 0x90, 0x6b, 0xbd, 0x1d, 0x2c, 0x3b, 0x60, 0x1a, 0x33, 0xe7, 0xf2, 0x47, 0xf3, 0x6, 0xc0, 0x8f, 0x34, 0x3, 0x10, 0x70, 0x9, 0xbe, 0x2f, 0x69, 0xbf, 0x4, 0x51, 0x9b, 0xaa, 0x56, 0x9c, 0x4c, 0x68, 0x9f, 0xc0, 0x72, 0xe3, 0x15, 0x4b, 0xbe, 0xf3, 0x1a, 0x3, 0x41, 0xf2, 0x4d, 0x48, 0x1f, 0x69, 0x6, 0x10, 0xe0, 0xa, 0xfc, 0xb0, 0xd0, 0xc1, 0x27, 0x6a, 0xfc, 0x8f, 0xc3, 0x1d, 0xc3, 0x69, 0xe5, 0xce, 0x2f, 0xaa, 0xd6, 0x1b, 0x37, 0x46, 0xb, 0xc8, 0xa9, 0x7a, 0x68, 0xd5, 0xfb, 0xc7, 0xa, 0xf8, 0x8c, 0x7e, 0x9f, 0xb, 0x63, 0xc9, 0xef, 0xe5, 0x2f, 0xa2, 0xfb, 0xe8, 0xea, 0x0, 0x7e, 0x3d, 0x73, 0xf5, 0x67, 0xcc, 0x6f, 0x14, 0xc4, 0x31, 0x41, 0x58, 0xbe, 0xaa, 0xe, 0x71, 0xd1, 0x43, 0x0, 0x0, 0x5, 0xd4, 0x8a, 0xcc, 0x3b, 0x1c, 0xa8, 0x88, 0xf7, 0x25, 0xca, 0xcf, 0xf0, 0x4d, 0x78, 0x55, 0x2c, 0x1, 0xe0, 0x0, 0xd0, 0x54, 0x25, 0xcc, 0xec, 0x2e, 0x40, 0xd2, 0x11, 0xb0, 0x77, 0x69, 0x7a, 0x85, 0x9, 0x1c, 0x77, 0xf, 0xd0, 0x3f, 0x5b, 0x43, 0x82, 0x6b, 0xad, 0xad, 0xca, 0xb4, 0x1c, 0xad, 0x5, 0x0, 0x2d, 0x79, 0xcb, 0x5e, 0x39, 0x83, 0x45, 0x2d, 0x4d, 0xb6, 0x90, 0x91, 0x8, 0xf4, 0x21, 0xf9, 0x91, 0x67, 0x0, 0x92, 0xfb, 0xb4, 0x6d, 0xb9, 0x0, 0xdb, 0x78, 0xaf, 0x6c, 0xb5, 0x64, 0x88, 0x1e, 0x2, 0xc8, 0xf, 0x19, 0xd8, 0xaa, 0xb, 0x8e, 0xef, 0x8, 0xfa, 0xe8, 0xfc, 0x26, 0x56, 0x5e, 0x9c, 0x10, 0x8f, 0x94, 0xdd, 0x46, 0xa5, 0x88, 0x9f, 0x7c, 0x63, 0xa6, 0x9f, 0xcf, 0x81, 0x0, 0x1a, 0x13, 0xc1, 0x74, 0xdd, 0x82, 0xf2, 0x7b, 0xa9, 0x28, 0x68, 0x5f, 0xc5, 0x50, 0xac, 0x71, 0x17, 0xf5, 0x94, 0x2c, 0x5a, 0x73, 0xe, 0x66, 0x43, 0x1b, 0x74, 0x55, 0x4, 0x91, 0x42, 0x20, 0x61, 0xde, 0x20, 0xb8, 0x85, 0xe1, 0x15, 0x27, 0x40, 0x91, 0x5c, 0x10, 0xb2, 0x7, 0x15, 0xcb, 0x9, 0xa5, 0x64, 0xc2, 0xe2, 0x97, 0x21, 0x9b, 0xa2, 0xa4, 0x8f, 0xeb, 0x23, 0xcf, 0x0, 0xec, 0x5, 0x20, 0xd8, 0x53, 0x0, 0x28, 0x25, 0xf4, 0x15, 0xc, 0x97, 0x21, 0x9c, 0x7, 0x32, 0x9a, 0x2f, 0x48, 0x12, 0xcc, 0x0, 0xa8, 0xea, 0xd0, 0xa9, 0x18, 0x4b, 0xa0, 0xde, 0x2, 0xd9, 0x82, 0x60, 0xc1, 0x81, 0xc7, 0xb6, 0x8, 0x76, 0x44, 0x60, 0x3b, 0xfc, 0xf9, 0x5a, 0x40, 0x13, 0xeb, 0x68, 0x3, 0xeb, 0xa4, 0x61, 0xf0, 0xd4, 0x5f, 0xed, 0x6b, 0xad, 0x7b, 0x8a, 0x8f, 0x57, 0x26, 0x85, 0x3b, 0x49, 0x7b, 0x3, 0xfa, 0xe6, 0xe0, 0x8b, 0x7f, 0x51, 0xb1, 0x56, 0x17, 0xed, 0x26, 0xe4, 0xa4, 0x1e, 0x4, 0x9d, 0x6f, 0xd3, 0x38, 0xcf, 0x6, 0x3e, 0x5a, 0xde, 0xaf, 0xaf, 0xaf, 0x3, 0x40, 0xfe, 0x8, 0xc7, 0x3c, 0x37, 0x16, 0x34, 0xee, 0x98, 0x6e, 0x20, 0x1c, 0x3f, 0xb0, 0x68, 0x41, 0xa2, 0x31, 0x5, 0x61, 0x1f, 0x45, 0x20, 0x4d, 0x2f, 0x40, 0xa7, 0xe5, 0x10, 0x17, 0x65, 0xd5, 0xcd, 0xbd, 0x63, 0x99, 0x9e, 0x34, 0x7f, 0x43, 0x43, 0xc8, 0xba, 0x97, 0x3, 0x7c, 0x7a, 0xf0, 0x25, 0xf7, 0xfd, 0xf7, 0xe0, 0xa9, 0xf, 0xec, 0xdd, 0xe6, 0x32, 0xc5, 0xbd, 0x18, 0x3c, 0xf5, 0x57, 0xdd, 0x1, 0xf6, 0x85, 0xec, 0x41, 0x20, 0x7a, 0x43, 0x38, 0x4, 0xd0, 0x27, 0x25, 0x7b, 0x24, 0x81, 0x81, 0xf0, 0xe7, 0xa, 0x80, 0xf0, 0x36, 0xaf, 0x35, 0x51, 0xcf, 0x3f, 0xf, 0x32, 0xf5, 0x75, 0xe3, 0xa4, 0x6f, 0x5c, 0x75, 0xf3, 0xbf, 0xb6, 0xf9, 0x4, 0xae, 0xdd, 0x5, 0x86, 0x5c, 0xfa, 0xc0, 0x30, 0x9b, 0x6d, 0xf9, 0xd, 0x80, 0xbd, 0x93, 0x30, 0x2, 0x85, 0xf6, 0xc7, 0x9, 0x6f, 0xba, 0xb9, 0x85, 0x34, 0x2b, 0x5, 0x3e, 0x44, 0x63, 0xee, 0x5c, 0x7d, 0xeb, 0x59, 0x25, 0xf, 0x9f, 0x6a, 0x73, 0x29, 0x86, 0x5d, 0xfe, 0x70, 0xf, 0x6b, 0xdd, 0x7d, 0x65, 0xed, 0x1, 0x34, 0x66, 0x7f, 0x59, 0xdb, 0xb, 0x72, 0xaf, 0x96, 0x6c, 0xff, 0xd6, 0x66, 0xcd, 0x1a, 0x2a, 0x44, 0xbe, 0xe9, 0x38, 0xd, 0x13, 0x56, 0xdd, 0x32, 0xf6, 0x85, 0x24, 0xd2, 0xac, 0x27, 0x18, 0x3c, 0xf5, 0x57, 0x23, 0xe5, 0x66, 0x5e, 0xf4, 0x77, 0x15, 0x49, 0x62, 0x15, 0x7d, 0xab, 0xa3, 0x66, 0x82, 0xd3, 0xc7, 0x4, 0x6c, 0x26, 0xcd, 0xb, 0x34, 0xce, 0x42, 0xc7, 0x98, 0xfb, 0x56, 0xde, 0x3c, 0x36, 0x72, 0x99, 0x78, 0x9b, 0x3d, 0x82, 0x56, 0xce, 0x3d, 0x63, 0x2b, 0xbc, 0x7d, 0x74, 0x5e, 0xb, 0x55, 0x68, 0x20, 0x2d, 0xfa, 0x79, 0x25, 0x49, 0x64, 0xd3, 0x2c, 0x1, 0xe8, 0x63, 0xa5, 0x83, 0x6a, 0xc5, 0x4c, 0xbd, 0xc1, 0xd0, 0xcb, 0x16, 0xef, 0x67, 0x6d, 0x76, 0x9c, 0x3f, 0xcc, 0x55, 0x61, 0x62, 0x8f, 0xd4, 0xc6, 0xb, 0xf4, 0xe8, 0xd0, 0xbe, 0x8c, 0x22, 0xb0, 0x2f, 0xa0, 0x33, 0x61, 0xdd, 0xc1, 0x2e, 0x30, 0x74, 0xf0, 0xd4, 0x7, 0x17, 0xac, 0xbe, 0x75, 0xec, 0xba, 0xe2, 0x4, 0xaa, 0x6e, 0xb9, 0xc3, 0xa6, 0x3f, 0x96, 0x32, 0x34, 0xbf, 0xf7, 0x48, 0xef, 0x2f, 0x45, 0xaa, 0x68, 0xf6, 0x37, 0x34, 0xce, 0xf9, 0xaa, 0x65, 0xde, 0xb1, 0x44, 0x9f, 0x19, 0x7a, 0xd9, 0x83, 0xfb, 0x77, 0x14, 0x71, 0x3a, 0x6, 0x34, 0x0, 0xd6, 0x9d, 0xee, 0xf, 0x94, 0x2c, 0xa8, 0x7b, 0x9b, 0xfc, 0x44, 0x59, 0x6, 0x87, 0x41, 0xfb, 0xcb, 0x9d, 0x5b, 0x24, 0x6f, 0x22, 0x4f, 0x9f, 0x80, 0xec, 0x38, 0x52, 0x7d, 0xa2, 0x4a, 0x55, 0x35, 0x3, 0xac, 0x9c, 0xf3, 0xf9, 0xac, 0x80, 0x17, 0xe0, 0x9f, 0xa3, 0x5a, 0x9d, 0xdc, 0x9f, 0x2f, 0xb7, 0xa7, 0x6d, 0x4, 0x9a, 0x86, 0xbd, 0x40, 0xc2, 0x88, 0xce, 0x26, 0x59, 0x92, 0x20, 0xd9, 0x43, 0x1, 0xec, 0x7, 0x50, 0x85, 0xcb, 0x3b, 0xc2, 0x78, 0xa8, 0x1c, 0x87, 0x28, 0xfe, 0xb6, 0x50, 0xbb, 0xa0, 0xdf, 0xad, 0xbe, 0x4a, 0xe3, 0x6c, 0x8c, 0x2a, 0x57, 0x4d, 0x63, 0xf7, 0x1f, 0x6e, 0x19, 0xfb, 0x2a, 0x8d, 0x79, 0x33, 0x98, 0x32, 0x8e, 0x76, 0x74, 0x8d, 0x9a, 0xf4, 0x88, 0xb3, 0x6d, 0x53, 0x0, 0x5, 0xe9, 0xe3, 0xb2, 0xf6, 0xe4, 0x21, 0x97, 0x2d, 0xee, 0xd9, 0xb9, 0x64, 0x4b, 0x6, 0x6, 0x5f, 0xfa, 0xe0, 0x60, 0x59, 0x4d, 0xf6, 0x55, 0xdd, 0xdc, 0x36, 0x37, 0x49, 0x40, 0xac, 0xd7, 0x40, 0xce, 0x96, 0xf, 0x10, 0xdc, 0xd2, 0xd0, 0xfd, 0x63, 0xaf, 0x47, 0xc5, 0xab, 0x89, 0x1, 0x6, 0x5f, 0x72, 0x9f, 0x1, 0xcc, 0x3, 0x2, 0x32, 0x2, 0x90, 0x53, 0xe5, 0xa, 0x2e, 0x14, 0x75, 0x61, 0xc5, 0x5d, 0x5f, 0x41, 0x78, 0x9e, 0x71, 0xa1, 0xf1, 0xb2, 0xf6, 0xd4, 0xc4, 0xa9, 0xd1, 0x9, 0x40, 0xe0, 0xc, 0xc0, 0x8e, 0xf1, 0x1c, 0xab, 0x0, 0x76, 0xc0, 0x89, 0x68, 0x34, 0x39, 0x5f, 0x3e, 0x90, 0x66, 0x57, 0xf1, 0x9, 0xa6, 0x1, 0xd4, 0xc4, 0x0, 0xd, 0x3d, 0x7a, 0xb, 0x34, 0xf7, 0x4a, 0xc8, 0xfa, 0x54, 0x8c, 0x98, 0x19, 0x2a, 0x35, 0x25, 0x5c, 0x1c, 0xb7, 0x60, 0x37, 0xb0, 0x83, 0x49, 0x9d, 0x3d, 0xe4, 0xd2, 0x87, 0x7a, 0x77, 0x36, 0x1, 0x6b, 0x81, 0x21, 0x97, 0x3e, 0x74, 0x2, 0x64, 0xc7, 0xe6, 0x25, 0xff, 0xf0, 0xa, 0xea, 0xb6, 0xe0, 0xaa, 0x54, 0x58, 0xdc, 0xb7, 0x61, 0x13, 0x2d, 0x77, 0xd1, 0x98, 0x57, 0xe2, 0xca, 0x57, 0x13, 0x3, 0x2c, 0xfb, 0xe9, 0xb1, 0xa2, 0x71, 0x56, 0x80, 0x39, 0x37, 0x2e, 0x86, 0x57, 0xf8, 0xb4, 0x86, 0x52, 0x52, 0x8e, 0xf7, 0x3e, 0xef, 0x2e, 0x45, 0x48, 0x1a, 0x7, 0xe0, 0x92, 0x76, 0xa0, 0x4b, 0x87, 0xc0, 0xb0, 0x69, 0x8f, 0xf4, 0x4, 0xf4, 0x45, 0x49, 0x47, 0x7b, 0x92, 0xbf, 0x9, 0x26, 0x4f, 0x22, 0xf0, 0x11, 0x87, 0xab, 0x52, 0x61, 0xb1, 0xd, 0xcb, 0x77, 0x15, 0x20, 0x40, 0x2e, 0x91, 0x70, 0x7f, 0x5c, 0x19, 0x6b, 0xd6, 0xdf, 0x57, 0xcd, 0x3d, 0x7d, 0xab, 0x31, 0xce, 0x8b, 0x20, 0x4b, 0xc, 0x3, 0x95, 0x76, 0x5f, 0x26, 0x30, 0x3e, 0x76, 0x87, 0xec, 0x85, 0x43, 0x2e, 0x7d, 0x68, 0x6c, 0x47, 0x10, 0x2c, 0x69, 0x90, 0xb5, 0x57, 0x49, 0xf6, 0xdc, 0xd0, 0xce, 0x1d, 0x55, 0xe2, 0x4, 0x95, 0xc6, 0xb, 0xe5, 0x65, 0x56, 0xff, 0xe1, 0x96, 0x33, 0x63, 0xd7, 0x59, 0x24, 0x62, 0xc0, 0x31, 0x4e, 0xea, 0x1a, 0x0, 0x9b, 0xdb, 0xd2, 0xc9, 0xc7, 0x89, 0x7f, 0x45, 0xcf, 0x7e, 0x55, 0x68, 0x25, 0xdb, 0x1f, 0xd0, 0x15, 0xc3, 0xa7, 0x3f, 0xba, 0x17, 0x76, 0x23, 0x18, 0x7a, 0xf9, 0xc3, 0x17, 0xc9, 0xba, 0x97, 0x90, 0xec, 0xe6, 0x1f, 0x22, 0xdb, 0xca, 0x15, 0x24, 0xa, 0x3f, 0xa5, 0xde, 0xb0, 0x8d, 0xf1, 0x82, 0x85, 0x96, 0xfe, 0x53, 0xc9, 0x35, 0x16, 0xc9, 0x30, 0x80, 0x49, 0xfd, 0x15, 0x60, 0x16, 0x2c, 0xa7, 0xb4, 0xb4, 0x56, 0x78, 0xe2, 0x9e, 0x7d, 0x7f, 0x44, 0x43, 0x1a, 0x40, 0xfa, 0xbc, 0xeb, 0x66, 0xef, 0x4e, 0x88, 0x36, 0xed, 0xe, 0xc3, 0xa6, 0x3d, 0x72, 0x34, 0x64, 0xaf, 0x4, 0xd1, 0x97, 0x9e, 0xda, 0xc7, 0xb0, 0x7a, 0x86, 0x12, 0xf8, 0x29, 0x3b, 0x61, 0x56, 0x3e, 0x9e, 0x48, 0xe3, 0xef, 0x4b, 0x65, 0x5e, 0x26, 0xcd, 0xba, 0x52, 0x65, 0xad, 0x99, 0x1, 0x86, 0x5f, 0xf1, 0x44, 0xca, 0x75, 0x33, 0x17, 0x93, 0xdc, 0xb3, 0x60, 0x82, 0xa3, 0xc6, 0x8b, 0x86, 0x14, 0x4, 0x1a, 0x7a, 0x9b, 0x2b, 0xc9, 0x9e, 0x36, 0xf4, 0xf2, 0xc5, 0x8b, 0x3b, 0x9b, 0xb8, 0xe5, 0x60, 0xd8, 0xb4, 0x47, 0x87, 0x59, 0xd7, 0x9d, 0x2b, 0xd9, 0x91, 0xb9, 0x63, 0x71, 0x88, 0xa, 0x8d, 0x64, 0x85, 0x97, 0x2, 0xa5, 0x2e, 0x3e, 0x9d, 0x70, 0x78, 0x4e, 0x93, 0x22, 0x9d, 0x7b, 0xff, 0x70, 0xf3, 0xbf, 0xfe, 0xb2, 0x54, 0x79, 0x6b, 0x62, 0x80, 0x61, 0x57, 0x3c, 0x9e, 0x92, 0xcd, 0x5c, 0x27, 0xeb, 0xde, 0x0, 0xa0, 0x67, 0xc1, 0x92, 0xe4, 0x4, 0x2e, 0x7f, 0xdf, 0x3b, 0xfa, 0x27, 0x8c, 0xc1, 0xba, 0xf6, 0xb3, 0x43, 0x2e, 0x5b, 0x7c, 0x7f, 0x65, 0xa5, 0xec, 0x38, 0x18, 0x7a, 0xf9, 0xa3, 0x43, 0x25, 0xf7, 0x2e, 0x40, 0x47, 0xfa, 0x36, 0xd, 0x86, 0x7e, 0x6b, 0xc1, 0x3, 0xbd, 0x65, 0xfe, 0x8, 0x7e, 0xc3, 0x57, 0xee, 0x14, 0x94, 0xf0, 0x5, 0xc0, 0xa5, 0xe1, 0xdf, 0xca, 0x95, 0xb9, 0x6a, 0x6, 0x18, 0x7a, 0xf9, 0xa3, 0xd, 0x72, 0x33, 0xdf, 0xb3, 0xae, 0xfb, 0xdf, 0x0, 0xd3, 0x5e, 0x68, 0xb4, 0x64, 0x5f, 0x9d, 0x2a, 0xd3, 0x3a, 0xdc, 0x18, 0xa6, 0x21, 0x9d, 0x39, 0xe4, 0xd2, 0x87, 0x7e, 0x3b, 0xf4, 0xf2, 0x47, 0x92, 0xde, 0x95, 0xac, 0x26, 0x18, 0x36, 0xed, 0xb1, 0x93, 0xad, 0xcd, 0x3c, 0x28, 0xab, 0xc3, 0xa, 0xd7, 0x52, 0x94, 0xd2, 0x7a, 0xe2, 0x70, 0x81, 0xd6, 0x71, 0xf3, 0x9a, 0xdd, 0x2e, 0x92, 0x1b, 0x40, 0xf3, 0xa6, 0x84, 0x5d, 0xa, 0xb6, 0x53, 0x4, 0x43, 0x62, 0x86, 0x27, 0xfc, 0x9, 0x6c, 0x75, 0x68, 0x67, 0x31, 0x54, 0xc5, 0x0, 0xc3, 0xaf, 0x78, 0xbc, 0x1b, 0xa0, 0x1f, 0x59, 0x6b, 0xaf, 0x3, 0xe1, 0xd0, 0x10, 0xc1, 0x21, 0xc7, 0x85, 0x2b, 0xc7, 0xa2, 0x18, 0x9f, 0x45, 0xe1, 0xcc, 0x8b, 0x2b, 0x5, 0x78, 0x8, 0xb8, 0x9f, 0xa1, 0x74, 0x9, 0x10, 0x46, 0xd0, 0xd1, 0xd6, 0xba, 0x2f, 0xf, 0xb9, 0xfc, 0x91, 0xe3, 0x3a, 0x8c, 0xc2, 0x25, 0x60, 0xc8, 0x65, 0xf, 0xff, 0xa7, 0xb5, 0xd9, 0x45, 0x24, 0xf, 0xa, 0xd4, 0x6f, 0x1a, 0xe3, 0xf9, 0x39, 0x17, 0x8a, 0x3f, 0x85, 0xf5, 0x46, 0xc, 0x2e, 0xa, 0xf1, 0x26, 0x3f, 0x2e, 0x7d, 0x7c, 0xac, 0x5c, 0x75, 0xf3, 0x99, 0x3, 0x8d, 0x93, 0xfe, 0x94, 0x49, 0x35, 0xee, 0x63, 0x52, 0x4d, 0x4d, 0x26, 0x95, 0xee, 0x63, 0x9c, 0xf4, 0x20, 0x3a, 0xe9, 0xd1, 0x74, 0xd2, 0x67, 0xd1, 0x38, 0x5f, 0xa6, 0x71, 0xbe, 0x44, 0xf0, 0xd9, 0x72, 0x65, 0x2f, 0x27, 0xb8, 0x47, 0x10, 0xff, 0xd7, 0x7b, 0xca, 0xda, 0xaf, 0x4a, 0xf6, 0x3b, 0x8, 0x56, 0xa3, 0xb0, 0xd2, 0x95, 0xae, 0x55, 0x2d, 0x8c, 0xf5, 0xd8, 0x5b, 0x62, 0xc8, 0xb9, 0x70, 0x2b, 0x68, 0x1e, 0x4b, 0x77, 0xdb, 0xe7, 0xbc, 0x17, 0x67, 0x1c, 0xd3, 0xe1, 0x9b, 0x48, 0xe, 0xbf, 0xe2, 0x89, 0x46, 0xeb, 0x66, 0xd6, 0xca, 0xba, 0x7, 0x91, 0xdc, 0x23, 0x98, 0x92, 0x87, 0xc4, 0x44, 0x71, 0x12, 0x78, 0xe8, 0x92, 0xab, 0x40, 0xe7, 0xe4, 0x95, 0x73, 0x3e, 0xf7, 0x7e, 0x71, 0x94, 0xa3, 0xbe, 0xf2, 0x5b, 0xb6, 0x6c, 0x7b, 0x97, 0x4e, 0xba, 0x81, 0xb2, 0xd6, 0x48, 0xd6, 0x5d, 0x35, 0xf7, 0x8c, 0xb2, 0x47, 0xcc, 0x54, 0x44, 0x85, 0xa1, 0xd3, 0x1e, 0xed, 0xe, 0x60, 0x32, 0xac, 0x9d, 0x5, 0xf8, 0x67, 0xff, 0xa1, 0xe3, 0xf, 0x8c, 0x40, 0xe1, 0x3c, 0x78, 0xb, 0xc8, 0xb7, 0x4, 0xde, 0xea, 0x66, 0xb3, 0xd7, 0xaf, 0xb9, 0xf5, 0xcc, 0x4c, 0xd, 0x59, 0xb4, 0x9, 0x86, 0x5c, 0xfe, 0x48, 0x9a, 0xc0, 0x22, 0x12, 0x47, 0xc9, 0xda, 0xdc, 0x2c, 0x1b, 0x2b, 0x26, 0x7a, 0x25, 0x55, 0x46, 0x56, 0xe0, 0x5d, 0xab, 0xe6, 0x9e, 0x3e, 0x25, 0xc9, 0xba, 0x54, 0x54, 0xd8, 0x61, 0xd3, 0x1e, 0x3b, 0x49, 0x72, 0x7f, 0xe3, 0x89, 0xb5, 0x1e, 0x9b, 0xb7, 0x4a, 0x2d, 0xee, 0xec, 0x87, 0x70, 0xcc, 0xb8, 0xc5, 0x23, 0x2c, 0x8a, 0xab, 0xc8, 0x38, 0x91, 0xa7, 0x83, 0x49, 0xda, 0x4a, 0x9a, 0xd7, 0x40, 0x2e, 0x2, 0xcc, 0x4f, 0x56, 0xce, 0xf9, 0x6c, 0xe2, 0x1e, 0x45, 0xc3, 0xaf, 0x78, 0x7c, 0xa8, 0xb5, 0xee, 0xb5, 0xde, 0xde, 0x48, 0x3a, 0x88, 0xa4, 0xbf, 0x3f, 0x62, 0x20, 0xaa, 0x7b, 0xc7, 0x27, 0xb6, 0xaa, 0x53, 0xb8, 0x2e, 0x51, 0x38, 0x2a, 0xf6, 0xa4, 0x2e, 0xc4, 0x97, 0xbf, 0xf, 0x3, 0x9f, 0x4d, 0x35, 0x34, 0x7d, 0x6e, 0xd9, 0xcf, 0x4e, 0x4a, 0xf4, 0xc8, 0x98, 0x8a, 0xe, 0x8d, 0x12, 0xf0, 0x16, 0xc0, 0x55, 0x20, 0x86, 0x12, 0x85, 0x47, 0xb7, 0x14, 0x54, 0xa8, 0x18, 0xca, 0x59, 0x7f, 0xc2, 0x61, 0x2c, 0xfb, 0x5d, 0x1e, 0xb5, 0xb9, 0x19, 0x70, 0x89, 0x64, 0xf, 0xc9, 0xe, 0x84, 0x78, 0x10, 0xa9, 0xb, 0x87, 0x4e, 0x7b, 0x74, 0x29, 0xc0, 0xc5, 0x0, 0x9f, 0x58, 0x75, 0xd3, 0xe7, 0x3e, 0xac, 0x16, 0x41, 0x43, 0xa7, 0x3d, 0x76, 0x24, 0x81, 0x33, 0x41, 0x9c, 0x62, 0xdd, 0xec, 0x27, 0x1, 0xf4, 0x26, 0xd1, 0xe4, 0x17, 0x26, 0xe7, 0xa, 0x17, 0xb9, 0x8c, 0x92, 0x6d, 0xb8, 0x8f, 0x7f, 0xe, 0xed, 0xba, 0xc2, 0xd7, 0x68, 0xcc, 0x6d, 0x49, 0x13, 0x3f, 0x8e, 0x14, 0x25, 0x61, 0xd8, 0xf4, 0x5f, 0x9f, 0x2e, 0xeb, 0x3e, 0xc, 0x44, 0xad, 0x70, 0xed, 0x70, 0x28, 0x68, 0x57, 0xa1, 0x1d, 0x4b, 0x20, 0xa9, 0x19, 0xe4, 0x3f, 0x0, 0xbc, 0xb, 0xe0, 0x6d, 0x80, 0x7f, 0x34, 0xc6, 0xbc, 0x28, 0x61, 0x83, 0x64, 0x37, 0x1b, 0x63, 0xb6, 0x9, 0xcc, 0x2, 0x70, 0x8d, 0x31, 0x8e, 0x9b, 0xcd, 0x34, 0x2, 0xec, 0x66, 0xc, 0xf, 0x4, 0x74, 0x8c, 0xb5, 0x3a, 0xe, 0xd0, 0x1, 0x0, 0x7a, 0xc8, 0xda, 0xde, 0x24, 0xf7, 0xcb, 0x21, 0x2d, 0x7c, 0x42, 0xa, 0xa, 0xfb, 0xe9, 0x44, 0x2a, 0x15, 0x4a, 0x4f, 0x92, 0x5, 0xcd, 0x8d, 0x3d, 0xf7, 0xeb, 0x73, 0xd5, 0x33, 0xd7, 0xf, 0x4e, 0x5c, 0xce, 0xa9, 0xf8, 0xec, 0x60, 0x9, 0x2b, 0x40, 0xf3, 0x2, 0xa0, 0xe3, 0x2, 0x4f, 0x9e, 0xf0, 0x69, 0xd1, 0xed, 0xf, 0x5, 0x63, 0x49, 0xee, 0xc1, 0x3b, 0x69, 0x3b, 0x68, 0x3a, 0x10, 0xd, 0x1b, 0x25, 0x1c, 0x2, 0xe0, 0x10, 0x3f, 0xc6, 0x9, 0x92, 0x1d, 0x27, 0xe1, 0x7d, 0x48, 0xcd, 0x90, 0xcd, 0x10, 0xb4, 0x0, 0xe4, 0x66, 0xb2, 0x24, 0xe9, 0x0, 0x4a, 0x59, 0xab, 0xee, 0x80, 0xf6, 0x7, 0x90, 0xf3, 0x48, 0xa, 0x16, 0xc9, 0xf8, 0xe, 0xd1, 0x2c, 0x76, 0xe7, 0xab, 0x9c, 0xf8, 0xc5, 0xe3, 0x40, 0x1, 0x7e, 0x45, 0x43, 0x4a, 0xb0, 0x0, 0xc, 0x69, 0x9e, 0x14, 0xf9, 0x83, 0xf6, 0x20, 0x3e, 0x50, 0x5, 0x3, 0x90, 0x7c, 0x17, 0xe4, 0x77, 0x64, 0xdd, 0x27, 0xdb, 0xeb, 0xb8, 0xb4, 0xa, 0x4a, 0x13, 0x2a, 0x57, 0x48, 0x81, 0x24, 0xc2, 0x4e, 0x97, 0xc1, 0x88, 0xda, 0x1d, 0x40, 0x5f, 0x40, 0x7d, 0xc1, 0x9c, 0x4a, 0x91, 0x4b, 0x26, 0x70, 0x79, 0xf, 0x8c, 0x6e, 0xc8, 0x7f, 0x9b, 0xcb, 0x28, 0xbf, 0x59, 0x46, 0xb2, 0x65, 0x2f, 0xc4, 0x6f, 0xee, 0x5c, 0x24, 0x43, 0x72, 0x9, 0x8d, 0xf3, 0x5f, 0x2b, 0x67, 0x9f, 0x5a, 0xd6, 0xa0, 0x53, 0x2d, 0x54, 0xdc, 0x85, 0xaf, 0x9c, 0xf3, 0x59, 0x57, 0x56, 0xcf, 0x1, 0xe6, 0x7, 0xcc, 0x4f, 0x3b, 0x29, 0xce, 0xae, 0xf, 0xc4, 0xdb, 0xb2, 0x11, 0x11, 0x16, 0xf5, 0x1e, 0x31, 0xdf, 0x44, 0x7d, 0xe7, 0x3f, 0x33, 0x58, 0x72, 0xe, 0x7f, 0x5b, 0x4e, 0x7f, 0x7e, 0x1, 0x86, 0x6, 0x86, 0x26, 0xbf, 0xb6, 0xda, 0xf, 0xf3, 0xe6, 0x1c, 0x20, 0xd2, 0x0, 0xfe, 0x7d, 0xb1, 0x52, 0x5e, 0x6c, 0xcf, 0x47, 0x4c, 0x19, 0x4b, 0xc5, 0x61, 0x89, 0xfa, 0x86, 0x5d, 0xb9, 0xe8, 0x19, 0x73, 0x1e, 0x58, 0x31, 0xfb, 0xd4, 0x76, 0xf5, 0x8e, 0xae, 0x6a, 0xc, 0x5f, 0x75, 0xd3, 0xe7, 0x32, 0xc6, 0x71, 0x66, 0xd0, 0x98, 0x3f, 0x7a, 0x1e, 0x81, 0xf0, 0x14, 0x83, 0xbc, 0xcd, 0x1a, 0xa0, 0x77, 0x94, 0x27, 0x3, 0x79, 0x3d, 0xf8, 0xf1, 0xc3, 0xe4, 0x1b, 0x11, 0x7c, 0xbb, 0x49, 0x7e, 0x4d, 0x8, 0xb, 0xc3, 0xa, 0xec, 0x61, 0x21, 0x3b, 0x49, 0x2e, 0x6e, 0x48, 0x78, 0x6c, 0x65, 0x53, 0x2a, 0x8e, 0x1b, 0x32, 0x52, 0x79, 0xc6, 0x2b, 0x22, 0xbc, 0xcd, 0xa1, 0x77, 0xa, 0x8b, 0x1f, 0x25, 0x7c, 0x5f, 0x9c, 0x6f, 0x51, 0x18, 0x23, 0xca, 0x15, 0x67, 0xe3, 0x29, 0x28, 0x77, 0x44, 0x1d, 0xa, 0x3b, 0x6, 0x56, 0xdc, 0x43, 0x77, 0x8, 0x3, 0x0, 0xc0, 0x8a, 0xd9, 0xa7, 0xbc, 0x9, 0x98, 0x6f, 0x48, 0xb0, 0xc1, 0x4a, 0x97, 0x90, 0xcd, 0x3a, 0xa8, 0x72, 0x40, 0x71, 0xff, 0x40, 0x54, 0x13, 0xd8, 0xaa, 0x3d, 0xd3, 0x5e, 0xb0, 0xb5, 0x1d, 0x22, 0x30, 0x57, 0x80, 0xc5, 0x8, 0xec, 0xc6, 0xc5, 0x47, 0x1b, 0xe2, 0x17, 0x7f, 0xc7, 0x32, 0xf9, 0x97, 0xcb, 0xaf, 0x5c, 0x1e, 0x95, 0x94, 0xc5, 0xbb, 0xf7, 0x27, 0xc0, 0x34, 0x61, 0xd8, 0x15, 0x4f, 0x8c, 0xa9, 0x4b, 0x6, 0x0, 0x80, 0x15, 0x37, 0x9e, 0xf2, 0x2b, 0x81, 0x73, 0xfd, 0x59, 0x89, 0xe0, 0xbc, 0xdb, 0x9c, 0xdf, 0xa3, 0x1f, 0x6, 0x1, 0xaf, 0xd0, 0x38, 0xf3, 0x40, 0xf3, 0x3d, 0x90, 0x8f, 0xa3, 0x50, 0x4b, 0x66, 0x72, 0x3e, 0x92, 0x9d, 0x24, 0x8a, 0x24, 0x8, 0x61, 0x1c, 0x2, 0x1a, 0xe, 0x60, 0xca, 0x51, 0x57, 0x3d, 0x9d, 0x6e, 0xaf, 0xfc, 0x6a, 0x56, 0xe3, 0x68, 0x9c, 0xaf, 0xd2, 0x38, 0xbf, 0x1, 0xe8, 0x2, 0xc, 0x66, 0xa5, 0x8, 0xf0, 0x3, 0x81, 0x4f, 0x1, 0x9c, 0x4d, 0x9a, 0xff, 0x30, 0xc6, 0x4c, 0x5f, 0x31, 0xfb, 0x94, 0x6f, 0x3, 0xe6, 0x6b, 0xa0, 0xf9, 0x6d, 0x28, 0xae, 0xef, 0x27, 0x17, 0xb5, 0x6d, 0x5a, 0xa5, 0x17, 0x6a, 0xfc, 0xbe, 0xf3, 0x2f, 0x7f, 0xd2, 0x43, 0x79, 0xbc, 0x68, 0x8c, 0x9b, 0x75, 0xcf, 0x6b, 0x2f, 0x6, 0x48, 0xa4, 0xc9, 0x8c, 0xb8, 0xf2, 0xa9, 0x23, 0x24, 0xfb, 0x6b, 0x49, 0x69, 0x49, 0x1b, 0xc, 0xb9, 0x95, 0xc6, 0xac, 0x0, 0x78, 0xf3, 0xf2, 0x59, 0x27, 0xbd, 0x19, 0x11, 0xff, 0x13, 0xd6, 0xba, 0xf3, 0x25, 0x9d, 0x60, 0x72, 0xaa, 0x5b, 0xe8, 0xa0, 0xe4, 0x92, 0xc5, 0x6d, 0x4b, 0x6f, 0xd1, 0xd6, 0x78, 0x51, 0x71, 0xc3, 0xcf, 0x95, 0xa4, 0x53, 0xd, 0x4, 0x55, 0x8d, 0xcd, 0x43, 0x5e, 0x2f, 0xca, 0x47, 0x68, 0xcc, 0xf8, 0x95, 0xb3, 0x4f, 0x2e, 0x77, 0xa, 0x7a, 0xd5, 0x25, 0xa8, 0x19, 0x46, 0x5c, 0xf9, 0xd4, 0xf5, 0x92, 0x5e, 0x7, 0x39, 0x6f, 0xc5, 0xac, 0x93, 0xca, 0x6e, 0xf5, 0x3a, 0xfc, 0x4b, 0x4f, 0x35, 0x42, 0xf6, 0x69, 0x41, 0xc7, 0x78, 0x2, 0x1e, 0x73, 0x15, 0x66, 0x58, 0xa7, 0x8b, 0x41, 0x51, 0x78, 0xc, 0x29, 0x45, 0x22, 0x96, 0xf9, 0xbe, 0x38, 0x4e, 0x71, 0xfc, 0x28, 0x4, 0x29, 0x26, 0x8d, 0xf6, 0x60, 0x15, 0x7f, 0x78, 0x7c, 0x97, 0x34, 0x3f, 0x58, 0x31, 0xfb, 0xe4, 0x1f, 0x26, 0x9d, 0x7e, 0xa7, 0xe, 0x9a, 0x23, 0xaf, 0x59, 0x4a, 0xb7, 0x65, 0xfb, 0xe3, 0x24, 0x8e, 0x6, 0xd0, 0xc3, 0xdb, 0x3c, 0x23, 0xd8, 0x87, 0x24, 0x8a, 0x5, 0x18, 0xf1, 0x5c, 0xe9, 0xe4, 0x43, 0x5c, 0xba, 0xa5, 0x58, 0x24, 0xa, 0x65, 0xc5, 0xdf, 0x95, 0xcb, 0x2f, 0xae, 0x4c, 0x8c, 0xf9, 0x46, 0xc1, 0x7a, 0x4b, 0xff, 0xe0, 0x68, 0x3e, 0x63, 0x85, 0xcf, 0xaf, 0xba, 0xf1, 0x94, 0x44, 0xcd, 0xc1, 0x9d, 0x6a, 0xca, 0x5d, 0xf6, 0xd3, 0x63, 0xb5, 0xf2, 0xc6, 0x53, 0x4f, 0x25, 0x53, 0xb7, 0x4a, 0x7c, 0xc3, 0x57, 0xd5, 0x19, 0xbd, 0xce, 0x90, 0x31, 0xcf, 0x61, 0x4d, 0xa1, 0x54, 0xdc, 0x8, 0xbd, 0x32, 0x36, 0x9d, 0xb8, 0x30, 0x96, 0xf8, 0xae, 0x5c, 0x7e, 0x71, 0x71, 0xe2, 0xbe, 0xf1, 0xe4, 0xe3, 0x90, 0x6e, 0x3b, 0x84, 0xe4, 0xb7, 0x92, 0xa6, 0x41, 0x67, 0xdb, 0xf2, 0x1, 0x0, 0xcb, 0x67, 0x8d, 0xb9, 0x16, 0x34, 0xd7, 0x4a, 0x58, 0xf, 0xef, 0x4, 0x92, 0x28, 0x4a, 0xed, 0x56, 0x57, 0xb0, 0xb7, 0x72, 0xb9, 0xb0, 0x52, 0xdf, 0x6, 0x2e, 0x71, 0x7e, 0xf8, 0x36, 0x0, 0x1f, 0x24, 0x8d, 0xfb, 0xba, 0xd2, 0x9b, 0x86, 0x7f, 0xe9, 0xe9, 0xde, 0xa0, 0x1e, 0x25, 0x30, 0x24, 0x5f, 0xbc, 0xb8, 0x3d, 0x74, 0x6b, 0x19, 0x71, 0x4b, 0xa5, 0xd1, 0x16, 0xa9, 0x22, 0x4e, 0x7a, 0xc8, 0x7d, 0x17, 0xac, 0x95, 0xf4, 0x67, 0x2d, 0x73, 0x5d, 0x9b, 0xef, 0xc9, 0x62, 0x5b, 0x4f, 0xa5, 0x7, 0xdd, 0xbe, 0xb7, 0x4b, 0x46, 0xfe, 0x5b, 0x0, 0x92, 0x5e, 0x27, 0xf9, 0xff, 0x56, 0xcc, 0x3e, 0x69, 0x66, 0xd2, 0x38, 0x6f, 0x77, 0x4b, 0x53, 0x25, 0x60, 0xc, 0xcf, 0x12, 0xb0, 0x7f, 0xa1, 0x46, 0x10, 0xc7, 0xa3, 0x49, 0xf0, 0x6e, 0xb5, 0x69, 0xb3, 0xd5, 0x73, 0x89, 0x19, 0x41, 0x17, 0x40, 0xd6, 0x6f, 0xdc, 0x8d, 0x3e, 0x81, 0x63, 0x36, 0x88, 0x28, 0xdc, 0x37, 0xc0, 0x8f, 0xf3, 0xf, 0xc7, 0x38, 0xd7, 0x2f, 0xfb, 0xd9, 0x89, 0xb3, 0xd1, 0xe, 0x50, 0x17, 0x43, 0x40, 0x0, 0x56, 0x9a, 0x2, 0xb0, 0x4f, 0xcc, 0xa0, 0x19, 0x46, 0x54, 0x95, 0x57, 0xf8, 0xfb, 0xa8, 0xb4, 0xa2, 0xde, 0x17, 0x43, 0x41, 0x9a, 0xf2, 0xaf, 0x90, 0x15, 0x34, 0x6c, 0x14, 0x33, 0x24, 0xcd, 0x12, 0x63, 0x9c, 0x13, 0x49, 0x73, 0xa9, 0xf2, 0x7b, 0x39, 0xd2, 0x5b, 0xff, 0x58, 0xd0, 0xe5, 0xe7, 0xbc, 0x87, 0x83, 0xd6, 0xef, 0xf9, 0xf4, 0xf3, 0xb2, 0xf6, 0x22, 0x3e, 0x50, 0x6f, 0x3d, 0x0, 0xb9, 0xb7, 0x7f, 0xab, 0xe8, 0xa6, 0x5f, 0x6b, 0xab, 0x2f, 0x47, 0xe4, 0x36, 0x30, 0x41, 0x99, 0x11, 0x42, 0xc1, 0xc6, 0xf7, 0xc4, 0x12, 0x49, 0xff, 0x43, 0xf2, 0xe9, 0x65, 0x33, 0x47, 0x67, 0x0, 0xfc, 0x6e, 0xe4, 0x55, 0xcf, 0xbe, 0x2d, 0x6b, 0x7f, 0x9, 0x61, 0xcf, 0x12, 0xbe, 0x23, 0x16, 0xa0, 0x1, 0xf9, 0x24, 0xc9, 0x6f, 0x2e, 0x9b, 0x39, 0x7a, 0x59, 0x72, 0x18, 0x6e, 0xd, 0x75, 0xd3, 0x3, 0xc, 0xbf, 0xf2, 0x99, 0x43, 0xad, 0xd4, 0xd8, 0x7a, 0x7d, 0x21, 0x4a, 0x48, 0xe2, 0x40, 0xbc, 0x74, 0x8f, 0x98, 0x6f, 0xa3, 0x24, 0x7d, 0xc4, 0xe4, 0x17, 0x91, 0x6, 0x10, 0x78, 0xfb, 0x22, 0x98, 0xb4, 0xb, 0xc9, 0x76, 0xa4, 0x31, 0xf, 0xd2, 0x38, 0xa3, 0x40, 0xf3, 0x79, 0x3a, 0xd, 0x4f, 0x2c, 0xff, 0xd9, 0x89, 0x39, 0x1f, 0xc5, 0x65, 0x33, 0x47, 0x3f, 0xe, 0x9a, 0xa1, 0x2, 0x7e, 0xed, 0x37, 0x79, 0x81, 0x94, 0x37, 0xc9, 0xc8, 0x60, 0x1, 0x89, 0x1, 0x79, 0x9b, 0x80, 0x69, 0xed, 0x4d, 0x7c, 0xa0, 0x9e, 0x7a, 0x0, 0xa2, 0x1f, 0xc1, 0xc6, 0xdc, 0x53, 0x4e, 0xb2, 0x2a, 0xd7, 0x52, 0x5b, 0x79, 0xd0, 0xf8, 0xdd, 0x27, 0x83, 0x77, 0x88, 0x77, 0x57, 0x60, 0x44, 0x7a, 0xe5, 0x7b, 0x89, 0xfc, 0x9c, 0x7d, 0xe0, 0xe, 0x61, 0xfe, 0xa, 0x70, 0x11, 0xa8, 0x5b, 0x1, 0xbc, 0xe, 0x68, 0xe7, 0xf2, 0x99, 0xa3, 0x23, 0x3d, 0x72, 0x97, 0xff, 0x6c, 0xf4, 0x9f, 0x47, 0x5c, 0xf5, 0xec, 0x64, 0x8, 0x93, 0x24, 0x3b, 0x23, 0xa8, 0x82, 0xef, 0xdc, 0x42, 0x80, 0x5f, 0x3, 0x79, 0xc7, 0x8a, 0x99, 0x27, 0xbc, 0xd7, 0x11, 0x68, 0xaf, 0x1f, 0x6, 0x0, 0x8e, 0x5, 0xd8, 0xc3, 0xf7, 0xc9, 0xa8, 0xc8, 0xc9, 0xc4, 0x9f, 0x7d, 0xa, 0x3c, 0x68, 0x2, 0x46, 0x0, 0x80, 0xd0, 0x92, 0x6c, 0x0, 0x21, 0x71, 0xbd, 0x48, 0x66, 0xab, 0xc6, 0x9b, 0x97, 0x0, 0xb2, 0x20, 0x7, 0x81, 0xdc, 0x22, 0x69, 0xeb, 0xf2, 0x99, 0xa3, 0xdb, 0xe4, 0x88, 0xba, 0x7c, 0xe6, 0xe8, 0x77, 0x46, 0x5e, 0xbd, 0x64, 0x2e, 0xc4, 0xc5, 0x90, 0x9e, 0x5, 0x70, 0xa0, 0xa4, 0x77, 0x40, 0x4e, 0x4, 0xf4, 0xc2, 0xa, 0x6f, 0xc8, 0xe8, 0x10, 0xa8, 0x1b, 0x35, 0x70, 0xf8, 0x97, 0x9f, 0x7d, 0x9e, 0xc4, 0x31, 0xbe, 0x27, 0x47, 0x5b, 0x9, 0x92, 0xd7, 0xbb, 0x3c, 0xcf, 0xd9, 0xdb, 0x1, 0x2c, 0x5, 0x70, 0x32, 0xa0, 0xb3, 0x51, 0x62, 0xdb, 0xd9, 0x90, 0xb7, 0x50, 0x45, 0x6e, 0xed, 0x45, 0xbd, 0x4d, 0x66, 0xf9, 0xcc, 0xd1, 0xd, 0x6d, 0xfa, 0x30, 0x6, 0x46, 0x5e, 0xbd, 0xe4, 0x50, 0x49, 0xc3, 0x0, 0xac, 0x5f, 0x3e, 0xf3, 0x84, 0xd, 0xed, 0x89, 0xe3, 0x48, 0x3c, 0x74, 0x74, 0x86, 0x71, 0x30, 0xe2, 0xaa, 0xe7, 0xde, 0x2, 0xd0, 0x2b, 0xbc, 0xdf, 0x50, 0x29, 0xa2, 0x14, 0xbf, 0x97, 0xf4, 0x17, 0x80, 0x13, 0x1, 0xac, 0xa1, 0x77, 0x9e, 0x71, 0x2f, 0x0, 0x7b, 0x4a, 0x6a, 0x80, 0x77, 0xbc, 0x7d, 0xf, 0x0, 0x9f, 0x2, 0xd4, 0x17, 0xc0, 0xbe, 0x0, 0x3e, 0x9, 0x78, 0x1b, 0x51, 0x55, 0xea, 0xcf, 0x1f, 0xc, 0x33, 0x92, 0x32, 0xa4, 0xe9, 0xb6, 0x7c, 0xe6, 0xf1, 0xd9, 0xb6, 0x7e, 0x1b, 0x5, 0x47, 0x7f, 0x65, 0x69, 0xea, 0xf7, 0x33, 0x8e, 0xad, 0x29, 0x8d, 0x6a, 0xa1, 0x6e, 0x86, 0x0, 0x82, 0x3f, 0x17, 0xf4, 0x15, 0xf9, 0xb, 0xa1, 0x3c, 0xbf, 0x48, 0x8f, 0x28, 0x11, 0x94, 0xf1, 0x37, 0x44, 0xf4, 0x5, 0x32, 0x6f, 0x14, 0xb8, 0xce, 0xcd, 0xba, 0x7f, 0x58, 0x39, 0xfb, 0x44, 0xb, 0x60, 0x93, 0x7f, 0xe5, 0x60, 0xc4, 0xd5, 0x2f, 0x90, 0xb0, 0x3d, 0x0, 0xee, 0x9, 0x8f, 0x21, 0xfa, 0xc8, 0x6a, 0x89, 0x31, 0x74, 0x0, 0x6f, 0x71, 0x65, 0x5, 0x83, 0x8e, 0x7f, 0xca, 0x6d, 0x32, 0xde, 0x81, 0x9d, 0x45, 0x7c, 0xa0, 0x8e, 0x18, 0x40, 0xc0, 0x8f, 0x48, 0xb3, 0x44, 0xb2, 0x97, 0x82, 0x3c, 0x2d, 0x24, 0x4, 0x14, 0xf4, 0xba, 0x7e, 0x80, 0xbf, 0xf, 0x1e, 0x20, 0x6b, 0x9, 0xe0, 0xfb, 0x12, 0x1f, 0xf5, 0x89, 0x1f, 0x9, 0xcb, 0x6f, 0x38, 0x4e, 0x0, 0xb6, 0xf8, 0x17, 0x46, 0x5c, 0xb5, 0xe4, 0x75, 0x92, 0xbf, 0x15, 0x70, 0x1c, 0x80, 0x22, 0x51, 0xa1, 0x75, 0xe1, 0x42, 0x5c, 0xa8, 0xd0, 0x9e, 0x8c, 0xdb, 0xea, 0xa8, 0x13, 0xad, 0xa, 0xea, 0x46, 0xd, 0x5c, 0x3e, 0xf3, 0xf8, 0xd7, 0x97, 0xdd, 0x30, 0xea, 0x3e, 0x80, 0xd7, 0x1, 0xbc, 0x58, 0xc2, 0xaf, 0x3, 0xe7, 0x92, 0x22, 0x87, 0x11, 0x92, 0x46, 0xa1, 0x77, 0xbf, 0x7, 0xf8, 0xbf, 0xcb, 0x67, 0x1e, 0x5f, 0xd1, 0x59, 0x43, 0xc6, 0x18, 0xd2, 0x98, 0xbb, 0x42, 0xf6, 0xf9, 0x78, 0x3b, 0x7d, 0xa1, 0x4b, 0x97, 0x6f, 0xac, 0x81, 0x5, 0xf8, 0x1a, 0xda, 0xd7, 0x61, 0xa0, 0xdd, 0xa1, 0x6e, 0xd9, 0x77, 0xc4, 0x55, 0x4b, 0x8e, 0x4, 0x30, 0x82, 0xe4, 0x89, 0x0, 0xc6, 0x1, 0x8, 0x6f, 0x11, 0x13, 0x8c, 0xc1, 0x9b, 0x1, 0x9c, 0xb5, 0x7c, 0xe6, 0xf1, 0x4b, 0xaa, 0xc9, 0x63, 0xe4, 0xd5, 0x2f, 0x1c, 0x28, 0xd9, 0x4d, 0xfe, 0xb9, 0x88, 0xa5, 0x5c, 0x0, 0xa, 0xc0, 0xd7, 0x30, 0x32, 0x92, 0x16, 0x1, 0x98, 0xbc, 0x7c, 0xe6, 0xf1, 0x65, 0x17, 0x61, 0xd6, 0x2b, 0xd4, 0x2d, 0x3, 0x4, 0x30, 0xe2, 0xea, 0xe7, 0xfb, 0x0, 0x38, 0x3, 0xc0, 0xbf, 0x10, 0x3c, 0xa, 0xc0, 0x18, 0xdf, 0x4a, 0xb0, 0x43, 0xd0, 0x95, 0xcb, 0x6f, 0x18, 0x75, 0x47, 0x8d, 0xe9, 0x3f, 0x65, 0x68, 0x8e, 0x87, 0x77, 0xf6, 0x9e, 0xe7, 0x25, 0x1c, 0xc3, 0xa, 0xb2, 0x5, 0xea, 0xc2, 0x2e, 0x2b, 0xfb, 0x9f, 0x0, 0x7e, 0xb8, 0xfc, 0x86, 0x51, 0x5d, 0xc, 0xd0, 0x11, 0x70, 0xd4, 0x57, 0x96, 0xe, 0x7, 0x30, 0x9, 0x5e, 0x6f, 0xb0, 0xe9, 0xc5, 0x19, 0xc7, 0x7e, 0xb7, 0x96, 0xf4, 0x46, 0x5e, 0xb3, 0x94, 0x92, 0x3d, 0x95, 0xe4, 0xaf, 0x0, 0xec, 0x11, 0xee, 0x5, 0x22, 0xb4, 0x90, 0x9c, 0xfc, 0xe1, 0x3f, 0x5b, 0x0, 0x63, 0x49, 0xf3, 0x48, 0x67, 0x2c, 0x4d, 0x4f, 0xa, 0x76, 0x2b, 0x6, 0x68, 0xf, 0x18, 0x79, 0xcd, 0xd2, 0x3d, 0x24, 0xbd, 0x4c, 0xf2, 0xc0, 0x62, 0xb5, 0x33, 0xce, 0x5b, 0x59, 0xd2, 0x26, 0x92, 0x2f, 0x91, 0xbc, 0xf8, 0xc5, 0x19, 0xc7, 0x6c, 0x6a, 0x4b, 0x3e, 0xf5, 0xa, 0xff, 0xf4, 0xc, 0x0, 0x0, 0x23, 0xaf, 0x7e, 0xe1, 0x7a, 0x1a, 0x5e, 0x7, 0x20, 0xe5, 0xfb, 0x61, 0x65, 0x0, 0xec, 0x82, 0xb0, 0xb, 0xc4, 0xe, 0x0, 0x5b, 0x24, 0x6d, 0x26, 0xb9, 0xd, 0xc2, 0x66, 0x41, 0x4b, 0x8c, 0x31, 0xbf, 0xfb, 0xfd, 0x4f, 0x8e, 0x59, 0x57, 0x63, 0xd6, 0x9d, 0xe, 0x75, 0xa3, 0x6, 0x76, 0x26, 0xd0, 0x98, 0xff, 0x91, 0x74, 0x8, 0x80, 0x1e, 0x24, 0xb7, 0xc0, 0xdb, 0x5b, 0x6f, 0x33, 0xd, 0xdf, 0x3, 0xf0, 0xb6, 0xa4, 0x57, 0x1, 0xbc, 0xf4, 0xe2, 0x8c, 0x63, 0xdf, 0xe9, 0xec, 0xb2, 0x76, 0x41, 0x17, 0x74, 0x41, 0x17, 0x74, 0x41, 0x17, 0x74, 0x41, 0x17, 0x74, 0x41, 0x17, 0x74, 0x41, 0x17, 0xd4, 0x6, 0xff, 0x1f, 0x32, 0x68, 0x5, 0x7e, 0x99, 0xd5, 0x97, 0x49, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x80, 0x0, 0x0, 0x0, 0x80, 0x8, 0x6, 0x0, 0x0, 0x0, 0xc3, 0x3e, 0x61, 0xcb, 0x0, 0x0, 0x19, 0xdb, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0xec, 0x99, 0x3, 0x94, 0x7b, 0x39, 0x14, 0xc6, 0xd7, 0xb6, 0xed, 0x87, 0x62, 0x6d, 0xdb, 0x33, 0xe5, 0x6b, 0xc7, 0x6b, 0xdb, 0xb6, 0x77, 0x5c, 0xb7, 0x6b, 0xdb, 0xb6, 0x6d, 0xdb, 0xb6, 0xbd, 0xdb, 0x74, 0xbf, 0xde, 0xe6, 0x35, 0xff, 0xe6, 0xcc, 0xdb, 0x1d, 0x9f, 0x37, 0xd3, 0xe4, 0x9c, 0xdf, 0x49, 0x5e, 0x9c, 0x7c, 0x37, 0x37, 0x39, 0xed, 0x54, 0x2a, 0xa8, 0xa0, 0x82, 0xa, 0x2a, 0xa8, 0xa0, 0x82, 0xa, 0x2a, 0xa8, 0xa0, 0x82, 0xa, 0xf5, 0x17, 0x8c, 0x48, 0x6a, 0xe, 0x23, 0xd4, 0x73, 0xa5, 0x16, 0xe8, 0xba, 0x5f, 0xb, 0x74, 0xdf, 0xac, 0x87, 0x7a, 0x2f, 0x34, 0xc3, 0xfd, 0x9d, 0x66, 0x24, 0x71, 0x0, 0xca, 0xa2, 0x66, 0x34, 0xb3, 0xba, 0x37, 0x9e, 0x5f, 0x78, 0x92, 0x2e, 0x5f, 0x5, 0x3d, 0xd4, 0x77, 0xe6, 0x72, 0xd, 0xa7, 0x33, 0x50, 0x2a, 0xa3, 0x35, 0x9c, 0x5e, 0xd4, 0x1a, 0xcf, 0xfc, 0x19, 0x7c, 0xae, 0x35, 0x76, 0xbe, 0xa5, 0x5, 0x3a, 0x9f, 0xd5, 0x1a, 0xbb, 0x1e, 0xd4, 0x83, 0x3d, 0xb7, 0x1b, 0xe1, 0xbe, 0x4b, 0xcd, 0x48, 0xf2, 0x0, 0x4f, 0x2c, 0xe7, 0x9f, 0x4, 0x4b, 0x57, 0xc1, 0x13, 0x3f, 0x6b, 0x16, 0x8, 0xfc, 0xe9, 0x72, 0xd, 0x67, 0x94, 0xb4, 0xc6, 0x32, 0x67, 0x56, 0x41, 0x9e, 0xc, 0x2f, 0xeb, 0xfc, 0xa, 0xc6, 0x70, 0x97, 0xc7, 0xca, 0x2c, 0x3e, 0x8e, 0x53, 0x55, 0xc1, 0xb4, 0xb2, 0x1b, 0xeb, 0x70, 0xcd, 0x38, 0xb1, 0x29, 0x23, 0x92, 0x38, 0x79, 0xa4, 0xfd, 0xad, 0xbe, 0xff, 0x63, 0x53, 0x1b, 0xd1, 0xf4, 0x36, 0x7a, 0xa0, 0xf3, 0x77, 0x12, 0xb6, 0xe1, 0xc, 0x46, 0xb1, 0x94, 0x6, 0xac, 0x36, 0x26, 0x63, 0x28, 0xc2, 0x0, 0x1a, 0xd6, 0x3c, 0xf0, 0x89, 0xa9, 0x95, 0x32, 0x63, 0x18, 0x8c, 0x68, 0x66, 0x29, 0x23, 0x92, 0xdc, 0x5, 0xc2, 0x77, 0xe1, 0x7e, 0x7e, 0xaa, 0x2a, 0x4a, 0xa0, 0xf3, 0xf, 0xe4, 0xef, 0x30, 0x62, 0xf7, 0x1f, 0xec, 0x7d, 0x0, 0xfd, 0xfd, 0x83, 0xfe, 0x4a, 0x2, 0xea, 0xdf, 0x11, 0xee, 0x5, 0x7e, 0xc7, 0x55, 0x70, 0x4, 0xd2, 0xd3, 0x28, 0x95, 0xc6, 0xe6, 0xb4, 0xaf, 0x60, 0x46, 0x53, 0xbb, 0x18, 0xa1, 0xbe, 0xab, 0xb0, 0xd9, 0x3f, 0x83, 0xaa, 0x6b, 0xd6, 0x85, 0x8, 0xdf, 0x98, 0x56, 0x66, 0xbd, 0x61, 0x8f, 0x11, 0xcb, 0x2d, 0x36, 0x45, 0x9f, 0xc, 0x94, 0x6, 0x3, 0x1f, 0xfb, 0x2f, 0x23, 0xdc, 0x7f, 0x99, 0x1e, 0x18, 0x5d, 0x3, 0x50, 0xc2, 0x47, 0xb3, 0xcb, 0x43, 0xf8, 0x3d, 0xe1, 0xe6, 0xef, 0xc4, 0x26, 0x33, 0x50, 0x2, 0xd8, 0xf8, 0xae, 0x32, 0x8c, 0xc7, 0x94, 0xbf, 0x1c, 0x84, 0xc0, 0x9, 0x7e, 0xdc, 0x13, 0xcb, 0xcf, 0x3f, 0xf4, 0x97, 0x7f, 0x72, 0x7a, 0x33, 0x9a, 0xde, 0x1b, 0xfd, 0xd0, 0xe9, 0x47, 0x9f, 0x83, 0x86, 0xe6, 0x14, 0xe8, 0x2a, 0xe2, 0x1d, 0xf0, 0xa2, 0x27, 0x5e, 0x98, 0x56, 0xa9, 0x36, 0xa, 0x1, 0xaf, 0xea, 0xc5, 0x3d, 0xb1, 0x6c, 0xb, 0x4e, 0xfc, 0xdd, 0xd8, 0xdc, 0x12, 0x87, 0x8b, 0xce, 0xd3, 0x41, 0x21, 0x2, 0x44, 0x63, 0x4, 0xd2, 0x30, 0x98, 0x33, 0xe1, 0x9, 0x66, 0x1a, 0xd2, 0x78, 0x10, 0xe, 0x2f, 0xfa, 0x47, 0xf4, 0x60, 0x37, 0x84, 0xa4, 0xfe, 0x2a, 0xfd, 0xcb, 0x4, 0x44, 0x9a, 0x8b, 0xcf, 0xec, 0x34, 0xc6, 0xfe, 0xc1, 0xd7, 0x7a, 0xe1, 0x74, 0x4a, 0xbd, 0x51, 0x8, 0x10, 0x31, 0x3, 0x31, 0x4a, 0x53, 0xc0, 0x0, 0x17, 0x5e, 0xe4, 0xf3, 0x3c, 0x2a, 0xe3, 0x14, 0xc9, 0x8, 0xac, 0xac, 0x5, 0x61, 0x1c, 0xdd, 0xb1, 0xaf, 0xf5, 0xa2, 0xe9, 0x4c, 0x2b, 0x37, 0xbf, 0x27, 0x56, 0x58, 0x6, 0xc6, 0x66, 0x80, 0xd, 0xd1, 0xf6, 0x1f, 0xd1, 0x8f, 0xe8, 0xd3, 0x19, 0x31, 0x3e, 0x28, 0x95, 0xbd, 0x7, 0xfa, 0x55, 0x6, 0x30, 0x1a, 0x1, 0xae, 0xfc, 0xb, 0x3d, 0x20, 0x84, 0x1f, 0x4, 0x4c, 0x8, 0x82, 0x38, 0xd4, 0xfb, 0x11, 0xae, 0x82, 0xd5, 0x21, 0xec, 0xac, 0x38, 0xdd, 0xcb, 0x80, 0x55, 0xbc, 0xf1, 0xc2, 0x9a, 0xde, 0xa6, 0xc2, 0x5a, 0x65, 0xb1, 0xe1, 0x21, 0x3a, 0x60, 0x64, 0xdd, 0x78, 0x4c, 0x5e, 0x8b, 0xbb, 0xfb, 0x1, 0x78, 0x9a, 0x77, 0xe5, 0xbe, 0x6, 0xd, 0x79, 0x25, 0x1a, 0xf7, 0xaf, 0xd1, 0xb8, 0x2, 0x3c, 0x4d, 0xe7, 0xcc, 0xa2, 0x5e, 0xfb, 0xe1, 0xc4, 0xc3, 0xb8, 0x53, 0x8b, 0xa0, 0x4, 0x18, 0xc5, 0x32, 0x21, 0xe9, 0x3b, 0x0, 0xe1, 0x0, 0xd2, 0x24, 0x20, 0xee, 0xf5, 0xcb, 0x71, 0xaf, 0x1f, 0xd, 0x91, 0xef, 0x45, 0xde, 0xaf, 0xbc, 0x9e, 0x83, 0x90, 0x7c, 0x1c, 0xe0, 0x3c, 0x8e, 0x9c, 0xcf, 0xc7, 0x14, 0x75, 0xfe, 0x42, 0x5f, 0x23, 0x7a, 0x4, 0x7a, 0x9b, 0xce, 0x5a, 0x1a, 0xde, 0x6b, 0x6f, 0x18, 0xef, 0xf2, 0x75, 0xfe, 0x6, 0xc8, 0x9e, 0x82, 0x53, 0xf9, 0x43, 0x79, 0x73, 0x8d, 0x50, 0x6f, 0x15, 0x5d, 0x66, 0xa0, 0x7c, 0xb4, 0x41, 0x5c, 0xe4, 0x69, 0x81, 0x28, 0x23, 0xb1, 0x45, 0x1b, 0xa4, 0xed, 0x7c, 0xb9, 0x4c, 0x8c, 0xed, 0x38, 0x9e, 0x21, 0xc6, 0xf9, 0x1b, 0x1e, 0x60, 0x35, 0x33, 0x96, 0x5b, 0xc4, 0xdb, 0x7c, 0xee, 0xec, 0x43, 0x59, 0x2f, 0xea, 0xcf, 0xe2, 0x8d, 0x9f, 0x65, 0xea, 0xe1, 0xbe, 0x77, 0x78, 0xbf, 0x5f, 0x9a, 0xb1, 0xfc, 0x46, 0xde, 0xa6, 0xb3, 0x67, 0xa8, 0x4b, 0x3, 0xc0, 0xe2, 0xb7, 0x81, 0x1, 0x7c, 0x62, 0x88, 0xd, 0x66, 0x94, 0x1e, 0x1c, 0x8c, 0xb7, 0xb1, 0xd3, 0xf2, 0x77, 0x69, 0x94, 0xa9, 0xf1, 0x1e, 0xb8, 0x52, 0xde, 0xc1, 0x15, 0x73, 0x3a, 0xae, 0x1c, 0x1d, 0xcc, 0x8a, 0xbc, 0xff, 0xf4, 0xa, 0x38, 0xed, 0xb, 0xa2, 0xfe, 0xa1, 0x7a, 0x10, 0xfd, 0x10, 0x3d, 0xd5, 0xf9, 0x22, 0xff, 0x8, 0xfc, 0xef, 0x30, 0x5f, 0xfd, 0x79, 0x80, 0xa6, 0xb3, 0x97, 0xc1, 0x46, 0xbe, 0x5b, 0x39, 0x91, 0x10, 0x2d, 0xdc, 0x87, 0x8d, 0x96, 0x8, 0x3b, 0xe0, 0x58, 0x26, 0xb5, 0x1d, 0x29, 0x21, 0x82, 0xe6, 0x27, 0xf2, 0x78, 0x9a, 0x83, 0x77, 0xc6, 0x75, 0xf0, 0xa, 0x1b, 0x7a, 0x5b, 0xce, 0x9b, 0x7d, 0xa0, 0x5f, 0x9, 0x51, 0xa6, 0xe3, 0xaa, 0xba, 0x8f, 0xd7, 0x2f, 0xf2, 0xd8, 0xf6, 0x2c, 0xd4, 0x97, 0xc7, 0xca, 0xe4, 0x51, 0x6f, 0xa9, 0xfa, 0xf3, 0x2, 0x91, 0xe4, 0x6b, 0x7a, 0x79, 0x83, 0xab, 0x9b, 0xda, 0xcf, 0x41, 0xda, 0x19, 0x51, 0x67, 0xbc, 0x9, 0xf5, 0x31, 0xc2, 0x9e, 0x27, 0xd2, 0x95, 0xf9, 0x93, 0x21, 0x3c, 0xf, 0x11, 0x1b, 0xa4, 0xfb, 0x7e, 0x53, 0x94, 0x15, 0x1, 0xd5, 0x95, 0xfb, 0xe1, 0x6b, 0x29, 0x52, 0x1c, 0x49, 0x3d, 0x8c, 0xff, 0x29, 0xd6, 0xad, 0x2f, 0x3, 0x88, 0xa6, 0x1f, 0xe2, 0x1b, 0xc8, 0x45, 0x75, 0x3b, 0x10, 0x8d, 0x10, 0x79, 0x7c, 0xfe, 0x94, 0xaf, 0x93, 0xa0, 0xc9, 0x67, 0x60, 0x8, 0xdb, 0xe2, 0x6a, 0x68, 0xa5, 0xb2, 0x8a, 0xc8, 0x4c, 0xea, 0x8b, 0x11, 0xa2, 0xf, 0x6, 0x60, 0x4, 0x89, 0xf, 0xcc, 0x58, 0xa1, 0xa5, 0x8e, 0x1e, 0x82, 0xf9, 0x5d, 0xe1, 0x1e, 0x3f, 0xb5, 0x4f, 0x13, 0xc5, 0x13, 0x9, 0x31, 0x67, 0x56, 0xf5, 0x8, 0x38, 0xd1, 0xe0, 0x4f, 0x23, 0x9c, 0x0, 0x55, 0x8f, 0xc5, 0x78, 0x2c, 0x90, 0xda, 0x89, 0xba, 0x89, 0x6f, 0x60, 0x3c, 0x7, 0xd4, 0xcb, 0x3b, 0xc0, 0x84, 0x1, 0xbc, 0x42, 0x9b, 0x10, 0x49, 0x4c, 0x48, 0x20, 0x18, 0xab, 0xc4, 0xfd, 0x22, 0x3d, 0xe5, 0x37, 0x21, 0xca, 0x64, 0x50, 0xc6, 0xe4, 0x7e, 0xf4, 0x70, 0xe2, 0x73, 0x3c, 0x92, 0xf, 0x98, 0xec, 0xff, 0xcb, 0xc7, 0x70, 0xef, 0xbd, 0x86, 0x85, 0x17, 0xcb, 0x8b, 0x36, 0xb1, 0xf8, 0x9, 0xe, 0x93, 0xd3, 0xc3, 0xc0, 0xf6, 0x28, 0x48, 0x27, 0x3f, 0x81, 0x27, 0x38, 0x74, 0x92, 0x8a, 0x5f, 0xc8, 0xe0, 0xe4, 0x7f, 0x66, 0x9f, 0x2, 0x2c, 0x96, 0xf1, 0xb8, 0x9e, 0x21, 0x2f, 0x60, 0xef, 0x5, 0xe, 0xc7, 0x77, 0x78, 0x44, 0x9e, 0x30, 0x19, 0xff, 0xef, 0xbf, 0xdf, 0x8c, 0xa4, 0x7e, 0x31, 0xb0, 0x60, 0xc0, 0xc5, 0x47, 0x1c, 0x55, 0x88, 0xfd, 0xc0, 0x61, 0xb0, 0xb2, 0xf7, 0xfb, 0x5b, 0xcf, 0x77, 0xef, 0x8f, 0x44, 0xb0, 0xce, 0x6e, 0xb8, 0xf1, 0x13, 0xf0, 0xb, 0xd7, 0xdc, 0x83, 0xa9, 0xef, 0x6f, 0xbd, 0x60, 0x66, 0x2c, 0xea, 0xc1, 0xaa, 0xf0, 0xd1, 0x54, 0x19, 0x26, 0xd2, 0xa, 0xc0, 0xf7, 0x26, 0xfd, 0x15, 0x7e, 0x21, 0x3c, 0xd8, 0xb5, 0xe2, 0x43, 0xf4, 0xd5, 0x30, 0x49, 0xb8, 0xf0, 0xd4, 0xf, 0x10, 0xf5, 0x21, 0x3c, 0x58, 0x2e, 0x87, 0x31, 0x9c, 0x8c, 0xfc, 0xe5, 0x1c, 0xfe, 0xfc, 0x58, 0x16, 0xf5, 0x1e, 0xe6, 0x8b, 0x23, 0xd0, 0x96, 0x21, 0x6, 0x3, 0x6d, 0x44, 0x5a, 0xa4, 0x1d, 0xcb, 0x44, 0x1d, 0xc7, 0x6f, 0x30, 0xf8, 0xbe, 0xd3, 0x36, 0xe, 0x79, 0xce, 0xed, 0x6, 0x3f, 0x5f, 0xe7, 0x36, 0x6, 0x3f, 0x10, 0xa0, 0x7c, 0xfa, 0x6f, 0x5d, 0xbe, 0xfd, 0xa2, 0x99, 0xdd, 0x29, 0x7e, 0xcb, 0x85, 0xb3, 0xe3, 0xdf, 0xb6, 0x87, 0xb0, 0x80, 0x62, 0xed, 0x42, 0x33, 0x3f, 0x22, 0xff, 0x61, 0x18, 0x42, 0x2, 0x86, 0xd0, 0xe2, 0x6f, 0xbf, 0x68, 0xae, 0x4a, 0xfd, 0xf3, 0x56, 0xc2, 0x82, 0x9e, 0x94, 0x36, 0x85, 0x99, 0x56, 0xba, 0xc4, 0x51, 0x60, 0x3f, 0x80, 0x2d, 0xfe, 0xfb, 0xde, 0xe6, 0x73, 0xda, 0xdc, 0xfc, 0x7a, 0x3f, 0xdb, 0xb6, 0x60, 0x8f, 0x95, 0x61, 0x9c, 0xda, 0x93, 0x62, 0xe5, 0xde, 0x41, 0xbd, 0x2b, 0x40, 0x17, 0x8c, 0xe2, 0xbe, 0x4a, 0xdd, 0x34, 0xd5, 0x3, 0x76, 0x5b, 0x90, 0x16, 0x38, 0x7e, 0x67, 0xfe, 0x87, 0xb4, 0x8c, 0x63, 0x19, 0xcf, 0x77, 0x48, 0x3b, 0xd7, 0x1d, 0xfc, 0x5c, 0x9d, 0xe7, 0x3b, 0xe0, 0xba, 0xb8, 0xf8, 0xbc, 0xe, 0xa3, 0x7d, 0x89, 0x17, 0xce, 0x5d, 0x79, 0xa7, 0xab, 0xa7, 0x73, 0xa5, 0xf8, 0xbe, 0x96, 0xf3, 0x22, 0x34, 0x51, 0x12, 0x31, 0x23, 0x26, 0x2e, 0x16, 0x4e, 0x65, 0x44, 0x94, 0xc7, 0x94, 0x9f, 0x2d, 0xe2, 0xbb, 0xc6, 0x60, 0x14, 0x2, 0x3a, 0xfd, 0xd8, 0x1f, 0x6f, 0xbc, 0xf0, 0xa4, 0xaf, 0xe5, 0xfc, 0xd, 0x5c, 0x29, 0x3e, 0x1e, 0x71, 0x8b, 0xe3, 0x34, 0xbf, 0xc5, 0x5, 0x2d, 0x3, 0xb1, 0x21, 0x66, 0xc, 0x69, 0xe, 0xff, 0xa6, 0x32, 0x29, 0x5f, 0xe4, 0x59, 0x20, 0x36, 0x78, 0x44, 0x9b, 0x11, 0x62, 0x11, 0xa3, 0xd7, 0xc6, 0x12, 0xf1, 0xb0, 0xd6, 0x21, 0xd2, 0xd5, 0x83, 0x2, 0xd7, 0x7f, 0x90, 0x3b, 0x4f, 0x7e, 0xeb, 0x85, 0x33, 0x60, 0x72, 0xbd, 0x74, 0xaa, 0x69, 0xe2, 0x5c, 0x4c, 0x97, 0x62, 0xd6, 0x1a, 0x20, 0xe3, 0x79, 0x55, 0x44, 0x3d, 0xd7, 0xcc, 0x97, 0xf0, 0x36, 0xb9, 0xd0, 0x0, 0xfc, 0xed, 0x17, 0x4f, 0xb, 0xb7, 0xb4, 0x79, 0xed, 0x6, 0xe6, 0xdc, 0x2, 0x89, 0x2d, 0xa5, 0x1, 0xa5, 0x6b, 0x90, 0xda, 0x38, 0xaf, 0x43, 0xb4, 0xa7, 0xf4, 0x78, 0xad, 0x1, 0x94, 0xef, 0xff, 0x47, 0x7c, 0xad, 0x17, 0xac, 0xef, 0x2a, 0x3, 0x58, 0xbe, 0xfd, 0xe2, 0x85, 0xf1, 0x98, 0x7b, 0xca, 0x63, 0xfd, 0xcb, 0xbd, 0x39, 0x0, 0x3b, 0x8f, 0x45, 0x71, 0xbc, 0x9f, 0x6d, 0xd, 0xd6, 0xae, 0xd7, 0xb6, 0xed, 0xdd, 0x87, 0x6a, 0x6d, 0xdb, 0xb6, 0x8d, 0xc7, 0xba, 0xfd, 0xb4, 0xb6, 0x6d, 0xdb, 0xb6, 0xed, 0xde, 0xee, 0x2f, 0xed, 0x49, 0x5e, 0xa6, 0x93, 0x4f, 0x2f, 0x49, 0x1f, 0x32, 0xf3, 0x9f, 0x73, 0x73, 0x93, 0x1e, 0xfe, 0xef, 0xe9, 0x4d, 0xa6, 0xd5, 0x93, 0x73, 0x9d, 0xcd, 0xa4, 0x5c, 0x37, 0xd7, 0x6b, 0x60, 0x7e, 0xef, 0x37, 0xfc, 0xc0, 0x37, 0x5, 0x6a, 0x3f, 0xf7, 0x23, 0x9, 0xfd, 0x0, 0xbc, 0x2, 0x9e, 0xe6, 0xbd, 0xc5, 0xc3, 0xbe, 0xc6, 0xd6, 0x7, 0x79, 0xbe, 0xbe, 0x9f, 0x78, 0x90, 0x2d, 0x8f, 0x82, 0x67, 0x19, 0xbf, 0xce, 0xbd, 0x5f, 0xf0, 0x99, 0xff, 0x2a, 0x3a, 0x80, 0xb5, 0xd, 0xfb, 0x64, 0xb0, 0x88, 0x4f, 0xf4, 0x32, 0xb7, 0xeb, 0x75, 0x25, 0xed, 0x1c, 0x9f, 0xee, 0xd, 0x44, 0x52, 0xbd, 0xe3, 0xb7, 0x1, 0xe1, 0xfd, 0x1f, 0x1a, 0x0, 0x23, 0xb7, 0x16, 0x67, 0x4b, 0x38, 0x59, 0xd6, 0xe1, 0xab, 0x82, 0x79, 0xa4, 0x35, 0x4c, 0xd7, 0xe4, 0x73, 0x48, 0x81, 0xa1, 0xc3, 0x7c, 0xaf, 0xa1, 0x5f, 0xe6, 0x2c, 0xee, 0x17, 0x2, 0x32, 0xd6, 0x24, 0x30, 0x25, 0xf4, 0x6f, 0x92, 0xf7, 0x31, 0x5, 0x7d, 0x96, 0x56, 0x7a, 0x23, 0x8f, 0x9f, 0x67, 0xfa, 0x9a, 0x3a, 0x23, 0xf8, 0xbf, 0x26, 0x5f, 0x61, 0x4b, 0xfb, 0x23, 0xe9, 0x89, 0x24, 0x76, 0x94, 0xb7, 0x29, 0x39, 0x34, 0x14, 0xcf, 0x8f, 0x61, 0x3c, 0xd, 0x78, 0xb9, 0x67, 0x43, 0x5f, 0x63, 0xc7, 0xc1, 0xbc, 0xab, 0x48, 0x43, 0x8e, 0x7, 0xf9, 0xfc, 0xab, 0x10, 0xe6, 0xfb, 0x5a, 0xb2, 0x55, 0xfc, 0xec, 0xf2, 0x4f, 0x89, 0xaf, 0x96, 0xf1, 0xc8, 0x9c, 0x39, 0x6e, 0xa4, 0xc5, 0xbc, 0x71, 0x4d, 0xf4, 0x49, 0x9e, 0x79, 0x8c, 0xbe, 0x7a, 0xc9, 0xed, 0xae, 0x18, 0xd8, 0xf3, 0xed, 0x3f, 0x92, 0xe, 0x91, 0xd4, 0xd7, 0x2a, 0x4e, 0xeb, 0x81, 0x3, 0x76, 0xab, 0x95, 0x73, 0x43, 0x2, 0x39, 0x9f, 0xcb, 0x9c, 0x71, 0xcd, 0xfa, 0x7c, 0xee, 0x73, 0xaa, 0x66, 0x5e, 0x19, 0xfa, 0x1b, 0xae, 0xff, 0xe, 0x1f, 0x5f, 0xa2, 0x80, 0x19, 0x8a, 0xdd, 0x10, 0x8e, 0xe7, 0x47, 0xd8, 0xdb, 0xef, 0xa4, 0x97, 0xa3, 0x0, 0xa7, 0xb0, 0xe7, 0xb9, 0x1b, 0xbd, 0xef, 0x51, 0x98, 0xbf, 0x88, 0xd9, 0xec, 0x7, 0xe8, 0xca, 0x47, 0x4d, 0xcc, 0xf3, 0x8c, 0x4b, 0xe6, 0x6b, 0xa5, 0xe8, 0x12, 0x42, 0x37, 0xb4, 0x7c, 0x42, 0x2c, 0xbb, 0xf7, 0x6, 0x2, 0x6c, 0xc2, 0x6a, 0x28, 0xf1, 0xa6, 0xcf, 0x8, 0xb6, 0xce, 0x30, 0xdb, 0x55, 0x66, 0x1f, 0x58, 0xa9, 0x3f, 0xb0, 0x62, 0xdf, 0x64, 0x7f, 0x72, 0x4, 0x6f, 0xcd, 0x86, 0xbb, 0xb4, 0xf9, 0x5d, 0x92, 0x47, 0xdf, 0x2c, 0x64, 0x78, 0x9b, 0x3c, 0xfc, 0x29, 0x44, 0x30, 0x16, 0x82, 0xb, 0xb1, 0x1a, 0x64, 0xa7, 0x8b, 0x3d, 0xe2, 0x8f, 0xe4, 0x86, 0xf5, 0x2c, 0x1, 0x62, 0x85, 0x61, 0xbe, 0xa6, 0x64, 0x33, 0xc9, 0xfe, 0xcf, 0x5b, 0x71, 0xaa, 0x45, 0x69, 0x90, 0xb1, 0xeb, 0xc0, 0x8e, 0xd2, 0x65, 0xd7, 0xb8, 0xe5, 0xf, 0x7e, 0x5d, 0xfb, 0x1d, 0xed, 0x7b, 0xff, 0xba, 0x3d, 0x5, 0xc5, 0x8a, 0x83, 0xe9, 0xa, 0x1d, 0xd8, 0xfe, 0x52, 0xf3, 0x43, 0x5b, 0x10, 0xc8, 0x5a, 0x3f, 0x9d, 0x8e, 0xfd, 0x3f, 0x6c, 0xe6, 0x7a, 0x7e, 0x13, 0x18, 0xcb, 0x8d, 0x60, 0x25, 0x1c, 0x42, 0xf0, 0xa, 0x48, 0xe0, 0xad, 0xba, 0xa3, 0xf3, 0x8, 0xbc, 0xd5, 0x12, 0xe6, 0x7b, 0xac, 0xe7, 0xc, 0x3b, 0xa, 0x30, 0xd6, 0x93, 0xdc, 0xf6, 0x33, 0xdf, 0xd9, 0x97, 0xfa, 0x23, 0x99, 0xa1, 0x3d, 0xb3, 0x20, 0xf2, 0x23, 0xf9, 0x11, 0xcb, 0xeb, 0xf8, 0xf2, 0x87, 0x9e, 0xb, 0xa4, 0x4e, 0xd2, 0xda, 0x58, 0xe6, 0x12, 0xab, 0xc0, 0xf2, 0x1e, 0x20, 0x8b, 0xc, 0x5b, 0x2f, 0xd1, 0x85, 0xa7, 0x59, 0xfd, 0xcd, 0x3d, 0x10, 0xcd, 0xe, 0xa, 0x26, 0x66, 0xc, 0xf6, 0x37, 0x77, 0xe, 0x61, 0x3c, 0x34, 0x10, 0xcd, 0xd, 0x72, 0x91, 0x4, 0x79, 0x48, 0x90, 0x3c, 0x87, 0x60, 0x4b, 0xac, 0xbe, 0x4a, 0x61, 0x4, 0x65, 0xce, 0x2b, 0xd2, 0x29, 0x78, 0xbb, 0xf4, 0x29, 0xfd, 0x5c, 0x83, 0xbf, 0xb1, 0xed, 0x3b, 0x1e, 0x49, 0xd7, 0xec, 0x25, 0xef, 0x45, 0x8e, 0xc6, 0xa7, 0xef, 0x29, 0x52, 0x6d, 0xfc, 0x4e, 0xe4, 0xc2, 0x4c, 0xfa, 0x32, 0x5d, 0xe0, 0xd1, 0x4a, 0xd, 0xe2, 0xc5, 0x61, 0xd8, 0x1d, 0x1e, 0x8c, 0x15, 0xc6, 0x53, 0xf0, 0x15, 0x2, 0x91, 0xcc, 0x26, 0x6c, 0x6c, 0x77, 0x86, 0x20, 0xbb, 0x33, 0x7f, 0x12, 0x73, 0x1b, 0xd0, 0x15, 0x87, 0xb8, 0x16, 0x34, 0xc, 0x1b, 0x8a, 0xa1, 0x33, 0x70, 0x8e, 0xd6, 0xd4, 0x66, 0x10, 0x80, 0xb1, 0xf3, 0x40, 0x37, 0x52, 0x27, 0xc4, 0xbf, 0x7c, 0xf, 0x3f, 0x18, 0x4a, 0x14, 0xc7, 0x7b, 0x7a, 0xd1, 0xa1, 0x25, 0x1c, 0x1f, 0x3f, 0xd1, 0xa, 0x25, 0x79, 0x50, 0x86, 0xef, 0xf6, 0xe3, 0x37, 0x24, 0x5d, 0xe0, 0x4f, 0x48, 0xf0, 0x16, 0xdd, 0xef, 0x27, 0xce, 0x4d, 0xd7, 0x6a, 0xc7, 0x6d, 0xcf, 0x43, 0x8a, 0xd, 0x5d, 0xd, 0x3a, 0xb4, 0xfb, 0xac, 0xc1, 0x30, 0xee, 0x70, 0x56, 0xe3, 0x3f, 0x3a, 0x5b, 0x19, 0x97, 0x9d, 0x86, 0x4e, 0x2e, 0xc6, 0x14, 0xbf, 0xf3, 0x26, 0x4f, 0x2f, 0x3d, 0xe8, 0x48, 0xcb, 0xf8, 0x1a, 0xda, 0x5f, 0x17, 0x5f, 0x55, 0xd5, 0x77, 0xa4, 0xfd, 0xf8, 0xd, 0x9, 0x94, 0x9, 0xc6, 0x35, 0x8b, 0x71, 0x89, 0x8e, 0xb0, 0x8f, 0xfb, 0xef, 0x6, 0x76, 0x9f, 0x3d, 0x38, 0x18, 0xcd, 0x36, 0xf2, 0xd8, 0xc5, 0x2e, 0x5c, 0x73, 0xb8, 0x7d, 0xde, 0x30, 0x7, 0x38, 0x97, 0x39, 0xa0, 0x27, 0x11, 0xe6, 0x13, 0x5c, 0x73, 0xf2, 0x4e, 0x4f, 0x2f, 0x3f, 0x2, 0xb1, 0xdc, 0x12, 0x74, 0x28, 0xde, 0x3d, 0x48, 0xf1, 0xcd, 0xf1, 0x21, 0xad, 0xcf, 0xe7, 0x7d, 0x8f, 0xe8, 0x2, 0xe6, 0xeb, 0xd5, 0x39, 0x73, 0xde, 0xb5, 0xb1, 0x7e, 0xce, 0xe2, 0x3c, 0x67, 0x89, 0xe8, 0xad, 0x3, 0x5c, 0xf, 0x3a, 0xb4, 0xdb, 0x8c, 0x61, 0xb4, 0xa5, 0xcf, 0xb4, 0xf6, 0xa3, 0x3b, 0x69, 0x17, 0xe8, 0xd2, 0xf5, 0x28, 0xc6, 0x5a, 0xf1, 0xef, 0x5d, 0x3a, 0x71, 0x87, 0xb, 0xc1, 0xb8, 0xb2, 0x51, 0xf6, 0xd2, 0xa9, 0x1e, 0xd1, 0xf3, 0x21, 0xb2, 0x5e, 0x50, 0xba, 0x4d, 0x5e, 0x7e, 0x7d, 0x10, 0x8c, 0x65, 0x1b, 0xea, 0xd0, 0xfa, 0x72, 0x61, 0x8, 0xf0, 0x35, 0x28, 0xc3, 0x7e, 0xc7, 0x80, 0xbe, 0x12, 0x80, 0xc9, 0xa9, 0x3b, 0xf8, 0xce, 0x1f, 0xe7, 0xe9, 0x43, 0x7, 0x4f, 0x26, 0xd, 0x90, 0xe0, 0x1d, 0xc9, 0x89, 0x42, 0x2a, 0x89, 0xab, 0x2e, 0xc0, 0x5e, 0x5, 0xec, 0x3, 0xdc, 0xff, 0x21, 0x29, 0xef, 0x6, 0x1e, 0xe4, 0xf5, 0xe9, 0xbf, 0xe, 0x13, 0x80, 0xa4, 0x21, 0x9b, 0x93, 0xaf, 0xf0, 0xd4, 0xb1, 0xb9, 0xa7, 0xf, 0x1e, 0x90, 0xe0, 0x78, 0x56, 0xe1, 0xaf, 0x5a, 0x1c, 0x75, 0x2e, 0xbe, 0xe4, 0xf, 0x19, 0x49, 0x5f, 0xec, 0x6e, 0xfb, 0x8f, 0x17, 0xc6, 0x12, 0xe4, 0x4f, 0x55, 0xe3, 0x9d, 0x40, 0xa4, 0x2d, 0x18, 0x3a, 0x7e, 0x66, 0x77, 0x7d, 0x8c, 0xa7, 0x8f, 0x1e, 0x10, 0x77, 0x2c, 0x5, 0x68, 0x97, 0x78, 0x94, 0xc4, 0x26, 0xd2, 0x45, 0x60, 0x43, 0x0, 0x1, 0x52, 0xf7, 0xb2, 0x2f, 0x59, 0xde, 0x95, 0x0, 0xb5, 0x7f, 0xbf, 0xd2, 0x9a, 0x37, 0x80, 0x0, 0xbf, 0x6b, 0xc6, 0x2, 0xcd, 0x4, 0xd9, 0xdc, 0x89, 0xec, 0x3e, 0x8, 0xa0, 0xaa, 0x7, 0xc9, 0xae, 0x3a, 0xcd, 0xcb, 0x96, 0x29, 0x9e, 0x3e, 0x7c, 0x4, 0xe3, 0x85, 0xb5, 0x28, 0xc2, 0xe3, 0x46, 0x61, 0x9a, 0x91, 0xb, 0x9a, 0x13, 0x8b, 0x31, 0xd2, 0x72, 0xde, 0x9c, 0x47, 0x91, 0x7f, 0xb3, 0x88, 0x4e, 0x77, 0x25, 0x38, 0x94, 0xf, 0x44, 0xf9, 0x75, 0xb4, 0xe9, 0xbf, 0xab, 0x6, 0x93, 0x8e, 0x0, 0x5d, 0x4, 0x94, 0xfa, 0x90, 0xbd, 0xc5, 0xe, 0x9e, 0x7e, 0x70, 0xb0, 0x2, 0x8f, 0xaf, 0xc6, 0x94, 0x2c, 0x49, 0x8c, 0x75, 0x1, 0x36, 0x95, 0x26, 0xd9, 0x8, 0xa6, 0x5d, 0xfc, 0x5d, 0x60, 0xf2, 0xb, 0xd8, 0x87, 0xa1, 0x94, 0x16, 0x60, 0x19, 0xd9, 0x3d, 0x44, 0xb4, 0xcf, 0x57, 0x1c, 0x56, 0x9a, 0x1e, 0x88, 0x75, 0x1, 0xab, 0x67, 0x54, 0x7f, 0x20, 0x0, 0x71, 0x4, 0xd9, 0x8c, 0xdd, 0x6b, 0xe4, 0x87, 0x18, 0xe7, 0x92, 0x7, 0xa4, 0x13, 0x90, 0x7c, 0xa2, 0xf, 0x2, 0x4c, 0x5f, 0x7a, 0xe7, 0x96, 0x81, 0xce, 0x7, 0x96, 0x98, 0xbe, 0xb8, 0x5f, 0xa, 0x86, 0xa1, 0x8a, 0x31, 0xbb, 0xa8, 0xea, 0x4a, 0x7f, 0x45, 0xd2, 0x8c, 0x8d, 0x5f, 0x3f, 0x21, 0x41, 0xdc, 0x66, 0x9e, 0xba, 0x91, 0x47, 0x91, 0xd1, 0xcc, 0x5d, 0x81, 0x78, 0x61, 0x61, 0x67, 0x5f, 0x0, 0xed, 0x71, 0xe3, 0xe0, 0x40, 0xac, 0x10, 0xa3, 0x55, 0xff, 0x7, 0x24, 0xb0, 0x74, 0xb9, 0xbb, 0x40, 0x87, 0x21, 0x79, 0x8e, 0xbe, 0x90, 0x77, 0xb, 0x53, 0xfa, 0x13, 0x1, 0x58, 0x2c, 0xeb, 0x10, 0xdf, 0xb7, 0xa0, 0xec, 0x26, 0xc8, 0x9f, 0xd4, 0x21, 0xa5, 0x18, 0x4b, 0x5e, 0x33, 0xaf, 0x53, 0xab, 0xd, 0xdd, 0xd8, 0xe5, 0x5e, 0xd, 0xc3, 0x84, 0x0, 0x69, 0xfb, 0x68, 0xc6, 0x69, 0x58, 0x1b, 0x4a, 0x4c, 0xdf, 0xd5, 0xd3, 0xcf, 0x8e, 0xf0, 0xee, 0x33, 0x27, 0xb2, 0x61, 0x3e, 0x5d, 0x62, 0x55, 0x5a, 0xac, 0xee, 0x14, 0x5e, 0x8a, 0x8f, 0xd4, 0xc0, 0xea, 0x7f, 0x9f, 0xee, 0x73, 0x56, 0x30, 0x3e, 0x7d, 0x39, 0x9b, 0xc, 0x2e, 0xe, 0xf, 0xed, 0x36, 0x73, 0x51, 0x14, 0xad, 0x1f, 0x88, 0x17, 0x23, 0xc1, 0x78, 0xf1, 0x40, 0x56, 0xea, 0x1b, 0x18, 0x2c, 0x1, 0xcd, 0x90, 0x6d, 0x88, 0x9e, 0x4f, 0x43, 0x89, 0x19, 0x6b, 0x7a, 0xfa, 0xe1, 0x11, 0xde, 0x6d, 0xe6, 0xca, 0x5a, 0x8c, 0x8e, 0xe6, 0xcb, 0xac, 0x8b, 0xc2, 0x9b, 0xe6, 0xbe, 0xd, 0xc6, 0xf3, 0xb3, 0x58, 0x4c, 0xdb, 0xfb, 0xe2, 0x33, 0x7, 0x77, 0xa3, 0xe0, 0x33, 0xc6, 0x51, 0xec, 0x55, 0x29, 0xf4, 0xe, 0xb4, 0xaf, 0x4, 0xf2, 0x68, 0x98, 0xd4, 0xc9, 0xe6, 0xec, 0x9d, 0x40, 0x4, 0x63, 0x20, 0x18, 0x35, 0xa0, 0x19, 0x56, 0xda, 0xd8, 0x6, 0xaa, 0xce, 0xc7, 0xa, 0x47, 0x62, 0x7b, 0x74, 0x7f, 0x24, 0x0, 0xb, 0x68, 0x45, 0xf2, 0xf7, 0x83, 0xe4, 0xce, 0x9, 0x28, 0x73, 0xee, 0x91, 0xac, 0xfa, 0xcc, 0xf7, 0xd8, 0xb8, 0x8f, 0x7a, 0x1d, 0x1a, 0xde, 0x7d, 0xd6, 0xc4, 0xee, 0x32, 0x75, 0x1a, 0x2b, 0xfe, 0x30, 0x1e, 0xc3, 0xde, 0x92, 0x62, 0xeb, 0xc0, 0x68, 0x56, 0x87, 0x32, 0xcf, 0xd9, 0x84, 0x2, 0x15, 0x5d, 0x7c, 0xf7, 0xaf, 0xe6, 0xe9, 0xa7, 0x7, 0xc4, 0x5e, 0x96, 0xe2, 0x3c, 0x23, 0x39, 0x53, 0x8e, 0xe4, 0x4d, 0xea, 0x80, 0xde, 0x2f, 0x59, 0xf1, 0x4f, 0x51, 0xf8, 0x13, 0x58, 0xb0, 0xa3, 0x6c, 0xb6, 0xaa, 0x19, 0xff, 0x73, 0x77, 0xce, 0x51, 0x96, 0x2b, 0x69, 0x0, 0x3f, 0xe7, 0xd9, 0xb6, 0xed, 0x77, 0xb5, 0xb6, 0x6d, 0x7b, 0xdb, 0x5a, 0xdb, 0xb6, 0x6d, 0x7b, 0x9b, 0xd7, 0xcd, 0x35, 0x9f, 0xcd, 0xb1, 0x6d, 0xab, 0xbb, 0xb2, 0xbf, 0x4a, 0xbe, 0x4c, 0x32, 0x75, 0x36, 0xe7, 0x4e, 0xcf, 0xad, 0x34, 0xf2, 0xc7, 0xef, 0x54, 0xa5, 0x92, 0xfb, 0xb9, 0xaa, 0x82, 0xc1, 0x5b, 0x49, 0xfe, 0x3a, 0x84, 0x22, 0x98, 0xa, 0x3, 0x1e, 0x25, 0x1c, 0x4d, 0xa8, 0x2f, 0xfc, 0x1e, 0x22, 0x8e, 0x27, 0x89, 0xd6, 0xc7, 0x2c, 0x79, 0x6c, 0x52, 0xb, 0x0, 0xdf, 0x4e, 0x25, 0x41, 0x9f, 0xc2, 0xcf, 0x88, 0x18, 0xfc, 0x5e, 0x30, 0x8e, 0x5, 0xf3, 0x5c, 0x38, 0x6e, 0x24, 0xfd, 0xbd, 0xd7, 0xbd, 0xb1, 0xfb, 0x70, 0x5b, 0x5f, 0xf7, 0x3e, 0x4d, 0x1, 0xf0, 0x1a, 0x36, 0x30, 0x82, 0xbe, 0x92, 0x7e, 0x6c, 0xf0, 0xc2, 0x64, 0xd7, 0x8d, 0x8d, 0x7d, 0x8f, 0x12, 0x33, 0x92, 0x5a, 0x4, 0x4f, 0x94, 0xb8, 0x5a, 0x8b, 0x27, 0xb9, 0xda, 0x74, 0x63, 0x43, 0xdf, 0xa9, 0x16, 0x97, 0xaa, 0xee, 0x9f, 0x22, 0x14, 0xe1, 0x7f, 0x70, 0xa4, 0xd, 0x61, 0x1c, 0xd7, 0x42, 0x8c, 0xac, 0x71, 0x5e, 0xc9, 0xf1, 0xd2, 0x54, 0x63, 0x7f, 0x3a, 0xc9, 0x5, 0xc0, 0xbe, 0x7c, 0x6d, 0x10, 0x57, 0x30, 0xe2, 0x74, 0x70, 0xf1, 0xa2, 0x15, 0x19, 0x1a, 0x96, 0xfe, 0xed, 0x99, 0xe6, 0xfc, 0xb9, 0x16, 0x5f, 0x5a, 0x74, 0xf7, 0x6a, 0x45, 0x8, 0xd6, 0x28, 0x69, 0xa7, 0x80, 0x3f, 0xde, 0x94, 0x6a, 0xea, 0xbf, 0x3a, 0xd1, 0x5, 0xd0, 0x9c, 0xbf, 0x6, 0x5f, 0x27, 0x2c, 0xc7, 0x6e, 0x77, 0xba, 0x69, 0xe0, 0x3c, 0x8b, 0xcb, 0x54, 0x6f, 0x51, 0xaa, 0x4c, 0xf1, 0xb5, 0xcf, 0x89, 0x1b, 0xf4, 0x78, 0x6d, 0x43, 0xcf, 0x40, 0xaa, 0x69, 0xe0, 0xe2, 0x24, 0x17, 0x0, 0x33, 0xf5, 0x4a, 0x7c, 0x5d, 0x2f, 0x3e, 0xdb, 0x62, 0x3c, 0xdd, 0x3c, 0xad, 0x5, 0xd0, 0x1d, 0x3d, 0x2e, 0x44, 0x9f, 0xb, 0x40, 0xef, 0xf7, 0xd8, 0x2, 0xce, 0x4e, 0xf8, 0xa, 0x70, 0x19, 0x2b, 0xec, 0x82, 0x20, 0x6, 0xd2, 0x46, 0xc7, 0x25, 0x32, 0xd6, 0x37, 0xa, 0x29, 0xa0, 0xb0, 0xce, 0xb7, 0x79, 0xa3, 0x52, 0x14, 0xe1, 0xea, 0x0, 0x43, 0x1a, 0xa4, 0x8d, 0xa2, 0x21, 0x7a, 0xac, 0xd6, 0xef, 0x5d, 0x7d, 0xd, 0xc9, 0x2f, 0x80, 0x54, 0x93, 0x14, 0x0, 0x3e, 0xd7, 0x4b, 0x50, 0x0, 0xdd, 0x14, 0x40, 0xc1, 0x5e, 0x1, 0xa4, 0x75, 0x1, 0x78, 0xa, 0x94, 0x4e, 0x9a, 0x1, 0xf4, 0x84, 0xe8, 0x3e, 0x34, 0x8c, 0xdf, 0x6a, 0x7d, 0x14, 0x40, 0x9e, 0x0, 0x5d, 0x9c, 0xec, 0x15, 0xa0, 0x70, 0x25, 0xbe, 0x6e, 0xa8, 0x15, 0x1b, 0xa8, 0xd1, 0x7, 0xe9, 0x23, 0x6f, 0x3c, 0xd5, 0x68, 0x75, 0xb, 0xe8, 0xeb, 0xe5, 0x8d, 0x1c, 0x82, 0x5d, 0x25, 0xa, 0x9c, 0x98, 0x11, 0x5d, 0xbd, 0x37, 0x11, 0xa0, 0x44, 0xdf, 0x4, 0x66, 0x5a, 0x8a, 0xd7, 0xe8, 0x98, 0xe2, 0xaf, 0xcd, 0xd8, 0xed, 0x4e, 0x59, 0xbd, 0x9, 0x6c, 0xea, 0xff, 0xe9, 0x8d, 0x5a, 0x30, 0xb0, 0x2f, 0x7, 0xec, 0x3f, 0xa6, 0x5, 0x12, 0x6, 0x72, 0x2c, 0xd7, 0x4, 0x63, 0x26, 0xe6, 0xb5, 0xe1, 0xeb, 0x9, 0x8, 0xb2, 0xe9, 0x2f, 0xa5, 0x0, 0x52, 0xc9, 0x2e, 0x80, 0xc2, 0xb5, 0x7e, 0xc, 0x25, 0x1e, 0x26, 0x46, 0xbc, 0x8c, 0x6b, 0x18, 0xf3, 0x5a, 0x81, 0x3e, 0xb1, 0xdb, 0x4e, 0xdc, 0xce, 0xb5, 0xf8, 0xac, 0x9a, 0xff, 0x34, 0x8a, 0xb6, 0x84, 0x92, 0x1e, 0x37, 0x52, 0xc9, 0x3d, 0xbb, 0x52, 0xcd, 0x85, 0x47, 0x25, 0x7c, 0x5, 0x78, 0x8a, 0xf8, 0xab, 0xec, 0xc5, 0xae, 0x77, 0x13, 0x5, 0x70, 0xb2, 0xc5, 0x15, 0x60, 0xe0, 0x2d, 0x6c, 0x3, 0xeb, 0x74, 0xb5, 0x71, 0x3f, 0x0, 0xbd, 0xca, 0x6d, 0x41, 0xc6, 0xac, 0xe3, 0xaf, 0x1c, 0x38, 0xf2, 0xd8, 0xc4, 0xee, 0xff, 0x2d, 0xc5, 0xd3, 0x88, 0xed, 0x67, 0x6d, 0xc7, 0x90, 0x89, 0x43, 0xdc, 0xf2, 0x5f, 0xe6, 0x25, 0xd3, 0x61, 0x76, 0xaa, 0xb4, 0xb5, 0x74, 0x1, 0x37, 0x63, 0x9d, 0xbc, 0x5c, 0xf8, 0x7b, 0xa, 0x5, 0x1, 0x18, 0x2e, 0x7d, 0xbe, 0x6f, 0xab, 0xb4, 0xd7, 0x42, 0xbf, 0x10, 0x36, 0xac, 0x5f, 0xda, 0x10, 0xe6, 0xf5, 0x72, 0xd, 0x72, 0x15, 0xc7, 0x9e, 0xdc, 0xe6, 0x62, 0x52, 0xb, 0x80, 0xb8, 0x96, 0xaf, 0x61, 0x7b, 0xbd, 0xfd, 0x46, 0xb7, 0x0, 0x24, 0x5e, 0x12, 0xb3, 0x50, 0x1f, 0xcc, 0x78, 0x1a, 0xc8, 0x78, 0x28, 0x7e, 0xd0, 0xb7, 0x89, 0x7c, 0xfd, 0x83, 0x42, 0xf8, 0x6c, 0xba, 0xa5, 0x74, 0x8a, 0x8d, 0x6a, 0x3d, 0x1e, 0x41, 0x37, 0x30, 0x23, 0x9f, 0x9b, 0x6e, 0x29, 0x34, 0xd2, 0x7e, 0x12, 0xe1, 0xbf, 0xc4, 0x81, 0x3b, 0x30, 0x6e, 0xf, 0x38, 0x3e, 0x28, 0x57, 0xb4, 0x1a, 0xa7, 0xe, 0x94, 0x57, 0x0, 0x85, 0xf, 0x64, 0xdb, 0xaa, 0x27, 0x26, 0xb3, 0x0, 0x4a, 0x39, 0x9d, 0x28, 0x10, 0x9f, 0xeb, 0x23, 0x15, 0x9e, 0x8c, 0xc1, 0xd8, 0x16, 0xa, 0xe1, 0x6f, 0x4c, 0xe0, 0xf7, 0x90, 0xc3, 0x33, 0xac, 0x19, 0x9f, 0x6b, 0x1f, 0x3c, 0x91, 0xa, 0xbe, 0x98, 0x19, 0xfa, 0x38, 0xda, 0x97, 0xd2, 0xb6, 0xa3, 0xe8, 0x7e, 0x14, 0x4e, 0xa0, 0xd8, 0x9a, 0x43, 0x14, 0xd8, 0xca, 0x6c, 0x6b, 0xf9, 0x9, 0x9, 0xdd, 0x2, 0x1e, 0xe5, 0x27, 0xdf, 0x52, 0x11, 0x28, 0x21, 0x98, 0x88, 0x22, 0x9b, 0x8f, 0x6a, 0x1b, 0xd8, 0x6e, 0xca, 0xe8, 0x7c, 0x4d, 0xae, 0xad, 0x7c, 0x64, 0x5c, 0xe, 0x7d, 0x87, 0x22, 0x18, 0x7, 0x9d, 0x38, 0x87, 0xb6, 0x2e, 0x90, 0xa1, 0xc0, 0x61, 0xe5, 0x79, 0x4d, 0xd2, 0x92, 0xcf, 0xaa, 0x76, 0x3a, 0xf1, 0xfa, 0x9c, 0xc4, 0x49, 0x4d, 0x3e, 0x3e, 0x35, 0xe3, 0xab, 0xcc, 0x38, 0x8a, 0xae, 0x25, 0xe8, 0xfd, 0x52, 0xba, 0xa5, 0x7c, 0x83, 0x55, 0x87, 0x72, 0x9d, 0x23, 0x47, 0x30, 0x53, 0xdf, 0x80, 0x61, 0xe3, 0xae, 0xa2, 0xe6, 0x1, 0x5, 0xce, 0xc1, 0x93, 0x17, 0xa4, 0xef, 0xc9, 0x70, 0xc1, 0xe0, 0x6f, 0x66, 0xdb, 0xca, 0x67, 0x27, 0xab, 0x0, 0x2a, 0x4f, 0x26, 0x19, 0xeb, 0x3, 0x3f, 0xf3, 0x66, 0x1c, 0x26, 0x43, 0xf4, 0x6f, 0x49, 0xbe, 0xf4, 0x69, 0xc1, 0xd5, 0x97, 0x7f, 0x88, 0xed, 0xe7, 0x59, 0x71, 0xdc, 0xd4, 0x5c, 0xe2, 0x57, 0x1e, 0xef, 0xa2, 0x15, 0x38, 0x36, 0xc0, 0xe0, 0xb5, 0xc8, 0x7e, 0x41, 0xc2, 0xf6, 0xff, 0x26, 0x99, 0xa1, 0x76, 0xe2, 0x24, 0xa4, 0xa3, 0xcf, 0x29, 0xf0, 0x56, 0x84, 0xe6, 0xfc, 0x70, 0xb6, 0xbd, 0x7a, 0x41, 0x5c, 0x2f, 0x36, 0x56, 0x84, 0x95, 0xd1, 0x1a, 0x14, 0x4, 0xfa, 0x46, 0xb, 0xe6, 0xb8, 0xd2, 0x20, 0x7, 0xc7, 0x8a, 0xdf, 0xc8, 0xb4, 0x55, 0x4f, 0x4e, 0xc4, 0xde, 0xdf, 0x5a, 0x4e, 0xe3, 0xcf, 0x5f, 0xd3, 0x4d, 0x92, 0x34, 0x29, 0x82, 0x38, 0x11, 0x5d, 0x12, 0xcb, 0x42, 0x8f, 0xfc, 0x27, 0x96, 0xd6, 0xbf, 0x6c, 0x1d, 0x96, 0x69, 0x29, 0xfd, 0x80, 0x76, 0xf, 0x38, 0x14, 0x83, 0x15, 0x90, 0x5, 0x85, 0xa5, 0xec, 0x5b, 0xaf, 0x4c, 0xc8, 0xe3, 0xdf, 0x47, 0x24, 0x3e, 0x4a, 0xda, 0x29, 0x1, 0x5d, 0xa2, 0xaf, 0xf4, 0xeb, 0x58, 0x1c, 0xd3, 0xff, 0x3a, 0x55, 0xa6, 0xb5, 0xf2, 0x54, 0x1e, 0x39, 0x76, 0x90, 0x30, 0x14, 0x15, 0x95, 0x28, 0x17, 0x8a, 0x61, 0x6a, 0x18, 0x5c, 0xf4, 0x8d, 0x76, 0xe5, 0x68, 0x79, 0x2c, 0x9b, 0xbf, 0x47, 0xfe, 0x39, 0xb3, 0x3b, 0xf9, 0x95, 0x27, 0xe3, 0xcf, 0xcd, 0x7e, 0x42, 0x82, 0x38, 0xd0, 0xd6, 0x8e, 0x55, 0x8d, 0x31, 0xe3, 0xd8, 0x40, 0x26, 0xd2, 0x2e, 0xee, 0x3f, 0x3e, 0x19, 0xdf, 0xcd, 0x4d, 0xfb, 0xd0, 0x89, 0xbc, 0xbe, 0xdd, 0x24, 0x5, 0xe0, 0x48, 0x5b, 0x17, 0xfb, 0x65, 0xb5, 0x14, 0xb7, 0x13, 0xc0, 0x8f, 0xcc, 0xd6, 0xe4, 0xe7, 0x3a, 0x86, 0x4e, 0x66, 0xf6, 0xff, 0x42, 0xfc, 0x91, 0xe4, 0x4f, 0x9, 0xca, 0x9f, 0x44, 0xc4, 0x70, 0x8c, 0x18, 0xa6, 0xe2, 0x5e, 0xe2, 0x46, 0x51, 0xb4, 0x17, 0xf4, 0xac, 0xb5, 0x81, 0xd2, 0xa4, 0x5d, 0x67, 0x4a, 0xf, 0xe2, 0xc0, 0x8b, 0x67, 0xe9, 0xa3, 0xdf, 0xc7, 0xf0, 0x61, 0x47, 0xfd, 0x71, 0x29, 0x4e, 0xfe, 0x3a, 0x89, 0x1f, 0xf7, 0x1f, 0x5f, 0x9d, 0x8a, 0x4a, 0xbf, 0x6, 0x65, 0xab, 0x33, 0x35, 0x1c, 0xcd, 0xa, 0xc6, 0x58, 0xe4, 0x31, 0xc9, 0x9f, 0xf0, 0xb6, 0x82, 0xf2, 0xf0, 0x23, 0x3a, 0x87, 0x4f, 0x9a, 0x55, 0xc9, 0x6f, 0x1f, 0x6c, 0xc0, 0xfe, 0x85, 0xe2, 0x8b, 0x3b, 0x23, 0xa3, 0x7c, 0xae, 0x35, 0x6e, 0x9e, 0x97, 0x36, 0x1a, 0x3f, 0xf, 0x5e, 0x1, 0x7c, 0x32, 0x76, 0x67, 0x1f, 0xd9, 0x35, 0x76, 0x34, 0x2f, 0x6f, 0x96, 0x7b, 0xc6, 0x95, 0xad, 0x40, 0xf0, 0x94, 0xb4, 0x1e, 0x6d, 0x95, 0xa1, 0x59, 0xb4, 0xf4, 0x3f, 0x86, 0x7d, 0xf7, 0x56, 0x89, 0x87, 0x2, 0x67, 0xa, 0x51, 0x1a, 0x1d, 0x33, 0x26, 0xce, 0x5c, 0x9e, 0xa4, 0x5e, 0x11, 0xab, 0xb3, 0x8f, 0xe8, 0xfa, 0xd3, 0x11, 0x54, 0x7b, 0x27, 0xca, 0x36, 0x83, 0x93, 0x6d, 0xb3, 0x87, 0xe, 0x20, 0x2d, 0x33, 0x47, 0xfa, 0xed, 0xd5, 0xea, 0xcc, 0x4f, 0xfe, 0x70, 0x8e, 0x2d, 0xeb, 0x1e, 0xdf, 0x76, 0x90, 0xb6, 0xae, 0x38, 0x44, 0xca, 0x89, 0x1a, 0xf7, 0x72, 0x31, 0xf8, 0xb9, 0x78, 0x9d, 0xed, 0x1a, 0x3b, 0x82, 0x6a, 0xff, 0x30, 0xca, 0xf6, 0x7a, 0xa, 0x2b, 0x4a, 0x5a, 0x6b, 0x84, 0xe5, 0xa6, 0x5b, 0xd0, 0xd3, 0x56, 0x2d, 0xcc, 0xdc, 0x65, 0x7f, 0x38, 0x4b, 0x91, 0xce, 0xd1, 0xb6, 0x82, 0x12, 0x1f, 0x94, 0xa5, 0x38, 0x28, 0x5f, 0xae, 0x81, 0x13, 0xc1, 0x38, 0xb9, 0x69, 0x8f, 0xd3, 0xd9, 0xa3, 0x98, 0xf9, 0x5f, 0xa2, 0xda, 0xc7, 0x41, 0x12, 0x55, 0x55, 0xf4, 0x75, 0x2b, 0x84, 0xfb, 0xe1, 0x31, 0xf3, 0x9a, 0xe8, 0xeb, 0x90, 0x17, 0xc8, 0xe5, 0x58, 0xf4, 0xdd, 0xc4, 0xd3, 0xc7, 0x69, 0x33, 0x6b, 0xe6, 0x8f, 0x3c, 0x83, 0xfd, 0x76, 0x19, 0xb6, 0x19, 0x13, 0xa1, 0xaa, 0x20, 0xc2, 0x3f, 0x21, 0x7a, 0x4c, 0xc0, 0x6f, 0x66, 0x39, 0x68, 0xff, 0x77, 0x72, 0x7c, 0x3f, 0x13, 0x61, 0x5, 0x13, 0x62, 0x27, 0x5b, 0xaf, 0x1e, 0x73, 0xf1, 0xfa, 0x65, 0xb7, 0xcf, 0xf9, 0x3b, 0xb2, 0x1d, 0xc3, 0x4f, 0x8f, 0x69, 0xd9, 0x1f, 0x3b, 0x8e, 0x4, 0x7c, 0x27, 0xdd, 0x5a, 0x99, 0xc8, 0x60, 0x1c, 0x55, 0xef, 0x3a, 0x2a, 0xfd, 0x43, 0xa3, 0xcd, 0xe8, 0xb, 0xa6, 0x5c, 0xfa, 0x8a, 0x40, 0x43, 0x65, 0x43, 0xa6, 0x7d, 0x68, 0x46, 0x7c, 0x35, 0xcc, 0xb4, 0xd, 0x7e, 0x8a, 0x80, 0x6f, 0xd4, 0x76, 0x82, 0x97, 0x74, 0xb1, 0xb5, 0xb6, 0xcf, 0xb5, 0x10, 0x59, 0x81, 0xec, 0x7f, 0x7b, 0xdf, 0x62, 0x46, 0x8f, 0xce, 0x76, 0x78, 0xf0, 0x5d, 0xe6, 0x1c, 0xa, 0xf0, 0x6, 0xe2, 0xf1, 0x64, 0x92, 0xfe, 0x12, 0x72, 0xf3, 0x56, 0xda, 0xc7, 0x30, 0x76, 0x78, 0xc, 0xc9, 0x1f, 0x3d, 0x81, 0x7d, 0xee, 0x93, 0xcc, 0xfe, 0xa0, 0xb2, 0xe9, 0x83, 0x73, 0xf0, 0x54, 0xa5, 0x9d, 0x14, 0x4a, 0x74, 0x86, 0x67, 0xd6, 0x16, 0x9c, 0xed, 0x79, 0xf4, 0xbb, 0x6e, 0x8a, 0x7e, 0xcd, 0x19, 0xef, 0xfd, 0xcf, 0xd1, 0xe8, 0x9f, 0xeb, 0xcd, 0xca, 0xfd, 0x3e, 0x29, 0xeb, 0x31, 0xc1, 0x57, 0xdd, 0xb2, 0xa4, 0xdf, 0x49, 0xe2, 0x4f, 0xfd, 0x7f, 0xb6, 0xe8, 0x18, 0x60, 0xc7, 0x61, 0xe4, 0xe7, 0x70, 0xf2, 0x73, 0x24, 0xd7, 0x1f, 0x66, 0xdd, 0x61, 0xaa, 0xea, 0x78, 0xe8, 0xe4, 0xe6, 0x62, 0x42, 0x3b, 0x99, 0xc3, 0x49, 0x8d, 0xf4, 0xe3, 0x45, 0x2, 0x21, 0x7d, 0x25, 0x38, 0xb0, 0x87, 0xc0, 0x2c, 0xcd, 0x52, 0x94, 0xa9, 0x96, 0xca, 0x91, 0x53, 0x91, 0x78, 0x66, 0x1a, 0x1, 0x1e, 0x2a, 0xa2, 0x77, 0x65, 0x78, 0xb5, 0xf2, 0x6d, 0xb2, 0x85, 0x11, 0xdb, 0x7d, 0xe8, 0xfc, 0xcd, 0x74, 0xef, 0x73, 0x4f, 0xcf, 0xba, 0xc6, 0xc, 0xb9, 0x15, 0xae, 0xdb, 0x30, 0x4, 0xc4, 0x3c, 0x6, 0xa3, 0xf, 0x91, 0xbf, 0x33, 0xae, 0x8d, 0xb8, 0x46, 0x85, 0xce, 0x2b, 0x19, 0xd3, 0xf6, 0x6c, 0xa5, 0xf2, 0xef, 0x63, 0x39, 0xfc, 0x44, 0xae, 0x73, 0xec, 0xc4, 0x98, 0xb6, 0xbe, 0x2c, 0x85, 0xf6, 0x1b, 0x96, 0xfc, 0x85, 0x2c, 0xf9, 0x7b, 0xfd, 0x19, 0xea, 0xdb, 0x22, 0x31, 0x89, 0xf0, 0x25, 0x2a, 0x46, 0x35, 0xe3, 0x25, 0x2b, 0xc9, 0xd0, 0xdf, 0x1f, 0xf5, 0xb6, 0xbf, 0x1e, 0x3d, 0xbd, 0x77, 0xb9, 0x1d, 0x23, 0xd7, 0x63, 0xc8, 0x9d, 0xbe, 0x71, 0xfe, 0xb2, 0x2c, 0xc7, 0x53, 0xc9, 0x1, 0x3a, 0x7d, 0x1b, 0x24, 0x50, 0x9b, 0x28, 0x84, 0xb9, 0x24, 0xea, 0x57, 0xd8, 0xfb, 0x4a, 0xf6, 0xc8, 0x93, 0xeb, 0xf4, 0x39, 0x45, 0xe1, 0x7f, 0x94, 0xc2, 0xfa, 0x1b, 0xb2, 0x17, 0xc1, 0x2e, 0x3f, 0xf1, 0xa2, 0xd7, 0xd7, 0x6d, 0xdd, 0xc7, 0xc0, 0xaf, 0xa1, 0xc5, 0xe8, 0x7f, 0xf3, 0xcc, 0xb8, 0xdb, 0xed, 0x1c, 0x7d, 0x3e, 0x6, 0x39, 0x30, 0x41, 0xa0, 0x9d, 0x69, 0x46, 0xb9, 0x48, 0x5f, 0xec, 0xd2, 0x7d, 0xdd, 0xee, 0xa6, 0x8, 0x16, 0xc3, 0xed, 0x30, 0x44, 0x22, 0xbf, 0xc9, 0xc, 0x7e, 0x1d, 0xab, 0x43, 0x9a, 0xfe, 0x85, 0xf4, 0x4f, 0xcd, 0x75, 0xfd, 0xe9, 0x44, 0x38, 0xee, 0x91, 0x6f, 0xfd, 0xcb, 0x89, 0x8c, 0x9d, 0x41, 0xb1, 0x5c, 0xc4, 0xf8, 0xe3, 0xd8, 0x47, 0xdf, 0xc3, 0xf1, 0x0, 0xbf, 0xbb, 0x9, 0xee, 0x67, 0xc6, 0xaf, 0xf7, 0x65, 0x83, 0xa9, 0x57, 0x8f, 0x49, 0xbf, 0x7e, 0x4c, 0x79, 0xf4, 0x27, 0xb0, 0xe5, 0x7f, 0xed, 0x9c, 0x3, 0x90, 0x2c, 0x49, 0x13, 0x80, 0xfb, 0xff, 0xcf, 0xb6, 0x6d, 0x6b, 0x7a, 0xe6, 0x6c, 0xdb, 0xb6, 0x6f, 0x7d, 0xb6, 0x6d, 0xdb, 0x76, 0xe0, 0x7c, 0xb7, 0xec, 0x99, 0xd5, 0xd9, 0xb6, 0x6d, 0x63, 0xdf, 0x54, 0xdd, 0x57, 0xbd, 0x39, 0x13, 0xf5, 0x2a, 0x5e, 0x5f, 0xaf, 0x63, 0xd0, 0x19, 0xf1, 0x45, 0x66, 0x55, 0x67, 0xd6, 0x54, 0x67, 0x66, 0xf5, 0xcc, 0xf2, 0x8a, 0xb5, 0x8f, 0x7b, 0xf9, 0x7f, 0x5e, 0x29, 0x8, 0x49, 0x9a, 0x8d, 0xd, 0x75, 0x93, 0x18, 0x4d, 0x57, 0x2, 0x9b, 0x24, 0x19, 0x46, 0x8f, 0xd, 0x4f, 0x58, 0xc8, 0x9c, 0xec, 0xc1, 0xb5, 0xd1, 0x36, 0xbf, 0x11, 0xf3, 0x1, 0x7b, 0x7f, 0x9e, 0x2f, 0x61, 0x7b, 0xfd, 0x9a, 0x27, 0x72, 0x7e, 0x4d, 0x73, 0x0, 0x1d, 0x8c, 0x3, 0x4e, 0x79, 0x27, 0xf4, 0x72, 0xfd, 0x65, 0x7c, 0xbf, 0x2, 0xed, 0xc2, 0x9a, 0xb2, 0xee, 0xf0, 0xef, 0x1, 0xed, 0xe2, 0xee, 0x3d, 0xf, 0x9a, 0x3d, 0x35, 0xaf, 0x50, 0xd3, 0x3c, 0xaf, 0x57, 0x2a, 0xc2, 0x9, 0x9a, 0x88, 0x6f, 0x0, 0xad, 0x27, 0x49, 0x51, 0x6, 0x29, 0x48, 0x29, 0x61, 0xf6, 0x55, 0xb4, 0xad, 0xf9, 0x62, 0x31, 0xa3, 0xe6, 0x42, 0x6d, 0xc7, 0x5a, 0xf1, 0x63, 0x75, 0xaf, 0x92, 0x57, 0x63, 0x77, 0xfa, 0x75, 0xad, 0xa5, 0xf7, 0xb, 0xb2, 0x3c, 0x5, 0x26, 0x81, 0x73, 0xe9, 0x4e, 0x1d, 0x52, 0xd3, 0xac, 0x38, 0x49, 0x46, 0x6b, 0xdf, 0x82, 0x31, 0xd8, 0x63, 0x57, 0x8b, 0x1d, 0xed, 0x67, 0x13, 0xbd, 0x66, 0xc4, 0x7a, 0xae, 0x2f, 0x7b, 0xb5, 0xed, 0x22, 0xe2, 0x8f, 0x4d, 0xb1, 0x5d, 0x3b, 0x6a, 0xad, 0x8, 0x7c, 0x8b, 0xb8, 0x78, 0xd7, 0x76, 0xf7, 0xc6, 0x41, 0x3b, 0xdc, 0x2b, 0x55, 0xf1, 0xeb, 0xda, 0xe6, 0xe0, 0xfd, 0xf2, 0x2d, 0xbf, 0xb6, 0x7f, 0xd3, 0xe8, 0xf0, 0xb4, 0x98, 0xb1, 0x20, 0x36, 0x14, 0x1b, 0x84, 0x64, 0xcb, 0x1c, 0x36, 0x73, 0x85, 0x58, 0x87, 0x1a, 0xc7, 0x76, 0xfd, 0xa2, 0xfd, 0x21, 0xde, 0xdf, 0xf2, 0x8b, 0x88, 0x8f, 0xb0, 0x23, 0xe7, 0x6c, 0x86, 0xb5, 0x17, 0xb0, 0x1b, 0xa0, 0xf5, 0x68, 0xaf, 0x94, 0xc5, 0xaf, 0x6d, 0xdb, 0x9a, 0xee, 0xcd, 0x83, 0xa6, 0x19, 0x14, 0x68, 0x6c, 0x25, 0xe3, 0xe2, 0x9c, 0xcc, 0x17, 0x35, 0x28, 0xeb, 0x7a, 0xc1, 0x4e, 0x0, 0x2b, 0x87, 0xe8, 0x96, 0xe7, 0x68, 0x82, 0x75, 0xbc, 0x52, 0x96, 0x15, 0x6a, 0x5a, 0xae, 0x5e, 0x81, 0x6e, 0x75, 0xb, 0x2b, 0x63, 0x80, 0xda, 0x96, 0xf7, 0x79, 0x62, 0xdc, 0x2, 0xa7, 0x63, 0x37, 0x33, 0x37, 0xc1, 0xe6, 0x18, 0x3e, 0xad, 0x15, 0x51, 0x7c, 0x3b, 0x87, 0x34, 0xc0, 0xcd, 0x2b, 0x36, 0x6, 0x93, 0x78, 0xa5, 0x2a, 0xa9, 0xba, 0xf6, 0x29, 0xd9, 0x64, 0x1b, 0xdd, 0x3a, 0xe, 0xb4, 0xc5, 0x8f, 0x34, 0x47, 0x3b, 0xfa, 0x4a, 0xa, 0xbf, 0x1b, 0xdf, 0xc4, 0x98, 0x3c, 0xf4, 0xaf, 0x6d, 0x5b, 0x6, 0xff, 0x5e, 0x8a, 0x55, 0xf4, 0x35, 0x36, 0x28, 0x40, 0x27, 0x80, 0x22, 0x2f, 0xa, 0x6d, 0xe, 0xcf, 0x47, 0x3c, 0x69, 0xf7, 0xf0, 0x4a, 0x59, 0xd2, 0xf5, 0x1d, 0x4b, 0x52, 0xe4, 0x4f, 0x29, 0xec, 0x57, 0x14, 0xbd, 0x83, 0x8d, 0x3f, 0xc8, 0xd7, 0xd6, 0x27, 0x31, 0x3f, 0x47, 0x84, 0xff, 0xbc, 0xf8, 0xe6, 0xf0, 0xd5, 0x7c, 0xca, 0xd, 0xe1, 0x46, 0x8d, 0x56, 0xa0, 0xa3, 0x69, 0xb3, 0xec, 0x61, 0xfb, 0x45, 0xf8, 0xb6, 0xb9, 0xf6, 0x28, 0xd2, 0x16, 0xf7, 0x1a, 0xca, 0xe4, 0x65, 0x85, 0x9a, 0xd6, 0x47, 0x39, 0x68, 0x53, 0x94, 0x7a, 0x13, 0x9c, 0xe5, 0xd7, 0xb5, 0xd7, 0xfb, 0xf5, 0x1d, 0x53, 0xf, 0xec, 0x43, 0x64, 0xc7, 0x64, 0x74, 0x76, 0x6f, 0x4a, 0xba, 0x5e, 0x92, 0xa1, 0x52, 0x62, 0xa7, 0x1d, 0x7c, 0x87, 0xb4, 0xad, 0x23, 0x89, 0x8f, 0x77, 0x7d, 0x5c, 0xff, 0x74, 0xd4, 0x5e, 0x22, 0xec, 0x91, 0xc6, 0xe4, 0x3, 0xbe, 0x25, 0xb7, 0x47, 0x7a, 0x15, 0x25, 0xf2, 0x6b, 0xe5, 0xdc, 0x5c, 0x2b, 0x9d, 0xfe, 0xb, 0xd0, 0x8, 0x61, 0x22, 0x55, 0x7f, 0x42, 0xdb, 0x1d, 0xda, 0x22, 0xc6, 0x68, 0x21, 0xca, 0xd7, 0xf5, 0x89, 0x5f, 0xc7, 0x9d, 0x8b, 0x7e, 0xd, 0x77, 0x7e, 0xf0, 0x7b, 0x8a, 0x88, 0x91, 0x27, 0x3, 0x5a, 0xc9, 0x1, 0x9, 0x56, 0xa8, 0x6d, 0x9b, 0xcc, 0xab, 0x44, 0x49, 0xd7, 0x7, 0x17, 0xf3, 0xd9, 0xe0, 0xf3, 0xe2, 0x69, 0xaa, 0x6f, 0x57, 0xa0, 0xab, 0x1d, 0x72, 0xa1, 0xd0, 0xa, 0xad, 0xe1, 0x47, 0xde, 0x6, 0x4e, 0xf3, 0x2a, 0x55, 0x52, 0x75, 0x1d, 0x3b, 0xd2, 0x4, 0xaf, 0xf1, 0xa8, 0xcb, 0xf3, 0x76, 0xa2, 0xcb, 0x1d, 0xee, 0x43, 0xc5, 0xce, 0xc5, 0xc7, 0x2a, 0x6c, 0x2d, 0x7c, 0x4a, 0x3, 0x1c, 0xe6, 0x55, 0xb2, 0xf8, 0x75, 0xc1, 0xec, 0x7c, 0x86, 0x78, 0x51, 0x6e, 0x1e, 0x2, 0xd1, 0x36, 0x81, 0x35, 0x3f, 0x78, 0xe2, 0xd7, 0x8, 0xe2, 0x63, 0x6d, 0x1b, 0xdc, 0x79, 0x50, 0x85, 0x42, 0x82, 0xf6, 0x43, 0x3b, 0xf4, 0x51, 0xc0, 0xb8, 0x5d, 0x45, 0xad, 0x6b, 0x62, 0xb0, 0x8d, 0xbf, 0x2, 0x6d, 0x48, 0xd5, 0xb6, 0x7f, 0x86, 0x6e, 0xf4, 0x2a, 0x5d, 0x32, 0xd, 0xd9, 0x9a, 0x74, 0x43, 0xf0, 0x85, 0x49, 0x18, 0x5a, 0x81, 0x2e, 0x17, 0xd8, 0xb3, 0xbd, 0x5f, 0x55, 0x98, 0x83, 0x71, 0xf0, 0x97, 0xc1, 0xf2, 0x53, 0x72, 0x8f, 0x2e, 0xca, 0x5e, 0x8f, 0x13, 0x6f, 0xf4, 0x97, 0xe4, 0xa5, 0xce, 0xab, 0x6, 0xf1, 0xeb, 0x83, 0xde, 0x74, 0x43, 0x56, 0xa3, 0x35, 0xda, 0x5, 0x2, 0x21, 0x1b, 0x47, 0x7c, 0xbc, 0xd8, 0xf1, 0xd7, 0x5d, 0xb2, 0x36, 0x4a, 0xd0, 0xb2, 0xef, 0xb0, 0xb0, 0x42, 0x61, 0x3e, 0xc8, 0x34, 0xe6, 0x56, 0x46, 0xef, 0xce, 0x29, 0x2e, 0x36, 0x8a, 0x1b, 0x67, 0x8f, 0xa5, 0x71, 0xcc, 0xfc, 0xab, 0xb0, 0xb9, 0x57, 0x2d, 0x42, 0xa7, 0xbf, 0x1, 0xe1, 0xa3, 0xd2, 0xe8, 0x92, 0xa4, 0x71, 0xbc, 0xb1, 0x12, 0x74, 0x61, 0xdf, 0xf2, 0xa8, 0x37, 0xcd, 0x92, 0xa3, 0x78, 0x1b, 0x52, 0xd0, 0x49, 0x3c, 0x11, 0x1a, 0x61, 0x43, 0xae, 0xfd, 0xa, 0xda, 0x8d, 0xb3, 0xc6, 0xf9, 0xfe, 0xf8, 0x6c, 0x2b, 0xfe, 0x19, 0xaf, 0x5a, 0xc4, 0xaf, 0xcf, 0x2e, 0x44, 0xc2, 0xde, 0x4f, 0x87, 0x49, 0xce, 0x29, 0xd0, 0x0, 0xe1, 0xd8, 0x21, 0x5b, 0x20, 0x62, 0xce, 0xbd, 0x1e, 0x45, 0xd6, 0xd6, 0x11, 0x36, 0x38, 0x31, 0xec, 0x51, 0x59, 0xb1, 0x8a, 0x62, 0xcb, 0x7c, 0x0, 0xd9, 0x7, 0x33, 0x8d, 0x9d, 0xab, 0xa5, 0x1b, 0x73, 0x53, 0xa4, 0x9b, 0x7a, 0xfe, 0xe7, 0x39, 0x92, 0x6e, 0xc8, 0x2d, 0xcc, 0x7d, 0x3e, 0x81, 0x9f, 0xac, 0x93, 0x1b, 0x6f, 0x2d, 0x59, 0xff, 0x46, 0xbf, 0x21, 0xbb, 0xa0, 0x57, 0x4d, 0xc2, 0xd, 0x6f, 0xc6, 0x8d, 0x7f, 0x26, 0xd, 0x60, 0x35, 0x41, 0x3c, 0xc4, 0x28, 0xdb, 0x6, 0xfb, 0x9a, 0xd1, 0x23, 0x8e, 0xfd, 0xf8, 0x67, 0xfc, 0x1, 0x45, 0x3f, 0x97, 0xa2, 0x2f, 0xa, 0x53, 0x31, 0xfe, 0xcf, 0xdf, 0xc8, 0xc5, 0x67, 0x16, 0x1a, 0xe1, 0x60, 0xeb, 0xad, 0x4e, 0x89, 0x86, 0xdc, 0xe1, 0xe9, 0xc6, 0xce, 0x99, 0xbc, 0x6a, 0x13, 0x1a, 0xe0, 0x4c, 0x6e, 0xfe, 0x67, 0x93, 0x5c, 0xb4, 0x26, 0xa1, 0x83, 0x82, 0x98, 0x3c, 0xd8, 0x63, 0x83, 0x72, 0xfc, 0x54, 0x41, 0x8b, 0xaf, 0x3b, 0x1f, 0x8b, 0xb3, 0x7e, 0x1f, 0xc5, 0x5a, 0x3c, 0xd3, 0xd4, 0x35, 0x27, 0x7a, 0x1a, 0x6f, 0x10, 0x42, 0xcc, 0x14, 0xc4, 0x2c, 0xc4, 0x1a, 0x9f, 0x81, 0xe6, 0x9, 0xf8, 0x8d, 0xdf, 0x90, 0x5b, 0xdb, 0x97, 0xb7, 0x8c, 0xaa, 0x13, 0x6e, 0xbe, 0x9b, 0x93, 0x91, 0xcf, 0x34, 0x75, 0x6a, 0x50, 0xa2, 0xe3, 0x50, 0x5, 0x88, 0xd5, 0x24, 0xf4, 0x26, 0xd8, 0x1f, 0xee, 0x66, 0xfc, 0x17, 0xe8, 0x28, 0xec, 0x78, 0x6b, 0x1c, 0xb, 0xbe, 0xca, 0xb2, 0xff, 0xf1, 0x86, 0x29, 0x34, 0xc2, 0x42, 0xec, 0x77, 0x7, 0x58, 0xd2, 0xab, 0x66, 0x21, 0x1, 0x5f, 0x83, 0x26, 0x21, 0xa, 0xb4, 0xd8, 0x91, 0x70, 0xdd, 0x1d, 0xbf, 0x97, 0x6e, 0xec, 0x4a, 0xc1, 0xc4, 0x8c, 0xe7, 0xce, 0x34, 0x75, 0xa7, 0x60, 0x4d, 0xc6, 0xeb, 0xc3, 0x26, 0xb0, 0x23, 0x1c, 0x83, 0xdf, 0xb5, 0x70, 0x3f, 0x3c, 0xb, 0xda, 0x7e, 0xcd, 0x81, 0x42, 0x8c, 0x2, 0x4d, 0xd3, 0xfe, 0x63, 0x5e, 0xcf, 0x1b, 0xa6, 0xac, 0x74, 0x48, 0x2f, 0x6b, 0x54, 0xb9, 0x64, 0x1a, 0xbb, 0x2e, 0xee, 0x2f, 0x8, 0x49, 0x86, 0x15, 0xad, 0xa2, 0x60, 0xbb, 0x28, 0x8, 0xfd, 0xf0, 0x57, 0x60, 0xfc, 0xb6, 0x49, 0xd5, 0x65, 0x23, 0xdf, 0x7b, 0xcd, 0x7, 0x32, 0x7c, 0xa6, 0x85, 0x39, 0x61, 0x3e, 0xe0, 0x4b, 0xb3, 0xce, 0x3e, 0x7b, 0x2d, 0x74, 0x2c, 0xe2, 0xab, 0x88, 0xd5, 0xd0, 0x37, 0x12, 0xd, 0x90, 0x8, 0x42, 0x22, 0xe7, 0xe2, 0xc4, 0x6e, 0x4b, 0x13, 0x3c, 0x16, 0x16, 0xfd, 0xe0, 0xee, 0x2, 0xca, 0x1a, 0x2b, 0x6b, 0xac, 0xc, 0x72, 0x8a, 0xcf, 0x26, 0x7e, 0xf2, 0x41, 0xbe, 0xde, 0xc4, 0x14, 0xb2, 0x93, 0xb5, 0xf2, 0xb2, 0x5e, 0x34, 0x4d, 0xe0, 0xec, 0x47, 0xf8, 0x91, 0x3d, 0x27, 0xd, 0x30, 0xc2, 0x8d, 0xb0, 0x14, 0x49, 0xdd, 0x1b, 0x9e, 0x0, 0xd, 0x24, 0xbd, 0xc7, 0xa0, 0x84, 0xd0, 0x66, 0xde, 0xa0, 0xe1, 0x29, 0x62, 0x66, 0xf6, 0x6, 0x29, 0xac, 0x31, 0x9, 0xd4, 0x12, 0x3b, 0x4e, 0x5e, 0x43, 0xd6, 0x8e, 0xc7, 0xf8, 0x13, 0x97, 0x47, 0xbf, 0x4, 0x13, 0x79, 0xa3, 0x22, 0x49, 0x23, 0x2c, 0xb, 0xfb, 0x92, 0xe0, 0xdb, 0xe0, 0x67, 0xd0, 0x16, 0x4a, 0x8a, 0xf0, 0x3d, 0xac, 0x31, 0xf4, 0xf, 0x60, 0x3d, 0x73, 0x11, 0xaf, 0xad, 0x6, 0x80, 0x81, 0x35, 0x0, 0xfc, 0x43, 0xec, 0x9d, 0xf0, 0x7f, 0x6f, 0xf4, 0x24, 0x91, 0x74, 0x53, 0xf7, 0x1c, 0xb0, 0x3f, 0x9c, 0x43, 0xc1, 0x3a, 0x40, 0x67, 0x28, 0x2, 0xfa, 0x77, 0xe6, 0xf6, 0x1e, 0x81, 0xf5, 0x3b, 0x56, 0x3c, 0xb8, 0xb7, 0xf, 0x58, 0x93, 0x2, 0x1f, 0xd2, 0x4b, 0x91, 0x5, 0x6c, 0x1b, 0xae, 0x2b, 0x33, 0x2f, 0xfc, 0x49, 0xec, 0xd1, 0x90, 0x34, 0xc0, 0x58, 0x9, 0x45, 0xf0, 0xe1, 0x42, 0xb8, 0x1e, 0x4e, 0x1e, 0x89, 0x5f, 0x48, 0xa1, 0x80, 0x1b, 0xd2, 0x50, 0x7f, 0x80, 0x29, 0xb2, 0x12, 0xb4, 0x8c, 0x6d, 0x94, 0xc1, 0xcc, 0xb, 0x79, 0xd8, 0x4c, 0xfe, 0x34, 0xbd, 0x5c, 0x25, 0x11, 0x9a, 0xc0, 0x7c, 0xcb, 0xf6, 0x33, 0xb4, 0xa6, 0x98, 0xe3, 0xc1, 0xdc, 0x4, 0xc1, 0xff, 0x53, 0x74, 0x2b, 0x3e, 0x73, 0x7b, 0xe5, 0x2f, 0x89, 0xf0, 0x68, 0x3f, 0x8b, 0xd3, 0xdd, 0x27, 0x8f, 0x7f, 0x85, 0xfe, 0x1b, 0x7e, 0xc6, 0xfe, 0x1a, 0xfd, 0x21, 0xbc, 0xcc, 0x69, 0xf, 0xd0, 0xf, 0x33, 0x77, 0x2b, 0xf6, 0xfe, 0x2b, 0x1d, 0xfa, 0xe4, 0xd2, 0x5e, 0x65, 0x48, 0x22, 0x9c, 0xe4, 0xa9, 0x38, 0xd1, 0x77, 0xc2, 0x43, 0xd8, 0x77, 0xc0, 0x35, 0x70, 0x16, 0xff, 0x60, 0xf9, 0x70, 0xd8, 0x3, 0x7b, 0xd, 0xae, 0xcd, 0xe2, 0x95, 0xbd, 0x24, 0x92, 0x48, 0x22, 0x89, 0x24, 0x92, 0x48, 0x22, 0x89, 0x24, 0x92, 0x48, 0x22, 0x89, 0xfc, 0xb, 0x31, 0x1b, 0x93, 0xfa, 0xac, 0xe1, 0x98, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char mini_checkerboard_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xe, 0xc3, 0x0, 0x0, 0xe, 0xc3, 0x1, 0xc7, 0x6f, 0xa8, 0x64, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x0, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x6e, 0x6b, 0x73, 0x63, 0x61, 0x70, 0x65, 0x2e, 0x6f, 0x72, 0x67, 0x9b, 0xee, 0x3c, 0x1a, 0x0, 0x0, 0x0, 0x33, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0x63, 0x7c, 0xf0, 0xe0, 0xc1, 0x7f, 0x6, 0x3c, 0x40, 0x5e, 0x5e, 0x1e, 0x9f, 0x34, 0x3, 0x13, 0x5e, 0x59, 0x22, 0xc0, 0xa8, 0x1, 0x83, 0xc1, 0x0, 0xc6, 0xff, 0xff, 0xff, 0xe3, 0x4d, 0x7, 0xf, 0x1f, 0x3e, 0xa4, 0xad, 0xb, 0x46, 0xd, 0x18, 0xc, 0x6, 0x0, 0x0, 0x6e, 0x41, 0xa, 0xba, 0x94, 0xaa, 0x47, 0x57, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x0, 0x0, 0x0, 0x0, 0x3a, 0x98, 0xa0, 0xbd, 0x0, 0x0, 0x0, 0x17, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x78, 0x0, 0x5, 0xff, 0xa1, 0x60, 0xa0, 0x4, 0x60, 0xc, 0x98, 0xc4, 0x0, 0x9, 0x0, 0x0, 0x44, 0x81, 0xef, 0x81, 0xc1, 0x26, 0x8e, 0x8, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char option_arrow_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x6, 0x0, 0x0, 0x0, 0x56, 0x75, 0x5c, 0xe7, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x98, 0x49, 0x44, 0x41, 0x54, 0x28, 0x91, 0xbd, 0x91, 0xb1, 0xd, 0xc2, 0x30, 0x10, 0x45, 0xdf, 0xd1, 0xb8, 0xf0, 0x2, 0xee, 0xdc, 0x87, 0x1, 0xd8, 0x24, 0xb5, 0xe9, 0x19, 0x87, 0x1e, 0xea, 0x6c, 0xc2, 0x0, 0xa4, 0xb5, 0xdc, 0x79, 0x1, 0x17, 0xae, 0x8e, 0x26, 0x48, 0x76, 0x14, 0x40, 0x48, 0x88, 0xdf, 0xfd, 0xf7, 0xef, 0x4b, 0x77, 0x3a, 0xf8, 0x85, 0x62, 0x8c, 0x21, 0xc6, 0x18, 0xb6, 0x32, 0x59, 0x83, 0x94, 0xd2, 0x5e, 0x55, 0x6f, 0x0, 0x22, 0x72, 0xf0, 0xde, 0xdf, 0xdb, 0x7c, 0xd7, 0x9a, 0x9c, 0xb3, 0x55, 0xd5, 0x9, 0xb0, 0x80, 0x55, 0xd5, 0x29, 0xe7, 0x6c, 0x5f, 0x16, 0x6a, 0xad, 0x67, 0x60, 0x68, 0xd0, 0xb0, 0xb0, 0x3f, 0xaa, 0x3b, 0x3a, 0xa5, 0x74, 0x51, 0xd5, 0xd0, 0xd, 0x88, 0x5c, 0xbd, 0xf7, 0xc7, 0xa7, 0xef, 0x6e, 0x30, 0xc6, 0x9c, 0x80, 0xb9, 0x41, 0xf3, 0xc2, 0xd8, 0x2c, 0x38, 0xe7, 0x8a, 0x88, 0x8c, 0x40, 0x1, 0x8a, 0x88, 0x8c, 0xce, 0xb9, 0xf2, 0x71, 0xcf, 0x77, 0x8f, 0xfb, 0x5a, 0xf, 0x28, 0x4a, 0x37, 0xff, 0x58, 0x46, 0x7b, 0x50, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x4, 0x0, 0x0, 0x0, 0xfc, 0x7c, 0x94, 0x6c, 0x0, 0x0, 0x0, 0x3e, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x20, 0x2, 0xdc, 0x4f, 0xb8, 0x9f, 0x80, 0x45, 0xf8, 0xa1, 0xf6, 0x83, 0x2f, 0xf, 0xbe, 0x3c, 0xd4, 0x46, 0x13, 0x7e, 0xc1, 0xfd, 0xe0, 0xea, 0x83, 0xff, 0x40, 0x78, 0xf5, 0x5, 0x37, 0xaa, 0xfa, 0xf9, 0x40, 0x41, 0x30, 0x7c, 0x38, 0x9f, 0x81, 0x12, 0x80, 0x69, 0x14, 0x61, 0xcb, 0x11, 0xce, 0xc5, 0xe5, 0x41, 0xc2, 0x0, 0x0, 0x95, 0x48, 0x37, 0x91, 0x1f, 0xec, 0x77, 0x5, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char option_button_disabled_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x40, 0xde, 0x8d, 0x6b, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x1, 0x32, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f, 0x3f, 0x3f, 0x5a, 0x5a, 0x5a, 0x2b, 0x2b, 0x31, 0x2e, 0x2e, 0x34, 0x59, 0x59, 0x59, 0x2a, 0x2a, 0x30, 0x4b, 0x4b, 0x4b, 0x22, 0x22, 0x27, 0x35, 0x35, 0x35, 0x4a, 0x4a, 0x4a, 0x24, 0x24, 0x28, 0x24, 0x24, 0x29, 0x56, 0x56, 0x56, 0x62, 0x62, 0x62, 0x2a, 0x2a, 0x31, 0x2a, 0x2a, 0x30, 0x2d, 0x2d, 0x34, 0x2f, 0x2f, 0x36, 0x2e, 0x2e, 0x35, 0x2c, 0x2c, 0x32, 0x48, 0x48, 0x48, 0x44, 0x44, 0x44, 0x43, 0x43, 0x43, 0x54, 0x54, 0x54, 0x26, 0x26, 0x2b, 0x24, 0x24, 0x28, 0x27, 0x27, 0x2d, 0x29, 0x29, 0x2f, 0x28, 0x28, 0x2e, 0x25, 0x25, 0x2b, 0x23, 0x23, 0x28, 0x26, 0x26, 0x2c, 0x25, 0x25, 0x2a, 0x2a, 0x2a, 0x2f, 0x2b, 0x2b, 0x31, 0x22, 0x22, 0x26, 0x52, 0x52, 0x52, 0x42, 0x42, 0x42, 0x2d, 0x2d, 0x33, 0x22, 0x22, 0x27, 0x51, 0x51, 0x51, 0x40, 0x40, 0x40, 0x27, 0x27, 0x2b, 0x2e, 0x2e, 0x34, 0x2c, 0x2c, 0x31, 0x29, 0x29, 0x2e, 0x4f, 0x4f, 0x4f, 0x3f, 0x3f, 0x3f, 0x4d, 0x4d, 0x4d, 0x3e, 0x3e, 0x3e, 0x24, 0x24, 0x2a, 0x24, 0x24, 0x29, 0x20, 0x20, 0x25, 0x4c, 0x4c, 0x4c, 0x3d, 0x3d, 0x3d, 0x28, 0x28, 0x2d, 0x2b, 0x2b, 0x30, 0x29, 0x29, 0x2d, 0x20, 0x20, 0x23, 0x4a, 0x4a, 0x4a, 0x3b, 0x3b, 0x3b, 0x22, 0x22, 0x28, 0x27, 0x27, 0x2c, 0x1e, 0x1e, 0x22, 0x49, 0x49, 0x49, 0x3a, 0x3a, 0x3a, 0x21, 0x21, 0x26, 0x21, 0x21, 0x25, 0x23, 0x23, 0x27, 0x20, 0x20, 0x24, 0x1d, 0x1d, 0x21, 0x39, 0x39, 0x39, 0x47, 0x47, 0x47, 0x1f, 0x1f, 0x24, 0x1f, 0x1f, 0x23, 0x1e, 0x1e, 0x21, 0x46, 0x46, 0x46, 0xff, 0xff, 0xff, 0xbd, 0x3f, 0x83, 0xbb, 0x0, 0x0, 0x0, 0x24, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x4, 0xa, 0x11, 0x19, 0x1f, 0x22, 0x24, 0x1d, 0x16, 0xd, 0x7, 0x2, 0x15, 0x25, 0x34, 0x3f, 0x46, 0x47, 0x48, 0x43, 0x3a, 0x2d, 0x1b, 0x77, 0xef, 0xe6, 0x49, 0xef, 0xe6, 0xef, 0xe7, 0x77, 0xef, 0xe4, 0x4a, 0xba, 0xea, 0xc1, 0xeb, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x65, 0xb5, 0xdd, 0x88, 0x9f, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x1, 0xb, 0x49, 0x44, 0x41, 0x54, 0x28, 0xcf, 0x8d, 0xd1, 0xd9, 0x56, 0xc2, 0x30, 0x10, 0x80, 0x61, 0xd6, 0xa2, 0xa8, 0x6c, 0x75, 0xdf, 0x10, 0x54, 0xa8, 0x82, 0x74, 0xd2, 0x4a, 0x49, 0x5b, 0xa4, 0xb5, 0x5a, 0x44, 0x10, 0x5c, 0xd0, 0xaa, 0x80, 0x8a, 0xcb, 0xfb, 0x3f, 0x83, 0x21, 0x24, 0x1c, 0x8e, 0x5e, 0xe8, 0x77, 0xfd, 0x9f, 0x93, 0x99, 0x89, 0xcf, 0x1f, 0x8, 0x86, 0xc2, 0x42, 0x84, 0x10, 0x66, 0x66, 0xa3, 0x73, 0xf3, 0xbe, 0x9f, 0x2, 0xb, 0xb1, 0x78, 0x22, 0x99, 0x12, 0x45, 0x71, 0x71, 0x69, 0x79, 0x25, 0xea, 0xff, 0x15, 0x4, 0x63, 0xab, 0x6b, 0x7b, 0xcc, 0x7e, 0x2e, 0x2f, 0x1d, 0x30, 0x87, 0x52, 0x21, 0xbf, 0xbe, 0x41, 0x82, 0x50, 0x7c, 0xb3, 0x78, 0x54, 0x1a, 0x93, 0x1, 0x29, 0x2a, 0x73, 0xac, 0x94, 0x35, 0x6d, 0x8b, 0x4, 0xe1, 0x84, 0x5c, 0xe2, 0xe4, 0xa, 0xd6, 0xb, 0x8c, 0xa1, 0x2b, 0xd8, 0x54, 0x48, 0x20, 0x24, 0xab, 0x27, 0x5c, 0xb5, 0x2, 0x39, 0x89, 0xa9, 0x19, 0x2a, 0x58, 0xa3, 0x20, 0x92, 0xb2, 0x4f, 0x39, 0xdb, 0x1, 0xe3, 0x8c, 0xa9, 0x9d, 0xbb, 0x60, 0x3a, 0xa3, 0x40, 0xac, 0x5f, 0x70, 0xf5, 0xe9, 0xc0, 0x20, 0x1, 0xd0, 0xa0, 0x71, 0xc9, 0x35, 0xca, 0x4d, 0x75, 0x6a, 0x86, 0xd6, 0x15, 0xa6, 0x4f, 0xb4, 0x3b, 0x5c, 0x1b, 0xa1, 0xeb, 0x1b, 0x46, 0xbf, 0x5, 0xed, 0xe, 0xd1, 0x21, 0xbb, 0xf7, 0x5c, 0xf7, 0xc1, 0xf2, 0x26, 0x6b, 0x7a, 0x4d, 0xeb, 0xd1, 0xa2, 0x6b, 0x3e, 0x3d, 0x73, 0xc5, 0x5e, 0x1f, 0x7b, 0xc, 0xe0, 0xc1, 0xcb, 0xab, 0x49, 0xf, 0xb5, 0xdd, 0x79, 0x63, 0x86, 0xbd, 0x77, 0xd, 0x33, 0xad, 0x41, 0xff, 0xe3, 0x33, 0x4d, 0x4f, 0xbd, 0x93, 0x19, 0x7e, 0x8d, 0xd9, 0x0, 0xee, 0x64, 0x6, 0xd7, 0x41, 0xd9, 0xdd, 0xff, 0x7c, 0xd6, 0x5f, 0xdf, 0xfd, 0xd, 0xbf, 0xaa, 0x55, 0xdf, 0x7c, 0xb2, 0x44, 0x90, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x40, 0xde, 0x8d, 0x6b, 0x0, 0x0, 0x1, 0x2f, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f, 0x3f, 0x3f, 0x5a, 0x5a, 0x5a, 0x2b, 0x2b, 0x31, 0x2e, 0x2e, 0x34, 0x59, 0x59, 0x59, 0x2a, 0x2a, 0x30, 0x4b, 0x4b, 0x4b, 0x22, 0x22, 0x27, 0x35, 0x35, 0x35, 0x4a, 0x4a, 0x4a, 0x24, 0x24, 0x28, 0x24, 0x24, 0x29, 0x56, 0x56, 0x56, 0x62, 0x62, 0x62, 0x2a, 0x2a, 0x31, 0x2a, 0x2a, 0x30, 0x2d, 0x2d, 0x34, 0x2f, 0x2f, 0x36, 0x2e, 0x2e, 0x35, 0x2c, 0x2c, 0x32, 0x48, 0x48, 0x48, 0x44, 0x44, 0x44, 0x43, 0x43, 0x43, 0x54, 0x54, 0x54, 0x26, 0x26, 0x2b, 0x24, 0x24, 0x28, 0x27, 0x27, 0x2d, 0x29, 0x29, 0x2f, 0x28, 0x28, 0x2e, 0x25, 0x25, 0x2b, 0x23, 0x23, 0x28, 0x26, 0x26, 0x2c, 0x25, 0x25, 0x2a, 0x2a, 0x2a, 0x2f, 0x2b, 0x2b, 0x31, 0x22, 0x22, 0x26, 0x52, 0x52, 0x52, 0x42, 0x42, 0x42, 0x2d, 0x2d, 0x33, 0x22, 0x22, 0x27, 0x51, 0x51, 0x51, 0x40, 0x40, 0x40, 0x27, 0x27, 0x2b, 0x2e, 0x2e, 0x34, 0x2c, 0x2c, 0x31, 0x29, 0x29, 0x2e, 0x4f, 0x4f, 0x4f, 0x3f, 0x3f, 0x3f, 0x4d, 0x4d, 0x4d, 0x3e, 0x3e, 0x3e, 0x24, 0x24, 0x2a, 0x24, 0x24, 0x29, 0x20, 0x20, 0x25, 0x4c, 0x4c, 0x4c, 0x3d, 0x3d, 0x3d, 0x28, 0x28, 0x2d, 0x2b, 0x2b, 0x30, 0x29, 0x29, 0x2d, 0x20, 0x20, 0x23, 0x4a, 0x4a, 0x4a, 0x3b, 0x3b, 0x3b, 0x22, 0x22, 0x28, 0x27, 0x27, 0x2c, 0x1e, 0x1e, 0x22, 0x49, 0x49, 0x49, 0x3a, 0x3a, 0x3a, 0x21, 0x21, 0x26, 0x21, 0x21, 0x25, 0x23, 0x23, 0x27, 0x20, 0x20, 0x24, 0x1d, 0x1d, 0x21, 0x39, 0x39, 0x39, 0x47, 0x47, 0x47, 0x1f, 0x1f, 0x24, 0x1f, 0x1f, 0x23, 0x1e, 0x1e, 0x21, 0x46, 0x46, 0x46, 0xd3, 0xa7, 0xd4, 0x88, 0x0, 0x0, 0x0, 0x24, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x4, 0xa, 0x11, 0x19, 0x1f, 0x22, 0x24, 0x1d, 0x16, 0xd, 0x7, 0x2, 0x15, 0x25, 0x34, 0x3f, 0x46, 0x47, 0x48, 0x43, 0x3a, 0x2d, 0x1b, 0x77, 0xef, 0xe6, 0x49, 0xef, 0xe6, 0xef, 0xe7, 0x77, 0xef, 0xe4, 0x4a, 0xba, 0xea, 0xc1, 0xeb, 0x0, 0x0, 0x0, 0xec, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x6c, 0x8e, 0x5, 0x4e, 0x0, 0x31, 0x10, 0x45, 0xff, 0xef, 0x56, 0xc2, 0xe2, 0xee, 0x4e, 0x3c, 0xc8, 0xd, 0xb8, 0x38, 0xa7, 0xc0, 0xdd, 0xdd, 0x5d, 0xbb, 0x94, 0x4c, 0xd2, 0xc1, 0xdf, 0x4a, 0x47, 0x5e, 0x27, 0xc3, 0xc, 0x80, 0x64, 0x24, 0xb8, 0xc7, 0x4f, 0x2c, 0x6b, 0xd5, 0x90, 0xff, 0xdd, 0x23, 0x7e, 0xc1, 0xa2, 0xb6, 0x64, 0xad, 0x26, 0x82, 0xc6, 0xef, 0x45, 0xbc, 0xe3, 0x1, 0x2c, 0x69, 0x9b, 0xc8, 0x7f, 0x5, 0x36, 0x1e, 0x41, 0x84, 0xd6, 0x4, 0x25, 0x90, 0xb7, 0x39, 0x6c, 0x4c, 0x2f, 0xbe, 0x68, 0xdf, 0x13, 0xa1, 0x9e, 0xc8, 0xa4, 0xb7, 0xe7, 0x47, 0x93, 0x63, 0x1b, 0xf9, 0xdc, 0x8, 0x88, 0x60, 0xbf, 0x4, 0xff, 0xd2, 0x56, 0x93, 0xe3, 0xb7, 0xb2, 0xf6, 0x2c, 0x36, 0x1, 0x16, 0xf4, 0x5f, 0x42, 0xc4, 0x17, 0x8f, 0xb5, 0xc0, 0xa5, 0x8, 0x30, 0x5f, 0xc2, 0x5d, 0xcf, 0xc9, 0xd, 0x74, 0x87, 0x8b, 0x5e, 0x56, 0x22, 0x24, 0xf7, 0x6d, 0xc2, 0xd1, 0x80, 0x26, 0x27, 0x5d, 0x5b, 0x67, 0x7d, 0x2f, 0x80, 0x4d, 0xc9, 0x7f, 0x9, 0x63, 0xa7, 0x61, 0x23, 0xc7, 0x74, 0x3d, 0xf, 0xae, 0x41, 0x84, 0x6f, 0x13, 0xe6, 0x26, 0xfa, 0x36, 0x46, 0x73, 0xbc, 0xba, 0x3b, 0xd6, 0xca, 0x8, 0xd0, 0xd6, 0x36, 0x4e, 0x35, 0xeb, 0xad, 0xd7, 0xb0, 0x60, 0x72, 0xdc, 0xda, 0x9c, 0x2, 0x67, 0x76, 0x64, 0x82, 0x99, 0x9b, 0xb6, 0x80, 0xb0, 0x7e, 0x8d, 0xf6, 0x5a, 0xdd, 0xe1, 0xb5, 0xba, 0xba, 0xb1, 0x0, 0xcd, 0xc7, 0x50, 0x23, 0xeb, 0xfb, 0x7f, 0xb4, 0xc8, 0x22, 0x18, 0xdd, 0x0, 0xd5, 0xec, 0x4e, 0x53, 0xc6, 0x18, 0x44, 0x3f, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char option_button_focus_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0xb4, 0x50, 0x4c, 0x54, 0x45, 0x95, 0xa9, 0xb0, 0x92, 0xa7, 0xae, 0x8e, 0xa2, 0xa9, 0x8a, 0x9d, 0xa4, 0x85, 0x98, 0x9f, 0x80, 0x93, 0x9b, 0x7b, 0x8f, 0x96, 0x77, 0x8a, 0x92, 0x72, 0x86, 0x8c, 0x6e, 0x80, 0x88, 0x69, 0x7c, 0x84, 0x64, 0x77, 0x7f, 0x60, 0x72, 0x7a, 0x5b, 0x6e, 0x75, 0x56, 0x69, 0x71, 0xc8, 0xe3, 0xe7, 0xc8, 0xe2, 0xe7, 0xca, 0xe3, 0xe7, 0xce, 0xe6, 0xe9, 0xce, 0xe6, 0xea, 0xd0, 0xe6, 0xe9, 0xce, 0xe5, 0xea, 0xd0, 0xe6, 0xea, 0xce, 0xe5, 0xe9, 0xd0, 0xe5, 0xe9, 0xd3, 0xe7, 0xeb, 0xd4, 0xe7, 0xeb, 0xd9, 0xea, 0xed, 0xd7, 0xe9, 0xed, 0xd7, 0xea, 0xed, 0xdc, 0xec, 0xef, 0xdc, 0xeb, 0xef, 0xe0, 0xed, 0xf1, 0xdf, 0xee, 0xf1, 0xdf, 0xed, 0xf1, 0xe0, 0xee, 0xf1, 0xe3, 0xf0, 0xf2, 0xe2, 0xef, 0xf2, 0xe3, 0xef, 0xf2, 0xe6, 0xf1, 0xf3, 0xe8, 0xf2, 0xf5, 0xe8, 0xf3, 0xf4, 0xe8, 0xf2, 0xf4, 0xe8, 0xf3, 0xf5, 0xd6, 0x5a, 0x5b, 0xd4, 0x57, 0x58, 0xe5, 0x89, 0x89, 0xd5, 0x57, 0x59, 0xd5, 0x58, 0x59, 0xd5, 0x59, 0x5a, 0xd6, 0x59, 0x5a, 0xd6, 0x5a, 0x5c, 0xd7, 0x5b, 0x5c, 0xd7, 0x5b, 0x5d, 0xd8, 0x5c, 0x5d, 0xd8, 0x5c, 0x5e, 0xd8, 0x5d, 0x5f, 0xd9, 0x5d, 0x5f, 0xe8, 0x6c, 0x6e, 0xff, 0xff, 0xff, 0xa1, 0xe, 0x37, 0x8c, 0x0, 0x0, 0x0, 0x2c, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0xac, 0x80, 0x68, 0x47, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x3b, 0x39, 0xe, 0xf4, 0x6c, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0xa3, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x5d, 0xce, 0xdb, 0x16, 0x42, 0x60, 0x18, 0x84, 0xe1, 0x4f, 0x8, 0x65, 0x57, 0x2a, 0x45, 0xd9, 0x15, 0xf9, 0xa3, 0x89, 0x28, 0xea, 0xfe, 0x2f, 0x2c, 0x4e, 0x2c, 0x79, 0xd6, 0xbc, 0xe7, 0x43, 0x34, 0xc5, 0xe5, 0x7f, 0x38, 0x9a, 0xdd, 0x31, 0x72, 0x9f, 0x11, 0xff, 0x80, 0x61, 0x18, 0xa6, 0x69, 0xac, 0xba, 0x50, 0xf0, 0x24, 0x14, 0x58, 0x5b, 0x9b, 0xed, 0xce, 0xb6, 0x6d, 0x6b, 0x8f, 0x42, 0x20, 0xb1, 0xc4, 0xc1, 0x71, 0xe, 0x7d, 0x8e, 0x83, 0x52, 0xa4, 0xf9, 0x13, 0xae, 0x7b, 0x74, 0x7b, 0xa7, 0x13, 0x9e, 0x73, 0x92, 0x72, 0x78, 0xbe, 0xef, 0x75, 0x7c, 0xcf, 0x47, 0x2e, 0x91, 0x5c, 0x21, 0x8, 0xc2, 0x20, 0x8c, 0x82, 0x73, 0x18, 0xa1, 0x92, 0x49, 0xa9, 0x71, 0x89, 0xe3, 0x38, 0x49, 0xba, 0x25, 0xa8, 0x15, 0x5a, 0xbc, 0x70, 0x1d, 0xe0, 0xb5, 0xa0, 0xe5, 0x1b, 0x69, 0xca, 0xd8, 0x8d, 0x31, 0x96, 0x65, 0x68, 0x96, 0xa4, 0x36, 0x60, 0x3, 0x34, 0x2a, 0x69, 0xed, 0xf8, 0x7a, 0xab, 0x91, 0xfe, 0xf9, 0x8e, 0x7c, 0x74, 0xd2, 0x27, 0x7e, 0x7e, 0x46, 0x20, 0x17, 0xe, 0x2d, 0x4e, 0x9, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0xb1, 0x50, 0x4c, 0x54, 0x45, 0x95, 0xa9, 0xb0, 0x92, 0xa7, 0xae, 0x8e, 0xa2, 0xa9, 0x8a, 0x9d, 0xa4, 0x85, 0x98, 0x9f, 0x80, 0x93, 0x9b, 0x7b, 0x8f, 0x96, 0x77, 0x8a, 0x92, 0x72, 0x86, 0x8c, 0x6e, 0x80, 0x88, 0x69, 0x7c, 0x84, 0x64, 0x77, 0x7f, 0x60, 0x72, 0x7a, 0x5b, 0x6e, 0x75, 0x56, 0x69, 0x71, 0xc8, 0xe3, 0xe7, 0xc8, 0xe2, 0xe7, 0xca, 0xe3, 0xe7, 0xce, 0xe6, 0xe9, 0xce, 0xe6, 0xea, 0xd0, 0xe6, 0xe9, 0xce, 0xe5, 0xea, 0xd0, 0xe6, 0xea, 0xce, 0xe5, 0xe9, 0xd0, 0xe5, 0xe9, 0xd3, 0xe7, 0xeb, 0xd4, 0xe7, 0xeb, 0xd9, 0xea, 0xed, 0xd7, 0xe9, 0xed, 0xd7, 0xea, 0xed, 0xdc, 0xec, 0xef, 0xdc, 0xeb, 0xef, 0xe0, 0xed, 0xf1, 0xdf, 0xee, 0xf1, 0xdf, 0xed, 0xf1, 0xe0, 0xee, 0xf1, 0xe3, 0xf0, 0xf2, 0xe2, 0xef, 0xf2, 0xe3, 0xef, 0xf2, 0xe6, 0xf1, 0xf3, 0xe8, 0xf2, 0xf5, 0xe8, 0xf3, 0xf4, 0xe8, 0xf2, 0xf4, 0xe8, 0xf3, 0xf5, 0xd6, 0x5a, 0x5b, 0xd4, 0x57, 0x58, 0xe5, 0x89, 0x89, 0xd5, 0x57, 0x59, 0xd5, 0x58, 0x59, 0xd5, 0x59, 0x5a, 0xd6, 0x59, 0x5a, 0xd6, 0x5a, 0x5c, 0xd7, 0x5b, 0x5c, 0xd7, 0x5b, 0x5d, 0xd8, 0x5c, 0x5d, 0xd8, 0x5c, 0x5e, 0xd8, 0x5d, 0x5f, 0xd9, 0x5d, 0x5f, 0xe8, 0x6c, 0x6e, 0x20, 0x6, 0x32, 0x78, 0x0, 0x0, 0x0, 0x2c, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0xac, 0x80, 0x68, 0x47, 0x0, 0x0, 0x0, 0x72, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x55, 0xc8, 0xc1, 0x8d, 0xc2, 0x30, 0x18, 0x6, 0xd1, 0x99, 0xdf, 0x8e, 0x7c, 0x59, 0x6d, 0xb, 0x14, 0x40, 0xff, 0xa5, 0x50, 0x0, 0x6d, 0x4, 0xe4, 0xf, 0x59, 0x8, 0x42, 0xde, 0xf1, 0x35, 0xce, 0xd0, 0x2b, 0xbf, 0x6e, 0x5d, 0xe5, 0x10, 0xbb, 0x95, 0x3b, 0x48, 0x2a, 0xe4, 0xd2, 0xec, 0x9a, 0xe6, 0x2, 0xcf, 0xd, 0x56, 0x30, 0x24, 0x48, 0x6, 0xb8, 0x82, 0xc2, 0x0, 0xd6, 0x3b, 0xf6, 0x6a, 0x12, 0xc0, 0xc8, 0x6e, 0x77, 0x3c, 0xa, 0xa3, 0xb3, 0x4d, 0x19, 0x76, 0xa5, 0xb, 0x12, 0x1b, 0xb8, 0x82, 0xc6, 0x22, 0x7c, 0x42, 0xc4, 0x40, 0x41, 0x59, 0x8a, 0x42, 0x80, 0x39, 0xc1, 0xae, 0x6c, 0x7c, 0xb9, 0xe2, 0x8f, 0x43, 0xf4, 0x9f, 0xb3, 0x17, 0x98, 0xa8, 0x1a, 0xb6, 0xa7, 0xd9, 0xa6, 0x4e, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char option_button_hover_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x40, 0xde, 0x8d, 0x6b, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x1, 0x44, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x42, 0x40, 0x4b, 0x5f, 0x5a, 0x6c, 0x2b, 0x2b, 0x31, 0x2e, 0x2e, 0x34, 0x5f, 0x5a, 0x6b, 0x2a, 0x2a, 0x30, 0x56, 0x53, 0x64, 0x22, 0x22, 0x27, 0x3e, 0x3b, 0x46, 0x57, 0x53, 0x63, 0x24, 0x24, 0x28, 0x24, 0x24, 0x29, 0x5b, 0x57, 0x68, 0x5a, 0x56, 0x67, 0x67, 0x63, 0x76, 0x2a, 0x2a, 0x31, 0x2a, 0x2a, 0x30, 0x2d, 0x2d, 0x34, 0x2f, 0x2f, 0x36, 0x2e, 0x2e, 0x35, 0x2c, 0x2c, 0x32, 0x4d, 0x4a, 0x57, 0x49, 0x46, 0x52, 0x48, 0x45, 0x51, 0x5a, 0x56, 0x65, 0x26, 0x26, 0x2b, 0x24, 0x24, 0x28, 0x27, 0x27, 0x2d, 0x29, 0x29, 0x2f, 0x28, 0x28, 0x2e, 0x25, 0x25, 0x2b, 0x23, 0x23, 0x28, 0x5b, 0x57, 0x66, 0x26, 0x26, 0x2c, 0x25, 0x25, 0x2a, 0x2a, 0x2a, 0x2f, 0x2b, 0x2b, 0x31, 0x22, 0x22, 0x26, 0x59, 0x55, 0x64, 0x47, 0x44, 0x50, 0x2d, 0x2d, 0x33, 0x22, 0x22, 0x27, 0x58, 0x54, 0x64, 0x46, 0x43, 0x50, 0x27, 0x27, 0x2b, 0x2e, 0x2e, 0x34, 0x2c, 0x2c, 0x31, 0x29, 0x29, 0x2e, 0x56, 0x53, 0x63, 0x45, 0x42, 0x4f, 0x56, 0x53, 0x62, 0x45, 0x42, 0x4e, 0x24, 0x24, 0x2a, 0x24, 0x24, 0x29, 0x20, 0x20, 0x25, 0x55, 0x51, 0x62, 0x44, 0x41, 0x4e, 0x28, 0x28, 0x2d, 0x2b, 0x2b, 0x30, 0x29, 0x29, 0x2d, 0x20, 0x20, 0x23, 0x55, 0x51, 0x60, 0x44, 0x41, 0x4d, 0x22, 0x22, 0x28, 0x27, 0x27, 0x2c, 0x1e, 0x1e, 0x22, 0x43, 0x40, 0x4c, 0x54, 0x50, 0x5f, 0x21, 0x21, 0x26, 0x21, 0x21, 0x25, 0x23, 0x23, 0x27, 0x20, 0x20, 0x24, 0x1d, 0x1d, 0x21, 0x47, 0x43, 0x51, 0x43, 0x3f, 0x4d, 0x42, 0x3f, 0x4c, 0x53, 0x4f, 0x5f, 0x1f, 0x1f, 0x24, 0x1f, 0x1f, 0x23, 0x1e, 0x1e, 0x21, 0x53, 0x50, 0x5f, 0x53, 0x4f, 0x5e, 0x5f, 0x5a, 0x6c, 0xff, 0xff, 0xff, 0xd1, 0x85, 0xc5, 0x5, 0x0, 0x0, 0x0, 0x24, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x4, 0xa, 0x11, 0x19, 0x1f, 0x22, 0x24, 0x1d, 0x16, 0xd, 0x7, 0x2, 0x15, 0x25, 0x34, 0x3f, 0x46, 0x47, 0x48, 0x43, 0x3a, 0x2d, 0x1b, 0x77, 0xef, 0xe6, 0x49, 0xef, 0xe6, 0xef, 0xe7, 0x77, 0xef, 0xe4, 0x4a, 0xba, 0xea, 0xc1, 0xeb, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x6b, 0x52, 0x65, 0xa5, 0x98, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x1, 0x10, 0x49, 0x44, 0x41, 0x54, 0x28, 0xcf, 0x8d, 0xd1, 0xd9, 0x52, 0xc2, 0x30, 0x14, 0x80, 0x61, 0xd6, 0xa2, 0xa8, 0x6c, 0x75, 0xdf, 0x77, 0xa8, 0xa2, 0x70, 0xd2, 0x4a, 0x25, 0x6d, 0x81, 0x62, 0xa1, 0x88, 0x20, 0x6e, 0xc5, 0xaa, 0x80, 0xfb, 0xfa, 0xfe, 0xf, 0x60, 0x49, 0x13, 0x86, 0xd1, 0xb, 0xfd, 0x6e, 0xf3, 0xcf, 0xe4, 0x24, 0xc7, 0xe3, 0xf5, 0xf9, 0x3, 0x41, 0x2e, 0xe4, 0xe0, 0x46, 0x46, 0xc3, 0x63, 0xe3, 0x9e, 0x9f, 0x7c, 0x13, 0x91, 0x68, 0x2c, 0x9e, 0xe0, 0x79, 0x7e, 0x72, 0x6a, 0x7a, 0x26, 0xec, 0xfd, 0x15, 0xf8, 0x23, 0xb3, 0x73, 0x9b, 0x5b, 0xae, 0xed, 0x64, 0x4a, 0xd8, 0xa1, 0x76, 0x85, 0x74, 0x6a, 0x7e, 0xc1, 0x9, 0x2, 0xd1, 0xc5, 0xbd, 0xfd, 0x8c, 0x2b, 0xb, 0x48, 0x94, 0xa8, 0x3, 0x31, 0x27, 0xcb, 0x4b, 0x4e, 0x10, 0x8c, 0x1d, 0xb2, 0xf3, 0x4c, 0x36, 0x8f, 0x95, 0x34, 0xa5, 0x2a, 0x22, 0xd6, 0x44, 0x27, 0xe0, 0xe2, 0x85, 0x22, 0x53, 0xc8, 0x43, 0x52, 0xa0, 0x4a, 0xaa, 0x4, 0x7a, 0x3f, 0x8, 0x25, 0xca, 0x47, 0x4c, 0xd9, 0x0, 0xb5, 0x42, 0x95, 0xaa, 0x26, 0x68, 0x46, 0x3f, 0xe0, 0x6b, 0xc7, 0x4c, 0x6d, 0x38, 0x50, 0x9d, 0x0, 0x48, 0x50, 0x3f, 0x61, 0xea, 0xb9, 0x86, 0x34, 0x34, 0x43, 0xf3, 0x14, 0x93, 0x2b, 0x5a, 0x67, 0x4c, 0xb, 0xa1, 0xf3, 0xb, 0x4a, 0xb9, 0x4, 0xf9, 0xa, 0x91, 0x21, 0xad, 0x36, 0x63, 0x5d, 0xeb, 0xf6, 0xe0, 0x99, 0x76, 0x43, 0xbf, 0xd1, 0xc9, 0x33, 0xad, 0xf6, 0x2d, 0x75, 0xd7, 0xe9, 0x62, 0x9b, 0x2, 0xdc, 0xbb, 0x7f, 0xd0, 0xc8, 0x47, 0x2d, 0x3f, 0x3e, 0x3d, 0xbb, 0x5e, 0x3a, 0xaf, 0x32, 0xa6, 0x9a, 0xbd, 0xee, 0xdb, 0xfb, 0xa, 0xf9, 0xea, 0xd5, 0xb5, 0x8f, 0x4f, 0xd7, 0x17, 0x80, 0x39, 0x98, 0xc1, 0x34, 0xd0, 0xfa, 0xc6, 0x7f, 0x96, 0xf5, 0xd7, 0xba, 0xbf, 0x1, 0xfe, 0x22, 0x58, 0x7c, 0xf4, 0xd2, 0xd1, 0x68, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x40, 0xde, 0x8d, 0x6b, 0x0, 0x0, 0x1, 0x41, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x42, 0x40, 0x4b, 0x5f, 0x5a, 0x6c, 0x2b, 0x2b, 0x31, 0x2e, 0x2e, 0x34, 0x5f, 0x5a, 0x6b, 0x2a, 0x2a, 0x30, 0x56, 0x53, 0x64, 0x22, 0x22, 0x27, 0x3e, 0x3b, 0x46, 0x57, 0x53, 0x63, 0x24, 0x24, 0x28, 0x24, 0x24, 0x29, 0x5b, 0x57, 0x68, 0x5a, 0x56, 0x67, 0x67, 0x63, 0x76, 0x2a, 0x2a, 0x31, 0x2a, 0x2a, 0x30, 0x2d, 0x2d, 0x34, 0x2f, 0x2f, 0x36, 0x2e, 0x2e, 0x35, 0x2c, 0x2c, 0x32, 0x4d, 0x4a, 0x57, 0x49, 0x46, 0x52, 0x48, 0x45, 0x51, 0x5a, 0x56, 0x65, 0x26, 0x26, 0x2b, 0x24, 0x24, 0x28, 0x27, 0x27, 0x2d, 0x29, 0x29, 0x2f, 0x28, 0x28, 0x2e, 0x25, 0x25, 0x2b, 0x23, 0x23, 0x28, 0x5b, 0x57, 0x66, 0x26, 0x26, 0x2c, 0x25, 0x25, 0x2a, 0x2a, 0x2a, 0x2f, 0x2b, 0x2b, 0x31, 0x22, 0x22, 0x26, 0x59, 0x55, 0x64, 0x47, 0x44, 0x50, 0x2d, 0x2d, 0x33, 0x22, 0x22, 0x27, 0x58, 0x54, 0x64, 0x46, 0x43, 0x50, 0x27, 0x27, 0x2b, 0x2e, 0x2e, 0x34, 0x2c, 0x2c, 0x31, 0x29, 0x29, 0x2e, 0x56, 0x53, 0x63, 0x45, 0x42, 0x4f, 0x56, 0x53, 0x62, 0x45, 0x42, 0x4e, 0x24, 0x24, 0x2a, 0x24, 0x24, 0x29, 0x20, 0x20, 0x25, 0x55, 0x51, 0x62, 0x44, 0x41, 0x4e, 0x28, 0x28, 0x2d, 0x2b, 0x2b, 0x30, 0x29, 0x29, 0x2d, 0x20, 0x20, 0x23, 0x55, 0x51, 0x60, 0x44, 0x41, 0x4d, 0x22, 0x22, 0x28, 0x27, 0x27, 0x2c, 0x1e, 0x1e, 0x22, 0x43, 0x40, 0x4c, 0x54, 0x50, 0x5f, 0x21, 0x21, 0x26, 0x21, 0x21, 0x25, 0x23, 0x23, 0x27, 0x20, 0x20, 0x24, 0x1d, 0x1d, 0x21, 0x47, 0x43, 0x51, 0x43, 0x3f, 0x4d, 0x42, 0x3f, 0x4c, 0x53, 0x4f, 0x5f, 0x1f, 0x1f, 0x24, 0x1f, 0x1f, 0x23, 0x1e, 0x1e, 0x21, 0x53, 0x50, 0x5f, 0x53, 0x4f, 0x5e, 0x5f, 0x5a, 0x6c, 0xd3, 0x26, 0x54, 0x35, 0x0, 0x0, 0x0, 0x24, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x4, 0xa, 0x11, 0x19, 0x1f, 0x22, 0x24, 0x1d, 0x16, 0xd, 0x7, 0x2, 0x15, 0x25, 0x34, 0x3f, 0x46, 0x47, 0x48, 0x43, 0x3a, 0x2d, 0x1b, 0x77, 0xef, 0xe6, 0x49, 0xef, 0xe6, 0xef, 0xe7, 0x77, 0xef, 0xe4, 0x4a, 0xba, 0xea, 0xc1, 0xeb, 0x0, 0x0, 0x0, 0xe5, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x85, 0x91, 0x43, 0x62, 0xc5, 0x60, 0x18, 0x45, 0xef, 0x8d, 0x51, 0xdb, 0xee, 0x46, 0xca, 0x6d, 0x77, 0x58, 0xce, 0x6b, 0xdb, 0x7c, 0x8a, 0xad, 0xea, 0x44, 0x1f, 0x4e, 0x92, 0x1f, 0x4c, 0x0, 0xe0, 0x9, 0x61, 0xf0, 0x89, 0x32, 0x12, 0xcd, 0xd4, 0x8, 0xef, 0x1f, 0x35, 0x54, 0xa0, 0x68, 0x1a, 0x34, 0x89, 0x8, 0x86, 0xa4, 0xd, 0x57, 0xb4, 0xdf, 0x79, 0x5, 0x89, 0x94, 0xba, 0xf9, 0xb3, 0xc0, 0xce, 0xeb, 0xf0, 0x17, 0x1c, 0xab, 0x11, 0x9, 0x1a, 0xf9, 0x96, 0x84, 0x5d, 0x5e, 0x43, 0x15, 0x7, 0x2e, 0x42, 0x41, 0x51, 0xd3, 0xbe, 0x67, 0xd5, 0x6b, 0x42, 0x3a, 0x38, 0x9b, 0xf5, 0x2e, 0x20, 0xfa, 0x5, 0x33, 0x41, 0x69, 0xf4, 0xeb, 0x49, 0x6c, 0x19, 0xe6, 0xbd, 0xdd, 0xd, 0x48, 0xa0, 0x92, 0xb, 0x36, 0x72, 0x6a, 0x26, 0xf0, 0x14, 0xa, 0x10, 0x72, 0xe1, 0x7d, 0xf4, 0xf6, 0x35, 0x1b, 0xc3, 0xe3, 0x18, 0x9d, 0x50, 0xf0, 0xe4, 0xc2, 0x17, 0xae, 0x27, 0xd3, 0xe4, 0x6e, 0xe8, 0xf8, 0x7e, 0xbc, 0x1, 0x48, 0x9e, 0x57, 0xf8, 0xc5, 0xfc, 0xbd, 0x7a, 0x98, 0xc4, 0x94, 0x47, 0xbf, 0xe4, 0xce, 0x48, 0x8, 0x6e, 0x69, 0x91, 0x63, 0x47, 0x73, 0x49, 0xbc, 0x77, 0x3e, 0xd7, 0x4b, 0x3b, 0x12, 0x36, 0x16, 0xb3, 0x85, 0x6a, 0x68, 0xce, 0x39, 0x62, 0xc6, 0xba, 0x3d, 0x8d, 0xe7, 0x91, 0x20, 0xac, 0xad, 0xa6, 0xc2, 0xe, 0x6, 0xcc, 0x74, 0xc, 0x2d, 0xe7, 0xf9, 0x55, 0x2, 0x28, 0x94, 0x37, 0xab, 0xee, 0xa1, 0xcc, 0xbf, 0xdb, 0xed, 0x3, 0x70, 0xe6, 0x4f, 0x4a, 0xc3, 0xed, 0xed, 0xf3, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char option_button_normal_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x40, 0xde, 0x8d, 0x6b, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x1, 0x44, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3c, 0x3a, 0x44, 0x56, 0x53, 0x61, 0x2b, 0x2b, 0x31, 0x2e, 0x2e, 0x34, 0x56, 0x52, 0x60, 0x2a, 0x2a, 0x30, 0x47, 0x44, 0x52, 0x22, 0x22, 0x27, 0x33, 0x31, 0x39, 0x47, 0x44, 0x50, 0x24, 0x24, 0x28, 0x24, 0x24, 0x29, 0x52, 0x50, 0x5d, 0x51, 0x4f, 0x5d, 0x5d, 0x5a, 0x6a, 0x2a, 0x2a, 0x31, 0x2a, 0x2a, 0x30, 0x2d, 0x2d, 0x34, 0x2f, 0x2f, 0x36, 0x2e, 0x2e, 0x35, 0x2c, 0x2c, 0x32, 0x46, 0x42, 0x4e, 0x42, 0x3e, 0x4a, 0x41, 0x3e, 0x49, 0x51, 0x4e, 0x5b, 0x26, 0x26, 0x2b, 0x24, 0x24, 0x28, 0x27, 0x27, 0x2d, 0x29, 0x29, 0x2f, 0x28, 0x28, 0x2e, 0x25, 0x25, 0x2b, 0x23, 0x23, 0x28, 0x40, 0x3e, 0x48, 0x50, 0x4e, 0x5a, 0x26, 0x26, 0x2c, 0x25, 0x25, 0x2a, 0x2a, 0x2a, 0x2f, 0x2b, 0x2b, 0x31, 0x22, 0x22, 0x26, 0x4f, 0x4c, 0x59, 0x3f, 0x3d, 0x47, 0x2d, 0x2d, 0x33, 0x22, 0x22, 0x27, 0x4e, 0x4a, 0x58, 0x3e, 0x3b, 0x46, 0x27, 0x27, 0x2b, 0x2e, 0x2e, 0x34, 0x2c, 0x2c, 0x31, 0x29, 0x29, 0x2e, 0x4b, 0x49, 0x55, 0x3c, 0x3a, 0x44, 0x4a, 0x47, 0x54, 0x3b, 0x39, 0x43, 0x24, 0x24, 0x2a, 0x24, 0x24, 0x29, 0x20, 0x20, 0x25, 0x49, 0x46, 0x53, 0x3a, 0x38, 0x42, 0x28, 0x28, 0x2d, 0x2b, 0x2b, 0x30, 0x29, 0x29, 0x2d, 0x20, 0x20, 0x23, 0x47, 0x45, 0x50, 0x39, 0x37, 0x40, 0x22, 0x22, 0x28, 0x27, 0x27, 0x2c, 0x1e, 0x1e, 0x22, 0x47, 0x43, 0x50, 0x38, 0x35, 0x3f, 0x46, 0x42, 0x4f, 0x21, 0x21, 0x26, 0x21, 0x21, 0x25, 0x23, 0x23, 0x27, 0x20, 0x20, 0x24, 0x1d, 0x1d, 0x21, 0x36, 0x34, 0x3e, 0x44, 0x41, 0x4e, 0x1f, 0x1f, 0x24, 0x1f, 0x1f, 0x23, 0x1e, 0x1e, 0x21, 0x44, 0x42, 0x4d, 0x44, 0x41, 0x4c, 0x4e, 0x4b, 0x58, 0xff, 0xff, 0xff, 0xd7, 0xc8, 0xfe, 0x88, 0x0, 0x0, 0x0, 0x24, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x4, 0xa, 0x11, 0x19, 0x1f, 0x22, 0x24, 0x1d, 0x16, 0xd, 0x7, 0x2, 0x15, 0x25, 0x34, 0x3f, 0x46, 0x47, 0x48, 0x43, 0x3a, 0x2d, 0x1b, 0x77, 0xef, 0xe6, 0x49, 0xef, 0xe6, 0xef, 0xe7, 0x77, 0xef, 0xe4, 0x4a, 0xba, 0xea, 0xc1, 0xeb, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x6b, 0x52, 0x65, 0xa5, 0x98, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x4, 0x4e, 0x1d, 0x2, 0xaf, 0x0, 0x0, 0x1, 0xe, 0x49, 0x44, 0x41, 0x54, 0x28, 0xcf, 0x8d, 0xd1, 0xd7, 0x56, 0xc2, 0x40, 0x10, 0x80, 0x61, 0x6a, 0x50, 0x54, 0x5a, 0xec, 0xbd, 0x43, 0x14, 0x85, 0xdd, 0x44, 0xa2, 0x6c, 0x12, 0x20, 0x18, 0xd, 0x22, 0x8, 0x16, 0x34, 0x16, 0xc0, 0x5e, 0xde, 0xff, 0x1, 0x5c, 0x36, 0xb3, 0x1c, 0x8e, 0x5e, 0xe8, 0x77, 0xfd, 0x9f, 0xb3, 0x33, 0xb3, 0x1e, 0xaf, 0xcf, 0x1f, 0x8, 0xa, 0x21, 0x4a, 0x18, 0x1a, 0xe, 0x8f, 0x8c, 0x7a, 0x7e, 0xf2, 0x8d, 0x45, 0xa2, 0xb1, 0x78, 0x42, 0x14, 0xc5, 0xf1, 0x89, 0xc9, 0xa9, 0xb0, 0xf7, 0x57, 0xe0, 0x8f, 0x4c, 0xcf, 0xac, 0x6f, 0xb8, 0x36, 0x93, 0x29, 0x69, 0xb, 0x6c, 0x4b, 0xe9, 0xd4, 0xec, 0x1c, 0xd, 0x2, 0xd1, 0xf9, 0x9d, 0xdd, 0x8c, 0x2b, 0x8b, 0xb0, 0xac, 0x80, 0x3d, 0x39, 0xa7, 0xaa, 0xb, 0x34, 0x8, 0xc6, 0xb2, 0x99, 0x7d, 0x70, 0x90, 0x27, 0x5a, 0x1a, 0xe8, 0x9a, 0x4c, 0xc, 0x99, 0x6, 0x42, 0xbc, 0x50, 0xe4, 0xa, 0x79, 0x94, 0x94, 0x40, 0x49, 0x57, 0x90, 0xd9, 0xb, 0x42, 0x89, 0xf2, 0x21, 0x57, 0xb6, 0x90, 0x7e, 0x4, 0x4a, 0xc7, 0x36, 0x32, 0xac, 0x5e, 0x20, 0x56, 0x4e, 0xb8, 0xca, 0x60, 0xa0, 0xd3, 0x0, 0xb1, 0xa0, 0x7a, 0xca, 0x55, 0x73, 0x35, 0x65, 0x60, 0x86, 0xfa, 0x19, 0x61, 0x4f, 0x34, 0x9a, 0x5c, 0x3, 0xe3, 0xf3, 0xb, 0xa0, 0x5d, 0x22, 0xf5, 0xa, 0xb3, 0x21, 0x5b, 0xd7, 0x5c, 0xeb, 0xc6, 0x74, 0xfa, 0x6b, 0x3a, 0x35, 0xf3, 0xd6, 0x64, 0x6b, 0xde, 0xdd, 0x73, 0xf, 0xed, 0xe, 0x71, 0x0, 0x22, 0xdd, 0xc7, 0x27, 0x83, 0x1d, 0x6a, 0xb1, 0xf9, 0xc, 0x5e, 0xda, 0xaf, 0x2a, 0x1, 0xf5, 0x6e, 0xe7, 0xed, 0x7d, 0x89, 0x9d, 0x7a, 0x79, 0xe5, 0xe3, 0xd3, 0xf5, 0x85, 0x90, 0xdd, 0x9f, 0xc1, 0xb6, 0xf0, 0xea, 0xda, 0x7f, 0x3e, 0xeb, 0xaf, 0xef, 0xfe, 0x6, 0x1a, 0x96, 0x59, 0x89, 0x91, 0xf7, 0xf1, 0x7b, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x40, 0xde, 0x8d, 0x6b, 0x0, 0x0, 0x1, 0x41, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3c, 0x3a, 0x44, 0x56, 0x53, 0x61, 0x2b, 0x2b, 0x31, 0x2e, 0x2e, 0x34, 0x56, 0x52, 0x60, 0x2a, 0x2a, 0x30, 0x47, 0x44, 0x52, 0x22, 0x22, 0x27, 0x33, 0x31, 0x39, 0x47, 0x44, 0x50, 0x24, 0x24, 0x28, 0x24, 0x24, 0x29, 0x52, 0x50, 0x5d, 0x51, 0x4f, 0x5d, 0x5d, 0x5a, 0x6a, 0x2a, 0x2a, 0x31, 0x2a, 0x2a, 0x30, 0x2d, 0x2d, 0x34, 0x2f, 0x2f, 0x36, 0x2e, 0x2e, 0x35, 0x2c, 0x2c, 0x32, 0x46, 0x42, 0x4e, 0x42, 0x3e, 0x4a, 0x41, 0x3e, 0x49, 0x51, 0x4e, 0x5b, 0x26, 0x26, 0x2b, 0x24, 0x24, 0x28, 0x27, 0x27, 0x2d, 0x29, 0x29, 0x2f, 0x28, 0x28, 0x2e, 0x25, 0x25, 0x2b, 0x23, 0x23, 0x28, 0x40, 0x3e, 0x48, 0x50, 0x4e, 0x5a, 0x26, 0x26, 0x2c, 0x25, 0x25, 0x2a, 0x2a, 0x2a, 0x2f, 0x2b, 0x2b, 0x31, 0x22, 0x22, 0x26, 0x4f, 0x4c, 0x59, 0x3f, 0x3d, 0x47, 0x2d, 0x2d, 0x33, 0x22, 0x22, 0x27, 0x4e, 0x4a, 0x58, 0x3e, 0x3b, 0x46, 0x27, 0x27, 0x2b, 0x2e, 0x2e, 0x34, 0x2c, 0x2c, 0x31, 0x29, 0x29, 0x2e, 0x4b, 0x49, 0x55, 0x3c, 0x3a, 0x44, 0x4a, 0x47, 0x54, 0x3b, 0x39, 0x43, 0x24, 0x24, 0x2a, 0x24, 0x24, 0x29, 0x20, 0x20, 0x25, 0x49, 0x46, 0x53, 0x3a, 0x38, 0x42, 0x28, 0x28, 0x2d, 0x2b, 0x2b, 0x30, 0x29, 0x29, 0x2d, 0x20, 0x20, 0x23, 0x47, 0x45, 0x50, 0x39, 0x37, 0x40, 0x22, 0x22, 0x28, 0x27, 0x27, 0x2c, 0x1e, 0x1e, 0x22, 0x47, 0x43, 0x50, 0x38, 0x35, 0x3f, 0x46, 0x42, 0x4f, 0x21, 0x21, 0x26, 0x21, 0x21, 0x25, 0x23, 0x23, 0x27, 0x20, 0x20, 0x24, 0x1d, 0x1d, 0x21, 0x36, 0x34, 0x3e, 0x44, 0x41, 0x4e, 0x1f, 0x1f, 0x24, 0x1f, 0x1f, 0x23, 0x1e, 0x1e, 0x21, 0x44, 0x42, 0x4d, 0x44, 0x41, 0x4c, 0x4e, 0x4b, 0x58, 0x8, 0xd9, 0x10, 0xcb, 0x0, 0x0, 0x0, 0x24, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x4, 0xa, 0x11, 0x19, 0x1f, 0x22, 0x24, 0x1d, 0x16, 0xd, 0x7, 0x2, 0x15, 0x25, 0x34, 0x3f, 0x46, 0x47, 0x48, 0x43, 0x3a, 0x2d, 0x1b, 0x77, 0xef, 0xe6, 0x49, 0xef, 0xe6, 0xef, 0xe7, 0x77, 0xef, 0xe4, 0x4a, 0xba, 0xea, 0xc1, 0xeb, 0x0, 0x0, 0x0, 0xe7, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x6c, 0x91, 0x53, 0x62, 0x5, 0x41, 0x14, 0x44, 0xab, 0x46, 0xb1, 0x6d, 0x67, 0x3, 0x59, 0x44, 0x16, 0x9e, 0xdf, 0xe8, 0x2f, 0xb6, 0xcd, 0xe7, 0x61, 0xe3, 0x3e, 0x4e, 0xb5, 0x2e, 0x4e, 0xdb, 0xa3, 0x11, 0x80, 0xc4, 0x51, 0xc6, 0x3f, 0x5a, 0xe5, 0xb1, 0x4f, 0x8, 0xd5, 0xff, 0x15, 0xd1, 0x26, 0xba, 0x7d, 0xbd, 0xec, 0xa3, 0x75, 0x94, 0x24, 0x11, 0xbb, 0xe1, 0x2f, 0x1f, 0xe0, 0x91, 0xde, 0x8, 0xf3, 0x1, 0xe, 0x3d, 0x42, 0x1, 0xe3, 0x49, 0xf, 0x1a, 0xc0, 0xb7, 0xb5, 0x47, 0x92, 0x52, 0xb7, 0x3b, 0x79, 0xa7, 0x80, 0x21, 0xc2, 0x2a, 0xa9, 0x15, 0x8b, 0x8e, 0x1c, 0x2e, 0x64, 0x71, 0x4, 0xd0, 0x5b, 0x34, 0x80, 0xa0, 0x34, 0x29, 0xab, 0xd5, 0x7a, 0xfb, 0x5e, 0xc2, 0x51, 0xc0, 0x3, 0x83, 0x6, 0x10, 0xa2, 0xa1, 0x62, 0x1f, 0xf0, 0xae, 0x0, 0x38, 0xd, 0xe0, 0x67, 0xfe, 0xe9, 0xb, 0x72, 0x86, 0xb7, 0x5, 0x46, 0xa, 0x48, 0xfc, 0xa6, 0x15, 0x1e, 0x96, 0xc5, 0x79, 0x99, 0xbe, 0x78, 0x59, 0x2c, 0x1, 0x5e, 0x92, 0x34, 0x6d, 0xb1, 0xf9, 0xda, 0x75, 0x66, 0x6d, 0xfa, 0xf3, 0x5, 0x7f, 0x58, 0x3, 0x8d, 0x15, 0xc8, 0x85, 0xf3, 0xd, 0x6b, 0x1f, 0xdf, 0x6e, 0x8c, 0x33, 0xd4, 0xc0, 0xce, 0xd6, 0xa8, 0x0, 0xd5, 0x20, 0xbc, 0xb5, 0xf6, 0xc2, 0x68, 0xb6, 0xf4, 0x8d, 0x6, 0x9c, 0xc3, 0x6d, 0x5a, 0x60, 0xf, 0x53, 0x7d, 0x72, 0x86, 0x6a, 0xf4, 0xf1, 0xed, 0x1, 0x74, 0x5a, 0x3f, 0xab, 0x94, 0xee, 0x3f, 0x7a, 0x64, 0x11, 0x8a, 0x6e, 0x0, 0x80, 0xdd, 0x4f, 0x5c, 0xe, 0xd7, 0x26, 0x1c, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char option_button_pressed_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x40, 0xde, 0x8d, 0x6b, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x1, 0x4d, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x31, 0x2f, 0x37, 0x46, 0x43, 0x4f, 0x2b, 0x2b, 0x31, 0x2e, 0x2e, 0x34, 0x47, 0x44, 0x50, 0x2a, 0x2a, 0x30, 0x55, 0x52, 0x5f, 0x22, 0x22, 0x27, 0x3d, 0x3a, 0x45, 0x56, 0x52, 0x60, 0x24, 0x24, 0x28, 0x24, 0x24, 0x29, 0x43, 0x40, 0x4c, 0x42, 0x40, 0x4b, 0x4c, 0x49, 0x56, 0x2a, 0x2a, 0x31, 0x2a, 0x2a, 0x30, 0x2d, 0x2d, 0x34, 0x2f, 0x2f, 0x36, 0x2e, 0x2e, 0x35, 0x2c, 0x2c, 0x32, 0x3a, 0x38, 0x41, 0x36, 0x34, 0x3d, 0x44, 0x41, 0x4c, 0x26, 0x26, 0x2b, 0x24, 0x24, 0x28, 0x27, 0x27, 0x2d, 0x29, 0x29, 0x2f, 0x28, 0x28, 0x2e, 0x25, 0x25, 0x2b, 0x23, 0x23, 0x28, 0x44, 0x42, 0x4e, 0x36, 0x34, 0x3e, 0x44, 0x41, 0x4e, 0x26, 0x26, 0x2c, 0x25, 0x25, 0x2a, 0x2a, 0x2a, 0x2f, 0x2b, 0x2b, 0x31, 0x22, 0x22, 0x26, 0x46, 0x42, 0x4f, 0x38, 0x35, 0x3f, 0x2d, 0x2d, 0x33, 0x22, 0x22, 0x27, 0x47, 0x45, 0x50, 0x39, 0x37, 0x40, 0x27, 0x27, 0x2b, 0x2e, 0x2e, 0x34, 0x2c, 0x2c, 0x31, 0x29, 0x29, 0x2e, 0x49, 0x46, 0x53, 0x3a, 0x38, 0x42, 0x4a, 0x47, 0x54, 0x3b, 0x39, 0x43, 0x24, 0x24, 0x2a, 0x24, 0x24, 0x29, 0x20, 0x20, 0x25, 0x4b, 0x49, 0x55, 0x3c, 0x3a, 0x44, 0x28, 0x28, 0x2d, 0x2b, 0x2b, 0x30, 0x29, 0x29, 0x2d, 0x20, 0x20, 0x23, 0x4e, 0x4a, 0x58, 0x3e, 0x3b, 0x46, 0x22, 0x22, 0x28, 0x27, 0x27, 0x2c, 0x1e, 0x1e, 0x22, 0x50, 0x4d, 0x5a, 0x3f, 0x3d, 0x48, 0x3f, 0x3d, 0x47, 0x4f, 0x4c, 0x59, 0x21, 0x21, 0x26, 0x21, 0x21, 0x25, 0x23, 0x23, 0x27, 0x20, 0x20, 0x24, 0x1d, 0x1d, 0x21, 0x45, 0x42, 0x4d, 0x41, 0x3e, 0x49, 0x40, 0x3e, 0x48, 0x50, 0x4e, 0x5a, 0x1f, 0x1f, 0x24, 0x1f, 0x1f, 0x23, 0x1e, 0x1e, 0x21, 0x52, 0x4e, 0x5c, 0x51, 0x4e, 0x5b, 0x5d, 0x59, 0x69, 0xff, 0xff, 0xff, 0x2, 0x4e, 0xff, 0xf1, 0x0, 0x0, 0x0, 0x24, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x4, 0xa, 0x11, 0x19, 0x1f, 0x22, 0x24, 0x1d, 0x16, 0xd, 0x7, 0x2, 0x15, 0x25, 0x34, 0x3f, 0x46, 0x47, 0x48, 0x43, 0x3a, 0x2d, 0x1b, 0x77, 0xef, 0xe6, 0x49, 0xef, 0xe6, 0xef, 0xe7, 0x77, 0xef, 0xe4, 0x4a, 0xba, 0xea, 0xc1, 0xeb, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x6e, 0x22, 0xf, 0x51, 0x17, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x1, 0xe, 0x49, 0x44, 0x41, 0x54, 0x28, 0xcf, 0x8d, 0xd1, 0x57, 0x53, 0xc2, 0x40, 0x10, 0xc0, 0x71, 0x6a, 0x50, 0x54, 0x5a, 0xec, 0xbd, 0x43, 0x14, 0xf5, 0x2e, 0x91, 0xa8, 0x5c, 0x12, 0x20, 0x18, 0xd, 0x22, 0x88, 0xd, 0x8d, 0xd, 0xb0, 0xd7, 0xef, 0xff, 0xea, 0x71, 0xd9, 0x63, 0x18, 0x7d, 0xd0, 0xdf, 0xf3, 0x7f, 0xe6, 0x76, 0xf7, 0x3c, 0x5e, 0x9f, 0x3f, 0x10, 0x14, 0x42, 0x94, 0xd0, 0xd3, 0x1b, 0xee, 0xeb, 0xf7, 0xfc, 0xe4, 0x1b, 0x88, 0x44, 0x63, 0xf1, 0x84, 0x28, 0x8a, 0x83, 0x43, 0xc3, 0x23, 0x61, 0xef, 0xaf, 0xc0, 0x1f, 0x19, 0x1d, 0x5b, 0x5c, 0x72, 0x2d, 0x27, 0x53, 0xd2, 0xa, 0x58, 0x95, 0xd2, 0xa9, 0xf1, 0x9, 0x1a, 0x4, 0xa2, 0x93, 0x6b, 0xeb, 0x60, 0x3, 0x61, 0x59, 0x1, 0x9b, 0x72, 0x46, 0x55, 0xa7, 0x68, 0x10, 0x8c, 0x6d, 0x6d, 0x73, 0x3b, 0x59, 0xa2, 0xa5, 0x81, 0xae, 0xc9, 0xc4, 0x90, 0x69, 0x20, 0xc4, 0x73, 0x79, 0x2e, 0x97, 0x45, 0x49, 0x9, 0x14, 0x74, 0x5, 0x99, 0xed, 0x20, 0x94, 0x28, 0xee, 0x72, 0x45, 0xb, 0xe9, 0x7b, 0xa0, 0xb0, 0x6f, 0x23, 0xc3, 0x6a, 0x7, 0x62, 0xe9, 0x80, 0x2b, 0x75, 0x7, 0x3a, 0xd, 0x10, 0xb, 0xca, 0x87, 0x5c, 0x39, 0x53, 0x51, 0xba, 0x66, 0xa8, 0x1e, 0x11, 0xf6, 0x44, 0xed, 0x98, 0xab, 0x61, 0x7c, 0x72, 0xa, 0xb4, 0x33, 0xa4, 0x9e, 0x63, 0x36, 0x64, 0xfd, 0x82, 0xab, 0x5f, 0x9a, 0x4e, 0x67, 0x4d, 0xa7, 0x62, 0x5e, 0x99, 0x6c, 0xcd, 0xeb, 0x9b, 0x5b, 0x70, 0xd7, 0x68, 0x12, 0x7, 0x20, 0xd2, 0xba, 0x7f, 0x30, 0xd8, 0xa1, 0xa6, 0x1f, 0x9f, 0x9e, 0x5d, 0x2f, 0x8d, 0x57, 0x95, 0x80, 0x6a, 0xab, 0xf9, 0xf6, 0x3e, 0xc3, 0x4e, 0x3d, 0x3b, 0xf7, 0xf1, 0xe9, 0xfa, 0x42, 0xc8, 0xee, 0xcc, 0x60, 0x5b, 0x78, 0x7e, 0xe1, 0x3f, 0x9f, 0xf5, 0xd7, 0x77, 0x7f, 0x3, 0x1c, 0x7f, 0x59, 0xc2, 0x5e, 0xdd, 0xbf, 0x43, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x40, 0xde, 0x8d, 0x6b, 0x0, 0x0, 0x1, 0x4a, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x31, 0x2f, 0x37, 0x46, 0x43, 0x4f, 0x2b, 0x2b, 0x31, 0x2e, 0x2e, 0x34, 0x47, 0x44, 0x50, 0x2a, 0x2a, 0x30, 0x55, 0x52, 0x5f, 0x22, 0x22, 0x27, 0x3d, 0x3a, 0x45, 0x56, 0x52, 0x60, 0x24, 0x24, 0x28, 0x24, 0x24, 0x29, 0x43, 0x40, 0x4c, 0x42, 0x40, 0x4b, 0x4c, 0x49, 0x56, 0x2a, 0x2a, 0x31, 0x2a, 0x2a, 0x30, 0x2d, 0x2d, 0x34, 0x2f, 0x2f, 0x36, 0x2e, 0x2e, 0x35, 0x2c, 0x2c, 0x32, 0x3a, 0x38, 0x41, 0x36, 0x34, 0x3d, 0x44, 0x41, 0x4c, 0x26, 0x26, 0x2b, 0x24, 0x24, 0x28, 0x27, 0x27, 0x2d, 0x29, 0x29, 0x2f, 0x28, 0x28, 0x2e, 0x25, 0x25, 0x2b, 0x23, 0x23, 0x28, 0x44, 0x42, 0x4e, 0x36, 0x34, 0x3e, 0x44, 0x41, 0x4e, 0x26, 0x26, 0x2c, 0x25, 0x25, 0x2a, 0x2a, 0x2a, 0x2f, 0x2b, 0x2b, 0x31, 0x22, 0x22, 0x26, 0x46, 0x42, 0x4f, 0x38, 0x35, 0x3f, 0x2d, 0x2d, 0x33, 0x22, 0x22, 0x27, 0x47, 0x45, 0x50, 0x39, 0x37, 0x40, 0x27, 0x27, 0x2b, 0x2e, 0x2e, 0x34, 0x2c, 0x2c, 0x31, 0x29, 0x29, 0x2e, 0x49, 0x46, 0x53, 0x3a, 0x38, 0x42, 0x4a, 0x47, 0x54, 0x3b, 0x39, 0x43, 0x24, 0x24, 0x2a, 0x24, 0x24, 0x29, 0x20, 0x20, 0x25, 0x4b, 0x49, 0x55, 0x3c, 0x3a, 0x44, 0x28, 0x28, 0x2d, 0x2b, 0x2b, 0x30, 0x29, 0x29, 0x2d, 0x20, 0x20, 0x23, 0x4e, 0x4a, 0x58, 0x3e, 0x3b, 0x46, 0x22, 0x22, 0x28, 0x27, 0x27, 0x2c, 0x1e, 0x1e, 0x22, 0x50, 0x4d, 0x5a, 0x3f, 0x3d, 0x48, 0x3f, 0x3d, 0x47, 0x4f, 0x4c, 0x59, 0x21, 0x21, 0x26, 0x21, 0x21, 0x25, 0x23, 0x23, 0x27, 0x20, 0x20, 0x24, 0x1d, 0x1d, 0x21, 0x45, 0x42, 0x4d, 0x41, 0x3e, 0x49, 0x40, 0x3e, 0x48, 0x50, 0x4e, 0x5a, 0x1f, 0x1f, 0x24, 0x1f, 0x1f, 0x23, 0x1e, 0x1e, 0x21, 0x52, 0x4e, 0x5c, 0x51, 0x4e, 0x5b, 0x5d, 0x59, 0x69, 0x10, 0x9d, 0xe0, 0x3c, 0x0, 0x0, 0x0, 0x24, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x4, 0xa, 0x11, 0x19, 0x1f, 0x22, 0x24, 0x1d, 0x16, 0xd, 0x7, 0x2, 0x15, 0x25, 0x34, 0x3f, 0x46, 0x47, 0x48, 0x43, 0x3a, 0x2d, 0x1b, 0x77, 0xef, 0xe6, 0x49, 0xef, 0xe6, 0xef, 0xe7, 0x77, 0xef, 0xe4, 0x4a, 0xba, 0xea, 0xc1, 0xeb, 0x0, 0x0, 0x0, 0xe6, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x6c, 0xcf, 0x3, 0x62, 0x4, 0x51, 0x10, 0x4, 0xd0, 0xaa, 0x31, 0x62, 0xdb, 0xb8, 0x49, 0x2e, 0x9e, 0x3b, 0xc4, 0xb6, 0x9d, 0xc5, 0x58, 0x1f, 0xc1, 0xd6, 0xe8, 0x77, 0xf7, 0x1b, 0x59, 0x6c, 0x2, 0x20, 0x37, 0xaa, 0xc5, 0x17, 0x7e, 0xc7, 0x62, 0x28, 0x45, 0x75, 0xfe, 0x6c, 0xe1, 0x4f, 0x68, 0x86, 0x41, 0x69, 0x44, 0x51, 0x4b, 0xb1, 0xce, 0xcc, 0xe4, 0x83, 0xd7, 0xb0, 0x48, 0x6b, 0x98, 0xe8, 0x9, 0x38, 0x70, 0x8b, 0xa, 0xcc, 0x12, 0x1a, 0xf0, 0x4d, 0xac, 0x87, 0xf3, 0x96, 0x6f, 0x8e, 0x5f, 0x56, 0xc0, 0x53, 0x20, 0x8f, 0xbf, 0xdb, 0x86, 0x58, 0x5b, 0x9, 0xbf, 0x47, 0x80, 0xa, 0x58, 0x1a, 0x38, 0xad, 0x9, 0x5f, 0xac, 0xe3, 0x20, 0xbc, 0x4b, 0x46, 0x4b, 0x0, 0x3a, 0x1a, 0x24, 0xd0, 0x69, 0x85, 0xc0, 0x63, 0x5, 0x60, 0x68, 0xf0, 0x36, 0x7f, 0xf3, 0xaa, 0xbe, 0xe1, 0x61, 0x81, 0x69, 0x5, 0x72, 0x5b, 0x83, 0xe4, 0x6a, 0x59, 0x16, 0xf7, 0x53, 0x47, 0x77, 0x8b, 0xad, 0x12, 0xe4, 0xb9, 0xa3, 0xc1, 0xe6, 0x83, 0x7b, 0x20, 0xd6, 0xb4, 0xe7, 0xbf, 0xed, 0xe1, 0x1a, 0xd8, 0xfa, 0xdf, 0xb9, 0x70, 0xb8, 0x21, 0xd6, 0xbb, 0x17, 0x1b, 0xe3, 0x4c, 0x6a, 0xb0, 0xbd, 0x25, 0x5, 0x3b, 0x5e, 0x7c, 0x21, 0xc0, 0xc2, 0x68, 0xee, 0xf1, 0xbc, 0x6, 0x46, 0xb1, 0xbd, 0x5e, 0x30, 0x5, 0x27, 0x19, 0x24, 0xb8, 0x61, 0x6e, 0xf8, 0xf5, 0xf7, 0xcd, 0x47, 0x16, 0xa0, 0x18, 0x13, 0x6a, 0x64, 0x7d, 0xff, 0x8f, 0x1e, 0x59, 0x84, 0xa2, 0x1b, 0x0, 0xe5, 0xe0, 0x4e, 0x46, 0x1d, 0x98, 0x92, 0x5c, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char panel_bg_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x1, 0x3, 0x0, 0x0, 0x0, 0xfe, 0xc1, 0x2c, 0xc8, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x6, 0x50, 0x4c, 0x54, 0x45, 0x25, 0x25, 0x2a, 0x35, 0x32, 0x3b, 0x4a, 0x73, 0x58, 0x4a, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x1, 0xff, 0x2, 0x2d, 0xde, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0xb, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0x40, 0x5, 0x0, 0x0, 0x10, 0x0, 0x1, 0xa1, 0xc5, 0x21, 0xc1, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x1, 0x3, 0x0, 0x0, 0x0, 0xfe, 0xc1, 0x2c, 0xc8, 0x0, 0x0, 0x0, 0x6, 0x50, 0x4c, 0x54, 0x45, 0x25, 0x25, 0x2a, 0x35, 0x32, 0x3b, 0x4a, 0x73, 0x58, 0x4a, 0x0, 0x0, 0x0, 0xa, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x40, 0x3, 0x0, 0x0, 0x10, 0x0, 0x1, 0xb3, 0xac, 0xe2, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char popup_bg_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0xa5, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3b, 0x3b, 0x43, 0x42, 0x42, 0x4b, 0x3e, 0x3e, 0x47, 0x3e, 0x3e, 0x46, 0x41, 0x41, 0x4a, 0x0, 0x0, 0x0, 0x3d, 0x3d, 0x45, 0x3b, 0x3b, 0x43, 0x3a, 0x3a, 0x42, 0x38, 0x38, 0x41, 0x37, 0x37, 0x3e, 0x36, 0x36, 0x3d, 0x35, 0x35, 0x3c, 0x0, 0x0, 0x0, 0x38, 0x38, 0x40, 0x38, 0x38, 0x40, 0x31, 0x31, 0x38, 0x34, 0x34, 0x3b, 0x34, 0x34, 0x3b, 0x39, 0x39, 0x3f, 0x31, 0x31, 0x38, 0x2f, 0x2f, 0x36, 0x2d, 0x2d, 0x33, 0x2c, 0x2c, 0x32, 0x2b, 0x2b, 0x31, 0x2a, 0x2a, 0x31, 0x2a, 0x2a, 0x30, 0x29, 0x29, 0x30, 0x29, 0x29, 0x2f, 0x28, 0x28, 0x2e, 0x28, 0x28, 0x2d, 0x27, 0x27, 0x2d, 0x27, 0x27, 0x2c, 0x29, 0x29, 0x2e, 0x26, 0x26, 0x2c, 0x35, 0x32, 0x3b, 0xf, 0xeb, 0x7f, 0x60, 0x0, 0x0, 0x0, 0x28, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x1, 0x3, 0x5, 0x8, 0xa, 0xb, 0x4, 0x13, 0x19, 0x1f, 0x22, 0x23, 0x16, 0x27, 0x35, 0x3f, 0x45, 0x46, 0x94, 0xf5, 0xfa, 0xfb, 0xf5, 0x40, 0xfc, 0xfb, 0xfb, 0xfb, 0xfb, 0xfc, 0xfc, 0x1a, 0xf5, 0xf6, 0x95, 0xfa, 0xfb, 0xf4, 0x94, 0x71, 0xda, 0xac, 0x92, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x36, 0x47, 0xbf, 0x88, 0xd1, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0xaf, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x65, 0xcf, 0xc9, 0x12, 0x82, 0x30, 0x10, 0x4, 0xd0, 0x1, 0x12, 0xb6, 0x0, 0x21, 0x2c, 0xb2, 0xaa, 0xa0, 0xa8, 0x80, 0x88, 0x8, 0xf8, 0xff, 0xbf, 0x66, 0x98, 0x93, 0xa5, 0xef, 0xd8, 0x55, 0xd3, 0xd5, 0x3, 0xa0, 0xa8, 0x1a, 0xa1, 0xba, 0x44, 0x89, 0xa6, 0x2a, 0x0, 0x8a, 0x41, 0x4d, 0xcb, 0x66, 0x8e, 0xc3, 0x6c, 0xcb, 0xa4, 0x86, 0x2, 0x2a, 0x75, 0x3d, 0xee, 0x8b, 0x20, 0x10, 0x3e, 0xf7, 0x5c, 0xaa, 0x82, 0x66, 0x7a, 0x61, 0x14, 0xef, 0xa4, 0x38, 0xa, 0x3d, 0x53, 0x3, 0x62, 0xf1, 0xa4, 0xed, 0x50, 0x9b, 0x70, 0x8b, 0x0, 0xb5, 0xd3, 0xac, 0xeb, 0x51, 0x97, 0xa5, 0x36, 0x5, 0x9d, 0x89, 0xbc, 0xbf, 0xa3, 0x3e, 0x17, 0x4c, 0x7, 0xdd, 0x9, 0x8a, 0xe1, 0x81, 0x86, 0x22, 0x70, 0x30, 0x28, 0xc7, 0x27, 0x1a, 0x4b, 0xc, 0x98, 0xd8, 0x4f, 0x2f, 0x34, 0xed, 0xb7, 0x13, 0x59, 0x7a, 0x98, 0x17, 0x34, 0x1f, 0xb7, 0x52, 0x52, 0xf1, 0x7a, 0x5d, 0xde, 0xd2, 0xb2, 0x9e, 0x78, 0x45, 0xb6, 0x61, 0xe7, 0xba, 0xb9, 0x48, 0xcd, 0xf5, 0xb6, 0xd, 0xc3, 0xe9, 0xe9, 0xd7, 0xf4, 0xbf, 0xe7, 0x7e, 0xdf, 0xff, 0x0, 0xda, 0x19, 0x15, 0x34, 0xd5, 0xa4, 0x90, 0x50, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0xa2, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3b, 0x3b, 0x43, 0x42, 0x42, 0x4b, 0x3e, 0x3e, 0x47, 0x3e, 0x3e, 0x46, 0x41, 0x41, 0x4a, 0x0, 0x0, 0x0, 0x3d, 0x3d, 0x45, 0x3b, 0x3b, 0x43, 0x3a, 0x3a, 0x42, 0x38, 0x38, 0x41, 0x37, 0x37, 0x3e, 0x36, 0x36, 0x3d, 0x35, 0x35, 0x3c, 0x0, 0x0, 0x0, 0x38, 0x38, 0x40, 0x38, 0x38, 0x40, 0x31, 0x31, 0x38, 0x34, 0x34, 0x3b, 0x34, 0x34, 0x3b, 0x39, 0x39, 0x3f, 0x31, 0x31, 0x38, 0x2f, 0x2f, 0x36, 0x2d, 0x2d, 0x33, 0x2c, 0x2c, 0x32, 0x2b, 0x2b, 0x31, 0x2a, 0x2a, 0x31, 0x2a, 0x2a, 0x30, 0x29, 0x29, 0x30, 0x29, 0x29, 0x2f, 0x28, 0x28, 0x2e, 0x28, 0x28, 0x2d, 0x27, 0x27, 0x2d, 0x27, 0x27, 0x2c, 0x29, 0x29, 0x2e, 0x26, 0x26, 0x2c, 0x36, 0xc6, 0xc8, 0x93, 0x0, 0x0, 0x0, 0x28, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x1, 0x3, 0x5, 0x8, 0xa, 0xb, 0x4, 0x13, 0x19, 0x1f, 0x22, 0x23, 0x16, 0x27, 0x35, 0x3f, 0x45, 0x46, 0x94, 0xf5, 0xfa, 0xfb, 0xf5, 0x40, 0xfc, 0xfb, 0xfb, 0xfb, 0xfb, 0xfc, 0xfc, 0x1a, 0xf5, 0xf6, 0x95, 0xfa, 0xfb, 0xf4, 0x94, 0x71, 0xda, 0xac, 0x92, 0x0, 0x0, 0x0, 0x7f, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x65, 0x8f, 0x35, 0x82, 0xc3, 0x0, 0xc, 0x4, 0x77, 0x24, 0x85, 0xba, 0xe3, 0xff, 0xff, 0xee, 0xca, 0x74, 0x41, 0xdb, 0x32, 0xf3, 0x94, 0x82, 0x85, 0x10, 0x1d, 0x92, 0xb2, 0x3, 0x8e, 0x95, 0x77, 0x93, 0x6c, 0x28, 0xed, 0x15, 0x54, 0x67, 0xa6, 0x41, 0x3e, 0x8, 0x9c, 0xc3, 0xf4, 0xf2, 0xf6, 0x2a, 0x80, 0xf8, 0x44, 0x2d, 0x79, 0x2d, 0x20, 0xe0, 0x2, 0xa8, 0xc3, 0x2e, 0x6f, 0xc, 0x9e, 0x4c, 0x3c, 0x21, 0x4, 0xd8, 0xf0, 0x2, 0x28, 0x24, 0xcd, 0x3, 0xa9, 0x19, 0x64, 0xce, 0x83, 0x4c, 0x45, 0xe6, 0x69, 0x1a, 0xd8, 0xe9, 0x99, 0x96, 0x7f, 0x77, 0x37, 0x59, 0x83, 0xcc, 0xef, 0x7f, 0x89, 0x1f, 0x8e, 0xbf, 0x95, 0xd3, 0x1d, 0xf0, 0xff, 0x7a, 0x63, 0x7e, 0x86, 0xcb, 0x73, 0x8c, 0x5e, 0xee, 0xca, 0xb1, 0xad, 0x5f, 0x3, 0xaf, 0xdb, 0x49, 0x94, 0x4b, 0x90, 0x40, 0xdf, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char popup_bg_disabled_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x7b, 0x50, 0x4c, 0x54, 0x45, 0xff, 0x0, 0xff, 0x67, 0x7a, 0x85, 0x66, 0x7a, 0x86, 0x68, 0x7b, 0x86, 0x57, 0x51, 0x51, 0x4c, 0x42, 0x40, 0x4d, 0x43, 0x41, 0x56, 0x4c, 0x4b, 0x4d, 0x44, 0x41, 0x4e, 0x44, 0x42, 0x4f, 0x45, 0x43, 0x67, 0x7b, 0x87, 0x4f, 0x44, 0x43, 0x50, 0x45, 0x44, 0x52, 0x46, 0x44, 0x51, 0x46, 0x45, 0x4b, 0x40, 0x3f, 0x51, 0x47, 0x45, 0x52, 0x48, 0x46, 0x53, 0x48, 0x47, 0x4b, 0x41, 0x3f, 0x54, 0x49, 0x46, 0x55, 0x4a, 0x47, 0x55, 0x49, 0x47, 0x68, 0x7c, 0x88, 0x4a, 0x40, 0x3e, 0x55, 0x4b, 0x49, 0x56, 0x4d, 0x4b, 0x53, 0x49, 0x47, 0x50, 0x46, 0x44, 0x4a, 0x41, 0x3e, 0x48, 0x3e, 0x3c, 0x4b, 0x42, 0x3f, 0x49, 0x3f, 0x3d, 0x46, 0x3d, 0x3c, 0x47, 0x3d, 0x3b, 0x47, 0x3e, 0x3b, 0x49, 0x40, 0x3d, 0x45, 0x3c, 0x3b, 0x46, 0x3c, 0x3a, 0xff, 0xff, 0xff, 0x2e, 0x48, 0xbd, 0x3e, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x28, 0xbd, 0xb0, 0xb5, 0xb2, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0xb3, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x2d, 0x8f, 0xdb, 0x16, 0x82, 0x20, 0x10, 0x45, 0x11, 0x19, 0x12, 0x91, 0x54, 0x44, 0x93, 0xb2, 0x48, 0xa1, 0xfc, 0xff, 0x3f, 0xec, 0xa0, 0xed, 0xb7, 0xd9, 0x73, 0xd6, 0x5c, 0x18, 0x3, 0x5, 0x2f, 0x1, 0x2f, 0xd8, 0x49, 0xc1, 0x5, 0x49, 0x40, 0xe2, 0x54, 0xc5, 0x85, 0x2a, 0xa9, 0x80, 0xac, 0x48, 0x64, 0xc3, 0x89, 0x64, 0x7d, 0x20, 0x89, 0x34, 0x2, 0x82, 0x48, 0x35, 0xe6, 0x7a, 0x6d, 0x1b, 0x45, 0x39, 0xc2, 0x3b, 0x92, 0x4d, 0x6f, 0x87, 0xc1, 0xf6, 0x30, 0x4e, 0x33, 0xed, 0xb2, 0x18, 0xa7, 0xdb, 0x64, 0x8d, 0x24, 0x37, 0x33, 0xed, 0x9d, 0xac, 0xfb, 0xf1, 0xfe, 0x18, 0x97, 0xa7, 0x3a, 0xc4, 0xcb, 0x51, 0x16, 0xf7, 0xc9, 0x42, 0x78, 0x88, 0xf0, 0x76, 0xca, 0xb4, 0xcb, 0x62, 0xd, 0x2, 0x2b, 0xc4, 0x16, 0x7c, 0x5e, 0x63, 0x9e, 0x35, 0x75, 0x6b, 0xd4, 0x58, 0x9b, 0x3e, 0x98, 0x8b, 0xbb, 0xd0, 0x8f, 0xa2, 0x64, 0x88, 0xc4, 0xb0, 0x7a, 0xe7, 0x3a, 0x1f, 0x12, 0x2, 0xf9, 0xb2, 0x6f, 0x8c, 0x31, 0x84, 0x18, 0xd3, 0x26, 0xf8, 0xf1, 0x8c, 0x16, 0xfb, 0x9e, 0xd2, 0xbe, 0xb, 0x5d, 0xfe, 0xff, 0xe5, 0x7a, 0x6, 0x67, 0xf9, 0x3, 0x92, 0x36, 0xd, 0x2d, 0xc1, 0xf2, 0x6d, 0x3c, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x78, 0x50, 0x4c, 0x54, 0x45, 0xff, 0x0, 0xff, 0x67, 0x7a, 0x85, 0x66, 0x7a, 0x86, 0x68, 0x7b, 0x86, 0x57, 0x51, 0x51, 0x4c, 0x42, 0x40, 0x4d, 0x43, 0x41, 0x56, 0x4c, 0x4b, 0x4d, 0x44, 0x41, 0x4e, 0x44, 0x42, 0x4f, 0x45, 0x43, 0x67, 0x7b, 0x87, 0x4f, 0x44, 0x43, 0x50, 0x45, 0x44, 0x52, 0x46, 0x44, 0x51, 0x46, 0x45, 0x4b, 0x40, 0x3f, 0x51, 0x47, 0x45, 0x52, 0x48, 0x46, 0x53, 0x48, 0x47, 0x4b, 0x41, 0x3f, 0x54, 0x49, 0x46, 0x55, 0x4a, 0x47, 0x55, 0x49, 0x47, 0x68, 0x7c, 0x88, 0x4a, 0x40, 0x3e, 0x55, 0x4b, 0x49, 0x56, 0x4d, 0x4b, 0x53, 0x49, 0x47, 0x50, 0x46, 0x44, 0x4a, 0x41, 0x3e, 0x48, 0x3e, 0x3c, 0x4b, 0x42, 0x3f, 0x49, 0x3f, 0x3d, 0x46, 0x3d, 0x3c, 0x47, 0x3d, 0x3b, 0x47, 0x3e, 0x3b, 0x49, 0x40, 0x3d, 0x45, 0x3c, 0x3b, 0x46, 0x3c, 0x3a, 0xdd, 0x63, 0x56, 0x8d, 0x0, 0x0, 0x0, 0xad, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x2d, 0x88, 0x35, 0x42, 0x4, 0x0, 0xc, 0x4, 0x77, 0x93, 0x9c, 0xbb, 0xf4, 0xc8, 0xff, 0xdf, 0x84, 0xb5, 0xb8, 0x5b, 0x84, 0x0, 0x37, 0xc5, 0xca, 0x10, 0xd, 0xc9, 0xce, 0xaa, 0xea, 0x24, 0x40, 0xca, 0x41, 0x64, 0x2b, 0x5, 0x87, 0x34, 0xa8, 0x88, 0x54, 0xef, 0x82, 0x80, 0x89, 0x34, 0x36, 0x96, 0xe0, 0x14, 0xa4, 0x12, 0xa6, 0x24, 0x18, 0xe1, 0xa8, 0x50, 0x59, 0x7c, 0x73, 0x30, 0x50, 0x55, 0x4a, 0x31, 0xd7, 0xb4, 0x89, 0xa1, 0x51, 0xb2, 0x9c, 0x1, 0x2c, 0x4, 0x83, 0x15, 0x12, 0x30, 0xab, 0xe9, 0x5a, 0x1, 0xb4, 0x40, 0xa1, 0x29, 0xbe, 0x75, 0xe, 0x5a, 0x70, 0xbe, 0x2a, 0xff, 0x12, 0xf1, 0xef, 0x1b, 0x5f, 0x8d, 0x5b, 0x68, 0xd, 0xdc, 0xe3, 0xf1, 0x71, 0x16, 0x3e, 0x5b, 0xc8, 0x33, 0xa9, 0xc7, 0xbc, 0x7f, 0xa4, 0x22, 0x6a, 0xb5, 0x90, 0xcb, 0xb2, 0x1a, 0x25, 0x67, 0x8b, 0x8f, 0x6f, 0xf8, 0x64, 0xa8, 0x35, 0x7a, 0x25, 0xa8, 0xa7, 0x1, 0x38, 0xc, 0xcc, 0xab, 0x4c, 0x5, 0xea, 0xe3, 0x76, 0x2f, 0x54, 0x93, 0xf3, 0xf, 0x4f, 0x10, 0x8d, 0x4c, 0x16, 0x9d, 0xcf, 0x1f, 0xd1, 0xf9, 0x3, 0x34, 0xc8, 0x4a, 0xb4, 0x1d, 0xb, 0xcd, 0x83, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char popup_checked_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x8, 0x6, 0x0, 0x0, 0x0, 0xc4, 0xf, 0xbe, 0x8b, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0xa3, 0x49, 0x44, 0x41, 0x54, 0x18, 0x95, 0x85, 0xcd, 0xa1, 0xa, 0xc2, 0x50, 0x0, 0x85, 0xe1, 0xff, 0xdc, 0x5d, 0xd8, 0x14, 0x4, 0xab, 0x69, 0x37, 0xac, 0x98, 0xd5, 0x27, 0xb0, 0x89, 0x16, 0x8b, 0xd5, 0xf7, 0xd0, 0xec, 0x73, 0xf8, 0x4, 0x16, 0x61, 0x4d, 0x10, 0xc, 0x16, 0xa3, 0x61, 0x71, 0xab, 0x16, 0xeb, 0x84, 0x3b, 0xae, 0x45, 0x8b, 0xa, 0x9e, 0x78, 0xce, 0x7, 0x7, 0xfe, 0x44, 0xbf, 0xca, 0xa2, 0x28, 0x3a, 0x71, 0x1c, 0x1f, 0x24, 0x3d, 0xcc, 0xe7, 0x18, 0x42, 0x50, 0x92, 0x24, 0x5b, 0x49, 0x23, 0xa0, 0xfd, 0x5, 0xaa, 0xaa, 0x5a, 0x1, 0x73, 0xe0, 0x1e, 0x45, 0xd1, 0x42, 0x65, 0x59, 0x9e, 0x80, 0x96, 0xf7, 0x7e, 0x62, 0xad, 0x1d, 0x2, 0xfb, 0x97, 0x9d, 0x39, 0xe7, 0x72, 0x1b, 0x42, 0x88, 0x25, 0xd, 0xac, 0xb5, 0x47, 0xa0, 0x7, 0x18, 0x60, 0xed, 0x9c, 0xcb, 0x1, 0x4c, 0xd3, 0x34, 0x53, 0xe0, 0xa, 0xf4, 0x81, 0x2e, 0xb0, 0x4b, 0xd3, 0x74, 0xf3, 0xbe, 0x34, 0x59, 0x96, 0xdd, 0xbc, 0xf7, 0x63, 0xe0, 0x2, 0x9c, 0xeb, 0xba, 0x5e, 0x4a, 0xa, 0x6f, 0xf0, 0x4, 0x57, 0x3d, 0x2c, 0x27, 0x2b, 0xe9, 0x62, 0x6b, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x8, 0x4, 0x0, 0x0, 0x0, 0x6e, 0x6, 0x76, 0x0, 0x0, 0x0, 0x0, 0x56, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0xc0, 0x3, 0x6e, 0xf0, 0xde, 0x3f, 0xf5, 0xe0, 0x30, 0x9c, 0xfb, 0x9f, 0xf1, 0xc1, 0xda, 0x7, 0xff, 0x1f, 0x9c, 0x85, 0xb, 0x3c, 0xa8, 0x1, 0x72, 0xdf, 0x3d, 0x56, 0x61, 0x78, 0x70, 0xf8, 0xc1, 0x99, 0x3b, 0x62, 0xf, 0xbc, 0x1e, 0xfc, 0x5, 0x42, 0x2f, 0xa0, 0xcc, 0xfd, 0x53, 0x40, 0x99, 0x6b, 0xf, 0xde, 0x3, 0xc9, 0x6a, 0xb0, 0x52, 0xa0, 0xec, 0xe5, 0x7, 0xff, 0x81, 0x70, 0xed, 0x7f, 0x46, 0x20, 0x17, 0x2a, 0x74, 0xfa, 0xc1, 0xb1, 0x1b, 0xbc, 0x10, 0x1e, 0x0, 0xfd, 0x1f, 0x33, 0x9, 0xf7, 0x50, 0x16, 0x2f, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char popup_hover_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x30, 0x50, 0x4c, 0x54, 0x45, 0xff, 0x0, 0xff, 0x20, 0x2e, 0x31, 0x83, 0xae, 0xb7, 0xb3, 0xd8, 0xe1, 0xaf, 0xd5, 0xde, 0xac, 0xd2, 0xdb, 0xa9, 0xcf, 0xd8, 0xa5, 0xcc, 0xd5, 0xa2, 0xc9, 0xd2, 0x9e, 0xc6, 0xcf, 0x9b, 0xc3, 0xcc, 0x97, 0xc0, 0xc9, 0x94, 0xbd, 0xc6, 0x91, 0xba, 0xc3, 0x8d, 0xb7, 0xc0, 0xff, 0xff, 0xff, 0x73, 0xd4, 0x4e, 0xcb, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0xf, 0x18, 0xba, 0x0, 0xd9, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0x14, 0x4, 0x3, 0x1, 0x6, 0x21, 0x25, 0x30, 0x50, 0x64, 0x10, 0x32, 0x6, 0x3, 0x20, 0xc3, 0x5, 0xc, 0x80, 0x8c, 0x50, 0x30, 0x0, 0x32, 0xd2, 0xc0, 0x0, 0xc8, 0x28, 0x7, 0x3, 0x20, 0xa3, 0x3, 0xc, 0x80, 0x8c, 0x99, 0x60, 0x0, 0x64, 0xac, 0x2, 0x3, 0x20, 0x63, 0x37, 0x18, 0x0, 0x19, 0x67, 0xc0, 0x0, 0xc8, 0xb8, 0xb, 0x6, 0x40, 0xc6, 0x3b, 0x30, 0x50, 0x44, 0x58, 0xa, 0x73, 0x6, 0x0, 0xe9, 0xb4, 0x2d, 0xf5, 0x51, 0xd4, 0xb8, 0xa1, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x2d, 0x50, 0x4c, 0x54, 0x45, 0xff, 0x0, 0xff, 0x20, 0x2e, 0x31, 0x83, 0xae, 0xb7, 0xb3, 0xd8, 0xe1, 0xaf, 0xd5, 0xde, 0xac, 0xd2, 0xdb, 0xa9, 0xcf, 0xd8, 0xa5, 0xcc, 0xd5, 0xa2, 0xc9, 0xd2, 0x9e, 0xc6, 0xcf, 0x9b, 0xc3, 0xcc, 0x97, 0xc0, 0xc9, 0x94, 0xbd, 0xc6, 0x91, 0xba, 0xc3, 0x8d, 0xb7, 0xc0, 0x9c, 0x2c, 0x91, 0xa9, 0x0, 0x0, 0x0, 0x1f, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x62, 0x14, 0x4, 0x3, 0x1, 0x26, 0x41, 0x28, 0x60, 0x62, 0x80, 0xd0, 0xc, 0x74, 0x61, 0x98, 0x80, 0x1, 0x3, 0xd3, 0x7b, 0x28, 0x0, 0x0, 0x1a, 0x86, 0xe, 0x98, 0x2c, 0x61, 0xda, 0x2e, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char popup_unchecked_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x1, 0x3, 0x0, 0x0, 0x0, 0xfe, 0xc1, 0x2c, 0xc8, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x6, 0x50, 0x4c, 0x54, 0x45, 0xff, 0x0, 0xff, 0xff, 0xff, 0xff, 0x9f, 0x18, 0x32, 0xe0, 0x0, 0x0, 0x0, 0x1, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x40, 0xe6, 0xd8, 0x66, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x1, 0xff, 0x2, 0x2d, 0xde, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x4, 0x4e, 0x1d, 0x2, 0xaf, 0x0, 0x0, 0x0, 0xb, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0x40, 0x5, 0x0, 0x0, 0x10, 0x0, 0x1, 0xa1, 0xc5, 0x21, 0xc1, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x1, 0x3, 0x0, 0x0, 0x0, 0xfe, 0xc1, 0x2c, 0xc8, 0x0, 0x0, 0x0, 0x6, 0x50, 0x4c, 0x54, 0x45, 0xff, 0x0, 0xff, 0xff, 0xff, 0xff, 0x9f, 0x18, 0x32, 0xe0, 0x0, 0x0, 0x0, 0x1, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x40, 0xe6, 0xd8, 0x66, 0x0, 0x0, 0x0, 0xa, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x40, 0x3, 0x0, 0x0, 0x10, 0x0, 0x1, 0xb3, 0xac, 0xe2, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char popup_window_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x2a, 0x0, 0x0, 0x0, 0x46, 0x8, 0x3, 0x0, 0x0, 0x0, 0x8d, 0x2b, 0xf6, 0x48, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x1, 0x6e, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0xe8, 0xe5, 0xf1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f, 0x1d, 0x22, 0x0, 0x0, 0x0, 0x1a, 0x19, 0x1c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x1e, 0x23, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f, 0x1d, 0x21, 0x17, 0x16, 0x19, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x21, 0x1f, 0x24, 0x1b, 0x1a, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x21, 0x1f, 0x24, 0x1e, 0x1c, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x22, 0x20, 0x25, 0x20, 0x1e, 0x23, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x21, 0x1f, 0x24, 0x0, 0x0, 0x0, 0x21, 0x1f, 0x24, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x22, 0x20, 0x25, 0x0, 0x0, 0x0, 0x20, 0x20, 0x25, 0x20, 0x1d, 0x25, 0x20, 0x1d, 0x22, 0x1d, 0x1d, 0x22, 0x1d, 0x1d, 0x20, 0x1d, 0x1a, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x32, 0x30, 0x38, 0xe8, 0xe5, 0xf1, 0xe5, 0xe2, 0xeb, 0xe3, 0xe1, 0xe8, 0xe1, 0xdf, 0xe7, 0xe0, 0xde, 0xe6, 0xdf, 0xdd, 0xe5, 0xde, 0xdc, 0xe4, 0xdd, 0xdb, 0xe3, 0xdc, 0xda, 0xe2, 0xda, 0xd8, 0xe0, 0xd9, 0xd7, 0xdf, 0xd7, 0xd6, 0xdf, 0xd6, 0xd4, 0xdd, 0xd5, 0xd3, 0xdc, 0xd4, 0xd1, 0xdb, 0xd3, 0xd0, 0xda, 0xd1, 0xce, 0xd8, 0xd0, 0xcd, 0xd7, 0xcf, 0xcd, 0xd7, 0xe2, 0xdf, 0xeb, 0x48, 0x46, 0x51, 0x42, 0x40, 0x4b, 0x40, 0x3e, 0x48, 0x40, 0x3d, 0x48, 0x48, 0x45, 0x50, 0x42, 0x3f, 0x4a, 0x3f, 0x3d, 0x48, 0x47, 0x44, 0x50, 0x41, 0x3f, 0x4a, 0x3f, 0x3d, 0x47, 0x41, 0x3e, 0x49, 0x3f, 0x3c, 0x47, 0x46, 0x43, 0x4f, 0x3e, 0x3c, 0x46, 0x40, 0x3e, 0x49, 0x3d, 0x3b, 0x46, 0x45, 0x43, 0x4e, 0x3d, 0x3b, 0x45, 0x44, 0x42, 0x4d, 0x3d, 0x3a, 0x45, 0x3e, 0x3c, 0x47, 0x3c, 0x3a, 0x44, 0x43, 0x42, 0x4c, 0x43, 0x40, 0x4c, 0x3e, 0x3b, 0x46, 0x3b, 0x39, 0x43, 0x43, 0x3f, 0x4c, 0x43, 0x3f, 0x4b, 0x3a, 0x38, 0x42, 0x42, 0x3e, 0x4b, 0x42, 0x3e, 0x49, 0x3a, 0x37, 0x41, 0x39, 0x37, 0x41, 0x3f, 0x3e, 0x48, 0x39, 0x37, 0x40, 0x38, 0x36, 0x40, 0x3e, 0x3d, 0x48, 0x38, 0x36, 0x3f, 0x3e, 0x3d, 0x47, 0x3a, 0x38, 0x41, 0x38, 0x35, 0x3f, 0x37, 0x35, 0x3e, 0x39, 0x36, 0x40, 0x37, 0x34, 0x3e, 0x3d, 0x3a, 0x46, 0x36, 0x34, 0x3d, 0x3d, 0x3a, 0x44, 0x37, 0x35, 0x3f, 0x35, 0x33, 0x3c, 0x46, 0x44, 0x4f, 0xff, 0xff, 0xff, 0x7e, 0xde, 0x1d, 0x81, 0x0, 0x0, 0x0, 0x33, 0x74, 0x52, 0x4e, 0x53, 0x0, 0xa2, 0x3, 0x9, 0x17, 0xc, 0x20, 0xf, 0x2a, 0x5e, 0x12, 0x30, 0x68, 0x46, 0x20, 0x4e, 0xa2, 0x7d, 0x3a, 0x4f, 0xa4, 0x7d, 0x3f, 0x25, 0x60, 0xc0, 0xb8, 0x57, 0x1d, 0xba, 0x59, 0xbd, 0x5b, 0x22, 0xbf, 0x5e, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xa1, 0x9f, 0x9e, 0x52, 0x92, 0x15, 0x44, 0x7e, 0xd8, 0x5, 0xc7, 0xf4, 0xac, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x79, 0xa1, 0xdc, 0xd4, 0xd0, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x1, 0xe8, 0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0xd5, 0xd6, 0xd9, 0x53, 0xd3, 0x60, 0x14, 0xc6, 0xe1, 0x92, 0x5a, 0xa3, 0x44, 0xa3, 0xd6, 0x85, 0xa0, 0xb1, 0x5a, 0xcb, 0xda, 0xbd, 0x7c, 0xb8, 0xef, 0x2b, 0x69, 0x21, 0xd0, 0xda, 0x22, 0x25, 0xd, 0x69, 0x20, 0x60, 0x69, 0x11, 0x2a, 0x22, 0xcb, 0x9f, 0xef, 0x78, 0x97, 0x7e, 0xe7, 0x3d, 0x33, 0x1d, 0xbd, 0x70, 0xfc, 0x5d, 0x3f, 0x77, 0xe7, 0xe2, 0x3d, 0x91, 0xc8, 0x7f, 0xd8, 0x88, 0x60, 0x1a, 0x21, 0x54, 0xcc, 0x3f, 0x84, 0xcd, 0xb, 0x4a, 0x1f, 0x31, 0xfd, 0x1d, 0x7d, 0xcc, 0x4, 0xe8, 0x13, 0x26, 0x40, 0x9f, 0x32, 0x1, 0xfa, 0x8c, 0x9, 0xd0, 0xe7, 0x4c, 0x80, 0xbe, 0x60, 0x2, 0xf4, 0x25, 0x13, 0xa0, 0xaf, 0x98, 0x0, 0x7d, 0xcd, 0x44, 0xa8, 0x22, 0xde, 0x30, 0x49, 0x54, 0x89, 0x9e, 0x13, 0x6f, 0x99, 0x64, 0x1a, 0x3b, 0x2f, 0xde, 0x31, 0x49, 0x54, 0xbd, 0x70, 0x51, 0xbc, 0x67, 0x92, 0xe8, 0xa8, 0x76, 0x49, 0x7c, 0x60, 0x12, 0x97, 0xf5, 0x68, 0x88, 0xea, 0x57, 0xae, 0x8a, 0x8f, 0x4c, 0xe2, 0x5a, 0x7c, 0x34, 0x4c, 0xaf, 0xdf, 0x10, 0x9f, 0x98, 0xc4, 0xcd, 0x5b, 0x21, 0xaa, 0x8c, 0x19, 0xe3, 0xb, 0x56, 0x19, 0x66, 0x2d, 0xdc, 0xbe, 0x63, 0x2a, 0x43, 0xd2, 0xbb, 0x9, 0x7d, 0x58, 0x7a, 0xef, 0x7e, 0x72, 0x58, 0xfa, 0x20, 0x35, 0x36, 0x2c, 0x1d, 0x37, 0x8, 0xad, 0xc0, 0x0, 0x5d, 0x5c, 0xb2, 0x61, 0x4b, 0x8b, 0x32, 0x9d, 0x58, 0x5e, 0xa9, 0xc2, 0x56, 0x96, 0x27, 0x8, 0xad, 0x7d, 0x86, 0xd5, 0x28, 0xad, 0xd7, 0x1a, 0xb0, 0x5a, 0x9d, 0xd2, 0x55, 0x4c, 0x57, 0x1, 0xad, 0x7c, 0x81, 0x55, 0x8, 0x9d, 0x5c, 0xb3, 0x9b, 0x30, 0x7b, 0x6d, 0x52, 0xa2, 0x53, 0xeb, 0x55, 0x7, 0x56, 0x5d, 0x9f, 0x22, 0xb4, 0xe5, 0xc2, 0x5a, 0x94, 0x6e, 0x34, 0x30, 0x6d, 0x6c, 0x10, 0xea, 0xb5, 0x7d, 0x58, 0xdb, 0x93, 0xe9, 0xf4, 0x66, 0x13, 0xd3, 0xe6, 0xe6, 0xb4, 0x4c, 0xb7, 0x9c, 0x0, 0xe6, 0x6c, 0x11, 0xba, 0xed, 0x62, 0xea, 0x6e, 0x13, 0xba, 0xe3, 0x7e, 0x85, 0xb9, 0x3b, 0x84, 0x96, 0xfd, 0xe, 0xcc, 0x2f, 0x13, 0xba, 0xeb, 0x77, 0x61, 0xfe, 0x2e, 0xa1, 0x76, 0xd0, 0x83, 0x5, 0x36, 0xa1, 0x7b, 0xc1, 0x37, 0x58, 0xb0, 0x27, 0xd3, 0x99, 0xfd, 0x83, 0x3e, 0xec, 0x60, 0x7f, 0x46, 0xa2, 0xb3, 0xad, 0xce, 0x77, 0x58, 0xa7, 0x35, 0x2b, 0xd3, 0xf6, 0x21, 0xa6, 0x87, 0x6d, 0x40, 0x7f, 0xc0, 0x0, 0x3d, 0xea, 0xfd, 0x84, 0xf5, 0x8e, 0x8, 0x75, 0xfa, 0x98, 0xf6, 0x1d, 0x42, 0x8f, 0x39, 0x7a, 0x4c, 0xe9, 0xc9, 0x29, 0xec, 0x64, 0x90, 0x46, 0x92, 0xa9, 0xb4, 0x75, 0xca, 0x64, 0xa5, 0x53, 0xc9, 0xc8, 0x1f, 0xd2, 0xc, 0x4f, 0x33, 0x3, 0x54, 0x4f, 0x64, 0x79, 0x9a, 0x4d, 0xe8, 0x21, 0x6a, 0xe6, 0xf2, 0x1e, 0x47, 0xbd, 0x7c, 0xce, 0xc, 0xd1, 0x42, 0xb1, 0x54, 0xef, 0x62, 0xd9, 0x3d, 0x2b, 0x15, 0xb, 0x21, 0xaa, 0x6a, 0xc6, 0xdc, 0x99, 0x67, 0x81, 0xbc, 0xfa, 0x9c, 0xa1, 0xa9, 0x21, 0x1a, 0x35, 0xe3, 0x46, 0x29, 0x9f, 0xcd, 0xa4, 0xa5, 0x32, 0xd9, 0x7c, 0xc9, 0x88, 0x9b, 0xe1, 0xe1, 0x54, 0x62, 0xa6, 0x56, 0xcc, 0x25, 0x52, 0xa4, 0x44, 0xae, 0xa8, 0x99, 0xb1, 0xd0, 0x5, 0x7e, 0x3f, 0x4, 0x6a, 0xc1, 0xd4, 0x93, 0x24, 0xdd, 0x2c, 0xa8, 0xd1, 0x1, 0xf9, 0xf, 0xfb, 0x5, 0x66, 0x6f, 0x2a, 0x9a, 0xa8, 0x51, 0x81, 0xce, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x2a, 0x0, 0x0, 0x0, 0x46, 0x8, 0x3, 0x0, 0x0, 0x0, 0x8d, 0x2b, 0xf6, 0x48, 0x0, 0x0, 0x1, 0x6b, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0xe8, 0xe5, 0xf1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f, 0x1d, 0x22, 0x0, 0x0, 0x0, 0x1a, 0x19, 0x1c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x1e, 0x23, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f, 0x1d, 0x21, 0x17, 0x16, 0x19, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x21, 0x1f, 0x24, 0x1b, 0x1a, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x21, 0x1f, 0x24, 0x1e, 0x1c, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x22, 0x20, 0x25, 0x20, 0x1e, 0x23, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x21, 0x1f, 0x24, 0x0, 0x0, 0x0, 0x21, 0x1f, 0x24, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x22, 0x20, 0x25, 0x0, 0x0, 0x0, 0x20, 0x20, 0x25, 0x20, 0x1d, 0x25, 0x20, 0x1d, 0x22, 0x1d, 0x1d, 0x22, 0x1d, 0x1d, 0x20, 0x1d, 0x1a, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x32, 0x30, 0x38, 0xe8, 0xe5, 0xf1, 0xe5, 0xe2, 0xeb, 0xe3, 0xe1, 0xe8, 0xe1, 0xdf, 0xe7, 0xe0, 0xde, 0xe6, 0xdf, 0xdd, 0xe5, 0xde, 0xdc, 0xe4, 0xdd, 0xdb, 0xe3, 0xdc, 0xda, 0xe2, 0xda, 0xd8, 0xe0, 0xd9, 0xd7, 0xdf, 0xd7, 0xd6, 0xdf, 0xd6, 0xd4, 0xdd, 0xd5, 0xd3, 0xdc, 0xd4, 0xd1, 0xdb, 0xd3, 0xd0, 0xda, 0xd1, 0xce, 0xd8, 0xd0, 0xcd, 0xd7, 0xcf, 0xcd, 0xd7, 0xe2, 0xdf, 0xeb, 0x48, 0x46, 0x51, 0x42, 0x40, 0x4b, 0x40, 0x3e, 0x48, 0x40, 0x3d, 0x48, 0x48, 0x45, 0x50, 0x42, 0x3f, 0x4a, 0x3f, 0x3d, 0x48, 0x47, 0x44, 0x50, 0x41, 0x3f, 0x4a, 0x3f, 0x3d, 0x47, 0x41, 0x3e, 0x49, 0x3f, 0x3c, 0x47, 0x46, 0x43, 0x4f, 0x3e, 0x3c, 0x46, 0x40, 0x3e, 0x49, 0x3d, 0x3b, 0x46, 0x45, 0x43, 0x4e, 0x3d, 0x3b, 0x45, 0x44, 0x42, 0x4d, 0x3d, 0x3a, 0x45, 0x3e, 0x3c, 0x47, 0x3c, 0x3a, 0x44, 0x43, 0x42, 0x4c, 0x43, 0x40, 0x4c, 0x3e, 0x3b, 0x46, 0x3b, 0x39, 0x43, 0x43, 0x3f, 0x4c, 0x43, 0x3f, 0x4b, 0x3a, 0x38, 0x42, 0x42, 0x3e, 0x4b, 0x42, 0x3e, 0x49, 0x3a, 0x37, 0x41, 0x39, 0x37, 0x41, 0x3f, 0x3e, 0x48, 0x39, 0x37, 0x40, 0x38, 0x36, 0x40, 0x3e, 0x3d, 0x48, 0x38, 0x36, 0x3f, 0x3e, 0x3d, 0x47, 0x3a, 0x38, 0x41, 0x38, 0x35, 0x3f, 0x37, 0x35, 0x3e, 0x39, 0x36, 0x40, 0x37, 0x34, 0x3e, 0x3d, 0x3a, 0x46, 0x36, 0x34, 0x3d, 0x3d, 0x3a, 0x44, 0x37, 0x35, 0x3f, 0x35, 0x33, 0x3c, 0x46, 0x44, 0x4f, 0xac, 0xa5, 0x1, 0x25, 0x0, 0x0, 0x0, 0x33, 0x74, 0x52, 0x4e, 0x53, 0x0, 0xa2, 0x3, 0x9, 0x17, 0xc, 0x20, 0xf, 0x2a, 0x5e, 0x12, 0x30, 0x68, 0x46, 0x20, 0x4e, 0xa2, 0x7d, 0x3a, 0x4f, 0xa4, 0x7d, 0x3f, 0x25, 0x60, 0xc0, 0xb8, 0x57, 0x1d, 0xba, 0x59, 0xbd, 0x5b, 0x22, 0xbf, 0x5e, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xa1, 0x9f, 0x9e, 0x52, 0x92, 0x15, 0x44, 0x7e, 0xd8, 0x5, 0xc7, 0xf4, 0xac, 0x0, 0x0, 0x1, 0x98, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0xed, 0xd6, 0x55, 0x9e, 0x14, 0x31, 0x10, 0x80, 0xf1, 0xb2, 0x20, 0x1d, 0xdc, 0x9d, 0x3b, 0x2c, 0xa7, 0x87, 0x4b, 0xe0, 0xee, 0xd0, 0x82, 0xcb, 0xea, 0xb4, 0x86, 0x79, 0x23, 0x93, 0xaa, 0xcc, 0xf, 0xd7, 0xfd, 0x9e, 0xff, 0xed, 0x1d, 0x21, 0xf8, 0xe2, 0xfe, 0x1c, 0x8a, 0x17, 0x32, 0xa1, 0xa2, 0x2b, 0x48, 0x66, 0xb8, 0xa2, 0x28, 0x10, 0x9a, 0xd1, 0xf7, 0x3d, 0x16, 0x66, 0xfa, 0x45, 0x74, 0x9b, 0xd2, 0x97, 0x52, 0xe2, 0x2f, 0xa6, 0x40, 0x5f, 0x4c, 0x1d, 0xf3, 0x97, 0x52, 0x5e, 0x46, 0xf7, 0xee, 0xe3, 0x88, 0x8a, 0x48, 0x9e, 0x8a, 0xec, 0x8c, 0x28, 0x2c, 0xa7, 0xf0, 0x99, 0xd2, 0x6e, 0xe7, 0x8e, 0x10, 0x9b, 0xd1, 0x11, 0xe7, 0xe, 0xd1, 0x17, 0x8e, 0x2, 0xe6, 0x55, 0xf8, 0x42, 0x4a, 0x74, 0x18, 0xbe, 0xf8, 0xac, 0x9b, 0x5f, 0x4a, 0xb7, 0x36, 0x20, 0xa5, 0xf9, 0x2f, 0x90, 0x50, 0x11, 0x36, 0x13, 0x49, 0xa9, 0xe7, 0x6c, 0x5e, 0xcf, 0x2e, 0x99, 0xf4, 0xd, 0xb8, 0x8c, 0x5, 0xa7, 0x28, 0x8, 0x98, 0x9, 0x68, 0xba, 0x41, 0x66, 0x1b, 0x8a, 0xa2, 0xb0, 0x4d, 0x59, 0x30, 0xa5, 0x94, 0xa3, 0x94, 0x52, 0x0, 0x6f, 0x53, 0x6f, 0x7c, 0x82, 0x16, 0xcc, 0x5a, 0x51, 0x14, 0xbd, 0x98, 0x79, 0x4c, 0x29, 0x72, 0xee, 0xac, 0x8c, 0xea, 0xac, 0xb9, 0x51, 0xa0, 0xce, 0xa, 0x44, 0x60, 0x46, 0xa4, 0x28, 0x2, 0x9b, 0x1, 0x2a, 0x5a, 0xa, 0x9a, 0x49, 0xa9, 0xe8, 0x79, 0x20, 0x33, 0x38, 0xaf, 0x68, 0xc5, 0x68, 0xc6, 0x95, 0xa2, 0xe7, 0x72, 0x67, 0x3d, 0x97, 0x52, 0x24, 0xcf, 0x66, 0x9e, 0x30, 0xa5, 0xef, 0x5a, 0x34, 0x6b, 0xdf, 0xa5, 0x14, 0xa4, 0x0, 0xb3, 0x42, 0x8c, 0xe5, 0x38, 0x37, 0xb4, 0x14, 0x3d, 0xd2, 0xda, 0xb4, 0x3d, 0xa2, 0x68, 0xe3, 0xc0, 0xcc, 0x35, 0x8a, 0x9e, 0x86, 0x4c, 0xa7, 0x15, 0x85, 0x9d, 0x6c, 0xb6, 0x13, 0x16, 0xe8, 0x54, 0x78, 0xbc, 0x8e, 0x60, 0x86, 0xd7, 0xd1, 0x17, 0xd3, 0x37, 0x6e, 0x48, 0x30, 0x4f, 0x70, 0x81, 0xbe, 0xed, 0x97, 0xd1, 0xfe, 0x6d, 0x44, 0xf7, 0xed, 0xa7, 0x63, 0x39, 0x79, 0x8c, 0xf6, 0xef, 0x8b, 0xe8, 0x61, 0xe6, 0x8d, 0x55, 0x5b, 0xae, 0x9e, 0x62, 0x3e, 0x1c, 0xd1, 0x3b, 0xf7, 0x9b, 0xc7, 0xfb, 0x9b, 0xab, 0x46, 0xcd, 0xab, 0x4b, 0xcd, 0xfd, 0x3b, 0x11, 0x1d, 0xe, 0x76, 0xf5, 0xc5, 0x2b, 0xe5, 0xf3, 0x67, 0x49, 0xcf, 0xcb, 0x2b, 0x8f, 0xea, 0xee, 0xe0, 0x10, 0xd1, 0xf0, 0xb2, 0x58, 0xb, 0x61, 0x75, 0xd6, 0x26, 0xcd, 0x56, 0x43, 0x58, 0x2b, 0x5e, 0x86, 0x88, 0x4e, 0x63, 0x33, 0x84, 0xf7, 0x1f, 0x26, 0xd5, 0x87, 0xf7, 0x61, 0x68, 0xc6, 0x29, 0xa2, 0x73, 0xdb, 0x5e, 0x2d, 0x57, 0x1f, 0xab, 0x56, 0xcb, 0xab, 0xed, 0x5c, 0xfe, 0xc4, 0x5d, 0xf1, 0x27, 0x1a, 0x8f, 0xba, 0x8d, 0xd7, 0xa0, 0x9a, 0x40, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char progress_bar_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x33, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2d, 0x2c, 0x2f, 0x48, 0x46, 0x4a, 0x4c, 0x4a, 0x4e, 0x48, 0x46, 0x4a, 0x40, 0x3e, 0x42, 0x38, 0x36, 0x3a, 0x27, 0x27, 0x27, 0xe1, 0x1d, 0x66, 0x4d, 0x0, 0x0, 0x0, 0xc, 0x74, 0x52, 0x4e, 0x53, 0xa, 0x1a, 0x26, 0x29, 0x2a, 0x48, 0x65, 0x6d, 0x6e, 0x66, 0xf5, 0xfe, 0xb7, 0x4a, 0xbe, 0x33, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x10, 0x95, 0xb2, 0xd, 0x2c, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x44, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0xc5, 0xcf, 0x31, 0x16, 0x0, 0x10, 0xc, 0x44, 0xc1, 0x4d, 0x84, 0x4, 0xc1, 0xfd, 0x6f, 0xab, 0xc9, 0x53, 0x70, 0x0, 0x53, 0x6e, 0xb5, 0x1f, 0x20, 0x4e, 0x12, 0x12, 0x13, 0x40, 0xb9, 0xa8, 0x5, 0x2d, 0x99, 0xc0, 0xb5, 0x75, 0xf, 0xbd, 0x55, 0x86, 0xe8, 0x98, 0x2b, 0xcc, 0xa1, 0x2, 0x31, 0x5f, 0x87, 0xdb, 0xbf, 0xe1, 0x3e, 0xf6, 0x5c, 0x7f, 0xe2, 0xee, 0xfc, 0xd, 0x60, 0x3b, 0xa, 0x1d, 0x9e, 0x6a, 0x29, 0x33, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x30, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2d, 0x2c, 0x2f, 0x48, 0x46, 0x4a, 0x4c, 0x4a, 0x4e, 0x48, 0x46, 0x4a, 0x40, 0x3e, 0x42, 0x38, 0x36, 0x3a, 0x43, 0x65, 0x7d, 0x95, 0x0, 0x0, 0x0, 0xc, 0x74, 0x52, 0x4e, 0x53, 0xa, 0x1a, 0x26, 0x29, 0x2a, 0x48, 0x65, 0x6d, 0x6e, 0x66, 0xf5, 0xfe, 0xb7, 0x4a, 0xbe, 0x33, 0x0, 0x0, 0x0, 0x35, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x64, 0x54, 0x52, 0x64, 0x60, 0x60, 0x78, 0x77, 0x8f, 0x51, 0x34, 0x8, 0xcc, 0xb8, 0xcd, 0xa8, 0xd9, 0x4, 0x66, 0xdc, 0x60, 0x74, 0x9f, 0xe, 0x66, 0xb4, 0x33, 0x7a, 0xb4, 0x1b, 0x0, 0x19, 0x7f, 0x3b, 0x28, 0x64, 0xc0, 0xd, 0x84, 0x5b, 0x1, 0xb7, 0x14, 0xee, 0xc, 0x0, 0xcf, 0x9d, 0x26, 0xff, 0xba, 0xcb, 0x90, 0x39, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char progress_fill_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x2, 0x62, 0x4b, 0x47, 0x44, 0x0, 0x26, 0x78, 0x80, 0xa6, 0xcf, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x4, 0x4e, 0x1d, 0x2, 0xaf, 0x0, 0x0, 0x0, 0x60, 0x49, 0x44, 0x41, 0x54, 0x28, 0xcf, 0x63, 0x60, 0x18, 0x78, 0xc0, 0x8, 0x63, 0x38, 0x58, 0x7c, 0xde, 0xf8, 0x45, 0xc, 0xc2, 0xe6, 0x79, 0xc5, 0xeb, 0x7f, 0xe0, 0x4, 0x9a, 0x2, 0xe3, 0x97, 0x1f, 0xb9, 0xff, 0x70, 0x43, 0xd8, 0x2c, 0x5f, 0xf9, 0xbf, 0x9e, 0x15, 0x87, 0xb2, 0x61, 0xa, 0xbe, 0x88, 0xfd, 0x81, 0x1b, 0xfb, 0x87, 0xfb, 0xb, 0x37, 0x8c, 0xcd, 0x44, 0xc8, 0xd, 0x54, 0x54, 0xc0, 0xf3, 0x8a, 0xe5, 0x2b, 0x8c, 0xcd, 0xf2, 0x95, 0xe7, 0x15, 0x86, 0x2, 0x5e, 0x7f, 0xfe, 0xaf, 0xec, 0xc, 0x10, 0xc8, 0xff, 0x95, 0xd7, 0x9f, 0xe6, 0x1, 0x4c, 0x2, 0x0, 0x0, 0x68, 0x3f, 0x16, 0xd7, 0xea, 0x7c, 0xdd, 0x1a, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x37, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x18, 0x4c, 0xc0, 0xc1, 0xc2, 0xf8, 0xa5, 0xfa, 0x7f, 0x8, 0x34, 0x7e, 0xe9, 0x60, 0x81, 0xa1, 0xc0, 0xf8, 0xa5, 0xca, 0x17, 0x85, 0xff, 0x10, 0xa8, 0xf2, 0xc5, 0xf8, 0x25, 0x86, 0x2, 0x75, 0xa0, 0x4, 0x1c, 0x2, 0x4d, 0xa1, 0xbf, 0x2, 0x4c, 0x47, 0x12, 0xf6, 0xe6, 0x20, 0x2, 0x0, 0x78, 0x21, 0x45, 0x61, 0x7f, 0xe2, 0xad, 0xaf, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char radio_checked_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x45, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x4, 0x3, 0x4, 0x9, 0x9, 0x9, 0x6, 0x6, 0x6, 0xa, 0xa, 0xb, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x7f, 0x7f, 0x82, 0xd8, 0xd8, 0xd8, 0xd9, 0xd9, 0xd9, 0x47, 0x47, 0x48, 0xd3, 0xd3, 0xd3, 0xa2, 0xa2, 0xa2, 0x79, 0x79, 0x79, 0x73, 0x73, 0x73, 0x1c, 0x1c, 0x1c, 0x3, 0x3, 0x3, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xa, 0x69, 0x4, 0xd4, 0x0, 0x0, 0x0, 0xb, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b, 0x88, 0xd1, 0xf7, 0x64, 0xf6, 0x2, 0xb3, 0xed, 0xd7, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x16, 0x7c, 0xd1, 0xa8, 0x19, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x69, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x6d, 0x8f, 0xdb, 0xe, 0xc0, 0x20, 0x8, 0x43, 0xdd, 0xc5, 0x3b, 0x9d, 0xa8, 0xec, 0xff, 0x7f, 0x75, 0x6a, 0x96, 0x2c, 0x8b, 0xf6, 0xad, 0x27, 0x14, 0x8a, 0x52, 0x2b, 0x69, 0x63, 0x9d, 0xb3, 0x46, 0xbf, 0x76, 0xf3, 0x21, 0x12, 0x40, 0x31, 0xf8, 0x7d, 0x0, 0x7f, 0x35, 0xdb, 0x45, 0x97, 0x1f, 0xf3, 0x81, 0x90, 0x38, 0x67, 0x4e, 0xa0, 0xd0, 0x53, 0x26, 0x22, 0x95, 0x2a, 0x52, 0x4b, 0x42, 0x34, 0xd, 0x58, 0x2, 0xd7, 0xbb, 0xa9, 0x32, 0xc8, 0x36, 0xe0, 0x80, 0x2c, 0x1d, 0x48, 0x6, 0xdc, 0xa, 0x4c, 0x91, 0x69, 0xe9, 0x74, 0x76, 0x2a, 0xa6, 0x8e, 0xaf, 0xfa, 0xb9, 0x7e, 0xee, 0xaf, 0x7, 0xb9, 0xfb, 0x8, 0xe7, 0x90, 0x1c, 0x65, 0x49, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x42, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x4, 0x3, 0x4, 0x9, 0x9, 0x9, 0x6, 0x6, 0x6, 0xa, 0xa, 0xb, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x7f, 0x7f, 0x82, 0xd8, 0xd8, 0xd8, 0xd9, 0xd9, 0xd9, 0x47, 0x47, 0x48, 0xd3, 0xd3, 0xd3, 0xa2, 0xa2, 0xa2, 0x79, 0x79, 0x79, 0x73, 0x73, 0x73, 0x1c, 0x1c, 0x1c, 0x3, 0x3, 0x3, 0x0, 0x0, 0x0, 0xd1, 0xa7, 0xf5, 0xaa, 0x0, 0x0, 0x0, 0xb, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b, 0x88, 0xd1, 0xf7, 0x64, 0xf6, 0x2, 0xb3, 0xed, 0xd7, 0x0, 0x0, 0x0, 0x63, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x6d, 0x4f, 0x55, 0x2, 0x43, 0x31, 0x8, 0x4b, 0xe8, 0x6a, 0xf7, 0xbf, 0xeb, 0xc, 0x9b, 0x6b, 0x1f, 0x9f, 0xc4, 0x89, 0xbf, 0xbb, 0x3f, 0x2a, 0x49, 0x64, 0xa6, 0x3e, 0x1e, 0x1c, 0x7c, 0x3e, 0xf2, 0x14, 0xb7, 0xc7, 0xac, 0xf1, 0x10, 0xa6, 0xe8, 0x1, 0x44, 0xad, 0x42, 0xb9, 0x33, 0x22, 0x43, 0x95, 0x68, 0x55, 0xa4, 0xdc, 0x1f, 0x1e, 0xa1, 0x67, 0xa2, 0x57, 0x96, 0x22, 0x0, 0xc2, 0x3d, 0xf5, 0x44, 0x8c, 0x8a, 0x5d, 0x21, 0x80, 0x74, 0x83, 0x1e, 0x97, 0xc7, 0x22, 0x59, 0x4c, 0xd7, 0xd8, 0xb5, 0x18, 0x4a, 0x7b, 0x57, 0x57, 0xdb, 0x1a, 0xf7, 0x77, 0x17, 0x3a, 0x56, 0x4e, 0x11, 0x6f, 0x82, 0x20, 0xde, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char radio_unchecked_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x2d, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x4, 0x3, 0x4, 0x9, 0x9, 0x9, 0x6, 0x6, 0x6, 0xa, 0xa, 0xb, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x7f, 0x7f, 0x82, 0xd9, 0xd9, 0xd9, 0x47, 0x47, 0x48, 0xff, 0xff, 0xff, 0xbd, 0x7d, 0x89, 0x66, 0x0, 0x0, 0x0, 0xb, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b, 0x88, 0xd1, 0xf7, 0x64, 0xf6, 0x2, 0xb3, 0xed, 0xd7, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0xe, 0x6f, 0xbd, 0x30, 0x4f, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x4a, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0x40, 0x80, 0xb0, 0x8a, 0xf6, 0x54, 0x10, 0x2d, 0xb9, 0xfa, 0xcc, 0x99, 0x5d, 0x93, 0x80, 0x8c, 0xb9, 0x67, 0x80, 0xe0, 0x26, 0x3, 0x3, 0xeb, 0x1a, 0x10, 0xe3, 0x54, 0x0, 0x3, 0xdb, 0x1e, 0x10, 0xe3, 0x74, 0x2, 0x3, 0xfb, 0x19, 0x30, 0x28, 0x60, 0xe0, 0x80, 0x30, 0x1a, 0x10, 0xc, 0xb8, 0x14, 0x5c, 0x31, 0x5c, 0x3b, 0xdc, 0x40, 0x6, 0x4b, 0x90, 0x15, 0x53, 0x90, 0x2d, 0x85, 0x2, 0x0, 0x37, 0xca, 0x3d, 0x81, 0xc4, 0xfc, 0x38, 0x7b, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x2a, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x4, 0x3, 0x4, 0x9, 0x9, 0x9, 0x6, 0x6, 0x6, 0xa, 0xa, 0xb, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x7f, 0x7f, 0x82, 0xd9, 0xd9, 0xd9, 0x47, 0x47, 0x48, 0x2b, 0x6e, 0xf2, 0xbf, 0x0, 0x0, 0x0, 0xb, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b, 0x88, 0xd1, 0xf7, 0x64, 0xf6, 0x2, 0xb3, 0xed, 0xd7, 0x0, 0x0, 0x0, 0x49, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x40, 0x2, 0x61, 0x15, 0xed, 0xa9, 0x20, 0x5a, 0x72, 0xf5, 0x99, 0x33, 0xbb, 0x26, 0x1, 0x19, 0x73, 0xcf, 0x0, 0xc1, 0x4d, 0x6, 0x6, 0xd6, 0x35, 0x20, 0xc6, 0xa9, 0x0, 0x6, 0xb6, 0x3d, 0x20, 0xc6, 0xe9, 0x4, 0x6, 0xf6, 0x33, 0x60, 0x50, 0xc0, 0xc0, 0x1, 0x61, 0x34, 0xc0, 0x19, 0x70, 0x29, 0xb8, 0x62, 0xb8, 0x76, 0x84, 0x81, 0xc, 0x96, 0x20, 0x2b, 0xa6, 0xc0, 0x2d, 0x45, 0x0, 0x0, 0x37, 0xca, 0x3d, 0x81, 0xb4, 0x84, 0xb6, 0x80, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char reference_border_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0xf, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0xff, 0xd1, 0xd1, 0xff, 0xb7, 0xb7, 0xff, 0x41, 0x41, 0xff, 0xff, 0xff, 0xd5, 0xfa, 0x24, 0x40, 0x0, 0x0, 0x0, 0x2, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x0, 0x76, 0x93, 0xcd, 0x38, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x4, 0x8f, 0x68, 0xd9, 0x51, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x27, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x50, 0x32, 0x6, 0x3, 0x25, 0x6, 0x5, 0x6, 0x30, 0x60, 0x62, 0x30, 0x10, 0x4, 0x3, 0x66, 0x6, 0x3, 0x1, 0x90, 0x0, 0x23, 0x2d, 0x18, 0x30, 0x2b, 0xe0, 0x96, 0xc2, 0x9c, 0x1, 0x0, 0x5, 0x29, 0x7, 0xb, 0xf6, 0x43, 0xc2, 0xd4, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x2, 0x3, 0x0, 0x0, 0x0, 0x62, 0x9d, 0x17, 0xf2, 0x0, 0x0, 0x0, 0xc, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0xff, 0xd1, 0xd1, 0xff, 0xb7, 0xb7, 0xff, 0x41, 0x41, 0x2b, 0x2, 0x77, 0xea, 0x0, 0x0, 0x0, 0x2, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x0, 0x76, 0x93, 0xcd, 0x38, 0x0, 0x0, 0x0, 0x25, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x58, 0xff, 0xff, 0xff, 0x2f, 0x86, 0x6, 0x6, 0x6, 0x26, 0x86, 0xa3, 0xa1, 0xa1, 0xc1, 0xc, 0x47, 0x18, 0x18, 0x84, 0x49, 0x22, 0xc0, 0xda, 0xc0, 0x6, 0x80, 0x8d, 0x2, 0x0, 0x36, 0x2b, 0x14, 0x3d, 0x85, 0x39, 0x85, 0x31, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char scroll_bg_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x3, 0x0, 0x0, 0x0, 0x61, 0xab, 0xac, 0xd5, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x48, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x40, 0x3e, 0x4a, 0x2a, 0x29, 0x2f, 0x20, 0x20, 0x24, 0x3f, 0x3e, 0x49, 0x1f, 0x1f, 0x24, 0x20, 0x20, 0x24, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x3f, 0x3e, 0x49, 0x3f, 0x3e, 0x49, 0x1e, 0x1e, 0x23, 0x20, 0x20, 0x25, 0x22, 0x22, 0x27, 0x23, 0x23, 0x27, 0x23, 0x23, 0x28, 0x25, 0x25, 0x2a, 0xff, 0xff, 0xff, 0x34, 0x3f, 0xa6, 0x65, 0x0, 0x0, 0x0, 0x11, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x4, 0x19, 0x40, 0x5d, 0x66, 0x28, 0x93, 0xf0, 0xfc, 0x94, 0xfc, 0xfd, 0x67, 0x1a, 0x96, 0x95, 0x1c, 0xf0, 0x43, 0x52, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x17, 0xb, 0xd6, 0x98, 0x8f, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x5c, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x55, 0x8e, 0x49, 0xe, 0xc0, 0x20, 0xc, 0x3, 0x3, 0x61, 0x9, 0x3b, 0x61, 0xfb, 0xff, 0x53, 0x4b, 0x5b, 0x55, 0x15, 0x73, 0x1b, 0xc9, 0xb2, 0xd, 0x20, 0x24, 0x2a, 0xad, 0x15, 0x4a, 0x1, 0x20, 0x8c, 0x25, 0xc7, 0xec, 0xc8, 0x1a, 0x1, 0xd2, 0x87, 0xd6, 0xc7, 0xe8, 0x2d, 0x78, 0x9, 0x48, 0x6d, 0xae, 0xcd, 0x6c, 0x84, 0xa0, 0x62, 0x5f, 0xf, 0x3d, 0x2a, 0x48, 0x3c, 0x5e, 0x19, 0x9c, 0x4e, 0x39, 0x62, 0x47, 0x41, 0x2e, 0x5f, 0x75, 0xc9, 0x7b, 0xb4, 0x52, 0x64, 0x8e, 0x54, 0xcd, 0x7d, 0xe1, 0xbf, 0x73, 0x1, 0x30, 0x2f, 0x7, 0x53, 0x16, 0x34, 0xbd, 0xfa, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x3, 0x0, 0x0, 0x0, 0x61, 0xab, 0xac, 0xd5, 0x0, 0x0, 0x0, 0x45, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x40, 0x3e, 0x4a, 0x2a, 0x29, 0x2f, 0x20, 0x20, 0x24, 0x3f, 0x3e, 0x49, 0x1f, 0x1f, 0x24, 0x20, 0x20, 0x24, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x3f, 0x3e, 0x49, 0x3f, 0x3e, 0x49, 0x1e, 0x1e, 0x23, 0x20, 0x20, 0x25, 0x22, 0x22, 0x27, 0x23, 0x23, 0x27, 0x23, 0x23, 0x28, 0x25, 0x25, 0x2a, 0x14, 0xee, 0x69, 0x20, 0x0, 0x0, 0x0, 0x11, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x4, 0x19, 0x40, 0x5d, 0x66, 0x28, 0x93, 0xf0, 0xfc, 0x94, 0xfc, 0xfd, 0x67, 0x1a, 0x96, 0x95, 0x1c, 0xf0, 0x43, 0x52, 0x0, 0x0, 0x0, 0x55, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x55, 0x8e, 0x45, 0x2, 0x80, 0x50, 0x10, 0x42, 0xc1, 0xee, 0xfb, 0x5f, 0xd4, 0xd6, 0xdf, 0xfd, 0x36, 0xd3, 0x3, 0x4, 0xd, 0x90, 0x6, 0xb2, 0x25, 0x39, 0xe0, 0xd2, 0xf9, 0xcb, 0x6a, 0x60, 0x6f, 0x27, 0xb7, 0xbc, 0x58, 0xb7, 0x53, 0x4d, 0x0, 0xf2, 0x3f, 0x5e, 0x36, 0x43, 0x5f, 0xc3, 0xf0, 0xdf, 0x17, 0xd7, 0xa6, 0xae, 0x60, 0x10, 0xff, 0x57, 0x16, 0xc5, 0x5a, 0xf1, 0x60, 0xe3, 0xe7, 0x5f, 0x37, 0x46, 0x74, 0xba, 0x9a, 0x16, 0xef, 0x37, 0x1c, 0x6f, 0x61, 0x47, 0x1, 0xa5, 0xc7, 0x32, 0x47, 0x38, 0x12, 0x92, 0xb1, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char scroll_button_down_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x21, 0x50, 0x4c, 0x54, 0x45, 0x2d, 0x2c, 0x2f, 0x48, 0x46, 0x4a, 0x2d, 0x2c, 0x2f, 0x2d, 0x2c, 0x2f, 0x2d, 0x2c, 0x2f, 0x4c, 0x4a, 0x4e, 0x48, 0x46, 0x4a, 0x40, 0x3e, 0x42, 0x38, 0x36, 0x3a, 0xc3, 0xc3, 0xc3, 0x59, 0x59, 0x59, 0xb3, 0x52, 0xf2, 0x5, 0x0, 0x0, 0x0, 0x5, 0x74, 0x52, 0x4e, 0x53, 0x8, 0xfe, 0x9, 0xd, 0x19, 0x4a, 0xb6, 0xc1, 0xe6, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0xa, 0x68, 0xd0, 0xf4, 0x56, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x4, 0x4e, 0x1d, 0x2, 0xaf, 0x0, 0x0, 0x0, 0x33, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0xc, 0x5, 0x3, 0x21, 0x86, 0xf4, 0xe, 0x30, 0x28, 0x63, 0x88, 0x80, 0x30, 0x5a, 0xf1, 0x33, 0x66, 0x2, 0x1, 0x2a, 0xa3, 0x73, 0xe6, 0xcc, 0x19, 0x10, 0x35, 0x40, 0x1, 0x8, 0xa3, 0x73, 0x6, 0x1, 0x73, 0xe0, 0x96, 0x1a, 0x42, 0x9c, 0x21, 0x2, 0x0, 0x5a, 0xfa, 0x3d, 0xf9, 0xfa, 0xe2, 0x64, 0xe2, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x21, 0x50, 0x4c, 0x54, 0x45, 0x2d, 0x2c, 0x2f, 0x48, 0x46, 0x4a, 0x2d, 0x2c, 0x2f, 0x2d, 0x2c, 0x2f, 0x2d, 0x2c, 0x2f, 0x4c, 0x4a, 0x4e, 0x48, 0x46, 0x4a, 0x40, 0x3e, 0x42, 0x38, 0x36, 0x3a, 0xc3, 0xc3, 0xc3, 0x59, 0x59, 0x59, 0xb3, 0x52, 0xf2, 0x5, 0x0, 0x0, 0x0, 0x5, 0x74, 0x52, 0x4e, 0x53, 0x8, 0xfe, 0x9, 0xd, 0x19, 0x4a, 0xb6, 0xc1, 0xe6, 0x0, 0x0, 0x0, 0x33, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0xc, 0x5, 0x3, 0x21, 0x86, 0xf4, 0xe, 0x30, 0x28, 0x63, 0x88, 0x80, 0x30, 0x5a, 0xf1, 0x33, 0x66, 0x2, 0x1, 0x2a, 0xa3, 0x73, 0xe6, 0xcc, 0x19, 0x10, 0x35, 0x40, 0x1, 0x8, 0xa3, 0x73, 0x6, 0x1, 0x73, 0xe0, 0x96, 0x1a, 0x42, 0x9c, 0x21, 0x2, 0x0, 0x5a, 0xfa, 0x3d, 0xf9, 0xfa, 0xe2, 0x64, 0xe2, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char scroll_button_down_hl_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x21, 0x50, 0x4c, 0x54, 0x45, 0x3d, 0x3b, 0x3f, 0x60, 0x5d, 0x62, 0x3d, 0x3b, 0x3f, 0x3d, 0x3b, 0x3f, 0x3d, 0x3b, 0x3f, 0x65, 0x62, 0x67, 0x60, 0x5d, 0x62, 0x56, 0x53, 0x58, 0x4b, 0x49, 0x4e, 0xce, 0xce, 0xce, 0x59, 0x59, 0x59, 0xb8, 0xf5, 0x6d, 0x48, 0x0, 0x0, 0x0, 0x5, 0x74, 0x52, 0x4e, 0x53, 0x7, 0xfe, 0xc, 0x9, 0x1c, 0xda, 0x2b, 0xa5, 0x57, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0xa, 0x68, 0xd0, 0xf4, 0x56, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x33, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0xc, 0x5, 0x3, 0x21, 0x86, 0xf4, 0xe, 0x30, 0x28, 0x63, 0x88, 0x80, 0x30, 0x5a, 0xf1, 0x33, 0x66, 0x2, 0x1, 0x2a, 0xa3, 0x73, 0xe6, 0xcc, 0x19, 0x10, 0x35, 0x40, 0x1, 0x8, 0xa3, 0x73, 0x6, 0x1, 0x73, 0xe0, 0x96, 0x1a, 0x42, 0x9c, 0x21, 0x2, 0x0, 0x5a, 0xfa, 0x3d, 0xf9, 0xfa, 0xe2, 0x64, 0xe2, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x21, 0x50, 0x4c, 0x54, 0x45, 0x3d, 0x3b, 0x3f, 0x60, 0x5d, 0x62, 0x3d, 0x3b, 0x3f, 0x3d, 0x3b, 0x3f, 0x3d, 0x3b, 0x3f, 0x65, 0x62, 0x67, 0x60, 0x5d, 0x62, 0x56, 0x53, 0x58, 0x4b, 0x49, 0x4e, 0xce, 0xce, 0xce, 0x59, 0x59, 0x59, 0xb8, 0xf5, 0x6d, 0x48, 0x0, 0x0, 0x0, 0x5, 0x74, 0x52, 0x4e, 0x53, 0x7, 0xfe, 0xc, 0x9, 0x1c, 0xda, 0x2b, 0xa5, 0x57, 0x0, 0x0, 0x0, 0x33, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0xc, 0x5, 0x3, 0x21, 0x86, 0xf4, 0xe, 0x30, 0x28, 0x63, 0x88, 0x80, 0x30, 0x5a, 0xf1, 0x33, 0x66, 0x2, 0x1, 0x2a, 0xa3, 0x73, 0xe6, 0xcc, 0x19, 0x10, 0x35, 0x40, 0x1, 0x8, 0xa3, 0x73, 0x6, 0x1, 0x73, 0xe0, 0x96, 0x1a, 0x42, 0x9c, 0x21, 0x2, 0x0, 0x5a, 0xfa, 0x3d, 0xf9, 0xfa, 0xe2, 0x64, 0xe2, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char scroll_button_left_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x30, 0x50, 0x4c, 0x54, 0x45, 0x2d, 0x2c, 0x2f, 0x48, 0x46, 0x4a, 0x2d, 0x2c, 0x2f, 0x2d, 0x2c, 0x2f, 0x2d, 0x2c, 0x2f, 0x4c, 0x4a, 0x4e, 0x48, 0x46, 0x4a, 0x40, 0x3e, 0x42, 0x38, 0x36, 0x3a, 0xc3, 0xc3, 0xc3, 0xc2, 0xc2, 0xc2, 0xc1, 0xc1, 0xc1, 0xc0, 0xc0, 0xc0, 0xbf, 0xbf, 0xbf, 0xbe, 0xbe, 0xbe, 0x59, 0x59, 0x59, 0x8e, 0x47, 0x76, 0xf1, 0x0, 0x0, 0x0, 0x5, 0x74, 0x52, 0x4e, 0x53, 0x8, 0xfe, 0x9, 0xd, 0x19, 0x4a, 0xb6, 0xc1, 0xe6, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0xf, 0x18, 0xba, 0x0, 0xd9, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x3e, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0xc, 0x5, 0x3, 0x21, 0x86, 0xf4, 0xe, 0x30, 0x28, 0x63, 0x88, 0x80, 0x30, 0x5a, 0x51, 0x19, 0x33, 0xa1, 0x8c, 0xae, 0x55, 0x50, 0xc6, 0x2e, 0x28, 0xa3, 0x7b, 0xf7, 0x6e, 0x8, 0xa3, 0xe7, 0xcc, 0x19, 0xa8, 0x14, 0x9c, 0xd1, 0x7b, 0x17, 0xa6, 0xfd, 0x1d, 0x86, 0x81, 0x60, 0x6, 0xdc, 0x52, 0x43, 0x88, 0x33, 0x44, 0x0, 0xcc, 0x4e, 0x3f, 0xd1, 0x4, 0x90, 0xbf, 0x60, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x30, 0x50, 0x4c, 0x54, 0x45, 0x2d, 0x2c, 0x2f, 0x48, 0x46, 0x4a, 0x2d, 0x2c, 0x2f, 0x2d, 0x2c, 0x2f, 0x2d, 0x2c, 0x2f, 0x4c, 0x4a, 0x4e, 0x48, 0x46, 0x4a, 0x40, 0x3e, 0x42, 0x38, 0x36, 0x3a, 0xc3, 0xc3, 0xc3, 0xc2, 0xc2, 0xc2, 0xc1, 0xc1, 0xc1, 0xc0, 0xc0, 0xc0, 0xbf, 0xbf, 0xbf, 0xbe, 0xbe, 0xbe, 0x59, 0x59, 0x59, 0x8e, 0x47, 0x76, 0xf1, 0x0, 0x0, 0x0, 0x5, 0x74, 0x52, 0x4e, 0x53, 0x8, 0xfe, 0x9, 0xd, 0x19, 0x4a, 0xb6, 0xc1, 0xe6, 0x0, 0x0, 0x0, 0x3e, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0xc, 0x5, 0x3, 0x21, 0x86, 0xf4, 0xe, 0x30, 0x28, 0x63, 0x88, 0x80, 0x30, 0x5a, 0x51, 0x19, 0x33, 0xa1, 0x8c, 0xae, 0x55, 0x50, 0xc6, 0x2e, 0x28, 0xa3, 0x7b, 0xf7, 0x6e, 0x8, 0xa3, 0xe7, 0xcc, 0x19, 0xa8, 0x14, 0x9c, 0xd1, 0x7b, 0x17, 0xa6, 0xfd, 0x1d, 0x86, 0x81, 0x60, 0x6, 0xdc, 0x52, 0x43, 0x88, 0x33, 0x44, 0x0, 0xcc, 0x4e, 0x3f, 0xd1, 0x4, 0x90, 0xbf, 0x60, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char scroll_button_left_hl_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x33, 0x50, 0x4c, 0x54, 0x45, 0x3d, 0x3b, 0x3f, 0x60, 0x5d, 0x62, 0x3d, 0x3b, 0x3f, 0x3d, 0x3b, 0x3f, 0x3d, 0x3b, 0x3f, 0x65, 0x62, 0x67, 0x60, 0x5d, 0x62, 0x56, 0x53, 0x58, 0x4b, 0x49, 0x4e, 0xc9, 0xc9, 0xc9, 0xc8, 0xc8, 0xc8, 0xc6, 0xc6, 0xc6, 0xc7, 0xc7, 0xc7, 0xc5, 0xc5, 0xc5, 0xc4, 0xc4, 0xc4, 0xc3, 0xc3, 0xc3, 0x59, 0x59, 0x59, 0x2a, 0x13, 0xff, 0x12, 0x0, 0x0, 0x0, 0x5, 0x74, 0x52, 0x4e, 0x53, 0x7, 0xfe, 0xc, 0x9, 0x1c, 0xda, 0x2b, 0xa5, 0x57, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x10, 0x95, 0xb2, 0xd, 0x2c, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x85, 0xcf, 0xcb, 0xe, 0x80, 0x20, 0xc, 0x44, 0xd1, 0xa2, 0x96, 0x47, 0x7, 0xe4, 0xff, 0xff, 0x16, 0xdc, 0x90, 0xe, 0xc6, 0x78, 0x97, 0x27, 0x69, 0xd3, 0x8a, 0x4, 0x75, 0x85, 0x43, 0x62, 0xca, 0xae, 0x14, 0x45, 0x33, 0xa5, 0xdf, 0x50, 0xa, 0x83, 0x99, 0x11, 0xa0, 0xa2, 0x7a, 0x0, 0xd0, 0xe0, 0xa1, 0x3d, 0xd1, 0xc8, 0x3d, 0xe3, 0xa5, 0xbd, 0x6f, 0x30, 0xe5, 0xef, 0xb0, 0x5, 0xaf, 0xe7, 0x4e, 0x7e, 0xff, 0x1a, 0xb, 0x26, 0x7, 0xac, 0xd9, 0xa3, 0x51, 0xe3, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x30, 0x50, 0x4c, 0x54, 0x45, 0x3d, 0x3b, 0x3f, 0x60, 0x5d, 0x62, 0x3d, 0x3b, 0x3f, 0x3d, 0x3b, 0x3f, 0x3d, 0x3b, 0x3f, 0x65, 0x62, 0x67, 0x60, 0x5d, 0x62, 0x56, 0x53, 0x58, 0x4b, 0x49, 0x4e, 0xc9, 0xc9, 0xc9, 0xc8, 0xc8, 0xc8, 0xc6, 0xc6, 0xc6, 0xc7, 0xc7, 0xc7, 0xc5, 0xc5, 0xc5, 0xc4, 0xc4, 0xc4, 0xc3, 0xc3, 0xc3, 0x58, 0xf9, 0x63, 0x6a, 0x0, 0x0, 0x0, 0x5, 0x74, 0x52, 0x4e, 0x53, 0x7, 0xfe, 0xc, 0x9, 0x1c, 0xda, 0x2b, 0xa5, 0x57, 0x0, 0x0, 0x0, 0x42, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x60, 0xc, 0x5, 0x3, 0x21, 0x86, 0xf4, 0xe, 0x30, 0x28, 0x63, 0x88, 0x80, 0x30, 0x5a, 0x51, 0x19, 0x33, 0xa1, 0x8c, 0xae, 0x55, 0x50, 0xc6, 0x9e, 0x3d, 0x10, 0x46, 0xf7, 0xee, 0xdb, 0x10, 0x46, 0xef, 0xdd, 0xbb, 0x50, 0xa9, 0x77, 0xef, 0xa0, 0x8c, 0xfe, 0x7f, 0x30, 0xed, 0xff, 0x81, 0xc, 0x4c, 0x93, 0x11, 0x96, 0x1a, 0x42, 0x9c, 0x21, 0x2, 0x0, 0xfe, 0x97, 0x40, 0xa0, 0xa6, 0x84, 0xb1, 0xf6, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char scroll_button_right_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x30, 0x50, 0x4c, 0x54, 0x45, 0x2d, 0x2c, 0x2f, 0x48, 0x46, 0x4a, 0x2d, 0x2c, 0x2f, 0x2d, 0x2c, 0x2f, 0x2d, 0x2c, 0x2f, 0x4c, 0x4a, 0x4e, 0x48, 0x46, 0x4a, 0x40, 0x3e, 0x42, 0x38, 0x36, 0x3a, 0xc3, 0xc3, 0xc3, 0xc2, 0xc2, 0xc2, 0xc1, 0xc1, 0xc1, 0xc0, 0xc0, 0xc0, 0xbf, 0xbf, 0xbf, 0xbe, 0xbe, 0xbe, 0x59, 0x59, 0x59, 0x8e, 0x47, 0x76, 0xf1, 0x0, 0x0, 0x0, 0x5, 0x74, 0x52, 0x4e, 0x53, 0x8, 0xfe, 0x9, 0xd, 0x19, 0x4a, 0xb6, 0xc1, 0xe6, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0xf, 0x18, 0xba, 0x0, 0xd9, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x40, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0xc, 0x5, 0x3, 0x21, 0x86, 0xf4, 0xe, 0x30, 0x28, 0x63, 0x88, 0x80, 0x30, 0x5a, 0x51, 0x18, 0x33, 0x61, 0x8c, 0x59, 0x2b, 0xa0, 0x8c, 0x5d, 0xab, 0xa0, 0x8c, 0xdd, 0xbb, 0x77, 0x40, 0x18, 0x67, 0xce, 0x9c, 0x80, 0x31, 0xa0, 0x52, 0x77, 0x6f, 0x40, 0x19, 0xef, 0x30, 0xc, 0x84, 0x30, 0xe0, 0x96, 0x1a, 0x42, 0x9c, 0x21, 0x2, 0x0, 0xfd, 0x36, 0x40, 0x93, 0xf1, 0x83, 0x5f, 0xf2, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x30, 0x50, 0x4c, 0x54, 0x45, 0x2d, 0x2c, 0x2f, 0x48, 0x46, 0x4a, 0x2d, 0x2c, 0x2f, 0x2d, 0x2c, 0x2f, 0x2d, 0x2c, 0x2f, 0x4c, 0x4a, 0x4e, 0x48, 0x46, 0x4a, 0x40, 0x3e, 0x42, 0x38, 0x36, 0x3a, 0xc3, 0xc3, 0xc3, 0xc2, 0xc2, 0xc2, 0xc1, 0xc1, 0xc1, 0xc0, 0xc0, 0xc0, 0xbf, 0xbf, 0xbf, 0xbe, 0xbe, 0xbe, 0x59, 0x59, 0x59, 0x8e, 0x47, 0x76, 0xf1, 0x0, 0x0, 0x0, 0x5, 0x74, 0x52, 0x4e, 0x53, 0x8, 0xfe, 0x9, 0xd, 0x19, 0x4a, 0xb6, 0xc1, 0xe6, 0x0, 0x0, 0x0, 0x40, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0xc, 0x5, 0x3, 0x21, 0x86, 0xf4, 0xe, 0x30, 0x28, 0x63, 0x88, 0x80, 0x30, 0x5a, 0x51, 0x18, 0x33, 0x61, 0x8c, 0x59, 0x2b, 0xa0, 0x8c, 0x5d, 0xab, 0xa0, 0x8c, 0xdd, 0xbb, 0x77, 0x40, 0x18, 0x67, 0xce, 0x9c, 0x80, 0x31, 0xa0, 0x52, 0x77, 0x6f, 0x40, 0x19, 0xef, 0x30, 0xc, 0x84, 0x30, 0xe0, 0x96, 0x1a, 0x42, 0x9c, 0x21, 0x2, 0x0, 0xfd, 0x36, 0x40, 0x93, 0xf1, 0x83, 0x5f, 0xf2, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char scroll_button_right_hl_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x36, 0x50, 0x4c, 0x54, 0x45, 0x3d, 0x3b, 0x3f, 0x60, 0x5d, 0x62, 0x3d, 0x3b, 0x3f, 0x3d, 0x3b, 0x3f, 0x3d, 0x3b, 0x3f, 0x65, 0x62, 0x67, 0x60, 0x5d, 0x62, 0x56, 0x53, 0x58, 0x4b, 0x49, 0x4e, 0xc9, 0xc9, 0xc9, 0xc8, 0xc8, 0xc8, 0xc6, 0xc6, 0xc6, 0xc7, 0xc7, 0xc7, 0xc5, 0xc5, 0xc5, 0xc4, 0xc4, 0xc4, 0xc3, 0xc3, 0xc3, 0xc2, 0xc2, 0xc2, 0x59, 0x59, 0x59, 0x56, 0xec, 0x9e, 0xdc, 0x0, 0x0, 0x0, 0x5, 0x74, 0x52, 0x4e, 0x53, 0x7, 0xfe, 0xc, 0x9, 0x1c, 0xda, 0x2b, 0xa5, 0x57, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x11, 0xe2, 0xb5, 0x3d, 0xba, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x4, 0x4e, 0x1d, 0x2, 0xaf, 0x0, 0x0, 0x0, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x85, 0xcf, 0xcb, 0xe, 0x80, 0x30, 0x8, 0x44, 0x51, 0xaa, 0xd2, 0x7, 0xb4, 0xd2, 0xff, 0xff, 0xda, 0xea, 0x6e, 0x46, 0x63, 0xbc, 0xcb, 0x93, 0x40, 0x40, 0x24, 0x29, 0x94, 0x36, 0xc9, 0xa5, 0x42, 0x25, 0x8b, 0x56, 0x4a, 0xbf, 0xa0, 0xb5, 0x7, 0x98, 0x19, 0x83, 0x77, 0xef, 0xc, 0x3e, 0xdc, 0x11, 0xc6, 0x1d, 0xc2, 0x79, 0x45, 0x23, 0x11, 0xc1, 0x4b, 0xe7, 0xfc, 0x3b, 0xc, 0xe0, 0xf5, 0xdc, 0xce, 0xef, 0x1f, 0xb, 0xc, 0x30, 0x7, 0xaf, 0x1f, 0x5b, 0x76, 0x12, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x33, 0x50, 0x4c, 0x54, 0x45, 0x3d, 0x3b, 0x3f, 0x60, 0x5d, 0x62, 0x3d, 0x3b, 0x3f, 0x3d, 0x3b, 0x3f, 0x3d, 0x3b, 0x3f, 0x65, 0x62, 0x67, 0x60, 0x5d, 0x62, 0x56, 0x53, 0x58, 0x4b, 0x49, 0x4e, 0xc9, 0xc9, 0xc9, 0xc8, 0xc8, 0xc8, 0xc6, 0xc6, 0xc6, 0xc7, 0xc7, 0xc7, 0xc5, 0xc5, 0xc5, 0xc4, 0xc4, 0xc4, 0xc3, 0xc3, 0xc3, 0xc2, 0xc2, 0xc2, 0x2e, 0x3d, 0xb1, 0x1e, 0x0, 0x0, 0x0, 0x5, 0x74, 0x52, 0x4e, 0x53, 0x7, 0xfe, 0xc, 0x9, 0x1c, 0xda, 0x2b, 0xa5, 0x57, 0x0, 0x0, 0x0, 0x49, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x65, 0xc8, 0x31, 0x16, 0x2, 0x20, 0x10, 0x43, 0xc1, 0xe4, 0x83, 0xdc, 0xff, 0xb8, 0x88, 0xf, 0x57, 0xb, 0x8b, 0x80, 0x53, 0xe, 0xf2, 0x23, 0x18, 0xc6, 0x68, 0x61, 0x74, 0xca, 0xa, 0x2e, 0x74, 0xf9, 0x85, 0xfd, 0x17, 0x5c, 0x81, 0xfb, 0x11, 0x2a, 0xaa, 0x65, 0x80, 0x20, 0xc3, 0x5f, 0xaf, 0x2b, 0x96, 0xce, 0x78, 0xea, 0x88, 0x39, 0x95, 0x91, 0x70, 0x29, 0x94, 0xd9, 0x6b, 0x87, 0xf5, 0xfe, 0x0, 0xc6, 0xa7, 0x1b, 0x66, 0x7b, 0x42, 0xf1, 0x14, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char scroll_button_up_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x21, 0x50, 0x4c, 0x54, 0x45, 0x2d, 0x2c, 0x2f, 0x48, 0x46, 0x4a, 0x2d, 0x2c, 0x2f, 0x2d, 0x2c, 0x2f, 0x2d, 0x2c, 0x2f, 0x4c, 0x4a, 0x4e, 0x48, 0x46, 0x4a, 0x40, 0x3e, 0x42, 0x38, 0x36, 0x3a, 0xc3, 0xc3, 0xc3, 0x59, 0x59, 0x59, 0xb3, 0x52, 0xf2, 0x5, 0x0, 0x0, 0x0, 0x5, 0x74, 0x52, 0x4e, 0x53, 0x8, 0xfe, 0x9, 0xd, 0x19, 0x4a, 0xb6, 0xc1, 0xe6, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0xa, 0x68, 0xd0, 0xf4, 0x56, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x36, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0xc, 0x5, 0x3, 0x21, 0x86, 0xf4, 0xe, 0x30, 0x28, 0x63, 0x88, 0x80, 0x30, 0x5a, 0xb1, 0x33, 0x3a, 0x67, 0x40, 0x19, 0x33, 0x67, 0x42, 0x18, 0x9d, 0x33, 0x67, 0xce, 0x0, 0x33, 0x66, 0x2, 0x1, 0x2a, 0x3, 0x9f, 0x39, 0x10, 0x6, 0xdc, 0x52, 0x43, 0x88, 0x33, 0x44, 0x0, 0x59, 0xc8, 0x3d, 0xf9, 0xf, 0x68, 0xc5, 0xa9, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x21, 0x50, 0x4c, 0x54, 0x45, 0x2d, 0x2c, 0x2f, 0x48, 0x46, 0x4a, 0x2d, 0x2c, 0x2f, 0x2d, 0x2c, 0x2f, 0x2d, 0x2c, 0x2f, 0x4c, 0x4a, 0x4e, 0x48, 0x46, 0x4a, 0x40, 0x3e, 0x42, 0x38, 0x36, 0x3a, 0xc3, 0xc3, 0xc3, 0x59, 0x59, 0x59, 0xb3, 0x52, 0xf2, 0x5, 0x0, 0x0, 0x0, 0x5, 0x74, 0x52, 0x4e, 0x53, 0x8, 0xfe, 0x9, 0xd, 0x19, 0x4a, 0xb6, 0xc1, 0xe6, 0x0, 0x0, 0x0, 0x36, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0xc, 0x5, 0x3, 0x21, 0x86, 0xf4, 0xe, 0x30, 0x28, 0x63, 0x88, 0x80, 0x30, 0x5a, 0xb1, 0x33, 0x3a, 0x67, 0x40, 0x19, 0x33, 0x67, 0x42, 0x18, 0x9d, 0x33, 0x67, 0xce, 0x0, 0x33, 0x66, 0x2, 0x1, 0x2a, 0x3, 0x9f, 0x39, 0x10, 0x6, 0xdc, 0x52, 0x43, 0x88, 0x33, 0x44, 0x0, 0x59, 0xc8, 0x3d, 0xf9, 0xf, 0x68, 0xc5, 0xa9, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char scroll_button_up_hl_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x21, 0x50, 0x4c, 0x54, 0x45, 0x3d, 0x3b, 0x3f, 0x60, 0x5d, 0x62, 0x3d, 0x3b, 0x3f, 0x3d, 0x3b, 0x3f, 0x3d, 0x3b, 0x3f, 0x65, 0x62, 0x67, 0x60, 0x5d, 0x62, 0x56, 0x53, 0x58, 0x4b, 0x49, 0x4e, 0xce, 0xce, 0xce, 0x59, 0x59, 0x59, 0xb8, 0xf5, 0x6d, 0x48, 0x0, 0x0, 0x0, 0x5, 0x74, 0x52, 0x4e, 0x53, 0x7, 0xfe, 0xc, 0x9, 0x1c, 0xda, 0x2b, 0xa5, 0x57, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0xa, 0x68, 0xd0, 0xf4, 0x56, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x36, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0xc, 0x5, 0x3, 0x21, 0x86, 0xf4, 0xe, 0x30, 0x28, 0x63, 0x88, 0x80, 0x30, 0x5a, 0xb1, 0x33, 0x3a, 0x67, 0x40, 0x19, 0x33, 0x67, 0x42, 0x18, 0x9d, 0x33, 0x67, 0xce, 0x0, 0x33, 0x66, 0x2, 0x1, 0x2a, 0x3, 0x9f, 0x39, 0x10, 0x6, 0xdc, 0x52, 0x43, 0x88, 0x33, 0x44, 0x0, 0x59, 0xc8, 0x3d, 0xf9, 0xf, 0x68, 0xc5, 0xa9, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x21, 0x50, 0x4c, 0x54, 0x45, 0x3d, 0x3b, 0x3f, 0x60, 0x5d, 0x62, 0x3d, 0x3b, 0x3f, 0x3d, 0x3b, 0x3f, 0x3d, 0x3b, 0x3f, 0x65, 0x62, 0x67, 0x60, 0x5d, 0x62, 0x56, 0x53, 0x58, 0x4b, 0x49, 0x4e, 0xce, 0xce, 0xce, 0x59, 0x59, 0x59, 0xb8, 0xf5, 0x6d, 0x48, 0x0, 0x0, 0x0, 0x5, 0x74, 0x52, 0x4e, 0x53, 0x7, 0xfe, 0xc, 0x9, 0x1c, 0xda, 0x2b, 0xa5, 0x57, 0x0, 0x0, 0x0, 0x36, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0xc, 0x5, 0x3, 0x21, 0x86, 0xf4, 0xe, 0x30, 0x28, 0x63, 0x88, 0x80, 0x30, 0x5a, 0xb1, 0x33, 0x3a, 0x67, 0x40, 0x19, 0x33, 0x67, 0x42, 0x18, 0x9d, 0x33, 0x67, 0xce, 0x0, 0x33, 0x66, 0x2, 0x1, 0x2a, 0x3, 0x9f, 0x39, 0x10, 0x6, 0xdc, 0x52, 0x43, 0x88, 0x33, 0x44, 0x0, 0x59, 0xc8, 0x3d, 0xf9, 0xf, 0x68, 0xc5, 0xa9, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char scroll_grabber_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x3, 0x0, 0x0, 0x0, 0x61, 0xab, 0xac, 0xd5, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x60, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x5b, 0x59, 0x61, 0x5b, 0x59, 0x61, 0x5a, 0x58, 0x60, 0x59, 0x57, 0x5f, 0x5a, 0x58, 0x60, 0x5a, 0x58, 0x60, 0x57, 0x56, 0x5e, 0x58, 0x56, 0x5e, 0x56, 0x55, 0x5d, 0x57, 0x55, 0x5d, 0x57, 0x55, 0x5d, 0x55, 0x53, 0x5b, 0x55, 0x53, 0x5b, 0x54, 0x53, 0x5b, 0x55, 0x54, 0x5c, 0x54, 0x52, 0x5a, 0x55, 0x53, 0x5b, 0x5a, 0x58, 0x60, 0x56, 0x54, 0x5c, 0x54, 0x53, 0x5a, 0x55, 0x53, 0x5b, 0x53, 0x51, 0x59, 0x52, 0x51, 0x59, 0x52, 0x50, 0x58, 0x51, 0x50, 0x58, 0x51, 0x4f, 0x57, 0x50, 0x4e, 0x56, 0x4f, 0x4d, 0x55, 0x50, 0x4f, 0x57, 0x54, 0x52, 0x5a, 0xff, 0xff, 0xff, 0xc7, 0x51, 0xc2, 0xf2, 0x0, 0x0, 0x0, 0x12, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x2c, 0xb8, 0xf4, 0x2e, 0xf2, 0xb8, 0xf4, 0xf5, 0xf4, 0xf5, 0xb8, 0x2f, 0xf2, 0x2e, 0xb8, 0xf4, 0xb8, 0x66, 0xf6, 0xf7, 0x12, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x1f, 0x5, 0xd, 0x10, 0xbd, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x50, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0xc0, 0x7, 0x18, 0x99, 0x98, 0x85, 0x98, 0x18, 0x21, 0x6c, 0x16, 0x56, 0x61, 0x11, 0x11, 0x61, 0x56, 0x16, 0x30, 0x87, 0x4d, 0x54, 0xc, 0x8, 0x44, 0xd9, 0xc0, 0x1c, 0x76, 0x71, 0x9, 0x20, 0x10, 0xe7, 0x0, 0x73, 0x38, 0x25, 0xa5, 0x80, 0x40, 0x92, 0xb, 0xcc, 0xe1, 0x96, 0x90, 0x6, 0x2, 0x9, 0x6e, 0x30, 0x87, 0x87, 0x57, 0x4a, 0x46, 0x46, 0x96, 0x97, 0x7, 0x62, 0x1c, 0x1f, 0xbf, 0x80, 0x9c, 0x20, 0x1f, 0x5e, 0xdb, 0x1, 0x23, 0xfd, 0x4, 0x11, 0x2d, 0x48, 0xcb, 0xd2, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x3, 0x0, 0x0, 0x0, 0x61, 0xab, 0xac, 0xd5, 0x0, 0x0, 0x0, 0x5d, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x5b, 0x59, 0x61, 0x5b, 0x59, 0x61, 0x5a, 0x58, 0x60, 0x59, 0x57, 0x5f, 0x5a, 0x58, 0x60, 0x5a, 0x58, 0x60, 0x57, 0x56, 0x5e, 0x58, 0x56, 0x5e, 0x56, 0x55, 0x5d, 0x57, 0x55, 0x5d, 0x57, 0x55, 0x5d, 0x55, 0x53, 0x5b, 0x55, 0x53, 0x5b, 0x54, 0x53, 0x5b, 0x55, 0x54, 0x5c, 0x54, 0x52, 0x5a, 0x55, 0x53, 0x5b, 0x5a, 0x58, 0x60, 0x56, 0x54, 0x5c, 0x54, 0x53, 0x5a, 0x55, 0x53, 0x5b, 0x53, 0x51, 0x59, 0x52, 0x51, 0x59, 0x52, 0x50, 0x58, 0x51, 0x50, 0x58, 0x51, 0x4f, 0x57, 0x50, 0x4e, 0x56, 0x4f, 0x4d, 0x55, 0x50, 0x4f, 0x57, 0x54, 0x52, 0x5a, 0xae, 0x55, 0xff, 0xf7, 0x0, 0x0, 0x0, 0x12, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x2c, 0xb8, 0xf4, 0x2e, 0xf2, 0xb8, 0xf4, 0xf5, 0xf4, 0xf5, 0xb8, 0x2f, 0xf2, 0x2e, 0xb8, 0xf4, 0xb8, 0x66, 0xf6, 0xf7, 0x12, 0x0, 0x0, 0x0, 0x48, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x64, 0xc7, 0xb1, 0x11, 0x80, 0x40, 0x8, 0x45, 0x41, 0xff, 0x83, 0x2, 0xe, 0xfb, 0x2f, 0x13, 0xe2, 0xf3, 0x6, 0x12, 0x1d, 0x37, 0x5b, 0xae, 0x97, 0x5f, 0x84, 0xdd, 0x68, 0xe2, 0x1e, 0x41, 0xb8, 0x77, 0x58, 0x6, 0xb6, 0xe8, 0x88, 0xd1, 0xe1, 0x93, 0xad, 0x63, 0xab, 0xa3, 0x3a, 0xa3, 0x26, 0xa9, 0x4a, 0x52, 0xf9, 0xc, 0x62, 0xcf, 0xa7, 0x8f, 0x1f, 0x1e, 0xbd, 0xff, 0x84, 0xee, 0x2, 0x0, 0x54, 0x76, 0x10, 0x19, 0x1e, 0xd7, 0x1d, 0x9b, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char scroll_grabber_hl_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x3, 0x0, 0x0, 0x0, 0x61, 0xab, 0xac, 0xd5, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x6c, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x97, 0xd0, 0xdf, 0x92, 0xcb, 0xdc, 0x84, 0xbb, 0xd4, 0x92, 0xca, 0xdc, 0x95, 0xd0, 0xdd, 0x83, 0xbb, 0xd3, 0x8b, 0xc8, 0xd7, 0x79, 0xb5, 0xcb, 0x78, 0xb4, 0xca, 0x73, 0xb0, 0xc7, 0x73, 0xb0, 0xc7, 0x7b, 0xc0, 0xcf, 0x79, 0xc5, 0xd1, 0x6b, 0xae, 0xc1, 0x75, 0xc6, 0xcf, 0x70, 0xbc, 0xca, 0x64, 0xa6, 0xbc, 0x71, 0xbc, 0xc9, 0x82, 0xba, 0xd4, 0x6a, 0xa2, 0xc6, 0x62, 0x9a, 0xc2, 0x61, 0x9a, 0xc1, 0x68, 0x9f, 0xc2, 0x5d, 0x92, 0xbb, 0x5c, 0x92, 0xb8, 0x58, 0x8d, 0xb6, 0x59, 0x8e, 0xb3, 0x56, 0x89, 0xb0, 0x5c, 0x91, 0xb2, 0x53, 0x84, 0xa9, 0x58, 0x8f, 0xae, 0x54, 0x83, 0xa4, 0x57, 0x8e, 0xad, 0x64, 0xa5, 0xba, 0xff, 0xff, 0xff, 0xbb, 0x65, 0x65, 0x27, 0x0, 0x0, 0x0, 0x13, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x25, 0xad, 0xf1, 0xad, 0x27, 0xef, 0xad, 0xf1, 0xf3, 0xf1, 0xf3, 0xad, 0x28, 0xef, 0x27, 0xad, 0xf2, 0xad, 0xcd, 0x8a, 0x27, 0xfe, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x23, 0x2a, 0x62, 0x6c, 0x3a, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x50, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0xc0, 0x7, 0x18, 0x99, 0x98, 0x85, 0x59, 0x18, 0x21, 0x6c, 0x56, 0x36, 0x11, 0x51, 0x31, 0x11, 0x36, 0x56, 0x30, 0x87, 0x5d, 0x5c, 0x2, 0x8, 0xc4, 0xd9, 0xc1, 0x1c, 0xe, 0x49, 0x29, 0x20, 0x90, 0xe4, 0x4, 0x73, 0xb8, 0xa4, 0x65, 0x80, 0x40, 0x9a, 0x1b, 0xcc, 0xe1, 0x91, 0x95, 0x3, 0x2, 0x59, 0x1e, 0x30, 0x87, 0x97, 0x4f, 0x5e, 0x41, 0x41, 0x91, 0x8f, 0x17, 0x62, 0x1c, 0xbf, 0x80, 0xa0, 0x92, 0x10, 0x3f, 0x5e, 0xdb, 0x1, 0x41, 0x87, 0x4, 0x7d, 0x15, 0xc4, 0xfd, 0x6a, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x3, 0x0, 0x0, 0x0, 0x61, 0xab, 0xac, 0xd5, 0x0, 0x0, 0x0, 0x69, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x97, 0xd0, 0xdf, 0x92, 0xcb, 0xdc, 0x84, 0xbb, 0xd4, 0x92, 0xca, 0xdc, 0x95, 0xd0, 0xdd, 0x83, 0xbb, 0xd3, 0x8b, 0xc8, 0xd7, 0x79, 0xb5, 0xcb, 0x78, 0xb4, 0xca, 0x73, 0xb0, 0xc7, 0x73, 0xb0, 0xc7, 0x7b, 0xc0, 0xcf, 0x79, 0xc5, 0xd1, 0x6b, 0xae, 0xc1, 0x75, 0xc6, 0xcf, 0x70, 0xbc, 0xca, 0x64, 0xa6, 0xbc, 0x71, 0xbc, 0xc9, 0x82, 0xba, 0xd4, 0x6a, 0xa2, 0xc6, 0x62, 0x9a, 0xc2, 0x61, 0x9a, 0xc1, 0x68, 0x9f, 0xc2, 0x5d, 0x92, 0xbb, 0x5c, 0x92, 0xb8, 0x58, 0x8d, 0xb6, 0x59, 0x8e, 0xb3, 0x56, 0x89, 0xb0, 0x5c, 0x91, 0xb2, 0x53, 0x84, 0xa9, 0x58, 0x8f, 0xae, 0x54, 0x83, 0xa4, 0x57, 0x8e, 0xad, 0x64, 0xa5, 0xba, 0x17, 0x3b, 0xfc, 0x67, 0x0, 0x0, 0x0, 0x13, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x25, 0xad, 0xf1, 0xad, 0x27, 0xef, 0xad, 0xf1, 0xf3, 0xf1, 0xf3, 0xad, 0x28, 0xef, 0x27, 0xad, 0xf2, 0xad, 0xcd, 0x8a, 0x27, 0xfe, 0x0, 0x0, 0x0, 0x49, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x75, 0xc7, 0xa5, 0x1, 0x3, 0x1, 0x0, 0x4, 0xc1, 0xdd, 0xb, 0x9a, 0x60, 0xff, 0x3d, 0x6, 0x54, 0xe0, 0x59, 0x3d, 0x8f, 0x9b, 0xb0, 0x66, 0x3, 0x98, 0xdc, 0xff, 0x35, 0x20, 0xec, 0x3c, 0x6b, 0xf5, 0xae, 0xff, 0x6c, 0xda, 0xdc, 0x36, 0x31, 0xc7, 0x6f, 0xc9, 0x16, 0x8c, 0x40, 0x1d, 0xba, 0x64, 0x21, 0x42, 0xc0, 0x97, 0xc9, 0xe6, 0x25, 0x8, 0x5c, 0xf4, 0xf6, 0x2c, 0x5f, 0x8c, 0x39, 0x4c, 0x3, 0xfe, 0x9a, 0x10, 0x43, 0x82, 0xcf, 0x27, 0x93, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char scroll_grabber_pressed_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x6, 0x0, 0x0, 0x0, 0x56, 0x75, 0x5c, 0xe7, 0x0, 0x0, 0x0, 0x4, 0x73, 0x42, 0x49, 0x54, 0x8, 0x8, 0x8, 0x8, 0x7c, 0x8, 0x64, 0x88, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xd, 0xd7, 0x0, 0x0, 0xd, 0xd7, 0x1, 0x42, 0x28, 0x9b, 0x78, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x0, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x6e, 0x6b, 0x73, 0x63, 0x61, 0x70, 0x65, 0x2e, 0x6f, 0x72, 0x67, 0x9b, 0xee, 0x3c, 0x1a, 0x0, 0x0, 0x0, 0x66, 0x49, 0x44, 0x41, 0x54, 0x28, 0x91, 0xcd, 0x91, 0xb1, 0xa, 0xc0, 0x20, 0x10, 0x43, 0x63, 0x71, 0xbf, 0x5f, 0x12, 0x9c, 0xfd, 0x1a, 0x3f, 0xcd, 0xa9, 0x83, 0xe0, 0x2f, 0x65, 0x2f, 0x9c, 0x8b, 0x83, 0x47, 0xed, 0x60, 0xbb, 0x34, 0xdb, 0x3d, 0x12, 0x48, 0x38, 0xa7, 0xaa, 0xd8, 0xd1, 0xb1, 0xe5, 0x7e, 0x13, 0xf0, 0xf3, 0xd1, 0x5a, 0xf3, 0x24, 0x23, 0x80, 0x34, 0x50, 0x11, 0x91, 0x1a, 0x42, 0xb8, 0x96, 0x1, 0x92, 0x51, 0x55, 0xf3, 0x84, 0x32, 0x49, 0x0, 0x38, 0x9f, 0x2a, 0x25, 0xdc, 0x65, 0xd8, 0xe7, 0xd1, 0x65, 0xe1, 0x31, 0xcc, 0x6c, 0x10, 0x91, 0x3a, 0x3a, 0x9b, 0xd1, 0xb3, 0xc7, 0xfd, 0xef, 0x71, 0x1d, 0x42, 0xe6, 0x21, 0x43, 0xf5, 0x2b, 0xd8, 0x6c, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x4, 0x0, 0x0, 0x0, 0xfc, 0x7c, 0x94, 0x6c, 0x0, 0x0, 0x0, 0x2f, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0xa0, 0x3a, 0xd8, 0xcf, 0xb2, 0xc1, 0x7d, 0xc3, 0x14, 0x20, 0x74, 0xdf, 0xcf, 0x82, 0x22, 0xb1, 0xc1, 0x7d, 0xfd, 0x2e, 0x8, 0xdc, 0xe0, 0x8e, 0x2a, 0x31, 0x5, 0x2e, 0x31, 0x85, 0x90, 0x4, 0xa6, 0x51, 0xb8, 0x2d, 0xa7, 0x36, 0x0, 0x0, 0x7b, 0xcd, 0x2b, 0x75, 0x45, 0x5e, 0xf8, 0x88, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char selection_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x2d, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfd, 0xfb, 0xff, 0xfd, 0xf7, 0xff, 0xfd, 0xf7, 0xff, 0xfd, 0xf7, 0xff, 0xfd, 0xf6, 0xff, 0xf6, 0xf4, 0xff, 0x15, 0x15, 0x17, 0xff, 0x70, 0xc0, 0x21, 0x0, 0x0, 0x0, 0xe, 0x74, 0x52, 0x4e, 0x53, 0x6, 0xf, 0x16, 0x18, 0x2a, 0x3b, 0x40, 0x3c, 0x6, 0x3d, 0x44, 0x3e, 0x31, 0x25, 0x8, 0x3d, 0x16, 0xb4, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0xe, 0x6f, 0xbd, 0x30, 0x4f, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x37, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0x54, 0x36, 0x6, 0x2, 0x23, 0x1, 0x6, 0x91, 0xb0, 0x34, 0x20, 0x48, 0x75, 0x64, 0x50, 0xef, 0x5c, 0x5, 0x4, 0x33, 0x8a, 0x18, 0xcc, 0xf6, 0xdc, 0x5, 0x82, 0xd3, 0xc9, 0xc, 0x66, 0x6b, 0x41, 0x8c, 0x5b, 0x94, 0x33, 0x60, 0x6, 0xc2, 0xad, 0x80, 0x5b, 0xa, 0x73, 0x6, 0x0, 0x45, 0x34, 0x48, 0x41, 0xa3, 0xc5, 0x91, 0x23, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x2d, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfd, 0xfb, 0xff, 0xfd, 0xf7, 0xff, 0xfd, 0xf7, 0xff, 0xfd, 0xf7, 0xff, 0xfd, 0xf6, 0xff, 0xf6, 0xf4, 0xff, 0x15, 0x15, 0x17, 0xff, 0x70, 0xc0, 0x21, 0x0, 0x0, 0x0, 0xe, 0x74, 0x52, 0x4e, 0x53, 0x6, 0xf, 0x16, 0x18, 0x2a, 0x3b, 0x40, 0x3c, 0x6, 0x3d, 0x44, 0x3e, 0x31, 0x25, 0x8, 0x3d, 0x16, 0xb4, 0x0, 0x0, 0x0, 0x37, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0x54, 0x36, 0x6, 0x2, 0x23, 0x1, 0x6, 0x91, 0xb0, 0x34, 0x20, 0x48, 0x75, 0x64, 0x50, 0xef, 0x5c, 0x5, 0x4, 0x33, 0x8a, 0x18, 0xcc, 0xf6, 0xdc, 0x5, 0x82, 0xd3, 0xc9, 0xc, 0x66, 0x6b, 0x41, 0x8c, 0x5b, 0x94, 0x33, 0x60, 0x6, 0xc2, 0xad, 0x80, 0x5b, 0xa, 0x73, 0x6, 0x0, 0x45, 0x34, 0x48, 0x41, 0xa3, 0xc5, 0x91, 0x23, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char selection_oof_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x30, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2c, 0x2, 0xfd, 0xfb, 0xff, 0xfd, 0xfb, 0xff, 0xfd, 0xfb, 0xff, 0xfd, 0xfb, 0xff, 0x15, 0x15, 0x17, 0xe9, 0x54, 0x1, 0x21, 0x0, 0x0, 0x0, 0xf, 0x74, 0x52, 0x4e, 0x53, 0xa, 0x1a, 0x26, 0x29, 0x2a, 0x48, 0x65, 0x6d, 0x6e, 0x66, 0x3, 0x20, 0x25, 0x16, 0xc, 0x1f, 0x74, 0xbf, 0x74, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0xf, 0x18, 0xba, 0x0, 0xd9, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x38, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0x54, 0x76, 0x1, 0x2, 0x23, 0x1, 0x6, 0xd1, 0xf4, 0xe, 0x20, 0x28, 0xb, 0x64, 0xd0, 0x5c, 0x7d, 0x6, 0x8, 0x76, 0x4d, 0x62, 0x70, 0xdf, 0xfb, 0xe, 0x8, 0x6e, 0x97, 0x30, 0x78, 0x9c, 0x3, 0x31, 0xde, 0xb4, 0x50, 0xca, 0x80, 0x1b, 0x8, 0xb7, 0x2, 0x6e, 0x29, 0xcc, 0x19, 0x0, 0x1a, 0x23, 0x52, 0x59, 0xa4, 0x2f, 0x3d, 0xa7, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x2d, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2c, 0x2, 0xfd, 0xfb, 0xff, 0xfd, 0xfb, 0xff, 0xfd, 0xfb, 0xff, 0xfd, 0xfb, 0xff, 0xaf, 0xdf, 0x90, 0xa5, 0x0, 0x0, 0x0, 0xf, 0x74, 0x52, 0x4e, 0x53, 0xa, 0x1a, 0x26, 0x29, 0x2a, 0x48, 0x65, 0x6d, 0x6e, 0x66, 0x3, 0x20, 0x25, 0x16, 0xc, 0x1f, 0x74, 0xbf, 0x74, 0x0, 0x0, 0x0, 0x37, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x64, 0x54, 0x52, 0x64, 0x60, 0x60, 0x78, 0x77, 0x8f, 0x51, 0x34, 0x8, 0xcc, 0xb8, 0xcd, 0xa8, 0xd9, 0x4, 0x66, 0xdc, 0x60, 0x74, 0x2f, 0x33, 0x4, 0x32, 0xde, 0xce, 0x64, 0xf4, 0x68, 0x53, 0x0, 0x32, 0xfe, 0xcd, 0xa0, 0x90, 0x1, 0x37, 0x10, 0x6e, 0x5, 0xdc, 0x52, 0xb8, 0x33, 0x0, 0xcc, 0x7, 0x26, 0xff, 0x1f, 0x38, 0x23, 0x97, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char spinbox_updown_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0xcd, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xe5, 0x53, 0x31, 0xe, 0x82, 0x40, 0x10, 0x9c, 0x5d, 0x22, 0x3e, 0x80, 0x86, 0xc4, 0x0, 0xe1, 0xf, 0x16, 0x5a, 0x58, 0xf9, 0x5, 0xe3, 0x13, 0xd0, 0xc2, 0xc4, 0xcf, 0xd8, 0xf0, 0x5, 0xe3, 0x1f, 0x2c, 0x2c, 0x6c, 0xf8, 0x1, 0xc5, 0x72, 0x85, 0x9, 0xd, 0xf, 0x10, 0x43, 0xce, 0x86, 0x82, 0xe0, 0xe9, 0x19, 0x8d, 0x95, 0x53, 0xce, 0xce, 0x6e, 0x26, 0x99, 0x59, 0xe0, 0x97, 0x10, 0x91, 0x95, 0x52, 0x2a, 0x79, 0xa5, 0xa1, 0x67, 0x83, 0xa2, 0x28, 0xa6, 0x0, 0x8e, 0x0, 0x98, 0x99, 0xe7, 0x61, 0x18, 0x9e, 0xde, 0x3e, 0x20, 0x22, 0x3e, 0x11, 0x65, 0x0, 0x46, 0x2d, 0x55, 0x3a, 0x8e, 0x33, 0xe, 0x82, 0xe0, 0xd2, 0xd7, 0x72, 0x9f, 0xc8, 0xb2, 0x6c, 0x0, 0x60, 0xdf, 0x59, 0x6, 0x0, 0xbf, 0x69, 0x9a, 0x43, 0x9e, 0xe7, 0x43, 0xeb, 0x1, 0xcf, 0xf3, 0x76, 0x44, 0x34, 0x33, 0x18, 0x9b, 0xb8, 0xae, 0x9b, 0x9a, 0x1c, 0xff, 0x3b, 0x1e, 0x62, 0x14, 0x91, 0x94, 0x88, 0x8c, 0xe5, 0x21, 0xa2, 0x34, 0x8a, 0xa2, 0x75, 0x97, 0x7b, 0x48, 0xa1, 0xaa, 0xaa, 0x8d, 0xd6, 0xda, 0x54, 0x9a, 0x73, 0x5d, 0xd7, 0x5b, 0xab, 0x83, 0xd6, 0xc5, 0xe7, 0x45, 0x2, 0x80, 0x38, 0x8e, 0x4b, 0xad, 0xf5, 0x2, 0xc0, 0x15, 0xc0, 0x8d, 0x99, 0x97, 0xa6, 0x65, 0x2b, 0x94, 0x52, 0x89, 0xed, 0x99, 0xbe, 0xc6, 0x1d, 0x31, 0x1f, 0x40, 0xdc, 0x74, 0x8a, 0x5b, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x59, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x20, 0x11, 0xdc, 0x4f, 0x7f, 0x98, 0x86, 0x47, 0xfa, 0x81, 0xe5, 0x83, 0x1f, 0xf, 0x7e, 0x3d, 0xb2, 0xc5, 0xa5, 0x5b, 0xe2, 0xc1, 0x93, 0x7, 0xff, 0x81, 0xf0, 0xf9, 0x63, 0x69, 0x2c, 0xd2, 0x67, 0x58, 0xef, 0x1f, 0x2, 0x4a, 0x42, 0xe0, 0xf1, 0xdb, 0xec, 0x98, 0xfa, 0x67, 0x2, 0x25, 0xe0, 0xf0, 0xe1, 0x2, 0x86, 0x41, 0x7, 0x30, 0x1d, 0x39, 0x3, 0xbf, 0x37, 0x8f, 0xdd, 0x66, 0x27, 0x29, 0xa0, 0x10, 0x4a, 0x2c, 0xa0, 0x41, 0x8d, 0x1b, 0x3c, 0x4c, 0x3, 0x46, 0x16, 0x69, 0x0, 0x0, 0x87, 0x2a, 0x58, 0xb5, 0x18, 0xe9, 0x80, 0x2c, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char submenu_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x8, 0x6, 0x0, 0x0, 0x0, 0xc4, 0xf, 0xbe, 0x8b, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x64, 0x49, 0x44, 0x41, 0x54, 0x18, 0x95, 0x7d, 0xca, 0x21, 0x12, 0x80, 0x20, 0x14, 0x45, 0xd1, 0xf7, 0x2d, 0x4, 0x36, 0x40, 0x63, 0xa8, 0xba, 0x1f, 0xbb, 0x9d, 0xe5, 0xb8, 0x0, 0xb3, 0xfb, 0xd1, 0xc, 0x8d, 0xd, 0x10, 0x48, 0xcf, 0x22, 0x6, 0xc7, 0xef, 0x6d, 0x77, 0xe6, 0x8, 0x0, 0xa4, 0x94, 0x88, 0x3b, 0x92, 0x4b, 0x8, 0x61, 0xeb, 0x3f, 0xe0, 0x95, 0x88, 0xac, 0x39, 0xe7, 0x49, 0x5, 0x0, 0x2c, 0xc9, 0xbd, 0x94, 0x62, 0x35, 0x0, 0x0, 0x63, 0x6b, 0x6d, 0xfd, 0x3, 0x4f, 0x1a, 0x38, 0x8d, 0x31, 0x51, 0x3, 0x55, 0x44, 0x66, 0xe7, 0x5c, 0xfd, 0x4, 0x24, 0xa3, 0xf7, 0xfe, 0xe8, 0x7f, 0x1, 0xe, 0xc2, 0x1e, 0x10, 0xa, 0xf0, 0x33, 0x4c, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x8, 0x4, 0x0, 0x0, 0x0, 0x6e, 0x6, 0x76, 0x0, 0x0, 0x0, 0x0, 0x2e, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x78, 0xc0, 0xf0, 0xe0, 0x3f, 0x8, 0xde, 0x4f, 0x60, 0x0, 0x3, 0xb8, 0xc0, 0x83, 0x2f, 0xf, 0xb5, 0xe1, 0x2, 0x50, 0x78, 0xf5, 0x5, 0x37, 0xaa, 0xc0, 0xff, 0x87, 0xf3, 0x31, 0x4, 0x30, 0xb5, 0x60, 0x1a, 0x8a, 0x61, 0x2d, 0x0, 0xa6, 0x55, 0x4f, 0xb1, 0x91, 0xd6, 0xa7, 0xae, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char tab_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x8, 0x4, 0x0, 0x0, 0x0, 0x6e, 0x6, 0x76, 0x0, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x2, 0x62, 0x4b, 0x47, 0x44, 0x0, 0x0, 0xaa, 0x8d, 0x23, 0x32, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x1f, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0xc0, 0x4, 0xff, 0x23, 0xff, 0x8b, 0xfc, 0x17, 0xf9, 0x1f, 0x49, 0xac, 0x10, 0x13, 0x3, 0x3, 0x61, 0x53, 0xb0, 0x98, 0x80, 0xc, 0x0, 0xa8, 0x3e, 0x18, 0x31, 0xbe, 0x78, 0xfc, 0x7a, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x8, 0x4, 0x0, 0x0, 0x0, 0x6e, 0x6, 0x76, 0x0, 0x0, 0x0, 0x0, 0x19, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0xc0, 0x2, 0xfe, 0x47, 0xfe, 0x17, 0x1, 0xc2, 0x48, 0xd2, 0x84, 0x10, 0x2, 0x84, 0xb9, 0x98, 0x0, 0x0, 0xbf, 0x67, 0x1d, 0x5, 0x89, 0x9b, 0x48, 0x90, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char tab_behind_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x5a, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, 0x2e, 0x36, 0x43, 0x40, 0x4d, 0x0, 0x0, 0x0, 0x43, 0x40, 0x4c, 0x3e, 0x3c, 0x47, 0x3e, 0x3b, 0x46, 0x31, 0x2f, 0x38, 0x2d, 0x2b, 0x33, 0x3f, 0x3c, 0x47, 0x35, 0x32, 0x3b, 0x5b, 0xb0, 0x1, 0xb7, 0x0, 0x0, 0x0, 0x18, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x1, 0x3, 0x5, 0x8, 0xa, 0xb, 0xc, 0x4, 0x11, 0x19, 0x1f, 0x22, 0x24, 0x15, 0x25, 0x34, 0x3f, 0x46, 0x47, 0x77, 0xf3, 0x7, 0xef, 0xd3, 0x51, 0x5e, 0xca, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x1d, 0xeb, 0x3, 0x71, 0x91, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x6e, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0xb5, 0xcc, 0x49, 0xe, 0x80, 0x20, 0x10, 0x44, 0xd1, 0x2, 0x6c, 0x90, 0x49, 0x26, 0x27, 0xd4, 0xfb, 0x9f, 0x53, 0x63, 0x34, 0x2e, 0x58, 0xfb, 0x97, 0x2f, 0xa9, 0x2, 0x18, 0x17, 0x1d, 0x49, 0xa5, 0x24, 0x75, 0x82, 0x33, 0x80, 0xf5, 0xa4, 0x8d, 0x75, 0xde, 0x3b, 0x6b, 0x34, 0xf5, 0xc, 0x9c, 0x86, 0x10, 0x53, 0x2e, 0x25, 0xa7, 0x18, 0x6, 0xe2, 0x10, 0x3a, 0x8c, 0xd3, 0x5a, 0xaf, 0xd6, 0x69, 0xc, 0x5a, 0x60, 0x36, 0x71, 0xd9, 0xf6, 0xbb, 0x6d, 0x89, 0x66, 0x6, 0xd9, 0x74, 0xec, 0x4f, 0x47, 0xb2, 0x4, 0xe9, 0x72, 0x7d, 0xa1, 0x66, 0x27, 0xa1, 0x7c, 0xf9, 0xa0, 0x78, 0xd5, 0x42, 0x33, 0x69, 0x4e, 0xff, 0x80, 0x13, 0xce, 0x8, 0x12, 0xa9, 0x90, 0xd8, 0x47, 0x93, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x57, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, 0x2e, 0x36, 0x43, 0x40, 0x4d, 0x0, 0x0, 0x0, 0x43, 0x40, 0x4c, 0x3e, 0x3c, 0x47, 0x3e, 0x3b, 0x46, 0x31, 0x2f, 0x38, 0x2d, 0x2b, 0x33, 0x3f, 0x3c, 0x47, 0x91, 0xf8, 0xc4, 0xb2, 0x0, 0x0, 0x0, 0x18, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x1, 0x3, 0x5, 0x8, 0xa, 0xb, 0xc, 0x4, 0x11, 0x19, 0x1f, 0x22, 0x24, 0x15, 0x25, 0x34, 0x3f, 0x46, 0x47, 0x77, 0xf3, 0x7, 0xef, 0xd3, 0x51, 0x5e, 0xca, 0x0, 0x0, 0x0, 0x5a, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0xb5, 0x8c, 0x35, 0x2, 0x80, 0x30, 0x10, 0x4, 0x6f, 0x73, 0xc4, 0x53, 0xf3, 0xff, 0x3f, 0xe2, 0xee, 0x4e, 0x9d, 0xe9, 0x56, 0x41, 0xd8, 0xa1, 0x69, 0x7, 0xd0, 0x43, 0x72, 0x19, 0x3d, 0x37, 0x10, 0x6c, 0x1f, 0x8d, 0x6a, 0x0, 0x2b, 0x25, 0xc1, 0x20, 0xa2, 0x69, 0x98, 0xba, 0xb6, 0x45, 0x9a, 0x2b, 0xbd, 0xe9, 0xd5, 0x69, 0xda, 0x0, 0xa9, 0x94, 0x9f, 0x68, 0x7, 0xc5, 0xd2, 0x50, 0x4a, 0x69, 0x71, 0x18, 0x63, 0xb3, 0x18, 0x7a, 0x71, 0x2e, 0xa3, 0xfd, 0x1b, 0xff, 0xc9, 0xff, 0x34, 0x86, 0x31, 0x3, 0x12, 0xb2, 0x4c, 0x6a, 0xfb, 0x60, 0xc7, 0xdc, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char tab_close_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0xfa, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xcd, 0x92, 0x5f, 0x4a, 0xc4, 0x30, 0x10, 0x87, 0xbf, 0xb1, 0xb9, 0xc2, 0x16, 0x7c, 0x6b, 0xc1, 0xa2, 0x85, 0x7a, 0x4, 0x2d, 0xfe, 0x39, 0xc4, 0x9e, 0x70, 0x4f, 0x61, 0xc5, 0x3d, 0x83, 0x5, 0x95, 0x4, 0xd2, 0x37, 0x5, 0x8f, 0x90, 0x94, 0xf1, 0xc5, 0x4a, 0x76, 0xcd, 0x22, 0xf8, 0xa2, 0xf3, 0x38, 0xc3, 0xef, 0x9b, 0xe4, 0x4b, 0xe0, 0x5f, 0x95, 0xf7, 0x7e, 0xed, 0x9c, 0x2b, 0xf, 0xcd, 0x9d, 0x73, 0xa5, 0xf7, 0x7e, 0x9d, 0xf6, 0x8e, 0xd2, 0xb0, 0x88, 0x6c, 0x8c, 0x31, 0x43, 0xe, 0xe2, 0x9c, 0x2b, 0x8d, 0x31, 0x83, 0x88, 0x6c, 0x52, 0xc8, 0x17, 0x20, 0xc6, 0x38, 0xa8, 0xea, 0x8, 0x74, 0xc6, 0x98, 0xed, 0x34, 0x4d, 0xc7, 0xcb, 0xcc, 0x5a, 0xbb, 0x2a, 0x8a, 0xe2, 0xe, 0xe8, 0x80, 0x17, 0xe0, 0x61, 0x99, 0x49, 0xba, 0xc5, 0x5a, 0xbb, 0xfa, 0xdc, 0x72, 0xe, 0x3c, 0x3, 0xd7, 0x21, 0x84, 0x98, 0xf6, 0x54, 0xf5, 0xaa, 0xae, 0xeb, 0xb7, 0x2c, 0x60, 0x1f, 0x22, 0x22, 0x56, 0x55, 0x23, 0xd0, 0xe6, 0xc2, 0x59, 0x40, 0x2, 0xd9, 0x8a, 0x48, 0xbb, 0x28, 0x50, 0xd5, 0x8b, 0xfd, 0xf0, 0x8e, 0x83, 0x9f, 0x4a, 0x44, 0xb2, 0xcb, 0xbe, 0x1, 0x92, 0x2b, 0xb4, 0xaa, 0x6a, 0x81, 0x27, 0xe0, 0x4, 0xb8, 0x4f, 0xc5, 0x66, 0x1, 0x19, 0x89, 0x97, 0x21, 0x84, 0x5e, 0x55, 0x1f, 0x81, 0xb3, 0x1c, 0x44, 0xe, 0x85, 0x53, 0x61, 0xb9, 0xd7, 0xa9, 0xaa, 0xea, 0x75, 0xe7, 0x4, 0xc6, 0x98, 0x1b, 0x11, 0xe9, 0x80, 0x31, 0xc6, 0xd8, 0xa7, 0xc2, 0x9a, 0xa6, 0x79, 0x9f, 0xe7, 0xf9, 0x16, 0x18, 0x81, 0x53, 0x55, 0xed, 0xb3, 0xa2, 0x7e, 0xf3, 0x95, 0xff, 0xbe, 0x3e, 0x0, 0xbd, 0x2c, 0x93, 0xec, 0xb, 0xe5, 0x4f, 0xb1, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x65, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0xad, 0x90, 0x1, 0x6, 0xc0, 0x30, 0xc, 0x45, 0x77, 0x89, 0xd5, 0x76, 0xb3, 0x9e, 0x7b, 0x65, 0x63, 0xd, 0xf9, 0xbb, 0x48, 0x3b, 0xb3, 0x92, 0x54, 0x42, 0xb1, 0x5, 0x88, 0xf7, 0xc8, 0xcf, 0x9f, 0xfe, 0x1a, 0x8e, 0x14, 0xf4, 0x4e, 0x81, 0x63, 0x87, 0x51, 0x90, 0x28, 0x8, 0x46, 0x42, 0x51, 0x4a, 0x9e, 0x79, 0x43, 0xc5, 0x81, 0x55, 0x6f, 0xbc, 0x34, 0xdc, 0x2b, 0x2e, 0x16, 0xe5, 0x3a, 0xb1, 0xb, 0xb6, 0xca, 0x3, 0x2b, 0xb2, 0xc2, 0xbe, 0xf0, 0x66, 0x71, 0x4f, 0x70, 0x3b, 0x61, 0x14, 0x89, 0x26, 0x71, 0x5d, 0x6c, 0x9f, 0x1e, 0x17, 0x35, 0xae, 0xfa, 0xeb, 0xdc, 0x62, 0xc3, 0x84, 0x2d, 0x77, 0x22, 0xda, 0x98, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char tab_container_bg_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x8a, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3c, 0x3a, 0x44, 0x56, 0x53, 0x61, 0x56, 0x52, 0x60, 0x47, 0x44, 0x52, 0x33, 0x31, 0x39, 0x47, 0x44, 0x50, 0x47, 0x44, 0x51, 0x52, 0x50, 0x5d, 0x51, 0x4f, 0x5d, 0x46, 0x42, 0x4e, 0x42, 0x3e, 0x4a, 0x41, 0x3e, 0x49, 0x51, 0x4e, 0x5b, 0x40, 0x3e, 0x48, 0x4f, 0x4c, 0x59, 0x3f, 0x3d, 0x47, 0x4e, 0x4a, 0x58, 0x3e, 0x3b, 0x46, 0x4b, 0x49, 0x55, 0x3c, 0x3a, 0x44, 0x4a, 0x47, 0x54, 0x3b, 0x39, 0x43, 0x49, 0x46, 0x53, 0x3a, 0x38, 0x42, 0x47, 0x45, 0x50, 0x39, 0x37, 0x40, 0x47, 0x43, 0x50, 0x38, 0x35, 0x3f, 0x36, 0x34, 0x3e, 0x44, 0x42, 0x4d, 0x44, 0x41, 0x4c, 0xff, 0xff, 0xff, 0xe5, 0x37, 0x10, 0x78, 0x0, 0x0, 0x0, 0x15, 0x74, 0x52, 0x4e, 0x53, 0x4, 0xa, 0x11, 0x19, 0x1f, 0x22, 0x24, 0x15, 0x25, 0x34, 0x3f, 0x46, 0x47, 0x48, 0x77, 0xef, 0xef, 0xef, 0x77, 0xef, 0xed, 0xe8, 0xff, 0x76, 0xed, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x2d, 0xcd, 0xda, 0x41, 0x3d, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x93, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x65, 0xcf, 0x47, 0x12, 0x82, 0x40, 0x10, 0x5, 0xd0, 0x9e, 0xc8, 0x44, 0x92, 0x22, 0x41, 0x54, 0x44, 0x40, 0x14, 0xef, 0x7f, 0x3e, 0x7, 0x8a, 0xea, 0x85, 0xbe, 0xe5, 0xaf, 0xea, 0xf0, 0x1, 0x8, 0x65, 0x5c, 0xc8, 0x40, 0x70, 0x46, 0x9, 0x0, 0x89, 0x94, 0x36, 0xd6, 0x79, 0xef, 0xac, 0xd1, 0x2a, 0x22, 0x40, 0x55, 0x9c, 0x14, 0xa7, 0x4d, 0x91, 0xc4, 0x8a, 0x2, 0xd3, 0x69, 0x59, 0xd5, 0x9b, 0xaa, 0x4c, 0x35, 0x3, 0x6e, 0x9a, 0xfa, 0xbc, 0xab, 0x1b, 0xc3, 0x41, 0xd8, 0xf6, 0x82, 0x5a, 0x2b, 0x40, 0xba, 0xeb, 0xd, 0x5d, 0x9d, 0x4, 0xe9, 0xbb, 0x3b, 0xea, 0xfc, 0x1a, 0xf4, 0xf, 0xd4, 0xaf, 0x81, 0x1b, 0x46, 0x34, 0x84, 0x11, 0x61, 0xa7, 0x27, 0x9a, 0xc2, 0x52, 0x6e, 0xe6, 0x17, 0x9a, 0xc3, 0x59, 0xa6, 0xb3, 0xf1, 0xbd, 0x1b, 0xb3, 0xf0, 0x18, 0x55, 0xf9, 0x61, 0xf9, 0x6c, 0x96, 0x63, 0x1e, 0x5e, 0xff, 0x2b, 0xf7, 0x5b, 0xff, 0xb, 0x69, 0x5a, 0x14, 0xfa, 0x84, 0xf6, 0xc2, 0x8, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x87, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3c, 0x3a, 0x44, 0x56, 0x53, 0x61, 0x56, 0x52, 0x60, 0x47, 0x44, 0x52, 0x33, 0x31, 0x39, 0x47, 0x44, 0x50, 0x47, 0x44, 0x51, 0x52, 0x50, 0x5d, 0x51, 0x4f, 0x5d, 0x46, 0x42, 0x4e, 0x42, 0x3e, 0x4a, 0x41, 0x3e, 0x49, 0x51, 0x4e, 0x5b, 0x40, 0x3e, 0x48, 0x4f, 0x4c, 0x59, 0x3f, 0x3d, 0x47, 0x4e, 0x4a, 0x58, 0x3e, 0x3b, 0x46, 0x4b, 0x49, 0x55, 0x3c, 0x3a, 0x44, 0x4a, 0x47, 0x54, 0x3b, 0x39, 0x43, 0x49, 0x46, 0x53, 0x3a, 0x38, 0x42, 0x47, 0x45, 0x50, 0x39, 0x37, 0x40, 0x47, 0x43, 0x50, 0x38, 0x35, 0x3f, 0x36, 0x34, 0x3e, 0x44, 0x42, 0x4d, 0x44, 0x41, 0x4c, 0x3f, 0x38, 0xaa, 0x5e, 0x0, 0x0, 0x0, 0x15, 0x74, 0x52, 0x4e, 0x53, 0x4, 0xa, 0x11, 0x19, 0x1f, 0x22, 0x24, 0x15, 0x25, 0x34, 0x3f, 0x46, 0x47, 0x48, 0x77, 0xef, 0xef, 0xef, 0x77, 0xef, 0xed, 0xe8, 0xff, 0x76, 0xed, 0x0, 0x0, 0x0, 0x65, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x65, 0xcf, 0x45, 0x2, 0x84, 0x30, 0x14, 0x4, 0xd1, 0x2e, 0x1c, 0xee, 0x7f, 0xca, 0xd1, 0xed, 0x28, 0x8d, 0x4b, 0x92, 0x5a, 0xbe, 0xe8, 0x2f, 0xc4, 0x9c, 0x24, 0xcf, 0x15, 0x54, 0xab, 0x78, 0xee, 0x53, 0x30, 0x4a, 0x85, 0xa6, 0xfc, 0xf1, 0x87, 0x11, 0xb2, 0x9a, 0x15, 0x9a, 0x37, 0x13, 0x74, 0xce, 0xb4, 0xd4, 0x77, 0xcb, 0xe, 0xb4, 0x96, 0x99, 0x10, 0x34, 0x81, 0x42, 0x50, 0x21, 0x9d, 0x41, 0x23, 0xf8, 0xc, 0x56, 0xe1, 0x10, 0x9c, 0x40, 0x4e, 0xfe, 0x6e, 0x72, 0x96, 0x7e, 0xd7, 0xdf, 0x3f, 0xb3, 0x79, 0x90, 0xcd, 0xf1, 0xc4, 0x26, 0x1e, 0x8e, 0x78, 0xfc, 0x1, 0xf5, 0x61, 0x3f, 0x44, 0xe8, 0xf1, 0xdd, 0xba, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char tab_current_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x9c, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f, 0x3d, 0x48, 0x5b, 0x58, 0x66, 0x5b, 0x57, 0x65, 0x57, 0x54, 0x62, 0x55, 0x53, 0x62, 0x4a, 0x46, 0x52, 0x46, 0x41, 0x4e, 0x45, 0x41, 0x4d, 0x55, 0x52, 0x60, 0x44, 0x41, 0x4c, 0x53, 0x50, 0x5e, 0x43, 0x40, 0x4b, 0x52, 0x4e, 0x5d, 0x41, 0x3e, 0x4a, 0x4f, 0x4d, 0x5a, 0x3f, 0x3d, 0x48, 0x4e, 0x4b, 0x59, 0x3e, 0x3c, 0x47, 0x4d, 0x4a, 0x58, 0x3d, 0x3b, 0x46, 0x4b, 0x49, 0x54, 0x3c, 0x3a, 0x44, 0x4b, 0x47, 0x54, 0x3b, 0x39, 0x43, 0x3b, 0x39, 0x42, 0x3b, 0x38, 0x43, 0x3b, 0x38, 0x42, 0x3a, 0x37, 0x41, 0x39, 0x37, 0x41, 0x3a, 0x38, 0x41, 0x39, 0x36, 0x3f, 0x38, 0x36, 0x3f, 0x39, 0x36, 0x40, 0x38, 0x36, 0x40, 0x37, 0x35, 0x3e, 0x37, 0x34, 0x3e, 0x36, 0x35, 0x3d, 0x35, 0x32, 0x3b, 0x59, 0xdd, 0xd3, 0xff, 0x0, 0x0, 0x0, 0x11, 0x74, 0x52, 0x4e, 0x53, 0x4, 0xa, 0x11, 0x19, 0x1f, 0x22, 0x24, 0x15, 0x25, 0x34, 0x3f, 0x46, 0x47, 0x48, 0x77, 0xef, 0xef, 0xa3, 0x31, 0x6b, 0xc2, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x33, 0x37, 0xd5, 0x7c, 0x5e, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0xa2, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x45, 0xcd, 0xd9, 0x12, 0x82, 0x30, 0xc, 0x40, 0xd1, 0x0, 0x2d, 0x4b, 0x5b, 0x36, 0x59, 0x44, 0x44, 0x44, 0xa4, 0x68, 0x59, 0x54, 0xfc, 0xff, 0x8f, 0x33, 0x30, 0x4c, 0x3d, 0x93, 0xa7, 0x3b, 0x93, 0x4, 0xc0, 0x30, 0x2d, 0x42, 0x6d, 0x44, 0x89, 0x65, 0x1a, 0x0, 0x86, 0xe3, 0x7a, 0x8c, 0xb, 0xdf, 0x17, 0x9c, 0x79, 0xae, 0x63, 0x80, 0xe9, 0x6, 0x61, 0x7c, 0xd8, 0xc4, 0x61, 0xe0, 0x9a, 0x60, 0x79, 0x51, 0x92, 0x66, 0x9b, 0x34, 0x89, 0x3c, 0xb, 0x8, 0xcb, 0xb3, 0xe3, 0x2e, 0xcb, 0x19, 0x1, 0xca, 0x8b, 0x93, 0x56, 0x70, 0xa, 0xb6, 0x28, 0xcf, 0x5a, 0x29, 0x6c, 0xb0, 0xfd, 0xea, 0xa2, 0x55, 0xfe, 0x1a, 0xea, 0xab, 0x56, 0xaf, 0x41, 0x34, 0x37, 0xad, 0xc1, 0x15, 0xca, 0xdb, 0xbb, 0xd6, 0xe2, 0x51, 0xc2, 0xba, 0x7f, 0xe8, 0xf0, 0x2d, 0x6, 0x29, 0xfb, 0x5e, 0xca, 0xc7, 0x53, 0xca, 0x3d, 0xa8, 0x61, 0x50, 0xc3, 0xa8, 0xc6, 0x41, 0xed, 0x61, 0x9a, 0xa6, 0x19, 0xbd, 0xe6, 0xf7, 0x1e, 0x3e, 0xcb, 0x82, 0x83, 0xbe, 0x18, 0x7e, 0xa1, 0xe5, 0x17, 0x1f, 0xcf, 0x5d, 0x82, 0x6b, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x99, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f, 0x3d, 0x48, 0x5b, 0x58, 0x66, 0x5b, 0x57, 0x65, 0x57, 0x54, 0x62, 0x55, 0x53, 0x62, 0x4a, 0x46, 0x52, 0x46, 0x41, 0x4e, 0x45, 0x41, 0x4d, 0x55, 0x52, 0x60, 0x44, 0x41, 0x4c, 0x53, 0x50, 0x5e, 0x43, 0x40, 0x4b, 0x52, 0x4e, 0x5d, 0x41, 0x3e, 0x4a, 0x4f, 0x4d, 0x5a, 0x3f, 0x3d, 0x48, 0x4e, 0x4b, 0x59, 0x3e, 0x3c, 0x47, 0x4d, 0x4a, 0x58, 0x3d, 0x3b, 0x46, 0x4b, 0x49, 0x54, 0x3c, 0x3a, 0x44, 0x4b, 0x47, 0x54, 0x3b, 0x39, 0x43, 0x3b, 0x39, 0x42, 0x3b, 0x38, 0x43, 0x3b, 0x38, 0x42, 0x3a, 0x37, 0x41, 0x39, 0x37, 0x41, 0x3a, 0x38, 0x41, 0x39, 0x36, 0x3f, 0x38, 0x36, 0x3f, 0x39, 0x36, 0x40, 0x38, 0x36, 0x40, 0x37, 0x35, 0x3e, 0x37, 0x34, 0x3e, 0x36, 0x35, 0x3d, 0xd7, 0x41, 0xa4, 0x19, 0x0, 0x0, 0x0, 0x11, 0x74, 0x52, 0x4e, 0x53, 0x4, 0xa, 0x11, 0x19, 0x1f, 0x22, 0x24, 0x15, 0x25, 0x34, 0x3f, 0x46, 0x47, 0x48, 0x77, 0xef, 0xef, 0xa3, 0x31, 0x6b, 0xc2, 0x0, 0x0, 0x0, 0x60, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x55, 0xca, 0x85, 0xd, 0xc0, 0x40, 0x14, 0xc3, 0x50, 0x27, 0xf7, 0xd5, 0xfd, 0xd7, 0x2d, 0xa6, 0x4c, 0x16, 0x3f, 0xb9, 0xd0, 0x11, 0x90, 0xa3, 0x52, 0x77, 0x49, 0x8e, 0x86, 0xd2, 0x26, 0x16, 0x7b, 0x59, 0x32, 0x68, 0x3, 0x37, 0x5d, 0xe0, 0x59, 0x3b, 0x74, 0x31, 0x67, 0x4b, 0x3b, 0xf, 0x71, 0xe5, 0xe8, 0xf, 0xec, 0xc0, 0x1f, 0x28, 0xf8, 0x2, 0x14, 0xf9, 0x42, 0xa8, 0xfc, 0x21, 0x3b, 0xe4, 0x1, 0x6f, 0x0, 0x18, 0x11, 0xac, 0x99, 0xc0, 0xe, 0x25, 0x22, 0x2d, 0x76, 0xc6, 0x13, 0x1a, 0x8, 0xac, 0x78, 0xfc, 0x1c, 0x70, 0x30, 0x2b, 0xba, 0xe9, 0x31, 0x70, 0xc1, 0x7f, 0x3b, 0x77, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char tab_menu_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x6f, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0x63, 0x60, 0x18, 0x5, 0xa3, 0x80, 0x81, 0x81, 0x11, 0x5d, 0xe0, 0xc1, 0x83, 0x7, 0xff, 0xf1, 0x69, 0x50, 0x50, 0x50, 0x40, 0xd1, 0xc3, 0x44, 0xa9, 0xb, 0xa8, 0x6f, 0x0, 0x23, 0x23, 0x63, 0x3c, 0x3, 0x3, 0xc3, 0x57, 0x2c, 0x6a, 0xbf, 0x33, 0x32, 0x32, 0xa6, 0x63, 0xa8, 0xc7, 0x66, 0xea, 0xfd, 0xfb, 0xf7, 0x35, 0x18, 0x18, 0x18, 0x56, 0x31, 0x32, 0x32, 0xea, 0x42, 0x85, 0x6e, 0x30, 0x33, 0x33, 0x87, 0xc9, 0xca, 0xca, 0x5e, 0x26, 0xca, 0x0, 0x6, 0x6, 0x6, 0x86, 0x17, 0x2f, 0x5e, 0x70, 0xff, 0xfc, 0xf9, 0x73, 0xa, 0x3, 0x3, 0x3, 0x3, 0x3b, 0x3b, 0x7b, 0x8e, 0x84, 0x84, 0x4, 0x36, 0x57, 0xd, 0x2, 0x0, 0x0, 0x67, 0xf2, 0x14, 0xc2, 0xc2, 0xbe, 0xf5, 0xb5, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x36, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x40, 0x5, 0xa3, 0xe0, 0xc1, 0x7f, 0x54, 0x48, 0x3, 0x5, 0xf, 0xe3, 0x1e, 0x7c, 0x81, 0x4b, 0x7f, 0x7b, 0x98, 0x86, 0xc5, 0x15, 0xf7, 0x35, 0xee, 0x5f, 0x2, 0x4b, 0x5f, 0x7f, 0xac, 0x8b, 0xc3, 0xa1, 0x2f, 0xb8, 0x1f, 0xce, 0x7f, 0x38, 0xff, 0x5, 0x37, 0x75, 0xbd, 0xf, 0x0, 0x52, 0xd4, 0x48, 0xb8, 0x2d, 0x78, 0x5a, 0x91, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char tab_menu_hl_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x6f, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0x63, 0x60, 0x18, 0x5, 0xa3, 0x80, 0x81, 0x81, 0x11, 0x5d, 0xe0, 0xc1, 0x83, 0x7, 0xff, 0xf1, 0x69, 0x50, 0x50, 0x50, 0x40, 0xd1, 0xc3, 0x44, 0xa9, 0xb, 0xa8, 0x6f, 0x0, 0x23, 0x23, 0x63, 0x3c, 0x3, 0x3, 0xc3, 0x57, 0x2c, 0x6a, 0xbf, 0x33, 0x32, 0x32, 0xa6, 0x63, 0xa8, 0xc7, 0x66, 0xea, 0xfd, 0xfb, 0xf7, 0x35, 0x18, 0x18, 0x18, 0x56, 0x31, 0x32, 0x32, 0xea, 0x42, 0x85, 0x6e, 0x30, 0x33, 0x33, 0x87, 0xc9, 0xca, 0xca, 0x5e, 0x26, 0xca, 0x0, 0x6, 0x6, 0x6, 0x86, 0x17, 0x2f, 0x5e, 0x70, 0xff, 0xfc, 0xf9, 0x73, 0xa, 0x3, 0x3, 0x3, 0x3, 0x3b, 0x3b, 0x7b, 0x8e, 0x84, 0x84, 0x4, 0x36, 0x57, 0xd, 0x2, 0x0, 0x0, 0x67, 0xf2, 0x14, 0xc2, 0xc2, 0xbe, 0xf5, 0xb5, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x36, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x40, 0x5, 0xa3, 0xe0, 0xc1, 0x7f, 0x54, 0x48, 0x3, 0x5, 0xf, 0xe3, 0x1e, 0x7c, 0x81, 0x4b, 0x7f, 0x7b, 0x98, 0x86, 0xc5, 0x15, 0xf7, 0x35, 0xee, 0x5f, 0x2, 0x4b, 0x5f, 0x7f, 0xac, 0x8b, 0xc3, 0xa1, 0x2f, 0xb8, 0x1f, 0xce, 0x7f, 0x38, 0xff, 0x5, 0x37, 0x75, 0xbd, 0xf, 0x0, 0x52, 0xd4, 0x48, 0xb8, 0x2d, 0x78, 0x5a, 0x91, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char toggle_off_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x20, 0x8, 0x3, 0x0, 0x0, 0x0, 0x95, 0x43, 0x8e, 0xb6, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x1, 0x7a, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x14, 0x14, 0x17, 0x20, 0x20, 0x25, 0x24, 0x24, 0x28, 0x24, 0x24, 0x29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x10, 0x13, 0x22, 0x22, 0x27, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x19, 0x19, 0x1c, 0x1a, 0x1a, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11, 0x11, 0x14, 0x12, 0x12, 0x14, 0x23, 0x23, 0x27, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x15, 0x15, 0x18, 0x20, 0x20, 0x25, 0x20, 0x20, 0x24, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x24, 0x24, 0x28, 0x0, 0x0, 0x0, 0x24, 0x24, 0x28, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x24, 0x24, 0x27, 0x15, 0x15, 0x18, 0x23, 0x23, 0x28, 0x12, 0x12, 0x14, 0x0, 0x0, 0x0, 0x1a, 0x1a, 0x1e, 0x0, 0x0, 0x0, 0x11, 0x11, 0x13, 0x22, 0x22, 0x26, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x24, 0x24, 0x29, 0x25, 0x25, 0x2a, 0x24, 0x24, 0x28, 0x25, 0x25, 0x28, 0x25, 0x25, 0x29, 0x25, 0x25, 0x27, 0x2d, 0x26, 0x2c, 0x4d, 0x2b, 0x37, 0x63, 0x2f, 0x3f, 0x6e, 0x31, 0x43, 0x71, 0x32, 0x44, 0x6c, 0x31, 0x42, 0x51, 0x2c, 0x39, 0x47, 0x2a, 0x35, 0x66, 0x30, 0x40, 0x4d, 0x2b, 0x38, 0x32, 0x26, 0x2e, 0x26, 0x25, 0x2a, 0x2e, 0x25, 0x2c, 0x3c, 0x28, 0x31, 0x52, 0x2c, 0x39, 0x68, 0x30, 0x40, 0x27, 0x25, 0x2a, 0x50, 0x2c, 0x38, 0x5f, 0x2e, 0x3d, 0x35, 0x27, 0x2f, 0x38, 0x27, 0x30, 0x5e, 0x2e, 0x3d, 0x43, 0x2a, 0x34, 0x5f, 0x2f, 0x3e, 0x2f, 0x25, 0x2c, 0x44, 0x2a, 0x34, 0x2b, 0x26, 0x2c, 0x64, 0x2f, 0x3f, 0x36, 0x27, 0x30, 0x37, 0x27, 0x30, 0x66, 0x2f, 0x40, 0x2c, 0x26, 0x2c, 0x46, 0x2a, 0x35, 0x53, 0x2c, 0x39, 0x40, 0x40, 0x44, 0xad, 0xad, 0xaf, 0xff, 0xff, 0xff, 0xf2, 0xf2, 0xf2, 0x77, 0x77, 0x7a, 0x5b, 0x5b, 0x5f, 0x32, 0x32, 0x37, 0x5d, 0x2e, 0x3d, 0x3e, 0x29, 0x32, 0xc9, 0xc9, 0xca, 0xbb, 0xbb, 0xbd, 0x69, 0x69, 0x6c, 0x69, 0x30, 0x41, 0x2f, 0x26, 0x2d, 0x84, 0x84, 0x87, 0xd6, 0xd6, 0xd7, 0x92, 0x92, 0x94, 0xa0, 0xa0, 0xa2, 0x4e, 0x4e, 0x52, 0x48, 0x2b, 0x36, 0x2c, 0x26, 0x2b, 0x97, 0xb0, 0x86, 0xb4, 0x0, 0x0, 0x0, 0x41, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x1, 0x2, 0x3, 0x4, 0x9, 0xe, 0x13, 0x16, 0x18, 0x19, 0xa, 0x26, 0x36, 0x44, 0x4d, 0x52, 0x54, 0x55, 0x6, 0x12, 0x27, 0x43, 0x98, 0xe5, 0xfa, 0xfe, 0x8, 0x17, 0x35, 0x86, 0xf3, 0x7, 0x3a, 0xb4, 0xb9, 0xb, 0x28, 0x8a, 0x8b, 0xf6, 0x45, 0x5, 0x9b, 0xe6, 0xe6, 0x37, 0xf, 0xfb, 0x4c, 0xfe, 0x4e, 0x4f, 0x50, 0xfb, 0x9c, 0xf6, 0x8c, 0x3b, 0xbb, 0x3c, 0x87, 0xf3, 0x53, 0x14, 0xe5, 0x7c, 0xf3, 0x66, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x6b, 0x52, 0x65, 0xa5, 0x98, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x2, 0x47, 0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0xd5, 0x55, 0xfb, 0x5b, 0x93, 0x50, 0x18, 0x96, 0x3, 0xc, 0x48, 0x60, 0xde, 0x70, 0x9b, 0x43, 0x37, 0x75, 0xa6, 0x9b, 0xb5, 0xad, 0x56, 0x59, 0x99, 0xe9, 0xc6, 0x39, 0xb3, 0x56, 0x59, 0xcd, 0x4c, 0xbb, 0xd9, 0x3d, 0xdb, 0xd, 0x74, 0xa6, 0xa3, 0xdb, 0xff, 0x1e, 0x70, 0x68, 0x6e, 0xc0, 0xe0, 0xe9, 0xe9, 0x97, 0x7a, 0x79, 0x9e, 0x3, 0xf, 0x7c, 0xdf, 0xcb, 0x7b, 0xbe, 0xf3, 0x5d, 0x86, 0x86, 0xfe, 0x21, 0x10, 0x80, 0x24, 0xa9, 0x40, 0x90, 0x24, 0x20, 0x3c, 0xdd, 0x1, 0x45, 0x87, 0x18, 0x96, 0x3b, 0x17, 0x0, 0x8e, 0x65, 0x42, 0x34, 0x5, 0xdc, 0x7f, 0xa7, 0x86, 0x59, 0x5e, 0x10, 0xc3, 0x23, 0xa3, 0x63, 0xbe, 0x18, 0x1d, 0x9, 0x8b, 0x2, 0xcf, 0xe, 0x53, 0xe, 0x15, 0x60, 0x7c, 0x42, 0x9a, 0x8c, 0x44, 0x63, 0x53, 0xc5, 0x52, 0x0, 0x8a, 0x53, 0xb1, 0x68, 0x64, 0x52, 0x9a, 0x18, 0xef, 0x13, 0x1, 0xe2, 0xf2, 0xf4, 0x4c, 0x42, 0x81, 0x10, 0x21, 0x84, 0xed, 0x90, 0x9, 0x88, 0xca, 0xc8, 0x93, 0x24, 0x31, 0x33, 0x2d, 0xc7, 0x7b, 0x18, 0x88, 0x24, 0x37, 0x3b, 0xa7, 0xc0, 0xcd, 0x3b, 0x77, 0x2b, 0xf7, 0x30, 0xee, 0x3f, 0xd8, 0xb4, 0x58, 0xca, 0x70, 0x80, 0x8e, 0xb9, 0x59, 0x2e, 0x49, 0x9c, 0xed, 0x9f, 0x11, 0xe6, 0x15, 0xb4, 0xf5, 0xf0, 0xd1, 0xe3, 0xaa, 0xf5, 0xb9, 0xba, 0xfd, 0x64, 0xe7, 0xe9, 0xd6, 0xae, 0xa5, 0x64, 0xd0, 0x4e, 0xe6, 0x5, 0xa6, 0x1b, 0x7, 0x90, 0x5a, 0x38, 0xaf, 0xa0, 0xbd, 0x67, 0xcf, 0x7b, 0x2d, 0x5e, 0xbc, 0xdc, 0xdb, 0xf5, 0x8d, 0xc5, 0xe2, 0x42, 0xea, 0xf7, 0x26, 0x28, 0x59, 0x5c, 0x82, 0xaf, 0xf6, 0xb7, 0xfb, 0x2d, 0x5e, 0xef, 0xbf, 0xa9, 0xfa, 0x31, 0x2c, 0xa5, 0xe5, 0xc, 0x96, 0x40, 0xd0, 0xfc, 0x32, 0x7c, 0xfb, 0xee, 0xbd, 0xd3, 0xe2, 0xc3, 0xc7, 0x4f, 0xbe, 0xe7, 0xb1, 0xcc, 0xd3, 0x98, 0x0, 0x84, 0x84, 0xb, 0xf0, 0x60, 0xc7, 0x6d, 0xf1, 0xf9, 0xc0, 0x7e, 0xa8, 0xd5, 0x1b, 0xcd, 0x56, 0x49, 0x6d, 0x18, 0xb0, 0x16, 0xcd, 0x7a, 0x7b, 0x31, 0x9b, 0xc3, 0x7b, 0x20, 0x19, 0x31, 0x86, 0xe, 0x8f, 0xdc, 0x4, 0x47, 0x87, 0xf6, 0x43, 0xfb, 0xb8, 0xf6, 0xa5, 0x51, 0x53, 0x4d, 0x47, 0xd5, 0xf6, 0x36, 0x90, 0x4f, 0x33, 0x24, 0x26, 0x60, 0x2f, 0x5d, 0x46, 0x27, 0xa7, 0x6e, 0x82, 0xd3, 0x13, 0x5b, 0x80, 0xe9, 0x74, 0xdc, 0x51, 0x75, 0x93, 0x40, 0xef, 0x12, 0x14, 0xb, 0x2c, 0x85, 0x9, 0xe4, 0x2b, 0xa, 0xaa, 0x78, 0x4, 0xac, 0x5a, 0xc1, 0x77, 0x55, 0x37, 0x96, 0xaf, 0x75, 0xb5, 0xdd, 0x6e, 0x6b, 0xd6, 0x62, 0x7f, 0xbf, 0x2a, 0xdb, 0x4, 0x6c, 0x58, 0xf1, 0x55, 0xa0, 0x99, 0xa, 0xea, 0xdf, 0x54, 0xd3, 0x53, 0x6d, 0x7b, 0x28, 0x60, 0xc4, 0x6b, 0xd0, 0x37, 0x6, 0x7a, 0xa7, 0xa4, 0x35, 0x5b, 0x4e, 0x82, 0x6e, 0xc, 0x40, 0x28, 0x1b, 0x70, 0xa, 0x6a, 0x53, 0x6f, 0xd6, 0x4b, 0x4e, 0x82, 0xee, 0x29, 0x18, 0x79, 0xb0, 0x12, 0x90, 0x7, 0x5a, 0xe7, 0xbb, 0x11, 0xcb, 0x96, 0x66, 0x2f, 0x18, 0x2b, 0x92, 0x9d, 0x7, 0x66, 0x26, 0x5e, 0x47, 0x7f, 0x91, 0x89, 0x66, 0x2d, 0x2c, 0xfe, 0x79, 0x2d, 0xdc, 0x38, 0xab, 0x5, 0xef, 0x6a, 0xfc, 0xe1, 0xef, 0xdf, 0x5b, 0x8d, 0x66, 0x3f, 0xb8, 0xb9, 0xaa, 0xc0, 0x9f, 0xce, 0x7e, 0xe0, 0xe3, 0xbf, 0x7a, 0xab, 0xa7, 0x1f, 0x98, 0x1d, 0x89, 0x13, 0xd6, 0x6e, 0xc3, 0x32, 0xc4, 0xd, 0x9, 0xd9, 0x80, 0xc6, 0xe5, 0xe9, 0x9f, 0x58, 0x13, 0xb8, 0x78, 0x7f, 0x4f, 0x4b, 0x32, 0x92, 0x18, 0x89, 0xe6, 0x3, 0x5b, 0xa2, 0xf1, 0xf3, 0x7c, 0x34, 0x22, 0x4a, 0x4c, 0xd2, 0xd1, 0x98, 0x9, 0x2a, 0xc5, 0xf2, 0xd9, 0x74, 0x61, 0x7d, 0x2c, 0x0, 0xeb, 0x85, 0x74, 0x96, 0x67, 0x53, 0x94, 0x6b, 0x36, 0x10, 0x20, 0x43, 0xe7, 0x36, 0xe4, 0xe0, 0xb9, 0x20, 0x6f, 0xe4, 0xe8, 0x8c, 0xf7, 0x6c, 0x31, 0x26, 0x53, 0xf0, 0x60, 0x32, 0x46, 0xd3, 0x80, 0xc9, 0xf4, 0xff, 0xe2, 0x17, 0x82, 0xde, 0x40, 0xde, 0x2d, 0xc3, 0x2a, 0xca, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x20, 0x8, 0x3, 0x0, 0x0, 0x0, 0x95, 0x43, 0x8e, 0xb6, 0x0, 0x0, 0x1, 0x7a, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x14, 0x14, 0x17, 0x20, 0x20, 0x25, 0x24, 0x24, 0x28, 0x24, 0x24, 0x29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x10, 0x13, 0x22, 0x22, 0x27, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x19, 0x19, 0x1c, 0x1a, 0x1a, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11, 0x11, 0x14, 0x12, 0x12, 0x14, 0x23, 0x23, 0x27, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x15, 0x15, 0x18, 0x20, 0x20, 0x25, 0x20, 0x20, 0x24, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x24, 0x24, 0x28, 0x0, 0x0, 0x0, 0x24, 0x24, 0x28, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x24, 0x24, 0x27, 0x15, 0x15, 0x18, 0x23, 0x23, 0x28, 0x12, 0x12, 0x14, 0x0, 0x0, 0x0, 0x1a, 0x1a, 0x1e, 0x0, 0x0, 0x0, 0x11, 0x11, 0x13, 0x22, 0x22, 0x26, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x24, 0x24, 0x29, 0x25, 0x25, 0x2a, 0x24, 0x24, 0x28, 0x25, 0x25, 0x28, 0x25, 0x25, 0x29, 0x25, 0x25, 0x27, 0x2d, 0x26, 0x2c, 0x4d, 0x2b, 0x37, 0x63, 0x2f, 0x3f, 0x6e, 0x31, 0x43, 0x71, 0x32, 0x44, 0x6c, 0x31, 0x42, 0x51, 0x2c, 0x39, 0x47, 0x2a, 0x35, 0x66, 0x30, 0x40, 0x4d, 0x2b, 0x38, 0x32, 0x26, 0x2e, 0x26, 0x25, 0x2a, 0x2e, 0x25, 0x2c, 0x3c, 0x28, 0x31, 0x52, 0x2c, 0x39, 0x68, 0x30, 0x40, 0x27, 0x25, 0x2a, 0x50, 0x2c, 0x38, 0x5f, 0x2e, 0x3d, 0x35, 0x27, 0x2f, 0x38, 0x27, 0x30, 0x5e, 0x2e, 0x3d, 0x43, 0x2a, 0x34, 0x5f, 0x2f, 0x3e, 0x2f, 0x25, 0x2c, 0x44, 0x2a, 0x34, 0x2b, 0x26, 0x2c, 0x64, 0x2f, 0x3f, 0x36, 0x27, 0x30, 0x37, 0x27, 0x30, 0x66, 0x2f, 0x40, 0x2c, 0x26, 0x2c, 0x46, 0x2a, 0x35, 0x53, 0x2c, 0x39, 0x40, 0x40, 0x44, 0xad, 0xad, 0xaf, 0xff, 0xff, 0xff, 0xf2, 0xf2, 0xf2, 0x77, 0x77, 0x7a, 0x5b, 0x5b, 0x5f, 0x32, 0x32, 0x37, 0x5d, 0x2e, 0x3d, 0x3e, 0x29, 0x32, 0xc9, 0xc9, 0xca, 0xbb, 0xbb, 0xbd, 0x69, 0x69, 0x6c, 0x69, 0x30, 0x41, 0x2f, 0x26, 0x2d, 0x84, 0x84, 0x87, 0xd6, 0xd6, 0xd7, 0x92, 0x92, 0x94, 0xa0, 0xa0, 0xa2, 0x4e, 0x4e, 0x52, 0x48, 0x2b, 0x36, 0x2c, 0x26, 0x2b, 0x97, 0xb0, 0x86, 0xb4, 0x0, 0x0, 0x0, 0x41, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x1, 0x2, 0x3, 0x4, 0x9, 0xe, 0x13, 0x16, 0x18, 0x19, 0xa, 0x26, 0x36, 0x44, 0x4d, 0x52, 0x54, 0x55, 0x6, 0x12, 0x27, 0x43, 0x98, 0xe5, 0xfa, 0xfe, 0x8, 0x17, 0x35, 0x86, 0xf3, 0x7, 0x3a, 0xb4, 0xb9, 0xb, 0x28, 0x8a, 0x8b, 0xf6, 0x45, 0x5, 0x9b, 0xe6, 0xe6, 0x37, 0xf, 0xfb, 0x4c, 0xfe, 0x4e, 0x4f, 0x50, 0xfb, 0x9c, 0xf6, 0x8c, 0x3b, 0xbb, 0x3c, 0x87, 0xf3, 0x53, 0x14, 0xe5, 0x7c, 0xf3, 0x66, 0x0, 0x0, 0x2, 0x29, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0xdd, 0x95, 0x3, 0x93, 0x24, 0x4b, 0x14, 0x85, 0x5f, 0xb9, 0xaa, 0x6d, 0x8e, 0x6d, 0xdb, 0x73, 0x2b, 0xb3, 0xe7, 0xad, 0x6d, 0xab, 0xdd, 0x63, 0xe3, 0xbf, 0x6f, 0x67, 0x65, 0xbb, 0xb4, 0xbb, 0x81, 0xc5, 0x97, 0x11, 0x27, 0x78, 0x4f, 0xea, 0xe2, 0xbf, 0x3f, 0x9, 0x86, 0xe5, 0x38, 0xde, 0x16, 0x8e, 0x63, 0x19, 0xc3, 0x70, 0x96, 0x17, 0x44, 0x49, 0x56, 0x1c, 0x36, 0x28, 0xb2, 0x24, 0xa, 0x3c, 0xab, 0xdf, 0x9d, 0x77, 0xca, 0x2e, 0xb7, 0xc7, 0xeb, 0xf3, 0x7, 0x2c, 0xf1, 0xfb, 0xbc, 0x1e, 0xb7, 0x4b, 0x76, 0xf2, 0x2d, 0xa7, 0x60, 0x83, 0xa1, 0x70, 0x24, 0x1a, 0x8b, 0x27, 0xb6, 0xc1, 0x86, 0xed, 0x44, 0x3c, 0x16, 0x8d, 0x84, 0x43, 0x41, 0xb6, 0x29, 0x3e, 0xd9, 0xd6, 0xde, 0xd1, 0xa9, 0x22, 0x84, 0x31, 0x6, 0xd, 0x4c, 0x40, 0x38, 0x85, 0xd, 0x4d, 0x3a, 0x3b, 0xda, 0xdb, 0x92, 0xd, 0xe, 0x4c, 0x97, 0xd2, 0xdd, 0xa3, 0xa2, 0x9d, 0xff, 0x6f, 0xdd, 0xbe, 0x43, 0xb9, 0x7b, 0x6f, 0x47, 0x73, 0x49, 0x21, 0x93, 0x73, 0xf4, 0x74, 0x2b, 0x5d, 0x4c, 0xfd, 0xfe, 0x92, 0xbb, 0x57, 0xc5, 0xf7, 0x1f, 0x3c, 0x7c, 0xf4, 0x18, 0x8, 0x8f, 0x9f, 0x3c, 0x7d, 0xf6, 0xfc, 0xfe, 0xb, 0xed, 0x24, 0x66, 0x37, 0xe9, 0x75, 0x4b, 0xb5, 0x77, 0x60, 0xfb, 0xfa, 0x7, 0x54, 0xfc, 0xf2, 0xd5, 0x6b, 0x68, 0xe0, 0xcd, 0xdb, 0x97, 0x2f, 0x2c, 0xdf, 0x62, 0xb0, 0xbf, 0xaf, 0x7a, 0x9, 0xbe, 0xcd, 0x33, 0x84, 0xde, 0xbd, 0x7f, 0x2, 0x4d, 0x7c, 0x78, 0xff, 0xf1, 0x31, 0x58, 0x30, 0x34, 0xdc, 0x36, 0x42, 0x8f, 0xc0, 0x8, 0xae, 0x51, 0xf4, 0xe9, 0xf3, 0x17, 0x68, 0xe1, 0xeb, 0xb7, 0x34, 0x58, 0x31, 0xea, 0x12, 0xa8, 0x1, 0x2b, 0xba, 0xc7, 0x50, 0xe6, 0x19, 0xe8, 0xc8, 0x66, 0x80, 0x92, 0xcb, 0x17, 0x8a, 0x25, 0xd8, 0x2d, 0x94, 0xd1, 0x64, 0xf, 0x8, 0xe3, 0x13, 0x93, 0xf4, 0xe, 0x9c, 0xe4, 0x89, 0xe3, 0xfd, 0x3, 0xd0, 0x71, 0xb0, 0xf, 0x94, 0xc3, 0xa3, 0xdc, 0x71, 0x21, 0xb7, 0x4b, 0x2, 0x35, 0xa1, 0x4c, 0xd, 0x4b, 0x1c, 0x35, 0x90, 0xa7, 0x67, 0xf0, 0xc9, 0x29, 0xe8, 0x38, 0x3d, 0xa9, 0x1c, 0x80, 0x4, 0x1d, 0x9d, 0xed, 0x9e, 0x13, 0x3, 0x22, 0x94, 0xed, 0x59, 0x99, 0xa7, 0x6, 0x6d, 0x73, 0x2a, 0xbe, 0x6d, 0xf0, 0x60, 0x8f, 0x6f, 0x13, 0x25, 0x41, 0x65, 0xb9, 0xc8, 0xef, 0x1e, 0x1e, 0x1e, 0xee, 0x69, 0x2, 0x94, 0xf9, 0xb6, 0x8a, 0x81, 0xec, 0x55, 0x2d, 0x4f, 0xb0, 0x47, 0x4e, 0x90, 0xbf, 0xdc, 0x25, 0x91, 0x44, 0x74, 0x27, 0x90, 0x3c, 0xb, 0xc8, 0xf2, 0xd, 0xce, 0xcf, 0x60, 0xaf, 0x58, 0xaa, 0x18, 0xe8, 0xdf, 0x80, 0x15, 0x27, 0x6c, 0x7e, 0x61, 0xb7, 0x78, 0x5e, 0xcc, 0x43, 0xab, 0x1, 0xfd, 0x5, 0x9a, 0x7, 0x8b, 0x36, 0x79, 0xb0, 0x77, 0x76, 0x5, 0x90, 0x2b, 0xed, 0x55, 0x84, 0xb2, 0x18, 0x16, 0x98, 0x5a, 0x26, 0x2e, 0xe1, 0x5f, 0xce, 0x44, 0x5a, 0xb, 0x83, 0x3f, 0x5f, 0xb, 0xcb, 0xb4, 0x16, 0xcc, 0xab, 0xf1, 0x9a, 0xc6, 0xdb, 0x57, 0x23, 0xed, 0x7, 0x2b, 0xab, 0x2a, 0xba, 0x69, 0xed, 0x7, 0xe6, 0x6c, 0xaf, 0xae, 0xd5, 0xfa, 0x1, 0xed, 0x48, 0x8a, 0x7b, 0x7d, 0x3, 0xa5, 0x10, 0x6d, 0x48, 0xb8, 0x2, 0x2a, 0x2f, 0x30, 0xa2, 0x73, 0xdd, 0xad, 0x24, 0x9b, 0x7b, 0x5a, 0x97, 0x14, 0xf6, 0x44, 0x63, 0x53, 0xdb, 0x60, 0xcb, 0xf6, 0x54, 0x2c, 0xea, 0x9, 0x4b, 0x5d, 0x6c, 0x6b, 0x57, 0xee, 0x93, 0x5d, 0x13, 0xc3, 0xb3, 0x9b, 0x1, 0x1b, 0x36, 0x67, 0x87, 0x27, 0x5c, 0x72, 0x1f, 0xcf, 0xe8, 0xa7, 0xca, 0x88, 0x30, 0xb9, 0xd5, 0x66, 0x3f, 0x17, 0xda, 0xb6, 0x26, 0x85, 0x11, 0x96, 0x31, 0x99, 0x4c, 0xfc, 0xf, 0x40, 0x27, 0xd3, 0xbf, 0xc4, 0x77, 0x82, 0xde, 0x40, 0xde, 0x4b, 0x3f, 0xe2, 0x98, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char toggle_on_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x20, 0x8, 0x3, 0x0, 0x0, 0x0, 0x95, 0x43, 0x8e, 0xb6, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x1, 0x74, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0xd, 0xf, 0x1a, 0x1a, 0x1e, 0x20, 0x20, 0x24, 0x22, 0x22, 0x27, 0x24, 0x24, 0x29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0xa, 0xc, 0x1d, 0x1d, 0x21, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11, 0x11, 0x14, 0x23, 0x23, 0x28, 0x12, 0x12, 0x15, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0xb, 0xd, 0x23, 0x23, 0x28, 0xb, 0xb, 0xd, 0x1e, 0x1e, 0x22, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0xe, 0x10, 0x1a, 0x1a, 0x1e, 0x1a, 0x1a, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x20, 0x24, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0xe, 0x10, 0xb, 0xb, 0xd, 0x0, 0x0, 0x0, 0x13, 0x13, 0x15, 0x0, 0x0, 0x0, 0xb, 0xb, 0xc, 0x1d, 0x1d, 0x21, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x25, 0x25, 0x2a, 0x24, 0x24, 0x29, 0x25, 0x2c, 0x36, 0x27, 0x49, 0x65, 0x29, 0x5d, 0x85, 0x2a, 0x66, 0x95, 0x2a, 0x68, 0x99, 0x29, 0x64, 0x92, 0x28, 0x4c, 0x6b, 0x25, 0x27, 0x2d, 0x27, 0x43, 0x5c, 0x29, 0x5f, 0x89, 0x27, 0x49, 0x66, 0x25, 0x30, 0x3e, 0x25, 0x26, 0x2d, 0x25, 0x25, 0x2b, 0x25, 0x26, 0x2c, 0x25, 0x2d, 0x38, 0x25, 0x3a, 0x4c, 0x27, 0x4d, 0x6b, 0x29, 0x60, 0x8c, 0x27, 0x44, 0x5c, 0x27, 0x4b, 0x69, 0x28, 0x59, 0x7f, 0x25, 0x34, 0x43, 0x25, 0x35, 0x45, 0x28, 0x58, 0x7f, 0x25, 0x26, 0x2b, 0x27, 0x40, 0x57, 0x27, 0x41, 0x57, 0x25, 0x2a, 0x33, 0x29, 0x5d, 0x87, 0x25, 0x34, 0x44, 0x25, 0x2b, 0x34, 0x40, 0x40, 0x44, 0xad, 0xad, 0xaf, 0xff, 0xff, 0xff, 0xf2, 0xf2, 0xf2, 0x77, 0x77, 0x7a, 0x5b, 0x5b, 0x5f, 0x4e, 0x4e, 0x52, 0xc9, 0xc9, 0xca, 0x27, 0x43, 0x5b, 0x27, 0x4d, 0x6c, 0x27, 0x4e, 0x6d, 0xbb, 0xbb, 0xbd, 0x69, 0x69, 0x6c, 0x28, 0x56, 0x7b, 0x26, 0x3b, 0x4e, 0x26, 0x3a, 0x4e, 0x32, 0x32, 0x37, 0x84, 0x84, 0x87, 0xd6, 0xd6, 0xd7, 0x29, 0x61, 0x8d, 0x25, 0x2e, 0x39, 0x92, 0x92, 0x94, 0xa0, 0xa0, 0xa2, 0xe4, 0xe4, 0xe5, 0x27, 0x44, 0x5d, 0xdd, 0xc9, 0xf2, 0x7e, 0x0, 0x0, 0x0, 0x41, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x1, 0x2, 0x3, 0x4, 0x9, 0xe, 0x13, 0x16, 0x18, 0x19, 0xa, 0x26, 0x36, 0x44, 0x4d, 0x52, 0x54, 0x55, 0x6, 0x12, 0x27, 0x43, 0x80, 0xc5, 0xe7, 0xf5, 0xfe, 0x8, 0x17, 0x35, 0x73, 0xd9, 0x7, 0x3a, 0x96, 0xf9, 0x9a, 0xb, 0x28, 0x76, 0xfb, 0x77, 0xde, 0x45, 0x5, 0x82, 0xc6, 0xc6, 0x37, 0xf, 0xe9, 0x4c, 0x4e, 0x4f, 0x50, 0x83, 0x78, 0x3b, 0x9c, 0x3c, 0x74, 0xda, 0x53, 0x14, 0x37, 0x21, 0x5a, 0x6c, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x65, 0xb5, 0xdd, 0x88, 0x9f, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x4, 0x4e, 0x1d, 0x2, 0xaf, 0x0, 0x0, 0x2, 0x28, 0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0xd5, 0x55, 0x69, 0x57, 0xd3, 0x40, 0x14, 0x25, 0x93, 0xa4, 0x49, 0x24, 0x49, 0xd9, 0x42, 0xd7, 0x0, 0x85, 0x50, 0x2c, 0xb4, 0x68, 0x5b, 0xab, 0x28, 0xb2, 0xc, 0x4b, 0x95, 0x82, 0x56, 0xab, 0x42, 0x45, 0x5c, 0x9b, 0xad, 0x45, 0x11, 0x6d, 0x3, 0xa8, 0x7f, 0xde, 0xc4, 0x94, 0x26, 0x69, 0x30, 0x89, 0xc7, 0x2f, 0x7a, 0x3f, 0xe4, 0x9c, 0xcc, 0x3b, 0xef, 0xce, 0x7d, 0x6f, 0xde, 0x32, 0x30, 0xf0, 0xf, 0x1, 0x1, 0x28, 0x8a, 0xf9, 0x2, 0x45, 0x1, 0x72, 0xa5, 0x3b, 0xc0, 0xf0, 0x10, 0x41, 0x52, 0xd7, 0x7c, 0x40, 0x91, 0x44, 0x8, 0xc7, 0x80, 0xfb, 0x76, 0x6c, 0x90, 0xa4, 0x19, 0x36, 0x3c, 0x34, 0x3c, 0xe2, 0x89, 0xe1, 0xa1, 0x30, 0xcb, 0xd0, 0xe4, 0x20, 0xd6, 0xa7, 0x2, 0x8c, 0x8e, 0x71, 0xe3, 0x91, 0x68, 0x2c, 0x9e, 0x80, 0x3e, 0x48, 0xc4, 0x63, 0xd1, 0xc8, 0x38, 0x37, 0x36, 0xea, 0x10, 0x1, 0x92, 0xfc, 0xc4, 0xe4, 0xd4, 0x86, 0x9f, 0xf3, 0x25, 0x36, 0xa6, 0x26, 0x27, 0xf8, 0xa4, 0x8d, 0x1, 0x49, 0x51, 0xd3, 0x33, 0x82, 0xa7, 0xcf, 0xe6, 0xd6, 0x76, 0xf9, 0x81, 0x89, 0x87, 0x3b, 0x9b, 0x50, 0x98, 0x99, 0xa6, 0x52, 0x88, 0x15, 0x3f, 0xc1, 0xcc, 0x7a, 0x6a, 0xaf, 0xec, 0xee, 0x3d, 0x7a, 0x5c, 0x7d, 0x62, 0xe0, 0x69, 0xed, 0xd9, 0xf3, 0x17, 0xfb, 0x95, 0xc4, 0x2c, 0x43, 0xf4, 0xf2, 0x0, 0xd2, 0x73, 0xd7, 0x33, 0x9e, 0xfe, 0x7, 0xf5, 0x97, 0xf6, 0xff, 0xc3, 0x57, 0x7, 0x95, 0xcc, 0xfc, 0x5c, 0xfa, 0x32, 0x8, 0x8c, 0x67, 0x17, 0xbc, 0xfc, 0x8f, 0x5e, 0xd7, 0x6b, 0xce, 0x93, 0x5a, 0xfd, 0xcd, 0xd1, 0x42, 0x96, 0xcf, 0x99, 0x12, 0x10, 0x9c, 0x5e, 0xf4, 0x8c, 0xff, 0xed, 0xbb, 0xf7, 0xfd, 0x47, 0x87, 0x7b, 0x1f, 0xe0, 0x22, 0x8d, 0x9b, 0x4, 0x20, 0xc4, 0xdc, 0xb0, 0x4c, 0xd, 0x51, 0x92, 0x15, 0xa8, 0x4a, 0x4d, 0xa8, 0xb6, 0xba, 0x47, 0xc7, 0x1f, 0xdd, 0xa4, 0x9f, 0x8e, 0xe1, 0xcd, 0x7c, 0xc1, 0x8c, 0x1, 0x25, 0xd8, 0x98, 0x65, 0x69, 0x9d, 0x34, 0x3e, 0x4b, 0xd, 0x55, 0x6a, 0x59, 0x4, 0xa7, 0x5f, 0xdc, 0x4, 0x5f, 0x4f, 0x61, 0x31, 0x4b, 0xa0, 0x26, 0x1, 0x79, 0x2b, 0x6e, 0x9, 0x90, 0xda, 0x10, 0x9e, 0x74, 0x54, 0x4d, 0x56, 0x7b, 0x4, 0x67, 0xe7, 0x6e, 0x82, 0xf3, 0x33, 0x28, 0x94, 0x48, 0xcc, 0x24, 0xe0, 0x6f, 0x5b, 0x6f, 0xa8, 0x6a, 0xfa, 0xe7, 0x42, 0x54, 0x5b, 0x17, 0x5a, 0x8f, 0xa0, 0x5c, 0x75, 0x13, 0x54, 0xcb, 0x10, 0xde, 0xe1, 0xbb, 0x4, 0x64, 0xd8, 0x2a, 0xa2, 0xb6, 0xa1, 0x40, 0xfc, 0xa6, 0x3b, 0x7f, 0x17, 0x3, 0x2b, 0x20, 0xd8, 0xa2, 0x65, 0xd1, 0x3a, 0xb0, 0x2d, 0x2b, 0x3a, 0x81, 0x22, 0x5, 0xcd, 0x1, 0x8, 0xe5, 0x6d, 0xaf, 0xa0, 0xca, 0x9a, 0x2c, 0xfe, 0x4a, 0xa0, 0x16, 0xf4, 0x15, 0xf4, 0x3a, 0x58, 0xb2, 0x99, 0xda, 0x9d, 0xa6, 0x9e, 0x4b, 0x5, 0xc2, 0xa6, 0xe2, 0x5d, 0x7, 0x4b, 0x5c, 0xb7, 0xe, 0xfe, 0xba, 0x12, 0x8d, 0x5e, 0x98, 0xff, 0xf3, 0x5e, 0xb8, 0x6b, 0xf5, 0x42, 0x80, 0x6e, 0xdc, 0x77, 0x76, 0xe3, 0xf, 0x67, 0x37, 0x1a, 0xf3, 0xe0, 0xde, 0xb2, 0xa7, 0x86, 0xfe, 0x79, 0x90, 0x59, 0xbe, 0x6f, 0x9b, 0x7, 0xc6, 0x44, 0xa2, 0x98, 0x95, 0x55, 0x18, 0x18, 0xab, 0x2b, 0xc, 0x95, 0x74, 0xce, 0xb4, 0x14, 0xc1, 0xb1, 0x91, 0x68, 0x51, 0xf0, 0x77, 0x16, 0x8a, 0xd1, 0x8, 0xcb, 0x11, 0xa9, 0xbe, 0xc1, 0x8c, 0x60, 0x69, 0x92, 0xce, 0x67, 0x4b, 0x6b, 0x23, 0x3e, 0x58, 0x2b, 0x65, 0xf3, 0x34, 0x99, 0xc6, 0x5c, 0xbb, 0x1, 0x1, 0x39, 0xbc, 0xb0, 0xce, 0xfb, 0xef, 0x5, 0x7e, 0xbd, 0x80, 0xe7, 0xae, 0xde, 0x2d, 0xfa, 0x66, 0xf2, 0x5f, 0x4c, 0xfa, 0x6a, 0xfa, 0xcd, 0x66, 0xfa, 0x7f, 0xf1, 0x13, 0xb7, 0x71, 0x36, 0xc6, 0x87, 0x41, 0xd4, 0x5, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x20, 0x8, 0x3, 0x0, 0x0, 0x0, 0x95, 0x43, 0x8e, 0xb6, 0x0, 0x0, 0x1, 0x74, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0xd, 0xf, 0x1a, 0x1a, 0x1e, 0x20, 0x20, 0x24, 0x22, 0x22, 0x27, 0x24, 0x24, 0x29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0xa, 0xc, 0x1d, 0x1d, 0x21, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11, 0x11, 0x14, 0x23, 0x23, 0x28, 0x12, 0x12, 0x15, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0xb, 0xd, 0x23, 0x23, 0x28, 0xb, 0xb, 0xd, 0x1e, 0x1e, 0x22, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0xe, 0x10, 0x1a, 0x1a, 0x1e, 0x1a, 0x1a, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x20, 0x24, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0xe, 0x10, 0xb, 0xb, 0xd, 0x0, 0x0, 0x0, 0x13, 0x13, 0x15, 0x0, 0x0, 0x0, 0xb, 0xb, 0xc, 0x1d, 0x1d, 0x21, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x25, 0x25, 0x2a, 0x24, 0x24, 0x29, 0x25, 0x2c, 0x36, 0x27, 0x49, 0x65, 0x29, 0x5d, 0x85, 0x2a, 0x66, 0x95, 0x2a, 0x68, 0x99, 0x29, 0x64, 0x92, 0x28, 0x4c, 0x6b, 0x25, 0x27, 0x2d, 0x27, 0x43, 0x5c, 0x29, 0x5f, 0x89, 0x27, 0x49, 0x66, 0x25, 0x30, 0x3e, 0x25, 0x26, 0x2d, 0x25, 0x25, 0x2b, 0x25, 0x26, 0x2c, 0x25, 0x2d, 0x38, 0x25, 0x3a, 0x4c, 0x27, 0x4d, 0x6b, 0x29, 0x60, 0x8c, 0x27, 0x44, 0x5c, 0x27, 0x4b, 0x69, 0x28, 0x59, 0x7f, 0x25, 0x34, 0x43, 0x25, 0x35, 0x45, 0x28, 0x58, 0x7f, 0x25, 0x26, 0x2b, 0x27, 0x40, 0x57, 0x27, 0x41, 0x57, 0x25, 0x2a, 0x33, 0x29, 0x5d, 0x87, 0x25, 0x34, 0x44, 0x25, 0x2b, 0x34, 0x40, 0x40, 0x44, 0xad, 0xad, 0xaf, 0xff, 0xff, 0xff, 0xf2, 0xf2, 0xf2, 0x77, 0x77, 0x7a, 0x5b, 0x5b, 0x5f, 0x4e, 0x4e, 0x52, 0xc9, 0xc9, 0xca, 0x27, 0x43, 0x5b, 0x27, 0x4d, 0x6c, 0x27, 0x4e, 0x6d, 0xbb, 0xbb, 0xbd, 0x69, 0x69, 0x6c, 0x28, 0x56, 0x7b, 0x26, 0x3b, 0x4e, 0x26, 0x3a, 0x4e, 0x32, 0x32, 0x37, 0x84, 0x84, 0x87, 0xd6, 0xd6, 0xd7, 0x29, 0x61, 0x8d, 0x25, 0x2e, 0x39, 0x92, 0x92, 0x94, 0xa0, 0xa0, 0xa2, 0xe4, 0xe4, 0xe5, 0x27, 0x44, 0x5d, 0xdd, 0xc9, 0xf2, 0x7e, 0x0, 0x0, 0x0, 0x41, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x1, 0x2, 0x3, 0x4, 0x9, 0xe, 0x13, 0x16, 0x18, 0x19, 0xa, 0x26, 0x36, 0x44, 0x4d, 0x52, 0x54, 0x55, 0x6, 0x12, 0x27, 0x43, 0x80, 0xc5, 0xe7, 0xf5, 0xfe, 0x8, 0x17, 0x35, 0x73, 0xd9, 0x7, 0x3a, 0x96, 0xf9, 0x9a, 0xb, 0x28, 0x76, 0xfb, 0x77, 0xde, 0x45, 0x5, 0x82, 0xc6, 0xc6, 0x37, 0xf, 0xe9, 0x4c, 0x4e, 0x4f, 0x50, 0x83, 0x78, 0x3b, 0x9c, 0x3c, 0x74, 0xda, 0x53, 0x14, 0x37, 0x21, 0x5a, 0x6c, 0x0, 0x0, 0x2, 0x4, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0xdd, 0x95, 0x63, 0x83, 0xdc, 0x60, 0x10, 0xc7, 0x1b, 0x3c, 0xc1, 0xda, 0x3e, 0xdb, 0x36, 0xe7, 0x6c, 0xdb, 0xa, 0xcf, 0xc6, 0x7e, 0xf8, 0x2a, 0x6d, 0xb8, 0xac, 0x7b, 0xbf, 0xf7, 0xf3, 0x1f, 0xcf, 0x7c, 0xf8, 0x97, 0xc0, 0x70, 0x82, 0x20, 0xb3, 0x42, 0x10, 0x38, 0x96, 0xd2, 0x1c, 0x27, 0x11, 0x45, 0x33, 0xac, 0x2d, 0xb, 0x2c, 0x43, 0x53, 0x88, 0xc4, 0xad, 0xde, 0x49, 0x3b, 0xe3, 0x70, 0xba, 0xdc, 0x1e, 0xaf, 0x2f, 0x23, 0x5e, 0x8f, 0xdb, 0xe5, 0x74, 0x30, 0x76, 0xd2, 0x14, 0x5, 0xee, 0xf, 0x4, 0x43, 0xe1, 0x48, 0x34, 0x16, 0x87, 0x2c, 0xc4, 0x63, 0xd1, 0x48, 0x38, 0x14, 0xc, 0xf8, 0x71, 0x83, 0x7d, 0xa2, 0xa0, 0xb0, 0xa8, 0x78, 0x4, 0x72, 0x64, 0xa4, 0xb8, 0xa8, 0xb0, 0x20, 0xa1, 0x53, 0xc0, 0x4a, 0xd8, 0xd2, 0xb2, 0x72, 0xc8, 0xc4, 0xe8, 0xd8, 0xf8, 0xc4, 0xa4, 0xc2, 0xd4, 0xf4, 0x28, 0x94, 0x97, 0x95, 0xb2, 0x25, 0x98, 0x96, 0x3f, 0xed, 0xac, 0xc8, 0x18, 0xfb, 0xcc, 0xec, 0xdc, 0xfc, 0xc2, 0xe2, 0xd2, 0x17, 0x96, 0x57, 0x56, 0xd7, 0xd6, 0x37, 0x66, 0xe2, 0x15, 0x4e, 0x5a, 0xad, 0x3, 0x5e, 0x59, 0x55, 0x5d, 0x93, 0xd1, 0x7e, 0x73, 0x6b, 0x1b, 0x74, 0xec, 0xec, 0x6e, 0xce, 0xd4, 0xd4, 0x56, 0x55, 0x7e, 0x4f, 0x82, 0x2c, 0x70, 0xd5, 0x41, 0x6, 0xf6, 0xf6, 0xb7, 0x56, 0xc0, 0xc0, 0xca, 0xd6, 0xc1, 0x5e, 0x5d, 0x7d, 0x41, 0x83, 0x12, 0x2, 0x86, 0x1c, 0x8d, 0x90, 0x89, 0xc3, 0xa3, 0x63, 0x30, 0xb1, 0x33, 0x77, 0x2, 0x8d, 0xe, 0xa4, 0x8, 0xe0, 0x94, 0xb3, 0x9, 0x54, 0x4e, 0xcf, 0x38, 0x5e, 0x0, 0x91, 0x93, 0x40, 0x94, 0x41, 0xe1, 0xfc, 0x2, 0x2c, 0x5c, 0x9e, 0x43, 0x73, 0x4b, 0xab, 0x92, 0x3, 0x41, 0xbb, 0xa2, 0xa0, 0x22, 0x5f, 0x9d, 0x5e, 0x73, 0xa7, 0x22, 0x27, 0x6b, 0x2, 0x37, 0xb7, 0x60, 0xe1, 0xee, 0x6, 0xda, 0xea, 0x69, 0x42, 0x11, 0x60, 0xda, 0x63, 0x5a, 0x0, 0xdc, 0x3d, 0xc0, 0xd5, 0x83, 0xf8, 0xc8, 0x8b, 0xaa, 0xc0, 0xd3, 0x33, 0x58, 0x78, 0x7e, 0x82, 0xf2, 0xe, 0x86, 0x54, 0x4, 0xa, 0x3a, 0xb5, 0x1e, 0x8a, 0x8f, 0x0, 0xf0, 0x72, 0x26, 0xca, 0x2f, 0x8f, 0xaa, 0xc0, 0xc4, 0x22, 0x58, 0x58, 0x9c, 0x0, 0xe8, 0x2a, 0xf8, 0x26, 0xc0, 0xb8, 0xb5, 0x21, 0xba, 0xff, 0x12, 0xc1, 0xd9, 0xeb, 0x67, 0xe3, 0xb7, 0xb3, 0x9c, 0x23, 0xa0, 0x5d, 0x6d, 0xa0, 0xf2, 0xf8, 0x0, 0xf7, 0xbc, 0xf0, 0x59, 0x40, 0xe0, 0x72, 0xad, 0x1, 0x4e, 0xb5, 0xe8, 0xba, 0x20, 0xf2, 0x8f, 0xfc, 0xd9, 0xd7, 0x2, 0x3e, 0xe6, 0xda, 0x5, 0xc, 0x39, 0xba, 0x41, 0xe3, 0xfe, 0x41, 0x2, 0x38, 0x15, 0x0, 0x24, 0x21, 0xf3, 0x1c, 0x74, 0x7, 0x11, 0xf6, 0xd3, 0x93, 0xa8, 0xee, 0x42, 0x6d, 0xfe, 0xbb, 0xd0, 0xa3, 0xed, 0x42, 0xe, 0xdb, 0xb8, 0x61, 0xdc, 0xc6, 0xa4, 0xba, 0x8d, 0xea, 0x3d, 0xe8, 0xed, 0xab, 0xc9, 0xe7, 0x1e, 0xd4, 0xf4, 0xf5, 0xab, 0xf7, 0x40, 0xb9, 0x48, 0xac, 0x73, 0x60, 0x10, 0x72, 0x66, 0x70, 0xc0, 0xc9, 0x26, 0x8c, 0x37, 0xad, 0x84, 0xe, 0xba, 0xc2, 0x91, 0xb6, 0x72, 0xc8, 0x4a, 0x79, 0x5b, 0x24, 0xec, 0xa, 0xd2, 0x25, 0xb8, 0xf9, 0x2a, 0x57, 0x32, 0x8e, 0x96, 0xfa, 0x8e, 0x21, 0x5f, 0x16, 0x86, 0x3a, 0xea, 0x5b, 0x1c, 0x4c, 0x25, 0x89, 0x59, 0xbf, 0x4a, 0x3, 0x6a, 0x1d, 0x2e, 0xc8, 0xfe, 0x17, 0xa, 0x86, 0x5b, 0x51, 0x3, 0x8e, 0xa5, 0xf9, 0x4c, 0x64, 0xe, 0x68, 0x9f, 0xe9, 0xbd, 0xf0, 0x9, 0xb7, 0x71, 0x36, 0xc6, 0x9b, 0x3d, 0x7f, 0x21, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char tool_button_pressed_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x2, 0x1, 0x50, 0x4c, 0x54, 0x45, 0x29, 0x3a, 0x40, 0x2d, 0x3e, 0x44, 0x26, 0x34, 0x3b, 0x24, 0x34, 0x39, 0x23, 0x31, 0x38, 0x22, 0x31, 0x37, 0x22, 0x31, 0x37, 0x22, 0x30, 0x36, 0x22, 0x31, 0x36, 0x26, 0x34, 0x3c, 0x32, 0x44, 0x4c, 0x26, 0x34, 0x39, 0x23, 0x31, 0x36, 0x21, 0x2e, 0x34, 0x1f, 0x2c, 0x30, 0x1f, 0x2b, 0x2f, 0x1f, 0x2a, 0x2e, 0x1e, 0x2b, 0x2f, 0x1f, 0x2b, 0x2e, 0x36, 0x4b, 0x52, 0x25, 0x33, 0x38, 0x20, 0x2f, 0x32, 0x1c, 0x29, 0x2e, 0x1b, 0x26, 0x2a, 0x1a, 0x23, 0x26, 0x18, 0x22, 0x26, 0x19, 0x22, 0x26, 0x19, 0x23, 0x26, 0x19, 0x26, 0x29, 0x20, 0x2d, 0x32, 0x25, 0x31, 0x38, 0x3c, 0x51, 0x59, 0x23, 0x31, 0x37, 0x1f, 0x2b, 0x31, 0x1a, 0x25, 0x2b, 0x17, 0x20, 0x24, 0x15, 0x1c, 0x21, 0x14, 0x1b, 0x21, 0x14, 0x1c, 0x21, 0x13, 0x1b, 0x21, 0x15, 0x1d, 0x21, 0x1a, 0x25, 0x2a, 0x40, 0x57, 0x60, 0x23, 0x31, 0x36, 0x1f, 0x2b, 0x31, 0x1b, 0x25, 0x29, 0x16, 0x1e, 0x23, 0x14, 0x1b, 0x1d, 0x12, 0x19, 0x1d, 0x12, 0x1b, 0x1d, 0x14, 0x1a, 0x1d, 0x45, 0x5e, 0x67, 0x22, 0x32, 0x37, 0x20, 0x2d, 0x31, 0x1a, 0x26, 0x2a, 0x15, 0x1f, 0x25, 0x14, 0x1c, 0x1f, 0x12, 0x1b, 0x1f, 0x12, 0x1b, 0x20, 0x14, 0x1b, 0x1f, 0x15, 0x1e, 0x24, 0x1a, 0x25, 0x29, 0x4b, 0x64, 0x6d, 0x23, 0x32, 0x38, 0x20, 0x2e, 0x32, 0x1b, 0x27, 0x2b, 0x17, 0x22, 0x27, 0x16, 0x1e, 0x23, 0x14, 0x1e, 0x23, 0x16, 0x20, 0x24, 0x14, 0x1e, 0x22, 0x15, 0x1e, 0x22, 0x17, 0x21, 0x27, 0x1c, 0x27, 0x2c, 0x4f, 0x6a, 0x75, 0x21, 0x2f, 0x33, 0x1d, 0x29, 0x2d, 0x19, 0x23, 0x2a, 0x18, 0x22, 0x27, 0x16, 0x21, 0x27, 0x18, 0x23, 0x29, 0x17, 0x21, 0x26, 0x19, 0x23, 0x29, 0x1c, 0x28, 0x2d, 0x21, 0x2e, 0x33, 0x54, 0x70, 0x7c, 0x23, 0x33, 0x38, 0x22, 0x30, 0x34, 0x1e, 0x2a, 0x2f, 0x1a, 0x26, 0x2d, 0x1a, 0x25, 0x2b, 0x19, 0x25, 0x2b, 0x1a, 0x26, 0x2d, 0x1a, 0x26, 0x2c, 0x18, 0x25, 0x2a, 0x1a, 0x24, 0x2a, 0x1a, 0x25, 0x2c, 0x1d, 0x2a, 0x2f, 0x22, 0x2f, 0x34, 0x59, 0x77, 0x82, 0x23, 0x33, 0x39, 0x22, 0x30, 0x35, 0x1f, 0x2c, 0x31, 0x1c, 0x28, 0x30, 0x1c, 0x28, 0x2e, 0x1b, 0x29, 0x2f, 0x1c, 0x2a, 0x31, 0x1b, 0x28, 0x2f, 0x1c, 0x28, 0x2d, 0x1b, 0x27, 0x2f, 0x1f, 0x2b, 0x31, 0x5e, 0x7d, 0x8a, 0x24, 0x34, 0x39, 0x21, 0x2f, 0x37, 0x20, 0x2d, 0x34, 0x1d, 0x2b, 0x33, 0x1d, 0x2b, 0x32, 0x1d, 0x2d, 0x35, 0x1e, 0x2e, 0x36, 0x1f, 0x2e, 0x36, 0x1d, 0x2b, 0x34, 0x1d, 0x2b, 0x31, 0x1d, 0x2b, 0x32, 0x20, 0x2d, 0x32, 0x21, 0x2f, 0x36, 0x63, 0x83, 0x90, 0x25, 0x34, 0x39, 0x21, 0x31, 0x36, 0x1f, 0x2e, 0x34, 0x1f, 0x2e, 0x34, 0x1f, 0x2e, 0x36, 0x20, 0x31, 0x39, 0x21, 0x33, 0x3b, 0x21, 0x32, 0x3b, 0x1f, 0x30, 0x37, 0x1f, 0x2e, 0x35, 0x1e, 0x2d, 0x33, 0x1f, 0x2d, 0x33, 0x21, 0x30, 0x36, 0x67, 0x8a, 0x97, 0x24, 0x33, 0x39, 0x20, 0x30, 0x36, 0x1f, 0x2f, 0x35, 0x21, 0x30, 0x37, 0x22, 0x32, 0x39, 0x21, 0x35, 0x3e, 0x24, 0x37, 0x41, 0x24, 0x36, 0x41, 0x21, 0x33, 0x3c, 0x21, 0x31, 0x38, 0x1e, 0x2f, 0x35, 0x1e, 0x2e, 0x35, 0x20, 0x2e, 0x35, 0x24, 0x31, 0x39, 0x6c, 0x90, 0x9e, 0x22, 0x30, 0x36, 0x1f, 0x2e, 0x36, 0x20, 0x30, 0x36, 0x20, 0x31, 0x39, 0x23, 0x34, 0x3d, 0x23, 0x37, 0x41, 0x26, 0x3c, 0x47, 0x26, 0x3b, 0x46, 0x22, 0x35, 0x3f, 0x22, 0x32, 0x3b, 0x1f, 0x30, 0x37, 0x1f, 0x2e, 0x35, 0x1f, 0x2d, 0x35, 0x21, 0x30, 0x36, 0x72, 0x96, 0xa5, 0x72, 0x96, 0xa5, 0xe8, 0x14, 0xaa, 0x3f, 0x0, 0x0, 0x0, 0xaa, 0x74, 0x52, 0x4e, 0x53, 0xc3, 0xc3, 0xe6, 0xd7, 0xcb, 0xc3, 0xbf, 0xbe, 0xbd, 0xe5, 0xc3, 0xd7, 0xc0, 0xac, 0xa0, 0x9a, 0x98, 0x98, 0x98, 0xc3, 0xcb, 0xac, 0x92, 0x82, 0x7b, 0x78, 0x78, 0x7b, 0x82, 0xac, 0xcb, 0xc3, 0xc3, 0xa0, 0x82, 0x6f, 0x67, 0x64, 0x63, 0x64, 0x67, 0x82, 0xc3, 0xbf, 0x9a, 0x7a, 0x67, 0x5e, 0x5b, 0x5a, 0x5e, 0xc3, 0xbd, 0x98, 0x78, 0x64, 0x5b, 0x57, 0x57, 0x5b, 0x64, 0x78, 0xc3, 0xbd, 0x98, 0x78, 0x63, 0x5a, 0x57, 0x56, 0x57, 0x5a, 0x63, 0x77, 0xc3, 0x98, 0x78, 0x63, 0x5a, 0x57, 0x56, 0x5a, 0x63, 0x77, 0x98, 0xc3, 0xbd, 0x98, 0x78, 0x63, 0x5a, 0x57, 0x56, 0x56, 0x57, 0x5a, 0x63, 0x77, 0x98, 0xc3, 0xbd, 0x98, 0x77, 0x63, 0x5a, 0x57, 0x56, 0x57, 0x5a, 0x63, 0x77, 0xc3, 0xbb, 0x96, 0x76, 0x63, 0x5a, 0x57, 0x56, 0x56, 0x57, 0x5a, 0x63, 0x76, 0x96, 0xc3, 0xb5, 0x92, 0x75, 0x62, 0x5a, 0x57, 0x56, 0x56, 0x57, 0x59, 0x62, 0x74, 0x92, 0xc3, 0xa9, 0x8b, 0x71, 0x61, 0x59, 0x57, 0x56, 0x56, 0x57, 0x59, 0x61, 0x71, 0x8b, 0xa9, 0xc3, 0x95, 0x7e, 0x6b, 0x5e, 0x59, 0x57, 0x56, 0x56, 0x57, 0x59, 0x5e, 0x6b, 0x7e, 0x95, 0xc3, 0x4f, 0x78, 0x99, 0x30, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0xa9, 0x27, 0xf, 0x6, 0x4, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0xff, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, 0x40, 0x7, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x1c, 0x1c, 0x6c, 0xac, 0x2c, 0xcc, 0x9c, 0x8c, 0xc, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 0x2, 0x82, 0x82, 0x42, 0xfc, 0x7c, 0xbc, 0x3c, 0xdc, 0x5c, 0xc, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 0x12, 0x92, 0x52, 0x52, 0x92, 0xd2, 0x32, 0x62, 0xb2, 0x72, 0xc2, 0xc, 0xf2, 0xa, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0x6a, 0xea, 0x1a, 0xca, 0x9a, 0x8a, 0xa, 0xf2, 0xc, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 0x6, 0x86, 0x86, 0x6, 0x46, 0x7a, 0xba, 0x3a, 0xda, 0x5a, 0xc, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0x56, 0x96, 0xd6, 0x36, 0xb6, 0xa6, 0x26, 0xc6, 0xc, 0x76, 0xf6, 0xe, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0xae, 0x6e, 0xee, 0x1e, 0x9e, 0xe, 0x26, 0x76, 0xc, 0x5e, 0xf6, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 0x1, 0x1, 0xfe, 0x81, 0x41, 0xc1, 0x21, 0xf6, 0x5e, 0xc, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, 0x9, 0x89, 0x49, 0x61, 0xa1, 0xc, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xa9, 0x29, 0xc9, 0xc, 0xf9, 0x5, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 0x15, 0x95, 0x55, 0xd5, 0x35, 0x5, 0xf9, 0xc, 0xb5, 0x75, 0xf5, 0xd, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0x75, 0xb5, 0xc, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, 0x13, 0x26, 0x4e, 0x9a, 0x3c, 0x65, 0xea, 0xb4, 0xe9, 0x33, 0x66, 0x76, 0x33, 0xcc, 0x9a, 0x3d, 0x67, 0xee, 0xbc, 0xf9, 0xb, 0x16, 0x2e, 0x5a, 0xbc, 0x64, 0xe9, 0xb2, 0xe5, 0x2b, 0x66, 0x31, 0xac, 0x44, 0x3, 0x0, 0xa4, 0xd7, 0x4d, 0x73, 0x12, 0x21, 0x19, 0xde, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x1, 0xfe, 0x50, 0x4c, 0x54, 0x45, 0x29, 0x3a, 0x40, 0x2d, 0x3e, 0x44, 0x26, 0x34, 0x3b, 0x24, 0x34, 0x39, 0x23, 0x31, 0x38, 0x22, 0x31, 0x37, 0x22, 0x31, 0x37, 0x22, 0x30, 0x36, 0x22, 0x31, 0x36, 0x26, 0x34, 0x3c, 0x32, 0x44, 0x4c, 0x26, 0x34, 0x39, 0x23, 0x31, 0x36, 0x21, 0x2e, 0x34, 0x1f, 0x2c, 0x30, 0x1f, 0x2b, 0x2f, 0x1f, 0x2a, 0x2e, 0x1e, 0x2b, 0x2f, 0x1f, 0x2b, 0x2e, 0x36, 0x4b, 0x52, 0x25, 0x33, 0x38, 0x20, 0x2f, 0x32, 0x1c, 0x29, 0x2e, 0x1b, 0x26, 0x2a, 0x1a, 0x23, 0x26, 0x18, 0x22, 0x26, 0x19, 0x22, 0x26, 0x19, 0x23, 0x26, 0x19, 0x26, 0x29, 0x20, 0x2d, 0x32, 0x25, 0x31, 0x38, 0x3c, 0x51, 0x59, 0x23, 0x31, 0x37, 0x1f, 0x2b, 0x31, 0x1a, 0x25, 0x2b, 0x17, 0x20, 0x24, 0x15, 0x1c, 0x21, 0x14, 0x1b, 0x21, 0x14, 0x1c, 0x21, 0x13, 0x1b, 0x21, 0x15, 0x1d, 0x21, 0x1a, 0x25, 0x2a, 0x40, 0x57, 0x60, 0x23, 0x31, 0x36, 0x1f, 0x2b, 0x31, 0x1b, 0x25, 0x29, 0x16, 0x1e, 0x23, 0x14, 0x1b, 0x1d, 0x12, 0x19, 0x1d, 0x12, 0x1b, 0x1d, 0x14, 0x1a, 0x1d, 0x45, 0x5e, 0x67, 0x22, 0x32, 0x37, 0x20, 0x2d, 0x31, 0x1a, 0x26, 0x2a, 0x15, 0x1f, 0x25, 0x14, 0x1c, 0x1f, 0x12, 0x1b, 0x1f, 0x12, 0x1b, 0x20, 0x14, 0x1b, 0x1f, 0x15, 0x1e, 0x24, 0x1a, 0x25, 0x29, 0x4b, 0x64, 0x6d, 0x23, 0x32, 0x38, 0x20, 0x2e, 0x32, 0x1b, 0x27, 0x2b, 0x17, 0x22, 0x27, 0x16, 0x1e, 0x23, 0x14, 0x1e, 0x23, 0x16, 0x20, 0x24, 0x14, 0x1e, 0x22, 0x15, 0x1e, 0x22, 0x17, 0x21, 0x27, 0x1c, 0x27, 0x2c, 0x4f, 0x6a, 0x75, 0x21, 0x2f, 0x33, 0x1d, 0x29, 0x2d, 0x19, 0x23, 0x2a, 0x18, 0x22, 0x27, 0x16, 0x21, 0x27, 0x18, 0x23, 0x29, 0x17, 0x21, 0x26, 0x19, 0x23, 0x29, 0x1c, 0x28, 0x2d, 0x21, 0x2e, 0x33, 0x54, 0x70, 0x7c, 0x23, 0x33, 0x38, 0x22, 0x30, 0x34, 0x1e, 0x2a, 0x2f, 0x1a, 0x26, 0x2d, 0x1a, 0x25, 0x2b, 0x19, 0x25, 0x2b, 0x1a, 0x26, 0x2d, 0x1a, 0x26, 0x2c, 0x18, 0x25, 0x2a, 0x1a, 0x24, 0x2a, 0x1a, 0x25, 0x2c, 0x1d, 0x2a, 0x2f, 0x22, 0x2f, 0x34, 0x59, 0x77, 0x82, 0x23, 0x33, 0x39, 0x22, 0x30, 0x35, 0x1f, 0x2c, 0x31, 0x1c, 0x28, 0x30, 0x1c, 0x28, 0x2e, 0x1b, 0x29, 0x2f, 0x1c, 0x2a, 0x31, 0x1b, 0x28, 0x2f, 0x1c, 0x28, 0x2d, 0x1b, 0x27, 0x2f, 0x1f, 0x2b, 0x31, 0x5e, 0x7d, 0x8a, 0x24, 0x34, 0x39, 0x21, 0x2f, 0x37, 0x20, 0x2d, 0x34, 0x1d, 0x2b, 0x33, 0x1d, 0x2b, 0x32, 0x1d, 0x2d, 0x35, 0x1e, 0x2e, 0x36, 0x1f, 0x2e, 0x36, 0x1d, 0x2b, 0x34, 0x1d, 0x2b, 0x31, 0x1d, 0x2b, 0x32, 0x20, 0x2d, 0x32, 0x21, 0x2f, 0x36, 0x63, 0x83, 0x90, 0x25, 0x34, 0x39, 0x21, 0x31, 0x36, 0x1f, 0x2e, 0x34, 0x1f, 0x2e, 0x34, 0x1f, 0x2e, 0x36, 0x20, 0x31, 0x39, 0x21, 0x33, 0x3b, 0x21, 0x32, 0x3b, 0x1f, 0x30, 0x37, 0x1f, 0x2e, 0x35, 0x1e, 0x2d, 0x33, 0x1f, 0x2d, 0x33, 0x21, 0x30, 0x36, 0x67, 0x8a, 0x97, 0x24, 0x33, 0x39, 0x20, 0x30, 0x36, 0x1f, 0x2f, 0x35, 0x21, 0x30, 0x37, 0x22, 0x32, 0x39, 0x21, 0x35, 0x3e, 0x24, 0x37, 0x41, 0x24, 0x36, 0x41, 0x21, 0x33, 0x3c, 0x21, 0x31, 0x38, 0x1e, 0x2f, 0x35, 0x1e, 0x2e, 0x35, 0x20, 0x2e, 0x35, 0x24, 0x31, 0x39, 0x6c, 0x90, 0x9e, 0x22, 0x30, 0x36, 0x1f, 0x2e, 0x36, 0x20, 0x30, 0x36, 0x20, 0x31, 0x39, 0x23, 0x34, 0x3d, 0x23, 0x37, 0x41, 0x26, 0x3c, 0x47, 0x26, 0x3b, 0x46, 0x22, 0x35, 0x3f, 0x22, 0x32, 0x3b, 0x1f, 0x30, 0x37, 0x1f, 0x2e, 0x35, 0x1f, 0x2d, 0x35, 0x21, 0x30, 0x36, 0x72, 0x96, 0xa5, 0x7e, 0x8c, 0xc3, 0xb0, 0x0, 0x0, 0x0, 0xaa, 0x74, 0x52, 0x4e, 0x53, 0xc3, 0xc3, 0xe6, 0xd7, 0xcb, 0xc3, 0xbf, 0xbe, 0xbd, 0xe5, 0xc3, 0xd7, 0xc0, 0xac, 0xa0, 0x9a, 0x98, 0x98, 0x98, 0xc3, 0xcb, 0xac, 0x92, 0x82, 0x7b, 0x78, 0x78, 0x7b, 0x82, 0xac, 0xcb, 0xc3, 0xc3, 0xa0, 0x82, 0x6f, 0x67, 0x64, 0x63, 0x64, 0x67, 0x82, 0xc3, 0xbf, 0x9a, 0x7a, 0x67, 0x5e, 0x5b, 0x5a, 0x5e, 0xc3, 0xbd, 0x98, 0x78, 0x64, 0x5b, 0x57, 0x57, 0x5b, 0x64, 0x78, 0xc3, 0xbd, 0x98, 0x78, 0x63, 0x5a, 0x57, 0x56, 0x57, 0x5a, 0x63, 0x77, 0xc3, 0x98, 0x78, 0x63, 0x5a, 0x57, 0x56, 0x5a, 0x63, 0x77, 0x98, 0xc3, 0xbd, 0x98, 0x78, 0x63, 0x5a, 0x57, 0x56, 0x56, 0x57, 0x5a, 0x63, 0x77, 0x98, 0xc3, 0xbd, 0x98, 0x77, 0x63, 0x5a, 0x57, 0x56, 0x57, 0x5a, 0x63, 0x77, 0xc3, 0xbb, 0x96, 0x76, 0x63, 0x5a, 0x57, 0x56, 0x56, 0x57, 0x5a, 0x63, 0x76, 0x96, 0xc3, 0xb5, 0x92, 0x75, 0x62, 0x5a, 0x57, 0x56, 0x56, 0x57, 0x59, 0x62, 0x74, 0x92, 0xc3, 0xa9, 0x8b, 0x71, 0x61, 0x59, 0x57, 0x56, 0x56, 0x57, 0x59, 0x61, 0x71, 0x8b, 0xa9, 0xc3, 0x95, 0x7e, 0x6b, 0x5e, 0x59, 0x57, 0x56, 0x56, 0x57, 0x59, 0x5e, 0x6b, 0x7e, 0x95, 0xc3, 0x4f, 0x78, 0x99, 0x30, 0x0, 0x0, 0x0, 0x67, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x5c, 0x8b, 0x5, 0x2, 0xc3, 0x30, 0xc, 0xc4, 0x72, 0x5d, 0x39, 0xf4, 0xff, 0x67, 0x8e, 0x79, 0x1a, 0x37, 0xa0, 0xa0, 0x6d, 0x5d, 0x6b, 0x2a, 0x5a, 0xfd, 0x30, 0xe6, 0x1, 0xf4, 0xa7, 0x76, 0xfa, 0x37, 0x74, 0x7, 0x98, 0x52, 0x83, 0x46, 0x97, 0x41, 0xfb, 0xd6, 0x2d, 0x86, 0xae, 0xfe, 0x84, 0x6b, 0x6d, 0x32, 0x6e, 0x58, 0x28, 0x22, 0x3a, 0x41, 0x32, 0xde, 0xd7, 0x6a, 0x67, 0x5b, 0xb7, 0xb7, 0xc9, 0xb0, 0xd8, 0xd6, 0x3a, 0x65, 0x34, 0xb4, 0x21, 0x8f, 0x1c, 0x3, 0x6d, 0x21, 0x84, 0x5d, 0x32, 0x8a, 0x48, 0x22, 0x6e, 0xda, 0xa8, 0x92, 0x36, 0x3e, 0x87, 0xea, 0x7b, 0x7e, 0x0, 0x62, 0xa8, 0x25, 0xad, 0x68, 0x1d, 0x7d, 0x1a, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char tooltip_bg_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x33, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2d, 0x2c, 0x2f, 0x48, 0x46, 0x4a, 0xdd, 0xdd, 0xdd, 0x4c, 0x4a, 0x4e, 0x48, 0x46, 0x4a, 0x40, 0x3e, 0x42, 0xdd, 0xdd, 0xdd, 0xfe, 0x3f, 0x83, 0xa9, 0x0, 0x0, 0x0, 0xd, 0x74, 0x52, 0x4e, 0x53, 0xa, 0x1a, 0x26, 0x29, 0x2a, 0x48, 0x65, 0x6d, 0x6e, 0x66, 0xf5, 0xfe, 0xcc, 0xff, 0xb7, 0x4a, 0xbe, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0xc, 0x81, 0xb3, 0x51, 0x63, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x44, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0xc5, 0xcf, 0xbb, 0x15, 0x0, 0x20, 0x8, 0x43, 0xd1, 0x80, 0x28, 0xf8, 0x41, 0xf7, 0xdf, 0xd6, 0x86, 0x63, 0xa1, 0x3, 0x78, 0xcb, 0x54, 0x79, 0x0, 0x71, 0x92, 0x90, 0x98, 0x0, 0xca, 0x45, 0x2d, 0x68, 0xc9, 0x4, 0xae, 0xad, 0x7b, 0xe8, 0xad, 0x32, 0x44, 0xe7, 0x1a, 0x61, 0x4d, 0x15, 0x88, 0xf9, 0x38, 0xdc, 0xfe, 0xd, 0xf7, 0xb1, 0xe7, 0xfa, 0x13, 0x77, 0xe7, 0x6f, 0xdc, 0x6c, 0x9, 0x25, 0x82, 0x67, 0x68, 0x78, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x30, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2d, 0x2c, 0x2f, 0x48, 0x46, 0x4a, 0xdd, 0xdd, 0xdd, 0x4c, 0x4a, 0x4e, 0x48, 0x46, 0x4a, 0x40, 0x3e, 0x42, 0xbc, 0x3, 0x4f, 0xe9, 0x0, 0x0, 0x0, 0xd, 0x74, 0x52, 0x4e, 0x53, 0xa, 0x1a, 0x26, 0x29, 0x2a, 0x48, 0x65, 0x6d, 0x6e, 0x66, 0xf5, 0xfe, 0xcc, 0xff, 0xb7, 0x4a, 0xbe, 0x0, 0x0, 0x0, 0x38, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x60, 0x54, 0x76, 0x1, 0x2, 0x23, 0x1, 0x6, 0xd1, 0xf4, 0xe, 0x20, 0x28, 0xb, 0x64, 0xd0, 0x5c, 0x7d, 0x17, 0x8, 0x76, 0x4d, 0x62, 0x70, 0x7f, 0x7f, 0x6, 0x8, 0xfe, 0x95, 0x30, 0x78, 0xdc, 0x1, 0x31, 0xce, 0xb6, 0x50, 0xc8, 0x80, 0x1b, 0x8, 0xb7, 0x2, 0x6e, 0x29, 0xdc, 0x19, 0x0, 0xcf, 0x24, 0x4d, 0xb3, 0xd0, 0x4d, 0xb9, 0x40, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char tree_bg_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0xa, 0x4, 0x3, 0x0, 0x0, 0x0, 0x7f, 0x1c, 0xd2, 0x8e, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x2a, 0x50, 0x4c, 0x54, 0x45, 0x17, 0x16, 0x1a, 0x1d, 0x1c, 0x21, 0x20, 0x1e, 0x24, 0x21, 0x1f, 0x25, 0x1d, 0x1c, 0x21, 0x20, 0x1e, 0x24, 0x1d, 0x1c, 0x21, 0x1d, 0x1c, 0x21, 0x24, 0x22, 0x29, 0x28, 0x26, 0x2d, 0x28, 0x26, 0x2e, 0x2b, 0x2a, 0x31, 0x2c, 0x2a, 0x32, 0xff, 0xff, 0xff, 0xb9, 0x11, 0x56, 0x3e, 0x0, 0x0, 0x0, 0x8, 0x74, 0x52, 0x4e, 0x53, 0x6f, 0xef, 0xf7, 0xf7, 0xf0, 0xf9, 0xf1, 0xee, 0xcf, 0x21, 0xd2, 0xdf, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0xd, 0xf6, 0xb4, 0x61, 0xf5, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x2d, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0x54, 0x36, 0x36, 0x12, 0x60, 0xf0, 0x98, 0xb5, 0x6a, 0x65, 0xb, 0x43, 0xe4, 0x9e, 0x33, 0xa7, 0xa7, 0x32, 0x58, 0x9d, 0x39, 0x73, 0x66, 0x31, 0x16, 0x12, 0x22, 0xb, 0x52, 0xd9, 0xc6, 0xc0, 0x2, 0xd4, 0x55, 0x0, 0x0, 0xc, 0x14, 0x1a, 0x90, 0x55, 0x1a, 0xec, 0xdb, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0xa, 0x4, 0x3, 0x0, 0x0, 0x0, 0x7f, 0x1c, 0xd2, 0x8e, 0x0, 0x0, 0x0, 0x2a, 0x50, 0x4c, 0x54, 0x45, 0x17, 0x16, 0x1a, 0x1d, 0x1c, 0x21, 0x20, 0x1e, 0x24, 0x21, 0x1f, 0x25, 0x1d, 0x1c, 0x21, 0x20, 0x1e, 0x24, 0x1d, 0x1c, 0x21, 0x1d, 0x1c, 0x21, 0x24, 0x22, 0x29, 0x28, 0x26, 0x2d, 0x28, 0x26, 0x2e, 0x2b, 0x2a, 0x31, 0x2c, 0x2a, 0x32, 0xff, 0xff, 0xff, 0xb9, 0x11, 0x56, 0x3e, 0x0, 0x0, 0x0, 0x8, 0x74, 0x52, 0x4e, 0x53, 0x6f, 0xef, 0xf7, 0xf7, 0xf0, 0xf9, 0xf1, 0xee, 0xcf, 0x21, 0xd2, 0xdf, 0x0, 0x0, 0x0, 0x2d, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0x54, 0x36, 0x36, 0x12, 0x60, 0xf0, 0x98, 0xb5, 0x6a, 0x65, 0xb, 0x43, 0xe4, 0x9e, 0x33, 0xa7, 0xa7, 0x32, 0x58, 0x9d, 0x39, 0x73, 0x66, 0x31, 0x16, 0x12, 0x22, 0xb, 0x52, 0xd9, 0xc6, 0xc0, 0x2, 0xd4, 0x55, 0x0, 0x0, 0xc, 0x14, 0x1a, 0x90, 0x55, 0x1a, 0xec, 0xdb, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char tree_bg_disabled_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0xa, 0x8, 0x4, 0x0, 0x0, 0x0, 0x27, 0x3b, 0x7, 0x36, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x2, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x87, 0x8f, 0xcc, 0xbf, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x64, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x95, 0xce, 0x31, 0x12, 0x2, 0x21, 0x10, 0x44, 0xd1, 0x3f, 0x40, 0xa1, 0x44, 0xa6, 0x46, 0xde, 0x63, 0x4f, 0xe5, 0x15, 0x38, 0xb2, 0xd6, 0x6, 0xb0, 0xc8, 0x30, 0x6, 0x96, 0xac, 0x56, 0x99, 0xf8, 0xb3, 0x7e, 0x51, 0xcb, 0xf9, 0x1a, 0xb3, 0x3f, 0xa, 0xaf, 0xc, 0xad, 0x2d, 0xcb, 0xe5, 0x76, 0x38, 0x5, 0x76, 0xec, 0x6c, 0xf7, 0xe0, 0x53, 0xe0, 0x13, 0xa1, 0x27, 0x27, 0x43, 0x26, 0x81, 0x20, 0xc8, 0x70, 0xfc, 0xe8, 0xf, 0x34, 0x67, 0xd8, 0x9c, 0x86, 0x61, 0x2e, 0x68, 0xe9, 0x91, 0xaf, 0x4b, 0x5a, 0x7d, 0x2a, 0x2c, 0x3, 0xed, 0xef, 0x1e, 0x6b, 0xcb, 0x4f, 0xa6, 0x66, 0x2b, 0x25, 0x6, 0x1, 0x37, 0x40, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0xa, 0x8, 0x4, 0x0, 0x0, 0x0, 0x27, 0x3b, 0x7, 0x36, 0x0, 0x0, 0x0, 0x4e, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x94, 0xc8, 0x67, 0x6b, 0x60, 0xe6, 0x60, 0x64, 0x80, 0x80, 0xff, 0xc, 0x7f, 0x7f, 0xfc, 0x6a, 0x60, 0x94, 0xfb, 0xc0, 0xce, 0xcf, 0xc2, 0x80, 0x10, 0xfc, 0xc3, 0xf0, 0xf3, 0x23, 0xa3, 0xe2, 0x4f, 0xe, 0x36, 0x54, 0xc1, 0x1f, 0xbf, 0x18, 0x95, 0xbe, 0x73, 0x70, 0xb0, 0x30, 0xc0, 0x1, 0x48, 0xf0, 0x7, 0x85, 0x82, 0x58, 0x2d, 0xc2, 0xe6, 0xa4, 0x4f, 0x20, 0xc7, 0x37, 0x32, 0xb3, 0x23, 0x39, 0xfe, 0xfb, 0xaf, 0x46, 0x0, 0xee, 0x2a, 0x2f, 0xce, 0x4c, 0x47, 0x66, 0xf6, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char tree_bg_focus_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x20, 0x8, 0x6, 0x0, 0x0, 0x0, 0x73, 0x7a, 0x7a, 0xf4, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xdb, 0xb, 0x4, 0x12, 0x2d, 0x3a, 0xb5, 0x1b, 0x14, 0x49, 0x0, 0x0, 0x2, 0xd9, 0x49, 0x44, 0x41, 0x54, 0x58, 0xc3, 0xc5, 0x57, 0x31, 0x8e, 0x14, 0x31, 0x10, 0xac, 0xea, 0x3d, 0x11, 0x91, 0xdf, 0x49, 0xf7, 0xf, 0x78, 0x1, 0xf, 0x40, 0x84, 0x44, 0x10, 0xf2, 0x20, 0x42, 0x62, 0x12, 0xc4, 0x3, 0x78, 0x1, 0xff, 0x21, 0x42, 0xb8, 0x8a, 0xc0, 0x1e, 0x4f, 0xdb, 0xe3, 0xb9, 0xbb, 0x45, 0x20, 0x7c, 0x1a, 0xdd, 0x8c, 0xec, 0xed, 0xae, 0xae, 0xea, 0xee, 0xe9, 0xe1, 0xfd, 0xed, 0xdd, 0xb, 0x0, 0xdf, 0xf1, 0x7f, 0xd6, 0x4b, 0xde, 0xdf, 0xde, 0xf9, 0xcb, 0xeb, 0x9f, 0xff, 0xc5, 0xfb, 0x9b, 0xaf, 0xcf, 0x70, 0xb3, 0x3d, 0x3c, 0xff, 0xf0, 0xd, 0x24, 0x11, 0x71, 0x1, 0x49, 0x90, 0x4, 0x0, 0x4, 0xd3, 0x2f, 0xb6, 0x7b, 0xf, 0xff, 0x86, 0x2d, 0x8c, 0x47, 0x60, 0x1b, 0x0, 0x61, 0x1b, 0xb6, 0x21, 0x15, 0xd8, 0xc6, 0x8f, 0x8f, 0xaf, 0x0, 0x60, 0x7, 0x0, 0xa2, 0x2, 0x20, 0x11, 0x41, 0x30, 0xa2, 0x2, 0xc1, 0xb5, 0x0, 0x8c, 0x79, 0xd9, 0x80, 0x24, 0x48, 0x0, 0x48, 0x28, 0x9d, 0xb9, 0xd9, 0xd, 0xb0, 0x31, 0x40, 0x5c, 0x2e, 0x1, 0x46, 0x0, 0xd, 0xd0, 0xb6, 0xef, 0x35, 0x8e, 0x13, 0x6, 0xbc, 0x33, 0x60, 0xa3, 0x9a, 0x11, 0x6c, 0x82, 0xe6, 0xa, 0x0, 0x86, 0xe8, 0x2f, 0x71, 0xa9, 0xf7, 0x9c, 0x4d, 0x1f, 0x69, 0x5e, 0x1, 0xd8, 0xa3, 0x37, 0xa4, 0xa, 0x27, 0x1a, 0x13, 0x79, 0x25, 0x9, 0xaa, 0xe3, 0xd8, 0x9c, 0x5f, 0xea, 0x7d, 0x67, 0x80, 0xd7, 0x31, 0x20, 0xab, 0x3, 0x20, 0x5, 0x20, 0x2a, 0x13, 0x41, 0x40, 0x2b, 0x0, 0x76, 0x22, 0xb9, 0xb1, 0xd1, 0x92, 0x91, 0x5d, 0x86, 0xf3, 0x35, 0xef, 0x5, 0xa3, 0x25, 0x60, 0xd, 0x6e, 0x66, 0xe5, 0x0, 0xc0, 0xa8, 0x54, 0x1, 0x6, 0xe9, 0x16, 0x9f, 0x4f, 0xdc, 0x1c, 0x13, 0xed, 0xb1, 0x55, 0x31, 0x78, 0x70, 0x8e, 0xca, 0xcb, 0x8e, 0x6a, 0xbe, 0x56, 0x88, 0x67, 0x38, 0xdb, 0x75, 0x58, 0x76, 0xdf, 0x1b, 0x6c, 0x7a, 0xc, 0x6c, 0x90, 0x0, 0xfd, 0xe0, 0xe8, 0x98, 0xe4, 0x4, 0xe2, 0x69, 0xc, 0xe4, 0x40, 0xaa, 0xf9, 0x63, 0x70, 0xbb, 0x4, 0x16, 0x9c, 0x12, 0xa7, 0x3e, 0xe7, 0x38, 0xb3, 0x4, 0x2b, 0x6f, 0xc7, 0x23, 0xbb, 0xc3, 0x66, 0xdb, 0x38, 0x7, 0x0, 0xcf, 0x32, 0x34, 0xb6, 0x52, 0xb4, 0x3c, 0xf7, 0x35, 0x10, 0xd9, 0xf7, 0x6, 0x56, 0x93, 0x4, 0x4b, 0x0, 0x43, 0x28, 0xf9, 0x4a, 0x3d, 0x6e, 0xb0, 0x3e, 0x9, 0x31, 0xa9, 0x62, 0xd6, 0xc4, 0x36, 0x9c, 0xf2, 0xd9, 0xbd, 0x41, 0x2d, 0x24, 0x68, 0xc7, 0x1f, 0x62, 0x60, 0x6a, 0xc1, 0x7f, 0x95, 0x81, 0xaa, 0x13, 0x61, 0x9, 0xa6, 0xf6, 0x1c, 0x30, 0x17, 0x11, 0x6f, 0x48, 0x12, 0x3b, 0xf3, 0x7b, 0xc2, 0xeb, 0xca, 0x92, 0xb7, 0x72, 0x5f, 0x31, 0x90, 0x11, 0x4e, 0x48, 0xb3, 0x13, 0xa6, 0xcc, 0x3e, 0x51, 0x60, 0x91, 0x53, 0x55, 0x87, 0xf3, 0x2a, 0x98, 0xff, 0x7c, 0x6c, 0x1a, 0xf9, 0xec, 0xda, 0xeb, 0x94, 0x13, 0x43, 0xdd, 0x3f, 0x2a, 0x41, 0xd2, 0xb, 0x27, 0x65, 0xe8, 0x13, 0x20, 0x29, 0x3f, 0xc6, 0x7c, 0x48, 0x65, 0x8, 0x41, 0xda, 0xa4, 0xd5, 0x11, 0xc0, 0x2a, 0x61, 0xce, 0x18, 0x58, 0xd2, 0xbe, 0x98, 0x48, 0x96, 0xdd, 0xf5, 0xbc, 0x11, 0x65, 0xb6, 0x12, 0x55, 0xcb, 0xde, 0xb3, 0x78, 0x27, 0x78, 0xdc, 0xcb, 0x72, 0xe6, 0xd7, 0x8a, 0x27, 0xe6, 0x52, 0x1f, 0x10, 0xe0, 0xb8, 0x92, 0x81, 0xb4, 0x3f, 0x1, 0x1d, 0xed, 0x6c, 0xd4, 0xef, 0x12, 0x2f, 0x73, 0xa0, 0xe, 0xf, 0x42, 0x24, 0x20, 0xf, 0x91, 0xbf, 0x6e, 0x44, 0xfb, 0xde, 0xa1, 0x4, 0xa5, 0x7, 0xaa, 0xa0, 0x23, 0xad, 0xd4, 0x4b, 0xaa, 0x73, 0x0, 0xb7, 0xa1, 0x82, 0x87, 0x46, 0x74, 0x9a, 0xf, 0x48, 0x5d, 0xb3, 0xd, 0xa2, 0xb0, 0x96, 0xe5, 0x7d, 0xc8, 0x81, 0x19, 0xf1, 0x36, 0x2b, 0xba, 0xbd, 0x5e, 0xb3, 0xb7, 0x55, 0x12, 0x76, 0x90, 0xc4, 0x3a, 0x1, 0xa7, 0x66, 0xbc, 0x3, 0x90, 0xe0, 0x8, 0xc8, 0x42, 0x29, 0xa5, 0x7b, 0xa2, 0x63, 0x9f, 0x88, 0x26, 0xa, 0x9c, 0x85, 0x6f, 0x7b, 0x2b, 0x0, 0x92, 0x51, 0x4a, 0x81, 0x5c, 0x2a, 0xcb, 0x2a, 0x47, 0x0, 0xb0, 0x2b, 0x8, 0x11, 0x62, 0x20, 0x58, 0x20, 0x47, 0x77, 0x5a, 0xe5, 0x98, 0x43, 0x3f, 0x2, 0xd8, 0xc1, 0xa5, 0x39, 0x40, 0x82, 0xb5, 0xd9, 0xd7, 0x5a, 0x2, 0x59, 0x80, 0x9, 0x8a, 0x0, 0x7f, 0x1, 0x8, 0x44, 0x8, 0x64, 0xe0, 0xe8, 0x6e, 0x4b, 0xb4, 0x87, 0xa6, 0xc4, 0x3d, 0x17, 0x24, 0xa3, 0xa8, 0xc0, 0x32, 0x8a, 0xea, 0x33, 0x67, 0x0, 0x6e, 0xc, 0x94, 0x5e, 0xe2, 0x46, 0x11, 0x3a, 0x0, 0x82, 0x57, 0x1, 0x98, 0xbf, 0xb, 0xa4, 0xf6, 0x55, 0xd4, 0x2a, 0xe1, 0x0, 0x40, 0xf5, 0xf3, 0xa5, 0xd3, 0x16, 0x6a, 0xb4, 0xa7, 0x19, 0xfa, 0x4f, 0x18, 0xe8, 0x2c, 0x34, 0xfb, 0x92, 0x20, 0xbb, 0xf, 0xa3, 0x1d, 0xc0, 0xcd, 0xe7, 0xb7, 0x83, 0xf9, 0xf2, 0x24, 0xd3, 0xd7, 0xaf, 0x40, 0x9a, 0x84, 0x1, 0xf0, 0xfe, 0xf6, 0xee, 0x1d, 0x80, 0x4f, 0xff, 0xc8, 0xdf, 0x63, 0xeb, 0xfd, 0x6f, 0x3, 0x74, 0x35, 0xa7, 0x2a, 0xf0, 0x17, 0xed, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x20, 0x8, 0x6, 0x0, 0x0, 0x0, 0x73, 0x7a, 0x7a, 0xf4, 0x0, 0x0, 0x2, 0x7f, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x62, 0x91, 0x16, 0x97, 0x30, 0x63, 0x60, 0x60, 0x38, 0xc9, 0x30, 0x30, 0xc0, 0x9c, 0x11, 0xe8, 0x80, 0xff, 0x6b, 0x3, 0x7f, 0xd, 0x88, 0xed, 0xc1, 0xeb, 0xd9, 0x18, 0x58, 0x60, 0x1c, 0x9e, 0xac, 0xdd, 0x0, 0x5a, 0xcb, 0x6, 0xc5, 0x99, 0x23, 0x6, 0xa2, 0xaf, 0xe4, 0xb3, 0xe5, 0x8a, 0x39, 0x69, 0xf8, 0xcf, 0xa8, 0x82, 0x2d, 0x52, 0xe0, 0x1e, 0x61, 0x63, 0xe0, 0x93, 0x29, 0x7a, 0x66, 0xdb, 0xdb, 0x7a, 0x5d, 0x92, 0x96, 0x45, 0x12, 0x55, 0xf, 0x24, 0xbd, 0x4, 0x50, 0x22, 0x81, 0x98, 0x70, 0x96, 0x63, 0x2b, 0x91, 0x3d, 0xdb, 0x80, 0xb0, 0xfd, 0x52, 0xf7, 0x85, 0x6d, 0xfe, 0xf9, 0xfb, 0x2f, 0x0, 0x2, 0x80, 0x18, 0x80, 0xa7, 0x4a, 0xa8, 0x6a, 0x40, 0xf8, 0x15, 0xc0, 0x9c, 0x61, 0x43, 0x77, 0xd3, 0xd, 0x48, 0x34, 0xce, 0x5e, 0x0, 0x84, 0xd0, 0x24, 0xe7, 0xf1, 0xa8, 0x17, 0x0, 0x3, 0x94, 0x7d, 0xef, 0x1c, 0xec, 0xe, 0x98, 0x38, 0x60, 0x33, 0xc7, 0x34, 0xb6, 0x90, 0xb5, 0x1, 0xf0, 0x76, 0xfb, 0x47, 0x3d, 0xe6, 0x59, 0x62, 0x89, 0x5, 0x60, 0x8f, 0xb1, 0x7d, 0x70, 0x6a, 0x9c, 0x20, 0xf1, 0x5e, 0x82, 0x49, 0x5c, 0xff, 0x27, 0x7f, 0xcc, 0x73, 0x1c, 0xd0, 0x6f, 0xe, 0xb4, 0x3b, 0x0, 0x52, 0x3, 0x35, 0x4e, 0x94, 0xa0, 0x37, 0x0, 0x9b, 0xa4, 0x18, 0x37, 0x5e, 0xd2, 0xe8, 0xd3, 0x2d, 0xd7, 0xbd, 0x52, 0x61, 0x3b, 0x97, 0x3b, 0x5c, 0xb9, 0x3, 0x98, 0xb1, 0xa, 0x8c, 0x34, 0xeb, 0x68, 0xef, 0xc2, 0x9f, 0x22, 0xc, 0x4e, 0xf2, 0x80, 0x42, 0xa8, 0x4e, 0xdd, 0x89, 0x8f, 0x50, 0xb4, 0x84, 0x9d, 0xbd, 0xb7, 0x33, 0x6d, 0xc0, 0x7b, 0x9, 0xc8, 0x17, 0xdf, 0x13, 0x4b, 0xca, 0xf3, 0x2f, 0xe, 0x24, 0x69, 0x8e, 0xf7, 0x68, 0x2d, 0x81, 0xfb, 0xa9, 0xfc, 0xe2, 0xbc, 0x73, 0xdc, 0x51, 0x7c, 0x1d, 0x9, 0xdd, 0x1, 0x72, 0xb6, 0x59, 0x1, 0x26, 0xe, 0xc2, 0xb8, 0x85, 0xf7, 0xe, 0xd8, 0x71, 0xe2, 0x9e, 0x6e, 0xae, 0x8e, 0x18, 0x2d, 0x0, 0x9, 0x1f, 0xd2, 0xbd, 0x17, 0xb4, 0x14, 0xc2, 0xc7, 0x29, 0x2, 0x33, 0x9f, 0x1c, 0xc5, 0xbc, 0x3, 0x5b, 0x9, 0x8c, 0xf9, 0xe2, 0x80, 0xff, 0xa0, 0x3, 0x53, 0x27, 0xe1, 0x6e, 0xac, 0x26, 0x3d, 0x60, 0x2d, 0x37, 0x36, 0xb9, 0x26, 0xc7, 0xa3, 0xd9, 0x9a, 0x2e, 0xea, 0xa7, 0x7a, 0x3, 0x38, 0x8, 0x23, 0xb8, 0x25, 0x51, 0x3a, 0xfb, 0xc3, 0x5c, 0x2c, 0x0, 0xf0, 0x69, 0xa, 0xce, 0x8f, 0x47, 0x5b, 0x18, 0x7f, 0x9f, 0x46, 0x3, 0x6f, 0x73, 0xff, 0xb5, 0x4, 0x26, 0xf5, 0x62, 0x1f, 0x43, 0xbc, 0x81, 0xa4, 0x3f, 0x12, 0xeb, 0x18, 0xd2, 0x74, 0x37, 0xf6, 0xe8, 0xcb, 0x1f, 0xa2, 0x88, 0x3d, 0x16, 0x1e, 0xed, 0x25, 0x38, 0xc5, 0x5e, 0x82, 0xd3, 0x2d, 0x13, 0x89, 0x25, 0x74, 0x47, 0xf0, 0xfb, 0x9e, 0xf1, 0x32, 0x86, 0x29, 0xc6, 0xe2, 0x0, 0xd, 0xae, 0x1f, 0x1d, 0x30, 0x9, 0x2d, 0xf6, 0x47, 0xcd, 0xc8, 0x23, 0x3e, 0x4c, 0x41, 0x77, 0x53, 0xae, 0x2f, 0x0, 0xbe, 0x97, 0xc0, 0xb7, 0xbd, 0xfb, 0x8, 0x76, 0x20, 0x56, 0x80, 0x50, 0x32, 0x5f, 0x46, 0x12, 0x68, 0xf6, 0x24, 0xa1, 0xb5, 0xf9, 0xd7, 0x9f, 0x25, 0xc9, 0x9c, 0x75, 0x81, 0x1b, 0x3e, 0x4f, 0xc1, 0xe8, 0x24, 0x16, 0x42, 0xd2, 0x40, 0x1c, 0xd9, 0xb6, 0x26, 0xc, 0xa4, 0x58, 0x1b, 0x70, 0x3e, 0x2c, 0x0, 0xdd, 0xb8, 0x8a, 0x76, 0x73, 0x5d, 0x57, 0x32, 0xc9, 0x45, 0xfe, 0x23, 0x3a, 0x2c, 0x8, 0x52, 0x32, 0xef, 0x0, 0xdd, 0x7e, 0x9d, 0xd9, 0xbe, 0xc6, 0xe5, 0xbe, 0xd6, 0x31, 0x1c, 0x88, 0x16, 0xad, 0xa2, 0x74, 0xd1, 0xae, 0x24, 0x95, 0xc4, 0xad, 0x6, 0xb, 0x0, 0x59, 0x1c, 0x67, 0xe7, 0x5c, 0x33, 0x6b, 0xef, 0x25, 0x68, 0x37, 0x58, 0xa8, 0x5, 0xfa, 0x17, 0x28, 0xaa, 0x1a, 0xa9, 0x96, 0x46, 0x77, 0x1c, 0xf8, 0x16, 0x71, 0xa0, 0x2f, 0xfc, 0x5a, 0xe7, 0x5d, 0x6b, 0x13, 0x76, 0x73, 0x89, 0x38, 0x72, 0x35, 0x1, 0x10, 0xfa, 0x9, 0x20, 0xe, 0xa4, 0xa9, 0x9f, 0xba, 0xc6, 0x5, 0x2f, 0x0, 0x6d, 0x43, 0x77, 0x6c, 0xab, 0x66, 0x6c, 0xa7, 0x7f, 0x73, 0x60, 0x77, 0x21, 0xe7, 0xf7, 0x53, 0x36, 0x75, 0x2, 0xfc, 0x37, 0x96, 0x15, 0xd1, 0x28, 0xc6, 0xff, 0x65, 0xa0, 0xd, 0x60, 0x2, 0x63, 0x4, 0x0, 0xf5, 0x8e, 0x13, 0x81, 0xf4, 0x3c, 0x86, 0x81, 0x1, 0x49, 0x0, 0x33, 0xd4, 0x35, 0xaa, 0x8d, 0x7e, 0xfe, 0xa5, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char tree_cursor_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0xe, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x96, 0xdd, 0xe3, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0xc6, 0x50, 0x4c, 0x54, 0x45, 0xd4, 0xab, 0x9e, 0xd3, 0xaa, 0x9d, 0xd4, 0xab, 0x9e, 0xd3, 0xaa, 0x9d, 0xd4, 0xab, 0x9c, 0xd4, 0xac, 0x9e, 0xd5, 0xaf, 0xa3, 0xd5, 0xb0, 0xa3, 0xd5, 0xaf, 0xa3, 0xd5, 0xad, 0xa1, 0xd5, 0xaf, 0xa3, 0xd5, 0xad, 0xa1, 0xd5, 0xb0, 0xa3, 0xd6, 0xad, 0xa0, 0xd6, 0xad, 0xa0, 0xd5, 0xb0, 0xa3, 0xd7, 0xb1, 0xa5, 0xd7, 0xb1, 0xa7, 0xd7, 0xb1, 0xa7, 0xd7, 0xb1, 0xa7, 0xd7, 0xb1, 0xa7, 0xd7, 0xb1, 0xa5, 0xd7, 0xb1, 0xa5, 0xd8, 0xb3, 0xa8, 0xd8, 0xb5, 0xaa, 0xda, 0xb3, 0xa8, 0xda, 0xb3, 0xa8, 0xd8, 0xb3, 0xa8, 0xd8, 0xb5, 0xaa, 0xda, 0xb3, 0xa8, 0xd8, 0xb3, 0xa8, 0xdb, 0xb7, 0xad, 0xda, 0xb8, 0xae, 0xdb, 0xb9, 0xad, 0xdb, 0xb9, 0xad, 0xdb, 0xb7, 0xad, 0xdd, 0xba, 0xb1, 0xdd, 0xbb, 0xb1, 0xdd, 0xbd, 0xb1, 0xdd, 0xbf, 0xb3, 0xdd, 0xbd, 0xb3, 0xdf, 0xc1, 0xb7, 0xdf, 0xc0, 0xb5, 0xdf, 0xbf, 0xb5, 0xe1, 0xc3, 0xb9, 0xe1, 0xc3, 0xbb, 0xe1, 0xc5, 0xbb, 0xe2, 0xc7, 0xbe, 0xe1, 0xc5, 0xbd, 0xe4, 0xcb, 0xc2, 0xe3, 0xca, 0xc1, 0xe3, 0xcb, 0xc3, 0xe6, 0xce, 0xc6, 0xe6, 0xd0, 0xc6, 0xe8, 0xd1, 0xca, 0xe8, 0xd1, 0xca, 0xe8, 0xd0, 0xca, 0xe8, 0xcf, 0xca, 0xb7, 0x7d, 0x69, 0xb1, 0x77, 0x63, 0xac, 0x73, 0x5c, 0xa6, 0x69, 0x56, 0x9c, 0x67, 0x54, 0x93, 0x62, 0x51, 0x88, 0x60, 0x50, 0x0, 0x0, 0x0, 0x39, 0x76, 0x1d, 0xc2, 0x0, 0x0, 0x0, 0x3a, 0x74, 0x52, 0x4e, 0x53, 0x32, 0x2f, 0x30, 0x33, 0x38, 0x40, 0x32, 0x2f, 0x2f, 0x2f, 0x31, 0x33, 0x33, 0x33, 0x36, 0x38, 0x31, 0x2f, 0x30, 0x31, 0x33, 0x33, 0x35, 0x2f, 0x2f, 0x2f, 0x30, 0x32, 0x33, 0x33, 0x33, 0x2f, 0x2f, 0x2f, 0x30, 0x30, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x32, 0x2f, 0x2f, 0x2f, 0xb8, 0xf, 0x95, 0x41, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x41, 0x89, 0xde, 0x6c, 0x4e, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x4, 0x4e, 0x1d, 0x2, 0xaf, 0x0, 0x0, 0x0, 0x9e, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x55, 0xcf, 0x5b, 0x17, 0x81, 0x40, 0x14, 0x5, 0xe0, 0xe3, 0x9a, 0x4b, 0x2e, 0x31, 0x14, 0x62, 0x22, 0x53, 0x4d, 0x83, 0x44, 0xc, 0xa6, 0xa9, 0xf9, 0xff, 0xbf, 0xca, 0xd4, 0x5a, 0x1e, 0x7c, 0xfb, 0xec, 0xb5, 0x9f, 0xf, 0x7c, 0xfe, 0x80, 0x80, 0x86, 0xd6, 0x6c, 0x69, 0xed, 0x8e, 0x80, 0xbc, 0x6b, 0x18, 0xbd, 0xfe, 0x60, 0x68, 0x9a, 0xa3, 0xf1, 0x24, 0x7, 0x39, 0xb5, 0x2c, 0x6b, 0x36, 0x47, 0x68, 0x81, 0xd0, 0x52, 0x42, 0x61, 0x3b, 0xb6, 0xb3, 0x72, 0xd6, 0x1b, 0x77, 0xeb, 0xee, 0xa, 0x28, 0x31, 0xc6, 0x9e, 0x87, 0x3d, 0xbc, 0x3f, 0xf8, 0x7e, 0x9, 0xea, 0x48, 0x8, 0x9, 0xc2, 0x28, 0x22, 0x21, 0x9, 0x14, 0x28, 0x1a, 0x33, 0x16, 0xd3, 0x98, 0xb2, 0x98, 0x51, 0x5, 0xe5, 0x49, 0x3b, 0xeb, 0x5e, 0x74, 0x4a, 0x28, 0x92, 0xca, 0xb5, 0xbe, 0xa4, 0x0, 0x99, 0xde, 0xd2, 0xca, 0xbd, 0x5a, 0x9, 0x79, 0x96, 0x3d, 0xb2, 0x9f, 0x1c, 0xc4, 0x93, 0xf3, 0x17, 0xaf, 0xfb, 0xe6, 0x2, 0xfe, 0x5f, 0xf8, 0x2, 0x30, 0xbc, 0x1f, 0xb4, 0x2b, 0xfc, 0x80, 0xca, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0xe, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x96, 0xdd, 0xe3, 0x0, 0x0, 0x0, 0xc3, 0x50, 0x4c, 0x54, 0x45, 0xd4, 0xab, 0x9e, 0xd3, 0xaa, 0x9d, 0xd4, 0xab, 0x9e, 0xd3, 0xaa, 0x9d, 0xd4, 0xab, 0x9c, 0xd4, 0xac, 0x9e, 0xd5, 0xaf, 0xa3, 0xd5, 0xb0, 0xa3, 0xd5, 0xaf, 0xa3, 0xd5, 0xad, 0xa1, 0xd5, 0xaf, 0xa3, 0xd5, 0xad, 0xa1, 0xd5, 0xb0, 0xa3, 0xd6, 0xad, 0xa0, 0xd6, 0xad, 0xa0, 0xd5, 0xb0, 0xa3, 0xd7, 0xb1, 0xa5, 0xd7, 0xb1, 0xa7, 0xd7, 0xb1, 0xa7, 0xd7, 0xb1, 0xa7, 0xd7, 0xb1, 0xa7, 0xd7, 0xb1, 0xa5, 0xd7, 0xb1, 0xa5, 0xd8, 0xb3, 0xa8, 0xd8, 0xb5, 0xaa, 0xda, 0xb3, 0xa8, 0xda, 0xb3, 0xa8, 0xd8, 0xb3, 0xa8, 0xd8, 0xb5, 0xaa, 0xda, 0xb3, 0xa8, 0xd8, 0xb3, 0xa8, 0xdb, 0xb7, 0xad, 0xda, 0xb8, 0xae, 0xdb, 0xb9, 0xad, 0xdb, 0xb9, 0xad, 0xdb, 0xb7, 0xad, 0xdd, 0xba, 0xb1, 0xdd, 0xbb, 0xb1, 0xdd, 0xbd, 0xb1, 0xdd, 0xbf, 0xb3, 0xdd, 0xbd, 0xb3, 0xdf, 0xc1, 0xb7, 0xdf, 0xc0, 0xb5, 0xdf, 0xbf, 0xb5, 0xe1, 0xc3, 0xb9, 0xe1, 0xc3, 0xbb, 0xe1, 0xc5, 0xbb, 0xe2, 0xc7, 0xbe, 0xe1, 0xc5, 0xbd, 0xe4, 0xcb, 0xc2, 0xe3, 0xca, 0xc1, 0xe3, 0xcb, 0xc3, 0xe6, 0xce, 0xc6, 0xe6, 0xd0, 0xc6, 0xe8, 0xd1, 0xca, 0xe8, 0xd1, 0xca, 0xe8, 0xd0, 0xca, 0xe8, 0xcf, 0xca, 0xb7, 0x7d, 0x69, 0xb1, 0x77, 0x63, 0xac, 0x73, 0x5c, 0xa6, 0x69, 0x56, 0x9c, 0x67, 0x54, 0x93, 0x62, 0x51, 0x88, 0x60, 0x50, 0x9e, 0xe4, 0xa3, 0x87, 0x0, 0x0, 0x0, 0x3a, 0x74, 0x52, 0x4e, 0x53, 0x32, 0x2f, 0x30, 0x33, 0x38, 0x40, 0x32, 0x2f, 0x2f, 0x2f, 0x31, 0x33, 0x33, 0x33, 0x36, 0x38, 0x31, 0x2f, 0x30, 0x31, 0x33, 0x33, 0x35, 0x2f, 0x2f, 0x2f, 0x30, 0x32, 0x33, 0x33, 0x33, 0x2f, 0x2f, 0x2f, 0x30, 0x30, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x32, 0x2f, 0x2f, 0x2f, 0xb8, 0xf, 0x95, 0x41, 0x0, 0x0, 0x0, 0x64, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x4d, 0xc9, 0x1, 0xa, 0x2, 0x31, 0xc, 0x44, 0xd1, 0xff, 0xdb, 0xec, 0x2a, 0x1e, 0x48, 0xc0, 0xfb, 0x7b, 0x2c, 0x3b, 0x96, 0x2c, 0x88, 0x3, 0x19, 0x78, 0x19, 0x5f, 0xfc, 0xa7, 0x7c, 0xb, 0x78, 0xd5, 0xb3, 0x3c, 0x45, 0xf5, 0xea, 0xf2, 0x21, 0xb4, 0xc2, 0xd8, 0xbc, 0x19, 0xcd, 0xb0, 0xab, 0xbc, 0x83, 0xa4, 0x1f, 0x6c, 0x1e, 0x82, 0xca, 0x67, 0x2c, 0x2d, 0xe, 0x25, 0x31, 0x67, 0x6a, 0x51, 0x99, 0xc0, 0xc8, 0xbe, 0x35, 0xcc, 0x45, 0xc, 0xca, 0xdc, 0x1c, 0x6, 0x70, 0x8f, 0xa1, 0xd7, 0x36, 0x13, 0xe8, 0xb5, 0x6d, 0x18, 0x6b, 0xb3, 0xf8, 0x65, 0xe6, 0xb, 0x36, 0x5c, 0x24, 0xde, 0x86, 0x96, 0x3a, 0xaf, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char tree_cursor_unfocus_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0xe, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x96, 0xdd, 0xe3, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x99, 0x50, 0x4c, 0x54, 0x45, 0xc0, 0xb5, 0xb2, 0xbf, 0xb4, 0xb1, 0xc0, 0xb5, 0xb2, 0xbf, 0xb4, 0xb1, 0xbf, 0xb5, 0xb1, 0xc0, 0xb5, 0xb2, 0xc3, 0xb8, 0xb5, 0xc3, 0xb8, 0xb5, 0xc2, 0xb7, 0xb4, 0xc3, 0xb8, 0xb5, 0xc2, 0xb7, 0xb4, 0xc3, 0xb8, 0xb5, 0xc2, 0xb7, 0xb4, 0xc3, 0xb8, 0xb5, 0xc5, 0xba, 0xb7, 0xc5, 0xbc, 0xb9, 0xc5, 0xbc, 0xb9, 0xc5, 0xbc, 0xb9, 0xc5, 0xbc, 0xb9, 0xc5, 0xba, 0xb7, 0xc5, 0xba, 0xb7, 0xc6, 0xbd, 0xba, 0xc7, 0xbe, 0xbb, 0xc7, 0xbe, 0xbb, 0xc6, 0xbd, 0xba, 0xc7, 0xbe, 0xbb, 0xc6, 0xbd, 0xba, 0xca, 0xc1, 0xbe, 0xca, 0xc1, 0xbe, 0xcd, 0xc4, 0xc1, 0xcd, 0xc6, 0xc3, 0xd0, 0xc9, 0xc6, 0xcf, 0xc8, 0xc5, 0xd2, 0xcb, 0xc8, 0xd3, 0xcb, 0xc9, 0xd3, 0xcc, 0xc9, 0xd5, 0xcd, 0xcb, 0xd4, 0xcc, 0xca, 0xd7, 0xd1, 0xcf, 0xd6, 0xd0, 0xce, 0xda, 0xd4, 0xd2, 0xdd, 0xd7, 0xd5, 0xdd, 0xd7, 0xd5, 0x9a, 0x8b, 0x86, 0x94, 0x85, 0x80, 0x8e, 0x80, 0x7a, 0x88, 0x79, 0x74, 0x81, 0x75, 0x6f, 0x7a, 0x6f, 0x6a, 0x73, 0x69, 0x65, 0x0, 0x0, 0x0, 0xfb, 0x87, 0x71, 0x8e, 0x0, 0x0, 0x0, 0x2b, 0x74, 0x52, 0x4e, 0x53, 0x32, 0x2f, 0x30, 0x33, 0x38, 0x40, 0x32, 0x2f, 0x2f, 0x31, 0x33, 0x33, 0x36, 0x38, 0x31, 0x2f, 0x30, 0x31, 0x33, 0x33, 0x35, 0x2f, 0x2f, 0x30, 0x32, 0x33, 0x33, 0x2f, 0x30, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x32, 0x2f, 0x82, 0xd8, 0x8a, 0x2f, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x32, 0x40, 0xd2, 0x4c, 0xc8, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x4, 0x4e, 0x1d, 0x2, 0xaf, 0x0, 0x0, 0x0, 0x82, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x55, 0xcf, 0xe9, 0x16, 0xc1, 0x30, 0x14, 0x4, 0xe0, 0xb1, 0x96, 0x16, 0x25, 0x34, 0x84, 0x26, 0x2d, 0xaa, 0xb6, 0xac, 0xef, 0xff, 0x72, 0x6e, 0x38, 0xe, 0xfd, 0xe6, 0xce, 0x99, 0xdf, 0x17, 0xcf, 0xe, 0x68, 0xf4, 0x48, 0x7f, 0x40, 0x86, 0x23, 0xd, 0x33, 0x4e, 0x92, 0x64, 0x32, 0x4d, 0xb3, 0x2c, 0x9d, 0xcd, 0xd, 0xec, 0x22, 0xcf, 0xf3, 0xe5, 0x8a, 0xb1, 0x35, 0x63, 0x1b, 0xb, 0x57, 0xf0, 0x82, 0x73, 0xbe, 0xdd, 0x9, 0x21, 0xf6, 0xe, 0xfe, 0xf0, 0x55, 0x96, 0xa5, 0x47, 0x90, 0x91, 0x52, 0x4a, 0x2a, 0x29, 0x3, 0x42, 0x55, 0x93, 0xaa, 0x8e, 0x53, 0x5, 0xf8, 0x23, 0x39, 0x51, 0xcf, 0x14, 0xf, 0xd7, 0x44, 0x97, 0xf7, 0x35, 0xe, 0xb6, 0xbd, 0xb6, 0x1f, 0xb4, 0x16, 0xe6, 0xf6, 0xc7, 0x40, 0xdf, 0x1f, 0x3f, 0x1a, 0xdd, 0x17, 0x5e, 0xc0, 0x36, 0x18, 0x83, 0x7f, 0x54, 0x76, 0x87, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0xe, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x96, 0xdd, 0xe3, 0x0, 0x0, 0x0, 0x96, 0x50, 0x4c, 0x54, 0x45, 0xc0, 0xb5, 0xb2, 0xbf, 0xb4, 0xb1, 0xc0, 0xb5, 0xb2, 0xbf, 0xb4, 0xb1, 0xbf, 0xb5, 0xb1, 0xc0, 0xb5, 0xb2, 0xc3, 0xb8, 0xb5, 0xc3, 0xb8, 0xb5, 0xc2, 0xb7, 0xb4, 0xc3, 0xb8, 0xb5, 0xc2, 0xb7, 0xb4, 0xc3, 0xb8, 0xb5, 0xc2, 0xb7, 0xb4, 0xc3, 0xb8, 0xb5, 0xc5, 0xba, 0xb7, 0xc5, 0xbc, 0xb9, 0xc5, 0xbc, 0xb9, 0xc5, 0xbc, 0xb9, 0xc5, 0xbc, 0xb9, 0xc5, 0xba, 0xb7, 0xc5, 0xba, 0xb7, 0xc6, 0xbd, 0xba, 0xc7, 0xbe, 0xbb, 0xc7, 0xbe, 0xbb, 0xc6, 0xbd, 0xba, 0xc7, 0xbe, 0xbb, 0xc6, 0xbd, 0xba, 0xca, 0xc1, 0xbe, 0xca, 0xc1, 0xbe, 0xcd, 0xc4, 0xc1, 0xcd, 0xc6, 0xc3, 0xd0, 0xc9, 0xc6, 0xcf, 0xc8, 0xc5, 0xd2, 0xcb, 0xc8, 0xd3, 0xcb, 0xc9, 0xd3, 0xcc, 0xc9, 0xd5, 0xcd, 0xcb, 0xd4, 0xcc, 0xca, 0xd7, 0xd1, 0xcf, 0xd6, 0xd0, 0xce, 0xda, 0xd4, 0xd2, 0xdd, 0xd7, 0xd5, 0xdd, 0xd7, 0xd5, 0x9a, 0x8b, 0x86, 0x94, 0x85, 0x80, 0x8e, 0x80, 0x7a, 0x88, 0x79, 0x74, 0x81, 0x75, 0x6f, 0x7a, 0x6f, 0x6a, 0x73, 0x69, 0x65, 0x9a, 0x51, 0xd2, 0xe3, 0x0, 0x0, 0x0, 0x2b, 0x74, 0x52, 0x4e, 0x53, 0x32, 0x2f, 0x30, 0x33, 0x38, 0x40, 0x32, 0x2f, 0x2f, 0x31, 0x33, 0x33, 0x36, 0x38, 0x31, 0x2f, 0x30, 0x31, 0x33, 0x33, 0x35, 0x2f, 0x2f, 0x30, 0x32, 0x33, 0x33, 0x2f, 0x30, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x32, 0x2f, 0x82, 0xd8, 0x8a, 0x2f, 0x0, 0x0, 0x0, 0x5f, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x62, 0xd1, 0x66, 0x40, 0x6, 0x2c, 0x8c, 0x57, 0x0, 0x2d, 0xc9, 0x87, 0x15, 0x4, 0x51, 0x8, 0x42, 0xd1, 0x7, 0x13, 0x3b, 0xd9, 0xfe, 0x1b, 0x1c, 0x16, 0xcf, 0xf, 0xa6, 0xab, 0x6a, 0xd3, 0x2a, 0xbf, 0x53, 0xb7, 0x66, 0xa8, 0x63, 0xe9, 0xd4, 0xbb, 0x88, 0x82, 0xcb, 0x47, 0xd9, 0xb, 0x54, 0xde, 0xec, 0x57, 0x97, 0xde, 0x63, 0x94, 0x12, 0xab, 0xec, 0xec, 0x56, 0xce, 0x69, 0x28, 0xc8, 0x9f, 0xbf, 0x9c, 0x39, 0xd8, 0x16, 0x47, 0x69, 0x65, 0xc, 0xe, 0xc3, 0x8e, 0xeb, 0x69, 0x28, 0x1, 0x0, 0xb0, 0xae, 0x0, 0x0, 0x90, 0x3f, 0xa6, 0x5b, 0x1b, 0xad, 0x12, 0x69, 0xd7, 0x5c, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char tree_title_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x1, 0x3, 0x0, 0x0, 0x0, 0x25, 0x3d, 0x6d, 0x22, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x6, 0x50, 0x4c, 0x54, 0x45, 0x25, 0x23, 0x25, 0x4c, 0x4a, 0x4e, 0x1, 0xf9, 0x98, 0x2e, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x1, 0xff, 0x2, 0x2d, 0xde, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0xc, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0x20, 0xd, 0x0, 0x0, 0x0, 0x30, 0x0, 0x1, 0xc7, 0xaa, 0x85, 0x8e, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x1, 0x3, 0x0, 0x0, 0x0, 0x25, 0x3d, 0x6d, 0x22, 0x0, 0x0, 0x0, 0x6, 0x50, 0x4c, 0x54, 0x45, 0x25, 0x23, 0x25, 0x4c, 0x4a, 0x4e, 0x1, 0xf9, 0x98, 0x2e, 0x0, 0x0, 0x0, 0xb, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x20, 0x11, 0x0, 0x0, 0x0, 0x30, 0x0, 0x1, 0x6e, 0xa6, 0xf, 0x3f, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char tree_title_pressed_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x1, 0x3, 0x0, 0x0, 0x0, 0x25, 0x3d, 0x6d, 0x22, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x6, 0x50, 0x4c, 0x54, 0x45, 0x36, 0x34, 0x36, 0x4c, 0x4a, 0x4e, 0x14, 0xd7, 0x5b, 0xf8, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x1, 0xff, 0x2, 0x2d, 0xde, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0xc, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0x20, 0xd, 0x0, 0x0, 0x0, 0x30, 0x0, 0x1, 0xc7, 0xaa, 0x85, 0x8e, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x1, 0x3, 0x0, 0x0, 0x0, 0x25, 0x3d, 0x6d, 0x22, 0x0, 0x0, 0x0, 0x6, 0x50, 0x4c, 0x54, 0x45, 0x36, 0x34, 0x36, 0x4c, 0x4a, 0x4e, 0x14, 0xd7, 0x5b, 0xf8, 0x0, 0x0, 0x0, 0xb, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x20, 0x11, 0x0, 0x0, 0x0, 0x30, 0x0, 0x1, 0x6e, 0xa6, 0xf, 0x3f, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char unchecked_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x36, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x38, 0x37, 0x40, 0x20, 0x20, 0x24, 0x20, 0x20, 0x24, 0x38, 0x36, 0x40, 0x20, 0x20, 0x25, 0x1e, 0x1e, 0x22, 0x1f, 0x1f, 0x23, 0x20, 0x20, 0x24, 0x22, 0x22, 0x27, 0x23, 0x23, 0x28, 0x25, 0x25, 0x2a, 0xff, 0xff, 0xff, 0xf7, 0x93, 0x46, 0x7a, 0x0, 0x0, 0x0, 0xb, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x7, 0x27, 0x50, 0x66, 0x68, 0xb4, 0xfa, 0xfb, 0xb4, 0xfa, 0xa4, 0x7f, 0xe1, 0x5a, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x11, 0xe2, 0xb5, 0x3d, 0xba, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x53, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0xb5, 0xcf, 0xc1, 0x12, 0x80, 0x20, 0x8, 0x45, 0x51, 0x5, 0x14, 0xd, 0x5, 0xff, 0xff, 0x6b, 0x23, 0x27, 0x67, 0x9a, 0x6c, 0xdb, 0x5d, 0x9e, 0xd, 0x8f, 0x10, 0xb6, 0x22, 0x20, 0xa5, 0x19, 0x21, 0x44, 0x7, 0xc8, 0x2c, 0x6d, 0x26, 0x9c, 0xc1, 0x1, 0xb9, 0xab, 0xcd, 0xb4, 0x33, 0x3a, 0x90, 0xe8, 0xb8, 0x53, 0x21, 0x87, 0xd4, 0x6c, 0x81, 0xb5, 0xf4, 0x17, 0x6c, 0x67, 0x9f, 0xc3, 0xca, 0x35, 0xc, 0x6a, 0x59, 0xd3, 0x8f, 0xa, 0x5f, 0xcf, 0xbd, 0x3a, 0x1, 0x93, 0xe2, 0x8, 0xa4, 0xb1, 0xeb, 0xd3, 0x56, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x33, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x38, 0x37, 0x40, 0x20, 0x20, 0x24, 0x20, 0x20, 0x24, 0x38, 0x36, 0x40, 0x20, 0x20, 0x25, 0x1e, 0x1e, 0x22, 0x1f, 0x1f, 0x23, 0x20, 0x20, 0x24, 0x22, 0x22, 0x27, 0x23, 0x23, 0x28, 0x25, 0x25, 0x2a, 0x23, 0xc3, 0x49, 0x39, 0x0, 0x0, 0x0, 0xb, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x7, 0x27, 0x50, 0x66, 0x68, 0xb4, 0xfa, 0xfb, 0xb4, 0xfa, 0xa4, 0x7f, 0xe1, 0x5a, 0x0, 0x0, 0x0, 0x4f, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0xb5, 0xcf, 0x45, 0x2, 0x80, 0x40, 0x8, 0x0, 0x40, 0x97, 0x66, 0xfb, 0xff, 0x9f, 0xb5, 0xdb, 0xb3, 0x73, 0xa4, 0x19, 0xbe, 0x2, 0x20, 0xf1, 0x8a, 0x10, 0xc2, 0x1c, 0x0, 0xd1, 0x94, 0x57, 0x49, 0x5, 0xe6, 0x0, 0x6a, 0xa9, 0x6d, 0x55, 0x8b, 0xe2, 0x1c, 0xa0, 0x54, 0xfb, 0xae, 0x26, 0x9a, 0x3, 0x9c, 0xdb, 0x11, 0x68, 0x99, 0xff, 0xa, 0x7c, 0xd6, 0xde, 0xf, 0x33, 0x9c, 0x3, 0xe0, 0x76, 0x9c, 0x1e, 0x1d, 0xbe, 0xcf, 0x7d, 0x4c, 0x93, 0xe2, 0x8, 0xa4, 0x66, 0x3c, 0xec, 0xed, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char updown_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x2b, 0x8a, 0x3e, 0x7d, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0xa6, 0x49, 0x44, 0x41, 0x54, 0x28, 0x91, 0xa5, 0x90, 0x21, 0xe, 0xc2, 0x50, 0x10, 0x44, 0xdf, 0x27, 0x9b, 0x10, 0x2e, 0xc0, 0x9, 0xd6, 0x81, 0xe3, 0x6, 0xe0, 0xa0, 0xd7, 0x2d, 0xae, 0x18, 0x24, 0x95, 0xc5, 0x7d, 0x51, 0xdd, 0xb, 0x60, 0xf6, 0x67, 0x31, 0xfb, 0x49, 0xc1, 0x20, 0x3a, 0x6a, 0x93, 0x99, 0x9d, 0xcc, 0xc, 0x2c, 0x45, 0xaa, 0x47, 0xce, 0x79, 0x2b, 0x22, 0x2d, 0x80, 0x99, 0x5d, 0x54, 0x75, 0xfa, 0x8, 0x82, 0xec, 0x80, 0x7d, 0xe8, 0x7, 0x33, 0x3b, 0xa9, 0xea, 0x94, 0x82, 0xbc, 0x1, 0x3b, 0x60, 0x8, 0xc1, 0x1e, 0x78, 0x9a, 0xd9, 0x51, 0xc2, 0x76, 0x57, 0xbf, 0x0, 0xaa, 0x9b, 0x88, 0xb4, 0x2b, 0x77, 0x7f, 0x1, 0x7d, 0xb5, 0x54, 0xd5, 0x29, 0x84, 0x7d, 0x70, 0x4b, 0x6b, 0x8e, 0xe3, 0x78, 0x7, 0x36, 0x66, 0x76, 0xae, 0xd5, 0x22, 0xf8, 0x15, 0x78, 0x89, 0xbb, 0xaf, 0x53, 0x4a, 0x7, 0x11, 0xe9, 0x72, 0xce, 0x5f, 0x21, 0xdd, 0xfd, 0x21, 0xa5, 0x94, 0x66, 0x96, 0xba, 0x9b, 0xd5, 0x1c, 0x4a, 0x29, 0xcd, 0xff, 0xa1, 0x7e, 0xa6, 0xbe, 0xc6, 0xd4, 0x9f, 0x3c, 0xcb, 0xf1, 0x6, 0x8e, 0x4e, 0x65, 0x44, 0x6f, 0x74, 0x5c, 0xa1, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0x81, 0x83, 0xf6, 0xf6, 0x0, 0x0, 0x0, 0x57, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x8d, 0x4e, 0xb5, 0x1, 0xc0, 0x30, 0xc, 0xf3, 0x15, 0xfe, 0xff, 0x96, 0x64, 0xa, 0x6c, 0xca, 0x56, 0xd2, 0x25, 0x65, 0xe6, 0xc8, 0x8b, 0x49, 0x20, 0x79, 0x28, 0x95, 0x81, 0xa1, 0xd4, 0x7d, 0x4, 0xbb, 0xa1, 0x50, 0xea, 0x3c, 0xa6, 0x71, 0x98, 0x96, 0x69, 0x58, 0x31, 0xcc, 0xb7, 0xe5, 0x2f, 0x48, 0x63, 0x26, 0xf6, 0xa2, 0xd4, 0x18, 0xf9, 0x7, 0x2d, 0xe3, 0x46, 0x89, 0xb4, 0xd2, 0xf8, 0xa3, 0x68, 0xe3, 0xd7, 0x14, 0x20, 0xe6, 0xc3, 0x3d, 0xd8, 0xca, 0x5e, 0x94, 0x32, 0xd0, 0x3, 0x91, 0xba, 0x5f, 0x1b, 0x4a, 0x9b, 0x12, 0x62, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char vseparator_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x2, 0x3, 0x0, 0x0, 0x0, 0xb9, 0x61, 0x56, 0x18, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0xc, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x73, 0x9b, 0xaa, 0xce, 0xdc, 0xe1, 0xff, 0xff, 0xff, 0x64, 0x6c, 0x1, 0xd2, 0x0, 0x0, 0x0, 0x3, 0x74, 0x52, 0x4e, 0x53, 0x0, 0xb3, 0xb3, 0x67, 0xf6, 0xdb, 0x93, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x3, 0x11, 0xc, 0x4c, 0xf2, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x10, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0x80, 0x81, 0xac, 0x95, 0xc, 0x48, 0x0, 0x0, 0xe, 0x79, 0x1, 0x14, 0xa1, 0xc9, 0x59, 0x2, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x2, 0x3, 0x0, 0x0, 0x0, 0xb9, 0x61, 0x56, 0x18, 0x0, 0x0, 0x0, 0x9, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x73, 0x9b, 0xaa, 0xce, 0xdc, 0xe1, 0xeb, 0x64, 0x9a, 0x78, 0x0, 0x0, 0x0, 0x3, 0x74, 0x52, 0x4e, 0x53, 0x0, 0xb3, 0xb3, 0x67, 0xf6, 0xdb, 0x93, 0x0, 0x0, 0x0, 0xf, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x80, 0x83, 0xac, 0x95, 0xc, 0x48, 0x0, 0x0, 0xe, 0x79, 0x1, 0x14, 0x17, 0x9a, 0x55, 0x26, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char vslider_bg_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x54, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x4d, 0x4b, 0x59, 0x34, 0x33, 0x3a, 0x2d, 0x2c, 0x32, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x3f, 0x3e, 0x49, 0x2a, 0x29, 0x2f, 0x20, 0x20, 0x24, 0x3f, 0x3e, 0x49, 0x3f, 0x3e, 0x49, 0x1f, 0x1f, 0x24, 0x40, 0x3e, 0x4a, 0x20, 0x20, 0x24, 0x34, 0x33, 0x3a, 0x20, 0x20, 0x25, 0x22, 0x22, 0x27, 0x23, 0x23, 0x28, 0x25, 0x25, 0x2a, 0x1e, 0x1e, 0x23, 0x23, 0x23, 0x27, 0x2d, 0x2c, 0x32, 0x1f, 0x1f, 0x23, 0xff, 0xff, 0xff, 0x3, 0x35, 0xf1, 0x5f, 0x0, 0x0, 0x0, 0x13, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x0, 0x0, 0x0, 0x4, 0x1a, 0x40, 0x5d, 0x19, 0x28, 0x96, 0xf0, 0xfd, 0x94, 0x95, 0xfc, 0x93, 0xfc, 0xc0, 0x0, 0xb4, 0xa, 0x5f, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x1b, 0x2, 0x60, 0xd4, 0xa4, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x64, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x9d, 0xcf, 0x39, 0x2, 0x80, 0x20, 0x10, 0x3, 0xc0, 0xe5, 0x90, 0x43, 0x50, 0x94, 0x1b, 0xfe, 0xff, 0x50, 0x5, 0x69, 0x94, 0xce, 0x94, 0x53, 0xec, 0x26, 0x0, 0x0, 0x88, 0x2e, 0x8c, 0x73, 0x26, 0x28, 0x82, 0x1e, 0x44, 0xe5, 0xaa, 0xb4, 0x56, 0x9b, 0x1c, 0x82, 0xc4, 0x6e, 0x9c, 0xf7, 0xce, 0x1c, 0x62, 0x0, 0x53, 0x2e, 0xc4, 0x18, 0x9c, 0x62, 0x3, 0xb8, 0xf6, 0xf1, 0x8e, 0x3f, 0xf9, 0x3, 0xd8, 0xa6, 0xdc, 0x20, 0x27, 0x8b, 0x3b, 0x90, 0x52, 0x43, 0x83, 0x50, 0xb, 0xf9, 0xb, 0xd3, 0xd1, 0xe9, 0xed, 0x5c, 0x6c, 0xaa, 0xfe, 0x1d, 0xf7, 0x9e, 0x7f, 0x1, 0x89, 0x5c, 0xa, 0x6b, 0x1f, 0xe5, 0xca, 0x60, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x51, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x4d, 0x4b, 0x59, 0x34, 0x33, 0x3a, 0x2d, 0x2c, 0x32, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x3f, 0x3e, 0x49, 0x2a, 0x29, 0x2f, 0x20, 0x20, 0x24, 0x3f, 0x3e, 0x49, 0x3f, 0x3e, 0x49, 0x1f, 0x1f, 0x24, 0x40, 0x3e, 0x4a, 0x20, 0x20, 0x24, 0x34, 0x33, 0x3a, 0x20, 0x20, 0x25, 0x22, 0x22, 0x27, 0x23, 0x23, 0x28, 0x25, 0x25, 0x2a, 0x1e, 0x1e, 0x23, 0x23, 0x23, 0x27, 0x2d, 0x2c, 0x32, 0x1f, 0x1f, 0x23, 0x30, 0x7, 0x9c, 0xfe, 0x0, 0x0, 0x0, 0x13, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x0, 0x0, 0x0, 0x4, 0x1a, 0x40, 0x5d, 0x19, 0x28, 0x96, 0xf0, 0xfd, 0x94, 0x95, 0xfc, 0x93, 0xfc, 0xc0, 0x0, 0xb4, 0xa, 0x5f, 0x0, 0x0, 0x0, 0x5f, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x2c, 0xc8, 0x83, 0x11, 0x0, 0x30, 0x0, 0xc0, 0xc0, 0xda, 0xf6, 0xfe, 0x8b, 0xd6, 0x39, 0xe6, 0xc1, 0xe, 0x12, 0xca, 0x38, 0x67, 0x82, 0xc0, 0x73, 0xe7, 0xa5, 0xd2, 0xc6, 0x68, 0x2b, 0xbf, 0x40, 0xe1, 0x7c, 0x2e, 0x25, 0xfb, 0x20, 0x3e, 0x30, 0x9d, 0x6b, 0x6b, 0x35, 0x6b, 0xf6, 0x81, 0x9b, 0xd2, 0x76, 0x25, 0xf2, 0x7, 0x28, 0xf5, 0x71, 0x60, 0xf4, 0x84, 0x2e, 0xe0, 0x35, 0x49, 0x29, 0x51, 0x90, 0x80, 0xa8, 0x94, 0x24, 0x33, 0x19, 0x2, 0x18, 0x86, 0xa2, 0x5b, 0x8b, 0xe9, 0x30, 0x4c, 0xa7, 0x63, 0x7a, 0xe, 0xc3, 0xfb, 0x0, 0x89, 0x5c, 0xa, 0x6b, 0x4f, 0x78, 0xac, 0x83, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char vslider_grabber_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x2, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xb7, 0xff, 0x88, 0x5, 0x1d, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe1, 0x1, 0x12, 0x1, 0x36, 0x8, 0x50, 0xb9, 0xa7, 0x53, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0xf6, 0x49, 0x44, 0x41, 0x54, 0x28, 0xcf, 0xbd, 0x90, 0xb1, 0x4a, 0x42, 0x51, 0x0, 0x86, 0xbf, 0x73, 0x8e, 0x71, 0xe5, 0x9a, 0x5c, 0x41, 0xd0, 0x66, 0x6b, 0x33, 0x1c, 0x7c, 0x80, 0xa0, 0xa5, 0x17, 0x8, 0xa2, 0x2d, 0x84, 0xf0, 0x1, 0xa2, 0x25, 0xf1, 0x9, 0x9a, 0x1c, 0xda, 0x5b, 0xb2, 0x47, 0xa8, 0xa5, 0xc1, 0xa0, 0x51, 0x88, 0xa2, 0x29, 0xa, 0xc1, 0x84, 0x8, 0x43, 0xf4, 0x96, 0x17, 0xcf, 0xed, 0xde, 0x73, 0x9c, 0xcc, 0x5c, 0xda, 0xea, 0x9f, 0x3f, 0xfe, 0x9f, 0xef, 0x87, 0x3f, 0x8f, 0x0, 0x40, 0xe1, 0xe2, 0x91, 0x42, 0x10, 0x32, 0xe6, 0x3, 0x8d, 0xc1, 0xce, 0x1, 0x45, 0xb6, 0xba, 0xbb, 0xba, 0xed, 0x95, 0x8c, 0xd0, 0x7d, 0xff, 0xe1, 0xee, 0xe2, 0xb6, 0xdd, 0x79, 0x61, 0xc4, 0xd7, 0xc, 0x48, 0x57, 0x2b, 0xeb, 0xb5, 0x28, 0xaf, 0x1, 0xc5, 0x12, 0x4e, 0xac, 0x7b, 0x6f, 0x57, 0x27, 0x8d, 0xcf, 0xe, 0x1, 0x56, 0x1, 0xb9, 0x9d, 0xba, 0x28, 0x6, 0x18, 0xc, 0x31, 0x21, 0x5a, 0xda, 0x4c, 0xb6, 0xbc, 0xb9, 0x35, 0x7c, 0xea, 0xbd, 0x13, 0x4a, 0x20, 0xe5, 0x95, 0xf4, 0x6c, 0x12, 0x30, 0x84, 0xf8, 0x44, 0x6b, 0xfb, 0xcd, 0x83, 0x3d, 0x1c, 0xf9, 0x8b, 0x80, 0x4a, 0xba, 0x88, 0x4, 0x30, 0x1e, 0xdd, 0x3b, 0x1b, 0xf1, 0x77, 0x87, 0x24, 0x81, 0x8b, 0x79, 0x3e, 0x3b, 0x6a, 0x5d, 0x33, 0x51, 0x80, 0x2d, 0x38, 0x2b, 0x65, 0xb5, 0x6c, 0x91, 0x28, 0x92, 0xa4, 0xad, 0xec, 0x76, 0xcf, 0x8f, 0xf, 0x1f, 0xdb, 0xc, 0x31, 0xb, 0x9a, 0xb1, 0xd0, 0x3, 0xfb, 0xda, 0x3a, 0xbd, 0xbc, 0x89, 0xfa, 0xf8, 0x73, 0xcd, 0x9f, 0x47, 0x45, 0x4, 0xf8, 0x4, 0x18, 0xfe, 0x2f, 0x53, 0x8, 0x62, 0x5c, 0xcf, 0x1f, 0x5f, 0xcb, 0x2c, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0xbc, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0xa0, 0x17, 0x60, 0x66, 0xe0, 0x65, 0x90, 0x61, 0x50, 0x67, 0xd0, 0x60, 0x50, 0x62, 0x10, 0x67, 0xe0, 0x2, 0xf2, 0x19, 0x51, 0xa5, 0xc5, 0xd2, 0xf2, 0x3a, 0xf, 0xce, 0x78, 0x3f, 0xed, 0x43, 0xff, 0xed, 0xc6, 0xf5, 0x41, 0xa9, 0x8a, 0x86, 0xc, 0x22, 0xc, 0xac, 0x8, 0x5, 0xbc, 0x69, 0x79, 0x93, 0x5e, 0xf4, 0xfd, 0x6f, 0x7, 0xc2, 0xae, 0xff, 0xfd, 0xff, 0xa7, 0xfd, 0xe9, 0x7f, 0x50, 0x31, 0x87, 0x47, 0x87, 0x81, 0x1b, 0x66, 0x8e, 0x4c, 0xe7, 0xc1, 0xbe, 0xff, 0x2d, 0xff, 0x9b, 0xa1, 0xb0, 0xf5, 0x7f, 0xe7, 0xff, 0xc9, 0xff, 0x27, 0xdc, 0xb6, 0xf0, 0x7, 0x9a, 0xc3, 0x2, 0x52, 0xa0, 0x3e, 0xe3, 0x7d, 0x3b, 0x54, 0x12, 0xa1, 0xa8, 0xe7, 0xff, 0x9c, 0x2f, 0x45, 0xc5, 0xc, 0xdc, 0xf8, 0x14, 0x7c, 0xaf, 0xaa, 0x65, 0xe0, 0xc1, 0x69, 0xc5, 0xc4, 0x3b, 0xe, 0xa1, 0xc, 0x62, 0xc, 0x2c, 0x68, 0x8e, 0xec, 0xf8, 0xdf, 0xfb, 0x7f, 0xda, 0xbf, 0x89, 0xf, 0x4a, 0xa6, 0xf2, 0xe8, 0x0, 0x75, 0x33, 0xa2, 0x79, 0x73, 0xea, 0x87, 0xbe, 0x7b, 0xbd, 0x47, 0x7d, 0x53, 0x58, 0x34, 0x18, 0x84, 0x19, 0x58, 0xb1, 0x7, 0x94, 0xa, 0x83, 0x14, 0x50, 0x27, 0x13, 0x3, 0x3d, 0x1, 0x0, 0x79, 0xc3, 0x79, 0x54, 0x19, 0x56, 0x3b, 0x28, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char vslider_grabber_disabled_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x2, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x87, 0x8f, 0xcc, 0xbf, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe1, 0x7, 0xa, 0x13, 0x2e, 0x39, 0x86, 0x33, 0xc2, 0xfe, 0x0, 0x0, 0x0, 0x1d, 0x69, 0x54, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x0, 0x0, 0x0, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x64, 0x2e, 0x65, 0x7, 0x0, 0x0, 0x0, 0xb7, 0x49, 0x44, 0x41, 0x54, 0x28, 0xcf, 0x63, 0x60, 0xa0, 0x13, 0x60, 0x66, 0xe0, 0x65, 0x90, 0x61, 0x50, 0x67, 0xd0, 0x60, 0x50, 0x62, 0x10, 0x67, 0xe0, 0x2, 0xf2, 0x19, 0x51, 0xa5, 0xc5, 0x8c, 0xf3, 0x5c, 0xf, 0xfa, 0xbc, 0xf7, 0xfe, 0xe0, 0x71, 0xdb, 0x71, 0xbd, 0x66, 0xaa, 0xa0, 0x21, 0x83, 0x8, 0x3, 0x2b, 0x42, 0x1, 0xaf, 0x71, 0x9e, 0xe7, 0xb, 0xf7, 0xff, 0x2e, 0x40, 0xe8, 0xfa, 0xdf, 0xe3, 0xbf, 0xf7, 0x1f, 0x8f, 0x7, 0x36, 0x73, 0xd8, 0x74, 0x18, 0xb8, 0x61, 0xe6, 0xc8, 0xb8, 0x1e, 0x74, 0xff, 0xef, 0x4, 0x87, 0xce, 0x40, 0x65, 0x5e, 0xff, 0x3d, 0x6e, 0xcb, 0xf8, 0x3, 0xcd, 0x61, 0x1, 0x29, 0x50, 0xf7, 0x79, 0xef, 0x82, 0xa4, 0x0, 0xa2, 0xc8, 0xed, 0xbf, 0xdf, 0x17, 0xcb, 0x62, 0xa0, 0x29, 0x78, 0x14, 0x7c, 0xb7, 0xad, 0x65, 0xe0, 0xc1, 0x69, 0x85, 0xe7, 0x1d, 0x85, 0x50, 0x6, 0x31, 0x88, 0x15, 0x48, 0x8e, 0x74, 0xf9, 0xef, 0xfe, 0xdf, 0xfb, 0x9f, 0xe7, 0x3, 0xab, 0xa9, 0x40, 0x47, 0xf2, 0xc0, 0x1c, 0x89, 0xe4, 0x4d, 0xf7, 0x7b, 0xee, 0x47, 0xd5, 0x53, 0x98, 0x34, 0x18, 0x84, 0x91, 0xbd, 0x89, 0x1c, 0x50, 0x2a, 0xc, 0x52, 0x40, 0x9d, 0x4c, 0xc, 0xf4, 0x4, 0x0, 0xf1, 0x9, 0x63, 0x9b, 0x3e, 0x2a, 0x19, 0x52, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0xb4, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0xa0, 0x17, 0x60, 0x66, 0xe0, 0x65, 0x90, 0x61, 0x50, 0x67, 0xd0, 0x60, 0x50, 0x62, 0x10, 0x67, 0xe0, 0x2, 0xf2, 0x19, 0x51, 0xa5, 0xc5, 0x8c, 0xf3, 0x5c, 0xf, 0xfa, 0xbc, 0xf7, 0xfe, 0xe0, 0x71, 0xdb, 0x71, 0xbd, 0x66, 0xaa, 0xa0, 0x21, 0x83, 0x8, 0x3, 0x2b, 0x42, 0x1, 0xaf, 0x71, 0x9e, 0xe7, 0xb, 0xf7, 0xff, 0x2e, 0x40, 0xe8, 0xfa, 0xdf, 0xe3, 0xbf, 0xf7, 0x1f, 0x8f, 0x7, 0x36, 0x73, 0xd8, 0x74, 0x18, 0xb8, 0x61, 0xe6, 0xc8, 0xb8, 0x1e, 0x74, 0xff, 0xef, 0x4, 0x87, 0xce, 0x40, 0x65, 0x5e, 0xff, 0x3d, 0x6e, 0xcb, 0xf8, 0x3, 0xcd, 0x61, 0x1, 0x29, 0x50, 0xf7, 0x79, 0xef, 0x2, 0x95, 0x44, 0x28, 0x72, 0xfb, 0xef, 0xf7, 0xc5, 0xb2, 0x98, 0x81, 0x1b, 0x9f, 0x82, 0xef, 0xb6, 0xb5, 0xc, 0x3c, 0x38, 0xad, 0xf0, 0xbc, 0xa3, 0x10, 0xca, 0x20, 0xc6, 0xc0, 0x82, 0xec, 0x48, 0x30, 0x74, 0xff, 0xef, 0xfd, 0xcf, 0xf3, 0x81, 0xd5, 0x54, 0x36, 0x1d, 0xa0, 0x6e, 0x46, 0xc, 0x6f, 0xba, 0xdf, 0x73, 0x3f, 0xaa, 0x9e, 0xc2, 0xa4, 0xc1, 0x20, 0xcc, 0xc0, 0x8a, 0x3d, 0xa0, 0x54, 0x18, 0xa4, 0x80, 0x3a, 0x99, 0x18, 0xe8, 0x9, 0x0, 0xf1, 0x9, 0x63, 0x9b, 0x53, 0x7f, 0x6d, 0x9b, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char vslider_grabber_hl_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0xc3, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x17, 0x2a, 0x29, 0x3a, 0x69, 0x69, 0x5b, 0xa6, 0xa5, 0x61, 0xb3, 0xbc, 0x63, 0xb7, 0xc8, 0x65, 0xbb, 0xca, 0x60, 0xaf, 0xb1, 0x48, 0x83, 0x83, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0xf, 0xf, 0x55, 0x9b, 0x9a, 0x60, 0xb2, 0xbd, 0x5e, 0xb1, 0xcd, 0x61, 0xb3, 0xc2, 0x0, 0x0, 0x0, 0x27, 0x48, 0x47, 0x62, 0xb4, 0xbd, 0x51, 0x93, 0x92, 0x68, 0xc0, 0xcf, 0x0, 0x0, 0x0, 0x56, 0x9d, 0x9c, 0x68, 0xc1, 0xcf, 0x2d, 0x52, 0x52, 0x63, 0xb7, 0xbf, 0x52, 0x96, 0x95, 0x62, 0xb3, 0xbf, 0x5e, 0xb0, 0xcd, 0x0, 0x0, 0x0, 0x3, 0x5, 0x5, 0x36, 0x63, 0x63, 0x63, 0xb4, 0xb6, 0x60, 0xb1, 0xbc, 0x63, 0xb7, 0xc7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x55, 0xa3, 0xc8, 0x4f, 0x98, 0xc4, 0x4b, 0x93, 0xc2, 0x4c, 0x94, 0xc2, 0x54, 0xa2, 0xc8, 0x5a, 0xab, 0xcb, 0x4e, 0x97, 0xc4, 0x49, 0x8f, 0xc0, 0x47, 0x8c, 0xbf, 0x48, 0x8e, 0xc0, 0x52, 0x9e, 0xc6, 0x51, 0x9d, 0xc6, 0x5a, 0xac, 0xcc, 0x53, 0x9f, 0xc7, 0x4d, 0x96, 0xc3, 0x4b, 0x92, 0xc2, 0xff, 0xff, 0xff, 0x76, 0xbd, 0x27, 0x7a, 0x0, 0x0, 0x0, 0x1, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x40, 0xe6, 0xd8, 0x66, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x0, 0x88, 0x5, 0x1d, 0x48, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe1, 0x1, 0x12, 0x1, 0x36, 0x11, 0x34, 0xd2, 0xf, 0x93, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x48, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, 0xa0, 0x12, 0x10, 0x14, 0xe0, 0xe7, 0xe3, 0x45, 0xe2, 0x4b, 0x9a, 0x18, 0x1b, 0x19, 0x1a, 0x48, 0x88, 0x8b, 0xc1, 0xe4, 0x4d, 0x2c, 0x2d, 0x80, 0xc0, 0xdc, 0xcc, 0x54, 0x6, 0x22, 0x20, 0x60, 0x6c, 0x1, 0x1, 0xe6, 0x56, 0x72, 0x68, 0x2, 0xd6, 0x8a, 0xa8, 0x5a, 0x6c, 0x94, 0x11, 0x86, 0xda, 0xdb, 0xd9, 0xaa, 0xa9, 0xaa, 0x20, 0x59, 0xab, 0xa3, 0xad, 0xc5, 0x40, 0x3d, 0x0, 0x0, 0xbf, 0x8e, 0xc, 0xed, 0xed, 0xc7, 0x67, 0x72, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x6c, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x5b, 0xa6, 0xa5, 0x61, 0xb3, 0xbc, 0x63, 0xb7, 0xc8, 0x65, 0xbb, 0xca, 0x60, 0xaf, 0xb1, 0x55, 0x9b, 0x9a, 0x60, 0xb2, 0xbd, 0x5e, 0xb1, 0xcd, 0x61, 0xb3, 0xc2, 0x62, 0xb4, 0xbd, 0x68, 0xc0, 0xcf, 0x68, 0xc1, 0xcf, 0x63, 0xb7, 0xbf, 0x52, 0x96, 0x95, 0x62, 0xb3, 0xbf, 0x5e, 0xb0, 0xcd, 0x63, 0xb4, 0xb6, 0x60, 0xb1, 0xbc, 0x63, 0xb7, 0xc7, 0x55, 0xa3, 0xc8, 0x4f, 0x98, 0xc4, 0x4b, 0x93, 0xc2, 0x4c, 0x94, 0xc2, 0x54, 0xa2, 0xc8, 0x5a, 0xab, 0xcb, 0x4e, 0x97, 0xc4, 0x49, 0x8f, 0xc0, 0x47, 0x8c, 0xbf, 0x48, 0x8e, 0xc0, 0x52, 0x9e, 0xc6, 0x51, 0x9d, 0xc6, 0x5a, 0xac, 0xcc, 0x53, 0x9f, 0xc7, 0x4d, 0x96, 0xc3, 0x4b, 0x92, 0xc2, 0x7f, 0xcb, 0x5d, 0x16, 0x0, 0x0, 0x0, 0x1, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x40, 0xe6, 0xd8, 0x66, 0x0, 0x0, 0x0, 0x47, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0xa0, 0x16, 0x60, 0x65, 0x61, 0x66, 0x62, 0x44, 0xe2, 0x73, 0x4a, 0x88, 0x8b, 0x89, 0x8a, 0x70, 0xb0, 0xb3, 0xc1, 0xe4, 0x25, 0x64, 0x65, 0x80, 0x40, 0x5a, 0x4a, 0x92, 0xb, 0x22, 0xc0, 0x22, 0x2e, 0x3, 0x1, 0xd2, 0x72, 0xdc, 0x68, 0x2, 0xf2, 0x3c, 0xa8, 0x5a, 0x14, 0x78, 0x11, 0x86, 0x2a, 0x2b, 0x29, 0xa, 0xf0, 0xf3, 0x21, 0x59, 0x2b, 0x2c, 0x24, 0xc8, 0x40, 0x3d, 0x0, 0x0, 0x19, 0x8b, 0x5, 0xfc, 0x96, 0x5c, 0x15, 0x3b, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char vslider_tick_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x4, 0x4, 0x3, 0x0, 0x0, 0x0, 0x75, 0x9a, 0xa2, 0xdf, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x1e, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x81, 0xa2, 0xad, 0x8c, 0xac, 0xb8, 0x38, 0x55, 0x5f, 0x82, 0x82, 0x82, 0x8d, 0x8d, 0x8d, 0x98, 0x98, 0x98, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0xff, 0xff, 0xff, 0xe1, 0x56, 0x59, 0xc8, 0x0, 0x0, 0x0, 0x9, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x0, 0x0, 0x0, 0x79, 0x79, 0x79, 0x31, 0x1c, 0x18, 0xed, 0xfe, 0x2b, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x9, 0xf1, 0xd9, 0xa5, 0xec, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x1d, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0x80, 0x1, 0xd7, 0x44, 0x5, 0x6, 0x6, 0xe6, 0x92, 0x30, 0x86, 0xf2, 0x62, 0x3, 0x20, 0xa3, 0xbd, 0x1c, 0x2e, 0x3, 0x0, 0x3f, 0xce, 0x3, 0xaf, 0xf9, 0x94, 0x50, 0x96, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x4, 0x4, 0x3, 0x0, 0x0, 0x0, 0x75, 0x9a, 0xa2, 0xdf, 0x0, 0x0, 0x0, 0x1b, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x81, 0xa2, 0xad, 0x8c, 0xac, 0xb8, 0x38, 0x55, 0x5f, 0x82, 0x82, 0x82, 0x8d, 0x8d, 0x8d, 0x98, 0x98, 0x98, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x7c, 0xda, 0x48, 0x6d, 0x0, 0x0, 0x0, 0x9, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x0, 0x0, 0x0, 0x79, 0x79, 0x79, 0x31, 0x1c, 0x18, 0xed, 0xfe, 0x2b, 0x0, 0x0, 0x0, 0x1c, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x80, 0x3, 0xd7, 0x44, 0x5, 0x6, 0x6, 0xe6, 0x92, 0x30, 0x86, 0xf2, 0x62, 0x3, 0x20, 0xa3, 0xbd, 0x1c, 0x2e, 0x3, 0x0, 0x3f, 0xce, 0x3, 0xaf, 0xed, 0xed, 0x7c, 0x2f, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char vsplit_bg_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x1, 0x3, 0x0, 0x0, 0x0, 0xfe, 0xc1, 0x2c, 0xc8, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x6, 0x50, 0x4c, 0x54, 0x45, 0x27, 0x27, 0x29, 0xff, 0xff, 0xff, 0x11, 0xab, 0xb9, 0xf3, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x1, 0xff, 0x2, 0x2d, 0xde, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0xb, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0x40, 0x5, 0x0, 0x0, 0x10, 0x0, 0x1, 0xa1, 0xc5, 0x21, 0xc1, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x1, 0x3, 0x0, 0x0, 0x0, 0xfe, 0xc1, 0x2c, 0xc8, 0x0, 0x0, 0x0, 0x6, 0x50, 0x4c, 0x54, 0x45, 0x27, 0x27, 0x29, 0xff, 0xff, 0xff, 0x11, 0xab, 0xb9, 0xf3, 0x0, 0x0, 0x0, 0xa, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x40, 0x3, 0x0, 0x0, 0x10, 0x0, 0x1, 0xb3, 0xac, 0xe2, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char vsplitter_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x8, 0x8, 0x0, 0x0, 0x0, 0x0, 0x6c, 0x9, 0xa6, 0x3, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x2, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x0, 0x76, 0x93, 0xcd, 0x38, 0x0, 0x0, 0x0, 0x2, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x87, 0x8f, 0xcc, 0xbf, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x1f, 0x49, 0x44, 0x41, 0x54, 0x28, 0xcf, 0x63, 0x60, 0xa0, 0x10, 0x30, 0x33, 0x2c, 0x10, 0x3d, 0x47, 0x9, 0x66, 0x66, 0x10, 0xbd, 0xf6, 0x98, 0x22, 0x3c, 0xe0, 0x60, 0x18, 0x84, 0x1, 0x0, 0x59, 0x34, 0x6a, 0x2d, 0x64, 0xeb, 0x72, 0x24, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x8, 0x8, 0x0, 0x0, 0x0, 0x0, 0x6c, 0x9, 0xa6, 0x3, 0x0, 0x0, 0x0, 0x2, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x0, 0x76, 0x93, 0xcd, 0x38, 0x0, 0x0, 0x0, 0x18, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0xa0, 0x1c, 0x2c, 0x48, 0xa5, 0xc, 0x33, 0xa4, 0x5a, 0x53, 0x86, 0x29, 0x7, 0xa3, 0x61, 0x0, 0x0, 0x18, 0x61, 0x34, 0xa1, 0xba, 0xa4, 0x4d, 0xe, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char window_resizer_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x8, 0x19, 0x11, 0x33, 0x13, 0xaa, 0xc0, 0xf, 0x5f, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x2f, 0x49, 0x44, 0x41, 0x54, 0x38, 0xcb, 0x63, 0x60, 0x18, 0x5, 0x24, 0x81, 0x17, 0x2f, 0x5e, 0xf4, 0xa3, 0x8b, 0x31, 0x91, 0xa2, 0xb9, 0xb9, 0xb9, 0x99, 0x7c, 0x9b, 0xb3, 0xb3, 0xb3, 0xfb, 0x87, 0x81, 0x66, 0x6c, 0x81, 0x48, 0x92, 0x66, 0xa2, 0x5c, 0x43, 0x91, 0xe6, 0x11, 0xa, 0x0, 0x73, 0x5b, 0x34, 0x19, 0x10, 0xa0, 0xb6, 0x7d, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x1e, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x18, 0xbc, 0xe0, 0x45, 0x3f, 0x1, 0xe9, 0xec, 0xfe, 0x81, 0x94, 0x86, 0xb1, 0x70, 0x48, 0x23, 0x58, 0x84, 0xa4, 0x7, 0x15, 0x0, 0x0, 0xed, 0x9f, 0x18, 0xe8, 0xcd, 0x91, 0xd8, 0xe, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
// shaders block
diff --git a/scene/resources/dynamic_font.cpp b/scene/resources/dynamic_font.cpp
index e5d463d391..2f2abd4e08 100644
--- a/scene/resources/dynamic_font.cpp
+++ b/scene/resources/dynamic_font.cpp
@@ -211,9 +211,9 @@ Error DynamicFontAtSize::_load() {
scale_color_font = float(id.size) / face->available_sizes[i].width;
}
}
- error = FT_Select_Size(face, best_match);
+ FT_Select_Size(face, best_match);
} else {
- error = FT_Set_Pixel_Sizes(face, 0, id.size * oversampling);
+ FT_Set_Pixel_Sizes(face, 0, id.size * oversampling);
}
ascent = (face->size->metrics.ascender / 64.0) / oversampling * scale_color_font;
@@ -314,7 +314,7 @@ void DynamicFontAtSize::set_texture_flags(uint32_t p_flags) {
texture_flags = p_flags;
for (int i = 0; i < textures.size(); i++) {
- Ref<ImageTexture> &tex = textures[i].texture;
+ Ref<ImageTexture> &tex = textures.write[i].texture;
if (!tex.is_null())
tex->set_flags(p_flags);
}
@@ -400,7 +400,7 @@ DynamicFontAtSize::TexturePosition DynamicFontAtSize::_find_texture_pos_for_glyp
for (int i = 0; i < textures.size(); i++) {
- CharTexture &ct = textures[i];
+ const CharTexture &ct = textures[i];
if (ct.texture->get_format() != p_image_format)
continue;
@@ -466,7 +466,7 @@ DynamicFontAtSize::TexturePosition DynamicFontAtSize::_find_texture_pos_for_glyp
}
tex.offsets.resize(texsize);
for (int i = 0; i < texsize; i++) //zero offsets
- tex.offsets[i] = 0;
+ tex.offsets.write[i] = 0;
textures.push_back(tex);
ret.index = textures.size() - 1;
@@ -493,7 +493,7 @@ DynamicFontAtSize::Character DynamicFontAtSize::_bitmap_to_character(FT_Bitmap b
//fit character in char texture
- CharTexture &tex = textures[tex_pos.index];
+ CharTexture &tex = textures.write[tex_pos.index];
{
PoolVector<uint8_t>::Write wr = tex.imgdata.write();
@@ -547,7 +547,7 @@ DynamicFontAtSize::Character DynamicFontAtSize::_bitmap_to_character(FT_Bitmap b
// update height array
for (int k = tex_pos.x; k < tex_pos.x + mw; k++) {
- tex.offsets[k] = tex_pos.y + mh;
+ tex.offsets.write[k] = tex_pos.y + mh;
}
Character chr;
@@ -698,9 +698,9 @@ void DynamicFont::_reload_cache() {
}
for (int i = 0; i < fallbacks.size(); i++) {
- fallback_data_at_size[i] = fallbacks[i]->_get_dynamic_font_at_size(cache_id);
+ fallback_data_at_size.write[i] = fallbacks.write[i]->_get_dynamic_font_at_size(cache_id);
if (outline_cache_id.outline_size > 0)
- fallback_outline_data_at_size[i] = fallbacks[i]->_get_dynamic_font_at_size(outline_cache_id);
+ fallback_outline_data_at_size.write[i] = fallbacks.write[i]->_get_dynamic_font_at_size(outline_cache_id);
}
emit_changed();
@@ -895,17 +895,17 @@ void DynamicFont::set_fallback(int p_idx, const Ref<DynamicFontData> &p_data) {
ERR_FAIL_COND(p_data.is_null());
ERR_FAIL_INDEX(p_idx, fallbacks.size());
- fallbacks[p_idx] = p_data;
- fallback_data_at_size[p_idx] = fallbacks[p_idx]->_get_dynamic_font_at_size(cache_id);
+ fallbacks.write[p_idx] = p_data;
+ fallback_data_at_size.write[p_idx] = fallbacks.write[p_idx]->_get_dynamic_font_at_size(cache_id);
}
void DynamicFont::add_fallback(const Ref<DynamicFontData> &p_data) {
ERR_FAIL_COND(p_data.is_null());
fallbacks.push_back(p_data);
- fallback_data_at_size.push_back(fallbacks[fallbacks.size() - 1]->_get_dynamic_font_at_size(cache_id)); //const..
+ fallback_data_at_size.push_back(fallbacks.write[fallbacks.size() - 1]->_get_dynamic_font_at_size(cache_id)); //const..
if (outline_cache_id.outline_size > 0)
- fallback_outline_data_at_size.push_back(fallbacks[fallbacks.size() - 1]->_get_dynamic_font_at_size(outline_cache_id));
+ fallback_outline_data_at_size.push_back(fallbacks.write[fallbacks.size() - 1]->_get_dynamic_font_at_size(outline_cache_id));
_change_notify();
emit_changed();
@@ -1092,7 +1092,7 @@ void DynamicFont::update_oversampling() {
dynamic_font_mutex->unlock();
for (int i = 0; i < changed.size(); i++) {
- changed[i]->emit_changed();
+ changed.write[i]->emit_changed();
}
}
diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp
index 0bae9d9b2d..3dfde01320 100644
--- a/scene/resources/font.cpp
+++ b/scene/resources/font.cpp
@@ -386,7 +386,7 @@ Vector<CharType> BitmapFont::get_char_keys() const {
int count = 0;
while ((ct = char_map.next(ct))) {
- chars[count++] = *ct;
+ chars.write[count++] = *ct;
};
return chars;
@@ -438,7 +438,7 @@ Vector<BitmapFont::KerningPairKey> BitmapFont::get_kerning_pair_keys() const {
int i = 0;
for (Map<KerningPairKey, int>::Element *E = kerning_map.front(); E; E = E->next()) {
- ret[i++] = E->key();
+ ret.write[i++] = E->key();
}
return ret;
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index 654d7b884e..b6d1916b2c 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -34,6 +34,8 @@
void Material::set_next_pass(const Ref<Material> &p_pass) {
+ ERR_FAIL_COND(p_pass == this);
+
if (next_pass == p_pass)
return;
@@ -145,11 +147,17 @@ void ShaderMaterial::_get_property_list(List<PropertyInfo> *p_list) const {
void ShaderMaterial::set_shader(const Ref<Shader> &p_shader) {
+ if (shader.is_valid()) {
+ shader->disconnect("changed", this, "_shader_changed");
+ }
+
shader = p_shader;
RID rid;
- if (shader.is_valid())
+ if (shader.is_valid()) {
rid = shader->get_rid();
+ shader->connect("changed", this, "_shader_changed");
+ }
VS::get_singleton()->material_set_shader(_get_material(), rid);
_change_notify(); //properties for shader exposed
@@ -171,12 +179,17 @@ Variant ShaderMaterial::get_shader_param(const StringName &p_param) const {
return VS::get_singleton()->material_get_param(_get_material(), p_param);
}
+void ShaderMaterial::_shader_changed() {
+ _change_notify(); //update all properties
+}
+
void ShaderMaterial::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_shader", "shader"), &ShaderMaterial::set_shader);
ClassDB::bind_method(D_METHOD("get_shader"), &ShaderMaterial::get_shader);
ClassDB::bind_method(D_METHOD("set_shader_param", "param", "value"), &ShaderMaterial::set_shader_param);
ClassDB::bind_method(D_METHOD("get_shader_param", "param"), &ShaderMaterial::get_shader_param);
+ ClassDB::bind_method(D_METHOD("_shader_changed"), &ShaderMaterial::_shader_changed);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shader", PROPERTY_HINT_RESOURCE_TYPE, "Shader"), "set_shader", "get_shader");
}
@@ -387,12 +400,17 @@ void SpatialMaterial::_update_shader() {
if (flags[FLAG_USE_VERTEX_LIGHTING]) {
code += ",vertex_lighting";
}
+ bool using_world = false;
if (flags[FLAG_TRIPLANAR_USE_WORLD] && (flags[FLAG_UV1_USE_TRIPLANAR] || flags[FLAG_UV2_USE_TRIPLANAR])) {
code += ",world_vertex_coords";
+ using_world = true;
}
if (flags[FLAG_DONT_RECEIVE_SHADOWS]) {
code += ",shadows_disabled";
}
+ if (flags[FLAG_DISABLE_AMBIENT_LIGHT]) {
+ code += ",ambient_light_disabled";
+ }
if (flags[FLAG_ENSURE_CORRECT_NORMALS]) {
code += ",ensure_correct_normals";
}
@@ -409,7 +427,7 @@ void SpatialMaterial::_update_shader() {
if (proximity_fade_enabled) {
code += "uniform float proximity_fade_distance;\n";
}
- if (distance_fade_enabled) {
+ if (distance_fade != DISTANCE_FADE_DISABLED) {
code += "uniform float distance_fade_min;\n";
code += "uniform float distance_fade_max;\n";
}
@@ -540,9 +558,20 @@ void SpatialMaterial::_update_shader() {
case BILLBOARD_ENABLED: {
code += "\tMODELVIEW_MATRIX = INV_CAMERA_MATRIX * mat4(CAMERA_MATRIX[0],CAMERA_MATRIX[1],CAMERA_MATRIX[2],WORLD_MATRIX[3]);\n";
+
+ if (flags[FLAG_BILLBOARD_KEEP_SCALE]) {
+ code += "\tMODELVIEW_MATRIX = MODELVIEW_MATRIX * mat4(vec4(length(WORLD_MATRIX[0].xyz),0,0,0),vec4(0,length(WORLD_MATRIX[1].xyz),0,0),vec4(0,0,length(WORLD_MATRIX[2].xyz),0),vec4(0,0,0,1));\n";
+ }
} break;
case BILLBOARD_FIXED_Y: {
+
code += "\tMODELVIEW_MATRIX = INV_CAMERA_MATRIX * mat4(CAMERA_MATRIX[0],WORLD_MATRIX[1],vec4(normalize(cross(CAMERA_MATRIX[0].xyz,WORLD_MATRIX[1].xyz)),0.0),WORLD_MATRIX[3]);\n";
+
+ if (flags[FLAG_BILLBOARD_KEEP_SCALE]) {
+ code += "\tMODELVIEW_MATRIX = MODELVIEW_MATRIX * mat4(vec4(length(WORLD_MATRIX[0].xyz),0,0,0),vec4(0,1,0,0),vec4(0,0,length(WORLD_MATRIX[2].xyz),0),vec4(0,0,0,1));\n";
+ } else {
+ code += "\tMODELVIEW_MATRIX = MODELVIEW_MATRIX * mat4(vec4(1,0,0,0),vec4(0,1.0/length(WORLD_MATRIX[1].xyz),0,0),vec4(0,0,1,0),vec4(0,0,0,1));\n";
+ }
} break;
case BILLBOARD_PARTICLES: {
@@ -559,8 +588,6 @@ void SpatialMaterial::_update_shader() {
code += "\tif (particles_anim_loop) particle_frame=clamp(particle_frame,0,particle_total_frames-1); else particle_frame=abs(particle_frame)%particle_total_frames;\n";
code += "\tUV /= vec2(float(particles_anim_h_frames),float(particles_anim_v_frames));\n";
code += "\tUV += vec2(float(particle_frame % particles_anim_h_frames) / float(particles_anim_h_frames),float(particle_frame / particles_anim_h_frames) / float(particles_anim_v_frames));\n";
- //handle rotation
- // code += "\tmat4 rotation = mat4("
} break;
}
@@ -759,7 +786,7 @@ void SpatialMaterial::_update_shader() {
code += "\tALBEDO *= 1.0 - ref_amount;\n";
code += "\tALPHA = 1.0;\n";
- } else if (features[FEATURE_TRANSPARENT] || flags[FLAG_USE_ALPHA_SCISSOR] || distance_fade_enabled || proximity_fade_enabled) {
+ } else if (features[FEATURE_TRANSPARENT] || flags[FLAG_USE_ALPHA_SCISSOR] || (distance_fade == DISTANCE_FADE_PIXEL_ALPHA) || proximity_fade_enabled) {
code += "\tALPHA = albedo.a * albedo_tex.a;\n";
}
@@ -770,8 +797,47 @@ void SpatialMaterial::_update_shader() {
code += "\tALPHA*=clamp(1.0-smoothstep(world_pos.z+proximity_fade_distance,world_pos.z,VERTEX.z),0.0,1.0);\n";
}
- if (distance_fade_enabled) {
- code += "\tALPHA*=clamp(smoothstep(distance_fade_min,distance_fade_max,-VERTEX.z),0.0,1.0);\n";
+ if (distance_fade != DISTANCE_FADE_DISABLED) {
+ if (distance_fade == DISTANCE_FADE_OBJECT_DITHER || distance_fade == DISTANCE_FADE_PIXEL_DITHER) {
+
+ code += "\t{\n";
+ if (distance_fade == DISTANCE_FADE_OBJECT_DITHER) {
+ code += "\t\tfloat fade_distance = abs((INV_CAMERA_MATRIX * WORLD_MATRIX[3]).z);\n";
+
+ } else {
+ code += "\t\tfloat fade_distance=-VERTEX.z;\n";
+ }
+
+ code += "\t\tfloat fade=clamp(smoothstep(distance_fade_min,distance_fade_max,fade_distance),0.0,1.0);\n";
+ code += "\t\tint x = int(FRAGCOORD.x) % 4;\n";
+ code += "\t\tint y = int(FRAGCOORD.y) % 4;\n";
+ code += "\t\tint index = x + y * 4;\n";
+ code += "\t\tfloat limit = 0.0;\n\n";
+ code += "\t\tif (x < 8) {\n";
+ code += "\t\t\tif (index == 0) limit = 0.0625;\n";
+ code += "\t\t\tif (index == 1) limit = 0.5625;\n";
+ code += "\t\t\tif (index == 2) limit = 0.1875;\n";
+ code += "\t\t\tif (index == 3) limit = 0.6875;\n";
+ code += "\t\t\tif (index == 4) limit = 0.8125;\n";
+ code += "\t\t\tif (index == 5) limit = 0.3125;\n";
+ code += "\t\t\tif (index == 6) limit = 0.9375;\n";
+ code += "\t\t\tif (index == 7) limit = 0.4375;\n";
+ code += "\t\t\tif (index == 8) limit = 0.25;\n";
+ code += "\t\t\tif (index == 9) limit = 0.75;\n";
+ code += "\t\t\tif (index == 10) limit = 0.125;\n";
+ code += "\t\t\tif (index == 11) limit = 0.625;\n";
+ code += "\t\t\tif (index == 12) limit = 1.0;\n";
+ code += "\t\t\tif (index == 13) limit = 0.5;\n";
+ code += "\t\t\tif (index == 14) limit = 0.875;\n";
+ code += "\t\t\tif (index == 15) limit = 0.375;\n";
+ code += "\t\t}\n\n";
+ code += "\tif (fade < limit)\n";
+ code += "\t\tdiscard;\n";
+ code += "\t}\n\n";
+
+ } else {
+ code += "\tALPHA*=clamp(smoothstep(distance_fade_min,distance_fade_max,-VERTEX.z),0.0,1.0);\n";
+ }
}
if (features[FEATURE_RIM]) {
@@ -1301,7 +1367,7 @@ void SpatialMaterial::_validate_property(PropertyInfo &property) const {
property.usage = 0;
}
- if ((property.name == "distance_fade_max_distance" || property.name == "distance_fade_min_distance") && !distance_fade_enabled) {
+ if ((property.name == "distance_fade_max_distance" || property.name == "distance_fade_min_distance") && distance_fade == DISTANCE_FADE_DISABLED) {
property.usage = 0;
}
@@ -1622,15 +1688,15 @@ float SpatialMaterial::get_proximity_fade_distance() const {
return proximity_fade_distance;
}
-void SpatialMaterial::set_distance_fade(bool p_enable) {
+void SpatialMaterial::set_distance_fade(DistanceFadeMode p_mode) {
- distance_fade_enabled = p_enable;
+ distance_fade = p_mode;
_queue_shader_change();
_change_notify();
}
-bool SpatialMaterial::is_distance_fade_enabled() const {
+SpatialMaterial::DistanceFadeMode SpatialMaterial::get_distance_fade() const {
- return distance_fade_enabled;
+ return distance_fade;
}
void SpatialMaterial::set_distance_fade_max_distance(float p_distance) {
@@ -1836,8 +1902,8 @@ void SpatialMaterial::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_proximity_fade_distance", "distance"), &SpatialMaterial::set_proximity_fade_distance);
ClassDB::bind_method(D_METHOD("get_proximity_fade_distance"), &SpatialMaterial::get_proximity_fade_distance);
- ClassDB::bind_method(D_METHOD("set_distance_fade", "enabled"), &SpatialMaterial::set_distance_fade);
- ClassDB::bind_method(D_METHOD("is_distance_fade_enabled"), &SpatialMaterial::is_distance_fade_enabled);
+ ClassDB::bind_method(D_METHOD("set_distance_fade", "mode"), &SpatialMaterial::set_distance_fade);
+ ClassDB::bind_method(D_METHOD("get_distance_fade"), &SpatialMaterial::get_distance_fade);
ClassDB::bind_method(D_METHOD("set_distance_fade_max_distance", "distance"), &SpatialMaterial::set_distance_fade_max_distance);
ClassDB::bind_method(D_METHOD("get_distance_fade_max_distance"), &SpatialMaterial::get_distance_fade_max_distance);
@@ -1855,6 +1921,7 @@ void SpatialMaterial::_bind_methods() {
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_fixed_size"), "set_flag", "get_flag", FLAG_FIXED_SIZE);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_albedo_tex_force_srgb"), "set_flag", "get_flag", FLAG_ALBEDO_TEXTURE_FORCE_SRGB);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_do_not_receive_shadows"), "set_flag", "get_flag", FLAG_DONT_RECEIVE_SHADOWS);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_disable_ambient_light"), "set_flag", "get_flag", FLAG_DISABLE_AMBIENT_LIGHT);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_ensure_correct_normals"), "set_flag", "get_flag", FLAG_ENSURE_CORRECT_NORMALS);
ADD_GROUP("Vertex Color", "vertex_color");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "vertex_color_use_as_albedo"), "set_flag", "get_flag", FLAG_ALBEDO_FROM_VERTEX_COLOR);
@@ -1869,6 +1936,7 @@ void SpatialMaterial::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "params_line_width", PROPERTY_HINT_RANGE, "0.1,128,0.1"), "set_line_width", "get_line_width");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "params_point_size", PROPERTY_HINT_RANGE, "0.1,128,0.1"), "set_point_size", "get_point_size");
ADD_PROPERTY(PropertyInfo(Variant::INT, "params_billboard_mode", PROPERTY_HINT_ENUM, "Disabled,Enabled,Y-Billboard,Particle Billboard"), "set_billboard_mode", "get_billboard_mode");
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "params_billboard_keep_scale"), "set_flag", "get_flag", FLAG_BILLBOARD_KEEP_SCALE);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "params_grow"), "set_grow_enabled", "is_grow_enabled");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "params_grow_amount", PROPERTY_HINT_RANGE, "-16,10,0.01"), "set_grow", "get_grow");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "params_use_alpha_scissor"), "set_flag", "get_flag", FLAG_USE_ALPHA_SCISSOR);
@@ -1978,7 +2046,7 @@ void SpatialMaterial::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "proximity_fade_enable"), "set_proximity_fade", "is_proximity_fade_enabled");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "proximity_fade_distance", PROPERTY_HINT_RANGE, "0,4096,0.1"), "set_proximity_fade_distance", "get_proximity_fade_distance");
ADD_GROUP("Distance Fade", "distance_fade_");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "distance_fade_enable"), "set_distance_fade", "is_distance_fade_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "distance_fade_mode", PROPERTY_HINT_ENUM, "Disabled,PixelAlpha,PixelDither,ObjectDither"), "set_distance_fade", "get_distance_fade");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "distance_fade_min_distance", PROPERTY_HINT_RANGE, "0,4096,0.1"), "set_distance_fade_min_distance", "get_distance_fade_min_distance");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "distance_fade_max_distance", PROPERTY_HINT_RANGE, "0,4096,0.1"), "set_distance_fade_max_distance", "get_distance_fade_max_distance");
@@ -2038,6 +2106,7 @@ void SpatialMaterial::_bind_methods() {
BIND_ENUM_CONSTANT(FLAG_SRGB_VERTEX_COLOR);
BIND_ENUM_CONSTANT(FLAG_USE_POINT_SIZE);
BIND_ENUM_CONSTANT(FLAG_FIXED_SIZE);
+ BIND_ENUM_CONSTANT(FLAG_BILLBOARD_KEEP_SCALE);
BIND_ENUM_CONSTANT(FLAG_UV1_USE_TRIPLANAR);
BIND_ENUM_CONSTANT(FLAG_UV2_USE_TRIPLANAR);
BIND_ENUM_CONSTANT(FLAG_AO_ON_UV2);
@@ -2046,6 +2115,7 @@ void SpatialMaterial::_bind_methods() {
BIND_ENUM_CONSTANT(FLAG_TRIPLANAR_USE_WORLD);
BIND_ENUM_CONSTANT(FLAG_ALBEDO_TEXTURE_FORCE_SRGB);
BIND_ENUM_CONSTANT(FLAG_DONT_RECEIVE_SHADOWS);
+ BIND_ENUM_CONSTANT(FLAG_DISABLE_AMBIENT_LIGHT);
BIND_ENUM_CONSTANT(FLAG_ENSURE_CORRECT_NORMALS);
BIND_ENUM_CONSTANT(FLAG_MAX);
@@ -2074,15 +2144,20 @@ void SpatialMaterial::_bind_methods() {
BIND_ENUM_CONSTANT(EMISSION_OP_ADD);
BIND_ENUM_CONSTANT(EMISSION_OP_MULTIPLY);
+
+ BIND_ENUM_CONSTANT(DISTANCE_FADE_DISABLED);
+ BIND_ENUM_CONSTANT(DISTANCE_FADE_PIXEL_ALPHA);
+ BIND_ENUM_CONSTANT(DISTANCE_FADE_PIXEL_DITHER);
+ BIND_ENUM_CONSTANT(DISTANCE_FADE_OBJECT_DITHER);
}
SpatialMaterial::SpatialMaterial() :
element(this) {
- //initialize to right values
+ // Initialize to the same values as the shader
set_albedo(Color(1.0, 1.0, 1.0, 1.0));
set_specular(0.5);
- set_roughness(0.0);
+ set_roughness(1.0);
set_metallic(0.0);
set_emission(Color(0, 0, 0));
set_emission_energy(1.0);
@@ -2112,7 +2187,7 @@ SpatialMaterial::SpatialMaterial() :
emission_op = EMISSION_OP_ADD;
proximity_fade_enabled = false;
- distance_fade_enabled = false;
+ distance_fade = DISTANCE_FADE_DISABLED;
set_proximity_fade_distance(1);
set_distance_fade_min_distance(0);
set_distance_fade_max_distance(10);
diff --git a/scene/resources/material.h b/scene/resources/material.h
index 87594213bc..f43d240a53 100644
--- a/scene/resources/material.h
+++ b/scene/resources/material.h
@@ -92,6 +92,8 @@ protected:
virtual bool _can_do_next_pass() const;
+ void _shader_changed();
+
public:
void set_shader(const Ref<Shader> &p_shader);
Ref<Shader> get_shader() const;
@@ -181,6 +183,7 @@ public:
FLAG_SRGB_VERTEX_COLOR,
FLAG_USE_POINT_SIZE,
FLAG_FIXED_SIZE,
+ FLAG_BILLBOARD_KEEP_SCALE,
FLAG_UV1_USE_TRIPLANAR,
FLAG_UV2_USE_TRIPLANAR,
FLAG_TRIPLANAR_USE_WORLD,
@@ -190,6 +193,7 @@ public:
FLAG_ALBEDO_TEXTURE_FORCE_SRGB,
FLAG_DONT_RECEIVE_SHADOWS,
FLAG_ENSURE_CORRECT_NORMALS,
+ FLAG_DISABLE_AMBIENT_LIGHT,
FLAG_MAX
};
@@ -229,6 +233,13 @@ public:
EMISSION_OP_MULTIPLY
};
+ enum DistanceFadeMode {
+ DISTANCE_FADE_DISABLED,
+ DISTANCE_FADE_PIXEL_ALPHA,
+ DISTANCE_FADE_PIXEL_DITHER,
+ DISTANCE_FADE_OBJECT_DITHER,
+ };
+
private:
union MaterialKey {
@@ -238,7 +249,7 @@ private:
uint64_t blend_mode : 2;
uint64_t depth_draw_mode : 2;
uint64_t cull_mode : 2;
- uint64_t flags : 16;
+ uint64_t flags : 18;
uint64_t detail_blend_mode : 2;
uint64_t diffuse_mode : 3;
uint64_t specular_mode : 2;
@@ -247,7 +258,7 @@ private:
uint64_t billboard_mode : 2;
uint64_t grow : 1;
uint64_t proximity_fade : 1;
- uint64_t distance_fade : 1;
+ uint64_t distance_fade : 2;
uint64_t emission_op : 1;
};
@@ -292,7 +303,7 @@ private:
mk.deep_parallax = deep_parallax ? 1 : 0;
mk.grow = grow_enabled;
mk.proximity_fade = proximity_fade_enabled;
- mk.distance_fade = distance_fade_enabled;
+ mk.distance_fade = distance_fade;
mk.emission_op = emission_op;
return mk;
@@ -398,7 +409,7 @@ private:
bool proximity_fade_enabled;
float proximity_fade_distance;
- bool distance_fade_enabled;
+ DistanceFadeMode distance_fade;
float distance_fade_max_distance;
float distance_fade_min_distance;
@@ -579,8 +590,8 @@ public:
void set_proximity_fade_distance(float p_distance);
float get_proximity_fade_distance() const;
- void set_distance_fade(bool p_enable);
- bool is_distance_fade_enabled() const;
+ void set_distance_fade(DistanceFadeMode p_mode);
+ DistanceFadeMode get_distance_fade() const;
void set_distance_fade_max_distance(float p_distance);
float get_distance_fade_max_distance() const;
@@ -626,6 +637,7 @@ VARIANT_ENUM_CAST(SpatialMaterial::SpecularMode)
VARIANT_ENUM_CAST(SpatialMaterial::BillboardMode)
VARIANT_ENUM_CAST(SpatialMaterial::TextureChannel)
VARIANT_ENUM_CAST(SpatialMaterial::EmissionOperator)
+VARIANT_ENUM_CAST(SpatialMaterial::DistanceFadeMode)
//////////////////////
diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp
index b0620d3363..dcd87a2a61 100644
--- a/scene/resources/mesh.cpp
+++ b/scene/resources/mesh.cpp
@@ -40,7 +40,6 @@
void Mesh::_clear_triangle_mesh() const {
triangle_mesh.unref();
- ;
}
Ref<TriangleMesh> Mesh::generate_triangle_mesh() const {
@@ -110,6 +109,54 @@ Ref<TriangleMesh> Mesh::generate_triangle_mesh() const {
return triangle_mesh;
}
+void Mesh::generate_debug_mesh_lines(Vector<Vector3> &r_lines) {
+
+ Ref<TriangleMesh> tm = generate_triangle_mesh();
+ if (tm.is_null())
+ return;
+
+ PoolVector<int> triangle_indices;
+ tm->get_indices(&triangle_indices);
+ const int triangles_num = tm->get_triangles().size();
+ PoolVector<Vector3> vertices = tm->get_vertices();
+
+ r_lines.resize(tm->get_triangles().size() * 6); // 3 lines x 2 points each line
+
+ PoolVector<int>::Read ind_r = triangle_indices.read();
+ PoolVector<Vector3>::Read ver_r = vertices.read();
+ for (int j = 0, x = 0, i = 0; i < triangles_num; j += 6, x += 3, ++i) {
+ // Triangle line 1
+ r_lines.write[j + 0] = ver_r[ind_r[x + 0]];
+ r_lines.write[j + 1] = ver_r[ind_r[x + 1]];
+
+ // Triangle line 2
+ r_lines.write[j + 2] = ver_r[ind_r[x + 1]];
+ r_lines.write[j + 3] = ver_r[ind_r[x + 2]];
+
+ // Triangle line 3
+ r_lines.write[j + 4] = ver_r[ind_r[x + 2]];
+ r_lines.write[j + 5] = ver_r[ind_r[x + 0]];
+ }
+}
+void Mesh::generate_debug_mesh_indices(Vector<Vector3> &r_points) {
+ Ref<TriangleMesh> tm = generate_triangle_mesh();
+ if (tm.is_null())
+ return;
+
+ PoolVector<Vector3> vertices = tm->get_vertices();
+
+ int vertices_size = vertices.size();
+ r_points.resize(vertices_size);
+ for (int i = 0; i < vertices_size; ++i) {
+ r_points.write[i] = vertices[i];
+ }
+}
+
+bool Mesh::surface_is_softbody_friendly(int p_idx) const {
+ const uint32_t surface_format = surface_get_format(p_idx);
+ return (surface_format & Mesh::ARRAY_FLAG_USE_DYNAMIC_UPDATE && (!(surface_format & Mesh::ARRAY_COMPRESS_VERTEX)) && (!(surface_format & Mesh::ARRAY_COMPRESS_NORMAL)));
+}
+
PoolVector<Face3> Mesh::get_faces() const {
Ref<TriangleMesh> tm = generate_triangle_mesh();
@@ -484,6 +531,10 @@ void Mesh::_bind_methods() {
BIND_ENUM_CONSTANT(ARRAY_MAX);
}
+void Mesh::clear_cache() {
+ _clear_triangle_mesh();
+}
+
Mesh::Mesh() {
}
@@ -616,7 +667,7 @@ bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) {
bone_aabb.resize(baabb.size());
for (int i = 0; i < baabb.size(); i++) {
- bone_aabb[i] = baabb[i];
+ bone_aabb.write[i] = baabb[i];
}
}
@@ -788,8 +839,8 @@ void ArrayMesh::add_surface_from_arrays(PrimitiveType p_primitive, const Array &
aabb.expand_to(vtx[i]);
}
- surfaces[surfaces.size() - 1].aabb = aabb;
- surfaces[surfaces.size() - 1].is_2d = arr.get_type() == Variant::POOL_VECTOR2_ARRAY;
+ surfaces.write[surfaces.size() - 1].aabb = aabb;
+ surfaces.write[surfaces.size() - 1].is_2d = arr.get_type() == Variant::POOL_VECTOR2_ARRAY;
_recompute_aabb();
}
@@ -908,18 +959,28 @@ void ArrayMesh::surface_set_material(int p_idx, const Ref<Material> &p_material)
ERR_FAIL_INDEX(p_idx, surfaces.size());
if (surfaces[p_idx].material == p_material)
return;
- surfaces[p_idx].material = p_material;
+ surfaces.write[p_idx].material = p_material;
VisualServer::get_singleton()->mesh_surface_set_material(mesh, p_idx, p_material.is_null() ? RID() : p_material->get_rid());
_change_notify("material");
emit_changed();
}
+int ArrayMesh::surface_find_by_name(const String &p_name) const {
+ for (int i = 0; i < surfaces.size(); i++) {
+ if (surfaces[i].name == p_name) {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
void ArrayMesh::surface_set_name(int p_idx, const String &p_name) {
ERR_FAIL_INDEX(p_idx, surfaces.size());
- surfaces[p_idx].name = p_name;
+ surfaces.write[p_idx].name = p_name;
emit_changed();
}
@@ -939,7 +1000,7 @@ void ArrayMesh::surface_update_region(int p_surface, int p_offset, const PoolVec
void ArrayMesh::surface_set_custom_aabb(int p_idx, const AABB &p_aabb) {
ERR_FAIL_INDEX(p_idx, surfaces.size());
- surfaces[p_idx].aabb = p_aabb;
+ surfaces.write[p_idx].aabb = p_aabb;
// set custom aabb too?
emit_changed();
}
@@ -1042,8 +1103,8 @@ void ArrayMesh::regen_normalmaps() {
for (int i = 0; i < surfs.size(); i++) {
- surfs[i]->generate_tangents();
- surfs[i]->commit(Ref<ArrayMesh>(this));
+ surfs.write[i]->generate_tangents();
+ surfs.write[i]->commit(Ref<ArrayMesh>(this));
}
}
@@ -1108,13 +1169,13 @@ Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texe
Vector3 v = p_base_transform.xform(r[j]);
Vector3 n = p_base_transform.basis.xform(rn[j]).normalized();
- vertices[(j + vertex_ofs) * 3 + 0] = v.x;
- vertices[(j + vertex_ofs) * 3 + 1] = v.y;
- vertices[(j + vertex_ofs) * 3 + 2] = v.z;
- normals[(j + vertex_ofs) * 3 + 0] = n.x;
- normals[(j + vertex_ofs) * 3 + 1] = n.y;
- normals[(j + vertex_ofs) * 3 + 2] = n.z;
- uv_index[j + vertex_ofs] = Pair<int, int>(i, j);
+ vertices.write[(j + vertex_ofs) * 3 + 0] = v.x;
+ vertices.write[(j + vertex_ofs) * 3 + 1] = v.y;
+ vertices.write[(j + vertex_ofs) * 3 + 2] = v.z;
+ normals.write[(j + vertex_ofs) * 3 + 0] = n.x;
+ normals.write[(j + vertex_ofs) * 3 + 1] = n.y;
+ normals.write[(j + vertex_ofs) * 3 + 2] = n.z;
+ uv_index.write[j + vertex_ofs] = Pair<int, int>(i, j);
}
PoolVector<int> rindices = arrays[Mesh::ARRAY_INDEX];
@@ -1197,31 +1258,31 @@ Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texe
SurfaceTool::Vertex v = surfaces[surface].vertices[uv_index[gen_vertices[gen_indices[i + j]]].second];
if (surfaces[surface].format & ARRAY_FORMAT_COLOR) {
- surfaces_tools[surface]->add_color(v.color);
+ surfaces_tools.write[surface]->add_color(v.color);
}
if (surfaces[surface].format & ARRAY_FORMAT_TEX_UV) {
- surfaces_tools[surface]->add_uv(v.uv);
+ surfaces_tools.write[surface]->add_uv(v.uv);
}
if (surfaces[surface].format & ARRAY_FORMAT_NORMAL) {
- surfaces_tools[surface]->add_normal(v.normal);
+ surfaces_tools.write[surface]->add_normal(v.normal);
}
if (surfaces[surface].format & ARRAY_FORMAT_TANGENT) {
Plane t;
t.normal = v.tangent;
t.d = v.binormal.dot(v.normal.cross(v.tangent)) < 0 ? -1 : 1;
- surfaces_tools[surface]->add_tangent(t);
+ surfaces_tools.write[surface]->add_tangent(t);
}
if (surfaces[surface].format & ARRAY_FORMAT_BONES) {
- surfaces_tools[surface]->add_bones(v.bones);
+ surfaces_tools.write[surface]->add_bones(v.bones);
}
if (surfaces[surface].format & ARRAY_FORMAT_WEIGHTS) {
- surfaces_tools[surface]->add_weights(v.weights);
+ surfaces_tools.write[surface]->add_weights(v.weights);
}
Vector2 uv2(gen_uvs[gen_indices[i + j] * 2 + 0], gen_uvs[gen_indices[i + j] * 2 + 1]);
- surfaces_tools[surface]->add_uv2(uv2);
+ surfaces_tools.write[surface]->add_uv2(uv2);
- surfaces_tools[surface]->add_vertex(v.vertex);
+ surfaces_tools.write[surface]->add_vertex(v.vertex);
}
}
@@ -1233,8 +1294,8 @@ Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texe
//generate surfaces
for (int i = 0; i < surfaces_tools.size(); i++) {
- surfaces_tools[i]->index();
- surfaces_tools[i]->commit(Ref<ArrayMesh>((ArrayMesh *)this), surfaces[i].format);
+ surfaces_tools.write[i]->index();
+ surfaces_tools.write[i]->commit(Ref<ArrayMesh>((ArrayMesh *)this), surfaces[i].format);
}
set_lightmap_size_hint(Size2(size_x, size_y));
@@ -1261,6 +1322,7 @@ void ArrayMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("surface_get_primitive_type", "surf_idx"), &ArrayMesh::surface_get_primitive_type);
ClassDB::bind_method(D_METHOD("surface_set_material", "surf_idx", "material"), &ArrayMesh::surface_set_material);
ClassDB::bind_method(D_METHOD("surface_get_material", "surf_idx"), &ArrayMesh::surface_get_material);
+ ClassDB::bind_method(D_METHOD("surface_find_by_name", "name"), &ArrayMesh::surface_find_by_name);
ClassDB::bind_method(D_METHOD("surface_set_name", "surf_idx", "name"), &ArrayMesh::surface_set_name);
ClassDB::bind_method(D_METHOD("surface_get_name", "surf_idx"), &ArrayMesh::surface_get_name);
ClassDB::bind_method(D_METHOD("surface_get_arrays", "surf_idx"), &ArrayMesh::surface_get_arrays);
@@ -1272,7 +1334,7 @@ void ArrayMesh::_bind_methods() {
ClassDB::set_method_flags(get_class_static(), _scs_create("center_geometry"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
ClassDB::bind_method(D_METHOD("regen_normalmaps"), &ArrayMesh::regen_normalmaps);
ClassDB::set_method_flags(get_class_static(), _scs_create("regen_normalmaps"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
- ClassDB::bind_method(D_METHOD("lightmap_unwrap"), &ArrayMesh::lightmap_unwrap);
+ ClassDB::bind_method(D_METHOD("lightmap_unwrap", "transform", "texel_size"), &ArrayMesh::lightmap_unwrap);
ClassDB::set_method_flags(get_class_static(), _scs_create("lightmap_unwrap"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
ClassDB::bind_method(D_METHOD("get_faces"), &ArrayMesh::get_faces);
ClassDB::bind_method(D_METHOD("generate_triangle_mesh"), &ArrayMesh::generate_triangle_mesh);
diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h
index a3fb068569..36bfca49f8 100644
--- a/scene/resources/mesh.h
+++ b/scene/resources/mesh.h
@@ -123,6 +123,7 @@ public:
virtual int get_surface_count() const = 0;
virtual int surface_get_array_len(int p_idx) const = 0;
virtual int surface_get_array_index_len(int p_idx) const = 0;
+ virtual bool surface_is_softbody_friendly(int p_idx) const;
virtual Array surface_get_arrays(int p_surface) const = 0;
virtual Array surface_get_blend_shape_arrays(int p_surface) const = 0;
virtual uint32_t surface_get_format(int p_idx) const = 0;
@@ -133,6 +134,8 @@ public:
PoolVector<Face3> get_faces() const;
Ref<TriangleMesh> generate_triangle_mesh() const;
+ void generate_debug_mesh_lines(Vector<Vector3> &r_lines);
+ void generate_debug_mesh_indices(Vector<Vector3> &r_points);
Ref<Shape> create_trimesh_shape() const;
Ref<Shape> create_convex_shape() const;
@@ -143,6 +146,7 @@ public:
void set_lightmap_size_hint(const Vector2 &p_size);
Size2 get_lightmap_size_hint() const;
+ void clear_cache();
Mesh();
};
@@ -208,6 +212,7 @@ public:
void surface_set_material(int p_idx, const Ref<Material> &p_material);
Ref<Material> surface_get_material(int p_idx) const;
+ int surface_find_by_name(const String &p_name) const;
void surface_set_name(int p_idx, const String &p_name);
String surface_get_name(int p_idx) const;
diff --git a/scene/resources/mesh_data_tool.cpp b/scene/resources/mesh_data_tool.cpp
index 8639b325c3..6732303925 100644
--- a/scene/resources/mesh_data_tool.cpp
+++ b/scene/resources/mesh_data_tool.cpp
@@ -120,7 +120,7 @@ Error MeshDataTool::create_from_surface(const Ref<ArrayMesh> &p_mesh, int p_surf
v.bones.push_back(bo[i * 4 + 3]);
}
- vertices[i] = v;
+ vertices.write[i] = v;
}
PoolVector<int> indices;
@@ -143,7 +143,7 @@ Error MeshDataTool::create_from_surface(const Ref<ArrayMesh> &p_mesh, int p_surf
for (int i = 0; i < icount; i += 3) {
- Vertex *v[3] = { &vertices[r[i + 0]], &vertices[r[i + 1]], &vertices[r[i + 2]] };
+ Vertex *v[3] = { &vertices.write[r[i + 0]], &vertices.write[r[i + 1]], &vertices.write[r[i + 2]] };
int fidx = faces.size();
Face face;
@@ -169,7 +169,7 @@ Error MeshDataTool::create_from_surface(const Ref<ArrayMesh> &p_mesh, int p_surf
edges.push_back(e);
}
- edges[face.edges[j]].faces.push_back(fidx);
+ edges.write[face.edges[j]].faces.push_back(fidx);
v[j]->faces.push_back(fidx);
v[j]->edges.push_back(face.edges[j]);
}
@@ -247,7 +247,7 @@ Error MeshDataTool::commit_to_surface(const Ref<ArrayMesh> &p_mesh) {
for (int i = 0; i < vcount; i++) {
- Vertex &vtx = vertices[i];
+ const Vertex &vtx = vertices[i];
vr[i] = vtx.vertex;
if (nr.ptr())
@@ -344,7 +344,7 @@ Vector3 MeshDataTool::get_vertex(int p_idx) const {
void MeshDataTool::set_vertex(int p_idx, const Vector3 &p_vertex) {
ERR_FAIL_INDEX(p_idx, vertices.size());
- vertices[p_idx].vertex = p_vertex;
+ vertices.write[p_idx].vertex = p_vertex;
}
Vector3 MeshDataTool::get_vertex_normal(int p_idx) const {
@@ -355,7 +355,7 @@ Vector3 MeshDataTool::get_vertex_normal(int p_idx) const {
void MeshDataTool::set_vertex_normal(int p_idx, const Vector3 &p_normal) {
ERR_FAIL_INDEX(p_idx, vertices.size());
- vertices[p_idx].normal = p_normal;
+ vertices.write[p_idx].normal = p_normal;
format |= Mesh::ARRAY_FORMAT_NORMAL;
}
@@ -367,7 +367,7 @@ Plane MeshDataTool::get_vertex_tangent(int p_idx) const {
void MeshDataTool::set_vertex_tangent(int p_idx, const Plane &p_tangent) {
ERR_FAIL_INDEX(p_idx, vertices.size());
- vertices[p_idx].tangent = p_tangent;
+ vertices.write[p_idx].tangent = p_tangent;
format |= Mesh::ARRAY_FORMAT_TANGENT;
}
@@ -379,7 +379,7 @@ Vector2 MeshDataTool::get_vertex_uv(int p_idx) const {
void MeshDataTool::set_vertex_uv(int p_idx, const Vector2 &p_uv) {
ERR_FAIL_INDEX(p_idx, vertices.size());
- vertices[p_idx].uv = p_uv;
+ vertices.write[p_idx].uv = p_uv;
format |= Mesh::ARRAY_FORMAT_TEX_UV;
}
@@ -391,7 +391,7 @@ Vector2 MeshDataTool::get_vertex_uv2(int p_idx) const {
void MeshDataTool::set_vertex_uv2(int p_idx, const Vector2 &p_uv2) {
ERR_FAIL_INDEX(p_idx, vertices.size());
- vertices[p_idx].uv2 = p_uv2;
+ vertices.write[p_idx].uv2 = p_uv2;
format |= Mesh::ARRAY_FORMAT_TEX_UV2;
}
@@ -403,7 +403,7 @@ Color MeshDataTool::get_vertex_color(int p_idx) const {
void MeshDataTool::set_vertex_color(int p_idx, const Color &p_color) {
ERR_FAIL_INDEX(p_idx, vertices.size());
- vertices[p_idx].color = p_color;
+ vertices.write[p_idx].color = p_color;
format |= Mesh::ARRAY_FORMAT_COLOR;
}
@@ -415,7 +415,7 @@ Vector<int> MeshDataTool::get_vertex_bones(int p_idx) const {
void MeshDataTool::set_vertex_bones(int p_idx, const Vector<int> &p_bones) {
ERR_FAIL_INDEX(p_idx, vertices.size());
- vertices[p_idx].bones = p_bones;
+ vertices.write[p_idx].bones = p_bones;
format |= Mesh::ARRAY_FORMAT_BONES;
}
@@ -426,7 +426,7 @@ Vector<float> MeshDataTool::get_vertex_weights(int p_idx) const {
}
void MeshDataTool::set_vertex_weights(int p_idx, const Vector<float> &p_weights) {
ERR_FAIL_INDEX(p_idx, vertices.size());
- vertices[p_idx].weights = p_weights;
+ vertices.write[p_idx].weights = p_weights;
format |= Mesh::ARRAY_FORMAT_WEIGHTS;
}
@@ -439,7 +439,7 @@ Variant MeshDataTool::get_vertex_meta(int p_idx) const {
void MeshDataTool::set_vertex_meta(int p_idx, const Variant &p_meta) {
ERR_FAIL_INDEX(p_idx, vertices.size());
- vertices[p_idx].meta = p_meta;
+ vertices.write[p_idx].meta = p_meta;
}
Vector<int> MeshDataTool::get_vertex_edges(int p_idx) const {
@@ -472,7 +472,7 @@ Variant MeshDataTool::get_edge_meta(int p_idx) const {
void MeshDataTool::set_edge_meta(int p_idx, const Variant &p_meta) {
ERR_FAIL_INDEX(p_idx, edges.size());
- edges[p_idx].meta = p_meta;
+ edges.write[p_idx].meta = p_meta;
}
int MeshDataTool::get_face_vertex(int p_face, int p_vertex) const {
@@ -495,7 +495,7 @@ Variant MeshDataTool::get_face_meta(int p_face) const {
void MeshDataTool::set_face_meta(int p_face, const Variant &p_meta) {
ERR_FAIL_INDEX(p_face, faces.size());
- faces[p_face].meta = p_meta;
+ faces.write[p_face].meta = p_meta;
}
Vector3 MeshDataTool::get_face_normal(int p_face) const {
diff --git a/scene/resources/mesh_library.cpp b/scene/resources/mesh_library.cpp
index e1d3540fd1..a1d3e0ba1e 100644
--- a/scene/resources/mesh_library.cpp
+++ b/scene/resources/mesh_library.cpp
@@ -209,7 +209,7 @@ Vector<int> MeshLibrary::get_item_list() const {
int idx = 0;
for (Map<int, Item>::Element *E = item_map.front(); E; E = E->next()) {
- ret[idx++] = E->key();
+ ret.write[idx++] = E->key();
}
return ret;
diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp
index 846f6e356e..07783d5f4a 100644
--- a/scene/resources/packed_scene.cpp
+++ b/scene/resources/packed_scene.cpp
@@ -31,6 +31,7 @@
#include "packed_scene.h"
#include "core/core_string_names.h"
+#include "engine.h"
#include "io/resource_loader.h"
#include "project_settings.h"
#include "scene/2d/node_2d.h"
@@ -279,7 +280,12 @@ Node *SceneState::instance(GenEditState p_edit_state) const {
stray_instances.push_back(node); //can't be added, go to stray list
}
} else {
- node->_set_name_nocheck(snames[n.name]);
+ if (Engine::get_singleton()->is_editor_hint()) {
+ //validate name if using editor, to avoid broken
+ node->set_name(snames[n.name]);
+ } else {
+ node->_set_name_nocheck(snames[n.name]);
+ }
}
}
@@ -325,7 +331,7 @@ Node *SceneState::instance(GenEditState p_edit_state) const {
if (c.binds.size()) {
binds.resize(c.binds.size());
for (int j = 0; j < c.binds.size(); j++)
- binds[j] = props[c.binds[j]];
+ binds.write[j] = props[c.binds[j]];
}
cfrom->connect(snames[c.signal], cto, snames[c.method], binds, CONNECT_PERSIST | c.flags);
@@ -389,7 +395,15 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map
nd.name = _nm_get_string(p_node->get_name(), name_map);
nd.instance = -1; //not instanced by default
- nd.index = p_node->get_index();
+
+ //really convoluted condition, but it basically checks that index is only saved when part of an inherited scene OR the node parent is from the edited scene
+ if (p_owner->get_scene_inherited_state().is_null() && (p_node == p_owner || (p_node->get_owner() == p_owner && (p_node->get_parent() == p_owner || p_node->get_parent()->get_owner() == p_owner)))) {
+ //do not save index, because it belongs to saved scene and scene is not inherited
+ nd.index = -1;
+ } else {
+ //part of an inherited scene, or parent is from an instanced scene
+ nd.index = p_node->get_index();
+ }
// if this node is part of an instanced scene or sub-instanced scene
// we need to get the corresponding instance states.
@@ -875,7 +889,7 @@ Error SceneState::pack(Node *p_scene) {
for (Map<StringName, int>::Element *E = name_map.front(); E; E = E->next()) {
- names[E->get()] = E->key();
+ names.write[E->get()] = E->key();
}
variants.resize(variant_map.size());
@@ -883,13 +897,13 @@ Error SceneState::pack(Node *p_scene) {
while ((K = variant_map.next(K))) {
int idx = variant_map[*K];
- variants[idx] = *K;
+ variants.write[idx] = *K;
}
node_paths.resize(nodepath_map.size());
for (Map<Node *, int>::Element *E = nodepath_map.front(); E; E = E->next()) {
- node_paths[E->get()] = scene->get_path_to(E->key());
+ node_paths.write[E->get()] = scene->get_path_to(E->key());
}
return OK;
@@ -1090,7 +1104,7 @@ void SceneState::set_bundled_scene(const Dictionary &p_dictionary) {
names.resize(namecount);
PoolVector<String>::Read r = snames.read();
for (int i = 0; i < names.size(); i++)
- names[i] = r[i];
+ names.write[i] = r[i];
}
Array svariants = p_dictionary["variants"];
@@ -1100,7 +1114,7 @@ void SceneState::set_bundled_scene(const Dictionary &p_dictionary) {
variants.resize(varcount);
for (int i = 0; i < varcount; i++) {
- variants[i] = svariants[i];
+ variants.write[i] = svariants[i];
}
} else {
@@ -1114,7 +1128,7 @@ void SceneState::set_bundled_scene(const Dictionary &p_dictionary) {
PoolVector<int>::Read r = snodes.read();
int idx = 0;
for (int i = 0; i < nc; i++) {
- NodeData &nd = nodes[i];
+ NodeData &nd = nodes.write[i];
nd.parent = r[idx++];
nd.owner = r[idx++];
nd.type = r[idx++];
@@ -1126,13 +1140,13 @@ void SceneState::set_bundled_scene(const Dictionary &p_dictionary) {
nd.properties.resize(r[idx++]);
for (int j = 0; j < nd.properties.size(); j++) {
- nd.properties[j].name = r[idx++];
- nd.properties[j].value = r[idx++];
+ nd.properties.write[j].name = r[idx++];
+ nd.properties.write[j].value = r[idx++];
}
nd.groups.resize(r[idx++]);
for (int j = 0; j < nd.groups.size(); j++) {
- nd.groups[j] = r[idx++];
+ nd.groups.write[j] = r[idx++];
}
}
}
@@ -1146,7 +1160,7 @@ void SceneState::set_bundled_scene(const Dictionary &p_dictionary) {
PoolVector<int>::Read r = sconns.read();
int idx = 0;
for (int i = 0; i < cc; i++) {
- ConnectionData &cd = connections[i];
+ ConnectionData &cd = connections.write[i];
cd.from = r[idx++];
cd.to = r[idx++];
cd.signal = r[idx++];
@@ -1156,7 +1170,7 @@ void SceneState::set_bundled_scene(const Dictionary &p_dictionary) {
for (int j = 0; j < cd.binds.size(); j++) {
- cd.binds[j] = r[idx++];
+ cd.binds.write[j] = r[idx++];
}
}
}
@@ -1167,7 +1181,7 @@ void SceneState::set_bundled_scene(const Dictionary &p_dictionary) {
}
node_paths.resize(np.size());
for (int i = 0; i < np.size(); i++) {
- node_paths[i] = np[i];
+ node_paths.write[i] = np[i];
}
Array ei;
@@ -1181,7 +1195,7 @@ void SceneState::set_bundled_scene(const Dictionary &p_dictionary) {
editable_instances.resize(ei.size());
for (int i = 0; i < editable_instances.size(); i++) {
- editable_instances[i] = ei[i];
+ editable_instances.write[i] = ei[i];
}
//path=p_dictionary["path"];
@@ -1563,13 +1577,13 @@ void SceneState::add_node_property(int p_node, int p_name, int p_value) {
NodeData::Property prop;
prop.name = p_name;
prop.value = p_value;
- nodes[p_node].properties.push_back(prop);
+ nodes.write[p_node].properties.push_back(prop);
}
void SceneState::add_node_group(int p_node, int p_group) {
ERR_FAIL_INDEX(p_node, nodes.size());
ERR_FAIL_INDEX(p_group, names.size());
- nodes[p_node].groups.push_back(p_group);
+ nodes.write[p_node].groups.push_back(p_group);
}
void SceneState::set_base_scene(int p_idx) {
diff --git a/scene/resources/physics_material.cpp b/scene/resources/physics_material.cpp
new file mode 100644
index 0000000000..dc5ca1aef6
--- /dev/null
+++ b/scene/resources/physics_material.cpp
@@ -0,0 +1,76 @@
+/*************************************************************************/
+/* physics_material.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* 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. */
+/*************************************************************************/
+#include "physics_material.h"
+
+void PhysicsMaterial::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_friction", "friction"), &PhysicsMaterial::set_friction);
+ ClassDB::bind_method(D_METHOD("get_friction"), &PhysicsMaterial::get_friction);
+
+ ClassDB::bind_method(D_METHOD("set_rough", "rough"), &PhysicsMaterial::set_rough);
+ ClassDB::bind_method(D_METHOD("is_rough"), &PhysicsMaterial::is_rough);
+
+ ClassDB::bind_method(D_METHOD("set_bounce", "bounce"), &PhysicsMaterial::set_bounce);
+ ClassDB::bind_method(D_METHOD("get_bounce"), &PhysicsMaterial::get_bounce);
+
+ ClassDB::bind_method(D_METHOD("set_absorbent", "absorbent"), &PhysicsMaterial::set_absorbent);
+ ClassDB::bind_method(D_METHOD("is_absorbent"), &PhysicsMaterial::is_absorbent);
+
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "friction"), "set_friction", "get_friction");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "rough"), "set_rough", "is_rough");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "bounce"), "set_bounce", "get_bounce");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "absorbent"), "set_absorbent", "is_absorbent");
+}
+
+void PhysicsMaterial::set_friction(real_t p_val) {
+ friction = p_val;
+ emit_changed();
+}
+
+void PhysicsMaterial::set_rough(bool p_val) {
+ rough = p_val;
+ emit_changed();
+}
+
+void PhysicsMaterial::set_bounce(real_t p_val) {
+ bounce = p_val;
+ emit_changed();
+}
+
+void PhysicsMaterial::set_absorbent(bool p_val) {
+ absorbent = p_val;
+ emit_changed();
+}
+
+PhysicsMaterial::PhysicsMaterial() :
+ friction(1),
+ rough(false),
+ bounce(0),
+ absorbent(false) {}
diff --git a/scene/resources/physics_material.h b/scene/resources/physics_material.h
new file mode 100644
index 0000000000..c69e44a7da
--- /dev/null
+++ b/scene/resources/physics_material.h
@@ -0,0 +1,74 @@
+/*************************************************************************/
+/* physics_material.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* 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. */
+/*************************************************************************/
+#ifndef physics_material_override_H
+#define physics_material_override_H
+
+#include "resource.h"
+#include "servers/physics_server.h"
+
+class PhysicsMaterial : public Resource {
+
+ GDCLASS(PhysicsMaterial, Resource);
+ OBJ_SAVE_TYPE(PhysicsMaterial);
+ RES_BASE_EXTENSION("phymat");
+
+ real_t friction;
+ bool rough;
+ real_t bounce;
+ bool absorbent;
+
+protected:
+ static void _bind_methods();
+
+public:
+ void set_friction(real_t p_val);
+ _FORCE_INLINE_ real_t get_friction() const { return friction; }
+
+ void set_rough(bool p_val);
+ _FORCE_INLINE_ bool is_rough() const { return rough; }
+
+ _FORCE_INLINE_ real_t computed_friction() const {
+ return rough ? -friction : friction;
+ }
+
+ void set_bounce(real_t p_val);
+ _FORCE_INLINE_ real_t get_bounce() const { return bounce; }
+
+ void set_absorbent(bool p_val);
+ _FORCE_INLINE_ bool is_absorbent() const { return absorbent; }
+
+ _FORCE_INLINE_ real_t computed_bounce() const {
+ return absorbent ? -bounce : bounce;
+ }
+
+ PhysicsMaterial();
+};
+
+#endif // physics_material_override_H
diff --git a/scene/resources/polygon_path_finder.cpp b/scene/resources/polygon_path_finder.cpp
index 6fea2e1a8e..44f9ebaf33 100644
--- a/scene/resources/polygon_path_finder.cpp
+++ b/scene/resources/polygon_path_finder.cpp
@@ -65,8 +65,8 @@ void PolygonPathFinder::setup(const Vector<Vector2> &p_points, const Vector<int>
for (int i = 0; i < p_points.size(); i++) {
- points[i].pos = p_points[i];
- points[i].penalty = 0;
+ points.write[i].pos = p_points[i];
+ points.write[i].penalty = 0;
outside_point.x = i == 0 ? p_points[0].x : (MAX(p_points[i].x, outside_point.x));
outside_point.y = i == 0 ? p_points[0].y : (MAX(p_points[i].y, outside_point.y));
@@ -88,8 +88,8 @@ void PolygonPathFinder::setup(const Vector<Vector2> &p_points, const Vector<int>
Edge e(p_connections[i], p_connections[i + 1]);
ERR_FAIL_INDEX(e.points[0], point_count);
ERR_FAIL_INDEX(e.points[1], point_count);
- points[p_connections[i]].connections.insert(p_connections[i + 1]);
- points[p_connections[i + 1]].connections.insert(p_connections[i]);
+ points.write[p_connections[i]].connections.insert(p_connections[i + 1]);
+ points.write[p_connections[i + 1]].connections.insert(p_connections[i]);
edges.insert(e);
}
@@ -126,8 +126,8 @@ void PolygonPathFinder::setup(const Vector<Vector2> &p_points, const Vector<int>
}
if (valid) {
- points[i].connections.insert(j);
- points[j].connections.insert(i);
+ points.write[i].connections.insert(j);
+ points.write[j].connections.insert(i);
}
}
}
@@ -227,21 +227,21 @@ Vector<Vector2> PolygonPathFinder::find_path(const Vector2 &p_from, const Vector
int aidx = points.size() - 2;
int bidx = points.size() - 1;
- points[aidx].pos = from;
- points[bidx].pos = to;
- points[aidx].distance = 0;
- points[bidx].distance = 0;
- points[aidx].prev = -1;
- points[bidx].prev = -1;
- points[aidx].penalty = 0;
- points[bidx].penalty = 0;
+ points.write[aidx].pos = from;
+ points.write[bidx].pos = to;
+ points.write[aidx].distance = 0;
+ points.write[bidx].distance = 0;
+ points.write[aidx].prev = -1;
+ points.write[bidx].prev = -1;
+ points.write[aidx].penalty = 0;
+ points.write[bidx].penalty = 0;
for (int i = 0; i < points.size() - 2; i++) {
bool valid_a = true;
bool valid_b = true;
- points[i].prev = -1;
- points[i].distance = 0;
+ points.write[i].prev = -1;
+ points.write[i].distance = 0;
if (!_is_point_inside(from * 0.5 + points[i].pos * 0.5)) {
valid_a = false;
@@ -292,26 +292,26 @@ Vector<Vector2> PolygonPathFinder::find_path(const Vector2 &p_from, const Vector
}
if (valid_a) {
- points[i].connections.insert(aidx);
- points[aidx].connections.insert(i);
+ points.write[i].connections.insert(aidx);
+ points.write[aidx].connections.insert(i);
}
if (valid_b) {
- points[i].connections.insert(bidx);
- points[bidx].connections.insert(i);
+ points.write[i].connections.insert(bidx);
+ points.write[bidx].connections.insert(i);
}
}
//solve graph
Set<int> open_list;
- points[aidx].distance = 0;
- points[aidx].prev = aidx;
+ points.write[aidx].distance = 0;
+ points.write[aidx].prev = aidx;
for (Set<int>::Element *E = points[aidx].connections.front(); E; E = E->next()) {
open_list.insert(E->get());
- points[E->get()].distance = from.distance_to(points[E->get()].pos);
- points[E->get()].prev = aidx;
+ points.write[E->get()].distance = from.distance_to(points[E->get()].pos);
+ points.write[E->get()].prev = aidx;
}
bool found_route = false;
@@ -342,12 +342,12 @@ Vector<Vector2> PolygonPathFinder::find_path(const Vector2 &p_from, const Vector
}
}
- Point &np = points[least_cost_point];
+ const Point &np = points[least_cost_point];
//open the neighbours for search
for (Set<int>::Element *E = np.connections.front(); E; E = E->next()) {
- Point &p = points[E->get()];
+ Point &p = points.write[E->get()];
float distance = np.pos.distance_to(p.pos) + np.distance;
if (p.prev != -1) {
@@ -392,18 +392,18 @@ Vector<Vector2> PolygonPathFinder::find_path(const Vector2 &p_from, const Vector
for (int i = 0; i < points.size() - 2; i++) {
- points[i].connections.erase(aidx);
- points[i].connections.erase(bidx);
- points[i].prev = -1;
- points[i].distance = 0;
+ points.write[i].connections.erase(aidx);
+ points.write[i].connections.erase(bidx);
+ points.write[i].prev = -1;
+ points.write[i].distance = 0;
}
- points[aidx].connections.clear();
- points[aidx].prev = -1;
- points[aidx].distance = 0;
- points[bidx].connections.clear();
- points[bidx].prev = -1;
- points[bidx].distance = 0;
+ points.write[aidx].connections.clear();
+ points.write[aidx].prev = -1;
+ points.write[aidx].distance = 0;
+ points.write[bidx].connections.clear();
+ points.write[bidx].prev = -1;
+ points.write[bidx].distance = 0;
return path;
}
@@ -427,13 +427,13 @@ void PolygonPathFinder::_set_data(const Dictionary &p_data) {
PoolVector<Vector2>::Read pr = p.read();
for (int i = 0; i < pc; i++) {
- points[i].pos = pr[i];
+ points.write[i].pos = pr[i];
PoolVector<int> con = c[i];
PoolVector<int>::Read cr = con.read();
int cc = con.size();
for (int j = 0; j < cc; j++) {
- points[i].connections.insert(cr[j]);
+ points.write[i].connections.insert(cr[j]);
}
}
@@ -443,7 +443,7 @@ void PolygonPathFinder::_set_data(const Dictionary &p_data) {
if (penalties.size() == pc) {
PoolVector<float>::Read pr = penalties.read();
for (int i = 0; i < pc; i++) {
- points[i].penalty = pr[i];
+ points.write[i].penalty = pr[i];
}
}
}
@@ -566,7 +566,7 @@ Rect2 PolygonPathFinder::get_bounds() const {
void PolygonPathFinder::set_point_penalty(int p_point, float p_penalty) {
ERR_FAIL_INDEX(p_point, points.size() - 2);
- points[p_point].penalty = p_penalty;
+ points.write[p_point].penalty = p_penalty;
}
float PolygonPathFinder::get_point_penalty(int p_point) const {
diff --git a/scene/resources/scene_format_text.cpp b/scene/resources/scene_format_text.cpp
index 597866eb74..fd9989fe72 100644
--- a/scene/resources/scene_format_text.cpp
+++ b/scene/resources/scene_format_text.cpp
@@ -896,7 +896,7 @@ static void bs_save_unicode_string(FileAccess *f, const String &p_string, bool p
CharString utf8 = p_string.utf8();
if (p_bit_on_len) {
- f->store_32(utf8.length() + 1 | 0x80000000);
+ f->store_32((utf8.length() + 1) | 0x80000000);
} else {
f->store_32(utf8.length() + 1);
}
@@ -1523,7 +1523,7 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r
for (Map<RES, int>::Element *E = external_resources.front(); E; E = E->next()) {
- sorted_er[E->get()] = E->key();
+ sorted_er.write[E->get()] = E->key();
}
for (int i = 0; i < sorted_er.size(); i++) {
diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp
index 36740a307b..f53f03c1c8 100644
--- a/scene/resources/shader.cpp
+++ b/scene/resources/shader.cpp
@@ -54,16 +54,20 @@ void Shader::set_code(const String &p_code) {
VisualServer::get_singleton()->shader_set_code(shader, p_code);
params_cache_dirty = true;
- emit_signal(SceneStringNames::get_singleton()->changed);
+
+ emit_changed();
}
String Shader::get_code() const {
+ _update_shader();
return VisualServer::get_singleton()->shader_get_code(shader);
}
void Shader::get_param_list(List<PropertyInfo> *p_params) const {
+ _update_shader();
+
List<PropertyInfo> local;
VisualServer::get_singleton()->shader_get_param_list(shader, &local);
params_cache.clear();
@@ -72,6 +76,9 @@ void Shader::get_param_list(List<PropertyInfo> *p_params) const {
for (List<PropertyInfo>::Element *E = local.front(); E; E = E->next()) {
PropertyInfo pi = E->get();
+ if (default_textures.has(pi.name)) { //do not show default textures
+ continue;
+ }
pi.name = "shader_param/" + pi.name;
params_cache[pi.name] = E->get().name;
if (p_params) {
@@ -86,6 +93,8 @@ void Shader::get_param_list(List<PropertyInfo> *p_params) const {
RID Shader::get_rid() const {
+ _update_shader();
+
return shader;
}
@@ -98,6 +107,8 @@ void Shader::set_default_texture_param(const StringName &p_param, const Ref<Text
default_textures.erase(p_param);
VS::get_singleton()->shader_set_default_texture_param(shader, p_param, RID());
}
+
+ emit_changed();
}
Ref<Texture> Shader::get_default_texture_param(const StringName &p_param) const {
@@ -120,6 +131,9 @@ bool Shader::has_param(const StringName &p_param) const {
return params_cache.has(p_param);
}
+void Shader::_update_shader() const {
+}
+
void Shader::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_mode"), &Shader::get_mode);
@@ -227,5 +241,5 @@ void ResourceFormatSaverShader::get_recognized_extensions(const RES &p_resource,
}
bool ResourceFormatSaverShader::recognize(const RES &p_resource) const {
- return Object::cast_to<Shader>(*p_resource) != NULL;
+ return p_resource->get_class_name() == "Shader"; //only shader, not inherited
}
diff --git a/scene/resources/shader.h b/scene/resources/shader.h
index 248a6f0125..efc5da7753 100644
--- a/scene/resources/shader.h
+++ b/scene/resources/shader.h
@@ -61,12 +61,13 @@ private:
mutable Map<StringName, StringName> params_cache; //map a shader param to a material param..
Map<StringName, Ref<Texture> > default_textures;
+ virtual void _update_shader() const; //used for visual shader
protected:
static void _bind_methods();
public:
//void set_mode(Mode p_mode);
- Mode get_mode() const;
+ virtual Mode get_mode() const;
void set_code(const String &p_code);
String get_code() const;
diff --git a/scene/resources/shape.cpp b/scene/resources/shape.cpp
index 418d8ce819..a48ce0564b 100644
--- a/scene/resources/shape.cpp
+++ b/scene/resources/shape.cpp
@@ -50,6 +50,15 @@ void Shape::add_vertices_to_array(PoolVector<Vector3> &array, const Transform &p
}
}
+real_t Shape::get_margin() const {
+ return margin;
+}
+
+void Shape::set_margin(real_t p_margin) {
+ margin = p_margin;
+ PhysicsServer::get_singleton()->shape_set_margin(shape, margin);
+}
+
Ref<ArrayMesh> Shape::get_debug_mesh() {
if (debug_mesh_cache.is_valid())
@@ -87,12 +96,22 @@ Ref<ArrayMesh> Shape::get_debug_mesh() {
return debug_mesh_cache;
}
-Shape::Shape() {
+void Shape::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_margin", "margin"), &Shape::set_margin);
+ ClassDB::bind_method(D_METHOD("get_margin"), &Shape::get_margin);
+
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "margin", PROPERTY_HINT_RANGE, "0.04,10,0.01"), "set_margin", "get_margin");
+}
+
+Shape::Shape() :
+ margin(0.04) {
ERR_PRINT("Constructor must not be called!");
}
-Shape::Shape(RID p_shape) {
+Shape::Shape(RID p_shape) :
+ margin(0.04) {
shape = p_shape;
}
diff --git a/scene/resources/shape.h b/scene/resources/shape.h
index ad87a69679..0c44b86e92 100644
--- a/scene/resources/shape.h
+++ b/scene/resources/shape.h
@@ -40,10 +40,13 @@ class Shape : public Resource {
OBJ_SAVE_TYPE(Shape);
RES_BASE_EXTENSION("shape");
RID shape;
+ real_t margin;
Ref<ArrayMesh> debug_mesh_cache;
protected:
+ static void _bind_methods();
+
_FORCE_INLINE_ RID get_shape() const { return shape; }
Shape(RID p_shape);
@@ -55,6 +58,9 @@ public:
void add_vertices_to_array(PoolVector<Vector3> &array, const Transform &p_xform);
+ real_t get_margin() const;
+ void set_margin(real_t p_margin);
+
Shape();
~Shape();
};
diff --git a/scene/resources/sky_box.cpp b/scene/resources/sky_box.cpp
index f2d5cb3516..4176aed4d8 100644
--- a/scene/resources/sky_box.cpp
+++ b/scene/resources/sky_box.cpp
@@ -405,7 +405,7 @@ void ProceduralSky::_update_sky() {
} else {
Ref<Image> image = _generate_sky();
- VS::get_singleton()->texture_allocate(texture, image->get_width(), image->get_height(), Image::FORMAT_RGBE9995, VS::TEXTURE_FLAG_FILTER | VS::TEXTURE_FLAG_REPEAT);
+ VS::get_singleton()->texture_allocate(texture, image->get_width(), image->get_height(), 0, Image::FORMAT_RGBE9995, VS::TEXTURE_TYPE_2D, VS::TEXTURE_FLAG_FILTER | VS::TEXTURE_FLAG_REPEAT);
VS::get_singleton()->texture_set_data(texture, image);
_radiance_changed();
}
@@ -422,7 +422,7 @@ void ProceduralSky::_queue_update() {
void ProceduralSky::_thread_done(const Ref<Image> &p_image) {
- VS::get_singleton()->texture_allocate(texture, p_image->get_width(), p_image->get_height(), Image::FORMAT_RGBE9995, VS::TEXTURE_FLAG_FILTER | VS::TEXTURE_FLAG_REPEAT);
+ VS::get_singleton()->texture_allocate(texture, p_image->get_width(), p_image->get_height(), 0, Image::FORMAT_RGBE9995, VS::TEXTURE_TYPE_2D, VS::TEXTURE_FLAG_FILTER | VS::TEXTURE_FLAG_REPEAT);
VS::get_singleton()->texture_set_data(texture, p_image);
_radiance_changed();
Thread::wait_to_finish(sky_thread);
@@ -532,14 +532,14 @@ ProceduralSky::ProceduralSky() {
texture = VS::get_singleton()->texture_create();
update_queued = false;
- sky_top_color = Color::hex(0x0c74f9ff);
- sky_horizon_color = Color::hex(0x8ed2e8ff);
- sky_curve = 0.25;
+ sky_top_color = Color::hex(0xa5d6f1ff);
+ sky_horizon_color = Color::hex(0xd6eafaff);
+ sky_curve = 0.09;
sky_energy = 1;
- ground_bottom_color = Color::hex(0x1a2530ff);
- ground_horizon_color = Color::hex(0x7bc9f3ff);
- ground_curve = 0.01;
+ ground_bottom_color = Color::hex(0x282f36ff);
+ ground_horizon_color = Color::hex(0x6c655fff);
+ ground_curve = 0.02;
ground_energy = 1;
sun_color = Color(1, 1, 1);
diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp
index ebad00b068..fb81375b0a 100644
--- a/scene/resources/style_box.cpp
+++ b/scene/resources/style_box.cpp
@@ -905,12 +905,20 @@ bool StyleBoxLine::is_vertical() const {
return vertical;
}
-void StyleBoxLine::set_grow(float p_grow) {
- grow = p_grow;
+void StyleBoxLine::set_grow_end(float p_grow_end) {
+ grow_end = p_grow_end;
emit_changed();
}
-float StyleBoxLine::get_grow() const {
- return grow;
+float StyleBoxLine::get_grow_end() const {
+ return grow_end;
+}
+
+void StyleBoxLine::set_grow_begin(float p_grow_begin) {
+ grow_begin = p_grow_begin;
+ emit_changed();
+}
+float StyleBoxLine::get_grow_begin() const {
+ return grow_begin;
}
void StyleBoxLine::_bind_methods() {
@@ -919,13 +927,16 @@ void StyleBoxLine::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_color"), &StyleBoxLine::get_color);
ClassDB::bind_method(D_METHOD("set_thickness", "thickness"), &StyleBoxLine::set_thickness);
ClassDB::bind_method(D_METHOD("get_thickness"), &StyleBoxLine::get_thickness);
- ClassDB::bind_method(D_METHOD("set_grow", "grow"), &StyleBoxLine::set_grow);
- ClassDB::bind_method(D_METHOD("get_grow"), &StyleBoxLine::get_grow);
+ ClassDB::bind_method(D_METHOD("set_grow_begin", "offset"), &StyleBoxLine::set_grow_begin);
+ ClassDB::bind_method(D_METHOD("get_grow_begin"), &StyleBoxLine::get_grow_begin);
+ ClassDB::bind_method(D_METHOD("set_grow_end", "offset"), &StyleBoxLine::set_grow_end);
+ ClassDB::bind_method(D_METHOD("get_grow_end"), &StyleBoxLine::get_grow_end);
ClassDB::bind_method(D_METHOD("set_vertical", "vertical"), &StyleBoxLine::set_vertical);
ClassDB::bind_method(D_METHOD("is_vertical"), &StyleBoxLine::is_vertical);
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "grow", PROPERTY_HINT_RANGE, "-300,300,1"), "set_grow", "get_grow");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "grow_begin", PROPERTY_HINT_RANGE, "-300,300,1"), "set_grow_begin", "get_grow_begin");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "grow_end", PROPERTY_HINT_RANGE, "-300,300,1"), "set_grow_end", "get_grow_end");
ADD_PROPERTY(PropertyInfo(Variant::INT, "thickness", PROPERTY_HINT_RANGE, "0,10"), "set_thickness", "get_thickness");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "vertical"), "set_vertical", "is_vertical");
}
@@ -941,12 +952,12 @@ void StyleBoxLine::draw(RID p_canvas_item, const Rect2 &p_rect) const {
Rect2i r = p_rect;
if (vertical) {
- r.position.y -= grow;
- r.size.y += grow * 2;
+ r.position.y -= grow_begin;
+ r.size.y += (grow_begin + grow_end);
r.size.x = thickness;
} else {
- r.position.x -= grow;
- r.size.x += grow * 2;
+ r.position.x -= grow_begin;
+ r.size.x += (grow_begin + grow_end);
r.size.y = thickness;
}
@@ -954,7 +965,8 @@ void StyleBoxLine::draw(RID p_canvas_item, const Rect2 &p_rect) const {
}
StyleBoxLine::StyleBoxLine() {
- grow = 1.0;
+ grow_begin = 1.0;
+ grow_end = 1.0;
thickness = 1;
color = Color(0.0, 0.0, 0.0);
vertical = false;
diff --git a/scene/resources/style_box.h b/scene/resources/style_box.h
index c1d84fe19f..ed193a1ab4 100644
--- a/scene/resources/style_box.h
+++ b/scene/resources/style_box.h
@@ -236,7 +236,8 @@ class StyleBoxLine : public StyleBox {
Color color;
int thickness;
bool vertical;
- float grow;
+ float grow_begin;
+ float grow_end;
protected:
virtual float get_style_margin(Margin p_margin) const;
@@ -252,8 +253,11 @@ public:
void set_vertical(bool p_vertical);
bool is_vertical() const;
- void set_grow(float p_grow);
- float get_grow() const;
+ void set_grow_begin(float p_grow);
+ float get_grow_begin() const;
+
+ void set_grow_end(float p_grow);
+ float get_grow_end() const;
virtual Size2 get_center_size() const;
diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp
index 5a42873d79..ec489e5c5b 100644
--- a/scene/resources/surface_tool.cpp
+++ b/scene/resources/surface_tool.cpp
@@ -421,6 +421,7 @@ Ref<ArrayMesh> SurfaceTool::commit(const Ref<ArrayMesh> &p_existing, uint32_t p_
Array a = commit_to_arrays();
mesh->add_surface_from_arrays(primitive, a, Array(), p_flags);
+
if (material.is_valid())
mesh->surface_set_material(surface, material);
@@ -465,7 +466,7 @@ void SurfaceTool::deindex() {
int idx = 0;
for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next()) {
- varr[idx++] = E->get();
+ varr.write[idx++] = E->get();
}
vertex_array.clear();
for (List<int>::Element *E = index_array.front(); E; E = E->next()) {
@@ -569,19 +570,19 @@ Vector<SurfaceTool::Vertex> SurfaceTool::create_vertex_array_from_triangle_array
if (lformat & VS::ARRAY_FORMAT_BONES) {
Vector<int> b;
b.resize(4);
- b[0] = barr[i * 4 + 0];
- b[1] = barr[i * 4 + 1];
- b[2] = barr[i * 4 + 2];
- b[3] = barr[i * 4 + 3];
+ b.write[0] = barr[i * 4 + 0];
+ b.write[1] = barr[i * 4 + 1];
+ b.write[2] = barr[i * 4 + 2];
+ b.write[3] = barr[i * 4 + 3];
v.bones = b;
}
if (lformat & VS::ARRAY_FORMAT_WEIGHTS) {
Vector<float> w;
w.resize(4);
- w[0] = warr[i * 4 + 0];
- w[1] = warr[i * 4 + 1];
- w[2] = warr[i * 4 + 2];
- w[3] = warr[i * 4 + 3];
+ w.write[0] = warr[i * 4 + 0];
+ w.write[1] = warr[i * 4 + 1];
+ w.write[2] = warr[i * 4 + 2];
+ w.write[3] = warr[i * 4 + 3];
v.weights = w;
}
@@ -674,19 +675,19 @@ void SurfaceTool::_create_list_from_arrays(Array arr, List<Vertex> *r_vertex, Li
if (lformat & VS::ARRAY_FORMAT_BONES) {
Vector<int> b;
b.resize(4);
- b[0] = barr[i * 4 + 0];
- b[1] = barr[i * 4 + 1];
- b[2] = barr[i * 4 + 2];
- b[3] = barr[i * 4 + 3];
+ b.write[0] = barr[i * 4 + 0];
+ b.write[1] = barr[i * 4 + 1];
+ b.write[2] = barr[i * 4 + 2];
+ b.write[3] = barr[i * 4 + 3];
v.bones = b;
}
if (lformat & VS::ARRAY_FORMAT_WEIGHTS) {
Vector<float> w;
w.resize(4);
- w[0] = warr[i * 4 + 0];
- w[1] = warr[i * 4 + 1];
- w[2] = warr[i * 4 + 2];
- w[3] = warr[i * 4 + 3];
+ w.write[0] = warr[i * 4 + 0];
+ w.write[1] = warr[i * 4 + 1];
+ w.write[2] = warr[i * 4 + 2];
+ w.write[3] = warr[i * 4 + 3];
v.weights = w;
}
@@ -845,7 +846,7 @@ void SurfaceTool::generate_tangents() {
vtx.resize(vertex_array.size());
int idx = 0;
for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next()) {
- vtx[idx++] = E;
+ vtx.write[idx++] = E;
E->get().binormal = Vector3();
E->get().tangent = Vector3();
}
diff --git a/scene/resources/text_file.cpp b/scene/resources/text_file.cpp
new file mode 100644
index 0000000000..e2fe0adfc5
--- /dev/null
+++ b/scene/resources/text_file.cpp
@@ -0,0 +1,77 @@
+/*************************************************************************/
+/* text_file.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* 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. */
+/*************************************************************************/
+
+#include "text_file.h"
+
+#include "os/file_access.h"
+
+bool TextFile::has_text() const {
+ return text != "";
+}
+
+String TextFile::get_text() const {
+ return text;
+}
+
+void TextFile::set_text(const String &p_code) {
+ text = p_code;
+}
+
+void TextFile::reload_from_file() {
+ load_text(path);
+}
+
+Error TextFile::load_text(const String &p_path) {
+
+ PoolVector<uint8_t> sourcef;
+ Error err;
+ FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
+ if (err) {
+ ERR_FAIL_COND_V(err, err);
+ }
+
+ int len = f->get_len();
+ sourcef.resize(len + 1);
+ PoolVector<uint8_t>::Write w = sourcef.write();
+ int r = f->get_buffer(w.ptr(), len);
+ f->close();
+ memdelete(f);
+ ERR_FAIL_COND_V(r != len, ERR_CANT_OPEN);
+ w[len] = 0;
+
+ String s;
+ if (s.parse_utf8((const char *)w.ptr())) {
+ ERR_EXPLAIN("Script '" + p_path + "' contains invalid unicode (utf-8), so it was not loaded. Please ensure that scripts are saved in valid utf-8 unicode.");
+ ERR_FAIL_V(ERR_INVALID_DATA);
+ }
+ text = s;
+ path = p_path;
+ return OK;
+}
diff --git a/scene/resources/text_file.h b/scene/resources/text_file.h
new file mode 100644
index 0000000000..40b648eebb
--- /dev/null
+++ b/scene/resources/text_file.h
@@ -0,0 +1,55 @@
+/*************************************************************************/
+/* text_file.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* 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. */
+/*************************************************************************/
+
+#ifndef TEXTFILE_H
+#define TEXTFILE_H
+
+#include "io/resource_loader.h"
+#include "io/resource_saver.h"
+
+class TextFile : public Resource {
+
+ GDCLASS(TextFile, Resource)
+
+private:
+ String text;
+ String path;
+
+public:
+ virtual bool has_text() const;
+ virtual String get_text() const;
+ virtual void set_text(const String &p_code);
+ virtual void reload_from_file();
+
+ void set_file_path(const String &p_path) { path = p_path; }
+ Error load_text(const String &p_path);
+};
+
+#endif // TEXTFILE_H
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index 54f5aea160..41f3ee1fce 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -124,7 +124,7 @@ bool ImageTexture::_set(const StringName &p_name, const Variant &p_value) {
Size2 s = p_value;
w = s.width;
h = s.height;
- VisualServer::get_singleton()->texture_set_size_override(texture, w, h);
+ VisualServer::get_singleton()->texture_set_size_override(texture, w, h, 0);
} else if (p_name == "_data") {
_set_data(p_value);
} else
@@ -151,13 +151,6 @@ bool ImageTexture::_get(const StringName &p_name, Variant &r_ret) const {
void ImageTexture::_get_property_list(List<PropertyInfo> *p_list) const {
- PropertyHint img_hint = PROPERTY_HINT_NONE;
- if (storage == STORAGE_COMPRESS_LOSSY) {
- img_hint = PROPERTY_HINT_IMAGE_COMPRESS_LOSSY;
- } else if (storage == STORAGE_COMPRESS_LOSSLESS) {
- img_hint = PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS;
- }
-
p_list->push_back(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, "Mipmaps,Repeat,Filter,Anisotropic,sRGB,Mirrored Repeat"));
p_list->push_back(PropertyInfo(Variant::OBJECT, "image", PROPERTY_HINT_RESOURCE_TYPE, "Image"));
p_list->push_back(PropertyInfo(Variant::VECTOR2, "size", PROPERTY_HINT_NONE, ""));
@@ -183,7 +176,7 @@ void ImageTexture::_reload_hook(const RID &p_hook) {
void ImageTexture::create(int p_width, int p_height, Image::Format p_format, uint32_t p_flags) {
flags = p_flags;
- VisualServer::get_singleton()->texture_allocate(texture, p_width, p_height, p_format, p_flags);
+ VisualServer::get_singleton()->texture_allocate(texture, p_width, p_height, 0, p_format, VS::TEXTURE_TYPE_2D, p_flags);
format = p_format;
w = p_width;
h = p_height;
@@ -196,7 +189,7 @@ void ImageTexture::create_from_image(const Ref<Image> &p_image, uint32_t p_flags
h = p_image->get_height();
format = p_image->get_format();
- VisualServer::get_singleton()->texture_allocate(texture, p_image->get_width(), p_image->get_height(), p_image->get_format(), p_flags);
+ VisualServer::get_singleton()->texture_allocate(texture, p_image->get_width(), p_image->get_height(), 0, p_image->get_format(), VS::TEXTURE_TYPE_2D, p_flags);
VisualServer::get_singleton()->texture_set_data(texture, p_image);
_change_notify();
}
@@ -221,9 +214,10 @@ Image::Format ImageTexture::get_format() const {
return format;
}
-
+#ifndef DISABLE_DEPRECATED
Error ImageTexture::load(const String &p_path) {
+ WARN_DEPRECATED
Ref<Image> img;
img.instance();
Error err = img->load(p_path);
@@ -232,9 +226,11 @@ Error ImageTexture::load(const String &p_path) {
}
return err;
}
-
+#endif
void ImageTexture::set_data(const Ref<Image> &p_image) {
+ ERR_FAIL_COND(p_image.is_null());
+
VisualServer::get_singleton()->texture_set_data(texture, p_image);
_change_notify();
@@ -299,7 +295,7 @@ void ImageTexture::set_size_override(const Size2 &p_size) {
w = s.x;
if (s.y != 0)
h = s.y;
- VisualServer::get_singleton()->texture_set_size_override(texture, w, h);
+ VisualServer::get_singleton()->texture_set_size_override(texture, w, h, 0);
}
void ImageTexture::set_path(const String &p_path, bool p_take_over) {
@@ -350,7 +346,9 @@ void ImageTexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("create", "width", "height", "format", "flags"), &ImageTexture::create, DEFVAL(FLAGS_DEFAULT));
ClassDB::bind_method(D_METHOD("create_from_image", "image", "flags"), &ImageTexture::create_from_image, DEFVAL(FLAGS_DEFAULT));
ClassDB::bind_method(D_METHOD("get_format"), &ImageTexture::get_format);
+#ifndef DISABLE_DEPRECATED
ClassDB::bind_method(D_METHOD("load", "path"), &ImageTexture::load);
+#endif
ClassDB::bind_method(D_METHOD("set_data", "image"), &ImageTexture::set_data);
ClassDB::bind_method(D_METHOD("set_storage", "mode"), &ImageTexture::set_storage);
ClassDB::bind_method(D_METHOD("get_storage"), &ImageTexture::get_storage);
@@ -590,7 +588,7 @@ Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &fla
int sh = th;
int mipmaps = Image::get_image_required_mipmaps(tw, th, format);
- int total_size = Image::get_image_data_size(tw, th, format, mipmaps);
+ int total_size = Image::get_image_data_size(tw, th, format, true);
int idx = 0;
int ofs = 0;
@@ -623,7 +621,11 @@ Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &fla
memdelete(f);
- if (bytes != total_size - ofs) {
+ int expected = total_size - ofs;
+ if (bytes < expected) {
+ //this is a compatibility workaround for older format, which saved less mipmaps. It is still recommended the image is reimported.
+ zeromem(w.ptr() + bytes, (expected - bytes));
+ } else if (bytes != expected) {
ERR_FAIL_V(ERR_FILE_CORRUPT);
}
}
@@ -646,7 +648,7 @@ Error StreamTexture::load(const String &p_path) {
if (err)
return err;
- VS::get_singleton()->texture_allocate(texture, image->get_width(), image->get_height(), image->get_format(), lflags);
+ VS::get_singleton()->texture_allocate(texture, image->get_width(), image->get_height(), 0, image->get_format(), VS::TEXTURE_TYPE_2D, lflags);
VS::get_singleton()->texture_set_data(texture, image);
w = lw;
@@ -1037,7 +1039,7 @@ bool LargeTexture::has_alpha() const {
void LargeTexture::set_flags(uint32_t p_flags) {
for (int i = 0; i < pieces.size(); i++) {
- pieces[i].texture->set_flags(p_flags);
+ pieces.write[i].texture->set_flags(p_flags);
}
}
@@ -1063,13 +1065,13 @@ int LargeTexture::add_piece(const Point2 &p_offset, const Ref<Texture> &p_textur
void LargeTexture::set_piece_offset(int p_idx, const Point2 &p_offset) {
ERR_FAIL_INDEX(p_idx, pieces.size());
- pieces[p_idx].offset = p_offset;
+ pieces.write[p_idx].offset = p_offset;
};
void LargeTexture::set_piece_texture(int p_idx, const Ref<Texture> &p_texture) {
ERR_FAIL_INDEX(p_idx, pieces.size());
- pieces[p_idx].texture = p_texture;
+ pieces.write[p_idx].texture = p_texture;
};
void LargeTexture::set_size(const Size2 &p_size) {
@@ -1153,7 +1155,6 @@ void LargeTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile
Size2 scale = p_rect.size / size;
- RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
for (int i = 0; i < pieces.size(); i++) {
// TODO
@@ -1168,7 +1169,6 @@ void LargeTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, cons
Size2 scale = p_rect.size / p_src_rect.size;
- RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
for (int i = 0; i < pieces.size(); i++) {
// TODO
@@ -1193,7 +1193,7 @@ void CubeMap::set_flags(uint32_t p_flags) {
flags = p_flags;
if (_is_valid())
- VS::get_singleton()->texture_set_flags(cubemap, flags | VS::TEXTURE_FLAG_CUBEMAP);
+ VS::get_singleton()->texture_set_flags(cubemap, flags);
}
uint32_t CubeMap::get_flags() const {
@@ -1209,7 +1209,7 @@ void CubeMap::set_side(Side p_side, const Ref<Image> &p_image) {
format = p_image->get_format();
w = p_image->get_width();
h = p_image->get_height();
- VS::get_singleton()->texture_allocate(cubemap, w, h, p_image->get_format(), flags | VS::TEXTURE_FLAG_CUBEMAP);
+ VS::get_singleton()->texture_allocate(cubemap, w, h, 0, p_image->get_format(), VS::TEXTURE_TYPE_CUBEMAP, flags);
}
VS::get_singleton()->texture_set_data(cubemap, p_image, VS::CubeMapSide(p_side));
@@ -1320,13 +1320,6 @@ bool CubeMap::_get(const StringName &p_name, Variant &r_ret) const {
void CubeMap::_get_property_list(List<PropertyInfo> *p_list) const {
- PropertyHint img_hint = PROPERTY_HINT_NONE;
- if (storage == STORAGE_COMPRESS_LOSSY) {
- img_hint = PROPERTY_HINT_IMAGE_COMPRESS_LOSSY;
- } else if (storage == STORAGE_COMPRESS_LOSSLESS) {
- img_hint = PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS;
- }
-
p_list->push_back(PropertyInfo(Variant::OBJECT, "side/left", PROPERTY_HINT_RESOURCE_TYPE, "Image"));
p_list->push_back(PropertyInfo(Variant::OBJECT, "side/right", PROPERTY_HINT_RESOURCE_TYPE, "Image"));
p_list->push_back(PropertyInfo(Variant::OBJECT, "side/bottom", PROPERTY_HINT_RESOURCE_TYPE, "Image"));
@@ -1472,7 +1465,7 @@ void CurveTexture::_update() {
Ref<Image> image = memnew(Image(_width, 1, false, Image::FORMAT_RF, data));
- VS::get_singleton()->texture_allocate(_texture, _width, 1, Image::FORMAT_RF, VS::TEXTURE_FLAG_FILTER);
+ VS::get_singleton()->texture_allocate(_texture, _width, 1, 0, Image::FORMAT_RF, VS::TEXTURE_TYPE_2D, VS::TEXTURE_FLAG_FILTER);
VS::get_singleton()->texture_set_data(_texture, image);
emit_changed();
@@ -1581,7 +1574,7 @@ void GradientTexture::_update() {
Ref<Image> image = memnew(Image(width, 1, false, Image::FORMAT_RGBA8, data));
- VS::get_singleton()->texture_allocate(texture, width, 1, Image::FORMAT_RGBA8, VS::TEXTURE_FLAG_FILTER);
+ VS::get_singleton()->texture_allocate(texture, width, 1, 0, Image::FORMAT_RGBA8, VS::TEXTURE_TYPE_2D, VS::TEXTURE_FLAG_FILTER);
VS::get_singleton()->texture_set_data(texture, image);
emit_changed();
@@ -1669,3 +1662,539 @@ ProxyTexture::~ProxyTexture() {
VS::get_singleton()->free(proxy);
}
+//////////////////////////////////////////////
+
+void AnimatedTexture::_update_proxy() {
+
+ RWLockRead r(rw_lock);
+
+ float delta;
+ if (prev_ticks == 0) {
+ delta = 0;
+ prev_ticks = OS::get_singleton()->get_ticks_usec();
+ } else {
+ uint64_t ticks = OS::get_singleton()->get_ticks_usec();
+ delta = float(double(ticks - prev_ticks) / 1000000.0);
+ prev_ticks = ticks;
+ }
+
+ time += delta;
+
+ float limit;
+
+ if (fps == 0) {
+ limit = 0;
+ } else {
+ limit = 1.0 / fps;
+ }
+
+ int iter_max = frame_count;
+ while (iter_max) {
+ float frame_limit = limit + frames[current_frame].delay_sec;
+
+ if (time > frame_limit) {
+ current_frame++;
+ if (current_frame >= frame_count) {
+ current_frame = 0;
+ }
+ time -= frame_limit;
+ } else {
+ break;
+ }
+ iter_max--;
+ }
+
+ if (frames[current_frame].texture.is_valid()) {
+ VisualServer::get_singleton()->texture_set_proxy(proxy, frames[current_frame].texture->get_rid());
+ }
+}
+
+void AnimatedTexture::set_frames(int p_frames) {
+ ERR_FAIL_COND(p_frames < 1 || p_frames > MAX_FRAMES);
+
+ RWLockWrite r(rw_lock);
+
+ frame_count = p_frames;
+}
+int AnimatedTexture::get_frames() const {
+ return frame_count;
+}
+
+void AnimatedTexture::set_frame_texture(int p_frame, const Ref<Texture> &p_texture) {
+ ERR_FAIL_INDEX(p_frame, MAX_FRAMES);
+
+ RWLockWrite w(rw_lock);
+
+ frames[p_frame].texture = p_texture;
+}
+Ref<Texture> AnimatedTexture::get_frame_texture(int p_frame) const {
+ ERR_FAIL_INDEX_V(p_frame, MAX_FRAMES, Ref<Texture>());
+
+ RWLockRead r(rw_lock);
+
+ return frames[p_frame].texture;
+}
+
+void AnimatedTexture::set_frame_delay(int p_frame, float p_delay_sec) {
+ ERR_FAIL_INDEX(p_frame, MAX_FRAMES);
+
+ RWLockRead r(rw_lock);
+
+ frames[p_frame].delay_sec = p_delay_sec;
+}
+float AnimatedTexture::get_frame_delay(int p_frame) const {
+ ERR_FAIL_INDEX_V(p_frame, MAX_FRAMES, 0);
+
+ RWLockRead r(rw_lock);
+
+ return frames[p_frame].delay_sec;
+}
+
+void AnimatedTexture::set_fps(float p_fps) {
+ ERR_FAIL_COND(p_fps < 0 || p_fps >= 1000);
+
+ fps = p_fps;
+}
+float AnimatedTexture::get_fps() const {
+ return fps;
+}
+
+int AnimatedTexture::get_width() const {
+ RWLockRead r(rw_lock);
+
+ if (!frames[current_frame].texture.is_valid()) {
+ return 1;
+ }
+
+ return frames[current_frame].texture->get_width();
+}
+int AnimatedTexture::get_height() const {
+ RWLockRead r(rw_lock);
+
+ if (!frames[current_frame].texture.is_valid()) {
+ return 1;
+ }
+
+ return frames[current_frame].texture->get_height();
+}
+RID AnimatedTexture::get_rid() const {
+ return proxy;
+}
+
+bool AnimatedTexture::has_alpha() const {
+
+ RWLockRead r(rw_lock);
+
+ if (!frames[current_frame].texture.is_valid()) {
+ return false;
+ }
+
+ return frames[current_frame].texture->has_alpha();
+}
+
+Ref<Image> AnimatedTexture::get_data() const {
+
+ RWLockRead r(rw_lock);
+
+ if (!frames[current_frame].texture.is_valid()) {
+ return Ref<Image>();
+ }
+
+ return frames[current_frame].texture->get_data();
+}
+
+void AnimatedTexture::set_flags(uint32_t p_flags) {
+}
+uint32_t AnimatedTexture::get_flags() const {
+
+ RWLockRead r(rw_lock);
+
+ if (!frames[current_frame].texture.is_valid()) {
+ return 0;
+ }
+
+ return frames[current_frame].texture->get_flags();
+}
+
+void AnimatedTexture::_validate_property(PropertyInfo &property) const {
+
+ String prop = property.name;
+ if (prop.begins_with("frame_")) {
+ int frame = prop.get_slicec('/', 0).get_slicec('_', 1).to_int();
+ if (frame >= frame_count) {
+ property.usage = 0;
+ }
+ }
+}
+
+void AnimatedTexture::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_frames", "frames"), &AnimatedTexture::set_frames);
+ ClassDB::bind_method(D_METHOD("get_frames"), &AnimatedTexture::get_frames);
+
+ ClassDB::bind_method(D_METHOD("set_fps", "fps"), &AnimatedTexture::set_fps);
+ ClassDB::bind_method(D_METHOD("get_fps"), &AnimatedTexture::get_fps);
+
+ ClassDB::bind_method(D_METHOD("set_frame_texture", "frame", "texture"), &AnimatedTexture::set_frame_texture);
+ ClassDB::bind_method(D_METHOD("get_frame_texture", "frame"), &AnimatedTexture::get_frame_texture);
+
+ ClassDB::bind_method(D_METHOD("set_frame_delay", "frame", "delay"), &AnimatedTexture::set_frame_delay);
+ ClassDB::bind_method(D_METHOD("get_frame_delay", "frame"), &AnimatedTexture::get_frame_delay);
+
+ ClassDB::bind_method(D_METHOD("_update_proxy"), &AnimatedTexture::_update_proxy);
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "frames", PROPERTY_HINT_RANGE, "1," + itos(MAX_FRAMES), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_frames", "get_frames");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "fps", PROPERTY_HINT_RANGE, "0,1024,0.1"), "set_fps", "get_fps");
+
+ for (int i = 0; i < MAX_FRAMES; i++) {
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "frame_" + itos(i) + "/texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_frame_texture", "get_frame_texture", i);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL, "frame_" + itos(i) + "/delay_sec", PROPERTY_HINT_RANGE, "0.0,16.0,0.01"), "set_frame_delay", "get_frame_delay", i);
+ }
+}
+
+AnimatedTexture::AnimatedTexture() {
+ proxy = VS::get_singleton()->texture_create();
+ VisualServer::get_singleton()->texture_set_force_redraw_if_visible(proxy, true);
+ time = 0;
+ frame_count = 1;
+ fps = 4;
+ prev_ticks = 0;
+ current_frame = 0;
+ VisualServer::get_singleton()->connect("frame_pre_draw", this, "_update_proxy");
+
+#ifndef NO_THREADS
+ rw_lock = RWLock::create();
+#else
+ rw_lock = NULL;
+#endif
+}
+
+AnimatedTexture::~AnimatedTexture() {
+ VS::get_singleton()->free(proxy);
+ if (rw_lock) {
+ memdelete(rw_lock);
+ }
+}
+///////////////////////////////
+
+void TextureLayered::set_flags(uint32_t p_flags) {
+ flags = p_flags;
+
+ if (texture.is_valid()) {
+ VS::get_singleton()->texture_set_flags(texture, flags);
+ }
+}
+
+uint32_t TextureLayered::get_flags() const {
+ return flags;
+}
+
+Image::Format TextureLayered::get_format() const {
+ return format;
+}
+
+uint32_t TextureLayered::get_width() const {
+ return width;
+}
+
+uint32_t TextureLayered::get_height() const {
+ return height;
+}
+
+uint32_t TextureLayered::get_depth() const {
+ return depth;
+}
+
+void TextureLayered::_set_data(const Dictionary &p_data) {
+ ERR_FAIL_COND(!p_data.has("width"));
+ ERR_FAIL_COND(!p_data.has("height"));
+ ERR_FAIL_COND(!p_data.has("depth"));
+ ERR_FAIL_COND(!p_data.has("format"));
+ ERR_FAIL_COND(!p_data.has("flags"));
+ ERR_FAIL_COND(!p_data.has("layers"));
+ int w = p_data["width"];
+ int h = p_data["height"];
+ int d = p_data["depth"];
+ Image::Format format = Image::Format(int(p_data["format"]));
+ int flags = p_data["flags"];
+ Array layers = p_data["layers"];
+ ERR_FAIL_COND(layers.size() != d);
+
+ create(w, h, d, format, flags);
+
+ for (int i = 0; i < layers.size(); i++) {
+ Ref<Image> img = layers[i];
+ ERR_CONTINUE(!img.is_valid());
+ ERR_CONTINUE(img->get_format() != format);
+ ERR_CONTINUE(img->get_width() != w);
+ ERR_CONTINUE(img->get_height() != h);
+ set_layer_data(img, i);
+ }
+}
+
+Dictionary TextureLayered::_get_data() const {
+ Dictionary d;
+ d["width"] = width;
+ d["height"] = height;
+ d["depth"] = depth;
+ d["flags"] = flags;
+ d["format"] = format;
+
+ Array layers;
+ for (int i = 0; i < depth; i++) {
+ layers.push_back(get_layer_data(i));
+ }
+ d["layers"] = layers;
+ return d;
+}
+
+void TextureLayered::create(uint32_t p_width, uint32_t p_height, uint32_t p_depth, Image::Format p_format, uint32_t p_flags) {
+ VS::get_singleton()->texture_allocate(texture, p_width, p_height, p_depth, p_format, is_3d ? VS::TEXTURE_TYPE_3D : VS::TEXTURE_TYPE_2D_ARRAY, p_flags);
+
+ width = p_width;
+ height = p_height;
+ depth = p_depth;
+
+ flags = p_flags;
+}
+
+void TextureLayered::set_layer_data(const Ref<Image> &p_image, int p_layer) {
+ ERR_FAIL_COND(!texture.is_valid());
+ VS::get_singleton()->texture_set_data(texture, p_image, p_layer);
+}
+
+Ref<Image> TextureLayered::get_layer_data(int p_layer) const {
+
+ ERR_FAIL_COND_V(!texture.is_valid(), Ref<Image>());
+ return VS::get_singleton()->texture_get_data(texture, p_layer);
+}
+
+void TextureLayered::set_data_partial(const Ref<Image> &p_image, int p_x_ofs, int p_y_ofs, int p_z, int p_mipmap) {
+ ERR_FAIL_COND(!texture.is_valid());
+ VS::get_singleton()->texture_set_data_partial(texture, p_image, 0, 0, p_image->get_width(), p_image->get_height(), p_x_ofs, p_y_ofs, p_mipmap, p_z);
+}
+
+RID TextureLayered::get_rid() const {
+ return texture;
+}
+
+void TextureLayered::set_path(const String &p_path, bool p_take_over) {
+ if (texture.is_valid()) {
+ VS::get_singleton()->texture_set_path(texture, p_path);
+ }
+
+ Resource::set_path(p_path, p_take_over);
+}
+
+void TextureLayered::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_flags", "flags"), &TextureLayered::set_flags);
+ ClassDB::bind_method(D_METHOD("get_flags"), &TextureLayered::get_flags);
+
+ ClassDB::bind_method(D_METHOD("get_format"), &TextureLayered::get_format);
+
+ ClassDB::bind_method(D_METHOD("get_width"), &TextureLayered::get_width);
+ ClassDB::bind_method(D_METHOD("get_height"), &TextureLayered::get_height);
+ ClassDB::bind_method(D_METHOD("get_depth"), &TextureLayered::get_depth);
+
+ ClassDB::bind_method(D_METHOD("create", "width", "height", "depth", "format", "flags"), &TextureLayered::create, DEFVAL(FLAGS_DEFAULT));
+ ClassDB::bind_method(D_METHOD("set_layer_data", "image", "layer"), &TextureLayered::set_layer_data);
+ ClassDB::bind_method(D_METHOD("get_layer_data", "layer"), &TextureLayered::get_layer_data);
+ ClassDB::bind_method(D_METHOD("set_data_partial", "image", "x_offset", "y_offset", "layer", "mipmap"), &TextureLayered::set_data_partial, DEFVAL(0));
+
+ ClassDB::bind_method(D_METHOD("_set_data", "data"), &TextureLayered::_set_data);
+ ClassDB::bind_method(D_METHOD("_get_data"), &TextureLayered::_get_data);
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, "Mipmaps,Repeat,Filter"), "set_flags", "get_flags");
+ ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_data", "_get_data");
+
+ BIND_ENUM_CONSTANT(FLAG_MIPMAPS);
+ BIND_ENUM_CONSTANT(FLAG_REPEAT);
+ BIND_ENUM_CONSTANT(FLAG_FILTER);
+ BIND_ENUM_CONSTANT(FLAGS_DEFAULT);
+}
+
+TextureLayered::TextureLayered(bool p_3d) {
+ is_3d = p_3d;
+ format = Image::FORMAT_MAX;
+ flags = FLAGS_DEFAULT;
+
+ width = 0;
+ height = 0;
+ depth = 0;
+
+ texture = VS::get_singleton()->texture_create();
+}
+
+TextureLayered::~TextureLayered() {
+ if (texture.is_valid()) {
+ VS::get_singleton()->free(texture);
+ }
+}
+
+RES ResourceFormatLoaderTextureLayered::load(const String &p_path, const String &p_original_path, Error *r_error) {
+
+ if (r_error) {
+ *r_error = ERR_CANT_OPEN;
+ }
+
+ Ref<TextureLayered> lt;
+ Ref<Texture3D> tex3d;
+ Ref<TextureArray> texarr;
+
+ if (p_path.ends_with("tex3d")) {
+ tex3d.instance();
+ lt = tex3d;
+ } else if (p_path.ends_with("texarr")) {
+ texarr.instance();
+ lt = texarr;
+ } else {
+ ERR_EXPLAIN("Unrecognized layered texture extension");
+ ERR_FAIL_V(RES());
+ }
+
+ FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
+ ERR_FAIL_COND_V(!f, RES());
+
+ uint8_t header[5] = { 0, 0, 0, 0, 0 };
+ f->get_buffer(header, 4);
+
+ if (header[0] == 'G' && header[1] == 'D' && header[2] == '3' && header[3] == 'T') {
+ if (tex3d.is_null()) {
+ memdelete(f);
+ ERR_FAIL_COND_V(tex3d.is_null(), RES())
+ }
+ } else if (header[0] == 'G' && header[1] == 'D' && header[2] == 'A' && header[3] == 'T') {
+ if (texarr.is_null()) {
+ memdelete(f);
+ ERR_FAIL_COND_V(texarr.is_null(), RES())
+ }
+ } else {
+
+ ERR_EXPLAIN("Unrecognized layered texture file format: " + String((const char *)header));
+ ERR_FAIL_V(RES());
+ }
+
+ int tw = f->get_32();
+ int th = f->get_32();
+ int td = f->get_32();
+ int flags = f->get_32(); //texture flags!
+ Image::Format format = Image::Format(f->get_32());
+ uint32_t compression = f->get_32(); // 0 - lossless (PNG), 1 - vram, 2 - uncompressed
+
+ lt->create(tw, th, td, format, flags);
+
+ for (int layer = 0; layer < td; layer++) {
+
+ Ref<Image> image;
+ image.instance();
+
+ if (compression == COMPRESSION_LOSSLESS) {
+ //look for a PNG file inside
+
+ int mipmaps = f->get_32();
+ Vector<Ref<Image> > mipmap_images;
+
+ for (int i = 0; i < mipmaps; i++) {
+ uint32_t size = f->get_32();
+
+ PoolVector<uint8_t> pv;
+ pv.resize(size);
+ {
+ PoolVector<uint8_t>::Write w = pv.write();
+ f->get_buffer(w.ptr(), size);
+ }
+
+ Ref<Image> img = Image::lossless_unpacker(pv);
+
+ if (img.is_null() || img->empty() || format != img->get_format()) {
+ if (r_error) {
+ *r_error = ERR_FILE_CORRUPT;
+ }
+ memdelete(f);
+ ERR_FAIL_V(RES());
+ }
+
+ mipmap_images.push_back(img);
+ }
+
+ if (mipmap_images.size() == 1) {
+
+ image = mipmap_images[0];
+
+ } else {
+ int total_size = Image::get_image_data_size(tw, th, format, true);
+ PoolVector<uint8_t> img_data;
+ img_data.resize(total_size);
+
+ {
+ PoolVector<uint8_t>::Write w = img_data.write();
+
+ int ofs = 0;
+ for (int i = 0; i < mipmap_images.size(); i++) {
+
+ PoolVector<uint8_t> id = mipmap_images[i]->get_data();
+ int len = id.size();
+ PoolVector<uint8_t>::Read r = id.read();
+ copymem(&w[ofs], r.ptr(), len);
+ ofs += len;
+ }
+ }
+
+ image->create(tw, th, true, format, img_data);
+ if (image->empty()) {
+ if (r_error) {
+ *r_error = ERR_FILE_CORRUPT;
+ }
+ memdelete(f);
+ ERR_FAIL_V(RES());
+ }
+ }
+
+ } else {
+
+ //look for regular format
+ bool mipmaps = (flags & Texture::FLAG_MIPMAPS);
+ int total_size = Image::get_image_data_size(tw, th, format, mipmaps);
+
+ PoolVector<uint8_t> img_data;
+ img_data.resize(total_size);
+
+ {
+ PoolVector<uint8_t>::Write w = img_data.write();
+ int bytes = f->get_buffer(w.ptr(), total_size);
+ if (bytes != total_size) {
+ if (r_error) {
+ *r_error = ERR_FILE_CORRUPT;
+ memdelete(f);
+ }
+ ERR_FAIL_V(RES());
+ }
+ }
+
+ image->create(tw, th, mipmaps, format, img_data);
+ }
+
+ lt->set_layer_data(image, layer);
+ }
+
+ if (r_error)
+ *r_error = OK;
+
+ return lt;
+}
+
+void ResourceFormatLoaderTextureLayered::get_recognized_extensions(List<String> *p_extensions) const {
+
+ p_extensions->push_back("tex3d");
+ p_extensions->push_back("texarr");
+}
+bool ResourceFormatLoaderTextureLayered::handles_type(const String &p_type) const {
+ return p_type == "Texture3D" || p_type == "TextureArray";
+}
+String ResourceFormatLoaderTextureLayered::get_resource_type(const String &p_path) const {
+
+ if (p_path.get_extension().to_lower() == "tex3d")
+ return "Texture3D";
+ if (p_path.get_extension().to_lower() == "texarr")
+ return "TextureArray";
+ return "";
+}
diff --git a/scene/resources/texture.h b/scene/resources/texture.h
index d81fd3b19b..b02cbb8fa8 100644
--- a/scene/resources/texture.h
+++ b/scene/resources/texture.h
@@ -33,11 +33,13 @@
#include "curve.h"
#include "io/resource_loader.h"
-#include "math_2d.h"
+#include "os/mutex.h"
+#include "os/rw_lock.h"
+#include "os/thread_safe.h"
+#include "rect2.h"
#include "resource.h"
#include "scene/resources/color_ramp.h"
#include "servers/visual_server.h"
-
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
@@ -124,7 +126,9 @@ public:
void set_flags(uint32_t p_flags);
uint32_t get_flags() const;
Image::Format get_format() const;
+#ifndef DISABLE_DEPRECATED
Error load(const String &p_path);
+#endif
void set_data(const Ref<Image> &p_image);
Ref<Image> get_data() const;
@@ -400,6 +404,88 @@ VARIANT_ENUM_CAST(CubeMap::Flags)
VARIANT_ENUM_CAST(CubeMap::Side)
VARIANT_ENUM_CAST(CubeMap::Storage)
+class TextureLayered : public Resource {
+
+ GDCLASS(TextureLayered, Resource)
+
+public:
+ enum Flags {
+ FLAG_MIPMAPS = VisualServer::TEXTURE_FLAG_MIPMAPS,
+ FLAG_REPEAT = VisualServer::TEXTURE_FLAG_REPEAT,
+ FLAG_FILTER = VisualServer::TEXTURE_FLAG_FILTER,
+ FLAG_CONVERT_TO_LINEAR = VisualServer::TEXTURE_FLAG_CONVERT_TO_LINEAR,
+ FLAGS_DEFAULT = FLAG_FILTER,
+ };
+
+private:
+ bool is_3d;
+ RID texture;
+ Image::Format format;
+ uint32_t flags;
+
+ int width;
+ int height;
+ int depth;
+
+ void _set_data(const Dictionary &p_data);
+ Dictionary _get_data() const;
+
+protected:
+ static void _bind_methods();
+
+public:
+ void set_flags(uint32_t p_flags);
+ uint32_t get_flags() const;
+
+ Image::Format get_format() const;
+ uint32_t get_width() const;
+ uint32_t get_height() const;
+ uint32_t get_depth() const;
+
+ void create(uint32_t p_width, uint32_t p_height, uint32_t p_depth, Image::Format p_format, uint32_t p_flags = FLAGS_DEFAULT);
+ void set_layer_data(const Ref<Image> &p_image, int p_layer);
+ Ref<Image> get_layer_data(int p_layer) const;
+ void set_data_partial(const Ref<Image> &p_image, int p_x_ofs, int p_y_ofs, int p_z, int p_mipmap = 0);
+
+ virtual RID get_rid() const;
+ virtual void set_path(const String &p_path, bool p_take_over = false);
+
+ TextureLayered(bool p_3d = false);
+ ~TextureLayered();
+};
+
+VARIANT_ENUM_CAST(TextureLayered::Flags)
+
+class Texture3D : public TextureLayered {
+
+ GDCLASS(Texture3D, TextureLayered)
+public:
+ Texture3D() :
+ TextureLayered(true) {}
+};
+
+class TextureArray : public TextureLayered {
+
+ GDCLASS(TextureArray, TextureLayered)
+public:
+ TextureArray() :
+ TextureLayered(false) {}
+};
+
+class ResourceFormatLoaderTextureLayered : public ResourceFormatLoader {
+public:
+ enum Compression {
+ COMPRESSION_LOSSLESS,
+ COMPRESSION_VRAM,
+ COMPRESSION_UNCOMPRESSED
+ };
+
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
+ virtual void get_recognized_extensions(List<String> *p_extensions) const;
+ virtual bool handles_type(const String &p_type) const;
+ virtual String get_resource_type(const String &p_path) const;
+};
+
class CurveTexture : public Texture {
GDCLASS(CurveTexture, Texture)
@@ -521,4 +607,71 @@ public:
~ProxyTexture();
};
+class AnimatedTexture : public Texture {
+ GDCLASS(AnimatedTexture, Texture)
+
+ //use readers writers lock for this, since its far more times read than written to
+ RWLock *rw_lock;
+
+private:
+ enum {
+ MAX_FRAMES = 256
+ };
+
+ RID proxy;
+
+ struct Frame {
+
+ Ref<Texture> texture;
+ float delay_sec;
+
+ Frame() {
+ delay_sec = 0;
+ }
+ };
+
+ Frame frames[MAX_FRAMES];
+ int frame_count;
+ int current_frame;
+
+ float fps;
+
+ float time;
+
+ uint64_t prev_ticks;
+
+ void _update_proxy();
+
+protected:
+ static void _bind_methods();
+ void _validate_property(PropertyInfo &property) const;
+
+public:
+ void set_frames(int p_frames);
+ int get_frames() const;
+
+ void set_frame_texture(int p_frame, const Ref<Texture> &p_texture);
+ Ref<Texture> get_frame_texture(int p_frame) const;
+
+ void set_frame_delay(int p_frame, float p_delay_sec);
+ float get_frame_delay(int p_frame) const;
+
+ void set_fps(float p_fps);
+ float get_fps() const;
+
+ virtual int get_width() const;
+ virtual int get_height() const;
+ virtual RID get_rid() const;
+
+ virtual bool has_alpha() const;
+
+ virtual void set_flags(uint32_t p_flags);
+ virtual uint32_t get_flags() const;
+
+ virtual Ref<Image> get_data() const;
+
+ AnimatedTexture();
+ ~AnimatedTexture();
+};
+
#endif
diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp
index 58057cda0c..3d2b6c36de 100644
--- a/scene/resources/tile_set.cpp
+++ b/scene/resources/tile_set.cpp
@@ -262,7 +262,7 @@ void TileSet::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::OBJECT, pre + "material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial"));
p_list->push_back(PropertyInfo(Variant::COLOR, pre + "modulate"));
p_list->push_back(PropertyInfo(Variant::RECT2, pre + "region"));
- p_list->push_back(PropertyInfo(Variant::INT, pre + "tile_mode", PROPERTY_HINT_ENUM, "SINGLE_TILE,AUTO_TILE"));
+ p_list->push_back(PropertyInfo(Variant::INT, pre + "tile_mode", PROPERTY_HINT_ENUM, "SINGLE_TILE,AUTO_TILE,ATLAS_TILE"));
if (tile_get_tile_mode(id) == AUTO_TILE) {
p_list->push_back(PropertyInfo(Variant::INT, pre + "autotile/bitmask_mode", PROPERTY_HINT_ENUM, "2X2,3X3 (minimal),3X3", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "autotile/bitmask_flags", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
@@ -272,6 +272,12 @@ void TileSet::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "autotile/occluder_map", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "autotile/navpoly_map", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "autotile/priority_map", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
+ } else if (tile_get_tile_mode(id) == ATLAS_TILE) {
+ p_list->push_back(PropertyInfo(Variant::VECTOR2, pre + "autotile/icon_coordinate", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
+ p_list->push_back(PropertyInfo(Variant::VECTOR2, pre + "autotile/tile_size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
+ p_list->push_back(PropertyInfo(Variant::INT, pre + "autotile/spacing", PROPERTY_HINT_RANGE, "0,256,1", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
+ p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "autotile/occluder_map", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
+ p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "autotile/navpoly_map", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
}
p_list->push_back(PropertyInfo(Variant::VECTOR2, pre + "occluder_offset"));
p_list->push_back(PropertyInfo(Variant::OBJECT, pre + "occluder", PROPERTY_HINT_RESOURCE_TYPE, "OccluderPolygon2D"));
@@ -494,8 +500,21 @@ uint16_t TileSet::autotile_get_bitmask(int p_id, Vector2 p_coord) {
const Map<Vector2, uint16_t> &TileSet::autotile_get_bitmask_map(int p_id) {
static Map<Vector2, uint16_t> dummy;
+ static Map<Vector2, uint16_t> dummy_atlas;
ERR_FAIL_COND_V(!tile_map.has(p_id), dummy);
- return tile_map[p_id].autotile_data.flags;
+ if (tile_get_tile_mode(p_id) == ATLAS_TILE) {
+ dummy_atlas = Map<Vector2, uint16_t>();
+ Rect2 region = tile_get_region(p_id);
+ Size2 size = autotile_get_size(p_id);
+ float spacing = autotile_get_spacing(p_id);
+ for (int x = 0; x < (region.size.x / (size.x + spacing)); x++) {
+ for (int y = 0; y < (region.size.y / (size.y + spacing)); y++) {
+ dummy_atlas.insert(Vector2(x, y), 0);
+ }
+ }
+ return dummy_atlas;
+ } else
+ return tile_map[p_id].autotile_data.flags;
}
Vector2 TileSet::autotile_get_subtile_for_bitmask(int p_id, uint16_t p_bitmask, const Node *p_tilemap_node, const Vector2 &p_tile_location) {
@@ -576,7 +595,7 @@ void TileSet::tile_set_shape(int p_id, int p_shape_id, const Ref<Shape2D> &p_sha
ERR_FAIL_COND(!tile_map.has(p_id));
if (tile_map[p_id].shapes_data.size() <= p_shape_id)
tile_map[p_id].shapes_data.resize(p_shape_id + 1);
- tile_map[p_id].shapes_data[p_shape_id].shape = p_shape;
+ tile_map[p_id].shapes_data.write[p_shape_id].shape = p_shape;
emit_changed();
}
@@ -594,7 +613,7 @@ void TileSet::tile_set_shape_transform(int p_id, int p_shape_id, const Transform
ERR_FAIL_COND(!tile_map.has(p_id));
if (tile_map[p_id].shapes_data.size() <= p_shape_id)
tile_map[p_id].shapes_data.resize(p_shape_id + 1);
- tile_map[p_id].shapes_data[p_shape_id].shape_transform = p_offset;
+ tile_map[p_id].shapes_data.write[p_shape_id].shape_transform = p_offset;
emit_changed();
}
@@ -622,7 +641,7 @@ void TileSet::tile_set_shape_one_way(int p_id, int p_shape_id, const bool p_one_
ERR_FAIL_COND(!tile_map.has(p_id));
if (tile_map[p_id].shapes_data.size() <= p_shape_id)
tile_map[p_id].shapes_data.resize(p_shape_id + 1);
- tile_map[p_id].shapes_data[p_shape_id].one_way_collision = p_one_way;
+ tile_map[p_id].shapes_data.write[p_shape_id].one_way_collision = p_one_way;
emit_changed();
}
@@ -923,6 +942,8 @@ void TileSet::_bind_methods() {
ClassDB::bind_method(D_METHOD("tile_get_normal_map", "id"), &TileSet::tile_get_normal_map);
ClassDB::bind_method(D_METHOD("tile_set_material", "id", "material"), &TileSet::tile_set_material);
ClassDB::bind_method(D_METHOD("tile_get_material", "id"), &TileSet::tile_get_material);
+ ClassDB::bind_method(D_METHOD("tile_set_modulate", "id", "color"), &TileSet::tile_set_modulate);
+ ClassDB::bind_method(D_METHOD("tile_get_modulate", "id"), &TileSet::tile_get_modulate);
ClassDB::bind_method(D_METHOD("tile_set_texture_offset", "id", "texture_offset"), &TileSet::tile_set_texture_offset);
ClassDB::bind_method(D_METHOD("tile_get_texture_offset", "id"), &TileSet::tile_get_texture_offset);
ClassDB::bind_method(D_METHOD("tile_set_region", "id", "region"), &TileSet::tile_set_region);
@@ -974,7 +995,7 @@ void TileSet::_bind_methods() {
BIND_ENUM_CONSTANT(SINGLE_TILE);
BIND_ENUM_CONSTANT(AUTO_TILE);
- BIND_ENUM_CONSTANT(ANIMATED_TILE);
+ BIND_ENUM_CONSTANT(ATLAS_TILE);
}
TileSet::TileSet() {
diff --git a/scene/resources/tile_set.h b/scene/resources/tile_set.h
index ec635ee5cc..40eee2700d 100644
--- a/scene/resources/tile_set.h
+++ b/scene/resources/tile_set.h
@@ -75,7 +75,7 @@ public:
enum TileMode {
SINGLE_TILE,
AUTO_TILE,
- ANIMATED_TILE
+ ATLAS_TILE
};
struct AutotileData {
diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp
new file mode 100644
index 0000000000..d8fc3677fb
--- /dev/null
+++ b/scene/resources/visual_shader.cpp
@@ -0,0 +1,1555 @@
+#include "visual_shader.h"
+#include "servers/visual/shader_types.h"
+#include "vmap.h"
+
+void VisualShaderNode::set_output_port_for_preview(int p_index) {
+
+ port_preview = p_index;
+}
+
+int VisualShaderNode::get_output_port_for_preview() const {
+
+ return port_preview;
+}
+
+void VisualShaderNode::set_input_port_default_value(int p_port, const Variant &p_value) {
+ default_input_values[p_port] = p_value;
+ emit_changed();
+}
+
+Variant VisualShaderNode::get_input_port_default_value(int p_port) const {
+ if (default_input_values.has(p_port)) {
+ return default_input_values[p_port];
+ }
+
+ return Variant();
+}
+
+bool VisualShaderNode::is_port_separator(int p_index) const {
+ return false;
+}
+
+Vector<VisualShader::DefaultTextureParam> VisualShaderNode::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const {
+ return Vector<VisualShader::DefaultTextureParam>();
+}
+String VisualShaderNode::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
+ return String();
+}
+
+Vector<StringName> VisualShaderNode::get_editable_properties() const {
+ return Vector<StringName>();
+}
+
+Array VisualShaderNode::_get_default_input_values() const {
+
+ Array ret;
+ for (Map<int, Variant>::Element *E = default_input_values.front(); E; E = E->next()) {
+ ret.push_back(E->key());
+ ret.push_back(E->get());
+ }
+ return ret;
+}
+void VisualShaderNode::_set_default_input_values(const Array &p_values) {
+
+ if (p_values.size() % 2 == 0) {
+ for (int i = 0; i < p_values.size(); i += 2) {
+ default_input_values[p_values[i + 0]] = p_values[i + 1];
+ }
+ }
+
+ emit_changed();
+}
+
+String VisualShaderNode::get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const {
+ return String();
+}
+
+void VisualShaderNode::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_output_port_for_preview", "port"), &VisualShaderNode::set_output_port_for_preview);
+ ClassDB::bind_method(D_METHOD("get_output_port_for_preview"), &VisualShaderNode::get_output_port_for_preview);
+
+ ClassDB::bind_method(D_METHOD("set_input_port_default_value", "port", "value"), &VisualShaderNode::set_input_port_default_value);
+ ClassDB::bind_method(D_METHOD("get_input_port_default_value", "port"), &VisualShaderNode::get_input_port_default_value);
+
+ ClassDB::bind_method(D_METHOD("_set_default_input_values", "values"), &VisualShaderNode::_set_default_input_values);
+ ClassDB::bind_method(D_METHOD("_get_default_input_values"), &VisualShaderNode::_get_default_input_values);
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "output_port_for_preview"), "set_output_port_for_preview", "get_output_port_for_preview");
+ ADD_PROPERTYNZ(PropertyInfo(Variant::ARRAY, "default_input_values", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_default_input_values", "_get_default_input_values");
+ ADD_SIGNAL(MethodInfo("editor_refresh_request"));
+}
+
+VisualShaderNode::VisualShaderNode() {
+ port_preview = -1;
+}
+
+/////////////////////////////////////////////////////////
+
+void VisualShader::add_node(Type p_type, const Ref<VisualShaderNode> &p_node, const Vector2 &p_position, int p_id) {
+ ERR_FAIL_COND(p_node.is_null());
+ ERR_FAIL_COND(p_id < 2);
+ ERR_FAIL_INDEX(p_type, TYPE_MAX);
+ Graph *g = &graph[p_type];
+ ERR_FAIL_COND(g->nodes.has(p_id));
+ Node n;
+ n.node = p_node;
+ n.position = p_position;
+
+ Ref<VisualShaderNodeUniform> uniform = n.node;
+ if (uniform.is_valid()) {
+ String valid_name = validate_uniform_name(uniform->get_uniform_name(), uniform);
+ uniform->set_uniform_name(valid_name);
+ }
+
+ Ref<VisualShaderNodeInput> input = n.node;
+ if (input.is_valid()) {
+ input->shader_mode = shader_mode;
+ input->shader_type = p_type;
+ input->connect("input_type_changed", this, "_input_type_changed", varray(p_type, p_id));
+ }
+
+ n.node->connect("changed", this, "_queue_update");
+
+ g->nodes[p_id] = n;
+
+ _queue_update();
+}
+
+void VisualShader::set_node_position(Type p_type, int p_id, const Vector2 &p_position) {
+ ERR_FAIL_INDEX(p_type, TYPE_MAX);
+ Graph *g = &graph[p_type];
+ ERR_FAIL_COND(!g->nodes.has(p_id));
+ g->nodes[p_id].position = p_position;
+}
+
+Vector2 VisualShader::get_node_position(Type p_type, int p_id) const {
+ ERR_FAIL_INDEX_V(p_type, TYPE_MAX, Vector2());
+ const Graph *g = &graph[p_type];
+ ERR_FAIL_COND_V(!g->nodes.has(p_id), Vector2());
+ return g->nodes[p_id].position;
+}
+Ref<VisualShaderNode> VisualShader::get_node(Type p_type, int p_id) const {
+ ERR_FAIL_INDEX_V(p_type, TYPE_MAX, Ref<VisualShaderNode>());
+ const Graph *g = &graph[p_type];
+ ERR_FAIL_COND_V(!g->nodes.has(p_id), Ref<VisualShaderNode>());
+ return g->nodes[p_id].node;
+}
+
+Vector<int> VisualShader::get_node_list(Type p_type) const {
+ ERR_FAIL_INDEX_V(p_type, TYPE_MAX, Vector<int>());
+ const Graph *g = &graph[p_type];
+
+ Vector<int> ret;
+ for (Map<int, Node>::Element *E = g->nodes.front(); E; E = E->next()) {
+ ret.push_back(E->key());
+ }
+
+ return ret;
+}
+int VisualShader::get_valid_node_id(Type p_type) const {
+ ERR_FAIL_INDEX_V(p_type, TYPE_MAX, NODE_ID_INVALID);
+ const Graph *g = &graph[p_type];
+ return g->nodes.size() ? MAX(2, g->nodes.back()->key() + 1) : 2;
+}
+
+int VisualShader::find_node_id(Type p_type, const Ref<VisualShaderNode> &p_node) const {
+ for (const Map<int, Node>::Element *E = graph[p_type].nodes.front(); E; E = E->next()) {
+ if (E->get().node == p_node)
+ return E->key();
+ }
+
+ return NODE_ID_INVALID;
+}
+
+void VisualShader::remove_node(Type p_type, int p_id) {
+ ERR_FAIL_INDEX(p_type, TYPE_MAX);
+ ERR_FAIL_COND(p_id < 2);
+ Graph *g = &graph[p_type];
+ ERR_FAIL_COND(!g->nodes.has(p_id));
+
+ Ref<VisualShaderNodeInput> input = g->nodes[p_id].node;
+ if (input.is_valid()) {
+ input->disconnect("input_type_changed", this, "_input_type_changed");
+ }
+
+ g->nodes[p_id].node->disconnect("changed", this, "_queue_update");
+
+ g->nodes.erase(p_id);
+
+ for (List<Connection>::Element *E = g->connections.front(); E;) {
+ List<Connection>::Element *N = E->next();
+ if (E->get().from_node == p_id || E->get().to_node == p_id) {
+ g->connections.erase(E);
+ }
+ E = N;
+ }
+
+ _queue_update();
+}
+
+bool VisualShader::is_node_connection(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) const {
+ ERR_FAIL_INDEX_V(p_type, TYPE_MAX, false);
+ const Graph *g = &graph[p_type];
+
+ for (const List<Connection>::Element *E = g->connections.front(); E; E = E->next()) {
+
+ if (E->get().from_node == p_from_node && E->get().from_port == p_from_port && E->get().to_node == p_to_node && E->get().to_port == p_to_port) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool VisualShader::can_connect_nodes(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) const {
+
+ ERR_FAIL_INDEX_V(p_type, TYPE_MAX, false);
+ const Graph *g = &graph[p_type];
+
+ if (!g->nodes.has(p_from_node))
+ return false;
+
+ if (p_from_port < 0 || p_from_port >= g->nodes[p_from_node].node->get_output_port_count())
+ return false;
+
+ if (!g->nodes.has(p_to_node))
+ return false;
+
+ if (p_to_port < 0 || p_to_port >= g->nodes[p_to_node].node->get_input_port_count())
+ return false;
+
+ VisualShaderNode::PortType from_port_type = g->nodes[p_from_node].node->get_output_port_type(p_from_port);
+ VisualShaderNode::PortType to_port_type = g->nodes[p_to_node].node->get_input_port_type(p_to_port);
+
+ if (MAX(0, from_port_type - 1) != (MAX(0, to_port_type - 1))) {
+ return false;
+ }
+
+ for (const List<Connection>::Element *E = g->connections.front(); E; E = E->next()) {
+
+ if (E->get().from_node == p_from_node && E->get().from_port == p_from_port && E->get().to_node == p_to_node && E->get().to_port == p_to_port) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+Error VisualShader::connect_nodes(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) {
+ ERR_FAIL_INDEX_V(p_type, TYPE_MAX, ERR_CANT_CONNECT);
+ Graph *g = &graph[p_type];
+
+ ERR_FAIL_COND_V(!g->nodes.has(p_from_node), ERR_INVALID_PARAMETER);
+ ERR_FAIL_INDEX_V(p_from_port, g->nodes[p_from_node].node->get_output_port_count(), ERR_INVALID_PARAMETER);
+ ERR_FAIL_COND_V(!g->nodes.has(p_to_node), ERR_INVALID_PARAMETER);
+ ERR_FAIL_INDEX_V(p_to_port, g->nodes[p_to_node].node->get_input_port_count(), ERR_INVALID_PARAMETER);
+
+ VisualShaderNode::PortType from_port_type = g->nodes[p_from_node].node->get_output_port_type(p_from_port);
+ VisualShaderNode::PortType to_port_type = g->nodes[p_to_node].node->get_input_port_type(p_to_port);
+
+ if (MAX(0, from_port_type - 1) != (MAX(0, to_port_type - 1))) {
+ ERR_EXPLAIN("Incompatible port types (scalar/vec with transform");
+ ERR_FAIL_V(ERR_INVALID_PARAMETER)
+ return ERR_INVALID_PARAMETER;
+ }
+
+ for (List<Connection>::Element *E = g->connections.front(); E; E = E->next()) {
+
+ if (E->get().from_node == p_from_node && E->get().from_port == p_from_port && E->get().to_node == p_to_node && E->get().to_port == p_to_port) {
+ ERR_FAIL_V(ERR_ALREADY_EXISTS);
+ }
+ }
+
+ Connection c;
+ c.from_node = p_from_node;
+ c.from_port = p_from_port;
+ c.to_node = p_to_node;
+ c.to_port = p_to_port;
+ g->connections.push_back(c);
+
+ _queue_update();
+ return OK;
+}
+void VisualShader::disconnect_nodes(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) {
+ ERR_FAIL_INDEX(p_type, TYPE_MAX);
+ Graph *g = &graph[p_type];
+
+ for (List<Connection>::Element *E = g->connections.front(); E; E = E->next()) {
+
+ if (E->get().from_node == p_from_node && E->get().from_port == p_from_port && E->get().to_node == p_to_node && E->get().to_port == p_to_port) {
+ g->connections.erase(E);
+ _queue_update();
+ return;
+ }
+ }
+}
+
+Array VisualShader::_get_node_connections(Type p_type) const {
+ ERR_FAIL_INDEX_V(p_type, TYPE_MAX, Array());
+ const Graph *g = &graph[p_type];
+
+ Array ret;
+ for (const List<Connection>::Element *E = g->connections.front(); E; E = E->next()) {
+ Dictionary d;
+ d["from_node"] = E->get().from_node;
+ d["from_port"] = E->get().from_port;
+ d["to_node"] = E->get().to_node;
+ d["to_port"] = E->get().to_port;
+ ret.push_back(d);
+ }
+
+ return ret;
+}
+void VisualShader::get_node_connections(Type p_type, List<Connection> *r_connections) const {
+ ERR_FAIL_INDEX(p_type, TYPE_MAX);
+ const Graph *g = &graph[p_type];
+
+ for (const List<Connection>::Element *E = g->connections.front(); E; E = E->next()) {
+ r_connections->push_back(E->get());
+ }
+}
+
+void VisualShader::set_mode(Mode p_mode) {
+ if (shader_mode == p_mode) {
+ return;
+ }
+
+ //erase input/output connections
+ modes.clear();
+ flags.clear();
+ shader_mode = p_mode;
+ for (int i = 0; i < TYPE_MAX; i++) {
+
+ for (Map<int, Node>::Element *E = graph[i].nodes.front(); E; E = E->next()) {
+
+ Ref<VisualShaderNodeInput> input = E->get().node;
+ if (input.is_valid()) {
+ input->shader_mode = shader_mode;
+ //input->input_index = 0;
+ }
+ }
+
+ Ref<VisualShaderNodeOutput> output = graph[i].nodes[NODE_ID_OUTPUT].node;
+ output->shader_mode = shader_mode;
+
+ // clear connections since they are no longer valid
+ for (List<Connection>::Element *E = graph[i].connections.front(); E;) {
+
+ bool keep = true;
+
+ List<Connection>::Element *N = E->next();
+
+ int from = E->get().from_node;
+ int to = E->get().to_node;
+
+ if (!graph[i].nodes.has(from)) {
+ keep = false;
+ } else {
+ Ref<VisualShaderNode> from_node = graph[i].nodes[from].node;
+ if (from_node->is_class("VisualShaderNodeOutput") || from_node->is_class("VisualShaderNodeInput")) {
+ keep = false;
+ }
+ }
+
+ if (!graph[i].nodes.has(to)) {
+ keep = false;
+ } else {
+ Ref<VisualShaderNode> to_node = graph[i].nodes[to].node;
+ if (to_node->is_class("VisualShaderNodeOutput") || to_node->is_class("VisualShaderNodeInput")) {
+ keep = false;
+ }
+ }
+
+ if (!keep) {
+ graph[i].connections.erase(E);
+ }
+ E = N;
+ }
+ }
+
+ _queue_update();
+ _change_notify();
+}
+
+void VisualShader::set_graph_offset(const Vector2 &p_offset) {
+ graph_offset = p_offset;
+}
+
+Vector2 VisualShader::get_graph_offset() const {
+ return graph_offset;
+}
+
+Shader::Mode VisualShader::get_mode() const {
+ return shader_mode;
+}
+
+String VisualShader::generate_preview_shader(Type p_type, int p_node, int p_port, Vector<DefaultTextureParam> &default_tex_params) const {
+
+ Ref<VisualShaderNode> node = get_node(p_type, p_node);
+ ERR_FAIL_COND_V(!node.is_valid(), String());
+ ERR_FAIL_COND_V(p_port < 0 || p_port >= node->get_output_port_count(), String());
+ ERR_FAIL_COND_V(node->get_output_port_type(p_port) == VisualShaderNode::PORT_TYPE_TRANSFORM, String());
+
+ StringBuilder global_code;
+ StringBuilder code;
+
+ global_code += String() + "shader_type canvas_item;\n";
+
+ //make it faster to go around through shader
+ VMap<ConnectionKey, const List<Connection>::Element *> input_connections;
+ VMap<ConnectionKey, const List<Connection>::Element *> output_connections;
+
+ for (const List<Connection>::Element *E = graph[p_type].connections.front(); E; E = E->next()) {
+ ConnectionKey from_key;
+ from_key.node = E->get().from_node;
+ from_key.port = E->get().from_port;
+
+ output_connections.insert(from_key, E);
+
+ ConnectionKey to_key;
+ to_key.node = E->get().to_node;
+ to_key.port = E->get().to_port;
+
+ input_connections.insert(to_key, E);
+ }
+
+ code += "\nvoid fragment() {\n";
+
+ Set<int> processed;
+ Error err = _write_node(p_type, global_code, code, default_tex_params, input_connections, output_connections, p_node, processed, true);
+ ERR_FAIL_COND_V(err != OK, String());
+
+ if (node->get_output_port_type(p_port) == VisualShaderNode::PORT_TYPE_SCALAR) {
+ code += "\tCOLOR.rgb = vec3( n_out" + itos(p_node) + "p" + itos(p_port) + " );\n";
+ } else {
+ code += "\tCOLOR.rgb = n_out" + itos(p_node) + "p" + itos(p_port) + ";\n";
+ }
+ code += "}\n";
+
+ //set code secretly
+ global_code += "\n\n";
+ String final_code = global_code;
+ final_code += code;
+ //print_line(final_code);
+ return final_code;
+}
+
+#define IS_INITIAL_CHAR(m_d) (((m_d) >= 'a' && (m_d) <= 'z') || ((m_d) >= 'A' && (m_d) <= 'Z'))
+
+#define IS_SYMBOL_CHAR(m_d) (((m_d) >= 'a' && (m_d) <= 'z') || ((m_d) >= 'A' && (m_d) <= 'Z') || ((m_d) >= '0' && (m_d) <= '9') || (m_d) == '_')
+
+String VisualShader::validate_uniform_name(const String &p_name, const Ref<VisualShaderNodeUniform> &p_uniform) const {
+
+ String name = p_name; //validate name first
+ while (name.length() && !IS_INITIAL_CHAR(name[0])) {
+ name = name.substr(1, name.length() - 1);
+ }
+ if (name != String()) {
+
+ String valid_name;
+
+ for (int i = 0; i < name.length(); i++) {
+ if (IS_SYMBOL_CHAR(name[i])) {
+ valid_name += String::chr(name[i]);
+ } else if (name[i] == ' ') {
+ valid_name += "_";
+ }
+ }
+
+ name = valid_name;
+ }
+
+ if (name == String()) {
+ name = p_uniform->get_caption();
+ }
+
+ int attempt = 1;
+
+ while (true) {
+
+ bool exists = false;
+ for (int i = 0; i < TYPE_MAX; i++) {
+ for (const Map<int, Node>::Element *E = graph[i].nodes.front(); E; E = E->next()) {
+ Ref<VisualShaderNodeUniform> node = E->get().node;
+ if (node == p_uniform) { //do not test on self
+ continue;
+ }
+ if (node.is_valid() && node->get_uniform_name() == name) {
+ exists = true;
+ break;
+ }
+ }
+ if (exists) {
+ break;
+ }
+ }
+
+ if (exists) {
+ //remove numbers, put new and try again
+ attempt++;
+ while (name.length() && name[name.length() - 1] >= '0' && name[name.length() - 1] <= '9') {
+ name = name.substr(0, name.length() - 1);
+ }
+ ERR_FAIL_COND_V(name == String(), String());
+ name += itos(attempt);
+ } else {
+ break;
+ }
+ }
+
+ return name;
+}
+
+VisualShader::RenderModeEnums VisualShader::render_mode_enums[] = {
+ { Shader::MODE_SPATIAL, "blend" },
+ { Shader::MODE_SPATIAL, "depth_draw" },
+ { Shader::MODE_SPATIAL, "cull" },
+ { Shader::MODE_SPATIAL, "diffuse" },
+ { Shader::MODE_SPATIAL, "specular" },
+ { Shader::MODE_CANVAS_ITEM, "blend" },
+ { Shader::MODE_CANVAS_ITEM, NULL }
+};
+
+static const char *type_string[VisualShader::TYPE_MAX] = {
+ "vertex",
+ "fragment",
+ "light"
+};
+bool VisualShader::_set(const StringName &p_name, const Variant &p_value) {
+
+ String name = p_name;
+ if (name == "mode") {
+ set_mode(Shader::Mode(int(p_value)));
+ return true;
+ } else if (name.begins_with("flags/")) {
+ StringName flag = name.get_slicec('/', 1);
+ bool enable = p_value;
+ if (enable) {
+ flags.insert(flag);
+ } else {
+ flags.erase(flag);
+ }
+ _queue_update();
+ return true;
+ } else if (name.begins_with("modes/")) {
+ String mode = name.get_slicec('/', 1);
+ int value = p_value;
+ if (value == 0) {
+ modes.erase(mode); //means its default anyway, so dont store it
+ } else {
+ modes[mode] = value;
+ }
+ _queue_update();
+ return true;
+ } else if (name.begins_with("nodes/")) {
+ String typestr = name.get_slicec('/', 1);
+ Type type = TYPE_VERTEX;
+ for (int i = 0; i < TYPE_MAX; i++) {
+ if (typestr == type_string[i]) {
+ type = Type(i);
+ break;
+ }
+ }
+
+ String index = name.get_slicec('/', 2);
+ if (index == "connections") {
+
+ Vector<int> conns = p_value;
+ if (conns.size() % 4 == 0) {
+ for (int i = 0; i < conns.size(); i += 4) {
+ connect_nodes(type, conns[i + 0], conns[i + 1], conns[i + 2], conns[i + 3]);
+ }
+ }
+ return true;
+ }
+
+ int id = index.to_int();
+ String what = name.get_slicec('/', 3);
+
+ if (what == "node") {
+ add_node(type, p_value, Vector2(), id);
+ return true;
+ } else if (what == "position") {
+ set_node_position(type, id, p_value);
+ return true;
+ }
+ }
+ return false;
+}
+
+bool VisualShader::_get(const StringName &p_name, Variant &r_ret) const {
+
+ String name = p_name;
+ if (name == "mode") {
+ r_ret = get_mode();
+ return true;
+ } else if (name.begins_with("flags/")) {
+ StringName flag = name.get_slicec('/', 1);
+ r_ret = flags.has(flag);
+ return true;
+ } else if (name.begins_with("modes/")) {
+ String mode = name.get_slicec('/', 1);
+ if (modes.has(mode)) {
+ r_ret = modes[mode];
+ } else {
+ r_ret = 0;
+ }
+ return true;
+ } else if (name.begins_with("nodes/")) {
+ String typestr = name.get_slicec('/', 1);
+ Type type = TYPE_VERTEX;
+ for (int i = 0; i < TYPE_MAX; i++) {
+ if (typestr == type_string[i]) {
+ type = Type(i);
+ break;
+ }
+ }
+
+ String index = name.get_slicec('/', 2);
+ if (index == "connections") {
+
+ Vector<int> conns;
+ for (const List<Connection>::Element *E = graph[type].connections.front(); E; E = E->next()) {
+ conns.push_back(E->get().from_node);
+ conns.push_back(E->get().from_port);
+ conns.push_back(E->get().to_node);
+ conns.push_back(E->get().to_port);
+ }
+
+ r_ret = conns;
+ return true;
+ }
+
+ int id = index.to_int();
+ String what = name.get_slicec('/', 3);
+
+ if (what == "node") {
+ r_ret = get_node(type, id);
+ return true;
+ } else if (what == "position") {
+ r_ret = get_node_position(type, id);
+ return true;
+ }
+ }
+ return false;
+}
+void VisualShader::_get_property_list(List<PropertyInfo> *p_list) const {
+
+ //mode
+ p_list->push_back(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Spatial,CanvasItem,Particles"));
+ //render modes
+
+ Map<String, String> blend_mode_enums;
+ Set<String> toggles;
+
+ for (int i = 0; i < ShaderTypes::get_singleton()->get_modes(VisualServer::ShaderMode(shader_mode)).size(); i++) {
+
+ String mode = ShaderTypes::get_singleton()->get_modes(VisualServer::ShaderMode(shader_mode))[i];
+ int idx = 0;
+ bool in_enum = false;
+ while (render_mode_enums[idx].string) {
+ if (mode.begins_with(render_mode_enums[idx].string)) {
+ String begin = render_mode_enums[idx].string;
+ String option = mode.replace_first(begin + "_", "");
+ if (!blend_mode_enums.has(begin)) {
+ blend_mode_enums[begin] = option;
+ } else {
+ blend_mode_enums[begin] += "," + option;
+ }
+ in_enum = true;
+ break;
+ }
+ idx++;
+ }
+
+ if (!in_enum) {
+ toggles.insert(mode);
+ }
+ }
+
+ for (Map<String, String>::Element *E = blend_mode_enums.front(); E; E = E->next()) {
+
+ p_list->push_back(PropertyInfo(Variant::INT, "modes/" + E->key(), PROPERTY_HINT_ENUM, E->get()));
+ }
+
+ for (Set<String>::Element *E = toggles.front(); E; E = E->next()) {
+ p_list->push_back(PropertyInfo(Variant::BOOL, "flags/" + E->get()));
+ }
+
+ for (int i = 0; i < TYPE_MAX; i++) {
+ for (Map<int, Node>::Element *E = graph[i].nodes.front(); E; E = E->next()) {
+
+ String prop_name = "nodes/";
+ prop_name += type_string[i];
+ prop_name += "/" + itos(E->key());
+
+ if (E->key() != NODE_ID_OUTPUT) {
+
+ p_list->push_back(PropertyInfo(Variant::OBJECT, prop_name + "/node", PROPERTY_HINT_RESOURCE_TYPE, "VisualShaderNode", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE));
+ }
+ p_list->push_back(PropertyInfo(Variant::VECTOR2, prop_name + "/position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ }
+ p_list->push_back(PropertyInfo(Variant::POOL_INT_ARRAY, "nodes/" + String(type_string[i]) + "/connections", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ }
+}
+
+Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBuilder &code, Vector<VisualShader::DefaultTextureParam> &def_tex_params, const VMap<ConnectionKey, const List<Connection>::Element *> &input_connections, const VMap<ConnectionKey, const List<Connection>::Element *> &output_connections, int node, Set<int> &processed, bool for_preview) const {
+
+ const Ref<VisualShaderNode> vsnode = graph[type].nodes[node].node;
+
+ //check inputs recursively first
+ int input_count = vsnode->get_input_port_count();
+ for (int i = 0; i < input_count; i++) {
+ ConnectionKey ck;
+ ck.node = node;
+ ck.port = i;
+
+ if (input_connections.has(ck)) {
+ int from_node = input_connections[ck]->get().from_node;
+ if (processed.has(from_node)) {
+ continue;
+ }
+
+ Error err = _write_node(type, global_code, code, def_tex_params, input_connections, output_connections, from_node, processed, for_preview);
+ if (err)
+ return err;
+ }
+ }
+
+ // then this node
+
+ code += "// " + vsnode->get_caption() + ":" + itos(node) + "\n";
+ Vector<String> input_vars;
+
+ input_vars.resize(vsnode->get_input_port_count());
+ String *inputs = input_vars.ptrw();
+
+ for (int i = 0; i < input_count; i++) {
+ ConnectionKey ck;
+ ck.node = node;
+ ck.port = i;
+
+ if (input_connections.has(ck)) {
+ //connected to something, use that output
+ int from_node = input_connections[ck]->get().from_node;
+ int from_port = input_connections[ck]->get().from_port;
+
+ VisualShaderNode::PortType in_type = vsnode->get_input_port_type(i);
+ VisualShaderNode::PortType out_type = graph[type].nodes[from_node].node->get_output_port_type(from_port);
+
+ String src_var = "n_out" + itos(from_node) + "p" + itos(from_port);
+
+ if (in_type == out_type) {
+ inputs[i] = src_var;
+ } else if (in_type == VisualShaderNode::PORT_TYPE_SCALAR && out_type == VisualShaderNode::PORT_TYPE_VECTOR) {
+ inputs[i] = "dot(" + src_var + ",vec3(0.333333,0.333333,0.333333))";
+ } else if (in_type == VisualShaderNode::PORT_TYPE_VECTOR && out_type == VisualShaderNode::PORT_TYPE_SCALAR) {
+ inputs[i] = "vec3(" + src_var + ")";
+ }
+ } else {
+
+ Variant defval = vsnode->get_input_port_default_value(i);
+ if (defval.get_type() == Variant::REAL || defval.get_type() == Variant::INT) {
+ float val = defval;
+ inputs[i] = "n_in" + itos(node) + "p" + itos(i);
+ code += "\tfloat " + inputs[i] + " = " + vformat("%.5f", val) + ";\n";
+ } else if (defval.get_type() == Variant::VECTOR3) {
+ Vector3 val = defval;
+ inputs[i] = "n_in" + itos(node) + "p" + itos(i);
+ code += "\tvec3 " + inputs[i] + " = " + vformat("vec3(%.5f,%.5f,%.5f);\n", val.x, val.y, val.z);
+ } else if (defval.get_type() == Variant::TRANSFORM) {
+ Transform val = defval;
+ val.basis.transpose();
+ inputs[i] = "n_in" + itos(node) + "p" + itos(i);
+ Array values;
+ for (int i = 0; i < 3; i++) {
+ values.push_back(val.basis[i].x);
+ values.push_back(val.basis[i].y);
+ values.push_back(val.basis[i].z);
+ }
+ values.push_back(val.origin.x);
+ values.push_back(val.origin.y);
+ values.push_back(val.origin.z);
+ bool err = false;
+ code += "\tmat4 " + inputs[i] + " = " + String("mat4( vec4(%.5f,%.5f,%.5f,0.0),vec4(%.5f,%.5f,%.5f,0.0),vec4(%.5f,%.5f,%.5f,0.0),vec4(%.5f,%.5f,%.5f,1.0) );\n").sprintf(values, &err);
+ } else {
+ //will go empty, node is expected to know what it is doing at this point and handle it
+ }
+ }
+ }
+
+ int output_count = vsnode->get_output_port_count();
+ Vector<String> output_vars;
+ output_vars.resize(vsnode->get_output_port_count());
+ String *outputs = output_vars.ptrw();
+
+ for (int i = 0; i < output_count; i++) {
+
+ outputs[i] = "n_out" + itos(node) + "p" + itos(i);
+ switch (vsnode->get_output_port_type(i)) {
+ case VisualShaderNode::PORT_TYPE_SCALAR: code += String() + "\tfloat " + outputs[i] + ";\n"; break;
+ case VisualShaderNode::PORT_TYPE_VECTOR: code += String() + "\tvec3 " + outputs[i] + ";\n"; break;
+ case VisualShaderNode::PORT_TYPE_TRANSFORM: code += String() + "\tmat4 " + outputs[i] + ";\n"; break;
+ default: {}
+ }
+ }
+
+ Vector<VisualShader::DefaultTextureParam> params = vsnode->get_default_texture_parameters(type, node);
+ for (int i = 0; i < params.size(); i++) {
+ def_tex_params.push_back(params[i]);
+ }
+
+ Ref<VisualShaderNodeInput> input = vsnode;
+
+ if (input.is_valid() && for_preview) {
+ //handle for preview
+ code += input->generate_code_for_preview(type, node, inputs, outputs);
+ } else {
+ //handle normally
+ global_code += vsnode->generate_global(get_mode(), type, node);
+ code += vsnode->generate_code(get_mode(), type, node, inputs, outputs);
+ }
+ code += "\n"; //
+ processed.insert(node);
+
+ return OK;
+}
+
+void VisualShader::_update_shader() const {
+ if (!dirty)
+ return;
+
+ dirty = false;
+
+ StringBuilder global_code;
+ StringBuilder code;
+ Vector<VisualShader::DefaultTextureParam> default_tex_params;
+ static const char *shader_mode_str[Shader::MODE_MAX] = { "spatial", "canvas_item", "particles" };
+
+ global_code += String() + "shader_type " + shader_mode_str[shader_mode] + ";\n";
+
+ String render_mode;
+
+ {
+ //fill render mode enums
+ int idx = 0;
+ while (render_mode_enums[idx].string) {
+
+ if (shader_mode == render_mode_enums[idx].mode) {
+
+ if (modes.has(render_mode_enums[idx].string)) {
+
+ int which = modes[render_mode_enums[idx].string];
+ int count = 0;
+ for (int i = 0; i < ShaderTypes::get_singleton()->get_modes(VisualServer::ShaderMode(shader_mode)).size(); i++) {
+ String mode = ShaderTypes::get_singleton()->get_modes(VisualServer::ShaderMode(shader_mode))[i];
+ if (mode.begins_with(render_mode_enums[idx].string)) {
+ if (count == which) {
+ if (render_mode != String()) {
+ render_mode += ", ";
+ }
+ render_mode += mode;
+ break;
+ }
+ count++;
+ }
+ }
+ }
+ }
+ idx++;
+ }
+
+ //fill render mode flags
+ for (int i = 0; i < ShaderTypes::get_singleton()->get_modes(VisualServer::ShaderMode(shader_mode)).size(); i++) {
+
+ String mode = ShaderTypes::get_singleton()->get_modes(VisualServer::ShaderMode(shader_mode))[i];
+ if (flags.has(mode)) {
+ if (render_mode != String()) {
+ render_mode += ", ";
+ }
+ render_mode += mode;
+ }
+ }
+ }
+
+ if (render_mode != String()) {
+
+ global_code += "render_mode " + render_mode + ";\n\n";
+ }
+
+ static const char *func_name[TYPE_MAX] = { "vertex", "fragment", "light" };
+
+ for (int i = 0; i < TYPE_MAX; i++) {
+
+ //make it faster to go around through shader
+ VMap<ConnectionKey, const List<Connection>::Element *> input_connections;
+ VMap<ConnectionKey, const List<Connection>::Element *> output_connections;
+
+ for (const List<Connection>::Element *E = graph[i].connections.front(); E; E = E->next()) {
+ ConnectionKey from_key;
+ from_key.node = E->get().from_node;
+ from_key.port = E->get().from_port;
+
+ output_connections.insert(from_key, E);
+
+ ConnectionKey to_key;
+ to_key.node = E->get().to_node;
+ to_key.port = E->get().to_port;
+
+ input_connections.insert(to_key, E);
+ }
+
+ code += "\nvoid " + String(func_name[i]) + "() {\n";
+
+ Set<int> processed;
+ Error err = _write_node(Type(i), global_code, code, default_tex_params, input_connections, output_connections, NODE_ID_OUTPUT, processed, false);
+ ERR_FAIL_COND(err != OK);
+
+ code += "}\n";
+ }
+
+ //set code secretly
+ global_code += "\n\n";
+ String final_code = global_code;
+ final_code += code;
+ const_cast<VisualShader *>(this)->set_code(final_code);
+ //print_line(final_code);
+ for (int i = 0; i < default_tex_params.size(); i++) {
+ const_cast<VisualShader *>(this)->set_default_texture_param(default_tex_params[i].name, default_tex_params[i].param);
+ }
+}
+
+void VisualShader::_queue_update() {
+ if (dirty) {
+ return;
+ }
+
+ dirty = true;
+ call_deferred("_update_shader");
+}
+
+void VisualShader::_input_type_changed(Type p_type, int p_id) {
+ //erase connections using this input, as type changed
+ Graph *g = &graph[p_type];
+
+ for (List<Connection>::Element *E = g->connections.front(); E;) {
+ List<Connection>::Element *N = E->next();
+ if (E->get().from_node == p_id) {
+ g->connections.erase(E);
+ }
+ E = N;
+ }
+}
+
+void VisualShader::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_mode", "mode"), &VisualShader::set_mode);
+
+ ClassDB::bind_method(D_METHOD("add_node", "type", "node", "position", "id"), &VisualShader::add_node);
+ ClassDB::bind_method(D_METHOD("set_node_position", "type", "id", "position"), &VisualShader::set_node_position);
+
+ ClassDB::bind_method(D_METHOD("get_node", "type", "id"), &VisualShader::get_node);
+ ClassDB::bind_method(D_METHOD("get_node_position", "type", "id"), &VisualShader::get_node_position);
+
+ ClassDB::bind_method(D_METHOD("get_node_list", "type"), &VisualShader::get_node_list);
+ ClassDB::bind_method(D_METHOD("get_valid_node_id", "type"), &VisualShader::get_valid_node_id);
+
+ ClassDB::bind_method(D_METHOD("remove_node", "type", "id"), &VisualShader::remove_node);
+
+ ClassDB::bind_method(D_METHOD("is_node_connection", "type", "from_node", "from_port", "to_node", "to_port"), &VisualShader::is_node_connection);
+ ClassDB::bind_method(D_METHOD("can_connect_nodes", "type", "from_node", "from_port", "to_node", "to_port"), &VisualShader::is_node_connection);
+
+ ClassDB::bind_method(D_METHOD("connect_nodes", "type", "from_node", "from_port", "to_node", "to_port"), &VisualShader::connect_nodes);
+ ClassDB::bind_method(D_METHOD("disconnect_nodes", "type", "from_node", "from_port", "to_node", "to_port"), &VisualShader::disconnect_nodes);
+
+ ClassDB::bind_method(D_METHOD("get_node_connections", "type"), &VisualShader::_get_node_connections);
+
+ ClassDB::bind_method(D_METHOD("set_graph_offset", "offset"), &VisualShader::set_graph_offset);
+ ClassDB::bind_method(D_METHOD("get_graph_offset"), &VisualShader::get_graph_offset);
+
+ ClassDB::bind_method(D_METHOD("_queue_update"), &VisualShader::_queue_update);
+ ClassDB::bind_method(D_METHOD("_update_shader"), &VisualShader::_update_shader);
+
+ ClassDB::bind_method(D_METHOD("_input_type_changed"), &VisualShader::_input_type_changed);
+
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "graph_offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_graph_offset", "get_graph_offset");
+
+ BIND_ENUM_CONSTANT(TYPE_VERTEX);
+ BIND_ENUM_CONSTANT(TYPE_FRAGMENT);
+ BIND_ENUM_CONSTANT(TYPE_LIGHT);
+ BIND_ENUM_CONSTANT(TYPE_MAX);
+
+ BIND_CONSTANT(NODE_ID_INVALID);
+ BIND_CONSTANT(NODE_ID_OUTPUT);
+}
+
+VisualShader::VisualShader() {
+ shader_mode = Shader::MODE_SPATIAL;
+
+ for (int i = 0; i < TYPE_MAX; i++) {
+ Ref<VisualShaderNodeOutput> output;
+ output.instance();
+ output->shader_type = Type(i);
+ output->shader_mode = shader_mode;
+ graph[i].nodes[NODE_ID_OUTPUT].node = output;
+ graph[i].nodes[NODE_ID_OUTPUT].position = Vector2(400, 150);
+ }
+
+ dirty = true;
+}
+
+///////////////////////////////////////////////////////////
+
+const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = {
+ // Spatial, Vertex
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "vertex", "VERTEX" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "normal", "NORMAL" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "tangent", "TANGENT" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "binormal", "BINORMAL" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV,0.0)" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "uv2", "vec3(UV2,0.0)" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "point_size", "POINT_SIZE" },
+
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "world", "WORLD_MATRIX" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "inv_camera", "INV_CAMERA_MATRIX" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "projection", "PROJECTION" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "vp_size", "vec3(VIEWPORT_SIZE, 0)" },
+
+ // Spatial, Fragment
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "vertex", "VERTEX" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "normal", "NORMAL" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "tangent", "TANGENT" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "binormal", "BINORMAL" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV,0.0)" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "uv2", "vec3(UV2,0.0)" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "point_coord", "vec2(POINT_COORD,0.0)" },
+
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(SCREEN_UV,0.0)" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "side", "float(FRONT_FACING ? 1.0 : 0.0)" },
+
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_TRANSFORM, "world", "WORLD_MATRIX" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_TRANSFORM, "inv_camera", "INV_CAMERA_MATRIX" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_TRANSFORM, "projection", "PROJECTION" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "vp_size", "vec3(VIEWPORT_SIZE, 0.0)" },
+
+ // Spatial, Light
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "normal", "NORMAL" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "view", "VIEW" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "light", "LIGHT" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "light_color", "LIGHT_COLOR" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "attenuation", "ATTENUATION" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "albedo", "ALBEDO" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "transmission", "TRANSMISSION" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "roughness", "ROUGHNESS" },
+
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_TRANSFORM, "world", "WORLD_MATRIX" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_TRANSFORM, "inv_camera", "INV_CAMERA_MATRIX" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_TRANSFORM, "projection", "PROJECTION" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "vp_size", "vec3(VIEWPORT_SIZE, 0.0)" },
+ // Canvas Item, Vertex
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "vertex", "vec3(VERTEX,0.0)" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV,0.0)" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "point_size", "POINT_SIZE" },
+
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "world", "WORLD_MATRIX" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "projection", "PROJECTION_MATRIX" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "extra", "EXTRA_MATRIX" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "light_pass", "float(AT_LIGHT_PASS ? 1.0 : 0.0)" },
+ // Canvas Item, Fragment
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV,0.0)" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(SCREEN_UV,0.0)" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "point_coord", "vec2(POINT_COORD,0.0)" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "light_pass", "float(AT_LIGHT_PASS ? 1.0 : 0.0)" },
+ // Canvas Item, Light
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV,0.0)" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "normal", "NORMAL" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "light_vec", "vec3(LIGHT_VEC,0.0)" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "light_height", "LIGHT_HEIGHT" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "light_color", "LIGHT_COLOR.rgb" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "light_alpha", "LIGHT_COLOR.a" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "light_uv", "vec3(LIGHT_UV,0.0)" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "shadow_color", "SHADOW_COLOR.rgb" },
+
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(SCREEN_UV,0.0)" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "point_coord", "vec2(POINT_COORD,0.0)" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
+ // Particles, Vertex
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "restart", "float(RESTART ? 1.0 : 0.0)" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "active", "float(ACTIVE ? 1.0 : 0.0)" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" },
+
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "delta", "DELTA" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "lifetime", "LIFETIME" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "index", "float(INDEX)" },
+
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "emission_transform", "EMISSION_TRANSFORM" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
+ { Shader::MODE_MAX, VisualShader::TYPE_MAX, VisualShaderNode::PORT_TYPE_TRANSFORM, NULL, NULL },
+};
+
+const VisualShaderNodeInput::Port VisualShaderNodeInput::preview_ports[] = {
+
+ // Spatial, Fragment
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "normal", "vec3(0.0,0.0,1.0)" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "tangent", "vec3(0.0,1.0,0.0)" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "binormal", "vec3(1.0,0.0,0.0)" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV,0.0)" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "uv2", "vec3(UV,0.0)" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "vec3(1.0)" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "1.0" },
+
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(UV,0.0)" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "side", "1.0" },
+
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "vp_size", "vec3(1.0,1.0, 0.0)" },
+
+ // Spatial, Light
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "normal", "vec3(0.0,0.0,1.0)" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "vp_size", "vec3(1.0, 1.0, 0.0)" },
+ // Canvas Item, Vertex
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "vertex", "vec3(VERTEX,0.0)" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV,0.0)" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "color", "vec3(1.0)" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "1.0" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
+ // Canvas Item, Fragment
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV,0.0)" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "vec3(1.0)" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "1.0" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(UV,0.0)" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
+ // Canvas Item, Light
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV,0.0)" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "normal", "vec3(0.0,0.0,1.0)" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "vec3(1.0)" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "1.0" },
+
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(UV,0.0)" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
+ // Particles, Vertex
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "color", "vec3(1.0)" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "1.0" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "vec3(0.0,0.0,1.0)" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
+ { Shader::MODE_MAX, VisualShader::TYPE_MAX, VisualShaderNode::PORT_TYPE_TRANSFORM, NULL, NULL },
+};
+
+int VisualShaderNodeInput::get_input_port_count() const {
+
+ return 0;
+}
+VisualShaderNodeInput::PortType VisualShaderNodeInput::get_input_port_type(int p_port) const {
+
+ return PORT_TYPE_SCALAR;
+}
+String VisualShaderNodeInput::get_input_port_name(int p_port) const {
+
+ return "";
+}
+
+int VisualShaderNodeInput::get_output_port_count() const {
+
+ return 1;
+}
+VisualShaderNodeInput::PortType VisualShaderNodeInput::get_output_port_type(int p_port) const {
+
+ return get_input_type_by_name(input_name);
+}
+String VisualShaderNodeInput::get_output_port_name(int p_port) const {
+ return "";
+}
+
+String VisualShaderNodeInput::get_caption() const {
+ return TTR("Input");
+}
+
+String VisualShaderNodeInput::generate_code_for_preview(VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const {
+
+ int idx = 0;
+
+ String code;
+
+ while (preview_ports[idx].mode != Shader::MODE_MAX) {
+ if (preview_ports[idx].mode == shader_mode && preview_ports[idx].shader_type == shader_type && preview_ports[idx].name == input_name) {
+ code = "\t" + p_output_vars[0] + " = " + preview_ports[idx].string + ";\n";
+ break;
+ }
+ idx++;
+ }
+
+ if (code == String()) {
+ switch (get_output_port_type(0)) {
+ case PORT_TYPE_SCALAR: {
+ code = "\t" + p_output_vars[0] + " = 0.0;\n";
+ } break; //default (none found) is scalar
+ case PORT_TYPE_VECTOR: {
+ code = "\t" + p_output_vars[0] + " = vec3(0.0);\n";
+ } break; //default (none found) is scalar
+ case PORT_TYPE_TRANSFORM: {
+ code = "\t" + p_output_vars[0] + " = mat4( vec4(1.0,0.0,0.0,0.0), vec4(0.0,1.0,0.0,0.0), vec4(0.0,0.0,1.0,0.0), vec4(0.0,0.0,0.0,1.0) );\n";
+ } break; //default (none found) is scalar
+ }
+ }
+
+ return code;
+}
+
+String VisualShaderNodeInput::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const {
+
+ int idx = 0;
+
+ String code;
+
+ while (ports[idx].mode != Shader::MODE_MAX) {
+ if (ports[idx].mode == shader_mode && ports[idx].shader_type == shader_type && ports[idx].name == input_name) {
+ code = "\t" + p_output_vars[0] + " = " + ports[idx].string + ";\n";
+ break;
+ }
+ idx++;
+ }
+
+ if (code == String()) {
+ code = "\t" + p_output_vars[0] + " = 0.0;\n"; //default (none found) is scalar
+ }
+
+ return code;
+}
+
+void VisualShaderNodeInput::set_input_name(String p_name) {
+ PortType prev_type = get_input_type_by_name(input_name);
+ input_name = p_name;
+ emit_changed();
+ if (get_input_type_by_name(input_name) != prev_type) {
+ emit_signal("input_type_changed");
+ }
+}
+
+String VisualShaderNodeInput::get_input_name() const {
+ return input_name;
+}
+
+VisualShaderNodeInput::PortType VisualShaderNodeInput::get_input_type_by_name(String p_name) const {
+
+ int idx = 0;
+
+ while (ports[idx].mode != Shader::MODE_MAX) {
+ if (ports[idx].mode == shader_mode && ports[idx].shader_type == shader_type && ports[idx].name == p_name) {
+ return ports[idx].type;
+ }
+ idx++;
+ }
+
+ return PORT_TYPE_SCALAR;
+}
+
+int VisualShaderNodeInput::get_input_index_count() const {
+ int idx = 0;
+ int count = 0;
+
+ while (ports[idx].mode != Shader::MODE_MAX) {
+ if (ports[idx].mode == shader_mode && ports[idx].shader_type == shader_type) {
+ count++;
+ }
+ idx++;
+ }
+
+ return count;
+}
+
+VisualShaderNodeInput::PortType VisualShaderNodeInput::get_input_index_type(int p_index) const {
+ int idx = 0;
+ int count = 0;
+
+ while (ports[idx].mode != Shader::MODE_MAX) {
+ if (ports[idx].mode == shader_mode && ports[idx].shader_type == shader_type) {
+ if (count == p_index) {
+ return ports[idx].type;
+ }
+ count++;
+ }
+ idx++;
+ }
+
+ return PORT_TYPE_SCALAR;
+}
+
+String VisualShaderNodeInput::get_input_index_name(int p_index) const {
+ int idx = 0;
+ int count = 0;
+
+ while (ports[idx].mode != Shader::MODE_MAX) {
+ if (ports[idx].mode == shader_mode && ports[idx].shader_type == shader_type) {
+ if (count == p_index) {
+ return ports[idx].name;
+ }
+ count++;
+ }
+ idx++;
+ }
+
+ return "";
+}
+
+void VisualShaderNodeInput::_validate_property(PropertyInfo &property) const {
+
+ if (property.name == "input_name") {
+ String port_list;
+
+ int idx = 0;
+
+ while (ports[idx].mode != Shader::MODE_MAX) {
+ if (ports[idx].mode == shader_mode && ports[idx].shader_type == shader_type) {
+ if (port_list != String()) {
+ port_list += ",";
+ }
+ port_list += ports[idx].name;
+ }
+ idx++;
+ }
+
+ if (port_list == "") {
+ port_list = TTR("None");
+ }
+ property.hint_string = port_list;
+ }
+}
+
+Vector<StringName> VisualShaderNodeInput::get_editable_properties() const {
+ Vector<StringName> props;
+ props.push_back("input_name");
+ return props;
+}
+
+void VisualShaderNodeInput::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_input_name", "name"), &VisualShaderNodeInput::set_input_name);
+ ClassDB::bind_method(D_METHOD("get_input_name"), &VisualShaderNodeInput::get_input_name);
+
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "input_name", PROPERTY_HINT_ENUM, ""), "set_input_name", "get_input_name");
+ ADD_SIGNAL(MethodInfo("input_type_changed"));
+}
+VisualShaderNodeInput::VisualShaderNodeInput() {
+ input_name = "[None]";
+ // changed when set
+ shader_type = VisualShader::TYPE_MAX;
+ shader_mode = Shader::MODE_MAX;
+}
+
+////////////////////////////////////////////
+
+const VisualShaderNodeOutput::Port VisualShaderNodeOutput::ports[] = {
+ // Spatial, Vertex
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "vertex", "VERTEX" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "normal", "NORMAL" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "tangent", "TANGENT" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "binormal", "BINORMAL" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "UV:xy" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "uv2", "UV2:xy" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "roughness", "ROUGHNESS" },
+ // Spatial, Fragment
+
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "albedo", "ALBEDO" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "ALPHA" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "metallic", "METALLIC" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "roughness", "ROUGHNESS" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "specular", "SPECULAR" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "emission", "EMISSION" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "ao", "AO" },
+
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "normal", "NORMAL" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "normalmap", "NORMALMAP" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "normalmap_depth", "NORMALMAP_DEPTH" },
+
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "rim", "RIM" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "rim_tint", "RIM_TINT" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "clearcoat", "CLEARCOAT" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "clearcoat_gloss", "CLEARCOAT_GLOSS" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "anisotropy", "ANISOTROPY" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "anisotropy_flow", "ANISOTROPY_FLOW:xy" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "subsurf_scatter", "SSS_STRENGTH" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "transmission", "TRANSMISSION" },
+
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha_scissor", "ALPHA_SCISSOR" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "ao_light_affect", "AO_LIGHT_AFFECT" },
+
+ // Spatial, Light
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "diffuse", "DIFFUSE_LIGHT" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "specular", "SPECULAR_LIGHT" },
+ // Canvas Item, Vertex
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "vertex", "VERTEX:xy" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "UV:xy" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" },
+ // Canvas Item, Fragment
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "normal", "NORMAL" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "normalmap", "NORMALMAP" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "normalmap_depth", "NORMALMAP_DEPTH" },
+ // Canvas Item, Light
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "light", "LIGHT.rgb" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "light_alpha", "LIGHT.rgb" },
+ // Particles, Vertex
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" },
+ { Shader::MODE_MAX, VisualShader::TYPE_MAX, VisualShaderNode::PORT_TYPE_TRANSFORM, NULL, NULL },
+};
+
+int VisualShaderNodeOutput::get_input_port_count() const {
+
+ int idx = 0;
+ int count = 0;
+
+ while (ports[idx].mode != Shader::MODE_MAX) {
+ if (ports[idx].mode == shader_mode && ports[idx].shader_type == shader_type) {
+ count++;
+ }
+ idx++;
+ }
+
+ return count;
+}
+
+VisualShaderNodeOutput::PortType VisualShaderNodeOutput::get_input_port_type(int p_port) const {
+
+ int idx = 0;
+ int count = 0;
+
+ while (ports[idx].mode != Shader::MODE_MAX) {
+ if (ports[idx].mode == shader_mode && ports[idx].shader_type == shader_type) {
+ if (count == p_port) {
+ return ports[idx].type;
+ }
+ count++;
+ }
+ idx++;
+ }
+
+ return PORT_TYPE_SCALAR;
+}
+
+String VisualShaderNodeOutput::get_input_port_name(int p_port) const {
+
+ int idx = 0;
+ int count = 0;
+
+ while (ports[idx].mode != Shader::MODE_MAX) {
+ if (ports[idx].mode == shader_mode && ports[idx].shader_type == shader_type) {
+ if (count == p_port) {
+ return String(ports[idx].name).capitalize();
+ }
+ count++;
+ }
+ idx++;
+ }
+
+ return String();
+}
+
+Variant VisualShaderNodeOutput::get_input_port_default_value(int p_port) const {
+ return Variant();
+}
+
+int VisualShaderNodeOutput::get_output_port_count() const {
+
+ return 0;
+}
+VisualShaderNodeOutput::PortType VisualShaderNodeOutput::get_output_port_type(int p_port) const {
+ return PORT_TYPE_SCALAR;
+}
+String VisualShaderNodeOutput::get_output_port_name(int p_port) const {
+ return String();
+}
+
+bool VisualShaderNodeOutput::is_port_separator(int p_index) const {
+
+ if (shader_mode == Shader::MODE_SPATIAL && shader_type == VisualShader::TYPE_FRAGMENT) {
+ String name = get_input_port_name(p_index);
+ return (name == "Normal" || name == "Rim" || name == "Alpha Scissor");
+ }
+ return false;
+}
+
+String VisualShaderNodeOutput::get_caption() const {
+ return TTR("Output");
+}
+
+String VisualShaderNodeOutput::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const {
+
+ int idx = 0;
+ int count = 0;
+
+ String code;
+ while (ports[idx].mode != Shader::MODE_MAX) {
+ if (ports[idx].mode == shader_mode && ports[idx].shader_type == shader_type) {
+
+ if (p_input_vars[count] != String()) {
+ String s = ports[idx].string;
+ if (s.find(":") != -1) {
+ code += "\t" + s.get_slicec(':', 0) + " = " + p_input_vars[count] + "." + s.get_slicec(':', 1) + ";\n";
+ } else {
+ code += "\t" + s + " = " + p_input_vars[count] + ";\n";
+ }
+ }
+ count++;
+ }
+ idx++;
+ }
+
+ return code;
+}
+
+VisualShaderNodeOutput::VisualShaderNodeOutput() {
+}
+
+///////////////////////////
+
+void VisualShaderNodeUniform::set_uniform_name(const String &p_name) {
+ uniform_name = p_name;
+ emit_signal("name_changed");
+ emit_changed();
+}
+
+String VisualShaderNodeUniform::get_uniform_name() const {
+ return uniform_name;
+}
+
+void VisualShaderNodeUniform::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_uniform_name", "name"), &VisualShaderNodeUniform::set_uniform_name);
+ ClassDB::bind_method(D_METHOD("get_uniform_name"), &VisualShaderNodeUniform::get_uniform_name);
+
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "uniform_name"), "set_uniform_name", "get_uniform_name");
+}
+
+VisualShaderNodeUniform::VisualShaderNodeUniform() {
+}
diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h
new file mode 100644
index 0000000000..6ff1c9a9fe
--- /dev/null
+++ b/scene/resources/visual_shader.h
@@ -0,0 +1,284 @@
+#ifndef VISUAL_SHADER_H
+#define VISUAL_SHADER_H
+
+#include "scene/resources/shader.h"
+#include "string_builder.h"
+
+class VisualShaderNodeUniform;
+class VisualShaderNode;
+
+class VisualShader : public Shader {
+ GDCLASS(VisualShader, Shader)
+public:
+ enum Type {
+ TYPE_VERTEX,
+ TYPE_FRAGMENT,
+ TYPE_LIGHT,
+ TYPE_MAX
+ };
+
+ struct Connection {
+ int from_node;
+ int from_port;
+ int to_node;
+ int to_port;
+ };
+
+ struct DefaultTextureParam {
+ StringName name;
+ Ref<Texture> param;
+ };
+
+private:
+ struct Node {
+ Ref<VisualShaderNode> node;
+ Vector2 position;
+ };
+
+ struct Graph {
+ Map<int, Node> nodes;
+ List<Connection> connections;
+ } graph[TYPE_MAX];
+
+ Shader::Mode shader_mode;
+
+ Array _get_node_connections(Type p_type) const;
+
+ Vector2 graph_offset;
+
+ struct RenderModeEnums {
+ Shader::Mode mode;
+ const char *string;
+ };
+
+ HashMap<String, int> modes;
+ Set<StringName> flags;
+
+ static RenderModeEnums render_mode_enums[];
+
+ volatile mutable bool dirty;
+ void _queue_update();
+
+ union ConnectionKey {
+
+ struct {
+ uint64_t node : 32;
+ uint64_t port : 32;
+ };
+ uint64_t key;
+ bool operator<(const ConnectionKey &p_key) const {
+ return key < p_key.key;
+ }
+ };
+
+ Error _write_node(Type p_type, StringBuilder &global_code, StringBuilder &code, Vector<DefaultTextureParam> &def_tex_params, const VMap<ConnectionKey, const List<Connection>::Element *> &input_connections, const VMap<ConnectionKey, const List<Connection>::Element *> &output_connections, int node, Set<int> &processed, bool for_preview) const;
+
+ void _input_type_changed(Type p_type, int p_id);
+
+protected:
+ virtual void _update_shader() const;
+ static void _bind_methods();
+
+ bool _set(const StringName &p_name, const Variant &p_value);
+ bool _get(const StringName &p_name, Variant &r_ret) const;
+ void _get_property_list(List<PropertyInfo> *p_list) const;
+
+public:
+ enum {
+ NODE_ID_INVALID = -1,
+ NODE_ID_OUTPUT = 0,
+ };
+
+ void add_node(Type p_type, const Ref<VisualShaderNode> &p_node, const Vector2 &p_position, int p_id);
+ void set_node_position(Type p_type, int p_id, const Vector2 &p_position);
+
+ Vector2 get_node_position(Type p_type, int p_id) const;
+ Ref<VisualShaderNode> get_node(Type p_type, int p_id) const;
+
+ Vector<int> get_node_list(Type p_type) const;
+ int get_valid_node_id(Type p_type) const;
+
+ int find_node_id(Type p_type, const Ref<VisualShaderNode> &p_node) const;
+ void remove_node(Type p_type, int p_id);
+
+ bool is_node_connection(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) const;
+ bool can_connect_nodes(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) const;
+ Error connect_nodes(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port);
+ void disconnect_nodes(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port);
+
+ void get_node_connections(Type p_type, List<Connection> *r_connections) const;
+
+ void set_mode(Mode p_mode);
+ virtual Mode get_mode() const;
+
+ void set_graph_offset(const Vector2 &p_offset);
+ Vector2 get_graph_offset() const;
+
+ String generate_preview_shader(Type p_type, int p_node, int p_port, Vector<DefaultTextureParam> &r_default_tex_params) const;
+
+ String validate_uniform_name(const String &p_name, const Ref<VisualShaderNodeUniform> &p_uniform) const;
+
+ VisualShader();
+};
+
+VARIANT_ENUM_CAST(VisualShader::Type)
+///
+///
+///
+
+class VisualShaderNode : public Resource {
+ GDCLASS(VisualShaderNode, Resource)
+
+ int port_preview;
+
+ Map<int, Variant> default_input_values;
+
+ Array _get_default_input_values() const;
+ void _set_default_input_values(const Array &p_values);
+
+protected:
+ static void _bind_methods();
+
+public:
+ enum PortType {
+ PORT_TYPE_SCALAR,
+ PORT_TYPE_VECTOR,
+ PORT_TYPE_TRANSFORM,
+ };
+
+ virtual String get_caption() const = 0;
+
+ virtual int get_input_port_count() const = 0;
+ virtual PortType get_input_port_type(int p_port) const = 0;
+ virtual String get_input_port_name(int p_port) const = 0;
+
+ void set_input_port_default_value(int p_port, const Variant &p_value);
+ Variant get_input_port_default_value(int p_port) const; // if NIL (default if node does not set anything) is returned, it means no default value is wanted if disconnected, thus no input var must be supplied (empty string will be supplied)
+
+ virtual int get_output_port_count() const = 0;
+ virtual PortType get_output_port_type(int p_port) const = 0;
+ virtual String get_output_port_name(int p_port) const = 0;
+
+ void set_output_port_for_preview(int p_index);
+ int get_output_port_for_preview() const;
+
+ virtual bool is_port_separator(int p_index) const;
+
+ virtual Vector<StringName> get_editable_properties() const;
+
+ virtual Vector<VisualShader::DefaultTextureParam> get_default_texture_parameters(VisualShader::Type p_type, int p_id) const;
+ virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const;
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const = 0; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+
+ virtual String get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const;
+
+ VisualShaderNode();
+};
+/////
+
+class VisualShaderNodeInput : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeInput, VisualShaderNode)
+
+ friend class VisualShader;
+ VisualShader::Type shader_type;
+ Shader::Mode shader_mode;
+
+ struct Port {
+ Shader::Mode mode;
+ VisualShader::Type shader_type;
+ PortType type;
+ const char *name;
+ const char *string;
+ };
+
+ static const Port ports[];
+ static const Port preview_ports[];
+
+ String input_name;
+
+protected:
+ static void _bind_methods();
+ void _validate_property(PropertyInfo &property) const;
+
+public:
+ virtual int get_input_port_count() const;
+ virtual PortType get_input_port_type(int p_port) const;
+ virtual String get_input_port_name(int p_port) const;
+
+ virtual int get_output_port_count() const;
+ virtual PortType get_output_port_type(int p_port) const;
+ virtual String get_output_port_name(int p_port) const;
+
+ virtual String get_caption() const;
+
+ virtual String generate_code_for_preview(VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const;
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const;
+
+ void set_input_name(String p_name);
+ String get_input_name() const;
+
+ int get_input_index_count() const;
+ PortType get_input_index_type(int p_index) const;
+ String get_input_index_name(int p_index) const;
+
+ PortType get_input_type_by_name(String p_name) const;
+
+ virtual Vector<StringName> get_editable_properties() const;
+
+ VisualShaderNodeInput();
+};
+
+///
+
+class VisualShaderNodeOutput : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeOutput, VisualShaderNode)
+public:
+ friend class VisualShader;
+ VisualShader::Type shader_type;
+ Shader::Mode shader_mode;
+
+ struct Port {
+ Shader::Mode mode;
+ VisualShader::Type shader_type;
+ PortType type;
+ const char *name;
+ const char *string;
+ };
+
+ static const Port ports[];
+
+public:
+ virtual int get_input_port_count() const;
+ virtual PortType get_input_port_type(int p_port) const;
+ virtual String get_input_port_name(int p_port) const;
+ Variant get_input_port_default_value(int p_port) const;
+
+ virtual int get_output_port_count() const;
+ virtual PortType get_output_port_type(int p_port) const;
+ virtual String get_output_port_name(int p_port) const;
+
+ virtual bool is_port_separator(int p_index) const;
+
+ virtual String get_caption() const;
+
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const;
+
+ VisualShaderNodeOutput();
+};
+
+class VisualShaderNodeUniform : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeUniform, VisualShaderNode)
+
+ String uniform_name;
+
+protected:
+ static void _bind_methods();
+
+public:
+ void set_uniform_name(const String &p_name);
+ String get_uniform_name() const;
+
+ VisualShaderNodeUniform();
+};
+
+#endif // VISUAL_SHADER_H
diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp
new file mode 100644
index 0000000000..98ecdbdf30
--- /dev/null
+++ b/scene/resources/visual_shader_nodes.cpp
@@ -0,0 +1,1896 @@
+#include "visual_shader_nodes.h"
+////////////// Scalar
+
+String VisualShaderNodeScalarConstant::get_caption() const {
+ return "Scalar";
+}
+
+int VisualShaderNodeScalarConstant::get_input_port_count() const {
+ return 0;
+}
+VisualShaderNodeScalarConstant::PortType VisualShaderNodeScalarConstant::get_input_port_type(int p_port) const {
+ return PORT_TYPE_SCALAR;
+}
+String VisualShaderNodeScalarConstant::get_input_port_name(int p_port) const {
+ return String();
+}
+
+int VisualShaderNodeScalarConstant::get_output_port_count() const {
+ return 1;
+}
+VisualShaderNodeScalarConstant::PortType VisualShaderNodeScalarConstant::get_output_port_type(int p_port) const {
+ return PORT_TYPE_SCALAR;
+}
+String VisualShaderNodeScalarConstant::get_output_port_name(int p_port) const {
+ return ""; //no output port means the editor will be used as port
+}
+
+String VisualShaderNodeScalarConstant::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const {
+ return "\t" + p_output_vars[0] + " = " + vformat("%.6f", constant) + ";\n";
+}
+
+void VisualShaderNodeScalarConstant::set_constant(float p_value) {
+
+ constant = p_value;
+ emit_changed();
+}
+
+float VisualShaderNodeScalarConstant::get_constant() const {
+
+ return constant;
+}
+
+Vector<StringName> VisualShaderNodeScalarConstant::get_editable_properties() const {
+ Vector<StringName> props;
+ props.push_back("constant");
+ return props;
+}
+
+void VisualShaderNodeScalarConstant::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_constant", "value"), &VisualShaderNodeScalarConstant::set_constant);
+ ClassDB::bind_method(D_METHOD("get_constant"), &VisualShaderNodeScalarConstant::get_constant);
+
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "constant"), "set_constant", "get_constant");
+}
+
+VisualShaderNodeScalarConstant::VisualShaderNodeScalarConstant() {
+ constant = 0;
+}
+
+////////////// Color
+
+String VisualShaderNodeColorConstant::get_caption() const {
+ return "Color";
+}
+
+int VisualShaderNodeColorConstant::get_input_port_count() const {
+ return 0;
+}
+VisualShaderNodeColorConstant::PortType VisualShaderNodeColorConstant::get_input_port_type(int p_port) const {
+ return PORT_TYPE_VECTOR;
+}
+String VisualShaderNodeColorConstant::get_input_port_name(int p_port) const {
+ return String();
+}
+
+int VisualShaderNodeColorConstant::get_output_port_count() const {
+ return 2;
+}
+VisualShaderNodeColorConstant::PortType VisualShaderNodeColorConstant::get_output_port_type(int p_port) const {
+ return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR;
+}
+String VisualShaderNodeColorConstant::get_output_port_name(int p_port) const {
+ return p_port == 0 ? "" : "alpha"; //no output port means the editor will be used as port
+}
+
+String VisualShaderNodeColorConstant::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const {
+
+ String code;
+ code += "\t" + p_output_vars[0] + " = " + vformat("vec3(%.6f,%.6f,%.6f)", constant.r, constant.g, constant.b) + ";\n";
+ code += "\t" + p_output_vars[1] + " = " + vformat("%.6f", constant.a) + ";\n";
+
+ return code;
+}
+
+void VisualShaderNodeColorConstant::set_constant(Color p_value) {
+
+ constant = p_value;
+ emit_changed();
+}
+
+Color VisualShaderNodeColorConstant::get_constant() const {
+
+ return constant;
+}
+
+Vector<StringName> VisualShaderNodeColorConstant::get_editable_properties() const {
+ Vector<StringName> props;
+ props.push_back("constant");
+ return props;
+}
+
+void VisualShaderNodeColorConstant::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_constant", "value"), &VisualShaderNodeColorConstant::set_constant);
+ ClassDB::bind_method(D_METHOD("get_constant"), &VisualShaderNodeColorConstant::get_constant);
+
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "constant"), "set_constant", "get_constant");
+}
+
+VisualShaderNodeColorConstant::VisualShaderNodeColorConstant() {
+ constant = Color(1, 1, 1, 1);
+}
+
+////////////// Vector
+
+String VisualShaderNodeVec3Constant::get_caption() const {
+ return "Vector";
+}
+
+int VisualShaderNodeVec3Constant::get_input_port_count() const {
+ return 0;
+}
+VisualShaderNodeVec3Constant::PortType VisualShaderNodeVec3Constant::get_input_port_type(int p_port) const {
+ return PORT_TYPE_VECTOR;
+}
+String VisualShaderNodeVec3Constant::get_input_port_name(int p_port) const {
+ return String();
+}
+
+int VisualShaderNodeVec3Constant::get_output_port_count() const {
+ return 1;
+}
+VisualShaderNodeVec3Constant::PortType VisualShaderNodeVec3Constant::get_output_port_type(int p_port) const {
+ return PORT_TYPE_VECTOR;
+}
+String VisualShaderNodeVec3Constant::get_output_port_name(int p_port) const {
+ return ""; //no output port means the editor will be used as port
+}
+
+String VisualShaderNodeVec3Constant::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const {
+ return "\t" + p_output_vars[0] + " = " + vformat("vec3(%.6f,%.6f,%.6f)", constant.x, constant.y, constant.z) + ";\n";
+}
+
+void VisualShaderNodeVec3Constant::set_constant(Vector3 p_value) {
+
+ constant = p_value;
+ emit_changed();
+}
+
+Vector3 VisualShaderNodeVec3Constant::get_constant() const {
+
+ return constant;
+}
+
+Vector<StringName> VisualShaderNodeVec3Constant::get_editable_properties() const {
+ Vector<StringName> props;
+ props.push_back("constant");
+ return props;
+}
+
+void VisualShaderNodeVec3Constant::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_constant", "value"), &VisualShaderNodeVec3Constant::set_constant);
+ ClassDB::bind_method(D_METHOD("get_constant"), &VisualShaderNodeVec3Constant::get_constant);
+
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "constant"), "set_constant", "get_constant");
+}
+
+VisualShaderNodeVec3Constant::VisualShaderNodeVec3Constant() {
+}
+
+////////////// Transform
+
+String VisualShaderNodeTransformConstant::get_caption() const {
+ return "Transform";
+}
+
+int VisualShaderNodeTransformConstant::get_input_port_count() const {
+ return 0;
+}
+VisualShaderNodeTransformConstant::PortType VisualShaderNodeTransformConstant::get_input_port_type(int p_port) const {
+ return PORT_TYPE_VECTOR;
+}
+String VisualShaderNodeTransformConstant::get_input_port_name(int p_port) const {
+ return String();
+}
+
+int VisualShaderNodeTransformConstant::get_output_port_count() const {
+ return 1;
+}
+VisualShaderNodeTransformConstant::PortType VisualShaderNodeTransformConstant::get_output_port_type(int p_port) const {
+ return PORT_TYPE_TRANSFORM;
+}
+String VisualShaderNodeTransformConstant::get_output_port_name(int p_port) const {
+ return ""; //no output port means the editor will be used as port
+}
+
+String VisualShaderNodeTransformConstant::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const {
+ Transform t = constant;
+ t.basis.transpose();
+
+ String code = "\t" + p_output_vars[0] + " = mat4(";
+ code += vformat("vec4(%.6f,%.6f,%.6f,0.0),", t.basis[0].x, t.basis[0].y, t.basis[0].z);
+ code += vformat("vec4(%.6f,%.6f,%.6f,0.0),", t.basis[1].x, t.basis[1].y, t.basis[1].z);
+ code += vformat("vec4(%.6f,%.6f,%.6f,0.0),", t.basis[2].x, t.basis[2].y, t.basis[2].z);
+ code += vformat("vec4(%.6f,%.6f,%.6f,1.0) );\n", t.origin.x, t.origin.y, t.origin.z);
+ return code;
+}
+
+void VisualShaderNodeTransformConstant::set_constant(Transform p_value) {
+
+ constant = p_value;
+ emit_changed();
+}
+
+Transform VisualShaderNodeTransformConstant::get_constant() const {
+
+ return constant;
+}
+
+Vector<StringName> VisualShaderNodeTransformConstant::get_editable_properties() const {
+ Vector<StringName> props;
+ props.push_back("constant");
+ return props;
+}
+
+void VisualShaderNodeTransformConstant::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_constant", "value"), &VisualShaderNodeTransformConstant::set_constant);
+ ClassDB::bind_method(D_METHOD("get_constant"), &VisualShaderNodeTransformConstant::get_constant);
+
+ ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "constant"), "set_constant", "get_constant");
+}
+
+VisualShaderNodeTransformConstant::VisualShaderNodeTransformConstant() {
+}
+
+////////////// Texture
+
+String VisualShaderNodeTexture::get_caption() const {
+ return "Texture";
+}
+
+int VisualShaderNodeTexture::get_input_port_count() const {
+ return 2;
+}
+VisualShaderNodeTexture::PortType VisualShaderNodeTexture::get_input_port_type(int p_port) const {
+ return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR;
+}
+String VisualShaderNodeTexture::get_input_port_name(int p_port) const {
+ return p_port == 0 ? "uv" : "lod";
+}
+
+int VisualShaderNodeTexture::get_output_port_count() const {
+ return 2;
+}
+VisualShaderNodeTexture::PortType VisualShaderNodeTexture::get_output_port_type(int p_port) const {
+ return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR;
+}
+String VisualShaderNodeTexture::get_output_port_name(int p_port) const {
+ return p_port == 0 ? "rgb" : "alpha";
+}
+
+static String make_unique_id(VisualShader::Type p_type, int p_id, const String &p_name) {
+
+ static const char *typepf[VisualShader::TYPE_MAX] = { "vtx", "frg", "lgt" };
+ return p_name + "_" + String(typepf[p_type]) + "_" + itos(p_id);
+}
+
+Vector<VisualShader::DefaultTextureParam> VisualShaderNodeTexture::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const {
+ VisualShader::DefaultTextureParam dtp;
+ dtp.name = make_unique_id(p_type, p_id, "tex");
+ dtp.param = texture;
+ Vector<VisualShader::DefaultTextureParam> ret;
+ ret.push_back(dtp);
+ return ret;
+}
+
+String VisualShaderNodeTexture::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
+
+ if (source == SOURCE_TEXTURE) {
+
+ String u = "uniform sampler2D " + make_unique_id(p_type, p_id, "tex");
+ switch (texture_type) {
+ case TYPE_DATA: break;
+ case TYPE_COLOR: u += " : hint_color"; break;
+ case TYPE_NORMALMAP: u += " : hint_normal"; break;
+ }
+ return u + ";";
+ }
+
+ return String();
+}
+
+String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const {
+
+ if (source == SOURCE_TEXTURE) {
+ String id = make_unique_id(p_type, p_id, "tex");
+ String code;
+ if (p_input_vars[0] == String()) { //none bound, do nothing
+
+ code += "\tvec4 " + id + "_read = vec4(0.0);\n";
+
+ } else if (p_input_vars[1] == String()) {
+ //no lod
+ code += "\tvec4 " + id + "_read = texture( " + id + " , " + p_input_vars[0] + ".xy );\n";
+ } else {
+ code += "\tvec4 " + id + "_read = textureLod( " + id + " , " + p_input_vars[0] + ".xy , " + p_input_vars[1] + " );\n";
+ }
+
+ code += "\t" + p_output_vars[0] + " = " + id + "_read.rgb;\n";
+ code += "\t" + p_output_vars[1] + " = " + id + "_read.a;\n";
+ return code;
+ }
+
+ if (source == SOURCE_SCREEN && (p_mode == Shader::MODE_SPATIAL || p_mode == Shader::MODE_CANVAS_ITEM) && p_type == VisualShader::TYPE_FRAGMENT) {
+
+ String code = "\t{\n";
+ if (p_input_vars[0] == String()) { //none bound, do nothing
+
+ code += "\t\tvec4 _tex_read = vec4(0.0);\n";
+
+ } else if (p_input_vars[1] == String()) {
+ //no lod
+ code += "\t\tvec4 _tex_read = textureLod( SCREEN_TEXTURE , " + p_input_vars[0] + ".xy, 0.0 );\n";
+ } else {
+ code += "\t\tvec4 _tex_read = textureLod( SCREEN_TEXTURE , " + p_input_vars[0] + ".xy , " + p_input_vars[1] + " );\n";
+ }
+
+ code += "\t\t" + p_output_vars[0] + " = _tex_read.rgb;\n";
+ code += "\t\t" + p_output_vars[1] + " = _tex_read.a;\n";
+ code += "\t}\n";
+ return code;
+ }
+
+ if (source == SOURCE_2D_TEXTURE && p_mode == Shader::MODE_CANVAS_ITEM && p_type == VisualShader::TYPE_FRAGMENT) {
+
+ String code = "\t{\n";
+ if (p_input_vars[0] == String()) { //none bound, do nothing
+
+ code += "\t\tvec4 _tex_read = vec4(0.0);\n";
+
+ } else if (p_input_vars[1] == String()) {
+ //no lod
+ code += "\t\tvec4 _tex_read = texture( TEXTURE , " + p_input_vars[0] + ".xy );\n";
+ } else {
+ code += "\t\tvec4 _tex_read = textureLod( TEXTURE , " + p_input_vars[0] + ".xy , " + p_input_vars[1] + " );\n";
+ }
+
+ code += "\t\t" + p_output_vars[0] + " = _tex_read.rgb;\n";
+ code += "\t\t" + p_output_vars[1] + " = _tex_read.a;\n";
+ code += "\t}\n";
+ return code;
+ }
+
+ if (source == SOURCE_2D_NORMAL && p_mode == Shader::MODE_CANVAS_ITEM && p_type == VisualShader::TYPE_FRAGMENT) {
+
+ String code = "\t{\n";
+ if (p_input_vars[0] == String()) { //none bound, do nothing
+
+ code += "\t\tvec4 _tex_read = vec4(0.0);\n";
+
+ } else if (p_input_vars[1] == String()) {
+ //no lod
+ code += "\t\tvec4 _tex_read = texture( NORMAL_TEXTURE , " + p_input_vars[0] + ".xy );\n";
+ } else {
+ code += "\t\tvec4 _tex_read = textureLod( NORMAL_TEXTURE , " + p_input_vars[0] + ".xy , " + p_input_vars[1] + " );\n";
+ }
+
+ code += "\t\t" + p_output_vars[0] + " = _tex_read.rgb;\n";
+ code += "\t\t" + p_output_vars[1] + " = _tex_read.a;\n";
+ code += "\t}\n";
+ return code;
+ }
+
+ //none
+ String code;
+ code += "\t" + p_output_vars[0] + " = vec3(0.0);\n";
+ code += "\t" + p_output_vars[1] + " = 1.0;\n";
+ return code;
+}
+
+void VisualShaderNodeTexture::set_source(Source p_source) {
+ source = p_source;
+ emit_changed();
+ emit_signal("editor_refresh_request");
+}
+
+VisualShaderNodeTexture::Source VisualShaderNodeTexture::get_source() const {
+ return source;
+}
+
+void VisualShaderNodeTexture::set_texture(Ref<Texture> p_value) {
+
+ texture = p_value;
+ emit_changed();
+}
+
+Ref<Texture> VisualShaderNodeTexture::get_texture() const {
+
+ return texture;
+}
+
+void VisualShaderNodeTexture::set_texture_type(TextureType p_type) {
+ texture_type = p_type;
+ emit_changed();
+}
+
+VisualShaderNodeTexture::TextureType VisualShaderNodeTexture::get_texture_type() const {
+ return texture_type;
+}
+
+Vector<StringName> VisualShaderNodeTexture::get_editable_properties() const {
+ Vector<StringName> props;
+ props.push_back("source");
+ if (source == SOURCE_TEXTURE) {
+ props.push_back("texture");
+ props.push_back("texture_type");
+ }
+ return props;
+}
+
+String VisualShaderNodeTexture::get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const {
+
+ if (source == SOURCE_TEXTURE) {
+ return String(); // all good
+ }
+
+ if (source == SOURCE_SCREEN && (p_mode == Shader::MODE_SPATIAL || p_mode == Shader::MODE_CANVAS_ITEM) && p_type == VisualShader::TYPE_FRAGMENT) {
+
+ return String(); // all good
+ }
+
+ if (source == SOURCE_2D_TEXTURE && p_mode == Shader::MODE_CANVAS_ITEM && p_type == VisualShader::TYPE_FRAGMENT) {
+
+ return String(); // all good
+ }
+
+ if (source == SOURCE_2D_NORMAL && p_mode == Shader::MODE_CANVAS_ITEM) {
+
+ return String(); // all good
+ }
+
+ return TTR("Invalid source for shader.");
+}
+
+void VisualShaderNodeTexture::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_source", "value"), &VisualShaderNodeTexture::set_source);
+ ClassDB::bind_method(D_METHOD("get_source"), &VisualShaderNodeTexture::get_source);
+
+ ClassDB::bind_method(D_METHOD("set_texture", "value"), &VisualShaderNodeTexture::set_texture);
+ ClassDB::bind_method(D_METHOD("get_texture"), &VisualShaderNodeTexture::get_texture);
+
+ ClassDB::bind_method(D_METHOD("set_texture_type", "value"), &VisualShaderNodeTexture::set_texture_type);
+ ClassDB::bind_method(D_METHOD("get_texture_type"), &VisualShaderNodeTexture::get_texture_type);
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "source", PROPERTY_HINT_ENUM, "Texture,Screen,Texture2D,NormalMap2D"), "set_source", "get_source");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_type", PROPERTY_HINT_ENUM, "Data,Color,Normalmap"), "set_texture_type", "get_texture_type");
+
+ BIND_ENUM_CONSTANT(SOURCE_TEXTURE);
+ BIND_ENUM_CONSTANT(SOURCE_SCREEN);
+ BIND_ENUM_CONSTANT(SOURCE_2D_TEXTURE);
+ BIND_ENUM_CONSTANT(SOURCE_2D_NORMAL);
+ BIND_ENUM_CONSTANT(TYPE_DATA);
+ BIND_ENUM_CONSTANT(TYPE_COLOR);
+ BIND_ENUM_CONSTANT(TYPE_NORMALMAP);
+}
+
+VisualShaderNodeTexture::VisualShaderNodeTexture() {
+ texture_type = TYPE_DATA;
+ source = SOURCE_TEXTURE;
+}
+
+////////////// CubeMap
+
+String VisualShaderNodeCubeMap::get_caption() const {
+ return "CubeMap";
+}
+
+int VisualShaderNodeCubeMap::get_input_port_count() const {
+ return 2;
+}
+VisualShaderNodeCubeMap::PortType VisualShaderNodeCubeMap::get_input_port_type(int p_port) const {
+ return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR;
+}
+String VisualShaderNodeCubeMap::get_input_port_name(int p_port) const {
+ return p_port == 0 ? "uv" : "lod";
+}
+
+int VisualShaderNodeCubeMap::get_output_port_count() const {
+ return 2;
+}
+VisualShaderNodeCubeMap::PortType VisualShaderNodeCubeMap::get_output_port_type(int p_port) const {
+ return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR;
+}
+String VisualShaderNodeCubeMap::get_output_port_name(int p_port) const {
+ return p_port == 0 ? "rgb" : "alpha";
+}
+
+Vector<VisualShader::DefaultTextureParam> VisualShaderNodeCubeMap::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const {
+ VisualShader::DefaultTextureParam dtp;
+ dtp.name = make_unique_id(p_type, p_id, "cube");
+ dtp.param = cube_map;
+ Vector<VisualShader::DefaultTextureParam> ret;
+ ret.push_back(dtp);
+ return ret;
+}
+
+String VisualShaderNodeCubeMap::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
+
+ String u = "uniform sampler2DCube " + make_unique_id(p_type, p_id, "cube");
+ switch (texture_type) {
+ case TYPE_DATA: break;
+ case TYPE_COLOR: u += " : hint_color"; break;
+ case TYPE_NORMALMAP: u += " : hint_normal"; break;
+ }
+ return u + ";";
+}
+
+String VisualShaderNodeCubeMap::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const {
+
+ String id = make_unique_id(p_type, p_id, "cube");
+ String code;
+ if (p_input_vars[0] == String()) { //none bound, do nothing
+
+ code += "\tvec4 " + id + "_read = vec4(0.0);\n";
+
+ } else if (p_input_vars[1] == String()) {
+ //no lod
+ code += "\tvec4 " + id + "_read = texture( " + id + " , " + p_input_vars[0] + " );\n";
+ } else {
+ code += "\tvec4 " + id + "_read = textureLod( " + id + " , " + p_input_vars[0] + " , " + p_input_vars[1] + " );\n";
+ }
+
+ code += "\t" + p_output_vars[0] + " = " + id + "_read.rgb;\n";
+ code += "\t" + p_output_vars[1] + " = " + id + "_read.a;\n";
+ return code;
+}
+
+void VisualShaderNodeCubeMap::set_cube_map(Ref<CubeMap> p_value) {
+
+ cube_map = p_value;
+ emit_changed();
+}
+
+Ref<CubeMap> VisualShaderNodeCubeMap::get_cube_map() const {
+
+ return cube_map;
+}
+
+void VisualShaderNodeCubeMap::set_texture_type(TextureType p_type) {
+ texture_type = p_type;
+ emit_changed();
+}
+
+VisualShaderNodeCubeMap::TextureType VisualShaderNodeCubeMap::get_texture_type() const {
+ return texture_type;
+}
+
+Vector<StringName> VisualShaderNodeCubeMap::get_editable_properties() const {
+ Vector<StringName> props;
+ props.push_back("cube_map");
+ props.push_back("texture_type");
+ return props;
+}
+
+void VisualShaderNodeCubeMap::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_cube_map", "value"), &VisualShaderNodeCubeMap::set_cube_map);
+ ClassDB::bind_method(D_METHOD("get_cube_map"), &VisualShaderNodeCubeMap::get_cube_map);
+
+ ClassDB::bind_method(D_METHOD("set_texture_type", "value"), &VisualShaderNodeCubeMap::set_texture_type);
+ ClassDB::bind_method(D_METHOD("get_texture_type"), &VisualShaderNodeCubeMap::get_texture_type);
+
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "cube_map", PROPERTY_HINT_RESOURCE_TYPE, "CubeMap"), "set_cube_map", "get_cube_map");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_type", PROPERTY_HINT_ENUM, "Data,Color,Normalmap"), "set_texture_type", "get_texture_type");
+
+ BIND_ENUM_CONSTANT(TYPE_DATA);
+ BIND_ENUM_CONSTANT(TYPE_COLOR);
+ BIND_ENUM_CONSTANT(TYPE_NORMALMAP);
+}
+
+VisualShaderNodeCubeMap::VisualShaderNodeCubeMap() {
+ texture_type = TYPE_DATA;
+}
+////////////// Scalar Op
+
+String VisualShaderNodeScalarOp::get_caption() const {
+ return "ScalarOp";
+}
+
+int VisualShaderNodeScalarOp::get_input_port_count() const {
+ return 2;
+}
+VisualShaderNodeScalarOp::PortType VisualShaderNodeScalarOp::get_input_port_type(int p_port) const {
+ return PORT_TYPE_SCALAR;
+}
+String VisualShaderNodeScalarOp::get_input_port_name(int p_port) const {
+ return p_port == 0 ? "a" : "b";
+}
+
+int VisualShaderNodeScalarOp::get_output_port_count() const {
+ return 1;
+}
+VisualShaderNodeScalarOp::PortType VisualShaderNodeScalarOp::get_output_port_type(int p_port) const {
+ return PORT_TYPE_SCALAR;
+}
+String VisualShaderNodeScalarOp::get_output_port_name(int p_port) const {
+ return "op"; //no output port means the editor will be used as port
+}
+
+String VisualShaderNodeScalarOp::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const {
+
+ String code = "\t" + p_output_vars[0] + " = ";
+ switch (op) {
+
+ case OP_ADD: code += p_input_vars[0] + " + " + p_input_vars[1] + ";\n"; break;
+ case OP_SUB: code += p_input_vars[0] + " - " + p_input_vars[1] + ";\n"; break;
+ case OP_MUL: code += p_input_vars[0] + " * " + p_input_vars[1] + ";\n"; break;
+ case OP_DIV: code += p_input_vars[0] + " / " + p_input_vars[1] + ";\n"; break;
+ case OP_MOD: code += "mod( " + p_input_vars[0] + " , " + p_input_vars[1] + " );\n"; break;
+ case OP_POW: code += "pow( " + p_input_vars[0] + " , " + p_input_vars[1] + " );\n"; break;
+ case OP_MAX: code += "max( " + p_input_vars[0] + " , " + p_input_vars[1] + " );\n"; break;
+ case OP_MIN: code += "min( " + p_input_vars[0] + " , " + p_input_vars[1] + " );\n"; break;
+ case OP_ATAN2: code += "atan( " + p_input_vars[0] + " , " + p_input_vars[1] + " );\n"; break;
+ }
+
+ return code;
+}
+
+void VisualShaderNodeScalarOp::set_operator(Operator p_op) {
+
+ op = p_op;
+ emit_changed();
+}
+
+VisualShaderNodeScalarOp::Operator VisualShaderNodeScalarOp::get_operator() const {
+
+ return op;
+}
+
+Vector<StringName> VisualShaderNodeScalarOp::get_editable_properties() const {
+ Vector<StringName> props;
+ props.push_back("operator");
+ return props;
+}
+
+void VisualShaderNodeScalarOp::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeScalarOp::set_operator);
+ ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeScalarOp::get_operator);
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "Add,Sub,Multiply,Divide,Remainder,Power,Max,Min,Atan2"), "set_operator", "get_operator");
+
+ BIND_ENUM_CONSTANT(OP_ADD);
+ BIND_ENUM_CONSTANT(OP_SUB);
+ BIND_ENUM_CONSTANT(OP_MUL);
+ BIND_ENUM_CONSTANT(OP_DIV);
+ BIND_ENUM_CONSTANT(OP_MOD);
+ BIND_ENUM_CONSTANT(OP_POW);
+ BIND_ENUM_CONSTANT(OP_MAX);
+ BIND_ENUM_CONSTANT(OP_MIN);
+ BIND_ENUM_CONSTANT(OP_ATAN2);
+}
+
+VisualShaderNodeScalarOp::VisualShaderNodeScalarOp() {
+ op = OP_ADD;
+ set_input_port_default_value(0, 0.0);
+ set_input_port_default_value(1, 0.0);
+}
+
+////////////// Vector Op
+
+String VisualShaderNodeVectorOp::get_caption() const {
+ return "VectorOp";
+}
+
+int VisualShaderNodeVectorOp::get_input_port_count() const {
+ return 2;
+}
+VisualShaderNodeVectorOp::PortType VisualShaderNodeVectorOp::get_input_port_type(int p_port) const {
+ return PORT_TYPE_VECTOR;
+}
+String VisualShaderNodeVectorOp::get_input_port_name(int p_port) const {
+ return p_port == 0 ? "a" : "b";
+}
+
+int VisualShaderNodeVectorOp::get_output_port_count() const {
+ return 1;
+}
+VisualShaderNodeVectorOp::PortType VisualShaderNodeVectorOp::get_output_port_type(int p_port) const {
+ return PORT_TYPE_VECTOR;
+}
+String VisualShaderNodeVectorOp::get_output_port_name(int p_port) const {
+ return "op"; //no output port means the editor will be used as port
+}
+
+String VisualShaderNodeVectorOp::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const {
+
+ String code = "\t" + p_output_vars[0] + " = ";
+ switch (op) {
+
+ case OP_ADD: code += p_input_vars[0] + " + " + p_input_vars[1] + ";\n"; break;
+ case OP_SUB: code += p_input_vars[0] + " - " + p_input_vars[1] + ";\n"; break;
+ case OP_MUL: code += p_input_vars[0] + " * " + p_input_vars[1] + ";\n"; break;
+ case OP_DIV: code += p_input_vars[0] + " / " + p_input_vars[1] + ";\n"; break;
+ case OP_MOD: code += "mod( " + p_input_vars[0] + " , " + p_input_vars[1] + " );\n"; break;
+ case OP_POW: code += "pow( " + p_input_vars[0] + " , " + p_input_vars[1] + " );\n"; break;
+ case OP_MAX: code += "max( " + p_input_vars[0] + " , " + p_input_vars[1] + " );\n"; break;
+ case OP_MIN: code += "min( " + p_input_vars[0] + " , " + p_input_vars[1] + " );\n"; break;
+ case OP_CROSS: code += "cross( " + p_input_vars[0] + " , " + p_input_vars[1] + " );\n"; break;
+ }
+
+ return code;
+}
+
+void VisualShaderNodeVectorOp::set_operator(Operator p_op) {
+
+ op = p_op;
+ emit_changed();
+}
+
+VisualShaderNodeVectorOp::Operator VisualShaderNodeVectorOp::get_operator() const {
+
+ return op;
+}
+
+Vector<StringName> VisualShaderNodeVectorOp::get_editable_properties() const {
+ Vector<StringName> props;
+ props.push_back("operator");
+ return props;
+}
+
+void VisualShaderNodeVectorOp::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeVectorOp::set_operator);
+ ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeVectorOp::get_operator);
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "Add,Sub,Multiply,Divide,Remainder,Power,Max,Min,Cross"), "set_operator", "get_operator");
+
+ BIND_ENUM_CONSTANT(OP_ADD);
+ BIND_ENUM_CONSTANT(OP_SUB);
+ BIND_ENUM_CONSTANT(OP_MUL);
+ BIND_ENUM_CONSTANT(OP_DIV);
+ BIND_ENUM_CONSTANT(OP_MOD);
+ BIND_ENUM_CONSTANT(OP_POW);
+ BIND_ENUM_CONSTANT(OP_MAX);
+ BIND_ENUM_CONSTANT(OP_MIN);
+ BIND_ENUM_CONSTANT(OP_CROSS);
+}
+
+VisualShaderNodeVectorOp::VisualShaderNodeVectorOp() {
+ op = OP_ADD;
+ set_input_port_default_value(0, Vector3());
+ set_input_port_default_value(1, Vector3());
+}
+
+////////////// Color Op
+
+String VisualShaderNodeColorOp::get_caption() const {
+ return "ColorOp";
+}
+
+int VisualShaderNodeColorOp::get_input_port_count() const {
+ return 2;
+}
+VisualShaderNodeColorOp::PortType VisualShaderNodeColorOp::get_input_port_type(int p_port) const {
+ return PORT_TYPE_VECTOR;
+}
+String VisualShaderNodeColorOp::get_input_port_name(int p_port) const {
+ return p_port == 0 ? "a" : "b";
+}
+
+int VisualShaderNodeColorOp::get_output_port_count() const {
+ return 1;
+}
+VisualShaderNodeColorOp::PortType VisualShaderNodeColorOp::get_output_port_type(int p_port) const {
+ return PORT_TYPE_VECTOR;
+}
+String VisualShaderNodeColorOp::get_output_port_name(int p_port) const {
+ return "op"; //no output port means the editor will be used as port
+}
+
+String VisualShaderNodeColorOp::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const {
+
+ String code;
+ static const char *axisn[3] = { "x", "y", "z" };
+ switch (op) {
+ case OP_SCREEN: {
+
+ code += "\t" + p_output_vars[0] + "=vec3(1.0)-(vec3(1.0)-" + p_input_vars[0] + ")*(vec3(1.0)-" + p_input_vars[1] + ");\n";
+ } break;
+ case OP_DIFFERENCE: {
+
+ code += "\t" + p_output_vars[0] + "=abs(" + p_input_vars[0] + "-" + p_input_vars[1] + ");\n";
+ } break;
+ case OP_DARKEN: {
+
+ code += "\t" + p_output_vars[0] + "=min(" + p_input_vars[0] + "," + p_input_vars[1] + ");\n";
+ } break;
+ case OP_LIGHTEN: {
+
+ code += "\t" + p_output_vars[0] + "=max(" + p_input_vars[0] + "," + p_input_vars[1] + ");\n";
+
+ } break;
+ case OP_OVERLAY: {
+
+ for (int i = 0; i < 3; i++) {
+ code += "\t{\n";
+ code += "\t\tfloat base=" + p_input_vars[0] + "." + axisn[i] + ";\n";
+ code += "\t\tfloat blend=" + p_input_vars[1] + "." + axisn[i] + ";\n";
+ code += "\t\tif (base < 0.5) {\n";
+ code += "\t\t\t" + p_output_vars[0] + "." + axisn[i] + " = 2.0 * base * blend;\n";
+ code += "\t\t} else {\n";
+ code += "\t\t\t" + p_output_vars[0] + "." + axisn[i] + " = 1.0 - 2.0 * (1.0 - blend) * (1.0 - base);\n";
+ code += "\t\t}\n";
+ code += "\t}\n";
+ }
+
+ } break;
+ case OP_DODGE: {
+
+ code += "\t" + p_output_vars[0] + "=(" + p_input_vars[0] + ")/(vec3(1.0)-" + p_input_vars[1] + ");\n";
+
+ } break;
+ case OP_BURN: {
+
+ code += "\t" + p_output_vars[0] + "=vec3(1.0)-(vec3(1.0)-" + p_input_vars[0] + ")/(" + p_input_vars[1] + ");\n";
+ } break;
+ case OP_SOFT_LIGHT: {
+
+ for (int i = 0; i < 3; i++) {
+ code += "\t{\n";
+ code += "\t\tfloat base=" + p_input_vars[0] + "." + axisn[i] + ";\n";
+ code += "\t\tfloat blend=" + p_input_vars[1] + "." + axisn[i] + ";\n";
+ code += "\t\tif (base < 0.5) {\n";
+ code += "\t\t\t" + p_output_vars[0] + "." + axisn[i] + " = (base * (blend+0.5));\n";
+ code += "\t\t} else {\n";
+ code += "\t\t\t" + p_output_vars[0] + "." + axisn[i] + " = (1.0 - (1.0-base) * (1.0-(blend-0.5)));\n";
+ code += "\t\t}\n";
+ code += "\t}\n";
+ }
+
+ } break;
+ case OP_HARD_LIGHT: {
+
+ for (int i = 0; i < 3; i++) {
+ code += "\t{\n";
+ code += "\t\tfloat base=" + p_input_vars[0] + "." + axisn[i] + ";\n";
+ code += "\t\tfloat blend=" + p_input_vars[1] + "." + axisn[i] + ";\n";
+ code += "\t\tif (base < 0.5) {\n";
+ code += "\t\t\t" + p_output_vars[0] + "." + axisn[i] + " = (base * (2.0*blend));\n";
+ code += "\t\t} else {\n";
+ code += "\t\t\t" + p_output_vars[0] + "." + axisn[i] + " = (1.0 - (1.0-base) * (1.0-2.0*(blend-0.5)));\n";
+ code += "\t\t}\n";
+ code += "\t}\n";
+ }
+
+ } break;
+ }
+
+ return code;
+}
+
+void VisualShaderNodeColorOp::set_operator(Operator p_op) {
+
+ op = p_op;
+ emit_changed();
+}
+
+VisualShaderNodeColorOp::Operator VisualShaderNodeColorOp::get_operator() const {
+
+ return op;
+}
+
+Vector<StringName> VisualShaderNodeColorOp::get_editable_properties() const {
+ Vector<StringName> props;
+ props.push_back("operator");
+ return props;
+}
+
+void VisualShaderNodeColorOp::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeColorOp::set_operator);
+ ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeColorOp::get_operator);
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "Screen,Difference,Darken,Lighten,Overlay,Dodge,Burn,SoftLight,HardLight"), "set_operator", "get_operator");
+
+ BIND_ENUM_CONSTANT(OP_SCREEN);
+ BIND_ENUM_CONSTANT(OP_DIFFERENCE);
+ BIND_ENUM_CONSTANT(OP_DARKEN);
+ BIND_ENUM_CONSTANT(OP_LIGHTEN);
+ BIND_ENUM_CONSTANT(OP_OVERLAY);
+ BIND_ENUM_CONSTANT(OP_DODGE);
+ BIND_ENUM_CONSTANT(OP_BURN);
+ BIND_ENUM_CONSTANT(OP_SOFT_LIGHT);
+ BIND_ENUM_CONSTANT(OP_HARD_LIGHT);
+}
+
+VisualShaderNodeColorOp::VisualShaderNodeColorOp() {
+ op = OP_SCREEN;
+ set_input_port_default_value(0, Vector3());
+ set_input_port_default_value(1, Vector3());
+}
+
+////////////// Transform Mult
+
+String VisualShaderNodeTransformMult::get_caption() const {
+ return "TransformMult";
+}
+
+int VisualShaderNodeTransformMult::get_input_port_count() const {
+ return 2;
+}
+VisualShaderNodeTransformMult::PortType VisualShaderNodeTransformMult::get_input_port_type(int p_port) const {
+ return PORT_TYPE_TRANSFORM;
+}
+String VisualShaderNodeTransformMult::get_input_port_name(int p_port) const {
+ return p_port == 0 ? "a" : "b";
+}
+
+int VisualShaderNodeTransformMult::get_output_port_count() const {
+ return 1;
+}
+VisualShaderNodeTransformMult::PortType VisualShaderNodeTransformMult::get_output_port_type(int p_port) const {
+ return PORT_TYPE_TRANSFORM;
+}
+String VisualShaderNodeTransformMult::get_output_port_name(int p_port) const {
+ return "mult"; //no output port means the editor will be used as port
+}
+
+String VisualShaderNodeTransformMult::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const {
+
+ if (op == OP_AxB) {
+ return "\t" + p_output_vars[0] + " = " + p_input_vars[0] + " * " + p_input_vars[1] + ";\n";
+ } else {
+ return "\t" + p_output_vars[0] + " = " + p_input_vars[1] + " * " + p_input_vars[0] + ";\n";
+ }
+}
+
+void VisualShaderNodeTransformMult::set_operator(Operator p_op) {
+
+ op = p_op;
+ emit_changed();
+}
+
+VisualShaderNodeTransformMult::Operator VisualShaderNodeTransformMult::get_operator() const {
+
+ return op;
+}
+
+Vector<StringName> VisualShaderNodeTransformMult::get_editable_properties() const {
+ Vector<StringName> props;
+ props.push_back("operator");
+ return props;
+}
+
+void VisualShaderNodeTransformMult::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeTransformMult::set_operator);
+ ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeTransformMult::get_operator);
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "A x B,B x A"), "set_operator", "get_operator");
+
+ BIND_ENUM_CONSTANT(OP_AxB);
+ BIND_ENUM_CONSTANT(OP_BxA);
+}
+
+VisualShaderNodeTransformMult::VisualShaderNodeTransformMult() {
+ op = OP_AxB;
+ set_input_port_default_value(0, Transform());
+ set_input_port_default_value(1, Transform());
+}
+
+////////////// TransformVec Mult
+
+String VisualShaderNodeTransformVecMult::get_caption() const {
+ return "TransformVectorMult";
+}
+
+int VisualShaderNodeTransformVecMult::get_input_port_count() const {
+ return 2;
+}
+VisualShaderNodeTransformVecMult::PortType VisualShaderNodeTransformVecMult::get_input_port_type(int p_port) const {
+ return p_port == 0 ? PORT_TYPE_TRANSFORM : PORT_TYPE_VECTOR;
+}
+String VisualShaderNodeTransformVecMult::get_input_port_name(int p_port) const {
+ return p_port == 0 ? "a" : "b";
+}
+
+int VisualShaderNodeTransformVecMult::get_output_port_count() const {
+ return 1;
+}
+VisualShaderNodeTransformVecMult::PortType VisualShaderNodeTransformVecMult::get_output_port_type(int p_port) const {
+ return PORT_TYPE_VECTOR;
+}
+String VisualShaderNodeTransformVecMult::get_output_port_name(int p_port) const {
+ return ""; //no output port means the editor will be used as port
+}
+
+String VisualShaderNodeTransformVecMult::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const {
+ if (op == OP_AxB) {
+ return "\t" + p_output_vars[0] + " = ( " + p_input_vars[0] + " * vec4(" + p_input_vars[1] + ", 1.0) ).xyz;\n";
+ } else if (op == OP_BxA) {
+ return "\t" + p_output_vars[0] + " = ( vec4(" + p_input_vars[1] + ", 1.0) * " + p_input_vars[0] + " ).xyz;\n";
+ } else if (op == OP_3x3_AxB) {
+ return "\t" + p_output_vars[0] + " = ( " + p_input_vars[0] + " * vec4(" + p_input_vars[1] + ", 0.0) ).xyz;\n";
+ } else {
+ return "\t" + p_output_vars[0] + " = ( vec4(" + p_input_vars[1] + ", 0.0) * " + p_input_vars[0] + " ).xyz;\n";
+ }
+}
+
+void VisualShaderNodeTransformVecMult::set_operator(Operator p_op) {
+
+ op = p_op;
+ emit_changed();
+}
+
+VisualShaderNodeTransformVecMult::Operator VisualShaderNodeTransformVecMult::get_operator() const {
+
+ return op;
+}
+
+Vector<StringName> VisualShaderNodeTransformVecMult::get_editable_properties() const {
+ Vector<StringName> props;
+ props.push_back("operator");
+ return props;
+}
+
+void VisualShaderNodeTransformVecMult::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeTransformVecMult::set_operator);
+ ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeTransformVecMult::get_operator);
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "A x B,B x A,A x B (3x3),B x A (3x3)"), "set_operator", "get_operator");
+
+ BIND_ENUM_CONSTANT(OP_AxB);
+ BIND_ENUM_CONSTANT(OP_BxA);
+ BIND_ENUM_CONSTANT(OP_3x3_AxB);
+ BIND_ENUM_CONSTANT(OP_3x3_BxA);
+}
+
+VisualShaderNodeTransformVecMult::VisualShaderNodeTransformVecMult() {
+ op = OP_AxB;
+ set_input_port_default_value(0, Transform());
+ set_input_port_default_value(1, Vector3());
+}
+
+////////////// Scalar Func
+
+String VisualShaderNodeScalarFunc::get_caption() const {
+ return "ScalarFunc";
+}
+
+int VisualShaderNodeScalarFunc::get_input_port_count() const {
+ return 1;
+}
+VisualShaderNodeScalarFunc::PortType VisualShaderNodeScalarFunc::get_input_port_type(int p_port) const {
+ return PORT_TYPE_SCALAR;
+}
+String VisualShaderNodeScalarFunc::get_input_port_name(int p_port) const {
+ return "";
+}
+
+int VisualShaderNodeScalarFunc::get_output_port_count() const {
+ return 1;
+}
+VisualShaderNodeScalarFunc::PortType VisualShaderNodeScalarFunc::get_output_port_type(int p_port) const {
+ return PORT_TYPE_SCALAR;
+}
+String VisualShaderNodeScalarFunc::get_output_port_name(int p_port) const {
+ return ""; //no output port means the editor will be used as port
+}
+
+String VisualShaderNodeScalarFunc::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const {
+
+ static const char *scalar_func_id[FUNC_NEGATE + 1] = {
+ "sin($)",
+ "cos($)",
+ "tan($)",
+ "asin($)",
+ "acos($)",
+ "atan($)",
+ "sinh($)",
+ "cosh($)",
+ "tanh($)",
+ "log($)",
+ "exp($)",
+ "sqrt($)",
+ "abs($)",
+ "sign($)",
+ "floor($)",
+ "round($)",
+ "ceil($)",
+ "fract($)",
+ "min(max($,0),1)",
+ "-($)",
+ };
+
+ return "\t" + p_output_vars[0] + " = " + String(scalar_func_id[func]).replace("$", p_input_vars[0]) + ";\n";
+}
+
+void VisualShaderNodeScalarFunc::set_function(Function p_func) {
+
+ func = p_func;
+ emit_changed();
+}
+
+VisualShaderNodeScalarFunc::Function VisualShaderNodeScalarFunc::get_function() const {
+
+ return func;
+}
+
+Vector<StringName> VisualShaderNodeScalarFunc::get_editable_properties() const {
+ Vector<StringName> props;
+ props.push_back("function");
+ return props;
+}
+
+void VisualShaderNodeScalarFunc::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeScalarFunc::set_function);
+ ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeScalarFunc::get_function);
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Sin,Cos,Tan,ASin,ACos,ATan,SinH,CosH,TanH,Log,Exp,Sqrt,Abs,Sign,Floor,Round,Ceil,Frac,Saturate,Negate"), "set_function", "get_function");
+
+ BIND_ENUM_CONSTANT(FUNC_SIN);
+ BIND_ENUM_CONSTANT(FUNC_COS);
+ BIND_ENUM_CONSTANT(FUNC_TAN);
+ BIND_ENUM_CONSTANT(FUNC_ASIN);
+ BIND_ENUM_CONSTANT(FUNC_ACOS);
+ BIND_ENUM_CONSTANT(FUNC_ATAN);
+ BIND_ENUM_CONSTANT(FUNC_SINH);
+ BIND_ENUM_CONSTANT(FUNC_COSH);
+ BIND_ENUM_CONSTANT(FUNC_TANH);
+ BIND_ENUM_CONSTANT(FUNC_LOG);
+ BIND_ENUM_CONSTANT(FUNC_EXP);
+ BIND_ENUM_CONSTANT(FUNC_SQRT);
+ BIND_ENUM_CONSTANT(FUNC_ABS);
+ BIND_ENUM_CONSTANT(FUNC_SIGN);
+ BIND_ENUM_CONSTANT(FUNC_FLOOR);
+ BIND_ENUM_CONSTANT(FUNC_ROUND);
+ BIND_ENUM_CONSTANT(FUNC_CEIL);
+ BIND_ENUM_CONSTANT(FUNC_FRAC);
+ BIND_ENUM_CONSTANT(FUNC_SATURATE);
+ BIND_ENUM_CONSTANT(FUNC_NEGATE);
+}
+
+VisualShaderNodeScalarFunc::VisualShaderNodeScalarFunc() {
+ func = FUNC_SIGN;
+ set_input_port_default_value(0, 0.0);
+}
+
+////////////// Vector Func
+
+String VisualShaderNodeVectorFunc::get_caption() const {
+ return "VectorFunc";
+}
+
+int VisualShaderNodeVectorFunc::get_input_port_count() const {
+ return 1;
+}
+VisualShaderNodeVectorFunc::PortType VisualShaderNodeVectorFunc::get_input_port_type(int p_port) const {
+ return PORT_TYPE_VECTOR;
+}
+String VisualShaderNodeVectorFunc::get_input_port_name(int p_port) const {
+ return "";
+}
+
+int VisualShaderNodeVectorFunc::get_output_port_count() const {
+ return 1;
+}
+VisualShaderNodeVectorFunc::PortType VisualShaderNodeVectorFunc::get_output_port_type(int p_port) const {
+ return PORT_TYPE_VECTOR;
+}
+String VisualShaderNodeVectorFunc::get_output_port_name(int p_port) const {
+ return ""; //no output port means the editor will be used as port
+}
+
+String VisualShaderNodeVectorFunc::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const {
+
+ static const char *vec_func_id[FUNC_HSV2RGB + 1] = {
+ "normalize($)",
+ "max(min($,vec3(1.0)),vec3(0.0))",
+ "-($)",
+ "1.0/($)",
+ "",
+ "",
+ };
+
+ String code;
+
+ if (func == FUNC_RGB2HSV) {
+ code += "\t{\n";
+ code += "\t\tvec3 c = " + p_input_vars[0] + ";\n";
+ code += "\t\tvec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n";
+ code += "\t\tvec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));\n";
+ code += "\t\tvec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));\n";
+ code += "\t\tfloat d = q.x - min(q.w, q.y);\n";
+ code += "\t\tfloat e = 1.0e-10;\n";
+ code += "\t\t" + p_output_vars[0] + "=vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n";
+ code += "\t}\n";
+ } else if (func == FUNC_HSV2RGB) {
+ code += "\t{\n";
+ code += "\t\tvec3 c = " + p_input_vars[0] + ";\n";
+ code += "\t\tvec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n";
+ code += "\t\tvec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);\n";
+ code += "\t\t" + p_output_vars[0] + "=c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);\n";
+ code += "\t}\n";
+
+ } else {
+ code += "\t" + p_output_vars[0] + "=" + String(vec_func_id[func]).replace("$", p_input_vars[0]) + ";\n";
+ }
+
+ return code;
+}
+
+void VisualShaderNodeVectorFunc::set_function(Function p_func) {
+
+ func = p_func;
+ emit_changed();
+}
+
+VisualShaderNodeVectorFunc::Function VisualShaderNodeVectorFunc::get_function() const {
+
+ return func;
+}
+
+Vector<StringName> VisualShaderNodeVectorFunc::get_editable_properties() const {
+ Vector<StringName> props;
+ props.push_back("function");
+ return props;
+}
+
+void VisualShaderNodeVectorFunc::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeVectorFunc::set_function);
+ ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeVectorFunc::get_function);
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Normalize,Saturate,Negate,Reciprocal,RGB2HSV,HSV2RGB"), "set_function", "get_function");
+
+ BIND_ENUM_CONSTANT(FUNC_NORMALIZE);
+ BIND_ENUM_CONSTANT(FUNC_SATURATE);
+ BIND_ENUM_CONSTANT(FUNC_NEGATE);
+ BIND_ENUM_CONSTANT(FUNC_RECIPROCAL);
+ BIND_ENUM_CONSTANT(FUNC_RGB2HSV);
+ BIND_ENUM_CONSTANT(FUNC_HSV2RGB);
+}
+
+VisualShaderNodeVectorFunc::VisualShaderNodeVectorFunc() {
+ func = FUNC_NORMALIZE;
+ set_input_port_default_value(0, Vector3());
+}
+
+////////////// Dot Product
+
+String VisualShaderNodeDotProduct::get_caption() const {
+ return "DotProduct";
+}
+
+int VisualShaderNodeDotProduct::get_input_port_count() const {
+ return 2;
+}
+VisualShaderNodeDotProduct::PortType VisualShaderNodeDotProduct::get_input_port_type(int p_port) const {
+ return PORT_TYPE_VECTOR;
+}
+String VisualShaderNodeDotProduct::get_input_port_name(int p_port) const {
+ return p_port == 0 ? "a" : "b";
+}
+
+int VisualShaderNodeDotProduct::get_output_port_count() const {
+ return 1;
+}
+VisualShaderNodeDotProduct::PortType VisualShaderNodeDotProduct::get_output_port_type(int p_port) const {
+ return PORT_TYPE_SCALAR;
+}
+String VisualShaderNodeDotProduct::get_output_port_name(int p_port) const {
+ return "dot";
+}
+
+String VisualShaderNodeDotProduct::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const {
+ return "\t" + p_output_vars[0] + " = dot( " + p_input_vars[0] + " , " + p_input_vars[1] + " );\n";
+}
+
+VisualShaderNodeDotProduct::VisualShaderNodeDotProduct() {
+ set_input_port_default_value(0, Vector3());
+ set_input_port_default_value(1, Vector3());
+}
+
+////////////// Vector Len
+
+String VisualShaderNodeVectorLen::get_caption() const {
+ return "VectorLen";
+}
+
+int VisualShaderNodeVectorLen::get_input_port_count() const {
+ return 1;
+}
+VisualShaderNodeVectorLen::PortType VisualShaderNodeVectorLen::get_input_port_type(int p_port) const {
+ return PORT_TYPE_VECTOR;
+}
+String VisualShaderNodeVectorLen::get_input_port_name(int p_port) const {
+ return "";
+}
+
+int VisualShaderNodeVectorLen::get_output_port_count() const {
+ return 1;
+}
+VisualShaderNodeVectorLen::PortType VisualShaderNodeVectorLen::get_output_port_type(int p_port) const {
+ return PORT_TYPE_SCALAR;
+}
+String VisualShaderNodeVectorLen::get_output_port_name(int p_port) const {
+ return "length";
+}
+
+String VisualShaderNodeVectorLen::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const {
+ return "\t" + p_output_vars[0] + " = length( " + p_input_vars[0] + " );\n";
+}
+
+VisualShaderNodeVectorLen::VisualShaderNodeVectorLen() {
+ set_input_port_default_value(0, Vector3());
+}
+
+////////////// Scalar Interp
+
+String VisualShaderNodeScalarInterp::get_caption() const {
+ return "ScalarInterp";
+}
+
+int VisualShaderNodeScalarInterp::get_input_port_count() const {
+ return 3;
+}
+VisualShaderNodeScalarInterp::PortType VisualShaderNodeScalarInterp::get_input_port_type(int p_port) const {
+ return PORT_TYPE_SCALAR;
+}
+String VisualShaderNodeScalarInterp::get_input_port_name(int p_port) const {
+ if (p_port == 0) {
+ return "a";
+ } else if (p_port == 1) {
+ return "b";
+ } else {
+ return "c";
+ }
+}
+
+int VisualShaderNodeScalarInterp::get_output_port_count() const {
+ return 1;
+}
+VisualShaderNodeScalarInterp::PortType VisualShaderNodeScalarInterp::get_output_port_type(int p_port) const {
+ return PORT_TYPE_SCALAR;
+}
+String VisualShaderNodeScalarInterp::get_output_port_name(int p_port) const {
+ return "mix";
+}
+
+String VisualShaderNodeScalarInterp::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const {
+ return "\t" + p_output_vars[0] + " = mix( " + p_input_vars[0] + " , " + p_input_vars[1] + " , " + p_input_vars[2] + " );\n";
+}
+
+VisualShaderNodeScalarInterp::VisualShaderNodeScalarInterp() {
+ set_input_port_default_value(0, 0.0);
+ set_input_port_default_value(1, 0.0);
+ set_input_port_default_value(2, 0.0);
+}
+
+////////////// Vector Interp
+
+String VisualShaderNodeVectorInterp::get_caption() const {
+ return "VectorInterp";
+}
+
+int VisualShaderNodeVectorInterp::get_input_port_count() const {
+ return 3;
+}
+VisualShaderNodeVectorInterp::PortType VisualShaderNodeVectorInterp::get_input_port_type(int p_port) const {
+ return PORT_TYPE_VECTOR;
+}
+String VisualShaderNodeVectorInterp::get_input_port_name(int p_port) const {
+ if (p_port == 0) {
+ return "a";
+ } else if (p_port == 1) {
+ return "b";
+ } else {
+ return "c";
+ }
+}
+
+int VisualShaderNodeVectorInterp::get_output_port_count() const {
+ return 1;
+}
+VisualShaderNodeVectorInterp::PortType VisualShaderNodeVectorInterp::get_output_port_type(int p_port) const {
+ return PORT_TYPE_VECTOR;
+}
+String VisualShaderNodeVectorInterp::get_output_port_name(int p_port) const {
+ return "mix";
+}
+
+String VisualShaderNodeVectorInterp::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const {
+ return "\t" + p_output_vars[0] + " = mix( " + p_input_vars[0] + " , " + p_input_vars[1] + " , " + p_input_vars[2] + " );\n";
+}
+
+VisualShaderNodeVectorInterp::VisualShaderNodeVectorInterp() {
+ set_input_port_default_value(0, Vector3());
+ set_input_port_default_value(1, Vector3());
+ set_input_port_default_value(2, Vector3());
+}
+
+////////////// Vector Compose
+String VisualShaderNodeVectorCompose::get_caption() const {
+ return "VectorCompose";
+}
+
+int VisualShaderNodeVectorCompose::get_input_port_count() const {
+ return 3;
+}
+VisualShaderNodeVectorCompose::PortType VisualShaderNodeVectorCompose::get_input_port_type(int p_port) const {
+ return PORT_TYPE_SCALAR;
+}
+String VisualShaderNodeVectorCompose::get_input_port_name(int p_port) const {
+ if (p_port == 0) {
+ return "x";
+ } else if (p_port == 1) {
+ return "y";
+ } else {
+ return "z";
+ }
+}
+
+int VisualShaderNodeVectorCompose::get_output_port_count() const {
+ return 1;
+}
+VisualShaderNodeVectorCompose::PortType VisualShaderNodeVectorCompose::get_output_port_type(int p_port) const {
+ return PORT_TYPE_VECTOR;
+}
+String VisualShaderNodeVectorCompose::get_output_port_name(int p_port) const {
+ return "vec";
+}
+
+String VisualShaderNodeVectorCompose::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const {
+ return "\t" + p_output_vars[0] + " = vec3( " + p_input_vars[0] + " , " + p_input_vars[1] + " , " + p_input_vars[2] + " );\n";
+}
+
+VisualShaderNodeVectorCompose::VisualShaderNodeVectorCompose() {
+
+ set_input_port_default_value(0, 0.0);
+ set_input_port_default_value(1, 0.0);
+ set_input_port_default_value(2, 0.0);
+}
+
+////////////// Transform Compose
+
+String VisualShaderNodeTransformCompose::get_caption() const {
+ return "TransformCompose";
+}
+
+int VisualShaderNodeTransformCompose::get_input_port_count() const {
+ return 4;
+}
+VisualShaderNodeTransformCompose::PortType VisualShaderNodeTransformCompose::get_input_port_type(int p_port) const {
+ return PORT_TYPE_VECTOR;
+}
+String VisualShaderNodeTransformCompose::get_input_port_name(int p_port) const {
+ if (p_port == 0) {
+ return "x";
+ } else if (p_port == 1) {
+ return "y";
+ } else if (p_port == 2) {
+ return "z";
+ } else {
+ return "origin";
+ }
+}
+
+int VisualShaderNodeTransformCompose::get_output_port_count() const {
+ return 1;
+}
+VisualShaderNodeTransformCompose::PortType VisualShaderNodeTransformCompose::get_output_port_type(int p_port) const {
+ return PORT_TYPE_TRANSFORM;
+}
+String VisualShaderNodeTransformCompose::get_output_port_name(int p_port) const {
+ return "xform";
+}
+
+String VisualShaderNodeTransformCompose::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const {
+ return "\t" + p_output_vars[0] + " = mat4( vec4(" + p_input_vars[0] + ", 0.0) , vec4(" + p_input_vars[1] + ", 0.0) , vec4(" + p_input_vars[2] + ",0.0), vec4(" + p_input_vars[3] + ",1.0) );\n";
+}
+
+VisualShaderNodeTransformCompose::VisualShaderNodeTransformCompose() {
+
+ set_input_port_default_value(0, Vector3());
+ set_input_port_default_value(1, Vector3());
+ set_input_port_default_value(2, Vector3());
+ set_input_port_default_value(3, Vector3());
+}
+
+////////////// Vector Decompose
+String VisualShaderNodeVectorDecompose::get_caption() const {
+ return "VectorDecompose";
+}
+
+int VisualShaderNodeVectorDecompose::get_input_port_count() const {
+ return 1;
+}
+VisualShaderNodeVectorDecompose::PortType VisualShaderNodeVectorDecompose::get_input_port_type(int p_port) const {
+ return PORT_TYPE_VECTOR;
+}
+String VisualShaderNodeVectorDecompose::get_input_port_name(int p_port) const {
+ return "vec";
+}
+
+int VisualShaderNodeVectorDecompose::get_output_port_count() const {
+ return 3;
+}
+VisualShaderNodeVectorDecompose::PortType VisualShaderNodeVectorDecompose::get_output_port_type(int p_port) const {
+ return PORT_TYPE_SCALAR;
+}
+String VisualShaderNodeVectorDecompose::get_output_port_name(int p_port) const {
+ if (p_port == 0) {
+ return "x";
+ } else if (p_port == 1) {
+ return "y";
+ } else {
+ return "z";
+ }
+}
+
+String VisualShaderNodeVectorDecompose::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const {
+ String code;
+ code += "\t" + p_output_vars[0] + " = " + p_input_vars[0] + ".x;\n";
+ code += "\t" + p_output_vars[1] + " = " + p_input_vars[0] + ".y;\n";
+ code += "\t" + p_output_vars[2] + " = " + p_input_vars[0] + ".z;\n";
+ return code;
+}
+
+VisualShaderNodeVectorDecompose::VisualShaderNodeVectorDecompose() {
+ set_input_port_default_value(0, Vector3());
+}
+
+////////////// Transform Decompose
+
+String VisualShaderNodeTransformDecompose::get_caption() const {
+ return "TransformDecompose";
+}
+
+int VisualShaderNodeTransformDecompose::get_input_port_count() const {
+ return 1;
+}
+VisualShaderNodeTransformDecompose::PortType VisualShaderNodeTransformDecompose::get_input_port_type(int p_port) const {
+ return PORT_TYPE_TRANSFORM;
+}
+String VisualShaderNodeTransformDecompose::get_input_port_name(int p_port) const {
+ return "xform";
+}
+
+int VisualShaderNodeTransformDecompose::get_output_port_count() const {
+ return 4;
+}
+VisualShaderNodeTransformDecompose::PortType VisualShaderNodeTransformDecompose::get_output_port_type(int p_port) const {
+ return PORT_TYPE_VECTOR;
+}
+String VisualShaderNodeTransformDecompose::get_output_port_name(int p_port) const {
+ if (p_port == 0) {
+ return "x";
+ } else if (p_port == 1) {
+ return "y";
+ } else if (p_port == 2) {
+ return "z";
+ } else {
+ return "origin";
+ }
+}
+
+String VisualShaderNodeTransformDecompose::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const {
+ String code;
+ code += "\t" + p_output_vars[0] + " = " + p_input_vars[0] + "[0].xyz;\n";
+ code += "\t" + p_output_vars[1] + " = " + p_input_vars[0] + "[1].xyz;\n";
+ code += "\t" + p_output_vars[2] + " = " + p_input_vars[0] + "[2].xyz;\n";
+ code += "\t" + p_output_vars[3] + " = " + p_input_vars[0] + "[3].xyz;\n";
+ return code;
+}
+
+VisualShaderNodeTransformDecompose::VisualShaderNodeTransformDecompose() {
+ set_input_port_default_value(0, Transform());
+}
+
+////////////// Scalar Uniform
+
+String VisualShaderNodeScalarUniform::get_caption() const {
+ return "ScalarUniform";
+}
+
+int VisualShaderNodeScalarUniform::get_input_port_count() const {
+ return 0;
+}
+VisualShaderNodeScalarUniform::PortType VisualShaderNodeScalarUniform::get_input_port_type(int p_port) const {
+ return PORT_TYPE_SCALAR;
+}
+String VisualShaderNodeScalarUniform::get_input_port_name(int p_port) const {
+ return String();
+}
+
+int VisualShaderNodeScalarUniform::get_output_port_count() const {
+ return 1;
+}
+VisualShaderNodeScalarUniform::PortType VisualShaderNodeScalarUniform::get_output_port_type(int p_port) const {
+ return PORT_TYPE_SCALAR;
+}
+String VisualShaderNodeScalarUniform::get_output_port_name(int p_port) const {
+ return ""; //no output port means the editor will be used as port
+}
+
+String VisualShaderNodeScalarUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
+ return "uniform float " + get_uniform_name() + ";\n";
+}
+String VisualShaderNodeScalarUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const {
+ return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
+}
+
+VisualShaderNodeScalarUniform::VisualShaderNodeScalarUniform() {
+}
+
+////////////// Color Uniform
+
+String VisualShaderNodeColorUniform::get_caption() const {
+ return "ColorUniform";
+}
+
+int VisualShaderNodeColorUniform::get_input_port_count() const {
+ return 0;
+}
+VisualShaderNodeColorUniform::PortType VisualShaderNodeColorUniform::get_input_port_type(int p_port) const {
+ return PORT_TYPE_VECTOR;
+}
+String VisualShaderNodeColorUniform::get_input_port_name(int p_port) const {
+ return String();
+}
+
+int VisualShaderNodeColorUniform::get_output_port_count() const {
+ return 2;
+}
+VisualShaderNodeColorUniform::PortType VisualShaderNodeColorUniform::get_output_port_type(int p_port) const {
+ return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR;
+}
+String VisualShaderNodeColorUniform::get_output_port_name(int p_port) const {
+ return p_port == 0 ? "color" : "alpha"; //no output port means the editor will be used as port
+}
+
+String VisualShaderNodeColorUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
+
+ return "uniform vec4 " + get_uniform_name() + " : hint_color;\n";
+}
+
+String VisualShaderNodeColorUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const {
+ String code = "\t" + p_output_vars[0] + " = " + get_uniform_name() + ".rgb;\n";
+ code += "\t" + p_output_vars[1] + " = " + get_uniform_name() + ".a;\n";
+ return code;
+}
+
+VisualShaderNodeColorUniform::VisualShaderNodeColorUniform() {
+}
+
+////////////// Vector Uniform
+
+String VisualShaderNodeVec3Uniform::get_caption() const {
+ return "VectorUniform";
+}
+
+int VisualShaderNodeVec3Uniform::get_input_port_count() const {
+ return 0;
+}
+VisualShaderNodeVec3Uniform::PortType VisualShaderNodeVec3Uniform::get_input_port_type(int p_port) const {
+ return PORT_TYPE_VECTOR;
+}
+String VisualShaderNodeVec3Uniform::get_input_port_name(int p_port) const {
+ return String();
+}
+
+int VisualShaderNodeVec3Uniform::get_output_port_count() const {
+ return 1;
+}
+VisualShaderNodeVec3Uniform::PortType VisualShaderNodeVec3Uniform::get_output_port_type(int p_port) const {
+ return PORT_TYPE_VECTOR;
+}
+String VisualShaderNodeVec3Uniform::get_output_port_name(int p_port) const {
+ return ""; //no output port means the editor will be used as port
+}
+String VisualShaderNodeVec3Uniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
+ return "uniform vec3 " + get_uniform_name() + ";\n";
+}
+
+String VisualShaderNodeVec3Uniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const {
+ return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
+}
+
+VisualShaderNodeVec3Uniform::VisualShaderNodeVec3Uniform() {
+}
+
+////////////// Transform Uniform
+
+String VisualShaderNodeTransformUniform::get_caption() const {
+ return "TransformUniform";
+}
+
+int VisualShaderNodeTransformUniform::get_input_port_count() const {
+ return 0;
+}
+VisualShaderNodeTransformUniform::PortType VisualShaderNodeTransformUniform::get_input_port_type(int p_port) const {
+ return PORT_TYPE_VECTOR;
+}
+String VisualShaderNodeTransformUniform::get_input_port_name(int p_port) const {
+ return String();
+}
+
+int VisualShaderNodeTransformUniform::get_output_port_count() const {
+ return 1;
+}
+VisualShaderNodeTransformUniform::PortType VisualShaderNodeTransformUniform::get_output_port_type(int p_port) const {
+ return PORT_TYPE_TRANSFORM;
+}
+String VisualShaderNodeTransformUniform::get_output_port_name(int p_port) const {
+ return ""; //no output port means the editor will be used as port
+}
+String VisualShaderNodeTransformUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
+ return "uniform mat4 " + get_uniform_name() + ";\n";
+}
+
+String VisualShaderNodeTransformUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const {
+ return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
+}
+
+VisualShaderNodeTransformUniform::VisualShaderNodeTransformUniform() {
+}
+
+////////////// Texture Uniform
+
+String VisualShaderNodeTextureUniform::get_caption() const {
+ return "TextureUniform";
+}
+
+int VisualShaderNodeTextureUniform::get_input_port_count() const {
+ return 2;
+}
+VisualShaderNodeTextureUniform::PortType VisualShaderNodeTextureUniform::get_input_port_type(int p_port) const {
+ return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR;
+}
+String VisualShaderNodeTextureUniform::get_input_port_name(int p_port) const {
+ return p_port == 0 ? "uv" : "lod";
+}
+
+int VisualShaderNodeTextureUniform::get_output_port_count() const {
+ return 2;
+}
+VisualShaderNodeTextureUniform::PortType VisualShaderNodeTextureUniform::get_output_port_type(int p_port) const {
+ return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR;
+}
+String VisualShaderNodeTextureUniform::get_output_port_name(int p_port) const {
+ return p_port == 0 ? "rgb" : "alpha";
+}
+
+String VisualShaderNodeTextureUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
+ String code = "uniform sampler2D " + get_uniform_name();
+
+ switch (texture_type) {
+ case TYPE_DATA:
+ if (color_default == COLOR_DEFAULT_BLACK)
+ code += " : hint_black;\n";
+ else
+ code += ";\n";
+ break;
+ case TYPE_COLOR:
+ if (color_default == COLOR_DEFAULT_BLACK)
+ code += " : hint_black_albedo;\n";
+ else
+ code += " : hint_albedo;\n";
+ break;
+ case TYPE_NORMALMAP: code += " : hint_normal;\n"; break;
+ case TYPE_ANISO: code += " : hint_aniso;\n"; break;
+ }
+
+ return code;
+}
+
+String VisualShaderNodeTextureUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const {
+
+ String id = get_uniform_name();
+ String code = "\t{\n";
+ if (p_input_vars[0] == String()) { //none bound, do nothing
+
+ code += "\t\tvec4 n_tex_read = vec4(0.0);\n";
+ } else if (p_input_vars[1] == String()) {
+ //no lod
+ code += "\t\tvec4 n_tex_read = texture( " + id + " , " + p_input_vars[0] + ".xy );\n";
+ } else {
+ code += "\t\tvec4 n_tex_read = textureLod( " + id + " , " + p_input_vars[0] + ".xy , " + p_input_vars[1] + " );\n";
+ }
+
+ code += "\t\t" + p_output_vars[0] + " = n_tex_read.rgb;\n";
+ code += "\t\t" + p_output_vars[1] + " = n_tex_read.a;\n";
+ code += "\t}\n";
+ return code;
+}
+
+void VisualShaderNodeTextureUniform::set_texture_type(TextureType p_type) {
+
+ texture_type = p_type;
+ emit_changed();
+}
+
+VisualShaderNodeTextureUniform::TextureType VisualShaderNodeTextureUniform::get_texture_type() const {
+ return texture_type;
+}
+
+void VisualShaderNodeTextureUniform::set_color_default(ColorDefault p_default) {
+ color_default = p_default;
+ emit_changed();
+}
+VisualShaderNodeTextureUniform::ColorDefault VisualShaderNodeTextureUniform::get_color_default() const {
+ return color_default;
+}
+
+Vector<StringName> VisualShaderNodeTextureUniform::get_editable_properties() const {
+ Vector<StringName> props;
+ props.push_back("texture_type");
+ props.push_back("color_default");
+ return props;
+}
+
+void VisualShaderNodeTextureUniform::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_texture_type", "type"), &VisualShaderNodeTextureUniform::set_texture_type);
+ ClassDB::bind_method(D_METHOD("get_texture_type"), &VisualShaderNodeTextureUniform::get_texture_type);
+
+ ClassDB::bind_method(D_METHOD("set_color_default", "type"), &VisualShaderNodeTextureUniform::set_color_default);
+ ClassDB::bind_method(D_METHOD("get_color_default"), &VisualShaderNodeTextureUniform::get_color_default);
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_type", PROPERTY_HINT_ENUM, "Data,Color,Normalmap,Aniso"), "set_texture_type", "get_texture_type");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "color_default", PROPERTY_HINT_ENUM, "White Default,Black Default"), "set_color_default", "get_color_default");
+
+ BIND_ENUM_CONSTANT(TYPE_DATA);
+ BIND_ENUM_CONSTANT(TYPE_COLOR);
+ BIND_ENUM_CONSTANT(TYPE_NORMALMAP);
+ BIND_ENUM_CONSTANT(TYPE_ANISO);
+
+ BIND_ENUM_CONSTANT(COLOR_DEFAULT_WHITE);
+ BIND_ENUM_CONSTANT(COLOR_DEFAULT_BLACK);
+}
+
+VisualShaderNodeTextureUniform::VisualShaderNodeTextureUniform() {
+ texture_type = TYPE_DATA;
+ color_default = COLOR_DEFAULT_WHITE;
+}
+
+////////////// CubeMap Uniform
+
+String VisualShaderNodeCubeMapUniform::get_caption() const {
+ return "CubeMapUniform";
+}
+
+int VisualShaderNodeCubeMapUniform::get_input_port_count() const {
+ return 2;
+}
+VisualShaderNodeCubeMapUniform::PortType VisualShaderNodeCubeMapUniform::get_input_port_type(int p_port) const {
+ return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR;
+}
+String VisualShaderNodeCubeMapUniform::get_input_port_name(int p_port) const {
+ return p_port == 0 ? "normal" : "lod";
+}
+
+int VisualShaderNodeCubeMapUniform::get_output_port_count() const {
+ return 2;
+}
+VisualShaderNodeCubeMapUniform::PortType VisualShaderNodeCubeMapUniform::get_output_port_type(int p_port) const {
+ return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR;
+}
+String VisualShaderNodeCubeMapUniform::get_output_port_name(int p_port) const {
+ return p_port == 0 ? "rgb" : "alpha";
+}
+
+String VisualShaderNodeCubeMapUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const {
+ return String();
+}
+
+VisualShaderNodeCubeMapUniform::VisualShaderNodeCubeMapUniform() {
+}
diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h
new file mode 100644
index 0000000000..2ede36fbc8
--- /dev/null
+++ b/scene/resources/visual_shader_nodes.h
@@ -0,0 +1,861 @@
+#ifndef VISUAL_SHADER_NODES_H
+#define VISUAL_SHADER_NODES_H
+
+#include "scene/resources/visual_shader.h"
+
+/// CONSTANTS ///
+
+class VisualShaderNodeScalarConstant : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeScalarConstant, VisualShaderNode)
+ float constant;
+
+protected:
+ static void _bind_methods();
+
+public:
+ virtual String get_caption() const;
+
+ virtual int get_input_port_count() const;
+ virtual PortType get_input_port_type(int p_port) const;
+ virtual String get_input_port_name(int p_port) const;
+
+ virtual int get_output_port_count() const;
+ virtual PortType get_output_port_type(int p_port) const;
+ virtual String get_output_port_name(int p_port) const;
+
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+
+ void set_constant(float p_value);
+ float get_constant() const;
+
+ virtual Vector<StringName> get_editable_properties() const;
+
+ VisualShaderNodeScalarConstant();
+};
+
+class VisualShaderNodeColorConstant : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeColorConstant, VisualShaderNode)
+ Color constant;
+
+protected:
+ static void _bind_methods();
+
+public:
+ virtual String get_caption() const;
+
+ virtual int get_input_port_count() const;
+ virtual PortType get_input_port_type(int p_port) const;
+ virtual String get_input_port_name(int p_port) const;
+
+ virtual int get_output_port_count() const;
+ virtual PortType get_output_port_type(int p_port) const;
+ virtual String get_output_port_name(int p_port) const;
+
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+
+ void set_constant(Color p_value);
+ Color get_constant() const;
+
+ virtual Vector<StringName> get_editable_properties() const;
+
+ VisualShaderNodeColorConstant();
+};
+
+class VisualShaderNodeVec3Constant : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeVec3Constant, VisualShaderNode)
+ Vector3 constant;
+
+protected:
+ static void _bind_methods();
+
+public:
+ virtual String get_caption() const;
+
+ virtual int get_input_port_count() const;
+ virtual PortType get_input_port_type(int p_port) const;
+ virtual String get_input_port_name(int p_port) const;
+
+ virtual int get_output_port_count() const;
+ virtual PortType get_output_port_type(int p_port) const;
+ virtual String get_output_port_name(int p_port) const;
+
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+
+ void set_constant(Vector3 p_value);
+ Vector3 get_constant() const;
+
+ virtual Vector<StringName> get_editable_properties() const;
+
+ VisualShaderNodeVec3Constant();
+};
+
+class VisualShaderNodeTransformConstant : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeTransformConstant, VisualShaderNode)
+ Transform constant;
+
+protected:
+ static void _bind_methods();
+
+public:
+ virtual String get_caption() const;
+
+ virtual int get_input_port_count() const;
+ virtual PortType get_input_port_type(int p_port) const;
+ virtual String get_input_port_name(int p_port) const;
+
+ virtual int get_output_port_count() const;
+ virtual PortType get_output_port_type(int p_port) const;
+ virtual String get_output_port_name(int p_port) const;
+
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+
+ void set_constant(Transform p_value);
+ Transform get_constant() const;
+
+ virtual Vector<StringName> get_editable_properties() const;
+
+ VisualShaderNodeTransformConstant();
+};
+
+//////////////////////////////////
+
+class VisualShaderNodeTexture : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeTexture, VisualShaderNode)
+ Ref<Texture> texture;
+
+public:
+ enum Source {
+ SOURCE_TEXTURE,
+ SOURCE_SCREEN,
+ SOURCE_2D_TEXTURE,
+ SOURCE_2D_NORMAL
+ };
+
+ enum TextureType {
+ TYPE_DATA,
+ TYPE_COLOR,
+ TYPE_NORMALMAP
+ };
+
+private:
+ Source source;
+ TextureType texture_type;
+
+protected:
+ static void _bind_methods();
+
+public:
+ virtual String get_caption() const;
+
+ virtual int get_input_port_count() const;
+ virtual PortType get_input_port_type(int p_port) const;
+ virtual String get_input_port_name(int p_port) const;
+
+ virtual int get_output_port_count() const;
+ virtual PortType get_output_port_type(int p_port) const;
+ virtual String get_output_port_name(int p_port) const;
+
+ virtual Vector<VisualShader::DefaultTextureParam> get_default_texture_parameters(VisualShader::Type p_type, int p_id) const;
+ virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const;
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+
+ void set_source(Source p_source);
+ Source get_source() const;
+
+ void set_texture(Ref<Texture> p_value);
+ Ref<Texture> get_texture() const;
+
+ void set_texture_type(TextureType p_type);
+ TextureType get_texture_type() const;
+
+ virtual Vector<StringName> get_editable_properties() const;
+
+ virtual String get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const;
+
+ VisualShaderNodeTexture();
+};
+
+VARIANT_ENUM_CAST(VisualShaderNodeTexture::TextureType)
+VARIANT_ENUM_CAST(VisualShaderNodeTexture::Source)
+
+//////////////////////////////////
+
+class VisualShaderNodeCubeMap : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeCubeMap, VisualShaderNode)
+ Ref<CubeMap> cube_map;
+
+public:
+ enum TextureType {
+ TYPE_DATA,
+ TYPE_COLOR,
+ TYPE_NORMALMAP
+ };
+
+private:
+ TextureType texture_type;
+
+protected:
+ static void _bind_methods();
+
+public:
+ virtual String get_caption() const;
+
+ virtual int get_input_port_count() const;
+ virtual PortType get_input_port_type(int p_port) const;
+ virtual String get_input_port_name(int p_port) const;
+
+ virtual int get_output_port_count() const;
+ virtual PortType get_output_port_type(int p_port) const;
+ virtual String get_output_port_name(int p_port) const;
+
+ virtual Vector<VisualShader::DefaultTextureParam> get_default_texture_parameters(VisualShader::Type p_type, int p_id) const;
+ virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const;
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+
+ void set_cube_map(Ref<CubeMap> p_value);
+ Ref<CubeMap> get_cube_map() const;
+
+ void set_texture_type(TextureType p_type);
+ TextureType get_texture_type() const;
+
+ virtual Vector<StringName> get_editable_properties() const;
+
+ VisualShaderNodeCubeMap();
+};
+
+VARIANT_ENUM_CAST(VisualShaderNodeCubeMap::TextureType)
+///////////////////////////////////////
+
+class VisualShaderNodeScalarOp : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeScalarOp, VisualShaderNode)
+
+public:
+ enum Operator {
+ OP_ADD,
+ OP_SUB,
+ OP_MUL,
+ OP_DIV,
+ OP_MOD,
+ OP_POW,
+ OP_MAX,
+ OP_MIN,
+ OP_ATAN2
+ };
+
+protected:
+ Operator op;
+
+ static void _bind_methods();
+
+public:
+ virtual String get_caption() const;
+
+ virtual int get_input_port_count() const;
+ virtual PortType get_input_port_type(int p_port) const;
+ virtual String get_input_port_name(int p_port) const;
+
+ virtual int get_output_port_count() const;
+ virtual PortType get_output_port_type(int p_port) const;
+ virtual String get_output_port_name(int p_port) const;
+
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+
+ void set_operator(Operator p_op);
+ Operator get_operator() const;
+
+ virtual Vector<StringName> get_editable_properties() const;
+
+ VisualShaderNodeScalarOp();
+};
+
+VARIANT_ENUM_CAST(VisualShaderNodeScalarOp::Operator)
+
+class VisualShaderNodeVectorOp : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeVectorOp, VisualShaderNode)
+
+public:
+ enum Operator {
+ OP_ADD,
+ OP_SUB,
+ OP_MUL,
+ OP_DIV,
+ OP_MOD,
+ OP_POW,
+ OP_MAX,
+ OP_MIN,
+ OP_CROSS
+
+ };
+
+protected:
+ Operator op;
+
+ static void _bind_methods();
+
+public:
+ virtual String get_caption() const;
+
+ virtual int get_input_port_count() const;
+ virtual PortType get_input_port_type(int p_port) const;
+ virtual String get_input_port_name(int p_port) const;
+
+ virtual int get_output_port_count() const;
+ virtual PortType get_output_port_type(int p_port) const;
+ virtual String get_output_port_name(int p_port) const;
+
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+
+ void set_operator(Operator p_op);
+ Operator get_operator() const;
+
+ virtual Vector<StringName> get_editable_properties() const;
+
+ VisualShaderNodeVectorOp();
+};
+
+VARIANT_ENUM_CAST(VisualShaderNodeVectorOp::Operator)
+
+class VisualShaderNodeColorOp : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeColorOp, VisualShaderNode)
+
+public:
+ enum Operator {
+ OP_SCREEN,
+ OP_DIFFERENCE,
+ OP_DARKEN,
+ OP_LIGHTEN,
+ OP_OVERLAY,
+ OP_DODGE,
+ OP_BURN,
+ OP_SOFT_LIGHT,
+ OP_HARD_LIGHT,
+ };
+
+protected:
+ Operator op;
+
+ static void _bind_methods();
+
+public:
+ virtual String get_caption() const;
+
+ virtual int get_input_port_count() const;
+ virtual PortType get_input_port_type(int p_port) const;
+ virtual String get_input_port_name(int p_port) const;
+
+ virtual int get_output_port_count() const;
+ virtual PortType get_output_port_type(int p_port) const;
+ virtual String get_output_port_name(int p_port) const;
+
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+
+ void set_operator(Operator p_op);
+ Operator get_operator() const;
+
+ virtual Vector<StringName> get_editable_properties() const;
+
+ VisualShaderNodeColorOp();
+};
+
+VARIANT_ENUM_CAST(VisualShaderNodeColorOp::Operator)
+
+class VisualShaderNodeTransformMult : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeTransformMult, VisualShaderNode)
+
+public:
+ enum Operator {
+ OP_AxB,
+ OP_BxA,
+ };
+
+protected:
+ Operator op;
+
+ static void _bind_methods();
+
+public:
+ virtual String get_caption() const;
+
+ virtual int get_input_port_count() const;
+ virtual PortType get_input_port_type(int p_port) const;
+ virtual String get_input_port_name(int p_port) const;
+
+ virtual int get_output_port_count() const;
+ virtual PortType get_output_port_type(int p_port) const;
+ virtual String get_output_port_name(int p_port) const;
+
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+
+ void set_operator(Operator p_op);
+ Operator get_operator() const;
+
+ virtual Vector<StringName> get_editable_properties() const;
+
+ VisualShaderNodeTransformMult();
+};
+
+VARIANT_ENUM_CAST(VisualShaderNodeTransformMult::Operator)
+
+class VisualShaderNodeTransformVecMult : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeTransformVecMult, VisualShaderNode)
+
+public:
+ enum Operator {
+ OP_AxB,
+ OP_BxA,
+ OP_3x3_AxB,
+ OP_3x3_BxA,
+ };
+
+protected:
+ Operator op;
+
+ static void _bind_methods();
+
+public:
+ virtual String get_caption() const;
+
+ virtual int get_input_port_count() const;
+ virtual PortType get_input_port_type(int p_port) const;
+ virtual String get_input_port_name(int p_port) const;
+
+ virtual int get_output_port_count() const;
+ virtual PortType get_output_port_type(int p_port) const;
+ virtual String get_output_port_name(int p_port) const;
+
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+
+ void set_operator(Operator p_op);
+ Operator get_operator() const;
+
+ virtual Vector<StringName> get_editable_properties() const;
+
+ VisualShaderNodeTransformVecMult();
+};
+
+VARIANT_ENUM_CAST(VisualShaderNodeTransformVecMult::Operator)
+
+///////////////////////////////////////
+
+class VisualShaderNodeScalarFunc : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeScalarFunc, VisualShaderNode)
+
+public:
+ enum Function {
+ FUNC_SIN,
+ FUNC_COS,
+ FUNC_TAN,
+ FUNC_ASIN,
+ FUNC_ACOS,
+ FUNC_ATAN,
+ FUNC_SINH,
+ FUNC_COSH,
+ FUNC_TANH,
+ FUNC_LOG,
+ FUNC_EXP,
+ FUNC_SQRT,
+ FUNC_ABS,
+ FUNC_SIGN,
+ FUNC_FLOOR,
+ FUNC_ROUND,
+ FUNC_CEIL,
+ FUNC_FRAC,
+ FUNC_SATURATE,
+ FUNC_NEGATE,
+ };
+
+protected:
+ Function func;
+
+ static void _bind_methods();
+
+public:
+ virtual String get_caption() const;
+
+ virtual int get_input_port_count() const;
+ virtual PortType get_input_port_type(int p_port) const;
+ virtual String get_input_port_name(int p_port) const;
+
+ virtual int get_output_port_count() const;
+ virtual PortType get_output_port_type(int p_port) const;
+ virtual String get_output_port_name(int p_port) const;
+
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+
+ void set_function(Function p_func);
+ Function get_function() const;
+
+ virtual Vector<StringName> get_editable_properties() const;
+
+ VisualShaderNodeScalarFunc();
+};
+
+VARIANT_ENUM_CAST(VisualShaderNodeScalarFunc::Function)
+
+///////////////////////////////////////
+
+class VisualShaderNodeVectorFunc : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeVectorFunc, VisualShaderNode)
+
+public:
+ enum Function {
+ FUNC_NORMALIZE,
+ FUNC_SATURATE,
+ FUNC_NEGATE,
+ FUNC_RECIPROCAL,
+ FUNC_RGB2HSV,
+ FUNC_HSV2RGB,
+ };
+
+protected:
+ Function func;
+
+ static void _bind_methods();
+
+public:
+ virtual String get_caption() const;
+
+ virtual int get_input_port_count() const;
+ virtual PortType get_input_port_type(int p_port) const;
+ virtual String get_input_port_name(int p_port) const;
+
+ virtual int get_output_port_count() const;
+ virtual PortType get_output_port_type(int p_port) const;
+ virtual String get_output_port_name(int p_port) const;
+
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+
+ void set_function(Function p_func);
+ Function get_function() const;
+
+ virtual Vector<StringName> get_editable_properties() const;
+
+ VisualShaderNodeVectorFunc();
+};
+
+VARIANT_ENUM_CAST(VisualShaderNodeVectorFunc::Function)
+
+///////////////////////////////////////
+
+class VisualShaderNodeDotProduct : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeDotProduct, VisualShaderNode)
+
+public:
+ virtual String get_caption() const;
+
+ virtual int get_input_port_count() const;
+ virtual PortType get_input_port_type(int p_port) const;
+ virtual String get_input_port_name(int p_port) const;
+
+ virtual int get_output_port_count() const;
+ virtual PortType get_output_port_type(int p_port) const;
+ virtual String get_output_port_name(int p_port) const;
+
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+
+ VisualShaderNodeDotProduct();
+};
+
+///////////////////////////////////////
+
+class VisualShaderNodeVectorLen : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeVectorLen, VisualShaderNode)
+
+public:
+ virtual String get_caption() const;
+
+ virtual int get_input_port_count() const;
+ virtual PortType get_input_port_type(int p_port) const;
+ virtual String get_input_port_name(int p_port) const;
+
+ virtual int get_output_port_count() const;
+ virtual PortType get_output_port_type(int p_port) const;
+ virtual String get_output_port_name(int p_port) const;
+
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+
+ VisualShaderNodeVectorLen();
+};
+
+///////////////////////////////////////
+
+class VisualShaderNodeScalarInterp : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeScalarInterp, VisualShaderNode)
+
+public:
+ virtual String get_caption() const;
+
+ virtual int get_input_port_count() const;
+ virtual PortType get_input_port_type(int p_port) const;
+ virtual String get_input_port_name(int p_port) const;
+
+ virtual int get_output_port_count() const;
+ virtual PortType get_output_port_type(int p_port) const;
+ virtual String get_output_port_name(int p_port) const;
+
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+
+ VisualShaderNodeScalarInterp();
+};
+
+///////////////////////////////////////
+
+class VisualShaderNodeVectorInterp : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeVectorInterp, VisualShaderNode)
+
+public:
+ virtual String get_caption() const;
+
+ virtual int get_input_port_count() const;
+ virtual PortType get_input_port_type(int p_port) const;
+ virtual String get_input_port_name(int p_port) const;
+
+ virtual int get_output_port_count() const;
+ virtual PortType get_output_port_type(int p_port) const;
+ virtual String get_output_port_name(int p_port) const;
+
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+
+ VisualShaderNodeVectorInterp();
+};
+
+///////////////////////////////////////
+
+class VisualShaderNodeVectorCompose : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeVectorCompose, VisualShaderNode)
+
+public:
+ virtual String get_caption() const;
+
+ virtual int get_input_port_count() const;
+ virtual PortType get_input_port_type(int p_port) const;
+ virtual String get_input_port_name(int p_port) const;
+
+ virtual int get_output_port_count() const;
+ virtual PortType get_output_port_type(int p_port) const;
+ virtual String get_output_port_name(int p_port) const;
+
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+
+ VisualShaderNodeVectorCompose();
+};
+
+///////////////////////////////////////
+
+class VisualShaderNodeTransformCompose : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeTransformCompose, VisualShaderNode)
+
+public:
+ virtual String get_caption() const;
+
+ virtual int get_input_port_count() const;
+ virtual PortType get_input_port_type(int p_port) const;
+ virtual String get_input_port_name(int p_port) const;
+
+ virtual int get_output_port_count() const;
+ virtual PortType get_output_port_type(int p_port) const;
+ virtual String get_output_port_name(int p_port) const;
+
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+
+ VisualShaderNodeTransformCompose();
+};
+
+///////////////////////////////////////
+
+class VisualShaderNodeVectorDecompose : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeVectorDecompose, VisualShaderNode)
+
+public:
+ virtual String get_caption() const;
+
+ virtual int get_input_port_count() const;
+ virtual PortType get_input_port_type(int p_port) const;
+ virtual String get_input_port_name(int p_port) const;
+
+ virtual int get_output_port_count() const;
+ virtual PortType get_output_port_type(int p_port) const;
+ virtual String get_output_port_name(int p_port) const;
+
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+
+ VisualShaderNodeVectorDecompose();
+};
+
+///////////////////////////////////////
+
+class VisualShaderNodeTransformDecompose : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeTransformDecompose, VisualShaderNode)
+
+public:
+ virtual String get_caption() const;
+
+ virtual int get_input_port_count() const;
+ virtual PortType get_input_port_type(int p_port) const;
+ virtual String get_input_port_name(int p_port) const;
+
+ virtual int get_output_port_count() const;
+ virtual PortType get_output_port_type(int p_port) const;
+ virtual String get_output_port_name(int p_port) const;
+
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+
+ VisualShaderNodeTransformDecompose();
+};
+
+///////////////////////////////////////
+
+class VisualShaderNodeScalarUniform : public VisualShaderNodeUniform {
+ GDCLASS(VisualShaderNodeScalarUniform, VisualShaderNodeUniform)
+
+public:
+ virtual String get_caption() const;
+
+ virtual int get_input_port_count() const;
+ virtual PortType get_input_port_type(int p_port) const;
+ virtual String get_input_port_name(int p_port) const;
+
+ virtual int get_output_port_count() const;
+ virtual PortType get_output_port_type(int p_port) const;
+ virtual String get_output_port_name(int p_port) const;
+
+ virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const;
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+
+ VisualShaderNodeScalarUniform();
+};
+
+class VisualShaderNodeColorUniform : public VisualShaderNodeUniform {
+ GDCLASS(VisualShaderNodeColorUniform, VisualShaderNodeUniform)
+
+public:
+ virtual String get_caption() const;
+
+ virtual int get_input_port_count() const;
+ virtual PortType get_input_port_type(int p_port) const;
+ virtual String get_input_port_name(int p_port) const;
+
+ virtual int get_output_port_count() const;
+ virtual PortType get_output_port_type(int p_port) const;
+ virtual String get_output_port_name(int p_port) const;
+
+ virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const;
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+
+ VisualShaderNodeColorUniform();
+};
+
+class VisualShaderNodeVec3Uniform : public VisualShaderNodeUniform {
+ GDCLASS(VisualShaderNodeVec3Uniform, VisualShaderNodeUniform)
+
+public:
+ virtual String get_caption() const;
+
+ virtual int get_input_port_count() const;
+ virtual PortType get_input_port_type(int p_port) const;
+ virtual String get_input_port_name(int p_port) const;
+
+ virtual int get_output_port_count() const;
+ virtual PortType get_output_port_type(int p_port) const;
+ virtual String get_output_port_name(int p_port) const;
+
+ virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const;
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+
+ VisualShaderNodeVec3Uniform();
+};
+
+class VisualShaderNodeTransformUniform : public VisualShaderNodeUniform {
+ GDCLASS(VisualShaderNodeTransformUniform, VisualShaderNodeUniform)
+
+public:
+ virtual String get_caption() const;
+
+ virtual int get_input_port_count() const;
+ virtual PortType get_input_port_type(int p_port) const;
+ virtual String get_input_port_name(int p_port) const;
+
+ virtual int get_output_port_count() const;
+ virtual PortType get_output_port_type(int p_port) const;
+ virtual String get_output_port_name(int p_port) const;
+
+ virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const;
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+
+ VisualShaderNodeTransformUniform();
+};
+
+//////////////////////////////////
+
+class VisualShaderNodeTextureUniform : public VisualShaderNodeUniform {
+ GDCLASS(VisualShaderNodeTextureUniform, VisualShaderNodeUniform)
+public:
+ enum TextureType {
+ TYPE_DATA,
+ TYPE_COLOR,
+ TYPE_NORMALMAP,
+ TYPE_ANISO,
+ };
+
+ enum ColorDefault {
+ COLOR_DEFAULT_WHITE,
+ COLOR_DEFAULT_BLACK
+ };
+
+private:
+ TextureType texture_type;
+ ColorDefault color_default;
+
+protected:
+ static void _bind_methods();
+
+public:
+ virtual String get_caption() const;
+
+ virtual int get_input_port_count() const;
+ virtual PortType get_input_port_type(int p_port) const;
+ virtual String get_input_port_name(int p_port) const;
+
+ virtual int get_output_port_count() const;
+ virtual PortType get_output_port_type(int p_port) const;
+ virtual String get_output_port_name(int p_port) const;
+
+ virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const;
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+
+ Vector<StringName> get_editable_properties() const;
+
+ void set_texture_type(TextureType p_type);
+ TextureType get_texture_type() const;
+
+ void set_color_default(ColorDefault p_default);
+ ColorDefault get_color_default() const;
+
+ VisualShaderNodeTextureUniform();
+};
+
+VARIANT_ENUM_CAST(VisualShaderNodeTextureUniform::TextureType)
+VARIANT_ENUM_CAST(VisualShaderNodeTextureUniform::ColorDefault)
+
+//////////////////////////////////
+
+class VisualShaderNodeCubeMapUniform : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeCubeMapUniform, VisualShaderNode)
+
+public:
+ virtual String get_caption() const;
+
+ virtual int get_input_port_count() const;
+ virtual PortType get_input_port_type(int p_port) const;
+ virtual String get_input_port_name(int p_port) const;
+
+ virtual int get_output_port_count() const;
+ virtual PortType get_output_port_type(int p_port) const;
+ virtual String get_output_port_name(int p_port) const;
+
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+
+ VisualShaderNodeCubeMapUniform();
+};
+
+#endif // VISUAL_SHADER_NODES_H
diff --git a/scene/scene_string_names.cpp b/scene/scene_string_names.cpp
index bf765385d0..e468b3dab4 100644
--- a/scene/scene_string_names.cpp
+++ b/scene/scene_string_names.cpp
@@ -102,6 +102,8 @@ SceneStringNames::SceneStringNames() {
_update_scroll = StaticCString::create("_update_scroll");
_update_xform = StaticCString::create("_update_xform");
+ _clips_input = StaticCString::create("_clips_input");
+
_proxgroup_add = StaticCString::create("_proxgroup_add");
_proxgroup_remove = StaticCString::create("_proxgroup_remove");
@@ -199,4 +201,6 @@ SceneStringNames::SceneStringNames() {
}
_mesh_changed = StaticCString::create("_mesh_changed");
+
+ parameters_base_path = "parameters/";
}
diff --git a/scene/scene_string_names.h b/scene/scene_string_names.h
index b88cf7d8d7..dbbcf79b9f 100644
--- a/scene/scene_string_names.h
+++ b/scene/scene_string_names.h
@@ -127,6 +127,8 @@ public:
StringName _update_scroll;
StringName _update_xform;
+ StringName _clips_input;
+
StringName _proxgroup_add;
StringName _proxgroup_remove;
@@ -201,6 +203,8 @@ public:
StringName output;
+ StringName parameters_base_path;
+
enum {
MAX_MATERIALS = 32
};