diff --git a/WebminCore.pm b/WebminCore.pm index 5f0ae5d3f..b011599e3 100644 --- a/WebminCore.pm +++ b/WebminCore.pm @@ -23,7 +23,7 @@ $main::export_to_caller = 1; # Add functions in web-lib-funcs.pl # Generated with : # grep -h "^sub " web-lib-funcs.pl ui-lib.pl | sed -e 's/sub //' | xargs echo -@EXPORT = qw(read_file read_file_cached read_file_cached_with_stat write_file html_escape html_unescape html_strip quote_escape quote_javascript tempname_dir tempname transname transname_timestamped trunc indexof indexoflc sysprint check_ipaddress check_ip6address generate_icon urlize un_urlize include copydata ReadParseMime ReadParse read_fully read_parse_mime_callback read_parse_mime_javascript PrintHeader header get_html_title get_html_framed_title get_html_status_line popup_header footer popup_footer load_module_preferences load_theme_library redirect kill_byname kill_byname_logged find_byname error error_stderr popup_error register_error_handler call_error_handlers error_setup wait_for fast_wait_for has_command make_date file_chooser_button popup_window_button popup_window_link read_acl acl_filename acl_check get_miniserv_config_file get_miniserv_config put_miniserv_config restart_miniserv reload_miniserv check_os_support http_download complete_http_download http_post ftp_download ftp_upload no_proxy open_socket download_timeout ftp_command to_ipaddress to_ip6address to_hostname icons_table replace_meta replace_file_line read_file_lines flush_file_lines unflush_file_lines unix_user_input unix_group_input hlink user_chooser_button group_chooser_button foreign_check foreign_exists foreign_available foreign_require foreign_call foreign_config foreign_installed foreign_defined get_system_hostname get_webmin_version get_webmin_version_release get_webmin_full_version get_module_acl get_group_module_acl save_module_acl save_group_module_acl init_config load_language_auto load_language text_subs text encode_base64 decode_base64 encode_base32 decode_base32 get_module_info get_all_module_infos list_themes get_theme_info list_locales list_languages safe_language read_env_file write_env_file lock_file unlock_file test_lock unlock_all_files can_lock_file webmin_log additional_log var_dump webmin_debug_log system_logged backquote_logged backquote_with_timeout backquote_command kill_logged rename_logged rename_file symlink_logged symlink_file link_file make_dir make_dir_recursive set_ownership_permissions unlink_logged unlink_file copy_permissions_source_dest copy_source_dest move_source_dest remote_session_name verify_session_id remote_foreign_require remote_foreign_call remote_foreign_check remote_foreign_config remote_eval remote_write remote_read remote_finished remote_error_setup remote_rpc_call remote_multi_callback remote_multi_callback_error serialise_variable unserialise_variable other_groups date_chooser_button help_file read_help_file seed_random disk_usage_kb recursive_disk_usage help_search_link make_http_connection validate_ssl_connection read_http_connection write_http_connection close_http_connection clean_environment reset_environment clean_language progress_callback switch_to_remote_user switch_to_unix_user eval_as_unix_user create_user_config_dirs create_missing_homedir filter_javascript resolve_links simplify_path same_file flush_webmin_caches list_usermods available_usermods get_available_module_infos get_visible_module_infos get_visible_modules_categories is_under_directory parse_http_url check_clicks_function load_entities_map entities_to_ascii get_product_name get_charset get_display_hostname save_module_config save_user_module_config nice_size get_perl_path get_goto_module select_all_link select_invert_link select_rows_link check_pid_file get_mod_lib module_root_directory list_mime_types guess_mime_type open_tempfile close_tempfile print_tempfile is_selinux_enabled get_clear_file_attributes reset_file_attributes cleanup_tempnames open_lock_tempfile END month_to_number number_to_month get_rbac_module_acl supports_rbac supports_ipv6 use_rbac_module_acl execute_command open_readfile open_execute_command translate_filename translate_command register_filename_callback register_command_callback capture_function_output capture_function_output_tempfile modules_chooser_button substitute_template substitute_pattern running_in_zone running_in_vserver running_in_xen running_in_openvz list_categories is_readonly_mode command_as_user list_osdn_mirrors convert_osdn_url get_current_dir supports_users supports_symlinks quote_path get_windows_root read_file_contents write_file_contents read_file_contents_limit unix_crypt split_quoted_string write_to_http_cache check_in_http_cache clear_http_cache supports_javascript get_module_name get_module_variable clear_time_locale reset_time_locale callers_package web_libs_package get_userdb_string connect_userdb disconnect_userdb split_userdb_string uniquelc list_combined_webmin_menu list_modules_webmin_menu module_to_menu_item list_combined_system_info shell_is_bash compare_version_numbers convert_to_json convert_from_json print_json get_referer_relative get_webmin_email_url get_webmin_browser_url trim ui_link ui_help ui_img ui_link_button ui_table_start ui_table_end ui_table_row ui_table_hr ui_table_span ui_columns_start ui_columns_row ui_columns_header ui_checked_columns_row ui_radio_columns_row ui_columns_end ui_columns_table ui_form_columns_table ui_form_elements_wrapper ui_form_start ui_form_end ui_textbox ui_filebox ui_bytesbox ui_upload ui_password ui_hidden ui_select ui_multi_select ui_multi_select_javascript ui_radio ui_yesno_radio ui_radio_row ui_checkbox ui_oneradio ui_textarea ui_user_textbox ui_users_textbox ui_group_textbox ui_groups_textbox ui_opt_textbox ui_submit ui_reset ui_button ui_date_input ui_buttons_start ui_buttons_end ui_buttons_row ui_buttons_hr ui_post_header ui_pre_footer ui_print_header ui_print_unbuffered_header ui_print_footer ui_config_link ui_print_endpage ui_subheading ui_links_row ui_hidden_javascript ui_hidden_start ui_hidden_end ui_hidden_table_row_start ui_hidden_table_row_end ui_hidden_table_start ui_hidden_table_end ui_tabs_start ui_tabs_end ui_tabs_start_tab ui_tabs_start_tabletab ui_tabs_end_tab ui_tabs_end_tabletab ui_max_text_width ui_radio_selector ui_radio_selector_javascript ui_switch_theme_javascript ui_grid_table ui_radio_table ui_up_down_arrows ui_hr ui_nav_link ui_confirmation_form ui_text_color ui_alert_box js_disable_inputs ui_page_flipper js_checkbox_disable js_redirect ui_webmin_link ui_line_break_double ui_page_refresh ui_details ui_div_row ui_space ui_newline ui_text_wrap ui_element_inline ui_paginations ui_hide_outside_of_viewport ui_read_file_contents_limit ui_note ui_brh ui_tag_start ui_tag_content ui_tag_end ui_tag ui_alert ui_button_icon ui_link_icon ui_icon ui_br ui_p ui_text_mask get_python_cmd get_buffer_size get_buffer_size_binary get_webprefix get_sub_ref_name setvar getvar delvar print_call_stack webmin_user_can_rpc webmin_user_login_mode webmin_user_is_admin webmin_user_is get_current_theme_info_cached miniserv_using_default_cert is_int float is_float parse_accepted_language get_default_system_locale get_http_redirect get_http_cookie create_wrapper get_lock_links_dir allocate_miniserv_websocket get_miniserv_websocket_url remove_miniserv_websocket cleanup_miniserv_websockets get_miniserv_websockets_modules get_webmin_base_url); +@EXPORT = qw(read_file read_file_cached read_file_cached_with_stat write_file html_escape html_unescape html_strip quote_escape quote_javascript tempname_dir tempname transname transname_timestamped trunc indexof indexoflc sysprint check_ipaddress check_ip6address generate_icon urlize un_urlize include copydata ReadParseMime ReadParse read_fully read_parse_mime_callback read_parse_mime_javascript PrintHeader header get_html_title get_html_framed_title get_html_status_line popup_header footer popup_footer load_module_preferences load_theme_library redirect kill_byname kill_byname_logged find_byname error error_stderr popup_error register_error_handler call_error_handlers error_setup wait_for fast_wait_for has_command make_date file_chooser_button popup_window_button popup_window_link read_acl acl_filename acl_check get_miniserv_config_file get_miniserv_config put_miniserv_config restart_miniserv reload_miniserv check_os_support http_download complete_http_download http_post ftp_download ftp_upload no_proxy open_socket download_timeout ftp_command to_ipaddress to_ip6address to_hostname icons_table replace_meta replace_file_line read_file_lines flush_file_lines unflush_file_lines unix_user_input unix_group_input hlink user_chooser_button group_chooser_button foreign_check foreign_exists foreign_available foreign_require foreign_call foreign_config foreign_installed foreign_defined get_system_hostname get_webmin_version get_webmin_version_release get_webmin_full_version get_module_acl get_group_module_acl save_module_acl save_group_module_acl init_config load_language_auto load_language text_subs text encode_base64 decode_base64 encode_base32 decode_base32 get_module_info get_all_module_infos list_themes get_theme_info list_locales list_languages safe_language read_env_file write_env_file lock_file unlock_file test_lock unlock_all_files can_lock_file webmin_log additional_log var_dump webmin_debug_log system_logged backquote_logged backquote_with_timeout backquote_command kill_logged rename_logged rename_file symlink_logged symlink_file link_file make_dir make_dir_recursive set_ownership_permissions unlink_logged unlink_file copy_permissions_source_dest copy_source_dest move_source_dest remote_session_name verify_session_id remote_foreign_require remote_foreign_call remote_foreign_check remote_foreign_config remote_eval remote_write remote_read remote_finished remote_error_setup remote_rpc_call remote_multi_callback remote_multi_callback_error serialise_variable unserialise_variable other_groups date_chooser_button help_file read_help_file seed_random disk_usage_kb recursive_disk_usage help_search_link make_http_connection validate_ssl_connection read_http_connection write_http_connection close_http_connection clean_environment reset_environment clean_language progress_callback switch_to_remote_user switch_to_unix_user eval_as_unix_user create_user_config_dirs create_missing_homedir filter_javascript resolve_links simplify_path same_file flush_webmin_caches list_usermods available_usermods get_available_module_infos get_visible_module_infos get_visible_modules_categories is_under_directory parse_http_url check_clicks_function load_entities_map entities_to_ascii get_product_name get_charset get_display_hostname save_module_config save_user_module_config nice_size get_perl_path get_goto_module select_all_link select_invert_link select_rows_link check_pid_file get_mod_lib module_root_directory list_mime_types guess_mime_type open_tempfile close_tempfile print_tempfile is_selinux_enabled get_clear_file_attributes reset_file_attributes cleanup_tempnames open_lock_tempfile END month_to_number number_to_month get_rbac_module_acl supports_rbac supports_ipv6 use_rbac_module_acl execute_command open_readfile open_execute_command translate_filename translate_command register_filename_callback register_command_callback capture_function_output capture_function_output_tempfile modules_chooser_button substitute_template substitute_pattern running_in_zone running_in_vserver running_in_xen running_in_openvz list_categories is_readonly_mode command_as_user list_osdn_mirrors convert_osdn_url get_current_dir supports_users supports_symlinks quote_path get_windows_root read_file_contents write_file_contents read_file_contents_limit unix_crypt split_quoted_string write_to_http_cache check_in_http_cache clear_http_cache supports_javascript get_module_name get_module_variable clear_time_locale reset_time_locale callers_package web_libs_package get_userdb_string connect_userdb disconnect_userdb split_userdb_string uniquelc list_combined_webmin_menu list_modules_webmin_menu module_to_menu_item list_combined_system_info shell_is_bash compare_version_numbers convert_to_json convert_from_json print_json get_referer_relative get_webmin_email_url get_webmin_browser_url trim ui_link ui_help ui_img ui_link_button ui_table_start ui_table_end ui_table_row ui_table_hr ui_table_span ui_columns_start ui_columns_row ui_columns_header ui_checked_columns_row ui_radio_columns_row ui_columns_end ui_columns_table ui_form_columns_table ui_form_elements_wrapper ui_form_start ui_form_end ui_textbox ui_filebox ui_bytesbox ui_upload ui_password ui_hidden ui_select ui_multi_select ui_multi_select_javascript ui_radio ui_yesno_radio ui_radio_row ui_checkbox ui_oneradio ui_textarea ui_user_textbox ui_users_textbox ui_group_textbox ui_groups_textbox ui_opt_textbox ui_submit ui_reset ui_button ui_date_input ui_buttons_start ui_buttons_end ui_buttons_row ui_buttons_hr ui_post_header ui_pre_footer ui_print_header ui_print_unbuffered_header ui_print_footer ui_config_link ui_print_endpage ui_subheading ui_links_row ui_hidden_javascript ui_hidden_start ui_hidden_end ui_hidden_table_row_start ui_hidden_table_row_end ui_hidden_table_start ui_hidden_table_end ui_tabs_start ui_tabs_end ui_tabs_start_tab ui_tabs_start_tabletab ui_tabs_end_tab ui_tabs_end_tabletab ui_max_text_width ui_radio_selector ui_radio_selector_javascript ui_switch_theme_javascript ui_grid_table ui_radio_table ui_up_down_arrows ui_hr ui_nav_link ui_confirmation_form ui_text_color ui_alert_box js_disable_inputs ui_page_flipper js_checkbox_disable js_redirect ui_webmin_link ui_line_break_double ui_page_refresh ui_details ui_div_row ui_space ui_newline ui_text_wrap ui_element_inline ui_paginations ui_hide_outside_of_viewport ui_read_file_contents_limit ui_note ui_brh ui_tag_start ui_tag_content ui_tag_end ui_tag ui_alert ui_button_icon ui_link_icon ui_icon ui_br ui_p ui_text_mask get_python_cmd get_buffer_size get_buffer_size_binary get_webprefix get_sub_ref_name setvar getvar delvar print_call_stack webmin_user_can_rpc webmin_user_login_mode webmin_user_is_admin webmin_user_is get_current_theme_info_cached miniserv_using_default_cert is_int float is_float parse_accepted_language get_default_system_locale get_http_redirect get_http_cookie create_wrapper get_lock_links_dir allocate_miniserv_websocket get_miniserv_websocket_url remove_miniserv_websocket cleanup_miniserv_websockets get_miniserv_websockets_modules get_webmin_base_url encrypt_phrase decrypt_phrase is_encrypt_phrase); # Add global variables in web-lib.pl push(@EXPORT, qw(&unique)); diff --git a/firewalld/config b/firewalld/config index 3de7e4fcd..7f597097e 100644 --- a/firewalld/config +++ b/firewalld/config @@ -1,4 +1,5 @@ firewall_cmd=firewall-cmd init_name=firewalld config_dir=/etc/firewalld -packet_handling=drop +packet_handling=0 +timeout=0 diff --git a/firewalld/config.info b/firewalld/config.info index 0b77490d9..6f4b52724 100644 --- a/firewalld/config.info +++ b/firewalld/config.info @@ -2,3 +2,4 @@ firewall_cmd=Full path to firewall-cmd program,0 init_name=FirewallD init script name,0 config_dir=FirewallD configuration directory,0 packet_handling=Default packet handling action,1,0-drop,1-reject +timeout=Timeout for temporary rules,15,timeout_data diff --git a/firewalld/config_info.pl b/firewalld/config_info.pl new file mode 100755 index 000000000..5e88a08a5 --- /dev/null +++ b/firewalld/config_info.pl @@ -0,0 +1,48 @@ +require './firewalld-lib.pl'; + +# show_timeout_data(value, config-option-name) +# Returns a radio button and a select box for timeout values +sub show_timeout_data +{ +my ($value, $name) = @_; +$name = &format_option_name($name); +my $radio = &ui_radio( + "${name}_def", !$value ? 1 : 0, + [ [ 1, $text{'config_timeout_none'} ], + [ 0, ' ' ] ] ); +my @list = &get_timeouts(); +my @opts = map { [ $_, $text{"config_timeout_$_"} ] } @list; +my $select = &ui_select($name, !$value ? $list[3] : $value, \@opts); +return $radio . ' ' . $select; +} + +# parse_timeout_data(old-value, config-option-name) +# Parses the timeout value from the form input +sub parse_timeout_data +{ +my ($oldval, $name) = @_; +$name = &format_option_name($name); +my $val = $in{$name} // ''; +return 0 if ($in{"${name}_def"}); +my %valid = map { $_ => 1 } &get_timeouts(); +&error(&text('config_timeout_err', $val)) unless($valid{$val}); +return $val; +} + +# get_timeouts +# Returns a list of valid timeout values for the select box +sub get_timeouts +{ +return qw(1m 5m 15m 30m 1h 3h 6h 12h 1d 3d 7d 30d); +} + +# format_option_name(name) +# Formats the option name for use in HTML element names +sub format_option_name +{ +my ($name) = @_; +$name =~ s/\s+/_/g; +$name =~ s/[^\x00-\x7F]/_/g; +$name = lc($name); +return $name; +} diff --git a/firewalld/firewalld-lib.pl b/firewalld/firewalld-lib.pl index 420ccc21c..9f69786ac 100644 --- a/firewalld/firewalld-lib.pl +++ b/firewalld/firewalld-lib.pl @@ -540,6 +540,14 @@ if (!$zone) { $zone = $zone->{'name'}; } +# Timeout +my $timeout = $opts->{'timeout'}; +if ($timeout) { + # Validate timeout format + &error(&text('config_timeout_err', $timeout)) + if ($timeout !~ /^(\d+)([smhd]?)$/); + } + # Permanent rule my $permanent = $opts->{'permanent'}; @@ -548,7 +556,8 @@ my $get_cmd = sub { my ($rtype) = @_; my $type = $rtype ? " --permanent" : ""; return "$config{'firewall_cmd'} --zone=\"".quotemeta($zone)."\"". - "$type --".quotemeta($action)."-rich-rule='$opts->{'rule'}'"; + "$type --".quotemeta($action)."-rich-rule='$opts->{'rule'}'". + ($timeout ? " --timeout=".quotemeta($timeout) : ""); }; for my $type (0..1) { diff --git a/firewalld/lang/en b/firewalld/lang/en index 732b4f453..44510e017 100644 --- a/firewalld/lang/en +++ b/firewalld/lang/en @@ -50,6 +50,21 @@ index_dependent=Failed to restart $1 dependent service index_manual=Edit Config Files. index_downrules=FirewallD rules cannot be created or edited and are not enforced unless the server is running. +config_timeout_none=None +config_timeout_1m=1 minute +config_timeout_5m=5 minutes +config_timeout_15m=15 minutes +config_timeout_30m=30 minutes +config_timeout_1h=1 hour +config_timeout_3h=3 hours +config_timeout_6h=6 hours +config_timeout_12h=12 hours +config_timeout_1d=1 day +config_timeout_3d=3 days +config_timeout_7d=7 days +config_timeout_30d=30 days +config_timeout_err=Invalid timeout value $1 + manual_title=Edit Config Files manual_editsel=Edit FirewallD configuration file manual_err=Failed to save config file diff --git a/firewalld/manage_ip.cgi b/firewalld/manage_ip.cgi index cb831da33..6cecbcb4e 100755 --- a/firewalld/manage_ip.cgi +++ b/firewalld/manage_ip.cgi @@ -6,7 +6,7 @@ use warnings; no warnings 'redefine'; no warnings 'uninitialized'; require './firewalld-lib.pl'; -our (%in, %text); +our (%in, %text, %config); &ReadParse(); # Setup error messages @@ -31,6 +31,7 @@ $ip =~ s/\Q$mask\E// if ($mask); # Block the IP my $perm = $in{'permanent'} ? 'perm' : ''; +my $timeout = $config{'timeout'} unless ($perm && $config{'timeout'}); my ($out, $rs) = &rich_rule('add', { 'rule' => &construct_rich_rule( @@ -38,7 +39,8 @@ my ($out, $rs) = &rich_rule('add', 'action' => $allow ? 'accept' : undef, 'priority' => $allow ? -32767 : -32766, ), - 'zone' => $zone->{'name'}, 'permanent' => $perm }); + 'zone' => $zone->{'name'}, 'permanent' => $perm, + 'timeout' => $timeout }); &error($out) if ($rs); &apply_firewalld() if ($perm); diff --git a/mailboxes/config.info.fr b/mailboxes/config.info.fr index 093309e90..29f19887c 100644 --- a/mailboxes/config.info.fr +++ b/mailboxes/config.info.fr @@ -31,7 +31,7 @@ show_count=Afficher le nombre de messages dans la boîte de réception?,1,1-Oui, sort_mode=Trier les boîtes aux lettres par,1,2-Taille,1-Nom d'utilisateur,0-Commander dans le fichier de mot de passe show_mail=Afficher uniquement les utilisateurs qui ont du courrier?,1,1-Oui,0-Non size_mode=Inclure tous les dossiers dans la taille?,1,1-Oui,0-Non (premier dossier uniquement) -ignore_users=Ignorer ces noms d'utilisateur (ne pas afficher),15,Liste des utilisateurs ignorés +ignore_users=Ignorer ces noms d'utilisateur (ne pas afficher),15,userIgnoreList ignore_users_enabled=Ignorer l'état de la liste,1,1-Activé,0-Désactivé line0.5=Options de dossier,11 diff --git a/phpini/install_mod.cgi b/phpini/install_mod.cgi index 1e3178573..2a91c98b9 100755 --- a/phpini/install_mod.cgi +++ b/phpini/install_mod.cgi @@ -31,11 +31,11 @@ if ($got) { } # Try to install them -&ui_print_header("".&html_escape($in{'file'})."", +&ui_print_unbuffered_header("".&html_escape($in{'file'})."", $text{'imod_title'}, ""); print &text('imod_alldoing', "".&html_escape($in{'mod'})."", - $ver),"
\n";
+ $ver),"
\n";
my $ok = 0;
foreach my $pkg (@poss) {
@@ -57,13 +57,13 @@ foreach my $pkg (@poss) {
}
if ($ok) {
print &text('imod_alldone',
- "".&html_escape($ok).""),"
\n"; + "".&html_escape($ok).""); &graceful_apache_restart($in{'file'}); &webmin_log("imod", undef, $in{'file'}, { 'mod' => $in{'mod'} }); } else { print &text('imod_allfailed', - "".&html_escape(join(" ", @poss)).""),"
\n"; + "".&html_escape(join(" ", @poss)).""); } &ui_print_footer("edit_mods.cgi?file=".&urlize($in{'file'}), diff --git a/proc/linux-lib.pl b/proc/linux-lib.pl index 97e333aa4..755fbdde8 100755 --- a/proc/linux-lib.pl +++ b/proc/linux-lib.pl @@ -513,7 +513,12 @@ if (&has_command("sensors")) { # CPU full output must have either voltage or fan data my ($cpu_volt) = $_ =~ /(?|in[\d+]\s*:\s+([\+\-0-9\.]+)\s+V|cpu\s+core\s+voltage\s*:\s+([0-9\.]+)\s+V)/i; - my ($cpu_fan_num, $cpu_fan_rpm) = $_ =~ /(?|fan([\d+])\s*:\s*([0-9]+)\s*rpm|cpu(\s)fan\s*:\s*([0-9]+)\s*rpm|cpu\s+fan\s*:\s*([0-9]+)\s*rpm)/i; + # CPU fans should be always labeled as 'cpu fan' or 'cpu_fan' or 'cpufan' + # and/or 'cpu fan 1', 'cpu_fan1', 'cpufan1', 'cpu_fan 2', 'cpu_fan2', + # 'cpufan2' etc. + my ($cpu_fan_num, $cpu_fan_rpm) = + $_ =~ /(?|^\s*cpu[_ ]?fan(?:[_ ]?(\d+))?\s*:\s*(\d+)\s*rpm)/i; + $cpu_fan_num //= 1 if (defined($cpu_fan_rpm)); $cpu++ if ($cpu_volt || $cpu_fan_num); # First just store fan data for any device if any diff --git a/ui-lib.pl b/ui-lib.pl index 36488827b..3a1e71171 100755 --- a/ui-lib.pl +++ b/ui-lib.pl @@ -1602,7 +1602,7 @@ return &theme_ui_buttons_end(@_) if (defined(&theme_ui_buttons_end)); return "\n"; } -=head2 ui_buttons_row(script, button-label, description, [hiddens], [after-submit], [before-submit]) +=head2 ui_buttons_row(script, button-label, description, [hiddens], [after-submit], [before-submit], [postmethod]) Returns HTML for a button with a description next to it, and perhaps other inputs. The parameters are : @@ -1619,15 +1619,18 @@ inputs. The parameters are : =item before-submit - HTML for text or inputs to appear before the submit button. +=item postmethod - Defines the method used to submit the form. Defaults to 'post'. + =cut sub ui_buttons_row { return &theme_ui_buttons_row(@_) if (defined(&theme_ui_buttons_row)); -my ($script, $label, $desc, $hiddens, $after, $before) = @_; +my ($script, $label, $desc, $hiddens, $after, $before, $postmethod) = @_; +$postmethod ||= 'post'; if (ref($hiddens)) { $hiddens = join("\n", map { &ui_hidden(@$_) } @$hiddens); } -return "