Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package cage for openSUSE:Factory checked in at 2026-04-13 23:19:26 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/cage (Old) and /work/SRC/openSUSE:Factory/.cage.new.21863 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "cage" Mon Apr 13 23:19:26 2026 rev:5 rq:1346379 version:0.3.0 Changes: -------- --- /work/SRC/openSUSE:Factory/cage/cage.changes 2025-10-10 17:10:44.240745807 +0200 +++ /work/SRC/openSUSE:Factory/.cage.new.21863/cage.changes 2026-04-13 23:21:13.953933237 +0200 @@ -1,0 +2,16 @@ +Mon Apr 13 08:02:34 UTC 2026 - Michael Vetter <[email protected]> + +- Update to version 0.3.0: + * build: bump version to 0.3.0 + * Make buffer bigger to prevent wayland disconnection + * build: drop cage_heaers + * Upgrade wlroots to v0.20 + * Fix segfault during cleanup when wlr_scene isn't created + * Implement the drm-lease-v1 protocol + * xwayland: fix crash when request_fullscreen is called while unmapped + * xdg_shell: skip configure in request_fullscreen handler if unmapped + * Fix segfault when title or app_id is NULL + * xwayland: remove associate/dissociate listeners + * Add support for wlr-foreign-toplevel-management + +------------------------------------------------------------------- Old: ---- cage-0.2.1.obscpio New: ---- cage-0.3.0.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ cage.spec ++++++ --- /var/tmp/diff_new_pack.likwio/_old 2026-04-13 23:21:14.433953042 +0200 +++ /var/tmp/diff_new_pack.likwio/_new 2026-04-13 23:21:14.433953042 +0200 @@ -1,7 +1,7 @@ # # spec file for package cage # -# Copyright (c) 2025 SUSE LLC and contributors +# Copyright (c) 2026 SUSE LLC and contributors # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,7 +17,7 @@ Name: cage -Version: 0.2.1 +Version: 0.3.0 Release: 0 Summary: Wayland Kiosk License: MIT @@ -27,7 +27,7 @@ BuildRequires: meson >= 0.43.0 BuildRequires: pkgconfig BuildRequires: scdoc -BuildRequires: wlroots-devel >= 0.19.0 +BuildRequires: wlroots-devel >= 0.20.0 BuildRequires: pkgconfig(pixman-1) BuildRequires: pkgconfig(wayland-protocols) >= 1.14 BuildRequires: pkgconfig(wayland-server) ++++++ _service ++++++ --- /var/tmp/diff_new_pack.likwio/_old 2026-04-13 23:21:14.465954362 +0200 +++ /var/tmp/diff_new_pack.likwio/_new 2026-04-13 23:21:14.469954527 +0200 @@ -3,7 +3,7 @@ <service name="obs_scm" mode="manual"> <param name="url">https://github.com/cage-kiosk/cage.git</param> <param name="scm">git</param> - <param name="revision">v0.2.1</param> + <param name="revision">v0.3.0</param> <param name="versionformat">@PARENT_TAG@</param> <param name="match-tag">*</param> <param name="versionrewrite-pattern">v(\d+\.\d+\.\d+)</param> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.likwio/_old 2026-04-13 23:21:14.493955517 +0200 +++ /var/tmp/diff_new_pack.likwio/_new 2026-04-13 23:21:14.497955682 +0200 @@ -1,6 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/cage-kiosk/cage.git</param> - <param name="changesrevision">f9626f79519f8ee22d7bb0c3880a66791d82f923</param></service></servicedata> + <param name="changesrevision">3783af4fadc27057b24025fefe78d942e3f01128</param></service></servicedata> (No newline at EOF) ++++++ cage-0.2.1.obscpio -> cage-0.3.0.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cage-0.2.1/.github/workflows/main.yml new/cage-0.3.0/.github/workflows/main.yml --- old/cage-0.2.1/.github/workflows/main.yml 2025-10-01 17:46:45.000000000 +0200 +++ new/cage-0.3.0/.github/workflows/main.yml 2026-04-11 09:28:43.000000000 +0200 @@ -6,7 +6,7 @@ branches: [ master ] env: - WLROOTS_VERSION: 0.19 + WLROOTS_VERSION: "0.20" jobs: compile: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cage-0.2.1/README.md new/cage-0.3.0/README.md --- old/cage-0.2.1/README.md 2025-10-01 17:46:45.000000000 +0200 +++ new/cage-0.3.0/README.md 2026-04-11 09:28:43.000000000 +0200 @@ -21,7 +21,7 @@ You can build Cage with the [meson](https://mesonbuild.com/) build system. It requires wayland, wlroots, and xkbcommon to be installed. Optionally, install -scdoc for manual pages. Cage is currently based on branch 0.18 of wlroots. +scdoc for manual pages. Cage is currently based on branch 0.20 of wlroots. Simply execute the following steps to build Cage: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cage-0.2.1/cage.c new/cage-0.3.0/cage.c --- old/cage-0.2.1/cage.c 2025-10-01 17:46:45.000000000 +0200 +++ new/cage-0.3.0/cage.c 2026-04-11 09:28:43.000000000 +0200 @@ -19,11 +19,13 @@ #include <unistd.h> #include <wayland-server-core.h> #include <wlr/backend.h> +#include <wlr/config.h> #include <wlr/render/allocator.h> #include <wlr/render/wlr_renderer.h> #include <wlr/types/wlr_compositor.h> #include <wlr/types/wlr_data_device.h> #include <wlr/types/wlr_export_dmabuf_v1.h> +#include <wlr/types/wlr_foreign_toplevel_management_v1.h> #include <wlr/types/wlr_gamma_control_v1.h> #include <wlr/types/wlr_idle_inhibit_v1.h> #include <wlr/types/wlr_idle_notify_v1.h> @@ -79,6 +81,19 @@ server->terminated = true; } +#if WLR_HAS_DRM_BACKEND +static void +handle_drm_lease_request(struct wl_listener *listener, void *data) +{ + struct wlr_drm_lease_request_v1 *req = data; + struct wlr_drm_lease_v1 *lease = wlr_drm_lease_request_v1_grant(req); + if (!lease) { + wlr_log(WLR_ERROR, "Failed to grant lease"); + wlr_drm_lease_request_v1_reject(req); + } +} +#endif + static int sigchld_handler(int fd, uint32_t mask, void *data) { @@ -305,6 +320,7 @@ return 1; } + wl_display_set_default_max_buffer_size(server.wl_display, 1024 * 1024); server.display_destroy.notify = handle_display_destroy; wl_display_add_destroy_listener(server.wl_display, &server.display_destroy); @@ -496,6 +512,16 @@ server.output_manager_test.notify = handle_output_manager_test; wl_signal_add(&server.output_manager_v1->events.test, &server.output_manager_test); +#if WLR_HAS_DRM_BACKEND + server.drm_lease_v1 = wlr_drm_lease_v1_manager_create(server.wl_display, server.backend); + if (server.drm_lease_v1) { + server.drm_lease_request.notify = handle_drm_lease_request; + wl_signal_add(&server.drm_lease_v1->events.request, &server.drm_lease_request); + } else { + wlr_log(WLR_INFO, "Failed to create wlr_drm_lease_manager_v1"); + } +#endif + if (!wlr_gamma_control_manager_v1_create(server.wl_display)) { wlr_log(WLR_ERROR, "Unable to create the gamma control manager"); ret = 1; @@ -527,6 +553,13 @@ goto end; } + server.foreign_toplevel_manager = wlr_foreign_toplevel_manager_v1_create(server.wl_display); + if (!server.foreign_toplevel_manager) { + wlr_log(WLR_ERROR, "Unable to create the foreign toplevel manager"); + ret = 1; + goto end; + } + #if CAGE_HAS_XWAYLAND struct wlr_xcursor_manager *xcursor_manager = NULL; struct wlr_xwayland *xwayland = wlr_xwayland_create(server.wl_display, compositor, true); @@ -556,8 +589,8 @@ struct wlr_xcursor *xcursor = wlr_xcursor_manager_get_xcursor(xcursor_manager, DEFAULT_XCURSOR, 1); if (xcursor) { struct wlr_xcursor_image *image = xcursor->images[0]; - wlr_xwayland_set_cursor(xwayland, image->buffer, image->width * 4, image->width, image->height, - image->hotspot_x, image->hotspot_y); + wlr_xwayland_set_cursor(xwayland, wlr_xcursor_image_get_buffer(image), image->hotspot_x, + image->hotspot_y); } } #endif @@ -604,6 +637,11 @@ #endif wl_display_destroy_clients(server.wl_display); +#if WLR_HAS_DRM_BACKEND + if (server.drm_lease_v1) { + wl_list_remove(&server.drm_lease_request.link); + } +#endif wl_list_remove(&server.new_virtual_pointer.link); wl_list_remove(&server.new_virtual_keyboard.link); wl_list_remove(&server.output_manager_apply.link); @@ -630,7 +668,9 @@ /* This function is not null-safe, but we only ever get here with a proper wl_display. */ wl_display_destroy(server.wl_display); - wlr_scene_node_destroy(&server.scene->tree.node); + if (server.scene != NULL) { + wlr_scene_node_destroy(&server.scene->tree.node); + } wlr_allocator_destroy(server.allocator); wlr_renderer_destroy(server.renderer); return ret; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cage-0.2.1/meson.build new/cage-0.3.0/meson.build --- old/cage-0.2.1/meson.build 2025-10-01 17:46:45.000000000 +0200 +++ new/cage-0.3.0/meson.build 2026-04-11 09:28:43.000000000 +0200 @@ -1,5 +1,5 @@ project('cage', 'c', - version: '0.2.1', + version: '0.3.0', license: 'MIT', meson_version: '>=0.58.1', default_options: [ @@ -35,35 +35,11 @@ ) endif -wlroots = dependency('wlroots-0.19', fallback: ['wlroots', 'wlroots']) -wayland_protos = dependency('wayland-protocols', version: '>=1.14') +wlroots = dependency('wlroots-0.20', fallback: ['wlroots', 'wlroots']) wayland_server = dependency('wayland-server') xkbcommon = dependency('xkbcommon') math = cc.find_library('m') -wl_protocol_dir = wayland_protos.get_variable('pkgdatadir') -wayland_scanner = find_program('wayland-scanner') -wayland_scanner_server = generator( - wayland_scanner, - output: '@[email protected]', - arguments: ['server-header', '@INPUT@', '@OUTPUT@'], -) - -server_protocols = [ - [wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml'], -] - -server_protos_headers = [] - -foreach p : server_protocols - xml = join_paths(p) - server_protos_headers += wayland_scanner_server.process(xml) -endforeach - -server_protos = declare_dependency( - sources: server_protos_headers, -) - have_xwayland = wlroots.get_variable(pkgconfig: 'have_xwayland', internal: 'have_xwayland') == 'true' version = '@0@'.format(meson.project_version()) @@ -117,30 +93,19 @@ 'seat.c', 'view.c', 'xdg_shell.c', -] - -cage_headers = [ configure_file(input: 'config.h.in', output: 'config.h', configuration: conf_data), - 'idle_inhibit_v1.h', - 'output.h', - 'seat.h', - 'server.h', - 'view.h', - 'xdg_shell.h', ] if conf_data.get('CAGE_HAS_XWAYLAND', 0) == 1 cage_sources += 'xwayland.c' - cage_headers += 'xwayland.h' endif executable( meson.project_name(), - cage_sources + cage_headers, + cage_sources, dependencies: [ - server_protos, wayland_server, wlroots, xkbcommon, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cage-0.2.1/output.c new/cage-0.3.0/output.c --- old/cage-0.2.1/output.c 2025-10-01 17:46:45.000000000 +0200 +++ new/cage-0.3.0/output.c 2026-04-11 09:28:43.000000000 +0200 @@ -237,6 +237,16 @@ struct cg_server *server = wl_container_of(listener, server, new_output); struct wlr_output *wlr_output = data; + if (wlr_output->non_desktop) { + wlr_log(WLR_DEBUG, "Not configuring non-desktop output: %s", wlr_output->name); +#if WLR_HAS_DRM_BACKEND + if (server->drm_lease_v1) { + wlr_drm_lease_v1_manager_offer_output(server->drm_lease_v1, wlr_output); + } +#endif + return; + } + if (!wlr_output_init_render(wlr_output, server->allocator, server->renderer)) { wlr_log(WLR_ERROR, "Failed to initialize output rendering"); return; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cage-0.2.1/server.h new/cage-0.3.0/server.h --- old/cage-0.2.1/server.h 2025-10-01 17:46:45.000000000 +0200 +++ new/cage-0.3.0/server.h 2026-04-11 09:28:43.000000000 +0200 @@ -4,6 +4,8 @@ #include "config.h" #include <wayland-server-core.h> +#include <wlr/config.h> +#include <wlr/types/wlr_drm_lease_v1.h> #include <wlr/types/wlr_idle_inhibit_v1.h> #include <wlr/types/wlr_idle_notify_v1.h> #include <wlr/types/wlr_output_layout.h> @@ -59,8 +61,15 @@ struct wl_listener output_manager_apply; struct wl_listener output_manager_test; +#if WLR_HAS_DRM_BACKEND + struct wlr_drm_lease_v1_manager *drm_lease_v1; + struct wl_listener drm_lease_request; +#endif + struct wlr_relative_pointer_manager_v1 *relative_pointer_manager; + struct wlr_foreign_toplevel_manager_v1 *foreign_toplevel_manager; + bool xdg_decoration; bool allow_vt_switch; bool return_app_code; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cage-0.2.1/view.c new/cage-0.3.0/view.c --- old/cage-0.2.1/view.c 2025-10-01 17:46:45.000000000 +0200 +++ new/cage-0.3.0/view.c 2026-04-11 09:28:43.000000000 +0200 @@ -13,6 +13,7 @@ #include <stdlib.h> #include <string.h> #include <wayland-server-core.h> +#include <wlr/types/wlr_foreign_toplevel_management_v1.h> #include <wlr/types/wlr_output.h> #include <wlr/types/wlr_scene.h> @@ -50,6 +51,7 @@ view_activate(struct cg_view *view, bool activate) { view->impl->activate(view, activate); + wlr_foreign_toplevel_handle_v1_set_activated(view->foreign_toplevel_handle, activate); } static bool @@ -115,6 +117,11 @@ { wl_list_remove(&view->link); + wl_list_remove(&view->request_activate.link); + wl_list_remove(&view->request_close.link); + wlr_foreign_toplevel_handle_v1_destroy(view->foreign_toplevel_handle); + view->foreign_toplevel_handle = NULL; + wlr_scene_node_destroy(&view->scene_tree->node); view->wlr_surface->data = NULL; @@ -122,13 +129,27 @@ } void +handle_surface_request_activate(struct wl_listener *listener, void *data) +{ + struct cg_view *view = wl_container_of(listener, view, request_activate); + + wlr_scene_node_raise_to_top(&view->scene_tree->node); + seat_set_focus(view->server->seat, view); +} + +void +handle_surface_request_close(struct wl_listener *listener, void *data) +{ + struct cg_view *view = wl_container_of(listener, view, request_close); + view->impl->close(view); +} + +void view_map(struct cg_view *view, struct wlr_surface *surface) { view->scene_tree = wlr_scene_subsurface_tree_create(&view->server->scene->tree, surface); - if (!view->scene_tree) { - wl_resource_post_no_memory(surface->resource); - return; - } + if (!view->scene_tree) + goto fail; view->scene_tree->node.data = view; view->wlr_surface = surface; @@ -144,7 +165,21 @@ } wl_list_insert(&view->server->views, &view->link); + + view->foreign_toplevel_handle = wlr_foreign_toplevel_handle_v1_create(view->server->foreign_toplevel_manager); + if (!view->foreign_toplevel_handle) + goto fail; + + view->request_activate.notify = handle_surface_request_activate; + wl_signal_add(&view->foreign_toplevel_handle->events.request_activate, &view->request_activate); + view->request_close.notify = handle_surface_request_close; + wl_signal_add(&view->foreign_toplevel_handle->events.request_close, &view->request_close); + seat_set_focus(view->server->seat, view); + return; + +fail: + wl_resource_post_no_memory(surface->resource); } void diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cage-0.2.1/view.h new/cage-0.3.0/view.h --- old/cage-0.2.1/view.h 2025-10-01 17:46:45.000000000 +0200 +++ new/cage-0.3.0/view.h 2026-04-11 09:28:43.000000000 +0200 @@ -32,6 +32,10 @@ enum cg_view_type type; const struct cg_view_impl *impl; + + struct wlr_foreign_toplevel_handle_v1 *foreign_toplevel_handle; + struct wl_listener request_activate; + struct wl_listener request_close; }; struct cg_view_impl { @@ -41,6 +45,7 @@ bool (*is_transient_for)(struct cg_view *child, struct cg_view *parent); void (*activate)(struct cg_view *view, bool activate); void (*maximize)(struct cg_view *view, int output_width, int output_height); + void (*close)(struct cg_view *view); void (*destroy)(struct cg_view *view); }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cage-0.2.1/xdg_shell.c new/cage-0.3.0/xdg_shell.c --- old/cage-0.2.1/xdg_shell.c 2025-10-01 17:46:45.000000000 +0200 +++ new/cage-0.3.0/xdg_shell.c 2026-04-11 09:28:43.000000000 +0200 @@ -10,6 +10,7 @@ #include <stdbool.h> #include <stdlib.h> #include <wayland-server-core.h> +#include <wlr/types/wlr_foreign_toplevel_management_v1.h> #include <wlr/types/wlr_scene.h> #include <wlr/types/wlr_xdg_shell.h> #include <wlr/util/log.h> @@ -184,9 +185,21 @@ } static void +close(struct cg_view *view) +{ + struct cg_xdg_shell_view *xdg_shell_view = xdg_shell_view_from_view(view); + wlr_xdg_toplevel_send_close(xdg_shell_view->xdg_toplevel); +} + +static void handle_xdg_toplevel_request_fullscreen(struct wl_listener *listener, void *data) { struct cg_xdg_shell_view *xdg_shell_view = wl_container_of(listener, xdg_shell_view, request_fullscreen); + bool fullscreen = xdg_shell_view->xdg_toplevel->requested.fullscreen; + + if (!xdg_shell_view->xdg_toplevel->base->surface->mapped) { + return; + } /** * Certain clients do not like figuring out their own window geometry if they @@ -195,9 +208,8 @@ struct wlr_box layout_box; wlr_output_layout_get_box(xdg_shell_view->view.server->output_layout, NULL, &layout_box); wlr_xdg_toplevel_set_size(xdg_shell_view->xdg_toplevel, layout_box.width, layout_box.height); - - wlr_xdg_toplevel_set_fullscreen(xdg_shell_view->xdg_toplevel, - xdg_shell_view->xdg_toplevel->requested.fullscreen); + wlr_xdg_toplevel_set_fullscreen(xdg_shell_view->xdg_toplevel, fullscreen); + wlr_foreign_toplevel_handle_v1_set_fullscreen(xdg_shell_view->view.foreign_toplevel_handle, fullscreen); } static void @@ -216,6 +228,14 @@ struct cg_view *view = &xdg_shell_view->view; view_map(view, xdg_shell_view->xdg_toplevel->base->surface); + + if (xdg_shell_view->xdg_toplevel->title) + wlr_foreign_toplevel_handle_v1_set_title(view->foreign_toplevel_handle, + xdg_shell_view->xdg_toplevel->title); + if (xdg_shell_view->xdg_toplevel->app_id) + wlr_foreign_toplevel_handle_v1_set_app_id(view->foreign_toplevel_handle, + xdg_shell_view->xdg_toplevel->app_id); + /* Activation state will be set by seat_set_focus */ } static void @@ -258,6 +278,7 @@ .activate = activate, .maximize = maximize, .destroy = destroy, + .close = close, }; void diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cage-0.2.1/xwayland.c new/cage-0.3.0/xwayland.c --- old/cage-0.2.1/xwayland.c 2025-10-01 17:46:45.000000000 +0200 +++ new/cage-0.3.0/xwayland.c 2026-04-11 09:28:43.000000000 +0200 @@ -9,6 +9,7 @@ #include <stdbool.h> #include <stdlib.h> #include <wayland-server-core.h> +#include <wlr/types/wlr_foreign_toplevel_management_v1.h> #include <wlr/util/log.h> #include <wlr/xwayland.h> @@ -103,11 +104,22 @@ } static void +close(struct cg_view *view) +{ + struct cg_xwayland_view *xwayland_view = xwayland_view_from_view(view); + wlr_xwayland_surface_close(xwayland_view->xwayland_surface); +} + +static void handle_xwayland_surface_request_fullscreen(struct wl_listener *listener, void *data) { struct cg_xwayland_view *xwayland_view = wl_container_of(listener, xwayland_view, request_fullscreen); struct wlr_xwayland_surface *xwayland_surface = xwayland_view->xwayland_surface; wlr_xwayland_surface_set_fullscreen(xwayland_view->xwayland_surface, xwayland_surface->fullscreen); + if (xwayland_view->view.foreign_toplevel_handle) { + wlr_foreign_toplevel_handle_v1_set_fullscreen(xwayland_view->view.foreign_toplevel_handle, + xwayland_surface->fullscreen); + } } static void @@ -131,6 +143,15 @@ } view_map(view, xwayland_view->xwayland_surface->surface); + + if (xwayland_view->xwayland_surface->title) + wlr_foreign_toplevel_handle_v1_set_title(view->foreign_toplevel_handle, + xwayland_view->xwayland_surface->title); + if (xwayland_view->xwayland_surface->class) + wlr_foreign_toplevel_handle_v1_set_app_id(view->foreign_toplevel_handle, + xwayland_view->xwayland_surface->class); + wlr_foreign_toplevel_handle_v1_set_fullscreen(view->foreign_toplevel_handle, + xwayland_view->xwayland_surface->fullscreen); } static void @@ -139,6 +160,8 @@ struct cg_xwayland_view *xwayland_view = wl_container_of(listener, xwayland_view, destroy); struct cg_view *view = &xwayland_view->view; + wl_list_remove(&xwayland_view->associate.link); + wl_list_remove(&xwayland_view->dissociate.link); wl_list_remove(&xwayland_view->destroy.link); wl_list_remove(&xwayland_view->request_fullscreen.link); xwayland_view->xwayland_surface = NULL; @@ -154,6 +177,7 @@ .activate = activate, .maximize = maximize, .destroy = destroy, + .close = close, }; void ++++++ cage.obsinfo ++++++ --- /var/tmp/diff_new_pack.likwio/_old 2026-04-13 23:21:14.649961954 +0200 +++ /var/tmp/diff_new_pack.likwio/_new 2026-04-13 23:21:14.653962119 +0200 @@ -1,5 +1,5 @@ name: cage -version: 0.2.1 -mtime: 1759333605 -commit: f9626f79519f8ee22d7bb0c3880a66791d82f923 +version: 0.3.0 +mtime: 1775892523 +commit: 3783af4fadc27057b24025fefe78d942e3f01128
